|
73 | 73 | import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING;
|
74 | 74 | import static com.oracle.graal.python.util.PythonUtils.toTruffleStringUncached;
|
75 | 75 | import static com.oracle.truffle.api.CompilerDirectives.shouldNotReachHere;
|
76 |
| -import static com.oracle.truffle.api.CompilerDirectives.transferToInterpreterAndInvalidate; |
77 | 76 |
|
78 | 77 | import java.util.regex.Matcher;
|
79 | 78 | import java.util.regex.Pattern;
|
|
91 | 90 | import com.oracle.graal.python.builtins.objects.cext.PythonNativeVoidPtr;
|
92 | 91 | import com.oracle.graal.python.builtins.objects.cext.capi.CApiContext.ModuleSpec;
|
93 | 92 | import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodesFactory.AsCharPointerNodeGen;
|
94 |
| -import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodesFactory.CreateFunctionNodeGen; |
95 | 93 | import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodesFactory.FromCharPointerNodeGen;
|
96 | 94 | import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodesFactory.PyErrFetchNodeGen;
|
97 | 95 | import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodesFactory.PyErrOccurredNodeGen;
|
|
101 | 99 | import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes.DefaultCheckFunctionResultNode;
|
102 | 100 | import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes.ExternalFunctionInvokeNode;
|
103 | 101 | import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes.PExternalFunctionWrapper;
|
104 |
| -import com.oracle.graal.python.builtins.objects.cext.capi.PyProcsWrapper.TpSlotWrapper; |
105 | 102 | import com.oracle.graal.python.builtins.objects.cext.capi.PythonNativeWrapper.PythonAbstractObjectNativeWrapper;
|
106 | 103 | import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions;
|
107 | 104 | import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.HandlePointerConverter;
|
|
151 | 148 | import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetMroStorageNode;
|
152 | 149 | import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetTypeFlagsNode;
|
153 | 150 | import com.oracle.graal.python.builtins.objects.type.TypeNodes.ProfileClassNode;
|
154 |
| -import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotBuiltin; |
155 |
| -import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotNative; |
156 |
| -import com.oracle.graal.python.builtins.objects.type.slots.TpSlot.TpSlotPython; |
157 | 151 | import com.oracle.graal.python.lib.PyFloatAsDoubleNode;
|
158 | 152 | import com.oracle.graal.python.lib.PyNumberAsSizeNode;
|
159 | 153 | import com.oracle.graal.python.lib.PyObjectLookupAttr;
|
|
195 | 189 | import com.oracle.truffle.api.CompilerDirectives;
|
196 | 190 | import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
|
197 | 191 | import com.oracle.truffle.api.RootCallTarget;
|
198 |
| -import com.oracle.truffle.api.TruffleLogger; |
199 | 192 | import com.oracle.truffle.api.dsl.Bind;
|
200 | 193 | import com.oracle.truffle.api.dsl.Cached;
|
201 | 194 | import com.oracle.truffle.api.dsl.Cached.Exclusive;
|
@@ -888,7 +881,7 @@ public static PCallCapiFunction getUncached() {
|
888 | 881 | * <p>
|
889 | 882 | * This method basically implements the native member inheritance that is done by
|
890 | 883 | * {@code inherit_special} or other code in {@code PyType_Ready}. In addition, we do a special
|
891 |
| - * case for special slots assignment that happens within {@Code type_new_alloc} for heap types. |
| 884 | + * case for special slots assignment that happens within {@code type_new_alloc} for heap types. |
892 | 885 | * </p>
|
893 | 886 | * <p>
|
894 | 887 | * Since it may be that a managed types needs to emulate such members but there is no
|
@@ -1974,7 +1967,7 @@ static PBuiltinFunction doIt(Node inliningTarget, Object methodDef, int element,
|
1974 | 1967 | // CPy-style methods
|
1975 | 1968 | // TODO(fa) support static and class methods
|
1976 | 1969 | PExternalFunctionWrapper sig = PExternalFunctionWrapper.fromMethodFlags(flags);
|
1977 |
| - RootCallTarget callTarget = PExternalFunctionWrapper.getOrCreateCallTarget(sig, PythonLanguage.get(inliningTarget), methodName, true, CExtContext.isMethStatic(flags)); |
| 1970 | + RootCallTarget callTarget = PExternalFunctionWrapper.getOrCreateCallTarget(sig, PythonLanguage.get(inliningTarget), methodName, CExtContext.isMethStatic(flags)); |
1978 | 1971 | mlMethObj = ensureCallableNode.execute(inliningTarget, mlMethObj, sig);
|
1979 | 1972 | PKeyword[] kwDefaults = ExternalFunctionNodes.createKwDefaults(mlMethObj);
|
1980 | 1973 | PBuiltinFunction function = PFactory.createBuiltinFunction(language, methodName, null, PythonUtils.EMPTY_OBJECT_ARRAY, kwDefaults, flags, callTarget);
|
@@ -2055,165 +2048,6 @@ static void doOther(Object object) {
|
2055 | 2048 | }
|
2056 | 2049 | }
|
2057 | 2050 |
|
2058 |
| - @GenerateUncached |
2059 |
| - @GenerateInline |
2060 |
| - @GenerateCached(false) |
2061 |
| - @ImportStatic({CApiGuards.class, PGuards.class}) |
2062 |
| - public abstract static class CreateFunctionNode extends Node { |
2063 |
| - |
2064 |
| - private static final TruffleLogger LOGGER = CApiContext.getLogger(CreateFunctionNode.class); |
2065 |
| - |
2066 |
| - public static PythonObject executeUncached(TruffleString name, Object callable, int wrapper, Object type, Object flags) { |
2067 |
| - return CreateFunctionNodeGen.getUncached().execute(null, name, callable, wrapper, type, flags); |
2068 |
| - } |
2069 |
| - |
2070 |
| - public abstract PythonObject execute(Node inliningTarget, TruffleString name, Object callable, int wrapper, Object type, Object flags); |
2071 |
| - |
2072 |
| - /* |
2073 |
| - * Note: this is called from PyTruffleType_AddSlot, which is similar to CPython's |
2074 |
| - * add_operators: it creates corresponding Python magic methods from slots, but only from |
2075 |
| - * slots declared on given native type and not from inherited slots. So we should not see |
2076 |
| - * here pointers to native wrappers of managed slots. However, one could: 1) initialize a |
2077 |
| - * type multiple times, in which case we'd see here inherited slots, or 2) "steal" a slot |
2078 |
| - * from some existing type. This is why we resolve native closures and handle delegates of |
2079 |
| - * type TpSlotBuiltin/Managed in the managed case. |
2080 |
| - */ |
2081 |
| - |
2082 |
| - @Specialization(guards = "!isNoValue(type)") |
2083 |
| - @TruffleBoundary |
2084 |
| - static PythonObject doPythonCallable(TruffleString name, PythonNativeWrapper callable, int signature, Object type, int flags) { |
2085 |
| - Object managedCallable = callable.getDelegate(); |
2086 |
| - PythonContext context = PythonContext.get(null); |
2087 |
| - PythonLanguage language = context.getLanguage(); |
2088 |
| - boolean doArgAndResultConversion = false; |
2089 |
| - if (managedCallable instanceof TpSlotBuiltin<?> builtinSlot) { |
2090 |
| - var builtin = builtinSlot.createBuiltin(context, type, name, PExternalFunctionWrapper.fromValue(signature)); |
2091 |
| - if (builtin != null) { |
2092 |
| - return builtin; |
2093 |
| - } |
2094 |
| - assert callable instanceof TpSlotWrapper; |
2095 |
| - managedCallable = callable; |
2096 |
| - doArgAndResultConversion = true; |
2097 |
| - } else if (managedCallable instanceof TpSlotPython pythonSlot) { |
2098 |
| - // Someone has "stolen" existing python slot and stashed it into its slot field |
2099 |
| - // See TpSlots#fromNative where we need to solve the same issue |
2100 |
| - assert callable instanceof TpSlotWrapper; |
2101 |
| - TpSlotPython newPythonSlot = pythonSlot.forNewType(type); |
2102 |
| - if (newPythonSlot != pythonSlot) { |
2103 |
| - managedCallable = ((TpSlotWrapper) callable).cloneWith(newPythonSlot); |
2104 |
| - } else { |
2105 |
| - managedCallable = callable; |
2106 |
| - } |
2107 |
| - doArgAndResultConversion = true; |
2108 |
| - } |
2109 |
| - PythonObject function = PExternalFunctionWrapper.createWrapperFunction(name, managedCallable, type, flags, signature, language, doArgAndResultConversion); |
2110 |
| - return function != null ? function : castToPythonObject(managedCallable); |
2111 |
| - } |
2112 |
| - |
2113 |
| - @Specialization |
2114 |
| - @TruffleBoundary |
2115 |
| - static PythonObject doPyCFunctionWrapper(TruffleString name, PyCFunctionWrapper wrapper, int signature, Object type, int flags) { |
2116 |
| - Object delegate = wrapper.getDelegate(); |
2117 |
| - assert !(delegate instanceof PythonAbstractObject); |
2118 |
| - PythonContext context = PythonContext.get(null); |
2119 |
| - PythonLanguage language = context.getLanguage(); |
2120 |
| - return PExternalFunctionWrapper.createWrapperFunction(name, delegate, type, flags, signature, language, false); |
2121 |
| - } |
2122 |
| - |
2123 |
| - @Specialization(guards = {"!isNativeWrapper(callable)"}) |
2124 |
| - @TruffleBoundary |
2125 |
| - static PythonObject doNativeCallableWithWrapper(TruffleString name, Object callable, int signature, Object type, int flags, |
2126 |
| - @CachedLibrary(limit = "3") InteropLibrary lib) { |
2127 |
| - PythonContext context = PythonContext.get(null); |
2128 |
| - Object resolvedCallable = resolveClosurePointer(context, callable, lib); |
2129 |
| - assert !(resolvedCallable instanceof TpSlotNative); |
2130 |
| - if (resolvedCallable instanceof TpSlotBuiltin<?> builtinSlot) { |
2131 |
| - // CPython also creates a new wrapper descriptor even for slots that already |
2132 |
| - // have some wrapper descriptor. We can use the slot itself to create the right |
2133 |
| - // descriptor avoiding the delegation |
2134 |
| - var builtin = builtinSlot.createBuiltin(context, type, name, PExternalFunctionWrapper.fromValue(signature)); |
2135 |
| - if (builtin != null) { |
2136 |
| - return builtin; |
2137 |
| - } |
2138 |
| - // Otherwise fallback to wrapping the callable as if it was just opaque native call |
2139 |
| - resolvedCallable = null; |
2140 |
| - } else if (resolvedCallable instanceof TpSlotPython pythonSlot) { |
2141 |
| - // Someone has "stolen" existing python slot and stashed it into its slot field |
2142 |
| - // We will delegate to the native closure to be as compatible with whatever |
2143 |
| - // native call trickery the user intends to do |
2144 |
| - // Note: we do not have a simple way to write back the new slot if it changed, |
2145 |
| - // so TpSlots#fromNative will do this again and will write back the new slot to the |
2146 |
| - // PyTypeObject slot field |
2147 |
| - TpSlotPython newSlot = pythonSlot.forNewType(type); |
2148 |
| - try { |
2149 |
| - Object wrapper = context.getCApiContext().getClosureExecutable(lib.asPointer(callable)); |
2150 |
| - if (wrapper instanceof TpSlotWrapper slotWrapper) { |
2151 |
| - TpSlotWrapper newWrapper = newSlot != pythonSlot ? slotWrapper.cloneWith(newSlot) : slotWrapper; |
2152 |
| - newWrapper.toNative(SignatureLibrary.getUncached()); |
2153 |
| - callable = context.getCApiContext().getClosureForExecutable(newWrapper); |
2154 |
| - } |
2155 |
| - resolvedCallable = null; |
2156 |
| - } catch (UnsupportedMessageException ignore) { |
2157 |
| - // resolveClosurePointer gave non-null result, it must be a pointer |
2158 |
| - throw CompilerDirectives.shouldNotReachHere(); |
2159 |
| - } |
2160 |
| - } |
2161 |
| - boolean doArgAndResultConversion; |
2162 |
| - if (resolvedCallable != null) { |
2163 |
| - doArgAndResultConversion = false; |
2164 |
| - } else { |
2165 |
| - doArgAndResultConversion = true; |
2166 |
| - resolvedCallable = callable; |
2167 |
| - } |
2168 |
| - PythonLanguage language = context.getLanguage(); |
2169 |
| - PythonObject function = PExternalFunctionWrapper.createWrapperFunction(name, resolvedCallable, type, flags, signature, language, doArgAndResultConversion); |
2170 |
| - return function != null ? function : castToPythonObject(resolvedCallable); |
2171 |
| - } |
2172 |
| - |
2173 |
| - private static PythonObject castToPythonObject(Object callable) { |
2174 |
| - if (callable instanceof PythonObject pythonObject) { |
2175 |
| - return pythonObject; |
2176 |
| - } |
2177 |
| - transferToInterpreterAndInvalidate(); |
2178 |
| - throw shouldNotReachHere("Unexpected class of callable: " + callable.getClass()); |
2179 |
| - } |
2180 |
| - |
2181 |
| - /** |
2182 |
| - * If possible resolves the pointer to a {@link PBuiltinFunction} (creating a fresh builtin |
2183 |
| - * from builtin slots). |
2184 |
| - */ |
2185 |
| - @TruffleBoundary |
2186 |
| - public static Object resolveClosurePointerToBuiltinFun(PythonContext context, Object callable, InteropLibrary lib, |
2187 |
| - Object type, TruffleString name, PExternalFunctionWrapper signature) { |
2188 |
| - Object delegate = resolveClosurePointer(context, callable, lib); |
2189 |
| - if (delegate instanceof TpSlotBuiltin<?> builtinSlot) { |
2190 |
| - return builtinSlot.createBuiltin(context, type, name, signature); |
2191 |
| - } |
2192 |
| - return delegate; |
2193 |
| - } |
2194 |
| - |
2195 |
| - /** |
2196 |
| - * Returns either {@link PBuiltinFunction} or {@link TpSlotBuiltin}. |
2197 |
| - */ |
2198 |
| - @TruffleBoundary |
2199 |
| - public static Object resolveClosurePointer(PythonContext context, Object callable, InteropLibrary lib) { |
2200 |
| - if (lib.isPointer(callable)) { |
2201 |
| - long pointer; |
2202 |
| - try { |
2203 |
| - pointer = lib.asPointer(callable); |
2204 |
| - } catch (UnsupportedMessageException e) { |
2205 |
| - throw shouldNotReachHere(e); |
2206 |
| - } |
2207 |
| - Object delegate = context.getCApiContext().getClosureDelegate(pointer); |
2208 |
| - if (delegate != null) { |
2209 |
| - LOGGER.fine(() -> PythonUtils.formatJString("resolved closure pointer %d 0x%x to %s", pointer, pointer, delegate)); |
2210 |
| - return delegate; |
2211 |
| - } |
2212 |
| - } |
2213 |
| - return null; |
2214 |
| - } |
2215 |
| - } |
2216 |
| - |
2217 | 2051 | /**
|
2218 | 2052 | * Similar to CPython's macro {@code Py_VISIT}, this node will call the provided visit function
|
2219 | 2053 | * on the item if that item is a native object. This is because we assume that the traverse and
|
|
0 commit comments