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.ClassReader;
|
||||
import org.teavm.model.ClassReaderSource;
|
||||
import org.teavm.model.MethodHolder;
|
||||
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");
|
||||
}
|
||||
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());
|
||||
}
|
||||
|
||||
|
|
|
@ -38,17 +38,17 @@ public class IfEmitter {
|
|||
BasicBlock block = pe.prepareBlock();
|
||||
fork.setThen(block);
|
||||
pe.enter(block);
|
||||
fragment.emit();
|
||||
pe.jump(join);
|
||||
pe.emitAndJump(fragment, join);
|
||||
pe.enter(join);
|
||||
return this;
|
||||
}
|
||||
|
||||
public IfEmitter elseDo(FragmentEmitter fragment) {
|
||||
BasicBlock block = pe.prepareBlock();
|
||||
fork.setThen(block);
|
||||
fork.setElse(block);
|
||||
pe.enter(block);
|
||||
fragment.emit();
|
||||
pe.jump(join);
|
||||
pe.emitAndJump(fragment, join);
|
||||
pe.enter(join);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -292,7 +292,6 @@ public final class ProgramEmitter {
|
|||
JumpInstruction insn = new JumpInstruction();
|
||||
insn.setTarget(block);
|
||||
addInstruction(insn);
|
||||
this.block = block;
|
||||
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)) {
|
||||
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));
|
||||
}
|
||||
|
||||
public ConditionEmitter isLessOrEuqalTo(ValueEmitter other) {
|
||||
public ConditionEmitter isLessOrEqualTo(ValueEmitter other) {
|
||||
return new ConditionEmitter(pe, compareTo(other).fork(BranchingCondition.LESS_OR_EQUAL));
|
||||
}
|
||||
|
||||
|
@ -640,8 +640,10 @@ public class ValueEmitter {
|
|||
}
|
||||
|
||||
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;
|
||||
} else if (pe.classSource.isSuperType(type, this.type).orElse(false)) {
|
||||
return pe.var(variable.getIndex(), type);
|
||||
}
|
||||
|
||||
if (type instanceof ValueType.Primitive) {
|
||||
|
@ -720,12 +722,24 @@ public class ValueEmitter {
|
|||
|
||||
CastIntegerInstruction insn = new CastIntegerInstruction(subtype, CastIntegerDirection.TO_INTEGER);
|
||||
insn.setValue(variable);
|
||||
ValueEmitter result = pe.newVar(ValueType.INTEGER);
|
||||
ValueEmitter result = pe.newVar(convertSubtype(subtype));
|
||||
insn.setReceiver(result.getVariable());
|
||||
pe.addInstruction(insn);
|
||||
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) {
|
||||
switch (subtype) {
|
||||
case BYTE:
|
||||
|
|
|
@ -32,7 +32,11 @@ public abstract class BasicBlockMapper implements InstructionVisitor {
|
|||
}
|
||||
|
||||
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 (Incoming incoming : phi.getIncomings()) {
|
||||
incoming.setSource(map(incoming.getSource()));
|
||||
|
|
|
@ -18,10 +18,19 @@ package org.teavm.platform.plugin;
|
|||
import org.teavm.cache.NoCache;
|
||||
import org.teavm.diagnostics.Diagnostics;
|
||||
import org.teavm.javascript.spi.GeneratedBy;
|
||||
import org.teavm.model.*;
|
||||
import org.teavm.model.emit.ForkEmitter;
|
||||
import org.teavm.model.AccessLevel;
|
||||
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.instructions.BinaryBranchingCondition;
|
||||
import org.teavm.model.util.ModelUtils;
|
||||
import org.teavm.platform.PlatformClass;
|
||||
import org.teavm.platform.metadata.ClassScopedMetadataProvider;
|
||||
|
@ -91,19 +100,11 @@ class MetadataProviderTransformer implements ClassHolderTransformer {
|
|||
|
||||
method.getModifiers().remove(ElementModifier.NATIVE);
|
||||
ProgramEmitter pe = ProgramEmitter.create(method, classSource);
|
||||
ForkEmitter fork = pe.getField(field.getReference(), field.getType()).fork(
|
||||
BinaryBranchingCondition.REFERENCE_NOT_EQUAL, pe.constantNull(field.getType()));
|
||||
|
||||
BasicBlock resourceFound = pe.prepareBlock();
|
||||
fork.setThen(resourceFound);
|
||||
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);
|
||||
pe.when(pe.getField(field.getReference(), field.getType()).isNull())
|
||||
.thenDo(() -> pe.setField(field.getReference(), pe.invoke(createMethod.getReference().getClassName(),
|
||||
createMethod.getReference().getName(), createMethod.getResultType())));
|
||||
pe.getField(field.getReference(), field.getType())
|
||||
.returnValue();
|
||||
|
||||
AnnotationHolder noCacheAnnot = new AnnotationHolder(NoCache.class.getName());
|
||||
method.getAnnotations().add(noCacheAnnot);
|
||||
|
|
Loading…
Reference in New Issue
Block a user