multi-index array expressions and related fixes
This commit is contained in:
@@ -52,7 +52,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
private int myLastLineNumber = -1;
|
private int myLastLineNumber = -1;
|
||||||
|
|
||||||
private final InstructionAdapter v;
|
private final InstructionAdapter v;
|
||||||
private final FrameMap myMap;
|
private final FrameMap myFrameMap;
|
||||||
private final JetTypeMapper typeMapper;
|
private final JetTypeMapper typeMapper;
|
||||||
|
|
||||||
private final GenerationState state;
|
private final GenerationState state;
|
||||||
@@ -68,7 +68,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
Type returnType,
|
Type returnType,
|
||||||
ClassContext context,
|
ClassContext context,
|
||||||
GenerationState state) {
|
GenerationState state) {
|
||||||
this.myMap = myMap;
|
this.myFrameMap = myMap;
|
||||||
this.typeMapper = state.getTypeMapper();
|
this.typeMapper = state.getTypeMapper();
|
||||||
this.returnType = returnType;
|
this.returnType = returnType;
|
||||||
this.state = state;
|
this.state = state;
|
||||||
@@ -264,7 +264,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
JetType paramType = parameterDescriptor.getOutType();
|
JetType paramType = parameterDescriptor.getOutType();
|
||||||
Type asmParamType = typeMapper.mapType(paramType);
|
Type asmParamType = typeMapper.mapType(paramType);
|
||||||
|
|
||||||
int iteratorVar = myMap.enterTemp();
|
int iteratorVar = myFrameMap.enterTemp();
|
||||||
gen(expression.getLoopRange(), loopRangeType);
|
gen(expression.getLoopRange(), loopRangeType);
|
||||||
invokeFunctionNoParams(iteratorDescriptor, asmIterType, v);
|
invokeFunctionNoParams(iteratorDescriptor, asmIterType, v);
|
||||||
v.store(iteratorVar, asmIterType);
|
v.store(iteratorVar, asmIterType);
|
||||||
@@ -289,7 +289,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
}
|
}
|
||||||
v.ifeq(end);
|
v.ifeq(end);
|
||||||
|
|
||||||
myMap.enter(parameterDescriptor, asmParamType.getSize());
|
myFrameMap.enter(parameterDescriptor, asmParamType.getSize());
|
||||||
v.load(iteratorVar, asmIterType);
|
v.load(iteratorVar, asmIterType);
|
||||||
invokeFunctionNoParams(nextDescriptor, asmParamType, v);
|
invokeFunctionNoParams(nextDescriptor, asmParamType, v);
|
||||||
|
|
||||||
@@ -304,10 +304,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
v.goTo(begin);
|
v.goTo(begin);
|
||||||
v.mark(end);
|
v.mark(end);
|
||||||
|
|
||||||
int paramIndex = myMap.leave(parameterDescriptor);
|
int paramIndex = myFrameMap.leave(parameterDescriptor);
|
||||||
//noinspection ConstantConditions
|
//noinspection ConstantConditions
|
||||||
v.visitLocalVariable(loopParameter.getName(), asmParamType.getDescriptor(), null, begin, end, paramIndex);
|
v.visitLocalVariable(loopParameter.getName(), asmParamType.getDescriptor(), null, begin, end, paramIndex);
|
||||||
myMap.leaveTemp();
|
myFrameMap.leaveTemp();
|
||||||
myBreakTargets.pop();
|
myBreakTargets.pop();
|
||||||
myContinueTargets.pop();
|
myContinueTargets.pop();
|
||||||
}
|
}
|
||||||
@@ -338,7 +338,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
JetType paramType = parameterDescriptor.getOutType();
|
JetType paramType = parameterDescriptor.getOutType();
|
||||||
Type asmParamType = typeMapper.mapType(paramType);
|
Type asmParamType = typeMapper.mapType(paramType);
|
||||||
|
|
||||||
myMap.enter(parameterDescriptor, asmParamType.getSize());
|
myFrameMap.enter(parameterDescriptor, asmParamType.getSize());
|
||||||
generatePrologue();
|
generatePrologue();
|
||||||
|
|
||||||
Label condition = new Label();
|
Label condition = new Label();
|
||||||
@@ -358,7 +358,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
v.mark(end);
|
v.mark(end);
|
||||||
|
|
||||||
cleanupTemp();
|
cleanupTemp();
|
||||||
final int paramIndex = myMap.leave(parameterDescriptor);
|
final int paramIndex = myFrameMap.leave(parameterDescriptor);
|
||||||
//noinspection ConstantConditions
|
//noinspection ConstantConditions
|
||||||
v.visitLocalVariable(expression.getLoopParameter().getName(), asmParamType.getDescriptor(), null, condition, end, paramIndex);
|
v.visitLocalVariable(expression.getLoopParameter().getName(), asmParamType.getDescriptor(), null, condition, end, paramIndex);
|
||||||
myBreakTargets.pop();
|
myBreakTargets.pop();
|
||||||
@@ -386,11 +386,11 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void generatePrologue() {
|
protected void generatePrologue() {
|
||||||
myLengthVar = myMap.enterTemp();
|
myLengthVar = myFrameMap.enterTemp();
|
||||||
gen(expression.getLoopRange(), loopRangeType);
|
gen(expression.getLoopRange(), loopRangeType);
|
||||||
v.arraylength();
|
v.arraylength();
|
||||||
v.store(myLengthVar, Type.INT_TYPE);
|
v.store(myLengthVar, Type.INT_TYPE);
|
||||||
myIndexVar = myMap.enterTemp();
|
myIndexVar = myFrameMap.enterTemp();
|
||||||
v.iconst(0);
|
v.iconst(0);
|
||||||
v.store(myIndexVar, Type.INT_TYPE);
|
v.store(myIndexVar, Type.INT_TYPE);
|
||||||
}
|
}
|
||||||
@@ -414,7 +414,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void cleanupTemp() {
|
protected void cleanupTemp() {
|
||||||
myMap.leaveTemp(2);
|
myFrameMap.leaveTemp(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -427,7 +427,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void generatePrologue() {
|
protected void generatePrologue() {
|
||||||
myEndVar = myMap.enterTemp();
|
myEndVar = myFrameMap.enterTemp();
|
||||||
if(isIntRangeExpr(expression.getLoopRange())) {
|
if(isIntRangeExpr(expression.getLoopRange())) {
|
||||||
JetBinaryExpression rangeExpression = (JetBinaryExpression) expression.getLoopRange();
|
JetBinaryExpression rangeExpression = (JetBinaryExpression) expression.getLoopRange();
|
||||||
//noinspection ConstantConditions
|
//noinspection ConstantConditions
|
||||||
@@ -461,7 +461,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void cleanupTemp() {
|
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 sharedVarType = getSharedVarType(variableDescriptor);
|
||||||
final Type type = sharedVarType != null ? sharedVarType : typeMapper.mapType(variableDescriptor.getOutType());
|
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);
|
VariableDescriptor variableDescriptor = bindingContext.get(BindingContext.VARIABLE, var);
|
||||||
assert variableDescriptor != null;
|
assert variableDescriptor != null;
|
||||||
|
|
||||||
int index = myMap.leave(variableDescriptor);
|
int index = myFrameMap.leave(variableDescriptor);
|
||||||
|
|
||||||
final Type sharedVarType = getSharedVarType(variableDescriptor);
|
final Type sharedVarType = getSharedVarType(variableDescriptor);
|
||||||
final Type type = sharedVarType != null ? sharedVarType : typeMapper.mapType(variableDescriptor.getOutType());
|
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) {
|
public int lookupLocal(DeclarationDescriptor descriptor) {
|
||||||
return myMap.getIndex(descriptor);
|
return myFrameMap.getIndex(descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void invokeFunctionNoParams(FunctionDescriptor functionDescriptor, Type type, InstructionAdapter v) {
|
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;
|
if (isSubclass((ClassDescriptor) curContextType, calleeContainingClass)) break;
|
||||||
|
|
||||||
final StackValue outer;
|
final StackValue outer;
|
||||||
if (!thisDone && myMap instanceof ConstructorFrameMap) {
|
if (!thisDone && myFrameMap instanceof ConstructorFrameMap) {
|
||||||
outer = StackValue.local(((ConstructorFrameMap) myMap).getOuterThisIndex(), JetTypeMapper.TYPE_OBJECT);
|
outer = StackValue.local(((ConstructorFrameMap) myFrameMap).getOuterThisIndex(), JetTypeMapper.TYPE_OBJECT);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
thisToStack();
|
thisToStack();
|
||||||
@@ -1631,12 +1631,20 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
DeclarationDescriptor op = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationReference());
|
DeclarationDescriptor op = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationReference());
|
||||||
final Callable callable = resolveToCallable(op);
|
final Callable callable = resolveToCallable(op);
|
||||||
final JetExpression lhs = expression.getLeft();
|
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);
|
Type lhsType = expressionType(lhs);
|
||||||
//noinspection ConstantConditions
|
//noinspection ConstantConditions
|
||||||
if (bindingContext.get(BindingContext.VARIABLE_REASSIGNMENT, expression)) {
|
if (bindingContext.get(BindingContext.VARIABLE_REASSIGNMENT, expression)) {
|
||||||
if (callable instanceof IntrinsicMethod) {
|
if (callable instanceof IntrinsicMethod) {
|
||||||
StackValue value = gen(lhs); // receiver
|
StackValue value = gen(lhs); // receiver
|
||||||
value.dupReceiver(v, 0); // receiver receiver
|
value.dupReceiver(v); // receiver receiver
|
||||||
value.put(lhsType, v); // receiver lhs
|
value.put(lhsType, v); // receiver lhs
|
||||||
final IntrinsicMethod intrinsic = (IntrinsicMethod) callable;
|
final IntrinsicMethod intrinsic = (IntrinsicMethod) callable;
|
||||||
//noinspection NullableProblems
|
//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) {
|
private void callAugAssignMethod(JetBinaryExpression expression, CallableMethod callable, Type lhsType, final boolean keepReturnValue) {
|
||||||
StackValue value = gen(expression.getLeft());
|
StackValue value = gen(expression.getLeft());
|
||||||
if (keepReturnValue) {
|
if (keepReturnValue) {
|
||||||
value.dupReceiver(v, 0);
|
value.dupReceiver(v);
|
||||||
}
|
}
|
||||||
value.put(lhsType, v);
|
value.put(lhsType, v);
|
||||||
genToJVMStack(expression.getRight());
|
genToJVMStack(expression.getRight());
|
||||||
@@ -1747,7 +1755,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
StackValue value = genQualified(receiver, operand);
|
StackValue value = genQualified(receiver, operand);
|
||||||
value.dupReceiver(v, 0);
|
value.dupReceiver(v);
|
||||||
value.put(asmType, v);
|
value.put(asmType, v);
|
||||||
if (asmType == Type.LONG_TYPE) {
|
if (asmType == Type.LONG_TYPE) {
|
||||||
//noinspection UnnecessaryBoxing
|
//noinspection UnnecessaryBoxing
|
||||||
@@ -1914,7 +1922,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(args.size() == 2) {
|
if(args.size() == 2) {
|
||||||
int sizeIndex = myMap.enterTemp(2);
|
int sizeIndex = myFrameMap.enterTemp(2);
|
||||||
int indexIndex = sizeIndex+1;
|
int indexIndex = sizeIndex+1;
|
||||||
|
|
||||||
v.dup();
|
v.dup();
|
||||||
@@ -1946,7 +1954,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
v.visitLabel(end);
|
v.visitLabel(end);
|
||||||
v.pop();
|
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);
|
JetType type = bindingContext.get(BindingContext.EXPRESSION_TYPE, array);
|
||||||
final Type arrayType = type == null ? Type.VOID_TYPE : typeMapper.mapType(type);
|
final Type arrayType = type == null ? Type.VOID_TYPE : typeMapper.mapType(type);
|
||||||
gen(array, arrayType);
|
gen(array, arrayType);
|
||||||
generateArrayIndex(expression);
|
final List<JetExpression> indices = expression.getIndexExpressions();
|
||||||
if (arrayType.getSort() == Type.ARRAY) {
|
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())) {
|
if(state.getStandardLibrary().getArray().equals(type.getConstructor().getDeclarationDescriptor())) {
|
||||||
JetType elementType = type.getArguments().get(0).getType();
|
JetType elementType = type.getArguments().get(0).getType();
|
||||||
Type notBoxed = typeMapper.mapType(elementType);
|
Type notBoxed = typeMapper.mapType(elementType);
|
||||||
@@ -1969,27 +1981,39 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DeclarationDescriptor operationDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, expression);
|
CallableMethod accessor = typeMapper.mapToCallableMethod(operationDescriptor, OwnerKind.IMPLEMENTATION);
|
||||||
CallableMethod accessor = typeMapper.mapToCallableMethod((FunctionDescriptor) operationDescriptor, OwnerKind.IMPLEMENTATION);
|
|
||||||
|
|
||||||
boolean isGetter = accessor.getSignature().getName().equals("get");
|
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) {
|
if(isGetter) {
|
||||||
ResolvedCall<FunctionDescriptor> resolvedCall = bindingContext.get(BindingContext.INDEXED_LVALUE_SET, expression);
|
if(getterDescriptor.getReceiverParameter().exists()) {
|
||||||
FunctionDescriptor setterDescriptor = resolvedCall == null ? null : resolvedCall.getResultingDescriptor();
|
index++;
|
||||||
return StackValue.collectionElement(
|
}
|
||||||
accessor.getSignature().getReturnType(),
|
asmType = accessor.getSignature().getReturnType();
|
||||||
accessor,
|
|
||||||
setterDescriptor != null ? typeMapper.mapToCallableMethod(setterDescriptor, OwnerKind.IMPLEMENTATION) : null);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ResolvedCall<FunctionDescriptor> resolvedCall = bindingContext.get(BindingContext.INDEXED_LVALUE_GET, expression);
|
if(setterDescriptor.getReceiverParameter().exists()) {
|
||||||
FunctionDescriptor getterDescriptor = resolvedCall == null ? null : resolvedCall.getResultingDescriptor();
|
index++;
|
||||||
return StackValue.collectionElement(
|
}
|
||||||
accessor.getSignature().getArgumentTypes()[1],
|
asmType = argumentTypes[argumentTypes.length-1];
|
||||||
getterDescriptor != null ? typeMapper.mapToCallableMethod(getterDescriptor, OwnerKind.IMPLEMENTATION) : null,
|
|
||||||
accessor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
@Override
|
||||||
public StackValue visitThrowExpression(JetThrowExpression expression, StackValue receiver) {
|
public StackValue visitThrowExpression(JetThrowExpression expression, StackValue receiver) {
|
||||||
gen(expression.getThrownExpression(), JetTypeMapper.TYPE_OBJECT);
|
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());
|
VariableDescriptor descriptor = bindingContext.get(BindingContext.VALUE_PARAMETER, clause.getCatchParameter());
|
||||||
assert descriptor != null;
|
assert descriptor != null;
|
||||||
Type descriptorType = typeMapper.mapType(descriptor.getOutType());
|
Type descriptorType = typeMapper.mapType(descriptor.getOutType());
|
||||||
myMap.enter(descriptor, 1);
|
myFrameMap.enter(descriptor, 1);
|
||||||
int index = lookupLocal(descriptor);
|
int index = lookupLocal(descriptor);
|
||||||
v.store(index, descriptorType);
|
v.store(index, descriptorType);
|
||||||
|
|
||||||
gen(clause.getCatchBody(), Type.VOID_TYPE);
|
gen(clause.getCatchBody(), Type.VOID_TYPE);
|
||||||
v.goTo(end); // TODO don't generate goto if there's no code following try/catch
|
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());
|
v.visitTryCatchBlock(tryStart, tryEnd, clauseStart, descriptorType.getInternalName());
|
||||||
}
|
}
|
||||||
if (finallyBlock != null) {
|
if (finallyBlock != null) {
|
||||||
Label finallyStart = new Label();
|
Label finallyStart = new Label();
|
||||||
v.mark(finallyStart);
|
v.mark(finallyStart);
|
||||||
|
|
||||||
int index = myMap.enterTemp();
|
int index = myFrameMap.enterTemp();
|
||||||
v.store(index, THROWABLE_TYPE);
|
v.store(index, THROWABLE_TYPE);
|
||||||
|
|
||||||
gen(finallyBlock.getFinalExpression(), Type.VOID_TYPE);
|
gen(finallyBlock.getFinalExpression(), Type.VOID_TYPE);
|
||||||
@@ -2104,7 +2121,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
v.load(index, THROWABLE_TYPE);
|
v.load(index, THROWABLE_TYPE);
|
||||||
v.athrow();
|
v.athrow();
|
||||||
|
|
||||||
myMap.leaveTemp();
|
myFrameMap.leaveTemp();
|
||||||
|
|
||||||
v.visitTryCatchBlock(tryStart, tryEnd, finallyStart, null);
|
v.visitTryCatchBlock(tryStart, tryEnd, finallyStart, null);
|
||||||
}
|
}
|
||||||
@@ -2159,7 +2176,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
if (pattern instanceof JetTypePattern) {
|
if (pattern instanceof JetTypePattern) {
|
||||||
JetTypeReference typeReference = ((JetTypePattern) pattern).getTypeReference();
|
JetTypeReference typeReference = ((JetTypePattern) pattern).getTypeReference();
|
||||||
JetType jetType = bindingContext.get(BindingContext.TYPE, typeReference);
|
JetType jetType = bindingContext.get(BindingContext.TYPE, typeReference);
|
||||||
expressionToMatch.dupReceiver(v, 0);
|
expressionToMatch.dupReceiver(v);
|
||||||
generateInstanceOf(expressionToMatch, jetType, false);
|
generateInstanceOf(expressionToMatch, jetType, false);
|
||||||
StackValue value = StackValue.onStack(Type.BOOLEAN_TYPE);
|
StackValue value = StackValue.onStack(Type.BOOLEAN_TYPE);
|
||||||
return negated ? StackValue.not(value) : value;
|
return negated ? StackValue.not(value) : value;
|
||||||
@@ -2169,7 +2186,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
}
|
}
|
||||||
else if (pattern instanceof JetExpressionPattern) {
|
else if (pattern instanceof JetExpressionPattern) {
|
||||||
final Type subjectType = expressionToMatch.type;
|
final Type subjectType = expressionToMatch.type;
|
||||||
expressionToMatch.dupReceiver(v, 0);
|
expressionToMatch.dupReceiver(v);
|
||||||
expressionToMatch.put(subjectType, v);
|
expressionToMatch.put(subjectType, v);
|
||||||
JetExpression condExpression = ((JetExpressionPattern) pattern).getExpression();
|
JetExpression condExpression = ((JetExpressionPattern) pattern).getExpression();
|
||||||
Type condType = isNumberPrimitive(subjectType) ? expressionType(condExpression) : OBJECT_TYPE;
|
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);
|
final VariableDescriptor variableDescriptor = bindingContext.get(BindingContext.VARIABLE, var);
|
||||||
assert variableDescriptor != null;
|
assert variableDescriptor != null;
|
||||||
final Type varType = typeMapper.mapType(variableDescriptor.getOutType());
|
final Type varType = typeMapper.mapType(variableDescriptor.getOutType());
|
||||||
myMap.enter(variableDescriptor, varType.getSize());
|
myFrameMap.enter(variableDescriptor, varType.getSize());
|
||||||
expressionToMatch.dupReceiver(v, 0);
|
expressionToMatch.dupReceiver(v);
|
||||||
expressionToMatch.put(varType, v);
|
expressionToMatch.put(varType, v);
|
||||||
final int varIndex = myMap.getIndex(variableDescriptor);
|
final int varIndex = myFrameMap.getIndex(variableDescriptor);
|
||||||
v.store(varIndex, varType);
|
v.store(varIndex, varType);
|
||||||
return generateWhenCondition(varType, varIndex, ((JetBindingPattern) pattern).getCondition(), null);
|
return generateWhenCondition(varType, varIndex, ((JetBindingPattern) pattern).getCondition(), null);
|
||||||
}
|
}
|
||||||
@@ -2202,7 +2219,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
|
|
||||||
Label lblFail = new Label();
|
Label lblFail = new Label();
|
||||||
Label lblDone = new Label();
|
Label lblDone = new Label();
|
||||||
expressionToMatch.dupReceiver(v, 0);
|
expressionToMatch.dupReceiver(v);
|
||||||
expressionToMatch.put(OBJECT_TYPE, v);
|
expressionToMatch.put(OBJECT_TYPE, v);
|
||||||
v.dup();
|
v.dup();
|
||||||
final String tupleClassName = "jet/Tuple" + entries.size();
|
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) {
|
public StackValue visitWhenExpression(JetWhenExpression expression, StackValue receiver) {
|
||||||
JetExpression expr = expression.getSubjectExpression();
|
JetExpression expr = expression.getSubjectExpression();
|
||||||
final Type subjectType = expressionType(expr);
|
final Type subjectType = expressionType(expr);
|
||||||
final int subjectLocal = myMap.enterTemp(subjectType.getSize());
|
final int subjectLocal = myFrameMap.enterTemp(subjectType.getSize());
|
||||||
gen(expr, subjectType);
|
gen(expr, subjectType);
|
||||||
v.store(subjectLocal, subjectType);
|
v.store(subjectLocal, subjectType);
|
||||||
|
|
||||||
@@ -2396,7 +2413,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
v.mark(nextCondition);
|
v.mark(nextCondition);
|
||||||
}
|
}
|
||||||
nextCondition = new Label();
|
nextCondition = new Label();
|
||||||
FrameMap.Mark mark = myMap.mark();
|
FrameMap.Mark mark = myFrameMap.mark();
|
||||||
Label thisEntry = new Label();
|
Label thisEntry = new Label();
|
||||||
if (!whenEntry.isElse()) {
|
if (!whenEntry.isElse()) {
|
||||||
final JetWhenCondition[] conditions = whenEntry.getConditions();
|
final JetWhenCondition[] conditions = whenEntry.getConditions();
|
||||||
@@ -2424,7 +2441,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
}
|
}
|
||||||
v.mark(end);
|
v.mark(end);
|
||||||
|
|
||||||
myMap.leaveTemp(subjectType.getSize());
|
myFrameMap.leaveTemp(subjectType.getSize());
|
||||||
return StackValue.onStack(expressionType(expression));
|
return StackValue.onStack(expressionType(expression));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -81,9 +81,10 @@ public class FunctionCodegen {
|
|||||||
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, jvmSignature.getReturnType(), context, state);
|
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, jvmSignature.getReturnType(), context, state);
|
||||||
|
|
||||||
Type[] argTypes = jvmSignature.getArgumentTypes();
|
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++) {
|
for (int i = 0; i < paramDescrs.size(); i++) {
|
||||||
ValueParameterDescriptor parameter = paramDescrs.get(i);
|
ValueParameterDescriptor parameter = paramDescrs.get(i);
|
||||||
frameMap.enter(parameter, argTypes[i].getSize());
|
frameMap.enter(parameter, argTypes[i+add].getSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
|
for (final TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
|
||||||
|
|||||||
@@ -547,6 +547,9 @@ public class JetTypeMapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public CallableMethod mapToCallableMethod(FunctionDescriptor functionDescriptor, OwnerKind kind) {
|
public CallableMethod mapToCallableMethod(FunctionDescriptor functionDescriptor, OwnerKind kind) {
|
||||||
|
if(functionDescriptor == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
final DeclarationDescriptor functionParent = functionDescriptor.getContainingDeclaration();
|
final DeclarationDescriptor functionParent = functionDescriptor.getContainingDeclaration();
|
||||||
final List<Type> valueParameterTypes = new ArrayList<Type>();
|
final List<Type> valueParameterTypes = new ArrayList<Type>();
|
||||||
Method descriptor = mapSignature(functionDescriptor.getOriginal(), valueParameterTypes, kind);
|
Method descriptor = mapSignature(functionDescriptor.getOriginal(), valueParameterTypes, kind);
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ public abstract class StackValue {
|
|||||||
throw new UnsupportedOperationException("cannot store to value " + this);
|
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) {
|
public void condJump(Label label, boolean jumpIfFalse, InstructionAdapter v) {
|
||||||
@@ -84,8 +84,8 @@ public abstract class StackValue {
|
|||||||
return new ArrayElement(type, unbox);
|
return new ArrayElement(type, unbox);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static StackValue collectionElement(Type type, CallableMethod getter, CallableMethod setter) {
|
public static StackValue collectionElement(Type type, CallableMethod getter, CallableMethod setter, FrameMap frame) {
|
||||||
return new CollectionElement(type, getter, setter);
|
return new CollectionElement(type, getter, setter, frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static StackValue field(Type type, String owner, String name, boolean isStatic) {
|
public static StackValue field(Type type, String owner, String name, boolean isStatic) {
|
||||||
@@ -456,24 +456,21 @@ public abstract class StackValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dupReceiver(InstructionAdapter v, int below) {
|
public void dupReceiver(InstructionAdapter v) {
|
||||||
if (below == 1) {
|
v.dup2(); // array and index
|
||||||
v.dup2X1();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
v.dup2(); // array and index
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class CollectionElement extends StackValue {
|
private static class CollectionElement extends StackValue {
|
||||||
private final CallableMethod getter;
|
private final CallableMethod getter;
|
||||||
private final CallableMethod setter;
|
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);
|
super(type);
|
||||||
this.getter = getter;
|
this.getter = getter;
|
||||||
this.setter = setter;
|
this.setter = setter;
|
||||||
|
this.frame = frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -494,13 +491,70 @@ public abstract class StackValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dupReceiver(InstructionAdapter v, int below) {
|
public void dupReceiver(InstructionAdapter v) {
|
||||||
if (below == 1) {
|
int size = calcSize();
|
||||||
v.dup2X1();
|
|
||||||
}
|
if(size == 2) {
|
||||||
else {
|
|
||||||
v.dup2(); // collection and index
|
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
|
@Override
|
||||||
public void dupReceiver(InstructionAdapter v, int below) {
|
public void dupReceiver(InstructionAdapter v) {
|
||||||
if (!isStatic) {
|
if (!isStatic) {
|
||||||
if (below == 1) {
|
v.dup();
|
||||||
v.dupX1();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
v.dup();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -557,7 +606,7 @@ public abstract class StackValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dupReceiver(InstructionAdapter v, int below) {
|
public void dupReceiver(InstructionAdapter v) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -607,14 +656,9 @@ public abstract class StackValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dupReceiver(InstructionAdapter v, int below) {
|
public void dupReceiver(InstructionAdapter v) {
|
||||||
if (!isStatic) {
|
if (!isStatic) {
|
||||||
if (below == 1) {
|
v.dup();
|
||||||
v.dupX1();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
v.dup();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -716,13 +760,8 @@ public abstract class StackValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dupReceiver(InstructionAdapter v, int below) {
|
public void dupReceiver(InstructionAdapter v) {
|
||||||
if (below == 1) {
|
v.dup();
|
||||||
v.dupX1();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
v.dup();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public class Increment implements IntrinsicMethod {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
StackValue value = codegen.genQualified(receiver, operand);
|
StackValue value = codegen.genQualified(receiver, operand);
|
||||||
value.dupReceiver(v, 0);
|
value. dupReceiver(v);
|
||||||
value.put(expectedType, v);
|
value.put(expectedType, v);
|
||||||
if (expectedType == Type.LONG_TYPE) {
|
if (expectedType == Type.LONG_TYPE) {
|
||||||
v.lconst(myDelta);
|
v.lconst(myDelta);
|
||||||
|
|||||||
@@ -107,4 +107,63 @@ public class ArrayGenTest extends CodegenTestCase {
|
|||||||
Method foo = generateFunction();
|
Method foo = generateFunction();
|
||||||
assertTrue((Integer)foo.invoke(null) == 12);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user