259
259
import com .oracle .truffle .api .CompilerDirectives .TruffleBoundary ;
260
260
import com .oracle .truffle .api .RootCallTarget ;
261
261
import com .oracle .truffle .api .TruffleLogger ;
262
- import com .oracle .truffle .api .dsl .Bind ;
263
262
import com .oracle .truffle .api .dsl .Cached ;
264
263
import com .oracle .truffle .api .dsl .Cached .Exclusive ;
265
264
import com .oracle .truffle .api .dsl .Cached .Shared ;
@@ -298,6 +297,13 @@ public final class PythonCextBuiltins extends PythonBuiltins {
298
297
299
298
public static final String NATIVE_NULL = "native_null" ;
300
299
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
+
301
307
private PythonObject errorHandler ;
302
308
303
309
@ Override
@@ -2252,11 +2258,11 @@ static Object doGeneric(Object object) {
2252
2258
@ ImportStatic (CExtContext .class )
2253
2259
abstract static class NewClassMethodNode extends Node {
2254
2260
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 ,
2256
2262
PythonObjectFactory factory );
2257
2263
2258
2264
@ 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 ,
2260
2266
Object doc , PythonObjectFactory factory ,
2261
2267
@ CachedLibrary (limit = "1" ) DynamicObjectLibrary dylib ,
2262
2268
@ Shared ("cf" ) @ Cached CreateFunctionNode createFunctionNode ,
@@ -2270,66 +2276,76 @@ static Object classOrStatic(String name, Object methObj, int flags, int wrapper,
2270
2276
}
2271
2277
dylib .put (function , __NAME__ , name );
2272
2278
dylib .put (function , __DOC__ , cstrPtr .execute (doc ));
2279
+ dylib .put (function , METHOD_DEF_PTR , methodDefPtr );
2273
2280
return function ;
2274
2281
}
2275
2282
2276
2283
@ 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 ,
2278
2285
Object doc , PythonObjectFactory factory ,
2279
2286
@ Cached PyObjectSetAttrNode setattr ,
2287
+ @ Cached WriteAttributeToObjectNode write ,
2280
2288
@ Shared ("cf" ) @ Cached CreateFunctionNode createFunctionNode ,
2281
2289
@ Shared ("cstr" ) @ Cached CharPtrToJavaObjectNode cstrPtr ) {
2282
2290
Object func = createFunctionNode .execute (name , methObj , wrapper , type , flags , factory );
2283
2291
setattr .execute (func , __NAME__ , name );
2284
2292
setattr .execute (func , __DOC__ , cstrPtr .execute (doc ));
2293
+ write .execute (func , METHOD_DEF_PTR , methodDefPtr );
2285
2294
return func ;
2286
2295
}
2287
2296
}
2288
2297
2289
2298
// 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" })
2291
2300
@ ArgumentClinic (name = "name" , conversion = ClinicConversion .String )
2292
2301
@ ArgumentClinic (name = "flags" , conversion = ClinicConversion .Int )
2293
2302
@ ArgumentClinic (name = "wrapper" , conversion = ClinicConversion .Int )
2294
2303
@ GenerateNodeFactory
2295
- abstract static class AddFunctionNode extends PythonClinicBuiltinNode {
2304
+ abstract static class AddFunctionToTypeNode extends PythonClinicBuiltinNode {
2296
2305
@ Override
2297
2306
protected ArgumentClinicProvider getArgumentClinic () {
2298
- return PythonCextBuiltinsClinicProviders .AddFunctionNodeClinicProviderGen .INSTANCE ;
2307
+ return PythonCextBuiltinsClinicProviders .AddFunctionToTypeNodeClinicProviderGen .INSTANCE ;
2299
2308
}
2300
2309
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 ,
2320
2312
Object tpDict , String name , Object cfunc , int flags , int wrapper , Object doc ,
2321
2313
@ Cached AsPythonObjectNode asPythonObjectNode ,
2322
- @ Bind ("getOwner(asPythonObjectNode, primary)" ) Object owner ,
2323
2314
@ Cached NewClassMethodNode newClassMethodNode ,
2324
2315
@ 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 ());
2326
2318
Object dict = asPythonObjectNode .execute (tpDict );
2327
2319
setItemNode .execute (frame , dict , name , func );
2328
2320
return 0 ;
2329
2321
}
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
+ }
2330
2335
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 ;
2333
2349
}
2334
2350
}
2335
2351
@@ -2400,11 +2416,11 @@ private static void addSlot(Object clsPtr, Object tpDictPtr, Object namePtr, Obj
2400
2416
2401
2417
abstract static class CFunctionNewExMethodNode extends Node {
2402
2418
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 ,
2404
2420
PythonObjectFactory factory );
2405
2421
2406
2422
@ 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 ,
2408
2424
PythonObjectFactory factory ,
2409
2425
@ SuppressWarnings ("unused" ) @ Cached AsPythonObjectNode asPythonObjectNode ,
2410
2426
@ Cached CreateFunctionNode createFunctionNode ,
@@ -2418,11 +2434,12 @@ static Object doNativeCallable(String name, Object methObj, Object flags, Object
2418
2434
dylib .put (func .getStorage (), __DOC__ , strDoc );
2419
2435
PBuiltinMethod method = factory .createBuiltinMethod (self , func );
2420
2436
dylib .put (method .getStorage (), __MODULE__ , module );
2437
+ dylib .put (method .getStorage (), METHOD_DEF_PTR , methodDefPtr );
2421
2438
return method ;
2422
2439
}
2423
2440
}
2424
2441
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" })
2426
2443
@ ArgumentClinic (name = "name" , conversion = ArgumentClinic .ClinicConversion .String )
2427
2444
@ GenerateNodeFactory
2428
2445
abstract static class PyCFunctionNewExMethod extends PythonClinicBuiltinNode {
@@ -2432,13 +2449,13 @@ protected ArgumentClinicProvider getArgumentClinic() {
2432
2449
}
2433
2450
2434
2451
@ 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 ,
2436
2453
@ Cached AsPythonObjectNode asPythonObjectNode ,
2437
2454
@ Cached CFunctionNewExMethodNode cFunctionNewExMethodNode ,
2438
2455
@ Cached ToNewRefNode newRefNode ) {
2439
2456
Object self = asPythonObjectNode .execute (selfO );
2440
2457
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 ());
2442
2459
return newRefNode .execute (func );
2443
2460
}
2444
2461
}
0 commit comments