Skip to content

Commit 0f9333f

Browse files
committed
intrinsified PyModule_AddObject
1 parent 28b1391 commit 0f9333f

File tree

4 files changed

+81
-10
lines changed

4 files changed

+81
-10
lines changed

graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_module.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,14 @@
4747
class SubModuleType(ModuleType):
4848
pass
4949

50+
def _reference_add_object(args):
51+
if not isinstance(args[0], ModuleType):
52+
if sys.version_info.minor >= 6:
53+
raise SystemError
54+
else:
55+
return -1
56+
args[0].__dict__[args[1]] = args[2]
57+
return 0
5058

5159
class TestPyModule(CPyExtTestCase):
5260

@@ -137,4 +145,19 @@ def compile_module(self, name):
137145
resultspec="O",
138146
argspec='O',
139147
arguments=["PyObject* object"],
140-
)
148+
)
149+
150+
test_PyModule_AddObject = CPyExtFunction(
151+
_reference_add_object,
152+
lambda: (
153+
(1, "testAddObject", None),
154+
(ModuleType("hello"), "testAddObject", None),
155+
(ModuleType("hello"), "testAddObject", "a"),
156+
(SubModuleType("subhello"), "testAddObject", "a"),
157+
),
158+
resultspec="i",
159+
argspec='OsO',
160+
arguments=["PyObject* m", "const char* k", "PyObject* v"],
161+
cmpfunc=unhandled_error_compare
162+
)
163+

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextModuleBuiltins.java

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,12 @@
4141
package com.oracle.graal.python.builtins.modules.cext;
4242

4343
import static com.oracle.graal.python.builtins.PythonBuiltinClassType.SystemError;
44-
import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError;
4544
import static com.oracle.graal.python.nodes.ErrorMessages.MODULE_S_HAS_NO;
46-
import static com.oracle.graal.python.nodes.ErrorMessages.S_NEEDS_NON_NULL_VALUE;
4745
import static com.oracle.graal.python.nodes.ErrorMessages.S_NEEDS_S_AS_FIRST_ARG;
48-
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__DICT__;
4946
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__DOC__;
5047
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__NAME__;
5148
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__PACKAGE__;
49+
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__DICT__;
5250

5351
import com.oracle.graal.python.annotations.ArgumentClinic;
5452
import com.oracle.graal.python.annotations.ArgumentClinic.ClinicConversion;
@@ -197,4 +195,58 @@ Object getName(VirtualFrame frame, Object o,
197195
}
198196
}
199197

198+
@Builtin(name = "PyModule_AddObject", minNumOfPositionalArgs = 3)
199+
@GenerateNodeFactory
200+
public abstract static class PyModuleAddObjectNode extends PythonTernaryBuiltinNode {
201+
@Specialization(guards = "isModuleSubtype(frame, m, getClassNode, isSubtypeNode)")
202+
Object addObject(VirtualFrame frame, Object m, String k, Object o,
203+
@SuppressWarnings("unused") @Cached GetClassNode getClassNode,
204+
@SuppressWarnings("unused") @Cached IsSubtypeNode isSubtypeNode,
205+
@Cached PyObjectLookupAttr lookupAttrNode,
206+
@Cached GetDictIfExistsNode getDictNode,
207+
@Cached BranchProfile noDictProfile,
208+
@CachedLibrary(limit = "3") HashingStorageLibrary lib,
209+
@Cached PRaiseNativeNode raiseNativeNode,
210+
@Cached TransformExceptionToNativeNode transformExceptionToNativeNode) {
211+
try {
212+
PDict dict = getDictNode.execute(m);
213+
if (dict == null) {
214+
noDictProfile.enter();
215+
return raiseNativeNode.raiseInt(frame, -1, SystemError, MODULE_S_HAS_NO, lookupAttrNode.execute(frame, m, __NAME__), __DICT__);
216+
}
217+
lib.setItem(dict.getDictStorage(), k, o);
218+
return 0;
219+
} catch (PException e) {
220+
transformExceptionToNativeNode.execute(e);
221+
return -1;
222+
}
223+
}
224+
225+
@Specialization(guards = "isModuleSubtype(frame, m, getClassNode, isSubtypeNode)")
226+
Object addObject(VirtualFrame frame, Object m, PString k, Object o,
227+
@SuppressWarnings("unused") @Cached GetClassNode getClassNode,
228+
@SuppressWarnings("unused") @Cached IsSubtypeNode isSubtypeNode,
229+
@Cached PyObjectLookupAttr lookupAttrNode,
230+
@Cached GetDictIfExistsNode getDictNode,
231+
@Cached BranchProfile noDictProfile,
232+
@CachedLibrary(limit = "3") HashingStorageLibrary lib,
233+
@Cached PRaiseNativeNode raiseNativeNode,
234+
@Cached TransformExceptionToNativeNode transformExceptionToNativeNode) {
235+
return addObject(frame, m, k.getValue(), o, getClassNode, isSubtypeNode, lookupAttrNode, getDictNode, noDictProfile, lib, raiseNativeNode, transformExceptionToNativeNode);
236+
}
237+
238+
@SuppressWarnings("unused")
239+
@Specialization(guards = "!isModuleSubtype(frame, m, getClassNode, isSubtypeNode)")
240+
public Object pop(VirtualFrame frame, Object m, Object key, Object defaultValue,
241+
@SuppressWarnings("unused") @Cached GetClassNode getClassNode,
242+
@SuppressWarnings("unused") @Cached IsSubtypeNode isSubtypeNode,
243+
@Cached PRaiseNativeNode raiseNativeNode) {
244+
return raiseNativeNode.raiseInt(frame, -1, SystemError, S_NEEDS_S_AS_FIRST_ARG, "PyModule_AddObject", "module");
245+
}
246+
247+
protected boolean isModuleSubtype(VirtualFrame frame, Object obj, GetClassNode getClassNode, IsSubtypeNode isSubtypeNode) {
248+
return isSubtypeNode.execute(frame, getClassNode.execute(obj), PythonBuiltinClassType.PythonModule);
249+
}
250+
}
251+
200252
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/ErrorMessages.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,7 @@ public abstract class ErrorMessages {
439439
public static final String MISSING_S = "Missing %s";
440440
public static final String MMAP_INDEX_OUT_OF_RANGE = "mmap index out of range";
441441
public static final String MODULE_HAS_NO_ATTR_S = "module has no attribute '%s'";
442+
public static final String MODULE_S_HAS_NO = "module '%s' has no %s";
442443
public static final String MODULE_PARTIALLY_INITIALIZED_S_HAS_NO_ATTR_S = "partially initialized module '%s' has no attribute '%s' (most likely due to a circular import)";
443444
public static final String MODULE_S_HAS_NO_ATTR_S = "module '%s' has no attribute '%s'";
444445
public static final String MULTI_DIMENSIONAL_SUB_VIEWS_NOT_IMPLEMENTED = "multi-dimensional sub-views are not implemented";
@@ -476,6 +477,7 @@ public abstract class ErrorMessages {
476477
public static final String NATIVE_S_SUBTYPES_NOT_IMPLEMENTED = "native %s subtypes not implemented";
477478
public static final String NEED_BYTELIKE_OBJ = "decoding to str: need a bytes-like object, %p found";
478479
public static final String DECODING_STR_NOT_SUPPORTED = "decoding str is not supported";
480+
public static final String S_NEEDS_S_AS_FIRST_ARG = "%s() needs %s as first arg";
479481
public static final String NEG_INF_PLUS_INF_IN = "-inf + inf in fsum";
480482
public static final String NEGATIVE_COUNT = "negative count";
481483
public static final String NEGATIVE_DATA_SIZE = "negative data size";

graalpython/lib-graalpython/python_cext.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,6 @@ def decorator(fun):
5050
return make_may_raise_wrapper(fun, error_result)
5151
return decorator
5252

53-
@may_raise(-1)
54-
def PyModule_AddObject(m, k, v):
55-
m.__dict__[k] = v
56-
return 0
57-
58-
5953
def METH_UNSUPPORTED():
6054
raise NotImplementedError("unsupported message type")
6155

0 commit comments

Comments
 (0)