|
1 | 1 | /*
|
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. |
3 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
4 | 4 | *
|
5 | 5 | * The Universal Permissive License (UPL), Version 1.0
|
|
40 | 40 | */
|
41 | 41 | package com.oracle.graal.python.builtins.modules.cext;
|
42 | 42 |
|
| 43 | +import static com.oracle.graal.python.builtins.PythonBuiltinClassType.SystemError; |
43 | 44 | import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError;
|
44 | 45 | import static com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiCallPath.Direct;
|
45 | 46 | import static com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiCallPath.Ignored;
|
|
69 | 70 | import com.oracle.graal.python.builtins.objects.module.PythonModule;
|
70 | 71 | import com.oracle.graal.python.builtins.objects.object.ObjectBuiltins;
|
71 | 72 | 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; |
73 | 75 | import com.oracle.graal.python.nodes.PRaiseNode;
|
| 76 | +import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode; |
74 | 77 | import com.oracle.graal.python.nodes.attributes.WriteAttributeToObjectNode;
|
75 | 78 | import com.oracle.graal.python.nodes.call.CallNode;
|
76 | 79 | import com.oracle.graal.python.nodes.classes.IsSubtypeNode;
|
77 | 80 | import com.oracle.graal.python.nodes.object.GetClassNode;
|
78 | 81 | import com.oracle.graal.python.runtime.PythonContext;
|
| 82 | +import com.oracle.truffle.api.CompilerDirectives; |
79 | 83 | import com.oracle.truffle.api.dsl.Bind;
|
80 | 84 | import com.oracle.truffle.api.dsl.Cached;
|
81 | 85 | import com.oracle.truffle.api.dsl.Cached.Shared;
|
@@ -156,10 +160,30 @@ Object run(TruffleString name,
|
156 | 160 | @CApiBuiltin(ret = PyObjectTransfer, args = {PyObject}, call = Direct)
|
157 | 161 | abstract static class PyModule_GetNameObject extends CApiUnaryBuiltinNode {
|
158 | 162 | @Specialization
|
159 |
| - static Object getName(Object o, |
| 163 | + static Object getName(PythonModule module, |
160 | 164 | @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 | + } |
163 | 187 | }
|
164 | 188 | }
|
165 | 189 |
|
|
0 commit comments