@@ -336,168 +336,128 @@ protected Object create(LazyPythonClass cls, byte[] barr) {
336336 public abstract static class ComplexNode extends PythonBuiltinNode {
337337
338338 @ Child private GetLazyClassNode getClassNode ;
339- @ Child private CoerceToDoubleNode castRealNode ;
340- @ Child private CoerceToDoubleNode castImagNode ;
341339 @ Child private LookupAndCallUnaryNode callComplexFunc ;
342- @ Child private CoerceToDoubleNode fallbackCoerce ;
340+ @ Child private CoerceToDoubleNode firstArgCoerceToDouble ;
341+ @ Child private CoerceToDoubleNode secondArgCoerceToDouble ;
343342
344343 private final IsBuiltinClassProfile isPrimitiveProfile = IsBuiltinClassProfile .create ();
345- private IsBuiltinClassProfile isComplexTypeProfile ;
346- private IsBuiltinClassProfile profile ;
347- private BranchProfile errorProfile ;
344+ @ CompilationFinal private IsBuiltinClassProfile isComplexTypeProfile ;
348345
349- protected boolean isPrimitiveComplex (LazyPythonClass cls ) {
350- return isPrimitiveProfile .profileClass (cls , PythonBuiltinClassType .PComplex );
346+ private PComplex createComplex (LazyPythonClass cls , double real , double imaginary ) {
347+ if (isPrimitiveProfile .profileClass (cls , PythonBuiltinClassType .PComplex )) {
348+ return factory ().createComplex (real , imaginary );
349+ }
350+ return factory ().createComplex (cls , real , imaginary );
351+ }
352+
353+ private PComplex createComplex (LazyPythonClass cls , PComplex value ) {
354+ if (isPrimitiveProfile .profileClass (cls , PythonBuiltinClassType .PComplex )) {
355+ return value ;
356+ }
357+ return factory ().createComplex (cls , value .getReal (), value .getImag ());
358+ }
359+
360+ @ Specialization (guards = {"isNoValue(real)" , "isNoValue(imag)" })
361+ @ SuppressWarnings ("unused" )
362+ PComplex complexFromNone (LazyPythonClass cls , PNone real , PNone imag ) {
363+ return createComplex (cls , 0 , 0 );
351364 }
352365
353366 @ Specialization
354367 PComplex complexFromIntInt (LazyPythonClass cls , int real , int imaginary ) {
355- if (isPrimitiveComplex (cls )) {
356- return factory ().createComplex (real , imaginary );
357- }
358- return factory ().createComplex (cls , real , imaginary );
368+ return createComplex (cls , real , imaginary );
359369 }
360370
361371 @ Specialization
362372 PComplex complexFromLongLong (LazyPythonClass cls , long real , long imaginary ) {
363- if (isPrimitiveComplex (cls )) {
364- return factory ().createComplex (real , imaginary );
365- }
366- return factory ().createComplex (cls , real , imaginary );
373+ return createComplex (cls , real , imaginary );
367374 }
368375
369376 @ Specialization
370377 PComplex complexFromLongLong (LazyPythonClass cls , PInt real , PInt imaginary ) {
371- if (isPrimitiveComplex (cls )) {
372- return factory ().createComplex (real .doubleValue (), imaginary .doubleValue ());
373- }
374- return factory ().createComplex (cls , real .doubleValue (), imaginary .doubleValue ());
378+ return createComplex (cls , real .doubleValue (), imaginary .doubleValue ());
375379 }
376380
377381 @ Specialization
378382 PComplex complexFromDoubleDouble (LazyPythonClass cls , double real , double imaginary ) {
379- if (isPrimitiveComplex (cls )) {
380- return factory ().createComplex (real , imaginary );
381- }
382- return factory ().createComplex (cls , real , imaginary );
383+ return createComplex (cls , real , imaginary );
383384 }
384385
385- @ Specialization
386- PComplex complexFromDouble (LazyPythonClass cls , double real , @ SuppressWarnings ("unused" ) PNone image ) {
387- if (isPrimitiveComplex (cls )) {
388- return factory ().createComplex (real , 0 );
389- }
390- return factory ().createComplex (cls , real , 0 );
386+ @ Specialization (guards = "isNoValue(imag)" )
387+ PComplex complexFromDouble (LazyPythonClass cls , double real , @ SuppressWarnings ("unused" ) PNone imag ) {
388+ return createComplex (cls , real , 0 );
391389 }
392390
393- @ Specialization
394- PComplex complexFromInt (LazyPythonClass cls , int real , @ SuppressWarnings ("unused" ) PNone image ) {
395- if (isPrimitiveComplex (cls )) {
396- return factory ().createComplex (real , 0 );
397- }
398- return factory ().createComplex (cls , real , 0 );
391+ @ Specialization (guards = "isNoValue(imag)" )
392+ PComplex complexFromInt (LazyPythonClass cls , int real , @ SuppressWarnings ("unused" ) PNone imag ) {
393+ return createComplex (cls , real , 0 );
399394 }
400395
401- @ Specialization
402- PComplex complexFromLong (LazyPythonClass cls , long real , @ SuppressWarnings ("unused" ) PNone image ) {
403- if (isPrimitiveComplex (cls )) {
404- return factory ().createComplex (real , 0 );
405- }
406- return factory ().createComplex (cls , real , 0 );
396+ @ Specialization (guards = "isNoValue(imag)" )
397+ PComplex complexFromLong (LazyPythonClass cls , long real , @ SuppressWarnings ("unused" ) PNone imag ) {
398+ return createComplex (cls , real , 0 );
407399 }
408400
409- @ Specialization
410- PComplex complexFromLong (LazyPythonClass cls , PInt real , @ SuppressWarnings ("unused" ) PNone image ) {
411- if (isPrimitiveComplex (cls )) {
412- return factory ().createComplex (real .doubleValue (), 0 );
413- }
414- return factory ().createComplex (cls , real .doubleValue (), 0 );
401+ @ Specialization (guards = "isNoValue(imag)" )
402+ PComplex complexFromLong (LazyPythonClass cls , PInt real , @ SuppressWarnings ("unused" ) PNone imag ) {
403+ return createComplex (cls , real .doubleValue (), 0 );
404+ }
405+
406+ @ Specialization (guards = {"isNoValue(imag)" , "!isNoValue(number)" , "!isString(number)" })
407+ PComplex complexFromObject (VirtualFrame frame , LazyPythonClass cls , Object number , @ SuppressWarnings ("unused" ) PNone imag ) {
408+ PComplex value = getComplexNumberFromObject (frame , number );
409+ return createComplex (cls , value );
415410 }
416411
417412 @ Specialization
418413 PComplex complexFromLongComplex (LazyPythonClass cls , long one , PComplex two ) {
419- if (isPrimitiveComplex (cls )) {
420- return factory ().createComplex (one - two .getImag (), two .getReal ());
421- }
422- return factory ().createComplex (cls , one - two .getImag (), two .getReal ());
414+ return createComplex (cls , one - two .getImag (), two .getReal ());
423415 }
424416
425417 @ Specialization
426418 PComplex complexFromPIntComplex (LazyPythonClass cls , PInt one , PComplex two ) {
427- if (isPrimitiveComplex (cls )) {
428- return factory ().createComplex (one .doubleValue () - two .getImag (), two .getReal ());
429- }
430- return factory ().createComplex (cls , one .doubleValue () - two .getImag (), two .getReal ());
419+ return createComplex (cls , one .doubleValue () - two .getImag (), two .getReal ());
431420 }
432421
433422 @ Specialization
434423 PComplex complexFromDoubleComplex (LazyPythonClass cls , double one , PComplex two ) {
435- if (isPrimitiveComplex (cls )) {
436- return factory ().createComplex (one - two .getImag (), two .getReal ());
437- }
438- return factory ().createComplex (cls , one - two .getImag (), two .getReal ());
424+ return createComplex (cls , one - two .getImag (), two .getReal ());
439425 }
440426
441- @ Specialization
442- PComplex complexFromComplexLong (VirtualFrame frame , LazyPythonClass cls , PComplex one , long two ) {
427+ @ Specialization ( guards = "!isString(one)" )
428+ PComplex complexFromComplexLong (VirtualFrame frame , LazyPythonClass cls , Object one , long two ) {
443429 PComplex value = getComplexNumberFromObject (frame , one );
444- if (isPrimitiveComplex (cls )) {
445- return factory ().createComplex (value .getReal (), value .getImag () + two );
446- }
447- return factory ().createComplex (cls , value .getReal (), value .getImag () + two );
430+ return createComplex (cls , value .getReal (), value .getImag () + two );
448431 }
449432
450- @ Specialization
451- PComplex complexFromComplexDouble (VirtualFrame frame , LazyPythonClass cls , PComplex one , double two ) {
433+ @ Specialization ( guards = "!isString(one)" )
434+ PComplex complexFromComplexDouble (VirtualFrame frame , LazyPythonClass cls , Object one , double two ) {
452435 PComplex value = getComplexNumberFromObject (frame , one );
453- if (isPrimitiveComplex (cls )) {
454- return factory ().createComplex (value .getReal (), value .getImag () + two );
455- }
456- return factory ().createComplex (cls , value .getReal (), value .getImag () + two );
436+ return createComplex (cls , value .getReal (), value .getImag () + two );
457437 }
458438
459- @ Specialization
460- PComplex complexFromComplexPInt (VirtualFrame frame , LazyPythonClass cls , PComplex one , PInt two ) {
439+ @ Specialization ( guards = "!isString(one)" )
440+ PComplex complexFromComplexPInt (VirtualFrame frame , LazyPythonClass cls , Object one , PInt two ) {
461441 PComplex value = getComplexNumberFromObject (frame , one );
462- if (isPrimitiveComplex (cls )) {
463- return factory ().createComplex (value .getReal (), value .getImag () + two .doubleValue ());
464- }
465- return factory ().createComplex (cls , value .getReal (), value .getImag () + two .doubleValue ());
442+ return createComplex (cls , value .getReal (), value .getImag () + two .doubleValue ());
466443 }
467444
468- @ Specialization
469- PComplex complexFromComplex (VirtualFrame frame , LazyPythonClass cls , PComplex number , @ SuppressWarnings ("unused" ) PNone image ) {
470- PComplex value = getComplexNumberFromObject (frame , number );
471- if (isPrimitiveComplex (cls )) {
472- return value ;
473- }
474- return factory ().createComplex (cls , value .getReal (), value .getImag ());
475- }
476-
477- @ Specialization
478- PComplex complexFromComplexComplex (VirtualFrame frame , LazyPythonClass cls , PComplex one , PComplex two ) {
445+ @ Specialization (guards = "!isString(one)" )
446+ PComplex complexFromComplexComplex (VirtualFrame frame , LazyPythonClass cls , Object one , PComplex two ) {
479447 PComplex value = getComplexNumberFromObject (frame , one );
480- if (isPrimitiveComplex (cls )) {
481- return factory ().createComplex (value .getReal () - two .getImag (), value .getImag () + two .getReal ());
482- }
483- return factory ().createComplex (cls , value .getReal () - two .getImag (), value .getImag () + two .getReal ());
448+ return createComplex (cls , value .getReal () - two .getImag (), value .getImag () + two .getReal ());
484449 }
485450
486- @ Specialization
487- @ SuppressWarnings ("unused" )
488- PComplex complexFromNone (LazyPythonClass cls , PNone real , PNone image ) {
489- if (real == PNone .NONE ) {
490- throw raise (TypeError , "complex() first argument must be a string or a number, not '%p'" , real );
491- }
492- if (isPrimitiveComplex (cls )) {
493- return factory ().createComplex (0 , 0 );
494- }
495- return factory ().createComplex (cls , 0 , 0 );
451+ @ Specialization (guards = {"!isString(one)" , "!isNoValue(two)" , "!isPComplex(two)" })
452+ PComplex complexFromComplexObject (VirtualFrame frame , LazyPythonClass cls , Object one , Object two ) {
453+ PComplex oneValue = getComplexNumberFromObject (frame , one );
454+ double twoValue = getSecondArgCoerceToDouble ().execute (frame , two );
455+ return createComplex (cls , oneValue .getReal (), oneValue .getImag () + twoValue );
496456 }
497457
498458 @ Specialization
499- PComplex complexFromObjectObject (LazyPythonClass cls , String real , Object imaginary ) {
500- if (!( imaginary instanceof PNone ) ) {
459+ PComplex complexFromString (LazyPythonClass cls , String real , Object imaginary ) {
460+ if (imaginary != PNone . NO_VALUE ) {
501461 throw raise (TypeError , "complex() can't take second arg if first is a string" );
502462 }
503463 return convertStringToComplex (real , cls );
@@ -513,41 +473,12 @@ private GetLazyClassNode getGetClassNode() {
513473
514474 private IsBuiltinClassProfile getIsComplexTypeProfile () {
515475 if (isComplexTypeProfile == null ) {
476+ CompilerDirectives .transferToInterpreterAndInvalidate ();
516477 isComplexTypeProfile = IsBuiltinClassProfile .create ();
517478 }
518479 return isComplexTypeProfile ;
519480 }
520481
521- private BranchProfile getErrorProfile () {
522- if (errorProfile == null ) {
523- errorProfile = BranchProfile .create ();
524- }
525- return errorProfile ;
526- }
527-
528- private CoerceToDoubleNode getCastRealNode () {
529- if (castRealNode == null ) {
530- CompilerDirectives .transferToInterpreterAndInvalidate ();
531- castRealNode = insert (CoerceToDoubleNode .create ());
532- }
533- return castRealNode ;
534- }
535-
536- private CoerceToDoubleNode getCastImagNode () {
537- if (castImagNode == null ) {
538- CompilerDirectives .transferToInterpreterAndInvalidate ();
539- castImagNode = insert (CoerceToDoubleNode .create ());
540- }
541- return castImagNode ;
542- }
543-
544- private IsBuiltinClassProfile getProfile () {
545- if (profile == null ) {
546- profile = IsBuiltinClassProfile .create ();
547- }
548- return profile ;
549- }
550-
551482 private LookupAndCallUnaryNode getCallComplexFunc () {
552483 if (callComplexFunc == null ) {
553484 CompilerDirectives .transferToInterpreterAndInvalidate ();
@@ -556,14 +487,24 @@ private LookupAndCallUnaryNode getCallComplexFunc() {
556487 return callComplexFunc ;
557488 }
558489
559- private CoerceToDoubleNode getFallbackCoerce () {
560- if (fallbackCoerce == null ) {
490+ private CoerceToDoubleNode getFirstArgCoerceToDouble () {
491+ if (firstArgCoerceToDouble == null ) {
561492 CompilerDirectives .transferToInterpreterAndInvalidate ();
562- fallbackCoerce = insert (CoerceToDoubleNode .create (val -> {
493+ firstArgCoerceToDouble = insert (CoerceToDoubleNode .create (val -> {
563494 throw raise (PythonBuiltinClassType .TypeError , "complex() first argument must be a string or a number, not '%p'" , val );
564495 }));
565496 }
566- return fallbackCoerce ;
497+ return firstArgCoerceToDouble ;
498+ }
499+
500+ private CoerceToDoubleNode getSecondArgCoerceToDouble () {
501+ if (secondArgCoerceToDouble == null ) {
502+ CompilerDirectives .transferToInterpreterAndInvalidate ();
503+ secondArgCoerceToDouble = insert (CoerceToDoubleNode .create (val -> {
504+ throw raise (PythonBuiltinClassType .TypeError , "complex() second argument must be a number, not '%p'" , val );
505+ }));
506+ }
507+ return secondArgCoerceToDouble ;
567508 }
568509
569510 private PComplex getComplexNumberFromObject (VirtualFrame frame , Object object ) {
@@ -572,9 +513,6 @@ private PComplex getComplexNumberFromObject(VirtualFrame frame, Object object) {
572513 } else {
573514 Object result = getCallComplexFunc ().executeObject (frame , object );
574515 if (result != PNone .NO_VALUE ) {
575- if (getIsComplexTypeProfile ().profileClass (getGetClassNode ().execute (object ), PythonBuiltinClassType .PComplex )) {
576- return (PComplex ) result ;
577- }
578516 if (result instanceof PComplex ) {
579517 // TODO we need pass here deprecation warning
580518 // DeprecationWarning: __complex__ returned non-complex (type %p).
@@ -590,44 +528,14 @@ private PComplex getComplexNumberFromObject(VirtualFrame frame, Object object) {
590528 // the class extending PComplex but doesn't have __complex__ method
591529 return (PComplex ) object ;
592530 }
593- return factory ().createComplex (getFallbackCoerce ().execute (frame , object ), 0.0 );
531+ return factory ().createComplex (getFirstArgCoerceToDouble ().execute (frame , object ), 0.0 );
594532 }
595533 }
596534
597535 @ Fallback
598- Object complexGeneric (VirtualFrame frame , @ SuppressWarnings ("unused" ) Object cls , Object realObj , Object imaginaryObj ) {
599- boolean noImag = PGuards .isNoValue (imaginaryObj );
600- if (noImag ) {
601- if (getIsComplexTypeProfile ().profileClass (getGetClassNode ().execute (realObj ), PythonBuiltinClassType .PComplex )) {
602- return realObj ;
603- }
604- Object result = getCallComplexFunc ().executeObject (frame , realObj );
605- if (result != PNone .NO_VALUE && result instanceof PComplex ) {
606- return result ;
607- }
608- }
609- try {
610- double real = getCastRealNode ().execute (frame , realObj );
611- double imag = !noImag ? getCastImagNode ().execute (frame , imaginaryObj ) : 0.0 ;
612- if (isPrimitiveComplex ((LazyPythonClass ) cls )) {
613- return factory ().createComplex (real , imag );
614- }
615- return factory ().createComplex ((LazyPythonClass ) cls , real , imag );
616- } catch (PException e ) {
617- getErrorProfile ().enter ();
618- e .expect (PythonBuiltinClassType .TypeError , getProfile ());
619- if (!(PGuards .isString (realObj ) || PGuards .isInteger (realObj ) || PGuards .isPInt (realObj ) || PGuards .isDouble (realObj ))) {
620- throw raise (TypeError , "complex() first argument must be a string or a number, not '%p'" , realObj );
621- }
622- if (!((PGuards .isInteger (imaginaryObj ) || PGuards .isPInt (imaginaryObj ) || PGuards .isDouble (imaginaryObj )))) {
623- throw raise (TypeError , "complex() second argument must be a number, not '%p'" , imaginaryObj );
624- }
625- throw raise (TypeError , "can't convert real %s imag %s" , realObj , imaginaryObj );
626- }
627- }
628-
629- protected static boolean isExactComplexType (GetLazyClassNode getClassNode , PComplex obj ) {
630- return getClassNode .execute (obj ) == PythonBuiltinClassType .PComplex ;
536+ @ SuppressWarnings ("unused" )
537+ Object complexGeneric (Object cls , Object realObj , Object imaginaryObj ) {
538+ throw raise (TypeError , "complex.__new__(X): X is not a type object (%p)" , cls );
631539 }
632540
633541 // Taken from Jython PyString's __complex__() method
@@ -794,10 +702,7 @@ private PComplex convertStringToComplex(String str, LazyPythonClass cls) {
794702 throw raise (ValueError , "malformed string for complex() %s" , str .substring (s ));
795703 }
796704
797- if (isPrimitiveComplex (cls )) {
798- return factory ().createComplex (x , y );
799- }
800- return factory ().createComplex (cls , x , y );
705+ return createComplex (cls , x , y );
801706 }
802707
803708 // Taken from Jython PyString directly
0 commit comments