Skip to content

Commit 996eca2

Browse files
committed
Start transition to new CodeRef handling.
This doesn't rip out any of the "old way", just starts using the new annotation for code ref static info instead.
1 parent 66f45f7 commit 996eca2

File tree

5 files changed

+129
-32
lines changed

5 files changed

+129
-32
lines changed

src/vm/jvm/QAST/Compiler.nqp

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3061,9 +3061,9 @@ class QAST::CompilerJAST {
30613061
# Compile to JAST and register this block as the deserialization
30623062
# handler.
30633063
self.as_jast($block);
3064-
my $des_meth := JAST::Method.new( :name('deserializeIdx'), :returns('Integer'), :static(0) );
3065-
$des_meth.append(JAST::PushIndex.new( :value($*CODEREFS.cuid_to_idx($block.cuid)) ));
3066-
$des_meth.append(JAST::Instruction.new( :op('ireturn') ));
3064+
my $des_meth := JAST::Method.new( :name('deserializeCuid'), :returns($TYPE_STR), :static(0) );
3065+
$des_meth.append(JAST::PushSVal.new( :value($block.cuid) ));
3066+
$des_meth.append(JAST::Instruction.new( :op('areturn') ));
30673067
$*JCLASS.add_method($des_meth);
30683068
}
30693069

@@ -3075,9 +3075,9 @@ class QAST::CompilerJAST {
30753075
QAST::Op.new( :op('null') )
30763076
);
30773077
self.as_jast($load_block);
3078-
my $load_meth := JAST::Method.new( :name('loadIdx'), :returns('Integer'), :static(0) );
3079-
$load_meth.append(JAST::PushIndex.new( :value($*CODEREFS.cuid_to_idx($load_block.cuid)) ));
3080-
$load_meth.append(JAST::Instruction.new( :op('ireturn') ));
3078+
my $load_meth := JAST::Method.new( :name('loadCuid'), :returns($TYPE_STR), :static(0) );
3079+
$load_meth.append(JAST::PushSVal.new( :value($load_block.cuid) ));
3080+
$load_meth.append(JAST::Instruction.new( :op('areturn') ));
30813081
$*JCLASS.add_method($load_meth);
30823082
}
30833083

@@ -3109,9 +3109,9 @@ class QAST::CompilerJAST {
31093109
$*JCLASS.add_method($hll_meth);
31103110

31113111
# Add method that returns the mainline block.
3112-
my $mainline_meth := JAST::Method.new( :name('mainlineIdx'), :returns('Integer'), :static(0) );
3113-
$mainline_meth.append(JAST::PushIndex.new( :value($*CODEREFS.cuid_to_idx($cu[0].cuid)) ));
3114-
$mainline_meth.append(JAST::Instruction.new( :op('ireturn') ));
3112+
my $mainline_meth := JAST::Method.new( :name('mainlineCuid'), :returns($TYPE_STR), :static(0) );
3113+
$mainline_meth.append(JAST::PushSVal.new( :value($cu[0].cuid) ));
3114+
$mainline_meth.append(JAST::Instruction.new( :op('areturn') ));
31153115
$*JCLASS.add_method($mainline_meth);
31163116

31173117
return $*JCLASS;
@@ -3386,8 +3386,11 @@ class QAST::CompilerJAST {
33863386
$*BLOCK_TA.add_temps_to_method($*JMETH);
33873387

33883388
# Flatten handlers and store.
3389-
my @flat_handlers;
3390-
for @handlers { for $_ { nqp::push(@flat_handlers, $_) } }
3389+
my @flat_handlers := [nqp::elems(@handlers)];
3390+
for @handlers {
3391+
nqp::push(@flat_handlers, nqp::elems($_));
3392+
for $_ { nqp::push(@flat_handlers, $_) }
3393+
}
33913394
$*JMETH.cr_handlers(@flat_handlers);
33923395

33933396
# Add method body JAST.

src/vm/jvm/QAST/JASTNodes.nqp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,9 @@ class JAST::Method is JAST::Node {
128128
@!arguments := [];
129129
@!locals := [];
130130
@!instructions := [];
131+
$!cr_name := '';
132+
$!cr_cuid := '';
133+
$!cr_outer := '';
131134
@!cr_olex := [];
132135
@!cr_ilex := [];
133136
@!cr_nlex := [];

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ else if (curLine.startsWith("++ handlers ")) {
244244
methodName, desc, null, null);
245245

246246
// Add code ref info annotation.
247-
if (crName != null) {
247+
if (crCuid != null && !crCuid.equals("")) {
248248
Type crAnnType = Type.getType("Lorg/perl6/nqp/runtime/CodeRefAnnotation;");
249249
AnnotationVisitor av = m.visitAnnotation(crAnnType.getDescriptor(), true);
250250
av.visit("name", crName);

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

Lines changed: 107 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
package org.perl6.nqp.runtime;
22

3+
import java.lang.annotation.*;
4+
import java.lang.invoke.MethodHandle;
5+
import java.lang.invoke.MethodHandles;
6+
import java.lang.invoke.MethodHandles.Lookup;
7+
import java.lang.reflect.Method;
8+
import java.util.ArrayList;
39
import java.util.HashMap;
410
import java.util.Map;
511

@@ -58,20 +64,75 @@ public static CompilationUnit setupCompilationUnit(ThreadContext tc, Class<?> cu
5864
* Does initialization work for the compilation unit.
5965
*/
6066
public void initializeCompilationUnit(ThreadContext tc) {
61-
/* Place code references into a lookup table by unique ID. Also
62-
* make sure each code ref has the appropriate STable. */
67+
/* Look through methods for code refs. */
6368
STable BOOTCodeSTable = tc.gc.BOOTCode == null ? null : tc.gc.BOOTCode.st;
64-
codeRefs = getCodeRefs();
65-
for (CodeRef c : codeRefs) {
66-
c.st = BOOTCodeSTable;
67-
cuidToCodeRef.put(c.staticInfo.uniqueId, c);
69+
ArrayList<CodeRef> codeRefList = new ArrayList<CodeRef>();
70+
ArrayList<String> outerCuid = new ArrayList<String>();
71+
Lookup l = MethodHandles.lookup();
72+
boolean codeRefsFound = false;
73+
try {
74+
for (Method m : this.getClass().getDeclaredMethods()) {
75+
if (m.isAnnotationPresent(CodeRefAnnotation.class)) {
76+
/* Got a code ref annotation. Turn to method handle. */
77+
CodeRefAnnotation cra = m.getAnnotation(CodeRefAnnotation.class);
78+
MethodHandle mh = l.unreflect(m).bindTo(this);
79+
80+
/* Munge handlers. */
81+
long[] flatHandlers = cra.handlers();
82+
int hptr = 0;
83+
int numHandlers = (int)flatHandlers[hptr++];
84+
long[][] handlers = new long[numHandlers][];
85+
for (int i = 0; i < numHandlers; i++) {
86+
int handlerThings = (int)flatHandlers[hptr++];
87+
handlers[i] = new long[handlerThings];
88+
for (int j = 0; j < handlerThings; j++)
89+
handlers[i][j] = flatHandlers[hptr++];
90+
}
91+
92+
/* Create and store. */
93+
String cuid = cra.cuid();
94+
CodeRef cr = new CodeRef(this, mh, cra.name(), cuid,
95+
cra.oLexicalNames(), cra.iLexicalNames(),
96+
cra.nLexicalNames(), cra.sLexicalNames(),
97+
handlers);
98+
cr.st = BOOTCodeSTable;
99+
codeRefList.add(cr);
100+
cuidToCodeRef.put(cuid, cr);
101+
102+
/* Stash outer, for later resolution. */
103+
outerCuid.add(cra.outerCuid());
104+
105+
codeRefsFound = true;
106+
}
107+
}
108+
109+
/* Resolve outers. */
110+
codeRefs = codeRefList.toArray(new CodeRef[0]);
111+
for (int i = 0; i < codeRefs.length; i++) {
112+
CodeRef outer = cuidToCodeRef.get(outerCuid.get(i));
113+
if (outer != null)
114+
codeRefs[i].staticInfo.outerStaticInfo = outer.staticInfo;
115+
}
116+
}
117+
catch (Throwable e) {
118+
e.printStackTrace();
119+
throw new RuntimeException(e);
68120
}
69121

70-
/* Wire up outer relationships. */
71-
int[] outerMap = getOuterMap();
72-
for (int i = 0; i < outerMap.length; i += 2)
73-
codeRefs[outerMap[i]].staticInfo.outerStaticInfo =
74-
codeRefs[outerMap[i + 1]].staticInfo;
122+
/* If we didn't find any by annotations, this is the fallback. */
123+
if (!codeRefsFound) {
124+
codeRefs = getCodeRefs();
125+
for (CodeRef c : codeRefs) {
126+
c.st = BOOTCodeSTable;
127+
cuidToCodeRef.put(c.staticInfo.uniqueId, c);
128+
}
129+
130+
/* Wire up outer relationships. */
131+
int[] outerMap = getOuterMap();
132+
for (int i = 0; i < outerMap.length; i += 2)
133+
codeRefs[outerMap[i]].staticInfo.outerStaticInfo =
134+
codeRefs[outerMap[i + 1]].staticInfo;
135+
}
75136

76137
/* Build callsite descriptors. */
77138
callSites = getCallSites();
@@ -80,29 +141,47 @@ public void initializeCompilationUnit(ThreadContext tc) {
80141
hllConfig = tc.gc.getHLLConfigFor(this.hllName());
81142

82143
/* Run any deserialization code. */
83-
int dIdx = deserializeIdx();
84-
if (dIdx >= 0)
144+
CodeRef desCodeRef = null;
145+
String desCuid = deserializeCuid();
146+
if (desCuid != null) {
147+
desCodeRef = lookupCodeRef(desCuid);
148+
}
149+
else {
150+
int dIdx = deserializeIdx();
151+
if (dIdx >= 0)
152+
desCodeRef = codeRefs[dIdx];
153+
}
154+
if (desCodeRef != null)
85155
try {
86-
Ops.invokeArgless(tc, codeRefs[dIdx]);
156+
Ops.invokeArgless(tc, desCodeRef);
87157
}
88158
catch (Exception e)
89159
{
90-
throw ExceptionHandling.dieInternal(tc, e.getMessage());
160+
throw ExceptionHandling.dieInternal(tc, e.toString());
91161
}
92162
}
93163

94164
/**
95165
* Runs code in the on-load hook, if one is available.
96166
*/
97167
public void runLoadIfAvailable(ThreadContext tc) {
98-
int lIdx = loadIdx();
99-
if (lIdx >= 0)
168+
CodeRef loadCodeRef = null;
169+
String loadCuid = loadCuid();
170+
if (loadCuid != null) {
171+
loadCodeRef = lookupCodeRef(loadCuid);
172+
}
173+
else {
174+
int lIdx = loadIdx();
175+
if (lIdx >= 0)
176+
loadCodeRef = codeRefs[lIdx];
177+
}
178+
if (loadCodeRef != null)
100179
try {
101-
Ops.invokeArgless(tc, codeRefs[lIdx]);
180+
Ops.invokeArgless(tc, loadCodeRef);
102181
}
103182
catch (Exception e)
104183
{
105-
throw ExceptionHandling.dieInternal(tc, e.getMessage());
184+
throw ExceptionHandling.dieInternal(tc, e.toString());
106185
}
107186
}
108187

@@ -189,18 +268,27 @@ public void setLexValue(String uniqueId, String name, String scHandle, int scIdx
189268
public int deserializeIdx() {
190269
return -1;
191270
}
271+
public String deserializeCuid() {
272+
return null;
273+
}
192274

193275
/**
194276
* Code generation overrides this if there's an SC to deserialize.
195277
*/
196278
public int loadIdx() {
197279
return -1;
198280
}
281+
public String loadCuid() {
282+
return null;
283+
}
199284

200285
/**
201286
* Code generation overrides this with the mainline blcok.
202287
*/
203288
public int mainlineIdx() {
204289
return -1;
205290
}
291+
public String mainlineCuid() {
292+
return null;
293+
}
206294
}

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4017,7 +4017,10 @@ public static long iscompunit(SixModelObject obj, ThreadContext tc) {
40174017
}
40184018
public static SixModelObject compunitmainline(SixModelObject obj, ThreadContext tc) {
40194019
EvalResult res = (EvalResult)obj;
4020-
return res.cu.codeRefs[res.cu.mainlineIdx()];
4020+
int mIdx = res.cu.mainlineIdx();
4021+
if (mIdx >= 0)
4022+
return res.cu.codeRefs[mIdx];
4023+
return res.cu.lookupCodeRef(res.cu.mainlineCuid());
40214024
}
40224025
public static SixModelObject compunitcodes(SixModelObject obj, ThreadContext tc) {
40234026
EvalResult res = (EvalResult)obj;

0 commit comments

Comments
 (0)