Extract common logic into generateIsCheck

This commit is contained in:
Denis Zharkov
2015-11-13 16:42:46 +03:00
parent f5a086140e
commit 34518c0ecc
3 changed files with 70 additions and 45 deletions
@@ -27,6 +27,7 @@ import com.intellij.util.containers.Stack;
import kotlin.CollectionsKt; import kotlin.CollectionsKt;
import kotlin.Unit; import kotlin.Unit;
import kotlin.jvm.functions.Function1; import kotlin.jvm.functions.Function1;
import kotlin.jvm.functions.Function2;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.backend.common.CodegenUtil; 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; 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<InstructionAdapter, Unit>() { return StackValue.operation(Type.BOOLEAN_TYPE, new Function1<InstructionAdapter, Unit>() {
@Override @Override
public Unit invoke(InstructionAdapter v) { 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) { if (leaveExpressionOnStack) {
v.dup(); v.dup();
} }
if (jetType.isMarkedNullable()) { CodegenUtilKt.generateIsCheck(v, kotlinType, new Function1<InstructionAdapter, Unit>() {
Label nope = new Label(); @Override
Label end = new Label(); public Unit invoke(InstructionAdapter adapter) {
generateInstanceOfInstruction(kotlinType);
v.dup(); return Unit.INSTANCE;
v.ifnull(nope); }
generateInstanceOfInstruction(jetType); });
v.goTo(end);
v.mark(nope);
v.pop();
v.iconst(1);
v.mark(end);
}
else {
generateInstanceOfInstruction(jetType);
}
return null; return null;
} }
}); });
@@ -21,6 +21,7 @@ import com.intellij.psi.PsiElement;
import com.intellij.util.ArrayUtil; import com.intellij.util.ArrayUtil;
import com.intellij.util.Function; import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.ContainerUtil;
import kotlin.Unit;
import kotlin.jvm.functions.Function1; import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -880,7 +881,7 @@ public class FunctionCodegen {
@NotNull InstructionAdapter iv, @NotNull InstructionAdapter iv,
@NotNull FunctionDescriptor descriptor, @NotNull FunctionDescriptor descriptor,
@NotNull Method bridge, @NotNull Method bridge,
@NotNull Method delegateTo @NotNull final Method delegateTo
) { ) {
if (BuiltinMethodsWithSpecialGenericSignature.getOverriddenBuiltinFunctionWithErasedValueParametersInJava(descriptor) == null) return; if (BuiltinMethodsWithSpecialGenericSignature.getOverriddenBuiltinFunctionWithErasedValueParametersInJava(descriptor) == null) return;
@@ -890,33 +891,14 @@ public class FunctionCodegen {
iv.load(1, OBJECT_TYPE); iv.load(1, OBJECT_TYPE);
KotlinType jetType = descriptor.getValueParameters().get(0).getType(); final KotlinType kotlinType = descriptor.getValueParameters().get(0).getType();
CodegenUtilKt.generateIsCheck(iv, kotlinType, new Function1<InstructionAdapter, Unit>() {
// TODO: reuse logic from ExpressionCodegen @Override
if (jetType.isMarkedNullable()) { public Unit invoke(InstructionAdapter adapter) {
Label nope = new Label(); TypeIntrinsics.instanceOf(adapter, kotlinType, boxType(delegateTo.getArgumentTypes()[0]));
Label end = new Label(); return Unit.INSTANCE;
}
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])
);
}
Label afterBarrier = new Label(); Label afterBarrier = new Label();
@@ -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)
}
}