Fix compile-time error in metaprogramming API when body of emit or lazy throws exception instead of returning value

This commit is contained in:
Alexey Andreev 2017-02-05 17:28:40 +03:00
parent 5e44c13caf
commit 9271d71906
2 changed files with 25 additions and 13 deletions

View File

@ -18,10 +18,6 @@ package org.teavm.model.instructions;
import org.teavm.model.Instruction; import org.teavm.model.Instruction;
import org.teavm.model.Variable; import org.teavm.model.Variable;
/**
*
* @author Alexey Andreev
*/
public class AssignInstruction extends Instruction { public class AssignInstruction extends Instruction {
private Variable assignee; private Variable assignee;
private Variable receiver; private Variable receiver;

View File

@ -147,7 +147,10 @@ public class CompositeMethodGenerator {
returnBlockIndex = program.basicBlockCount() - 1; returnBlockIndex = program.basicBlockCount() - 1;
for (int i = capturedValues.size(); i < template.variableCount(); ++i) { for (int i = capturedValues.size(); i < template.variableCount(); ++i) {
program.createVariable(); VariableReader variable = template.variableAt(i);
Variable variableCopy = program.createVariable();
variableCopy.setDebugName(variable.getDebugName());
variableCopy.setLabel(variable.getLabel());
} }
// Pre-create phis // Pre-create phis
@ -305,10 +308,11 @@ public class CompositeMethodGenerator {
add(insn); add(insn);
return insn.getReceiver(); return insn.getReceiver();
} else if (value instanceof ValueImpl) { } else if (value instanceof ValueImpl) {
return varContext.emitVariable((ValueImpl<?>) value, new CallLocation(MetaprogrammingImpl.templateMethod, Variable result = varContext.emitVariable((ValueImpl<?>) value,
location)); new CallLocation(MetaprogrammingImpl.templateMethod, location));
return coalesce(result);
} else if (value instanceof LazyValueImpl) { } else if (value instanceof LazyValueImpl) {
return lazy((LazyValueImpl<?>) value); return coalesce(lazy((LazyValueImpl<?>) value));
} else if (value instanceof ReflectFieldImpl) { } else if (value instanceof ReflectFieldImpl) {
ReflectFieldImpl reflectField = (ReflectFieldImpl) value; ReflectFieldImpl reflectField = (ReflectFieldImpl) value;
diagnostics.error(new CallLocation(MetaprogrammingImpl.templateMethod, location), diagnostics.error(new CallLocation(MetaprogrammingImpl.templateMethod, location),
@ -356,7 +360,7 @@ public class CompositeMethodGenerator {
if (result instanceof ValueImpl) { if (result instanceof ValueImpl) {
return ((ValueImpl<?>) result).innerValue; return ((ValueImpl<?>) result).innerValue;
} else if (result instanceof LazyValueImpl) { } else if (result instanceof LazyValueImpl) {
return lazy((LazyValueImpl) result); return lazy((LazyValueImpl<?>) result);
} else if (result != null) { } else if (result != null) {
throw new IllegalStateException("Unknown value type: " + result.getClass().getName()); throw new IllegalStateException("Unknown value type: " + result.getClass().getName());
} else { } else {
@ -364,6 +368,16 @@ public class CompositeMethodGenerator {
} }
} }
private Variable coalesce(Variable var) {
if (var == null) {
NullConstantInstruction nullInsn = new NullConstantInstruction();
nullInsn.setReceiver(program.createVariable());
var = nullInsn.getReceiver();
add(nullInsn);
}
return var;
}
Variable box(Variable var, ValueType type) { Variable box(Variable var, ValueType type) {
if (type instanceof ValueType.Primitive) { if (type instanceof ValueType.Primitive) {
switch (((ValueType.Primitive) type).getKind()) { switch (((ValueType.Primitive) type).getKind()) {
@ -805,10 +819,12 @@ public class CompositeMethodGenerator {
if (type == InvocationType.VIRTUAL && instance != null) { if (type == InvocationType.VIRTUAL && instance != null) {
if (method.getClassName().equals(Value.class.getName())) { if (method.getClassName().equals(Value.class.getName())) {
if (method.getName().equals("get")) { if (method.getName().equals("get")) {
AssignInstruction insn = new AssignInstruction(); if (receiver != null) {
insn.setReceiver(var(receiver)); AssignInstruction insn = new AssignInstruction();
insn.setAssignee(var(instance)); insn.setReceiver(var(receiver));
add(insn); insn.setAssignee(var(instance));
add(insn);
}
return; return;
} else { } else {
diagnostics.error(new CallLocation(MetaprogrammingImpl.templateMethod, location), diagnostics.error(new CallLocation(MetaprogrammingImpl.templateMethod, location),