Propagate KotlinType into codegen methods where it's possible

This commit is contained in:
Mikhail Zarechenskiy
2018-07-17 16:30:08 +03:00
parent ec9d8e580e
commit 045e3f53b0
30 changed files with 129 additions and 93 deletions
@@ -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) {
@@ -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);
}
}
@@ -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
@@ -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
@@ -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
@@ -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)
}
}
@@ -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()
@@ -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)
}
}
@@ -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)
@@ -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)
}
@@ -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)
}
@@ -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()
@@ -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()
@@ -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
@@ -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()
@@ -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) {
@@ -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
@@ -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)
}
}
@@ -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)
}
}
@@ -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