mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
Add support of clinit
This commit is contained in:
parent
d2cdd5e1e9
commit
8c6cf1840b
|
@ -56,6 +56,10 @@ public final class Example {
|
||||||
for (int i = 0; i < str.length(); ++i) {
|
for (int i = 0; i < str.length(); ++i) {
|
||||||
WasmRuntime.print(str.charAt(i));
|
WasmRuntime.print(str.charAt(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Initialized.foo();
|
||||||
|
Initialized.foo();
|
||||||
|
Initialized.foo();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Base instance(int index) {
|
private static Base instance(int index) {
|
||||||
|
@ -110,4 +114,14 @@ public final class Example {
|
||||||
return 123;
|
return 123;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class Initialized {
|
||||||
|
static {
|
||||||
|
WasmRuntime.print(9999);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void foo() {
|
||||||
|
WasmRuntime.print(8888);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -264,7 +264,8 @@ public class WasmTarget implements TeaVMTarget {
|
||||||
|
|
||||||
WasmBlock block = new WasmBlock(false);
|
WasmBlock block = new WasmBlock(false);
|
||||||
|
|
||||||
int index = classGenerator.getClassPointer(ValueType.object(className));
|
int index = classGenerator.getClassPointer(ValueType.object(className))
|
||||||
|
+ classGenerator.getFieldOffset(new FieldReference(RuntimeClass.class.getName(), "flags"));
|
||||||
WasmExpression initFlag = new WasmLoadInt32(4, new WasmInt32Constant(index), WasmInt32Subtype.INT32);
|
WasmExpression initFlag = new WasmLoadInt32(4, new WasmInt32Constant(index), WasmInt32Subtype.INT32);
|
||||||
initFlag = new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.AND, initFlag,
|
initFlag = new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.AND, initFlag,
|
||||||
new WasmInt32Constant(RuntimeClass.INITIALIZED));
|
new WasmInt32Constant(RuntimeClass.INITIALIZED));
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.teavm.model.ClassReaderSource;
|
||||||
import org.teavm.model.ElementModifier;
|
import org.teavm.model.ElementModifier;
|
||||||
import org.teavm.model.FieldReader;
|
import org.teavm.model.FieldReader;
|
||||||
import org.teavm.model.FieldReference;
|
import org.teavm.model.FieldReference;
|
||||||
|
import org.teavm.model.MethodDescriptor;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
import org.teavm.model.ValueType;
|
import org.teavm.model.ValueType;
|
||||||
import org.teavm.model.classes.TagRegistry;
|
import org.teavm.model.classes.TagRegistry;
|
||||||
|
@ -281,6 +282,17 @@ public class WasmClassGenerator {
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasClinit(String className) {
|
||||||
|
if (isStructure(className)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ClassReader cls = classSource.get(className);
|
||||||
|
if (cls == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return cls.getMethod(new MethodDescriptor("<clinit>", ValueType.VOID)) != null;
|
||||||
|
}
|
||||||
|
|
||||||
private class ClassBinaryData {
|
private class ClassBinaryData {
|
||||||
ValueType type;
|
ValueType type;
|
||||||
int size;
|
int size;
|
||||||
|
|
|
@ -33,6 +33,7 @@ import org.teavm.model.classes.TagRegistry;
|
||||||
import org.teavm.model.classes.VirtualTableProvider;
|
import org.teavm.model.classes.VirtualTableProvider;
|
||||||
import org.teavm.wasm.binary.BinaryWriter;
|
import org.teavm.wasm.binary.BinaryWriter;
|
||||||
import org.teavm.wasm.intrinsics.WasmIntrinsic;
|
import org.teavm.wasm.intrinsics.WasmIntrinsic;
|
||||||
|
import org.teavm.wasm.model.expression.WasmExpression;
|
||||||
|
|
||||||
public class WasmGenerationContext {
|
public class WasmGenerationContext {
|
||||||
private ClassReaderSource classSource;
|
private ClassReaderSource classSource;
|
||||||
|
|
|
@ -962,24 +962,13 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(InitClassStatement statement) {
|
public void visit(InitClassStatement statement) {
|
||||||
if (hasClinit(statement.getClassName())) {
|
if (classGenerator.hasClinit(statement.getClassName())) {
|
||||||
result = new WasmCall(WasmMangling.mangleInitializer(statement.getClassName()));
|
result = new WasmCall(WasmMangling.mangleInitializer(statement.getClassName()));
|
||||||
} else {
|
} else {
|
||||||
result = null;
|
result = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasClinit(String className) {
|
|
||||||
if (classGenerator.isStructure(className)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
ClassReader cls = context.getClassSource().get(className);
|
|
||||||
if (cls == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return cls.getMethod(new MethodDescriptor("<clinit>", ValueType.VOID)) != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(PrimitiveCastExpr expr) {
|
public void visit(PrimitiveCastExpr expr) {
|
||||||
expr.getValue().acceptVisitor(this);
|
expr.getValue().acceptVisitor(this);
|
||||||
|
|
|
@ -21,11 +21,22 @@ import org.teavm.ast.decompilation.Decompiler;
|
||||||
import org.teavm.model.ClassHolder;
|
import org.teavm.model.ClassHolder;
|
||||||
import org.teavm.model.ClassHolderSource;
|
import org.teavm.model.ClassHolderSource;
|
||||||
import org.teavm.model.ElementModifier;
|
import org.teavm.model.ElementModifier;
|
||||||
|
import org.teavm.model.FieldReference;
|
||||||
import org.teavm.model.MethodHolder;
|
import org.teavm.model.MethodHolder;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
import org.teavm.model.ValueType;
|
import org.teavm.model.ValueType;
|
||||||
|
import org.teavm.runtime.RuntimeClass;
|
||||||
import org.teavm.wasm.model.WasmFunction;
|
import org.teavm.wasm.model.WasmFunction;
|
||||||
import org.teavm.wasm.model.WasmLocal;
|
import org.teavm.wasm.model.WasmLocal;
|
||||||
|
import org.teavm.wasm.model.expression.WasmCall;
|
||||||
|
import org.teavm.wasm.model.expression.WasmConditional;
|
||||||
|
import org.teavm.wasm.model.expression.WasmExpression;
|
||||||
|
import org.teavm.wasm.model.expression.WasmInt32Constant;
|
||||||
|
import org.teavm.wasm.model.expression.WasmInt32Subtype;
|
||||||
|
import org.teavm.wasm.model.expression.WasmIntBinary;
|
||||||
|
import org.teavm.wasm.model.expression.WasmIntBinaryOperation;
|
||||||
|
import org.teavm.wasm.model.expression.WasmIntType;
|
||||||
|
import org.teavm.wasm.model.expression.WasmLoadInt32;
|
||||||
|
|
||||||
public class WasmGenerator {
|
public class WasmGenerator {
|
||||||
private Decompiler decompiler;
|
private Decompiler decompiler;
|
||||||
|
@ -60,6 +71,20 @@ public class WasmGenerator {
|
||||||
function.setResult(WasmGeneratorUtil.mapType(methodReference.getReturnType()));
|
function.setResult(WasmGeneratorUtil.mapType(methodReference.getReturnType()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (needsClinitCall(method) && classGenerator.hasClinit(method.getOwnerName())) {
|
||||||
|
int index = classGenerator.getClassPointer(ValueType.object(method.getOwnerName()))
|
||||||
|
+ classGenerator.getFieldOffset(new FieldReference(RuntimeClass.class.getName(), "flags"));
|
||||||
|
WasmExpression initFlag = new WasmLoadInt32(4, new WasmInt32Constant(index), WasmInt32Subtype.INT32);
|
||||||
|
initFlag = new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.AND, initFlag,
|
||||||
|
new WasmInt32Constant(RuntimeClass.INITIALIZED));
|
||||||
|
|
||||||
|
WasmConditional conditional = new WasmConditional(initFlag);
|
||||||
|
MethodReference clinit = new MethodReference(method.getOwnerName(),
|
||||||
|
"<clinit>", ValueType.VOID);
|
||||||
|
conditional.getThenBlock().getBody().add(new WasmCall(WasmMangling.mangleMethod(clinit)));
|
||||||
|
function.getBody().add(conditional);
|
||||||
|
}
|
||||||
|
|
||||||
WasmGenerationVisitor visitor = new WasmGenerationVisitor(context, classGenerator, function, firstVariable);
|
WasmGenerationVisitor visitor = new WasmGenerationVisitor(context, classGenerator, function, firstVariable);
|
||||||
methodAst.getBody().acceptVisitor(visitor);
|
methodAst.getBody().acceptVisitor(visitor);
|
||||||
function.getBody().add(visitor.result);
|
function.getBody().add(visitor.result);
|
||||||
|
@ -67,6 +92,16 @@ public class WasmGenerator {
|
||||||
return function;
|
return function;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean needsClinitCall(MethodHolder method) {
|
||||||
|
if (method.getName().equals("<clinit>")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (method.getName().equals("<init>")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return method.hasModifier(ElementModifier.STATIC);
|
||||||
|
}
|
||||||
|
|
||||||
public WasmFunction generateNative(MethodReference methodReference) {
|
public WasmFunction generateNative(MethodReference methodReference) {
|
||||||
WasmFunction function = new WasmFunction(WasmMangling.mangleMethod(methodReference));
|
WasmFunction function = new WasmFunction(WasmMangling.mangleMethod(methodReference));
|
||||||
for (int i = 0; i < methodReference.parameterCount(); ++i) {
|
for (int i = 0; i < methodReference.parameterCount(); ++i) {
|
||||||
|
|
|
@ -183,8 +183,10 @@ class WasmRenderingVisitor implements WasmExpressionVisitor {
|
||||||
lf();
|
lf();
|
||||||
renderBlock(expression.getThenBlock(), "then");
|
renderBlock(expression.getThenBlock(), "then");
|
||||||
|
|
||||||
|
if (!expression.getElseBlock().getBody().isEmpty()) {
|
||||||
lf();
|
lf();
|
||||||
renderBlock(expression.getElseBlock(), "else");
|
renderBlock(expression.getElseBlock(), "else");
|
||||||
|
}
|
||||||
|
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user