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) {
|
return new StackValue(stackValue.type) {
|
||||||
|
|
||||||
@Override
|
@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;
|
Type innerType = stackValue.type;
|
||||||
stackValue.put(innerType, v);
|
stackValue.put(innerType, v);
|
||||||
if (innerType.getSort() == Type.OBJECT || innerType.getSort() == Type.ARRAY) {
|
if (innerType.getSort() == Type.OBJECT || innerType.getSort() == Type.ARRAY) {
|
||||||
|
|||||||
+4
-14
@@ -1,23 +1,13 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2017 JetBrains s.r.o.
|
* 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.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.codegen
|
package org.jetbrains.kotlin.codegen
|
||||||
|
|
||||||
import com.intellij.psi.tree.IElementType
|
import com.intellij.psi.tree.IElementType
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
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.Label
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||||
@@ -58,7 +48,7 @@ abstract class SafeCallFusedWithPrimitiveEqualityBase(
|
|||||||
v.mark(endLabel)
|
v.mark(endLabel)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun putSelector(type: Type, v: InstructionAdapter) {
|
override fun putSelector(type: Type, kotlinType: KotlinType?, v: InstructionAdapter) {
|
||||||
val falseLabel = Label()
|
val falseLabel = Label()
|
||||||
val endLabel = Label()
|
val endLabel = Label()
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2015 JetBrains s.r.o.
|
* 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.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.codegen
|
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.fakeAlwaysFalseIfeq
|
||||||
import org.jetbrains.kotlin.codegen.pseudoInsns.fakeAlwaysTrueIfeq
|
import org.jetbrains.kotlin.codegen.pseudoInsns.fakeAlwaysTrueIfeq
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
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.Label
|
||||||
import org.jetbrains.org.objectweb.asm.Opcodes.*
|
import org.jetbrains.org.objectweb.asm.Opcodes.*
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
@@ -32,7 +22,7 @@ open class BranchedValue(
|
|||||||
val opcode: Int
|
val opcode: Int
|
||||||
) : StackValue(Type.BOOLEAN_TYPE) {
|
) : StackValue(Type.BOOLEAN_TYPE) {
|
||||||
|
|
||||||
override fun putSelector(type: Type, v: InstructionAdapter) {
|
override fun putSelector(type: Type, kotlinType: KotlinType?, v: InstructionAdapter) {
|
||||||
val branchJumpLabel = Label()
|
val branchJumpLabel = Label()
|
||||||
condJump(branchJumpLabel, v, true)
|
condJump(branchJumpLabel, v, true)
|
||||||
val endLabel = Label()
|
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)
|
v.iconst(1)
|
||||||
coerceTo(type, v)
|
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)
|
v.iconst(0)
|
||||||
coerceTo(type, v)
|
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) {
|
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")
|
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.descriptors.*;
|
||||||
import org.jetbrains.kotlin.resolve.InlineClassesUtilsKt;
|
import org.jetbrains.kotlin.resolve.InlineClassesUtilsKt;
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
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.Type;
|
||||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||||
|
|
||||||
@@ -127,7 +128,7 @@ public class CallReceiver extends StackValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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;
|
StackValue currentExtensionReceiver = extensionReceiver;
|
||||||
boolean hasExtensionReceiver = extensionReceiver != none();
|
boolean hasExtensionReceiver = extensionReceiver != none();
|
||||||
if (extensionReceiver instanceof SafeCall) {
|
if (extensionReceiver instanceof SafeCall) {
|
||||||
@@ -141,7 +142,12 @@ public class CallReceiver extends StackValue {
|
|||||||
dispatchReceiver.put(dispatchReceiverType, v);
|
dispatchReceiver.put(dispatchReceiverType, v);
|
||||||
|
|
||||||
currentExtensionReceiver
|
currentExtensionReceiver
|
||||||
.moveToTopOfStack(hasExtensionReceiver ? type : currentExtensionReceiver.type, v, dispatchReceiverType.getSize());
|
.moveToTopOfStack(
|
||||||
|
hasExtensionReceiver ? type : currentExtensionReceiver.type,
|
||||||
|
hasExtensionReceiver ? kotlinType : currentExtensionReceiver.kotlinType,
|
||||||
|
v,
|
||||||
|
dispatchReceiverType.getSize()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -341,7 +341,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
value.put(type, v);
|
value.put(type, null, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -916,7 +916,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
if (isStatement) {
|
if (isStatement) {
|
||||||
DeclarationDescriptor descriptor = bindingContext.get(DECLARATION_TO_DESCRIPTOR, function);
|
DeclarationDescriptor descriptor = bindingContext.get(DECLARATION_TO_DESCRIPTOR, function);
|
||||||
int index = lookupLocalIndex(descriptor);
|
int index = lookupLocalIndex(descriptor);
|
||||||
closure.put(OBJECT_TYPE, v);
|
closure.put(OBJECT_TYPE, null, v);
|
||||||
v.store(index, OBJECT_TYPE);
|
v.store(index, OBJECT_TYPE);
|
||||||
return StackValue.none();
|
return StackValue.none();
|
||||||
}
|
}
|
||||||
@@ -1186,7 +1186,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
blockResult = statementResult;
|
blockResult = statementResult;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
statementResult.put(Type.VOID_TYPE, v);
|
statementResult.put(Type.VOID_TYPE, null, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
addLeaveTaskToRemoveDescriptorFromFrameMap(statement, blockEnd, leaveTasks);
|
addLeaveTaskToRemoveDescriptorFromFrameMap(statement, blockEnd, leaveTasks);
|
||||||
@@ -1527,7 +1527,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
StackValue.Local localForReturnValue = StackValue.local(returnValIndex, returnType);
|
StackValue.Local localForReturnValue = StackValue.local(returnValIndex, returnType);
|
||||||
localForReturnValue.store(StackValue.onStack(returnType), v);
|
localForReturnValue.store(StackValue.onStack(returnType), v);
|
||||||
doFinallyOnReturn(afterReturnLabel);
|
doFinallyOnReturn(afterReturnLabel);
|
||||||
localForReturnValue.put(returnType, v);
|
localForReturnValue.put(returnType, null, v);
|
||||||
myFrameMap.leaveTemp(returnType);
|
myFrameMap.leaveTemp(returnType);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -1590,7 +1590,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (typeForExpression.getSort() == Type.VOID) {
|
if (typeForExpression.getSort() == Type.VOID) {
|
||||||
StackValue.none().put(returnType, v);
|
StackValue.none().put(returnType, null, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
v.areturn(returnType);
|
v.areturn(returnType);
|
||||||
@@ -2124,7 +2124,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
Label afterAll = new Label();
|
Label afterAll = new Label();
|
||||||
|
|
||||||
Type functionType = typeMapper.mapType(samType.getKotlinFunctionType());
|
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.dup();
|
||||||
v.ifnull(afterAll);
|
v.ifnull(afterAll);
|
||||||
@@ -2356,7 +2356,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
|
|
||||||
if (!isConstructor) { // otherwise already
|
if (!isConstructor) { // otherwise already
|
||||||
receiver = StackValue.receiver(resolvedCall, receiver, this, callableMethod);
|
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)
|
// 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:
|
// 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) {
|
private StackValue genUnlessProvided(@Nullable StackValue pregenerated, @NotNull KtExpression expr, @NotNull Type type) {
|
||||||
if (pregenerated != null) {
|
if (pregenerated != null) {
|
||||||
pregenerated.put(type, v);
|
pregenerated.put(type, null, v);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
gen(expr, type);
|
gen(expr, type);
|
||||||
@@ -3244,7 +3244,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
int notEquals = opToken != KtTokens.EQEQ ? 1 : 0;
|
int notEquals = opToken != KtTokens.EQEQ ? 1 : 0;
|
||||||
Label end = new Label();
|
Label end = new Label();
|
||||||
StackValue leftValue = pregeneratedLeft != null ? pregeneratedLeft : gen(left);
|
StackValue leftValue = pregeneratedLeft != null ? pregeneratedLeft : gen(left);
|
||||||
leftValue.put(leftValue.type, v);
|
leftValue.put(leftValue.type, leftValue.kotlinType, v);
|
||||||
leftValue = StackValue.onStack(leftValue.type);
|
leftValue = StackValue.onStack(leftValue.type);
|
||||||
Type leftType = left754Type.type;
|
Type leftType = left754Type.type;
|
||||||
Type rightType = right754Type.type;
|
Type rightType = right754Type.type;
|
||||||
@@ -3252,11 +3252,11 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
leftValue.dup(v, false);
|
leftValue.dup(v, false);
|
||||||
Label leftIsNull = new Label();
|
Label leftIsNull = new Label();
|
||||||
v.ifnull(leftIsNull);
|
v.ifnull(leftIsNull);
|
||||||
StackValue.coercion(leftValue, leftType).put(leftType, v);
|
StackValue.coercion(leftValue, leftType).put(leftType, null, v);
|
||||||
StackValue nonNullLeftValue = StackValue.onStack(leftType);
|
StackValue nonNullLeftValue = StackValue.onStack(leftType);
|
||||||
|
|
||||||
StackValue rightValue = gen(right);
|
StackValue rightValue = gen(right);
|
||||||
rightValue.put(rightValue.type, v);
|
rightValue.put(rightValue.type, rightValue.kotlinType, v);
|
||||||
rightValue = StackValue.onStack(rightValue.type);
|
rightValue = StackValue.onStack(rightValue.type);
|
||||||
if (right754Type.isNullable) {
|
if (right754Type.isNullable) {
|
||||||
rightValue.dup(v, false);
|
rightValue.dup(v, false);
|
||||||
@@ -3269,16 +3269,16 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
v.mark(rightIsNotNull);
|
v.mark(rightIsNotNull);
|
||||||
}
|
}
|
||||||
|
|
||||||
StackValue.coercion(rightValue, rightType).put(rightType, v);
|
StackValue.coercion(rightValue, rightType).put(rightType, null, v);
|
||||||
StackValue nonNullRightValue = StackValue.onStack(rightType);
|
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);
|
v.goTo(end);
|
||||||
|
|
||||||
//left is null case
|
//left is null case
|
||||||
v.mark(leftIsNull);
|
v.mark(leftIsNull);
|
||||||
AsmUtil.pop(v, leftValue.type);//pop null left
|
AsmUtil.pop(v, leftValue.type);//pop null left
|
||||||
rightValue = gen(right);
|
rightValue = gen(right);
|
||||||
rightValue.put(rightValue.type, v);
|
rightValue.put(rightValue.type, rightValue.kotlinType, v);
|
||||||
rightValue = StackValue.onStack(rightValue.type);
|
rightValue = StackValue.onStack(rightValue.type);
|
||||||
if (right754Type.isNullable) {
|
if (right754Type.isNullable) {
|
||||||
Label rightIsNotNull = new Label();
|
Label rightIsNotNull = new Label();
|
||||||
@@ -3299,13 +3299,13 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
StackValue.coercion(leftValue, leftType).put(leftType, v);
|
StackValue.coercion(leftValue, leftType).put(leftType, null, v);
|
||||||
leftValue = StackValue.onStack(leftType);
|
leftValue = StackValue.onStack(leftType);
|
||||||
}
|
}
|
||||||
|
|
||||||
//right is nullable cause left is not
|
//right is nullable cause left is not
|
||||||
StackValue rightValue = gen(right);
|
StackValue rightValue = gen(right);
|
||||||
rightValue.put(rightValue.type, v);
|
rightValue.put(rightValue.type, rightValue.kotlinType, v);
|
||||||
rightValue = StackValue.onStack(rightValue.type);
|
rightValue = StackValue.onStack(rightValue.type);
|
||||||
|
|
||||||
rightValue.dup(v, false);
|
rightValue.dup(v, false);
|
||||||
@@ -3317,9 +3317,9 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
v.goTo(end);
|
v.goTo(end);
|
||||||
|
|
||||||
v.mark(rightIsNotNull);
|
v.mark(rightIsNotNull);
|
||||||
StackValue.coercion(rightValue, rightType).put(rightType, v);
|
StackValue.coercion(rightValue, rightType).put(rightType, null, v);
|
||||||
StackValue nonNullRightValue = StackValue.onStack(rightType);
|
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);
|
v.mark(end);
|
||||||
}
|
}
|
||||||
@@ -3359,11 +3359,11 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
}
|
}
|
||||||
|
|
||||||
return StackValue.operation(exprType, v -> {
|
return StackValue.operation(exprType, v -> {
|
||||||
value.put(value.type, v);
|
value.put(value.type, value.kotlinType, v);
|
||||||
v.dup();
|
v.dup();
|
||||||
|
|
||||||
v.ifnull(ifNull);
|
v.ifnull(ifNull);
|
||||||
StackValue.onStack(leftType).put(exprType, v);
|
StackValue.onStack(leftType).put(exprType, null, v);
|
||||||
|
|
||||||
Label end = new Label();
|
Label end = new Label();
|
||||||
v.goTo(end);
|
v.goTo(end);
|
||||||
@@ -3458,10 +3458,10 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
if (keepReturnValue) {
|
if (keepReturnValue) {
|
||||||
value = StackValue.complexWriteReadReceiver(value);
|
value = StackValue.complexWriteReadReceiver(value);
|
||||||
}
|
}
|
||||||
value.put(lhsType, v);
|
value.put(lhsType, null, v);
|
||||||
StackValue receiver = StackValue.onStack(lhsType);
|
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) {
|
if (keepReturnValue) {
|
||||||
value.store(StackValue.onStack(callable.getReturnType()), v, true);
|
value.store(StackValue.onStack(callable.getReturnType()), v, true);
|
||||||
@@ -3497,7 +3497,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
|
|
||||||
Type exprType = expressionType(expr);
|
Type exprType = expressionType(expr);
|
||||||
if (compileTimeConstant != null) {
|
if (compileTimeConstant != null) {
|
||||||
StackValue.constant(compileTimeConstant.getValue(), exprType).put(exprType, v);
|
StackValue.constant(compileTimeConstant.getValue(), exprType).put(exprType, null, v);
|
||||||
} else {
|
} else {
|
||||||
gen(expr, exprType);
|
gen(expr, exprType);
|
||||||
}
|
}
|
||||||
@@ -3549,7 +3549,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
if (isPrimitive(base.type)) return base;
|
if (isPrimitive(base.type)) return base;
|
||||||
|
|
||||||
return StackValue.operation(base.type, v -> {
|
return StackValue.operation(base.type, v -> {
|
||||||
base.put(base.type, v);
|
base.put(base.type, base.kotlinType, v);
|
||||||
v.dup();
|
v.dup();
|
||||||
Label ok = new Label();
|
Label ok = new Label();
|
||||||
v.ifnonnull(ok);
|
v.ifnonnull(ok);
|
||||||
@@ -3600,7 +3600,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
return StackValue.operation(asmBaseType, v -> {
|
return StackValue.operation(asmBaseType, v -> {
|
||||||
StackValue value = StackValue.complexWriteReadReceiver(gen(expression.getBaseExpression()));
|
StackValue value = StackValue.complexWriteReadReceiver(gen(expression.getBaseExpression()));
|
||||||
|
|
||||||
value.put(asmBaseType, v);
|
value.put(asmBaseType, null, v);
|
||||||
AsmUtil.dup(v, asmBaseType);
|
AsmUtil.dup(v, asmBaseType);
|
||||||
|
|
||||||
StackValue previousValue = StackValue.local(myFrameMap.enterTemp(asmBaseType), asmBaseType);
|
StackValue previousValue = StackValue.local(myFrameMap.enterTemp(asmBaseType), asmBaseType);
|
||||||
@@ -3613,13 +3613,13 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
StackValue result = invokeFunction(resolvedCall, StackValue.onStack(asmBaseType));
|
StackValue result = invokeFunction(resolvedCall, StackValue.onStack(asmBaseType));
|
||||||
result.put(result.type, v);
|
result.put(result.type, result.kotlinType, v);
|
||||||
storeType = result.type;
|
storeType = result.type;
|
||||||
}
|
}
|
||||||
|
|
||||||
value.store(StackValue.onStack(storeType), v, true);
|
value.store(StackValue.onStack(storeType), v, true);
|
||||||
|
|
||||||
previousValue.put(asmBaseType, v);
|
previousValue.put(asmBaseType, null, v);
|
||||||
|
|
||||||
myFrameMap.leaveTemp(asmBaseType);
|
myFrameMap.leaveTemp(asmBaseType);
|
||||||
|
|
||||||
@@ -3756,12 +3756,12 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
if (variableDescriptor.isLateInit()) {
|
if (variableDescriptor.isLateInit()) {
|
||||||
assert initializer == null : "Initializer should be null for lateinit var " + variableDescriptor + ": " + initializer;
|
assert initializer == null : "Initializer should be null for lateinit var " + variableDescriptor + ": " + initializer;
|
||||||
v.aconst(null);
|
v.aconst(null);
|
||||||
storeTo.storeSelector(storeTo.type, v);
|
storeTo.storeSelector(storeTo.type, storeTo.kotlinType, v);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert initializer != null : "Initializer should be not null for " + variableDescriptor;
|
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);
|
markLineNumber(variableDeclaration, false);
|
||||||
Type resultType = initializer.type;
|
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
|
@NotNull
|
||||||
@@ -3798,14 +3798,14 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
arguments.get(1).asElement(),
|
arguments.get(1).asElement(),
|
||||||
new StackValue(K_PROPERTY_TYPE) {
|
new StackValue(K_PROPERTY_TYPE) {
|
||||||
@Override
|
@Override
|
||||||
public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) {
|
public void putSelector(@NotNull Type type, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v) {
|
||||||
metadataValue.put(type, v);
|
metadataValue.put(type, kotlinType, v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
StackValue result = invokeFunction(provideDelegateResolvedCall, provideDelegateReceiver);
|
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(0).asElement());
|
||||||
tempVariables.remove(arguments.get(1).asElement());
|
tempVariables.remove(arguments.get(1).asElement());
|
||||||
return result.type;
|
return result.type;
|
||||||
@@ -3831,8 +3831,8 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
StackValue value = context.getFunctionDescriptor().isInline()
|
StackValue value = context.getFunctionDescriptor().isInline()
|
||||||
? generatePropertyReference(variable.getDelegate(), variableDescriptor, variableDescriptor, null)
|
? generatePropertyReference(variable.getDelegate(), variableDescriptor, variableDescriptor, null)
|
||||||
: PropertyCodegen.getDelegatedPropertyMetadata(variableDescriptor, bindingContext);
|
: PropertyCodegen.getDelegatedPropertyMetadata(variableDescriptor, bindingContext);
|
||||||
value.put(K_PROPERTY_TYPE, v);
|
value.put(K_PROPERTY_TYPE, null, v);
|
||||||
metadataVar.storeSelector(K_PROPERTY_TYPE, v);
|
metadataVar.storeSelector(K_PROPERTY_TYPE, null, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -3883,10 +3883,11 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
ReceiverParameterDescriptor dispatchReceiver = constructor.getDispatchReceiverParameter();
|
ReceiverParameterDescriptor dispatchReceiver = constructor.getDispatchReceiverParameter();
|
||||||
ClassDescriptor containingDeclaration = constructor.getContainingDeclaration();
|
ClassDescriptor containingDeclaration = constructor.getContainingDeclaration();
|
||||||
if (dispatchReceiver != null) {
|
if (dispatchReceiver != null) {
|
||||||
Type receiverType = typeMapper.mapType(dispatchReceiver.getType());
|
KotlinType kotlinType = dispatchReceiver.getType();
|
||||||
|
Type receiverType = typeMapper.mapType(kotlinType);
|
||||||
ReceiverValue receiver = getConstructorReceiver(resolvedCall);
|
ReceiverValue receiver = getConstructorReceiver(resolvedCall);
|
||||||
boolean callSuper = containingDeclaration.isInner() && receiver instanceof ImplicitClassReceiver;
|
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
|
// 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);
|
StackValue value = genQualified(receiver, left);
|
||||||
|
|
||||||
return StackValue.operation(boxType(asmType(rightType)), v -> {
|
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) {
|
if (value.type == Type.VOID_TYPE) {
|
||||||
StackValue.putUnitInstance(v);
|
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) {
|
private StackValue generateIsCheck(StackValue expressionToGen, KotlinType kotlinType, boolean leaveExpressionOnStack) {
|
||||||
return StackValue.operation(Type.BOOLEAN_TYPE, v -> {
|
return StackValue.operation(Type.BOOLEAN_TYPE, v -> {
|
||||||
expressionToGen.put(OBJECT_TYPE, v);
|
expressionToGen.put(OBJECT_TYPE, null, v);
|
||||||
if (leaveExpressionOnStack) {
|
if (leaveExpressionOnStack) {
|
||||||
v.dup();
|
v.dup();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
* 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.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.codegen;
|
package org.jetbrains.kotlin.codegen;
|
||||||
@@ -71,14 +60,25 @@ public abstract class StackValue {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public final Type type;
|
public final Type type;
|
||||||
|
@Nullable
|
||||||
|
public final KotlinType kotlinType;
|
||||||
private final boolean canHaveSideEffects;
|
private final boolean canHaveSideEffects;
|
||||||
|
|
||||||
protected StackValue(@NotNull Type type) {
|
protected StackValue(@NotNull Type type) {
|
||||||
this(type, true);
|
this(type, null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected StackValue(@NotNull Type type, boolean canHaveSideEffects) {
|
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.type = type;
|
||||||
|
this.kotlinType = kotlinType;
|
||||||
this.canHaveSideEffects = canHaveSideEffects;
|
this.canHaveSideEffects = canHaveSideEffects;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,28 +90,31 @@ public abstract class StackValue {
|
|||||||
* @param v the visitor used to genClassOrObject the instructions
|
* @param v the visitor used to genClassOrObject the instructions
|
||||||
* @param depth the number of new values put onto the stack
|
* @param depth the number of new values put onto the stack
|
||||||
*/
|
*/
|
||||||
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) {
|
||||||
put(type, v);
|
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) {
|
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) {
|
if (!skipReceiver) {
|
||||||
putReceiver(v, true);
|
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) {
|
public boolean isNonStaticAccess(boolean isRead) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void putReceiver(@NotNull InstructionAdapter v, boolean isRead) {
|
public void putReceiver(@NotNull InstructionAdapter v, boolean isRead) {
|
||||||
//by default there is no receiver
|
//by default there is no receiver
|
||||||
//if you have it inherit StackValueWithSimpleReceiver
|
//if you have it inherit StackValueWithSimpleReceiver
|
||||||
@@ -135,11 +138,11 @@ public abstract class StackValue {
|
|||||||
if (!skipReceiver) {
|
if (!skipReceiver) {
|
||||||
putReceiver(v, false);
|
putReceiver(v, false);
|
||||||
}
|
}
|
||||||
value.put(value.type, v);
|
value.put(value.type, value.kotlinType, v);
|
||||||
storeSelector(value.type, 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);
|
throw new UnsupportedOperationException("Cannot store to value " + this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -447,7 +450,7 @@ public abstract class StackValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void putUnitInstance(@NotNull InstructionAdapter v) {
|
public static void putUnitInstance(@NotNull InstructionAdapter v) {
|
||||||
unit().put(UNIT_TYPE, v);
|
unit().put(UNIT_TYPE, null, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static StackValue unit() {
|
public static StackValue unit() {
|
||||||
@@ -661,7 +664,7 @@ public abstract class StackValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
coerceTo(type, v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -692,7 +695,7 @@ public abstract class StackValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
v.load(index, this.type);
|
||||||
if (isLateinit) {
|
if (isLateinit) {
|
||||||
StackValue.genNonNullAssertForLateinit(v, name.asString());
|
StackValue.genNonNullAssertForLateinit(v, name.asString());
|
||||||
@@ -702,7 +705,7 @@ public abstract class StackValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
coerceFrom(topOfStackType, v);
|
||||||
v.store(index, this.type);
|
v.store(index, this.type);
|
||||||
if (isLateinit) {
|
if (isLateinit) {
|
||||||
@@ -746,7 +749,7 @@ public abstract class StackValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
ResolvedCall<FunctionDescriptor> resolvedCall = getResolvedCall(true);
|
||||||
List<? extends ValueArgument> arguments = resolvedCall.getCall().getValueArguments();
|
List<? extends ValueArgument> arguments = resolvedCall.getCall().getValueArguments();
|
||||||
assert arguments.size() == 2 : "Resolved call for 'getValue' should have 2 arguments, but was " +
|
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(0).asElement(), StackValue.constant(null, OBJECT_TYPE));
|
||||||
codegen.tempVariables.put(arguments.get(1).asElement(), metadataValue);
|
codegen.tempVariables.put(arguments.get(1).asElement(), metadataValue);
|
||||||
StackValue lastValue = codegen.invokeFunction(resolvedCall, delegateValue);
|
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(0).asElement());
|
||||||
codegen.tempVariables.remove(arguments.get(1).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(1).asElement(), metadataValue);
|
||||||
codegen.tempVariables.put(arguments.get(2).asElement(), rightSide);
|
codegen.tempVariables.put(arguments.get(2).asElement(), rightSide);
|
||||||
StackValue lastValue = codegen.invokeFunction(resolvedCall, delegateValue);
|
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(0).asElement());
|
||||||
codegen.tempVariables.remove(arguments.get(1).asElement());
|
codegen.tempVariables.remove(arguments.get(1).asElement());
|
||||||
@@ -786,14 +789,14 @@ public abstract class StackValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
coerceTo(type, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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) {
|
if (depth == 0) {
|
||||||
put(type, v);
|
put(type, kotlinType, v);
|
||||||
}
|
}
|
||||||
else if (depth == 1) {
|
else if (depth == 1) {
|
||||||
int size = this.type.getSize();
|
int size = this.type.getSize();
|
||||||
@@ -843,7 +846,7 @@ public abstract class StackValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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) {
|
if (value instanceof Integer || value instanceof Byte || value instanceof Short) {
|
||||||
v.iconst(((Number) value).intValue());
|
v.iconst(((Number) value).intValue());
|
||||||
}
|
}
|
||||||
@@ -878,7 +881,7 @@ public abstract class StackValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
coerceFrom(topOfStackType, v);
|
||||||
v.astore(this.type);
|
v.astore(this.type);
|
||||||
}
|
}
|
||||||
@@ -890,7 +893,7 @@ public abstract class StackValue {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void putSelector(
|
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
|
v.aload(this.type); // assumes array and index are on the stack
|
||||||
coerceTo(type, v);
|
coerceTo(type, v);
|
||||||
@@ -932,11 +935,11 @@ public abstract class StackValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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;
|
ResolvedCall<?> call = isGetter ? resolvedGetCall : resolvedSetCall;
|
||||||
StackValue newReceiver = StackValue.receiver(call, receiver, codegen, callable);
|
StackValue newReceiver = StackValue.receiver(call, receiver, codegen, callable);
|
||||||
ArgumentGenerator generator = createArgumentGenerator();
|
ArgumentGenerator generator = createArgumentGenerator();
|
||||||
newReceiver.put(newReceiver.type, v);
|
newReceiver.put(newReceiver.type, newReceiver.kotlinType, v);
|
||||||
callGenerator.processAndPutHiddenParameters(false);
|
callGenerator.processAndPutHiddenParameters(false);
|
||||||
|
|
||||||
defaultArgs = generator.generate(valueArguments, valueArguments, call.getResultingDescriptor());
|
defaultArgs = generator.generate(valueArguments, valueArguments, call.getResultingDescriptor());
|
||||||
@@ -1012,7 +1015,7 @@ public abstract class StackValue {
|
|||||||
|
|
||||||
if (resolvedSetCall.getDispatchReceiver() != null) {
|
if (resolvedSetCall.getDispatchReceiver() != null) {
|
||||||
if (resolvedSetCall.getExtensionReceiver() != 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);
|
v.load(realReceiverIndex, realReceiverType);
|
||||||
}
|
}
|
||||||
@@ -1077,7 +1080,7 @@ public abstract class StackValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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) {
|
if (getter == null) {
|
||||||
throw new UnsupportedOperationException("no getter specified");
|
throw new UnsupportedOperationException("no getter specified");
|
||||||
}
|
}
|
||||||
@@ -1141,7 +1144,7 @@ public abstract class StackValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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) {
|
if (setter == null) {
|
||||||
throw new UnsupportedOperationException("no setter specified");
|
throw new UnsupportedOperationException("no setter specified");
|
||||||
}
|
}
|
||||||
@@ -1197,13 +1200,13 @@ public abstract class StackValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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());
|
v.visitFieldInsn(isStaticPut ? GETSTATIC : GETFIELD, owner.getInternalName(), name, this.type.getDescriptor());
|
||||||
coerceTo(type, v);
|
coerceTo(type, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
coerceFrom(topOfStackType, v);
|
||||||
v.visitFieldInsn(isStaticStore ? PUTSTATIC : PUTFIELD, owner.getInternalName(), name, this.type.getDescriptor());
|
v.visitFieldInsn(isStaticStore ? PUTSTATIC : PUTFIELD, owner.getInternalName(), name, this.type.getDescriptor());
|
||||||
}
|
}
|
||||||
@@ -1242,7 +1245,7 @@ public abstract class StackValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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) {
|
if (getter == null) {
|
||||||
assert fieldName != null : "Property should have either a getter or a field name: " + descriptor;
|
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;
|
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();
|
value = ((Double) value).floatValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
StackValue.constant(value, this.type).putSelector(type, v);
|
StackValue.constant(value, this.type).putSelector(type, null, v);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1345,7 +1348,7 @@ public abstract class StackValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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) {
|
if (setter == null) {
|
||||||
coerceFrom(topOfStackType, v);
|
coerceFrom(topOfStackType, v);
|
||||||
assert fieldName != null : "Property should have either a setter or a field name: " + descriptor;
|
assert fieldName != null : "Property should have either a setter or a field name: " + descriptor;
|
||||||
@@ -1406,7 +1409,7 @@ public abstract class StackValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
generator.gen(expression, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1437,7 +1440,7 @@ public abstract class StackValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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 refType = refType(this.type);
|
||||||
Type sharedType = sharedTypeForType(this.type);
|
Type sharedType = sharedTypeForType(this.type);
|
||||||
v.visitFieldInsn(GETFIELD, sharedType.getInternalName(), "element", refType.getDescriptor());
|
v.visitFieldInsn(GETFIELD, sharedType.getInternalName(), "element", refType.getDescriptor());
|
||||||
@@ -1449,7 +1452,7 @@ public abstract class StackValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
coerceFrom(topOfStackType, v);
|
||||||
Type refType = refType(this.type);
|
Type refType = refType(this.type);
|
||||||
Type sharedType = sharedTypeForType(this.type);
|
Type sharedType = sharedTypeForType(this.type);
|
||||||
@@ -1501,7 +1504,7 @@ public abstract class StackValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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 sharedType = sharedTypeForType(this.type);
|
||||||
Type refType = refType(this.type);
|
Type refType = refType(this.type);
|
||||||
v.visitFieldInsn(GETFIELD, sharedType.getInternalName(), "element", refType.getDescriptor());
|
v.visitFieldInsn(GETFIELD, sharedType.getInternalName(), "element", refType.getDescriptor());
|
||||||
@@ -1513,7 +1516,7 @@ public abstract class StackValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
coerceFrom(topOfStackType, v);
|
||||||
v.visitFieldInsn(PUTFIELD, sharedTypeForType(type).getInternalName(), "element", refType(type).getDescriptor());
|
v.visitFieldInsn(PUTFIELD, sharedTypeForType(type).getInternalName(), "element", refType(type).getDescriptor());
|
||||||
}
|
}
|
||||||
@@ -1539,9 +1542,13 @@ public abstract class StackValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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 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
|
@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)) {
|
if (!type.equals(Type.VOID_TYPE)) {
|
||||||
v.load(index, Type.INT_TYPE);
|
v.load(index, Type.INT_TYPE);
|
||||||
coerceTo(type, v);
|
coerceTo(type, v);
|
||||||
@@ -1576,7 +1583,7 @@ public abstract class StackValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
v.iinc(index, increment);
|
||||||
if (!type.equals(Type.VOID_TYPE)) {
|
if (!type.equals(Type.VOID_TYPE)) {
|
||||||
v.load(index, Type.INT_TYPE);
|
v.load(index, Type.INT_TYPE);
|
||||||
@@ -1603,13 +1610,13 @@ public abstract class StackValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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 = 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.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);
|
coerceTo(type, v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1639,7 +1646,11 @@ public abstract class StackValue {
|
|||||||
public void putReceiver(@NotNull InstructionAdapter v, boolean isRead) {
|
public void putReceiver(@NotNull InstructionAdapter v, boolean isRead) {
|
||||||
boolean hasReceiver = isNonStaticAccess(isRead);
|
boolean hasReceiver = isNonStaticAccess(isRead);
|
||||||
if (hasReceiver || receiver.canHaveSideEffects()) {
|
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) {
|
if (!skipReceiver) {
|
||||||
putReceiver(v, false);
|
putReceiver(v, false);
|
||||||
}
|
}
|
||||||
rightSide.put(rightSide.type, v);
|
rightSide.put(rightSide.type, rightSide.kotlinType, v);
|
||||||
storeSelector(rightSide.type, v);
|
storeSelector(rightSide.type, rightSide.kotlinType, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected StackValueWithSimpleReceiver changeReceiver(@NotNull StackValue newReceiver) {
|
protected StackValueWithSimpleReceiver changeReceiver(@NotNull StackValue newReceiver) {
|
||||||
@@ -1722,14 +1733,14 @@ public abstract class StackValue {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void putSelector(
|
public void putSelector(
|
||||||
@NotNull Type type, @NotNull InstructionAdapter v
|
@NotNull Type type, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v
|
||||||
) {
|
) {
|
||||||
boolean wasPut = false;
|
boolean wasPut = false;
|
||||||
StackValue receiver = originalValueWithReceiver.receiver;
|
StackValue receiver = originalValueWithReceiver.receiver;
|
||||||
for (boolean operation : isReadOperations) {
|
for (boolean operation : isReadOperations) {
|
||||||
if (originalValueWithReceiver.isNonStaticAccess(operation)) {
|
if (originalValueWithReceiver.isNonStaticAccess(operation)) {
|
||||||
if (!wasPut) {
|
if (!wasPut) {
|
||||||
receiver.put(receiver.type, v);
|
receiver.put(receiver.type, receiver.kotlinType, v);
|
||||||
wasPut = true;
|
wasPut = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -1739,7 +1750,7 @@ public abstract class StackValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!wasPut && receiver.canHaveSideEffects()) {
|
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
|
@Override
|
||||||
public void putSelector(
|
public void putSelector(
|
||||||
@NotNull Type type, @NotNull InstructionAdapter v
|
@NotNull Type type, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v
|
||||||
) {
|
) {
|
||||||
for (StackValue instruction : instructions) {
|
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
|
@Override
|
||||||
public void putSelector(
|
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
|
@Override
|
||||||
@@ -1797,9 +1808,9 @@ public abstract class StackValue {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void storeSelector(
|
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
|
@Override
|
||||||
@@ -1841,8 +1852,8 @@ public abstract class StackValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) {
|
public void putSelector(@NotNull Type type, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v) {
|
||||||
receiver.put(this.type, v);
|
receiver.put(this.type, this.kotlinType, v);
|
||||||
if (ifNull != null) {
|
if (ifNull != null) {
|
||||||
//not a primitive
|
//not a primitive
|
||||||
v.dup();
|
v.dup();
|
||||||
@@ -1862,7 +1873,7 @@ public abstract class StackValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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();
|
Label end = new Label();
|
||||||
|
|
||||||
v.goTo(end);
|
v.goTo(end);
|
||||||
|
|||||||
@@ -1,17 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2015 JetBrains s.r.o.
|
* 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.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.codegen
|
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.StackValue.*
|
||||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
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.Constant
|
||||||
|
import org.jetbrains.kotlin.load.java.EnumEntry
|
||||||
import org.jetbrains.kotlin.load.java.descriptors.NullDefaultValue
|
import org.jetbrains.kotlin.load.java.descriptors.NullDefaultValue
|
||||||
import org.jetbrains.kotlin.load.java.descriptors.StringDefaultValue
|
import org.jetbrains.kotlin.load.java.descriptors.StringDefaultValue
|
||||||
import org.jetbrains.kotlin.load.java.descriptors.getDefaultValueFromAnnotation
|
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.kotlin.utils.DFS
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||||
@@ -34,14 +25,14 @@ class CoercionValue(
|
|||||||
private val castType: Type
|
private val castType: Type
|
||||||
) : StackValue(castType, value.canHaveSideEffects()) {
|
) : StackValue(castType, value.canHaveSideEffects()) {
|
||||||
|
|
||||||
override fun putSelector(type: Type, v: InstructionAdapter) {
|
override fun putSelector(type: Type, kotlinType: KotlinType?, v: InstructionAdapter) {
|
||||||
value.putSelector(value.type, v)
|
value.putSelector(value.type, value.kotlinType, v)
|
||||||
StackValue.coerce(value.type, castType, v)
|
StackValue.coerce(value.type, castType, v)
|
||||||
StackValue.coerce(castType, type, v)
|
StackValue.coerce(castType, type, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun storeSelector(topOfStackType: Type, v: InstructionAdapter) {
|
override fun storeSelector(topOfStackType: Type, topOfStackKotlinType: KotlinType?, v: InstructionAdapter) {
|
||||||
value.storeSelector(topOfStackType, v)
|
value.storeSelector(topOfStackType, topOfStackKotlinType, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun putReceiver(v: InstructionAdapter, isRead: Boolean) {
|
override fun putReceiver(v: InstructionAdapter, isRead: Boolean) {
|
||||||
@@ -63,15 +54,15 @@ class StackValueWithLeaveTask(
|
|||||||
stackValue.putReceiver(v, isRead)
|
stackValue.putReceiver(v, isRead)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun putSelector(type: Type, v: InstructionAdapter) {
|
override fun putSelector(type: Type, kotlinType: KotlinType?, v: InstructionAdapter) {
|
||||||
stackValue.putSelector(type, v)
|
stackValue.putSelector(type, kotlinType, v)
|
||||||
leaveTasks(stackValue)
|
leaveTasks(stackValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
open class OperationStackValue(resultType: Type, val lambda: (v: InstructionAdapter) -> Unit) : StackValue(resultType) {
|
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)
|
lambda(v)
|
||||||
coerceTo(type, v)
|
coerceTo(type, v)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2017 JetBrains s.r.o.
|
* 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.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.codegen.range
|
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.codegen.range.inExpression.InExpressionGenerator
|
||||||
import org.jetbrains.kotlin.psi.KtForExpression
|
import org.jetbrains.kotlin.psi.KtForExpression
|
||||||
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
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.Type
|
||||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||||
|
|
||||||
@@ -52,7 +42,7 @@ interface BoundedValue {
|
|||||||
|
|
||||||
fun BoundedValue.asStackValue(): StackValue =
|
fun BoundedValue.asStackValue(): StackValue =
|
||||||
object : StackValue(instanceType) {
|
object : StackValue(instanceType) {
|
||||||
override fun putSelector(type: Type, v: InstructionAdapter) {
|
override fun putSelector(type: Type, kotlinType: KotlinType?, v: InstructionAdapter) {
|
||||||
putInstance(v, type)
|
putInstance(v, type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-14
@@ -1,17 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2017 JetBrains s.r.o.
|
* 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.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.codegen.range.inExpression
|
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.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCallWithAssert
|
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.Label
|
||||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
@@ -40,7 +30,7 @@ class CallBasedInExpressionGenerator(
|
|||||||
|
|
||||||
private fun gen(argument: StackValue): BranchedValue =
|
private fun gen(argument: StackValue): BranchedValue =
|
||||||
object : BranchedValue(argument, null, argument.type, Opcodes.IFEQ) {
|
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)
|
invokeFunction(v)
|
||||||
coerceTo(type, v)
|
coerceTo(type, v)
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-15
@@ -1,17 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2017 JetBrains s.r.o.
|
* 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.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.android.synthetic.codegen
|
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.CacheImplementation
|
||||||
import kotlinx.android.extensions.LayoutContainer
|
import kotlinx.android.extensions.LayoutContainer
|
||||||
import org.jetbrains.kotlin.android.synthetic.AndroidConst
|
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.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.descriptors.ContainerOptionsProxy
|
||||||
import org.jetbrains.kotlin.android.synthetic.res.AndroidSyntheticProperty
|
import org.jetbrains.kotlin.android.synthetic.res.AndroidSyntheticProperty
|
||||||
import org.jetbrains.kotlin.codegen.StackValue
|
import org.jetbrains.kotlin.codegen.StackValue
|
||||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.lowerIfFlexible
|
import org.jetbrains.kotlin.types.lowerIfFlexible
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||||
@@ -46,7 +36,7 @@ class ResourcePropertyStackValue(
|
|||||||
assert(containerOptions.containerType != AndroidContainerType.UNKNOWN)
|
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
|
val returnTypeString = typeMapper.mapType(resource.type.lowerIfFlexible()).className
|
||||||
if (AndroidConst.FRAGMENT_FQNAME == returnTypeString || AndroidConst.SUPPORT_FRAGMENT_FQNAME == returnTypeString) {
|
if (AndroidConst.FRAGMENT_FQNAME == returnTypeString || AndroidConst.SUPPORT_FRAGMENT_FQNAME == returnTypeString) {
|
||||||
return putSelectorForFragment(v)
|
return putSelectorForFragment(v)
|
||||||
|
|||||||
Reference in New Issue
Block a user