This commit is contained in:
konsoletyper 2015-02-14 01:18:43 +04:00
parent 4cf084d848
commit 4ce1031c0c
6 changed files with 35 additions and 23 deletions

View File

@ -36,7 +36,7 @@ public class TThread extends TObject implements TRunnable {
private long id; private long id;
private TString name; private TString name;
private TRunnable target; TRunnable target;
public TThread() { public TThread() {
this(null, null); this(null, null);

View File

@ -46,11 +46,14 @@ public class Decompiler {
private Set<MethodReference> methodsToPass = new HashSet<>(); private Set<MethodReference> methodsToPass = new HashSet<>();
private RegularMethodNodeCache regularMethodCache; private RegularMethodNodeCache regularMethodCache;
private Set<MethodReference> asyncMethods; private Set<MethodReference> asyncMethods;
private Set<MethodReference> asyncFamilyMethods;
public Decompiler(ClassHolderSource classSource, ClassLoader classLoader, Set<MethodReference> asyncMethods) { public Decompiler(ClassHolderSource classSource, ClassLoader classLoader, Set<MethodReference> asyncMethods,
Set<MethodReference> asyncFamilyMethods) {
this.classSource = classSource; this.classSource = classSource;
this.classLoader = classLoader; this.classLoader = classLoader;
this.asyncMethods = asyncMethods; this.asyncMethods = asyncMethods;
this.asyncFamilyMethods = asyncFamilyMethods;
} }
public RegularMethodNodeCache getRegularMethodCache() { public RegularMethodNodeCache getRegularMethodCache() {
@ -196,7 +199,10 @@ public class Decompiler {
public AsyncMethodNode decompileAsync(MethodHolder method) { public AsyncMethodNode decompileAsync(MethodHolder method) {
AsyncMethodNode node = new AsyncMethodNode(method.getReference()); AsyncMethodNode node = new AsyncMethodNode(method.getReference());
AsyncProgramSplitter splitter = new AsyncProgramSplitter(asyncMethods); Set<MethodReference> splitMethods = new HashSet<>();
splitMethods.addAll(asyncMethods);
splitMethods.addAll(asyncFamilyMethods);
AsyncProgramSplitter splitter = new AsyncProgramSplitter(splitMethods);
splitter.split(method.getProgram()); splitter.split(method.getProgram());
for (int i = 0; i < splitter.size(); ++i) { for (int i = 0; i < splitter.size(); ++i) {
Integer input = null; Integer input = null;

View File

@ -76,6 +76,9 @@ public class AsyncMethodFinder {
} }
} }
} }
for (MethodReference method : asyncMethods) {
addOverridenToFamily(method);
}
for (String clsName : classSource.getClassNames()) { for (String clsName : classSource.getClassNames()) {
ClassReader cls = classSource.get(clsName); ClassReader cls = classSource.get(clsName);
for (MethodReader method : cls.getMethods()) { for (MethodReader method : cls.getMethods()) {
@ -114,16 +117,16 @@ public class AsyncMethodFinder {
for (CallSite callSite : node.getCallerCallSites()) { for (CallSite callSite : node.getCallerCallSites()) {
add(callSite.getCaller().getMethod()); add(callSite.getCaller().getMethod());
} }
Set<MethodReference> visited = new HashSet<>(); }
Set<MethodReference> overriden = new HashSet<>();
if (cls.getParent() != null && !cls.getParent().equals(cls.getName())) { private void addOverridenToFamily(MethodReference methodRef) {
findOverridenMethods(new MethodReference(cls.getParent(), methodRef.getDescriptor()), overriden, visited); asyncFamilyMethods.put(methodRef, true);
ClassReader cls = classSource.get(methodRef.getClassName());
if (cls == null) {
return;
} }
for (String iface : cls.getInterfaces()) { for (MethodReference overridenMethod : findOverridenMethods(cls, methodRef)) {
findOverridenMethods(new MethodReference(iface, methodRef.getDescriptor()), overriden, visited); addOverridenToFamily(overridenMethod);
}
for (MethodReference overridenMethod : overriden) {
add(overridenMethod);
} }
} }
@ -145,6 +148,15 @@ public class AsyncMethodFinder {
if (cls == null) { if (cls == null) {
return false; return false;
} }
for (MethodReference overridenMethod : findOverridenMethods(cls, methodRef)) {
if (addToFamily(overridenMethod)) {
return true;
}
}
return false;
}
private Set<MethodReference> findOverridenMethods(ClassReader cls, MethodReference methodRef) {
List<String> parents = new ArrayList<>(); List<String> parents = new ArrayList<>();
if (cls.getParent() != null && !cls.getParent().equals(cls.getName())) { if (cls.getParent() != null && !cls.getParent().equals(cls.getName())) {
parents.add(cls.getParent()); parents.add(cls.getParent());
@ -156,13 +168,7 @@ public class AsyncMethodFinder {
for (String parent : parents) { for (String parent : parents) {
findOverridenMethods(new MethodReference(parent, methodRef.getDescriptor()), overriden, visited); findOverridenMethods(new MethodReference(parent, methodRef.getDescriptor()), overriden, visited);
} }
return overriden;
for (MethodReference overridenMethod : overriden) {
if (addToFamily(overridenMethod)) {
return true;
}
}
return false;
} }
private void findOverridenMethods(MethodReference methodRef, Set<MethodReference> result, private void findOverridenMethods(MethodReference methodRef, Set<MethodReference> result,

View File

@ -562,7 +562,7 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
asyncFamilyMethods.addAll(asyncFinder.getAsyncFamilyMethods()); asyncFamilyMethods.addAll(asyncFinder.getAsyncFamilyMethods());
progressListener.phaseStarted(TeaVMPhase.DECOMPILATION, classes.getClassNames().size()); progressListener.phaseStarted(TeaVMPhase.DECOMPILATION, classes.getClassNames().size());
Decompiler decompiler = new Decompiler(classes, classLoader, asyncFinder.getAsyncMethods()); Decompiler decompiler = new Decompiler(classes, classLoader, asyncMethods, asyncFamilyMethods);
decompiler.setRegularMethodCache(incremental ? astCache : null); decompiler.setRegularMethodCache(incremental ? astCache : null);
for (Map.Entry<MethodReference, Generator> entry : methodGenerators.entrySet()) { for (Map.Entry<MethodReference, Generator> entry : methodGenerators.entrySet()) {

View File

@ -472,7 +472,7 @@ function $rt_asyncAdapter(f) {
return $return($rt_asyncResult(result)); return $return($rt_asyncResult(result));
} }
} }
function $rt_rootInvocationAdapter(f, extraArgs) { function $rt_rootInvocationAdapter(f) {
return function() { return function() {
var args = Array.prototype.slice.apply(arguments); var args = Array.prototype.slice.apply(arguments);
args.push(function(result) { args.push(function(result) {

View File

@ -132,8 +132,8 @@ public class PlatformGenerator implements Generator, Injector, DependencyPlugin
private void generateStartThread(GeneratorContext context, SourceWriter writer) throws IOException { private void generateStartThread(GeneratorContext context, SourceWriter writer) throws IOException {
String runnable = context.getParameterName(1); String runnable = context.getParameterName(1);
writer.append("window.setTimeout(function()").ws().append("{").indent().softNewLine(); writer.append("window.setTimeout(function()").ws().append("{").indent().softNewLine();
writer.appendMethodBody(Platform.class, "launchThread", Runnable.class, void.class).append("(") writer.append("$rt_rootInvocationAdapter(").appendMethodBody(Platform.class, "launchThread", Runnable.class,
.append(runnable).append(");").softNewLine(); void.class).append(")(").append(runnable).append(");").softNewLine();
writer.outdent().append("},").ws().append("0);").softNewLine(); writer.outdent().append("},").ws().append("0);").softNewLine();
} }
} }