1 /* 2 * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 package vm.mlvm.share; 25 26 import java.lang.invoke.MethodHandle; 27 import java.lang.invoke.MethodHandles; 28 import java.lang.invoke.MethodType; 29 import java.util.List; 30 import java.util.LinkedList; 31 32 import vm.mlvm.share.ClassfileGenerator; 33 import vm.mlvm.share.CustomClassLoaders; 34 import vm.mlvm.share.Env; 35 import vm.mlvm.share.MlvmTest; 36 import vm.share.options.Option; 37 38 public class ClassfileGeneratorTest extends MlvmTest { 39 40 public static final String CLASS_NAME = "Dummy"; 41 42 @Option(name = "generator", default_value = "", description = "Class name of the generator. Must inherit from vm.mlvm.share.ClassfileGenerator") 43 private String generatorClassNameOpt; 44 45 private Class<? extends ClassfileGenerator> generatorClass; 46 47 public ClassfileGeneratorTest() { 48 } 49 50 public ClassfileGeneratorTest(Class<? extends ClassfileGenerator> genClass) { 51 generatorClass = genClass; 52 } 53 54 @Override 55 public boolean run() throws Throwable { 56 if (generatorClass == null) { 57 generatorClass = Class.forName(generatorClassNameOpt).asSubclass(ClassfileGenerator.class); 58 } 59 60 Env.traceVerbose("Generating class"); 61 ClassfileGenerator gen = generatorClass.newInstance(); 62 63 gen.setClassName(null, CLASS_NAME); 64 ClassfileGenerator.Klass k = gen.generateBytecodes()[0]; 65 k.writeClass("."); 66 ClassLoader cl = CustomClassLoaders.makeClassBytesLoader(k.getBytes(), k.getClassName()); 67 68 Env.traceNormal("Loading class " + k.getClassName()); 69 Class<?> dummyClass = cl.loadClass(k.getClassName()); 70 71 MethodType mt = MethodType.fromMethodDescriptorString(k.getMainMethodSignature(), getClass().getClassLoader()); 72 MethodHandle m = MethodHandles.lookup().findStatic(dummyClass, k.getMainMethodName(), mt); 73 74 Env.traceVerbose("Main method: " + m); 75 76 // Generate default parameter values 77 List<Object> arguments = new LinkedList<>(); 78 for(Class<?> t : mt.wrap().parameterArray()) { 79 Object arg; 80 if (t.isArray()) { 81 arg = java.lang.reflect.Array.newInstance(t.getComponentType(), 0); 82 } else { 83 arg = t.newInstance(); 84 } 85 arguments.add(arg); 86 } 87 88 Env.traceNormal("Invoking method " + m); 89 m.invokeWithArguments(arguments); 90 91 return true; 92 } 93 94 public static void main(String[] args) { 95 MlvmTest.launch(args); 96 } 97 98 }