mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
Adds some JVM classes.
This commit is contained in:
parent
04e12562a0
commit
18e35b80e6
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package org.teavm.classlib.java.lang;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public class TException extends TThrowable {
|
||||
private static final long serialVersionUID = -2188339106250208952L;
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -45,4 +45,9 @@ class TObjectTests {
|
|||
public void properInstanceDetected() {
|
||||
assertTrue(Object.class.isInstance(new Object()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void alwaysFails() {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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]);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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 : {
|
||||
|
|
Loading…
Reference in New Issue
Block a user