konsoletyper 2015-02-21 13:04:09 +04:00
parent 123aac84fa
commit 34aeb6e3c9
6 changed files with 44 additions and 9 deletions

View File

@ -252,6 +252,10 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent {
if (methodRef == null) {
throw new IllegalArgumentException();
}
MethodReader methodReader = methodReaderCache.map(methodRef);
if (methodReader != null) {
methodRef = methodReader.getReference();
}
callGraph.getNode(methodRef);
boolean added = true;
if (callLocation != null && callLocation.getMethod() != null) {
@ -472,6 +476,12 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent {
return methodCache.getKnown(methodRef);
}
@Override
public MethodDependency getMethodImplementation(MethodReference methodRef) {
MethodReader method = methodReaderCache.map(methodRef);
return method != null ? methodCache.getKnown(method.getReference()) : null;
}
public void processDependencies() {
interrupted = false;
int index = 0;

View File

@ -40,6 +40,8 @@ public interface DependencyInfo {
MethodDependencyInfo getMethod(MethodReference methodRef);
MethodDependencyInfo getMethodImplementation(MethodReference methodRef);
ClassDependencyInfo getClass(String className);
CallGraph getCallGraph();

View File

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

View File

@ -28,9 +28,11 @@ import org.teavm.model.instructions.MonitorEnterInstruction;
public class AsyncProgramSplitter {
private List<Part> parts = new ArrayList<>();
private Map<Long, Integer> partMap = new HashMap<>();
private ClassReaderSource classSource;
private Set<MethodReference> asyncMethods = new HashSet<>();
public AsyncProgramSplitter(Set<MethodReference> asyncMethods) {
public AsyncProgramSplitter(ClassReaderSource classSource, Set<MethodReference> asyncMethods) {
this.classSource = classSource;
this.asyncMethods = asyncMethods;
}
@ -62,7 +64,7 @@ public class AsyncProgramSplitter {
Integer receiver;
if (insn instanceof InvokeInstruction) {
InvokeInstruction invoke = (InvokeInstruction)insn;
if (!asyncMethods.contains(invoke.getMethod())) {
if (!asyncMethods.contains(findRealMethod(invoke.getMethod()))) {
continue;
}
receiver = invoke.getReceiver() != null ? invoke.getReceiver().getIndex() : null;
@ -148,6 +150,25 @@ public class AsyncProgramSplitter {
partMap.clear();
}
private MethodReference findRealMethod(MethodReference method) {
String clsName = method.getClassName();
while (clsName != null) {
ClassReader cls = classSource.get(clsName);
if (cls == null) {
break;
}
MethodReader methodReader = cls.getMethod(method.getDescriptor());
if (methodReader != null) {
return new MethodReference(clsName, method.getDescriptor());
}
clsName = cls.getParent();
if (clsName != null && clsName.equals(cls.getName())) {
break;
}
}
return method;
}
private Program createStubCopy(Program program) {
Program copy = new Program();
for (int i = 0; i < program.basicBlockCount(); ++i) {

View File

@ -74,7 +74,8 @@ public class Devirtualization {
if (cls == null || !isAssignable(ref.getClassName(), cls)) {
continue;
}
MethodDependencyInfo methodDep = dependency.getMethod(new MethodReference(className, ref.getDescriptor()));
MethodDependencyInfo methodDep = dependency.getMethodImplementation(new MethodReference(
className, ref.getDescriptor()));
if (methodDep != null) {
methods.add(methodDep.getReference());
}

View File

@ -558,6 +558,9 @@ function $rt_guardAsync(f, continuation) {
function TeaVMAsyncError(cause) {
this.message = "Async error occured";
this.cause = cause;
if (cause) {
this.$javaException = cause.$javaException;
}
}
TeaVMAsyncError.prototype = new Error();
TeaVMAsyncError.prototype.constructor = TeaVMAsyncError;