Propagate KotlinType into codegen methods where it's possible
This commit is contained in:
@@ -75,7 +75,7 @@ interface CallGenerator {
|
|||||||
|
|
||||||
override fun putCapturedValueOnStack(
|
override fun putCapturedValueOnStack(
|
||||||
stackValue: StackValue, valueType: Type, paramIndex: Int) {
|
stackValue: StackValue, valueType: Type, paramIndex: Int) {
|
||||||
stackValue.put(stackValue.type, codegen.v)
|
stackValue.put(stackValue.type, stackValue.kotlinType, codegen.v)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun putValueIfNeeded(parameterType: JvmKotlinType, value: StackValue, kind: ValueKind, parameterIndex: Int) {
|
override fun putValueIfNeeded(parameterType: JvmKotlinType, value: StackValue, kind: ValueKind, parameterIndex: Int) {
|
||||||
|
|||||||
+6
-4
@@ -179,15 +179,16 @@ class DefaultParameterValueSubstitutor(val state: GenerationState) {
|
|||||||
val delegateOwner = delegateFunctionDescriptor.containingDeclaration
|
val delegateOwner = delegateFunctionDescriptor.containingDeclaration
|
||||||
if (delegateOwner is ClassDescriptor && delegateOwner.isCompanionObject) {
|
if (delegateOwner is ClassDescriptor && delegateOwner.isCompanionObject) {
|
||||||
val singletonValue = StackValue.singleton(delegateOwner, typeMapper)
|
val singletonValue = StackValue.singleton(delegateOwner, typeMapper)
|
||||||
singletonValue.put(singletonValue.type, v)
|
singletonValue.put(singletonValue.type, singletonValue.kotlinType, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val receiver = functionDescriptor.extensionReceiverParameter
|
val receiver = functionDescriptor.extensionReceiverParameter
|
||||||
if (receiver != null) {
|
if (receiver != null) {
|
||||||
|
val receiverKotlinType = receiver.returnType
|
||||||
val receiverType = typeMapper.mapType(receiver)
|
val receiverType = typeMapper.mapType(receiver)
|
||||||
val receiverIndex = frameMap.enter(receiver, receiverType)
|
val receiverIndex = frameMap.enter(receiver, receiverType)
|
||||||
StackValue.local(receiverIndex, receiverType).put(receiverType, v)
|
StackValue.local(receiverIndex, receiverType, receiverKotlinType).put(receiverType, receiverKotlinType, v)
|
||||||
}
|
}
|
||||||
for (parameter in remainingParameters) {
|
for (parameter in remainingParameters) {
|
||||||
frameMap.enter(parameter, typeMapper.mapType(parameter))
|
frameMap.enter(parameter, typeMapper.mapType(parameter))
|
||||||
@@ -196,10 +197,11 @@ class DefaultParameterValueSubstitutor(val state: GenerationState) {
|
|||||||
var mask = 0
|
var mask = 0
|
||||||
val masks = arrayListOf<Int>()
|
val masks = arrayListOf<Int>()
|
||||||
for (parameterDescriptor in functionDescriptor.valueParameters) {
|
for (parameterDescriptor in functionDescriptor.valueParameters) {
|
||||||
val paramType = typeMapper.mapType(parameterDescriptor.type)
|
val paramKotlinType = parameterDescriptor.type
|
||||||
|
val paramType = typeMapper.mapType(paramKotlinType)
|
||||||
if (parameterDescriptor in remainingParameters) {
|
if (parameterDescriptor in remainingParameters) {
|
||||||
val index = frameMap.getIndex(parameterDescriptor)
|
val index = frameMap.getIndex(parameterDescriptor)
|
||||||
StackValue.local(index, paramType).put(paramType, v)
|
StackValue.local(index, paramType, paramKotlinType).put(paramType, paramKotlinType, v)
|
||||||
} else {
|
} else {
|
||||||
AsmUtil.pushDefaultValueOnStack(paramType, v)
|
AsmUtil.pushDefaultValueOnStack(paramType, v)
|
||||||
val i = parameterDescriptor.index
|
val i = parameterDescriptor.index
|
||||||
|
|||||||
@@ -724,6 +724,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
boolean isStatement
|
boolean isStatement
|
||||||
) {
|
) {
|
||||||
Type targetType = isStatement ? Type.VOID_TYPE : expressionType(ifExpression);
|
Type targetType = isStatement ? Type.VOID_TYPE : expressionType(ifExpression);
|
||||||
|
KotlinType targetKotlinType = isStatement ? null : kotlinType(ifExpression);
|
||||||
return StackValue.operation(targetType, v -> {
|
return StackValue.operation(targetType, v -> {
|
||||||
Label elseLabel = new Label();
|
Label elseLabel = new Label();
|
||||||
BranchedValue.Companion.condJump(condition, elseLabel, inverse, v);
|
BranchedValue.Companion.condJump(condition, elseLabel, inverse, v);
|
||||||
@@ -733,7 +734,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
v.mark(elseLabel);
|
v.mark(elseLabel);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
gen(expression, targetType);
|
gen(expression, targetType, targetKotlinType);
|
||||||
Label end = new Label();
|
Label end = new Label();
|
||||||
v.goTo(end);
|
v.goTo(end);
|
||||||
|
|
||||||
@@ -1554,7 +1555,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
putStackValue(returnedExpression, returnType, returnKotlinType, valueToReturn);
|
putStackValue(returnedExpression, returnType, returnKotlinType, valueToReturn);
|
||||||
|
|
||||||
Label afterReturnLabel = new Label();
|
Label afterReturnLabel = new Label();
|
||||||
generateFinallyBlocksIfNeeded(returnType, afterReturnLabel);
|
generateFinallyBlocksIfNeeded(returnType, returnKotlinType, afterReturnLabel);
|
||||||
|
|
||||||
if (isNonLocalReturn) {
|
if (isNonLocalReturn) {
|
||||||
generateGlobalReturnFlag(v, nonLocalReturn.labelName);
|
generateGlobalReturnFlag(v, nonLocalReturn.labelName);
|
||||||
@@ -1569,12 +1570,16 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void generateFinallyBlocksIfNeeded(Type returnType, @NotNull Label afterReturnLabel) {
|
public void generateFinallyBlocksIfNeeded(
|
||||||
|
@NotNull Type returnType,
|
||||||
|
@Nullable KotlinType returnKotlinType,
|
||||||
|
@NotNull Label afterReturnLabel
|
||||||
|
) {
|
||||||
if (hasFinallyBlocks()) {
|
if (hasFinallyBlocks()) {
|
||||||
if (!Type.VOID_TYPE.equals(returnType)) {
|
if (!Type.VOID_TYPE.equals(returnType)) {
|
||||||
int returnValIndex = myFrameMap.enterTemp(returnType);
|
int returnValIndex = myFrameMap.enterTemp(returnType);
|
||||||
StackValue.Local localForReturnValue = StackValue.local(returnValIndex, returnType);
|
StackValue.Local localForReturnValue = StackValue.local(returnValIndex, returnType, returnKotlinType);
|
||||||
localForReturnValue.store(StackValue.onStack(returnType), v);
|
localForReturnValue.store(StackValue.onStack(returnType, returnKotlinType), v);
|
||||||
doFinallyOnReturn(afterReturnLabel);
|
doFinallyOnReturn(afterReturnLabel);
|
||||||
localForReturnValue.put(returnType, null, v);
|
localForReturnValue.put(returnType, null, v);
|
||||||
myFrameMap.leaveTemp(returnType);
|
myFrameMap.leaveTemp(returnType);
|
||||||
@@ -1899,7 +1904,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
return StackValue.shared(parameterOffsetInConstructor, parentResult.type);
|
return StackValue.shared(parameterOffsetInConstructor, parentResult.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
return adjustVariableValue(StackValue.local(parameterOffsetInConstructor, parentResult.type), descriptor);
|
return adjustVariableValue(StackValue.local(parameterOffsetInConstructor, parentResult.type, parentResult.kotlinType), descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
private StackValue stackValueForLocal(DeclarationDescriptor descriptor, int index) {
|
private StackValue stackValueForLocal(DeclarationDescriptor descriptor, int index) {
|
||||||
@@ -2862,9 +2867,9 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
boolean arrayOfReferences = KotlinBuiltIns.isArray(outType);
|
boolean arrayOfReferences = KotlinBuiltIns.isArray(outType);
|
||||||
if (size == 1) {
|
if (size == 1) {
|
||||||
Type arrayType = getArrayType(arrayOfReferences ? AsmTypes.OBJECT_TYPE : elementType);
|
Type arrayType = getArrayType(arrayOfReferences ? AsmTypes.OBJECT_TYPE : elementType);
|
||||||
return StackValue.operation(type, adapter -> {
|
return StackValue.operation(type, outType, adapter -> {
|
||||||
KtExpression spreadArgument = arguments.get(0).getArgumentExpression();
|
KtExpression spreadArgument = arguments.get(0).getArgumentExpression();
|
||||||
gen(spreadArgument, type);
|
gen(spreadArgument, type, outType);
|
||||||
if (!canSkipArrayCopyForSpreadArgument(spreadArgument)) {
|
if (!canSkipArrayCopyForSpreadArgument(spreadArgument)) {
|
||||||
v.dup();
|
v.dup();
|
||||||
v.arraylength();
|
v.arraylength();
|
||||||
@@ -3671,12 +3676,12 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
FunctionDescriptor descriptor = accessibleFunctionDescriptor(resolvedCall);
|
FunctionDescriptor descriptor = accessibleFunctionDescriptor(resolvedCall);
|
||||||
Callable callable = resolveToCallable(descriptor, false, resolvedCall);
|
Callable callable = resolveToCallable(descriptor, false, resolvedCall);
|
||||||
KtExpression lhs = expression.getLeft();
|
KtExpression lhs = expression.getLeft();
|
||||||
Type lhsType = expressionType(lhs);
|
JvmKotlinType jvmKotlinType = new JvmKotlinType(expressionType(lhs), kotlinType(lhs));
|
||||||
|
|
||||||
boolean keepReturnValue = Boolean.TRUE.equals(bindingContext.get(VARIABLE_REASSIGNMENT, expression))
|
boolean keepReturnValue = Boolean.TRUE.equals(bindingContext.get(VARIABLE_REASSIGNMENT, expression))
|
||||||
|| !KotlinBuiltIns.isUnit(descriptor.getReturnType());
|
|| !KotlinBuiltIns.isUnit(descriptor.getReturnType());
|
||||||
|
|
||||||
putCallAugAssignMethod(expression, resolvedCall, callable, lhsType, keepReturnValue);
|
putCallAugAssignMethod(expression, resolvedCall, callable, descriptor.getReturnType(), jvmKotlinType, keepReturnValue);
|
||||||
|
|
||||||
return Unit.INSTANCE;
|
return Unit.INSTANCE;
|
||||||
});
|
});
|
||||||
@@ -3686,20 +3691,21 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
@NotNull KtBinaryExpression expression,
|
@NotNull KtBinaryExpression expression,
|
||||||
@NotNull ResolvedCall<?> resolvedCall,
|
@NotNull ResolvedCall<?> resolvedCall,
|
||||||
@NotNull Callable callable,
|
@NotNull Callable callable,
|
||||||
@NotNull Type lhsType,
|
@Nullable KotlinType returnKotlinType,
|
||||||
|
@NotNull JvmKotlinType jvmKotlinType,
|
||||||
boolean keepReturnValue
|
boolean keepReturnValue
|
||||||
) {
|
) {
|
||||||
StackValue value = gen(expression.getLeft());
|
StackValue value = gen(expression.getLeft());
|
||||||
if (keepReturnValue) {
|
if (keepReturnValue) {
|
||||||
value = StackValue.complexWriteReadReceiver(value);
|
value = StackValue.complexWriteReadReceiver(value);
|
||||||
}
|
}
|
||||||
value.put(lhsType, null, v);
|
value.put(jvmKotlinType.getType(), jvmKotlinType.getKotlinType(), v);
|
||||||
StackValue receiver = StackValue.onStack(lhsType);
|
StackValue receiver = StackValue.onStack(jvmKotlinType.getType(), jvmKotlinType.getKotlinType());
|
||||||
|
|
||||||
callable.invokeMethodWithArguments(resolvedCall, receiver, this).put(callable.getReturnType(), null, v);
|
callable.invokeMethodWithArguments(resolvedCall, receiver, this).put(callable.getReturnType(), null, v);
|
||||||
|
|
||||||
if (keepReturnValue) {
|
if (keepReturnValue) {
|
||||||
value.store(StackValue.onStack(callable.getReturnType()), v, true);
|
value.store(StackValue.onStack(callable.getReturnType(), returnKotlinType), v, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3731,10 +3737,11 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
}
|
}
|
||||||
|
|
||||||
Type exprType = expressionType(expr);
|
Type exprType = expressionType(expr);
|
||||||
|
KotlinType exprKotlinType = kotlinType(expr);
|
||||||
if (compileTimeConstant != null) {
|
if (compileTimeConstant != null) {
|
||||||
StackValue.constant(compileTimeConstant.getValue(), exprType).put(exprType, null, v);
|
StackValue.constant(compileTimeConstant.getValue(), exprType).put(exprType, null, v);
|
||||||
} else {
|
} else {
|
||||||
gen(expr, exprType);
|
gen(expr, exprType, exprKotlinType);
|
||||||
}
|
}
|
||||||
genInvokeAppendMethod(v, exprType.getSort() == Type.ARRAY ? OBJECT_TYPE : exprType);
|
genInvokeAppendMethod(v, exprType.getSort() == Type.ARRAY ? OBJECT_TYPE : exprType);
|
||||||
}
|
}
|
||||||
@@ -3805,6 +3812,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
|
|
||||||
Type asmResultType = expressionType(expression);
|
Type asmResultType = expressionType(expression);
|
||||||
Type asmBaseType = expressionType(expression.getBaseExpression());
|
Type asmBaseType = expressionType(expression.getBaseExpression());
|
||||||
|
KotlinType kotlinBaseType = kotlinType(expression.getBaseExpression());
|
||||||
|
|
||||||
DeclarationDescriptor cls = op.getContainingDeclaration();
|
DeclarationDescriptor cls = op.getContainingDeclaration();
|
||||||
|
|
||||||
@@ -3832,29 +3840,32 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return StackValue.operation(asmBaseType, v -> {
|
return StackValue.operation(asmBaseType, kotlinBaseType, v -> {
|
||||||
StackValue value = StackValue.complexWriteReadReceiver(gen(expression.getBaseExpression()));
|
StackValue value = StackValue.complexWriteReadReceiver(gen(expression.getBaseExpression()));
|
||||||
|
|
||||||
value.put(asmBaseType, null, v);
|
value.put(asmBaseType, kotlinBaseType, v);
|
||||||
AsmUtil.dup(v, asmBaseType);
|
AsmUtil.dup(v, asmBaseType);
|
||||||
|
|
||||||
StackValue previousValue = StackValue.local(myFrameMap.enterTemp(asmBaseType), asmBaseType);
|
StackValue previousValue = StackValue.local(myFrameMap.enterTemp(asmBaseType), asmBaseType, kotlinBaseType);
|
||||||
previousValue.store(StackValue.onStack(asmBaseType), v);
|
previousValue.store(StackValue.onStack(asmBaseType, kotlinBaseType), v);
|
||||||
|
|
||||||
Type storeType;
|
Type storeType;
|
||||||
|
KotlinType storeKotlinType;
|
||||||
if (isPrimitiveNumberClassDescriptor && AsmUtil.isPrimitive(asmBaseType)) {
|
if (isPrimitiveNumberClassDescriptor && AsmUtil.isPrimitive(asmBaseType)) {
|
||||||
genIncrement(asmBaseType, increment, v);
|
genIncrement(asmBaseType, increment, v);
|
||||||
storeType = asmBaseType;
|
storeType = asmBaseType;
|
||||||
|
storeKotlinType = kotlinBaseType;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
StackValue result = invokeFunction(resolvedCall, StackValue.onStack(asmBaseType));
|
StackValue result = invokeFunction(resolvedCall, StackValue.onStack(asmBaseType, kotlinBaseType));
|
||||||
result.put(result.type, result.kotlinType, v);
|
result.put(result.type, result.kotlinType, v);
|
||||||
storeType = result.type;
|
storeType = result.type;
|
||||||
|
storeKotlinType = result.kotlinType;
|
||||||
}
|
}
|
||||||
|
|
||||||
value.store(StackValue.onStack(storeType), v, true);
|
value.store(StackValue.onStack(storeType, storeKotlinType), v, true);
|
||||||
|
|
||||||
previousValue.put(asmBaseType, null, v);
|
previousValue.put(asmBaseType, kotlinBaseType, v);
|
||||||
|
|
||||||
myFrameMap.leaveTemp(asmBaseType);
|
myFrameMap.leaveTemp(asmBaseType);
|
||||||
|
|
||||||
@@ -3902,9 +3913,9 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
|
|
||||||
int tempVarIndex = myFrameMap.enterTemp(initializerAsmType);
|
int tempVarIndex = myFrameMap.enterTemp(initializerAsmType);
|
||||||
|
|
||||||
gen(initializer, initializerAsmType);
|
gen(initializer, initializerAsmType, initializerType);
|
||||||
v.store(tempVarIndex, initializerAsmType);
|
v.store(tempVarIndex, initializerAsmType);
|
||||||
StackValue.Local local = StackValue.local(tempVarIndex, initializerAsmType);
|
StackValue.Local local = StackValue.local(tempVarIndex, initializerAsmType, initializerType);
|
||||||
|
|
||||||
initializeDestructuringDeclarationVariables(multiDeclaration, initializerAsReceiver, local, asProperty);
|
initializeDestructuringDeclarationVariables(multiDeclaration, initializerAsReceiver, local, asProperty);
|
||||||
|
|
||||||
@@ -4025,7 +4036,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
StackValue metadataValue,
|
StackValue metadataValue,
|
||||||
ResolvedCall<FunctionDescriptor> provideDelegateResolvedCall
|
ResolvedCall<FunctionDescriptor> provideDelegateResolvedCall
|
||||||
) {
|
) {
|
||||||
StackValue provideDelegateReceiver = StackValue.onStack(initializer.type);
|
StackValue provideDelegateReceiver = StackValue.onStack(initializer.type, initializer.kotlinType);
|
||||||
|
|
||||||
List<? extends ValueArgument> arguments = provideDelegateResolvedCall.getCall().getValueArguments();
|
List<? extends ValueArgument> arguments = provideDelegateResolvedCall.getCall().getValueArguments();
|
||||||
assert arguments.size() == 2 :
|
assert arguments.size() == 2 :
|
||||||
@@ -4291,8 +4302,9 @@ The "returned" value of try expression with no finally is either the last expres
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
Type expectedAsmType = isStatement ? Type.VOID_TYPE : expressionType(expression);
|
Type expectedAsmType = isStatement ? Type.VOID_TYPE : expressionType(expression);
|
||||||
|
KotlinType expectedKotlinType = isStatement ? null : kotlinType(expression);
|
||||||
|
|
||||||
return StackValue.operation(expectedAsmType, v -> {
|
return StackValue.operation(expectedAsmType, expectedKotlinType, v -> {
|
||||||
KtFinallySection finallyBlock = expression.getFinallyBlock();
|
KtFinallySection finallyBlock = expression.getFinallyBlock();
|
||||||
FinallyBlockStackElement finallyBlockStackElement = null;
|
FinallyBlockStackElement finallyBlockStackElement = null;
|
||||||
if (finallyBlock != null) {
|
if (finallyBlock != null) {
|
||||||
@@ -4306,7 +4318,7 @@ The "returned" value of try expression with no finally is either the last expres
|
|||||||
v.mark(tryStart);
|
v.mark(tryStart);
|
||||||
v.nop(); // prevent verify error on empty try
|
v.nop(); // prevent verify error on empty try
|
||||||
|
|
||||||
gen(expression.getTryBlock(), expectedAsmType);
|
gen(expression.getTryBlock(), expectedAsmType, expectedKotlinType);
|
||||||
|
|
||||||
int savedValue = -1;
|
int savedValue = -1;
|
||||||
if (!isStatement) {
|
if (!isStatement) {
|
||||||
@@ -4346,7 +4358,7 @@ The "returned" value of try expression with no finally is either the last expres
|
|||||||
Label catchVariableStart = new Label();
|
Label catchVariableStart = new Label();
|
||||||
v.mark(catchVariableStart);
|
v.mark(catchVariableStart);
|
||||||
|
|
||||||
gen(catchBody, expectedAsmType);
|
gen(catchBody, expectedAsmType, expectedKotlinType);
|
||||||
|
|
||||||
if (!isStatement) {
|
if (!isStatement) {
|
||||||
v.store(savedValue, expectedAsmType);
|
v.store(savedValue, expectedAsmType);
|
||||||
@@ -4589,20 +4601,23 @@ The "returned" value of try expression with no finally is either the last expres
|
|||||||
|
|
||||||
int subjectLocal;
|
int subjectLocal;
|
||||||
Type subjectType;
|
Type subjectType;
|
||||||
|
KotlinType subjectKotlinType;
|
||||||
VariableDescriptor subjectVariableDescriptor = null;
|
VariableDescriptor subjectVariableDescriptor = null;
|
||||||
if (subjectVariable != null) {
|
if (subjectVariable != null) {
|
||||||
subjectVariableDescriptor = bindingContext.get(BindingContext.VARIABLE, subjectVariable);
|
subjectVariableDescriptor = bindingContext.get(BindingContext.VARIABLE, subjectVariable);
|
||||||
assert subjectVariableDescriptor != null : "Unresolved subject variable: " + subjectVariable.getName();
|
assert subjectVariableDescriptor != null : "Unresolved subject variable: " + subjectVariable.getName();
|
||||||
|
subjectKotlinType = subjectVariableDescriptor.getType();
|
||||||
subjectType = asmType(subjectVariableDescriptor.getType());
|
subjectType = asmType(subjectVariableDescriptor.getType());
|
||||||
subjectLocal = myFrameMap.enter(subjectVariableDescriptor, subjectType);
|
subjectLocal = myFrameMap.enter(subjectVariableDescriptor, subjectType);
|
||||||
visitProperty(subjectVariable, null);
|
visitProperty(subjectVariable, null);
|
||||||
tempVariables.put(subjectExpression, StackValue.local(subjectLocal, subjectType));
|
tempVariables.put(subjectExpression, StackValue.local(subjectLocal, subjectType, subjectKotlinType));
|
||||||
}
|
}
|
||||||
else if (subjectExpression != null) {
|
else if (subjectExpression != null) {
|
||||||
|
subjectKotlinType = kotlinType(subjectExpression);
|
||||||
subjectType = expressionType(subjectExpression);
|
subjectType = expressionType(subjectExpression);
|
||||||
subjectLocal = myFrameMap.enterTemp(subjectType);
|
subjectLocal = myFrameMap.enterTemp(subjectType);
|
||||||
gen(subjectExpression, subjectType);
|
gen(subjectExpression, subjectType, subjectKotlinType);
|
||||||
tempVariables.put(subjectExpression, StackValue.local(subjectLocal, subjectType));
|
tempVariables.put(subjectExpression, StackValue.local(subjectLocal, subjectType, subjectKotlinType));
|
||||||
v.store(subjectLocal, subjectType);
|
v.store(subjectLocal, subjectType);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -1614,7 +1614,7 @@ public class FunctionCodegen {
|
|||||||
|
|
||||||
StackValue stackValue = AsmUtil.genNotNullAssertions(
|
StackValue stackValue = AsmUtil.genNotNullAssertions(
|
||||||
state,
|
state,
|
||||||
StackValue.onStack(delegateToMethod.getReturnType()),
|
StackValue.onStack(delegateToMethod.getReturnType(), delegatedTo.getReturnType()),
|
||||||
RuntimeAssertionInfo.create(
|
RuntimeAssertionInfo.create(
|
||||||
delegateFunction.getReturnType(),
|
delegateFunction.getReturnType(),
|
||||||
delegatedTo.getReturnType(),
|
delegatedTo.getReturnType(),
|
||||||
@@ -1622,7 +1622,7 @@ public class FunctionCodegen {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
stackValue.put(delegateMethod.getReturnType(), iv);
|
stackValue.put(delegateMethod.getReturnType(), delegatedTo.getReturnType(), iv);
|
||||||
|
|
||||||
iv.areturn(delegateMethod.getReturnType());
|
iv.areturn(delegateMethod.getReturnType());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -579,7 +579,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
iv.store(2, OBJECT_TYPE);
|
iv.store(2, OBJECT_TYPE);
|
||||||
|
|
||||||
for (PropertyDescriptor propertyDescriptor : properties) {
|
for (PropertyDescriptor propertyDescriptor : properties) {
|
||||||
Type asmType = typeMapper.mapType(propertyDescriptor);
|
KotlinType kotlinType = propertyDescriptor.getReturnType();
|
||||||
|
Type asmType = typeMapper.mapType(kotlinType);
|
||||||
|
|
||||||
Type thisPropertyType = genPropertyOnStack(iv, context, propertyDescriptor, ImplementationBodyCodegen.this.classAsmType, 0);
|
Type thisPropertyType = genPropertyOnStack(iv, context, propertyDescriptor, ImplementationBodyCodegen.this.classAsmType, 0);
|
||||||
StackValue.coerce(thisPropertyType, asmType, iv);
|
StackValue.coerce(thisPropertyType, asmType, iv);
|
||||||
@@ -596,8 +597,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
iv.ifne(ne);
|
iv.ifne(ne);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
StackValue value =
|
StackValue value = genEqualsForExpressionsOnStack(
|
||||||
genEqualsForExpressionsOnStack(KtTokens.EQEQ, StackValue.onStack(asmType), StackValue.onStack(asmType));
|
KtTokens.EQEQ, StackValue.onStack(asmType, kotlinType), StackValue.onStack(asmType, kotlinType)
|
||||||
|
);
|
||||||
value.put(Type.BOOLEAN_TYPE, iv);
|
value.put(Type.BOOLEAN_TYPE, iv);
|
||||||
iv.ifeq(ne);
|
iv.ifeq(ne);
|
||||||
}
|
}
|
||||||
@@ -1474,7 +1476,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
ClassDescriptor containingTrait = (ClassDescriptor) containingDeclaration;
|
ClassDescriptor containingTrait = (ClassDescriptor) containingDeclaration;
|
||||||
Type traitImplType = typeMapper.mapDefaultImpls(containingTrait);
|
Type traitImplType = typeMapper.mapDefaultImpls(containingTrait);
|
||||||
|
|
||||||
Method traitMethod = typeMapper.mapAsmMethod(interfaceFun.getOriginal(), OwnerKind.DEFAULT_IMPLS);
|
FunctionDescriptor originalInterfaceFun = interfaceFun.getOriginal();
|
||||||
|
Method traitMethod = typeMapper.mapAsmMethod(originalInterfaceFun, OwnerKind.DEFAULT_IMPLS);
|
||||||
|
|
||||||
Type[] argTypes = signature.getAsmMethod().getArgumentTypes();
|
Type[] argTypes = signature.getAsmMethod().getArgumentTypes();
|
||||||
Type[] originalArgTypes = traitMethod.getArgumentTypes();
|
Type[] originalArgTypes = traitMethod.getArgumentTypes();
|
||||||
@@ -1499,7 +1502,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Type returnType = signature.getReturnType();
|
Type returnType = signature.getReturnType();
|
||||||
StackValue.onStack(traitMethod.getReturnType()).put(returnType, iv);
|
StackValue.onStack(traitMethod.getReturnType(), originalInterfaceFun.getReturnType()).put(returnType, iv);
|
||||||
iv.areturn(returnType);
|
iv.areturn(returnType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -63,7 +63,7 @@ class JvmStaticInCompanionObjectGenerator(
|
|||||||
propertyValue.put(signature.returnType, iv)
|
propertyValue.put(signature.returnType, iv)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
propertyValue.store(StackValue.onStack(propertyValue.type), iv, true)
|
propertyValue.store(StackValue.onStack(propertyValue.type, propertyValue.kotlinType), iv, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -823,7 +823,7 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
|||||||
property.put(signature.getReturnType(), iv);
|
property.put(signature.getReturnType(), iv);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
property.store(StackValue.onStack(property.type), iv, true);
|
property.store(StackValue.onStack(property.type, property.kotlinType), iv, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
iv.areturn(signature.getReturnType());
|
iv.areturn(signature.getReturnType());
|
||||||
@@ -906,7 +906,7 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
|||||||
|
|
||||||
callableMethod.genInvokeInstruction(iv);
|
callableMethod.genInvokeInstruction(iv);
|
||||||
|
|
||||||
return StackValue.onStack(callableMethod.getReturnType());
|
return StackValue.onStack(callableMethod.getReturnType(), functionDescriptor.getReturnType());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void generateAssertField() {
|
public void generateAssertField() {
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ class PropertyReferenceCodegen(
|
|||||||
assert(receiverValue != null) { "Receiver expected for bound property reference: $classDescriptor" }
|
assert(receiverValue != null) { "Receiver expected for bound property reference: $classDescriptor" }
|
||||||
iv.anew(asmType)
|
iv.anew(asmType)
|
||||||
iv.dup()
|
iv.dup()
|
||||||
receiverValue!!.put(receiverValue.type, iv)
|
receiverValue!!.put(receiverValue.type, receiverValue.kotlinType, iv)
|
||||||
iv.invokespecial(asmType.internalName, "<init>", constructor.descriptor, false)
|
iv.invokespecial(asmType.internalName, "<init>", constructor.descriptor, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -265,7 +265,9 @@ class PropertyReferenceCodegen(
|
|||||||
val typeMapper = state.typeMapper
|
val typeMapper = state.typeMapper
|
||||||
if (target is PropertyImportedFromObject) {
|
if (target is PropertyImportedFromObject) {
|
||||||
val containingObject = target.containingObject
|
val containingObject = target.containingObject
|
||||||
StackValue.singleton(containingObject, typeMapper).put(typeMapper.mapClass(containingObject), v)
|
StackValue
|
||||||
|
.singleton(containingObject, typeMapper)
|
||||||
|
.put(typeMapper.mapClass(containingObject), containingObject.defaultType, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (receiverType != null) {
|
if (receiverType != null) {
|
||||||
@@ -276,7 +278,7 @@ class PropertyReferenceCodegen(
|
|||||||
else {
|
else {
|
||||||
val receivers = originalFunctionDesc.valueParameters.dropLast(if (isGetter) 0 else 1)
|
val receivers = originalFunctionDesc.valueParameters.dropLast(if (isGetter) 0 else 1)
|
||||||
receivers.forEachIndexed { i, valueParameterDescriptor ->
|
receivers.forEachIndexed { i, valueParameterDescriptor ->
|
||||||
StackValue.local(i + 1, OBJECT_TYPE).put(typeMapper.mapType(valueParameterDescriptor), v)
|
StackValue.local(i + 1, OBJECT_TYPE).put(typeMapper.mapType(valueParameterDescriptor), valueParameterDescriptor.type, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1821,7 +1821,7 @@ public abstract class StackValue {
|
|||||||
value = StackValue.complexReceiver(value, true, false, true);
|
value = StackValue.complexReceiver(value, true, false, true);
|
||||||
value.put(this.type, this.kotlinType, v);
|
value.put(this.type, this.kotlinType, v);
|
||||||
|
|
||||||
value.store(codegen.invokeFunction(resolvedCall, StackValue.onStack(this.type)), v, true);
|
value.store(codegen.invokeFunction(resolvedCall, StackValue.onStack(this.type, this.kotlinType)), v, true);
|
||||||
|
|
||||||
value.put(this.type, this.kotlinType, v, true);
|
value.put(this.type, this.kotlinType, v, true);
|
||||||
coerceTo(type, kotlinType, v);
|
coerceTo(type, kotlinType, v);
|
||||||
|
|||||||
@@ -68,10 +68,10 @@ public class RemapVisitor extends MethodBodyVisitor {
|
|||||||
StackValue inline = nodeRemapper.getFieldForInline(fin, null);
|
StackValue inline = nodeRemapper.getFieldForInline(fin, null);
|
||||||
assert inline != null : "Captured field should have not null stackValue " + fin;
|
assert inline != null : "Captured field should have not null stackValue " + fin;
|
||||||
if (Opcodes.PUTSTATIC == opcode) {
|
if (Opcodes.PUTSTATIC == opcode) {
|
||||||
inline.store(StackValue.onStack(inline.type), this);
|
inline.store(StackValue.onStack(inline.type, inline.kotlinType), this);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
inline.put(inline.type, this);
|
inline.put(inline.type, inline.kotlinType, this);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -349,7 +349,7 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
|
|||||||
frameMap.enterTemp(Type.INT_TYPE)
|
frameMap.enterTemp(Type.INT_TYPE)
|
||||||
}
|
}
|
||||||
|
|
||||||
finallyCodegen.generateFinallyBlocksIfNeeded(extension.returnType, extension.finallyIntervalEnd.label)
|
finallyCodegen.generateFinallyBlocksIfNeeded(extension.returnType, null, extension.finallyIntervalEnd.label)
|
||||||
|
|
||||||
//Exception table for external try/catch/finally blocks will be generated in original codegen after exiting this method
|
//Exception table for external try/catch/finally blocks will be generated in original codegen after exiting this method
|
||||||
insertNodeBefore(finallyNode, intoNode, curInstr)
|
insertNodeBefore(finallyNode, intoNode, curInstr)
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ class ArrayIndicesRangeValue(rangeCall: ResolvedCall<out CallableDescriptor>) :
|
|||||||
StackValue.constant(0, asmElementType),
|
StackValue.constant(0, asmElementType),
|
||||||
true,
|
true,
|
||||||
StackValue.operation(Type.INT_TYPE) { v ->
|
StackValue.operation(Type.INT_TYPE) { v ->
|
||||||
codegen.generateCallReceiver(rangeCall).put(codegen.asmType(expectedReceiverType), v)
|
codegen.generateCallReceiver(rangeCall).put(codegen.asmType(expectedReceiverType), expectedReceiverType, v)
|
||||||
v.arraylength()
|
v.arraylength()
|
||||||
},
|
},
|
||||||
false
|
false
|
||||||
|
|||||||
+1
-1
@@ -38,7 +38,7 @@ class CharSequenceIndicesRangeValue(rangeCall: ResolvedCall<out CallableDescript
|
|||||||
StackValue.constant(0, asmElementType),
|
StackValue.constant(0, asmElementType),
|
||||||
true,
|
true,
|
||||||
StackValue.operation(Type.INT_TYPE) { v ->
|
StackValue.operation(Type.INT_TYPE) { v ->
|
||||||
codegen.generateCallReceiver(rangeCall).put(codegen.asmType(expectedReceiverType), v)
|
codegen.generateCallReceiver(rangeCall).put(codegen.asmType(expectedReceiverType), expectedReceiverType, v)
|
||||||
v.invokeinterface("java/lang/CharSequence", "length", "()I")
|
v.invokeinterface("java/lang/CharSequence", "length", "()I")
|
||||||
},
|
},
|
||||||
false
|
false
|
||||||
|
|||||||
+1
-1
@@ -38,7 +38,7 @@ class CollectionIndicesRangeValue(rangeCall: ResolvedCall<out CallableDescriptor
|
|||||||
StackValue.constant(0, asmElementType),
|
StackValue.constant(0, asmElementType),
|
||||||
true,
|
true,
|
||||||
StackValue.operation(Type.INT_TYPE) { v ->
|
StackValue.operation(Type.INT_TYPE) { v ->
|
||||||
codegen.generateCallReceiver(rangeCall).put(codegen.asmType(expectedReceiverType), v)
|
codegen.generateCallReceiver(rangeCall).put(codegen.asmType(expectedReceiverType), expectedReceiverType, v)
|
||||||
v.invokeinterface("java/util/Collection", "size", "()I")
|
v.invokeinterface("java/util/Collection", "size", "()I")
|
||||||
},
|
},
|
||||||
false
|
false
|
||||||
|
|||||||
+9
-7
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.codegen.StackValue
|
|||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.KtForExpression
|
import org.jetbrains.kotlin.psi.KtForExpression
|
||||||
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.org.objectweb.asm.Label
|
import org.jetbrains.org.objectweb.asm.Label
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
|
|
||||||
@@ -28,14 +29,15 @@ abstract class AbstractForInProgressionLoopGenerator(codegen: ExpressionCodegen,
|
|||||||
AbstractForInProgressionOrRangeLoopGenerator(codegen, forExpression) {
|
AbstractForInProgressionOrRangeLoopGenerator(codegen, forExpression) {
|
||||||
protected var incrementVar: Int = -1
|
protected var incrementVar: Int = -1
|
||||||
protected val asmLoopRangeType: Type
|
protected val asmLoopRangeType: Type
|
||||||
|
protected val kotlinLoopRangeType: KotlinType
|
||||||
protected val incrementType: Type
|
protected val incrementType: Type
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val loopRangeType = bindingContext.getType(forExpression.loopRange!!)!!
|
kotlinLoopRangeType = bindingContext.getType(forExpression.loopRange!!)!!
|
||||||
asmLoopRangeType = codegen.asmType(loopRangeType)
|
asmLoopRangeType = codegen.asmType(kotlinLoopRangeType)
|
||||||
|
|
||||||
val incrementProp = loopRangeType.memberScope.getContributedVariables(Name.identifier("step"), NoLookupLocation.FROM_BACKEND)
|
val incrementProp = kotlinLoopRangeType.memberScope.getContributedVariables(Name.identifier("step"), NoLookupLocation.FROM_BACKEND)
|
||||||
assert(incrementProp.size == 1) { loopRangeType.toString() + " " + incrementProp.size }
|
assert(incrementProp.size == 1) { kotlinLoopRangeType.toString() + " " + incrementProp.size }
|
||||||
incrementType = codegen.asmType(incrementProp.iterator().next().type)
|
incrementType = codegen.asmType(incrementProp.iterator().next().type)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,7 +52,7 @@ abstract class AbstractForInProgressionLoopGenerator(codegen: ExpressionCodegen,
|
|||||||
protected abstract fun storeProgressionParametersToLocalVars()
|
protected abstract fun storeProgressionParametersToLocalVars()
|
||||||
|
|
||||||
override fun checkEmptyLoop(loopExit: Label) {
|
override fun checkEmptyLoop(loopExit: Label) {
|
||||||
loopParameter().put(asmElementType, v)
|
loopParameter().put(asmElementType, elementType, v)
|
||||||
v.load(endVar, asmElementType)
|
v.load(endVar, asmElementType)
|
||||||
v.load(incrementVar, incrementType)
|
v.load(incrementVar, incrementType)
|
||||||
|
|
||||||
@@ -92,7 +94,7 @@ abstract class AbstractForInProgressionLoopGenerator(codegen: ExpressionCodegen,
|
|||||||
checkPostCondition(loopExit)
|
checkPostCondition(loopExit)
|
||||||
|
|
||||||
val loopParameter = loopParameter()
|
val loopParameter = loopParameter()
|
||||||
loopParameter.put(asmElementType, v)
|
loopParameter.put(asmElementType, elementType, v)
|
||||||
v.load(incrementVar, asmElementType)
|
v.load(incrementVar, asmElementType)
|
||||||
v.add(asmElementType)
|
v.add(asmElementType)
|
||||||
|
|
||||||
@@ -100,6 +102,6 @@ abstract class AbstractForInProgressionLoopGenerator(codegen: ExpressionCodegen,
|
|||||||
StackValue.coerce(Type.INT_TYPE, asmElementType, v)
|
StackValue.coerce(Type.INT_TYPE, asmElementType, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
loopParameter.store(StackValue.onStack(asmElementType), v)
|
loopParameter.store(StackValue.onStack(asmElementType, elementType), v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+1
-1
@@ -50,7 +50,7 @@ abstract class AbstractForInProgressionOrRangeLoopGenerator(codegen: ExpressionC
|
|||||||
assert(endVar != -1) {
|
assert(endVar != -1) {
|
||||||
"endVar must be allocated, endVar = " + endVar
|
"endVar must be allocated, endVar = " + endVar
|
||||||
}
|
}
|
||||||
loopParameter().put(asmElementType, v)
|
loopParameter().put(asmElementType, elementType, v)
|
||||||
v.load(endVar, asmElementType)
|
v.load(endVar, asmElementType)
|
||||||
if (asmElementType.sort == Type.LONG) {
|
if (asmElementType.sort == Type.LONG) {
|
||||||
v.lcmp()
|
v.lcmp()
|
||||||
|
|||||||
+3
-3
@@ -38,7 +38,7 @@ abstract class AbstractForInRangeLoopGenerator(
|
|||||||
protected abstract fun storeRangeStartAndEnd()
|
protected abstract fun storeRangeStartAndEnd()
|
||||||
|
|
||||||
override fun checkEmptyLoop(loopExit: Label) {
|
override fun checkEmptyLoop(loopExit: Label) {
|
||||||
loopParameter().put(asmElementType, v)
|
loopParameter().put(asmElementType, elementType, v)
|
||||||
v.load(endVar, asmElementType)
|
v.load(endVar, asmElementType)
|
||||||
if (asmElementType.sort == Type.LONG) {
|
if (asmElementType.sort == Type.LONG) {
|
||||||
v.lcmp()
|
v.lcmp()
|
||||||
@@ -69,9 +69,9 @@ abstract class AbstractForInRangeLoopGenerator(
|
|||||||
v.iinc(loopParameterVar, step)
|
v.iinc(loopParameterVar, step)
|
||||||
} else {
|
} else {
|
||||||
val loopParameter = loopParameter()
|
val loopParameter = loopParameter()
|
||||||
loopParameter.put(asmElementType, v)
|
loopParameter.put(asmElementType, elementType, v)
|
||||||
genIncrement(asmElementType, step, v)
|
genIncrement(asmElementType, step, v)
|
||||||
loopParameter.store(StackValue.onStack(asmElementType), v)
|
loopParameter.store(StackValue.onStack(asmElementType, elementType), v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -24,7 +24,8 @@ class ArrayWithIndexForLoopGenerator(
|
|||||||
rangeCall: ResolvedCall<out CallableDescriptor>
|
rangeCall: ResolvedCall<out CallableDescriptor>
|
||||||
) : AbstractWithIndexForLoopGenerator(codegen, forExpression, loopParameter, rangeCall) {
|
) : AbstractWithIndexForLoopGenerator(codegen, forExpression, loopParameter, rangeCall) {
|
||||||
|
|
||||||
private val arrayType = codegen.asmType(ExpressionCodegen.getExpectedReceiverType(rangeCall))
|
private val arrayKotlinType = ExpressionCodegen.getExpectedReceiverType(rangeCall)
|
||||||
|
private val arrayType = codegen.asmType(arrayKotlinType)
|
||||||
private val arrayElementType = AsmUtil.correctElementType(arrayType)
|
private val arrayElementType = AsmUtil.correctElementType(arrayType)
|
||||||
private var arrayVar = -1
|
private var arrayVar = -1
|
||||||
private var arrayLengthVar = -1
|
private var arrayLengthVar = -1
|
||||||
@@ -43,7 +44,7 @@ class ArrayWithIndexForLoopGenerator(
|
|||||||
val arrayValue = StackValue.local(arrayVar, arrayType)
|
val arrayValue = StackValue.local(arrayVar, arrayType)
|
||||||
arrayValue.store(codegen.generateCallReceiver(rangeCall), v)
|
arrayValue.store(codegen.generateCallReceiver(rangeCall), v)
|
||||||
|
|
||||||
arrayValue.put(arrayType, v)
|
arrayValue.put(arrayType, arrayKotlinType, v)
|
||||||
v.arraylength()
|
v.arraylength()
|
||||||
v.store(arrayLengthVar, Type.INT_TYPE)
|
v.store(arrayLengthVar, Type.INT_TYPE)
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -49,7 +49,7 @@ class ForInArrayLoopGenerator(
|
|||||||
arrayVar = value.index // no need to copy local variable into another variable
|
arrayVar = value.index // no need to copy local variable into another variable
|
||||||
} else {
|
} else {
|
||||||
arrayVar = createLoopTempVariable(OBJECT_TYPE)
|
arrayVar = createLoopTempVariable(OBJECT_TYPE)
|
||||||
value.put(asmLoopRangeType, v)
|
value.put(asmLoopRangeType, loopRangeType, v)
|
||||||
v.store(arrayVar, OBJECT_TYPE)
|
v.store(arrayVar, OBJECT_TYPE)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -50,7 +50,7 @@ class ForInCharSequenceLoopGenerator(
|
|||||||
// (see controlStructures/forInCharSequenceMut.kt).
|
// (see controlStructures/forInCharSequenceMut.kt).
|
||||||
// We should always store the corresponding CharSequence to a local variable to preserve the Iterator-based behavior.
|
// We should always store the corresponding CharSequence to a local variable to preserve the Iterator-based behavior.
|
||||||
charSequenceVar = createLoopTempVariable(charSequenceType)
|
charSequenceVar = createLoopTempVariable(charSequenceType)
|
||||||
value.put(asmLoopRangeType, v)
|
value.put(asmLoopRangeType, loopRangeType, v)
|
||||||
v.store(charSequenceVar, charSequenceType)
|
v.store(charSequenceVar, charSequenceType)
|
||||||
|
|
||||||
if (canCacheLength) {
|
if (canCacheLength) {
|
||||||
@@ -81,7 +81,7 @@ class ForInCharSequenceLoopGenerator(
|
|||||||
v.load(charSequenceVar, charSequenceType)
|
v.load(charSequenceVar, charSequenceType)
|
||||||
v.load(indexVar, Type.INT_TYPE)
|
v.load(indexVar, Type.INT_TYPE)
|
||||||
v.invokeCharSequenceMethod("charAt", "(I)C")
|
v.invokeCharSequenceMethod("charAt", "(I)C")
|
||||||
StackValue.onStack(Type.CHAR_TYPE).put(asmElementType, codegen.v)
|
StackValue.onStack(Type.CHAR_TYPE).put(asmElementType, elementType, codegen.v)
|
||||||
v.store(loopParameterVar, asmElementType)
|
v.store(loopParameterVar, asmElementType)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -82,7 +82,7 @@ class ForInDefinitelySafeSimpleProgressionLoopGenerator(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun checkPreCondition(loopExit: Label) {
|
override fun checkPreCondition(loopExit: Label) {
|
||||||
loopParameter().put(asmElementType, v)
|
loopParameter().put(asmElementType, elementType, v)
|
||||||
v.load(endVar, asmElementType)
|
v.load(endVar, asmElementType)
|
||||||
if (asmElementType.sort == Type.LONG) {
|
if (asmElementType.sort == Type.LONG) {
|
||||||
v.lcmp()
|
v.lcmp()
|
||||||
|
|||||||
+1
-1
@@ -26,7 +26,7 @@ class ForInProgressionExpressionLoopGenerator(
|
|||||||
private val rangeExpression: KtExpression
|
private val rangeExpression: KtExpression
|
||||||
) : AbstractForInProgressionLoopGenerator(codegen, forExpression) {
|
) : AbstractForInProgressionLoopGenerator(codegen, forExpression) {
|
||||||
override fun storeProgressionParametersToLocalVars() {
|
override fun storeProgressionParametersToLocalVars() {
|
||||||
codegen.gen(rangeExpression, asmLoopRangeType)
|
codegen.gen(rangeExpression, asmLoopRangeType, kotlinLoopRangeType)
|
||||||
v.dup()
|
v.dup()
|
||||||
v.dup()
|
v.dup()
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -30,7 +30,7 @@ class ForInRangeInstanceLoopGenerator(
|
|||||||
override fun storeRangeStartAndEnd() {
|
override fun storeRangeStartAndEnd() {
|
||||||
val loopRangeType = codegen.bindingContext.getType(rangeExpression)!!
|
val loopRangeType = codegen.bindingContext.getType(rangeExpression)!!
|
||||||
val asmLoopRangeType = codegen.asmType(loopRangeType)
|
val asmLoopRangeType = codegen.asmType(loopRangeType)
|
||||||
codegen.gen(rangeExpression, asmLoopRangeType)
|
codegen.gen(rangeExpression, asmLoopRangeType, loopRangeType)
|
||||||
v.dup()
|
v.dup()
|
||||||
|
|
||||||
// ranges inherit first and last from corresponding progressions
|
// ranges inherit first and last from corresponding progressions
|
||||||
|
|||||||
+1
-1
@@ -91,7 +91,7 @@ class ForInSimpleProgressionLoopGenerator(
|
|||||||
override fun checkPreCondition(loopExit: Label) {
|
override fun checkPreCondition(loopExit: Label) {
|
||||||
// Generate pre-condition loop if end is not inclusive.
|
// Generate pre-condition loop if end is not inclusive.
|
||||||
if (!isEndInclusive) {
|
if (!isEndInclusive) {
|
||||||
loopParameter().put(asmElementType, v)
|
loopParameter().put(asmElementType, elementType, v)
|
||||||
v.load(endVar, asmElementType)
|
v.load(endVar, asmElementType)
|
||||||
if (asmElementType.sort == Type.LONG) {
|
if (asmElementType.sort == Type.LONG) {
|
||||||
v.lcmp()
|
v.lcmp()
|
||||||
|
|||||||
+1
-1
@@ -42,7 +42,7 @@ class CallBasedInExpressionGenerator(
|
|||||||
|
|
||||||
private fun invokeFunction(v: InstructionAdapter) {
|
private fun invokeFunction(v: InstructionAdapter) {
|
||||||
val result = codegen.invokeFunction(resolvedCall.call, resolvedCall, none())
|
val result = codegen.invokeFunction(resolvedCall.call, resolvedCall, none())
|
||||||
result.put(result.type, v)
|
result.put(result.type, result.kotlinType, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.codegen.`when`
|
package org.jetbrains.kotlin.codegen.`when`
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.cfg.WhenChecker
|
import org.jetbrains.kotlin.cfg.WhenChecker
|
||||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||||
import org.jetbrains.kotlin.codegen.StackValue
|
import org.jetbrains.kotlin.codegen.StackValue
|
||||||
@@ -13,6 +14,7 @@ import org.jetbrains.kotlin.psi.KtWhenExpression
|
|||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
||||||
import org.jetbrains.kotlin.resolve.constants.NullValue
|
import org.jetbrains.kotlin.resolve.constants.NullValue
|
||||||
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.TypeUtils
|
import org.jetbrains.kotlin.types.TypeUtils
|
||||||
import org.jetbrains.org.objectweb.asm.Label
|
import org.jetbrains.org.objectweb.asm.Label
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
@@ -41,6 +43,8 @@ abstract class SwitchCodegen(
|
|||||||
|
|
||||||
protected var subjectLocal = -1
|
protected var subjectLocal = -1
|
||||||
|
|
||||||
|
protected val resultKotlinType: KotlinType? = if (!isStatement) codegen.kotlinType(expression) else null
|
||||||
|
|
||||||
protected val resultType: Type = if (isStatement) Type.VOID_TYPE else codegen.expressionType(expression)
|
protected val resultType: Type = if (isStatement) Type.VOID_TYPE else codegen.expressionType(expression)
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
@@ -138,10 +142,10 @@ abstract class SwitchCodegen(
|
|||||||
?: throw AssertionError("Unresolved subject variable: $expression")
|
?: throw AssertionError("Unresolved subject variable: $expression")
|
||||||
subjectLocal = codegen.frameMap.enter(mySubjectVariable, subjectType)
|
subjectLocal = codegen.frameMap.enter(mySubjectVariable, subjectType)
|
||||||
codegen.visitProperty(subjectVariable, null)
|
codegen.visitProperty(subjectVariable, null)
|
||||||
StackValue.local(subjectLocal, subjectType).put(subjectType, codegen.v)
|
StackValue.local(subjectLocal, subjectType, subjectKotlinType).put(subjectType, subjectKotlinType, codegen.v)
|
||||||
subjectVariableDescriptor = mySubjectVariable
|
subjectVariableDescriptor = mySubjectVariable
|
||||||
} else {
|
} else {
|
||||||
codegen.gen(subjectExpression, subjectType)
|
codegen.gen(subjectExpression, subjectType, subjectKotlinType)
|
||||||
subjectVariableDescriptor = null
|
subjectVariableDescriptor = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -206,7 +210,7 @@ abstract class SwitchCodegen(
|
|||||||
v.visitLabel(entryLabelsIterator.next())
|
v.visitLabel(entryLabelsIterator.next())
|
||||||
|
|
||||||
val mark = codegen.myFrameMap.mark()
|
val mark = codegen.myFrameMap.mark()
|
||||||
codegen.gen(entry.expression, resultType)
|
codegen.gen(entry.expression, resultType, resultKotlinType)
|
||||||
mark.dropTo()
|
mark.dropTo()
|
||||||
|
|
||||||
if (!entry.isElse) {
|
if (!entry.isElse) {
|
||||||
|
|||||||
+9
-9
@@ -180,7 +180,7 @@ class ExpressionCodegen(
|
|||||||
//coerceNotToUnit(r.type, Type.VOID_TYPE)
|
//coerceNotToUnit(r.type, Type.VOID_TYPE)
|
||||||
exp.accept(this, data)
|
exp.accept(this, data)
|
||||||
}
|
}
|
||||||
return coerceNotToUnit(result.type, expression.type.toKotlinType())
|
return coerceNotToUnit(result.type, result.kotlinType, expression.type.toKotlinType())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitMemberAccess(expression: IrMemberAccessExpression, data: BlockInfo): StackValue {
|
override fun visitMemberAccess(expression: IrMemberAccessExpression, data: BlockInfo): StackValue {
|
||||||
@@ -306,7 +306,7 @@ class ExpressionCodegen(
|
|||||||
mv.aconst(null)
|
mv.aconst(null)
|
||||||
mv.athrow()
|
mv.athrow()
|
||||||
} else if (expression.descriptor !is ConstructorDescriptor) {
|
} else if (expression.descriptor !is ConstructorDescriptor) {
|
||||||
return returnType?.run { coerceNotToUnit(callable.returnType, this) } ?: onStack(callable.returnType)
|
return returnType?.run { coerceNotToUnit(callable.returnType, returnType, this) } ?: onStack(callable.returnType, returnType)
|
||||||
} else {
|
} else {
|
||||||
return none()
|
return none()
|
||||||
}
|
}
|
||||||
@@ -576,7 +576,7 @@ class ExpressionCodegen(
|
|||||||
|
|
||||||
val result = thenBranch.run {
|
val result = thenBranch.run {
|
||||||
val stackValue = gen(this, data)
|
val stackValue = gen(this, data)
|
||||||
coerceNotToUnit(stackValue.type, type)
|
coerceNotToUnit(stackValue.type, stackValue.kotlinType, type)
|
||||||
}
|
}
|
||||||
|
|
||||||
mv.goTo(end)
|
mv.goTo(end)
|
||||||
@@ -963,13 +963,13 @@ class ExpressionCodegen(
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun coerceNotToUnit(fromType: Type, toType: KotlinType): StackValue {
|
private fun coerceNotToUnit(fromType: Type, fromKotlinType: KotlinType?, toKotlinType: KotlinType): StackValue {
|
||||||
val asmType = toType.asmType
|
val asmToType = toKotlinType.asmType
|
||||||
if (asmType != AsmTypes.UNIT_TYPE || TypeUtils.isNullableType(toType)) {
|
if (asmToType != AsmTypes.UNIT_TYPE || TypeUtils.isNullableType(toKotlinType)) {
|
||||||
coerce(fromType, asmType, mv)
|
coerce(fromType, fromKotlinType, asmToType, toKotlinType, mv)
|
||||||
return onStack(asmType)
|
return onStack(asmToType, toKotlinType)
|
||||||
}
|
}
|
||||||
return onStack(fromType)
|
return onStack(fromType, fromKotlinType)
|
||||||
}
|
}
|
||||||
|
|
||||||
val IrExpression.asmType: Type
|
val IrExpression.asmType: Type
|
||||||
|
|||||||
+7
-1
@@ -74,7 +74,13 @@ class PrimitiveComparison(
|
|||||||
|
|
||||||
return object : IrIntrinsicFunction(expression, signature, context, listOf(parameterType, parameterType)) {
|
return object : IrIntrinsicFunction(expression, signature, context, listOf(parameterType, parameterType)) {
|
||||||
override fun genInvokeInstruction(v: InstructionAdapter) {
|
override fun genInvokeInstruction(v: InstructionAdapter) {
|
||||||
StackValue.cmp(operatorToken, parameterType, StackValue.onStack(parameterType), StackValue.onStack(parameterType))
|
StackValue
|
||||||
|
.cmp(
|
||||||
|
operatorToken,
|
||||||
|
parameterType,
|
||||||
|
StackValue.onStack(parameterType, primitiveNumberType),
|
||||||
|
StackValue.onStack(parameterType, primitiveNumberType)
|
||||||
|
)
|
||||||
.put(Type.BOOLEAN_TYPE, v)
|
.put(Type.BOOLEAN_TYPE, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -92,7 +92,7 @@ abstract class AbstractAndroidExtensionsExpressionCodegenExtension : ExpressionC
|
|||||||
return StackValue.functionCall(Type.VOID_TYPE, null) {
|
return StackValue.functionCall(Type.VOID_TYPE, null) {
|
||||||
val bytecodeClassName = c.typeMapper.mapType(container).internalName
|
val bytecodeClassName = c.typeMapper.mapType(container).internalName
|
||||||
|
|
||||||
actualReceiver.put(c.typeMapper.mapType(container), it)
|
actualReceiver.put(c.typeMapper.mapType(container), container.defaultType, it)
|
||||||
it.invokevirtual(bytecodeClassName, CLEAR_CACHE_METHOD_NAME, "()V", false)
|
it.invokevirtual(bytecodeClassName, CLEAR_CACHE_METHOD_NAME, "()V", false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -45,8 +45,9 @@ class ResourcePropertyStackValue(
|
|||||||
val syntheticProperty = resource as AndroidSyntheticProperty
|
val syntheticProperty = resource as AndroidSyntheticProperty
|
||||||
|
|
||||||
if ((containerOptions.cache ?: globalCacheImpl).hasCache && shouldCacheResource(resource)) {
|
if ((containerOptions.cache ?: globalCacheImpl).hasCache && shouldCacheResource(resource)) {
|
||||||
val declarationDescriptorType = typeMapper.mapType(container)
|
val declarationDescriptorKotlinType = container.defaultType
|
||||||
receiver.put(declarationDescriptorType, v)
|
val declarationDescriptorType = typeMapper.mapType(declarationDescriptorKotlinType)
|
||||||
|
receiver.put(declarationDescriptorType, declarationDescriptorKotlinType, v)
|
||||||
|
|
||||||
val resourceId = syntheticProperty.resource.id
|
val resourceId = syntheticProperty.resource.id
|
||||||
val packageName = resourceId.packageName ?: androidPackage
|
val packageName = resourceId.packageName ?: androidPackage
|
||||||
|
|||||||
Reference in New Issue
Block a user