Skip to content

Commit 5bec8bd

Browse files
committed
Create specialized objects instead of GraalHPyArithmetic
1 parent fade08a commit 5bec8bd

File tree

2 files changed

+138
-102
lines changed

2 files changed

+138
-102
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyContext.java

Lines changed: 34 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,9 @@
6969
import com.oracle.graal.python.builtins.objects.cext.capi.CApiContext;
7070
import com.oracle.graal.python.builtins.objects.cext.common.CExtContext;
7171
import com.oracle.graal.python.builtins.objects.cext.common.ReferenceStack;
72-
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctions.GraalHPyArithmetic;
7372
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctions.GraalHPyAsIndex;
7473
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctions.GraalHPyAsPyObject;
74+
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctions.GraalHPyBinaryArithmetic;
7575
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctions.GraalHPyBuilderBuild;
7676
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctions.GraalHPyBuilderCancel;
7777
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctions.GraalHPyBuilderNew;
@@ -95,6 +95,7 @@
9595
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctions.GraalHPyGetAttr;
9696
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctions.GraalHPyGetItem;
9797
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctions.GraalHPyHasAttr;
98+
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctions.GraalHPyInplaceArithmetic;
9899
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctions.GraalHPyIsNumber;
99100
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctions.GraalHPyIsTrue;
100101
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctions.GraalHPyListAppend;
@@ -106,9 +107,11 @@
106107
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctions.GraalHPyRichcompare;
107108
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctions.GraalHPySetAttr;
108109
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctions.GraalHPySetItem;
110+
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctions.GraalHPyTernaryArithmetic;
109111
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctions.GraalHPyTupleFromArray;
110112
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctions.GraalHPyTypeFromSpec;
111113
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctions.GraalHPyTypeGenericNew;
114+
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctions.GraalHPyUnaryArithmetic;
112115
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctions.GraalHPyUnicodeAsUTF8String;
113116
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctions.GraalHPyUnicodeFromString;
114117
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyContextFunctions.GraalHPyUnicodeFromWchar;
@@ -651,44 +654,44 @@ private static Object[] createMembers(PythonContext context) {
651654
members[HPyContextMembers.CTX_CAST.ordinal()] = new GraalHPyCast();
652655

653656
// unary
654-
members[HPyContextMembers.CTX_NEGATIVE.ordinal()] = new GraalHPyArithmetic(UnaryArithmetic.Neg);
655-
members[HPyContextMembers.CTX_POSITIVE.ordinal()] = new GraalHPyArithmetic(UnaryArithmetic.Pos);
657+
members[HPyContextMembers.CTX_NEGATIVE.ordinal()] = new GraalHPyUnaryArithmetic(UnaryArithmetic.Neg);
658+
members[HPyContextMembers.CTX_POSITIVE.ordinal()] = new GraalHPyUnaryArithmetic(UnaryArithmetic.Pos);
656659
members[HPyContextMembers.CTX_ABSOLUTE.ordinal()] = new GraalHPyCallBuiltinFunction(BuiltinNames.ABS, 1);
657-
members[HPyContextMembers.CTX_INVERT.ordinal()] = new GraalHPyArithmetic(UnaryArithmetic.Invert);
660+
members[HPyContextMembers.CTX_INVERT.ordinal()] = new GraalHPyUnaryArithmetic(UnaryArithmetic.Invert);
658661
members[HPyContextMembers.CTX_INDEX.ordinal()] = new GraalHPyAsIndex();
659662
members[HPyContextMembers.CTX_LONG.ordinal()] = new GraalHPyCallBuiltinFunction(BuiltinNames.INT, 1);
660663
members[HPyContextMembers.CTX_FLOAT.ordinal()] = new GraalHPyCallBuiltinFunction(BuiltinNames.FLOAT, 1);
661664

662665
// binary
663-
members[HPyContextMembers.CTX_ADD.ordinal()] = new GraalHPyArithmetic(BinaryArithmetic.Add);
664-
members[HPyContextMembers.CTX_SUB.ordinal()] = new GraalHPyArithmetic(BinaryArithmetic.Sub);
665-
members[HPyContextMembers.CTX_MULTIPLY.ordinal()] = new GraalHPyArithmetic(BinaryArithmetic.Mul);
666-
members[HPyContextMembers.CTX_MATRIXMULTIPLY.ordinal()] = new GraalHPyArithmetic(BinaryArithmetic.MatMul);
667-
members[HPyContextMembers.CTX_FLOORDIVIDE.ordinal()] = new GraalHPyArithmetic(BinaryArithmetic.FloorDiv);
668-
members[HPyContextMembers.CTX_TRUEDIVIDE.ordinal()] = new GraalHPyArithmetic(BinaryArithmetic.TrueDiv);
669-
members[HPyContextMembers.CTX_REMAINDER.ordinal()] = new GraalHPyArithmetic(BinaryArithmetic.Mod);
670-
members[HPyContextMembers.CTX_DIVMOD.ordinal()] = new GraalHPyArithmetic(BinaryArithmetic.DivMod);
671-
members[HPyContextMembers.CTX_LSHIFT.ordinal()] = new GraalHPyArithmetic(BinaryArithmetic.LShift);
672-
members[HPyContextMembers.CTX_RSHIFT.ordinal()] = new GraalHPyArithmetic(BinaryArithmetic.RShift);
673-
members[HPyContextMembers.CTX_AND.ordinal()] = new GraalHPyArithmetic(BinaryArithmetic.And);
674-
members[HPyContextMembers.CTX_XOR.ordinal()] = new GraalHPyArithmetic(BinaryArithmetic.Xor);
675-
members[HPyContextMembers.CTX_OR.ordinal()] = new GraalHPyArithmetic(BinaryArithmetic.Or);
676-
members[HPyContextMembers.CTX_INPLACEADD.ordinal()] = new GraalHPyArithmetic(InplaceArithmetic.IAdd);
677-
members[HPyContextMembers.CTX_INPLACESUBTRACT.ordinal()] = new GraalHPyArithmetic(InplaceArithmetic.ISub);
678-
members[HPyContextMembers.CTX_INPLACEMULTIPLY.ordinal()] = new GraalHPyArithmetic(InplaceArithmetic.IMul);
679-
members[HPyContextMembers.CTX_INPLACEMATRIXMULTIPLY.ordinal()] = new GraalHPyArithmetic(InplaceArithmetic.IMatMul);
680-
members[HPyContextMembers.CTX_INPLACEFLOORDIVIDE.ordinal()] = new GraalHPyArithmetic(InplaceArithmetic.IFloorDiv);
681-
members[HPyContextMembers.CTX_INPLACETRUEDIVIDE.ordinal()] = new GraalHPyArithmetic(InplaceArithmetic.ITrueDiv);
682-
members[HPyContextMembers.CTX_INPLACEREMAINDER.ordinal()] = new GraalHPyArithmetic(InplaceArithmetic.IMod);
683-
members[HPyContextMembers.CTX_INPLACELSHIFT.ordinal()] = new GraalHPyArithmetic(InplaceArithmetic.ILShift);
684-
members[HPyContextMembers.CTX_INPLACERSHIFT.ordinal()] = new GraalHPyArithmetic(InplaceArithmetic.IRShift);
685-
members[HPyContextMembers.CTX_INPLACEAND.ordinal()] = new GraalHPyArithmetic(InplaceArithmetic.IAnd);
686-
members[HPyContextMembers.CTX_INPLACEXOR.ordinal()] = new GraalHPyArithmetic(InplaceArithmetic.IXor);
687-
members[HPyContextMembers.CTX_INPLACEOR.ordinal()] = new GraalHPyArithmetic(InplaceArithmetic.IOr);
666+
members[HPyContextMembers.CTX_ADD.ordinal()] = new GraalHPyBinaryArithmetic(BinaryArithmetic.Add);
667+
members[HPyContextMembers.CTX_SUB.ordinal()] = new GraalHPyBinaryArithmetic(BinaryArithmetic.Sub);
668+
members[HPyContextMembers.CTX_MULTIPLY.ordinal()] = new GraalHPyBinaryArithmetic(BinaryArithmetic.Mul);
669+
members[HPyContextMembers.CTX_MATRIXMULTIPLY.ordinal()] = new GraalHPyBinaryArithmetic(BinaryArithmetic.MatMul);
670+
members[HPyContextMembers.CTX_FLOORDIVIDE.ordinal()] = new GraalHPyBinaryArithmetic(BinaryArithmetic.FloorDiv);
671+
members[HPyContextMembers.CTX_TRUEDIVIDE.ordinal()] = new GraalHPyBinaryArithmetic(BinaryArithmetic.TrueDiv);
672+
members[HPyContextMembers.CTX_REMAINDER.ordinal()] = new GraalHPyBinaryArithmetic(BinaryArithmetic.Mod);
673+
members[HPyContextMembers.CTX_DIVMOD.ordinal()] = new GraalHPyBinaryArithmetic(BinaryArithmetic.DivMod);
674+
members[HPyContextMembers.CTX_LSHIFT.ordinal()] = new GraalHPyBinaryArithmetic(BinaryArithmetic.LShift);
675+
members[HPyContextMembers.CTX_RSHIFT.ordinal()] = new GraalHPyBinaryArithmetic(BinaryArithmetic.RShift);
676+
members[HPyContextMembers.CTX_AND.ordinal()] = new GraalHPyBinaryArithmetic(BinaryArithmetic.And);
677+
members[HPyContextMembers.CTX_XOR.ordinal()] = new GraalHPyBinaryArithmetic(BinaryArithmetic.Xor);
678+
members[HPyContextMembers.CTX_OR.ordinal()] = new GraalHPyBinaryArithmetic(BinaryArithmetic.Or);
679+
members[HPyContextMembers.CTX_INPLACEADD.ordinal()] = new GraalHPyInplaceArithmetic(InplaceArithmetic.IAdd);
680+
members[HPyContextMembers.CTX_INPLACESUBTRACT.ordinal()] = new GraalHPyInplaceArithmetic(InplaceArithmetic.ISub);
681+
members[HPyContextMembers.CTX_INPLACEMULTIPLY.ordinal()] = new GraalHPyInplaceArithmetic(InplaceArithmetic.IMul);
682+
members[HPyContextMembers.CTX_INPLACEMATRIXMULTIPLY.ordinal()] = new GraalHPyInplaceArithmetic(InplaceArithmetic.IMatMul);
683+
members[HPyContextMembers.CTX_INPLACEFLOORDIVIDE.ordinal()] = new GraalHPyInplaceArithmetic(InplaceArithmetic.IFloorDiv);
684+
members[HPyContextMembers.CTX_INPLACETRUEDIVIDE.ordinal()] = new GraalHPyInplaceArithmetic(InplaceArithmetic.ITrueDiv);
685+
members[HPyContextMembers.CTX_INPLACEREMAINDER.ordinal()] = new GraalHPyInplaceArithmetic(InplaceArithmetic.IMod);
686+
members[HPyContextMembers.CTX_INPLACELSHIFT.ordinal()] = new GraalHPyInplaceArithmetic(InplaceArithmetic.ILShift);
687+
members[HPyContextMembers.CTX_INPLACERSHIFT.ordinal()] = new GraalHPyInplaceArithmetic(InplaceArithmetic.IRShift);
688+
members[HPyContextMembers.CTX_INPLACEAND.ordinal()] = new GraalHPyInplaceArithmetic(InplaceArithmetic.IAnd);
689+
members[HPyContextMembers.CTX_INPLACEXOR.ordinal()] = new GraalHPyInplaceArithmetic(InplaceArithmetic.IXor);
690+
members[HPyContextMembers.CTX_INPLACEOR.ordinal()] = new GraalHPyInplaceArithmetic(InplaceArithmetic.IOr);
688691

689692
// ternary
690-
members[HPyContextMembers.CTX_POWER.ordinal()] = new GraalHPyArithmetic(TernaryArithmetic.Pow);
691-
members[HPyContextMembers.CTX_INPLACEPOWER.ordinal()] = new GraalHPyArithmetic(InplaceArithmetic.IPow);
693+
members[HPyContextMembers.CTX_POWER.ordinal()] = new GraalHPyTernaryArithmetic(TernaryArithmetic.Pow);
694+
members[HPyContextMembers.CTX_INPLACEPOWER.ordinal()] = new GraalHPyInplaceArithmetic(InplaceArithmetic.IPow);
692695

693696
members[HPyContextMembers.CTX_DICT_CHECK.ordinal()] = new GraalHPyCheckBuiltinType(PDict);
694697
members[HPyContextMembers.CTX_DICT_NEW.ordinal()] = new GraalHPyDictNew();

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyContextFunctions.java

Lines changed: 104 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,6 @@
139139
import com.oracle.truffle.api.RootCallTarget;
140140
import com.oracle.truffle.api.TruffleLogger;
141141
import com.oracle.truffle.api.dsl.Cached;
142-
import com.oracle.truffle.api.dsl.CachedLanguage;
143142
import com.oracle.truffle.api.dsl.Specialization;
144143
import com.oracle.truffle.api.interop.ArityException;
145144
import com.oracle.truffle.api.interop.InteropException;
@@ -374,55 +373,20 @@ Object execute(Object[] arguments,
374373
}
375374

376375
@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 {
382377

383378
@CompilationFinal private RootCallTarget callTarget;
384379

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-
413380
@ExportMessage
414381
Object execute(Object[] arguments,
415-
@CachedLanguage @SuppressWarnings("unused") PythonLanguage language,
416382
@Cached HPyAsContextNode asContextNode,
417383
@Cached HPyAsPythonObjectNode asPythonObjectNode,
418384
@Cached HPyAsHandleNode asHandleNode,
419385
@Cached GenericInvokeNode invokeNode,
420386
@Cached TransformExceptionToNativeNode transformExceptionToNativeNode) throws ArityException {
421387

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.
426390
checkArguments(arguments);
427391

428392
GraalHPyContext context = asContextNode.execute(arguments[0]);
@@ -433,52 +397,121 @@ Object execute(Object[] arguments,
433397
}
434398

435399
try {
436-
Object result = invokeNode.execute(getCallTarget(language), pythonArguments);
400+
Object result = invokeNode.execute(ensureCallTarget(), pythonArguments);
437401
return asHandleNode.execute(result);
438402
} catch (PException e) {
439403
transformExceptionToNativeNode.execute(e);
440404
return context.getNullHandle();
441405
}
442406
}
443407

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());
459412
}
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) {
461434
CompilerDirectives.transferToInterpreterAndInvalidate();
462-
int expected = min > arguments.length ? min : max;
463-
throw ArityException.create(expected, arguments.length);
435+
throw ArityException.create(2, arguments.length);
464436
}
465437
}
466438

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) {
469457
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);
480459
}
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);
482515
}
483516
}
484517

0 commit comments

Comments
 (0)