diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index 3ec3ca7aa5d..972bc0038a7 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -27,6 +27,7 @@ import com.intellij.util.containers.Stack; import kotlin.CollectionsKt; import kotlin.Unit; import kotlin.jvm.functions.Function1; +import kotlin.jvm.functions.Function2; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.backend.common.CodegenUtil; @@ -3749,7 +3750,7 @@ The "returned" value of try expression with no finally is either the last expres return negated ? StackValue.not(value) : value; } - private StackValue generateInstanceOf(final StackValue expressionToGen, final KotlinType jetType, final boolean leaveExpressionOnStack) { + private StackValue generateInstanceOf(final StackValue expressionToGen, final KotlinType kotlinType, final boolean leaveExpressionOnStack) { return StackValue.operation(Type.BOOLEAN_TYPE, new Function1() { @Override public Unit invoke(InstructionAdapter v) { @@ -3757,22 +3758,13 @@ The "returned" value of try expression with no finally is either the last expres if (leaveExpressionOnStack) { v.dup(); } - if (jetType.isMarkedNullable()) { - Label nope = new Label(); - Label end = new Label(); - - v.dup(); - v.ifnull(nope); - generateInstanceOfInstruction(jetType); - v.goTo(end); - v.mark(nope); - v.pop(); - v.iconst(1); - v.mark(end); - } - else { - generateInstanceOfInstruction(jetType); - } + CodegenUtilKt.generateIsCheck(v, kotlinType, new Function1() { + @Override + public Unit invoke(InstructionAdapter adapter) { + generateInstanceOfInstruction(kotlinType); + return Unit.INSTANCE; + } + }); return null; } }); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java index b0e898740f3..8729c48ea60 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java @@ -21,6 +21,7 @@ import com.intellij.psi.PsiElement; import com.intellij.util.ArrayUtil; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; +import kotlin.Unit; import kotlin.jvm.functions.Function1; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -880,7 +881,7 @@ public class FunctionCodegen { @NotNull InstructionAdapter iv, @NotNull FunctionDescriptor descriptor, @NotNull Method bridge, - @NotNull Method delegateTo + @NotNull final Method delegateTo ) { if (BuiltinMethodsWithSpecialGenericSignature.getOverriddenBuiltinFunctionWithErasedValueParametersInJava(descriptor) == null) return; @@ -890,33 +891,14 @@ public class FunctionCodegen { iv.load(1, OBJECT_TYPE); - KotlinType jetType = descriptor.getValueParameters().get(0).getType(); - - // TODO: reuse logic from ExpressionCodegen - if (jetType.isMarkedNullable()) { - Label nope = new Label(); - Label end = new Label(); - - iv.dup(); - iv.ifnull(nope); - TypeIntrinsics.instanceOf( - iv, - jetType, - boxType(delegateTo.getArgumentTypes()[0]) - ); - iv.goTo(end); - iv.mark(nope); - iv.pop(); - iv.iconst(1); - iv.mark(end); - } - else { - TypeIntrinsics.instanceOf( - iv, - jetType, - boxType(delegateTo.getArgumentTypes()[0]) - ); - } + final KotlinType kotlinType = descriptor.getValueParameters().get(0).getType(); + CodegenUtilKt.generateIsCheck(iv, kotlinType, new Function1() { + @Override + public Unit invoke(InstructionAdapter adapter) { + TypeIntrinsics.instanceOf(adapter, kotlinType, boxType(delegateTo.getArgumentTypes()[0])); + return Unit.INSTANCE; + } + }); Label afterBarrier = new Label(); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/codegenUtil.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/codegenUtil.kt new file mode 100644 index 00000000000..3150bfc799d --- /dev/null +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/codegenUtil.kt @@ -0,0 +1,51 @@ +/* + * 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. + */ + + +package org.jetbrains.kotlin.codegen + +import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.org.objectweb.asm.Label +import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter + +fun generateIsCheck( + v: InstructionAdapter, + type: KotlinType, + generateInstanceOfInstruction: (InstructionAdapter) -> Unit +) { + if (type.isMarkedNullable) { + val nope = Label() + val end = Label() + + with(v) { + dup() + + ifnull(nope) + + generateInstanceOfInstruction(this) + goTo(end) + + mark(nope) + pop() + iconst(1) + + mark(end) + } + } + else { + generateInstanceOfInstruction(v) + } +}