Fixes devirtualization bug. Adds exception message displaying when test

fails. Fixes java.util.Arrays.deepToString
This commit is contained in:
konsoletyper 2014-03-11 10:41:59 +04:00
parent 79a4983fb5
commit d8477f1e9d
6 changed files with 114 additions and 3 deletions

View File

@ -1514,7 +1514,7 @@ public class TArrays extends TObject {
deepToString(a[0], out, visited);
for (int i = 1; i < a.length; ++i) {
out.append(TString.wrap(", "));
deepToString(a[0], out, visited);
deepToString(a[i], out, visited);
}
}
visited.remove(visited.size() - 1);

View File

@ -67,9 +67,12 @@ public class Devirtualization {
private Set<MethodReference> getImplementations(String[] classNames, MethodReference ref) {
Set<MethodReference> methods = new HashSet<>();
for (String className : classNames) {
if (className.startsWith("[")) {
className = "java.lang.Object";
}
ClassReader cls = classSource.get(className);
if (cls == null || !isAssignable(ref.getClassName(), cls)) {
break;
continue;
}
MethodDependencyInfo methodDep = dependency.getMethod(new MethodReference(className, ref.getDescriptor()));
if (methodDep != null) {

View File

@ -318,6 +318,7 @@ public class BuildJavascriptTestMojo extends AbstractMojo {
.build();
vm.setMinifying(minifying);
vm.installPlugins();
new TestExceptionPlugin().install(vm);
for (ClassHolderTransformer transformer : transformerInstances) {
vm.add(transformer);
}
@ -326,8 +327,11 @@ public class BuildJavascriptTestMojo extends AbstractMojo {
try (Writer innerWriter = new OutputStreamWriter(new FileOutputStream(file), "UTF-8")) {
MethodReference cons = new MethodReference(methodRef.getClassName(),
new MethodDescriptor("<init>", ValueType.VOID));
MethodReference exceptionMsg = new MethodReference("java.lang.Throwable", "getMessage",
ValueType.object("java.lang.String"));
vm.entryPoint("initInstance", cons);
vm.entryPoint("runTest", methodRef).withValue(0, cons.getClassName());
vm.entryPoint("extractException", exceptionMsg);
vm.exportType("TestClass", cons.getClassName());
vm.build(innerWriter, new DirectoryBuildTarget(outputDir));
if (!vm.hasMissingItems()) {

View File

@ -0,0 +1,69 @@
/*
* Copyright 2014 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.maven;
import org.teavm.dependency.*;
import org.teavm.model.ClassReader;
import org.teavm.model.ClassReaderSource;
import org.teavm.model.MethodReference;
import org.teavm.model.ValueType;
/**
*
* @author Alexey Andreev
*/
class TestExceptionDependency implements DependencyListener {
private MethodReference getMessageRef = new MethodReference("java.lang.Throwable", "getMessage",
ValueType.object("java.lang.String"));
private DependencyNode allClasses;
@Override
public void started(DependencyChecker dependencyChecker) {
allClasses = dependencyChecker.createNode();
}
@Override
public void classAchieved(DependencyChecker dependencyChecker, String className) {
if (isException(dependencyChecker.getClassSource(), className)) {
allClasses.propagate(className);
}
}
private boolean isException(ClassReaderSource classSource, String className) {
while (className != null) {
if (className.equals("java.lang.Throwable")) {
return true;
}
ClassReader cls = classSource.get(className);
if (cls == null) {
return false;
}
className = cls.getParent();
}
return false;
}
@Override
public void methodAchieved(DependencyChecker dependencyChecker, MethodDependency method) {
if (method.getReference().equals(getMessageRef)) {
allClasses.connect(method.getVariable(0));
}
}
@Override
public void fieldAchieved(DependencyChecker dependencyChecker, FieldDependency field) {
}
}

View File

@ -0,0 +1,30 @@
/*
* Copyright 2014 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.maven;
import org.teavm.vm.spi.TeaVMHost;
import org.teavm.vm.spi.TeaVMPlugin;
/**
*
* @author Alexey Andreev
*/
public class TestExceptionPlugin implements TeaVMPlugin {
@Override
public void install(TeaVMHost host) {
host.add(new TestExceptionDependency());
}
}

View File

@ -221,8 +221,13 @@ JUnitClient.run = function() {
message.status = "exception";
if (e.$javaException && e.$javaException.constructor.$meta) {
message.exception = e.$javaException.constructor.$meta.name;
message.stack = e.$javaException.constructor.$meta.name + ": ";
var exceptionMessage = extractException(e.$javaException);
message.stack += exceptionMessage ? $rt_ustr(exceptionMessage) : "";
message.stack += "\n" + e.stack;
} else {
message.stack = e.stack;
}
message.stack = e.stack;
}
window.parent.postMessage(JSON.stringify(message), "*");
});