174
174
import com .oracle .graal .python .nodes .expression .UnaryOpNode ;
175
175
import com .oracle .graal .python .nodes .frame .DeleteGlobalNode ;
176
176
import com .oracle .graal .python .nodes .frame .DeleteGlobalNodeGen ;
177
+ import com .oracle .graal .python .nodes .frame .GetFrameLocalsNode ;
177
178
import com .oracle .graal .python .nodes .frame .MaterializeFrameNode ;
178
179
import com .oracle .graal .python .nodes .frame .ReadFromLocalsNode ;
179
180
import com .oracle .graal .python .nodes .frame .ReadFromLocalsNodeGen ;
@@ -2962,7 +2963,10 @@ private void invokeTraceFunction(VirtualFrame virtualFrame, Object arg, PythonCo
2962
2963
if (line != -1 ) {
2963
2964
pyFrame .setLineLock (line );
2964
2965
}
2966
+ // Force locals dict sync, so that we can sync them back later
2967
+ GetFrameLocalsNode .getUncached ().execute (pyFrame );
2965
2968
Object result = CallTernaryMethodNode .getUncached ().execute (null , traceFn , pyFrame , event .pythonName , nonNullArg );
2969
+ syncLocalsBack (virtualFrame , pyFrame );
2966
2970
Object realResult = result == PNone .NONE ? null : result ;
2967
2971
pyFrame .setLocalTraceFun (realResult );
2968
2972
} catch (Throwable e ) {
@@ -2976,6 +2980,36 @@ private void invokeTraceFunction(VirtualFrame virtualFrame, Object arg, PythonCo
2976
2980
}
2977
2981
}
2978
2982
2983
+ // PyFrame_LocalsToFast
2984
+ private void syncLocalsBack (VirtualFrame virtualFrame , PFrame pyFrame ) {
2985
+ Frame localFrame = virtualFrame ;
2986
+ if (co .isGeneratorOrCoroutine ()) {
2987
+ localFrame = PArguments .getGeneratorFrame (virtualFrame );
2988
+ }
2989
+ Object localsDict = pyFrame .getLocalsDict ();
2990
+ copyLocalsArray (localFrame , localsDict , varnames , 0 , false );
2991
+ copyLocalsArray (localFrame , localsDict , cellvars , celloffset , true );
2992
+ copyLocalsArray (localFrame , localsDict , freevars , freeoffset , true );
2993
+ }
2994
+
2995
+ private static void copyLocalsArray (Frame localFrame , Object localsDict , TruffleString [] namesArray , int offset , boolean deref ) {
2996
+ for (int i = 0 ; i < namesArray .length ; i ++) {
2997
+ TruffleString varname = namesArray [i ];
2998
+ Object value = null ;
2999
+ try {
3000
+ value = PyObjectGetItem .getUncached ().execute (null , localsDict , varname );
3001
+ } catch (AbstractTruffleException e ) {
3002
+ // CPython ignores all exceptions
3003
+ }
3004
+ if (deref ) {
3005
+ PCell cell = (PCell ) localFrame .getObject (offset + i );
3006
+ cell .setRef (value );
3007
+ } else {
3008
+ localFrame .setObject (offset + i , value );
3009
+ }
3010
+ }
3011
+ }
3012
+
2979
3013
private void profileCEvent (VirtualFrame virtualFrame , Object callable , PythonContext .ProfileEvent event , MutableLoopData mutableData , boolean profilingEnabled ) {
2980
3014
if (profilingEnabled ) {
2981
3015
profileCEvent (virtualFrame , callable , event , mutableData );
@@ -3012,7 +3046,10 @@ private void invokeProfileFunction(VirtualFrame virtualFrame, Object arg, Python
3012
3046
}
3013
3047
3014
3048
try {
3049
+ // Force locals dict sync, so that we can sync them back later
3050
+ GetFrameLocalsNode .getUncached ().execute (pyFrame );
3015
3051
Object result = CallTernaryMethodNode .getUncached ().execute (null , profileFun , pyFrame , event .name , arg == null ? PNone .NONE : arg );
3052
+ syncLocalsBack (virtualFrame , pyFrame );
3016
3053
Object realResult = result == PNone .NONE ? null : result ;
3017
3054
pyFrame .setLocalTraceFun (realResult );
3018
3055
} catch (Throwable e ) {
0 commit comments