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.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<InstructionAdapter, Unit>() {
@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<InstructionAdapter, Unit>() {
@Override
public Unit invoke(InstructionAdapter adapter) {
generateInstanceOfInstruction(kotlinType);
return Unit.INSTANCE;
}
});
return null;
}
});
@@ -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<InstructionAdapter, Unit>() {
@Override
public Unit invoke(InstructionAdapter adapter) {
TypeIntrinsics.instanceOf(adapter, kotlinType, boxType(delegateTo.getArgumentTypes()[0]));
return Unit.INSTANCE;
}
});
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)
}
}