Skip to content

Commit dc57688

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 3c16c81 commit dc57688

File tree

2 files changed

+10
-29
lines changed

2 files changed

+10
-29
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 & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,9 @@
3737
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
3838
import com.oracle.graal.python.builtins.PythonBuiltins;
3939
import com.oracle.graal.python.builtins.objects.PNone;
40-
import com.oracle.graal.python.builtins.objects.dict.PDict;
4140
import com.oracle.graal.python.builtins.objects.object.PythonObject;
4241
import com.oracle.graal.python.nodes.PGuards;
43-
import com.oracle.graal.python.nodes.object.SetDictNode;
44-
import com.oracle.graal.python.runtime.object.PFactory;
42+
import com.oracle.graal.python.nodes.object.GetOrCreateDictNode;
4543
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
4644
import com.oracle.truffle.api.object.Shape;
4745
import com.oracle.truffle.api.strings.TruffleString;
@@ -78,6 +76,7 @@ public final class PythonModule extends PythonObject {
7876
private PythonBuiltins builtins;
7977
private Object moduleState;
8078

79+
@TruffleBoundary
8180
public PythonModule(Object clazz, Shape instanceShape) {
8281
super(clazz, instanceShape);
8382
setAttribute(T___NAME__, PNone.NO_VALUE);
@@ -87,6 +86,7 @@ public PythonModule(Object clazz, Shape instanceShape) {
8786
setAttribute(T___SPEC__, PNone.NO_VALUE);
8887
setAttribute(T___CACHED__, PNone.NO_VALUE);
8988
setAttribute(T___FILE__, PNone.NO_VALUE);
89+
GetOrCreateDictNode.executeUncached(this);
9090
}
9191

9292
/**
@@ -102,6 +102,7 @@ private PythonModule(PythonLanguage lang, TruffleString moduleName) {
102102
setAttribute(T___SPEC__, PNone.NONE);
103103
setAttribute(T___CACHED__, PNone.NO_VALUE);
104104
setAttribute(T___FILE__, PNone.NO_VALUE);
105+
GetOrCreateDictNode.executeUncached(this);
105106
}
106107

107108
/**
@@ -110,10 +111,7 @@ private PythonModule(PythonLanguage lang, TruffleString moduleName) {
110111
@TruffleBoundary
111112
public static PythonModule createInternal(TruffleString moduleName) {
112113
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;
114+
return new PythonModule(language, moduleName);
117115
}
118116

119117
public PythonBuiltins getBuiltins() {

0 commit comments

Comments
 (0)