139
139
import com .oracle .truffle .api .RootCallTarget ;
140
140
import com .oracle .truffle .api .TruffleLogger ;
141
141
import com .oracle .truffle .api .dsl .Cached ;
142
- import com .oracle .truffle .api .dsl .CachedLanguage ;
143
142
import com .oracle .truffle .api .dsl .Specialization ;
144
143
import com .oracle .truffle .api .interop .ArityException ;
145
144
import com .oracle .truffle .api .interop .InteropException ;
@@ -374,55 +373,20 @@ Object execute(Object[] arguments,
374
373
}
375
374
376
375
@ ExportLibrary (InteropLibrary .class )
377
- public static final class GraalHPyArithmetic extends GraalHPyContextFunction {
378
- private final UnaryArithmetic unaryOperator ;
379
- private final BinaryArithmetic binaryOperator ;
380
- private final InplaceArithmetic inplaceOperator ;
381
- private final TernaryArithmetic ternaryOperator ;
376
+ abstract static class GraalHPyArithmetic extends GraalHPyContextFunction {
382
377
383
378
@ CompilationFinal private RootCallTarget callTarget ;
384
379
385
- public GraalHPyArithmetic (UnaryArithmetic unaryOperator ) {
386
- this .unaryOperator = unaryOperator ;
387
- this .binaryOperator = null ;
388
- this .inplaceOperator = null ;
389
- this .ternaryOperator = null ;
390
- }
391
-
392
- public GraalHPyArithmetic (BinaryArithmetic binaryOperator ) {
393
- this .unaryOperator = null ;
394
- this .binaryOperator = binaryOperator ;
395
- this .inplaceOperator = null ;
396
- this .ternaryOperator = null ;
397
- }
398
-
399
- public GraalHPyArithmetic (InplaceArithmetic inplaceOperator ) {
400
- this .unaryOperator = null ;
401
- this .binaryOperator = null ;
402
- this .inplaceOperator = inplaceOperator ;
403
- this .ternaryOperator = null ;
404
- }
405
-
406
- public GraalHPyArithmetic (TernaryArithmetic ternaryOperator ) {
407
- this .unaryOperator = null ;
408
- this .binaryOperator = null ;
409
- this .inplaceOperator = null ;
410
- this .ternaryOperator = ternaryOperator ;
411
- }
412
-
413
380
@ ExportMessage
414
381
Object execute (Object [] arguments ,
415
- @ CachedLanguage @ SuppressWarnings ("unused" ) PythonLanguage language ,
416
382
@ Cached HPyAsContextNode asContextNode ,
417
383
@ Cached HPyAsPythonObjectNode asPythonObjectNode ,
418
384
@ Cached HPyAsHandleNode asHandleNode ,
419
385
@ Cached GenericInvokeNode invokeNode ,
420
386
@ Cached TransformExceptionToNativeNode transformExceptionToNativeNode ) throws ArityException {
421
387
422
- // We need to do argument checking at this position because our helper root node that
423
- // just dispatches to the appropriate 'LookupAndCallXXXNode' won't do any argument
424
- // checking. So it would just crash if there are too few arguments or just ignore if
425
- // there are too many.
388
+ // We need to do argument checking at this position because our helper root node won't
389
+ // do it.
426
390
checkArguments (arguments );
427
391
428
392
GraalHPyContext context = asContextNode .execute (arguments [0 ]);
@@ -433,52 +397,121 @@ Object execute(Object[] arguments,
433
397
}
434
398
435
399
try {
436
- Object result = invokeNode .execute (getCallTarget ( language ), pythonArguments );
400
+ Object result = invokeNode .execute (ensureCallTarget ( ), pythonArguments );
437
401
return asHandleNode .execute (result );
438
402
} catch (PException e ) {
439
403
transformExceptionToNativeNode .execute (e );
440
404
return context .getNullHandle ();
441
405
}
442
406
}
443
407
444
- private void checkArguments (Object [] arguments ) throws ArityException {
445
- // note: we always add 1 for the context
446
- int min ;
447
- int max ;
448
- if (unaryOperator != null ) {
449
- min = max = 2 ;
450
- } else if (binaryOperator != null ) {
451
- min = max = 3 ;
452
- } else if (inplaceOperator != null ) {
453
- min = 3 ;
454
- max = 4 ;
455
- } else if (ternaryOperator != null ) {
456
- min = max = 4 ;
457
- } else {
458
- throw CompilerDirectives .shouldNotReachHere ();
408
+ private RootCallTarget ensureCallTarget () {
409
+ if (callTarget == null ) {
410
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
411
+ callTarget = createCallTarget (PythonLanguage .getCurrent ());
459
412
}
460
- if (min > arguments .length || max < arguments .length ) {
413
+ return callTarget ;
414
+ }
415
+
416
+ protected abstract void checkArguments (Object [] arguments ) throws ArityException ;
417
+
418
+ protected abstract RootCallTarget createCallTarget (PythonLanguage language );
419
+
420
+ }
421
+
422
+ @ ExportLibrary (InteropLibrary .class )
423
+ public static final class GraalHPyUnaryArithmetic extends GraalHPyArithmetic {
424
+ private final UnaryArithmetic unaryOperator ;
425
+
426
+ public GraalHPyUnaryArithmetic (UnaryArithmetic unaryOperator ) {
427
+ this .unaryOperator = unaryOperator ;
428
+ }
429
+
430
+ @ Override
431
+ protected void checkArguments (Object [] arguments ) throws ArityException {
432
+ // we also need to account for the HPy context
433
+ if (arguments .length != 2 ) {
461
434
CompilerDirectives .transferToInterpreterAndInvalidate ();
462
- int expected = min > arguments .length ? min : max ;
463
- throw ArityException .create (expected , arguments .length );
435
+ throw ArityException .create (2 , arguments .length );
464
436
}
465
437
}
466
438
467
- private RootCallTarget getCallTarget (PythonLanguage language ) {
468
- if (callTarget == null ) {
439
+ @ Override
440
+ protected RootCallTarget createCallTarget (PythonLanguage language ) {
441
+ return language .getOrCreateUnaryArithmeticCallTarget (unaryOperator );
442
+ }
443
+ }
444
+
445
+ @ ExportLibrary (InteropLibrary .class )
446
+ public static final class GraalHPyBinaryArithmetic extends GraalHPyArithmetic {
447
+ private final BinaryArithmetic binaryOperator ;
448
+
449
+ public GraalHPyBinaryArithmetic (BinaryArithmetic unaryOperator ) {
450
+ this .binaryOperator = unaryOperator ;
451
+ }
452
+
453
+ @ Override
454
+ protected void checkArguments (Object [] arguments ) throws ArityException {
455
+ // we also need to account for the HPy context
456
+ if (arguments .length != 3 ) {
469
457
CompilerDirectives .transferToInterpreterAndInvalidate ();
470
- if (unaryOperator != null ) {
471
- callTarget = language .getOrCreateUnaryArithmeticCallTarget (unaryOperator );
472
- } else if (binaryOperator != null ) {
473
- callTarget = language .getOrCreateBinaryArithmeticCallTarget (binaryOperator );
474
- } else if (inplaceOperator != null ) {
475
- callTarget = language .getOrCreateInplaceArithmeticCallTarget (inplaceOperator );
476
- } else if (ternaryOperator != null ) {
477
- callTarget = language .getOrCreateTernaryArithmeticCallTarget (ternaryOperator );
478
- }
479
- throw CompilerDirectives .shouldNotReachHere ();
458
+ throw ArityException .create (3 , arguments .length );
480
459
}
481
- return callTarget ;
460
+ }
461
+
462
+ @ Override
463
+ protected RootCallTarget createCallTarget (PythonLanguage language ) {
464
+ return language .getOrCreateBinaryArithmeticCallTarget (binaryOperator );
465
+ }
466
+ }
467
+
468
+ @ ExportLibrary (InteropLibrary .class )
469
+ public static final class GraalHPyTernaryArithmetic extends GraalHPyArithmetic {
470
+ private final TernaryArithmetic ternaryOperator ;
471
+
472
+ public GraalHPyTernaryArithmetic (TernaryArithmetic unaryOperator ) {
473
+ this .ternaryOperator = unaryOperator ;
474
+ }
475
+
476
+ @ Override
477
+ protected void checkArguments (Object [] arguments ) throws ArityException {
478
+ // we also need to account for the HPy context
479
+ if (arguments .length != 4 ) {
480
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
481
+ throw ArityException .create (4 , arguments .length );
482
+ }
483
+ }
484
+
485
+ @ Override
486
+ protected RootCallTarget createCallTarget (PythonLanguage language ) {
487
+ return language .getOrCreateTernaryArithmeticCallTarget (ternaryOperator );
488
+ }
489
+ }
490
+
491
+ @ ExportLibrary (InteropLibrary .class )
492
+ public static final class GraalHPyInplaceArithmetic extends GraalHPyArithmetic {
493
+ private final InplaceArithmetic inplaceOperator ;
494
+
495
+ public GraalHPyInplaceArithmetic (InplaceArithmetic unaryOperator ) {
496
+ this .inplaceOperator = unaryOperator ;
497
+ }
498
+
499
+ @ Override
500
+ protected void checkArguments (Object [] arguments ) throws ArityException {
501
+ // we also need to account for the HPy context
502
+ if (inplaceOperator .isTernary () && arguments .length != 4 ) {
503
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
504
+ throw ArityException .create (4 , arguments .length );
505
+ }
506
+ if (!inplaceOperator .isTernary () && arguments .length != 3 ) {
507
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
508
+ throw ArityException .create (3 , arguments .length );
509
+ }
510
+ }
511
+
512
+ @ Override
513
+ protected RootCallTarget createCallTarget (PythonLanguage language ) {
514
+ return language .getOrCreateInplaceArithmeticCallTarget (inplaceOperator );
482
515
}
483
516
}
484
517
0 commit comments