# HG changeset patch # User Jaroslav Tulach # Date 1358157471 -3600 # Node ID b107ed66f2e762a6d1ace7960fb1d38a7ccebbd8 # Parent d7ec46950980ab417cd0ea7f8bef72051434c0a1 Following standard object oriented calling conventions. Method run of Runnable r can now be called as r.run__V() diff -r d7ec46950980 -r b107ed66f2e7 emul/src/main/java/java/lang/Class.java --- a/emul/src/main/java/java/lang/Class.java Sun Jan 13 06:59:05 2013 +0100 +++ b/emul/src/main/java/java/lang/Class.java Mon Jan 14 10:57:51 2013 +0100 @@ -216,7 +216,7 @@ + "\nif (c['cons__V']) {" + "\n if ((c.cons__V.access & 0x1) != 0) {" + "\n var inst = c();" - + "\n c.cons__V(inst);" + + "\n c.cons__V.call(inst);" + "\n return inst;" + "\n }" + "\n return illegal;" diff -r d7ec46950980 -r b107ed66f2e7 vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Sun Jan 13 06:59:05 2013 +0100 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Mon Jan 14 10:57:51 2013 +0100 @@ -249,7 +249,7 @@ new LocalsMapper(stackMapIterator.getArguments()); out.append(prefix).append(name).append(" = function("); - lmapper.outputArguments(out); + lmapper.outputArguments(out, m.isStatic()); out.append(") {").append("\n"); final byte[] byteCodes = m.getCode(); @@ -275,6 +275,9 @@ out.append(';'); } } + if (!m.isStatic()) { + out.append(" var ").append(" lcA0 = this;\n"); + } // maxStack includes two stack positions for every pushed long / double // so this might generate more stack variables than we need @@ -1330,7 +1333,11 @@ out.append("constructor."); } out.append(mn); - out.append('('); + if (isStatic) { + out.append('('); + } else { + out.append(".call("); + } if (numArguments > 0) { out.append(vars[0]); for (int j = 1; j < numArguments; ++j) { @@ -1366,10 +1373,11 @@ out.append(vars[0]).append('.'); out.append(mn); out.append('('); - out.append(vars[0]); + String sep = ""; for (int j = 1; j < numArguments; ++j) { - out.append(", "); + out.append(sep); out.append(vars[j]); + sep = ", "; } out.append(");"); i += 2; @@ -1443,13 +1451,11 @@ final String mn = findMethodName(m, cnt); out.append(prefix).append(mn); out.append(" = function("); - String space; + String space = ""; int index; if (!isStatic) { - space = outputArg(out, p.args, 0); index = 1; } else { - space = ""; index = 0; } for (int i = 0; i < cnt.length(); i++) { @@ -1458,6 +1464,9 @@ index++; } out.append(") {").append("\n"); + if (!isStatic) { + out.append(" var ").append(p.args[0]).append(" = this;\n"); + } out.append(p.body); out.append("\n}\n"); return mn; @@ -1600,7 +1609,7 @@ out.append(" stA0 = e;"); out.append("} else {"); out.append(" stA0 = vm.java_lang_Throwable(true);"); - out.append(" vm.java_lang_Throwable.cons__VLjava_lang_String_2(stA0, e.toString());"); + out.append(" vm.java_lang_Throwable.cons__VLjava_lang_String_2.call(stA0, e.toString());"); out.append("}"); out.append("gt=" + e.handler_pc + "; continue;"); } else { diff -r d7ec46950980 -r b107ed66f2e7 vm/src/main/java/org/apidesign/vm4brwsr/LocalsMapper.java --- a/vm/src/main/java/org/apidesign/vm4brwsr/LocalsMapper.java Sun Jan 13 06:59:05 2013 +0100 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/LocalsMapper.java Mon Jan 14 10:57:51 2013 +0100 @@ -33,13 +33,14 @@ localTypeRecords = new TypeArray(initTypeRecords); } - public void outputArguments(final Appendable out) throws IOException { + public void outputArguments(final Appendable out, boolean isStatic) throws IOException { final int argRecordCount = argTypeRecords.getSize(); - if (argRecordCount > 0) { - Variable variable = getVariable(argTypeRecords, 0); + int first = isStatic ? 0 : 1; + if (argRecordCount > first) { + Variable variable = getVariable(argTypeRecords, first); out.append(variable); - int i = variable.isCategory2() ? 2 : 1; + int i = first + (variable.isCategory2() ? 2 : 1); while (i < argRecordCount) { variable = getVariable(argTypeRecords, i); out.append(", "); diff -r d7ec46950980 -r b107ed66f2e7 vm/src/main/java/org/apidesign/vm4brwsr/VM.java --- a/vm/src/main/java/org/apidesign/vm4brwsr/VM.java Sun Jan 13 06:59:05 2013 +0100 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/VM.java Mon Jan 14 10:57:51 2013 +0100 @@ -117,7 +117,7 @@ + " var loader = {};\n" + " loader.vm = vm;\n" + " loader.loadClass = function(name) {\n" - + " var attr = name.replace__Ljava_lang_String_2CC(name, '.','_');\n" + + " var attr = name.replace__Ljava_lang_String_2CC('.','_');\n" + " var fn = vm[attr];\n" + " if (fn) return fn(false);\n" + " if (!args[0]) throw 'bck2brwsr initialized without loader function, cannot load ' + name;\n" diff -r d7ec46950980 -r b107ed66f2e7 vm/src/main/java/org/apidesign/vm4brwsr/VMLazy.java --- a/vm/src/main/java/org/apidesign/vm4brwsr/VMLazy.java Sun Jan 13 06:59:05 2013 +0100 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/VMLazy.java Mon Jan 14 10:57:51 2013 +0100 @@ -114,15 +114,15 @@ @JavaScriptBody(args = {"self", "n"}, body = - "var cls = n.replace__Ljava_lang_String_2CC(n, '/','_').toString();" - + "\nvar dot = n.replace__Ljava_lang_String_2CC(n,'/','.').toString();" + "var cls = n.replace__Ljava_lang_String_2CC('/','_').toString();" + + "\nvar dot = n.replace__Ljava_lang_String_2CC('/','.').toString();" + "\nvar lazy = self.fld_lazy;" + "\nvar loader = lazy.fld_loader;" + "\nvar vm = loader.vm;" + "\nif (vm[cls]) return false;" + "\nvm[cls] = function() {" + "\n var instance = arguments.length == 0 || arguments[0] === true;" - + "\n return lazy.load__Ljava_lang_Object_2Ljava_lang_String_2Z(lazy, dot, instance);" + + "\n return lazy.load__Ljava_lang_Object_2Ljava_lang_String_2Z(dot, instance);" + "\n};" + "\nreturn true;") @Override diff -r d7ec46950980 -r b107ed66f2e7 vm/src/test/java/org/apidesign/vm4brwsr/Instance.java --- a/vm/src/test/java/org/apidesign/vm4brwsr/Instance.java Sun Jan 13 06:59:05 2013 +0100 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/Instance.java Mon Jan 14 10:57:51 2013 +0100 @@ -125,4 +125,11 @@ public static boolean iofObject() { return jsObj() instanceof Object; } + + public static int jscall() { + return jsgetbytes(new Instance()); + } + + @JavaScriptBody(args = { "instance" }, body = "return instance.getByte__B();") + private static native int jsgetbytes(Instance instance); } diff -r d7ec46950980 -r b107ed66f2e7 vm/src/test/java/org/apidesign/vm4brwsr/InstanceTest.java --- a/vm/src/test/java/org/apidesign/vm4brwsr/InstanceTest.java Sun Jan 13 06:59:05 2013 +0100 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/InstanceTest.java Mon Jan 14 10:57:51 2013 +0100 @@ -131,6 +131,14 @@ Double.valueOf(1) ); } + + @Test public void jsCallingConvention() throws Exception { + assertExec( + "Pointer to 'this' is passed automatically (and not as a first argument)", + Instance.class, "jscall__I", + Double.valueOf(31) + ); + } protected String startCompilationWith() { return "org/apidesign/vm4brwsr/Instance";