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":
|
||||
generateClone(context, writer);
|
||||
break;
|
||||
case "wrap":
|
||||
generateWrap(context, writer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,6 +48,9 @@ public class ObjectNativeGenerator implements Generator, DependencyPlugin {
|
|||
case "getClass":
|
||||
achieveGetClass(checker);
|
||||
break;
|
||||
case "wrap":
|
||||
achieveWrap(checker, method);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,4 +102,13 @@ public class ObjectNativeGenerator implements Generator, DependencyPlugin {
|
|||
MethodGraph graph = checker.attachMethodGraph(method);
|
||||
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
|
||||
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;
|
||||
|
||||
import org.teavm.classlib.java.lang.reflect.TArray;
|
||||
import org.teavm.javascript.ni.GeneratedBy;
|
||||
|
||||
/**
|
||||
|
@ -10,7 +11,17 @@ public final class TSystem extends TObject {
|
|||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -14,9 +14,19 @@ class TSystemTests {
|
|||
TObject b = new TObject();
|
||||
TObject[] src = { a, b, a };
|
||||
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(b, dest[1]);
|
||||
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));
|
||||
}
|
||||
renderer.renderRuntime();
|
||||
writer.append("runTests = function() {").newLine().indent();
|
||||
writer.append("document.getElementById(\"start-button\").style.display = 'none';").newLine();
|
||||
for (String testClass : testClasses) {
|
||||
renderClassTest(classSource.getClassHolder(testClass));
|
||||
}
|
||||
writer.outdent().append("}").newLine();
|
||||
out.println(writer);
|
||||
renderFoot();
|
||||
}
|
||||
|
@ -87,6 +90,16 @@ public class ClasslibTestGenerator {
|
|||
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(" <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(" <body>");
|
||||
out.println(" <script type=\"text/javascript\">");
|
||||
|
@ -94,6 +107,7 @@ public class ClasslibTestGenerator {
|
|||
|
||||
private static void renderFoot() {
|
||||
out.println(" </script>");
|
||||
out.println(" <button id=\"start-button\" onclick=\"runTests()\">Run tests</button>");
|
||||
out.println(" </body>");
|
||||
out.println("</html>");
|
||||
}
|
||||
|
|
|
@ -1246,6 +1246,7 @@ public class ProgramParser {
|
|||
ArrayLengthInstruction insn = new ArrayLengthInstruction();
|
||||
insn.setArray(getVariable(a));
|
||||
insn.setReceiver(getVariable(a));
|
||||
builder.add(insn);
|
||||
break;
|
||||
}
|
||||
case Opcodes.ATHROW: {
|
||||
|
|
|
@ -157,6 +157,11 @@ $rt_init = function(cls, constructor, args) {
|
|||
cls.prototype[constructor].apply(obj, args);
|
||||
return obj;
|
||||
}
|
||||
$rt_throw = function(ex) {
|
||||
var err = new Error("Java exception thrown");
|
||||
err.$javaException = ex;
|
||||
throw err;
|
||||
}
|
||||
|
||||
$rt = {
|
||||
createBooleanArray : function(cls, sz) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user