mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
Fix bugs in emit API
This commit is contained in:
parent
ce525f0a78
commit
0be4ca336d
|
@ -26,7 +26,9 @@ import org.teavm.model.ClassHolderSource;
|
||||||
import org.teavm.model.ClassHolderTransformer;
|
import org.teavm.model.ClassHolderTransformer;
|
||||||
import org.teavm.model.ClassReader;
|
import org.teavm.model.ClassReader;
|
||||||
import org.teavm.model.ClassReaderSource;
|
import org.teavm.model.ClassReaderSource;
|
||||||
|
import org.teavm.model.MethodHolder;
|
||||||
import org.teavm.model.util.ModelUtils;
|
import org.teavm.model.util.ModelUtils;
|
||||||
|
import org.teavm.optimization.UnreachableBasicBlockEliminator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -54,6 +56,11 @@ class DependencyClassSource implements ClassHolderSource {
|
||||||
throw new IllegalArgumentException("Class " + cls.getName() + " is already defined");
|
throw new IllegalArgumentException("Class " + cls.getName() + " is already defined");
|
||||||
}
|
}
|
||||||
generatedClasses.put(cls.getName(), cls);
|
generatedClasses.put(cls.getName(), cls);
|
||||||
|
for (MethodHolder method : cls.getMethods()) {
|
||||||
|
if (method.getProgram() != null && method.getProgram().basicBlockCount() > 0) {
|
||||||
|
new UnreachableBasicBlockEliminator().optimize(method.getProgram());
|
||||||
|
}
|
||||||
|
}
|
||||||
cache.remove(cls.getName());
|
cache.remove(cls.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,17 +38,17 @@ public class IfEmitter {
|
||||||
BasicBlock block = pe.prepareBlock();
|
BasicBlock block = pe.prepareBlock();
|
||||||
fork.setThen(block);
|
fork.setThen(block);
|
||||||
pe.enter(block);
|
pe.enter(block);
|
||||||
fragment.emit();
|
pe.emitAndJump(fragment, join);
|
||||||
pe.jump(join);
|
pe.enter(join);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IfEmitter elseDo(FragmentEmitter fragment) {
|
public IfEmitter elseDo(FragmentEmitter fragment) {
|
||||||
BasicBlock block = pe.prepareBlock();
|
BasicBlock block = pe.prepareBlock();
|
||||||
fork.setThen(block);
|
fork.setElse(block);
|
||||||
pe.enter(block);
|
pe.enter(block);
|
||||||
fragment.emit();
|
pe.emitAndJump(fragment, join);
|
||||||
pe.jump(join);
|
pe.enter(join);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -292,7 +292,6 @@ public final class ProgramEmitter {
|
||||||
JumpInstruction insn = new JumpInstruction();
|
JumpInstruction insn = new JumpInstruction();
|
||||||
insn.setTarget(block);
|
insn.setTarget(block);
|
||||||
addInstruction(insn);
|
addInstruction(insn);
|
||||||
this.block = block;
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -415,7 +415,7 @@ public class ValueEmitter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pe.classSource.isSuperType(((ValueType.Object) type).getClassName(), method.getClassName())
|
if (!pe.classSource.isSuperType(method.getClassName(), ((ValueType.Object) type).getClassName())
|
||||||
.orElse(true)) {
|
.orElse(true)) {
|
||||||
throw new EmitException("Can't call " + method + " on non-compatible class " + type);
|
throw new EmitException("Can't call " + method + " on non-compatible class " + type);
|
||||||
}
|
}
|
||||||
|
@ -615,7 +615,7 @@ public class ValueEmitter {
|
||||||
return new ConditionEmitter(pe, compareTo(other).fork(BranchingCondition.LESS));
|
return new ConditionEmitter(pe, compareTo(other).fork(BranchingCondition.LESS));
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConditionEmitter isLessOrEuqalTo(ValueEmitter other) {
|
public ConditionEmitter isLessOrEqualTo(ValueEmitter other) {
|
||||||
return new ConditionEmitter(pe, compareTo(other).fork(BranchingCondition.LESS_OR_EQUAL));
|
return new ConditionEmitter(pe, compareTo(other).fork(BranchingCondition.LESS_OR_EQUAL));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -640,8 +640,10 @@ public class ValueEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ValueEmitter cast(ValueType type) {
|
public ValueEmitter cast(ValueType type) {
|
||||||
if (type.equals(this.type) || pe.classSource.isSuperType(type, this.type).orElse(false)) {
|
if (type.equals(this.type)) {
|
||||||
return this;
|
return this;
|
||||||
|
} else if (pe.classSource.isSuperType(type, this.type).orElse(false)) {
|
||||||
|
return pe.var(variable.getIndex(), type);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type instanceof ValueType.Primitive) {
|
if (type instanceof ValueType.Primitive) {
|
||||||
|
@ -720,12 +722,24 @@ public class ValueEmitter {
|
||||||
|
|
||||||
CastIntegerInstruction insn = new CastIntegerInstruction(subtype, CastIntegerDirection.TO_INTEGER);
|
CastIntegerInstruction insn = new CastIntegerInstruction(subtype, CastIntegerDirection.TO_INTEGER);
|
||||||
insn.setValue(variable);
|
insn.setValue(variable);
|
||||||
ValueEmitter result = pe.newVar(ValueType.INTEGER);
|
ValueEmitter result = pe.newVar(convertSubtype(subtype));
|
||||||
insn.setReceiver(result.getVariable());
|
insn.setReceiver(result.getVariable());
|
||||||
pe.addInstruction(insn);
|
pe.addInstruction(insn);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ValueType convertSubtype(IntegerSubtype subtype) {
|
||||||
|
switch (subtype) {
|
||||||
|
case BYTE:
|
||||||
|
return ValueType.BYTE;
|
||||||
|
case SHORT:
|
||||||
|
return ValueType.SHORT;
|
||||||
|
case CHARACTER:
|
||||||
|
return ValueType.CHARACTER;
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Unknown subtype: " + subtype);
|
||||||
|
}
|
||||||
|
|
||||||
public ValueEmitter castToInteger(IntegerSubtype subtype) {
|
public ValueEmitter castToInteger(IntegerSubtype subtype) {
|
||||||
switch (subtype) {
|
switch (subtype) {
|
||||||
case BYTE:
|
case BYTE:
|
||||||
|
|
|
@ -32,7 +32,11 @@ public abstract class BasicBlockMapper implements InstructionVisitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void transform(BasicBlock block) {
|
public void transform(BasicBlock block) {
|
||||||
block.getLastInstruction().acceptVisitor(this);
|
Instruction lastInsn = block.getLastInstruction();
|
||||||
|
if (lastInsn == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lastInsn.acceptVisitor(this);
|
||||||
for (Phi phi : block.getPhis()) {
|
for (Phi phi : block.getPhis()) {
|
||||||
for (Incoming incoming : phi.getIncomings()) {
|
for (Incoming incoming : phi.getIncomings()) {
|
||||||
incoming.setSource(map(incoming.getSource()));
|
incoming.setSource(map(incoming.getSource()));
|
||||||
|
|
|
@ -18,10 +18,19 @@ package org.teavm.platform.plugin;
|
||||||
import org.teavm.cache.NoCache;
|
import org.teavm.cache.NoCache;
|
||||||
import org.teavm.diagnostics.Diagnostics;
|
import org.teavm.diagnostics.Diagnostics;
|
||||||
import org.teavm.javascript.spi.GeneratedBy;
|
import org.teavm.javascript.spi.GeneratedBy;
|
||||||
import org.teavm.model.*;
|
import org.teavm.model.AccessLevel;
|
||||||
import org.teavm.model.emit.ForkEmitter;
|
import org.teavm.model.AnnotationHolder;
|
||||||
|
import org.teavm.model.AnnotationReader;
|
||||||
|
import org.teavm.model.AnnotationValue;
|
||||||
|
import org.teavm.model.CallLocation;
|
||||||
|
import org.teavm.model.ClassHolder;
|
||||||
|
import org.teavm.model.ClassHolderTransformer;
|
||||||
|
import org.teavm.model.ClassReaderSource;
|
||||||
|
import org.teavm.model.ElementModifier;
|
||||||
|
import org.teavm.model.FieldHolder;
|
||||||
|
import org.teavm.model.MethodHolder;
|
||||||
|
import org.teavm.model.ValueType;
|
||||||
import org.teavm.model.emit.ProgramEmitter;
|
import org.teavm.model.emit.ProgramEmitter;
|
||||||
import org.teavm.model.instructions.BinaryBranchingCondition;
|
|
||||||
import org.teavm.model.util.ModelUtils;
|
import org.teavm.model.util.ModelUtils;
|
||||||
import org.teavm.platform.PlatformClass;
|
import org.teavm.platform.PlatformClass;
|
||||||
import org.teavm.platform.metadata.ClassScopedMetadataProvider;
|
import org.teavm.platform.metadata.ClassScopedMetadataProvider;
|
||||||
|
@ -91,19 +100,11 @@ class MetadataProviderTransformer implements ClassHolderTransformer {
|
||||||
|
|
||||||
method.getModifiers().remove(ElementModifier.NATIVE);
|
method.getModifiers().remove(ElementModifier.NATIVE);
|
||||||
ProgramEmitter pe = ProgramEmitter.create(method, classSource);
|
ProgramEmitter pe = ProgramEmitter.create(method, classSource);
|
||||||
ForkEmitter fork = pe.getField(field.getReference(), field.getType()).fork(
|
pe.when(pe.getField(field.getReference(), field.getType()).isNull())
|
||||||
BinaryBranchingCondition.REFERENCE_NOT_EQUAL, pe.constantNull(field.getType()));
|
.thenDo(() -> pe.setField(field.getReference(), pe.invoke(createMethod.getReference().getClassName(),
|
||||||
|
createMethod.getReference().getName(), createMethod.getResultType())));
|
||||||
BasicBlock resourceFound = pe.prepareBlock();
|
pe.getField(field.getReference(), field.getType())
|
||||||
fork.setThen(resourceFound);
|
.returnValue();
|
||||||
pe.getField(field.getReference(), field.getType()).returnValue();
|
|
||||||
|
|
||||||
BasicBlock block = pe.prepareBlock();
|
|
||||||
fork.setElse(block);
|
|
||||||
pe.enter(block);
|
|
||||||
pe.setField(field.getReference(), pe.invoke(createMethod.getReference().getClassName(),
|
|
||||||
createMethod.getReference().getName(), createMethod.getResultType()));
|
|
||||||
pe.jump(resourceFound);
|
|
||||||
|
|
||||||
AnnotationHolder noCacheAnnot = new AnnotationHolder(NoCache.class.getName());
|
AnnotationHolder noCacheAnnot = new AnnotationHolder(NoCache.class.getName());
|
||||||
method.getAnnotations().add(noCacheAnnot);
|
method.getAnnotations().add(noCacheAnnot);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user