19
19
#include " capi/types.h"
20
20
#include " core/types.h"
21
21
#include " runtime/objmodel.h"
22
+ #include " runtime/rewrite_args.h"
22
23
#include " runtime/types.h"
23
24
24
25
namespace pyston {
@@ -27,14 +28,24 @@ extern "C" {
27
28
BoxedClass* classobj_cls, *instance_cls;
28
29
}
29
30
30
- static Box* classLookup (BoxedClassobj* cls, BoxedString* attr) {
31
- Box* r = cls->getattr (attr);
31
+
32
+ static Box* classLookup (BoxedClassobj* cls, BoxedString* attr, GetattrRewriteArgs* rewrite_args = NULL ) {
33
+ if (rewrite_args)
34
+ assert (!rewrite_args->out_success );
35
+
36
+ Box* r = cls->getattr (attr, rewrite_args);
32
37
if (r)
33
38
return r;
34
39
40
+ if (rewrite_args) {
41
+ // abort rewriting because we currenly don't guard the particular 'bases' hierarchy
42
+ rewrite_args->out_success = false ;
43
+ rewrite_args = NULL ;
44
+ }
45
+
35
46
for (auto b : *cls->bases ) {
36
47
RELEASE_ASSERT (b->cls == classobj_cls, " " );
37
- Box* r = classLookup (static_cast <BoxedClassobj*>(b), attr);
48
+ Box* r = classLookup (static_cast <BoxedClassobj*>(b), attr, rewrite_args );
38
49
if (r)
39
50
return r;
40
51
}
@@ -253,38 +264,76 @@ Box* classobjStr(Box* _obj) {
253
264
254
265
255
266
// Analogous to CPython's instance_getattr2
256
- static Box* instanceGetattributeSimple (BoxedInstance* inst, BoxedString* attr_str) {
257
- Box* r = inst->getattr (attr_str);
267
+ static Box* instanceGetattributeSimple (BoxedInstance* inst, BoxedString* attr_str,
268
+ GetattrRewriteArgs* rewriter_args = NULL ) {
269
+ Box* r = inst->getattr (attr_str, rewriter_args);
258
270
if (r)
259
271
return r;
260
272
261
- r = classLookup (inst->inst_cls , attr_str);
273
+ RewriterVar* r_inst = NULL ;
274
+ RewriterVar* r_inst_cls = NULL ;
275
+ if (rewriter_args) {
276
+ if (!rewriter_args->out_success )
277
+ rewriter_args = NULL ;
278
+ else {
279
+ rewriter_args->out_success = false ;
280
+ r_inst = rewriter_args->obj ;
281
+ r_inst_cls = r_inst->getAttr (offsetof (BoxedInstance, inst_cls));
282
+ }
283
+ }
284
+ GetattrRewriteArgs grewriter_inst_args (rewriter_args ? rewriter_args->rewriter : NULL , r_inst_cls,
285
+ rewriter_args ? rewriter_args->rewriter ->getReturnDestination ()
286
+ : Location ());
287
+ r = classLookup (inst->inst_cls , attr_str, rewriter_args ? &grewriter_inst_args : NULL );
288
+ if (!grewriter_inst_args.out_success )
289
+ rewriter_args = NULL ;
290
+
262
291
if (r) {
263
- return processDescriptor (r, inst, inst->inst_cls );
292
+ Box* rtn = processDescriptor (r, inst, inst->inst_cls );
293
+ if (rewriter_args) {
294
+ RewriterVar* r_rtn = rewriter_args->rewriter ->call (true , (void *)processDescriptor,
295
+ grewriter_inst_args.out_rtn , r_inst, r_inst_cls);
296
+ rewriter_args->out_rtn = r_rtn;
297
+ rewriter_args->out_success = true ;
298
+ rewriter_args->out_return_convention = GetattrRewriteArgs::VALID_RETURN;
299
+ }
300
+ return rtn;
264
301
}
265
302
266
303
return NULL ;
267
304
}
268
305
269
- static Box* instanceGetattributeWithFallback (BoxedInstance* inst, BoxedString* attr_str) {
270
- Box* attr_obj = instanceGetattributeSimple (inst, attr_str);
306
+ static Box* instanceGetattributeWithFallback (BoxedInstance* inst, BoxedString* attr_str,
307
+ GetattrRewriteArgs* rewriter_args = NULL ) {
308
+ Box* attr_obj = instanceGetattributeSimple (inst, attr_str, rewriter_args);
271
309
272
310
if (attr_obj) {
273
311
return attr_obj;
274
312
}
275
313
314
+ if (rewriter_args) {
315
+ if (!rewriter_args->out_success )
316
+ rewriter_args = NULL ;
317
+ else
318
+ rewriter_args->out_success = false ;
319
+
320
+ // abort rewriting for now
321
+ rewriter_args = NULL ;
322
+ }
323
+
276
324
static BoxedString* getattr_str = internStringImmortal (" __getattr__" );
277
325
Box* getattr = classLookup (inst->inst_cls , getattr_str);
278
326
279
327
if (getattr) {
280
328
getattr = processDescriptor (getattr, inst, inst->inst_cls );
281
- return runtimeCall (getattr, ArgPassSpec (1 ), attr_str, NULL , NULL , NULL , NULL );
329
+ return runtimeCallInternal<CXX> (getattr, NULL , ArgPassSpec (1 ), attr_str, NULL , NULL , NULL , NULL );
282
330
}
283
331
284
332
return NULL ;
285
333
}
286
334
287
- static Box* _instanceGetattribute (Box* _inst, BoxedString* attr_str, bool raise_on_missing) {
335
+ static Box* _instanceGetattribute (Box* _inst, BoxedString* attr_str, bool raise_on_missing,
336
+ GetattrRewriteArgs* rewriter_args = NULL ) {
288
337
RELEASE_ASSERT (_inst->cls == instance_cls, " " );
289
338
BoxedInstance* inst = static_cast <BoxedInstance*>(_inst);
290
339
@@ -297,7 +346,7 @@ static Box* _instanceGetattribute(Box* _inst, BoxedString* attr_str, bool raise_
297
346
return inst->inst_cls ;
298
347
}
299
348
300
- Box* attr = instanceGetattributeWithFallback (inst, attr_str);
349
+ Box* attr = instanceGetattributeWithFallback (inst, attr_str, rewriter_args );
301
350
if (attr) {
302
351
return attr;
303
352
} else if (!raise_on_missing) {
@@ -308,25 +357,34 @@ static Box* _instanceGetattribute(Box* _inst, BoxedString* attr_str, bool raise_
308
357
}
309
358
}
310
359
311
- Box* instanceGetattribute (Box* _inst, Box* _attr) {
312
- STAT_TIMER (t0, " us_timer_instance_getattribute" , 0 );
360
+ // Analogous to CPython's instance_getattr
361
+ Box* instance_getattro (Box* cls, Box* attr) noexcept {
362
+ return instanceGetattroInternal<CAPI>(cls, attr, NULL );
363
+ }
364
+
365
+ template <ExceptionStyle S>
366
+ Box* instanceGetattroInternal (Box* cls, Box* _attr, GetattrRewriteArgs* rewrite_args) noexcept (S == CAPI) {
367
+ STAT_TIMER (t0, " us_timer_instance_getattro" , 0 );
313
368
314
369
RELEASE_ASSERT (_attr->cls == str_cls, " " );
315
370
BoxedString* attr = static_cast <BoxedString*>(_attr);
316
- return _instanceGetattribute (_inst, attr, true );
317
- }
318
371
319
-
320
- // Analogous to CPython's instance_getattr
321
- static Box* instance_getattro (Box* cls, Box* attr) noexcept {
322
- try {
323
- return instanceGetattribute (cls, attr);
324
- } catch (ExcInfo e) {
325
- setCAPIException (e);
326
- return NULL ;
372
+ if (S == CAPI) {
373
+ try {
374
+ return _instanceGetattribute (cls, attr, true , rewrite_args);
375
+ } catch (ExcInfo e) {
376
+ setCAPIException (e);
377
+ return NULL ;
378
+ }
379
+ } else {
380
+ return _instanceGetattribute (cls, attr, true , rewrite_args);
327
381
}
328
382
}
329
383
384
+ // Force instantiation of the template
385
+ template Box* instanceGetattroInternal<CAPI>(Box*, Box*, GetattrRewriteArgs*) noexcept ;
386
+ template Box* instanceGetattroInternal<CXX>(Box*, Box*, GetattrRewriteArgs*);
387
+
330
388
Box* instanceSetattr (Box* _inst, Box* _attr, Box* value) {
331
389
RELEASE_ASSERT (_inst->cls == instance_cls, " " );
332
390
BoxedInstance* inst = static_cast <BoxedInstance*>(_inst);
@@ -1458,7 +1516,7 @@ void setupClassobj() {
1458
1516
1459
1517
1460
1518
instance_cls->giveAttr (" __getattribute__" ,
1461
- new BoxedFunction (boxRTFunction ((void *)instanceGetattribute , UNKNOWN, 2 )));
1519
+ new BoxedFunction (boxRTFunction ((void *)instanceGetattroInternal<CXX> , UNKNOWN, 2 )));
1462
1520
instance_cls->giveAttr (" __setattr__" , new BoxedFunction (boxRTFunction ((void *)instanceSetattr, UNKNOWN, 3 )));
1463
1521
instance_cls->giveAttr (" __delattr__" , new BoxedFunction (boxRTFunction ((void *)instanceDelattr, UNKNOWN, 2 )));
1464
1522
instance_cls->giveAttr (" __str__" , new BoxedFunction (boxRTFunction ((void *)instanceStr, UNKNOWN, 1 )));
0 commit comments