Replace ArrayList with array to store arguments of InvokeInstruction

This commit is contained in:
Alexey Andreev 2019-01-09 12:51:52 +03:00
parent f589b0035a
commit 9305a532bb
25 changed files with 151 additions and 104 deletions

View File

@ -531,7 +531,7 @@ public class JavaScriptTarget implements TeaVMTarget, TeaVMJavaScriptHost {
initExceptionInsn.setInstance(exceptionVar); initExceptionInsn.setInstance(exceptionVar);
initExceptionInsn.setMethod(new MethodReference(NoSuchMethodError.class, "<init>", String.class, void.class)); initExceptionInsn.setMethod(new MethodReference(NoSuchMethodError.class, "<init>", String.class, void.class));
initExceptionInsn.setType(InvocationType.SPECIAL); initExceptionInsn.setType(InvocationType.SPECIAL);
initExceptionInsn.getArguments().add(constVar); initExceptionInsn.setArguments(constVar);
block.add(initExceptionInsn); block.add(initExceptionInsn);
RaiseInstruction raiseInsn = new RaiseInstruction(); RaiseInstruction raiseInsn = new RaiseInstruction();

View File

@ -1039,9 +1039,11 @@ public class ProgramIO {
MethodDescriptor methodDesc = parseMethodDescriptor(symbolTable.at(input.readInt())); MethodDescriptor methodDesc = parseMethodDescriptor(symbolTable.at(input.readInt()));
insn.setMethod(createMethodReference(className, methodDesc)); insn.setMethod(createMethodReference(className, methodDesc));
int paramCount = insn.getMethod().getDescriptor().parameterCount(); int paramCount = insn.getMethod().getDescriptor().parameterCount();
Variable[] arguments = new Variable[paramCount];
for (int i = 0; i < paramCount; ++i) { for (int i = 0; i < paramCount; ++i) {
insn.getArguments().add(program.variableAt(input.readShort())); arguments[i] = program.variableAt(input.readShort());
} }
insn.setArguments(arguments);
return insn; return insn;
} }
case 34: { case 34: {
@ -1054,9 +1056,11 @@ public class ProgramIO {
MethodDescriptor methodDesc = parseMethodDescriptor(symbolTable.at(input.readInt())); MethodDescriptor methodDesc = parseMethodDescriptor(symbolTable.at(input.readInt()));
insn.setMethod(createMethodReference(className, methodDesc)); insn.setMethod(createMethodReference(className, methodDesc));
int paramCount = insn.getMethod().getDescriptor().parameterCount(); int paramCount = insn.getMethod().getDescriptor().parameterCount();
Variable[] arguments = new Variable[paramCount];
for (int i = 0; i < paramCount; ++i) { for (int i = 0; i < paramCount; ++i) {
insn.getArguments().add(program.variableAt(input.readShort())); arguments[i] = program.variableAt(input.readShort());
} }
insn.setArguments(arguments);
return insn; return insn;
} }
case 35: { case 35: {
@ -1069,9 +1073,11 @@ public class ProgramIO {
MethodDescriptor methodDesc = parseMethodDescriptor(symbolTable.at(input.readInt())); MethodDescriptor methodDesc = parseMethodDescriptor(symbolTable.at(input.readInt()));
insn.setMethod(createMethodReference(className, methodDesc)); insn.setMethod(createMethodReference(className, methodDesc));
int paramCount = insn.getMethod().getDescriptor().parameterCount(); int paramCount = insn.getMethod().getDescriptor().parameterCount();
Variable[] arguments = new Variable[paramCount];
for (int i = 0; i < paramCount; ++i) { for (int i = 0; i < paramCount; ++i) {
insn.getArguments().add(program.variableAt(input.readShort())); arguments[i] = program.variableAt(input.readShort());
} }
insn.setArguments(arguments);
return insn; return insn;
} }
case 36: { case 36: {

View File

@ -179,8 +179,7 @@ public class InstructionReadVisitor implements InstructionVisitor {
@Override @Override
public void visit(InvokeInstruction insn) { public void visit(InvokeInstruction insn) {
reader.invoke(insn.getReceiver(), insn.getInstance(), insn.getMethod(), reader.invoke(insn.getReceiver(), insn.getInstance(), insn.getMethod(), insn.getArguments(), insn.getType());
Collections.unmodifiableList(insn.getArguments()), insn.getType());
} }
@Override @Override

View File

@ -236,9 +236,12 @@ public final class ProgramEmitter {
insn.setType(InvocationType.SPECIAL); insn.setType(InvocationType.SPECIAL);
insn.setMethod(method); insn.setMethod(method);
insn.setReceiver(result); insn.setReceiver(result);
for (ValueEmitter arg : arguments) { Variable[] insnArguments = new Variable[arguments.length];
insn.getArguments().add(arg.variable); for (int i = 0; i < insnArguments.length; ++i) {
insnArguments[i] = arguments[i].variable;
} }
insn.setArguments(insnArguments);
addInstruction(insn); addInstruction(insn);
return result != null ? var(result, method.getReturnType()) : null; return result != null ? var(result, method.getReturnType()) : null;
} }
@ -260,9 +263,11 @@ public final class ProgramEmitter {
insn.setType(InvocationType.SPECIAL); insn.setType(InvocationType.SPECIAL);
insn.setMethod(method); insn.setMethod(method);
insn.setReceiver(result); insn.setReceiver(result);
for (ValueEmitter arg : arguments) { Variable[] insnArguments = new Variable[arguments.length];
insn.getArguments().add(arg.variable); for (int i = 0; i < insnArguments.length; ++i) {
insnArguments[i] = arguments[i].variable;
} }
insn.setArguments(insnArguments);
addInstruction(insn); addInstruction(insn);
return result != null ? var(result, resultType) : null; return result != null ? var(result, resultType) : null;
} }

View File

@ -445,9 +445,11 @@ public class ValueEmitter {
insn.setMethod(method); insn.setMethod(method);
insn.setInstance(variable); insn.setInstance(variable);
insn.setReceiver(result); insn.setReceiver(result);
for (ValueEmitter arg : arguments) { Variable[] insnArguments = new Variable[arguments.length];
insn.getArguments().add(arg.variable); for (int i = 0; i < insnArguments.length; ++i) {
insnArguments[i] = arguments[i].variable;
} }
insn.setArguments(insnArguments);
pe.addInstruction(insn); pe.addInstruction(insn);
return result != null ? pe.var(result, method.getReturnType()) : null; return result != null ? pe.var(result, method.getReturnType()) : null;
} }
@ -474,9 +476,11 @@ public class ValueEmitter {
insn.setMethod(method); insn.setMethod(method);
insn.setInstance(variable); insn.setInstance(variable);
insn.setReceiver(result); insn.setReceiver(result);
for (ValueEmitter arg : arguments) { Variable[] insnArguments = new Variable[arguments.length];
insn.getArguments().add(arg.variable); for (int i = 0; i < insnArguments.length; ++i) {
insnArguments[i] = arguments[i].variable;
} }
insn.setArguments(insnArguments);
pe.addInstruction(insn); pe.addInstruction(insn);
return result != null ? pe.var(result, resultType) : null; return result != null ? pe.var(result, resultType) : null;
} }

View File

@ -15,8 +15,10 @@
*/ */
package org.teavm.model.instructions; package org.teavm.model.instructions;
import java.util.AbstractList;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.function.UnaryOperator;
import org.teavm.model.Instruction; import org.teavm.model.Instruction;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;
import org.teavm.model.Variable; import org.teavm.model.Variable;
@ -25,7 +27,7 @@ public class InvokeInstruction extends Instruction {
private InvocationType type; private InvocationType type;
private MethodReference method; private MethodReference method;
private Variable instance; private Variable instance;
private List<Variable> arguments = new ArrayList<>(1); private Variable[] arguments;
private Variable receiver; private Variable receiver;
public InvocationType getType() { public InvocationType getType() {
@ -44,8 +46,20 @@ public class InvokeInstruction extends Instruction {
this.instance = instance; this.instance = instance;
} }
public List<Variable> getArguments() { public List<? extends Variable> getArguments() {
return arguments; return argumentList;
}
public void replaceArguments(UnaryOperator<Variable> f) {
if (arguments != null) {
for (int i = 0; i < arguments.length; ++i) {
arguments[i] = f.apply(arguments[i]);
}
}
}
public void setArguments(Variable... arguments) {
this.arguments = arguments.length > 0 ? arguments.clone() : null;
} }
public MethodReference getMethod() { public MethodReference getMethod() {
@ -68,4 +82,19 @@ public class InvokeInstruction extends Instruction {
public void acceptVisitor(InstructionVisitor visitor) { public void acceptVisitor(InstructionVisitor visitor) {
visitor.visit(this); visitor.visit(this);
} }
private List<? extends Variable> argumentList = new AbstractList<Variable>() {
@Override
public Variable get(int index) {
if (arguments == null) {
throw new IndexOutOfBoundsException();
}
return arguments[index];
}
@Override
public int size() {
return arguments != null ? arguments.length : 0;
}
};
} }

View File

@ -95,7 +95,7 @@ public class ClassInitializerTransformer {
InvokeInstruction checkInitialized = new InvokeInstruction(); InvokeInstruction checkInitialized = new InvokeInstruction();
checkInitialized.setType(InvocationType.SPECIAL); checkInitialized.setType(InvocationType.SPECIAL);
checkInitialized.setMethod(new MethodReference(Allocator.class, "isInitialized", Class.class, boolean.class)); checkInitialized.setMethod(new MethodReference(Allocator.class, "isInitialized", Class.class, boolean.class));
checkInitialized.getArguments().add(clsVariable); checkInitialized.setArguments(clsVariable);
checkInitialized.setReceiver(initializedVariable); checkInitialized.setReceiver(initializedVariable);
block.add(checkInitialized); block.add(checkInitialized);

View File

@ -185,7 +185,7 @@ public class ExceptionHandlingShadowStackContributor {
raise.setMethod(new MethodReference(ExceptionHandling.class, "throwException", Throwable.class, raise.setMethod(new MethodReference(ExceptionHandling.class, "throwException", Throwable.class,
void.class)); void.class));
raise.setType(InvocationType.SPECIAL); raise.setType(InvocationType.SPECIAL);
raise.getArguments().add(((RaiseInstruction) insn).getException()); raise.setArguments(((RaiseInstruction) insn).getException());
raise.setLocation(insn.getLocation()); raise.setLocation(insn.getLocation());
insn.replace(raise); insn.replace(raise);
insn = raise; insn = raise;
@ -300,7 +300,7 @@ public class ExceptionHandlingShadowStackContributor {
InvokeInstruction registerInsn = new InvokeInstruction(); InvokeInstruction registerInsn = new InvokeInstruction();
registerInsn.setMethod(new MethodReference(ShadowStack.class, "registerCallSite", int.class, void.class)); registerInsn.setMethod(new MethodReference(ShadowStack.class, "registerCallSite", int.class, void.class));
registerInsn.setType(InvocationType.SPECIAL); registerInsn.setType(InvocationType.SPECIAL);
registerInsn.getArguments().add(idVariable); registerInsn.setArguments(idVariable);
instructions.add(registerInsn); instructions.add(registerInsn);
return instructions; return instructions;

View File

@ -374,18 +374,20 @@ public class GCShadowStackContributor {
slotConstant.setLocation(callInstruction.getLocation()); slotConstant.setLocation(callInstruction.getLocation());
instructionsToAdd.add(slotConstant); instructionsToAdd.add(slotConstant);
List<Variable> arguments = new ArrayList<>();
InvokeInstruction registerInvocation = new InvokeInstruction(); InvokeInstruction registerInvocation = new InvokeInstruction();
registerInvocation.setLocation(callInstruction.getLocation()); registerInvocation.setLocation(callInstruction.getLocation());
registerInvocation.setType(InvocationType.SPECIAL); registerInvocation.setType(InvocationType.SPECIAL);
registerInvocation.getArguments().add(slotVar); arguments.add(slotVar);
if (var >= 0) { if (var >= 0) {
registerInvocation.setMethod(new MethodReference(ShadowStack.class, "registerGCRoot", int.class, registerInvocation.setMethod(new MethodReference(ShadowStack.class, "registerGCRoot", int.class,
Object.class, void.class)); Object.class, void.class));
registerInvocation.getArguments().add(program.variableAt(var)); arguments.add(program.variableAt(var));
} else { } else {
registerInvocation.setMethod(new MethodReference(ShadowStack.class, "removeGCRoot", int.class, registerInvocation.setMethod(new MethodReference(ShadowStack.class, "removeGCRoot", int.class,
void.class)); void.class));
} }
registerInvocation.setArguments(arguments.toArray(new Variable[0]));
instructionsToAdd.add(registerInvocation); instructionsToAdd.add(registerInvocation);
} }

View File

@ -74,7 +74,7 @@ public class ShadowStackTransformer {
InvokeInstruction invocation = new InvokeInstruction(); InvokeInstruction invocation = new InvokeInstruction();
invocation.setType(InvocationType.SPECIAL); invocation.setType(InvocationType.SPECIAL);
invocation.setMethod(new MethodReference(ShadowStack.class, "allocStack", int.class, void.class)); invocation.setMethod(new MethodReference(ShadowStack.class, "allocStack", int.class, void.class));
invocation.getArguments().add(sizeVariable); invocation.setArguments(sizeVariable);
instructionsToAdd.add(invocation); instructionsToAdd.add(invocation);
block.addFirstAll(instructionsToAdd); block.addFirstAll(instructionsToAdd);
@ -139,7 +139,7 @@ public class ShadowStackTransformer {
InvokeInstruction invocation = new InvokeInstruction(); InvokeInstruction invocation = new InvokeInstruction();
invocation.setType(InvocationType.SPECIAL); invocation.setType(InvocationType.SPECIAL);
invocation.setMethod(new MethodReference(ShadowStack.class, "releaseStack", int.class, void.class)); invocation.setMethod(new MethodReference(ShadowStack.class, "releaseStack", int.class, void.class));
invocation.getArguments().add(sizeVariable); invocation.setArguments(sizeVariable);
instructionsToAdd.add(invocation); instructionsToAdd.add(invocation);
exitBlock.getLastInstruction().insertPreviousAll(instructionsToAdd); exitBlock.getLastInstruction().insertPreviousAll(instructionsToAdd);

View File

@ -727,7 +727,7 @@ public class GlobalValueNumbering implements MethodOptimization {
int instance = map[insn.getInstance().getIndex()]; int instance = map[insn.getInstance().getIndex()];
insn.setInstance(program.variableAt(instance)); insn.setInstance(program.variableAt(instance));
} }
insn.getArguments().replaceAll(mapper); insn.replaceArguments(mapper);
} }
@Override @Override

View File

@ -713,9 +713,9 @@ public class ListingParser {
lexer.getIndex()); lexer.getIndex());
} }
insn.setInstance(arguments.get(0)); insn.setInstance(arguments.get(0));
insn.getArguments().addAll(arguments.subList(1, arguments.size())); insn.setArguments(arguments.subList(1, arguments.size()).toArray(new Variable[0]));
} else { } else {
insn.getArguments().addAll(arguments); insn.setArguments(arguments.toArray(new Variable[0]));
} }
addInstruction(insn); addInstruction(insn);

View File

@ -411,9 +411,11 @@ public class InstructionCopyReader implements InstructionReader {
insnCopy.setType(type); insnCopy.setType(type);
insnCopy.setInstance(instance != null ? copyVar(instance) : null); insnCopy.setInstance(instance != null ? copyVar(instance) : null);
insnCopy.setReceiver(receiver != null ? copyVar(receiver) : null); insnCopy.setReceiver(receiver != null ? copyVar(receiver) : null);
for (VariableReader arg : arguments) { Variable[] argsCopy = new Variable[arguments.size()];
insnCopy.getArguments().add(copyVar(arg)); for (int i = 0; i < argsCopy.length; ++i) {
argsCopy[i] = copyVar(arguments.get(i));
} }
insnCopy.setArguments(argsCopy);
copy = insnCopy; copy = insnCopy;
copy.setLocation(location); copy.setLocation(location);
} }

View File

@ -267,9 +267,7 @@ public class InstructionVariableMapper extends AbstractInstructionVisitor {
if (insn.getInstance() != null) { if (insn.getInstance() != null) {
insn.setInstance(map(insn.getInstance())); insn.setInstance(map(insn.getInstance()));
} }
for (int i = 0; i < insn.getArguments().size(); ++i) { insn.replaceArguments(this::map);
insn.getArguments().set(i, map(insn.getArguments().get(i)));
}
} }
@Override @Override

View File

@ -117,7 +117,7 @@ public class MissingItemsProcessor {
initExceptionInsn.setMethod(new MethodReference(exceptionName, "<init>", ValueType.object("java.lang.String"), initExceptionInsn.setMethod(new MethodReference(exceptionName, "<init>", ValueType.object("java.lang.String"),
ValueType.VOID)); ValueType.VOID));
initExceptionInsn.setType(InvocationType.SPECIAL); initExceptionInsn.setType(InvocationType.SPECIAL);
initExceptionInsn.getArguments().add(constVar); initExceptionInsn.setArguments(constVar);
initExceptionInsn.setLocation(location); initExceptionInsn.setLocation(location);
instructionsToAdd.add(initExceptionInsn); instructionsToAdd.add(initExceptionInsn);

View File

@ -686,10 +686,7 @@ public class PhiUpdater {
@Override @Override
public void visit(InvokeInstruction insn) { public void visit(InvokeInstruction insn) {
List<Variable> args = insn.getArguments(); insn.replaceArguments(v -> use(v));
for (int i = 0; i < args.size(); ++i) {
args.set(i, use(args.get(i)));
}
if (insn.getInstance() != null) { if (insn.getInstance() != null) {
insn.setInstance(use(insn.getInstance())); insn.setInstance(use(insn.getInstance()));
} }

View File

@ -657,7 +657,7 @@ public class ProgramParser {
if (result >= 0) { if (result >= 0) {
insn.setReceiver(getVariable(result)); insn.setReceiver(getVariable(result));
} }
insn.getArguments().addAll(Arrays.asList(args)); insn.setArguments(args);
addInstruction(insn); addInstruction(insn);
} else { } else {
InvokeInstruction insn = new InvokeInstruction(); InvokeInstruction insn = new InvokeInstruction();
@ -671,7 +671,7 @@ public class ProgramParser {
insn.setReceiver(getVariable(result)); insn.setReceiver(getVariable(result));
} }
insn.setInstance(getVariable(instance)); insn.setInstance(getVariable(instance));
insn.getArguments().addAll(Arrays.asList(args)); insn.setArguments(args);
addInstruction(insn); addInstruction(insn);
} }
break; break;

View File

@ -329,7 +329,12 @@ class JSClassProcessor {
if (method.getProgram() != null && method.getProgram().basicBlockCount() > 0) { if (method.getProgram() != null && method.getProgram().basicBlockCount() > 0) {
invoke.setMethod(new MethodReference(method.getOwnerName(), method.getName() + "$static", invoke.setMethod(new MethodReference(method.getOwnerName(), method.getName() + "$static",
getStaticSignature(method.getReference()))); getStaticSignature(method.getReference())));
invoke.getArguments().add(0, invoke.getInstance()); Variable[] newArguments = new Variable[invoke.getArguments().size() + 1];
newArguments[0] = invoke.getInstance();
for (int i = 0; i < invoke.getArguments().size(); ++i) {
newArguments[i + 1] = invoke.getArguments().get(i);
}
invoke.setArguments(newArguments);
invoke.setInstance(null); invoke.setInstance(null);
} }
invoke.setType(InvocationType.SPECIAL); invoke.setType(InvocationType.SPECIAL);
@ -369,16 +374,18 @@ class JSClassProcessor {
newInvoke.setType(InvocationType.SPECIAL); newInvoke.setType(InvocationType.SPECIAL);
newInvoke.setReceiver(result); newInvoke.setReceiver(result);
newInvoke.setLocation(invoke.getLocation()); newInvoke.setLocation(invoke.getLocation());
List<Variable> newArgs = new ArrayList<>();
if (invoke.getInstance() != null) { if (invoke.getInstance() != null) {
Variable arg = marshaller.wrapArgument(callLocation, invoke.getInstance(), Variable arg = marshaller.wrapArgument(callLocation, invoke.getInstance(),
ValueType.object(method.getOwnerName()), false); ValueType.object(method.getOwnerName()), false);
newInvoke.getArguments().add(arg); newArgs.add(arg);
} }
for (int i = 0; i < invoke.getArguments().size(); ++i) { for (int i = 0; i < invoke.getArguments().size(); ++i) {
Variable arg = marshaller.wrapArgument(callLocation, invoke.getArguments().get(i), Variable arg = marshaller.wrapArgument(callLocation, invoke.getArguments().get(i),
method.parameterType(i), byRefParams[i]); method.parameterType(i), byRefParams[i]);
newInvoke.getArguments().add(arg); newArgs.add(arg);
} }
newInvoke.setArguments(newArgs.toArray(new Variable[0]));
replacement.add(newInvoke); replacement.add(newInvoke);
if (result != null) { if (result != null) {
result = marshaller.unwrapReturnValue(callLocation, result, method.getResultType()); result = marshaller.unwrapReturnValue(callLocation, result, method.getResultType());
@ -501,15 +508,17 @@ class JSClassProcessor {
newInvoke.setMethod(JSMethods.invoke(method.parameterCount())); newInvoke.setMethod(JSMethods.invoke(method.parameterCount()));
newInvoke.setType(InvocationType.SPECIAL); newInvoke.setType(InvocationType.SPECIAL);
newInvoke.setReceiver(result); newInvoke.setReceiver(result);
newInvoke.getArguments().add(invoke.getInstance()); List<Variable> newArguments = new ArrayList<>();
newInvoke.getArguments().add(marshaller.addStringWrap(marshaller.addString(name, invoke.getLocation()), newArguments.add(invoke.getInstance());
newArguments.add(marshaller.addStringWrap(marshaller.addString(name, invoke.getLocation()),
invoke.getLocation())); invoke.getLocation()));
newInvoke.setLocation(invoke.getLocation()); newInvoke.setLocation(invoke.getLocation());
for (int i = 0; i < invoke.getArguments().size(); ++i) { for (int i = 0; i < invoke.getArguments().size(); ++i) {
Variable arg = marshaller.wrapArgument(callLocation, invoke.getArguments().get(i), Variable arg = marshaller.wrapArgument(callLocation, invoke.getArguments().get(i),
method.parameterType(i), byRefParams[i]); method.parameterType(i), byRefParams[i]);
newInvoke.getArguments().add(arg); newArguments.add(arg);
} }
newInvoke.setArguments(newArguments.toArray(new Variable[0]));
replacement.add(newInvoke); replacement.add(newInvoke);
if (result != null) { if (result != null) {
result = marshaller.unwrapReturnValue(callLocation, result, method.getResultType()); result = marshaller.unwrapReturnValue(callLocation, result, method.getResultType());
@ -661,10 +670,12 @@ class JSClassProcessor {
insn.setInstance(marshaller.unwrapReturnValue(location, program.variableAt(paramIndex++), insn.setInstance(marshaller.unwrapReturnValue(location, program.variableAt(paramIndex++),
ValueType.object(calleeRef.getClassName()))); ValueType.object(calleeRef.getClassName())));
} }
Variable[] args = new Variable[callee.parameterCount()];
for (int i = 0; i < callee.parameterCount(); ++i) { for (int i = 0; i < callee.parameterCount(); ++i) {
insn.getArguments().add(marshaller.unwrapReturnValue(location, program.variableAt(paramIndex++), args[i] = marshaller.unwrapReturnValue(location, program.variableAt(paramIndex++),
callee.parameterType(i))); callee.parameterType(i));
} }
insn.setArguments(args);
if (callee.getResultType() != ValueType.VOID) { if (callee.getResultType() != ValueType.VOID) {
insn.setReceiver(program.createVariable()); insn.setReceiver(program.createVariable());
} }
@ -691,8 +702,7 @@ class JSClassProcessor {
insn.setType(InvocationType.SPECIAL); insn.setType(InvocationType.SPECIAL);
insn.setMethod(JSMethods.GET); insn.setMethod(JSMethods.GET);
insn.setReceiver(receiver); insn.setReceiver(receiver);
insn.getArguments().add(instance); insn.setArguments(instance, nameVar);
insn.getArguments().add(nameVar);
insn.setLocation(location); insn.setLocation(location);
replacement.add(insn); replacement.add(insn);
} }
@ -702,9 +712,7 @@ class JSClassProcessor {
InvokeInstruction insn = new InvokeInstruction(); InvokeInstruction insn = new InvokeInstruction();
insn.setType(InvocationType.SPECIAL); insn.setType(InvocationType.SPECIAL);
insn.setMethod(JSMethods.SET); insn.setMethod(JSMethods.SET);
insn.getArguments().add(instance); insn.setArguments(instance, nameVar, value);
insn.getArguments().add(nameVar);
insn.getArguments().add(value);
insn.setLocation(location); insn.setLocation(location);
replacement.add(insn); replacement.add(insn);
} }
@ -714,8 +722,7 @@ class JSClassProcessor {
insn.setType(InvocationType.SPECIAL); insn.setType(InvocationType.SPECIAL);
insn.setMethod(JSMethods.GET); insn.setMethod(JSMethods.GET);
insn.setReceiver(receiver); insn.setReceiver(receiver);
insn.getArguments().add(array); insn.setArguments(array, index);
insn.getArguments().add(index);
insn.setLocation(location); insn.setLocation(location);
replacement.add(insn); replacement.add(insn);
} }
@ -724,9 +731,7 @@ class JSClassProcessor {
InvokeInstruction insn = new InvokeInstruction(); InvokeInstruction insn = new InvokeInstruction();
insn.setType(InvocationType.SPECIAL); insn.setType(InvocationType.SPECIAL);
insn.setMethod(JSMethods.SET); insn.setMethod(JSMethods.SET);
insn.getArguments().add(array); insn.setArguments(array, index, value);
insn.getArguments().add(index);
insn.getArguments().add(value);
insn.setLocation(location); insn.setLocation(location);
replacement.add(insn); replacement.add(insn);
} }

View File

@ -125,15 +125,14 @@ class JSObjectClassTransformer implements ClassHolderTransformer {
JSValueMarshaller marshaller = new JSValueMarshaller(diagnostics, typeHelper, hierarchy.getClassSource(), JSValueMarshaller marshaller = new JSValueMarshaller(diagnostics, typeHelper, hierarchy.getClassSource(),
program, marshallInstructions); program, marshallInstructions);
List<Variable> variablesToPass = new ArrayList<>(); Variable[] variablesToPass = new Variable[method.parameterCount()];
for (int i = 0; i < method.parameterCount(); ++i) { for (int i = 0; i < method.parameterCount(); ++i) {
variablesToPass.add(program.createVariable()); variablesToPass[i] = program.createVariable();
} }
for (int i = 0; i < method.parameterCount(); ++i) { for (int i = 0; i < method.parameterCount(); ++i) {
Variable var = marshaller.unwrapReturnValue(callLocation, variablesToPass.get(i), variablesToPass[i] = marshaller.unwrapReturnValue(callLocation, variablesToPass[i],
method.parameterType(i)); method.parameterType(i));
variablesToPass.set(i, var);
} }
basicBlock.addAll(marshallInstructions); basicBlock.addAll(marshallInstructions);
@ -143,7 +142,7 @@ class JSObjectClassTransformer implements ClassHolderTransformer {
invocation.setType(InvocationType.VIRTUAL); invocation.setType(InvocationType.VIRTUAL);
invocation.setInstance(program.variableAt(0)); invocation.setInstance(program.variableAt(0));
invocation.setMethod(methodRef); invocation.setMethod(methodRef);
invocation.getArguments().addAll(variablesToPass); invocation.setArguments(variablesToPass);
basicBlock.add(invocation); basicBlock.add(invocation);
ExitInstruction exit = new ExitInstruction(); ExitInstruction exit = new ExitInstruction();

View File

@ -15,6 +15,7 @@
*/ */
package org.teavm.jso.impl; package org.teavm.jso.impl;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.function.Function; import java.util.function.Function;
import org.teavm.diagnostics.Diagnostics; import org.teavm.diagnostics.Diagnostics;
@ -90,8 +91,7 @@ class JSValueMarshaller {
insn.setType(InvocationType.SPECIAL); insn.setType(InvocationType.SPECIAL);
insn.setMethod(JSMethods.FUNCTION); insn.setMethod(JSMethods.FUNCTION);
insn.setReceiver(functor); insn.setReceiver(functor);
insn.getArguments().add(var); insn.setArguments(var, nameVar);
insn.getArguments().add(nameVar);
insn.setLocation(location.getSourceLocation()); insn.setLocation(location.getSourceLocation());
replacement.add(insn); replacement.add(insn);
return functor; return functor;
@ -103,7 +103,7 @@ class JSValueMarshaller {
insn.setMethod(JSMethods.ARRAY_DATA); insn.setMethod(JSMethods.ARRAY_DATA);
insn.setReceiver(program.createVariable()); insn.setReceiver(program.createVariable());
insn.setType(InvocationType.SPECIAL); insn.setType(InvocationType.SPECIAL);
insn.getArguments().add(var); insn.setArguments(var);
replacement.add(insn); replacement.add(insn);
return insn.getReceiver(); return insn.getReceiver();
} }
@ -127,7 +127,7 @@ class JSValueMarshaller {
InvokeInstruction insn = new InvokeInstruction(); InvokeInstruction insn = new InvokeInstruction();
insn.setMethod(referenceCache.getCached(new MethodReference(JS.class.getName(), "wrap", insn.setMethod(referenceCache.getCached(new MethodReference(JS.class.getName(), "wrap",
getWrappedType(type), getWrapperType(type)))); getWrappedType(type), getWrapperType(type))));
insn.getArguments().add(var); insn.setArguments(var);
insn.setReceiver(result); insn.setReceiver(result);
insn.setType(InvocationType.SPECIAL); insn.setType(InvocationType.SPECIAL);
insn.setLocation(location); insn.setLocation(location);
@ -145,7 +145,7 @@ class JSValueMarshaller {
while (--degree > 1) { while (--degree > 1) {
insn = new InvokeInstruction(); insn = new InvokeInstruction();
insn.setMethod(JSMethods.ARRAY_MAPPER); insn.setMethod(JSMethods.ARRAY_MAPPER);
insn.getArguments().add(function); insn.setArguments(function);
function = program.createVariable(); function = program.createVariable();
insn.setReceiver(function); insn.setReceiver(function);
insn.setType(InvocationType.SPECIAL); insn.setType(InvocationType.SPECIAL);
@ -156,8 +156,7 @@ class JSValueMarshaller {
insn = new InvokeInstruction(); insn = new InvokeInstruction();
insn.setMethod(referenceCache.getCached(new MethodReference(JS.class.getName(), "map", insn.setMethod(referenceCache.getCached(new MethodReference(JS.class.getName(), "map",
getWrappedType(type), ValueType.parse(Function.class), getWrapperType(type)))); getWrappedType(type), ValueType.parse(Function.class), getWrapperType(type))));
insn.getArguments().add(var); insn.setArguments(var, function);
insn.getArguments().add(function);
insn.setReceiver(result); insn.setReceiver(result);
insn.setType(InvocationType.SPECIAL); insn.setType(InvocationType.SPECIAL);
insn.setLocation(location); insn.setLocation(location);
@ -309,6 +308,7 @@ class JSValueMarshaller {
InvokeInstruction insn = new InvokeInstruction(); InvokeInstruction insn = new InvokeInstruction();
insn.setMethod(singleDimensionArrayUnwrapper(type)); insn.setMethod(singleDimensionArrayUnwrapper(type));
insn.setType(InvocationType.SPECIAL); insn.setType(InvocationType.SPECIAL);
List<Variable> args = new ArrayList<>();
if (insn.getMethod().parameterCount() == 2) { if (insn.getMethod().parameterCount() == 2) {
Variable cls = program.createVariable(); Variable cls = program.createVariable();
@ -317,10 +317,11 @@ class JSValueMarshaller {
clsInsn.setLocation(location.getSourceLocation()); clsInsn.setLocation(location.getSourceLocation());
clsInsn.setReceiver(cls); clsInsn.setReceiver(cls);
replacement.add(clsInsn); replacement.add(clsInsn);
insn.getArguments().add(cls); args.add(cls);
} }
insn.getArguments().add(var); args.add(var);
insn.setArguments(args.toArray(new Variable[0]));
insn.setReceiver(result); insn.setReceiver(result);
replacement.add(insn); replacement.add(insn);
return result; return result;
@ -340,7 +341,7 @@ class JSValueMarshaller {
clsInsn.setLocation(location.getSourceLocation()); clsInsn.setLocation(location.getSourceLocation());
clsInsn.setReceiver(cls); clsInsn.setReceiver(cls);
replacement.add(clsInsn); replacement.add(clsInsn);
insn.getArguments().add(cls); insn.setArguments(cls);
} }
insn.setReceiver(function); insn.setReceiver(function);
@ -359,8 +360,7 @@ class JSValueMarshaller {
insn = new InvokeInstruction(); insn = new InvokeInstruction();
insn.setMethod(JSMethods.ARRAY_UNMAPPER); insn.setMethod(JSMethods.ARRAY_UNMAPPER);
insn.setType(InvocationType.SPECIAL); insn.setType(InvocationType.SPECIAL);
insn.getArguments().add(cls); insn.setArguments(cls, function);
insn.getArguments().add(function);
function = program.createVariable(); function = program.createVariable();
insn.setReceiver(function); insn.setReceiver(function);
replacement.add(insn); replacement.add(insn);
@ -375,9 +375,7 @@ class JSValueMarshaller {
insn = new InvokeInstruction(); insn = new InvokeInstruction();
insn.setMethod(JSMethods.UNMAP_ARRAY); insn.setMethod(JSMethods.UNMAP_ARRAY);
insn.getArguments().add(cls); insn.setArguments(cls, var, function);
insn.getArguments().add(var);
insn.getArguments().add(function);
insn.setReceiver(var); insn.setReceiver(var);
insn.setType(InvocationType.SPECIAL); insn.setType(InvocationType.SPECIAL);
insn.setLocation(location.getSourceLocation()); insn.setLocation(location.getSourceLocation());
@ -454,7 +452,7 @@ class JSValueMarshaller {
InvokeInstruction insn = new InvokeInstruction(); InvokeInstruction insn = new InvokeInstruction();
insn.setMethod(referenceCache.getCached(referenceCache.getCached(new MethodReference( insn.setMethod(referenceCache.getCached(referenceCache.getCached(new MethodReference(
JS.class.getName(), methodName, argType, resultType)))); JS.class.getName(), methodName, argType, resultType))));
insn.getArguments().add(var); insn.setArguments(var);
insn.setReceiver(result); insn.setReceiver(result);
insn.setType(InvocationType.SPECIAL); insn.setType(InvocationType.SPECIAL);
insn.setLocation(location); insn.setLocation(location);
@ -476,8 +474,7 @@ class JSValueMarshaller {
insn.setType(InvocationType.SPECIAL); insn.setType(InvocationType.SPECIAL);
insn.setMethod(JSMethods.FUNCTION_AS_OBJECT); insn.setMethod(JSMethods.FUNCTION_AS_OBJECT);
insn.setReceiver(functor); insn.setReceiver(functor);
insn.getArguments().add(var); insn.setArguments(var, nameVar);
insn.getArguments().add(nameVar);
insn.setLocation(location.getSourceLocation()); insn.setLocation(location.getSourceLocation());
replacement.add(insn); replacement.add(insn);
return functor; return functor;

View File

@ -406,7 +406,7 @@ public class CompositeMethodGenerator {
InvokeInstruction insn = new InvokeInstruction(); InvokeInstruction insn = new InvokeInstruction();
insn.setMethod(new MethodReference(wrapper, "valueOf", primitive, wrapper)); insn.setMethod(new MethodReference(wrapper, "valueOf", primitive, wrapper));
insn.setType(InvocationType.SPECIAL); insn.setType(InvocationType.SPECIAL);
insn.getArguments().add(var); insn.setArguments(var);
var = program.createVariable(); var = program.createVariable();
insn.setReceiver(var); insn.setReceiver(var);
add(insn); add(insn);
@ -851,7 +851,7 @@ public class CompositeMethodGenerator {
insn.setReceiver(var(receiver)); insn.setReceiver(var(receiver));
insn.setMethod(method); insn.setMethod(method);
insn.setType(type); insn.setType(type);
insn.getArguments().addAll(arguments.stream().map(this::var).collect(Collectors.toList())); insn.setArguments(arguments.stream().map(this::var).toArray(Variable[]::new));
add(insn); add(insn);
} }
@ -932,7 +932,7 @@ public class CompositeMethodGenerator {
insn.setType(Modifier.isStatic(reflectMethod.getModifiers()) ? InvocationType.SPECIAL insn.setType(Modifier.isStatic(reflectMethod.getModifiers()) ? InvocationType.SPECIAL
: InvocationType.VIRTUAL); : InvocationType.VIRTUAL);
insn.setMethod(reflectMethod.method.getReference()); insn.setMethod(reflectMethod.method.getReference());
emitArguments(var(arguments.get(1)), reflectMethod, insn.getArguments()); insn.setArguments(emitArguments(var(arguments.get(1)), reflectMethod));
add(insn); add(insn);
if (receiver != null) { if (receiver != null) {
@ -964,7 +964,7 @@ public class CompositeMethodGenerator {
insn.setInstance(constructInsn.getReceiver()); insn.setInstance(constructInsn.getReceiver());
insn.setType(InvocationType.SPECIAL); insn.setType(InvocationType.SPECIAL);
insn.setMethod(reflectMethod.method.getReference()); insn.setMethod(reflectMethod.method.getReference());
emitArguments(var(arguments.get(0)), reflectMethod, insn.getArguments()); insn.setArguments(emitArguments(var(arguments.get(0)), reflectMethod));
add(insn); add(insn);
return true; return true;
@ -1054,14 +1054,14 @@ public class CompositeMethodGenerator {
} }
} }
private void emitArguments(Variable argumentsVar, ReflectMethodImpl reflectMethod, private Variable[] emitArguments(Variable argumentsVar, ReflectMethodImpl reflectMethod) {
List<Variable> arguments) {
UnwrapArrayInstruction unwrapInsn = new UnwrapArrayInstruction(ArrayElementType.OBJECT); UnwrapArrayInstruction unwrapInsn = new UnwrapArrayInstruction(ArrayElementType.OBJECT);
unwrapInsn.setArray(argumentsVar); unwrapInsn.setArray(argumentsVar);
unwrapInsn.setReceiver(program.createVariable()); unwrapInsn.setReceiver(program.createVariable());
add(unwrapInsn); add(unwrapInsn);
argumentsVar = unwrapInsn.getReceiver(); argumentsVar = unwrapInsn.getReceiver();
Variable[] arguments = new Variable[reflectMethod.getParameterCount()];
for (int i = 0; i < reflectMethod.getParameterCount(); ++i) { for (int i = 0; i < reflectMethod.getParameterCount(); ++i) {
IntegerConstantInstruction indexInsn = new IntegerConstantInstruction(); IntegerConstantInstruction indexInsn = new IntegerConstantInstruction();
indexInsn.setConstant(i); indexInsn.setConstant(i);
@ -1074,9 +1074,10 @@ public class CompositeMethodGenerator {
extractArgInsn.setReceiver(program.createVariable()); extractArgInsn.setReceiver(program.createVariable());
add(extractArgInsn); add(extractArgInsn);
arguments.add(unbox(extractArgInsn.getReceiver(), arguments[i] = unbox(extractArgInsn.getReceiver(), reflectMethod.method.parameterType(i));
reflectMethod.method.parameterType(i)));
} }
return arguments;
} }
private Variable unwrapArray(ValueType type, Variable array) { private Variable unwrapArray(ValueType type, Variable array) {

View File

@ -130,9 +130,11 @@ public class ProxyVariableContext extends VariableContext {
initInsn.setInstance(constructInsn.getReceiver()); initInsn.setInstance(constructInsn.getReceiver());
initInsn.setMethod(ctor.getReference()); initInsn.setMethod(ctor.getReference());
initInsn.setType(InvocationType.SPECIAL); initInsn.setType(InvocationType.SPECIAL);
Variable[] initArgs = new Variable[capturedValues.size()];
for (int i = 0; i < capturedValues.size(); ++i) { for (int i = 0; i < capturedValues.size(); ++i) {
initInsn.getArguments().add(capturedValues.get(i).value); initArgs[i] = capturedValues.get(i).value;
} }
initInsn.setArguments(initArgs);
generator.add(initInsn); generator.add(initInsn);
return constructInsn.getReceiver(); return constructInsn.getReceiver();

View File

@ -333,7 +333,7 @@ class UsageGenerator {
InvokeInstruction insn = new InvokeInstruction(); InvokeInstruction insn = new InvokeInstruction();
insn.setType(InvocationType.SPECIAL); insn.setType(InvocationType.SPECIAL);
insn.setMethod(new MethodReference(boxed, "valueOf", primitive, boxed)); insn.setMethod(new MethodReference(boxed, "valueOf", primitive, boxed));
insn.getArguments().add(var); insn.setArguments(var);
var = program.createVariable(); var = program.createVariable();
insn.setReceiver(var); insn.setReceiver(var);

View File

@ -80,8 +80,12 @@ class ResourceProgramTransformer {
System.arraycopy(method.getDescriptor().getSignature(), 0, types, 1, System.arraycopy(method.getDescriptor().getSignature(), 0, types, 1,
method.getDescriptor().parameterCount() + 1); method.getDescriptor().parameterCount() + 1);
accessInsn.setMethod(new MethodReference(ResourceAccessor.class.getName(), method.getName(), types)); accessInsn.setMethod(new MethodReference(ResourceAccessor.class.getName(), method.getName(), types));
accessInsn.getArguments().add(insn.getInstance()); Variable[] accessArgs = new Variable[insn.getArguments().size() + 1];
accessInsn.getArguments().addAll(insn.getArguments()); accessArgs[0] = insn.getInstance();
for (int i = 0; i < insn.getArguments().size(); ++i) {
accessArgs[i + 1] = insn.getArguments().get(i);
}
accessInsn.setArguments(accessArgs);
accessInsn.setReceiver(insn.getReceiver()); accessInsn.setReceiver(insn.getReceiver());
return Arrays.asList(accessInsn); return Arrays.asList(accessInsn);
} }
@ -111,13 +115,13 @@ class ResourceProgramTransformer {
InvokeInstruction keysInsn = new InvokeInstruction(); InvokeInstruction keysInsn = new InvokeInstruction();
keysInsn.setType(InvocationType.SPECIAL); keysInsn.setType(InvocationType.SPECIAL);
keysInsn.setMethod(KEYS); keysInsn.setMethod(KEYS);
keysInsn.getArguments().add(insn.getInstance()); keysInsn.setArguments(insn.getInstance());
keysInsn.setReceiver(tmp); keysInsn.setReceiver(tmp);
InvokeInstruction transformInsn = new InvokeInstruction(); InvokeInstruction transformInsn = new InvokeInstruction();
transformInsn.setType(InvocationType.SPECIAL); transformInsn.setType(InvocationType.SPECIAL);
transformInsn.setMethod(KEYS_TO_STRINGS); transformInsn.setMethod(KEYS_TO_STRINGS);
transformInsn.getArguments().add(tmp); transformInsn.setArguments(tmp);
transformInsn.setReceiver(insn.getReceiver()); transformInsn.setReceiver(insn.getReceiver());
return Arrays.asList(keysInsn, transformInsn); return Arrays.asList(keysInsn, transformInsn);
@ -161,7 +165,7 @@ class ResourceProgramTransformer {
InvokeInstruction castInvoke = new InvokeInstruction(); InvokeInstruction castInvoke = new InvokeInstruction();
castInvoke.setType(InvocationType.SPECIAL); castInvoke.setType(InvocationType.SPECIAL);
castInvoke.setMethod(CAST_TO_STRING); castInvoke.setMethod(CAST_TO_STRING);
castInvoke.getArguments().add(resultVar); castInvoke.setArguments(resultVar);
castInvoke.setReceiver(insn.getReceiver()); castInvoke.setReceiver(insn.getReceiver());
instructions.add(castInvoke); instructions.add(castInvoke);
return instructions; return instructions;
@ -191,8 +195,7 @@ class ResourceProgramTransformer {
InvokeInstruction accessorInvoke = new InvokeInstruction(); InvokeInstruction accessorInvoke = new InvokeInstruction();
accessorInvoke.setType(InvocationType.SPECIAL); accessorInvoke.setType(InvocationType.SPECIAL);
accessorInvoke.setMethod(GET_PROPERTY); accessorInvoke.setMethod(GET_PROPERTY);
accessorInvoke.getArguments().add(insn.getInstance()); accessorInvoke.setArguments(insn.getInstance(), nameVar);
accessorInvoke.getArguments().add(nameVar);
accessorInvoke.setReceiver(resultVar); accessorInvoke.setReceiver(resultVar);
instructions.add(accessorInvoke); instructions.add(accessorInvoke);
} }
@ -208,7 +211,7 @@ class ResourceProgramTransformer {
+ primitiveCapitalized.substring(1); + primitiveCapitalized.substring(1);
castInvoke.setMethod(new MethodReference(ResourceAccessor.class, "castTo" + primitiveCapitalized, castInvoke.setMethod(new MethodReference(ResourceAccessor.class, "castTo" + primitiveCapitalized,
Object.class, primitive)); Object.class, primitive));
castInvoke.getArguments().add(resultVar); castInvoke.setArguments(resultVar);
castInvoke.setReceiver(insn.getReceiver()); castInvoke.setReceiver(insn.getReceiver());
instructions.add(castInvoke); instructions.add(castInvoke);
} }
@ -247,7 +250,7 @@ class ResourceProgramTransformer {
InvokeInstruction castInvoke = new InvokeInstruction(); InvokeInstruction castInvoke = new InvokeInstruction();
castInvoke.setType(InvocationType.SPECIAL); castInvoke.setType(InvocationType.SPECIAL);
castInvoke.setMethod(CAST_FROM_STRING); castInvoke.setMethod(CAST_FROM_STRING);
castInvoke.getArguments().add(insn.getArguments().get(0)); castInvoke.setArguments(insn.getArguments().get(0));
castInvoke.setReceiver(castVar); castInvoke.setReceiver(castVar);
instructions.add(castInvoke); instructions.add(castInvoke);
setProperty(insn, property, instructions, castVar); setProperty(insn, property, instructions, castVar);
@ -272,9 +275,7 @@ class ResourceProgramTransformer {
InvokeInstruction accessorInvoke = new InvokeInstruction(); InvokeInstruction accessorInvoke = new InvokeInstruction();
accessorInvoke.setType(InvocationType.SPECIAL); accessorInvoke.setType(InvocationType.SPECIAL);
accessorInvoke.setMethod(PUT); accessorInvoke.setMethod(PUT);
accessorInvoke.getArguments().add(insn.getInstance()); accessorInvoke.setArguments(insn.getInstance(), nameVar, valueVar);
accessorInvoke.getArguments().add(nameVar);
accessorInvoke.getArguments().add(valueVar);
instructions.add(accessorInvoke); instructions.add(accessorInvoke);
} }
@ -288,7 +289,7 @@ class ResourceProgramTransformer {
+ primitiveCapitalized.substring(1); + primitiveCapitalized.substring(1);
castInvoke.setMethod(new MethodReference(ResourceAccessor.class, "castFrom" + primitiveCapitalized, castInvoke.setMethod(new MethodReference(ResourceAccessor.class, "castFrom" + primitiveCapitalized,
primitive, Object.class)); primitive, Object.class));
castInvoke.getArguments().add(insn.getArguments().get(0)); castInvoke.setArguments(insn.getArguments().get(0));
castInvoke.setReceiver(castVar); castInvoke.setReceiver(castVar);
instructions.add(castInvoke); instructions.add(castInvoke);
setProperty(insn, property, instructions, castVar); setProperty(insn, property, instructions, castVar);

View File

@ -60,7 +60,7 @@ public class StringAmplifierTransformer implements ClassHolderTransformer {
amplifyInstruction.setMethod(new MethodReference(StringAmplifier.class, "amplify", amplifyInstruction.setMethod(new MethodReference(StringAmplifier.class, "amplify",
String.class, String.class)); String.class, String.class));
amplifyInstruction.setType(InvocationType.SPECIAL); amplifyInstruction.setType(InvocationType.SPECIAL);
amplifyInstruction.getArguments().add(var); amplifyInstruction.setArguments(var);
amplifyInstruction.setReceiver(invoke.getReceiver()); amplifyInstruction.setReceiver(invoke.getReceiver());
amplifyInstruction.setLocation(invoke.getLocation()); amplifyInstruction.setLocation(invoke.getLocation());