JVM_IR. Support anonymous object/lambda reification

This commit is contained in:
Mikhael Bogdanov
2019-08-05 14:49:19 +02:00
parent 0571f90762
commit 645736f167
29 changed files with 42 additions and 51 deletions
@@ -19,7 +19,6 @@ package org.jetbrains.kotlin.codegen
import org.jetbrains.kotlin.codegen.inline.NameGenerator
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeParametersUsages
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
interface BaseExpressionCodegen {
@@ -32,8 +31,6 @@ interface BaseExpressionCodegen {
val lastLineNumber: Int
fun consumeReifiedOperationMarker(typeParameterDescriptor: TypeParameterDescriptor)
fun propagateChildReifiedTypeParametersUsages(reifiedTypeParametersUsages: ReifiedTypeParametersUsages)
fun pushClosureOnStack(
@@ -92,6 +92,7 @@ import org.jetbrains.org.objectweb.asm.commons.Method;
import java.util.*;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isInt;
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
@@ -1031,7 +1032,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
@NotNull
public StackValue putClosureInstanceOnStack(
private StackValue putClosureInstanceOnStack(
@NotNull ClosureCodegen closureCodegen,
@Nullable StackValue functionReferenceReceiver
) {
@@ -4839,16 +4840,16 @@ The "returned" value of try expression with no finally is either the last expres
putReifiedOperationMarkerIfTypeIsReifiedParameterImpl(type, operationKind, v, null);
}
public static void putReifiedOperationMarkerIfTypeIsReifiedParameter(
private static void putReifiedOperationMarkerIfTypeIsReifiedParameter(
@NotNull KotlinType type, @NotNull ReifiedTypeInliner.OperationKind operationKind, @NotNull InstructionAdapter v,
@NotNull BaseExpressionCodegen codegen
@NotNull ExpressionCodegen codegen
) {
putReifiedOperationMarkerIfTypeIsReifiedParameterImpl(type, operationKind, v, codegen);
}
private static void putReifiedOperationMarkerIfTypeIsReifiedParameterImpl(
@NotNull KotlinType type, @NotNull ReifiedTypeInliner.OperationKind operationKind, @NotNull InstructionAdapter v,
@Nullable BaseExpressionCodegen codegen
@Nullable ExpressionCodegen codegen
) {
Pair<TypeParameterDescriptor, ReificationArgument> typeParameterAndReificationArgument = extractReificationArgument(type);
if (typeParameterAndReificationArgument != null && typeParameterAndReificationArgument.getFirst().isReified()) {
@@ -4862,7 +4863,11 @@ The "returned" value of try expression with no finally is either the last expres
@Override
public void propagateChildReifiedTypeParametersUsages(@NotNull ReifiedTypeParametersUsages usages) {
parentCodegen.getReifiedTypeParametersUsages().propagateChildUsagesWithinContext(usages, context);
parentCodegen.getReifiedTypeParametersUsages().propagateChildUsagesWithinContext(
usages,
() -> context.getContextDescriptor().getTypeParameters().stream().filter(TypeParameterDescriptor::isReified).map(
it -> it.getName().asString()).collect(Collectors.toSet())
);
}
@Override
@@ -5079,8 +5084,7 @@ The "returned" value of try expression with no finally is either the last expres
return v;
}
@Override
public void consumeReifiedOperationMarker(@NotNull TypeParameterDescriptor typeParameterDescriptor) {
private void consumeReifiedOperationMarker(@NotNull TypeParameterDescriptor typeParameterDescriptor) {
if (typeParameterDescriptor.getContainingDeclaration() != context.getContextDescriptor()) {
parentCodegen.getReifiedTypeParametersUsages().
addUsedReifiedParameter(typeParameterDescriptor.getName().asString());
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.codegen.inline
import org.jetbrains.kotlin.codegen.context.MethodContext
import org.jetbrains.kotlin.codegen.generateAsCast
import org.jetbrains.kotlin.codegen.generateIsCheck
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
@@ -349,18 +348,14 @@ class ReifiedTypeParametersUsages {
usedTypeParameters.add(name)
}
fun propagateChildUsagesWithinContext(child: ReifiedTypeParametersUsages, context: MethodContext) {
fun propagateChildUsagesWithinContext(child: ReifiedTypeParametersUsages, reifiedTypeParameterNamesInContext: () -> Set<String>) {
if (!child.wereUsedReifiedParameters()) return
// used for propagating reified TP usages from children member codegen to parent's
// mark enclosing object-literal/lambda as needed reification iff
// 1. at least one of it's method contains operations to reify
// 2. reified type parameter of these operations is not from current method signature
// i.e. from outer scope
child.usedTypeParameters.filterNot { name ->
context.contextDescriptor.typeParameters.any { typeParameter ->
typeParameter.isReified && typeParameter.name.asString() == name
}
}.forEach { usedTypeParameters.add(it) }
usedTypeParameters.addAll(child.usedTypeParameters - reifiedTypeParameterNamesInContext())
}
fun mergeAll(other: ReifiedTypeParametersUsages) {