@@ -80,21 +80,11 @@ is_notshareable_raised(PyThreadState *tstate)
80
80
}
81
81
82
82
static void
83
- unwrap_not_shareable (PyThreadState * tstate )
83
+ unwrap_not_shareable (PyThreadState * tstate , _PyXI_failure * failure )
84
84
{
85
- if (!is_notshareable_raised (tstate )) {
86
- return ;
87
- }
88
- PyObject * exc = _PyErr_GetRaisedException (tstate );
89
- PyObject * cause = PyException_GetCause (exc );
90
- if (cause != NULL ) {
91
- Py_DECREF (exc );
92
- exc = cause ;
85
+ if (_PyXI_UnwrapNotShareableError (tstate , failure ) < 0 ) {
86
+ _PyErr_Clear (tstate );
93
87
}
94
- else {
95
- assert (PyException_GetContext (exc ) == NULL );
96
- }
97
- _PyErr_SetRaisedException (tstate , exc );
98
88
}
99
89
100
90
@@ -532,13 +522,30 @@ _interp_call_pack(PyThreadState *tstate, struct interp_call *call,
532
522
return 0 ;
533
523
}
534
524
525
+ static void
526
+ wrap_notshareable (PyThreadState * tstate , const char * label )
527
+ {
528
+ if (!is_notshareable_raised (tstate )) {
529
+ return ;
530
+ }
531
+ assert (label != NULL && strlen (label ) > 0 );
532
+ PyObject * cause = _PyErr_GetRaisedException (tstate );
533
+ _PyXIData_FormatNotShareableError (tstate , "%s not shareable" , label );
534
+ PyObject * exc = _PyErr_GetRaisedException (tstate );
535
+ PyException_SetCause (exc , cause );
536
+ _PyErr_SetRaisedException (tstate , exc );
537
+ }
538
+
535
539
static int
536
540
_interp_call_unpack (struct interp_call * call ,
537
541
PyObject * * p_func , PyObject * * p_args , PyObject * * p_kwargs )
538
542
{
543
+ PyThreadState * tstate = PyThreadState_Get ();
544
+
539
545
// Unpack the func.
540
546
PyObject * func = _PyXIData_NewObject (call -> func );
541
547
if (func == NULL ) {
548
+ wrap_notshareable (tstate , "func" );
542
549
return -1 ;
543
550
}
544
551
// Unpack the args.
@@ -553,6 +560,7 @@ _interp_call_unpack(struct interp_call *call,
553
560
else {
554
561
args = _PyXIData_NewObject (call -> args );
555
562
if (args == NULL ) {
563
+ wrap_notshareable (tstate , "args" );
556
564
Py_DECREF (func );
557
565
return -1 ;
558
566
}
@@ -563,6 +571,7 @@ _interp_call_unpack(struct interp_call *call,
563
571
if (call -> kwargs != NULL ) {
564
572
kwargs = _PyXIData_NewObject (call -> kwargs );
565
573
if (kwargs == NULL ) {
574
+ wrap_notshareable (tstate , "kwargs" );
566
575
Py_DECREF (func );
567
576
Py_DECREF (args );
568
577
return -1 ;
@@ -577,7 +586,7 @@ _interp_call_unpack(struct interp_call *call,
577
586
578
587
static int
579
588
_make_call (struct interp_call * call ,
580
- PyObject * * p_result , _PyXI_errcode * p_errcode )
589
+ PyObject * * p_result , _PyXI_failure * failure )
581
590
{
582
591
assert (call != NULL && call -> func != NULL );
583
592
PyThreadState * tstate = _PyThreadState_GET ();
@@ -588,12 +597,10 @@ _make_call(struct interp_call *call,
588
597
assert (func == NULL );
589
598
assert (args == NULL );
590
599
assert (kwargs == NULL );
591
- * p_errcode = is_notshareable_raised (tstate )
592
- ? _PyXI_ERR_NOT_SHAREABLE
593
- : _PyXI_ERR_OTHER ;
600
+ _PyXI_InitFailure (failure , _PyXI_ERR_OTHER , NULL );
601
+ unwrap_not_shareable (tstate , failure );
594
602
return -1 ;
595
603
}
596
- * p_errcode = _PyXI_ERR_NO_ERROR ;
597
604
598
605
// Make the call.
599
606
PyObject * resobj = PyObject_Call (func , args , kwargs );
@@ -608,17 +615,17 @@ _make_call(struct interp_call *call,
608
615
}
609
616
610
617
static int
611
- _run_script (_PyXIData_t * script , PyObject * ns , _PyXI_errcode * p_errcode )
618
+ _run_script (_PyXIData_t * script , PyObject * ns , _PyXI_failure * failure )
612
619
{
613
620
PyObject * code = _PyXIData_NewObject (script );
614
621
if (code == NULL ) {
615
- * p_errcode = _PyXI_ERR_NOT_SHAREABLE ;
622
+ _PyXI_InitFailure ( failure , _PyXI_ERR_NOT_SHAREABLE , NULL ) ;
616
623
return -1 ;
617
624
}
618
625
PyObject * result = PyEval_EvalCode (code , ns , ns );
619
626
Py_DECREF (code );
620
627
if (result == NULL ) {
621
- * p_errcode = _PyXI_ERR_UNCAUGHT_EXCEPTION ;
628
+ _PyXI_InitFailure ( failure , _PyXI_ERR_UNCAUGHT_EXCEPTION , NULL ) ;
622
629
return -1 ;
623
630
}
624
631
assert (result == Py_None );
@@ -644,8 +651,14 @@ _run_in_interpreter(PyThreadState *tstate, PyInterpreterState *interp,
644
651
PyObject * shareables , struct run_result * runres )
645
652
{
646
653
assert (!_PyErr_Occurred (tstate ));
654
+ int res = -1 ;
655
+ _PyXI_failure * failure = _PyXI_NewFailure ();
656
+ if (failure == NULL ) {
657
+ return -1 ;
658
+ }
647
659
_PyXI_session * session = _PyXI_NewSession ();
648
660
if (session == NULL ) {
661
+ _PyXI_FreeFailure (failure );
649
662
return -1 ;
650
663
}
651
664
_PyXI_session_result result = {0 };
@@ -655,43 +668,44 @@ _run_in_interpreter(PyThreadState *tstate, PyInterpreterState *interp,
655
668
// If an error occured at this step, it means that interp
656
669
// was not prepared and switched.
657
670
_PyXI_FreeSession (session );
671
+ _PyXI_FreeFailure (failure );
658
672
assert (result .excinfo == NULL );
659
673
return -1 ;
660
674
}
661
675
662
676
// Run in the interpreter.
663
- int res = -1 ;
664
- _PyXI_errcode errcode = _PyXI_ERR_NO_ERROR ;
665
677
if (script != NULL ) {
666
678
assert (call == NULL );
667
- PyObject * mainns = _PyXI_GetMainNamespace (session , & errcode );
679
+ PyObject * mainns = _PyXI_GetMainNamespace (session , failure );
668
680
if (mainns == NULL ) {
669
681
goto finally ;
670
682
}
671
- res = _run_script (script , mainns , & errcode );
683
+ res = _run_script (script , mainns , failure );
672
684
}
673
685
else {
674
686
assert (call != NULL );
675
687
PyObject * resobj ;
676
- res = _make_call (call , & resobj , & errcode );
688
+ res = _make_call (call , & resobj , failure );
677
689
if (res == 0 ) {
678
- res = _PyXI_Preserve (session , "resobj" , resobj , & errcode );
690
+ res = _PyXI_Preserve (session , "resobj" , resobj , failure );
679
691
Py_DECREF (resobj );
680
692
if (res < 0 ) {
681
693
goto finally ;
682
694
}
683
695
}
684
696
}
685
- int exitres ;
686
697
687
698
finally :
688
699
// Clean up and switch back.
689
- exitres = _PyXI_Exit (session , errcode , & result );
700
+ (void )res ;
701
+ int exitres = _PyXI_Exit (session , failure , & result );
690
702
assert (res == 0 || exitres != 0 );
691
703
_PyXI_FreeSession (session );
704
+ _PyXI_FreeFailure (failure );
692
705
693
706
res = exitres ;
694
707
if (_PyErr_Occurred (tstate )) {
708
+ // It's a directly propagated exception.
695
709
assert (res < 0 );
696
710
}
697
711
else if (res < 0 ) {
@@ -1064,7 +1078,7 @@ interp_set___main___attrs(PyObject *self, PyObject *args, PyObject *kwargs)
1064
1078
1065
1079
// Clean up and switch back.
1066
1080
assert (!PyErr_Occurred ());
1067
- int res = _PyXI_Exit (session , _PyXI_ERR_NO_ERROR , NULL );
1081
+ int res = _PyXI_Exit (session , NULL , NULL );
1068
1082
_PyXI_FreeSession (session );
1069
1083
assert (res == 0 );
1070
1084
if (res < 0 ) {
@@ -1124,7 +1138,7 @@ interp_exec(PyObject *self, PyObject *args, PyObject *kwds)
1124
1138
// global variables. They will be resolved against __main__.
1125
1139
_PyXIData_t xidata = {0 };
1126
1140
if (_PyCode_GetScriptXIData (tstate , code , & xidata ) < 0 ) {
1127
- unwrap_not_shareable (tstate );
1141
+ unwrap_not_shareable (tstate , NULL );
1128
1142
return NULL ;
1129
1143
}
1130
1144
@@ -1188,7 +1202,7 @@ interp_run_string(PyObject *self, PyObject *args, PyObject *kwds)
1188
1202
1189
1203
_PyXIData_t xidata = {0 };
1190
1204
if (_PyCode_GetScriptXIData (tstate , script , & xidata ) < 0 ) {
1191
- unwrap_not_shareable (tstate );
1205
+ unwrap_not_shareable (tstate , NULL );
1192
1206
return NULL ;
1193
1207
}
1194
1208
@@ -1251,7 +1265,7 @@ interp_run_func(PyObject *self, PyObject *args, PyObject *kwds)
1251
1265
1252
1266
_PyXIData_t xidata = {0 };
1253
1267
if (_PyCode_GetScriptXIData (tstate , code , & xidata ) < 0 ) {
1254
- unwrap_not_shareable (tstate );
1268
+ unwrap_not_shareable (tstate , NULL );
1255
1269
return NULL ;
1256
1270
}
1257
1271
@@ -1542,16 +1556,16 @@ capture_exception(PyObject *self, PyObject *args, PyObject *kwds)
1542
1556
}
1543
1557
PyObject * captured = NULL ;
1544
1558
1545
- _PyXI_excinfo info = { 0 } ;
1546
- if (_PyXI_InitExcInfo ( & info , exc ) < 0 ) {
1559
+ _PyXI_excinfo * info = _PyXI_NewExcInfo ( exc ) ;
1560
+ if (info == NULL ) {
1547
1561
goto finally ;
1548
1562
}
1549
- captured = _PyXI_ExcInfoAsObject (& info );
1563
+ captured = _PyXI_ExcInfoAsObject (info );
1550
1564
if (captured == NULL ) {
1551
1565
goto finally ;
1552
1566
}
1553
1567
1554
- PyObject * formatted = _PyXI_FormatExcInfo (& info );
1568
+ PyObject * formatted = _PyXI_FormatExcInfo (info );
1555
1569
if (formatted == NULL ) {
1556
1570
Py_CLEAR (captured );
1557
1571
goto finally ;
@@ -1564,7 +1578,7 @@ capture_exception(PyObject *self, PyObject *args, PyObject *kwds)
1564
1578
}
1565
1579
1566
1580
finally :
1567
- _PyXI_ClearExcInfo ( & info );
1581
+ _PyXI_FreeExcInfo ( info );
1568
1582
if (exc != exc_arg ) {
1569
1583
if (PyErr_Occurred ()) {
1570
1584
PyErr_SetRaisedException (exc );
0 commit comments