@@ -3133,16 +3133,6 @@ class QAST::CompilerJAST {
3133
3133
$ * JMETH . cr_nlex(@ lex_names [$ RT_NUM ]);
3134
3134
$ * JMETH . cr_slex(@ lex_names [$ RT_STR ]);
3135
3135
3136
- # Emit prelude. This creates and stashes the CallFrame.
3137
- $ * JMETH . add_local(' cf' , $ TYPE_CF );
3138
- $ * JMETH . append (JAST::Instruction. new ( : op(' new' ), $ TYPE_CF ));
3139
- $ * JMETH . append ($ DUP );
3140
- $ * JMETH . append ($ ALOAD_1 );
3141
- $ * JMETH . append (JAST::Instruction. new ( : op(' aload' ), ' cr' ));
3142
- $ * JMETH . append (JAST::Instruction. new ( : op(' invokespecial' ), $ TYPE_CF , ' <init>' ,
3143
- ' Void' , $ TYPE_TC , $ TYPE_CR ));
3144
- $ * JMETH . append (JAST::Instruction. new ( : op(' astore' ), ' cf' ));
3145
-
3146
3136
# Unless we have custom args processing...
3147
3137
my $ il := JAST::InstructionList. new ();
3148
3138
unless $ node . custom_args {
@@ -3302,6 +3292,16 @@ class QAST::CompilerJAST {
3302
3292
$ * JMETH . append (JAST::Instruction. new ( : op(' ifnonnull' ), JAST::Label. new ( : name(' RESUME' ) ) ));
3303
3293
}
3304
3294
3295
+ # Emit prelude (after checking for resume). This creates and stashes the CallFrame.
3296
+ $ * JMETH . add_local(' cf' , $ TYPE_CF );
3297
+ $ * JMETH . append (JAST::Instruction. new ( : op(' new' ), $ TYPE_CF ));
3298
+ $ * JMETH . append ($ DUP );
3299
+ $ * JMETH . append ($ ALOAD_1 );
3300
+ $ * JMETH . append (JAST::Instruction. new ( : op(' aload' ), ' cr' ));
3301
+ $ * JMETH . append (JAST::Instruction. new ( : op(' invokespecial' ), $ TYPE_CF , ' <init>' ,
3302
+ ' Void' , $ TYPE_TC , $ TYPE_CR ));
3303
+ $ * JMETH . append (JAST::Instruction. new ( : op(' astore' ), ' cf' ));
3304
+
3305
3305
# Emit the postlude. We catch any exceptions. Control ones are
3306
3306
# rethrown, after calling CallFrame.leave. Others are passed on to
3307
3307
# dieInternal. Finally, if there's no exception, we also need to
@@ -3336,8 +3336,11 @@ class QAST::CompilerJAST {
3336
3336
$ saver . append ($ ACONST_NULL );
3337
3337
3338
3338
my @ merged ;
3339
- for $ * JMETH . arguments { nqp :: push (@ merged , $ _ ); }
3340
- for $ * JMETH . locals { nqp :: push (@ merged , $ _ ); }
3339
+ # don't save/reload the resume pointer (could get messy :p) or the thread context (restored separately since we can change threads)
3340
+ # or the callframe (can also change)
3341
+ # also self doesn't get saved/restored, but that's OK because the resume handle is primed with it.
3342
+ for $ * JMETH . arguments { nqp :: push (@ merged , $ _ ) unless $ _ [0 ] eq ' resume' || $ _ [0 ] eq ' tc' }
3343
+ for $ * JMETH . locals { nqp :: push (@ merged , $ _ ) unless $ _ [0 ] eq ' cf' }
3341
3344
3342
3345
my int $ i := 0 ;
3343
3346
my int $ ict := + @ merged ;
@@ -3347,6 +3350,12 @@ class QAST::CompilerJAST {
3347
3350
3348
3351
$ resume . append (JAST::Label. new ( : name( ' RESUME' ) ));
3349
3352
$ resume . append (JAST::Instruction. new ( : op(' aload' ), ' resume' ));
3353
+ $ resume . append (JAST::Instruction. new ( : op(' getfield' ), $ TYPE_RESUME , ' tc' , $ TYPE_TC ));
3354
+ $ resume . append (JAST::Instruction. new ( : op(' astore' ), ' tc' ));
3355
+ $ resume . append (JAST::Instruction. new ( : op(' aload' ), ' resume' ));
3356
+ $ resume . append (JAST::Instruction. new ( : op(' getfield' ), $ TYPE_RESUME , ' callFrame' , $ TYPE_CF ));
3357
+ $ resume . append (JAST::Instruction. new ( : op(' astore' ), ' cf' ));
3358
+ $ resume . append (JAST::Instruction. new ( : op(' aload' ), ' resume' ));
3350
3359
$ resume . append (JAST::Instruction. new ( : op(' getfield' ), $ TYPE_RESUME , ' saveSpace' , ' [' ~ $ TYPE_OBJ ));
3351
3360
3352
3361
for @ merged {
@@ -3395,7 +3404,7 @@ class QAST::CompilerJAST {
3395
3404
3396
3405
$ resume . append (JAST::Instruction. new ( : op(' aload' ), ' resume' ));
3397
3406
$ resume . append (JAST::Instruction. new ( : op(' invokevirtual' ),
3398
- $ TYPE_RESUME , ' resumeNext ' , ' Void' ));
3407
+ $ TYPE_RESUME , ' resumeNextSave ' , ' Void' ));
3399
3408
3400
3409
$ resume . append (JAST::Instruction. new ( : op(' aload' ), ' resume' ));
3401
3410
$ resume . append (JAST::Instruction. new ( : op(' getfield' ), $ TYPE_RESUME , ' resumePoint' , ' Integer' ));
0 commit comments