# HG changeset patch # User Jaroslav Tulach # Date 1426158474 -3600 # Node ID fbe883b5a7934745cee4c7f098f499c76d9fbfde # Parent ea9fd59c8b62e766bfc6fd7989ed6af2c469f0dd Optimize only simpleLoopTest... method and first check the generated code before compiling it as JavaScript diff -r ea9fd59c8b62 -r fbe883b5a793 rt/flow/src/test/java/org/apidesign/bck2brwsr/flow/LoopControlTest.java --- a/rt/flow/src/test/java/org/apidesign/bck2brwsr/flow/LoopControlTest.java Thu Mar 12 11:16:15 2015 +0100 +++ b/rt/flow/src/test/java/org/apidesign/bck2brwsr/flow/LoopControlTest.java Thu Mar 12 12:07:54 2015 +0100 @@ -41,8 +41,12 @@ boolean called; @Override public boolean analyze(Flow request) { - called = true; - return GraalFlowAnalyzer.getDefault().analyze(request); + if (request.getMethodName().equals("simpleLoopTestWithExit")) { + called = true; + return GraalFlowAnalyzer.getDefault().analyze(request); + } else { + return false; + } } } MyFlow flow = new MyFlow(); @@ -72,6 +76,9 @@ assertNotEquals(end, -1, "Control loop end defined" + code); final String body = code.substring(begin, end); assertFalse(body.contains("gt"), "No gt control flow used: " + body); + + int exp = LoopControl.simpleLoopTestWithExit(123); + vm.assertExec("Is the code compilable?", LoopControl.class, "simpleLoopTestWithExit__II", exp, 123); } } diff -r ea9fd59c8b62 -r fbe883b5a793 rt/flow/src/test/java/org/apidesign/bck2brwsr/flow/TestVM.java --- a/rt/flow/src/test/java/org/apidesign/bck2brwsr/flow/TestVM.java Thu Mar 12 11:16:15 2015 +0100 +++ b/rt/flow/src/test/java/org/apidesign/bck2brwsr/flow/TestVM.java Thu Mar 12 12:07:54 2015 +0100 @@ -42,16 +42,15 @@ import static org.testng.Assert.*; public final class TestVM { - private final Invocable code; + private final ScriptEngine js; + private Invocable code; private final CharSequence codeSeq; - private final Object bck2brwsr; + private Object bck2brwsr; - private TestVM(Invocable code, CharSequence codeSeq) throws ScriptException, NoSuchMethodException { - this.code = code; + private TestVM(ScriptEngine js, CharSequence codeSeq) throws ScriptException, NoSuchMethodException { + this.js = js; this.codeSeq = codeSeq; - this.bck2brwsr = ((ScriptEngine)code).eval("bck2brwsr(function(n) { return loader.get(n); })"); - ((ScriptEngine)code).getContext().setAttribute("loader", this, ScriptContext.ENGINE_SCOPE); } public Object execCode( @@ -60,11 +59,11 @@ ) throws Exception { Object ret = null; try { - ret = code.invokeMethod(bck2brwsr, "loadClass", clazz.getName()); + ret = getCode().invokeMethod(bck2brwsr, "loadClass", clazz.getName()); List ma = new ArrayList(); ma.add(method); ma.addAll(Arrays.asList(args)); - ret = code.invokeMethod(ret, "invoke", ma.toArray()); + ret = getCode().invokeMethod(ret, "invoke", ma.toArray()); } catch (ScriptException ex) { fail("Execution failed in " + dumpJS(codeSeq) + ": " + ex.getMessage(), ex); } catch (NoSuchMethodException ex) { @@ -80,11 +79,11 @@ // in case of Long it is necessary convert it to number // since the Long is represented by two numbers in JavaScript try { - final Object toFP = ((ScriptEngine)code).eval("Number.prototype.toFP"); + final Object toFP = ((ScriptEngine)getCode()).eval("Number.prototype.toFP"); if (ret instanceof Long) { - ret = code.invokeMethod(toFP, "call", ret); + ret = getCode().invokeMethod(toFP, "call", ret); } - ret = code.invokeFunction("Number", ret); + ret = getCode().invokeFunction("Number", ret); } catch (ScriptException ex) { fail("Conversion to number failed in " + dumpJS(codeSeq) + ": " + ex.getMessage(), ex); } catch (NoSuchMethodException ex) { @@ -144,96 +143,7 @@ eng[0] = js; } try { - Object res = js.eval(sb.toString()); - assertTrue(js instanceof Invocable, "It is invocable object: " + res); - return new TestVM((Invocable) js, sb); - } catch (Exception ex) { - if (sb.length() > 2000) { - sb = dumpJS(sb); - } - fail("Could not evaluate:" + ex.getClass() + ":" + ex.getMessage() + "\n" + sb, ex); - return null; - } - } - - static TestVM compileClassAsExtension( - StringBuilder sb, ScriptEngine[] eng, - String name, final String resourceName, final String resourceContent - ) throws ScriptException, IOException { - return compileClassesAsExtension(sb, eng, resourceName, resourceContent, name); - } - static TestVM compileClassesAsExtension( - StringBuilder sb, ScriptEngine[] eng, - final String resourceName, final String resourceContent, String... names - ) throws ScriptException, IOException { - if (sb == null) { - sb = new StringBuilder(); - } - if (eng[0] == null) { - ScriptEngineManager sem = new ScriptEngineManager(); - ScriptEngine js = sem.getEngineByExtension("js"); - eng[0] = js; - Bck2Brwsr.newCompiler().resources(new EmulationResources()) - .obfuscation(ObfuscationLevel.NONE).generate(sb); - } - Set exp = new HashSet(); - for (String n : names) { - int last = n.lastIndexOf('/'); - exp.add(n.substring(0, last + 1)); - } - Bck2Brwsr b2b = Bck2Brwsr.newCompiler(). - resources(new EmulationResources() { - @Override - public InputStream get(String name) throws IOException { - if (name.equals(resourceName)) { - return new ByteArrayInputStream(resourceContent.getBytes("UTF-8")); - } - return super.get(name); - } - }). - addClasses(names). - addResources("org/apidesign/vm4brwsr/obj.js"). - addExported(exp.toArray(new String[0])). - obfuscation(ObfuscationLevel.FULL). - library(); - if (resourceName != null) { - b2b = b2b.addResources(resourceName); - } - b2b.generate(sb); - try { - defineAtoB(eng[0]); - Object res = eng[0].eval(sb.toString()); - assertTrue(eng[0] instanceof Invocable, "It is invocable object: " + res); - return new TestVM((Invocable) eng[0], sb); - } catch (Exception ex) { - if (sb.length() > 2000) { - sb = dumpJS(sb); - } - fail("Could not evaluate:" + ex.getClass() + ":" + ex.getMessage() + "\n" + sb, ex); - return null; - } - } - - static TestVM compileClassAndResources(StringBuilder sb, ScriptEngine[] eng, String name, String... resources) throws ScriptException, IOException { - if (sb == null) { - sb = new StringBuilder(); - } - Bck2Brwsr b2b = Bck2Brwsr.newCompiler(). - resources(new EmulationResources()). - addRootClasses(name). - addResources(resources); - b2b.generate(sb); - ScriptEngineManager sem = new ScriptEngineManager(); - ScriptEngine js = sem.getEngineByExtension("js"); - if (eng != null) { - eng[0] = js; - } - try { - defineAtoB(js); - - Object res = js.eval(sb.toString()); - assertTrue(js instanceof Invocable, "It is invocable object: " + res); - return new TestVM((Invocable) js, sb); + return new TestVM(js, sb); } catch (Exception ex) { if (sb.length() > 2000) { sb = dumpJS(sb); @@ -243,20 +153,16 @@ } } - private static void defineAtoB(ScriptEngine js) throws ScriptException { - js.eval("atob = function(s) { return new String(org.apidesign.vm4brwsr.ResourcesTest.parseBase64Binary(s)); }"); - } - Object loadClass(String loadClass, String name) throws ScriptException, NoSuchMethodException { - return code.invokeMethod(bck2brwsr, "loadClass", LoopControl.class.getName()); + return getCode().invokeMethod(bck2brwsr, "loadClass", LoopControl.class.getName()); } Object invokeMethod(Object obj, String method, Object... params) throws ScriptException, NoSuchMethodException { - return code.invokeMethod(obj, method, params); + return getCode().invokeMethod(obj, method, params); } Object invokeFunction(String methodName, Object... args) throws ScriptException, NoSuchMethodException { - return code.invokeFunction(methodName, args); + return getCode().invokeFunction(methodName, args); } static StringBuilder dumpJS(CharSequence sb) throws IOException { @@ -279,6 +185,19 @@ final CharSequence codeSeq() { return codeSeq; } + + /** + * @return the code + */ + private Invocable getCode() throws ScriptException { + if (code == null) { + Object res = js.eval(code.toString()); + code = (Invocable) js; + this.bck2brwsr = ((ScriptEngine)code).eval("bck2brwsr(function(n) { return loader.get(n); })"); + ((ScriptEngine)code).getContext().setAttribute("loader", this, ScriptContext.ENGINE_SCOPE); + } + return (Invocable)code; + } private static class EmulationResources implements Bck2Brwsr.Resources { @Override