mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -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) {
|
||||
WasmRuntime.print(str.charAt(i));
|
||||
}
|
||||
|
||||
Initialized.foo();
|
||||
Initialized.foo();
|
||||
Initialized.foo();
|
||||
}
|
||||
|
||||
private static Base instance(int index) {
|
||||
|
@ -110,4 +114,14 @@ public final class Example {
|
|||
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);
|
||||
|
||||
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);
|
||||
initFlag = new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.AND, initFlag,
|
||||
new WasmInt32Constant(RuntimeClass.INITIALIZED));
|
||||
|
|
|
@ -29,6 +29,7 @@ import org.teavm.model.ClassReaderSource;
|
|||
import org.teavm.model.ElementModifier;
|
||||
import org.teavm.model.FieldReader;
|
||||
import org.teavm.model.FieldReference;
|
||||
import org.teavm.model.MethodDescriptor;
|
||||
import org.teavm.model.MethodReference;
|
||||
import org.teavm.model.ValueType;
|
||||
import org.teavm.model.classes.TagRegistry;
|
||||
|
@ -281,6 +282,17 @@ public class WasmClassGenerator {
|
|||
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 {
|
||||
ValueType type;
|
||||
int size;
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.teavm.model.classes.TagRegistry;
|
|||
import org.teavm.model.classes.VirtualTableProvider;
|
||||
import org.teavm.wasm.binary.BinaryWriter;
|
||||
import org.teavm.wasm.intrinsics.WasmIntrinsic;
|
||||
import org.teavm.wasm.model.expression.WasmExpression;
|
||||
|
||||
public class WasmGenerationContext {
|
||||
private ClassReaderSource classSource;
|
||||
|
|
|
@ -962,24 +962,13 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
|||
|
||||
@Override
|
||||
public void visit(InitClassStatement statement) {
|
||||
if (hasClinit(statement.getClassName())) {
|
||||
if (classGenerator.hasClinit(statement.getClassName())) {
|
||||
result = new WasmCall(WasmMangling.mangleInitializer(statement.getClassName()));
|
||||
} else {
|
||||
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
|
||||
public void visit(PrimitiveCastExpr expr) {
|
||||
expr.getValue().acceptVisitor(this);
|
||||
|
|
|
@ -21,11 +21,22 @@ import org.teavm.ast.decompilation.Decompiler;
|
|||
import org.teavm.model.ClassHolder;
|
||||
import org.teavm.model.ClassHolderSource;
|
||||
import org.teavm.model.ElementModifier;
|
||||
import org.teavm.model.FieldReference;
|
||||
import org.teavm.model.MethodHolder;
|
||||
import org.teavm.model.MethodReference;
|
||||
import org.teavm.model.ValueType;
|
||||
import org.teavm.runtime.RuntimeClass;
|
||||
import org.teavm.wasm.model.WasmFunction;
|
||||
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 {
|
||||
private Decompiler decompiler;
|
||||
|
@ -60,6 +71,20 @@ public class WasmGenerator {
|
|||
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);
|
||||
methodAst.getBody().acceptVisitor(visitor);
|
||||
function.getBody().add(visitor.result);
|
||||
|
@ -67,6 +92,16 @@ public class WasmGenerator {
|
|||
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) {
|
||||
WasmFunction function = new WasmFunction(WasmMangling.mangleMethod(methodReference));
|
||||
for (int i = 0; i < methodReference.parameterCount(); ++i) {
|
||||
|
|
|
@ -183,8 +183,10 @@ class WasmRenderingVisitor implements WasmExpressionVisitor {
|
|||
lf();
|
||||
renderBlock(expression.getThenBlock(), "then");
|
||||
|
||||
lf();
|
||||
renderBlock(expression.getElseBlock(), "else");
|
||||
if (!expression.getElseBlock().getBody().isEmpty()) {
|
||||
lf();
|
||||
renderBlock(expression.getElseBlock(), "else");
|
||||
}
|
||||
|
||||
close();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user