diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/reflect/AnnotationDependencyListener.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/reflect/AnnotationDependencyListener.java index e8df3d21f..a93cb5893 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/reflect/AnnotationDependencyListener.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/reflect/AnnotationDependencyListener.java @@ -31,14 +31,11 @@ import org.teavm.model.ClassReader; import org.teavm.model.ClassReaderSource; import org.teavm.model.ElementModifier; import org.teavm.model.FieldHolder; -import org.teavm.model.FieldReference; import org.teavm.model.MethodHolder; import org.teavm.model.MethodReader; -import org.teavm.model.MethodReference; import org.teavm.model.ValueType; import org.teavm.model.emit.ProgramEmitter; import org.teavm.model.emit.ValueEmitter; -import org.teavm.model.instructions.ArrayElementType; import org.teavm.platform.PlatformAnnotationProvider; /** @@ -94,8 +91,8 @@ public class AnnotationDependencyListener extends AbstractDependencyListener { MethodHolder accessor = new MethodHolder(methodDecl.getDescriptor()); ProgramEmitter pe = ProgramEmitter.create(accessor); - ValueEmitter thisVal = pe.newVar(); - ValueEmitter result = thisVal.getField(field.getReference(), field.getType()); + ValueEmitter thisVal = pe.newVar(implementor); + ValueEmitter result = thisVal.getField(field.getName(), field.getType()); if (field.getType() instanceof ValueType.Array) { result = result.cloneArray(); } @@ -108,22 +105,21 @@ public class AnnotationDependencyListener extends AbstractDependencyListener { MethodHolder ctor = new MethodHolder("", ctorSignature.toArray(new ValueType[ctorSignature.size()])); ProgramEmitter pe = ProgramEmitter.create(ctor); - ValueEmitter thisVal = pe.newVar(); - thisVal.invokeSpecial(new MethodReference(Object.class, "", void.class)); + ValueEmitter thisVar = pe.newVar(implementor); + thisVar.invokeSpecial(Object.class, ""); for (MethodReader methodDecl : annotation.getMethods()) { if (methodDecl.hasModifier(ElementModifier.STATIC)) { continue; } - ValueEmitter param = pe.newVar(); - FieldReference field = new FieldReference(implementorName, "$" + methodDecl.getName()); - thisVal.setField(field, methodDecl.getResultType(), param); + ValueEmitter param = pe.newVar(methodDecl.getResultType()); + thisVar.setField("$" + methodDecl.getName(), param); } pe.exit(); implementor.addMethod(ctor); MethodHolder annotTypeMethod = new MethodHolder("annotationType", ValueType.parse(Class.class)); pe = ProgramEmitter.create(annotTypeMethod); - pe.newVar(); + pe.newVar(implementor); pe.constant(ValueType.object(annotationType)).returnValue(); implementor.addMethod(annotTypeMethod); @@ -169,10 +165,8 @@ public class AnnotationDependencyListener extends AbstractDependencyListener { MethodHolder ctor = new MethodHolder("", ValueType.VOID); ctor.setLevel(AccessLevel.PUBLIC); ProgramEmitter pe = ProgramEmitter.create(ctor); - ValueEmitter thisVar = pe.newVar(); - - thisVar.invokeSpecial(new MethodReference(Object.class, "", void.class)); - pe.exit(); + ValueEmitter thisVar = pe.newVar(cls); + thisVar.invokeSpecial(Object.class, "").exit(); ClassReader annotatedClass = agent.getClassSource().get(className); cls.addMethod(ctor); @@ -204,8 +198,7 @@ public class AnnotationDependencyListener extends AbstractDependencyListener { ValueEmitter array = pe.constructArray(Annotation.class, annotations.size()); for (int i = 0; i < annotations.size(); ++i) { - array.unwrapArray(ArrayElementType.OBJECT).setElement(i, - generateAnnotationInstance(agent, pe, annotations.get(i))); + array.unwrapArray().setElement(i, generateAnnotationInstance(agent, pe, annotations.get(i))); } array.returnValue(); @@ -217,25 +210,20 @@ public class AnnotationDependencyListener extends AbstractDependencyListener { AnnotationReader annotation) { ClassReader annotationClass = agent.getClassSource().get(annotation.getType()); if (annotationClass == null) { - return pe.constantNull(); + return pe.constantNull(ValueType.object(annotation.getType())); } String className = getAnnotationImplementor(agent, annotation.getType()); - List ctorSignature = new ArrayList<>(); List params = new ArrayList<>(); for (MethodReader methodDecl : annotationClass.getMethods()) { - ctorSignature.add(methodDecl.getResultType()); AnnotationValue value = annotation.getValue(methodDecl.getName()); if (value == null) { value = methodDecl.getAnnotationDefault(); } params.add(generateAnnotationValue(agent, pe, methodDecl.getResultType(), value)); } - ctorSignature.add(ValueType.VOID); - MethodReference ctor = new MethodReference(className, "", ctorSignature.toArray( - new ValueType[ctorSignature.size()])); - return pe.construct(ctor, params.toArray(new ValueEmitter[params.size()])); + return pe.construct(className, params.toArray(new ValueEmitter[params.size()])); } private ValueEmitter generateAnnotationValue(DependencyAgent agent, ProgramEmitter pe, ValueType type, @@ -262,8 +250,7 @@ public class AnnotationDependencyListener extends AbstractDependencyListener { ValueType itemType = ((ValueType.Array) type).getItemType(); ValueEmitter array = pe.constructArray(itemType, list.size()); for (int i = 0; i < list.size(); ++i) { - array.unwrapArray(ArrayElementType.OBJECT).setElement(i, - generateAnnotationValue(agent, pe, itemType, list.get(i))); + array.unwrapArray().setElement(i, generateAnnotationValue(agent, pe, itemType, list.get(i))); } return array; } diff --git a/teavm-core/src/main/java/org/teavm/model/emit/ChooseEmitter.java b/teavm-core/src/main/java/org/teavm/model/emit/ChooseEmitter.java new file mode 100644 index 000000000..c7886828e --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/model/emit/ChooseEmitter.java @@ -0,0 +1,57 @@ +/* + * Copyright 2015 Alexey Andreev. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.teavm.model.emit; + +import org.teavm.model.BasicBlock; +import org.teavm.model.instructions.SwitchInstruction; +import org.teavm.model.instructions.SwitchTableEntry; + +/** + * + * @author Alexey Andreev + */ +public class ChooseEmitter { + private ProgramEmitter pe; + private SwitchInstruction insn; + private BasicBlock joinBlock; + + ChooseEmitter(ProgramEmitter pe, SwitchInstruction insn, BasicBlock joinBlock) { + this.pe = pe; + this.insn = insn; + this.joinBlock = joinBlock; + insn.setDefaultTarget(joinBlock); + } + + public ChooseEmitter option(int value, FragmentEmitter fragment) { + SwitchTableEntry entry = new SwitchTableEntry(); + entry.setCondition(value); + entry.setTarget(pe.createBlock()); + fragment.emit(); + pe.jump(joinBlock); + return this; + } + + public ProgramEmitter otherwise(FragmentEmitter fragment) { + insn.setDefaultTarget(pe.createBlock()); + fragment.emit(); + pe.jump(joinBlock); + return pe; + } + + public FragmentEmitter breakChoise() { + return () -> pe.jump(joinBlock); + } +} diff --git a/teavm-core/src/main/java/org/teavm/model/emit/ComputationEmitter.java b/teavm-core/src/main/java/org/teavm/model/emit/ComputationEmitter.java index 3b7ac4547..337e013a0 100644 --- a/teavm-core/src/main/java/org/teavm/model/emit/ComputationEmitter.java +++ b/teavm-core/src/main/java/org/teavm/model/emit/ComputationEmitter.java @@ -20,5 +20,5 @@ package org.teavm.model.emit; * @author Alexey Andreev */ public interface ComputationEmitter { - ValueEmitter emit(ProgramEmitter pe); + ValueEmitter emit(); } diff --git a/teavm-core/src/main/java/org/teavm/model/emit/ConditionEmitter.java b/teavm-core/src/main/java/org/teavm/model/emit/ConditionEmitter.java new file mode 100644 index 000000000..457fc6b26 --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/model/emit/ConditionEmitter.java @@ -0,0 +1,62 @@ +/* + * Copyright 2015 Alexey Andreev. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.teavm.model.emit; + +import org.teavm.model.BasicBlock; +import org.teavm.model.instructions.BinaryBranchingCondition; +import org.teavm.model.instructions.BranchingCondition; + +/** + * + * @author Alexey Andreev + */ +public class ConditionEmitter { + private ProgramEmitter pe; + private ComputationEmitter argument; + private BasicBlock join; + + ConditionEmitter(ProgramEmitter pe, ComputationEmitter argument, BasicBlock join) { + this.pe = pe; + this.argument = argument; + this.join = join; + } + + public IfEmitter isTrue() { + return new IfEmitter(pe, argument.emit().fork(BranchingCondition.NOT_EQUAL), join); + } + + public IfEmitter isFalse() { + return new IfEmitter(pe, argument.emit().fork(BranchingCondition.NOT_NULL), join); + } + + public IfEmitter equalTo(ComputationEmitter other) { + return new IfEmitter(pe, argument.emit().fork(BinaryBranchingCondition.EQUAL, other.emit()), join); + } + + public IfEmitter notEqualTo(ComputationEmitter other) { + return new IfEmitter(pe, argument.emit().fork(BinaryBranchingCondition.NOT_EQUAL, other.emit()), join); + } + + public IfEmitter sameAs(ComputationEmitter other) { + return new IfEmitter(pe, argument.emit().fork(BinaryBranchingCondition.REFERENCE_EQUAL, other.emit()), + join); + } + + public IfEmitter notSameAs(ComputationEmitter other) { + return new IfEmitter(pe, argument.emit().fork(BinaryBranchingCondition.REFERENCE_NOT_EQUAL, other.emit()), + join); + } +} diff --git a/teavm-core/src/main/java/org/teavm/model/emit/FragmentEmitter.java b/teavm-core/src/main/java/org/teavm/model/emit/FragmentEmitter.java index 4a9f7f908..53e953835 100644 --- a/teavm-core/src/main/java/org/teavm/model/emit/FragmentEmitter.java +++ b/teavm-core/src/main/java/org/teavm/model/emit/FragmentEmitter.java @@ -20,5 +20,5 @@ package org.teavm.model.emit; * @author Alexey Andreev */ public interface FragmentEmitter { - void emit(ProgramEmitter pe); + void emit(); } diff --git a/teavm-core/src/main/java/org/teavm/model/emit/IfEmitter.java b/teavm-core/src/main/java/org/teavm/model/emit/IfEmitter.java index bc6f16050..45bf9223f 100644 --- a/teavm-core/src/main/java/org/teavm/model/emit/IfEmitter.java +++ b/teavm-core/src/main/java/org/teavm/model/emit/IfEmitter.java @@ -16,7 +16,6 @@ package org.teavm.model.emit; import org.teavm.model.BasicBlock; -import org.teavm.model.instructions.BranchingCondition; /** * @@ -27,36 +26,30 @@ public class IfEmitter { private ForkEmitter fork; private BasicBlock join; - IfEmitter(ProgramEmitter pe, ForkEmitter fork) { + IfEmitter(ProgramEmitter pe, ForkEmitter fork, BasicBlock join) { this.pe = pe; this.fork = fork; - this.join = pe.createBlock(); + this.join = join; } - public IfEmitter and(ComputationEmitter condition) { - BasicBlock block = pe.createBlock(); - fork = fork.and(block, condition.emit(pe).fork(BranchingCondition.NOT_EQUAL)); - pe.setBlock(join); - return this; + public ConditionEmitter and(ComputationEmitter condition) { + return new ConditionEmitter(pe, condition, join); } - public IfEmitter or(ComputationEmitter condition) { - BasicBlock block = pe.createBlock(); - fork = fork.or(block, condition.emit(pe).fork(BranchingCondition.NOT_EQUAL)); - pe.setBlock(join); - return this; + public ConditionEmitter or(ComputationEmitter condition) { + return new ConditionEmitter(pe, condition, join); } public IfEmitter thenDo(FragmentEmitter fragment) { fork.setThen(pe.createBlock()); - fragment.emit(pe); + fragment.emit(); pe.jump(join); return this; } public IfEmitter elseDo(FragmentEmitter fragment) { fork.setThen(pe.createBlock()); - fragment.emit(pe); + fragment.emit(); pe.jump(join); return this; } diff --git a/teavm-core/src/main/java/org/teavm/model/emit/PhiEmitter.java b/teavm-core/src/main/java/org/teavm/model/emit/PhiEmitter.java new file mode 100644 index 000000000..26a9232ea --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/model/emit/PhiEmitter.java @@ -0,0 +1,36 @@ +/* + * Copyright 2015 Alexey Andreev. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.teavm.model.emit; + +import org.teavm.model.Phi; + +/** + * + * @author Alexey Andreev + */ +public class PhiEmitter { + Phi phi; + ValueEmitter value; + + PhiEmitter(Phi phi, ValueEmitter value) { + this.phi = phi; + this.value = value; + } + + public ValueEmitter getValue() { + return value; + } +} diff --git a/teavm-core/src/main/java/org/teavm/model/emit/ProgramEmitter.java b/teavm-core/src/main/java/org/teavm/model/emit/ProgramEmitter.java index 70db2229f..2d087444f 100644 --- a/teavm-core/src/main/java/org/teavm/model/emit/ProgramEmitter.java +++ b/teavm-core/src/main/java/org/teavm/model/emit/ProgramEmitter.java @@ -21,10 +21,11 @@ import org.teavm.model.FieldReference; import org.teavm.model.Instruction; import org.teavm.model.InstructionLocation; import org.teavm.model.MethodHolder; +import org.teavm.model.MethodReference; +import org.teavm.model.Phi; import org.teavm.model.Program; import org.teavm.model.ValueType; import org.teavm.model.Variable; -import org.teavm.model.instructions.BranchingCondition; import org.teavm.model.instructions.ClassConstantInstruction; import org.teavm.model.instructions.ConstructArrayInstruction; import org.teavm.model.instructions.ConstructInstruction; @@ -41,6 +42,7 @@ import org.teavm.model.instructions.LongConstantInstruction; import org.teavm.model.instructions.NullConstantInstruction; import org.teavm.model.instructions.PutFieldInstruction; import org.teavm.model.instructions.StringConstantInstruction; +import org.teavm.model.instructions.SwitchInstruction; /** * @@ -176,6 +178,14 @@ public final class ProgramEmitter { if (resultType != ValueType.VOID) { result = program.createVariable(); } + + ValueType[] argumentTypes = new ValueType[arguments.length + 1]; + for (int i = 0; i < arguments.length; ++i) { + argumentTypes[i] = arguments[i].type; + } + argumentTypes[arguments.length] = resultType; + MethodReference method = new MethodReference(className, methodName, argumentTypes); + InvokeInstruction insn = new InvokeInstruction(); insn.setType(InvocationType.SPECIAL); insn.setMethod(method); @@ -203,7 +213,7 @@ public final class ProgramEmitter { insn.setType(className); addInstruction(insn); ValueEmitter instance = var(var, ValueType.object(className)); - instance.invokeSpecial(method, arguments); + instance.invokeSpecial("", void.class, arguments); return instance; } @@ -301,7 +311,41 @@ public final class ProgramEmitter { return new ProgramEmitter(program, block); } - public IfEmitter when(ComputationEmitter condition) { - return new IfEmitter(this, condition.emit(this).fork(BranchingCondition.NOT_EQUAL)); + public ConditionEmitter when(ComputationEmitter condition) { + return new ConditionEmitter(this, condition, program.createBasicBlock()); + } + + public PhiEmitter phi(ValueType type, BasicBlock block) { + ValueEmitter value = newVar(type); + Phi phi = new Phi(); + phi.setReceiver(value.getVariable()); + block.getPhis().add(phi); + return new PhiEmitter(phi, value); + } + + public PhiEmitter phi(Class cls, BasicBlock block) { + return phi(ValueType.parse(cls), block); + } + + public PhiEmitter phi(ClassReader cls, BasicBlock block) { + return phi(ValueType.object(cls.getName()), block); + } + + public PhiEmitter phi(ValueType type) { + return phi(type, block); + } + + public PhiEmitter phi(Class cls) { + return phi(ValueType.parse(cls)); + } + + public PhiEmitter phi(ClassReader cls) { + return phi(ValueType.object(cls.getName())); + } + + public ChooseEmitter choise(ValueEmitter value) { + SwitchInstruction insn = new SwitchInstruction(); + insn.setCondition(value.getVariable()); + return new ChooseEmitter(this, insn, program.createBasicBlock()); } } diff --git a/teavm-core/src/main/java/org/teavm/model/emit/ValueEmitter.java b/teavm-core/src/main/java/org/teavm/model/emit/ValueEmitter.java index 1558b2560..ccfec672b 100644 --- a/teavm-core/src/main/java/org/teavm/model/emit/ValueEmitter.java +++ b/teavm-core/src/main/java/org/teavm/model/emit/ValueEmitter.java @@ -23,6 +23,7 @@ import org.teavm.model.Phi; import org.teavm.model.PrimitiveType; import org.teavm.model.ValueType; import org.teavm.model.Variable; +import org.teavm.model.instructions.ArrayElementType; import org.teavm.model.instructions.ArrayLengthInstruction; import org.teavm.model.instructions.BinaryBranchingCondition; import org.teavm.model.instructions.BinaryBranchingInstruction; @@ -311,7 +312,7 @@ public class ValueEmitter { switch (common) { case FLOAT: case DOUBLE: - throw new IllegalArgumentException("Can't perform bitwise operation between non-integers"); + throw new IllegalArgumentException("Can't perform bitwise operation between non-integers: " + common); default: break; } @@ -338,27 +339,64 @@ public class ValueEmitter { } public ValueEmitter shl(ValueEmitter other) { - return binary(BinaryOperation.SHIFT_LEFT, other); + return shift(BinaryOperation.SHIFT_LEFT, other); } public ValueEmitter shl(int value) { - return binary(BinaryOperation.SHIFT_LEFT, pe.constant(value)); + return shl(pe.constant(value)); } public ValueEmitter shr(ValueEmitter other) { - return binary(BinaryOperation.SHIFT_RIGHT, other); + return shift(BinaryOperation.SHIFT_RIGHT, other); } public ValueEmitter shr(int value) { - return binary(BinaryOperation.SHIFT_RIGHT, pe.constant(value)); + return shr(pe.constant(value)); } public ValueEmitter shru(ValueEmitter other) { - return binary(BinaryOperation.SHIFT_RIGHT_UNSIGNED, other); + return shift(BinaryOperation.SHIFT_RIGHT_UNSIGNED, other); } public ValueEmitter shru(int value) { - return binary(BinaryOperation.SHIFT_RIGHT_UNSIGNED, pe.constant(value)); + return shru(pe.constant(value)); + } + + private ValueEmitter shift(BinaryOperation op, ValueEmitter other) { + if (!(type instanceof ValueType.Primitive) || !(other.type instanceof ValueType.Primitive)) { + throw new IllegalArgumentException("Can't shift " + type + " by " + other.type); + } + + ValueType valueType = type; + PrimitiveType kind = ((ValueType.Primitive) type).getKind(); + switch (kind) { + case FLOAT: + case DOUBLE: + throw new IllegalArgumentException("Can't perform bit shift operation over non-integer: " + type); + default: + break; + } + + PrimitiveType shiftKind = ((ValueType.Primitive) type).getKind(); + switch (kind) { + case BYTE: + case SHORT: + case INTEGER: + break; + default: + throw new IllegalArgumentException("Can't perform bit shift operation with non-integer " + + "shift: " + type); + } + other = other.castToInteger(convertToIntegerSubtype(shiftKind)); + + ValueEmitter value = this; + IntegerSubtype subtype = convertToIntegerSubtype(kind); + if (subtype != null) { + value = value.castToInteger(subtype); + valueType = ValueType.INTEGER; + } + + return binaryOp(op, value, other, valueType); } public ValueEmitter invoke(InvocationType invokeType, String className, String name, ValueType resultType, @@ -368,7 +406,6 @@ public class ValueEmitter { } Variable result = null; - String className = ((ValueType.Object) type).getClassName(); ValueType[] signature = new ValueType[arguments.length + 1]; for (int i = 0; i < arguments.length; ++i) { signature[i] = arguments[i].type; @@ -435,6 +472,7 @@ public class ValueEmitter { invokeVirtual(name, ValueType.VOID, arguments); } + public ValueEmitter join(BasicBlock block, ValueEmitter other, BasicBlock otherBlock, ValueType type) { Variable var = pe.getProgram().createVariable(); Phi phi = new Phi(); @@ -505,7 +543,38 @@ public class ValueEmitter { return this; } if (type instanceof ValueType.Primitive) { + if (!(this.type instanceof ValueType.Primitive)) { + throw new IllegalStateException("Can't convert " + this.type + " to " + type); + } + ValueEmitter value = this; + PrimitiveType sourceKind = ((ValueType.Primitive) this.type).getKind(); + PrimitiveType targetKind = ((ValueType.Primitive) type).getKind(); + + if (sourceKind == PrimitiveType.BOOLEAN || targetKind == PrimitiveType.BOOLEAN) { + throw new IllegalStateException("Can't convert " + this.type + " to " + type); + } + + IntegerSubtype sourceSubtype = convertToIntegerSubtype(sourceKind); + if (sourceSubtype != null) { + sourceKind = PrimitiveType.INTEGER; + value = castToInteger(sourceSubtype); + } + NumericOperandType sourceNumeric = convertToNumeric(sourceKind); + NumericOperandType targetNumeric = convertToNumeric(sourceKind); + + CastNumberInstruction insn = new CastNumberInstruction(sourceNumeric, targetNumeric); + insn.setValue(value.getVariable()); + value = pe.newVar(type); + insn.setReceiver(value.getVariable()); + pe.addInstruction(insn); + + IntegerSubtype targetSubtype = convertToIntegerSubtype(targetKind); + if (targetSubtype != null) { + value = castFromInteger(targetSubtype); + } + + return value; } else { if (this.type instanceof ValueType.Primitive) { throw new IllegalStateException("Can't convert " + this.type + " to " + type); @@ -591,8 +660,13 @@ public class ValueEmitter { } public ValueEmitter unwrapArray() { + if (!(type instanceof ValueType.Array)) { + throw new IllegalStateException("Can't unwrap non-array value: " + type); + } + + ValueType elementType = ((ValueType.Array) type).getItemType(); Variable result = pe.getProgram().createVariable(); - UnwrapArrayInstruction insn = new UnwrapArrayInstruction(elementType); + UnwrapArrayInstruction insn = new UnwrapArrayInstruction(getArrayElementType(elementType)); insn.setArray(variable); insn.setReceiver(result); pe.addInstruction(insn); @@ -626,4 +700,35 @@ public class ValueEmitter { pe.addInstruction(insn); return pe.var(result, type); } + + private ArrayElementType getArrayElementType(ValueType type) { + if (type instanceof ValueType.Primitive) { + switch (((ValueType.Primitive) type).getKind()) { + case BOOLEAN: + case BYTE: + return ArrayElementType.BYTE; + case SHORT: + return ArrayElementType.SHORT; + case CHARACTER: + return ArrayElementType.CHAR; + case INTEGER: + return ArrayElementType.INT; + case LONG: + return ArrayElementType.LONG; + case FLOAT: + return ArrayElementType.FLOAT; + case DOUBLE: + return ArrayElementType.DOUBLE; + } + } + return ArrayElementType.OBJECT; + } + + public ProgramEmitter enter(PhiEmitter phi) { + Incoming incoming = new Incoming(); + incoming.setValue(variable); + incoming.setSource(pe.getBlock()); + phi.phi.getIncomings().add(incoming); + return pe; + } } diff --git a/teavm-maven/teavm-maven-plugin/.factorypath b/teavm-maven/teavm-maven-plugin/.factorypath new file mode 100644 index 000000000..d1aae2f90 --- /dev/null +++ b/teavm-maven/teavm-maven-plugin/.factorypath @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +