First working prototype of CPS

This commit is contained in:
konsoletyper 2015-02-01 22:55:33 +04:00
parent 62d3e9f40e
commit 071f2bb46c
4 changed files with 33 additions and 11 deletions

View File

@ -156,11 +156,11 @@ public class Decompiler {
} }
public MethodNode decompile(MethodHolder method) { 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); !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()); Generator generator = generators.get(method.getReference());
if (generator == null) { if (generator == null) {
AnnotationHolder annotHolder = method.getAnnotations().get(GeneratedBy.class.getName()); AnnotationHolder annotHolder = method.getAnnotations().get(GeneratedBy.class.getName());
@ -182,7 +182,7 @@ public class Decompiler {
method.getDescriptor())); method.getDescriptor()));
methodNode.getModifiers().addAll(mapModifiers(method.getModifiers())); methodNode.getModifiers().addAll(mapModifiers(method.getModifiers()));
methodNode.setGenerator(generator); methodNode.setGenerator(generator);
methodNode.setAsync(async); methodNode.setAsync(asyncMethods.contains(method.getReference()));
return methodNode; return methodNode;
} }

View File

@ -526,7 +526,10 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
writer.append(variableName(i)); writer.append(variableName(i));
} }
if (method.isAsync()) { 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(); writer.append(")").ws().append("{").softNewLine().indent();
method.acceptVisitor(new MethodBodyRenderer()); method.acceptVisitor(new MethodBodyRenderer());
@ -1438,6 +1441,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
lastCallSite = callSite; lastCallSite = callSite;
} }
boolean virtual = false; boolean virtual = false;
boolean hasParams = false;
switch (expr.getType()) { switch (expr.getType()) {
case STATIC: case STATIC:
writer.append(fullName).append("("); writer.append(fullName).append("(");
@ -1447,12 +1451,14 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
writer.append(",").ws(); writer.append(",").ws();
} }
expr.getArguments().get(i).acceptVisitor(this); expr.getArguments().get(i).acceptVisitor(this);
hasParams = true;
} }
break; break;
case SPECIAL: case SPECIAL:
writer.append(fullName).append("("); writer.append(fullName).append("(");
prevCallSite = debugEmitter.emitCallSite(); prevCallSite = debugEmitter.emitCallSite();
expr.getArguments().get(0).acceptVisitor(this); expr.getArguments().get(0).acceptVisitor(this);
hasParams = true;
for (int i = 1; i < expr.getArguments().size(); ++i) { for (int i = 1; i < expr.getArguments().size(); ++i) {
writer.append(",").ws(); writer.append(",").ws();
expr.getArguments().get(i).acceptVisitor(this); expr.getArguments().get(i).acceptVisitor(this);
@ -1465,6 +1471,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
if (i > 1) { if (i > 1) {
writer.append(",").ws(); writer.append(",").ws();
} }
hasParams = true;
expr.getArguments().get(i).acceptVisitor(this); expr.getArguments().get(i).acceptVisitor(this);
} }
virtual = true; virtual = true;
@ -1476,12 +1483,16 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
if (i > 0) { if (i > 0) {
writer.append(",").ws(); writer.append(",").ws();
} }
hasParams = true;
expr.getArguments().get(i).acceptVisitor(this); expr.getArguments().get(i).acceptVisitor(this);
} }
break; break;
} }
if (expr.getAsyncTarget() != null) { 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(')'); writer.append(')');
if (lastCallSite != null) { if (lastCallSite != null) {

View File

@ -436,7 +436,8 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
renderer.renderStringPool(); renderer.renderStringPool();
for (Map.Entry<String, TeaVMEntryPoint> entry : entryPoints.entrySet()) { for (Map.Entry<String, TeaVMEntryPoint> entry : entryPoints.entrySet()) {
sourceWriter.append("var ").append(entry.getKey()).ws().append("=").ws() 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<String, String> entry : exportedClasses.entrySet()) { for (Map.Entry<String, String> entry : exportedClasses.entrySet()) {
sourceWriter.append("var ").append(entry.getKey()).ws().append("=").ws() sourceWriter.append("var ").append(entry.getKey()).ws().append("=").ws()

View File

@ -406,6 +406,14 @@ function $rt_asyncAdapter(f) {
return $return(result); 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; var $rt_stringPool_instance;
function $rt_stringPool(strings) { function $rt_stringPool(strings) {
$rt_stringPool_instance = new Array(strings.length); $rt_stringPool_instance = new Array(strings.length);
@ -420,11 +428,13 @@ var $rt_continueCounter = 0;
function $rt_continue(f) { function $rt_continue(f) {
if ($rt_continueCounter++ == 10) { if ($rt_continueCounter++ == 10) {
$rt_continueCounter = 0; $rt_continueCounter = 0;
var self = f; return function() {
var args = arguments; var self = this;
setTimeout(function() { var args = arguments;
f.apply(self, args); setTimeout(function() {
}, 0); f.apply(self, args);
}, 0);
};
} else { } else {
return f; return f;
} }