Refactoring: propagate KotlinType through hierarchy of StackValue
Mainly, this is needed to introduce boxing over inline classes
This commit is contained in:
@@ -702,7 +702,7 @@ public class AsmUtil {
|
||||
return new StackValue(stackValue.type) {
|
||||
|
||||
@Override
|
||||
public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) {
|
||||
public void putSelector(@NotNull Type type, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v) {
|
||||
Type innerType = stackValue.type;
|
||||
stackValue.put(innerType, v);
|
||||
if (innerType.getSort() == Type.OBJECT || innerType.getSort() == Type.ARRAY) {
|
||||
|
||||
+4
-14
@@ -1,23 +1,13 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
import com.intellij.psi.tree.IElementType
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.org.objectweb.asm.Label
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
@@ -58,7 +48,7 @@ abstract class SafeCallFusedWithPrimitiveEqualityBase(
|
||||
v.mark(endLabel)
|
||||
}
|
||||
|
||||
override fun putSelector(type: Type, v: InstructionAdapter) {
|
||||
override fun putSelector(type: Type, kotlinType: KotlinType?, v: InstructionAdapter) {
|
||||
val falseLabel = Label()
|
||||
val endLabel = Label()
|
||||
|
||||
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen
|
||||
@@ -20,6 +9,7 @@ import com.intellij.psi.tree.IElementType
|
||||
import org.jetbrains.kotlin.codegen.pseudoInsns.fakeAlwaysFalseIfeq
|
||||
import org.jetbrains.kotlin.codegen.pseudoInsns.fakeAlwaysTrueIfeq
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.org.objectweb.asm.Label
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes.*
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
@@ -32,7 +22,7 @@ open class BranchedValue(
|
||||
val opcode: Int
|
||||
) : StackValue(Type.BOOLEAN_TYPE) {
|
||||
|
||||
override fun putSelector(type: Type, v: InstructionAdapter) {
|
||||
override fun putSelector(type: Type, kotlinType: KotlinType?, v: InstructionAdapter) {
|
||||
val branchJumpLabel = Label()
|
||||
condJump(branchJumpLabel, v, true)
|
||||
val endLabel = Label()
|
||||
@@ -75,7 +65,7 @@ open class BranchedValue(
|
||||
}
|
||||
}
|
||||
|
||||
override fun putSelector(type: Type, v: InstructionAdapter) {
|
||||
override fun putSelector(type: Type, kotlinType: KotlinType?, v: InstructionAdapter) {
|
||||
v.iconst(1)
|
||||
coerceTo(type, v)
|
||||
}
|
||||
@@ -97,7 +87,7 @@ open class BranchedValue(
|
||||
}
|
||||
}
|
||||
|
||||
override fun putSelector(type: Type, v: InstructionAdapter) {
|
||||
override fun putSelector(type: Type, kotlinType: KotlinType?, v: InstructionAdapter) {
|
||||
v.iconst(0)
|
||||
coerceTo(type, v)
|
||||
}
|
||||
@@ -180,7 +170,7 @@ class Invert(val condition: BranchedValue) : BranchedValue(condition, null, Type
|
||||
|
||||
class CondJump(val condition: BranchedValue, op: Int) : BranchedValue(condition, null, Type.BOOLEAN_TYPE, op) {
|
||||
|
||||
override fun putSelector(type: Type, v: InstructionAdapter) {
|
||||
override fun putSelector(type: Type, kotlinType: KotlinType?, v: InstructionAdapter) {
|
||||
throw UnsupportedOperationException("Use condJump instead")
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.resolve.InlineClassesUtilsKt;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||
|
||||
@@ -127,7 +128,7 @@ public class CallReceiver extends StackValue {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) {
|
||||
public void putSelector(@NotNull Type type, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v) {
|
||||
StackValue currentExtensionReceiver = extensionReceiver;
|
||||
boolean hasExtensionReceiver = extensionReceiver != none();
|
||||
if (extensionReceiver instanceof SafeCall) {
|
||||
@@ -141,7 +142,12 @@ public class CallReceiver extends StackValue {
|
||||
dispatchReceiver.put(dispatchReceiverType, v);
|
||||
|
||||
currentExtensionReceiver
|
||||
.moveToTopOfStack(hasExtensionReceiver ? type : currentExtensionReceiver.type, v, dispatchReceiverType.getSize());
|
||||
.moveToTopOfStack(
|
||||
hasExtensionReceiver ? type : currentExtensionReceiver.type,
|
||||
hasExtensionReceiver ? kotlinType : currentExtensionReceiver.kotlinType,
|
||||
v,
|
||||
dispatchReceiverType.getSize()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -341,7 +341,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
}
|
||||
|
||||
value.put(type, v);
|
||||
value.put(type, null, v);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -916,7 +916,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
if (isStatement) {
|
||||
DeclarationDescriptor descriptor = bindingContext.get(DECLARATION_TO_DESCRIPTOR, function);
|
||||
int index = lookupLocalIndex(descriptor);
|
||||
closure.put(OBJECT_TYPE, v);
|
||||
closure.put(OBJECT_TYPE, null, v);
|
||||
v.store(index, OBJECT_TYPE);
|
||||
return StackValue.none();
|
||||
}
|
||||
@@ -1186,7 +1186,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
blockResult = statementResult;
|
||||
}
|
||||
else {
|
||||
statementResult.put(Type.VOID_TYPE, v);
|
||||
statementResult.put(Type.VOID_TYPE, null, v);
|
||||
}
|
||||
|
||||
addLeaveTaskToRemoveDescriptorFromFrameMap(statement, blockEnd, leaveTasks);
|
||||
@@ -1527,7 +1527,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
StackValue.Local localForReturnValue = StackValue.local(returnValIndex, returnType);
|
||||
localForReturnValue.store(StackValue.onStack(returnType), v);
|
||||
doFinallyOnReturn(afterReturnLabel);
|
||||
localForReturnValue.put(returnType, v);
|
||||
localForReturnValue.put(returnType, null, v);
|
||||
myFrameMap.leaveTemp(returnType);
|
||||
}
|
||||
else {
|
||||
@@ -1590,7 +1590,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
|
||||
if (typeForExpression.getSort() == Type.VOID) {
|
||||
StackValue.none().put(returnType, v);
|
||||
StackValue.none().put(returnType, null, v);
|
||||
}
|
||||
|
||||
v.areturn(returnType);
|
||||
@@ -2124,7 +2124,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
Label afterAll = new Label();
|
||||
|
||||
Type functionType = typeMapper.mapType(samType.getKotlinFunctionType());
|
||||
expression.accept(visitor, StackValue.none()).put(functionType, v);
|
||||
expression.accept(visitor, StackValue.none()).put(functionType, null, v);
|
||||
|
||||
v.dup();
|
||||
v.ifnull(afterAll);
|
||||
@@ -2356,7 +2356,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
if (!isConstructor) { // otherwise already
|
||||
receiver = StackValue.receiver(resolvedCall, receiver, this, callableMethod);
|
||||
receiver.put(receiver.type, v);
|
||||
receiver.put(receiver.type, receiver.kotlinType, v);
|
||||
|
||||
// In regular cases we add an inline marker just before receiver is loaded (to spill the stack before a suspension)
|
||||
// But in case of safe call things we get the following bytecode:
|
||||
@@ -3023,7 +3023,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
private StackValue genUnlessProvided(@Nullable StackValue pregenerated, @NotNull KtExpression expr, @NotNull Type type) {
|
||||
if (pregenerated != null) {
|
||||
pregenerated.put(type, v);
|
||||
pregenerated.put(type, null, v);
|
||||
}
|
||||
else {
|
||||
gen(expr, type);
|
||||
@@ -3244,7 +3244,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
int notEquals = opToken != KtTokens.EQEQ ? 1 : 0;
|
||||
Label end = new Label();
|
||||
StackValue leftValue = pregeneratedLeft != null ? pregeneratedLeft : gen(left);
|
||||
leftValue.put(leftValue.type, v);
|
||||
leftValue.put(leftValue.type, leftValue.kotlinType, v);
|
||||
leftValue = StackValue.onStack(leftValue.type);
|
||||
Type leftType = left754Type.type;
|
||||
Type rightType = right754Type.type;
|
||||
@@ -3252,11 +3252,11 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
leftValue.dup(v, false);
|
||||
Label leftIsNull = new Label();
|
||||
v.ifnull(leftIsNull);
|
||||
StackValue.coercion(leftValue, leftType).put(leftType, v);
|
||||
StackValue.coercion(leftValue, leftType).put(leftType, null, v);
|
||||
StackValue nonNullLeftValue = StackValue.onStack(leftType);
|
||||
|
||||
StackValue rightValue = gen(right);
|
||||
rightValue.put(rightValue.type, v);
|
||||
rightValue.put(rightValue.type, rightValue.kotlinType, v);
|
||||
rightValue = StackValue.onStack(rightValue.type);
|
||||
if (right754Type.isNullable) {
|
||||
rightValue.dup(v, false);
|
||||
@@ -3269,16 +3269,16 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
v.mark(rightIsNotNull);
|
||||
}
|
||||
|
||||
StackValue.coercion(rightValue, rightType).put(rightType, v);
|
||||
StackValue.coercion(rightValue, rightType).put(rightType, null, v);
|
||||
StackValue nonNullRightValue = StackValue.onStack(rightType);
|
||||
StackValue.cmp(opToken, leftType, nonNullLeftValue, nonNullRightValue).put(Type.BOOLEAN_TYPE, v);
|
||||
StackValue.cmp(opToken, leftType, nonNullLeftValue, nonNullRightValue).put(Type.BOOLEAN_TYPE, null, v);
|
||||
v.goTo(end);
|
||||
|
||||
//left is null case
|
||||
v.mark(leftIsNull);
|
||||
AsmUtil.pop(v, leftValue.type);//pop null left
|
||||
rightValue = gen(right);
|
||||
rightValue.put(rightValue.type, v);
|
||||
rightValue.put(rightValue.type, rightValue.kotlinType, v);
|
||||
rightValue = StackValue.onStack(rightValue.type);
|
||||
if (right754Type.isNullable) {
|
||||
Label rightIsNotNull = new Label();
|
||||
@@ -3299,13 +3299,13 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
return;
|
||||
}
|
||||
else {
|
||||
StackValue.coercion(leftValue, leftType).put(leftType, v);
|
||||
StackValue.coercion(leftValue, leftType).put(leftType, null, v);
|
||||
leftValue = StackValue.onStack(leftType);
|
||||
}
|
||||
|
||||
//right is nullable cause left is not
|
||||
StackValue rightValue = gen(right);
|
||||
rightValue.put(rightValue.type, v);
|
||||
rightValue.put(rightValue.type, rightValue.kotlinType, v);
|
||||
rightValue = StackValue.onStack(rightValue.type);
|
||||
|
||||
rightValue.dup(v, false);
|
||||
@@ -3317,9 +3317,9 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
v.goTo(end);
|
||||
|
||||
v.mark(rightIsNotNull);
|
||||
StackValue.coercion(rightValue, rightType).put(rightType, v);
|
||||
StackValue.coercion(rightValue, rightType).put(rightType, null, v);
|
||||
StackValue nonNullRightValue = StackValue.onStack(rightType);
|
||||
StackValue.cmp(opToken, leftType, leftValue, nonNullRightValue).put(Type.BOOLEAN_TYPE, v);
|
||||
StackValue.cmp(opToken, leftType, leftValue, nonNullRightValue).put(Type.BOOLEAN_TYPE, null, v);
|
||||
|
||||
v.mark(end);
|
||||
}
|
||||
@@ -3359,11 +3359,11 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
|
||||
return StackValue.operation(exprType, v -> {
|
||||
value.put(value.type, v);
|
||||
value.put(value.type, value.kotlinType, v);
|
||||
v.dup();
|
||||
|
||||
v.ifnull(ifNull);
|
||||
StackValue.onStack(leftType).put(exprType, v);
|
||||
StackValue.onStack(leftType).put(exprType, null, v);
|
||||
|
||||
Label end = new Label();
|
||||
v.goTo(end);
|
||||
@@ -3458,10 +3458,10 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
if (keepReturnValue) {
|
||||
value = StackValue.complexWriteReadReceiver(value);
|
||||
}
|
||||
value.put(lhsType, v);
|
||||
value.put(lhsType, null, v);
|
||||
StackValue receiver = StackValue.onStack(lhsType);
|
||||
|
||||
callable.invokeMethodWithArguments(resolvedCall, receiver, this).put(callable.getReturnType(), v);
|
||||
callable.invokeMethodWithArguments(resolvedCall, receiver, this).put(callable.getReturnType(), null, v);
|
||||
|
||||
if (keepReturnValue) {
|
||||
value.store(StackValue.onStack(callable.getReturnType()), v, true);
|
||||
@@ -3497,7 +3497,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
Type exprType = expressionType(expr);
|
||||
if (compileTimeConstant != null) {
|
||||
StackValue.constant(compileTimeConstant.getValue(), exprType).put(exprType, v);
|
||||
StackValue.constant(compileTimeConstant.getValue(), exprType).put(exprType, null, v);
|
||||
} else {
|
||||
gen(expr, exprType);
|
||||
}
|
||||
@@ -3549,7 +3549,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
if (isPrimitive(base.type)) return base;
|
||||
|
||||
return StackValue.operation(base.type, v -> {
|
||||
base.put(base.type, v);
|
||||
base.put(base.type, base.kotlinType, v);
|
||||
v.dup();
|
||||
Label ok = new Label();
|
||||
v.ifnonnull(ok);
|
||||
@@ -3600,7 +3600,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
return StackValue.operation(asmBaseType, v -> {
|
||||
StackValue value = StackValue.complexWriteReadReceiver(gen(expression.getBaseExpression()));
|
||||
|
||||
value.put(asmBaseType, v);
|
||||
value.put(asmBaseType, null, v);
|
||||
AsmUtil.dup(v, asmBaseType);
|
||||
|
||||
StackValue previousValue = StackValue.local(myFrameMap.enterTemp(asmBaseType), asmBaseType);
|
||||
@@ -3613,13 +3613,13 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
else {
|
||||
StackValue result = invokeFunction(resolvedCall, StackValue.onStack(asmBaseType));
|
||||
result.put(result.type, v);
|
||||
result.put(result.type, result.kotlinType, v);
|
||||
storeType = result.type;
|
||||
}
|
||||
|
||||
value.store(StackValue.onStack(storeType), v, true);
|
||||
|
||||
previousValue.put(asmBaseType, v);
|
||||
previousValue.put(asmBaseType, null, v);
|
||||
|
||||
myFrameMap.leaveTemp(asmBaseType);
|
||||
|
||||
@@ -3756,12 +3756,12 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
if (variableDescriptor.isLateInit()) {
|
||||
assert initializer == null : "Initializer should be null for lateinit var " + variableDescriptor + ": " + initializer;
|
||||
v.aconst(null);
|
||||
storeTo.storeSelector(storeTo.type, v);
|
||||
storeTo.storeSelector(storeTo.type, storeTo.kotlinType, v);
|
||||
return;
|
||||
}
|
||||
|
||||
assert initializer != null : "Initializer should be not null for " + variableDescriptor;
|
||||
initializer.put(initializer.type, v);
|
||||
initializer.put(initializer.type, initializer.kotlinType, v);
|
||||
|
||||
markLineNumber(variableDeclaration, false);
|
||||
Type resultType = initializer.type;
|
||||
@@ -3776,7 +3776,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
}
|
||||
|
||||
storeTo.storeSelector(resultType, v);
|
||||
storeTo.storeSelector(resultType, null, v);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -3798,14 +3798,14 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
arguments.get(1).asElement(),
|
||||
new StackValue(K_PROPERTY_TYPE) {
|
||||
@Override
|
||||
public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) {
|
||||
metadataValue.put(type, v);
|
||||
public void putSelector(@NotNull Type type, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v) {
|
||||
metadataValue.put(type, kotlinType, v);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
StackValue result = invokeFunction(provideDelegateResolvedCall, provideDelegateReceiver);
|
||||
result.put(result.type, v);
|
||||
result.put(result.type, result.kotlinType, v);
|
||||
tempVariables.remove(arguments.get(0).asElement());
|
||||
tempVariables.remove(arguments.get(1).asElement());
|
||||
return result.type;
|
||||
@@ -3831,8 +3831,8 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
StackValue value = context.getFunctionDescriptor().isInline()
|
||||
? generatePropertyReference(variable.getDelegate(), variableDescriptor, variableDescriptor, null)
|
||||
: PropertyCodegen.getDelegatedPropertyMetadata(variableDescriptor, bindingContext);
|
||||
value.put(K_PROPERTY_TYPE, v);
|
||||
metadataVar.storeSelector(K_PROPERTY_TYPE, v);
|
||||
value.put(K_PROPERTY_TYPE, null, v);
|
||||
metadataVar.storeSelector(K_PROPERTY_TYPE, null, v);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -3883,10 +3883,11 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
ReceiverParameterDescriptor dispatchReceiver = constructor.getDispatchReceiverParameter();
|
||||
ClassDescriptor containingDeclaration = constructor.getContainingDeclaration();
|
||||
if (dispatchReceiver != null) {
|
||||
Type receiverType = typeMapper.mapType(dispatchReceiver.getType());
|
||||
KotlinType kotlinType = dispatchReceiver.getType();
|
||||
Type receiverType = typeMapper.mapType(kotlinType);
|
||||
ReceiverValue receiver = getConstructorReceiver(resolvedCall);
|
||||
boolean callSuper = containingDeclaration.isInner() && receiver instanceof ImplicitClassReceiver;
|
||||
generateReceiverValue(receiver, callSuper).put(receiverType, v);
|
||||
generateReceiverValue(receiver, callSuper).put(receiverType, kotlinType, v);
|
||||
}
|
||||
|
||||
// Resolved call to local class constructor doesn't have dispatchReceiver, so we need to generate closure on stack
|
||||
@@ -4193,7 +4194,7 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
StackValue value = genQualified(receiver, left);
|
||||
|
||||
return StackValue.operation(boxType(asmType(rightType)), v -> {
|
||||
value.put(boxType(value.type), v);
|
||||
value.put(boxType(value.type), null, v);
|
||||
|
||||
if (value.type == Type.VOID_TYPE) {
|
||||
StackValue.putUnitInstance(v);
|
||||
@@ -4239,7 +4240,7 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
|
||||
private StackValue generateIsCheck(StackValue expressionToGen, KotlinType kotlinType, boolean leaveExpressionOnStack) {
|
||||
return StackValue.operation(Type.BOOLEAN_TYPE, v -> {
|
||||
expressionToGen.put(OBJECT_TYPE, v);
|
||||
expressionToGen.put(OBJECT_TYPE, null, v);
|
||||
if (leaveExpressionOnStack) {
|
||||
v.dup();
|
||||
}
|
||||
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen;
|
||||
@@ -71,14 +60,25 @@ public abstract class StackValue {
|
||||
|
||||
@NotNull
|
||||
public final Type type;
|
||||
@Nullable
|
||||
public final KotlinType kotlinType;
|
||||
private final boolean canHaveSideEffects;
|
||||
|
||||
protected StackValue(@NotNull Type type) {
|
||||
this(type, true);
|
||||
this(type, null, true);
|
||||
}
|
||||
|
||||
protected StackValue(@NotNull Type type, boolean canHaveSideEffects) {
|
||||
this(type, null, canHaveSideEffects);
|
||||
}
|
||||
|
||||
protected StackValue(@NotNull Type type, @Nullable KotlinType kotlinType) {
|
||||
this(type, kotlinType, true);
|
||||
}
|
||||
|
||||
protected StackValue(@NotNull Type type, @Nullable KotlinType kotlinType, boolean canHaveSideEffects) {
|
||||
this.type = type;
|
||||
this.kotlinType = kotlinType;
|
||||
this.canHaveSideEffects = canHaveSideEffects;
|
||||
}
|
||||
|
||||
@@ -90,28 +90,31 @@ public abstract class StackValue {
|
||||
* @param v the visitor used to genClassOrObject the instructions
|
||||
* @param depth the number of new values put onto the stack
|
||||
*/
|
||||
public void moveToTopOfStack(@NotNull Type type, @NotNull InstructionAdapter v, int depth) {
|
||||
put(type, v);
|
||||
public void moveToTopOfStack(@NotNull Type type, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v, int depth) {
|
||||
put(type, kotlinType, v);
|
||||
}
|
||||
|
||||
public void put(@NotNull Type type, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v) {
|
||||
put(type, kotlinType, v, false);
|
||||
}
|
||||
|
||||
public void put(@NotNull Type type, @NotNull InstructionAdapter v) {
|
||||
put(type, v, false);
|
||||
put(type, null, v, false);
|
||||
}
|
||||
|
||||
public void put(@NotNull Type type, @NotNull InstructionAdapter v, boolean skipReceiver) {
|
||||
public void put(@NotNull Type type, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v, boolean skipReceiver) {
|
||||
if (!skipReceiver) {
|
||||
putReceiver(v, true);
|
||||
}
|
||||
putSelector(type, v);
|
||||
putSelector(type, kotlinType, v);
|
||||
}
|
||||
|
||||
public abstract void putSelector(@NotNull Type type, @NotNull InstructionAdapter v);
|
||||
public abstract void putSelector(@NotNull Type type, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v);
|
||||
|
||||
public boolean isNonStaticAccess(boolean isRead) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public void putReceiver(@NotNull InstructionAdapter v, boolean isRead) {
|
||||
//by default there is no receiver
|
||||
//if you have it inherit StackValueWithSimpleReceiver
|
||||
@@ -135,11 +138,11 @@ public abstract class StackValue {
|
||||
if (!skipReceiver) {
|
||||
putReceiver(v, false);
|
||||
}
|
||||
value.put(value.type, v);
|
||||
storeSelector(value.type, v);
|
||||
value.put(value.type, value.kotlinType, v);
|
||||
storeSelector(value.type, value.kotlinType, v);
|
||||
}
|
||||
|
||||
protected void storeSelector(@NotNull Type topOfStackType, @NotNull InstructionAdapter v) {
|
||||
protected void storeSelector(@NotNull Type topOfStackType, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v) {
|
||||
throw new UnsupportedOperationException("Cannot store to value " + this);
|
||||
}
|
||||
|
||||
@@ -447,7 +450,7 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
public static void putUnitInstance(@NotNull InstructionAdapter v) {
|
||||
unit().put(UNIT_TYPE, v);
|
||||
unit().put(UNIT_TYPE, null, v);
|
||||
}
|
||||
|
||||
public static StackValue unit() {
|
||||
@@ -661,7 +664,7 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) {
|
||||
public void putSelector(@NotNull Type type, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v) {
|
||||
coerceTo(type, v);
|
||||
}
|
||||
}
|
||||
@@ -692,7 +695,7 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) {
|
||||
public void putSelector(@NotNull Type type, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v) {
|
||||
v.load(index, this.type);
|
||||
if (isLateinit) {
|
||||
StackValue.genNonNullAssertForLateinit(v, name.asString());
|
||||
@@ -702,7 +705,7 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeSelector(@NotNull Type topOfStackType, @NotNull InstructionAdapter v) {
|
||||
public void storeSelector(@NotNull Type topOfStackType, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v) {
|
||||
coerceFrom(topOfStackType, v);
|
||||
v.store(index, this.type);
|
||||
if (isLateinit) {
|
||||
@@ -746,7 +749,7 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) {
|
||||
public void putSelector(@NotNull Type type, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v) {
|
||||
ResolvedCall<FunctionDescriptor> resolvedCall = getResolvedCall(true);
|
||||
List<? extends ValueArgument> arguments = resolvedCall.getCall().getValueArguments();
|
||||
assert arguments.size() == 2 : "Resolved call for 'getValue' should have 2 arguments, but was " +
|
||||
@@ -755,7 +758,7 @@ public abstract class StackValue {
|
||||
codegen.tempVariables.put(arguments.get(0).asElement(), StackValue.constant(null, OBJECT_TYPE));
|
||||
codegen.tempVariables.put(arguments.get(1).asElement(), metadataValue);
|
||||
StackValue lastValue = codegen.invokeFunction(resolvedCall, delegateValue);
|
||||
lastValue.put(type, v);
|
||||
lastValue.put(type, kotlinType, v);
|
||||
|
||||
codegen.tempVariables.remove(arguments.get(0).asElement());
|
||||
codegen.tempVariables.remove(arguments.get(1).asElement());
|
||||
@@ -772,7 +775,7 @@ public abstract class StackValue {
|
||||
codegen.tempVariables.put(arguments.get(1).asElement(), metadataValue);
|
||||
codegen.tempVariables.put(arguments.get(2).asElement(), rightSide);
|
||||
StackValue lastValue = codegen.invokeFunction(resolvedCall, delegateValue);
|
||||
lastValue.put(Type.VOID_TYPE, v);
|
||||
lastValue.put(Type.VOID_TYPE, null, v);
|
||||
|
||||
codegen.tempVariables.remove(arguments.get(0).asElement());
|
||||
codegen.tempVariables.remove(arguments.get(1).asElement());
|
||||
@@ -786,14 +789,14 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) {
|
||||
public void putSelector(@NotNull Type type, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v) {
|
||||
coerceTo(type, v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moveToTopOfStack(@NotNull Type type, @NotNull InstructionAdapter v, int depth) {
|
||||
public void moveToTopOfStack(@NotNull Type type, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v, int depth) {
|
||||
if (depth == 0) {
|
||||
put(type, v);
|
||||
put(type, kotlinType, v);
|
||||
}
|
||||
else if (depth == 1) {
|
||||
int size = this.type.getSize();
|
||||
@@ -843,7 +846,7 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) {
|
||||
public void putSelector(@NotNull Type type, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v) {
|
||||
if (value instanceof Integer || value instanceof Byte || value instanceof Short) {
|
||||
v.iconst(((Number) value).intValue());
|
||||
}
|
||||
@@ -878,7 +881,7 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeSelector(@NotNull Type topOfStackType, @NotNull InstructionAdapter v) {
|
||||
public void storeSelector(@NotNull Type topOfStackType, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v) {
|
||||
coerceFrom(topOfStackType, v);
|
||||
v.astore(this.type);
|
||||
}
|
||||
@@ -890,7 +893,7 @@ public abstract class StackValue {
|
||||
|
||||
@Override
|
||||
public void putSelector(
|
||||
@NotNull Type type, @NotNull InstructionAdapter v
|
||||
@NotNull Type type, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v
|
||||
) {
|
||||
v.aload(this.type); // assumes array and index are on the stack
|
||||
coerceTo(type, v);
|
||||
@@ -932,11 +935,11 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) {
|
||||
public void putSelector(@NotNull Type type, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v) {
|
||||
ResolvedCall<?> call = isGetter ? resolvedGetCall : resolvedSetCall;
|
||||
StackValue newReceiver = StackValue.receiver(call, receiver, codegen, callable);
|
||||
ArgumentGenerator generator = createArgumentGenerator();
|
||||
newReceiver.put(newReceiver.type, v);
|
||||
newReceiver.put(newReceiver.type, newReceiver.kotlinType, v);
|
||||
callGenerator.processAndPutHiddenParameters(false);
|
||||
|
||||
defaultArgs = generator.generate(valueArguments, valueArguments, call.getResultingDescriptor());
|
||||
@@ -1012,7 +1015,7 @@ public abstract class StackValue {
|
||||
|
||||
if (resolvedSetCall.getDispatchReceiver() != null) {
|
||||
if (resolvedSetCall.getExtensionReceiver() != null) {
|
||||
codegen.generateReceiverValue(resolvedSetCall.getDispatchReceiver(), false).put(OBJECT_TYPE, v);
|
||||
codegen.generateReceiverValue(resolvedSetCall.getDispatchReceiver(), false).put(OBJECT_TYPE, null, v);
|
||||
}
|
||||
v.load(realReceiverIndex, realReceiverType);
|
||||
}
|
||||
@@ -1077,7 +1080,7 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) {
|
||||
public void putSelector(@NotNull Type type, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v) {
|
||||
if (getter == null) {
|
||||
throw new UnsupportedOperationException("no getter specified");
|
||||
}
|
||||
@@ -1141,7 +1144,7 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeSelector(@NotNull Type topOfStackType, @NotNull InstructionAdapter v) {
|
||||
public void storeSelector(@NotNull Type topOfStackType, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v) {
|
||||
if (setter == null) {
|
||||
throw new UnsupportedOperationException("no setter specified");
|
||||
}
|
||||
@@ -1197,13 +1200,13 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) {
|
||||
public void putSelector(@NotNull Type type, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v) {
|
||||
v.visitFieldInsn(isStaticPut ? GETSTATIC : GETFIELD, owner.getInternalName(), name, this.type.getDescriptor());
|
||||
coerceTo(type, v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeSelector(@NotNull Type topOfStackType, @NotNull InstructionAdapter v) {
|
||||
public void storeSelector(@NotNull Type topOfStackType, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v) {
|
||||
coerceFrom(topOfStackType, v);
|
||||
v.visitFieldInsn(isStaticStore ? PUTSTATIC : PUTFIELD, owner.getInternalName(), name, this.type.getDescriptor());
|
||||
}
|
||||
@@ -1242,7 +1245,7 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) {
|
||||
public void putSelector(@NotNull Type type, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v) {
|
||||
if (getter == null) {
|
||||
assert fieldName != null : "Property should have either a getter or a field name: " + descriptor;
|
||||
assert backingFieldOwner != null : "Property should have either a getter or a backingFieldOwner: " + descriptor;
|
||||
@@ -1314,7 +1317,7 @@ public abstract class StackValue {
|
||||
value = ((Double) value).floatValue();
|
||||
}
|
||||
|
||||
StackValue.constant(value, this.type).putSelector(type, v);
|
||||
StackValue.constant(value, this.type).putSelector(type, null, v);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1345,7 +1348,7 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeSelector(@NotNull Type topOfStackType, @NotNull InstructionAdapter v) {
|
||||
public void storeSelector(@NotNull Type topOfStackType, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v) {
|
||||
if (setter == null) {
|
||||
coerceFrom(topOfStackType, v);
|
||||
assert fieldName != null : "Property should have either a setter or a field name: " + descriptor;
|
||||
@@ -1406,7 +1409,7 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) {
|
||||
public void putSelector(@NotNull Type type, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v) {
|
||||
generator.gen(expression, type);
|
||||
}
|
||||
}
|
||||
@@ -1437,7 +1440,7 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) {
|
||||
public void putSelector(@NotNull Type type, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v) {
|
||||
Type refType = refType(this.type);
|
||||
Type sharedType = sharedTypeForType(this.type);
|
||||
v.visitFieldInsn(GETFIELD, sharedType.getInternalName(), "element", refType.getDescriptor());
|
||||
@@ -1449,7 +1452,7 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeSelector(@NotNull Type topOfStackType, @NotNull InstructionAdapter v) {
|
||||
public void storeSelector(@NotNull Type topOfStackType, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v) {
|
||||
coerceFrom(topOfStackType, v);
|
||||
Type refType = refType(this.type);
|
||||
Type sharedType = sharedTypeForType(this.type);
|
||||
@@ -1501,7 +1504,7 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) {
|
||||
public void putSelector(@NotNull Type type, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v) {
|
||||
Type sharedType = sharedTypeForType(this.type);
|
||||
Type refType = refType(this.type);
|
||||
v.visitFieldInsn(GETFIELD, sharedType.getInternalName(), "element", refType.getDescriptor());
|
||||
@@ -1513,7 +1516,7 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeSelector(@NotNull Type topOfStackType, @NotNull InstructionAdapter v) {
|
||||
public void storeSelector(@NotNull Type topOfStackType, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v) {
|
||||
coerceFrom(topOfStackType, v);
|
||||
v.visitFieldInsn(PUTFIELD, sharedTypeForType(type).getInternalName(), "element", refType(type).getDescriptor());
|
||||
}
|
||||
@@ -1539,9 +1542,13 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) {
|
||||
public void putSelector(@NotNull Type type, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v) {
|
||||
StackValue stackValue = codegen.generateThisOrOuter(descriptor, isSuper);
|
||||
stackValue.put(coerceType ? type : stackValue.type, v);
|
||||
stackValue.put(
|
||||
coerceType ? type : stackValue.type,
|
||||
coerceType ? kotlinType : stackValue.kotlinType,
|
||||
v
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1556,7 +1563,7 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) {
|
||||
public void putSelector(@NotNull Type type, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v) {
|
||||
if (!type.equals(Type.VOID_TYPE)) {
|
||||
v.load(index, Type.INT_TYPE);
|
||||
coerceTo(type, v);
|
||||
@@ -1576,7 +1583,7 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) {
|
||||
public void putSelector(@NotNull Type type, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v) {
|
||||
v.iinc(index, increment);
|
||||
if (!type.equals(Type.VOID_TYPE)) {
|
||||
v.load(index, Type.INT_TYPE);
|
||||
@@ -1603,13 +1610,13 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) {
|
||||
public void putSelector(@NotNull Type type, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v) {
|
||||
value = StackValue.complexReceiver(value, true, false, true);
|
||||
value.put(this.type, v);
|
||||
value.put(this.type, this.kotlinType, v);
|
||||
|
||||
value.store(codegen.invokeFunction(resolvedCall, StackValue.onStack(this.type)), v, true);
|
||||
|
||||
value.put(this.type, v, true);
|
||||
value.put(this.type, this.kotlinType, v, true);
|
||||
coerceTo(type, v);
|
||||
}
|
||||
}
|
||||
@@ -1639,7 +1646,11 @@ public abstract class StackValue {
|
||||
public void putReceiver(@NotNull InstructionAdapter v, boolean isRead) {
|
||||
boolean hasReceiver = isNonStaticAccess(isRead);
|
||||
if (hasReceiver || receiver.canHaveSideEffects()) {
|
||||
receiver.put(hasReceiver ? receiver.type : Type.VOID_TYPE, v);
|
||||
receiver.put(
|
||||
hasReceiver ? receiver.type : Type.VOID_TYPE,
|
||||
hasReceiver ? receiver.kotlinType : null,
|
||||
v
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1695,8 +1706,8 @@ public abstract class StackValue {
|
||||
if (!skipReceiver) {
|
||||
putReceiver(v, false);
|
||||
}
|
||||
rightSide.put(rightSide.type, v);
|
||||
storeSelector(rightSide.type, v);
|
||||
rightSide.put(rightSide.type, rightSide.kotlinType, v);
|
||||
storeSelector(rightSide.type, rightSide.kotlinType, v);
|
||||
}
|
||||
|
||||
protected StackValueWithSimpleReceiver changeReceiver(@NotNull StackValue newReceiver) {
|
||||
@@ -1722,14 +1733,14 @@ public abstract class StackValue {
|
||||
|
||||
@Override
|
||||
public void putSelector(
|
||||
@NotNull Type type, @NotNull InstructionAdapter v
|
||||
@NotNull Type type, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v
|
||||
) {
|
||||
boolean wasPut = false;
|
||||
StackValue receiver = originalValueWithReceiver.receiver;
|
||||
for (boolean operation : isReadOperations) {
|
||||
if (originalValueWithReceiver.isNonStaticAccess(operation)) {
|
||||
if (!wasPut) {
|
||||
receiver.put(receiver.type, v);
|
||||
receiver.put(receiver.type, receiver.kotlinType, v);
|
||||
wasPut = true;
|
||||
}
|
||||
else {
|
||||
@@ -1739,7 +1750,7 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
if (!wasPut && receiver.canHaveSideEffects()) {
|
||||
receiver.put(Type.VOID_TYPE, v);
|
||||
receiver.put(Type.VOID_TYPE, null, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1755,10 +1766,10 @@ public abstract class StackValue {
|
||||
|
||||
@Override
|
||||
public void putSelector(
|
||||
@NotNull Type type, @NotNull InstructionAdapter v
|
||||
@NotNull Type type, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v
|
||||
) {
|
||||
for (StackValue instruction : instructions) {
|
||||
instruction.put(instruction.type, v);
|
||||
instruction.put(instruction.type, instruction.kotlinType, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1782,9 +1793,9 @@ public abstract class StackValue {
|
||||
|
||||
@Override
|
||||
public void putSelector(
|
||||
@NotNull Type type, @NotNull InstructionAdapter v
|
||||
@NotNull Type type, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v
|
||||
) {
|
||||
originalValue.putSelector(type, v);
|
||||
originalValue.putSelector(type, kotlinType, v);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1797,9 +1808,9 @@ public abstract class StackValue {
|
||||
|
||||
@Override
|
||||
public void storeSelector(
|
||||
@NotNull Type topOfStackType, @NotNull InstructionAdapter v
|
||||
@NotNull Type topOfStackType, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v
|
||||
) {
|
||||
originalValue.storeSelector(topOfStackType, v);
|
||||
originalValue.storeSelector(topOfStackType, kotlinType, v);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1841,8 +1852,8 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) {
|
||||
receiver.put(this.type, v);
|
||||
public void putSelector(@NotNull Type type, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v) {
|
||||
receiver.put(this.type, this.kotlinType, v);
|
||||
if (ifNull != null) {
|
||||
//not a primitive
|
||||
v.dup();
|
||||
@@ -1862,7 +1873,7 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) {
|
||||
public void putSelector(@NotNull Type type, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v) {
|
||||
Label end = new Label();
|
||||
|
||||
v.goTo(end);
|
||||
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen
|
||||
@@ -20,11 +9,13 @@ import org.jetbrains.kotlin.codegen.AsmUtil.unboxPrimitiveTypeOrNull
|
||||
import org.jetbrains.kotlin.codegen.StackValue.*
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.load.java.*
|
||||
import org.jetbrains.kotlin.load.java.Constant
|
||||
import org.jetbrains.kotlin.load.java.EnumEntry
|
||||
import org.jetbrains.kotlin.load.java.descriptors.NullDefaultValue
|
||||
import org.jetbrains.kotlin.load.java.descriptors.StringDefaultValue
|
||||
import org.jetbrains.kotlin.load.java.descriptors.getDefaultValueFromAnnotation
|
||||
import org.jetbrains.kotlin.load.java.lexicalCastFrom
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.utils.DFS
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
@@ -34,14 +25,14 @@ class CoercionValue(
|
||||
private val castType: Type
|
||||
) : StackValue(castType, value.canHaveSideEffects()) {
|
||||
|
||||
override fun putSelector(type: Type, v: InstructionAdapter) {
|
||||
value.putSelector(value.type, v)
|
||||
override fun putSelector(type: Type, kotlinType: KotlinType?, v: InstructionAdapter) {
|
||||
value.putSelector(value.type, value.kotlinType, v)
|
||||
StackValue.coerce(value.type, castType, v)
|
||||
StackValue.coerce(castType, type, v)
|
||||
}
|
||||
|
||||
override fun storeSelector(topOfStackType: Type, v: InstructionAdapter) {
|
||||
value.storeSelector(topOfStackType, v)
|
||||
override fun storeSelector(topOfStackType: Type, topOfStackKotlinType: KotlinType?, v: InstructionAdapter) {
|
||||
value.storeSelector(topOfStackType, topOfStackKotlinType, v)
|
||||
}
|
||||
|
||||
override fun putReceiver(v: InstructionAdapter, isRead: Boolean) {
|
||||
@@ -63,15 +54,15 @@ class StackValueWithLeaveTask(
|
||||
stackValue.putReceiver(v, isRead)
|
||||
}
|
||||
|
||||
override fun putSelector(type: Type, v: InstructionAdapter) {
|
||||
stackValue.putSelector(type, v)
|
||||
override fun putSelector(type: Type, kotlinType: KotlinType?, v: InstructionAdapter) {
|
||||
stackValue.putSelector(type, kotlinType, v)
|
||||
leaveTasks(stackValue)
|
||||
}
|
||||
}
|
||||
|
||||
open class OperationStackValue(resultType: Type, val lambda: (v: InstructionAdapter) -> Unit) : StackValue(resultType) {
|
||||
|
||||
override fun putSelector(type: Type, v: InstructionAdapter) {
|
||||
override fun putSelector(type: Type, kotlinType: KotlinType?, v: InstructionAdapter) {
|
||||
lambda(v)
|
||||
coerceTo(type, v)
|
||||
}
|
||||
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen.range
|
||||
@@ -22,6 +11,7 @@ import org.jetbrains.kotlin.codegen.range.forLoop.ForLoopGenerator
|
||||
import org.jetbrains.kotlin.codegen.range.inExpression.InExpressionGenerator
|
||||
import org.jetbrains.kotlin.psi.KtForExpression
|
||||
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
@@ -52,7 +42,7 @@ interface BoundedValue {
|
||||
|
||||
fun BoundedValue.asStackValue(): StackValue =
|
||||
object : StackValue(instanceType) {
|
||||
override fun putSelector(type: Type, v: InstructionAdapter) {
|
||||
override fun putSelector(type: Type, kotlinType: KotlinType?, v: InstructionAdapter) {
|
||||
putInstance(v, type)
|
||||
}
|
||||
}
|
||||
|
||||
+4
-14
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen.range.inExpression
|
||||
@@ -23,6 +12,7 @@ import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCallWithAssert
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.org.objectweb.asm.Label
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
@@ -40,7 +30,7 @@ class CallBasedInExpressionGenerator(
|
||||
|
||||
private fun gen(argument: StackValue): BranchedValue =
|
||||
object : BranchedValue(argument, null, argument.type, Opcodes.IFEQ) {
|
||||
override fun putSelector(type: Type, v: InstructionAdapter) {
|
||||
override fun putSelector(type: Type, kotlinType: KotlinType?, v: InstructionAdapter) {
|
||||
invokeFunction(v)
|
||||
coerceTo(type, v)
|
||||
}
|
||||
|
||||
+5
-15
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.android.synthetic.codegen
|
||||
@@ -19,14 +8,15 @@ package org.jetbrains.kotlin.android.synthetic.codegen
|
||||
import kotlinx.android.extensions.CacheImplementation
|
||||
import kotlinx.android.extensions.LayoutContainer
|
||||
import org.jetbrains.kotlin.android.synthetic.AndroidConst
|
||||
import org.jetbrains.kotlin.android.synthetic.codegen.AbstractAndroidExtensionsExpressionCodegenExtension.Companion.shouldCacheResource
|
||||
import org.jetbrains.kotlin.android.synthetic.codegen.AbstractAndroidExtensionsExpressionCodegenExtension.Companion.CACHED_FIND_VIEW_BY_ID_METHOD_NAME
|
||||
import org.jetbrains.kotlin.android.synthetic.codegen.AbstractAndroidExtensionsExpressionCodegenExtension.Companion.shouldCacheResource
|
||||
import org.jetbrains.kotlin.android.synthetic.descriptors.ContainerOptionsProxy
|
||||
import org.jetbrains.kotlin.android.synthetic.res.AndroidSyntheticProperty
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.lowerIfFlexible
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
@@ -46,7 +36,7 @@ class ResourcePropertyStackValue(
|
||||
assert(containerOptions.containerType != AndroidContainerType.UNKNOWN)
|
||||
}
|
||||
|
||||
override fun putSelector(type: Type, v: InstructionAdapter) {
|
||||
override fun putSelector(type: Type, kotlinType: KotlinType?, v: InstructionAdapter) {
|
||||
val returnTypeString = typeMapper.mapType(resource.type.lowerIfFlexible()).className
|
||||
if (AndroidConst.FRAGMENT_FQNAME == returnTypeString || AndroidConst.SUPPORT_FRAGMENT_FQNAME == returnTypeString) {
|
||||
return putSelectorForFragment(v)
|
||||
|
||||
Reference in New Issue
Block a user