@@ -432,7 +432,6 @@ struct interp_call {
432
432
_PyXIData_t * func ;
433
433
_PyXIData_t * args ;
434
434
_PyXIData_t * kwargs ;
435
- _PyXIData_t * result ;// dynamically allocated
436
435
struct {
437
436
_PyXIData_t func ;
438
437
_PyXIData_t args ;
@@ -454,64 +453,6 @@ _interp_call_clear(struct interp_call *call)
454
453
if (temp .kwargs != NULL ) {
455
454
_PyXIData_Clear (NULL ,temp .kwargs );
456
455
}
457
- if (temp .result != NULL ) {
458
- (void )_PyXIData_ReleaseAndRawFree (temp .result );
459
- }
460
- }
461
-
462
- static int
463
- _interp_call_init_result (struct interp_call * call )
464
- {
465
- call -> result = _PyXIData_New ();
466
- return (call -> result == NULL ) ?-1 :0 ;
467
- }
468
-
469
- static void
470
- _interp_call_clear_result (struct interp_call * call )
471
- {
472
- _PyXIData_t * xidata = call -> result ;
473
- if (xidata == NULL ) {
474
- return ;
475
- }
476
- call -> result = NULL ;
477
- _PyXIData_Clear (NULL ,xidata );
478
- _PyXIData_Release (xidata );
479
- PyMem_RawFree (xidata );
480
- }
481
-
482
- static int
483
- _interp_call_clear_result_immediately (PyThreadState * tstate ,
484
- struct interp_call * call ,
485
- PyInterpreterState * interp )
486
- {
487
- _PyXIData_t * xidata = call -> result ;
488
- if (xidata == NULL ) {
489
- return 0 ;
490
- }
491
- assert (tstate == _PyThreadState_GET ());
492
- assert (interp != NULL );
493
- assert (interp == _PyInterpreterState_LookUpID (_PyXIData_INTERPID (xidata )));
494
- if (tstate -> interp == interp ) {
495
- // There's no need to switch interpreters.
496
- _interp_call_clear_result (call );
497
- return 0 ;
498
- }
499
-
500
- // It's from a different interpreter.
501
- PyThreadState * temp_tstate =
502
- _PyThreadState_NewBound (interp ,_PyThreadState_WHENCE_EXEC );
503
- if (temp_tstate == NULL ) {
504
- return -1 ;
505
- }
506
- PyThreadState * save_tstate = PyThreadState_Swap (temp_tstate );
507
- assert (save_tstate == tstate );
508
-
509
- _interp_call_clear_result (call );
510
-
511
- PyThreadState_Clear (temp_tstate );
512
- (void )PyThreadState_Swap (save_tstate );
513
- PyThreadState_Delete (temp_tstate );
514
- return 0 ;
515
456
}
516
457
517
458
static int
@@ -522,7 +463,6 @@ _interp_call_pack(PyThreadState *tstate, struct interp_call *call,
522
463
assert (call -> func == NULL );
523
464
assert (call -> args == NULL );
524
465
assert (call -> kwargs == NULL );
525
- assert (call -> result == NULL );
526
466
// Handle the func.
527
467
if (!PyCallable_Check (func )) {
528
468
_PyErr_Format (tstate ,PyExc_TypeError ,
@@ -571,34 +511,11 @@ _interp_call_pack(PyThreadState *tstate, struct interp_call *call,
571
511
return 0 ;
572
512
}
573
513
574
- static PyObject *
575
- _interp_call_pop_result (PyThreadState * tstate ,struct interp_call * call ,
576
- PyInterpreterState * interp )
577
- {
578
- assert (tstate == _PyThreadState_GET ());
579
- assert (!_PyErr_Occurred (tstate ));
580
- assert (call -> result != NULL );
581
- PyObject * res = _PyXIData_NewObject (call -> result );
582
- PyObject * exc = _PyErr_GetRaisedException (tstate );
583
-
584
- if (_interp_call_clear_result_immediately (tstate ,call ,interp )< 0 ) {
585
- // We couldn't do it immediately, so we fall back to adding
586
- // a pending call. If this fails then there are other,
587
- // bigger problems.
588
- (int )_PyXIData_ReleaseAndRawFree (call -> result );
589
- call -> result = NULL ;
590
- }
591
-
592
- _PyErr_SetRaisedException (tstate ,exc );
593
- return res ;
594
- }
595
-
596
514
static int
597
- _make_call (struct interp_call * call )
515
+ _make_call (struct interp_call * call , PyObject * * p_result )
598
516
{
599
517
assert (call != NULL && call -> func != NULL );
600
518
int res = -1 ;
601
- PyThreadState * tstate = _PyThreadState_GET ();
602
519
PyObject * args = NULL ;
603
520
PyObject * kwargs = NULL ;
604
521
PyObject * resobj = NULL ;
@@ -629,22 +546,12 @@ _make_call(struct interp_call *call)
629
546
}
630
547
assert (PyDict_Check (kwargs ));
631
548
}
632
- // Prepare call->result.
633
- if (_interp_call_init_result (call )< 0 ) {
634
- gotofinally ;
635
- }
636
549
// Make the call.
637
550
resobj = PyObject_Call (func ,args ,kwargs );
638
551
if (resobj == NULL ) {
639
- _interp_call_clear_result (call );
640
- gotofinally ;
641
- }
642
- // Pack the result.
643
- xidata_fallback_t fallback = _PyXIDATA_FULL_FALLBACK ;
644
- if (_PyObject_GetXIData (tstate ,resobj ,fallback ,call -> result )< 0 ) {
645
- _interp_call_clear_result (call );
646
552
gotofinally ;
647
553
}
554
+ * p_result = resobj ;
648
555
res = 0 ;
649
556
650
557
finally :
@@ -671,19 +578,32 @@ _run_script(_PyXIData_t *script, PyObject *ns)
671
578
return 0 ;
672
579
}
673
580
581
+ struct run_result {
582
+ PyObject * result ;
583
+ PyObject * excinfo ;
584
+ };
585
+
586
+ static void
587
+ _run_result_clear (struct run_result * runres )
588
+ {
589
+ Py_CLEAR (runres -> result );
590
+ Py_CLEAR (runres -> excinfo );
591
+ }
592
+
674
593
static int
675
594
_run_in_interpreter (PyThreadState * tstate ,PyInterpreterState * interp ,
676
595
_PyXIData_t * script ,struct interp_call * call ,
677
- PyObject * shareables ,_PyXI_session_result * result )
596
+ PyObject * shareables ,struct run_result * runres )
678
597
{
679
598
assert (!_PyErr_Occurred (tstate ));
680
599
_PyXI_session * session = _PyXI_NewSession ();
681
600
if (session == NULL ) {
682
601
return -1 ;
683
602
}
603
+ _PyXI_session_result result = {0 };
684
604
685
605
// Prep and switch interpreters.
686
- if (_PyXI_Enter (session ,interp ,shareables ,result )< 0 ) {
606
+ if (_PyXI_Enter (session ,interp ,shareables ,& result )< 0 ) {
687
607
// If an error occured at this step, it means that interp
688
608
// was not prepared and switched.
689
609
_PyXI_FreeSession (session );
@@ -692,7 +612,6 @@ _run_in_interpreter(PyThreadState *tstate, PyInterpreterState *interp,
692
612
693
613
int res = -1 ;
694
614
if (script != NULL ) {
695
- // Run the script.
696
615
assert (call == NULL );
697
616
PyObject * mainns = _PyXI_GetMainNamespace (session );
698
617
if (mainns == NULL ) {
@@ -702,13 +621,31 @@ _run_in_interpreter(PyThreadState *tstate, PyInterpreterState *interp,
702
621
}
703
622
else {
704
623
assert (call != NULL );
705
- res = _make_call (call );
624
+ PyObject * resobj ;
625
+ res = _make_call (call ,& resobj );
626
+ if (res == 0 ) {
627
+ (void )_PyXI_Preserve (session ,"resobj" ,resobj );
628
+ Py_DECREF (resobj );
629
+ }
706
630
}
707
631
708
632
finally :
709
633
// Clean up and switch back.
710
- (void )_PyXI_Exit (session ,result );
634
+ (void )_PyXI_Exit (session ,& result );
711
635
_PyXI_FreeSession (session );
636
+ if (res < 0 ) {
637
+ runres -> excinfo = result .excinfo ;
638
+ }
639
+ else if (result .excinfo != NULL ) {
640
+ runres -> excinfo = result .excinfo ;
641
+ res = -1 ;
642
+ }
643
+ else {
644
+ runres -> result = _PyXI_GetPreserved (& result ,"resobj" );
645
+ if (_PyErr_Occurred (tstate )) {
646
+ res = -1 ;
647
+ }
648
+ }
712
649
return res ;
713
650
}
714
651
@@ -1137,13 +1074,13 @@ interp_exec(PyObject *self, PyObject *args, PyObject *kwds)
1137
1074
return NULL ;
1138
1075
}
1139
1076
1140
- _PyXI_session_result result = {0 };
1077
+ struct run_result runres = {0 };
1141
1078
int res = _run_in_interpreter (
1142
- tstate ,interp ,& xidata ,NULL ,shared ,& result );
1079
+ tstate ,interp ,& xidata ,NULL ,shared ,& runres );
1143
1080
_PyXIData_Release (& xidata );
1144
1081
if (res < 0 ) {
1145
- assert ((result .excinfo == NULL )!= (PyErr_Occurred ()== NULL ));
1146
- return result .excinfo ;
1082
+ assert ((runres .excinfo == NULL )!= (PyErr_Occurred ()== NULL ));
1083
+ return runres .excinfo ;
1147
1084
}
1148
1085
Py_RETURN_NONE ;
1149
1086
#undef FUNCNAME
@@ -1201,13 +1138,13 @@ interp_run_string(PyObject *self, PyObject *args, PyObject *kwds)
1201
1138
return NULL ;
1202
1139
}
1203
1140
1204
- _PyXI_session_result result = {0 };
1141
+ struct run_result runres = {0 };
1205
1142
int res = _run_in_interpreter (
1206
- tstate ,interp ,& xidata ,NULL ,shared ,& result );
1143
+ tstate ,interp ,& xidata ,NULL ,shared ,& runres );
1207
1144
_PyXIData_Release (& xidata );
1208
1145
if (res < 0 ) {
1209
- assert ((result .excinfo == NULL )!= (PyErr_Occurred ()== NULL ));
1210
- return result .excinfo ;
1146
+ assert ((runres .excinfo == NULL )!= (PyErr_Occurred ()== NULL ));
1147
+ return runres .excinfo ;
1211
1148
}
1212
1149
Py_RETURN_NONE ;
1213
1150
#undef FUNCNAME
@@ -1264,13 +1201,13 @@ interp_run_func(PyObject *self, PyObject *args, PyObject *kwds)
1264
1201
return NULL ;
1265
1202
}
1266
1203
1267
- _PyXI_session_result result = {0 };
1204
+ struct run_result runres = {0 };
1268
1205
int res = _run_in_interpreter (
1269
- tstate ,interp ,& xidata ,NULL ,shared ,& result );
1206
+ tstate ,interp ,& xidata ,NULL ,shared ,& runres );
1270
1207
_PyXIData_Release (& xidata );
1271
1208
if (res < 0 ) {
1272
- assert ((result .excinfo == NULL )!= (PyErr_Occurred ()== NULL ));
1273
- return result .excinfo ;
1209
+ assert ((runres .excinfo == NULL )!= (PyErr_Occurred ()== NULL ));
1210
+ return runres .excinfo ;
1274
1211
}
1275
1212
Py_RETURN_NONE ;
1276
1213
#undef FUNCNAME
@@ -1291,17 +1228,18 @@ interp_call(PyObject *self, PyObject *args, PyObject *kwds)
1291
1228
#define FUNCNAME MODULE_NAME_STR ".call"
1292
1229
PyThreadState * tstate = _PyThreadState_GET ();
1293
1230
static char * kwlist []= {"id" ,"callable" ,"args" ,"kwargs" ,
1294
- "restrict" ,NULL };
1231
+ "preserve_exc" , " restrict" ,NULL };
1295
1232
PyObject * id ,* callable ;
1296
1233
PyObject * args_obj = NULL ;
1297
1234
PyObject * kwargs_obj = NULL ;
1235
+ int preserve_exc = 0 ;
1298
1236
int restricted = 0 ;
1299
1237
if (!PyArg_ParseTupleAndKeywords (args ,kwds ,
1300
- "OO|O!O!$p :" FUNCNAME ,kwlist ,
1238
+ "OO|O!O!$pp :" FUNCNAME ,kwlist ,
1301
1239
& id ,& callable ,
1302
1240
& PyTuple_Type ,& args_obj ,
1303
1241
& PyDict_Type ,& kwargs_obj ,
1304
- & restricted ))
1242
+ & preserve_exc , & restricted ))
1305
1243
{
1306
1244
return NULL ;
1307
1245
}
@@ -1319,31 +1257,22 @@ interp_call(PyObject *self, PyObject *args, PyObject *kwds)
1319
1257
}
1320
1258
1321
1259
PyObject * res_and_exc = NULL ;
1322
- _PyXI_session_result result = {0 };
1323
- if (_run_in_interpreter (tstate ,interp ,NULL ,& call ,NULL ,& result )< 0 ) {
1324
- assert (result .preserved == NULL );
1325
- if (result .excinfo == NULL ) {
1260
+ struct run_result runres = {0 };
1261
+ if (_run_in_interpreter (tstate ,interp ,NULL ,& call ,NULL ,& runres )< 0 ) {
1262
+ if (runres .excinfo == NULL ) {
1326
1263
assert (_PyErr_Occurred (tstate ));
1327
1264
gotofinally ;
1328
1265
}
1329
1266
assert (!_PyErr_Occurred (tstate ));
1330
- assert (call .result == NULL );
1331
- res_and_exc = Py_BuildValue ("OO" ,Py_None ,result .excinfo );
1332
- Py_CLEAR (result .excinfo );
1333
- }
1334
- else {
1335
- assert (result .preserved == NULL );
1336
- assert (result .excinfo == NULL );
1337
- PyObject * res = _interp_call_pop_result (tstate ,& call ,interp );
1338
- if (res == NULL ) {
1339
- gotofinally ;
1340
- }
1341
- res_and_exc = Py_BuildValue ("OO" ,res ,Py_None );
1342
- Py_DECREF (res );
1343
1267
}
1268
+ assert (runres .result == NULL || runres .excinfo == NULL );
1269
+ res_and_exc = Py_BuildValue ("OO" ,
1270
+ (runres .result ?runres .result :Py_None ),
1271
+ (runres .excinfo ?runres .excinfo :Py_None ));
1344
1272
1345
1273
finally :
1346
1274
_interp_call_clear (& call );
1275
+ _run_result_clear (& runres );
1347
1276
return res_and_exc ;
1348
1277
#undef FUNCNAME
1349
1278
}