jaroslav@201: /** jaroslav@201: * Back 2 Browser Bytecode Translator jaroslav@201: * Copyright (C) 2012 Jaroslav Tulach jaroslav@201: * jaroslav@201: * This program is free software: you can redistribute it and/or modify jaroslav@201: * it under the terms of the GNU General Public License as published by jaroslav@201: * the Free Software Foundation, version 2 of the License. jaroslav@201: * jaroslav@201: * This program is distributed in the hope that it will be useful, jaroslav@201: * but WITHOUT ANY WARRANTY; without even the implied warranty of jaroslav@201: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the jaroslav@201: * GNU General Public License for more details. jaroslav@201: * jaroslav@201: * You should have received a copy of the GNU General Public License jaroslav@201: * along with this program. Look for COPYING file in the top folder. jaroslav@201: * If not, see http://opensource.org/licenses/GPL-2.0. jaroslav@201: */ jaroslav@201: package org.apidesign.vm4brwsr; jaroslav@201: jaroslav@201: import java.io.IOException; jaroslav@201: import java.io.InputStream; jaroslav@277: import java.util.Set; jaroslav@277: import java.util.TreeSet; jaroslav@201: import javax.script.Invocable; jaroslav@201: import javax.script.ScriptContext; jaroslav@201: import javax.script.ScriptEngine; jaroslav@201: import javax.script.ScriptException; jaroslav@201: import org.testng.annotations.BeforeClass; jaroslav@201: import static org.testng.Assert.*; jaroslav@201: import org.testng.annotations.Test; jaroslav@201: jaroslav@201: /** Implements loading class by class. jaroslav@201: * jaroslav@201: * @author Jaroslav Tulach jaroslav@201: */ jaroslav@201: public class VMLazyTest { jaroslav@201: jaroslav@201: jaroslav@201: private static CharSequence codeSeq; jaroslav@201: private static Invocable code; jaroslav@201: jaroslav@201: @BeforeClass jaroslav@201: public void compileTheCode() throws Exception { jaroslav@201: StringBuilder sb = new StringBuilder(); jaroslav@277: sb.append("\nvar data = {};"); jaroslav@277: sb.append("\nfunction test(clazz, method) {"); jaroslav@277: sb.append("\n if (!data.bck2brwsr) data.bck2brwsr = bck2brwsr(function(name) { return loader.get(name); });"); jaroslav@277: sb.append("\n var c = data.bck2brwsr.loadClass(clazz);"); jaroslav@201: sb.append("\n return c[method]();"); jaroslav@201: sb.append("\n}"); jaroslav@201: jaroslav@201: jaroslav@277: jaroslav@201: ScriptEngine[] arr = { null }; jaroslav@201: code = StaticMethodTest.compileClass(sb, arr, jaroslav@277: "org/apidesign/vm4brwsr/GenJS" jaroslav@201: ); jaroslav@201: arr[0].getContext().setAttribute("loader", new FindBytes(), ScriptContext.ENGINE_SCOPE); jaroslav@201: codeSeq = sb; jaroslav@201: } jaroslav@201: jaroslav@201: @Test public void invokeStaticMethod() throws Exception { jaroslav@201: assertExec("Trying to get -1", "test", Double.valueOf(-1), jaroslav@277: StaticMethod.class.getName(), "minusOne__I" jaroslav@201: ); jaroslav@201: } jaroslav@214: jaroslav@214: @Test public void loadDependantClass() throws Exception { jaroslav@277: assertExec("Expecting zero", "test", Double.valueOf(0), jaroslav@277: InstanceSub.class.getName(), "recallDbl__D" jaroslav@214: ); jaroslav@214: } jaroslav@201: jaroslav@201: private static void assertExec(String msg, String methodName, Object expRes, Object... args) throws Exception { jaroslav@201: Object ret = null; jaroslav@201: try { jaroslav@201: ret = code.invokeFunction(methodName, args); jaroslav@201: } catch (ScriptException ex) { jaroslav@201: fail("Execution failed in\n" + StaticMethodTest.dumpJS(codeSeq), ex); jaroslav@201: } catch (NoSuchMethodException ex) { jaroslav@201: fail("Cannot find method in\n" + StaticMethodTest.dumpJS(codeSeq), ex); jaroslav@201: } jaroslav@201: if (ret == null && expRes == null) { jaroslav@201: return; jaroslav@201: } jaroslav@201: if (expRes.equals(ret)) { jaroslav@201: return; jaroslav@201: } jaroslav@215: assertEquals(ret, expRes, msg + "was: " + ret + "\n" + StaticMethodTest.dumpJS(codeSeq)); jaroslav@201: } jaroslav@201: jaroslav@201: public static final class FindBytes { jaroslav@277: private static Set requested = new TreeSet(); jaroslav@277: jaroslav@201: public byte[] get(String name) throws IOException { jaroslav@277: if (!requested.add(name)) { jaroslav@277: throw new IllegalStateException("Requested for second time: " + name); jaroslav@277: } jaroslav@277: jaroslav@201: InputStream is = VMLazyTest.class.getClassLoader().getResourceAsStream(name); jaroslav@201: if (is == null) { jaroslav@201: throw new IOException("Can't find " + name); jaroslav@201: } jaroslav@201: byte[] arr = new byte[is.available()]; jaroslav@201: int len = is.read(arr); jaroslav@201: if (len != arr.length) { jaroslav@201: throw new IOException("Read only " + len + " wanting " + arr.length); jaroslav@201: } jaroslav@215: /* jaroslav@201: System.err.print("loader['" + name + "'] = ["); jaroslav@201: for (int i = 0; i < arr.length; i++) { jaroslav@201: if (i > 0) { jaroslav@201: System.err.print(", "); jaroslav@201: } jaroslav@201: System.err.print(arr[i]); jaroslav@201: } jaroslav@201: System.err.println("]"); jaroslav@215: */ jaroslav@201: return arr; jaroslav@201: } jaroslav@201: } jaroslav@201: }