mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
Adds some JVM class library implementation
This commit is contained in:
parent
f6927a72af
commit
ce56214ed5
|
@ -33,6 +33,9 @@ public class ObjectNativeGenerator implements Generator, DependencyPlugin {
|
||||||
case "clone":
|
case "clone":
|
||||||
generateClone(context, writer);
|
generateClone(context, writer);
|
||||||
break;
|
break;
|
||||||
|
case "wrap":
|
||||||
|
generateWrap(context, writer);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,6 +48,9 @@ public class ObjectNativeGenerator implements Generator, DependencyPlugin {
|
||||||
case "getClass":
|
case "getClass":
|
||||||
achieveGetClass(checker);
|
achieveGetClass(checker);
|
||||||
break;
|
break;
|
||||||
|
case "wrap":
|
||||||
|
achieveWrap(checker, method);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,4 +102,13 @@ public class ObjectNativeGenerator implements Generator, DependencyPlugin {
|
||||||
MethodGraph graph = checker.attachMethodGraph(method);
|
MethodGraph graph = checker.attachMethodGraph(method);
|
||||||
graph.getVariableNode(0).connect(graph.getResultNode());
|
graph.getVariableNode(0).connect(graph.getResultNode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void generateWrap(GeneratorContext context, SourceWriter writer) {
|
||||||
|
writer.append("return ").append(context.getParameterName(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void achieveWrap(DependencyChecker checker, MethodReference method) {
|
||||||
|
MethodGraph graph = checker.attachMethodGraph(method);
|
||||||
|
graph.getVariableNode(1).connect(graph.getResultNode());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
package org.teavm.classlib.java.lang;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev
|
||||||
|
*/
|
||||||
|
public class TNullPointerException extends TRuntimeException {
|
||||||
|
private static final long serialVersionUID = 2639861320773057190L;
|
||||||
|
|
||||||
|
public TNullPointerException(TString message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TNullPointerException() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
}
|
|
@ -65,4 +65,8 @@ public class TObject {
|
||||||
@Override
|
@Override
|
||||||
protected void finalize() throws TThrowable {
|
protected void finalize() throws TThrowable {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GeneratedBy(ObjectNativeGenerator.class)
|
||||||
|
@PluggableDependency(ObjectNativeGenerator.class)
|
||||||
|
public static native TObject wrap(Object obj);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package org.teavm.classlib.java.lang;
|
package org.teavm.classlib.java.lang;
|
||||||
|
|
||||||
|
import org.teavm.classlib.java.lang.reflect.TArray;
|
||||||
import org.teavm.javascript.ni.GeneratedBy;
|
import org.teavm.javascript.ni.GeneratedBy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -10,7 +11,17 @@ public final class TSystem extends TObject {
|
||||||
private TSystem() {
|
private TSystem() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length) {
|
public static void arraycopy(TObject src, int srcPos, TObject dest, int destPos, int length) {
|
||||||
|
if (src == null || dest == null) {
|
||||||
|
throw new TNullPointerException(TString.wrap("Either src or dest is null"));
|
||||||
|
}
|
||||||
|
if (src.getClass0() != dest.getClass0()) {
|
||||||
|
throw new ArrayStoreException();
|
||||||
|
}
|
||||||
|
if (srcPos < 0 || destPos < 0 || length < 0 || srcPos + length > TArray.getLength(src) ||
|
||||||
|
destPos + length > TArray.getLength(dest)) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
doArrayCopy(src, srcPos, dest, destPos, length);
|
doArrayCopy(src, srcPos, dest, destPos, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,9 +14,19 @@ class TSystemTests {
|
||||||
TObject b = new TObject();
|
TObject b = new TObject();
|
||||||
TObject[] src = { a, b, a };
|
TObject[] src = { a, b, a };
|
||||||
TObject[] dest = new TObject[3];
|
TObject[] dest = new TObject[3];
|
||||||
TSystem.arraycopy(src, 0, dest, 0, 3);
|
TSystem.arraycopy(TObject.wrap(src), 0, TObject.wrap(dest), 0, 3);
|
||||||
assertSame(a, dest[0]);
|
assertSame(a, dest[0]);
|
||||||
assertSame(b, dest[1]);
|
assertSame(b, dest[1]);
|
||||||
assertSame(a, dest[2]);
|
assertSame(a, dest[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void failsToCopyArraysWithInvalidIndexes() {
|
||||||
|
TSystem.arraycopy(TObject.wrap(new TObject[0]), 0, TObject.wrap(new TObject[0]), 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void failsToCopyArraysWithIncompatibleElements() {
|
||||||
|
TSystem.arraycopy(TObject.wrap(new TObject[1]), 0, TObject.wrap(new int[1]), 0, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
package org.teavm.classlib.java.lang.reflect;
|
||||||
|
|
||||||
|
import org.teavm.classlib.java.lang.TIllegalArgumentException;
|
||||||
|
import org.teavm.classlib.java.lang.TObject;
|
||||||
|
import org.teavm.dependency.PluggableDependency;
|
||||||
|
import org.teavm.javascript.ni.GeneratedBy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev
|
||||||
|
*/
|
||||||
|
public final class TArray extends TObject {
|
||||||
|
@GeneratedBy(TArrayNativeGenerator.class)
|
||||||
|
@PluggableDependency(TArrayNativeGenerator.class)
|
||||||
|
public static native int getLength(TObject array) throws TIllegalArgumentException;
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
package org.teavm.classlib.java.lang.reflect;
|
||||||
|
|
||||||
|
import org.teavm.codegen.SourceWriter;
|
||||||
|
import org.teavm.dependency.DependencyChecker;
|
||||||
|
import org.teavm.dependency.DependencyConsumer;
|
||||||
|
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.MethodDescriptor;
|
||||||
|
import org.teavm.model.MethodReference;
|
||||||
|
import org.teavm.model.ValueType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev
|
||||||
|
*/
|
||||||
|
public class TArrayNativeGenerator implements Generator, DependencyPlugin {
|
||||||
|
@Override
|
||||||
|
public void methodAchieved(DependencyChecker checker, MethodReference method) {
|
||||||
|
if (method.getName().equals("getLength")) {
|
||||||
|
achieveGetLength(checker, method);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) {
|
||||||
|
switch (methodRef.getName()) {
|
||||||
|
case "getLength":
|
||||||
|
generateGetLength(context, writer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateGetLength(GeneratorContext context, SourceWriter writer) {
|
||||||
|
String array = context.getParameterName(1);
|
||||||
|
writer.append("if (" + array + " === null || " + array + " .$cls.$meta.item === undefined) {")
|
||||||
|
.newLine().indent();
|
||||||
|
String clsName = "java.lang.IllegalArgumentException";
|
||||||
|
MethodReference cons = new MethodReference(clsName, new MethodDescriptor("<init>", ValueType.VOID));
|
||||||
|
writer.append("$rt_throw(").appendClass(clsName).append(".").appendMethod(cons).append("());").newLine();
|
||||||
|
writer.outdent().append("}").newLine();
|
||||||
|
writer.append("return array.length");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void achieveGetLength(final DependencyChecker checker, MethodReference methodRef) {
|
||||||
|
final MethodGraph graph = checker.attachMethodGraph(methodRef);
|
||||||
|
graph.getVariableNode(1).addConsumer(new DependencyConsumer() {
|
||||||
|
@Override public void consume(String type) {
|
||||||
|
if (!type.startsWith("[")) {
|
||||||
|
MethodReference cons = new MethodReference("java.lang.IllegalArgumentException",
|
||||||
|
new MethodDescriptor("<init>", ValueType.VOID));
|
||||||
|
checker.addEntryPoint(cons);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -66,9 +66,12 @@ public class ClasslibTestGenerator {
|
||||||
out.println(IOUtils.toString(input));
|
out.println(IOUtils.toString(input));
|
||||||
}
|
}
|
||||||
renderer.renderRuntime();
|
renderer.renderRuntime();
|
||||||
|
writer.append("runTests = function() {").newLine().indent();
|
||||||
|
writer.append("document.getElementById(\"start-button\").style.display = 'none';").newLine();
|
||||||
for (String testClass : testClasses) {
|
for (String testClass : testClasses) {
|
||||||
renderClassTest(classSource.getClassHolder(testClass));
|
renderClassTest(classSource.getClassHolder(testClass));
|
||||||
}
|
}
|
||||||
|
writer.outdent().append("}").newLine();
|
||||||
out.println(writer);
|
out.println(writer);
|
||||||
renderFoot();
|
renderFoot();
|
||||||
}
|
}
|
||||||
|
@ -87,6 +90,16 @@ public class ClasslibTestGenerator {
|
||||||
out.println(" <title>TeaVM JUnit tests</title>");
|
out.println(" <title>TeaVM JUnit tests</title>");
|
||||||
out.println(" <meta http-equiv=\"Content-Type\" content=\"text/html;charset=UTF-8\"/>");
|
out.println(" <meta http-equiv=\"Content-Type\" content=\"text/html;charset=UTF-8\"/>");
|
||||||
out.println(" <title>TeaVM JUnit tests</title>");
|
out.println(" <title>TeaVM JUnit tests</title>");
|
||||||
|
out.println(" <style type=\"text/css\">");
|
||||||
|
out.println(" table {");
|
||||||
|
out.println(" border-collapse: collapse;");
|
||||||
|
out.println(" border: 2px solid black;");
|
||||||
|
out.println(" margin: 2em 1em 2em 1em;");
|
||||||
|
out.println(" }");
|
||||||
|
out.println(" table td {");
|
||||||
|
out.println(" border: 1px solid gray;");
|
||||||
|
out.println(" }");
|
||||||
|
out.println(" </style>");
|
||||||
out.println(" </head>");
|
out.println(" </head>");
|
||||||
out.println(" <body>");
|
out.println(" <body>");
|
||||||
out.println(" <script type=\"text/javascript\">");
|
out.println(" <script type=\"text/javascript\">");
|
||||||
|
@ -94,6 +107,7 @@ public class ClasslibTestGenerator {
|
||||||
|
|
||||||
private static void renderFoot() {
|
private static void renderFoot() {
|
||||||
out.println(" </script>");
|
out.println(" </script>");
|
||||||
|
out.println(" <button id=\"start-button\" onclick=\"runTests()\">Run tests</button>");
|
||||||
out.println(" </body>");
|
out.println(" </body>");
|
||||||
out.println("</html>");
|
out.println("</html>");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1246,6 +1246,7 @@ public class ProgramParser {
|
||||||
ArrayLengthInstruction insn = new ArrayLengthInstruction();
|
ArrayLengthInstruction insn = new ArrayLengthInstruction();
|
||||||
insn.setArray(getVariable(a));
|
insn.setArray(getVariable(a));
|
||||||
insn.setReceiver(getVariable(a));
|
insn.setReceiver(getVariable(a));
|
||||||
|
builder.add(insn);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Opcodes.ATHROW: {
|
case Opcodes.ATHROW: {
|
||||||
|
|
|
@ -157,6 +157,11 @@ $rt_init = function(cls, constructor, args) {
|
||||||
cls.prototype[constructor].apply(obj, args);
|
cls.prototype[constructor].apply(obj, args);
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
$rt_throw = function(ex) {
|
||||||
|
var err = new Error("Java exception thrown");
|
||||||
|
err.$javaException = ex;
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
|
||||||
$rt = {
|
$rt = {
|
||||||
createBooleanArray : function(cls, sz) {
|
createBooleanArray : function(cls, sz) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user