Skip to content

Commit b37f6f2

Browse files
committed
Misc bugfixes
1 parent 580a904 commit b37f6f2

File tree

3 files changed

+32
-14
lines changed

3 files changed

+32
-14
lines changed

src/vm/jvm/QAST/Compiler.nqp

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3133,16 +3133,6 @@ class QAST::CompilerJAST {
31333133
$*JMETH.cr_nlex(@lex_names[$RT_NUM]);
31343134
$*JMETH.cr_slex(@lex_names[$RT_STR]);
31353135

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-
31463136
# Unless we have custom args processing...
31473137
my $il := JAST::InstructionList.new();
31483138
unless $node.custom_args {
@@ -3302,6 +3292,16 @@ class QAST::CompilerJAST {
33023292
$*JMETH.append(JAST::Instruction.new( :op('ifnonnull'), JAST::Label.new( :name('RESUME') ) ));
33033293
}
33043294

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+
33053305
# Emit the postlude. We catch any exceptions. Control ones are
33063306
# rethrown, after calling CallFrame.leave. Others are passed on to
33073307
# dieInternal. Finally, if there's no exception, we also need to
@@ -3336,8 +3336,11 @@ class QAST::CompilerJAST {
33363336
$saver.append($ACONST_NULL);
33373337

33383338
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' }
33413344

33423345
my int $i := 0;
33433346
my int $ict := +@merged;
@@ -3347,6 +3350,12 @@ class QAST::CompilerJAST {
33473350

33483351
$resume.append(JAST::Label.new( :name( 'RESUME' ) ));
33493352
$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' ));
33503359
$resume.append(JAST::Instruction.new( :op('getfield'), $TYPE_RESUME, 'saveSpace', '['~$TYPE_OBJ ));
33513360

33523361
for @merged {
@@ -3395,7 +3404,7 @@ class QAST::CompilerJAST {
33953404

33963405
$resume.append(JAST::Instruction.new( :op('aload'), 'resume' ));
33973406
$resume.append(JAST::Instruction.new( :op('invokevirtual'),
3398-
$TYPE_RESUME, 'resumeNext', 'Void' ));
3407+
$TYPE_RESUME, 'resumeNextSave', 'Void' ));
33993408

34003409
$resume.append(JAST::Instruction.new( :op('aload'), 'resume' ));
34013410
$resume.append(JAST::Instruction.new( :op('getfield'), $TYPE_RESUME, 'resumePoint', 'Integer' ));

src/vm/jvm/runtime/org/perl6/nqp/runtime/Ops.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4167,7 +4167,6 @@ public static void continuationreset(SixModelObject key, SixModelObject run, Thr
41674167

41684168
if (resume != null) {
41694169
// reload stuff here, then don't goto because java source doesn't have that
4170-
// XXX: compiler should be modified to take ThreadContext from continuation, NOT RELOAD RESUME..., wrap resumeNext in an appropriate handler
41714170
Object[] bits = resume.saveSpace;
41724171
key = (SixModelObject) bits[0];
41734172
tc = resume.tc;
@@ -4221,6 +4220,7 @@ public static SixModelObject continuationclone(SixModelObject in, ThreadContext
42214220
nroot = nnew;
42224221
}
42234222
ntail = nnew;
4223+
read = read.next;
42244224
}
42254225

42264226
STable contType = tc.gc.Continuation.st;

src/vm/jvm/runtime/org/perl6/nqp/runtime/ResumeStatus.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,15 @@ public void resumeNext() throws Throwable {
5454
Ops.invokeDirect(tc, thunk, Ops.emptyCallSite, false, Ops.emptyArgList);
5555
}
5656
}
57+
58+
/** Restores the next frame. If it suspends, put this frame on the new continuation. */
59+
public void resumeNextSave() throws Throwable {
60+
try {
61+
resumeNext();
62+
} catch (SaveStackException sse) {
63+
throw sse.pushFrame(resumePoint, method, saveSpace, callFrame);
64+
}
65+
}
5766
}
5867

5968
/** The first frame of this continuation. Subsequent frames can be accessed using {@link Frame#next}. */

0 commit comments

Comments
 (0)