Skip to content

Commit 1a3ab86

Browse files
committed
[GR-52438] Cleanup the API of Write/Read attribute nodes
PullRequest: graalpython/3224
2 parents 9b11c77 + 0539e0e commit 1a3ab86

23 files changed

+199
-302
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/Python3Core.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -949,7 +949,7 @@ private void initializeImportlib() {
949949
LOGGER.log(Level.FINE, () -> "initializing zipimport failed");
950950
} else {
951951
LOGGER.log(Level.FINE, () -> "# installing zipimport hook");
952-
Object zipimport = null;
952+
PythonModule zipimport = null;
953953
try {
954954
zipimport = AbstractImportNode.importModule(toTruffleStringUncached("zipimport"));
955955
} catch (PException e) {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/CodecsTruffleModuleBuiltins.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ public BuiltinDescr(Supplier<PythonBuiltinBaseNode> nodeSupplier, Class<?> nodeC
191191

192192
@TruffleBoundary
193193
static PTuple codecsInfo(PythonModule self, TruffleString encoding, PythonContext context, PythonObjectFactory factory) {
194-
PythonModule codecsModule = (PythonModule) AbstractImportNode.importModule(T_CODECS);
194+
PythonModule codecsModule = AbstractImportNode.importModule(T_CODECS);
195195
CodecsTruffleModuleBuiltins codecsTruffleBuiltins = (CodecsTruffleModuleBuiltins) self.getBuiltins();
196196
if (self.getAttribute(T_TRUFFLE_CODEC) instanceof PNone) {
197197
initCodecClasses(self, codecsModule, context, factory);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1010,7 +1010,7 @@ static void doNativeClass(PythonNativeClass object, TruffleString key, Object va
10101010
@Specialization(guards = {"!isPythonBuiltinClass(object)"})
10111011
static void doObject(PythonObject object, TruffleString key, Object value,
10121012
@Exclusive @Cached(inline = false) WriteAttributeToDynamicObjectNode writeAttrToDynamicObjectNode) {
1013-
writeAttrToDynamicObjectNode.execute(object.getStorage(), key, value);
1013+
writeAttrToDynamicObjectNode.execute(object, key, value);
10141014
}
10151015
}
10161016

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

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -41,7 +41,6 @@
4141
package com.oracle.graal.python.builtins.modules.cext;
4242

4343
import static com.oracle.graal.python.builtins.PythonBuiltinClassType.AttributeError;
44-
import static com.oracle.graal.python.builtins.PythonBuiltinClassType.ImportError;
4544
import static com.oracle.graal.python.builtins.PythonBuiltinClassType.ValueError;
4645
import static com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiCallPath.Direct;
4746
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.ConstCharPtr;
@@ -366,9 +365,6 @@ static Object doGeneric(TruffleString name, @SuppressWarnings("unused") int noBl
366365
if (object == null) {
367366
// noBlock has no effect anymore since 3.3
368367
object = AbstractImportNode.importModule(trace, T_IMPORT_ALL);
369-
if (object == PNone.NO_VALUE) {
370-
throw raiseNode.get(inliningTarget).raise(ImportError, PY_CAPSULE_IMPORT_S_IS_NOT_VALID, trace);
371-
}
372368
} else {
373369
object = getAttrNode.execute(object, trace);
374370
}

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@
152152
import com.oracle.graal.python.nodes.object.GetClassNode;
153153
import com.oracle.graal.python.nodes.object.GetDictIfExistsNode;
154154
import com.oracle.graal.python.nodes.object.SetDictNode;
155+
import com.oracle.graal.python.nodes.util.CastToTruffleStringNode;
155156
import com.oracle.graal.python.runtime.PythonContext;
156157
import com.oracle.graal.python.runtime.sequence.PSequence;
157158
import com.oracle.graal.python.runtime.sequence.storage.NativeByteSequenceStorage;
@@ -835,6 +836,7 @@ static Object doTpDict(PythonManagedClass object, Object value,
835836
@Bind("this") Node inliningTarget,
836837
@Cached GetDictIfExistsNode getDict,
837838
@Cached SetDictNode setDict,
839+
@Cached CastToTruffleStringNode castNode,
838840
@Cached WriteAttributeToObjectNode writeAttrNode,
839841
@Cached HashingStorageGetIterator getIterator,
840842
@Cached HashingStorageIteratorNext itNext,
@@ -845,7 +847,7 @@ static Object doTpDict(PythonManagedClass object, Object value,
845847
HashingStorage storage = dict.getDictStorage();
846848
HashingStorageIterator it = getIterator.execute(inliningTarget, storage);
847849
while (itNext.execute(inliningTarget, storage, it)) {
848-
writeAttrNode.execute(object, itKey.execute(inliningTarget, storage, it), itValue.execute(inliningTarget, storage, it));
850+
writeAttrNode.execute(object, castNode.castKnownString(inliningTarget, itKey.execute(inliningTarget, storage, it)), itValue.execute(inliningTarget, storage, it));
849851
}
850852
PDict existing = getDict.execute(object);
851853
if (existing != null) {

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@
9696
import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode;
9797
import com.oracle.graal.python.nodes.attributes.WriteAttributeToDynamicObjectNode;
9898
import com.oracle.graal.python.nodes.classes.IsSubtypeNode;
99+
import com.oracle.graal.python.nodes.util.CastToTruffleStringNode;
99100
import com.oracle.graal.python.runtime.PythonContext;
100101
import com.oracle.graal.python.runtime.PythonOptions;
101102
import com.oracle.graal.python.runtime.object.PythonObjectFactory;
@@ -130,8 +131,11 @@ public final class PythonCextTypeBuiltins {
130131
abstract static class _PyType_Lookup extends CApiBinaryBuiltinNode {
131132
@Specialization
132133
Object doGeneric(Object type, Object name,
134+
@Bind("this") Node inliningTarget,
135+
@Cached CastToTruffleStringNode castToTruffleStringNode,
133136
@Cached LookupAttributeInMRONode.Dynamic lookupAttributeInMRONode) {
134-
Object result = lookupAttributeInMRONode.execute(type, name);
137+
TruffleString key = castToTruffleStringNode.castKnownString(inliningTarget, name);
138+
Object result = lookupAttributeInMRONode.execute(type, key);
135139
if (result == PNone.NO_VALUE) {
136140
return getNativeNull();
137141
}
@@ -302,7 +306,7 @@ abstract static class PyTruffleType_AddSlot extends CApi7BuiltinNode {
302306
@TruffleBoundary
303307
static int addSlot(Object clazz, PDict tpDict, TruffleString memberName, Object cfunc, int flags, int wrapper, Object memberDoc) {
304308
// create wrapper descriptor
305-
Object wrapperDescriptor = CreateFunctionNode.executeUncached(memberName, cfunc, wrapper, clazz, flags);
309+
PythonObject wrapperDescriptor = CreateFunctionNode.executeUncached(memberName, cfunc, wrapper, clazz, flags);
306310
WriteAttributeToDynamicObjectNode.getUncached().execute(wrapperDescriptor, SpecialAttributeNames.T___DOC__, memberDoc);
307311

308312
// add wrapper descriptor to tp_dict

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/HashlibModuleBuiltins.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ public void initialize(Python3Core core) {
167167
super.initialize(core);
168168
}
169169

170-
private void addDigestAlias(PythonModule self, Object mod, ReadAttributeFromDynamicObjectNode readNode, EconomicMapStorage storage, String digest) {
170+
private void addDigestAlias(PythonModule self, PythonModule mod, ReadAttributeFromDynamicObjectNode readNode, EconomicMapStorage storage, String digest) {
171171
TruffleString tsDigest = toTruffleStringUncached(digest);
172172
Object function = readNode.execute(mod, tsDigest);
173173
if (function != NO_VALUE) {
@@ -182,10 +182,10 @@ public void postInitialize(Python3Core core) {
182182
PythonModule self = core.lookupBuiltinModule(T_HASHLIB);
183183
ReadAttributeFromDynamicObjectNode readNode = ReadAttributeFromDynamicObjectNode.getUncached();
184184
EconomicMapStorage storage = (EconomicMapStorage) HiddenAttr.ReadNode.executeUncached(self, HiddenAttr.ORIGINAL_CONSTRUCTORS, NO_VALUE);
185-
Object sha3module = AbstractImportNode.importModule(T_SHA3);
185+
PythonModule sha3module = AbstractImportNode.importModule(T_SHA3);
186186
for (int i = 0; i < DIGEST_ALIASES.length; i += 2) {
187187
String module = DIGEST_ALIASES[i + 1];
188-
Object mod = module.equals(J_SHA3) ? sha3module : core.lookupBuiltinModule(toTruffleStringUncached(module));
188+
PythonModule mod = module.equals(J_SHA3) ? sha3module : core.lookupBuiltinModule(toTruffleStringUncached(module));
189189
addDigestAlias(self, mod, readNode, storage, DIGEST_ALIASES[i]);
190190
}
191191
}

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

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@
6464
import static com.oracle.graal.python.runtime.exception.PythonErrorType.SystemError;
6565
import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING;
6666
import static com.oracle.graal.python.util.PythonUtils.toTruffleStringUncached;
67+
import static com.oracle.truffle.api.CompilerDirectives.shouldNotReachHere;
68+
import static com.oracle.truffle.api.CompilerDirectives.transferToInterpreter;
6769

6870
import java.util.regex.Matcher;
6971
import java.util.regex.Pattern;
@@ -212,7 +214,7 @@ public abstract static class SubtypeNew extends Node {
212214
* tget the <code>typename_subtype_new</code> function
213215
*/
214216
protected NativeCAPISymbol getFunction() {
215-
throw CompilerDirectives.shouldNotReachHere();
217+
throw shouldNotReachHere();
216218
}
217219

218220
protected abstract Object execute(Object object, Object arg);
@@ -238,7 +240,7 @@ Object callNativeConstructor(Object object, Object arg,
238240
Object result = interopLibrary.execute(importCAPISymbolNode.execute(inliningTarget, cApiContext, getFunction()), toSulongNode.execute(object), arg);
239241
return toJavaNode.execute(result);
240242
} catch (UnsupportedMessageException | UnsupportedTypeException | ArityException e) {
241-
throw CompilerDirectives.shouldNotReachHere("C subtype_new function failed", e);
243+
throw shouldNotReachHere("C subtype_new function failed", e);
242244
}
243245
}
244246
}
@@ -839,7 +841,7 @@ static Object doWithoutContext(NativeCAPISymbol name, Object[] args,
839841
return ensureTruffleStringNode.execute(inliningTarget, interopLibrary.execute(importCExtSymbolNode.execute(inliningTarget, cApiContext, name), args));
840842
} catch (UnsupportedTypeException | ArityException | UnsupportedMessageException e) {
841843
// consider these exceptions to be fatal internal errors
842-
throw CompilerDirectives.shouldNotReachHere(e);
844+
throw shouldNotReachHere(e);
843845
}
844846
}
845847

@@ -921,7 +923,7 @@ public static long lookupNativeI64MemberInMRO(Object cls, CFields nativeMemberNa
921923
if (managedMemberName instanceof HiddenAttr ha) {
922924
attr = HiddenAttr.ReadNode.executeUncached((PythonAbstractObject) mroCls, ha, NO_VALUE);
923925
} else {
924-
attr = ReadAttributeFromObjectNode.getUncachedForceType().execute(mroCls, managedMemberName);
926+
attr = ReadAttributeFromObjectNode.getUncachedForceType().execute(mroCls, CompilerDirectives.castExact(managedMemberName, TruffleString.class));
925927
}
926928
if (attr != NO_VALUE) {
927929
return PyNumberAsSizeNode.executeExactUncached(attr);
@@ -1126,7 +1128,7 @@ static Object doNativeObject(Object object, long value,
11261128
long refCount = CApiTransitions.readNativeRefCount(pointer);
11271129
CApiTransitions.writeNativeRefCount(pointer, refCount + value);
11281130
} catch (UnsupportedMessageException e) {
1129-
throw CompilerDirectives.shouldNotReachHere(e);
1131+
throw shouldNotReachHere(e);
11301132
}
11311133
}
11321134
return object;
@@ -1219,7 +1221,7 @@ static Object resolveGeneric(Node inliningTarget, Object pointerObject,
12191221
try {
12201222
pointer = lib.asPointer(pointerObject);
12211223
} catch (UnsupportedMessageException e) {
1222-
throw CompilerDirectives.shouldNotReachHere(e);
1224+
throw shouldNotReachHere(e);
12231225
}
12241226
lookup = CApiTransitions.lookupNative(pointer);
12251227
if (lookup != null) {
@@ -1427,7 +1429,7 @@ Object doGeneric(TruffleString f, Object vaList) {
14271429
// That should really not happen because we created the unicode
14281430
// object with FromCharPointerNode which guarantees to return a
14291431
// String/PString.
1430-
throw CompilerDirectives.shouldNotReachHere();
1432+
throw shouldNotReachHere();
14311433
}
14321434
vaArgIdx++;
14331435
valid = true;
@@ -1516,7 +1518,7 @@ private static int getAndCastToInt(InteropLibrary lib, PRaiseNode raiseNode, Obj
15161518
try {
15171519
return lib.asInt(value);
15181520
} catch (UnsupportedMessageException e) {
1519-
throw CompilerDirectives.shouldNotReachHere();
1521+
throw shouldNotReachHere();
15201522
}
15211523
}
15221524
if (!lib.isPointer(value)) {
@@ -1526,7 +1528,7 @@ private static int getAndCastToInt(InteropLibrary lib, PRaiseNode raiseNode, Obj
15261528
try {
15271529
return (int) lib.asPointer(value);
15281530
} catch (UnsupportedMessageException e) {
1529-
throw CompilerDirectives.shouldNotReachHere();
1531+
throw shouldNotReachHere();
15301532
}
15311533
}
15321534
throw raiseNode.raise(PythonBuiltinClassType.SystemError, ErrorMessages.P_OBJ_CANT_BE_INTEPRETED_AS_INTEGER, value);
@@ -1541,7 +1543,7 @@ private static long castToLong(InteropLibrary lib, PRaiseNode raiseNode, Object
15411543
try {
15421544
return lib.asLong(value);
15431545
} catch (UnsupportedMessageException e) {
1544-
throw CompilerDirectives.shouldNotReachHere();
1546+
throw shouldNotReachHere();
15451547
}
15461548
}
15471549
if (!lib.isPointer(value)) {
@@ -1551,7 +1553,7 @@ private static long castToLong(InteropLibrary lib, PRaiseNode raiseNode, Object
15511553
try {
15521554
return lib.asPointer(value);
15531555
} catch (UnsupportedMessageException e) {
1554-
throw CompilerDirectives.shouldNotReachHere();
1556+
throw shouldNotReachHere();
15551557
}
15561558
}
15571559
throw raiseNode.raise(PythonBuiltinClassType.SystemError, ErrorMessages.P_OBJ_CANT_BE_INTEPRETED_AS_INTEGER, value);
@@ -1681,7 +1683,7 @@ static Object doGeneric(CApiContext capiContext, ModuleSpec moduleSpec, Object m
16811683
ErrorMessages.CREATION_FAILD_WITHOUT_EXCEPTION, ErrorMessages.CREATION_RAISED_EXCEPTION);
16821684
module = toJavaNode.execute(result);
16831685
} catch (UnsupportedTypeException | ArityException | UnsupportedMessageException e) {
1684-
throw CompilerDirectives.shouldNotReachHere(e);
1686+
throw shouldNotReachHere(e);
16851687
}
16861688

16871689
/*
@@ -1801,7 +1803,7 @@ static int doGeneric(CApiContext capiContext, PythonModule module, Object module
18011803
}
18021804
}
18031805
} catch (UnsupportedMessageException | UnsupportedTypeException | ArityException e) {
1804-
throw CompilerDirectives.shouldNotReachHere();
1806+
throw shouldNotReachHere();
18051807
}
18061808

18071809
return 0;
@@ -1859,7 +1861,7 @@ static PBuiltinFunction doIt(Node inliningTarget, Object methodDef, int element,
18591861

18601862
// write doc string; we need to directly write to the storage otherwise it is disallowed
18611863
// writing to builtin types.
1862-
writeAttributeToDynamicObjectNode.execute(function.getStorage(), SpecialAttributeNames.T___DOC__, methodDoc);
1864+
writeAttributeToDynamicObjectNode.execute(function, SpecialAttributeNames.T___DOC__, methodDoc);
18631865

18641866
return function;
18651867
}
@@ -1940,23 +1942,23 @@ public abstract static class CreateFunctionNode extends Node {
19401942

19411943
private static final TruffleLogger LOGGER = CApiContext.getLogger(CreateFunctionNode.class);
19421944

1943-
public static Object executeUncached(TruffleString name, Object callable, int wrapper, Object type, Object flags) {
1945+
public static PythonObject executeUncached(TruffleString name, Object callable, int wrapper, Object type, Object flags) {
19441946
return CreateFunctionNodeGen.getUncached().execute(null, name, callable, wrapper, type, flags);
19451947
}
19461948

1947-
public abstract Object execute(Node inliningTarget, TruffleString name, Object callable, int wrapper, Object type, Object flags);
1949+
public abstract PythonObject execute(Node inliningTarget, TruffleString name, Object callable, int wrapper, Object type, Object flags);
19481950

19491951
@Specialization(guards = "!isNoValue(type)")
19501952
@TruffleBoundary
1951-
static Object doPythonCallable(TruffleString name, PythonNativeWrapper callable, int signature, Object type, int flags) {
1953+
static PythonObject doPythonCallable(TruffleString name, PythonNativeWrapper callable, int signature, Object type, int flags) {
19521954
// This can happen if a native type inherits slots from a managed type. Therefore,
19531955
// something like 'base->tp_new' will be a wrapper of the managed '__new__'. So, in this
19541956
// case, we assume that the object is already callable.
19551957
Object managedCallable = callable.getDelegate();
19561958
PythonContext context = PythonContext.get(null);
19571959
PythonLanguage language = context.getLanguage();
19581960
PBuiltinFunction function = PExternalFunctionWrapper.createWrapperFunction(name, managedCallable, type, flags, signature, language, context.factory(), false);
1959-
return function != null ? function : managedCallable;
1961+
return function != null ? function : castToPythonObject(managedCallable);
19601962
}
19611963

19621964
@Specialization
@@ -1971,7 +1973,7 @@ static PBuiltinFunction doPyCFunctionWrapper(TruffleString name, PyCFunctionWrap
19711973

19721974
@Specialization(guards = {"!isNativeWrapper(callable)"})
19731975
@TruffleBoundary
1974-
static Object doNativeCallableWithWrapper(TruffleString name, Object callable, int signature, Object type, int flags,
1976+
static PythonObject doNativeCallableWithWrapper(TruffleString name, Object callable, int signature, Object type, int flags,
19751977
@CachedLibrary(limit = "3") InteropLibrary lib) {
19761978
/*
19771979
* This can happen if a native type inherits slots from a managed type. For example, if
@@ -1990,7 +1992,15 @@ static Object doNativeCallableWithWrapper(TruffleString name, Object callable, i
19901992
}
19911993
PythonLanguage language = context.getLanguage();
19921994
PBuiltinFunction function = PExternalFunctionWrapper.createWrapperFunction(name, resolvedCallable, type, flags, signature, language, context.factory(), doArgAndResultConversion);
1993-
return function != null ? function : resolvedCallable;
1995+
return function != null ? function : castToPythonObject(resolvedCallable);
1996+
}
1997+
1998+
private static PythonObject castToPythonObject(Object callable) {
1999+
if (callable instanceof PythonObject pythonObject) {
2000+
return pythonObject;
2001+
}
2002+
transferToInterpreter();
2003+
throw shouldNotReachHere("Unexpected class of callable: " + callable.getClass());
19942004
}
19952005

19962006
@TruffleBoundary
@@ -2000,7 +2010,7 @@ public static Object resolveClosurePointer(PythonContext context, Object callabl
20002010
try {
20012011
pointer = lib.asPointer(callable);
20022012
} catch (UnsupportedMessageException e) {
2003-
throw CompilerDirectives.shouldNotReachHere(e);
2013+
throw shouldNotReachHere(e);
20042014
}
20052015
Object delegate = context.getCApiContext().getClosureDelegate(pointer);
20062016
if (delegate != null) {

0 commit comments

Comments
 (0)