From 071f2bb46caab356b6cc1544b4e486f930025be4 Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Sun, 1 Feb 2015 22:55:33 +0400 Subject: [PATCH] First working prototype of CPS --- .../java/org/teavm/javascript/Decompiler.java | 6 +++--- .../java/org/teavm/javascript/Renderer.java | 15 ++++++++++++-- .../src/main/java/org/teavm/vm/TeaVM.java | 3 ++- .../resources/org/teavm/javascript/runtime.js | 20 ++++++++++++++----- 4 files changed, 33 insertions(+), 11 deletions(-) diff --git a/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java b/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java index e11b7c07a..8e97a19d9 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java @@ -156,11 +156,11 @@ public class Decompiler { } public MethodNode decompile(MethodHolder method) { - return method.getModifiers().contains(ElementModifier.NATIVE) ? decompileNative(method, false) : + return method.getModifiers().contains(ElementModifier.NATIVE) ? decompileNative(method) : !asyncMethods.contains(method.getReference()) ? decompileRegular(method) : decompileAsync(method); } - public NativeMethodNode decompileNative(MethodHolder method, boolean async) { + public NativeMethodNode decompileNative(MethodHolder method) { Generator generator = generators.get(method.getReference()); if (generator == null) { AnnotationHolder annotHolder = method.getAnnotations().get(GeneratedBy.class.getName()); @@ -182,7 +182,7 @@ public class Decompiler { method.getDescriptor())); methodNode.getModifiers().addAll(mapModifiers(method.getModifiers())); methodNode.setGenerator(generator); - methodNode.setAsync(async); + methodNode.setAsync(asyncMethods.contains(method.getReference())); return methodNode; } diff --git a/teavm-core/src/main/java/org/teavm/javascript/Renderer.java b/teavm-core/src/main/java/org/teavm/javascript/Renderer.java index 16befdbe6..d6b55904d 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Renderer.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Renderer.java @@ -526,7 +526,10 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext writer.append(variableName(i)); } if (method.isAsync()) { - writer.append(',').ws().append("$return,").ws().append("$throw"); + if (startParam < ref.parameterCount() + 1) { + writer.append(',').ws(); + } + writer.append("$return,").ws().append("$throw"); } writer.append(")").ws().append("{").softNewLine().indent(); method.acceptVisitor(new MethodBodyRenderer()); @@ -1438,6 +1441,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext lastCallSite = callSite; } boolean virtual = false; + boolean hasParams = false; switch (expr.getType()) { case STATIC: writer.append(fullName).append("("); @@ -1447,12 +1451,14 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext writer.append(",").ws(); } expr.getArguments().get(i).acceptVisitor(this); + hasParams = true; } break; case SPECIAL: writer.append(fullName).append("("); prevCallSite = debugEmitter.emitCallSite(); expr.getArguments().get(0).acceptVisitor(this); + hasParams = true; for (int i = 1; i < expr.getArguments().size(); ++i) { writer.append(",").ws(); expr.getArguments().get(i).acceptVisitor(this); @@ -1465,6 +1471,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext if (i > 1) { writer.append(",").ws(); } + hasParams = true; expr.getArguments().get(i).acceptVisitor(this); } virtual = true; @@ -1476,12 +1483,16 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext if (i > 0) { writer.append(",").ws(); } + hasParams = true; expr.getArguments().get(i).acceptVisitor(this); } break; } if (expr.getAsyncTarget() != null) { - writer.append(',').ws().append("$rt_continue($part_").append(expr.getAsyncTarget()).append(')'); + if (hasParams) { + writer.append(',').ws(); + } + writer.append("$rt_continue($part_").append(expr.getAsyncTarget()).append(')'); } writer.append(')'); if (lastCallSite != null) { diff --git a/teavm-core/src/main/java/org/teavm/vm/TeaVM.java b/teavm-core/src/main/java/org/teavm/vm/TeaVM.java index ea59790cc..7a03aa30b 100644 --- a/teavm-core/src/main/java/org/teavm/vm/TeaVM.java +++ b/teavm-core/src/main/java/org/teavm/vm/TeaVM.java @@ -436,7 +436,8 @@ public class TeaVM implements TeaVMHost, ServiceRepository { renderer.renderStringPool(); for (Map.Entry entry : entryPoints.entrySet()) { sourceWriter.append("var ").append(entry.getKey()).ws().append("=").ws() - .appendMethodBody(entry.getValue().reference).append(";").softNewLine(); + .append("$rt_rootInvocationAdapter(") + .appendMethodBody(entry.getValue().reference).append(");").softNewLine(); } for (Map.Entry entry : exportedClasses.entrySet()) { sourceWriter.append("var ").append(entry.getKey()).ws().append("=").ws() diff --git a/teavm-core/src/main/resources/org/teavm/javascript/runtime.js b/teavm-core/src/main/resources/org/teavm/javascript/runtime.js index e4ade6e48..e71694365 100644 --- a/teavm-core/src/main/resources/org/teavm/javascript/runtime.js +++ b/teavm-core/src/main/resources/org/teavm/javascript/runtime.js @@ -406,6 +406,14 @@ function $rt_asyncAdapter(f) { return $return(result); } } +function $rt_rootInvocationAdapter(f) { + return function() { + var args = Array.prototype.slice.apply(arguments); + args.push(function() {}); + args.push(function() {}); + return f.apply(this, args); + } +} var $rt_stringPool_instance; function $rt_stringPool(strings) { $rt_stringPool_instance = new Array(strings.length); @@ -420,11 +428,13 @@ var $rt_continueCounter = 0; function $rt_continue(f) { if ($rt_continueCounter++ == 10) { $rt_continueCounter = 0; - var self = f; - var args = arguments; - setTimeout(function() { - f.apply(self, args); - }, 0); + return function() { + var self = this; + var args = arguments; + setTimeout(function() { + f.apply(self, args); + }, 0); + }; } else { return f; }