Skip to content

Commit 6fa2db1

Browse files
committed
Store promoted string for module name in PyModule_GetNameObject
1 parent 3696d15 commit 6fa2db1

File tree

1 file changed

+29
-5
lines changed

1 file changed

+29
-5
lines changed

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

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2021, 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
@@ -40,6 +40,7 @@
4040
*/
4141
package com.oracle.graal.python.builtins.modules.cext;
4242

43+
import static com.oracle.graal.python.builtins.PythonBuiltinClassType.SystemError;
4344
import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError;
4445
import static com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiCallPath.Direct;
4546
import static com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiCallPath.Ignored;
@@ -69,13 +70,16 @@
6970
import com.oracle.graal.python.builtins.objects.module.PythonModule;
7071
import com.oracle.graal.python.builtins.objects.object.ObjectBuiltins;
7172
import com.oracle.graal.python.builtins.objects.str.StringBuiltins.PrefixSuffixNode;
72-
import com.oracle.graal.python.lib.PyObjectLookupAttr;
73+
import com.oracle.graal.python.lib.PyUnicodeCheckNode;
74+
import com.oracle.graal.python.nodes.ErrorMessages;
7375
import com.oracle.graal.python.nodes.PRaiseNode;
76+
import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode;
7477
import com.oracle.graal.python.nodes.attributes.WriteAttributeToObjectNode;
7578
import com.oracle.graal.python.nodes.call.CallNode;
7679
import com.oracle.graal.python.nodes.classes.IsSubtypeNode;
7780
import com.oracle.graal.python.nodes.object.GetClassNode;
7881
import com.oracle.graal.python.runtime.PythonContext;
82+
import com.oracle.truffle.api.CompilerDirectives;
7983
import com.oracle.truffle.api.dsl.Bind;
8084
import com.oracle.truffle.api.dsl.Cached;
8185
import com.oracle.truffle.api.dsl.Cached.Shared;
@@ -156,10 +160,30 @@ Object run(TruffleString name,
156160
@CApiBuiltin(ret = PyObjectTransfer, args = {PyObject}, call = Direct)
157161
abstract static class PyModule_GetNameObject extends CApiUnaryBuiltinNode {
158162
@Specialization
159-
static Object getName(Object o,
163+
static Object getName(PythonModule module,
160164
@Bind("this") Node inliningTarget,
161-
@Cached PyObjectLookupAttr lookupAttrNode) {
162-
return lookupAttrNode.execute(null, inliningTarget, o, T___NAME__);
165+
@Cached PythonCextBuiltins.PromoteBorrowedValue promoteBorrowedValue,
166+
@Cached PyUnicodeCheckNode pyUnicodeCheckNode,
167+
// CPython reads from the module dict directly
168+
@Cached ReadAttributeFromObjectNode read,
169+
@Cached WriteAttributeToObjectNode write) {
170+
/*
171+
* Even thought the function returns a new reference, CPython assumes that the unicode
172+
* object returned from this function is still kept alive by the module's dict after a
173+
* decref, see PyModule_GetName. So we have to store the promoted string.
174+
*/
175+
Object nameAttr = read.execute(module, T___NAME__);
176+
if (!pyUnicodeCheckNode.execute(inliningTarget, nameAttr)) {
177+
CompilerDirectives.transferToInterpreterAndInvalidate();
178+
throw PRaiseNode.raiseUncached(inliningTarget, SystemError, ErrorMessages.NAMELESS_MODULE);
179+
}
180+
Object promotedName = promoteBorrowedValue.execute(inliningTarget, nameAttr);
181+
if (promotedName == null) {
182+
return nameAttr;
183+
} else {
184+
write.execute(module, T___NAME__, promotedName);
185+
return promotedName;
186+
}
163187
}
164188
}
165189

0 commit comments

Comments
 (0)