# HG changeset patch # User Jaroslav Tulach # Date 1401266838 -7200 # Node ID 752f48257d4aa94d0ff827c99ffc33ea50bb2380 # Parent 5186733b7e07b8640fa702ef7c2593ee11a05f9b All classes loaded through the 'vm' object will have 'invoke' method that can be used to invoke static methods like main(String[]), so our examples no longer need to rely on initialization in static initializers. diff -r 5186733b7e07 -r 752f48257d4a javaquery/demo-calculator/src/main/java/org/apidesign/bck2brwsr/demo/calc/staticcompilation/Calc.java --- a/javaquery/demo-calculator/src/main/java/org/apidesign/bck2brwsr/demo/calc/staticcompilation/Calc.java Wed May 28 09:07:48 2014 +0200 +++ b/javaquery/demo-calculator/src/main/java/org/apidesign/bck2brwsr/demo/calc/staticcompilation/Calc.java Wed May 28 10:47:18 2014 +0200 @@ -39,7 +39,7 @@ @Property(name = "history", type = double.class, array = true) }) public class Calc { - static { + public static void main(String... args) throws Exception { new Calculator().applyBindings().setOperation("plus"); } diff -r 5186733b7e07 -r 752f48257d4a javaquery/demo-calculator/src/main/resources/org/apidesign/bck2brwsr/demo/calc/staticcompilation/Calculator.xhtml --- a/javaquery/demo-calculator/src/main/resources/org/apidesign/bck2brwsr/demo/calc/staticcompilation/Calculator.xhtml Wed May 28 09:07:48 2014 +0200 +++ b/javaquery/demo-calculator/src/main/resources/org/apidesign/bck2brwsr/demo/calc/staticcompilation/Calculator.xhtml Wed May 28 10:47:18 2014 +0200 @@ -92,7 +92,8 @@ diff -r 5186733b7e07 -r 752f48257d4a rt/vm/src/main/java/org/apidesign/vm4brwsr/Bck2Brwsr.java --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/Bck2Brwsr.java Wed May 28 09:07:48 2014 +0200 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/Bck2Brwsr.java Wed May 28 10:47:18 2014 +0200 @@ -26,7 +26,7 @@ * be used to bootstrap and load the virtual machine:
  * var vm = bck2brwsr();
  * var main = vm.loadClass('org.your.pkg.Main');
- * main.main__V_3Ljava_lang_String_2(null);
+ * main.invoke('main');
  * 
* In case one wants to initialize the virtual machine with ability to * load classes lazily when needed, one can provide a loader function to @@ -39,15 +39,27 @@ * function is asked for its byte code and the system dynamically transforms * it to JavaScript. *

- * Instead of a loader function, one can also provide a URL to a JAR file. + * Instead of a loader function, one can also provide a URL to a JAR file + * or a library JavaScript file generated with {@link #library(java.lang.String...)} + * option on. * The bck2brwsr system will do its best to download the file - * and provide loader function for it automatically. + * and provide loader function for it automatically. In order to use + * the JAR file emul.zip module needs to be available in the system. *

- * One can provide as many loader functions and JAR URL references as necessary. + * One can provide as many loader functions and URL references as necessary. * Then the initialization code would look like:

  * var vm = bck2brwsr(url1, url2, fnctn1, url3, functn2);
  * 
* The provided URLs and loader functions will be consulted one by one. + *

+ * The initialization of the Bck2Brwsr is done asynchronously since + * version 0.9. E.g. call to

+ * var vm = bck2brwsr('myapp.js');
+ * var main = vm.loadClass('org.your.pkg.Main');
+ * main.invoke('main');
+ * 
+ * returns immediately and the call to the static main method will happen + * once the virtual machine is initialized and the class available. * * @author Jaroslav Tulach */ diff -r 5186733b7e07 -r 752f48257d4a rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java Wed May 28 09:07:48 2014 +0200 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java Wed May 28 10:47:18 2014 +0200 @@ -493,14 +493,28 @@ + " var at = pending.indexOf(ev.target);\n" + " pending.splice(at, 1);\n" + " if (pending.length === 0) {\n" - + " for (var i = 0; i < pendingClasses.length; i += 2) {\n" - + " var vm = pendingClasses[i];\n" - + " var n = pendingClasses[i + 1];\n" - + " vm.loadClass(n);\n" + + " for (var i = 0; i < pendingClasses.length; i += 3) {\n" + + " invokeMethod(pendingClasses[i], pendingClasses[i + 1], pendingClasses[i + 2]);\n" + " }\n" + " pendingClasses = [];\n" + " }\n" + " }\n" + + " function invokeMethod(vm, n, args) {\n" + + " var clazz = vm.loadClass(n);\n" + + " if (args) {\n" + + " var seek = args[0];\n" + + " var prefix = seek.indexOf('__') == -1 ? seek + '__' : seek;\n" + + " args = Array.prototype.slice.call(args, 1);\n" + + " var found = '';\n" + + " for (var m in clazz) {\n" + + " if (m.indexOf(prefix) === 0) {\n" + + " return clazz[m].apply(null, args);\n" + + " }\n" + + " found += m.toString() + '\\n'\n" + + " }\n" + + " throw 'Cannot find ' + seek + ' in ' + n + ' found:\\n' + found;\n" + + " }\n" + + " }\n" + " function extensionError(ev) {\n" + " console.log('error loading ' + ev.target.src);\n" + " extensionLoaded(ev);\n" @@ -611,14 +625,29 @@ + " loader.loadClass = function(name) {\n" + " if (pending.length === 0) {\n" + " try {\n" - + " return loadClass(name);\n" + + " var c = loadClass(name);\n" + + " c['invoke'] = function() {\n" + + " return invokeMethod(vm, name, arguments);\n" + + " };\n" + + " return c;\n" + " } catch (err) {\n" + " if (pending.length === 0) throw err;\n" + " }\n" + " }\n" + " pendingClasses.push(vm);\n" + " pendingClasses.push(name);\n" - + " return null;\n" + + " pendingClasses.push(null);\n" + + " return {\n" + + " 'invoke' : function() {\n" + + " if (pending.length === 0) {\n" + + " invokeMethod(vm, name, arguments);\n" + + " return;\n" + + " }\n" + + " pendingClasses.push(vm);\n" + + " pendingClasses.push(name);\n" + + " pendingClasses.push(arguments);\n" + + " }\n" + + " };\n" + " }\n" + " return loader;\n" + " };\n"); diff -r 5186733b7e07 -r 752f48257d4a rt/vm/src/test/java/org/apidesign/vm4brwsr/TestVM.java --- a/rt/vm/src/test/java/org/apidesign/vm4brwsr/TestVM.java Wed May 28 09:07:48 2014 +0200 +++ b/rt/vm/src/test/java/org/apidesign/vm4brwsr/TestVM.java Wed May 28 10:47:18 2014 +0200 @@ -23,7 +23,10 @@ import java.io.IOException; import java.io.InputStream; import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Enumeration; +import java.util.List; import javax.script.Invocable; import javax.script.ScriptContext; import javax.script.ScriptEngine; @@ -60,7 +63,10 @@ Object ret = null; try { ret = code.invokeMethod(bck2brwsr, "loadClass", clazz.getName()); - ret = code.invokeMethod(ret, method, args); + List ma = new ArrayList<>(); + ma.add(method); + ma.addAll(Arrays.asList(args)); + ret = code.invokeMethod(ret, "invoke", ma.toArray()); } catch (ScriptException ex) { fail("Execution failed in " + dumpJS(codeSeq) + ": " + ex.getMessage(), ex); } catch (NoSuchMethodException ex) {