mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
Refactoring of array generation
This commit is contained in:
parent
ce56214ed5
commit
ac0df0ca6b
|
@ -39,7 +39,7 @@ public class SystemNativeGenerator implements Generator, DependencyPlugin {
|
||||||
String destPos = context.getParameterName(4);
|
String destPos = context.getParameterName(4);
|
||||||
String length = context.getParameterName(5);
|
String length = context.getParameterName(5);
|
||||||
writer.append("for (var i = 0; i < " + length + "; i = (i + 1) | 0) {").indent().newLine();
|
writer.append("for (var i = 0; i < " + length + "; i = (i + 1) | 0) {").indent().newLine();
|
||||||
writer.append(dest + "[" + srcPos + "++] = " + src + "[" + destPos + "++];").newLine();
|
writer.append(dest + ".data[" + srcPos + "++] = " + src + ".data[" + destPos + "++];").newLine();
|
||||||
writer.outdent().append("}").newLine();
|
writer.outdent().append("}").newLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
package org.teavm.classlib.java.lang;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||||
|
*/
|
||||||
|
public class TArrayStoreException extends TRuntimeException {
|
||||||
|
private static final long serialVersionUID = 3911921304974631232L;
|
||||||
|
|
||||||
|
public TArrayStoreException() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public TArrayStoreException(TString message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,12 +15,12 @@ public final class TSystem extends TObject {
|
||||||
if (src == null || dest == null) {
|
if (src == null || dest == null) {
|
||||||
throw new TNullPointerException(TString.wrap("Either src or dest is null"));
|
throw new TNullPointerException(TString.wrap("Either src or dest is null"));
|
||||||
}
|
}
|
||||||
if (src.getClass0() != dest.getClass0()) {
|
if (src.getClass() != dest.getClass()) {
|
||||||
throw new ArrayStoreException();
|
throw new TArrayStoreException();
|
||||||
}
|
}
|
||||||
if (srcPos < 0 || destPos < 0 || length < 0 || srcPos + length > TArray.getLength(src) ||
|
if (srcPos < 0 || destPos < 0 || length < 0 || srcPos + length > TArray.getLength(src) ||
|
||||||
destPos + length > TArray.getLength(dest)) {
|
destPos + length > TArray.getLength(dest)) {
|
||||||
throw new IndexOutOfBoundsException();
|
throw new TIndexOutOfBoundsException();
|
||||||
}
|
}
|
||||||
doArrayCopy(src, srcPos, dest, destPos, length);
|
doArrayCopy(src, srcPos, dest, destPos, length);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,22 +14,45 @@ public class TThrowable extends RuntimeException {
|
||||||
private TString message;
|
private TString message;
|
||||||
private TThrowable cause;
|
private TThrowable cause;
|
||||||
|
|
||||||
|
@Rename("fakeInit")
|
||||||
public TThrowable() {
|
public TThrowable() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Rename("<init>")
|
||||||
|
private void init() {
|
||||||
fillInStackTrace();
|
fillInStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
public TThrowable(TString message) {
|
@Rename("fakeInit")
|
||||||
|
public TThrowable(@SuppressWarnings("unused") TString message) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Rename("<init>")
|
||||||
|
private void init(TString message) {
|
||||||
fillInStackTrace();
|
fillInStackTrace();
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@Rename("fakeInit")
|
||||||
public TThrowable(TString message, TThrowable cause) {
|
public TThrowable(TString message, TThrowable cause) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Rename("<init>")
|
||||||
|
private void init(TString message, TThrowable cause) {
|
||||||
fillInStackTrace();
|
fillInStackTrace();
|
||||||
this.message = message;
|
this.message = message;
|
||||||
this.cause = cause;
|
this.cause = cause;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@Rename("fakeInit")
|
||||||
public TThrowable(TThrowable cause) {
|
public TThrowable(TThrowable cause) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Rename("<init>")
|
||||||
|
private void init(TThrowable cause) {
|
||||||
|
fillInStackTrace();
|
||||||
this.cause = cause;
|
this.cause = cause;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ public class TArrayNativeGenerator implements Generator, DependencyPlugin {
|
||||||
MethodReference cons = new MethodReference(clsName, new MethodDescriptor("<init>", ValueType.VOID));
|
MethodReference cons = new MethodReference(clsName, new MethodDescriptor("<init>", ValueType.VOID));
|
||||||
writer.append("$rt_throw(").appendClass(clsName).append(".").appendMethod(cons).append("());").newLine();
|
writer.append("$rt_throw(").appendClass(clsName).append(".").appendMethod(cons).append("());").newLine();
|
||||||
writer.outdent().append("}").newLine();
|
writer.outdent().append("}").newLine();
|
||||||
writer.append("return array.length");
|
writer.append("return " + array + ".data.length;").newLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void achieveGetLength(final DependencyChecker checker, MethodReference methodRef) {
|
private void achieveGetLength(final DependencyChecker checker, MethodReference methodRef) {
|
||||||
|
|
|
@ -121,7 +121,7 @@ public class DependencyChecker {
|
||||||
exceptionOccured.set(null);
|
exceptionOccured.set(null);
|
||||||
while (true) {
|
while (true) {
|
||||||
try {
|
try {
|
||||||
if (executor.getActiveCount() == 0 || executor.awaitTermination(1, TimeUnit.SECONDS)) {
|
if (executor.getActiveCount() == 0 || executor.awaitTermination(10, TimeUnit.MILLISECONDS)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
|
@ -197,7 +197,7 @@ public class DependencyChecker {
|
||||||
}
|
}
|
||||||
final MethodGraph graph = new MethodGraph(parameterNodes, paramCount, resultNode, this);
|
final MethodGraph graph = new MethodGraph(parameterNodes, paramCount, resultNode, this);
|
||||||
final MethodHolder currentMethod = method;
|
final MethodHolder currentMethod = method;
|
||||||
executor.submit(new Runnable() {
|
schedule(new Runnable() {
|
||||||
@Override public void run() {
|
@Override public void run() {
|
||||||
DependencyGraphBuilder graphBuilder = new DependencyGraphBuilder(DependencyChecker.this);
|
DependencyGraphBuilder graphBuilder = new DependencyGraphBuilder(DependencyChecker.this);
|
||||||
graphBuilder.buildGraph(currentMethod, graph);
|
graphBuilder.buildGraph(currentMethod, graph);
|
||||||
|
|
|
@ -174,6 +174,13 @@ class DependencyGraphBuilder {
|
||||||
arrayNode.getArrayItemNode().connect(receiverNode);
|
arrayNode.getArrayItemNode().connect(receiverNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(UnwrapArrayInstruction insn) {
|
||||||
|
DependencyNode arrayNode = nodes[insn.getArray().getIndex()];
|
||||||
|
DependencyNode receiverNode = nodes[insn.getReceiver().getIndex()];
|
||||||
|
arrayNode.connect(receiverNode);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(CloneArrayInstruction insn) {
|
public void visit(CloneArrayInstruction insn) {
|
||||||
DependencyNode arrayNode = nodes[insn.getArray().getIndex()];
|
DependencyNode arrayNode = nodes[insn.getArray().getIndex()];
|
||||||
|
|
|
@ -147,6 +147,15 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
|
||||||
resultExpr = Expr.subscript(array, index);
|
resultExpr = Expr.subscript(array, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(UnwrapArrayExpr expr) {
|
||||||
|
expr.getArray().acceptVisitor(this);
|
||||||
|
Expr arrayExpr = resultExpr;
|
||||||
|
UnwrapArrayExpr result = new UnwrapArrayExpr(expr.getElementType());
|
||||||
|
result.setArray(arrayExpr);
|
||||||
|
resultExpr = result;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(InvocationExpr expr) {
|
public void visit(InvocationExpr expr) {
|
||||||
Expr[] args = new Expr[expr.getArguments().size()];
|
Expr[] args = new Expr[expr.getArguments().size()];
|
||||||
|
|
|
@ -63,6 +63,11 @@ class ReadWriteStatsBuilder implements StatementVisitor, ExprVisitor {
|
||||||
expr.getIndex().acceptVisitor(this);
|
expr.getIndex().acceptVisitor(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(UnwrapArrayExpr expr) {
|
||||||
|
expr.getArray().acceptVisitor(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(InvocationExpr expr) {
|
public void visit(InvocationExpr expr) {
|
||||||
for (Expr arg : expr.getArguments()) {
|
for (Expr arg : expr.getArguments()) {
|
||||||
|
|
|
@ -48,6 +48,7 @@ public class Renderer implements ExprVisitor, StatementVisitor {
|
||||||
public void renderRuntime() {
|
public void renderRuntime() {
|
||||||
renderRuntimeCls();
|
renderRuntimeCls();
|
||||||
renderRuntimeString();
|
renderRuntimeString();
|
||||||
|
renderRuntimeObjcls();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void renderRuntimeCls() {
|
private void renderRuntimeCls() {
|
||||||
|
@ -72,14 +73,19 @@ public class Renderer implements ExprVisitor, StatementVisitor {
|
||||||
ValueType.arrayOf(ValueType.CHARACTER), ValueType.VOID));
|
ValueType.arrayOf(ValueType.CHARACTER), ValueType.VOID));
|
||||||
writer.append("$rt_str = function(str) {").indent().newLine();
|
writer.append("$rt_str = function(str) {").indent().newLine();
|
||||||
writer.append("var characters = $rt_createNumericArray($rt_charcls(), str.length);").newLine();
|
writer.append("var characters = $rt_createNumericArray($rt_charcls(), str.length);").newLine();
|
||||||
|
writer.append("var charsBuffer = characters.data;").newLine();
|
||||||
writer.append("for (var i = 0; i < str.length; i = (i + 1) | 0) {").indent().newLine();
|
writer.append("for (var i = 0; i < str.length; i = (i + 1) | 0) {").indent().newLine();
|
||||||
writer.append("characters[i] = str.charCodeAt(i);").newLine();
|
writer.append("charsBuffer[i] = str.charCodeAt(i);").newLine();
|
||||||
writer.outdent().append("}").newLine();
|
writer.outdent().append("}").newLine();
|
||||||
writer.append("return ").appendClass("java.lang.String").append(".")
|
writer.append("return ").appendClass("java.lang.String").append(".")
|
||||||
.appendMethod(stringCons).append("(characters);").newLine();
|
.appendMethod(stringCons).append("(characters);").newLine();
|
||||||
writer.outdent().append("}").newLine();
|
writer.outdent().append("}").newLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void renderRuntimeObjcls() {
|
||||||
|
writer.append("$rt_objcls = function() { return ").appendClass("java.lang.Object").append("; }").newLine();
|
||||||
|
}
|
||||||
|
|
||||||
public void render(ClassNode cls) {
|
public void render(ClassNode cls) {
|
||||||
writer.appendClass(cls.getName()).append(" = function() {").indent().newLine();
|
writer.appendClass(cls.getName()).append(" = function() {").indent().newLine();
|
||||||
for (FieldNode field : cls.getFields()) {
|
for (FieldNode field : cls.getFields()) {
|
||||||
|
@ -375,9 +381,9 @@ public class Renderer implements ExprVisitor, StatementVisitor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(ThrowStatement statement) {
|
public void visit(ThrowStatement statement) {
|
||||||
writer.append("throw ");
|
writer.append("$rt_throw(");
|
||||||
statement.getException().acceptVisitor(this);
|
statement.getException().acceptVisitor(this);
|
||||||
writer.append(";").newLine();
|
writer.append(");").newLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -722,6 +728,12 @@ public class Renderer implements ExprVisitor, StatementVisitor {
|
||||||
writer.append(']');
|
writer.append(']');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(UnwrapArrayExpr expr) {
|
||||||
|
expr.getArray().acceptVisitor(this);
|
||||||
|
writer.append(".data");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(InvocationExpr expr) {
|
public void visit(InvocationExpr expr) {
|
||||||
String className = naming.getNameFor(expr.getMethod().getClassName());
|
String className = naming.getNameFor(expr.getMethod().getClassName());
|
||||||
|
|
|
@ -437,6 +437,13 @@ public class StatementGenerator implements InstructionVisitor {
|
||||||
assign(Expr.unary(UnaryOperation.LENGTH, Expr.var(insn.getArray().getIndex())), insn.getReceiver().getIndex());
|
assign(Expr.unary(UnaryOperation.LENGTH, Expr.var(insn.getArray().getIndex())), insn.getReceiver().getIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(UnwrapArrayInstruction insn) {
|
||||||
|
UnwrapArrayExpr unwrapExpr = new UnwrapArrayExpr(insn.getElementType());
|
||||||
|
unwrapExpr.setArray(Expr.var(insn.getArray().getIndex()));
|
||||||
|
assign(unwrapExpr, insn.getReceiver().getIndex());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(CloneArrayInstruction insn) {
|
public void visit(CloneArrayInstruction insn) {
|
||||||
MethodDescriptor cloneMethodDesc = new MethodDescriptor("clone", ValueType.object("java.lang.Object"));
|
MethodDescriptor cloneMethodDesc = new MethodDescriptor("clone", ValueType.object("java.lang.Object"));
|
||||||
|
|
|
@ -155,6 +155,11 @@ class UnusedVariableEliminator implements ExprVisitor, StatementVisitor {
|
||||||
expr.getIndex().acceptVisitor(this);
|
expr.getIndex().acceptVisitor(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(UnwrapArrayExpr expr) {
|
||||||
|
expr.getArray().acceptVisitor(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(InvocationExpr expr) {
|
public void visit(InvocationExpr expr) {
|
||||||
for (Expr arg : expr.getArguments()) {
|
for (Expr arg : expr.getArguments()) {
|
||||||
|
|
|
@ -32,6 +32,8 @@ public interface ExprVisitor {
|
||||||
|
|
||||||
void visit(SubscriptExpr expr);
|
void visit(SubscriptExpr expr);
|
||||||
|
|
||||||
|
void visit(UnwrapArrayExpr expr);
|
||||||
|
|
||||||
void visit(InvocationExpr expr);
|
void visit(InvocationExpr expr);
|
||||||
|
|
||||||
void visit(QualificationExpr expr);
|
void visit(QualificationExpr expr);
|
||||||
|
|
|
@ -44,6 +44,11 @@ public class RenamingVisitor implements StatementVisitor, ExprVisitor {
|
||||||
expr.getIndex().acceptVisitor(this);
|
expr.getIndex().acceptVisitor(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(UnwrapArrayExpr expr) {
|
||||||
|
expr.getArray().acceptVisitor(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(InvocationExpr expr) {
|
public void visit(InvocationExpr expr) {
|
||||||
for (Expr arg : expr.getArguments()) {
|
for (Expr arg : expr.getArguments()) {
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
package org.teavm.javascript.ast;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import org.teavm.model.instructions.ArrayElementType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||||
|
*/
|
||||||
|
public class UnwrapArrayExpr extends Expr {
|
||||||
|
private ArrayElementType elementType;
|
||||||
|
private Expr array;
|
||||||
|
|
||||||
|
public UnwrapArrayExpr(ArrayElementType elementType) {
|
||||||
|
this.elementType = elementType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayElementType getElementType() {
|
||||||
|
return elementType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Expr getArray() {
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setArray(Expr array) {
|
||||||
|
this.array = array;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void acceptVisitor(ExprVisitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected UnwrapArrayExpr clone(Map<Expr, Expr> cache) {
|
||||||
|
UnwrapArrayExpr copy = (UnwrapArrayExpr)cache.get(this);
|
||||||
|
if (copy == null) {
|
||||||
|
copy = new UnwrapArrayExpr(elementType);
|
||||||
|
copy.array = array != null ? array.clone(cache) : null;
|
||||||
|
cache.put(copy, copy);
|
||||||
|
}
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package org.teavm.model.instructions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||||
|
*/
|
||||||
|
public enum ArrayElementType {
|
||||||
|
CHAR,
|
||||||
|
BYTE,
|
||||||
|
SHORT,
|
||||||
|
INT,
|
||||||
|
LONG,
|
||||||
|
FLOAT,
|
||||||
|
DOUBLE,
|
||||||
|
OBJECT
|
||||||
|
}
|
|
@ -57,6 +57,8 @@ public interface InstructionVisitor {
|
||||||
|
|
||||||
void visit(CloneArrayInstruction insn);
|
void visit(CloneArrayInstruction insn);
|
||||||
|
|
||||||
|
void visit(UnwrapArrayInstruction insn);
|
||||||
|
|
||||||
void visit(GetElementInstruction insn);
|
void visit(GetElementInstruction insn);
|
||||||
|
|
||||||
void visit(PutElementInstruction insn);
|
void visit(PutElementInstruction insn);
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
package org.teavm.model.instructions;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Alexey Andreev
|
|
||||||
*/
|
|
||||||
public enum UnaryInstructionType {
|
|
||||||
NEGATE
|
|
||||||
}
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
package org.teavm.model.instructions;
|
||||||
|
|
||||||
|
import org.teavm.model.Instruction;
|
||||||
|
import org.teavm.model.Variable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||||
|
*/
|
||||||
|
public class UnwrapArrayInstruction extends Instruction {
|
||||||
|
private Variable array;
|
||||||
|
private Variable receiver;
|
||||||
|
private ArrayElementType elementType;
|
||||||
|
|
||||||
|
public UnwrapArrayInstruction(ArrayElementType elementType) {
|
||||||
|
this.elementType = elementType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Variable getArray() {
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setArray(Variable array) {
|
||||||
|
this.array = array;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Variable getReceiver() {
|
||||||
|
return receiver;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReceiver(Variable receiver) {
|
||||||
|
this.receiver = receiver;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayElementType getElementType() {
|
||||||
|
return elementType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void acceptVisitor(InstructionVisitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
|
}
|
|
@ -223,6 +223,10 @@ class ClassRefsRenamer implements InstructionVisitor {
|
||||||
public void visit(PutElementInstruction insn) {
|
public void visit(PutElementInstruction insn) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(UnwrapArrayInstruction insn) {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(InvokeInstruction insn) {
|
public void visit(InvokeInstruction insn) {
|
||||||
String className = classNameMapper.map(insn.getMethod().getClassName());
|
String className = classNameMapper.map(insn.getMethod().getClassName());
|
||||||
|
|
|
@ -124,6 +124,11 @@ public class DefinitionExtractor implements InstructionVisitor {
|
||||||
definedVariables = new Variable[0];
|
definedVariables = new Variable[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(UnwrapArrayInstruction insn) {
|
||||||
|
definedVariables = new Variable[] { insn.getReceiver() };
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(GetElementInstruction insn) {
|
public void visit(GetElementInstruction insn) {
|
||||||
definedVariables = new Variable[] { insn.getReceiver() };
|
definedVariables = new Variable[] { insn.getReceiver() };
|
||||||
|
|
|
@ -307,9 +307,15 @@ public class InstructionStringifier implements InstructionVisitor {
|
||||||
.append(" to ").append(insn.getTargetType());
|
.append(" to ").append(insn.getTargetType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(UnwrapArrayInstruction insn) {
|
||||||
|
sb.append("@").append(insn.getReceiver().getIndex()).append("@").append(" := @")
|
||||||
|
.append(insn.getArray()).append(".data");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(ArrayLengthInstruction insn) {
|
public void visit(ArrayLengthInstruction insn) {
|
||||||
sb.append("@").append(insn.getReceiver().getIndex()).append("@")
|
sb.append("@").append(insn.getReceiver().getIndex()).append(" := @")
|
||||||
.append(insn.getArray().getIndex()).append(".length");
|
.append(insn.getArray().getIndex()).append(".length");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -165,6 +165,11 @@ public class InstructionTransitionExtractor implements InstructionVisitor {
|
||||||
targets = null;
|
targets = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(UnwrapArrayInstruction insn) {
|
||||||
|
targets = null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(CloneArrayInstruction insn) {
|
public void visit(CloneArrayInstruction insn) {
|
||||||
targets = null;
|
targets = null;
|
||||||
|
|
|
@ -698,11 +698,15 @@ public class ProgramParser {
|
||||||
builder.add(insn);
|
builder.add(insn);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadArrayElement(int sz) {
|
private void loadArrayElement(int sz, ArrayElementType type) {
|
||||||
int arrIndex = --currentDepth;
|
int arrIndex = --currentDepth;
|
||||||
int array = --currentDepth;
|
int array = --currentDepth;
|
||||||
int var = currentDepth;
|
int var = currentDepth;
|
||||||
currentDepth += sz;
|
currentDepth += sz;
|
||||||
|
UnwrapArrayInstruction unwrapInsn = new UnwrapArrayInstruction(type);
|
||||||
|
unwrapInsn.setArray(getVariable(array));
|
||||||
|
unwrapInsn.setReceiver(unwrapInsn.getArray());
|
||||||
|
builder.add(unwrapInsn);
|
||||||
GetElementInstruction insn = new GetElementInstruction();
|
GetElementInstruction insn = new GetElementInstruction();
|
||||||
insn.setArray(getVariable(array));
|
insn.setArray(getVariable(array));
|
||||||
insn.setIndex(getVariable(arrIndex));
|
insn.setIndex(getVariable(arrIndex));
|
||||||
|
@ -710,11 +714,15 @@ public class ProgramParser {
|
||||||
builder.add(insn);
|
builder.add(insn);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void storeArrayElement(int sz) {
|
private void storeArrayElement(int sz, ArrayElementType type) {
|
||||||
currentDepth -= sz;
|
currentDepth -= sz;
|
||||||
int value = currentDepth;
|
int value = currentDepth;
|
||||||
int arrIndex = --currentDepth;
|
int arrIndex = --currentDepth;
|
||||||
int array = --currentDepth;
|
int array = --currentDepth;
|
||||||
|
UnwrapArrayInstruction unwrapInsn = new UnwrapArrayInstruction(type);
|
||||||
|
unwrapInsn.setArray(getVariable(array));
|
||||||
|
unwrapInsn.setReceiver(unwrapInsn.getArray());
|
||||||
|
builder.add(unwrapInsn);
|
||||||
PutElementInstruction insn = new PutElementInstruction();
|
PutElementInstruction insn = new PutElementInstruction();
|
||||||
insn.setArray(getVariable(array));
|
insn.setArray(getVariable(array));
|
||||||
insn.setIndex(getVariable(arrIndex));
|
insn.setIndex(getVariable(arrIndex));
|
||||||
|
@ -775,28 +783,52 @@ public class ProgramParser {
|
||||||
pushConstant(2F);
|
pushConstant(2F);
|
||||||
break;
|
break;
|
||||||
case Opcodes.BALOAD:
|
case Opcodes.BALOAD:
|
||||||
|
loadArrayElement(1, ArrayElementType.BYTE);
|
||||||
|
break;
|
||||||
case Opcodes.IALOAD:
|
case Opcodes.IALOAD:
|
||||||
|
loadArrayElement(1, ArrayElementType.INT);
|
||||||
|
break;
|
||||||
case Opcodes.FALOAD:
|
case Opcodes.FALOAD:
|
||||||
|
loadArrayElement(1, ArrayElementType.FLOAT);
|
||||||
|
break;
|
||||||
case Opcodes.SALOAD:
|
case Opcodes.SALOAD:
|
||||||
|
loadArrayElement(1, ArrayElementType.SHORT);
|
||||||
|
break;
|
||||||
case Opcodes.CALOAD:
|
case Opcodes.CALOAD:
|
||||||
|
loadArrayElement(1, ArrayElementType.CHAR);
|
||||||
|
break;
|
||||||
case Opcodes.AALOAD:
|
case Opcodes.AALOAD:
|
||||||
loadArrayElement(1);
|
loadArrayElement(1, ArrayElementType.OBJECT);
|
||||||
break;
|
break;
|
||||||
case Opcodes.DALOAD:
|
case Opcodes.DALOAD:
|
||||||
|
loadArrayElement(2, ArrayElementType.DOUBLE);
|
||||||
|
break;
|
||||||
case Opcodes.LALOAD:
|
case Opcodes.LALOAD:
|
||||||
loadArrayElement(2);
|
loadArrayElement(2, ArrayElementType.LONG);
|
||||||
break;
|
break;
|
||||||
case Opcodes.BASTORE:
|
case Opcodes.BASTORE:
|
||||||
|
storeArrayElement(1, ArrayElementType.BYTE);
|
||||||
|
break;
|
||||||
case Opcodes.IASTORE:
|
case Opcodes.IASTORE:
|
||||||
|
storeArrayElement(1, ArrayElementType.INT);
|
||||||
|
break;
|
||||||
case Opcodes.FASTORE:
|
case Opcodes.FASTORE:
|
||||||
|
storeArrayElement(1, ArrayElementType.FLOAT);
|
||||||
|
break;
|
||||||
case Opcodes.SASTORE:
|
case Opcodes.SASTORE:
|
||||||
|
storeArrayElement(1, ArrayElementType.SHORT);
|
||||||
|
break;
|
||||||
case Opcodes.CASTORE:
|
case Opcodes.CASTORE:
|
||||||
|
storeArrayElement(1, ArrayElementType.CHAR);
|
||||||
|
break;
|
||||||
case Opcodes.AASTORE:
|
case Opcodes.AASTORE:
|
||||||
storeArrayElement(1);
|
storeArrayElement(1, ArrayElementType.OBJECT);
|
||||||
break;
|
break;
|
||||||
case Opcodes.DASTORE:
|
case Opcodes.DASTORE:
|
||||||
|
storeArrayElement(2, ArrayElementType.DOUBLE);
|
||||||
|
break;
|
||||||
case Opcodes.LASTORE:
|
case Opcodes.LASTORE:
|
||||||
storeArrayElement(2);
|
storeArrayElement(2, ArrayElementType.LONG);
|
||||||
break;
|
break;
|
||||||
case Opcodes.POP:
|
case Opcodes.POP:
|
||||||
--currentDepth;
|
--currentDepth;
|
||||||
|
@ -1243,6 +1275,10 @@ public class ProgramParser {
|
||||||
}
|
}
|
||||||
case Opcodes.ARRAYLENGTH: {
|
case Opcodes.ARRAYLENGTH: {
|
||||||
int a = currentDepth - 1;
|
int a = currentDepth - 1;
|
||||||
|
UnwrapArrayInstruction unwrapInsn = new UnwrapArrayInstruction(ArrayElementType.OBJECT);
|
||||||
|
unwrapInsn.setArray(getVariable(a));
|
||||||
|
unwrapInsn.setReceiver(getVariable(a));
|
||||||
|
builder.add(unwrapInsn);
|
||||||
ArrayLengthInstruction insn = new ArrayLengthInstruction();
|
ArrayLengthInstruction insn = new ArrayLengthInstruction();
|
||||||
insn.setArray(getVariable(a));
|
insn.setArray(getVariable(a));
|
||||||
insn.setReceiver(getVariable(a));
|
insn.setReceiver(getVariable(a));
|
||||||
|
|
|
@ -357,6 +357,12 @@ public class SSATransformer {
|
||||||
insn.setReceiver(define(insn.getReceiver()));
|
insn.setReceiver(define(insn.getReceiver()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(UnwrapArrayInstruction insn) {
|
||||||
|
insn.setArray(use(insn.getArray()));
|
||||||
|
insn.setReceiver(define(insn.getReceiver()));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(CloneArrayInstruction insn) {
|
public void visit(CloneArrayInstruction insn) {
|
||||||
insn.setArray(use(insn.getArray()));
|
insn.setArray(use(insn.getArray()));
|
||||||
|
|
|
@ -21,36 +21,37 @@ $rt_isAssignable = function(from, to) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$rt_createArray = function(cls, sz) {
|
$rt_createArray = function(cls, sz) {
|
||||||
var arr = new Array(sz);
|
var data = new Array(sz);
|
||||||
arr.$class = $rt_arraycls(cls);
|
var arr = new ($rt_arraycls(cls))(data);
|
||||||
arr.$id = $rt_lastObjectId++;
|
arr.$id = $rt_nextId();
|
||||||
for (var i = 0; i < sz; i = (i + 1) | 0) {
|
for (var i = 0; i < sz; i = (i + 1) | 0) {
|
||||||
arr[i] = null;
|
arr.data[i] = null;
|
||||||
}
|
}
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
$rt_createNumericArray = function(cls, sz) {
|
$rt_createNumericArray = function(cls, sz) {
|
||||||
var arr = $rt_createArray(cls, sz);
|
var arr = $rt_createArray(cls, sz);
|
||||||
for (var i = 0; i < sz; i = (i + 1) | 0) {
|
for (var i = 0; i < sz; i = (i + 1) | 0) {
|
||||||
arr[i] = 0;
|
arr.data[i] = 0;
|
||||||
}
|
}
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
$rt_createLongArray = function(sz) {
|
$rt_createLongArray = function(sz) {
|
||||||
var arr = $rt.createArray($rt_longcls(), sz);
|
var arr = $rt.createArray($rt_longcls(), sz);
|
||||||
for (var i = 0; i < sz; i = (i + 1) | 0) {
|
for (var i = 0; i < sz; i = (i + 1) | 0) {
|
||||||
arr[i] = Long.ZERO;
|
arr.data[i] = Long.ZERO;
|
||||||
}
|
}
|
||||||
return arr;
|
return arr;
|
||||||
},
|
},
|
||||||
$rt_arraycls = function(cls) {
|
$rt_arraycls = function(cls) {
|
||||||
if (cls.$array == undefined) {
|
if (cls.$array == undefined) {
|
||||||
cls.$array = {
|
var arraycls = function(data) {
|
||||||
$meta : { item : cls },
|
this.data = data;
|
||||||
|
this.$cls = arraycls;
|
||||||
};
|
};
|
||||||
if ($rt.objcls) {
|
arraycls.prototype = new ($rt_objcls())();
|
||||||
cls.$array.$meta.supertypes = [$rt.objcls()];
|
arraycls.$meta = { item : cls, supertypes : [$rt_objcls()] };
|
||||||
}
|
cls.$array = arraycls;
|
||||||
}
|
}
|
||||||
return cls.$array;
|
return cls.$array;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user