Skip to content

Commit e47d0bf

Browse files
committed
Infrastructure to support LEAVE and friends.
1 parent 754bc44 commit e47d0bf

File tree

10 files changed

+39
-1
lines changed

10 files changed

+39
-1
lines changed

src/QAST/Block.nqp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ class QAST::Block is QAST::Node {
22
has str $!name;
33
has str $!blocktype;
44
has int $!custom_args;
5+
has int $!has_exit_handler;
56
has str $!cuid;
67
has %!symbol;
78

@@ -14,6 +15,7 @@ class QAST::Block is QAST::Node {
1415
nqp::isnull_s($!blocktype) ?? "" !! $!blocktype
1516
}
1617
method custom_args(*@value) { $!custom_args := @value[0] if @value; $!custom_args }
18+
method has_exit_handler(*@value) { $!has_exit_handler := @value[0] if @value; $!has_exit_handler }
1719

1820
my $cur_cuid := 0;
1921
my $cuid_suffix := ~nqp::time_n();

src/vm/jvm/QAST/Compiler.nqp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3484,6 +3484,11 @@ class QAST::CompilerJAST {
34843484
$*JMETH.append($resume);
34853485
}
34863486

3487+
# Set exit handler flag if needed.
3488+
if $node.has_exit_handler {
3489+
$*JMETH.has_exit_handler(1);
3490+
}
3491+
34873492
# Finalize method and add it to the class.
34883493
$*JCLASS.add_method($*JMETH);
34893494
}

src/vm/jvm/QAST/JASTNodes.nqp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ class JAST::Method is JAST::Node {
113113
has @!cr_nlex;
114114
has @!cr_slex;
115115
has @!cr_handlers;
116+
has int $!has_exit_handler;
116117

117118
method BUILD(:$name!, :$returns!, :$static = 1) {
118119
$!name := $name;
@@ -159,6 +160,7 @@ class JAST::Method is JAST::Node {
159160
method cr_nlex(*@value) { @value ?? (@!cr_nlex := @value[0]) !! @!cr_nlex }
160161
method cr_slex(*@value) { @value ?? (@!cr_slex := @value[0]) !! @!cr_slex }
161162
method cr_handlers(*@value) { @value ?? (@!cr_handlers := @value[0]) !! @!cr_handlers }
163+
method has_exit_handler(*@value) { $!has_exit_handler := @value[0] if @value; $!has_exit_handler }
162164

163165
method dump(@dumped) {
164166
nqp::push(@dumped, "+ method");
@@ -181,6 +183,9 @@ class JAST::Method is JAST::Node {
181183
for @!cr_nlex { nqp::push(@dumped, "++ nlex $_"); }
182184
for @!cr_slex { nqp::push(@dumped, "++ slex $_"); }
183185
nqp::push(@dumped, "++ handlers " ~ join(' ', @!cr_handlers));
186+
if $!has_exit_handler {
187+
nqp::push(@dumped, "++ has_exit_handler");
188+
}
184189
for @!instructions {
185190
$_.dump(@dumped);
186191
}

src/vm/jvm/runtime/org/perl6/nqp/jast2bc/JASTToJVMBytecode.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ private static boolean processMethod(JavaClass jcout, BufferedReader in, ClassWr
200200
Label endAll = new Label();
201201
long[] crHandlers = null;
202202
int curArgIndex = 1;
203+
boolean hasExitHandler = false;
203204

204205
MethodVisitor m = null;
205206
boolean contAfter = false;
@@ -262,6 +263,8 @@ else if (curLine.startsWith("++ handlers ")) {
262263
crHandlers = new long[0];
263264
}
264265
}
266+
else if (curLine.startsWith("++ has_exit_handler"))
267+
hasExitHandler = true;
265268
else
266269
throw new Exception("Cannot understand '" + curLine + "'");
267270
continue;
@@ -316,6 +319,7 @@ else if (curLine.startsWith("++ handlers ")) {
316319
}
317320

318321
if (crHandlers.length != 1 || crHandlers[0] != 0) av.visit("handlers", crHandlers);
322+
if (hasExitHandler) av.visit("hasExitHandler", hasExitHandler);
319323
av.visitEnd();
320324
}
321325

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,8 +222,16 @@ public void autoClose(StaticCodeInfo wanted) {
222222
}
223223

224224
// Does work needed to leave this callframe.
225+
private static final CallSiteDescriptor exitHandlerCallSite = new CallSiteDescriptor(
226+
new byte[] { CallSiteDescriptor.ARG_OBJ, CallSiteDescriptor.ARG_OBJ }, null);
225227
public void leave() {
226-
this.codeRef.staticInfo.priorInvocation = this;
228+
StaticCodeInfo sci = this.codeRef.staticInfo;
229+
sci.priorInvocation = this;
230+
if (sci.hasExitHandler) {
231+
HLLConfig hll = sci.compUnit.hllConfig;
232+
Ops.invokeDirect(tc, hll.exitHandler, exitHandlerCallSite,
233+
new Object[] { this.codeRef, Ops.result_o(this.caller) });
234+
}
227235
this.tc.curFrame = this.caller;
228236
}
229237

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@
1414
String[] nLexicalNames() default {};
1515
String[] sLexicalNames() default {};
1616
long[] handlers() default {0};
17+
boolean hasExitHandler() default false;
1718
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ public void initializeCompilationUnit(ThreadContext tc) {
9494
ann.nLexicalNames(), ann.sLexicalNames(),
9595
m.handlers);
9696
cr.staticInfo.methodName = m.methodName;
97+
cr.staticInfo.hasExitHandler = ann.hasExitHandler();
9798
cr.st = BOOTCodeSTable;
9899
codeRefList.add(cr);
99100

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,4 +85,9 @@ public class HLLConfig {
8585
public SixModelObject foreignTransformHash;
8686
public SixModelObject foreignTransformCode;
8787
public SixModelObject foreignTransformAny;
88+
89+
/**
90+
* Block exit handler, for those that need it.
91+
*/
92+
public SixModelObject exitHandler;
8893
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3920,6 +3920,8 @@ public static SixModelObject sethllconfig(String language, SixModelObject config
39203920
config.foreignTransformAny = configHash.at_key_boxed(tc, "foreign_transform_any");
39213921
if (configHash.exists_key(tc, "null_value") != 0)
39223922
config.nullValue = configHash.at_key_boxed(tc, "null_value");
3923+
if (configHash.exists_key(tc, "exit_handler") != 0)
3924+
config.exitHandler = configHash.at_key_boxed(tc, "exit_handler");
39233925
return configHash;
39243926
}
39253927
public static SixModelObject getcomp(String name, ThreadContext tc) {

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ public class StaticCodeInfo implements Cloneable {
8080
public HashMap<String, Integer> nLexicalMap;
8181
public HashMap<String, Integer> sLexicalMap;
8282

83+
/**
84+
* Does this code object have a block exit handler?
85+
*/
86+
public boolean hasExitHandler;
87+
8388
public Integer oTryGetLexicalIdx(String name) {
8489
if (oLexicalMap == null) {
8590
HashMap<String, Integer> map = new HashMap<String, Integer>();

0 commit comments

Comments
 (0)