~ubuntu-branches/ubuntu/vivid/nqp/vivid-proposed

« back to all changes in this revision

Viewing changes to src/vm/jvm/runtime/org/perl6/nqp/runtime/IndyBootstrap.java

  • Committer: Package Import Robot
  • Author(s): Alessandro Ghedini
  • Date: 2013-11-01 12:09:18 UTC
  • mfrom: (1.1.4)
  • Revision ID: package-import@ubuntu.com-20131101120918-kx51sl0sxl3exsxi
Tags: 2013.10-1
* New upstream release
* Bump versioned (Build-)Depends on parrot
* Update patches
* Install new README.pod
* Fix vcs-field-not-canonical
* Do not install rubyish examples
* Do not Depends on parrot-devel anymore
* Add 07_disable-serialization-tests.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package org.perl6.nqp.runtime;
 
2
 
 
3
import java.lang.invoke.*;
 
4
import java.lang.invoke.MethodHandles.Lookup;
 
5
 
 
6
import org.perl6.nqp.sixmodel.*;
 
7
import org.perl6.nqp.sixmodel.reprs.LexoticInstance;
 
8
 
 
9
public class IndyBootstrap {
 
10
    public static CallSite wval_noa(Lookup caller, String name, MethodType type) {
 
11
        try {
 
12
            /* Look up wval resolver method. */
 
13
            MethodType resType = MethodType.methodType(SixModelObject.class,
 
14
                    MutableCallSite.class, String.class, int.class, ThreadContext.class);
 
15
            MethodHandle res = caller.findStatic(IndyBootstrap.class, "wvalResolve_noa", resType);
 
16
            
 
17
            /* Create a mutable callsite, and curry the resolver with it. */
 
18
            MutableCallSite cs = new MutableCallSite(type);
 
19
            cs.setTarget(MethodHandles.insertArguments(res, 0, cs));
 
20
            
 
21
            /* Produce callsite; it'll be updated with the resolved WVal upon the
 
22
             * first invocation. */
 
23
            return cs;
 
24
        }
 
25
        catch (Exception e) {
 
26
            throw new RuntimeException(e);
 
27
        }
 
28
    }
 
29
    
 
30
    public static SixModelObject wvalResolve_noa(MutableCallSite cs, String sc, int idx, ThreadContext tc) {
 
31
        /* Look up the WVal. */
 
32
        SixModelObject res = tc.gc.scs.get(sc).root_objects.get(idx);
 
33
        
 
34
        /* Update this callsite, so that we never run the lookup again and instead
 
35
         * just always use the resolved object. Discards incoming arguments, as
 
36
         * they are no longer needed. */
 
37
        if (!tc.curFrame.codeRef.staticInfo.compUnit.shared)
 
38
            cs.setTarget(MethodHandles.dropArguments(
 
39
                        MethodHandles.constant(SixModelObject.class, res),
 
40
                        0, String.class, int.class, ThreadContext.class));
 
41
        
 
42
        /* Hand back the resulting object, for this first call. */
 
43
        return res;
 
44
    }
 
45
    
 
46
    public static CallSite subcall_noa(Lookup caller, String _, MethodType type) {
 
47
        try {
 
48
            /* Look up subcall resolver method. */
 
49
            MethodType resType = MethodType.methodType(void.class,
 
50
                    Lookup.class, MutableCallSite.class, String.class,
 
51
                    int.class, ThreadContext.class, Object[].class);
 
52
            MethodHandle res = caller.findStatic(IndyBootstrap.class, "subcallResolve_noa", resType);
 
53
            
 
54
            /* Create a mutable callsite, and curry the resolver with it and
 
55
             * the sub name. */
 
56
            MutableCallSite cs = new MutableCallSite(type);
 
57
            cs.setTarget(MethodHandles
 
58
                .insertArguments(res, 0, caller, cs)
 
59
                .asCollector(Object[].class, type.parameterCount() - 3)
 
60
                .asType(type));
 
61
            
 
62
            /* Produce callsite; it'll be updated with the resolved call upon the
 
63
             * first invocation. */
 
64
            return cs;
 
65
        }
 
66
        catch (Exception e) {
 
67
            throw new RuntimeException(e);
 
68
        }
 
69
    }
 
70
    
 
71
    public static void subcallResolve_noa(Lookup caller, MutableCallSite cs, String name, int csIdx, ThreadContext tc, Object... args) {
 
72
        /* Locate the thing to call. */
 
73
        SixModelObject invokee = Ops.getlex(name, tc);
 
74
        
 
75
        /* Don't update callsite in cases where it's not safe. */
 
76
        boolean shared = tc.curFrame.codeRef.staticInfo.compUnit.shared;
 
77
        if (invokee.st != null && invokee.st.ContainerSpec != null) {
 
78
            invokee = Ops.decont(invokee, tc);
 
79
            shared = true;
 
80
        }
 
81
        
 
82
        /* Resolve callsite descriptor. */
 
83
        CallSiteDescriptor csd = csIdx >= 0
 
84
            ? tc.curFrame.codeRef.staticInfo.compUnit.callSites[csIdx]
 
85
            : Ops.emptyCallSite;
 
86
        CallSiteDescriptor csdOrig = csd;
 
87
        
 
88
        /* If it's lexotic, then resolve to something to do the throwing. */
 
89
        if (invokee instanceof LexoticInstance) {
 
90
            /* Go by result type, updating callsite appropriately so we
 
91
             * don't have to do this in the future. */
 
92
            LexoticException throwee = tc.theLexotic;
 
93
            throwee.target = ((LexoticInstance)invokee).target;
 
94
            switch (csd.argFlags[0]) {
 
95
            case CallSiteDescriptor.ARG_OBJ:
 
96
                throwee.payload = (SixModelObject)args[0];
 
97
                try {
 
98
                    if (!shared) cs.setTarget(MethodHandles.insertArguments(
 
99
                        caller.findStatic(IndyBootstrap.class, "lexotic_o_noa",
 
100
                            MethodType.methodType(void.class, long.class, String.class, int.class,
 
101
                                    ThreadContext.class, SixModelObject.class)),
 
102
                        0, throwee.target));
 
103
                }
 
104
                catch (Exception e) {
 
105
                    throw new RuntimeException(e);
 
106
                }
 
107
                break;
 
108
            case CallSiteDescriptor.ARG_INT:
 
109
                SixModelObject intBoxType = tc.curFrame.codeRef.staticInfo.compUnit.hllConfig.intBoxType;
 
110
                throwee.payload = Ops.box_i((long)args[0], intBoxType, tc);
 
111
                try {
 
112
                    if (!shared) cs.setTarget(MethodHandles.insertArguments(
 
113
                        caller.findStatic(IndyBootstrap.class, "lexotic_i_noa",
 
114
                            MethodType.methodType(void.class, long.class,
 
115
                                    SixModelObject.class, String.class, int.class,
 
116
                                    ThreadContext.class, long.class)),
 
117
                        0, throwee.target, intBoxType));
 
118
                }
 
119
                catch (Exception e) {
 
120
                    throw new RuntimeException(e);
 
121
                }
 
122
                break;
 
123
            case CallSiteDescriptor.ARG_NUM:
 
124
                SixModelObject numBoxType = tc.curFrame.codeRef.staticInfo.compUnit.hllConfig.numBoxType;
 
125
                throwee.payload = Ops.box_n((double)args[0], numBoxType, tc);
 
126
                try {
 
127
                    if (!shared) cs.setTarget(MethodHandles.insertArguments(
 
128
                        caller.findStatic(IndyBootstrap.class, "lexotic_n_noa",
 
129
                            MethodType.methodType(void.class, long.class,
 
130
                                    SixModelObject.class, String.class, int.class,
 
131
                                    ThreadContext.class, double.class)),
 
132
                        0, throwee.target, numBoxType));
 
133
                }
 
134
                catch (Exception e) {
 
135
                    throw new RuntimeException(e);
 
136
                }
 
137
                break;
 
138
            case CallSiteDescriptor.ARG_STR:
 
139
                SixModelObject strBoxType = tc.curFrame.codeRef.staticInfo.compUnit.hllConfig.strBoxType;
 
140
                throwee.payload = Ops.box_s((String)args[0], strBoxType, tc);
 
141
                try {
 
142
                    if (!shared) cs.setTarget(MethodHandles.insertArguments(
 
143
                        caller.findStatic(IndyBootstrap.class, "lexotic_s_noa",
 
144
                            MethodType.methodType(void.class, long.class,
 
145
                                    SixModelObject.class, String.class, int.class,
 
146
                                    ThreadContext.class, String.class)),
 
147
                        0, throwee.target, strBoxType));
 
148
                }
 
149
                catch (Exception e) {
 
150
                    throw new RuntimeException(e);
 
151
                }
 
152
                break;
 
153
            default:
 
154
                throw ExceptionHandling.dieInternal(tc, "Invalid lexotic invocation argument");
 
155
            }
 
156
            throw throwee;
 
157
        }
 
158
        
 
159
        /* Otherwise, get the code ref. */
 
160
        CodeRef cr;
 
161
        if (invokee instanceof CodeRef) {
 
162
            cr = (CodeRef)invokee;
 
163
        }
 
164
        else {
 
165
            InvocationSpec is = invokee.st.InvocationSpec;
 
166
            if (is == null)
 
167
                throw ExceptionHandling.dieInternal(tc, "Can not invoke this object");
 
168
            if (is.ClassHandle != null)
 
169
                cr = (CodeRef)invokee.get_attribute_boxed(tc, is.ClassHandle, is.AttrName, is.Hint);
 
170
            else {
 
171
                cr = (CodeRef)is.InvocationHandler;
 
172
                csd = csd.injectInvokee(tc, args, invokee);
 
173
                args = tc.flatArgs;
 
174
            }
 
175
        }
 
176
        
 
177
        /* Now need to adapt to the target callsite by binding the CodeRef
 
178
         * and callsite with what they've been resolved to. Don't do it if
 
179
         * it's a compiler stub, though. */
 
180
        if (!cr.isCompilerStub && !shared) {
 
181
            try {
 
182
                MethodType invType = MethodType.methodType(void.class,
 
183
                    MethodHandle.class, String.class, CallSiteDescriptor.class,
 
184
                    ThreadContext.class, Object[].class);
 
185
                MethodHandle inv = caller.findStatic(IndyBootstrap.class, "subInvoker", invType);
 
186
                cs.setTarget(MethodHandles
 
187
                    .dropArguments(
 
188
                        MethodHandles.insertArguments(inv, 0, cr.staticInfo.mh, name, csdOrig),
 
189
                        0, String.class, int.class)
 
190
                    .asVarargsCollector(Object[].class)
 
191
                    .asType(cs.getTarget().type()));
 
192
            }
 
193
            catch (Throwable t) {
 
194
                throw ExceptionHandling.dieInternal(tc, t);
 
195
            }
 
196
        }
 
197
        
 
198
        /* Make the sub call directly for this initial call. */
 
199
        try {
 
200
            cr.staticInfo.mh.invokeExact(tc, (CodeRef)cr, csd, args);
 
201
        }
 
202
        catch (ControlException e) {
 
203
            throw e;
 
204
        }
 
205
        catch (Throwable e) {
 
206
            ExceptionHandling.dieInternal(tc, e);
 
207
        }
 
208
    }
 
209
    
 
210
    public static void lexotic_o_noa(long target, String _, int __, ThreadContext tc, SixModelObject arg) {
 
211
        LexoticException throwee = tc.theLexotic;
 
212
        throwee.target = target;
 
213
        throwee.payload = arg;
 
214
        throw throwee;
 
215
    }
 
216
    
 
217
    public static void lexotic_i_noa(long target, SixModelObject boxType, String _, int __, ThreadContext tc, long arg) {
 
218
        LexoticException throwee = tc.theLexotic;
 
219
        throwee.target = target;
 
220
        throwee.payload = Ops.box_i(arg, boxType, tc);
 
221
        throw throwee;
 
222
    }
 
223
    
 
224
    public static void lexotic_n_noa(long target, SixModelObject boxType, String _, int __, ThreadContext tc, double arg) {
 
225
        LexoticException throwee = tc.theLexotic;
 
226
        throwee.target = target;
 
227
        throwee.payload = Ops.box_n(arg, boxType, tc);
 
228
        throw throwee;
 
229
    }
 
230
    
 
231
    public static void lexotic_s_noa(long target, SixModelObject boxType, String _, int __, ThreadContext tc, String arg) {
 
232
        LexoticException throwee = tc.theLexotic;
 
233
        throwee.target = target;
 
234
        throwee.payload = Ops.box_s(arg, boxType, tc);
 
235
        throw throwee;
 
236
    }
 
237
    
 
238
    public static void subInvoker(MethodHandle mh, String name, CallSiteDescriptor csd, ThreadContext tc, Object[] args) throws Throwable { 
 
239
        SixModelObject invokee = Ops.getlex(name, tc);
 
240
        CodeRef cr;
 
241
        if (invokee instanceof CodeRef) {
 
242
            cr = (CodeRef)invokee;
 
243
        }
 
244
        else {
 
245
            InvocationSpec is = invokee.st.InvocationSpec;
 
246
            if (is == null)
 
247
                throw ExceptionHandling.dieInternal(tc, "Can not invoke this object");
 
248
            if (is.ClassHandle != null)
 
249
                cr = (CodeRef)invokee.get_attribute_boxed(tc, is.ClassHandle, is.AttrName, is.Hint);
 
250
            else {
 
251
                cr = (CodeRef)is.InvocationHandler;
 
252
                csd = csd.injectInvokee(tc, args, invokee);
 
253
                args = tc.flatArgs;
 
254
            }
 
255
        }
 
256
        mh.invokeExact(tc, cr, csd, args);
 
257
    }
 
258
    
 
259
    public static CallSite indcall_noa(Lookup caller, String _, MethodType type) {
 
260
        try {
 
261
            /* Look up indirect call invoker method. */
 
262
            MethodType resType = MethodType.methodType(void.class,
 
263
                    MutableCallSite.class, int.class, ThreadContext.class,
 
264
                    SixModelObject.class, Object[].class);
 
265
            MethodHandle res = caller.findStatic(IndyBootstrap.class, "indcallInvoker_noa", resType);
 
266
            
 
267
            /* Create a mutable callsite, and curry the resolver with it and
 
268
             * the sub name. */
 
269
            MutableCallSite cs = new MutableCallSite(type);
 
270
            cs.setTarget(MethodHandles
 
271
                .insertArguments(res, 0, cs)
 
272
                .asCollector(Object[].class, type.parameterCount() - 3)
 
273
                .asType(type));
 
274
            
 
275
            /* Produce callsite. */
 
276
            return cs;
 
277
        }
 
278
        catch (Exception e) {
 
279
            throw new RuntimeException(e);
 
280
        }
 
281
    }
 
282
    
 
283
    public static void indcallInvoker_noa(MutableCallSite cs, int csIdx,
 
284
            ThreadContext tc, SixModelObject invokee, Object... args) {
 
285
        /* Resolve callsite descriptor. */
 
286
        CallSiteDescriptor csd = csIdx >= 0
 
287
            ? tc.curFrame.codeRef.staticInfo.compUnit.callSites[csIdx]
 
288
            : Ops.emptyCallSite;
 
289
        
 
290
        /* Get the code ref. */
 
291
        CodeRef cr;
 
292
        invokee = Ops.decont(invokee, tc);
 
293
        if (invokee instanceof LexoticInstance)
 
294
            Ops.invokeLexotic(invokee, csd, args, tc);
 
295
        if (invokee instanceof CodeRef) {
 
296
            cr = (CodeRef)invokee;
 
297
        }
 
298
        else {
 
299
            InvocationSpec is = invokee.st.InvocationSpec;
 
300
            if (is == null)
 
301
                throw ExceptionHandling.dieInternal(tc, "Can not invoke this object");
 
302
            if (is.ClassHandle != null)
 
303
                cr = (CodeRef)invokee.get_attribute_boxed(tc, is.ClassHandle, is.AttrName, is.Hint);
 
304
            else {
 
305
                cr = (CodeRef)is.InvocationHandler;
 
306
                csd = csd.injectInvokee(tc, args, invokee);
 
307
                args = tc.flatArgs;
 
308
            }
 
309
        }
 
310
        
 
311
        /* Make the call. */
 
312
        try {
 
313
            cr.staticInfo.mh.invokeExact(tc, cr, csd, args);
 
314
        }
 
315
        catch (ControlException e) {
 
316
            throw e;
 
317
        }
 
318
        catch (Throwable e) {
 
319
            ExceptionHandling.dieInternal(tc, e);
 
320
        }
 
321
    }
 
322
    
 
323
    public static CallSite methcall_noa(Lookup caller, String _, MethodType type) {
 
324
        try {
 
325
            /* Look up methcall resolver method. */
 
326
            MethodType resType = MethodType.methodType(void.class,
 
327
                    Lookup.class, MutableCallSite.class, String.class,
 
328
                    int.class, ThreadContext.class, Object[].class);
 
329
            MethodHandle res = caller.findStatic(IndyBootstrap.class, "methcallResolve_noa", resType);
 
330
            
 
331
            /* Create a mutable callsite, and curry the resolver with it and
 
332
             * the method name. */
 
333
            MutableCallSite cs = new MutableCallSite(type);
 
334
            cs.setTarget(MethodHandles
 
335
                .insertArguments(res, 0, caller, cs)
 
336
                .asCollector(Object[].class, type.parameterCount() - 3)
 
337
                .asType(type));
 
338
            
 
339
            /* Produce callsite; it'll build up a PIC over various polymorphic
 
340
             * invocations. */
 
341
            return cs;
 
342
        }
 
343
        catch (Exception e) {
 
344
            throw new RuntimeException(e);
 
345
        }
 
346
    }
 
347
    
 
348
    public static void methcallResolve_noa(Lookup caller, MutableCallSite cs, String name, int csIdx,
 
349
            ThreadContext tc, Object... args) {
 
350
        /* Resolve callsite descriptor. */
 
351
        CallSiteDescriptor csd = csIdx >= 0
 
352
            ? tc.curFrame.codeRef.staticInfo.compUnit.callSites[csIdx]
 
353
            : Ops.emptyCallSite;
 
354
        
 
355
        /* Try to resolve method to a coderef. */
 
356
        SixModelObject invocant = (SixModelObject)args[0];
 
357
        SixModelObject invokee = Ops.findmethod(invocant, name, tc);
 
358
        if (invokee == null)
 
359
            throw ExceptionHandling.dieInternal(tc,
 
360
                "Method '" + name + "' not found for invocant of class '" + Ops.typeName(invocant, tc) + "'"); 
 
361
        CodeRef cr;
 
362
        if (invokee instanceof CodeRef) {
 
363
            cr = (CodeRef)invokee;
 
364
        }
 
365
        else {
 
366
            InvocationSpec is = invokee.st.InvocationSpec;
 
367
            if (is == null)
 
368
                throw ExceptionHandling.dieInternal(tc, "Can not invoke this object");
 
369
            if (is.ClassHandle != null)
 
370
                cr = (CodeRef)invokee.get_attribute_boxed(tc, is.ClassHandle, is.AttrName, is.Hint);
 
371
            else {
 
372
                cr = (CodeRef)is.InvocationHandler;
 
373
                csd = csd.injectInvokee(tc, args, invokee);
 
374
                args = tc.flatArgs;
 
375
            }
 
376
        }
 
377
        
 
378
        /* Update callsite, stacking up guarded clauses. Don't do it if it
 
379
         * is a dynamic compiler stub, though. */
 
380
        /* XXX Needs fixing for no-optional-args workaround. */
 
381
        /*if (!cr.isCompilerStub) {
 
382
            MethodType gType = MethodType.methodType(boolean.class,
 
383
                    STable.class, ThreadContext.class, SixModelObject.class);
 
384
            MethodHandle guard;
 
385
            STable guardSTable;
 
386
            try {
 
387
                if (invocant.st.ContainerSpec == null) {
 
388
                    guard = caller.findStatic(IndyBootstrap.class, "stGuard", gType);
 
389
                    guardSTable = invocant.st;
 
390
                }
 
391
                else {
 
392
                    guard = caller.findStatic(IndyBootstrap.class, "stGuardCont", gType);
 
393
                    guardSTable = Ops.decont(invocant, tc).st;
 
394
                }
 
395
            }
 
396
            catch (Exception e) {
 
397
                throw new RuntimeException(e);
 
398
            }
 
399
            cs.setTarget(
 
400
                MethodHandles.guardWithTest(
 
401
                    MethodHandles.insertArguments(guard, 0, guardSTable),
 
402
                    MethodHandles
 
403
                        .insertArguments(cr.staticInfo.mh, 1, cr, csd)
 
404
                        .asVarargsCollector(Object[].class)
 
405
                        .asType(cs.getTarget().type()),
 
406
                    cs.getTarget()));
 
407
        }*/
 
408
        
 
409
        /* Make the call directly for this initial call. */
 
410
        try {
 
411
            cr.staticInfo.mh.invokeExact(tc, cr, csd, args);
 
412
        }
 
413
        catch (ControlException e) {
 
414
            throw e;
 
415
        }
 
416
        catch (Throwable e) {
 
417
            ExceptionHandling.dieInternal(tc, e);
 
418
        }
 
419
    }
 
420
    
 
421
    public static boolean stGuard(STable expected, ThreadContext _, SixModelObject obj) {
 
422
        return obj.st == expected;
 
423
    }
 
424
    
 
425
    public static boolean stGuardCont(STable expected, ThreadContext tc, SixModelObject obj) {
 
426
        return Ops.decont(obj, tc).st == expected;
 
427
    }
 
428
    
 
429
    public static CallSite indmethcall_noa(Lookup caller, String _, MethodType type) {
 
430
        try {
 
431
            /* Look up methcall invoker method. */
 
432
            MethodType resType = MethodType.methodType(void.class,
 
433
                    MutableCallSite.class, int.class,
 
434
                    ThreadContext.class, String.class, Object[].class);
 
435
            MethodHandle res = caller.findStatic(IndyBootstrap.class, "indmethcallInvoker_noa", resType);
 
436
            
 
437
            /* Create a mutable callsite, and curry the resolver with it and
 
438
             * the method name. */
 
439
            MutableCallSite cs = new MutableCallSite(type);
 
440
            cs.setTarget(MethodHandles
 
441
                .insertArguments(res, 0, cs)
 
442
                .asCollector(Object[].class, type.parameterCount() - 3)
 
443
                .asType(type));
 
444
            
 
445
            /* Produce callsite. */
 
446
            return cs;
 
447
        }
 
448
        catch (Exception e) {
 
449
            throw new RuntimeException(e);
 
450
        }
 
451
    }
 
452
    
 
453
    public static void indmethcallInvoker_noa(MutableCallSite cs, int csIdx,
 
454
            ThreadContext tc, String name, Object... args) {
 
455
        /* Resolve callsite descriptor. */
 
456
        CallSiteDescriptor csd = csIdx >= 0
 
457
            ? tc.curFrame.codeRef.staticInfo.compUnit.callSites[csIdx]
 
458
            : Ops.emptyCallSite;
 
459
        
 
460
        /* Try to resolve method to a coderef. */
 
461
        SixModelObject invocant = (SixModelObject)args[0];
 
462
        SixModelObject invokee = Ops.findmethod(invocant, name, tc);
 
463
        if (invokee == null)
 
464
            throw ExceptionHandling.dieInternal(tc,
 
465
                "Method '" + name + "' not found for invocant of class '" + Ops.typeName(invocant, tc) + "'");
 
466
        CodeRef cr;
 
467
        if (invokee instanceof CodeRef) {
 
468
            cr = (CodeRef)invokee;
 
469
        }
 
470
        else {
 
471
            InvocationSpec is = invokee.st.InvocationSpec;
 
472
            if (is == null)
 
473
                throw ExceptionHandling.dieInternal(tc, "Can not invoke this object");
 
474
            if (is.ClassHandle != null)
 
475
                cr = (CodeRef)invokee.get_attribute_boxed(tc, is.ClassHandle, is.AttrName, is.Hint);
 
476
            else {
 
477
                cr = (CodeRef)is.InvocationHandler;
 
478
                csd = csd.injectInvokee(tc, args, invokee);
 
479
                args = tc.flatArgs;
 
480
            }
 
481
        }
 
482
 
 
483
        /* Make the call. */
 
484
        try {
 
485
            cr.staticInfo.mh.invokeExact(tc, cr, csd, args);
 
486
        }
 
487
        catch (ControlException e) {
 
488
            throw e;
 
489
        }
 
490
        catch (Throwable e) {
 
491
            ExceptionHandling.dieInternal(tc, e);
 
492
        }
 
493
    }
 
494
}