Adds some JVM classes.

This commit is contained in:
Alexey Andreev 2013-11-22 17:19:51 +04:00
parent 04e12562a0
commit 18e35b80e6
15 changed files with 253 additions and 55 deletions

View File

@ -0,0 +1,25 @@
package org.teavm.classlib.java.lang;
import org.teavm.codegen.SourceWriter;
import org.teavm.javascript.ni.Generator;
import org.teavm.javascript.ni.GeneratorContext;
import org.teavm.model.MethodReference;
/**
*
* @author Alexey Andreev
*/
public class StringNativeGenerator implements Generator {
@Override
public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) {
switch (methodRef.getName()) {
case "wrap":
generateWrap(context, writer);
break;
}
}
private void generateWrap(GeneratorContext context, SourceWriter writer) {
writer.append("return ").append(context.getParameterName(1)).newLine();
}
}

View File

@ -0,0 +1,52 @@
package org.teavm.classlib.java.lang;
import org.teavm.codegen.SourceWriter;
import org.teavm.dependency.DependencyChecker;
import org.teavm.dependency.DependencyNode;
import org.teavm.dependency.DependencyPlugin;
import org.teavm.dependency.MethodGraph;
import org.teavm.javascript.ni.Generator;
import org.teavm.javascript.ni.GeneratorContext;
import org.teavm.model.MethodReference;
/**
*
* @author Alexey Andreev
*/
public class SystemNativeGenerator implements Generator, DependencyPlugin {
@Override
public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) {
switch (methodRef.getName()) {
case "doArrayCopy":
generateArrayCopy(context, writer);
break;
}
}
@Override
public void methodAchieved(DependencyChecker checker, MethodReference method) {
switch (method.getName()) {
case "doArrayCopy":
achieveArrayCopy(checker, method);
break;
}
}
private void generateArrayCopy(GeneratorContext context, SourceWriter writer) {
String src = context.getParameterName(1);
String srcPos = context.getParameterName(2);
String dest = context.getParameterName(3);
String destPos = context.getParameterName(4);
String length = context.getParameterName(5);
writer.append("for (var i = 0; i < " + length + "; i = (i + 1) | 0) {").indent().newLine();
writer.append(dest + "[" + srcPos + "++] = " + src + "[" + destPos + "++];").newLine();
writer.outdent().append("}").newLine();
}
private void achieveArrayCopy(DependencyChecker checker, MethodReference method) {
MethodGraph graph = checker.attachMethodGraph(method);
DependencyNode src = graph.getVariableNode(1);
DependencyNode dest = graph.getVariableNode(3);
src.getArrayItemNode().connect(dest.getArrayItemNode());
}
}

View File

@ -0,0 +1,9 @@
package org.teavm.classlib.java.lang;
/**
*
* @author Alexey Andreev
*/
public class TException extends TThrowable {
private static final long serialVersionUID = -2188339106250208952L;
}

View File

@ -31,6 +31,9 @@ public class TObject {
@GeneratedBy(ObjectNativeGenerator.class)
public native boolean equals(TObject other);
@Rename("toString")
public native TString toString0();
@Override
@GeneratedBy(ObjectNativeGenerator.class)
@PluggableDependency(ObjectNativeGenerator.class)

View File

@ -45,4 +45,9 @@ class TObjectTests {
public void properInstanceDetected() {
assertTrue(Object.class.isInstance(new Object()));
}
@Test
public void alwaysFails() {
fail();
}
}

View File

@ -1,9 +1,36 @@
package org.teavm.classlib.java.lang;
import org.teavm.javascript.ni.GeneratedBy;
/**
*
*
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
public class TString {
public class TString extends TObject {
private char[] characters;
public TString() {
this.characters = new char[0];
}
public TString(TString other) {
characters = other.characters;
}
public TString(char[] characters) {
this.characters = new char[characters.length];
for (int i = 0; i < characters.length; ++i) {
this.characters[i] = characters[i];
}
}
public TString(char[] value, int offset, int count) {
this.characters = new char[count];
for (int i = 0; i < count; ++i) {
this.characters[i] = value[i + offset];
}
}
@GeneratedBy(StringNativeGenerator.class)
public static native TString wrap(String str);
}

View File

@ -0,0 +1,19 @@
package org.teavm.classlib.java.lang;
import org.teavm.javascript.ni.GeneratedBy;
/**
*
* @author Alexey Andreev
*/
public final class TSystem extends TObject {
private TSystem() {
}
public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length) {
doArrayCopy(src, srcPos, dest, destPos, length);
}
@GeneratedBy(SystemNativeGenerator.class)
private static native void doArrayCopy(Object src, int srcPos, Object dest, int destPos, int length);
}

View File

@ -0,0 +1,22 @@
package org.teavm.classlib.java.lang;
import static org.junit.Assert.*;
import org.junit.Test;
/**
*
* @author Alexey Andreev
*/
class TSystemTests {
@Test
public void copiesArray() {
TObject a = new TObject();
TObject b = new TObject();
TObject[] src = { a, b, a };
TObject[] dest = new TObject[3];
TSystem.arraycopy(src, 0, dest, 0, 3);
assertSame(a, dest[0]);
assertSame(b, dest[1]);
assertSame(a, dest[2]);
}
}

View File

@ -6,4 +6,6 @@ package org.teavm.classlib.java.lang;
*/
public class TThrowable extends Throwable {
private static final long serialVersionUID = 2026791432677149320L;
private TString message;
private TThrowable cause;
}

View File

@ -1,7 +1,9 @@
package org.teavm.classlibgen;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.util.*;
import org.apache.commons.io.IOUtils;
import org.teavm.codegen.DefaultAliasProvider;
@ -19,6 +21,7 @@ import org.teavm.model.resource.ClasspathClassHolderSource;
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
public class ClasslibTestGenerator {
private static PrintStream out;
private static ClasspathClassHolderSource classSource;
private static Decompiler decompiler;
private static DefaultAliasProvider aliasProvider;
@ -27,9 +30,13 @@ public class ClasslibTestGenerator {
private static Renderer renderer;
private static List<MethodReference> testMethods = new ArrayList<>();
private static Map<String, List<MethodReference>> groupedMethods = new HashMap<>();
private static String[] testClasses = { "java.lang.ObjectTests" };
private static String[] testClasses = { "java.lang.ObjectTests", "java.lang.SystemTests" };
public static void main(String[] args) throws IOException {
out = System.out;
if (args.length > 0) {
out = new PrintStream(new FileOutputStream(args[0]));
}
classSource = new ClasspathClassHolderSource();
decompiler = new Decompiler(classSource);
aliasProvider = new DefaultAliasProvider();
@ -52,15 +59,16 @@ public class ClasslibTestGenerator {
renderHead();
ClassLoader classLoader = ClasslibTestGenerator.class.getClassLoader();
try (InputStream input = classLoader.getResourceAsStream("org/teavm/classlib/junit-support.js")) {
System.out.println(IOUtils.toString(input));
out.println(IOUtils.toString(input));
}
try (InputStream input = classLoader.getResourceAsStream("org/teavm/javascript/runtime.js")) {
System.out.println(IOUtils.toString(input));
out.println(IOUtils.toString(input));
}
renderer.renderRuntime();
for (String testClass : testClasses) {
renderClassTest(classSource.getClassHolder(testClass));
}
System.out.println(writer);
out.println(writer);
renderFoot();
}
@ -72,21 +80,21 @@ public class ClasslibTestGenerator {
}
private static void renderHead() {
System.out.println("<!DOCTYPE html>");
System.out.println("<html>");
System.out.println(" <head>");
System.out.println(" <title>TeaVM JUnit tests</title>");
System.out.println(" <meta http-equiv=\"Content-Type\" content=\"text/html;charset=UTF-8\"/>");
System.out.println(" <title>TeaVM JUnit tests</title>");
System.out.println(" </head>");
System.out.println(" <body>");
System.out.println(" <script type=\"text/javascript\">");
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println(" <head>");
out.println(" <title>TeaVM JUnit tests</title>");
out.println(" <meta http-equiv=\"Content-Type\" content=\"text/html;charset=UTF-8\"/>");
out.println(" <title>TeaVM JUnit tests</title>");
out.println(" </head>");
out.println(" <body>");
out.println(" <script type=\"text/javascript\">");
}
private static void renderFoot() {
System.out.println(" </script>");
System.out.println(" </body>");
System.out.println("</html>");
out.println(" </script>");
out.println(" </body>");
out.println("</html>");
}
private static void renderClassTest(ClassHolder cls) {

View File

@ -19,10 +19,14 @@ runTestCase = function(instance, methodName, realMethodName) {
} catch (e) {
if (e instanceof JUnitAssertionFailure) {
statusCell.appendChild(document.createTextNode("assertion failed"));
exceptionCell.appendChild(document.createTextNode(e.stack));
var exceptionText = document.createElement("pre");
exceptionText.appendChild(document.createTextNode(e.stack));
exceptionCell.appendChild(exceptionText);
} else {
statusCell.appendChild(document.createTextNode("unexpected exception"));
exceptionCell.appendChild(document.createTextNode(e.stack));
var exceptionText = document.createElement("pre");
exceptionText.appendChild(document.createTextNode(e.stack));
exceptionCell.appendChild(exceptionText);
}
}
}

View File

@ -40,13 +40,15 @@ public class ConcurrentCachedMapper<T, R> implements Mapper<T, R> {
listener.keyAdded(preimage);
}
} else {
CountDownLatch latch = oldWrapper.latch;
wrapper = oldWrapper;
try {
latch.await();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
CountDownLatch latch = wrapper.latch;
if (latch != null) {
try {
latch.await();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
return wrapper.value;

View File

@ -76,18 +76,18 @@ public class DependencyNode {
arrayItemNodeLatch.countDown();
arrayItemNodeLatch = null;
} else {
CountDownLatch latch = arrayItemNodeLatch;
if (latch != null) {
try {
latch.await();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return result;
}
}
result = arrayItemNode.get();
}
}
CountDownLatch latch = arrayItemNodeLatch;
if (latch != null) {
try {
latch.await();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return result;
}
}
return result;
}

View File

@ -45,6 +45,26 @@ public class Renderer implements ExprVisitor, StatementVisitor {
return naming;
}
public void renderRuntime() {
renderRuntimeCls();
}
private void renderRuntimeCls() {
writer.append("$rt_cls = function(cls) {").indent().newLine();
String classClass = "java.lang.Class";
writer.append("var cls = cls.classObject;").newLine();
writer.append("if (cls === undefined) {").newLine().indent();
MethodReference createMethodRef = new MethodReference(classClass, new MethodDescriptor("createNew",
ValueType.object(classClass)));
writer.append("cls = ").appendClass(classClass).append('.').appendMethod(createMethodRef)
.append("();").newLine();
writer.append("cls.$data = cls;").newLine();
writer.append("cls.classObject = cls;").newLine();
writer.outdent().append("}").newLine();
writer.append("return cls;").newLine();
writer.outdent().append("}").newLine();
}
public void render(ClassNode cls) {
writer.appendClass(cls.getName()).append(" = function() {").indent().newLine();
for (FieldNode field : cls.getFields()) {

View File

@ -20,6 +20,26 @@ $rt_isAssignable = function(from, to) {
}
return false;
}
$rt_createArray = function(cls, sz) {
var arr = new Array(sz);
arr.$class = $rt_arraycls(cls);
arr.$id = $rt_lastObjectId++;
for (var i = 0; i < sz; i = (i + 1) | 0) {
arr[i] = null;
}
return arr;
}
$rt_arraycls = function(cls) {
if (cls.$array == undefined) {
cls.$array = {
$meta : { item : cls },
};
if ($rt.objcls) {
cls.$array.$meta.supertypes = [$rt.objcls()];
}
}
return cls.$array;
}
$rt = {
createBooleanArray : function(cls, sz) {
@ -43,15 +63,6 @@ $rt = {
}
return arr;
},
createArray : function(cls, sz) {
var arr = new Array(sz);
arr.$class = $rt.arraycls(cls);
arr.$id = $rt.lastObjectId++;
for (var i = 0; i < sz; i = (i + 1) | 0) {
arr[i] = null;
}
return arr;
},
createMultiArray : function(cls, dimensions) {
for (var i = 1; i < dimensions.length; i = (i + 1) | 0) {
cls = $rt.arraycls(cls);
@ -75,17 +86,6 @@ $rt = {
$rt.setId(arr, $rt.lastObjectId++);
return arr;
},
arraycls : function(cls) {
if (cls.$array == undefined) {
cls.$array = {
$meta : { item : cls },
};
if ($rt.objcls) {
cls.$array.$meta.supertypes = [$rt.objcls()];
}
}
return cls.$array;
},
createcls : function() {
return {
$meta : {