Skip to content

Commit c5d76a4

Browse files
committed
Create the dict eagerly for modules so it's always there
* graalpython/lib-python/3/test/test_descr.py::test.test_descr.ClassPropertiesAndMethods.test_uninitialized_modules caught a case where module.tp_new is called without module.tp_init and that caused an NPE from ReadAttributeFromModuleNode. * It seems much simpler and more efficient to always have that guarantee.
1 parent 0dd7344 commit c5d76a4

File tree

2 files changed

+10
-26
lines changed

2 files changed

+10
-26
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/module/ModuleBuiltins.java

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,6 @@
9999
import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider;
100100
import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile;
101101
import com.oracle.graal.python.nodes.object.GetDictIfExistsNode;
102-
import com.oracle.graal.python.nodes.object.GetOrCreateDictNode;
103-
import com.oracle.graal.python.nodes.object.SetDictNode;
104102
import com.oracle.graal.python.nodes.util.CannotCastException;
105103
import com.oracle.graal.python.nodes.util.CastToTruffleStringNode;
106104
import com.oracle.graal.python.runtime.PythonContext;
@@ -141,8 +139,7 @@ public abstract static class ModuleNewNode extends PythonBuiltinNode {
141139

142140
@Specialization
143141
@SuppressWarnings("unused")
144-
static Object doGeneric(Object cls, Object[] varargs, PKeyword[] kwargs,
145-
@Bind Node inliningTarget,
142+
static PythonModule doGeneric(Object cls, Object[] varargs, PKeyword[] kwargs,
146143
@Bind PythonLanguage language,
147144
@Cached TypeNodes.GetInstanceShape getInstanceShape) {
148145
return PFactory.createPythonModule(language, cls, getInstanceShape.execute(cls));
@@ -161,15 +158,12 @@ protected ArgumentClinicProvider getArgumentClinic() {
161158

162159
@Specialization
163160
public PNone module(PythonModule self, TruffleString name, Object doc,
164-
@Bind Node inliningTarget,
165161
@Cached WriteAttributeToObjectNode writeName,
166162
@Cached WriteAttributeToObjectNode writeDoc,
167163
@Cached WriteAttributeToObjectNode writePackage,
168164
@Cached WriteAttributeToObjectNode writeLoader,
169-
@Cached WriteAttributeToObjectNode writeSpec,
170-
@Cached GetOrCreateDictNode getDict) {
171-
// create dict if missing
172-
getDict.execute(inliningTarget, self);
165+
@Cached WriteAttributeToObjectNode writeSpec) {
166+
assert GetDictIfExistsNode.getUncached().execute(self) != null : "PythonModule always have a dict";
173167

174168
// init
175169
writeName.execute(self, T___NAME__, name);
@@ -216,19 +210,14 @@ public abstract static class ModuleDictNode extends PythonBinaryBuiltinNode {
216210

217211
@Specialization(guards = "isNoValue(none)")
218212
static Object doManaged(PythonModule self, @SuppressWarnings("unused") PNone none,
219-
@Bind Node inliningTarget,
220-
@Exclusive @Cached GetDictIfExistsNode getDict,
221-
@Cached SetDictNode setDict) {
213+
@Exclusive @Cached GetDictIfExistsNode getDict) {
222214
PDict dict = getDict.execute(self);
223-
if (dict == null) {
224-
dict = createDict(inliningTarget, self, setDict);
225-
}
215+
assert dict != null : "PythonModule always have a dict";
226216
return dict;
227217
}
228218

229219
@Specialization(guards = "isNoValue(none)")
230220
static Object doNativeObject(PythonAbstractNativeObject self, @SuppressWarnings("unused") PNone none,
231-
@Bind Node inliningTarget,
232221
@Exclusive @Cached GetDictIfExistsNode getDict,
233222
@Cached PRaiseNode raiseNode) {
234223
PDict dict = getDict.execute(self);
@@ -243,12 +232,6 @@ static Object doError(Object self, @SuppressWarnings("unused") Object dict,
243232
@Bind Node inliningTarget) {
244233
throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.DESCRIPTOR_DICT_FOR_MOD_OBJ_DOES_NOT_APPLY_FOR_P, self);
245234
}
246-
247-
private static PDict createDict(Node inliningTarget, PythonModule self, SetDictNode setDict) {
248-
PDict dict = PFactory.createDictFixedStorage(PythonLanguage.get(inliningTarget), self);
249-
setDict.execute(inliningTarget, self, dict);
250-
return dict;
251-
}
252235
}
253236

254237
@Slot(value = SlotKind.tp_getattro, isComplex = true)

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/module/PythonModule.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import com.oracle.graal.python.builtins.objects.dict.PDict;
4141
import com.oracle.graal.python.builtins.objects.object.PythonObject;
4242
import com.oracle.graal.python.nodes.PGuards;
43+
import com.oracle.graal.python.nodes.object.GetOrCreateDictNode;
4344
import com.oracle.graal.python.nodes.object.SetDictNode;
4445
import com.oracle.graal.python.runtime.object.PFactory;
4546
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
@@ -78,6 +79,7 @@ public final class PythonModule extends PythonObject {
7879
private PythonBuiltins builtins;
7980
private Object moduleState;
8081

82+
@TruffleBoundary
8183
public PythonModule(Object clazz, Shape instanceShape) {
8284
super(clazz, instanceShape);
8385
setAttribute(T___NAME__, PNone.NO_VALUE);
@@ -87,6 +89,7 @@ public PythonModule(Object clazz, Shape instanceShape) {
8789
setAttribute(T___SPEC__, PNone.NO_VALUE);
8890
setAttribute(T___CACHED__, PNone.NO_VALUE);
8991
setAttribute(T___FILE__, PNone.NO_VALUE);
92+
GetOrCreateDictNode.executeUncached(this);
9093
}
9194

9295
/**
@@ -102,6 +105,7 @@ private PythonModule(PythonLanguage lang, TruffleString moduleName) {
102105
setAttribute(T___SPEC__, PNone.NONE);
103106
setAttribute(T___CACHED__, PNone.NO_VALUE);
104107
setAttribute(T___FILE__, PNone.NO_VALUE);
108+
GetOrCreateDictNode.executeUncached(this);
105109
}
106110

107111
/**
@@ -110,10 +114,7 @@ private PythonModule(PythonLanguage lang, TruffleString moduleName) {
110114
@TruffleBoundary
111115
public static PythonModule createInternal(TruffleString moduleName) {
112116
PythonLanguage language = PythonLanguage.get(null);
113-
PythonModule pythonModule = new PythonModule(language, moduleName);
114-
PDict dict = PFactory.createDictFixedStorage(language, pythonModule);
115-
SetDictNode.executeUncached(pythonModule, dict);
116-
return pythonModule;
117+
return new PythonModule(language, moduleName);
117118
}
118119

119120
public PythonBuiltins getBuiltins() {

0 commit comments

Comments
 (0)