Refactoring of model to allow multithreaded optimization

This commit is contained in:
konsoletyper 2014-01-28 14:13:12 +04:00
parent 619c50729b
commit 0c240f5636
27 changed files with 758 additions and 24 deletions

View File

@ -159,7 +159,7 @@ public class DependencyChecker {
for (int i = 0; i < varCount; ++i) { for (int i = 0; i < varCount; ++i) {
parameterNodes[i] = new DependencyNode(this); parameterNodes[i] = new DependencyNode(this);
if (shouldLog) { if (shouldLog) {
parameterNodes[i].setTag(method.getOwner().getName() + "#" + method.getDescriptor() + ":" + i); parameterNodes[i].setTag(method.getOwnerName() + "#" + method.getDescriptor() + ":" + i);
} }
} }
DependencyNode resultNode; DependencyNode resultNode;
@ -168,7 +168,7 @@ public class DependencyChecker {
} else { } else {
resultNode = new DependencyNode(this); resultNode = new DependencyNode(this);
if (shouldLog) { 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); final MethodGraph graph = new MethodGraph(parameterNodes, paramCount, resultNode, this);

View File

@ -120,7 +120,7 @@ public class Decompiler {
public NativeMethodNode decompileNative(MethodHolder method) { public NativeMethodNode decompileNative(MethodHolder method) {
AnnotationHolder annotHolder = method.getAnnotations().get(GeneratedBy.class.getName()); AnnotationHolder annotHolder = method.getAnnotations().get(GeneratedBy.class.getName());
if (annotHolder == null) { 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"); " is native, but no " + GeneratedBy.class.getName() + " annotation found");
} }
ValueType annotValue = annotHolder.getValues().get("value").getJavaClass(); ValueType annotValue = annotHolder.getValues().get("value").getJavaClass();
@ -131,9 +131,9 @@ public class Decompiler {
generator = (Generator)generatorClass.newInstance(); generator = (Generator)generatorClass.newInstance();
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) { } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
throw new DecompilationException("Error instantiating generator " + generatorClassName + 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())); method.getDescriptor()));
methodNode.getModifiers().addAll(mapModifiers(method.getModifiers())); methodNode.getModifiers().addAll(mapModifiers(method.getModifiers()));
methodNode.setGenerator(generator); methodNode.setGenerator(generator);
@ -193,7 +193,7 @@ public class Decompiler {
} }
SequentialStatement result = new SequentialStatement(); SequentialStatement result = new SequentialStatement();
result.getSequence().addAll(rootStmt.getBody()); 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); RegularMethodNode methodNode = new RegularMethodNode(reference);
methodNode.getModifiers().addAll(mapModifiers(method.getModifiers())); methodNode.getModifiers().addAll(mapModifiers(method.getModifiers()));
methodNode.setBody(result); methodNode.setBody(result);

View File

@ -16,12 +16,13 @@
package org.teavm.model; package org.teavm.model;
import java.util.*; import java.util.*;
import org.teavm.model.instructions.InstructionReader;
/** /**
* *
* @author Alexey Andreev * @author Alexey Andreev
*/ */
public class BasicBlock { public class BasicBlock implements BasicBlockReader {
private Program program; private Program program;
private int index; private int index;
private List<Phi> phis = new ArrayList<>(); private List<Phi> phis = new ArrayList<>();
@ -32,10 +33,12 @@ public class BasicBlock {
this.index = index; this.index = index;
} }
@Override
public Program getProgram() { public Program getProgram() {
return program; return program;
} }
@Override
public int getIndex() { public int getIndex() {
return index; return index;
} }
@ -153,4 +156,29 @@ public class BasicBlock {
public List<Phi> getPhis() { public List<Phi> getPhis() {
return safePhis; return safePhis;
} }
private List<Phi> immutablePhis = Collections.unmodifiableList(phis);
@Override
public List<? extends PhiReader> 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);
}
}
} }

View File

@ -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<? extends PhiReader> readPhis();
int instructionCount();
void readInstruction(int index, InstructionReader reader);
void readAllInstructions(InstructionReader reader);
}

View File

@ -21,7 +21,7 @@ import java.util.*;
* *
* @author Alexey Andreev * @author Alexey Andreev
*/ */
public class ClassHolder extends ElementHolder { public class ClassHolder extends ElementHolder implements ClassReader {
private String parent = Object.class.getName(); private String parent = Object.class.getName();
private Set<String> interfaces = new HashSet<>(); private Set<String> interfaces = new HashSet<>();
private Map<MethodDescriptor, MethodHolder> methods = new HashMap<>(); private Map<MethodDescriptor, MethodHolder> methods = new HashMap<>();
@ -31,6 +31,7 @@ public class ClassHolder extends ElementHolder {
super(name); super(name);
} }
@Override
public String getParent() { public String getParent() {
return parent; return parent;
} }
@ -39,14 +40,17 @@ public class ClassHolder extends ElementHolder {
this.parent = parent; this.parent = parent;
} }
@Override
public Set<String> getInterfaces() { public Set<String> getInterfaces() {
return interfaces; return interfaces;
} }
@Override
public MethodHolder getMethod(MethodDescriptor method) { public MethodHolder getMethod(MethodDescriptor method) {
return methods.get(method); return methods.get(method);
} }
@Override
public Collection<MethodHolder> getMethods() { public Collection<MethodHolder> getMethods() {
return methods.values(); return methods.values();
} }
@ -72,10 +76,12 @@ public class ClassHolder extends ElementHolder {
method.setOwner(null); method.setOwner(null);
} }
@Override
public FieldHolder getField(String name) { public FieldHolder getField(String name) {
return fields.get(name); return fields.get(name);
} }
@Override
public Collection<FieldHolder> getFields() { public Collection<FieldHolder> getFields() {
return fields.values(); return fields.values();
} }

View File

@ -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<String> getInterfaces();
MethodReader getMethod(MethodDescriptor method);
Collection<? extends MethodReader> getMethods();
FieldReader getField(String name);
Collection<? extends FieldReader> getFields();
}

View File

@ -21,7 +21,7 @@ import java.util.EnumSet;
* *
* @author Alexey Andreev * @author Alexey Andreev
*/ */
public abstract class ElementHolder { public abstract class ElementHolder implements ElementReader {
private EnumSet<ElementModifier> modifiers = EnumSet.noneOf(ElementModifier.class); private EnumSet<ElementModifier> modifiers = EnumSet.noneOf(ElementModifier.class);
private AnnotationContainer annotations = new AnnotationContainer(); private AnnotationContainer annotations = new AnnotationContainer();
private AccessLevel level = AccessLevel.PACKAGE_PRIVATE; private AccessLevel level = AccessLevel.PACKAGE_PRIVATE;
@ -31,10 +31,21 @@ public abstract class ElementHolder {
this.name = name; this.name = name;
} }
@Override
public EnumSet<ElementModifier> readModifiers() {
return modifiers.clone();
}
@Override
public boolean hasModifier(ElementModifier modifier) {
return modifiers.contains(modifier);
}
public EnumSet<ElementModifier> getModifiers() { public EnumSet<ElementModifier> getModifiers() {
return modifiers; return modifiers;
} }
@Override
public AccessLevel getLevel() { public AccessLevel getLevel() {
return level; return level;
} }
@ -43,6 +54,7 @@ public abstract class ElementHolder {
this.level = level; this.level = level;
} }
@Override
public String getName() { public String getName() {
return name; return name;
} }

View File

@ -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<ElementModifier> readModifiers();
boolean hasModifier(ElementModifier modifier);
String getName();
}

View File

@ -20,7 +20,7 @@ package org.teavm.model;
* *
* @author Alexey Andreev * @author Alexey Andreev
*/ */
public class FieldHolder extends MemberHolder { public class FieldHolder extends MemberHolder implements FieldReader {
private ValueType type; private ValueType type;
private Object initialValue; private Object initialValue;
private ClassHolder owner; private ClassHolder owner;
@ -29,6 +29,7 @@ public class FieldHolder extends MemberHolder {
super(name); super(name);
} }
@Override
public ValueType getType() { public ValueType getType() {
return type; return type;
} }
@ -37,6 +38,7 @@ public class FieldHolder extends MemberHolder {
this.type = type; this.type = type;
} }
@Override
public Object getInitialValue() { public Object getInitialValue() {
return initialValue; return initialValue;
} }
@ -45,12 +47,16 @@ public class FieldHolder extends MemberHolder {
this.initialValue = initialValue; this.initialValue = initialValue;
} }
@Override ClassHolder getOwner() {
public ClassHolder getOwner() {
return owner; return owner;
} }
void setOwner(ClassHolder owner) { void setOwner(ClassHolder owner) {
this.owner = owner; this.owner = owner;
} }
@Override
public String getOwnerName() {
return owner != null ? owner.getName() : null;
}
} }

View File

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

View File

@ -19,11 +19,12 @@ package org.teavm.model;
* *
* @author Alexey Andreev * @author Alexey Andreev
*/ */
public class Incoming { public class Incoming implements IncomingReader {
private Phi phi; private Phi phi;
private Variable value; private Variable value;
private BasicBlock source; private BasicBlock source;
@Override
public Variable getValue() { public Variable getValue() {
return value; return value;
} }
@ -32,6 +33,7 @@ public class Incoming {
this.value = value; this.value = value;
} }
@Override
public BasicBlock getSource() { public BasicBlock getSource() {
return source; return source;
} }
@ -40,6 +42,7 @@ public class Incoming {
this.source = source; this.source = source;
} }
@Override
public Phi getPhi() { public Phi getPhi() {
return phi; return phi;
} }

View File

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

View File

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

View File

@ -19,10 +19,11 @@ package org.teavm.model;
* *
* @author Alexey Andreev * @author Alexey Andreev
*/ */
public abstract class MemberHolder extends ElementHolder { public abstract class MemberHolder extends ElementHolder implements MemberReader {
public MemberHolder(String name) { public MemberHolder(String name) {
super(name); super(name);
} }
public abstract ClassHolder getOwner(); @Override
public abstract String getOwnerName();
} }

View File

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

View File

@ -19,10 +19,10 @@ package org.teavm.model;
* *
* @author Alexey Andreev * @author Alexey Andreev
*/ */
public class MethodHolder extends MemberHolder { public class MethodHolder extends MemberHolder implements MethodReader {
private MethodDescriptor descriptor; private MethodDescriptor descriptor;
private ClassHolder owner; private ClassHolder owner;
private Program program; private volatile Program program;
public MethodHolder(MethodDescriptor descriptor) { public MethodHolder(MethodDescriptor descriptor) {
super(descriptor.getName()); super(descriptor.getName());
@ -33,28 +33,37 @@ public class MethodHolder extends MemberHolder {
this(new MethodDescriptor(name, signature)); this(new MethodDescriptor(name, signature));
} }
@Override
public ValueType getResultType() { public ValueType getResultType() {
return descriptor.getResultType(); return descriptor.getResultType();
} }
@Override
public int parameterCount() { public int parameterCount() {
return descriptor.parameterCount(); return descriptor.parameterCount();
} }
@Override
public ValueType[] getSignature() { public ValueType[] getSignature() {
return descriptor.getSignature(); return descriptor.getSignature();
} }
@Override
public ValueType parameterType(int index) { public ValueType parameterType(int index) {
return descriptor.parameterType(index); return descriptor.parameterType(index);
} }
@Override
public ValueType[] getParameterTypes() { public ValueType[] getParameterTypes() {
return descriptor.getParameterTypes(); return descriptor.getParameterTypes();
} }
@Override @Override
public ClassHolder getOwner() { public String getOwnerName() {
return owner != null ? owner.getName() : null;
}
ClassHolder getOwner() {
return owner; return owner;
} }
@ -62,10 +71,17 @@ public class MethodHolder extends MemberHolder {
this.owner = owner; this.owner = owner;
} }
@Override
public MethodDescriptor getDescriptor() { public MethodDescriptor getDescriptor() {
return descriptor; return descriptor;
} }
@Override
public MethodReference getReference() {
return owner != null ? new MethodReference(owner.getName(), descriptor) : null;
}
@Override
public Program getProgram() { public Program getProgram() {
return program; return program;
} }

View File

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

View File

@ -17,17 +17,19 @@ package org.teavm.model;
import java.util.AbstractList; import java.util.AbstractList;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
/** /**
* *
* @author Alexey Andreev * @author Alexey Andreev
*/ */
public class Phi { public class Phi implements PhiReader {
private BasicBlock basicBlock; private BasicBlock basicBlock;
private Variable receiver; private Variable receiver;
private List<Incoming> incomings = new ArrayList<>(); private List<Incoming> incomings = new ArrayList<>();
@Override
public BasicBlock getBasicBlock() { public BasicBlock getBasicBlock() {
return basicBlock; return basicBlock;
} }
@ -36,6 +38,7 @@ public class Phi {
this.basicBlock = basicBlock; this.basicBlock = basicBlock;
} }
@Override
public Variable getReceiver() { public Variable getReceiver() {
return receiver; return receiver;
} }
@ -95,4 +98,11 @@ public class Phi {
public List<Incoming> getIncomings() { public List<Incoming> getIncomings() {
return safeIncomings; return safeIncomings;
} }
private List<? extends IncomingReader> immutableIncomings = Collections.unmodifiableList(incomings);
@Override
public List<? extends IncomingReader> readIncomings() {
return immutableIncomings;
}
} }

View File

@ -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<? extends IncomingReader> readIncomings();
}

View File

@ -22,7 +22,7 @@ import java.util.List;
* *
* @author Alexey Andreev * @author Alexey Andreev
*/ */
public class Program { public class Program implements ProgramReader {
private List<BasicBlock> basicBlocks = new ArrayList<>(); private List<BasicBlock> basicBlocks = new ArrayList<>();
private List<Variable> variables = new ArrayList<>(); private List<Variable> variables = new ArrayList<>();
private MethodHolder method; private MethodHolder method;
@ -54,10 +54,12 @@ public class Program {
packed = false; packed = false;
} }
@Override
public int basicBlockCount() { public int basicBlockCount() {
return basicBlocks.size(); return basicBlocks.size();
} }
@Override
public BasicBlock basicBlockAt(int index) { public BasicBlock basicBlockAt(int index) {
return basicBlocks.get(index); return basicBlocks.get(index);
} }
@ -106,15 +108,22 @@ public class Program {
packed = true; packed = true;
} }
@Override
public int variableCount() { public int variableCount() {
return variables.size(); return variables.size();
} }
@Override
public Variable variableAt(int index) { public Variable variableAt(int index) {
return variables.get(index); return variables.get(index);
} }
public MethodHolder getMethod() { @Override
public MethodReference getMethodReference() {
return method != null ? method.getReference() : null;
}
MethodHolder getMethod() {
return method; return method;
} }

View File

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

View File

@ -19,7 +19,7 @@ package org.teavm.model;
* *
* @author Alexey Andreev * @author Alexey Andreev
*/ */
public class Variable { public class Variable implements VariableReader {
private Program program; private Program program;
private int index; private int index;
private int register; private int register;
@ -28,6 +28,7 @@ public class Variable {
this.program = program; this.program = program;
} }
@Override
public int getIndex() { public int getIndex() {
return index; return index;
} }
@ -36,6 +37,7 @@ public class Variable {
this.index = index; this.index = index;
} }
@Override
public Program getProgram() { public Program getProgram() {
return program; return program;
} }
@ -44,6 +46,7 @@ public class Variable {
this.program = program; this.program = program;
} }
@Override
public int getRegister() { public int getRegister() {
return register; return register;
} }

View File

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

View File

@ -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<? extends SwitchTableEntryReader> 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<? extends VariableReader> 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<? extends VariableReader> arguments,
InvocationType type);
void isInstance(VariableReader receiver, VariableReader value, ValueType type);
void initClass(String className);
}

View File

@ -21,7 +21,7 @@ import org.teavm.model.BasicBlock;
* *
* @author Alexey Andreev * @author Alexey Andreev
*/ */
public class SwitchTableEntry { public class SwitchTableEntry implements SwitchTableEntryReader {
private int condition; private int condition;
private BasicBlock target; private BasicBlock target;
private SwitchInstruction instruction; private SwitchInstruction instruction;
@ -34,6 +34,7 @@ public class SwitchTableEntry {
this.instruction = instruction; this.instruction = instruction;
} }
@Override
public int getCondition() { public int getCondition() {
return condition; return condition;
} }
@ -42,6 +43,7 @@ public class SwitchTableEntry {
this.condition = condition; this.condition = condition;
} }
@Override
public BasicBlock getTarget() { public BasicBlock getTarget() {
return target; return target;
} }

View File

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

View File

@ -54,7 +54,7 @@ class ClassRefsRenamer implements InstructionVisitor {
renamedCls.addMethod(rename(method)); renamedCls.addMethod(rename(method));
} }
for (FieldHolder field : cls.getFields().toArray(new FieldHolder[0])) { for (FieldHolder field : cls.getFields().toArray(new FieldHolder[0])) {
field.getOwner().removeField(field); cls.removeField(field);
renamedCls.addField(field); renamedCls.addField(field);
} }
rename(cls.getAnnotations(), renamedCls.getAnnotations()); rename(cls.getAnnotations(), renamedCls.getAnnotations());