Fixes variable mapping

This commit is contained in:
konsoletyper 2014-08-07 12:23:47 +04:00
parent 2b52bbedf8
commit 1b374c7466
31 changed files with 333 additions and 132 deletions

View File

@ -33,8 +33,8 @@ public class JavacSupport implements ClassHolderTransformer {
ValueType.object("javax.tools.JavaCompiler"))); ValueType.object("javax.tools.JavaCompiler")));
Program program = new Program(); Program program = new Program();
BasicBlock block = program.createBasicBlock(); BasicBlock block = program.createBasicBlock();
program.createVariable(null); program.createVariable();
Variable var = program.createVariable(null); Variable var = program.createVariable();
ConstructInstruction construct = new ConstructInstruction(); ConstructInstruction construct = new ConstructInstruction();
construct.setReceiver(var); construct.setReceiver(var);
construct.setType("com.sun.tools.javac.api.JavacTool"); construct.setType("com.sun.tools.javac.api.JavacTool");

View File

@ -54,10 +54,13 @@ public class IntegerArray {
return data[index]; return data[index];
} }
public int[] getRange(int start, int end) {
return Arrays.copyOfRange(data, start, end);
}
public void set(int index, int value) { public void set(int index, int value) {
if (index >= sz) { if (index >= sz) {
throw new IndexOutOfBoundsException("Index " + index + throw new IndexOutOfBoundsException("Index " + index + " is greater than the list size " + sz);
" is greater than the list size " + sz);
} }
data[index] = value; data[index] = value;
} }
@ -90,6 +93,15 @@ public class IntegerArray {
data[sz - 1] = item; data[sz - 1] = item;
} }
public void remove(int index) {
remove(index, 1);
}
public void remove(int index, int count) {
System.arraycopy(data, index + count, data, index, sz - index - count);
sz -= count;
}
public boolean contains(int item) { public boolean contains(int item) {
for (int i = 0; i < sz; ++i) { for (int i = 0; i < sz; ++i) {
if (data[i] == item) { if (data[i] == item) {

View File

@ -44,7 +44,7 @@ public class DebugInformation {
Mapping classMapping; Mapping classMapping;
Mapping methodMapping; Mapping methodMapping;
Mapping lineMapping; Mapping lineMapping;
Mapping[] variableMappings; MultiMapping[] variableMappings;
List<Map<Integer, Integer>> classesMetadata; List<Map<Integer, Integer>> classesMetadata;
public String[] getCoveredSourceFiles() { public String[] getCoveredSourceFiles() {
@ -105,18 +105,18 @@ public class DebugInformation {
return getMethodAt(new GeneratedLocation(line, column)); return getMethodAt(new GeneratedLocation(line, column));
} }
public String getVariableMeaningAt(int line, int column, String variable) { public String[] getVariableMeaningAt(int line, int column, String variable) {
return getVariableMeaningAt(new GeneratedLocation(line, column), variable); return getVariableMeaningAt(new GeneratedLocation(line, column), variable);
} }
public String getVariableMeaningAt(GeneratedLocation location, String variable) { public String[] getVariableMeaningAt(GeneratedLocation location, String variable) {
Integer varIndex = variableNameMap.get(variable); Integer varIndex = variableNameMap.get(variable);
if (varIndex == null) { if (varIndex == null) {
return null; return new String[0];
} }
Mapping mapping = variableMappings[varIndex]; MultiMapping mapping = variableMappings[varIndex];
if (mapping == null) { if (mapping == null) {
return null; return new String[0];
} }
return componentByKey(mapping, variableNames, location); return componentByKey(mapping, variableNames, location);
} }
@ -140,11 +140,30 @@ public class DebugInformation {
return valueIndex >= 0 ? values[valueIndex] : null; return valueIndex >= 0 ? values[valueIndex] : null;
} }
private String[] componentByKey(MultiMapping mapping, String[] values, GeneratedLocation location) {
int keyIndex = indexByKey(mapping, location);
if (keyIndex < 0) {
return new String[0];
}
int start = mapping.offsets[keyIndex];
int end = mapping.offsets[keyIndex + 1];
String[] result = new String[end - start];
for (int i = 0; i < result.length; ++i) {
result[i] = values[mapping.data[i + start]];
}
return result;
}
private int indexByKey(Mapping mapping, GeneratedLocation location) { private int indexByKey(Mapping mapping, GeneratedLocation location) {
int index = Collections.binarySearch(mapping.keyList(), location); int index = Collections.binarySearch(mapping.keyList(), location);
return index >= 0 ? index : -index - 2; return index >= 0 ? index : -index - 2;
} }
private int indexByKey(MultiMapping mapping, GeneratedLocation location) {
int index = Collections.binarySearch(mapping.keyList(), location);
return index >= 0 ? index : -index - 2;
}
public void write(OutputStream output) throws IOException { public void write(OutputStream output) throws IOException {
DebugInformationWriter writer = new DebugInformationWriter(new DataOutputStream(output)); DebugInformationWriter writer = new DebugInformationWriter(new DataOutputStream(output));
writer.write(this); writer.write(this);
@ -308,6 +327,32 @@ public class DebugInformation {
} }
} }
static class MultiMapping {
int[] lines;
int[] columns;
int[] offsets;
int[] data;
public MultiMapping(int[] lines, int[] columns, int[] offsets, int[] data) {
this.lines = lines;
this.columns = columns;
this.offsets = offsets;
this.data = data;
}
public LocationList keyList() {
return new LocationList(lines, columns);
}
public int size() {
return lines.length;
}
public GeneratedLocation key(int index) {
return new GeneratedLocation(lines[index], columns[index]);
}
}
static class LocationList extends AbstractList<GeneratedLocation> { static class LocationList extends AbstractList<GeneratedLocation> {
private int[] lines; private int[] lines;
private int[] columns; private int[] columns;

View File

@ -36,7 +36,7 @@ public class DebugInformationBuilder implements DebugInformationEmitter {
private Mapping lineMapping = new Mapping(); private Mapping lineMapping = new Mapping();
private Mapping classMapping = new Mapping(); private Mapping classMapping = new Mapping();
private Mapping methodMapping = new Mapping(); private Mapping methodMapping = new Mapping();
private Map<Integer, Mapping> variableMappings = new HashMap<>(); private Map<Integer, MultiMapping> variableMappings = new HashMap<>();
private MethodDescriptor currentMethod; private MethodDescriptor currentMethod;
private String currentClass; private String currentClass;
private String currentFileName; private String currentFileName;
@ -88,15 +88,19 @@ public class DebugInformationBuilder implements DebugInformationEmitter {
} }
@Override @Override
public void emitVariable(String sourceName, String generatedName) { public void emitVariable(String[] sourceNames, String generatedName) {
int sourceIndex = variableNames.index(sourceName); int[] sourceIndexes = new int[sourceNames.length];
for (int i = 0; i < sourceIndexes.length; ++i) {
sourceIndexes[i] = variableNames.index(sourceNames[i]);
}
Arrays.sort(sourceIndexes);
int generatedIndex = variableNames.index(generatedName); int generatedIndex = variableNames.index(generatedName);
Mapping mapping = variableMappings.get(generatedIndex); MultiMapping mapping = variableMappings.get(generatedIndex);
if (mapping == null) { if (mapping == null) {
mapping = new Mapping(); mapping = new MultiMapping();
variableMappings.put(generatedIndex, mapping); variableMappings.put(generatedIndex, mapping);
} }
mapping.add(locationProvider, sourceIndex); mapping.add(locationProvider, sourceIndexes);
} }
@Override @Override
@ -130,9 +134,9 @@ public class DebugInformationBuilder implements DebugInformationEmitter {
debugInformation.lineMapping = lineMapping.build(); debugInformation.lineMapping = lineMapping.build();
debugInformation.classMapping = classMapping.build(); debugInformation.classMapping = classMapping.build();
debugInformation.methodMapping = methodMapping.build(); debugInformation.methodMapping = methodMapping.build();
debugInformation.variableMappings = new DebugInformation.Mapping[variableNames.list.size()]; debugInformation.variableMappings = new DebugInformation.MultiMapping[variableNames.list.size()];
for (int var : variableMappings.keySet()) { for (int var : variableMappings.keySet()) {
Mapping mapping = variableMappings.get(var); MultiMapping mapping = variableMappings.get(var);
debugInformation.variableMappings[var] = mapping.build(); debugInformation.variableMappings[var] = mapping.build();
} }
@ -163,6 +167,12 @@ public class DebugInformationBuilder implements DebugInformationEmitter {
int last = lines.size() - 1; int last = lines.size() - 1;
if (lines.get(last) == location.getLine() && columns.get(last) == location.getColumn()) { if (lines.get(last) == location.getLine() && columns.get(last) == location.getColumn()) {
values.set(last, value); values.set(last, value);
// TODO: check why this gives an invalid result
/*if (values.get(last) == values.get(last - 1)) {
values.remove(last);
lines.remove(last);
columns.remove(last);
}*/
return; return;
} }
} }
@ -176,6 +186,78 @@ public class DebugInformationBuilder implements DebugInformationEmitter {
} }
} }
static class MultiMapping {
IntegerArray lines = new IntegerArray(1);
IntegerArray columns = new IntegerArray(1);
IntegerArray offsets = new IntegerArray(1);
IntegerArray data = new IntegerArray(1);
public MultiMapping() {
offsets.add(0);
}
public void add(LocationProvider location, int[] values) {
if (lines.size() > 1) {
int last = lines.size() - 1;
if (lines.get(last) == location.getLine() && columns.get(last) == location.getColumn()) {
addToLast(values);
return;
}
}
lines.add(location.getLine());
columns.add(location.getColumn());
data.addAll(values);
offsets.add(data.size());
}
private void addToLast(int[] values) {
int start = offsets.get(offsets.size() - 2);
int end = offsets.get(offsets.size() - 1);
int[] existing = data.getRange(start, end);
values = merge(existing, values);
if (values.length == existing.length) {
return;
}
data.remove(start, end - start);
data.addAll(values);
offsets.set(offsets.size() - 1, data.size());
}
private int[] merge(int[] a, int[] b) {
int[] result = new int[a.length + b.length];
int i = 0;
int j = 0;
int k = 0;
while (i < a.length && j < b.length) {
int p = a[i];
int q = b[j];
if (p == q) {
result[k++] = p;
++i;
++j;
} else if (p < q) {
result[k++] = p;
++i;
} else {
result[k++] = q;
++j;
}
}
while (i < a.length) {
result[k++] = a[i++];
}
while (j < b.length) {
result[k++] = b[j++];
}
return k < result.length ? Arrays.copyOf(result, k) : result;
}
public DebugInformation.MultiMapping build() {
return new DebugInformation.MultiMapping(lines.getAll(), columns.getAll(), offsets.getAll(),
data.getAll());
}
}
static class MappedList { static class MappedList {
private List<String> list = new ArrayList<>(); private List<String> list = new ArrayList<>();
private Map<String, Integer> map = new HashMap<>(); private Map<String, Integer> map = new HashMap<>();

View File

@ -31,7 +31,7 @@ public interface DebugInformationEmitter {
void emitClass(String className); void emitClass(String className);
void emitVariable(String sourceName, String generatedName); void emitVariable(String[] sourceNames, String generatedName);
void addClass(String className); void addClass(String className);

View File

@ -53,13 +53,13 @@ class DebugInformationReader {
return debugInfo; return debugInfo;
} }
private DebugInformation.Mapping[] readVariableMappings(int count) throws IOException { private DebugInformation.MultiMapping[] readVariableMappings(int count) throws IOException {
DebugInformation.Mapping[] mappings = new DebugInformation.Mapping[count]; DebugInformation.MultiMapping[] mappings = new DebugInformation.MultiMapping[count];
int varCount = readUnsignedNumber(); int varCount = readUnsignedNumber();
int lastVar = 0; int lastVar = 0;
while (varCount-- > 0) { while (varCount-- > 0) {
lastVar += readUnsignedNumber(); lastVar += readUnsignedNumber();
mappings[lastVar] = readMapping(); mappings[lastVar] = readMultiMapping();
} }
return mappings; return mappings;
} }
@ -86,6 +86,32 @@ class DebugInformationReader {
return !negative ? number : -number; return !negative ? number : -number;
} }
private DebugInformation.MultiMapping readMultiMapping() throws IOException {
int[] lines = readRle();
int last = 0;
for (int i = 0; i < lines.length; ++i) {
last += lines[i];
lines[i] = last;
}
int[] columns = new int[lines.length];
resetRelativeNumber();
for (int i = 0; i < columns.length; ++i) {
columns[i] = readRelativeNumber();
}
int[] offsets = new int[lines.length + 1];
int lastOffset = 0;
for (int i = 1; i < offsets.length; ++i) {
lastOffset += readUnsignedNumber();
offsets[i] = lastOffset;
}
int[] data = new int[lastOffset];
resetRelativeNumber();
for (int i = 0; i < data.length; ++i) {
data[i] = readRelativeNumber();
}
return new DebugInformation.MultiMapping(lines, columns, offsets, data);
}
private DebugInformation.Mapping readMapping() throws IOException { private DebugInformation.Mapping readMapping() throws IOException {
int[] lines = readRle(); int[] lines = readRle();
int last = 0; int last = 0;

View File

@ -53,7 +53,7 @@ class DebugInformationWriter {
int lastVar = 0; int lastVar = 0;
writeUnsignedNumber(nonNullVariableMappings(debugInfo)); writeUnsignedNumber(nonNullVariableMappings(debugInfo));
for (int i = 0; i < debugInfo.variableMappings.length; ++i) { for (int i = 0; i < debugInfo.variableMappings.length; ++i) {
DebugInformation.Mapping mapping = debugInfo.variableMappings[i]; DebugInformation.MultiMapping mapping = debugInfo.variableMappings[i];
if (mapping == null) { if (mapping == null) {
continue; continue;
} }
@ -94,6 +94,30 @@ class DebugInformationWriter {
} }
} }
private void writeMapping(DebugInformation.MultiMapping mapping) throws IOException {
int[] lines = mapping.lines.clone();
int last = 0;
for (int i = 0; i < lines.length; ++i) {
int next = lines[i];
lines[i] -= last;
last = next;
}
writeRle(lines);
resetRelativeNumber();
for (int i = 0; i < mapping.columns.length; ++i) {
writeRelativeNumber(mapping.columns[i]);
}
int lastOffset = 0;
for (int i = 1; i < mapping.offsets.length; ++i) {
writeUnsignedNumber(mapping.offsets[i] - lastOffset);
lastOffset = mapping.offsets[i];
}
resetRelativeNumber();
for (int i = 0; i < mapping.data.length; ++i) {
writeRelativeNumber(mapping.data[i]);
}
}
private void writeMapping(DebugInformation.Mapping mapping) throws IOException { private void writeMapping(DebugInformation.Mapping mapping) throws IOException {
int[] lines = mapping.lines.clone(); int[] lines = mapping.lines.clone();
int last = 0; int last = 0;

View File

@ -280,15 +280,15 @@ public class Debugger {
} }
} }
public String mapVariable(String variable, JavaScriptLocation location) { String[] mapVariable(String variable, JavaScriptLocation location) {
DebugInformation debugInfo = debugInformationMap.get(location.getScript()); DebugInformation debugInfo = debugInformationMap.get(location.getScript());
if (debugInfo == null) { if (debugInfo == null) {
return null; return new String[0];
} }
return debugInfo.getVariableMeaningAt(location.getLine(), location.getColumn(), variable); return debugInfo.getVariableMeaningAt(location.getLine(), location.getColumn(), variable);
} }
public String mapField(String className, String jsField) { String mapField(String className, String jsField) {
for (DebugInformation debugInfo : debugInformationMap.values()) { for (DebugInformation debugInfo : debugInformationMap.values()) {
String meaning = debugInfo.getFieldMeaning(className, jsField); String meaning = debugInfo.getFieldMeaning(className, jsField);
if (meaning != null) { if (meaning != null) {

View File

@ -37,7 +37,7 @@ public class DummyDebugInformationEmitter implements DebugInformationEmitter {
} }
@Override @Override
public void emitVariable(String sourceName, String generatedName) { public void emitVariable(String[] sourceName, String generatedName) {
} }
@Override @Override

View File

@ -62,12 +62,11 @@ class VariableMap extends AbstractMap<String, Variable> {
Map<String, Variable> vars = new HashMap<>(); Map<String, Variable> vars = new HashMap<>();
for (Map.Entry<String, JavaScriptVariable> entry : jsVariables.entrySet()) { for (Map.Entry<String, JavaScriptVariable> entry : jsVariables.entrySet()) {
JavaScriptVariable jsVar = entry.getValue(); JavaScriptVariable jsVar = entry.getValue();
String name = debugger.mapVariable(entry.getKey(), location); String[] names = debugger.mapVariable(entry.getKey(), location);
if (name == null) {
continue;
}
Value value = new Value(debugger, jsVar.getValue()); Value value = new Value(debugger, jsVar.getValue());
vars.put(entry.getKey(), new Variable(name, value)); for (String name : names) {
vars.put(name, new Variable(name, value));
}
} }
backingMap.compareAndSet(null, vars); backingMap.compareAndSet(null, vars);
} }

View File

@ -271,7 +271,7 @@ public class Decompiler {
int paramCount = method.getSignature().length; int paramCount = method.getSignature().length;
for (int i = 0; i < paramCount; ++i) { for (int i = 0; i < paramCount; ++i) {
Variable var = program.variableAt(i); Variable var = program.variableAt(i);
methodNode.getParameterDebugNames().add(var.getDebugName()); methodNode.getParameterDebugNames().add(new HashSet<>(var.getDebugNames()));
} }
return methodNode; return methodNode;
} }

View File

@ -49,7 +49,7 @@ public class NullPointerExceptionTransformer implements ClassHolderTransformer {
} }
NullCheckInstruction nullCheck = new NullCheckInstruction(); NullCheckInstruction nullCheck = new NullCheckInstruction();
nullCheck.setValue(invoke.getInstance()); nullCheck.setValue(invoke.getInstance());
Variable var = block.getProgram().createVariable(null); Variable var = block.getProgram().createVariable();
nullCheck.setReceiver(var); nullCheck.setReceiver(var);
invoke.setInstance(var); invoke.setInstance(var);
block.getInstructions().add(i++, nullCheck); block.getInstructions().add(i++, nullCheck);

View File

@ -522,7 +522,8 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
try { try {
MethodReference ref = method.getReference(); MethodReference ref = method.getReference();
for (int i = 0; i < method.getParameterDebugNames().size(); ++i) { for (int i = 0; i < method.getParameterDebugNames().size(); ++i) {
debugEmitter.emitVariable(method.getParameterDebugNames().get(i), variableName(i)); debugEmitter.emitVariable(method.getParameterDebugNames().get(i).toArray(new String[0]),
variableName(i));
} }
int variableCount = 0; int variableCount = 0;
for (int var : method.getVariables()) { for (int var : method.getVariables()) {
@ -609,7 +610,8 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
} }
if (statement.getLeftValue() instanceof VariableExpr) { if (statement.getLeftValue() instanceof VariableExpr) {
VariableExpr receiver = (VariableExpr)statement.getLeftValue(); VariableExpr receiver = (VariableExpr)statement.getLeftValue();
debugEmitter.emitVariable(statement.getDebugName(), variableName(receiver.getIndex())); debugEmitter.emitVariable(statement.getDebugNames().toArray(new String[0]),
variableName(receiver.getIndex()));
} }
} catch (IOException e) { } catch (IOException e) {
throw new RenderingException("IO error occured", e); throw new RenderingException("IO error occured", e);

View File

@ -244,7 +244,7 @@ class StatementGenerator implements InstructionVisitor {
public void visit(AssignInstruction insn) { public void visit(AssignInstruction insn) {
AssignmentStatement stmt = Statement.assign(Expr.var(insn.getReceiver().getIndex()), AssignmentStatement stmt = Statement.assign(Expr.var(insn.getReceiver().getIndex()),
Expr.var(insn.getAssignee().getIndex())); Expr.var(insn.getAssignee().getIndex()));
stmt.setDebugName(insn.getReceiver().getDebugName()); stmt.getDebugNames().addAll(insn.getReceiver().getDebugNames());
stmt.setLocation(currentLocation); stmt.setLocation(currentLocation);
statements.add(stmt); statements.add(stmt);
} }
@ -574,7 +574,7 @@ class StatementGenerator implements InstructionVisitor {
private void assign(Expr source, Variable target) { private void assign(Expr source, Variable target) {
AssignmentStatement stmt = Statement.assign(Expr.var(target.getIndex()), source); AssignmentStatement stmt = Statement.assign(Expr.var(target.getIndex()), source);
stmt.setLocation(currentLocation); stmt.setLocation(currentLocation);
stmt.setDebugName(target.getDebugName()); stmt.getDebugNames().addAll(target.getDebugNames());
statements.add(stmt); statements.add(stmt);
} }

View File

@ -15,6 +15,9 @@
*/ */
package org.teavm.javascript.ast; package org.teavm.javascript.ast;
import java.util.HashSet;
import java.util.Set;
/** /**
* *
* @author Alexey Andreev * @author Alexey Andreev
@ -23,7 +26,7 @@ public class AssignmentStatement extends Statement {
private Expr leftValue; private Expr leftValue;
private Expr rightValue; private Expr rightValue;
private NodeLocation location; private NodeLocation location;
private String debugName; private Set<String> debugNames = new HashSet<>();
public Expr getLeftValue() { public Expr getLeftValue() {
return leftValue; return leftValue;
@ -49,12 +52,8 @@ public class AssignmentStatement extends Statement {
this.location = location; this.location = location;
} }
public String getDebugName() { public Set<String> getDebugNames() {
return debugName; return debugNames;
}
public void setDebugName(String debugName) {
this.debugName = debugName;
} }
@Override @Override

View File

@ -17,6 +17,7 @@ package org.teavm.javascript.ast;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Set;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;
/** /**
@ -26,7 +27,7 @@ import org.teavm.model.MethodReference;
public class RegularMethodNode extends MethodNode { public class RegularMethodNode extends MethodNode {
private Statement body; private Statement body;
private List<Integer> variables = new ArrayList<>(); private List<Integer> variables = new ArrayList<>();
private List<String> parameterDebugNames = new ArrayList<>(); private List<Set<String>> parameterDebugNames = new ArrayList<>();
public RegularMethodNode(MethodReference reference) { public RegularMethodNode(MethodReference reference) {
super(reference); super(reference);
@ -44,7 +45,7 @@ public class RegularMethodNode extends MethodNode {
return variables; return variables;
} }
public List<String> getParameterDebugNames() { public List<Set<String>> getParameterDebugNames() {
return parameterDebugNames; return parameterDebugNames;
} }

View File

@ -35,8 +35,8 @@ public class Program implements ProgramReader {
return block; return block;
} }
public Variable createVariable(String debugName) { public Variable createVariable() {
Variable variable = new Variable(this, debugName); Variable variable = new Variable(this);
variable.setIndex(variables.size()); variable.setIndex(variables.size());
variables.add(variable); variables.add(variable);
variable.setRegister(lastUsedRegister++); variable.setRegister(lastUsedRegister++);

View File

@ -15,6 +15,10 @@
*/ */
package org.teavm.model; package org.teavm.model;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
/** /**
* *
* @author Alexey Andreev * @author Alexey Andreev
@ -23,11 +27,11 @@ public class Variable implements VariableReader {
private Program program; private Program program;
private int index; private int index;
private int register; private int register;
private String debugName; private Set<String> debugNames;
Variable(Program program, String debugName) { Variable(Program program) {
this.program = program; this.program = program;
this.debugName = debugName; this.debugNames = new HashSet<>();
} }
@Override @Override
@ -57,25 +61,12 @@ public class Variable implements VariableReader {
this.register = register; this.register = register;
} }
public Set<String> getDebugNames() {
return debugNames;
}
@Override @Override
public String getDebugName() { public Set<String> readDebugNames() {
return debugName; return Collections.unmodifiableSet(debugNames);
}
public void setDebugName(String debugName) {
this.debugName = debugName;
}
public void mergeDebugName(String otherDebugName) {
if (otherDebugName == null) {
return;
}
String[] parts = debugName != null ? debugName.split("\\|") : new String[0];
for (String part : parts) {
if (otherDebugName.equals(part)) {
return;
}
}
debugName = debugName != null ? debugName + "|" + otherDebugName : otherDebugName;
} }
} }

View File

@ -15,6 +15,8 @@
*/ */
package org.teavm.model; package org.teavm.model;
import java.util.Set;
/** /**
* *
* @author Alexey Andreev * @author Alexey Andreev
@ -24,7 +26,7 @@ public interface VariableReader {
ProgramReader getProgram(); ProgramReader getProgram();
String getDebugName(); Set<String> readDebugNames();
int getRegister(); int getRegister();
} }

View File

@ -29,8 +29,16 @@ public class ListingBuilder {
for (int i = 0; i < program.variableCount(); ++i) { for (int i = 0; i < program.variableCount(); ++i) {
sb.append(prefix).append("var @").append(i); sb.append(prefix).append("var @").append(i);
VariableReader var = program.variableAt(i); VariableReader var = program.variableAt(i);
if (var.getDebugName() != null) { if (!var.readDebugNames().isEmpty()) {
sb.append(" as ").append(var.getDebugName()); sb.append(" as ");
boolean first = true;
for (String debugName : var.readDebugNames()) {
if (!first) {
sb.append(", ");
}
first = false;
sb.append(debugName);
}
} }
sb.append('\n'); sb.append('\n');
} }

View File

@ -73,7 +73,8 @@ public final class ProgramUtils {
InstructionCopyReader insnCopier = new InstructionCopyReader(); InstructionCopyReader insnCopier = new InstructionCopyReader();
insnCopier.programCopy = copy; insnCopier.programCopy = copy;
for (int i = 0; i < program.variableCount(); ++i) { for (int i = 0; i < program.variableCount(); ++i) {
copy.createVariable(program.variableAt(i).getDebugName()); Variable var = copy.createVariable();
var.getDebugNames().addAll(program.variableAt(i).readDebugNames());
} }
for (int i = 0; i < program.basicBlockCount(); ++i) { for (int i = 0; i < program.basicBlockCount(); ++i) {
copy.createBasicBlock(); copy.createBasicBlock();

View File

@ -97,7 +97,7 @@ public class RegisterAllocator {
final Phi phi = incoming.getPhi(); final Phi phi = incoming.getPhi();
Program program = phi.getBasicBlock().getProgram(); Program program = phi.getBasicBlock().getProgram();
AssignInstruction copyInstruction = new AssignInstruction(); AssignInstruction copyInstruction = new AssignInstruction();
Variable firstCopy = program.createVariable(incoming.getValue().getDebugName()); Variable firstCopy = program.createVariable();
copyInstruction.setReceiver(firstCopy); copyInstruction.setReceiver(firstCopy);
copyInstruction.setAssignee(incoming.getValue()); copyInstruction.setAssignee(incoming.getValue());
BasicBlock source = blockMap.get(incoming.getSource()); BasicBlock source = blockMap.get(incoming.getSource());
@ -214,14 +214,14 @@ public class RegisterAllocator {
varMap[tryCatch.getExceptionVariable().getIndex()])); varMap[tryCatch.getExceptionVariable().getIndex()]));
} }
} }
String[] originalNames = new String[program.variableCount()]; String[][] originalNames = new String[program.variableCount()][];
for (int i = 0; i < program.variableCount(); ++i) { for (int i = 0; i < program.variableCount(); ++i) {
Variable var = program.variableAt(i); Variable var = program.variableAt(i);
originalNames[i] = var.getDebugName(); originalNames[i] = var.getDebugNames().toArray(new String[0]);
var.setDebugName(null); var.getDebugNames().clear();
} }
for (int i = 0; i < program.variableCount(); ++i) { for (int i = 0; i < program.variableCount(); ++i) {
program.variableAt(varMap[i]).mergeDebugName(originalNames[i]); program.variableAt(varMap[i]).getDebugNames().addAll(Arrays.asList(originalNames[i]));
} }
} }

View File

@ -114,7 +114,7 @@ public class GlobalValueNumbering implements MethodOptimization {
if (map[i] != i) { if (map[i] != i) {
Variable var = program.variableAt(i); Variable var = program.variableAt(i);
Variable mapVar = program.variableAt(map[i]); Variable mapVar = program.variableAt(map[i]);
mapVar.mergeDebugName(var.getDebugName()); mapVar.getDebugNames().addAll(var.getDebugNames());
program.deleteVariable(i); program.deleteVariable(i);
} }
} }

View File

@ -179,7 +179,7 @@ public class LoopInvariantMotion implements MethodOptimization {
phi.getIncomings().remove(j--); phi.getIncomings().remove(j--);
if (preheaderPhi == null) { if (preheaderPhi == null) {
preheaderPhi = new Phi(); preheaderPhi = new Phi();
preheaderPhi.setReceiver(program.createVariable(null)); preheaderPhi.setReceiver(program.createVariable());
preheader.getPhis().add(preheaderPhi); preheader.getPhis().add(preheaderPhi);
} }
preheaderPhi.getIncomings().add(incoming); preheaderPhi.getIncomings().add(incoming);
@ -391,7 +391,8 @@ public class LoopInvariantMotion implements MethodOptimization {
@Override @Override
public void visit(ClassConstantInstruction insn) { public void visit(ClassConstantInstruction insn) {
var = program.createVariable(insn.getReceiver().getDebugName()); var = program.createVariable();
var.getDebugNames().addAll(insn.getReceiver().getDebugNames());
ClassConstantInstruction copy = new ClassConstantInstruction(); ClassConstantInstruction copy = new ClassConstantInstruction();
copy.setConstant(insn.getConstant()); copy.setConstant(insn.getConstant());
copy.setReceiver(var); copy.setReceiver(var);
@ -400,7 +401,8 @@ public class LoopInvariantMotion implements MethodOptimization {
@Override @Override
public void visit(NullConstantInstruction insn) { public void visit(NullConstantInstruction insn) {
var = program.createVariable(insn.getReceiver().getDebugName()); var = program.createVariable();
var.getDebugNames().addAll(insn.getReceiver().getDebugNames());
NullConstantInstruction copy = new NullConstantInstruction(); NullConstantInstruction copy = new NullConstantInstruction();
copy.setReceiver(var); copy.setReceiver(var);
this.copy = copy; this.copy = copy;
@ -408,7 +410,8 @@ public class LoopInvariantMotion implements MethodOptimization {
@Override @Override
public void visit(IntegerConstantInstruction insn) { public void visit(IntegerConstantInstruction insn) {
var = program.createVariable(insn.getReceiver().getDebugName()); var = program.createVariable();
var.getDebugNames().addAll(insn.getReceiver().getDebugNames());
IntegerConstantInstruction copy = new IntegerConstantInstruction(); IntegerConstantInstruction copy = new IntegerConstantInstruction();
copy.setConstant(insn.getConstant()); copy.setConstant(insn.getConstant());
copy.setReceiver(var); copy.setReceiver(var);
@ -417,7 +420,8 @@ public class LoopInvariantMotion implements MethodOptimization {
@Override @Override
public void visit(LongConstantInstruction insn) { public void visit(LongConstantInstruction insn) {
var = program.createVariable(insn.getReceiver().getDebugName()); var = program.createVariable();
var.getDebugNames().addAll(insn.getReceiver().getDebugNames());
LongConstantInstruction copy = new LongConstantInstruction(); LongConstantInstruction copy = new LongConstantInstruction();
copy.setConstant(insn.getConstant()); copy.setConstant(insn.getConstant());
copy.setReceiver(var); copy.setReceiver(var);
@ -426,7 +430,8 @@ public class LoopInvariantMotion implements MethodOptimization {
@Override @Override
public void visit(FloatConstantInstruction insn) { public void visit(FloatConstantInstruction insn) {
var = program.createVariable(insn.getReceiver().getDebugName()); var = program.createVariable();
var.getDebugNames().addAll(insn.getReceiver().getDebugNames());
FloatConstantInstruction copy = new FloatConstantInstruction(); FloatConstantInstruction copy = new FloatConstantInstruction();
copy.setConstant(insn.getConstant()); copy.setConstant(insn.getConstant());
copy.setReceiver(var); copy.setReceiver(var);
@ -435,7 +440,8 @@ public class LoopInvariantMotion implements MethodOptimization {
@Override @Override
public void visit(DoubleConstantInstruction insn) { public void visit(DoubleConstantInstruction insn) {
var = program.createVariable(insn.getReceiver().getDebugName()); var = program.createVariable();
var.getDebugNames().addAll(insn.getReceiver().getDebugNames());
DoubleConstantInstruction copy = new DoubleConstantInstruction(); DoubleConstantInstruction copy = new DoubleConstantInstruction();
copy.setConstant(insn.getConstant()); copy.setConstant(insn.getConstant());
copy.setReceiver(var); copy.setReceiver(var);
@ -444,7 +450,8 @@ public class LoopInvariantMotion implements MethodOptimization {
@Override @Override
public void visit(StringConstantInstruction insn) { public void visit(StringConstantInstruction insn) {
var = program.createVariable(insn.getReceiver().getDebugName()); var = program.createVariable();
var.getDebugNames().addAll(insn.getReceiver().getDebugNames());
StringConstantInstruction copy = new StringConstantInstruction(); StringConstantInstruction copy = new StringConstantInstruction();
copy.setConstant(insn.getConstant()); copy.setConstant(insn.getConstant());
copy.setReceiver(var); copy.setReceiver(var);

View File

@ -44,7 +44,7 @@ public final class Parser {
method.setProgram(program); method.setProgram(program);
parseAnnotations(method.getAnnotations(), node.visibleAnnotations, node.invisibleAnnotations); parseAnnotations(method.getAnnotations(), node.visibleAnnotations, node.invisibleAnnotations);
while (program.variableCount() <= method.parameterCount()) { while (program.variableCount() <= method.parameterCount()) {
program.createVariable(null); program.createVariable();
} }
return method; return method;
} }

View File

@ -115,7 +115,7 @@ public class ProgramParser implements VariableDebugInformation {
} }
int signatureVars = countSignatureVariables(method.desc); int signatureVars = countSignatureVariables(method.desc);
while (program.variableCount() <= signatureVars) { while (program.variableCount() <= signatureVars) {
program.createVariable(null); program.createVariable();
} }
return program; return program;
} }
@ -334,7 +334,7 @@ public class ProgramParser implements VariableDebugInformation {
private Variable getVariable(int index) { private Variable getVariable(int index) {
while (index >= program.variableCount()) { while (index >= program.variableCount()) {
program.createVariable(null); program.createVariable();
} }
return program.variableAt(index); return program.variableAt(index);
} }

View File

@ -140,17 +140,19 @@ public class SSATransformer {
processed[currentBlock.getIndex()] = true; processed[currentBlock.getIndex()] = true;
variableMap = Arrays.copyOf(task.variables, task.variables.length); variableMap = Arrays.copyOf(task.variables, task.variables.length);
for (Phi phi : currentBlock.getPhis()) { for (Phi phi : currentBlock.getPhis()) {
Variable var = program.createVariable(phi.getReceiver().getDebugName()); Variable var = program.createVariable();
var.getDebugNames().addAll(phi.getReceiver().getDebugNames());
variableMap[phi.getReceiver().getIndex()] = var; variableMap[phi.getReceiver().getIndex()] = var;
phi.setReceiver(var); phi.setReceiver(var);
} }
if (!caughtBlocks.get(currentBlock.getIndex()).isEmpty()) { if (!caughtBlocks.get(currentBlock.getIndex()).isEmpty()) {
Phi phi = new Phi(); Phi phi = new Phi();
phi.setReceiver(program.createVariable(null)); phi.setReceiver(program.createVariable());
for (TryCatchBlock tryCatch : caughtBlocks.get(currentBlock.getIndex())) { for (TryCatchBlock tryCatch : caughtBlocks.get(currentBlock.getIndex())) {
variableMap[tryCatch.getExceptionVariable().getIndex()] = phi.getReceiver(); variableMap[tryCatch.getExceptionVariable().getIndex()] = phi.getReceiver();
tryCatch.setExceptionVariable(program.createVariable( Set<String> debugNames = tryCatch.getExceptionVariable().getDebugNames();
tryCatch.getExceptionVariable().getDebugName())); tryCatch.setExceptionVariable(program.createVariable());
tryCatch.getExceptionVariable().getDebugNames().addAll(debugNames);
Incoming incoming = new Incoming(); Incoming incoming = new Incoming();
incoming.setSource(tryCatch.getProtectedBlock()); incoming.setSource(tryCatch.getProtectedBlock());
incoming.setValue(tryCatch.getExceptionVariable()); incoming.setValue(tryCatch.getExceptionVariable());
@ -182,7 +184,7 @@ public class SSATransformer {
incoming.setSource(currentBlock); incoming.setSource(currentBlock);
incoming.setValue(var); incoming.setValue(var);
phi.getIncomings().add(incoming); phi.getIncomings().add(incoming);
phi.getReceiver().mergeDebugName(var.getDebugName()); phi.getReceiver().getDebugNames().addAll(var.getDebugNames());
} }
} }
} }
@ -219,7 +221,7 @@ public class SSATransformer {
} }
private Variable define(Variable var) { private Variable define(Variable var) {
Variable result = program.createVariable(null); Variable result = program.createVariable();
variableMap[var.getIndex()] = result; variableMap[var.getIndex()] = result;
return result; return result;
} }
@ -231,7 +233,7 @@ public class SSATransformer {
} }
String debugName = variableDebugMap.get(var.getIndex()); String debugName = variableDebugMap.get(var.getIndex());
if (debugName != null) { if (debugName != null) {
mappedVar.setDebugName(debugName); mappedVar.getDebugNames().add(debugName);
} }
return mappedVar; return mappedVar;
} }

View File

@ -5,18 +5,18 @@ Bundle-SymbolicName: teavm-eclipse-plugin;singleton:=true
Bundle-Version: 0.2.0.qualifer Bundle-Version: 0.2.0.qualifer
Bundle-Vendor: Alexey Andreev <konsoletyper@gmail.com> Bundle-Vendor: Alexey Andreev <konsoletyper@gmail.com>
Bundle-RequiredExecutionEnvironment: JavaSE-1.7 Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Require-Bundle: org.eclipse.core.runtime;bundle-version="3.9.0", Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.8.0,4.0)",
org.eclipse.debug.core;bundle-version="3.8.0", org.eclipse.debug.core;bundle-version="[3.7.0,4.0)",
org.eclipse.debug.ui;bundle-version="3.9.0", org.eclipse.debug.ui;bundle-version="[3.8.0,4.0)",
org.eclipse.swt;bundle-version="3.102.0", org.eclipse.swt;bundle-version="[3.8.1,4.0)",
org.eclipse.ui;bundle-version="3.105.0", org.eclipse.ui;bundle-version="[3.7.1,4.0)",
org.eclipse.jdt.debug;bundle-version="3.8.0", org.eclipse.jdt.debug;bundle-version="[3.7.101,4.0.0)",
org.eclipse.jdt.debug.ui;bundle-version="3.6.200", org.eclipse.jdt.debug.ui;bundle-version="[3.6.100,4.0.0)",
org.eclipse.jdt.core;bundle-version="3.9.2", org.eclipse.jdt.core;bundle-version="[3.8.3,4.0.0)",
org.eclipse.jdt.launching;bundle-version="3.7.1", org.eclipse.jdt.launching;bundle-version="[3.6.1,4.0.0)",
org.eclipse.ui.editors;bundle-version="3.8.100", org.eclipse.ui.editors;bundle-version="[3.8.0,4.0.0)",
org.eclipse.ui.ide;bundle-version="3.9.0", org.eclipse.ui.ide;bundle-version="[3.8.2,4.0.0)",
org.eclipse.jdt.ui;bundle-version="3.9.2" org.eclipse.jdt.ui;bundle-version="[3.8.2,4.0.0)"
Bundle-ClassPath: ., Bundle-ClassPath: .,
lib/asm-5.0.1.jar, lib/asm-5.0.1.jar,
lib/asm-commons-5.0.1.jar, lib/asm-commons-5.0.1.jar,

View File

@ -44,13 +44,13 @@ public class JCLHacks implements ClassHolderTransformer {
MethodHolder method = new MethodHolder(desc); MethodHolder method = new MethodHolder(desc);
Program program = new Program(); Program program = new Program();
for (int i = 0; i < desc.parameterCount(); ++i) { for (int i = 0; i < desc.parameterCount(); ++i) {
program.createVariable(null); program.createVariable();
} }
if (!staticMethod) { if (!staticMethod) {
program.createVariable(null); program.createVariable();
} }
program.createVariable(null); program.createVariable();
Variable var = program.createVariable(null); Variable var = program.createVariable();
BasicBlock block = program.createBasicBlock(); BasicBlock block = program.createBasicBlock();
ConstructInstruction cons = new ConstructInstruction(); ConstructInstruction cons = new ConstructInstruction();
cons.setType("java.lang.SecurityException"); cons.setType("java.lang.SecurityException");
@ -75,8 +75,8 @@ public class JCLHacks implements ClassHolderTransformer {
private MethodHolder createThreadSleep() { private MethodHolder createThreadSleep() {
MethodHolder method = new MethodHolder("sleep", ValueType.LONG, ValueType.VOID); MethodHolder method = new MethodHolder("sleep", ValueType.LONG, ValueType.VOID);
Program program = new Program(); Program program = new Program();
program.createVariable(null); program.createVariable();
program.createVariable(null); program.createVariable();
BasicBlock block = program.createBasicBlock(); BasicBlock block = program.createBasicBlock();
ExitInstruction exit = new ExitInstruction(); ExitInstruction exit = new ExitInstruction();
block.getInstructions().add(exit); block.getInstructions().add(exit);

View File

@ -81,7 +81,7 @@ class JavascriptNativeProcessor {
if (isProperGetter(method.getDescriptor())) { if (isProperGetter(method.getDescriptor())) {
String propertyName = method.getName().charAt(0) == 'i' ? cutPrefix(method.getName(), 2) : String propertyName = method.getName().charAt(0) == 'i' ? cutPrefix(method.getName(), 2) :
cutPrefix(method.getName(), 3); cutPrefix(method.getName(), 3);
Variable result = invoke.getReceiver() != null ? program.createVariable(null) : null; Variable result = invoke.getReceiver() != null ? program.createVariable() : null;
addPropertyGet(propertyName, invoke.getInstance(), result); addPropertyGet(propertyName, invoke.getInstance(), result);
if (result != null) { if (result != null) {
result = unwrap(result, method.getResultType()); result = unwrap(result, method.getResultType());
@ -96,7 +96,7 @@ class JavascriptNativeProcessor {
} }
} else if (method.getAnnotations().get(JSIndexer.class.getName()) != null) { } else if (method.getAnnotations().get(JSIndexer.class.getName()) != null) {
if (isProperGetIndexer(method.getDescriptor())) { if (isProperGetIndexer(method.getDescriptor())) {
Variable result = invoke.getReceiver() != null ? program.createVariable(null) : null; Variable result = invoke.getReceiver() != null ? program.createVariable() : null;
addIndexerGet(invoke.getInstance(), wrap(invoke.getArguments().get(0), addIndexerGet(invoke.getInstance(), wrap(invoke.getArguments().get(0),
method.parameterType(0)), result); method.parameterType(0)), result);
if (result != null) { if (result != null) {
@ -143,7 +143,7 @@ class JavascriptNativeProcessor {
"a proper native JavaScript method or constructor declaration"); "a proper native JavaScript method or constructor declaration");
} }
} }
Variable result = invoke.getReceiver() != null ? program.createVariable(null) : null; Variable result = invoke.getReceiver() != null ? program.createVariable() : null;
InvokeInstruction newInvoke = new InvokeInstruction(); InvokeInstruction newInvoke = new InvokeInstruction();
ValueType[] signature = new ValueType[method.parameterCount() + 3]; ValueType[] signature = new ValueType[method.parameterCount() + 3];
Arrays.fill(signature, ValueType.object(JSObject.class.getName())); Arrays.fill(signature, ValueType.object(JSObject.class.getName()));
@ -226,7 +226,7 @@ class JavascriptNativeProcessor {
} }
private Variable addString(String str) { private Variable addString(String str) {
Variable var = program.createVariable(null); Variable var = program.createVariable();
StringConstantInstruction nameInsn = new StringConstantInstruction(); StringConstantInstruction nameInsn = new StringConstantInstruction();
nameInsn.setReceiver(var); nameInsn.setReceiver(var);
nameInsn.setConstant(str); nameInsn.setConstant(str);
@ -261,7 +261,7 @@ class JavascriptNativeProcessor {
} else if (className.equals("java.lang.String")) { } else if (className.equals("java.lang.String")) {
return unwrap(var, "unwrapString", ValueType.object("java.lang.String")); return unwrap(var, "unwrapString", ValueType.object("java.lang.String"));
} else { } else {
Variable result = program.createVariable(null); Variable result = program.createVariable();
CastInstruction castInsn = new CastInstruction(); CastInstruction castInsn = new CastInstruction();
castInsn.setReceiver(result); castInsn.setReceiver(result);
castInsn.setValue(var); castInsn.setValue(var);
@ -274,7 +274,7 @@ class JavascriptNativeProcessor {
} }
private Variable unwrap(Variable var, String methodName, ValueType resultType) { private Variable unwrap(Variable var, String methodName, ValueType resultType) {
Variable result = program.createVariable(null); Variable result = program.createVariable();
InvokeInstruction insn = new InvokeInstruction(); InvokeInstruction insn = new InvokeInstruction();
insn.setMethod(new MethodReference(JS.class.getName(), methodName, ValueType.object(JSObject.class.getName()), insn.setMethod(new MethodReference(JS.class.getName(), methodName, ValueType.object(JSObject.class.getName()),
resultType)); resultType));
@ -301,7 +301,7 @@ class JavascriptNativeProcessor {
throw new RuntimeException("Wrong functor: " + type.getName()); throw new RuntimeException("Wrong functor: " + type.getName());
} }
String name = type.getMethods().iterator().next().getName(); String name = type.getMethods().iterator().next().getName();
Variable functor = program.createVariable(null); Variable functor = program.createVariable();
Variable nameVar = addStringWrap(addString(name)); Variable nameVar = addStringWrap(addString(name));
InvokeInstruction insn = new InvokeInstruction(); InvokeInstruction insn = new InvokeInstruction();
insn.setMethod(new MethodReference(JS.class.getName(), "function", insn.setMethod(new MethodReference(JS.class.getName(), "function",
@ -321,7 +321,7 @@ class JavascriptNativeProcessor {
return var; return var;
} }
} }
Variable result = program.createVariable(null); Variable result = program.createVariable();
InvokeInstruction insn = new InvokeInstruction(); InvokeInstruction insn = new InvokeInstruction();
insn.setMethod(new MethodReference(JS.class.getName(), "wrap", type, insn.setMethod(new MethodReference(JS.class.getName(), "wrap", type,
ValueType.object(JSObject.class.getName()))); ValueType.object(JSObject.class.getName())));

View File

@ -131,7 +131,7 @@ class ResourceProgramTransformer {
} else if (type instanceof ValueType.Object) { } else if (type instanceof ValueType.Object) {
switch (((ValueType.Object)type).getClassName()) { switch (((ValueType.Object)type).getClassName()) {
case "java.lang.String": { case "java.lang.String": {
Variable resultVar = insn.getProgram().createVariable(null); Variable resultVar = insn.getProgram().createVariable();
getProperty(insn, property, instructions, resultVar); getProperty(insn, property, instructions, resultVar);
InvokeInstruction castInvoke = new InvokeInstruction(); InvokeInstruction castInvoke = new InvokeInstruction();
castInvoke.setType(InvocationType.SPECIAL); castInvoke.setType(InvocationType.SPECIAL);
@ -143,7 +143,7 @@ class ResourceProgramTransformer {
return instructions; return instructions;
} }
default: { default: {
Variable resultVar = insn.getProgram().createVariable(null); Variable resultVar = insn.getProgram().createVariable();
getProperty(insn, property, instructions, resultVar); getProperty(insn, property, instructions, resultVar);
CastInstruction castInsn = new CastInstruction(); CastInstruction castInsn = new CastInstruction();
castInsn.setReceiver(insn.getReceiver()); castInsn.setReceiver(insn.getReceiver());
@ -159,7 +159,7 @@ class ResourceProgramTransformer {
private void getProperty(InvokeInstruction insn, String property, List<Instruction> instructions, private void getProperty(InvokeInstruction insn, String property, List<Instruction> instructions,
Variable resultVar) { Variable resultVar) {
Variable nameVar = program.createVariable(null); Variable nameVar = program.createVariable();
StringConstantInstruction nameInsn = new StringConstantInstruction(); StringConstantInstruction nameInsn = new StringConstantInstruction();
nameInsn.setConstant(property); nameInsn.setConstant(property);
nameInsn.setReceiver(nameVar); nameInsn.setReceiver(nameVar);
@ -176,7 +176,7 @@ class ResourceProgramTransformer {
private void getAndCastProperty(InvokeInstruction insn, String property, List<Instruction> instructions, private void getAndCastProperty(InvokeInstruction insn, String property, List<Instruction> instructions,
Class<?> primitive) { Class<?> primitive) {
Variable resultVar = program.createVariable(null); Variable resultVar = program.createVariable();
getProperty(insn, property, instructions, resultVar); getProperty(insn, property, instructions, resultVar);
InvokeInstruction castInvoke = new InvokeInstruction(); InvokeInstruction castInvoke = new InvokeInstruction();
castInvoke.setType(InvocationType.SPECIAL); castInvoke.setType(InvocationType.SPECIAL);
@ -220,7 +220,7 @@ class ResourceProgramTransformer {
} else if (type instanceof ValueType.Object) { } else if (type instanceof ValueType.Object) {
switch (((ValueType.Object)type).getClassName()) { switch (((ValueType.Object)type).getClassName()) {
case "java.lang.String": { case "java.lang.String": {
Variable castVar = insn.getProgram().createVariable(null); Variable castVar = insn.getProgram().createVariable();
InvokeInstruction castInvoke = new InvokeInstruction(); InvokeInstruction castInvoke = new InvokeInstruction();
castInvoke.setType(InvocationType.SPECIAL); castInvoke.setType(InvocationType.SPECIAL);
castInvoke.setMethod(new MethodReference(ResourceAccessor.class, "castFromString", castInvoke.setMethod(new MethodReference(ResourceAccessor.class, "castFromString",
@ -242,7 +242,7 @@ class ResourceProgramTransformer {
private void setProperty(InvokeInstruction insn, String property, List<Instruction> instructions, private void setProperty(InvokeInstruction insn, String property, List<Instruction> instructions,
Variable valueVar) { Variable valueVar) {
Variable nameVar = program.createVariable(null); Variable nameVar = program.createVariable();
StringConstantInstruction nameInsn = new StringConstantInstruction(); StringConstantInstruction nameInsn = new StringConstantInstruction();
nameInsn.setConstant(property); nameInsn.setConstant(property);
nameInsn.setReceiver(nameVar); nameInsn.setReceiver(nameVar);
@ -259,7 +259,7 @@ class ResourceProgramTransformer {
private void castAndSetProperty(InvokeInstruction insn, String property, List<Instruction> instructions, private void castAndSetProperty(InvokeInstruction insn, String property, List<Instruction> instructions,
Class<?> primitive) { Class<?> primitive) {
Variable castVar = program.createVariable(null); Variable castVar = program.createVariable();
InvokeInstruction castInvoke = new InvokeInstruction(); InvokeInstruction castInvoke = new InvokeInstruction();
castInvoke.setType(InvocationType.SPECIAL); castInvoke.setType(InvocationType.SPECIAL);
String primitiveCapitalized = primitive.getName(); String primitiveCapitalized = primitive.getName();