259259import com .oracle .truffle .api .CompilerDirectives .TruffleBoundary ;
260260import com .oracle .truffle .api .RootCallTarget ;
261261import com .oracle .truffle .api .TruffleLogger ;
262- import com .oracle .truffle .api .dsl .Bind ;
263262import com .oracle .truffle .api .dsl .Cached ;
264263import com .oracle .truffle .api .dsl .Cached .Exclusive ;
265264import com .oracle .truffle .api .dsl .Cached .Shared ;
@@ -298,6 +297,13 @@ public final class PythonCextBuiltins extends PythonBuiltins {
298297
299298 public static final String NATIVE_NULL = "native_null" ;
300299
300+ /*
301+ * Native pointer to the PyMethodDef struct for functions created in C. We need to keep it
302+ * because the C program may expect to get its pointer back when accessing m_ml member of
303+ * methods.
304+ */
305+ public static final HiddenKey METHOD_DEF_PTR = new HiddenKey ("method_def_ptr" );
306+
301307 private PythonObject errorHandler ;
302308
303309 @ Override
@@ -2252,11 +2258,11 @@ static Object doGeneric(Object object) {
22522258 @ ImportStatic (CExtContext .class )
22532259 abstract static class NewClassMethodNode extends Node {
22542260
2255- abstract Object execute (String name , Object methObj , Object flags , Object wrapper , Object type , Object doc ,
2261+ abstract Object execute (Object methodDefPtr , String name , Object methObj , Object flags , Object wrapper , Object type , Object doc ,
22562262 PythonObjectFactory factory );
22572263
22582264 @ Specialization (guards = "isClassOrStaticMethod(flags)" )
2259- static Object classOrStatic (String name , Object methObj , int flags , int wrapper , Object type ,
2265+ static Object classOrStatic (Object methodDefPtr , String name , Object methObj , int flags , int wrapper , Object type ,
22602266 Object doc , PythonObjectFactory factory ,
22612267 @ CachedLibrary (limit = "1" ) DynamicObjectLibrary dylib ,
22622268 @ Shared ("cf" ) @ Cached CreateFunctionNode createFunctionNode ,
@@ -2270,66 +2276,76 @@ static Object classOrStatic(String name, Object methObj, int flags, int wrapper,
22702276 }
22712277 dylib .put (function , __NAME__ , name );
22722278 dylib .put (function , __DOC__ , cstrPtr .execute (doc ));
2279+ dylib .put (function , METHOD_DEF_PTR , methodDefPtr );
22732280 return function ;
22742281 }
22752282
22762283 @ Specialization (guards = "!isClassOrStaticMethod(flags)" )
2277- static Object doNativeCallable (String name , Object methObj , int flags , int wrapper , Object type ,
2284+ static Object doNativeCallable (Object methodDefPtr , String name , Object methObj , int flags , int wrapper , Object type ,
22782285 Object doc , PythonObjectFactory factory ,
22792286 @ Cached PyObjectSetAttrNode setattr ,
2287+ @ Cached WriteAttributeToObjectNode write ,
22802288 @ Shared ("cf" ) @ Cached CreateFunctionNode createFunctionNode ,
22812289 @ Shared ("cstr" ) @ Cached CharPtrToJavaObjectNode cstrPtr ) {
22822290 Object func = createFunctionNode .execute (name , methObj , wrapper , type , flags , factory );
22832291 setattr .execute (func , __NAME__ , name );
22842292 setattr .execute (func , __DOC__ , cstrPtr .execute (doc ));
2293+ write .execute (func , METHOD_DEF_PTR , methodDefPtr );
22852294 return func ;
22862295 }
22872296 }
22882297
22892298 // directly called without landing function
2290- @ Builtin (name = "AddFunction " , minNumOfPositionalArgs = 6 , parameterNames = {"primary" , "tpDict" , "name" , "cfunc" , "flags" , "wrapper" , "doc" })
2299+ @ Builtin (name = "AddFunctionToType " , parameterNames = {"method_def_ptr" , "primary" , "tpDict" , "name" , "cfunc" , "flags" , "wrapper" , "doc" })
22912300 @ ArgumentClinic (name = "name" , conversion = ClinicConversion .String )
22922301 @ ArgumentClinic (name = "flags" , conversion = ClinicConversion .Int )
22932302 @ ArgumentClinic (name = "wrapper" , conversion = ClinicConversion .Int )
22942303 @ GenerateNodeFactory
2295- abstract static class AddFunctionNode extends PythonClinicBuiltinNode {
2304+ abstract static class AddFunctionToTypeNode extends PythonClinicBuiltinNode {
22962305 @ Override
22972306 protected ArgumentClinicProvider getArgumentClinic () {
2298- return PythonCextBuiltinsClinicProviders .AddFunctionNodeClinicProviderGen .INSTANCE ;
2307+ return PythonCextBuiltinsClinicProviders .AddFunctionToTypeNodeClinicProviderGen .INSTANCE ;
22992308 }
23002309
2301- @ Specialization (guards = "isPythonModule(owner)" )
2302- Object moduleFunction (VirtualFrame frame , @ SuppressWarnings ("unused" ) Object primary ,
2303- @ SuppressWarnings ("unused" ) Object tpDict ,
2304- String name , Object cfunc , int flags , int wrapper , Object doc ,
2305- @ SuppressWarnings ("unused" ) @ Cached AsPythonObjectNode asPythonObjectNode ,
2306- @ Bind ("getOwner(asPythonObjectNode, primary)" ) Object owner ,
2307- @ Cached ObjectBuiltins .SetattrNode setattrNode ,
2308- @ CachedLibrary (limit = "1" ) DynamicObjectLibrary dylib ,
2309- @ Cached CFunctionNewExMethodNode cFunctionNewExMethodNode ) {
2310- PythonModule mod = (PythonModule ) owner ;
2311- Object modName = dylib .getOrDefault (mod .getStorage (), __NAME__ , null );
2312- assert modName != null : "module name is missing!" ;
2313- Object func = cFunctionNewExMethodNode .execute (name , cfunc , flags , wrapper , mod , modName , doc , factory ());
2314- setattrNode .execute (frame , mod , name , func );
2315- return 0 ;
2316- }
2317-
2318- @ Specialization (guards = "!isPythonModule(owner)" )
2319- Object classMethod (VirtualFrame frame , @ SuppressWarnings ("unused" ) Object primary ,
2310+ @ Specialization
2311+ Object classMethod (VirtualFrame frame , Object methodDefPtr , Object primary ,
23202312 Object tpDict , String name , Object cfunc , int flags , int wrapper , Object doc ,
23212313 @ Cached AsPythonObjectNode asPythonObjectNode ,
2322- @ Bind ("getOwner(asPythonObjectNode, primary)" ) Object owner ,
23232314 @ Cached NewClassMethodNode newClassMethodNode ,
23242315 @ Cached DictBuiltins .SetItemNode setItemNode ) {
2325- Object func = newClassMethodNode .execute (name , cfunc , flags , wrapper , owner , doc , factory ());
2316+ Object type = asPythonObjectNode .execute (primary );
2317+ Object func = newClassMethodNode .execute (methodDefPtr , name , cfunc , flags , wrapper , type , doc , factory ());
23262318 Object dict = asPythonObjectNode .execute (tpDict );
23272319 setItemNode .execute (frame , dict , name , func );
23282320 return 0 ;
23292321 }
2322+ }
2323+
2324+ // directly called without landing function
2325+ @ Builtin (name = "AddFunctionToModule" , parameterNames = {"method_def_ptr" , "primary" , "name" , "cfunc" , "flags" , "wrapper" , "doc" })
2326+ @ ArgumentClinic (name = "name" , conversion = ClinicConversion .String )
2327+ @ ArgumentClinic (name = "flags" , conversion = ClinicConversion .Int )
2328+ @ ArgumentClinic (name = "wrapper" , conversion = ClinicConversion .Int )
2329+ @ GenerateNodeFactory
2330+ abstract static class AddFunctionToModuleNode extends PythonClinicBuiltinNode {
2331+ @ Override
2332+ protected ArgumentClinicProvider getArgumentClinic () {
2333+ return PythonCextBuiltinsClinicProviders .AddFunctionToModuleNodeClinicProviderGen .INSTANCE ;
2334+ }
23302335
2331- static Object getOwner (AsPythonObjectNode asPythonObjectNode , Object primary ) {
2332- return asPythonObjectNode .execute (primary );
2336+ @ Specialization
2337+ Object moduleFunction (VirtualFrame frame , Object methodDefPtr , Object primary ,
2338+ String name , Object cfunc , int flags , int wrapper , Object doc ,
2339+ @ Cached AsPythonObjectNode asPythonObjectNode ,
2340+ @ Cached ObjectBuiltins .SetattrNode setattrNode ,
2341+ @ CachedLibrary (limit = "1" ) DynamicObjectLibrary dylib ,
2342+ @ Cached CFunctionNewExMethodNode cFunctionNewExMethodNode ) {
2343+ PythonModule mod = (PythonModule ) asPythonObjectNode .execute (primary );
2344+ Object modName = dylib .getOrDefault (mod .getStorage (), __NAME__ , null );
2345+ assert modName != null : "module name is missing!" ;
2346+ Object func = cFunctionNewExMethodNode .execute (methodDefPtr , name , cfunc , flags , wrapper , mod , modName , doc , factory ());
2347+ setattrNode .execute (frame , mod , name , func );
2348+ return 0 ;
23332349 }
23342350 }
23352351
@@ -2400,11 +2416,11 @@ private static void addSlot(Object clsPtr, Object tpDictPtr, Object namePtr, Obj
24002416
24012417 abstract static class CFunctionNewExMethodNode extends Node {
24022418
2403- abstract Object execute (String name , Object methObj , Object flags , Object wrapper , Object self , Object module , Object doc ,
2419+ abstract Object execute (Object methodDefPtr , String name , Object methObj , Object flags , Object wrapper , Object self , Object module , Object doc ,
24042420 PythonObjectFactory factory );
24052421
24062422 @ Specialization
2407- static Object doNativeCallable (String name , Object methObj , Object flags , Object wrapper , Object self , Object module , Object doc ,
2423+ static Object doNativeCallable (Object methodDefPtr , String name , Object methObj , Object flags , Object wrapper , Object self , Object module , Object doc ,
24082424 PythonObjectFactory factory ,
24092425 @ SuppressWarnings ("unused" ) @ Cached AsPythonObjectNode asPythonObjectNode ,
24102426 @ Cached CreateFunctionNode createFunctionNode ,
@@ -2418,11 +2434,12 @@ static Object doNativeCallable(String name, Object methObj, Object flags, Object
24182434 dylib .put (func .getStorage (), __DOC__ , strDoc );
24192435 PBuiltinMethod method = factory .createBuiltinMethod (self , func );
24202436 dylib .put (method .getStorage (), __MODULE__ , module );
2437+ dylib .put (method .getStorage (), METHOD_DEF_PTR , methodDefPtr );
24212438 return method ;
24222439 }
24232440 }
24242441
2425- @ Builtin (name = "PyCFunction_NewEx" , minNumOfPositionalArgs = 7 , parameterNames = {"name" , "cfunc" , "flags" , "wrapper" , "self" , "module" , "doc" })
2442+ @ Builtin (name = "PyCFunction_NewEx" , minNumOfPositionalArgs = 8 , parameterNames = {"method_def_ptr" , "name" , "cfunc" , "flags" , "wrapper" , "self" , "module" , "doc" })
24262443 @ ArgumentClinic (name = "name" , conversion = ArgumentClinic .ClinicConversion .String )
24272444 @ GenerateNodeFactory
24282445 abstract static class PyCFunctionNewExMethod extends PythonClinicBuiltinNode {
@@ -2432,13 +2449,13 @@ protected ArgumentClinicProvider getArgumentClinic() {
24322449 }
24332450
24342451 @ Specialization
2435- Object doNativeCallable (String name , Object methObj , int flags , int wrapper , Object selfO , Object moduleO , Object doc ,
2452+ Object doNativeCallable (Object methodDefPtr , String name , Object methObj , int flags , int wrapper , Object selfO , Object moduleO , Object doc ,
24362453 @ Cached AsPythonObjectNode asPythonObjectNode ,
24372454 @ Cached CFunctionNewExMethodNode cFunctionNewExMethodNode ,
24382455 @ Cached ToNewRefNode newRefNode ) {
24392456 Object self = asPythonObjectNode .execute (selfO );
24402457 Object module = asPythonObjectNode .execute (moduleO );
2441- Object func = cFunctionNewExMethodNode .execute (name , methObj , flags , wrapper , self , module , doc , factory ());
2458+ Object func = cFunctionNewExMethodNode .execute (methodDefPtr , name , methObj , flags , wrapper , self , module , doc , factory ());
24422459 return newRefNode .execute (func );
24432460 }
24442461 }
0 commit comments