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@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@201: jaroslav@201: sb.append("\nfunction test(clazz, as, method) {"); jaroslav@201: sb.append("\n var l = new lazyVM();"); jaroslav@201: sb.append("\n var c = l.loadClass(clazz, as);"); jaroslav@201: sb.append("\n return c[method]();"); jaroslav@201: sb.append("\n}"); jaroslav@201: jaroslav@201: jaroslav@201: sb.append("\nfunction lazyVM() {"); jaroslav@201: sb.append("\n var self = this;"); jaroslav@201: sb.append("\n this.constructor.prototype.loadClass = function(res, name) {"); jaroslav@207: sb.append("\n var script = org_apidesign_vm4brwsr_VMLazy(true).toJavaScriptLjava_lang_StringAB(loader.get(res + '.class'));"); jaroslav@202: sb.append("\n try {"); jaroslav@213: sb.append("\n new Function(script)(self, name);"); jaroslav@202: sb.append("\n } catch (ex) {"); jaroslav@202: sb.append("\n throw 'Cannot compile ' + res + ' error: ' + ex + ' script:\\n' + script;"); jaroslav@202: sb.append("\n };"); jaroslav@211: sb.append("\n return self[name](true);"); jaroslav@201: sb.append("\n };"); jaroslav@201: sb.append("\n"); jaroslav@201: sb.append("\n}\n"); jaroslav@201: jaroslav@201: ScriptEngine[] arr = { null }; jaroslav@201: code = StaticMethodTest.compileClass(sb, arr, jaroslav@201: "org/apidesign/vm4brwsr/VMLazy" 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@211: "org/apidesign/vm4brwsr/StaticMethod", "org_apidesign_vm4brwsr_StaticMethod", "minusOneI" jaroslav@201: ); jaroslav@201: } jaroslav@201: 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@201: assertEquals(ret, expRes, msg + "was: " + ret + "\n" + codeSeq); jaroslav@201: } jaroslav@201: jaroslav@201: public static final class FindBytes { jaroslav@201: public byte[] get(String name) throws IOException { 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@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@201: return arr; jaroslav@201: } jaroslav@201: } jaroslav@201: }