1
1
package org .perl6 .nqp .runtime ;
2
2
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 ;
3
9
import java .util .HashMap ;
4
10
import java .util .Map ;
5
11
@@ -58,20 +64,75 @@ public static CompilationUnit setupCompilationUnit(ThreadContext tc, Class<?> cu
58
64
* Does initialization work for the compilation unit.
59
65
*/
60
66
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. */
63
68
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 );
68
120
}
69
121
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
+ }
75
136
76
137
/* Build callsite descriptors. */
77
138
callSites = getCallSites ();
@@ -80,29 +141,47 @@ public void initializeCompilationUnit(ThreadContext tc) {
80
141
hllConfig = tc .gc .getHLLConfigFor (this .hllName ());
81
142
82
143
/* 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 )
85
155
try {
86
- Ops .invokeArgless (tc , codeRefs [ dIdx ] );
156
+ Ops .invokeArgless (tc , desCodeRef );
87
157
}
88
158
catch (Exception e )
89
159
{
90
- throw ExceptionHandling .dieInternal (tc , e .getMessage ());
160
+ throw ExceptionHandling .dieInternal (tc , e .toString ());
91
161
}
92
162
}
93
163
94
164
/**
95
165
* Runs code in the on-load hook, if one is available.
96
166
*/
97
167
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 )
100
179
try {
101
- Ops .invokeArgless (tc , codeRefs [ lIdx ] );
180
+ Ops .invokeArgless (tc , loadCodeRef );
102
181
}
103
182
catch (Exception e )
104
183
{
105
- throw ExceptionHandling .dieInternal (tc , e .getMessage ());
184
+ throw ExceptionHandling .dieInternal (tc , e .toString ());
106
185
}
107
186
}
108
187
@@ -189,18 +268,27 @@ public void setLexValue(String uniqueId, String name, String scHandle, int scIdx
189
268
public int deserializeIdx () {
190
269
return -1 ;
191
270
}
271
+ public String deserializeCuid () {
272
+ return null ;
273
+ }
192
274
193
275
/**
194
276
* Code generation overrides this if there's an SC to deserialize.
195
277
*/
196
278
public int loadIdx () {
197
279
return -1 ;
198
280
}
281
+ public String loadCuid () {
282
+ return null ;
283
+ }
199
284
200
285
/**
201
286
* Code generation overrides this with the mainline blcok.
202
287
*/
203
288
public int mainlineIdx () {
204
289
return -1 ;
205
290
}
291
+ public String mainlineCuid () {
292
+ return null ;
293
+ }
206
294
}
0 commit comments