Skip to content

Commit 0d83127

Browse files
committed
Refactor 'moduleobject.c'.
1 parent e946fda commit 0d83127

File tree

7 files changed

+122
-61
lines changed

7 files changed

+122
-61
lines changed

graalpython/com.oracle.graal.python.cext/src/moduleobject.c

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -46,24 +46,23 @@ int PyModule_AddFunctions(PyObject* mod, PyMethodDef* methods) {
4646
return -1;
4747
}
4848
int idx = 0;
49-
void* mod_w = to_java(mod);
5049
PyMethodDef def = methods[idx];
5150
while (def.ml_name != NULL) {
52-
truffle_invoke(PY_TRUFFLE_CEXT,
51+
polyglot_invoke(PY_TRUFFLE_CEXT,
5352
"AddFunction",
54-
mod_w,
55-
truffle_read_string((const char*)(def.ml_name)),
56-
truffle_address_to_function(def.ml_meth),
57-
truffle_address_to_function(get_method_flags_cwrapper(def.ml_flags)),
53+
native_to_java(mod),
54+
polyglot_from_string((const char*)(def.ml_name), SRC_CS),
55+
def.ml_meth,
56+
get_method_flags_cwrapper(def.ml_flags),
5857
get_method_flags_wrapper(def.ml_flags),
59-
truffle_read_string((const char*)(def.ml_doc ? def.ml_doc : "")));
58+
polyglot_from_string((const char*)(def.ml_doc ? def.ml_doc : ""), SRC_CS));
6059
def = methods[++idx];
6160
}
6261
return 0;
6362
}
6463

6564
int PyModule_SetDocString(PyObject* m, const char* doc) {
66-
truffle_invoke(PY_TRUFFLE_CEXT, "PyModule_SetDocString", to_java(m), truffle_read_string(doc));
65+
UPCALL_CEXT_VOID("PyModule_SetDocString", native_to_java(m), polyglot_from_string(doc, SRC_CS));
6766
return 0;
6867
}
6968

@@ -75,7 +74,7 @@ PyObject* _PyModule_CreateInitialized(PyModuleDef* moduledef, int apiversion) {
7574
return NULL;
7675
}
7776

78-
PyObject* mod = to_sulong(truffle_invoke(PY_TRUFFLE_CEXT, "_PyModule_CreateInitialized_PyModule_New", truffle_read_string(moduledef->m_name)));
77+
PyModuleObject* mod = polyglot_as_PyModuleObject(UPCALL_CEXT_O("_PyModule_CreateInitialized_PyModule_New", polyglot_from_string(moduledef->m_name, SRC_CS)));
7978

8079
if (moduledef->m_size > 0) {
8180
void* md_state = PyMem_MALLOC(moduledef->m_size);
@@ -84,32 +83,32 @@ PyObject* _PyModule_CreateInitialized(PyModuleDef* moduledef, int apiversion) {
8483
return NULL;
8584
}
8685
memset(md_state, 0, moduledef->m_size);
87-
truffle_write(to_java(mod), "md_state", md_state);
86+
mod->md_state = md_state;
8887
}
8988

9089
if (moduledef->m_methods != NULL) {
91-
if (PyModule_AddFunctions(mod, moduledef->m_methods) != 0) {
90+
if (PyModule_AddFunctions((PyObject*) mod, moduledef->m_methods) != 0) {
9291
return NULL;
9392
}
9493
}
9594

9695
if (moduledef->m_doc != NULL) {
97-
if (PyModule_SetDocString(mod, moduledef->m_doc) != 0) {
96+
if (PyModule_SetDocString((PyObject*) mod, moduledef->m_doc) != 0) {
9897
return NULL;
9998
}
10099
}
101100

102-
truffle_write(to_java(mod), "md_def", moduledef);
103-
return mod;
101+
mod->md_def = moduledef;
102+
return (PyObject*) mod;
104103
}
105104

106105
int PyModule_AddObject(PyObject* m, const char* k, PyObject* v) {
107-
truffle_invoke(PY_TRUFFLE_CEXT, "PyModule_AddObject", to_java(m), truffle_read_string(k), to_java(v));
106+
UPCALL_CEXT_VOID("PyModule_AddObject", native_to_java(m), polyglot_from_string(k, SRC_CS), native_to_java(v));
108107
return 0;
109108
}
110109

111110
int PyModule_AddIntConstant(PyObject* m, const char* k, long constant) {
112-
truffle_invoke(PY_TRUFFLE_CEXT, "PyModule_AddObject", to_java(m), truffle_read_string(k), constant);
111+
UPCALL_CEXT_VOID("PyModule_AddObject", native_to_java(m), polyglot_from_string(k, SRC_CS), PyLong_FromLong(constant));
113112
return 0;
114113
}
115114

@@ -122,5 +121,5 @@ PyObject* PyModule_GetDict(PyObject* o) {
122121
PyErr_BadInternalCall();
123122
return NULL;
124123
}
125-
return ((PyModuleObject*)polyglot_as_PyModuleObject(o))->md_dict;
124+
return (polyglot_as_PyModuleObject(o))->md_dict;
126125
}

graalpython/com.oracle.graal.python.cext/src/object.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,8 @@ int PyType_Ready(PyTypeObject* cls) {
222222
#define ADD_SLOT_CONV(name, clanding, meth, flags) ADD_METHOD_OR_SLOT(name, clanding, meth, flags, name)
223223
#define ADD_METHOD_OR_SLOT(name, clanding, meth, flags, doc) \
224224
if (meth) { \
225-
UPCALL_CEXT_VOID("AddFunction", \
225+
polyglot_invoke(PY_TRUFFLE_CEXT, \
226+
"AddFunction", \
226227
javacls, \
227228
polyglot_from_string((name), SRC_CS), \
228229
(meth), \

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ public abstract class NativeMemberNames {
7070
public static final String UNICODE_STATE_COMPACT = "compact";
7171
public static final String UNICODE_STATE_ASCII = "ascii";
7272
public static final String UNICODE_STATE_READY = "ready";
73+
public static final String MD_STATE = "md_state";
74+
public static final String MD_DEF = "md_def";
7375
public static final String MD_DICT = "md_dict";
7476
public static final String BUF_DELEGATE = "buf_delegate";
7577
public static final String NB_ADD = "nb_add";
@@ -109,6 +111,8 @@ public static boolean isValid(String key) {
109111
case UNICODE_STATE_COMPACT:
110112
case UNICODE_STATE_ASCII:
111113
case UNICODE_STATE_READY:
114+
case MD_STATE:
115+
case MD_DEF:
112116
case MD_DICT:
113117
case NB_ADD:
114118
case NB_INDEX:

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,13 @@
4040

4141
import com.oracle.graal.python.builtins.objects.PythonAbstractObject;
4242
import com.oracle.graal.python.builtins.objects.cext.CArrayWrappers.CStringWrapper;
43+
import com.oracle.graal.python.builtins.objects.common.DynamicObjectStorage.PythonObjectDictStorage;
4344
import com.oracle.graal.python.builtins.objects.type.PythonClass;
4445
import com.oracle.truffle.api.interop.ForeignAccess;
4546
import com.oracle.truffle.api.interop.TruffleObject;
47+
import com.oracle.truffle.api.object.Layout;
48+
import com.oracle.truffle.api.object.ObjectType;
49+
import com.oracle.truffle.api.object.Shape;
4650

4751
public abstract class NativeWrappers {
4852
public abstract static class PythonNativeWrapper implements TruffleObject {
@@ -65,6 +69,10 @@ public boolean isNative() {
6569
return nativePointer != null;
6670
}
6771

72+
static boolean isInstance(TruffleObject o) {
73+
return o instanceof PythonNativeWrapper;
74+
}
75+
6876
@Override
6977
public ForeignAccess getForeignAccess() {
7078
return PythonObjectNativeWrapperMRForeign.ACCESS;
@@ -76,7 +84,11 @@ public ForeignAccess getForeignAccess() {
7684
* correct shape of the corresponding native type {@code struct _object}.
7785
*/
7886
public static class PythonObjectNativeWrapper extends PythonNativeWrapper {
87+
private static final Layout OBJECT_LAYOUT = Layout.newLayout().build();
88+
private static final Shape SHAPE = OBJECT_LAYOUT.createShape(new ObjectType());
89+
7990
private final PythonAbstractObject pythonObject;
91+
private PythonObjectDictStorage nativeMemberStore;
8092

8193
public PythonObjectNativeWrapper(PythonAbstractObject object) {
8294
this.pythonObject = object;
@@ -105,6 +117,17 @@ public Object getDelegate() {
105117
return pythonObject;
106118
}
107119

120+
public PythonObjectDictStorage createNativeMemberStore() {
121+
if (nativeMemberStore == null) {
122+
nativeMemberStore = new PythonObjectDictStorage(SHAPE.newInstance());
123+
}
124+
return nativeMemberStore;
125+
}
126+
127+
public PythonObjectDictStorage getNativeMemberStore() {
128+
return nativeMemberStore;
129+
}
130+
108131
@Override
109132
public String toString() {
110133
return String.format("PythonObjectNativeWrapper(%s, isNative=%s)", pythonObject, isNative());

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

Lines changed: 72 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@
5555
import com.oracle.graal.python.builtins.objects.cext.PythonObjectNativeWrapperMRFactory.ToPyObjectNodeGen;
5656
import com.oracle.graal.python.builtins.objects.cext.PythonObjectNativeWrapperMRFactory.WriteNativeMemberNodeGen;
5757
import com.oracle.graal.python.builtins.objects.cext.UnicodeObjectNodes.UnicodeAsWideCharNode;
58+
import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes;
59+
import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.GetItemNode;
60+
import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.SetItemNode;
5861
import com.oracle.graal.python.builtins.objects.dict.PDict;
5962
import com.oracle.graal.python.builtins.objects.memoryview.PBuffer;
6063
import com.oracle.graal.python.builtins.objects.object.PythonObject;
@@ -92,23 +95,27 @@
9295
import com.oracle.truffle.api.nodes.Node;
9396
import com.oracle.truffle.api.nodes.UnexpectedResultException;
9497

95-
@MessageResolution(receiverType = PythonObjectNativeWrapper.class)
98+
@MessageResolution(receiverType = PythonNativeWrapper.class)
9699
public class PythonObjectNativeWrapperMR {
97100
protected static String GP_OBJECT = "gp_object";
98101

99102
@Resolve(message = "READ")
100103
abstract static class ReadNode extends Node {
101104
@Child private ReadNativeMemberNode readNativeMemberNode;
102105

103-
public Object access(Object object, Object key) {
106+
public Object access(PythonNativeWrapper object, String key) {
107+
// special key for the debugger
104108
if (key.equals(GP_OBJECT)) {
105-
return ((PythonNativeWrapper) object).getDelegate();
109+
return object.getDelegate();
106110
}
107-
if (readNativeMemberNode == null) {
108-
CompilerDirectives.transferToInterpreterAndInvalidate();
109-
readNativeMemberNode = insert(ReadNativeMemberNode.create());
111+
if (NativeMemberNames.isValid(key)) {
112+
if (readNativeMemberNode == null) {
113+
CompilerDirectives.transferToInterpreterAndInvalidate();
114+
readNativeMemberNode = insert(ReadNativeMemberNode.create());
115+
}
116+
return readNativeMemberNode.execute(object.getDelegate(), key);
110117
}
111-
return readNativeMemberNode.execute(((PythonNativeWrapper) object).getDelegate(), key);
118+
throw UnknownIdentifierException.raise(key.toString());
112119
}
113120
}
114121

@@ -117,10 +124,11 @@ public Object access(Object object, Object key) {
117124
abstract static class ReadNativeMemberNode extends PBaseNode {
118125
@Child GetClassNode getClass = GetClassNode.create();
119126
@Child private ToSulongNode toSulongNode;
127+
@Child private HashingStorageNodes.GetItemNode getItemNode;
120128

121129
@CompilationFinal long wcharSize = -1;
122130

123-
abstract Object execute(Object receiver, Object key);
131+
abstract Object execute(Object receiver, String key);
124132

125133
@Specialization(guards = "eq(OB_BASE, key)")
126134
Object doObBase(Object o, @SuppressWarnings("unused") String key) {
@@ -132,11 +140,6 @@ Object doObBase(PString o, @SuppressWarnings("unused") String key) {
132140
return getToSulongNode().execute(o);
133141
}
134142

135-
@Specialization(guards = "eq(_BASE, key)")
136-
Object doObBase(String o, @SuppressWarnings("unused") String key) {
137-
return getToSulongNode().execute(o);
138-
}
139-
140143
@Specialization(guards = "eq(OB_REFCNT, key)")
141144
int doObRefcnt(@SuppressWarnings("unused") Object o, @SuppressWarnings("unused") String key) {
142145
return 0;
@@ -187,7 +190,7 @@ Object doTpName(PythonClass object, @SuppressWarnings("unused") String key) {
187190
Object doTpBase(PythonClass object, @SuppressWarnings("unused") String key) {
188191
PythonClass superClass = object.getSuperClass();
189192
if (superClass != null) {
190-
return PythonObjectNativeWrapper.wrap(superClass);
193+
return getToSulongNode().execute(superClass);
191194
}
192195
return getToSulongNode().execute(object);
193196
}
@@ -275,16 +278,16 @@ Object doObItem(PSequence object, @SuppressWarnings("unused") String key) {
275278
}
276279

277280
@Specialization(guards = "eq(UNICODE_WSTR, key)")
278-
Object doWstr(String object, @SuppressWarnings("unused") String key,
281+
Object doWstr(PString object, @SuppressWarnings("unused") String key,
279282
@Cached("create(0)") UnicodeAsWideCharNode asWideCharNode) {
280-
return new PySequenceArrayWrapper(asWideCharNode.execute(object, sizeofWchar(), object.length()));
283+
return new PySequenceArrayWrapper(asWideCharNode.execute(object, sizeofWchar(), object.len()));
281284
}
282285

283286
@Specialization(guards = "eq(UNICODE_WSTR_LENGTH, key)")
284-
long doWstrLength(String object, @SuppressWarnings("unused") String key,
287+
long doWstrLength(PString object, @SuppressWarnings("unused") String key,
285288
@Cached("create(0)") UnicodeAsWideCharNode asWideCharNode) {
286289
long sizeofWchar = sizeofWchar();
287-
PBytes result = asWideCharNode.execute(object, sizeofWchar, object.length());
290+
PBytes result = asWideCharNode.execute(object, sizeofWchar, object.len());
288291
return result.len() / sizeofWchar;
289292
}
290293

@@ -306,8 +309,16 @@ Object doObSval(PBuffer object, @SuppressWarnings("unused") String key) {
306309
}
307310

308311
@Fallback
309-
Object doGeneric(@SuppressWarnings("unused") Object receiver, Object key) {
310-
throw UnknownIdentifierException.raise(key.toString());
312+
Object doGeneric(Object object, String key) {
313+
// This is the preliminary generic case: There are native members we know that they
314+
// exist but we do currently not represent them. So, store them into a dynamic object
315+
// such that native code at least reads the value that was written before.
316+
if (object instanceof PythonAbstractObject) {
317+
PythonObjectNativeWrapper nativeWrapper = ((PythonAbstractObject) object).getNativeWrapper();
318+
assert nativeWrapper != null;
319+
return getGetItemNode().execute(nativeWrapper.getNativeMemberStore(), key);
320+
}
321+
throw UnknownIdentifierException.raise(key);
311322
}
312323

313324
protected boolean eq(String expected, String actual) {
@@ -318,6 +329,14 @@ public static ReadNativeMemberNode create() {
318329
return ReadNativeMemberNodeGen.create();
319330
}
320331

332+
private HashingStorageNodes.GetItemNode getGetItemNode() {
333+
if (getItemNode == null) {
334+
CompilerDirectives.transferToInterpreterAndInvalidate();
335+
getItemNode = insert(GetItemNode.create());
336+
}
337+
return getItemNode;
338+
}
339+
321340
private ToSulongNode getToSulongNode() {
322341
if (toSulongNode == null) {
323342
CompilerDirectives.transferToInterpreterAndInvalidate();
@@ -343,21 +362,25 @@ private long sizeofWchar() {
343362

344363
@Resolve(message = "WRITE")
345364
abstract static class WriteNode extends Node {
346-
@Child private WriteNativeMemberNode readNativeMemberNode;
365+
@Child private WriteNativeMemberNode writeNativeMemberNode;
347366

348-
public Object access(Object object, Object key, Object value) {
349-
if (readNativeMemberNode == null) {
350-
CompilerDirectives.transferToInterpreterAndInvalidate();
351-
readNativeMemberNode = insert(WriteNativeMemberNode.create());
367+
public Object access(PythonNativeWrapper object, String key, Object value) {
368+
if (NativeMemberNames.isValid(key)) {
369+
if (writeNativeMemberNode == null) {
370+
CompilerDirectives.transferToInterpreterAndInvalidate();
371+
writeNativeMemberNode = insert(WriteNativeMemberNode.create());
372+
}
373+
return writeNativeMemberNode.execute(object.getDelegate(), key, value);
352374
}
353-
return readNativeMemberNode.execute(((PythonNativeWrapper) object).getDelegate(), key, value);
375+
throw UnknownIdentifierException.raise(key);
354376
}
355377
}
356378

357379
@ImportStatic({NativeMemberNames.class, PGuards.class})
358380
abstract static class WriteNativeMemberNode extends Node {
381+
@Child private HashingStorageNodes.SetItemNode setItemNode;
359382

360-
abstract Object execute(Object receiver, Object key, Object value);
383+
abstract Object execute(Object receiver, String key, Object value);
361384

362385
@Specialization(guards = "eq(OB_TYPE, key)")
363386
Object doObType(PythonObject object, @SuppressWarnings("unused") String key, @SuppressWarnings("unused") PythonClass value) {
@@ -399,15 +422,31 @@ Object doTpSubclasses(PythonClass object, @SuppressWarnings("unused") String key
399422
}
400423

401424
@Fallback
402-
Object doGeneric(Object object, Object key, @SuppressWarnings("unused") Object value) {
403-
CompilerDirectives.transferToInterpreter();
404-
throw new AssertionError("Cannot modify member '" + key + "' of " + object);
425+
Object doGeneric(Object object, String key, Object value) {
426+
// This is the preliminary generic case: There are native members we know that they
427+
// exist but we do currently not represent them. So, store them into a dynamic object
428+
// such that native code at least reads the value that was written before.
429+
if (object instanceof PythonAbstractObject) {
430+
PythonObjectNativeWrapper nativeWrapper = ((PythonAbstractObject) object).getNativeWrapper();
431+
assert nativeWrapper != null;
432+
getSetItemNode().execute(null, nativeWrapper.createNativeMemberStore(), key, value);
433+
return value;
434+
}
435+
throw UnknownIdentifierException.raise(key);
405436
}
406437

407438
protected boolean eq(String expected, String actual) {
408439
return expected.equals(actual);
409440
}
410441

442+
private HashingStorageNodes.SetItemNode getSetItemNode() {
443+
if (setItemNode == null) {
444+
CompilerDirectives.transferToInterpreterAndInvalidate();
445+
setItemNode = insert(SetItemNode.create());
446+
}
447+
return setItemNode;
448+
}
449+
411450
public static WriteNativeMemberNode create() {
412451
return WriteNativeMemberNodeGen.create();
413452
}
@@ -470,7 +509,7 @@ public int access(Object object, Object fieldName) {
470509
@Resolve(message = "HAS_KEYS")
471510
abstract static class HasKeysNode extends Node {
472511
public Object access(Object obj) {
473-
return obj instanceof PythonObjectNativeWrapper;
512+
return obj instanceof PythonNativeWrapper;
474513
}
475514
}
476515

@@ -479,7 +518,7 @@ abstract static class PForeignKeysNode extends Node {
479518
@Child Node objKeys = Message.KEYS.createNode();
480519

481520
public Object access(Object object) {
482-
if (object instanceof PythonObjectNativeWrapper) {
521+
if (object instanceof PythonNativeWrapper) {
483522
return PythonLanguage.getContext().getEnv().asGuestValue(new String[]{GP_OBJECT});
484523
} else {
485524
throw UnsupportedMessageException.raise(Message.KEYS);
@@ -503,7 +542,7 @@ Object access(PythonNativeWrapper obj) {
503542
abstract static class IsPointerNode extends Node {
504543
@Child private Node isPointerNode;
505544

506-
Object access(PythonObjectNativeWrapper obj) {
545+
Object access(PythonNativeWrapper obj) {
507546
return obj.isNative() && (!(obj.getNativePointer() instanceof TruffleObject) || ForeignAccess.sendIsPointer(getIsPointerNode(), (TruffleObject) obj.getNativePointer()));
508547
}
509548

0 commit comments

Comments
 (0)