Supported inline of array convention simple cases; Fix for KT-9211: M13 an extension function that is inline, and for get(v) causes an exception when called using brackets

#KT-9211 Fixed
This commit is contained in:
Michael Bogdanov
2016-01-18 14:59:43 +03:00
parent 84dbdf2ccb
commit 23480a5698
17 changed files with 303 additions and 15 deletions
@@ -2443,7 +2443,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
@NotNull
private CallGenerator getOrCreateCallGenerator(@NotNull ResolvedCall<?> resolvedCall) {
CallGenerator getOrCreateCallGenerator(@NotNull ResolvedCall<?> resolvedCall) {
Map<TypeParameterDescriptor, KotlinType> typeArguments = resolvedCall.getTypeArguments();
TypeParameterMappings mappings = new TypeParameterMappings();
for (Map.Entry<TypeParameterDescriptor, KotlinType> entry : typeArguments.entrySet()) {
@@ -3476,10 +3476,6 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
ResolvedCall<FunctionDescriptor> resolvedCall = isGetter ? resolvedGetCall : resolvedSetCall;
assert resolvedCall != null : "couldn't find resolved call: " + expression.getText();
ArgumentGenerator argumentGenerator = new CallBasedArgumentGenerator(
this, defaultCallGenerator, resolvedCall.getResultingDescriptor().getValueParameters(), callable.getValueParameterTypes()
);
List<ResolvedValueArgument> valueArguments = resolvedCall.getValueArgumentsByIndex();
assert valueArguments != null : "Failed to arrange value arguments by index: " + operationDescriptor;
@@ -3490,7 +3486,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
return new StackValue.CollectionElementReceiver(
callable, receiver, resolvedGetCall, resolvedSetCall, isGetter, this, argumentGenerator, valueArguments
callable, receiver, resolvedGetCall, resolvedSetCall, isGetter, this, valueArguments
);
}
@@ -47,7 +47,7 @@ public class FrameMap {
myVarSizes.remove(descriptor);
int oldIndex = myVarIndex.remove(descriptor);
if (oldIndex != myMaxIndex) {
throw new IllegalStateException("descriptor can be left only if it is last");
throw new IllegalStateException("Descriptor can be left only if it is last: " + descriptor);
}
return oldIndex;
}
@@ -17,8 +17,9 @@
package org.jetbrains.kotlin.codegen;
import com.intellij.psi.tree.IElementType;
import kotlin.collections.ArraysKt;
import kotlin.Unit;
import kotlin.collections.ArraysKt;
import kotlin.collections.CollectionsKt;
import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
@@ -768,13 +769,14 @@ public abstract class StackValue {
private final Callable callable;
private final boolean isGetter;
private final ExpressionCodegen codegen;
private final ArgumentGenerator argumentGenerator;
private final List<ResolvedValueArgument> valueArguments;
private final FrameMap frame;
private final StackValue receiver;
private final ResolvedCall<FunctionDescriptor> resolvedGetCall;
private final ResolvedCall<FunctionDescriptor> resolvedSetCall;
private DefaultCallMask mask;
private CallGenerator callGenerator;
boolean isComplexOperationWithDup;
public CollectionElementReceiver(
@NotNull Callable callable,
@@ -783,7 +785,6 @@ public abstract class StackValue {
ResolvedCall<FunctionDescriptor> resolvedSetCall,
boolean isGetter,
@NotNull ExpressionCodegen codegen,
ArgumentGenerator argumentGenerator,
List<ResolvedValueArgument> valueArguments
) {
super(OBJECT_TYPE);
@@ -793,7 +794,6 @@ public abstract class StackValue {
this.receiver = receiver;
this.resolvedGetCall = resolvedGetCall;
this.resolvedSetCall = resolvedSetCall;
this.argumentGenerator = argumentGenerator;
this.valueArguments = valueArguments;
this.codegen = codegen;
this.frame = codegen.myFrameMap;
@@ -803,8 +803,25 @@ public abstract class StackValue {
public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) {
ResolvedCall<?> call = isGetter ? resolvedGetCall : resolvedSetCall;
StackValue newReceiver = StackValue.receiver(call, receiver, codegen, callable);
ArgumentGenerator generator = createArgumentGenerator();
newReceiver.put(newReceiver.type, v);
mask = argumentGenerator.generate(valueArguments, valueArguments);
callGenerator.putHiddenParams();
mask = generator.generate(valueArguments, valueArguments);
}
private ArgumentGenerator createArgumentGenerator() {
assert callGenerator == null :
"'putSelector' and 'createArgumentGenerator' methods should be called once for CollectionElementReceiver: " + callable;
ResolvedCall<FunctionDescriptor> resolvedCall = isGetter ? resolvedGetCall : resolvedSetCall;
assert resolvedCall != null : "Resolved call should be non-null: " + callable;
callGenerator =
!isComplexOperationWithDup ? codegen.getOrCreateCallGenerator(resolvedCall) : codegen.defaultCallGenerator;
return new CallBasedArgumentGenerator(
codegen,
callGenerator,
resolvedCall.getResultingDescriptor().getValueParameters(), callable.getValueParameterTypes()
);
}
@Override
@@ -932,7 +949,7 @@ public abstract class StackValue {
if (getter == null) {
throw new UnsupportedOperationException("no getter specified");
}
CallGenerator callGenerator = codegen.defaultCallGenerator;
CallGenerator callGenerator = getCallGenerator();
callGenerator.genCall(getter, resolvedGetCall, genDefaultMaskIfPresent(callGenerator), codegen);
coerceTo(type, v);
}
@@ -942,6 +959,14 @@ public abstract class StackValue {
return mask.generateOnStackIfNeeded(callGenerator);
}
private CallGenerator getCallGenerator() {
CallGenerator generator = ((CollectionElementReceiver) receiver).callGenerator;
assert generator != null :
"CollectionElementReceiver should be putted on stack before CollectionElement:" +
" getCall = " + resolvedGetCall + ", setCall = " + resolvedSetCall;
return generator;
}
@Override
public int receiverSize() {
if (isStandardStack(codegen.typeMapper, resolvedGetCall, 1) && isStandardStack(codegen.typeMapper, resolvedSetCall, 2)) {
@@ -991,8 +1016,13 @@ public abstract class StackValue {
Type lastParameterType = ArraysKt.last(setter.getParameterTypes());
coerce(topOfStackType, lastParameterType, v);
//*Convention setter couldn't have default parameters, just getter can have it at last positions
getCallGenerator().afterParameterPut(lastParameterType, StackValue.onStack(lastParameterType),
CollectionsKt.getLastIndex(setter.getValueParameterTypes()));
//Convention setter couldn't have default parameters, just getter can have it at last positions
//We should remove default parameters of getter from stack*/
//Note that it works only for non-inline case
CollectionElementReceiver collectionElementReceiver = (CollectionElementReceiver) receiver;
if (collectionElementReceiver.isGetter) {
List<ResolvedValueArgument> arguments = collectionElementReceiver.valueArguments;
@@ -1007,7 +1037,7 @@ public abstract class StackValue {
}
}
codegen.defaultCallGenerator.genCall(setter, resolvedSetCall, false, codegen);
getCallGenerator().genCall(setter, resolvedSetCall, false, codegen);
Type returnType = setter.getReturnType();
if (returnType != Type.VOID_TYPE) {
pop(v, returnType);
@@ -1529,6 +1559,11 @@ public abstract class StackValue {
super(value.type, value.receiver.canHaveSideEffects());
this.originalValueWithReceiver = value;
this.isReadOperations = isReadOperations;
if (value instanceof CollectionElement) {
if (value.receiver instanceof CollectionElementReceiver) {
((CollectionElementReceiver) value.receiver).isComplexOperationWithDup = true;
}
}
}
@Override