multi-index array expressions and related fixes

This commit is contained in:
Alex Tkachman
2011-11-02 23:51:27 +01:00
parent 532af2639f
commit 3ad5e74abb
6 changed files with 221 additions and 102 deletions
@@ -52,7 +52,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
private int myLastLineNumber = -1;
private final InstructionAdapter v;
private final FrameMap myMap;
private final FrameMap myFrameMap;
private final JetTypeMapper typeMapper;
private final GenerationState state;
@@ -68,7 +68,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
Type returnType,
ClassContext context,
GenerationState state) {
this.myMap = myMap;
this.myFrameMap = myMap;
this.typeMapper = state.getTypeMapper();
this.returnType = returnType;
this.state = state;
@@ -264,7 +264,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
JetType paramType = parameterDescriptor.getOutType();
Type asmParamType = typeMapper.mapType(paramType);
int iteratorVar = myMap.enterTemp();
int iteratorVar = myFrameMap.enterTemp();
gen(expression.getLoopRange(), loopRangeType);
invokeFunctionNoParams(iteratorDescriptor, asmIterType, v);
v.store(iteratorVar, asmIterType);
@@ -289,7 +289,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
}
v.ifeq(end);
myMap.enter(parameterDescriptor, asmParamType.getSize());
myFrameMap.enter(parameterDescriptor, asmParamType.getSize());
v.load(iteratorVar, asmIterType);
invokeFunctionNoParams(nextDescriptor, asmParamType, v);
@@ -304,10 +304,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
v.goTo(begin);
v.mark(end);
int paramIndex = myMap.leave(parameterDescriptor);
int paramIndex = myFrameMap.leave(parameterDescriptor);
//noinspection ConstantConditions
v.visitLocalVariable(loopParameter.getName(), asmParamType.getDescriptor(), null, begin, end, paramIndex);
myMap.leaveTemp();
myFrameMap.leaveTemp();
myBreakTargets.pop();
myContinueTargets.pop();
}
@@ -338,7 +338,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
JetType paramType = parameterDescriptor.getOutType();
Type asmParamType = typeMapper.mapType(paramType);
myMap.enter(parameterDescriptor, asmParamType.getSize());
myFrameMap.enter(parameterDescriptor, asmParamType.getSize());
generatePrologue();
Label condition = new Label();
@@ -358,7 +358,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
v.mark(end);
cleanupTemp();
final int paramIndex = myMap.leave(parameterDescriptor);
final int paramIndex = myFrameMap.leave(parameterDescriptor);
//noinspection ConstantConditions
v.visitLocalVariable(expression.getLoopParameter().getName(), asmParamType.getDescriptor(), null, condition, end, paramIndex);
myBreakTargets.pop();
@@ -386,11 +386,11 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
@Override
protected void generatePrologue() {
myLengthVar = myMap.enterTemp();
myLengthVar = myFrameMap.enterTemp();
gen(expression.getLoopRange(), loopRangeType);
v.arraylength();
v.store(myLengthVar, Type.INT_TYPE);
myIndexVar = myMap.enterTemp();
myIndexVar = myFrameMap.enterTemp();
v.iconst(0);
v.store(myIndexVar, Type.INT_TYPE);
}
@@ -414,7 +414,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
}
protected void cleanupTemp() {
myMap.leaveTemp(2);
myFrameMap.leaveTemp(2);
}
}
@@ -427,7 +427,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
@Override
protected void generatePrologue() {
myEndVar = myMap.enterTemp();
myEndVar = myFrameMap.enterTemp();
if(isIntRangeExpr(expression.getLoopRange())) {
JetBinaryExpression rangeExpression = (JetBinaryExpression) expression.getLoopRange();
//noinspection ConstantConditions
@@ -461,7 +461,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
@Override
protected void cleanupTemp() {
myMap.leaveTemp(1);
myFrameMap.leaveTemp(1);
}
}
@@ -634,7 +634,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
final Type sharedVarType = getSharedVarType(variableDescriptor);
final Type type = sharedVarType != null ? sharedVarType : typeMapper.mapType(variableDescriptor.getOutType());
myMap.enter(variableDescriptor, type.getSize());
myFrameMap.enter(variableDescriptor, type.getSize());
}
}
@@ -658,7 +658,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
VariableDescriptor variableDescriptor = bindingContext.get(BindingContext.VARIABLE, var);
assert variableDescriptor != null;
int index = myMap.leave(variableDescriptor);
int index = myFrameMap.leave(variableDescriptor);
final Type sharedVarType = getSharedVarType(variableDescriptor);
final Type type = sharedVarType != null ? sharedVarType : typeMapper.mapType(variableDescriptor.getOutType());
@@ -859,7 +859,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
}
public int lookupLocal(DeclarationDescriptor descriptor) {
return myMap.getIndex(descriptor);
return myFrameMap.getIndex(descriptor);
}
public void invokeFunctionNoParams(FunctionDescriptor functionDescriptor, Type type, InstructionAdapter v) {
@@ -1122,8 +1122,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
if (isSubclass((ClassDescriptor) curContextType, calleeContainingClass)) break;
final StackValue outer;
if (!thisDone && myMap instanceof ConstructorFrameMap) {
outer = StackValue.local(((ConstructorFrameMap) myMap).getOuterThisIndex(), JetTypeMapper.TYPE_OBJECT);
if (!thisDone && myFrameMap instanceof ConstructorFrameMap) {
outer = StackValue.local(((ConstructorFrameMap) myFrameMap).getOuterThisIndex(), JetTypeMapper.TYPE_OBJECT);
}
else {
thisToStack();
@@ -1188,12 +1188,12 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
else if(resolvedValueArgument instanceof VarargValueArgument) {
VarargValueArgument valueArgument = (VarargValueArgument) resolvedValueArgument;
JetType outType = valueParameterDescriptor.getOutType();
Type type = typeMapper.mapType(outType);
assert type.getSort() == Type.ARRAY;
Type elementType = type.getElementType();
int size = valueArgument.getArgumentExpressions().size();
v.iconst(valueArgument.getArgumentExpressions().size());
v.newarray(elementType);
for(int i = 0; i != size; ++i) {
@@ -1202,7 +1202,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
gen(valueArgument.getArgumentExpressions().get(i), elementType);
StackValue.arrayElement(elementType, false).store(v);
}
// throw new UnsupportedOperationException("Varargs are not supported yet");
}
else {
@@ -1631,12 +1631,20 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
DeclarationDescriptor op = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationReference());
final Callable callable = resolveToCallable(op);
final JetExpression lhs = expression.getLeft();
// if(lhs instanceof JetArrayAccessExpression) {
// JetArrayAccessExpression arrayAccessExpression = (JetArrayAccessExpression) lhs;
// if(arrayAccessExpression.getIndexExpressions().size() != 1) {
// throw new UnsupportedOperationException("Augmented assignment with multi-index");
// }
// }
Type lhsType = expressionType(lhs);
//noinspection ConstantConditions
if (bindingContext.get(BindingContext.VARIABLE_REASSIGNMENT, expression)) {
if (callable instanceof IntrinsicMethod) {
StackValue value = gen(lhs); // receiver
value.dupReceiver(v, 0); // receiver receiver
value.dupReceiver(v); // receiver receiver
value.put(lhsType, v); // receiver lhs
final IntrinsicMethod intrinsic = (IntrinsicMethod) callable;
//noinspection NullableProblems
@@ -1659,7 +1667,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
private void callAugAssignMethod(JetBinaryExpression expression, CallableMethod callable, Type lhsType, final boolean keepReturnValue) {
StackValue value = gen(expression.getLeft());
if (keepReturnValue) {
value.dupReceiver(v, 0);
value.dupReceiver(v);
}
value.put(lhsType, v);
genToJVMStack(expression.getRight());
@@ -1747,7 +1755,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
}
}
StackValue value = genQualified(receiver, operand);
value.dupReceiver(v, 0);
value.dupReceiver(v);
value.put(asmType, v);
if (asmType == Type.LONG_TYPE) {
//noinspection UnnecessaryBoxing
@@ -1914,7 +1922,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
}
if(args.size() == 2) {
int sizeIndex = myMap.enterTemp(2);
int sizeIndex = myFrameMap.enterTemp(2);
int indexIndex = sizeIndex+1;
v.dup();
@@ -1946,7 +1954,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
v.visitLabel(end);
v.pop();
myMap.leaveTemp(2);
myFrameMap.leaveTemp(2);
}
}
@@ -1956,8 +1964,12 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
JetType type = bindingContext.get(BindingContext.EXPRESSION_TYPE, array);
final Type arrayType = type == null ? Type.VOID_TYPE : typeMapper.mapType(type);
gen(array, arrayType);
generateArrayIndex(expression);
if (arrayType.getSort() == Type.ARRAY) {
final List<JetExpression> indices = expression.getIndexExpressions();
FunctionDescriptor operationDescriptor = (FunctionDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, expression);
if (arrayType.getSort() == Type.ARRAY && indices.size() == 1 && operationDescriptor.getValueParameters().get(0).getOutType().equals(state.getStandardLibrary().getIntType())) {
for (JetExpression index : indices) {
gen(index, Type.INT_TYPE);
}
if(state.getStandardLibrary().getArray().equals(type.getConstructor().getDeclarationDescriptor())) {
JetType elementType = type.getArguments().get(0).getType();
Type notBoxed = typeMapper.mapType(elementType);
@@ -1969,27 +1981,39 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
}
}
else {
DeclarationDescriptor operationDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, expression);
CallableMethod accessor = typeMapper.mapToCallableMethod((FunctionDescriptor) operationDescriptor, OwnerKind.IMPLEMENTATION);
CallableMethod accessor = typeMapper.mapToCallableMethod(operationDescriptor, OwnerKind.IMPLEMENTATION);
boolean isGetter = accessor.getSignature().getName().equals("get");
ResolvedCall<FunctionDescriptor> resolvedSetCall = bindingContext.get(BindingContext.INDEXED_LVALUE_SET, expression);
FunctionDescriptor setterDescriptor = resolvedSetCall == null ? null : resolvedSetCall.getResultingDescriptor();
CallableMethod setter = resolvedSetCall == null ? null : typeMapper.mapToCallableMethod(setterDescriptor, OwnerKind.IMPLEMENTATION);
ResolvedCall<FunctionDescriptor> resolvedGetCall = bindingContext.get(BindingContext.INDEXED_LVALUE_GET, expression);
FunctionDescriptor getterDescriptor = resolvedGetCall == null ? null : resolvedGetCall.getResultingDescriptor();
CallableMethod getter = resolvedGetCall == null ? null : typeMapper.mapToCallableMethod(getterDescriptor, OwnerKind.IMPLEMENTATION);
Type asmType;
Type[] argumentTypes = accessor.getSignature().getArgumentTypes();
int index = 0;
if(isGetter) {
ResolvedCall<FunctionDescriptor> resolvedCall = bindingContext.get(BindingContext.INDEXED_LVALUE_SET, expression);
FunctionDescriptor setterDescriptor = resolvedCall == null ? null : resolvedCall.getResultingDescriptor();
return StackValue.collectionElement(
accessor.getSignature().getReturnType(),
accessor,
setterDescriptor != null ? typeMapper.mapToCallableMethod(setterDescriptor, OwnerKind.IMPLEMENTATION) : null);
if(getterDescriptor.getReceiverParameter().exists()) {
index++;
}
asmType = accessor.getSignature().getReturnType();
}
else {
ResolvedCall<FunctionDescriptor> resolvedCall = bindingContext.get(BindingContext.INDEXED_LVALUE_GET, expression);
FunctionDescriptor getterDescriptor = resolvedCall == null ? null : resolvedCall.getResultingDescriptor();
return StackValue.collectionElement(
accessor.getSignature().getArgumentTypes()[1],
getterDescriptor != null ? typeMapper.mapToCallableMethod(getterDescriptor, OwnerKind.IMPLEMENTATION) : null,
accessor);
if(setterDescriptor.getReceiverParameter().exists()) {
index++;
}
asmType = argumentTypes[argumentTypes.length-1];
}
for (JetExpression jetExpression : expression.getIndexExpressions()) {
gen(jetExpression, argumentTypes[index]);
index++;
}
return StackValue.collectionElement(asmType, getter, setter, myFrameMap);
}
}
@@ -2033,13 +2057,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
}
}
private void generateArrayIndex(JetArrayAccessExpression expression) {
final List<JetExpression> indices = expression.getIndexExpressions();
for (JetExpression index : indices) {
gen(index, Type.INT_TYPE);
}
}
@Override
public StackValue visitThrowExpression(JetThrowExpression expression, StackValue receiver) {
gen(expression.getThrownExpression(), JetTypeMapper.TYPE_OBJECT);
@@ -2082,21 +2099,21 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
VariableDescriptor descriptor = bindingContext.get(BindingContext.VALUE_PARAMETER, clause.getCatchParameter());
assert descriptor != null;
Type descriptorType = typeMapper.mapType(descriptor.getOutType());
myMap.enter(descriptor, 1);
myFrameMap.enter(descriptor, 1);
int index = lookupLocal(descriptor);
v.store(index, descriptorType);
gen(clause.getCatchBody(), Type.VOID_TYPE);
v.goTo(end); // TODO don't generate goto if there's no code following try/catch
myMap.leave(descriptor);
myFrameMap.leave(descriptor);
v.visitTryCatchBlock(tryStart, tryEnd, clauseStart, descriptorType.getInternalName());
}
if (finallyBlock != null) {
Label finallyStart = new Label();
v.mark(finallyStart);
int index = myMap.enterTemp();
int index = myFrameMap.enterTemp();
v.store(index, THROWABLE_TYPE);
gen(finallyBlock.getFinalExpression(), Type.VOID_TYPE);
@@ -2104,7 +2121,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
v.load(index, THROWABLE_TYPE);
v.athrow();
myMap.leaveTemp();
myFrameMap.leaveTemp();
v.visitTryCatchBlock(tryStart, tryEnd, finallyStart, null);
}
@@ -2159,7 +2176,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
if (pattern instanceof JetTypePattern) {
JetTypeReference typeReference = ((JetTypePattern) pattern).getTypeReference();
JetType jetType = bindingContext.get(BindingContext.TYPE, typeReference);
expressionToMatch.dupReceiver(v, 0);
expressionToMatch.dupReceiver(v);
generateInstanceOf(expressionToMatch, jetType, false);
StackValue value = StackValue.onStack(Type.BOOLEAN_TYPE);
return negated ? StackValue.not(value) : value;
@@ -2169,7 +2186,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
}
else if (pattern instanceof JetExpressionPattern) {
final Type subjectType = expressionToMatch.type;
expressionToMatch.dupReceiver(v, 0);
expressionToMatch.dupReceiver(v);
expressionToMatch.put(subjectType, v);
JetExpression condExpression = ((JetExpressionPattern) pattern).getExpression();
Type condType = isNumberPrimitive(subjectType) ? expressionType(condExpression) : OBJECT_TYPE;
@@ -2184,10 +2201,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
final VariableDescriptor variableDescriptor = bindingContext.get(BindingContext.VARIABLE, var);
assert variableDescriptor != null;
final Type varType = typeMapper.mapType(variableDescriptor.getOutType());
myMap.enter(variableDescriptor, varType.getSize());
expressionToMatch.dupReceiver(v, 0);
myFrameMap.enter(variableDescriptor, varType.getSize());
expressionToMatch.dupReceiver(v);
expressionToMatch.put(varType, v);
final int varIndex = myMap.getIndex(variableDescriptor);
final int varIndex = myFrameMap.getIndex(variableDescriptor);
v.store(varIndex, varType);
return generateWhenCondition(varType, varIndex, ((JetBindingPattern) pattern).getCondition(), null);
}
@@ -2202,7 +2219,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
Label lblFail = new Label();
Label lblDone = new Label();
expressionToMatch.dupReceiver(v, 0);
expressionToMatch.dupReceiver(v);
expressionToMatch.put(OBJECT_TYPE, v);
v.dup();
final String tupleClassName = "jet/Tuple" + entries.size();
@@ -2384,7 +2401,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
public StackValue visitWhenExpression(JetWhenExpression expression, StackValue receiver) {
JetExpression expr = expression.getSubjectExpression();
final Type subjectType = expressionType(expr);
final int subjectLocal = myMap.enterTemp(subjectType.getSize());
final int subjectLocal = myFrameMap.enterTemp(subjectType.getSize());
gen(expr, subjectType);
v.store(subjectLocal, subjectType);
@@ -2396,7 +2413,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
v.mark(nextCondition);
}
nextCondition = new Label();
FrameMap.Mark mark = myMap.mark();
FrameMap.Mark mark = myFrameMap.mark();
Label thisEntry = new Label();
if (!whenEntry.isElse()) {
final JetWhenCondition[] conditions = whenEntry.getConditions();
@@ -2424,7 +2441,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
}
v.mark(end);
myMap.leaveTemp(subjectType.getSize());
myFrameMap.leaveTemp(subjectType.getSize());
return StackValue.onStack(expressionType(expression));
}
@@ -81,9 +81,10 @@ public class FunctionCodegen {
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, jvmSignature.getReturnType(), context, state);
Type[] argTypes = jvmSignature.getArgumentTypes();
int add = functionDescriptor.getReceiverParameter().exists() ? state.getTypeMapper().mapType(functionDescriptor.getReceiverParameter().getType()).getSize() : 0;
for (int i = 0; i < paramDescrs.size(); i++) {
ValueParameterDescriptor parameter = paramDescrs.get(i);
frameMap.enter(parameter, argTypes[i].getSize());
frameMap.enter(parameter, argTypes[i+add].getSize());
}
for (final TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
@@ -547,6 +547,9 @@ public class JetTypeMapper {
}
public CallableMethod mapToCallableMethod(FunctionDescriptor functionDescriptor, OwnerKind kind) {
if(functionDescriptor == null)
return null;
final DeclarationDescriptor functionParent = functionDescriptor.getContainingDeclaration();
final List<Type> valueParameterTypes = new ArrayList<Type>();
Method descriptor = mapSignature(functionDescriptor.getOriginal(), valueParameterTypes, kind);
@@ -38,7 +38,7 @@ public abstract class StackValue {
throw new UnsupportedOperationException("cannot store to value " + this);
}
public void dupReceiver(InstructionAdapter v, int below) {
public void dupReceiver(InstructionAdapter v) {
}
public void condJump(Label label, boolean jumpIfFalse, InstructionAdapter v) {
@@ -84,8 +84,8 @@ public abstract class StackValue {
return new ArrayElement(type, unbox);
}
public static StackValue collectionElement(Type type, CallableMethod getter, CallableMethod setter) {
return new CollectionElement(type, getter, setter);
public static StackValue collectionElement(Type type, CallableMethod getter, CallableMethod setter, FrameMap frame) {
return new CollectionElement(type, getter, setter, frame);
}
public static StackValue field(Type type, String owner, String name, boolean isStatic) {
@@ -456,24 +456,21 @@ public abstract class StackValue {
}
@Override
public void dupReceiver(InstructionAdapter v, int below) {
if (below == 1) {
v.dup2X1();
}
else {
v.dup2(); // array and index
}
public void dupReceiver(InstructionAdapter v) {
v.dup2(); // array and index
}
}
private static class CollectionElement extends StackValue {
private final CallableMethod getter;
private final CallableMethod setter;
private final FrameMap frame;
public CollectionElement(Type type, CallableMethod getter, CallableMethod setter) {
public CollectionElement(Type type, CallableMethod getter, CallableMethod setter, FrameMap frame) {
super(type);
this.getter = getter;
this.setter = setter;
this.frame = frame;
}
@Override
@@ -494,13 +491,70 @@ public abstract class StackValue {
}
@Override
public void dupReceiver(InstructionAdapter v, int below) {
if (below == 1) {
v.dup2X1();
}
else {
public void dupReceiver(InstructionAdapter v) {
int size = calcSize();
if(size == 2) {
v.dup2(); // collection and index
}
else {
Method signature = getter.getSignature();
Type[] argumentTypes = signature.getArgumentTypes();
int firstIndex = frame.enterTemp();
int lastIndex = firstIndex;
frame.leaveTemp();
for(int i = argumentTypes.length-1; i >= 0; i--) {
int sz = argumentTypes[i].getSize();
frame.enterTemp(sz);
lastIndex += sz;
v.store(lastIndex-sz, argumentTypes[i]);
}
if(getter.getInvokeOpcode() != Opcodes.INVOKESTATIC) {
frame.enterTemp();
lastIndex++;
v.store(lastIndex-1, JetTypeMapper.TYPE_OBJECT);
}
firstIndex = lastIndex;
int curIndex = lastIndex;
if(getter.getInvokeOpcode() != Opcodes.INVOKESTATIC) {
v.load(curIndex-1, JetTypeMapper.TYPE_OBJECT);
curIndex--;
}
for(int i = 0; i != argumentTypes.length; i++) {
int sz = argumentTypes[i].getSize();
v.load(curIndex-sz, argumentTypes[i]);
curIndex -= sz;
}
curIndex = firstIndex;
if(getter.getInvokeOpcode() != Opcodes.INVOKESTATIC) {
v.load(curIndex-1, JetTypeMapper.TYPE_OBJECT);
curIndex--;
}
for(int i = 0; i != argumentTypes.length; i++) {
int sz = argumentTypes[i].getSize();
v.load(curIndex-sz, argumentTypes[i]);
curIndex -= sz;
}
frame.leaveTemp(size);
}
}
private int calcSize() {
assert getter != null;
int size = getter.getInvokeOpcode() == Opcodes.INVOKESTATIC ? 0 : 1;
Method signature = getter.getSignature();
Type[] argumentTypes = signature.getArgumentTypes();
for(int i = 0; i != argumentTypes.length; ++i)
size += argumentTypes[i].getSize();
return size;
}
}
@@ -523,14 +577,9 @@ public abstract class StackValue {
}
@Override
public void dupReceiver(InstructionAdapter v, int below) {
public void dupReceiver(InstructionAdapter v) {
if (!isStatic) {
if (below == 1) {
v.dupX1();
}
else {
v.dup();
}
v.dup();
}
}
@@ -557,7 +606,7 @@ public abstract class StackValue {
}
@Override
public void dupReceiver(InstructionAdapter v, int below) {
public void dupReceiver(InstructionAdapter v) {
}
@Override
@@ -607,14 +656,9 @@ public abstract class StackValue {
}
@Override
public void dupReceiver(InstructionAdapter v, int below) {
public void dupReceiver(InstructionAdapter v) {
if (!isStatic) {
if (below == 1) {
v.dupX1();
}
else {
v.dup();
}
v.dup();
}
}
}
@@ -716,13 +760,8 @@ public abstract class StackValue {
}
@Override
public void dupReceiver(InstructionAdapter v, int below) {
if (below == 1) {
v.dupX1();
}
else {
v.dup();
}
public void dupReceiver(InstructionAdapter v) {
v.dup();
}
@Override
@@ -32,7 +32,7 @@ public class Increment implements IntrinsicMethod {
}
}
StackValue value = codegen.genQualified(receiver, operand);
value.dupReceiver(v, 0);
value. dupReceiver(v);
value.put(expectedType, v);
if (expectedType == Type.LONG_TYPE) {
v.lconst(myDelta);
@@ -107,4 +107,63 @@ public class ArrayGenTest extends CodegenTestCase {
Method foo = generateFunction();
assertTrue((Integer)foo.invoke(null) == 12);
}
public void testCollectionAssignGetMultiIndex () throws Exception {
loadText("import java.util.ArrayList\n" +
"fun box() : String { val s = ArrayList<String>(1); s.add(\"\"); s [1, -1] = \"5\"; s[2, -2] += \"7\"; return s[2,-2] }\n" +
"fun ArrayList<String>.get(index1: Int, index2 : Int) = this[index1+index2]\n" +
"fun ArrayList<String>.set(index1: Int, index2 : Int, elem: String) { this[index1+index2] = elem }\n");
System.out.println(generateToText());
Method foo = generateFunction("box");
assertTrue(foo.invoke(null).equals("57"));
}
public void testArrayGetAssignMultiIndex () throws Exception {
loadText(
"fun box() : String? { val s = Array<String>(1,{ \"\" }); s [1, -1] = \"5\"; s[2, -2] += \"7\"; return s[-3,3] }\n" +
"fun Array<String>.get(index1: Int, index2 : Int) = this[index1+index2]\n" +
"fun Array<String>.set(index1: Int, index2 : Int, elem: String) { this[index1+index2] = elem\n }");
System.out.println(generateToText());
Method foo = generateFunction("box");
assertTrue(foo.invoke(null).equals("57"));
}
public void testCollectionGetMultiIndex () throws Exception {
loadText("import java.util.ArrayList\n" +
"fun box() : String { val s = ArrayList<String>(1); s.add(\"\"); s [1, -1] = \"5\"; return s[2, -2] }\n" +
"fun ArrayList<String>.get(index1: Int, index2 : Int) = this[index1+index2]\n" +
"fun ArrayList<String>.set(index1: Int, index2 : Int, elem: String) { this[index1+index2] = elem }\n");
System.out.println(generateToText());
Method foo = generateFunction("box");
assertTrue(foo.invoke(null).equals("5"));
}
public void testArrayGetMultiIndex () throws Exception {
loadText(
"fun box() : String? { val s = Array<String>(1,{ \"\" }); s [1, -1] = \"5\"; return s[-2, 2] }\n" +
"fun Array<String>.get(index1: Int, index2 : Int) = this[index1+index2]\n" +
"fun Array<String>.set(index1: Int, index2 : Int, elem: String) { this[index1+index2] = elem\n }");
System.out.println(generateToText());
Method foo = generateFunction("box");
assertTrue(foo.invoke(null).equals("5"));
}
public void testMap () throws Exception {
loadText(
"fun box() : Int? { val s = java.util.HashMap<String,Int?>(); s[\"239\"] = 239; return s[\"239\"] }\n" +
"fun java.util.HashMap<String,Int?>.set(index: String, elem: Int?) { this.put(index, elem) }");
System.out.println(generateToText());
Method foo = generateFunction("box");
assertTrue((Integer)foo.invoke(null) == 239);
}
public void testLongDouble () throws Exception {
loadText(
"fun box() : Int { var l = IntArray(1); l[0.lng] = 4; l[0.lng] += 6; return l[0.lng];}\n" +
"fun IntArray.set(index: Long, elem: Int) { this[index.int] = elem }\n" +
"fun IntArray.get(index: Long) = this[index.int]");
System.out.println(generateToText());
Method foo = generateFunction("box");
assertTrue((Integer)foo.invoke(null) == 10);
}
}