Fix bugs in emit API

This commit is contained in:
Alexey Andreev 2015-07-30 18:11:31 +03:00
parent ce525f0a78
commit 0be4ca336d
6 changed files with 52 additions and 27 deletions

View File

@ -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());
}

View File

@ -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;
}
}

View File

@ -292,7 +292,6 @@ public final class ProgramEmitter {
JumpInstruction insn = new JumpInstruction();
insn.setTarget(block);
addInstruction(insn);
this.block = block;
return this;
}

View File

@ -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:

View File

@ -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()));

View File

@ -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);