83
83
import com .oracle .graal .python .runtime .ExecutionContext .CalleeContext ;
84
84
import com .oracle .graal .python .runtime .ExecutionContext .IndirectCallContext ;
85
85
import com .oracle .graal .python .runtime .PythonContext ;
86
+ import com .oracle .graal .python .runtime .PythonContext .GetThreadStateNode ;
87
+ import com .oracle .graal .python .runtime .PythonContext .PythonThreadState ;
88
+ import com .oracle .graal .python .runtime .PythonContextFactory .GetThreadStateNodeGen ;
86
89
import com .oracle .graal .python .runtime .PythonOptions ;
87
90
import com .oracle .graal .python .runtime .exception .PException ;
88
91
import com .oracle .graal .python .runtime .exception .PythonErrorType ;
@@ -297,28 +300,33 @@ abstract static class HPyExternalFunctionInvokeNode extends Node implements Indi
297
300
@ Child private HPyConvertArgsToSulongNode toSulongNode ;
298
301
@ Child private HPyCheckFunctionResultNode checkFunctionResultNode ;
299
302
@ Child private HPyCloseArgHandlesNode handleCloseNode ;
303
+ @ Child private GetThreadStateNode getThreadStateNode ;
300
304
301
305
@ CompilationFinal private Assumption nativeCodeDoesntNeedExceptionState = Truffle .getRuntime ().createAssumption ();
302
306
@ CompilationFinal private Assumption nativeCodeDoesntNeedMyFrame = Truffle .getRuntime ().createAssumption ();
303
307
304
308
HPyExternalFunctionInvokeNode () {
309
+ CompilerAsserts .neverPartOfCompilation ();
305
310
this .toSulongNode = HPyAllAsHandleNodeGen .create ();
306
311
this .checkFunctionResultNode = HPyCheckHandleResultNodeGen .create ();
307
312
this .handleCloseNode = this .toSulongNode .createCloseHandleNode ();
313
+ this .getThreadStateNode = GetThreadStateNodeGen .create ();
308
314
}
309
315
310
316
HPyExternalFunctionInvokeNode (HPyConvertArgsToSulongNode convertArgsNode ) {
311
317
CompilerAsserts .neverPartOfCompilation ();
312
318
this .toSulongNode = convertArgsNode != null ? convertArgsNode : HPyAllAsHandleNodeGen .create ();
313
319
this .checkFunctionResultNode = HPyCheckHandleResultNodeGen .create ();
314
320
this .handleCloseNode = this .toSulongNode .createCloseHandleNode ();
321
+ this .getThreadStateNode = GetThreadStateNodeGen .create ();
315
322
}
316
323
317
324
HPyExternalFunctionInvokeNode (HPyCheckFunctionResultNode checkFunctionResultNode , HPyConvertArgsToSulongNode convertArgsNode ) {
318
325
CompilerAsserts .neverPartOfCompilation ();
319
326
this .toSulongNode = convertArgsNode != null ? convertArgsNode : HPyAllAsHandleNodeGen .create ();
320
327
this .checkFunctionResultNode = checkFunctionResultNode != null ? checkFunctionResultNode : HPyCheckHandleResultNodeGen .create ();
321
328
this .handleCloseNode = this .toSulongNode .createCloseHandleNode ();
329
+ this .getThreadStateNode = GetThreadStateNodeGen .create ();
322
330
}
323
331
324
332
public abstract Object execute (VirtualFrame frame , String name , Object callable , Object [] frameArgs );
@@ -335,21 +343,23 @@ Object doIt(VirtualFrame frame, String name, Object callable, Object[] arguments
335
343
// first arg is always the HPyContext
336
344
convertedArguments [0 ] = hPyContext ;
337
345
346
+ PythonThreadState pythonThreadState = getThreadStateNode .execute (ctx );
347
+
338
348
// If any code requested the caught exception (i.e. used 'sys.exc_info()'), we store
339
349
// it to the context since we cannot propagate it through the native frames.
340
- Object state = IndirectCallContext .enter (frame , ctx , this );
350
+ Object state = IndirectCallContext .enter (frame , pythonThreadState , this );
341
351
342
352
try {
343
- return checkFunctionResultNode .execute (ctx , name , lib .execute (callable , convertedArguments ));
353
+ return checkFunctionResultNode .execute (pythonThreadState , hPyContext , name , lib .execute (callable , convertedArguments ));
344
354
} catch (UnsupportedTypeException | UnsupportedMessageException e ) {
345
355
throw raiseNode .raise (PythonBuiltinClassType .TypeError , "Calling native function %s failed: %m" , name , e );
346
356
} catch (ArityException e ) {
347
357
throw raiseNode .raise (PythonBuiltinClassType .TypeError , "Calling native function %s expected %d arguments but got %d." , name , e .getExpectedMinArity (), e .getActualArity ());
348
358
} finally {
349
359
// special case after calling a C function: transfer caught exception back to frame
350
360
// to simulate the global state semantics
351
- PArguments .setException (frame , ctx .getCaughtException ());
352
- IndirectCallContext .exit (frame , ctx , state );
361
+ PArguments .setException (frame , pythonThreadState .getCaughtException ());
362
+ IndirectCallContext .exit (frame , pythonThreadState , state );
353
363
354
364
// close all handles (if necessary)
355
365
if (handleCloseNode != null ) {
@@ -928,29 +938,29 @@ abstract static class HPyCheckFunctionResultNode extends CheckFunctionResultNode
928
938
*/
929
939
@ Override
930
940
public final Object execute (PythonContext context , String name , Object result ) {
931
- return execute (context , context .getHPyContext (), name , result );
941
+ return execute (context . getThreadState () , context .getHPyContext (), name , result );
932
942
}
933
943
934
944
/**
935
945
* This is the preferred way for executing the node since it avoids unnecessary field reads
936
946
* in the interpreter or multi-context mode.
937
947
*/
938
- public abstract Object execute (PythonContext context , GraalHPyContext nativeContext , String name , Object value );
948
+ public abstract Object execute (PythonThreadState pythonThreadState , GraalHPyContext nativeContext , String name , Object value );
939
949
940
- protected final void checkFunctionResult (String name , boolean indicatesError , PythonContext context , PRaiseNode raise , PythonObjectFactory factory , PythonLanguage language ) {
941
- PException currentException = context .getCurrentException ();
950
+ protected final void checkFunctionResult (String name , boolean indicatesError , PythonThreadState pythonThreadState , PRaiseNode raise , PythonObjectFactory factory , PythonLanguage language ) {
951
+ PException currentException = pythonThreadState .getCurrentException ();
942
952
boolean errOccurred = currentException != null ;
943
953
if (indicatesError ) {
944
954
// consume exception
945
- context .setCurrentException (null );
955
+ pythonThreadState .setCurrentException (null );
946
956
if (!errOccurred ) {
947
957
throw raise .raise (PythonErrorType .SystemError , ErrorMessages .RETURNED_NULL_WO_SETTING_ERROR , name );
948
958
} else {
949
959
throw currentException .getExceptionForReraise ();
950
960
}
951
961
} else if (errOccurred ) {
952
962
// consume exception
953
- context .setCurrentException (null );
963
+ pythonThreadState .setCurrentException (null );
954
964
PBaseException sysExc = factory .createBaseException (PythonErrorType .SystemError , ErrorMessages .RETURNED_RESULT_WITH_ERROR_SET , new Object []{name });
955
965
sysExc .setCause (currentException .getEscapedException ());
956
966
throw PException .fromObject (sysExc , this , PythonOptions .isPExceptionWithJavaStacktrace (language ));
@@ -963,17 +973,17 @@ protected final void checkFunctionResult(String name, boolean indicatesError, Py
963
973
public abstract static class HPyCheckHandleResultNode extends HPyCheckFunctionResultNode {
964
974
965
975
@ Specialization (guards = "value == 0" )
966
- Object doIntegerNull (PythonContext context , @ SuppressWarnings ("unused" ) GraalHPyContext nativeContext , String name , @ SuppressWarnings ("unused" ) int value ,
976
+ Object doIntegerNull (PythonThreadState pythonThreadState , @ SuppressWarnings ("unused" ) GraalHPyContext nativeContext , String name , @ SuppressWarnings ("unused" ) int value ,
967
977
@ Shared ("language" ) @ CachedLanguage PythonLanguage language ,
968
978
@ Shared ("fact" ) @ Cached PythonObjectFactory factory ,
969
979
@ Shared ("raiseNode" ) @ Cached PRaiseNode raiseNode ) {
970
980
// NULL handle must not be closed
971
- checkFunctionResult (name , true , context , raiseNode , factory , language );
981
+ checkFunctionResult (name , true , pythonThreadState , raiseNode , factory , language );
972
982
throw CompilerDirectives .shouldNotReachHere ("an exception should have been thrown" );
973
983
}
974
984
975
985
@ Specialization (replaces = "doIntegerNull" )
976
- Object doInteger (PythonContext context , GraalHPyContext nativeContext , String name , int value ,
986
+ Object doInteger (PythonThreadState pythonThreadState , GraalHPyContext nativeContext , String name , int value ,
977
987
@ Exclusive @ Cached HPyAsPythonObjectNode asPythonObjectNode ,
978
988
@ Shared ("language" ) @ CachedLanguage PythonLanguage language ,
979
989
@ Shared ("fact" ) @ Cached PythonObjectFactory factory ,
@@ -984,22 +994,22 @@ Object doInteger(PythonContext context, GraalHPyContext nativeContext, String na
984
994
// handle and we don't need it any longer. So, close it in every case.
985
995
nativeContext .releaseHPyHandleForObject (value );
986
996
}
987
- checkFunctionResult (name , isNullHandle , context , raiseNode , factory , language );
997
+ checkFunctionResult (name , isNullHandle , pythonThreadState , raiseNode , factory , language );
988
998
return asPythonObjectNode .execute (nativeContext , value );
989
999
}
990
1000
991
1001
@ Specialization (guards = "value == 0" )
992
- Object doLongNull (PythonContext context , @ SuppressWarnings ("unused" ) GraalHPyContext nativeContext , String name , @ SuppressWarnings ("unused" ) long value ,
1002
+ Object doLongNull (PythonThreadState pythonThreadState , @ SuppressWarnings ("unused" ) GraalHPyContext nativeContext , String name , @ SuppressWarnings ("unused" ) long value ,
993
1003
@ Shared ("language" ) @ CachedLanguage PythonLanguage language ,
994
1004
@ Shared ("fact" ) @ Cached PythonObjectFactory factory ,
995
1005
@ Shared ("raiseNode" ) @ Cached PRaiseNode raiseNode ) {
996
1006
// NULL handle must not be closed
997
- checkFunctionResult (name , true , context , raiseNode , factory , language );
1007
+ checkFunctionResult (name , true , pythonThreadState , raiseNode , factory , language );
998
1008
throw CompilerDirectives .shouldNotReachHere ("an exception should have been thrown" );
999
1009
}
1000
1010
1001
1011
@ Specialization (replaces = "doLongNull" )
1002
- Object doLong (PythonContext context , GraalHPyContext nativeContext , String name , long value ,
1012
+ Object doLong (PythonThreadState pythonThreadState , GraalHPyContext nativeContext , String name , long value ,
1003
1013
@ Exclusive @ Cached HPyAsPythonObjectNode asPythonObjectNode ,
1004
1014
@ Shared ("language" ) @ CachedLanguage PythonLanguage language ,
1005
1015
@ Shared ("fact" ) @ Cached PythonObjectFactory factory ,
@@ -1010,22 +1020,22 @@ Object doLong(PythonContext context, GraalHPyContext nativeContext, String name,
1010
1020
// handle and we don't need it any longer. So, close it in every case.
1011
1021
nativeContext .releaseHPyHandleForObject (value );
1012
1022
}
1013
- checkFunctionResult (name , isNullHandle , context , raiseNode , factory , language );
1023
+ checkFunctionResult (name , isNullHandle , pythonThreadState , raiseNode , factory , language );
1014
1024
return asPythonObjectNode .execute (nativeContext , value );
1015
1025
}
1016
1026
1017
1027
@ Specialization (guards = "isNullHandle(nativeContext, handle)" )
1018
- Object doNullHandle (PythonContext context , @ SuppressWarnings ("unused" ) GraalHPyContext nativeContext , String name , @ SuppressWarnings ("unused" ) GraalHPyHandle handle ,
1028
+ Object doNullHandle (PythonThreadState pythonThreadState , @ SuppressWarnings ("unused" ) GraalHPyContext nativeContext , String name , @ SuppressWarnings ("unused" ) GraalHPyHandle handle ,
1019
1029
@ Shared ("language" ) @ CachedLanguage PythonLanguage language ,
1020
1030
@ Shared ("fact" ) @ Cached PythonObjectFactory factory ,
1021
1031
@ Shared ("raiseNode" ) @ Cached PRaiseNode raiseNode ) {
1022
1032
// NULL handle must not be closed
1023
- checkFunctionResult (name , true , context , raiseNode , factory , language );
1033
+ checkFunctionResult (name , true , pythonThreadState , raiseNode , factory , language );
1024
1034
throw CompilerDirectives .shouldNotReachHere ("an exception should have been thrown" );
1025
1035
}
1026
1036
1027
1037
@ Specialization (guards = "!isNullHandle(nativeContext, handle)" , replaces = "doNullHandle" )
1028
- Object doNonNullHandle (PythonContext context , GraalHPyContext nativeContext , String name , GraalHPyHandle handle ,
1038
+ Object doNonNullHandle (PythonThreadState pythonThreadState , GraalHPyContext nativeContext , String name , GraalHPyHandle handle ,
1029
1039
@ Cached ConditionProfile isAllocatedProfile ,
1030
1040
@ Exclusive @ Cached HPyAsPythonObjectNode asPythonObjectNode ,
1031
1041
@ Shared ("language" ) @ CachedLanguage PythonLanguage language ,
@@ -1034,12 +1044,12 @@ Object doNonNullHandle(PythonContext context, GraalHPyContext nativeContext, Str
1034
1044
// Python land is receiving a handle from an HPy extension, so we are now owning the
1035
1045
// handle and we don't need it any longer. So, close it in every case.
1036
1046
handle .close (nativeContext , isAllocatedProfile );
1037
- checkFunctionResult (name , false , context , raiseNode , factory , language );
1047
+ checkFunctionResult (name , false , pythonThreadState , raiseNode , factory , language );
1038
1048
return asPythonObjectNode .execute (nativeContext , handle );
1039
1049
}
1040
1050
1041
1051
@ Specialization (replaces = {"doIntegerNull" , "doNonNullHandle" })
1042
- Object doHandle (PythonContext context , GraalHPyContext nativeContext , String name , GraalHPyHandle handle ,
1052
+ Object doHandle (PythonThreadState pythonThreadState , GraalHPyContext nativeContext , String name , GraalHPyHandle handle ,
1043
1053
@ Cached ConditionProfile isAllocatedProfile ,
1044
1054
@ Exclusive @ Cached HPyAsPythonObjectNode asPythonObjectNode ,
1045
1055
@ Shared ("language" ) @ CachedLanguage PythonLanguage language ,
@@ -1051,12 +1061,12 @@ Object doHandle(PythonContext context, GraalHPyContext nativeContext, String nam
1051
1061
// handle and we don't need it any longer. So, close it in every case.
1052
1062
handle .close (nativeContext , isAllocatedProfile );
1053
1063
}
1054
- checkFunctionResult (name , isNullHandle , context , raiseNode , factory , language );
1064
+ checkFunctionResult (name , isNullHandle , pythonThreadState , raiseNode , factory , language );
1055
1065
return asPythonObjectNode .execute (nativeContext , handle );
1056
1066
}
1057
1067
1058
1068
@ Specialization (replaces = {"doIntegerNull" , "doInteger" , "doLongNull" , "doLong" , "doNullHandle" , "doNonNullHandle" , "doHandle" })
1059
- Object doGeneric (PythonContext context , GraalHPyContext nativeContext , String name , Object value ,
1069
+ Object doGeneric (PythonThreadState pythonThreadState , GraalHPyContext nativeContext , String name , Object value ,
1060
1070
@ Cached HPyEnsureHandleNode ensureHandleNode ,
1061
1071
@ Cached ConditionProfile isAllocatedProfile ,
1062
1072
@ Cached HPyAsPythonObjectNode asPythonObjectNode ,
@@ -1070,7 +1080,7 @@ Object doGeneric(PythonContext context, GraalHPyContext nativeContext, String na
1070
1080
// handle and we don't need it any longer. So, close it in every case.
1071
1081
handle .close (nativeContext , isAllocatedProfile );
1072
1082
}
1073
- checkFunctionResult (name , isNullHandle (nativeContext , handle ), context , raiseNode , factory , language );
1083
+ checkFunctionResult (name , isNullHandle (nativeContext , handle ), pythonThreadState , raiseNode , factory , language );
1074
1084
return asPythonObjectNode .execute (nativeContext , handle );
1075
1085
}
1076
1086
@@ -1085,38 +1095,38 @@ protected static boolean isNullHandle(GraalHPyContext nativeContext, GraalHPyHan
1085
1095
*/
1086
1096
@ ImportStatic (PGuards .class )
1087
1097
abstract static class HPyCheckPrimitiveResultNode extends HPyCheckFunctionResultNode {
1088
- public abstract int executeInt (PythonContext context , GraalHPyContext nativeContext , String name , int value );
1098
+ public abstract int executeInt (PythonThreadState context , GraalHPyContext nativeContext , String name , int value );
1089
1099
1090
- public abstract long executeLong (PythonContext context , GraalHPyContext nativeContext , String name , long value );
1100
+ public abstract long executeLong (PythonThreadState context , GraalHPyContext nativeContext , String name , long value );
1091
1101
1092
1102
@ Specialization
1093
- int doInteger (PythonContext context , @ SuppressWarnings ("unused" ) GraalHPyContext nativeContext , String name , int value ,
1103
+ int doInteger (PythonThreadState pythonThreadState , @ SuppressWarnings ("unused" ) GraalHPyContext nativeContext , String name , int value ,
1094
1104
@ Shared ("language" ) @ CachedLanguage PythonLanguage language ,
1095
1105
@ Shared ("fact" ) @ Cached PythonObjectFactory factory ,
1096
1106
@ Shared ("raiseNode" ) @ Cached PRaiseNode raiseNode ) {
1097
- checkFunctionResult (name , value == -1 , context , raiseNode , factory , language );
1107
+ checkFunctionResult (name , value == -1 , pythonThreadState , raiseNode , factory , language );
1098
1108
return value ;
1099
1109
}
1100
1110
1101
1111
@ Specialization (replaces = "doInteger" )
1102
- long doLong (PythonContext context , @ SuppressWarnings ("unused" ) GraalHPyContext nativeContext , String name , long value ,
1112
+ long doLong (PythonThreadState pythonThreadState , @ SuppressWarnings ("unused" ) GraalHPyContext nativeContext , String name , long value ,
1103
1113
@ Shared ("language" ) @ CachedLanguage PythonLanguage language ,
1104
1114
@ Shared ("fact" ) @ Cached PythonObjectFactory factory ,
1105
1115
@ Shared ("raiseNode" ) @ Cached PRaiseNode raiseNode ) {
1106
- checkFunctionResult (name , value == -1 , context , raiseNode , factory , language );
1116
+ checkFunctionResult (name , value == -1 , pythonThreadState , raiseNode , factory , language );
1107
1117
return value ;
1108
1118
}
1109
1119
1110
1120
@ Specialization (limit = "1" )
1111
- Object doObject (PythonContext context , @ SuppressWarnings ("unused" ) GraalHPyContext nativeContext , String name , Object value ,
1121
+ Object doObject (PythonThreadState pythonThreadState , @ SuppressWarnings ("unused" ) GraalHPyContext nativeContext , String name , Object value ,
1112
1122
@ Shared ("language" ) @ CachedLanguage PythonLanguage language ,
1113
1123
@ Shared ("fact" ) @ Cached PythonObjectFactory factory ,
1114
1124
@ CachedLibrary ("value" ) InteropLibrary lib ,
1115
1125
@ Shared ("raiseNode" ) @ Cached PRaiseNode raiseNode ) {
1116
1126
if (lib .fitsInLong (value )) {
1117
1127
try {
1118
1128
long lvalue = lib .asLong (value );
1119
- checkFunctionResult (name , lvalue == -1 , context , raiseNode , factory , language );
1129
+ checkFunctionResult (name , lvalue == -1 , pythonThreadState , raiseNode , factory , language );
1120
1130
return lvalue ;
1121
1131
} catch (UnsupportedMessageException e ) {
1122
1132
throw CompilerDirectives .shouldNotReachHere ();
0 commit comments