Skip to content

Commit 37096d2

Browse files
committed
Separate HPy func signatures from wrappers and support reverse methods
1 parent 9106a1b commit 37096d2

File tree

4 files changed

+230
-60
lines changed

4 files changed

+230
-60
lines changed

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

Lines changed: 124 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,20 @@
7777
import static com.oracle.graal.python.nodes.SpecialMethodNames.__OR__;
7878
import static com.oracle.graal.python.nodes.SpecialMethodNames.__POS__;
7979
import static com.oracle.graal.python.nodes.SpecialMethodNames.__POW__;
80+
import static com.oracle.graal.python.nodes.SpecialMethodNames.__RADD__;
81+
import static com.oracle.graal.python.nodes.SpecialMethodNames.__RAND__;
8082
import static com.oracle.graal.python.nodes.SpecialMethodNames.__REPR__;
83+
import static com.oracle.graal.python.nodes.SpecialMethodNames.__RFLOORDIV__;
84+
import static com.oracle.graal.python.nodes.SpecialMethodNames.__RLSHIFT__;
85+
import static com.oracle.graal.python.nodes.SpecialMethodNames.__RMATMUL__;
86+
import static com.oracle.graal.python.nodes.SpecialMethodNames.__RMOD__;
87+
import static com.oracle.graal.python.nodes.SpecialMethodNames.__RMUL__;
88+
import static com.oracle.graal.python.nodes.SpecialMethodNames.__ROR__;
89+
import static com.oracle.graal.python.nodes.SpecialMethodNames.__RRSHIFT__;
8190
import static com.oracle.graal.python.nodes.SpecialMethodNames.__RSHIFT__;
91+
import static com.oracle.graal.python.nodes.SpecialMethodNames.__RSUB__;
92+
import static com.oracle.graal.python.nodes.SpecialMethodNames.__RTRUEDIV__;
93+
import static com.oracle.graal.python.nodes.SpecialMethodNames.__RXOR__;
8294
import static com.oracle.graal.python.nodes.SpecialMethodNames.__SETITEM__;
8395
import static com.oracle.graal.python.nodes.SpecialMethodNames.__SUB__;
8496
import static com.oracle.graal.python.nodes.SpecialMethodNames.__TRUEDIV__;
@@ -107,7 +119,9 @@ public abstract class GraalHPyDef {
107119
public static final int HPY_DEF_KIND_MEMBER = 3;
108120
public static final int HPY_DEF_KIND_GETSET = 4;
109121

110-
/** Same as {@code HPyFuncSignature.Signature} */
122+
/**
123+
* Same as {@code HPyFuncSignature.Signature}.
124+
*/
111125
enum HPyFuncSignature {
112126
VARARGS(1), // METH_VARARGS
113127
KEYWORDS(2), // METH_VARARGS | METH_KEYWORDS
@@ -144,8 +158,15 @@ enum HPyFuncSignature {
144158
/** The corresponding C enum value. */
145159
private final int value;
146160

161+
private final HPySlotWrapper slotWrapper;
162+
147163
HPyFuncSignature(int value) {
164+
this(value, null);
165+
}
166+
167+
HPyFuncSignature(int value, HPySlotWrapper slotWrapper) {
148168
this.value = value;
169+
this.slotWrapper = slotWrapper;
149170
}
150171

151172
public int getValue() {
@@ -169,6 +190,46 @@ static boolean isValid(int value) {
169190
}
170191
}
171192

193+
/**
194+
* An enumeration of all available slot wrappers as used by CPython (see
195+
* {@code typeobject.c: slotdefs}. Each enum value (except of {@link #NULL} and
196+
* {@link #DESTROYFUNC}) corresponds to a wrapper function which name starts with {@code wrap_}.
197+
* For example, value {@link #UNARYFUNC} corresponds to wrapper function {@code wrap_unaryfunc}.
198+
*/
199+
enum HPySlotWrapper {
200+
NULL,
201+
UNARYFUNC,
202+
BINARYFUNC,
203+
BINARYFUNC_L,
204+
BINARYFUNC_R,
205+
CALL,
206+
HASHFUNC,
207+
TERNARYFUNC,
208+
TERNARYFUNC_R,
209+
INQUIRYPRED,
210+
DEL,
211+
INIT,
212+
LENFUNC,
213+
DELITEM,
214+
SQ_ITEM,
215+
SQ_SETITEM,
216+
SQ_DELITEM,
217+
OBJOBJARGPROC,
218+
INDEXARGFUNC,
219+
SETATTR,
220+
DELATTR,
221+
RICHCMP_LT,
222+
RICHCMP_LE,
223+
RICHCMP_EQ,
224+
RICHCMP_NE,
225+
RICHCMP_GT,
226+
RICHCMP_GE,
227+
DESCR_GET,
228+
DESCR_SET,
229+
DESCR_DELETE,
230+
DESTROYFUNC
231+
}
232+
172233
/* enum values of 'HPyMember_FieldType' */
173234
public static final int HPY_MEMBER_SHORT = 0;
174235
public static final int HPY_MEMBER_INT = 1;
@@ -202,53 +263,53 @@ static boolean isValid(int value) {
202263

203264
/* enum values for 'HPySlot_Slot' */
204265
enum HPySlot {
205-
HPY_NB_ABSOLUTE(6, HPyFuncSignature.UNARYFUNC, __ABS__),
206-
HPY_NB_ADD(7, HPyFuncSignature.BINARYFUNC, __ADD__),
207-
HPY_NB_AND(8, HPyFuncSignature.BINARYFUNC, __AND__),
208-
HPY_NB_BOOL(9, HPyFuncSignature.INQUIRY, __BOOL__),
209-
HPY_NB_DIVMOD(10, HPyFuncSignature.BINARYFUNC, __DIVMOD__),
210-
HPY_NB_FLOAT(11, HPyFuncSignature.UNARYFUNC, __FLOAT__),
211-
HPY_NB_FLOOR_DIVIDE(12, HPyFuncSignature.BINARYFUNC, __FLOORDIV__),
212-
HPY_NB_INDEX(13, HPyFuncSignature.UNARYFUNC, __INDEX__),
213-
HPY_NB_INPLACE_ADD(14, HPyFuncSignature.BINARYFUNC, __IADD__),
214-
HPY_NB_INPLACE_AND(15, HPyFuncSignature.BINARYFUNC, __IAND__),
215-
HPY_NB_INPLACE_FLOOR_DIVIDE(16, HPyFuncSignature.BINARYFUNC, __IFLOORDIV__),
216-
HPY_NB_INPLACE_LSHIFT(17, HPyFuncSignature.BINARYFUNC, __ILSHIFT__),
217-
HPY_NB_INPLACE_MULTIPLY(18, HPyFuncSignature.BINARYFUNC, __IMUL__),
218-
HPY_NB_INPLACE_OR(19, HPyFuncSignature.BINARYFUNC, __IOR__),
219-
HPY_NB_INPLACE_POWER(20, HPyFuncSignature.TERNARYFUNC, __IPOW__),
220-
HPY_NB_INPLACE_REMAINDER(21, HPyFuncSignature.BINARYFUNC, __IMOD__),
221-
HPY_NB_INPLACE_RSHIFT(22, HPyFuncSignature.BINARYFUNC, __IRSHIFT__),
222-
HPY_NB_INPLACE_SUBTRACT(23, HPyFuncSignature.BINARYFUNC, __ISUB__),
223-
HPY_NB_INPLACE_TRUE_DIVIDE(24, HPyFuncSignature.BINARYFUNC, __ITRUEDIV__),
224-
HPY_NB_INPLACE_XOR(25, HPyFuncSignature.BINARYFUNC, __IXOR__),
225-
HPY_NB_INT(26, HPyFuncSignature.UNARYFUNC, __INT__),
226-
HPY_NB_INVERT(27, HPyFuncSignature.UNARYFUNC, __INVERT__),
227-
HPY_NB_LSHIFT(28, HPyFuncSignature.BINARYFUNC, __LSHIFT__),
228-
HPY_NB_MULTIPLY(29, HPyFuncSignature.BINARYFUNC, __MUL__),
229-
HPY_NB_NEGATIVE(30, HPyFuncSignature.UNARYFUNC, __NEG__),
230-
HPY_NB_OR(31, HPyFuncSignature.BINARYFUNC, __OR__),
231-
HPY_NB_POSITIVE(32, HPyFuncSignature.UNARYFUNC, __POS__),
232-
HPY_NB_POWER(33, HPyFuncSignature.TERNARYFUNC, __POW__),
233-
HPY_NB_REMAINDER(34, HPyFuncSignature.BINARYFUNC, __MOD__),
234-
HPY_NB_RSHIFT(35, HPyFuncSignature.BINARYFUNC, __RSHIFT__),
235-
HPY_NB_SUBTRACT(36, HPyFuncSignature.BINARYFUNC, __SUB__),
236-
HPY_NB_TRUE_DIVIDE(37, HPyFuncSignature.BINARYFUNC, __TRUEDIV__),
237-
HPY_NB_XOR(38, HPyFuncSignature.BINARYFUNC, __XOR__),
238-
HPY_SQ_ASS_ITEM(39, HPyFuncSignature.SSIZEOBJARGPROC, __SETITEM__, __DELITEM__),
239-
HPY_SQ_CONCAT(40, HPyFuncSignature.BINARYFUNC, __ADD__),
240-
HPY_SQ_CONTAINS(41, HPyFuncSignature.OBJOBJPROC, __CONTAINS__),
241-
HPY_SQ_INPLACE_CONCAT(42, HPyFuncSignature.BINARYFUNC, __IADD__),
242-
HPY_SQ_INPLACE_REPEAT(43, HPyFuncSignature.SSIZEARGFUNC, __IMUL__),
243-
HPY_SQ_ITEM(44, HPyFuncSignature.SSIZEARGFUNC, __GETITEM__),
244-
HPY_SQ_LENGTH(45, HPyFuncSignature.LENFUNC, __LEN__),
245-
HPY_SQ_REPEAT(46, HPyFuncSignature.SSIZEARGFUNC, __MUL__),
246-
HPY_TP_INIT(60, HPyFuncSignature.INITPROC, __INIT__),
247-
HPY_TP_NEW(65, HPyFuncSignature.KEYWORDS, __NEW__),
248-
HPY_TP_REPR(66, HPyFuncSignature.REPRFUNC, __REPR__),
249-
HPY_NB_MATRIX_MULTIPLY(75, HPyFuncSignature.BINARYFUNC, __MATMUL__),
250-
HPY_NB_INPLACE_MATRIX_MULTIPLY(76, HPyFuncSignature.BINARYFUNC, __IMATMUL__),
251-
HPY_TP_DESTROY(1000, HPyFuncSignature.DESTROYFUNC, TYPE_HPY_DESTROY);
266+
HPY_NB_ABSOLUTE(6, HPySlotWrapper.UNARYFUNC, __ABS__),
267+
HPY_NB_ADD(7, HPySlotWrapper.BINARYFUNC_L, __ADD__, HPySlotWrapper.BINARYFUNC_R, __RADD__),
268+
HPY_NB_AND(8, HPySlotWrapper.BINARYFUNC_L, __AND__, HPySlotWrapper.BINARYFUNC_R, __RAND__),
269+
HPY_NB_BOOL(9, HPySlotWrapper.INQUIRYPRED, __BOOL__),
270+
HPY_NB_DIVMOD(10, HPySlotWrapper.BINARYFUNC_L, __DIVMOD__),
271+
HPY_NB_FLOAT(11, HPySlotWrapper.UNARYFUNC, __FLOAT__),
272+
HPY_NB_FLOOR_DIVIDE(12, HPySlotWrapper.BINARYFUNC_L, __FLOORDIV__, HPySlotWrapper.BINARYFUNC_R, __RFLOORDIV__),
273+
HPY_NB_INDEX(13, HPySlotWrapper.UNARYFUNC, __INDEX__),
274+
HPY_NB_INPLACE_ADD(14, HPySlotWrapper.BINARYFUNC_L, __IADD__),
275+
HPY_NB_INPLACE_AND(15, HPySlotWrapper.BINARYFUNC_L, __IAND__),
276+
HPY_NB_INPLACE_FLOOR_DIVIDE(16, HPySlotWrapper.BINARYFUNC_L, __IFLOORDIV__),
277+
HPY_NB_INPLACE_LSHIFT(17, HPySlotWrapper.BINARYFUNC_L, __ILSHIFT__),
278+
HPY_NB_INPLACE_MULTIPLY(18, HPySlotWrapper.BINARYFUNC_L, __IMUL__),
279+
HPY_NB_INPLACE_OR(19, HPySlotWrapper.BINARYFUNC_L, __IOR__),
280+
HPY_NB_INPLACE_POWER(20, HPySlotWrapper.TERNARYFUNC, __IPOW__),
281+
HPY_NB_INPLACE_REMAINDER(21, HPySlotWrapper.BINARYFUNC_L, __IMOD__),
282+
HPY_NB_INPLACE_RSHIFT(22, HPySlotWrapper.BINARYFUNC_L, __IRSHIFT__),
283+
HPY_NB_INPLACE_SUBTRACT(23, HPySlotWrapper.BINARYFUNC_L, __ISUB__),
284+
HPY_NB_INPLACE_TRUE_DIVIDE(24, HPySlotWrapper.BINARYFUNC_L, __ITRUEDIV__),
285+
HPY_NB_INPLACE_XOR(25, HPySlotWrapper.BINARYFUNC_L, __IXOR__),
286+
HPY_NB_INT(26, HPySlotWrapper.UNARYFUNC, __INT__),
287+
HPY_NB_INVERT(27, HPySlotWrapper.UNARYFUNC, __INVERT__),
288+
HPY_NB_LSHIFT(28, HPySlotWrapper.BINARYFUNC_L, __LSHIFT__, HPySlotWrapper.BINARYFUNC_R, __RLSHIFT__),
289+
HPY_NB_MULTIPLY(29, HPySlotWrapper.BINARYFUNC_L, __MUL__, HPySlotWrapper.BINARYFUNC_R, __RMUL__),
290+
HPY_NB_NEGATIVE(30, HPySlotWrapper.UNARYFUNC, __NEG__),
291+
HPY_NB_OR(31, HPySlotWrapper.BINARYFUNC_L, __OR__, HPySlotWrapper.BINARYFUNC_R, __ROR__),
292+
HPY_NB_POSITIVE(32, HPySlotWrapper.UNARYFUNC, __POS__),
293+
HPY_NB_POWER(33, HPySlotWrapper.TERNARYFUNC, __POW__),
294+
HPY_NB_REMAINDER(34, HPySlotWrapper.BINARYFUNC_L, __MOD__, HPySlotWrapper.BINARYFUNC_R, __RMOD__),
295+
HPY_NB_RSHIFT(35, HPySlotWrapper.BINARYFUNC_L, __RSHIFT__, HPySlotWrapper.BINARYFUNC_R, __RRSHIFT__),
296+
HPY_NB_SUBTRACT(36, HPySlotWrapper.BINARYFUNC_L, __SUB__, HPySlotWrapper.BINARYFUNC_R, __RSUB__),
297+
HPY_NB_TRUE_DIVIDE(37, HPySlotWrapper.BINARYFUNC_L, __TRUEDIV__, HPySlotWrapper.BINARYFUNC_R, __RTRUEDIV__),
298+
HPY_NB_XOR(38, HPySlotWrapper.BINARYFUNC_L, __XOR__, HPySlotWrapper.BINARYFUNC_R, __RXOR__),
299+
HPY_SQ_ASS_ITEM(39, HPySlotWrapper.SQ_SETITEM, __SETITEM__, HPySlotWrapper.SQ_DELITEM, __DELITEM__),
300+
HPY_SQ_CONCAT(40, HPySlotWrapper.BINARYFUNC_L, __ADD__),
301+
HPY_SQ_CONTAINS(41, HPySlotWrapper.OBJOBJARGPROC, __CONTAINS__),
302+
HPY_SQ_INPLACE_CONCAT(42, HPySlotWrapper.BINARYFUNC_L, __IADD__),
303+
HPY_SQ_INPLACE_REPEAT(43, HPySlotWrapper.INDEXARGFUNC, __IMUL__),
304+
HPY_SQ_ITEM(44, HPySlotWrapper.SQ_ITEM, __GETITEM__),
305+
HPY_SQ_LENGTH(45, HPySlotWrapper.LENFUNC, __LEN__),
306+
HPY_SQ_REPEAT(46, HPySlotWrapper.INDEXARGFUNC, __MUL__, __RMUL__),
307+
HPY_TP_INIT(60, HPySlotWrapper.INIT, __INIT__),
308+
HPY_TP_NEW(65, HPySlotWrapper.NULL, __NEW__),
309+
HPY_TP_REPR(66, HPySlotWrapper.UNARYFUNC, __REPR__),
310+
HPY_NB_MATRIX_MULTIPLY(75, HPySlotWrapper.BINARYFUNC_L, __MATMUL__, HPySlotWrapper.BINARYFUNC_R, __RMATMUL__),
311+
HPY_NB_INPLACE_MATRIX_MULTIPLY(76, HPySlotWrapper.BINARYFUNC_L, __IMATMUL__),
312+
HPY_TP_DESTROY(1000, HPySlotWrapper.DESTROYFUNC, TYPE_HPY_DESTROY);
252313

253314
/** The corresponding C enum value. */
254315
private final int value;
@@ -261,30 +322,39 @@ enum HPySlot {
261322
@CompilationFinal(dimensions = 1) private final Object[] attributeKeys;
262323

263324
/** The signatures of the slot functions. */
264-
@CompilationFinal(dimensions = 1) private final HPyFuncSignature[] signatures;
325+
@CompilationFinal(dimensions = 1) private final HPySlotWrapper[] signatures;
265326

266327
/**
267328
* Common case: one slot causes the creation of one attribute.
268329
*/
269-
HPySlot(int value, HPyFuncSignature signature, Object attributeKey) {
330+
HPySlot(int value, HPySlotWrapper signature, Object attributeKey) {
270331
this.value = value;
271332
this.attributeKeys = new Object[]{attributeKey};
272-
this.signatures = new HPyFuncSignature[]{signature};
333+
this.signatures = new HPySlotWrapper[]{signature};
273334
}
274335

275336
/**
276337
* Special case: one slot causes the creation of multiple attributes using the same
277338
* signature.
278339
*/
279-
HPySlot(int value, HPyFuncSignature signature, Object... attributeKeys) {
340+
HPySlot(int value, HPySlotWrapper signature, Object... attributeKeys) {
280341
this.value = value;
281342
this.attributeKeys = attributeKeys;
282-
this.signatures = new HPyFuncSignature[this.attributeKeys.length];
343+
this.signatures = new HPySlotWrapper[this.attributeKeys.length];
283344
for (int i = 0; i < this.signatures.length; i++) {
284345
this.signatures[i] = signature;
285346
}
286347
}
287348

349+
/**
350+
* Special case: one slot causes the creation of two attributes using different signatures.
351+
*/
352+
HPySlot(int value, HPySlotWrapper sig0, Object key0, HPySlotWrapper sig1, Object key1) {
353+
this.value = value;
354+
this.attributeKeys = new Object[]{key0, key1};
355+
this.signatures = new HPySlotWrapper[]{sig0, sig1};
356+
}
357+
288358
int getValue() {
289359
return value;
290360
}
@@ -293,7 +363,7 @@ Object[] getAttributeKeys() {
293363
return attributeKeys;
294364
}
295365

296-
HPyFuncSignature[] getSignatures() {
366+
HPySlotWrapper[] getSignatures() {
297367
return signatures;
298368
}
299369

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585
import com.oracle.graal.python.builtins.objects.cext.common.CExtToNativeNode;
8686
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPyFuncSignature;
8787
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPySlot;
88+
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPySlotWrapper;
8889
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyLegacyDef.HPyLegacySlot;
8990
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyMemberAccessNodes.HPyDeleteMemberNode;
9091
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyMemberAccessNodes.HPyGetSetDescriptorGetterRootNode;
@@ -880,7 +881,7 @@ static HPyProperty doIt(GraalHPyContext context, Object enclosingType, Object sl
880881

881882
HPyProperty property = null;
882883
Object[] methodNames = slot.getAttributeKeys();
883-
HPyFuncSignature[] signatures = slot.getSignatures();
884+
HPySlotWrapper[] slotWrappers = slot.getSignatures();
884885
if (methodNames == null || methodNames.length == 0) {
885886
CompilerDirectives.transferToInterpreterAndInvalidate();
886887
throw raiseNode.raise(PythonBuiltinClassType.SystemError, "slot %s is not yet supported", slot.name());
@@ -905,7 +906,7 @@ static HPyProperty doIt(GraalHPyContext context, Object enclosingType, Object sl
905906
// create properties
906907
for (int i = 0; i < methodNames.length; i++) {
907908
Object methodName = methodNames[i];
908-
HPyFuncSignature signature = signatures[i];
909+
HPySlotWrapper slotWrapper = slotWrappers[i];
909910
String methodNameStr = methodName instanceof HiddenKey ? ((HiddenKey) methodName).getName() : (String) methodName;
910911

911912
Object function;
@@ -916,8 +917,7 @@ static HPyProperty doIt(GraalHPyContext context, Object enclosingType, Object sl
916917
*/
917918
function = methodFunctionPointer;
918919
} else {
919-
function = HPyExternalFunctionNodes.createWrapperFunction(language, signature, methodNameStr, methodFunctionPointer, HPY_TP_NEW.equals(slot) ? null : enclosingType,
920-
factory);
920+
function = HPyExternalFunctionNodes.createWrapperFunction(language, slotWrapper, methodNameStr, methodFunctionPointer, HPY_TP_NEW.equals(slot) ? null : enclosingType, factory);
921921
}
922922
property = new HPyProperty(methodName, function, property);
923923
}

0 commit comments

Comments
 (0)