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