1/*
2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 *   - Redistributions of source code must retain the above copyright
9 *     notice, this list of conditions and the following disclaimer.
10 *
11 *   - Redistributions in binary form must reproduce the above copyright
12 *     notice, this list of conditions and the following disclaimer in the
13 *     documentation and/or other materials provided with the distribution.
14 *
15 *   - Neither the name of Oracle nor the names of its
16 *     contributors may be used to endorse or promote products derived
17 *     from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32// Simple sample to demonstrate openjdk asmtools assembler with
33// nashorn dynalink linker in a invokedynamic instruction.
34//
35// To assemble this file, use the following command:
36//
37//    java -cp <asmtools.jar> org.openjdk.asmtools.Main jasm Main.asm
38//
39// See also: https://wiki.openjdk.java.net/display/CodeTools/asmtools
40//
41// NOTE: Uses dynalink API defined by JEP-276 (http://openjdk.java.net/jeps/276)
42
43super public class Main
44	version 52:0
45{
46
47private static final Field linker:"Ljdk/dynalink/DynamicLinker;";
48
49/*
50   static {
51        // create dynalink linker factory
52        final DynamicLinkerFactory factory = new DynamicLinkerFactory();
53
54        // create standard linker that can handle Java POJOs
55        linker = factory.createLinker();
56   }
57*/
58static Method "<clinit>":"()V"
59        stack 2 locals 1
60{
61    new     class jdk/dynalink/DynamicLinkerFactory;
62    dup;
63    invokespecial   Method jdk/dynalink/DynamicLinkerFactory."<init>":"()V";
64    astore_0;
65    aload_0;
66    invokevirtual   Method jdk/dynalink/DynamicLinkerFactory.createLinker:"()Ljdk/dynalink/DynamicLinker;";
67    putstatic       Field linker:"Ljdk/dynalink/DynamicLinker;";
68    return;
69}
70
71/*
72    // Bootstrap method used with invokedynamic methods
73
74    public static CallSite bootstrap(MethodHandles.Lookup caller, String name, MethodType type) {
75        // use dynalink linker to perform the actual linking
76        return linker.link(
77            new SimpleRelinkableCallSite(
78                new CallSiteDescriptor(
79                    MethodHandles.publicLookup(), 
80                    new NamedOperation(StandardOperation.GET_PROPERTY, name), type)
81            )
82        );
83    }
84
85 */
86public static Method bootstrap:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;"
87        stack 10 locals 3
88{
89    getstatic       Field linker:"Ljdk/dynalink/DynamicLinker;";
90    new     class jdk/dynalink/support/SimpleRelinkableCallSite;
91    dup;
92    new     class jdk/dynalink/CallSiteDescriptor;
93    dup;
94    invokestatic    Method java/lang/invoke/MethodHandles.publicLookup:"()Ljava/lang/invoke/MethodHandles$Lookup;";
95    new     class jdk/dynalink/NamedOperation;
96    dup;
97    getstatic       Field jdk/dynalink/StandardOperation.GET_PROPERTY:"Ljdk/dynalink/StandardOperation;";
98    aload_1;
99    invokespecial   Method jdk/dynalink/NamedOperation."<init>":"(Ljdk/dynalink/Operation;Ljava/lang/Object;)V";
100    aload_2;
101    invokespecial   Method jdk/dynalink/CallSiteDescriptor."<init>":"(Ljava/lang/invoke/MethodHandles$Lookup;Ljdk/dynalink/Operation;Ljava/lang/invoke/MethodType;)V";
102    invokespecial   Method jdk/dynalink/support/SimpleRelinkableCallSite."<init>":"(Ljdk/dynalink/CallSiteDescriptor;)V";
103    invokevirtual   Method jdk/dynalink/DynamicLinker.link:"(Ljdk/dynalink/RelinkableCallSite;)Ljdk/dynalink/RelinkableCallSite;";
104    checkcast       class java/lang/invoke/CallSite;
105    areturn;
106}
107
108// default constructor that does nothing!
109public Method "<init>":"()V"
110	stack 1 locals 1
111{
112    aload_0;
113    invokespecial	Method java/lang/Object."<init>":"()V";
114    return;
115}
116
117public static Method main:"([Ljava/lang/String;)V"
118	stack 2 locals 2
119{
120    // List l = new ArrayList();
121    new	class java/util/ArrayList;
122    dup;
123    invokespecial	Method java/util/ArrayList."<init>":"()V";
124    astore_1;
125    aload_1;
126
127    // l.add("hello");
128    ldc	String "hello";
129    invokeinterface	InterfaceMethod java/util/List.add:"(Ljava/lang/Object;)Z",  2;
130    pop;
131
132    // l.add("world");
133    aload_1;
134    ldc	String "world";
135    invokeinterface	InterfaceMethod java/util/List.add:"(Ljava/lang/Object;)Z",  2;
136    pop;
137
138    // printLength(l);
139    aload_1;
140    invokestatic	Method printLength:"(Ljava/lang/Object;)V";
141
142    // printLength(args); // args is argument of main method
143    aload_0;
144    invokestatic	Method printLength:"(Ljava/lang/Object;)V";
145    return;
146}
147
148private static Method printLength:"(Ljava/lang/Object;)V"
149	stack 2 locals 1
150{
151    getstatic	Field java/lang/System.out:"Ljava/io/PrintStream;";
152    aload_0;
153
154    // Using bootstrap method in this class with the following invokedynamic
155    // which uses dynalink linker. Dynalink's bean linker handles Java beans.
156    // 'length' property on a bean - arrays, lists supported
157
158    invokedynamic   InvokeDynamic REF_invokeStatic:Main.bootstrap:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;":"length":"(Ljava/lang/Object;)Ljava/lang/Object;";
159
160    // print 'length' value
161    invokevirtual	Method java/io/PrintStream.println:"(Ljava/lang/Object;)V";
162    return;
163}
164
165} // end Class Main
166