@@ -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,24 +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_GetXIDataWithFallback (
645
- tstate ,resobj ,fallback ,call -> result )< 0 )
646
- {
647
- _interp_call_clear_result (call );
648
552
gotofinally ;
649
553
}
554
+ * p_result = resobj ;
650
555
res = 0 ;
651
556
652
557
finally :
@@ -673,19 +578,32 @@ _run_script(_PyXIData_t *script, PyObject *ns)
673
578
return 0 ;
674
579
}
675
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
+
676
593
static int
677
594
_run_in_interpreter (PyThreadState * tstate ,PyInterpreterState * interp ,
678
595
_PyXIData_t * script ,struct interp_call * call ,
679
- PyObject * shareables ,_PyXI_session_result * result )
596
+ PyObject * shareables ,struct run_result * runres )
680
597
{
681
598
assert (!_PyErr_Occurred (tstate ));
682
599
_PyXI_session * session = _PyXI_NewSession ();
683
600
if (session == NULL ) {
684
601
return -1 ;
685
602
}
603
+ _PyXI_session_result result = {0 };
686
604
687
605
// Prep and switch interpreters.
688
- if (_PyXI_Enter (session ,interp ,shareables ,result )< 0 ) {
606
+ if (_PyXI_Enter (session ,interp ,shareables ,& result )< 0 ) {
689
607
// If an error occured at this step, it means that interp
690
608
// was not prepared and switched.
691
609
_PyXI_FreeSession (session );
@@ -694,7 +612,6 @@ _run_in_interpreter(PyThreadState *tstate, PyInterpreterState *interp,
694
612
695
613
int res = -1 ;
696
614
if (script != NULL ) {
697
- // Run the script.
698
615
assert (call == NULL );
699
616
PyObject * mainns = _PyXI_GetMainNamespace (session );
700
617
if (mainns == NULL ) {
@@ -704,13 +621,31 @@ _run_in_interpreter(PyThreadState *tstate, PyInterpreterState *interp,
704
621
}
705
622
else {
706
623
assert (call != NULL );
707
- 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
+ }
708
630
}
709
631
710
632
finally :
711
633
// Clean up and switch back.
712
- (void )_PyXI_Exit (session ,result );
634
+ (void )_PyXI_Exit (session ,& result );
713
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
+ }
714
649
return res ;
715
650
}
716
651
@@ -1139,13 +1074,13 @@ interp_exec(PyObject *self, PyObject *args, PyObject *kwds)
1139
1074
return NULL ;
1140
1075
}
1141
1076
1142
- _PyXI_session_result result = {0 };
1077
+ struct run_result runres = {0 };
1143
1078
int res = _run_in_interpreter (
1144
- tstate ,interp ,& xidata ,NULL ,shared ,& result );
1079
+ tstate ,interp ,& xidata ,NULL ,shared ,& runres );
1145
1080
_PyXIData_Release (& xidata );
1146
1081
if (res < 0 ) {
1147
- assert ((result .excinfo == NULL )!= (PyErr_Occurred ()== NULL ));
1148
- return result .excinfo ;
1082
+ assert ((runres .excinfo == NULL )!= (PyErr_Occurred ()== NULL ));
1083
+ return runres .excinfo ;
1149
1084
}
1150
1085
Py_RETURN_NONE ;
1151
1086
#undef FUNCNAME
@@ -1203,13 +1138,13 @@ interp_run_string(PyObject *self, PyObject *args, PyObject *kwds)
1203
1138
return NULL ;
1204
1139
}
1205
1140
1206
- _PyXI_session_result result = {0 };
1141
+ struct run_result runres = {0 };
1207
1142
int res = _run_in_interpreter (
1208
- tstate ,interp ,& xidata ,NULL ,shared ,& result );
1143
+ tstate ,interp ,& xidata ,NULL ,shared ,& runres );
1209
1144
_PyXIData_Release (& xidata );
1210
1145
if (res < 0 ) {
1211
- assert ((result .excinfo == NULL )!= (PyErr_Occurred ()== NULL ));
1212
- return result .excinfo ;
1146
+ assert ((runres .excinfo == NULL )!= (PyErr_Occurred ()== NULL ));
1147
+ return runres .excinfo ;
1213
1148
}
1214
1149
Py_RETURN_NONE ;
1215
1150
#undef FUNCNAME
@@ -1266,13 +1201,13 @@ interp_run_func(PyObject *self, PyObject *args, PyObject *kwds)
1266
1201
return NULL ;
1267
1202
}
1268
1203
1269
- _PyXI_session_result result = {0 };
1204
+ struct run_result runres = {0 };
1270
1205
int res = _run_in_interpreter (
1271
- tstate ,interp ,& xidata ,NULL ,shared ,& result );
1206
+ tstate ,interp ,& xidata ,NULL ,shared ,& runres );
1272
1207
_PyXIData_Release (& xidata );
1273
1208
if (res < 0 ) {
1274
- assert ((result .excinfo == NULL )!= (PyErr_Occurred ()== NULL ));
1275
- return result .excinfo ;
1209
+ assert ((runres .excinfo == NULL )!= (PyErr_Occurred ()== NULL ));
1210
+ return runres .excinfo ;
1276
1211
}
1277
1212
Py_RETURN_NONE ;
1278
1213
#undef FUNCNAME
@@ -1293,17 +1228,18 @@ interp_call(PyObject *self, PyObject *args, PyObject *kwds)
1293
1228
#define FUNCNAME MODULE_NAME_STR ".call"
1294
1229
PyThreadState * tstate = _PyThreadState_GET ();
1295
1230
static char * kwlist []= {"id" ,"callable" ,"args" ,"kwargs" ,
1296
- "restrict" ,NULL };
1231
+ "preserve_exc" , " restrict" ,NULL };
1297
1232
PyObject * id ,* callable ;
1298
1233
PyObject * args_obj = NULL ;
1299
1234
PyObject * kwargs_obj = NULL ;
1235
+ int preserve_exc = 0 ;
1300
1236
int restricted = 0 ;
1301
1237
if (!PyArg_ParseTupleAndKeywords (args ,kwds ,
1302
- "OO|O!O!$p :" FUNCNAME ,kwlist ,
1238
+ "OO|O!O!$pp :" FUNCNAME ,kwlist ,
1303
1239
& id ,& callable ,
1304
1240
& PyTuple_Type ,& args_obj ,
1305
1241
& PyDict_Type ,& kwargs_obj ,
1306
- & restricted ))
1242
+ & preserve_exc , & restricted ))
1307
1243
{
1308
1244
return NULL ;
1309
1245
}
@@ -1321,31 +1257,22 @@ interp_call(PyObject *self, PyObject *args, PyObject *kwds)
1321
1257
}
1322
1258
1323
1259
PyObject * res_and_exc = NULL ;
1324
- _PyXI_session_result result = {0 };
1325
- if (_run_in_interpreter (tstate ,interp ,NULL ,& call ,NULL ,& result )< 0 ) {
1326
- assert (result .preserved == NULL );
1327
- 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 ) {
1328
1263
assert (_PyErr_Occurred (tstate ));
1329
1264
gotofinally ;
1330
1265
}
1331
1266
assert (!_PyErr_Occurred (tstate ));
1332
- assert (call .result == NULL );
1333
- res_and_exc = Py_BuildValue ("OO" ,Py_None ,result .excinfo );
1334
- Py_CLEAR (result .excinfo );
1335
- }
1336
- else {
1337
- assert (result .preserved == NULL );
1338
- assert (result .excinfo == NULL );
1339
- PyObject * res = _interp_call_pop_result (tstate ,& call ,interp );
1340
- if (res == NULL ) {
1341
- gotofinally ;
1342
- }
1343
- res_and_exc = Py_BuildValue ("OO" ,res ,Py_None );
1344
- Py_DECREF (res );
1345
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 ));
1346
1272
1347
1273
finally :
1348
1274
_interp_call_clear (& call );
1275
+ _run_result_clear (& runres );
1349
1276
return res_and_exc ;
1350
1277
#undef FUNCNAME
1351
1278
}