diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java index ac8056755..79a1ae37b 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java @@ -159,7 +159,7 @@ public class DependencyChecker { for (int i = 0; i < varCount; ++i) { parameterNodes[i] = new DependencyNode(this); if (shouldLog) { - parameterNodes[i].setTag(method.getOwner().getName() + "#" + method.getDescriptor() + ":" + i); + parameterNodes[i].setTag(method.getOwnerName() + "#" + method.getDescriptor() + ":" + i); } } DependencyNode resultNode; @@ -168,7 +168,7 @@ public class DependencyChecker { } else { resultNode = new DependencyNode(this); if (shouldLog) { - resultNode.setTag(method.getOwner().getName() + "#" + method.getDescriptor() + ":RESULT"); + resultNode.setTag(method.getOwnerName() + "#" + method.getDescriptor() + ":RESULT"); } } final MethodGraph graph = new MethodGraph(parameterNodes, paramCount, resultNode, this); diff --git a/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java b/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java index 0aab4352b..9bd265369 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java @@ -120,7 +120,7 @@ public class Decompiler { public NativeMethodNode decompileNative(MethodHolder method) { AnnotationHolder annotHolder = method.getAnnotations().get(GeneratedBy.class.getName()); if (annotHolder == null) { - throw new DecompilationException("Method " + method.getOwner().getName() + "." + method.getDescriptor() + + throw new DecompilationException("Method " + method.getOwnerName() + "." + method.getDescriptor() + " is native, but no " + GeneratedBy.class.getName() + " annotation found"); } ValueType annotValue = annotHolder.getValues().get("value").getJavaClass(); @@ -131,9 +131,9 @@ public class Decompiler { generator = (Generator)generatorClass.newInstance(); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) { throw new DecompilationException("Error instantiating generator " + generatorClassName + - " for native method " + method.getOwner().getName() + "." + method.getDescriptor()); + " for native method " + method.getOwnerName() + "." + method.getDescriptor()); } - NativeMethodNode methodNode = new NativeMethodNode(new MethodReference(method.getOwner().getName(), + NativeMethodNode methodNode = new NativeMethodNode(new MethodReference(method.getOwnerName(), method.getDescriptor())); methodNode.getModifiers().addAll(mapModifiers(method.getModifiers())); methodNode.setGenerator(generator); @@ -193,7 +193,7 @@ public class Decompiler { } SequentialStatement result = new SequentialStatement(); result.getSequence().addAll(rootStmt.getBody()); - MethodReference reference = new MethodReference(method.getOwner().getName(), method.getDescriptor()); + MethodReference reference = new MethodReference(method.getOwnerName(), method.getDescriptor()); RegularMethodNode methodNode = new RegularMethodNode(reference); methodNode.getModifiers().addAll(mapModifiers(method.getModifiers())); methodNode.setBody(result); diff --git a/teavm-core/src/main/java/org/teavm/model/BasicBlock.java b/teavm-core/src/main/java/org/teavm/model/BasicBlock.java index d0ef60cba..a4114da1e 100644 --- a/teavm-core/src/main/java/org/teavm/model/BasicBlock.java +++ b/teavm-core/src/main/java/org/teavm/model/BasicBlock.java @@ -16,12 +16,13 @@ package org.teavm.model; import java.util.*; +import org.teavm.model.instructions.InstructionReader; /** * * @author Alexey Andreev */ -public class BasicBlock { +public class BasicBlock implements BasicBlockReader { private Program program; private int index; private List phis = new ArrayList<>(); @@ -32,10 +33,12 @@ public class BasicBlock { this.index = index; } + @Override public Program getProgram() { return program; } + @Override public int getIndex() { return index; } @@ -153,4 +156,29 @@ public class BasicBlock { public List getPhis() { return safePhis; } + + private List immutablePhis = Collections.unmodifiableList(phis); + + @Override + public List readPhis() { + return immutablePhis; + } + + @Override + public int instructionCount() { + return instructions.size(); + } + + @Override + public void readInstruction(int index, InstructionReader reader) { + instructions.get(index).acceptVisitor(new InstructionReadVisitor(reader)); + } + + @Override + public void readAllInstructions(InstructionReader reader) { + InstructionReadVisitor visitor = new InstructionReadVisitor(reader); + for (Instruction insn : instructions) { + insn.acceptVisitor(visitor); + } + } } diff --git a/teavm-core/src/main/java/org/teavm/model/BasicBlockReader.java b/teavm-core/src/main/java/org/teavm/model/BasicBlockReader.java new file mode 100644 index 000000000..1cc01d8ce --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/model/BasicBlockReader.java @@ -0,0 +1,37 @@ +/* + * Copyright 2014 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; + +import java.util.List; +import org.teavm.model.instructions.InstructionReader; + +/** + * + * @author Alexey Andreev + */ +public interface BasicBlockReader { + ProgramReader getProgram(); + + int getIndex(); + + List readPhis(); + + int instructionCount(); + + void readInstruction(int index, InstructionReader reader); + + void readAllInstructions(InstructionReader reader); +} diff --git a/teavm-core/src/main/java/org/teavm/model/ClassHolder.java b/teavm-core/src/main/java/org/teavm/model/ClassHolder.java index 1924c3b85..22d1e19e2 100644 --- a/teavm-core/src/main/java/org/teavm/model/ClassHolder.java +++ b/teavm-core/src/main/java/org/teavm/model/ClassHolder.java @@ -21,7 +21,7 @@ import java.util.*; * * @author Alexey Andreev */ -public class ClassHolder extends ElementHolder { +public class ClassHolder extends ElementHolder implements ClassReader { private String parent = Object.class.getName(); private Set interfaces = new HashSet<>(); private Map methods = new HashMap<>(); @@ -31,6 +31,7 @@ public class ClassHolder extends ElementHolder { super(name); } + @Override public String getParent() { return parent; } @@ -39,14 +40,17 @@ public class ClassHolder extends ElementHolder { this.parent = parent; } + @Override public Set getInterfaces() { return interfaces; } + @Override public MethodHolder getMethod(MethodDescriptor method) { return methods.get(method); } + @Override public Collection getMethods() { return methods.values(); } @@ -72,10 +76,12 @@ public class ClassHolder extends ElementHolder { method.setOwner(null); } + @Override public FieldHolder getField(String name) { return fields.get(name); } + @Override public Collection getFields() { return fields.values(); } diff --git a/teavm-core/src/main/java/org/teavm/model/ClassReader.java b/teavm-core/src/main/java/org/teavm/model/ClassReader.java new file mode 100644 index 000000000..6854e8a6b --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/model/ClassReader.java @@ -0,0 +1,37 @@ +/* + * Copyright 2014 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; + +import java.util.Collection; +import java.util.Set; + +/** + * + * @author Alexey Andreev + */ +public interface ClassReader extends ElementReader { + String getParent(); + + Set getInterfaces(); + + MethodReader getMethod(MethodDescriptor method); + + Collection getMethods(); + + FieldReader getField(String name); + + Collection getFields(); +} diff --git a/teavm-core/src/main/java/org/teavm/model/ElementHolder.java b/teavm-core/src/main/java/org/teavm/model/ElementHolder.java index 290a186b5..1d53dc47d 100644 --- a/teavm-core/src/main/java/org/teavm/model/ElementHolder.java +++ b/teavm-core/src/main/java/org/teavm/model/ElementHolder.java @@ -21,7 +21,7 @@ import java.util.EnumSet; * * @author Alexey Andreev */ -public abstract class ElementHolder { +public abstract class ElementHolder implements ElementReader { private EnumSet modifiers = EnumSet.noneOf(ElementModifier.class); private AnnotationContainer annotations = new AnnotationContainer(); private AccessLevel level = AccessLevel.PACKAGE_PRIVATE; @@ -31,10 +31,21 @@ public abstract class ElementHolder { this.name = name; } + @Override + public EnumSet readModifiers() { + return modifiers.clone(); + } + + @Override + public boolean hasModifier(ElementModifier modifier) { + return modifiers.contains(modifier); + } + public EnumSet getModifiers() { return modifiers; } + @Override public AccessLevel getLevel() { return level; } @@ -43,6 +54,7 @@ public abstract class ElementHolder { this.level = level; } + @Override public String getName() { return name; } diff --git a/teavm-core/src/main/java/org/teavm/model/ElementReader.java b/teavm-core/src/main/java/org/teavm/model/ElementReader.java new file mode 100644 index 000000000..c2239f95b --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/model/ElementReader.java @@ -0,0 +1,32 @@ +/* + * Copyright 2014 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; + +import java.util.EnumSet; + +/** + * + * @author Alexey Andreev + */ +public interface ElementReader { + AccessLevel getLevel(); + + EnumSet readModifiers(); + + boolean hasModifier(ElementModifier modifier); + + String getName(); +} diff --git a/teavm-core/src/main/java/org/teavm/model/FieldHolder.java b/teavm-core/src/main/java/org/teavm/model/FieldHolder.java index d2c71fbfe..10aef8983 100644 --- a/teavm-core/src/main/java/org/teavm/model/FieldHolder.java +++ b/teavm-core/src/main/java/org/teavm/model/FieldHolder.java @@ -20,7 +20,7 @@ package org.teavm.model; * * @author Alexey Andreev */ -public class FieldHolder extends MemberHolder { +public class FieldHolder extends MemberHolder implements FieldReader { private ValueType type; private Object initialValue; private ClassHolder owner; @@ -29,6 +29,7 @@ public class FieldHolder extends MemberHolder { super(name); } + @Override public ValueType getType() { return type; } @@ -37,6 +38,7 @@ public class FieldHolder extends MemberHolder { this.type = type; } + @Override public Object getInitialValue() { return initialValue; } @@ -45,12 +47,16 @@ public class FieldHolder extends MemberHolder { this.initialValue = initialValue; } - @Override - public ClassHolder getOwner() { + ClassHolder getOwner() { return owner; } void setOwner(ClassHolder owner) { this.owner = owner; } + + @Override + public String getOwnerName() { + return owner != null ? owner.getName() : null; + } } diff --git a/teavm-core/src/main/java/org/teavm/model/FieldReader.java b/teavm-core/src/main/java/org/teavm/model/FieldReader.java new file mode 100644 index 000000000..577df212a --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/model/FieldReader.java @@ -0,0 +1,26 @@ +/* + * Copyright 2014 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; + +/** + * + * @author Alexey Andreev + */ +public interface FieldReader extends MemberReader { + ValueType getType(); + + Object getInitialValue(); +} diff --git a/teavm-core/src/main/java/org/teavm/model/Incoming.java b/teavm-core/src/main/java/org/teavm/model/Incoming.java index d7df07bd4..df2952e32 100644 --- a/teavm-core/src/main/java/org/teavm/model/Incoming.java +++ b/teavm-core/src/main/java/org/teavm/model/Incoming.java @@ -19,11 +19,12 @@ package org.teavm.model; * * @author Alexey Andreev */ -public class Incoming { +public class Incoming implements IncomingReader { private Phi phi; private Variable value; private BasicBlock source; + @Override public Variable getValue() { return value; } @@ -32,6 +33,7 @@ public class Incoming { this.value = value; } + @Override public BasicBlock getSource() { return source; } @@ -40,6 +42,7 @@ public class Incoming { this.source = source; } + @Override public Phi getPhi() { return phi; } diff --git a/teavm-core/src/main/java/org/teavm/model/IncomingReader.java b/teavm-core/src/main/java/org/teavm/model/IncomingReader.java new file mode 100644 index 000000000..1098a532f --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/model/IncomingReader.java @@ -0,0 +1,28 @@ +/* + * Copyright 2014 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; + +/** + * + * @author Alexey Andreev + */ +public interface IncomingReader { + VariableReader getValue(); + + BasicBlockReader getSource(); + + PhiReader getPhi(); +} diff --git a/teavm-core/src/main/java/org/teavm/model/InstructionReadVisitor.java b/teavm-core/src/main/java/org/teavm/model/InstructionReadVisitor.java new file mode 100644 index 000000000..92dd04378 --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/model/InstructionReadVisitor.java @@ -0,0 +1,199 @@ +/* + * Copyright 2014 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; + +import java.util.Collections; +import org.teavm.model.instructions.*; + +/** + * + * @author Alexey Andreev + */ +class InstructionReadVisitor implements InstructionVisitor { + private InstructionReader reader; + + public InstructionReadVisitor(InstructionReader reader) { + this.reader = reader; + } + + @Override + public void visit(EmptyInstruction insn) { + reader.nop(); + } + + @Override + public void visit(ClassConstantInstruction insn) { + reader.classConstant(insn.getReceiver(), insn.getConstant()); + } + + @Override + public void visit(NullConstantInstruction insn) { + reader.nullConstant(insn.getReceiver()); + } + + @Override + public void visit(IntegerConstantInstruction insn) { + reader.integerConstant(insn.getReceiver(), insn.getConstant()); + } + + @Override + public void visit(LongConstantInstruction insn) { + reader.longConstant(insn.getReceiver(), insn.getConstant()); + } + + @Override + public void visit(FloatConstantInstruction insn) { + reader.floatConstant(insn.getReceiver(), insn.getConstant()); + } + + @Override + public void visit(DoubleConstantInstruction insn) { + reader.doubleConstant(insn.getReceiver(), insn.getConstant()); + } + + @Override + public void visit(StringConstantInstruction insn) { + reader.stringConstant(insn.getReceiver(), insn.getConstant()); + } + + @Override + public void visit(BinaryInstruction insn) { + reader.binary(insn.getOperation(), insn.getReceiver(), insn.getFirstOperand(), insn.getSecondOperand(), + insn.getOperandType()); + } + + @Override + public void visit(NegateInstruction insn) { + reader.negate(insn.getReceiver(), insn.getOperand(), insn.getOperandType()); + } + + @Override + public void visit(AssignInstruction insn) { + reader.assign(insn.getReceiver(), insn.getAssignee()); + } + + @Override + public void visit(CastInstruction insn) { + reader.cast(insn.getReceiver(), insn.getValue(), insn.getTargetType()); + } + + @Override + public void visit(CastNumberInstruction insn) { + reader.cast(insn.getReceiver(), insn.getValue(), insn.getSourceType(), insn.getTargetType()); + } + + @Override + public void visit(CastIntegerInstruction insn) { + reader.cast(insn.getReceiver(), insn.getReceiver(), insn.getTargetType(), insn.getDirection()); + } + + @Override + public void visit(BranchingInstruction insn) { + reader.jumpIf(insn.getCondition(), insn.getOperand(), insn.getConsequent(), insn.getAlternative()); + } + + @Override + public void visit(BinaryBranchingInstruction insn) { + reader.jumpIf(insn.getCondition(), insn.getFirstOperand(), insn.getSecondOperand(), insn.getConsequent(), + insn.getAlternative()); + } + + @Override + public void visit(JumpInstruction insn) { + reader.jump(insn.getTarget()); + } + + @Override + public void visit(SwitchInstruction insn) { + reader.choose(insn.getCondition(), Collections.unmodifiableList(insn.getEntries()), insn.getDefaultTarget()); + } + + @Override + public void visit(ExitInstruction insn) { + reader.exit(insn.getValueToReturn()); + } + + @Override + public void visit(RaiseInstruction insn) { + reader.raise(insn.getException()); + } + + @Override + public void visit(ConstructArrayInstruction insn) { + reader.createArray(insn.getReceiver(), insn.getItemType(), insn.getSize()); + } + + @Override + public void visit(ConstructInstruction insn) { + reader.create(insn.getReceiver(), insn.getType()); + } + + @Override + public void visit(ConstructMultiArrayInstruction insn) { + reader.createArray(insn.getReceiver(), insn.getItemType(), Collections.unmodifiableList(insn.getDimensions())); + } + + @Override + public void visit(GetFieldInstruction insn) { + reader.getField(insn.getReceiver(), insn.getInstance(), insn.getField(), insn.getFieldType()); + } + + @Override + public void visit(PutFieldInstruction insn) { + reader.putField(insn.getInstance(), insn.getField(), insn.getValue()); + } + + @Override + public void visit(ArrayLengthInstruction insn) { + reader.arrayLength(insn.getReceiver(), insn.getArray()); + } + + @Override + public void visit(CloneArrayInstruction insn) { + reader.cloneArray(insn.getReceiver(), insn.getArray()); + } + + @Override + public void visit(UnwrapArrayInstruction insn) { + reader.unwrapArray(insn.getReceiver(), insn.getArray(), insn.getElementType()); + } + + @Override + public void visit(GetElementInstruction insn) { + reader.getElement(insn.getReceiver(), insn.getArray(), insn.getIndex()); + } + + @Override + public void visit(PutElementInstruction insn) { + reader.putElement(insn.getArray(), insn.getIndex(), insn.getValue()); + } + + @Override + public void visit(InvokeInstruction insn) { + reader.invoke(insn.getReceiver(), insn.getInstance(), insn.getMethod(), + Collections.unmodifiableList(insn.getArguments()), insn.getType()); + } + + @Override + public void visit(IsInstanceInstruction insn) { + reader.isInstance(insn.getReceiver(), insn.getValue(), insn.getType()); + } + + @Override + public void visit(InitClassInstruction insn) { + reader.initClass(insn.getClassName()); + } +} diff --git a/teavm-core/src/main/java/org/teavm/model/MemberHolder.java b/teavm-core/src/main/java/org/teavm/model/MemberHolder.java index 484ac77f3..b4e9552d3 100644 --- a/teavm-core/src/main/java/org/teavm/model/MemberHolder.java +++ b/teavm-core/src/main/java/org/teavm/model/MemberHolder.java @@ -19,10 +19,11 @@ package org.teavm.model; * * @author Alexey Andreev */ -public abstract class MemberHolder extends ElementHolder { +public abstract class MemberHolder extends ElementHolder implements MemberReader { public MemberHolder(String name) { super(name); } - public abstract ClassHolder getOwner(); + @Override + public abstract String getOwnerName(); } diff --git a/teavm-core/src/main/java/org/teavm/model/MemberReader.java b/teavm-core/src/main/java/org/teavm/model/MemberReader.java new file mode 100644 index 000000000..16b83daf5 --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/model/MemberReader.java @@ -0,0 +1,24 @@ +/* + * Copyright 2014 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; + +/** + * + * @author Alexey Andreev + */ +public interface MemberReader extends ElementReader { + String getOwnerName(); +} diff --git a/teavm-core/src/main/java/org/teavm/model/MethodHolder.java b/teavm-core/src/main/java/org/teavm/model/MethodHolder.java index 433a9694f..345a1314a 100644 --- a/teavm-core/src/main/java/org/teavm/model/MethodHolder.java +++ b/teavm-core/src/main/java/org/teavm/model/MethodHolder.java @@ -19,10 +19,10 @@ package org.teavm.model; * * @author Alexey Andreev */ -public class MethodHolder extends MemberHolder { +public class MethodHolder extends MemberHolder implements MethodReader { private MethodDescriptor descriptor; private ClassHolder owner; - private Program program; + private volatile Program program; public MethodHolder(MethodDescriptor descriptor) { super(descriptor.getName()); @@ -33,28 +33,37 @@ public class MethodHolder extends MemberHolder { this(new MethodDescriptor(name, signature)); } + @Override public ValueType getResultType() { return descriptor.getResultType(); } + @Override public int parameterCount() { return descriptor.parameterCount(); } + @Override public ValueType[] getSignature() { return descriptor.getSignature(); } + @Override public ValueType parameterType(int index) { return descriptor.parameterType(index); } + @Override public ValueType[] getParameterTypes() { return descriptor.getParameterTypes(); } @Override - public ClassHolder getOwner() { + public String getOwnerName() { + return owner != null ? owner.getName() : null; + } + + ClassHolder getOwner() { return owner; } @@ -62,10 +71,17 @@ public class MethodHolder extends MemberHolder { this.owner = owner; } + @Override public MethodDescriptor getDescriptor() { return descriptor; } + @Override + public MethodReference getReference() { + return owner != null ? new MethodReference(owner.getName(), descriptor) : null; + } + + @Override public Program getProgram() { return program; } diff --git a/teavm-core/src/main/java/org/teavm/model/MethodReader.java b/teavm-core/src/main/java/org/teavm/model/MethodReader.java new file mode 100644 index 000000000..152767e27 --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/model/MethodReader.java @@ -0,0 +1,38 @@ +/* + * Copyright 2014 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; + +/** + * + * @author Alexey Andreev + */ +public interface MethodReader extends MemberReader { + ValueType getResultType(); + + int parameterCount(); + + ValueType[] getSignature(); + + ValueType parameterType(int index); + + ValueType[] getParameterTypes(); + + MethodDescriptor getDescriptor(); + + MethodReference getReference(); + + ProgramReader getProgram(); +} diff --git a/teavm-core/src/main/java/org/teavm/model/Phi.java b/teavm-core/src/main/java/org/teavm/model/Phi.java index 744d106fd..00f715882 100644 --- a/teavm-core/src/main/java/org/teavm/model/Phi.java +++ b/teavm-core/src/main/java/org/teavm/model/Phi.java @@ -17,17 +17,19 @@ package org.teavm.model; import java.util.AbstractList; import java.util.ArrayList; +import java.util.Collections; import java.util.List; /** * * @author Alexey Andreev */ -public class Phi { +public class Phi implements PhiReader { private BasicBlock basicBlock; private Variable receiver; private List incomings = new ArrayList<>(); + @Override public BasicBlock getBasicBlock() { return basicBlock; } @@ -36,6 +38,7 @@ public class Phi { this.basicBlock = basicBlock; } + @Override public Variable getReceiver() { return receiver; } @@ -95,4 +98,11 @@ public class Phi { public List getIncomings() { return safeIncomings; } + + private List immutableIncomings = Collections.unmodifiableList(incomings); + + @Override + public List readIncomings() { + return immutableIncomings; + } } diff --git a/teavm-core/src/main/java/org/teavm/model/PhiReader.java b/teavm-core/src/main/java/org/teavm/model/PhiReader.java new file mode 100644 index 000000000..7577a6786 --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/model/PhiReader.java @@ -0,0 +1,30 @@ +/* + * Copyright 2014 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; + +import java.util.List; + +/** + * + * @author Alexey Andreev + */ +public interface PhiReader { + BasicBlockReader getBasicBlock(); + + VariableReader getReceiver(); + + List readIncomings(); +} diff --git a/teavm-core/src/main/java/org/teavm/model/Program.java b/teavm-core/src/main/java/org/teavm/model/Program.java index 57d66b4cb..9c3cab944 100644 --- a/teavm-core/src/main/java/org/teavm/model/Program.java +++ b/teavm-core/src/main/java/org/teavm/model/Program.java @@ -22,7 +22,7 @@ import java.util.List; * * @author Alexey Andreev */ -public class Program { +public class Program implements ProgramReader { private List basicBlocks = new ArrayList<>(); private List variables = new ArrayList<>(); private MethodHolder method; @@ -54,10 +54,12 @@ public class Program { packed = false; } + @Override public int basicBlockCount() { return basicBlocks.size(); } + @Override public BasicBlock basicBlockAt(int index) { return basicBlocks.get(index); } @@ -106,15 +108,22 @@ public class Program { packed = true; } + @Override public int variableCount() { return variables.size(); } + @Override public Variable variableAt(int index) { return variables.get(index); } - public MethodHolder getMethod() { + @Override + public MethodReference getMethodReference() { + return method != null ? method.getReference() : null; + } + + MethodHolder getMethod() { return method; } diff --git a/teavm-core/src/main/java/org/teavm/model/ProgramReader.java b/teavm-core/src/main/java/org/teavm/model/ProgramReader.java new file mode 100644 index 000000000..4193ecbda --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/model/ProgramReader.java @@ -0,0 +1,32 @@ +/* + * Copyright 2014 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; + +/** + * + * @author Alexey Andreev + */ +public interface ProgramReader { + int basicBlockCount(); + + BasicBlockReader basicBlockAt(int index); + + int variableCount(); + + VariableReader variableAt(int index); + + MethodReference getMethodReference(); +} diff --git a/teavm-core/src/main/java/org/teavm/model/Variable.java b/teavm-core/src/main/java/org/teavm/model/Variable.java index b0fb3b27a..ceb63fc01 100644 --- a/teavm-core/src/main/java/org/teavm/model/Variable.java +++ b/teavm-core/src/main/java/org/teavm/model/Variable.java @@ -19,7 +19,7 @@ package org.teavm.model; * * @author Alexey Andreev */ -public class Variable { +public class Variable implements VariableReader { private Program program; private int index; private int register; @@ -28,6 +28,7 @@ public class Variable { this.program = program; } + @Override public int getIndex() { return index; } @@ -36,6 +37,7 @@ public class Variable { this.index = index; } + @Override public Program getProgram() { return program; } @@ -44,6 +46,7 @@ public class Variable { this.program = program; } + @Override public int getRegister() { return register; } diff --git a/teavm-core/src/main/java/org/teavm/model/VariableReader.java b/teavm-core/src/main/java/org/teavm/model/VariableReader.java new file mode 100644 index 000000000..d93ed618e --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/model/VariableReader.java @@ -0,0 +1,28 @@ +/* + * Copyright 2014 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; + +/** + * + * @author Alexey Andreev + */ +public interface VariableReader { + int getIndex(); + + ProgramReader getProgram(); + + int getRegister(); +} diff --git a/teavm-core/src/main/java/org/teavm/model/instructions/InstructionReader.java b/teavm-core/src/main/java/org/teavm/model/instructions/InstructionReader.java new file mode 100644 index 000000000..5df676fed --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/model/instructions/InstructionReader.java @@ -0,0 +1,99 @@ +/* + * Copyright 2014 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.instructions; + +import java.util.List; +import org.teavm.model.*; + +/** + * + * @author Alexey Andreev + */ +public interface InstructionReader { + void nop(); + + void classConstant(VariableReader receiver, ValueType cst); + + void nullConstant(VariableReader receiver); + + void integerConstant(VariableReader receiver, int cst); + + void longConstant(VariableReader receiver, long cst); + + void floatConstant(VariableReader receiver, float cst); + + void doubleConstant(VariableReader receiver, double cst); + + void stringConstant(VariableReader receiver, String cst); + + void binary(BinaryOperation op, VariableReader receiver, VariableReader first, VariableReader second, + NumericOperandType type); + + void negate(VariableReader receiver, VariableReader operand, NumericOperandType type); + + void assign(VariableReader receiver, VariableReader assignee); + + void cast(VariableReader receiver, VariableReader value, ValueType targetType); + + void cast(VariableReader receiver, VariableReader value, NumericOperandType sourceType, + NumericOperandType targetType); + + void cast(VariableReader receiver, VariableReader value, IntegerSubtype type, + CastIntegerDirection targetType); + + void jumpIf(BranchingCondition cond, VariableReader operand, BasicBlockReader consequent, + BasicBlockReader alternative); + + void jumpIf(BinaryBranchingCondition cond, VariableReader first, VariableReader second, + BasicBlockReader consequent, BasicBlockReader alternative); + + void jump(BasicBlockReader target); + + void choose(VariableReader condition, List table, + BasicBlockReader defaultTarget); + + void exit(VariableReader valueToReturn); + + void raise(VariableReader exception); + + void createArray(VariableReader receiver, ValueType itemType, VariableReader size); + + void createArray(VariableReader receiver, ValueType itemType, List dimensions); + + void create(VariableReader receiver, String type); + + void getField(VariableReader receiver, VariableReader instance, FieldReference field, ValueType fieldType); + + void putField(VariableReader instance, FieldReference field, VariableReader value); + + void arrayLength(VariableReader receiver, VariableReader array); + + void cloneArray(VariableReader receiver, VariableReader array); + + void unwrapArray(VariableReader receiver, VariableReader array, ArrayElementType elementType); + + void getElement(VariableReader receiver, VariableReader array, VariableReader index); + + void putElement(VariableReader array, VariableReader index, VariableReader value); + + void invoke(VariableReader receiver, VariableReader instance, MethodReference method, + List arguments, + InvocationType type); + + void isInstance(VariableReader receiver, VariableReader value, ValueType type); + + void initClass(String className); +} diff --git a/teavm-core/src/main/java/org/teavm/model/instructions/SwitchTableEntry.java b/teavm-core/src/main/java/org/teavm/model/instructions/SwitchTableEntry.java index 034ee1a42..c06d379d7 100644 --- a/teavm-core/src/main/java/org/teavm/model/instructions/SwitchTableEntry.java +++ b/teavm-core/src/main/java/org/teavm/model/instructions/SwitchTableEntry.java @@ -21,7 +21,7 @@ import org.teavm.model.BasicBlock; * * @author Alexey Andreev */ -public class SwitchTableEntry { +public class SwitchTableEntry implements SwitchTableEntryReader { private int condition; private BasicBlock target; private SwitchInstruction instruction; @@ -34,6 +34,7 @@ public class SwitchTableEntry { this.instruction = instruction; } + @Override public int getCondition() { return condition; } @@ -42,6 +43,7 @@ public class SwitchTableEntry { this.condition = condition; } + @Override public BasicBlock getTarget() { return target; } diff --git a/teavm-core/src/main/java/org/teavm/model/instructions/SwitchTableEntryReader.java b/teavm-core/src/main/java/org/teavm/model/instructions/SwitchTableEntryReader.java new file mode 100644 index 000000000..4986e85c1 --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/model/instructions/SwitchTableEntryReader.java @@ -0,0 +1,28 @@ +/* + * Copyright 2014 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.instructions; + +import org.teavm.model.BasicBlockReader; + +/** + * + * @author Alexey Andreev + */ +public interface SwitchTableEntryReader { + int getCondition(); + + BasicBlockReader getTarget(); +} diff --git a/teavm-core/src/main/java/org/teavm/model/resource/ClassRefsRenamer.java b/teavm-core/src/main/java/org/teavm/model/resource/ClassRefsRenamer.java index 5f1ffe643..91edf4fcf 100644 --- a/teavm-core/src/main/java/org/teavm/model/resource/ClassRefsRenamer.java +++ b/teavm-core/src/main/java/org/teavm/model/resource/ClassRefsRenamer.java @@ -54,7 +54,7 @@ class ClassRefsRenamer implements InstructionVisitor { renamedCls.addMethod(rename(method)); } for (FieldHolder field : cls.getFields().toArray(new FieldHolder[0])) { - field.getOwner().removeField(field); + cls.removeField(field); renamedCls.addField(field); } rename(cls.getAnnotations(), renamedCls.getAnnotations());