Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Misc bugfixes
  • Loading branch information
sorear committed Jun 15, 2013
1 parent 580a904 commit b37f6f2
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 14 deletions.
35 changes: 22 additions & 13 deletions src/vm/jvm/QAST/Compiler.nqp
Expand Up @@ -3133,16 +3133,6 @@ class QAST::CompilerJAST {
$*JMETH.cr_nlex(@lex_names[$RT_NUM]);
$*JMETH.cr_slex(@lex_names[$RT_STR]);

# Emit prelude. This creates and stashes the CallFrame.
$*JMETH.add_local('cf', $TYPE_CF);
$*JMETH.append(JAST::Instruction.new( :op('new'), $TYPE_CF ));
$*JMETH.append($DUP);
$*JMETH.append($ALOAD_1);
$*JMETH.append(JAST::Instruction.new( :op('aload'), 'cr' ));
$*JMETH.append(JAST::Instruction.new( :op('invokespecial'), $TYPE_CF, '<init>',
'Void', $TYPE_TC, $TYPE_CR ));
$*JMETH.append(JAST::Instruction.new( :op('astore'), 'cf' ));

# Unless we have custom args processing...
my $il := JAST::InstructionList.new();
unless $node.custom_args {
Expand Down Expand Up @@ -3302,6 +3292,16 @@ class QAST::CompilerJAST {
$*JMETH.append(JAST::Instruction.new( :op('ifnonnull'), JAST::Label.new( :name('RESUME') ) ));
}

# Emit prelude (after checking for resume). This creates and stashes the CallFrame.
$*JMETH.add_local('cf', $TYPE_CF);
$*JMETH.append(JAST::Instruction.new( :op('new'), $TYPE_CF ));
$*JMETH.append($DUP);
$*JMETH.append($ALOAD_1);
$*JMETH.append(JAST::Instruction.new( :op('aload'), 'cr' ));
$*JMETH.append(JAST::Instruction.new( :op('invokespecial'), $TYPE_CF, '<init>',
'Void', $TYPE_TC, $TYPE_CR ));
$*JMETH.append(JAST::Instruction.new( :op('astore'), 'cf' ));

# Emit the postlude. We catch any exceptions. Control ones are
# rethrown, after calling CallFrame.leave. Others are passed on to
# dieInternal. Finally, if there's no exception, we also need to
Expand Down Expand Up @@ -3336,8 +3336,11 @@ class QAST::CompilerJAST {
$saver.append($ACONST_NULL);

my @merged;
for $*JMETH.arguments { nqp::push(@merged, $_); }
for $*JMETH.locals { nqp::push(@merged, $_); }
# don't save/reload the resume pointer (could get messy :p) or the thread context (restored separately since we can change threads)
# or the callframe (can also change)
# also self doesn't get saved/restored, but that's OK because the resume handle is primed with it.
for $*JMETH.arguments { nqp::push(@merged, $_) unless $_[0] eq 'resume' || $_[0] eq 'tc' }
for $*JMETH.locals { nqp::push(@merged, $_) unless $_[0] eq 'cf' }

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

$resume.append(JAST::Label.new( :name( 'RESUME' ) ));
$resume.append(JAST::Instruction.new( :op('aload'), 'resume' ));
$resume.append(JAST::Instruction.new( :op('getfield'), $TYPE_RESUME, 'tc', $TYPE_TC ));
$resume.append(JAST::Instruction.new( :op('astore'), 'tc' ));
$resume.append(JAST::Instruction.new( :op('aload'), 'resume' ));
$resume.append(JAST::Instruction.new( :op('getfield'), $TYPE_RESUME, 'callFrame', $TYPE_CF ));
$resume.append(JAST::Instruction.new( :op('astore'), 'cf' ));
$resume.append(JAST::Instruction.new( :op('aload'), 'resume' ));
$resume.append(JAST::Instruction.new( :op('getfield'), $TYPE_RESUME, 'saveSpace', '['~$TYPE_OBJ ));

for @merged {
Expand Down Expand Up @@ -3395,7 +3404,7 @@ class QAST::CompilerJAST {

$resume.append(JAST::Instruction.new( :op('aload'), 'resume' ));
$resume.append(JAST::Instruction.new( :op('invokevirtual'),
$TYPE_RESUME, 'resumeNext', 'Void' ));
$TYPE_RESUME, 'resumeNextSave', 'Void' ));

$resume.append(JAST::Instruction.new( :op('aload'), 'resume' ));
$resume.append(JAST::Instruction.new( :op('getfield'), $TYPE_RESUME, 'resumePoint', 'Integer' ));
Expand Down
2 changes: 1 addition & 1 deletion src/vm/jvm/runtime/org/perl6/nqp/runtime/Ops.java
Expand Up @@ -4167,7 +4167,6 @@ public static void continuationreset(SixModelObject key, SixModelObject run, Thr

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

STable contType = tc.gc.Continuation.st;
Expand Down
9 changes: 9 additions & 0 deletions src/vm/jvm/runtime/org/perl6/nqp/runtime/ResumeStatus.java
Expand Up @@ -54,6 +54,15 @@ public void resumeNext() throws Throwable {
Ops.invokeDirect(tc, thunk, Ops.emptyCallSite, false, Ops.emptyArgList);
}
}

/** Restores the next frame. If it suspends, put this frame on the new continuation. */
public void resumeNextSave() throws Throwable {
try {
resumeNext();
} catch (SaveStackException sse) {
throw sse.pushFrame(resumePoint, method, saveSpace, callFrame);
}
}
}

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

0 comments on commit b37f6f2

Please sign in to comment.