Do not use KotlinTypeMapper in generateTypeOf inline intrinsic
Make ReifiedTypeInliner and related classes generic over the KotlinTypeMarker subtype (KotlinType or IrType), add a typeSystem to get arguments/nullability and other properties of types regardless of their representation, but still fall back to KotlinType when generating the actual bytecode of other intrinsics (as/is)
This commit is contained in:
@@ -77,10 +77,8 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature
|
|||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.*;
|
import org.jetbrains.kotlin.resolve.scopes.receivers.*;
|
||||||
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor;
|
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor;
|
||||||
import org.jetbrains.kotlin.types.KotlinType;
|
import org.jetbrains.kotlin.types.*;
|
||||||
import org.jetbrains.kotlin.types.SimpleType;
|
import org.jetbrains.kotlin.types.checker.ClassicTypeSystemContextImpl;
|
||||||
import org.jetbrains.kotlin.types.TypeProjection;
|
|
||||||
import org.jetbrains.kotlin.types.TypeUtils;
|
|
||||||
import org.jetbrains.kotlin.types.expressions.DoubleColonLHS;
|
import org.jetbrains.kotlin.types.expressions.DoubleColonLHS;
|
||||||
import org.jetbrains.kotlin.types.typesApproximation.CapturedTypeApproximationKt;
|
import org.jetbrains.kotlin.types.typesApproximation.CapturedTypeApproximationKt;
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions;
|
import org.jetbrains.kotlin.util.OperatorNameConventions;
|
||||||
@@ -125,6 +123,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
private final TailRecursionCodegen tailRecursionCodegen;
|
private final TailRecursionCodegen tailRecursionCodegen;
|
||||||
public final CallGenerator defaultCallGenerator = new CallGenerator.DefaultCallGenerator(this);
|
public final CallGenerator defaultCallGenerator = new CallGenerator.DefaultCallGenerator(this);
|
||||||
private final SwitchCodegenProvider switchCodegenProvider;
|
private final SwitchCodegenProvider switchCodegenProvider;
|
||||||
|
public final TypeSystemCommonBackendContext typeSystem;
|
||||||
|
|
||||||
private final Stack<BlockStackElement> blockStackElements = new Stack<>();
|
private final Stack<BlockStackElement> blockStackElements = new Stack<>();
|
||||||
|
|
||||||
@@ -157,6 +156,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
this.parentCodegen = parentCodegen;
|
this.parentCodegen = parentCodegen;
|
||||||
this.tailRecursionCodegen = new TailRecursionCodegen(context, this, this.v, state);
|
this.tailRecursionCodegen = new TailRecursionCodegen(context, this, this.v, state);
|
||||||
this.switchCodegenProvider = new SwitchCodegenProvider(this);
|
this.switchCodegenProvider = new SwitchCodegenProvider(this);
|
||||||
|
this.typeSystem = new ClassicTypeSystemContextImpl(state.getModule().getBuiltIns());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -2622,7 +2622,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
private CallGenerator getOrCreateCallGenerator(
|
private CallGenerator getOrCreateCallGenerator(
|
||||||
@NotNull CallableDescriptor descriptor,
|
@NotNull CallableDescriptor descriptor,
|
||||||
@Nullable KtElement callElement,
|
@Nullable KtElement callElement,
|
||||||
@Nullable TypeParameterMappings typeParameterMappings,
|
@Nullable TypeParameterMappings<KotlinType> typeParameterMappings,
|
||||||
boolean isDefaultCompilation
|
boolean isDefaultCompilation
|
||||||
) {
|
) {
|
||||||
if (callElement == null) return defaultCallGenerator;
|
if (callElement == null) return defaultCallGenerator;
|
||||||
@@ -2672,7 +2672,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
CallGenerator getOrCreateCallGenerator(@NotNull ResolvedCall<?> resolvedCall, @NotNull CallableDescriptor descriptor) {
|
CallGenerator getOrCreateCallGenerator(@NotNull ResolvedCall<?> resolvedCall, @NotNull CallableDescriptor descriptor) {
|
||||||
Map<TypeParameterDescriptor, KotlinType> typeArguments = getTypeArgumentsForResolvedCall(resolvedCall, descriptor);
|
Map<TypeParameterDescriptor, KotlinType> typeArguments = getTypeArgumentsForResolvedCall(resolvedCall, descriptor);
|
||||||
|
|
||||||
TypeParameterMappings mappings = new TypeParameterMappings();
|
TypeParameterMappings<KotlinType> mappings = new TypeParameterMappings<>();
|
||||||
for (Map.Entry<TypeParameterDescriptor, KotlinType> entry : typeArguments.entrySet()) {
|
for (Map.Entry<TypeParameterDescriptor, KotlinType> entry : typeArguments.entrySet()) {
|
||||||
TypeParameterDescriptor key = entry.getKey();
|
TypeParameterDescriptor key = entry.getKey();
|
||||||
KotlinType type = entry.getValue();
|
KotlinType type = entry.getValue();
|
||||||
|
|||||||
@@ -47,8 +47,9 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
|||||||
protected val functionDescriptor: FunctionDescriptor,
|
protected val functionDescriptor: FunctionDescriptor,
|
||||||
private val methodOwner: Type,
|
private val methodOwner: Type,
|
||||||
protected val jvmSignature: JvmMethodSignature,
|
protected val jvmSignature: JvmMethodSignature,
|
||||||
private val typeParameterMappings: TypeParameterMappings,
|
private val typeParameterMappings: TypeParameterMappings<*>,
|
||||||
protected val sourceCompiler: SourceCompilerForInline
|
protected val sourceCompiler: SourceCompilerForInline,
|
||||||
|
private val reifiedTypeInliner: ReifiedTypeInliner<*>
|
||||||
) {
|
) {
|
||||||
init {
|
init {
|
||||||
assert(InlineUtil.isInline(functionDescriptor)) {
|
assert(InlineUtil.isInline(functionDescriptor)) {
|
||||||
@@ -59,13 +60,8 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
|||||||
// TODO: implement AS_FUNCTION inline strategy
|
// TODO: implement AS_FUNCTION inline strategy
|
||||||
private val asFunctionInline = false
|
private val asFunctionInline = false
|
||||||
|
|
||||||
protected val typeMapper = state.typeMapper
|
|
||||||
|
|
||||||
private val initialFrameSize = codegen.frameMap.currentSize
|
private val initialFrameSize = codegen.frameMap.currentSize
|
||||||
|
|
||||||
private val reifiedTypeInliner =
|
|
||||||
ReifiedTypeInliner(typeParameterMappings, state.typeMapper, state.languageVersionSettings)
|
|
||||||
|
|
||||||
private val isSameModule: Boolean
|
private val isSameModule: Boolean
|
||||||
|
|
||||||
protected val invocationParamBuilder = ParametersBuilder.newBuilder()
|
protected val invocationParamBuilder = ParametersBuilder.newBuilder()
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ class RootInliningContext(
|
|||||||
nameGenerator: NameGenerator,
|
nameGenerator: NameGenerator,
|
||||||
val sourceCompilerForInline: SourceCompilerForInline,
|
val sourceCompilerForInline: SourceCompilerForInline,
|
||||||
override val callSiteInfo: InlineCallSiteInfo,
|
override val callSiteInfo: InlineCallSiteInfo,
|
||||||
val inlineMethodReifier: ReifiedTypeInliner,
|
val inlineMethodReifier: ReifiedTypeInliner<*>,
|
||||||
typeParameterMappings: TypeParameterMappings
|
typeParameterMappings: TypeParameterMappings<*>
|
||||||
) : InliningContext(
|
) : InliningContext(
|
||||||
null, expressionMap, state, nameGenerator, TypeRemapper.createRoot(typeParameterMappings), null, false
|
null, expressionMap, state, nameGenerator, TypeRemapper.createRoot(typeParameterMappings), null, false
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.codegen.inline
|
|||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||||
import org.jetbrains.kotlin.codegen.OwnerKind
|
|
||||||
import org.jetbrains.kotlin.codegen.PropertyReferenceCodegen
|
import org.jetbrains.kotlin.codegen.PropertyReferenceCodegen
|
||||||
import org.jetbrains.kotlin.codegen.StackValue
|
import org.jetbrains.kotlin.codegen.StackValue
|
||||||
import org.jetbrains.kotlin.codegen.binding.CalculatedClosure
|
import org.jetbrains.kotlin.codegen.binding.CalculatedClosure
|
||||||
@@ -32,7 +31,6 @@ import org.jetbrains.org.objectweb.asm.Opcodes
|
|||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
import org.jetbrains.org.objectweb.asm.commons.Method
|
import org.jetbrains.org.objectweb.asm.commons.Method
|
||||||
import org.jetbrains.org.objectweb.asm.tree.FieldInsnNode
|
import org.jetbrains.org.objectweb.asm.tree.FieldInsnNode
|
||||||
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
|
||||||
import kotlin.properties.Delegates
|
import kotlin.properties.Delegates
|
||||||
|
|
||||||
interface FunctionalArgument
|
interface FunctionalArgument
|
||||||
@@ -51,7 +49,7 @@ abstract class LambdaInfo(@JvmField val isCrossInline: Boolean) : FunctionalArgu
|
|||||||
|
|
||||||
lateinit var node: SMAPAndMethodNode
|
lateinit var node: SMAPAndMethodNode
|
||||||
|
|
||||||
abstract fun generateLambdaBody(sourceCompiler: SourceCompilerForInline, reifiedTypeInliner: ReifiedTypeInliner)
|
abstract fun generateLambdaBody(sourceCompiler: SourceCompilerForInline, reifiedTypeInliner: ReifiedTypeInliner<*>)
|
||||||
|
|
||||||
open val hasDispatchReceiver = true
|
open val hasDispatchReceiver = true
|
||||||
|
|
||||||
@@ -108,7 +106,7 @@ class DefaultLambda(
|
|||||||
var originalBoundReceiverType: Type? = null
|
var originalBoundReceiverType: Type? = null
|
||||||
private set
|
private set
|
||||||
|
|
||||||
override fun generateLambdaBody(sourceCompiler: SourceCompilerForInline, reifiedTypeInliner: ReifiedTypeInliner) {
|
override fun generateLambdaBody(sourceCompiler: SourceCompilerForInline, reifiedTypeInliner: ReifiedTypeInliner<*>) {
|
||||||
val classReader = buildClassReaderByInternalName(sourceCompiler.state, lambdaClassType.internalName)
|
val classReader = buildClassReaderByInternalName(sourceCompiler.state, lambdaClassType.internalName)
|
||||||
var isPropertyReference = false
|
var isPropertyReference = false
|
||||||
var isFunctionReference = false
|
var isFunctionReference = false
|
||||||
@@ -189,7 +187,7 @@ internal fun Type.boxReceiverForBoundReference(kotlinType: KotlinType, typeMappe
|
|||||||
AsmUtil.boxType(this, kotlinType, typeMapper)
|
AsmUtil.boxType(this, kotlinType, typeMapper)
|
||||||
|
|
||||||
abstract class ExpressionLambda(isCrossInline: Boolean) : LambdaInfo(isCrossInline) {
|
abstract class ExpressionLambda(isCrossInline: Boolean) : LambdaInfo(isCrossInline) {
|
||||||
override fun generateLambdaBody(sourceCompiler: SourceCompilerForInline, reifiedTypeInliner: ReifiedTypeInliner) {
|
override fun generateLambdaBody(sourceCompiler: SourceCompilerForInline, reifiedTypeInliner: ReifiedTypeInliner<*>) {
|
||||||
node = sourceCompiler.generateLambdaBody(this)
|
node = sourceCompiler.generateLambdaBody(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,8 +23,10 @@ import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
|||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||||
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
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
|
||||||
|
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||||
|
|
||||||
class PsiInlineCodegen(
|
class PsiInlineCodegen(
|
||||||
codegen: ExpressionCodegen,
|
codegen: ExpressionCodegen,
|
||||||
@@ -32,10 +34,17 @@ class PsiInlineCodegen(
|
|||||||
function: FunctionDescriptor,
|
function: FunctionDescriptor,
|
||||||
methodOwner: Type,
|
methodOwner: Type,
|
||||||
signature: JvmMethodSignature,
|
signature: JvmMethodSignature,
|
||||||
typeParameterMappings: TypeParameterMappings,
|
typeParameterMappings: TypeParameterMappings<KotlinType>,
|
||||||
sourceCompiler: SourceCompilerForInline
|
sourceCompiler: SourceCompilerForInline
|
||||||
) : InlineCodegen<ExpressionCodegen>(
|
) : InlineCodegen<ExpressionCodegen>(
|
||||||
codegen, state, function, methodOwner, signature, typeParameterMappings, sourceCompiler
|
codegen, state, function, methodOwner, signature, typeParameterMappings, sourceCompiler,
|
||||||
|
ReifiedTypeInliner(typeParameterMappings, object : ReifiedTypeInliner.IntrinsicsSupport<KotlinType> {
|
||||||
|
override fun putClassInstance(v: InstructionAdapter, type: KotlinType) {
|
||||||
|
AsmUtil.putJavaLangClassInstance(v, state.typeMapper.mapType(type), type, state.typeMapper)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toKotlinType(type: KotlinType): KotlinType = type
|
||||||
|
}, codegen.typeSystem, state.languageVersionSettings)
|
||||||
), CallGenerator {
|
), CallGenerator {
|
||||||
|
|
||||||
override fun generateAssertFieldIfNeeded(info: RootInliningContext) {
|
override fun generateAssertFieldIfNeeded(info: RootInliningContext) {
|
||||||
@@ -154,7 +163,7 @@ class PsiInlineCodegen(
|
|||||||
assert(isInlinableParameterExpression(ktLambda)) { "Couldn't find inline expression in ${expression.text}" }
|
assert(isInlinableParameterExpression(ktLambda)) { "Couldn't find inline expression in ${expression.text}" }
|
||||||
|
|
||||||
return PsiExpressionLambda(
|
return PsiExpressionLambda(
|
||||||
ktLambda!!, typeMapper, state.languageVersionSettings,
|
ktLambda!!, state.typeMapper, state.languageVersionSettings,
|
||||||
parameter.isCrossinline, getBoundCallableReferenceReceiver(expression) != null
|
parameter.isCrossinline, getBoundCallableReferenceReceiver(expression) != null
|
||||||
).also { lambda ->
|
).also { lambda ->
|
||||||
val closureInfo = invocationParamBuilder.addNextValueParameter(type, true, null, parameter.index)
|
val closureInfo = invocationParamBuilder.addNextValueParameter(type, true, null, parameter.index)
|
||||||
|
|||||||
@@ -20,15 +20,13 @@ import org.jetbrains.kotlin.codegen.generateAsCast
|
|||||||
import org.jetbrains.kotlin.codegen.generateIsCheck
|
import org.jetbrains.kotlin.codegen.generateIsCheck
|
||||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
|
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
|
||||||
import org.jetbrains.kotlin.codegen.optimization.common.intConstant
|
import org.jetbrains.kotlin.codegen.optimization.common.intConstant
|
||||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
||||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
|
||||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.TypeUtils
|
import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||||
import org.jetbrains.kotlin.types.typeUtil.builtIns
|
import org.jetbrains.kotlin.types.model.TypeParameterMarker
|
||||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||||
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
|
||||||
@@ -37,37 +35,23 @@ import org.jetbrains.org.objectweb.asm.tree.*
|
|||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
|
|
||||||
class ReificationArgument(
|
class ReificationArgument(
|
||||||
val parameterName: String, val nullable: Boolean, private val arrayDepth: Int
|
val parameterName: String, val nullable: Boolean, val arrayDepth: Int
|
||||||
) {
|
) {
|
||||||
fun asString() = "[".repeat(arrayDepth) + parameterName + (if (nullable) "?" else "")
|
fun asString(): String =
|
||||||
fun combine(replacement: ReificationArgument) =
|
"[".repeat(arrayDepth) + parameterName + (if (nullable) "?" else "")
|
||||||
|
|
||||||
|
fun combine(replacement: ReificationArgument): ReificationArgument =
|
||||||
ReificationArgument(
|
ReificationArgument(
|
||||||
replacement.parameterName,
|
replacement.parameterName,
|
||||||
this.nullable || (replacement.nullable && this.arrayDepth == 0),
|
this.nullable || (replacement.nullable && this.arrayDepth == 0),
|
||||||
this.arrayDepth + replacement.arrayDepth
|
this.arrayDepth + replacement.arrayDepth
|
||||||
)
|
)
|
||||||
|
|
||||||
fun reify(replacementAsmType: Type, kotlinType: KotlinType) =
|
|
||||||
Pair(
|
|
||||||
Type.getType("[".repeat(arrayDepth) + replacementAsmType),
|
|
||||||
TypeUtils.makeNullableIfNeeded(kotlinType.arrayOf(arrayDepth), nullable)
|
|
||||||
)
|
|
||||||
|
|
||||||
private fun KotlinType.arrayOf(arrayDepth: Int): KotlinType {
|
|
||||||
val builtins = this.builtIns
|
|
||||||
var currentType = this
|
|
||||||
|
|
||||||
repeat(arrayDepth) {
|
|
||||||
currentType = builtins.getArrayType(Variance.INVARIANT, currentType)
|
|
||||||
}
|
|
||||||
|
|
||||||
return currentType
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class ReifiedTypeInliner(
|
class ReifiedTypeInliner<KT : KotlinTypeMarker>(
|
||||||
private val parametersMapping: TypeParameterMappings?,
|
private val parametersMapping: TypeParameterMappings<KT>?,
|
||||||
private val typeMapper: KotlinTypeMapper,
|
private val intrinsicsSupport: IntrinsicsSupport<KT>,
|
||||||
|
private val typeSystem: TypeSystemCommonBackendContext,
|
||||||
private val languageVersionSettings: LanguageVersionSettings
|
private val languageVersionSettings: LanguageVersionSettings
|
||||||
) {
|
) {
|
||||||
enum class OperationKind {
|
enum class OperationKind {
|
||||||
@@ -76,6 +60,12 @@ class ReifiedTypeInliner(
|
|||||||
val id: Int get() = ordinal
|
val id: Int get() = ordinal
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface IntrinsicsSupport<KT : KotlinTypeMarker> {
|
||||||
|
fun putClassInstance(v: InstructionAdapter, type: KT)
|
||||||
|
|
||||||
|
fun toKotlinType(type: KT): KotlinType
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val REIFIED_OPERATION_MARKER_METHOD_NAME = "reifiedOperationMarker"
|
const val REIFIED_OPERATION_MARKER_METHOD_NAME = "reifiedOperationMarker"
|
||||||
const val NEED_CLASS_REIFICATION_MARKER_METHOD_NAME = "needClassReification"
|
const val NEED_CLASS_REIFICATION_MARKER_METHOD_NAME = "needClassReification"
|
||||||
@@ -112,14 +102,17 @@ class ReifiedTypeInliner(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun putReifiedOperationMarkerIfNeeded(
|
fun putReifiedOperationMarkerIfNeeded(
|
||||||
typeParameter: TypeParameterDescriptor,
|
typeParameter: TypeParameterMarker,
|
||||||
isNullable: Boolean,
|
isNullable: Boolean,
|
||||||
operationKind: OperationKind,
|
operationKind: OperationKind,
|
||||||
v: InstructionAdapter
|
v: InstructionAdapter,
|
||||||
|
typeSystem: TypeSystemCommonBackendContext
|
||||||
) {
|
) {
|
||||||
if (typeParameter.isReified) {
|
with(typeSystem) {
|
||||||
val argument = ReificationArgument(typeParameter.name.asString(), isNullable, 0)
|
if (typeParameter.isReified()) {
|
||||||
putReifiedOperationMarker(operationKind, argument, v)
|
val argument = ReificationArgument(typeParameter.getName().asString(), isNullable, 0)
|
||||||
|
putReifiedOperationMarker(operationKind, argument, v)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -165,7 +158,9 @@ class ReifiedTypeInliner(
|
|||||||
// process* methods return false if marker should be reified further
|
// process* methods return false if marker should be reified further
|
||||||
// or it's invalid (may be emitted explicitly in code)
|
// or it's invalid (may be emitted explicitly in code)
|
||||||
// they return true if instruction is reified and marker can be deleted
|
// they return true if instruction is reified and marker can be deleted
|
||||||
val (asmType, kotlinType) = reificationArgument.reify(mapping.asmType, mapping.type)
|
val (asmType, type) = reify(reificationArgument, mapping.asmType, mapping.type)
|
||||||
|
|
||||||
|
val kotlinType = intrinsicsSupport.toKotlinType(type)
|
||||||
|
|
||||||
if (when (operationKind) {
|
if (when (operationKind) {
|
||||||
OperationKind.NEW_ARRAY -> processNewArray(insn, asmType)
|
OperationKind.NEW_ARRAY -> processNewArray(insn, asmType)
|
||||||
@@ -174,7 +169,7 @@ class ReifiedTypeInliner(
|
|||||||
OperationKind.IS -> processIs(insn, instructions, kotlinType, asmType)
|
OperationKind.IS -> processIs(insn, instructions, kotlinType, asmType)
|
||||||
OperationKind.JAVA_CLASS -> processJavaClass(insn, asmType)
|
OperationKind.JAVA_CLASS -> processJavaClass(insn, asmType)
|
||||||
OperationKind.ENUM_REIFIED -> processSpecialEnumFunction(insn, instructions, asmType)
|
OperationKind.ENUM_REIFIED -> processSpecialEnumFunction(insn, instructions, asmType)
|
||||||
OperationKind.TYPE_OF -> processTypeOf(insn, instructions, kotlinType)
|
OperationKind.TYPE_OF -> processTypeOf(insn, instructions, type)
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
instructions.remove(insn.previous.previous!!) // PUSH operation ID
|
instructions.remove(insn.previous.previous!!) // PUSH operation ID
|
||||||
@@ -190,6 +185,27 @@ class ReifiedTypeInliner(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun reify(argument: ReificationArgument, replacementAsmType: Type, type: KT): Pair<Type, KT> =
|
||||||
|
with(typeSystem) {
|
||||||
|
val arrayType = type.arrayOf(argument.arrayDepth)
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
Pair(
|
||||||
|
Type.getType("[".repeat(argument.arrayDepth) + replacementAsmType),
|
||||||
|
(if (argument.nullable) arrayType.makeNullable() else arrayType) as KT
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun KotlinTypeMarker.arrayOf(arrayDepth: Int): KotlinTypeMarker {
|
||||||
|
var currentType = this
|
||||||
|
|
||||||
|
repeat(arrayDepth) {
|
||||||
|
currentType = typeSystem.arrayType(currentType)
|
||||||
|
}
|
||||||
|
|
||||||
|
return currentType
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun processNewArray(insn: MethodInsnNode, parameter: Type) =
|
private fun processNewArray(insn: MethodInsnNode, parameter: Type) =
|
||||||
processNextTypeInsn(insn, parameter, Opcodes.ANEWARRAY)
|
processNextTypeInsn(insn, parameter, Opcodes.ANEWARRAY)
|
||||||
|
|
||||||
@@ -236,10 +252,10 @@ class ReifiedTypeInliner(
|
|||||||
private fun processTypeOf(
|
private fun processTypeOf(
|
||||||
insn: MethodInsnNode,
|
insn: MethodInsnNode,
|
||||||
instructions: InsnList,
|
instructions: InsnList,
|
||||||
kotlinType: KotlinType
|
type: KT
|
||||||
) = rewriteNextTypeInsn(insn, Opcodes.ACONST_NULL) { stubConstNull: AbstractInsnNode ->
|
) = rewriteNextTypeInsn(insn, Opcodes.ACONST_NULL) { stubConstNull: AbstractInsnNode ->
|
||||||
val newMethodNode = MethodNode(Opcodes.API_VERSION)
|
val newMethodNode = MethodNode(Opcodes.API_VERSION)
|
||||||
val stackSize = generateTypeOf(InstructionAdapter(newMethodNode), kotlinType, typeMapper)
|
val stackSize = typeSystem.generateTypeOf(InstructionAdapter(newMethodNode), type, intrinsicsSupport)
|
||||||
|
|
||||||
instructions.insert(insn, newMethodNode.instructions)
|
instructions.insert(insn, newMethodNode.instructions)
|
||||||
instructions.remove(stubConstNull)
|
instructions.remove(stubConstNull)
|
||||||
@@ -316,38 +332,33 @@ val MethodInsnNode.operationKind: ReifiedTypeInliner.OperationKind?
|
|||||||
ReifiedTypeInliner.OperationKind.values().getOrNull(it)
|
ReifiedTypeInliner.OperationKind.values().getOrNull(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
class TypeParameterMappings() {
|
class TypeParameterMappings<KT : KotlinTypeMarker> {
|
||||||
private val mappingsByName = hashMapOf<String, TypeParameterMapping>()
|
private val mappingsByName = hashMapOf<String, TypeParameterMapping<KT>>()
|
||||||
|
|
||||||
fun addParameterMappingToType(name: String, type: KotlinType, asmType: Type, signature: String, isReified: Boolean) {
|
fun addParameterMappingToType(name: String, type: KT, asmType: Type, signature: String, isReified: Boolean) {
|
||||||
mappingsByName[name] = TypeParameterMapping(
|
mappingsByName[name] = TypeParameterMapping(
|
||||||
name, type, asmType, reificationArgument = null, signature = signature, isReified = isReified
|
name, type, asmType, reificationArgument = null, signature = signature, isReified = isReified
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addParameterMappingForFurtherReification(
|
fun addParameterMappingForFurtherReification(name: String, type: KT, reificationArgument: ReificationArgument, isReified: Boolean) {
|
||||||
name: String,
|
|
||||||
type: KotlinType,
|
|
||||||
reificationArgument: ReificationArgument,
|
|
||||||
isReified: Boolean
|
|
||||||
) {
|
|
||||||
mappingsByName[name] = TypeParameterMapping(
|
mappingsByName[name] = TypeParameterMapping(
|
||||||
name, type, asmType = null, reificationArgument = reificationArgument, signature = null, isReified = isReified
|
name, type, asmType = null, reificationArgument = reificationArgument, signature = null, isReified = isReified
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
operator fun get(name: String): TypeParameterMapping? = mappingsByName[name]
|
operator fun get(name: String): TypeParameterMapping<KT>? = mappingsByName[name]
|
||||||
|
|
||||||
fun hasReifiedParameters() = mappingsByName.values.any { it.isReified }
|
fun hasReifiedParameters() = mappingsByName.values.any { it.isReified }
|
||||||
|
|
||||||
internal inline fun forEach(l: (TypeParameterMapping) -> Unit) {
|
internal inline fun forEach(l: (TypeParameterMapping<KT>) -> Unit) {
|
||||||
mappingsByName.values.forEach(l)
|
mappingsByName.values.forEach(l)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TypeParameterMapping(
|
class TypeParameterMapping<KT : KotlinTypeMarker>(
|
||||||
val name: String,
|
val name: String,
|
||||||
val type: KotlinType,
|
val type: KT,
|
||||||
val asmType: Type?,
|
val asmType: Type?,
|
||||||
val reificationArgument: ReificationArgument?,
|
val reificationArgument: ReificationArgument?,
|
||||||
val signature: String?,
|
val signature: String?,
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ class TypeRemapper private constructor(
|
|||||||
typeParametersMapping[name] = TypeParameter(name, name, false, null)
|
typeParametersMapping[name] = TypeParameter(name, name, false, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun registerTypeParameter(mapping: TypeParameterMapping) {
|
fun registerTypeParameter(mapping: TypeParameterMapping<*>) {
|
||||||
typeParametersMapping[mapping.name] = TypeParameter(
|
typeParametersMapping[mapping.name] = TypeParameter(
|
||||||
mapping.name, mapping.reificationArgument?.parameterName, mapping.isReified, mapping.signature
|
mapping.name, mapping.reificationArgument?.parameterName, mapping.isReified, mapping.signature
|
||||||
)
|
)
|
||||||
@@ -64,8 +64,8 @@ class TypeRemapper private constructor(
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun createRoot(formalTypeParameters: TypeParameterMappings?): TypeRemapper {
|
fun createRoot(formalTypeParameters: TypeParameterMappings<*>?): TypeRemapper {
|
||||||
return TypeRemapper(HashMap<String, String?>()).apply {
|
return TypeRemapper(HashMap()).apply {
|
||||||
formalTypeParameters?.forEach {
|
formalTypeParameters?.forEach {
|
||||||
registerTypeParameter(it)
|
registerTypeParameter(it)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,9 +23,12 @@ import org.jetbrains.kotlin.resolve.calls.checkers.TypeOfChecker
|
|||||||
import org.jetbrains.kotlin.resolve.calls.checkers.isBuiltInCoroutineContext
|
import org.jetbrains.kotlin.resolve.calls.checkers.isBuiltInCoroutineContext
|
||||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.*
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.*
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.TypeProjection
|
import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.checker.ClassicTypeSystemContextImpl
|
||||||
import org.jetbrains.kotlin.types.typeUtil.builtIns
|
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||||
|
import org.jetbrains.kotlin.types.model.TypeArgumentMarker
|
||||||
|
import org.jetbrains.kotlin.types.model.TypeParameterMarker
|
||||||
|
import org.jetbrains.kotlin.types.model.TypeVariance
|
||||||
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
|
||||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||||
@@ -38,11 +41,15 @@ internal fun generateInlineIntrinsic(
|
|||||||
): MethodNode? {
|
): MethodNode? {
|
||||||
val languageVersionSettings = state.languageVersionSettings
|
val languageVersionSettings = state.languageVersionSettings
|
||||||
val typeMapper = state.typeMapper
|
val typeMapper = state.typeMapper
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
val typeSystem = ClassicTypeSystemContextImpl(state.module.builtIns)
|
||||||
|
|
||||||
return when {
|
return when {
|
||||||
isSpecialEnumMethod(descriptor) ->
|
isSpecialEnumMethod(descriptor) ->
|
||||||
createSpecialEnumMethodBody(descriptor.name.asString(), typeArguments!!.keys.single(), typeMapper)
|
createSpecialEnumMethodBody(descriptor.name.asString(), typeArguments!!.keys.single(), typeMapper, typeSystem)
|
||||||
TypeOfChecker.isTypeOf(descriptor) ->
|
TypeOfChecker.isTypeOf(descriptor) ->
|
||||||
createTypeOfMethodBody(typeArguments!!.keys.single())
|
typeSystem.createTypeOfMethodBody(typeArguments!!.keys.single())
|
||||||
descriptor.isBuiltInIntercepted(languageVersionSettings) ->
|
descriptor.isBuiltInIntercepted(languageVersionSettings) ->
|
||||||
createMethodNodeForIntercepted(descriptor, typeMapper, languageVersionSettings)
|
createMethodNodeForIntercepted(descriptor, typeMapper, languageVersionSettings)
|
||||||
descriptor.isBuiltInCoroutineContext(languageVersionSettings) ->
|
descriptor.isBuiltInCoroutineContext(languageVersionSettings) ->
|
||||||
@@ -69,13 +76,15 @@ private fun isSpecialEnumMethod(descriptor: FunctionDescriptor): Boolean {
|
|||||||
(name == "enumValueOf" && parameters.size == 1 && KotlinBuiltIns.isString(parameters[0].type))
|
(name == "enumValueOf" && parameters.size == 1 && KotlinBuiltIns.isString(parameters[0].type))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createSpecialEnumMethodBody(name: String, typeParameter: TypeParameterDescriptor, typeMapper: KotlinTypeMapper): MethodNode {
|
private fun createSpecialEnumMethodBody(
|
||||||
|
name: String, typeParameter: TypeParameterDescriptor, typeMapper: KotlinTypeMapper, typeSystem: TypeSystemCommonBackendContext
|
||||||
|
): MethodNode {
|
||||||
val isValueOf = "enumValueOf" == name
|
val isValueOf = "enumValueOf" == name
|
||||||
val invokeType = typeMapper.mapType(typeParameter.defaultType)
|
val invokeType = typeMapper.mapType(typeParameter.defaultType)
|
||||||
val desc = getSpecialEnumFunDescriptor(invokeType, isValueOf)
|
val desc = getSpecialEnumFunDescriptor(invokeType, isValueOf)
|
||||||
val node = MethodNode(Opcodes.API_VERSION, Opcodes.ACC_STATIC, "fake", desc, null, null)
|
val node = MethodNode(Opcodes.API_VERSION, Opcodes.ACC_STATIC, "fake", desc, null, null)
|
||||||
ReifiedTypeInliner.putReifiedOperationMarkerIfNeeded(
|
ReifiedTypeInliner.putReifiedOperationMarkerIfNeeded(
|
||||||
typeParameter, false, ReifiedTypeInliner.OperationKind.ENUM_REIFIED, InstructionAdapter(node)
|
typeParameter, false, ReifiedTypeInliner.OperationKind.ENUM_REIFIED, InstructionAdapter(node), typeSystem
|
||||||
)
|
)
|
||||||
if (isValueOf) {
|
if (isValueOf) {
|
||||||
node.visitInsn(Opcodes.ACONST_NULL)
|
node.visitInsn(Opcodes.ACONST_NULL)
|
||||||
@@ -98,7 +107,7 @@ internal fun getSpecialEnumFunDescriptor(type: Type, isValueOf: Boolean): String
|
|||||||
if (isValueOf) Type.getMethodDescriptor(type, JAVA_STRING_TYPE)
|
if (isValueOf) Type.getMethodDescriptor(type, JAVA_STRING_TYPE)
|
||||||
else Type.getMethodDescriptor(AsmUtil.getArrayType(type))
|
else Type.getMethodDescriptor(AsmUtil.getArrayType(type))
|
||||||
|
|
||||||
private fun createTypeOfMethodBody(typeParameter: TypeParameterDescriptor): MethodNode {
|
private fun TypeSystemCommonBackendContext.createTypeOfMethodBody(typeParameter: TypeParameterMarker): MethodNode {
|
||||||
val node = MethodNode(Opcodes.API_VERSION, Opcodes.ACC_STATIC, "fake", Type.getMethodDescriptor(K_TYPE), null, null)
|
val node = MethodNode(Opcodes.API_VERSION, Opcodes.ACC_STATIC, "fake", Type.getMethodDescriptor(K_TYPE), null, null)
|
||||||
val v = InstructionAdapter(node)
|
val v = InstructionAdapter(node)
|
||||||
|
|
||||||
@@ -110,33 +119,36 @@ private fun createTypeOfMethodBody(typeParameter: TypeParameterDescriptor): Meth
|
|||||||
return node
|
return node
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun putTypeOfReifiedTypeParameter(v: InstructionAdapter, typeParameter: TypeParameterDescriptor, isNullable: Boolean) {
|
private fun TypeSystemCommonBackendContext.putTypeOfReifiedTypeParameter(
|
||||||
ReifiedTypeInliner.putReifiedOperationMarkerIfNeeded(typeParameter, isNullable, ReifiedTypeInliner.OperationKind.TYPE_OF, v)
|
v: InstructionAdapter, typeParameter: TypeParameterMarker, isNullable: Boolean
|
||||||
|
) {
|
||||||
|
ReifiedTypeInliner.putReifiedOperationMarkerIfNeeded(typeParameter, isNullable, ReifiedTypeInliner.OperationKind.TYPE_OF, v, this)
|
||||||
v.aconst(null)
|
v.aconst(null)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns some upper bound on maximum stack size
|
// Returns some upper bound on maximum stack size
|
||||||
internal fun generateTypeOf(v: InstructionAdapter, kotlinType: KotlinType, typeMapper: KotlinTypeMapper): Int {
|
internal fun <KT : KotlinTypeMarker> TypeSystemCommonBackendContext.generateTypeOf(
|
||||||
val asmType = typeMapper.mapType(kotlinType)
|
v: InstructionAdapter, type: KT, intrinsicsSupport: ReifiedTypeInliner.IntrinsicsSupport<KT>
|
||||||
AsmUtil.putJavaLangClassInstance(v, asmType, kotlinType, typeMapper)
|
): Int {
|
||||||
|
intrinsicsSupport.putClassInstance(v, type)
|
||||||
|
|
||||||
val arguments = kotlinType.arguments
|
val argumentsSize = type.argumentsCount()
|
||||||
val useArray = arguments.size >= 3
|
val useArray = argumentsSize >= 3
|
||||||
|
|
||||||
if (useArray) {
|
if (useArray) {
|
||||||
v.iconst(arguments.size)
|
v.iconst(argumentsSize)
|
||||||
v.newarray(K_TYPE_PROJECTION)
|
v.newarray(K_TYPE_PROJECTION)
|
||||||
}
|
}
|
||||||
|
|
||||||
var maxStackSize = 3
|
var maxStackSize = 3
|
||||||
|
|
||||||
for (i in 0 until arguments.size) {
|
for (i in 0 until argumentsSize) {
|
||||||
if (useArray) {
|
if (useArray) {
|
||||||
v.dup()
|
v.dup()
|
||||||
v.iconst(i)
|
v.iconst(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
val stackSize = doGenerateTypeProjection(v, arguments[i], typeMapper)
|
val stackSize = doGenerateTypeProjection(v, type.getArgument(i), intrinsicsSupport)
|
||||||
maxStackSize = maxOf(maxStackSize, stackSize + i + 5)
|
maxStackSize = maxOf(maxStackSize, stackSize + i + 5)
|
||||||
|
|
||||||
if (useArray) {
|
if (useArray) {
|
||||||
@@ -144,9 +156,9 @@ internal fun generateTypeOf(v: InstructionAdapter, kotlinType: KotlinType, typeM
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val methodName = if (kotlinType.isMarkedNullable) "nullableTypeOf" else "typeOf"
|
val methodName = if (type.isMarkedNullable()) "nullableTypeOf" else "typeOf"
|
||||||
|
|
||||||
val projections = when (arguments.size) {
|
val projections = when (argumentsSize) {
|
||||||
0 -> emptyArray()
|
0 -> emptyArray()
|
||||||
1 -> arrayOf(K_TYPE_PROJECTION)
|
1 -> arrayOf(K_TYPE_PROJECTION)
|
||||||
2 -> arrayOf(K_TYPE_PROJECTION, K_TYPE_PROJECTION)
|
2 -> arrayOf(K_TYPE_PROJECTION, K_TYPE_PROJECTION)
|
||||||
@@ -159,37 +171,39 @@ internal fun generateTypeOf(v: InstructionAdapter, kotlinType: KotlinType, typeM
|
|||||||
return maxStackSize
|
return maxStackSize
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun doGenerateTypeProjection(
|
private fun <KT : KotlinTypeMarker> TypeSystemCommonBackendContext.doGenerateTypeProjection(
|
||||||
v: InstructionAdapter,
|
v: InstructionAdapter,
|
||||||
projection: TypeProjection,
|
projection: TypeArgumentMarker,
|
||||||
typeMapper: KotlinTypeMapper
|
intrinsicsSupport: ReifiedTypeInliner.IntrinsicsSupport<KT>
|
||||||
): Int {
|
): Int {
|
||||||
// KTypeProjection members could be static, see KT-30083 and KT-30084
|
// KTypeProjection members could be static, see KT-30083 and KT-30084
|
||||||
v.getstatic(K_TYPE_PROJECTION.internalName, "Companion", K_TYPE_PROJECTION_COMPANION.descriptor)
|
v.getstatic(K_TYPE_PROJECTION.internalName, "Companion", K_TYPE_PROJECTION_COMPANION.descriptor)
|
||||||
|
|
||||||
if (projection.isStarProjection) {
|
if (projection.isStarProjection()) {
|
||||||
v.invokevirtual(K_TYPE_PROJECTION_COMPANION.internalName, "getSTAR", Type.getMethodDescriptor(K_TYPE_PROJECTION), false)
|
v.invokevirtual(K_TYPE_PROJECTION_COMPANION.internalName, "getSTAR", Type.getMethodDescriptor(K_TYPE_PROJECTION), false)
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
val type = projection.type
|
@Suppress("UNCHECKED_CAST")
|
||||||
val descriptor = type.constructor.declarationDescriptor
|
val type = projection.getType() as KT
|
||||||
val stackSize = if (descriptor is TypeParameterDescriptor) {
|
val typeParameterClassifier = type.typeConstructor().getTypeParameterClassifier()
|
||||||
if (descriptor.isReified) {
|
val stackSize = if (typeParameterClassifier != null) {
|
||||||
putTypeOfReifiedTypeParameter(v, descriptor, type.isMarkedNullable)
|
if (typeParameterClassifier.isReified()) {
|
||||||
|
putTypeOfReifiedTypeParameter(v, typeParameterClassifier, type.isMarkedNullable())
|
||||||
2
|
2
|
||||||
} else {
|
} else {
|
||||||
// TODO: support non-reified type parameters in typeOf
|
// TODO: support non-reified type parameters in typeOf
|
||||||
generateTypeOf(v, type.builtIns.nullableAnyType, typeMapper)
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
generateTypeOf(v, nullableAnyType() as KT, intrinsicsSupport)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
generateTypeOf(v, type, typeMapper)
|
generateTypeOf(v, type, intrinsicsSupport)
|
||||||
}
|
}
|
||||||
|
|
||||||
val methodName = when (projection.projectionKind) {
|
val methodName = when (projection.getVariance()) {
|
||||||
Variance.INVARIANT -> "invariant"
|
TypeVariance.INV -> "invariant"
|
||||||
Variance.IN_VARIANCE -> "contravariant"
|
TypeVariance.IN -> "contravariant"
|
||||||
Variance.OUT_VARIANCE -> "covariant"
|
TypeVariance.OUT -> "covariant"
|
||||||
}
|
}
|
||||||
v.invokevirtual(K_TYPE_PROJECTION_COMPANION.internalName, methodName, Type.getMethodDescriptor(K_TYPE_PROJECTION, K_TYPE), false)
|
v.invokevirtual(K_TYPE_PROJECTION_COMPANION.internalName, methodName, Type.getMethodDescriptor(K_TYPE_PROJECTION, K_TYPE), false)
|
||||||
|
|
||||||
|
|||||||
@@ -431,6 +431,10 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
|||||||
return this.firSafeNullable()
|
return this.firSafeNullable()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun nullableAnyType(): SimpleTypeMarker = TODO("not implemented")
|
||||||
|
|
||||||
|
override fun arrayType(componentType: KotlinTypeMarker): SimpleTypeMarker = TODO("not implemented")
|
||||||
|
|
||||||
override fun TypeConstructorMarker.isFinalClassOrEnumEntryOrAnnotationClassConstructor(): Boolean {
|
override fun TypeConstructorMarker.isFinalClassOrEnumEntryOrAnnotationClassConstructor(): Boolean {
|
||||||
val firRegularClass = toFirRegularClass() ?: return false
|
val firRegularClass = toFirRegularClass() ?: return false
|
||||||
|
|
||||||
@@ -485,6 +489,8 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
|||||||
|
|
||||||
override fun TypeParameterMarker.getName() = (this as ConeTypeParameterSymbol).name
|
override fun TypeParameterMarker.getName() = (this as ConeTypeParameterSymbol).name
|
||||||
|
|
||||||
|
override fun TypeParameterMarker.isReified(): Boolean = TODO("not implemented")
|
||||||
|
|
||||||
override fun KotlinTypeMarker.isInterfaceOrAnnotationClass(): Boolean {
|
override fun KotlinTypeMarker.isInterfaceOrAnnotationClass(): Boolean {
|
||||||
val classKind = typeConstructor().toFirRegularClass()?.classKind ?: return false
|
val classKind = typeConstructor().toFirRegularClass()?.classKind ?: return false
|
||||||
return classKind == ClassKind.ANNOTATION_CLASS || classKind == ClassKind.INTERFACE
|
return classKind == ClassKind.ANNOTATION_CLASS || classKind == ClassKind.INTERFACE
|
||||||
|
|||||||
+27
-16
@@ -44,6 +44,7 @@ import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
|||||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||||
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
import org.jetbrains.kotlin.utils.keysToMap
|
import org.jetbrains.kotlin.utils.keysToMap
|
||||||
@@ -908,12 +909,7 @@ class ExpressionCodegen(
|
|||||||
putReifiedOperationMarkerIfTypeIsReifiedParameter(classType, ReifiedTypeInliner.OperationKind.JAVA_CLASS, mv, this)
|
putReifiedOperationMarkerIfTypeIsReifiedParameter(classType, ReifiedTypeInliner.OperationKind.JAVA_CLASS, mv, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
val asmType = typeMapper.mapType(classType)
|
generateClassInstance(mv, classType)
|
||||||
if (classType.getClass()?.isInline == true || !isPrimitive(asmType)) {
|
|
||||||
mv.aconst(typeMapper.boxType(classType))
|
|
||||||
} else {
|
|
||||||
mv.getstatic(boxType(asmType).internalName, "TYPE", "Ljava/lang/Class;")
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
throw AssertionError("not an IrGetClass or IrClassReference: ${classReference.dump()}")
|
throw AssertionError("not an IrGetClass or IrClassReference: ${classReference.dump()}")
|
||||||
}
|
}
|
||||||
@@ -924,6 +920,15 @@ class ExpressionCodegen(
|
|||||||
return classReference.onStack
|
return classReference.onStack
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun generateClassInstance(v: InstructionAdapter, classType: IrType) {
|
||||||
|
val asmType = typeMapper.mapType(classType)
|
||||||
|
if (classType.getClass()?.isInline == true || !isPrimitive(asmType)) {
|
||||||
|
v.aconst(typeMapper.boxType(classType))
|
||||||
|
} else {
|
||||||
|
v.getstatic(boxType(asmType).internalName, "TYPE", "Ljava/lang/Class;")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun getOrCreateCallGenerator(
|
private fun getOrCreateCallGenerator(
|
||||||
element: IrFunctionAccessExpression, data: BlockInfo, signature: JvmMethodSignature
|
element: IrFunctionAccessExpression, data: BlockInfo, signature: JvmMethodSignature
|
||||||
): IrCallGenerator {
|
): IrCallGenerator {
|
||||||
@@ -964,7 +969,19 @@ class ExpressionCodegen(
|
|||||||
val original = (callee as? IrSimpleFunction)?.resolveFakeOverride() ?: irFunction
|
val original = (callee as? IrSimpleFunction)?.resolveFakeOverride() ?: irFunction
|
||||||
val methodOwner = callee.parent.safeAs<IrClass>()?.let(typeMapper::mapClass) ?: MethodSignatureMapper.FAKE_OWNER_TYPE
|
val methodOwner = callee.parent.safeAs<IrClass>()?.let(typeMapper::mapClass) ?: MethodSignatureMapper.FAKE_OWNER_TYPE
|
||||||
val sourceCompiler = IrSourceCompilerForInline(state, element, this, data)
|
val sourceCompiler = IrSourceCompilerForInline(state, element, this, data)
|
||||||
return IrInlineCodegen(this, state, original.descriptor, methodOwner, signature, mappings, sourceCompiler)
|
val typeParameterMappings = mappings.toTypeParameterMappings()
|
||||||
|
|
||||||
|
val reifiedTypeInliner = ReifiedTypeInliner(typeParameterMappings, object : ReifiedTypeInliner.IntrinsicsSupport<IrType> {
|
||||||
|
override fun putClassInstance(v: InstructionAdapter, type: IrType) {
|
||||||
|
generateClassInstance(v, type)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toKotlinType(type: IrType): KotlinType = type.toKotlinType()
|
||||||
|
}, IrTypeCheckerContext(context.irBuiltIns), state.languageVersionSettings)
|
||||||
|
|
||||||
|
return IrInlineCodegen(
|
||||||
|
this, state, original.descriptor, methodOwner, signature, typeParameterMappings, sourceCompiler, reifiedTypeInliner
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun consumeReifiedOperationMarker(typeParameter: IrTypeParameter) {
|
private fun consumeReifiedOperationMarker(typeParameter: IrTypeParameter) {
|
||||||
@@ -1099,23 +1116,17 @@ class IrTypeParameterMappings {
|
|||||||
mappingsByName.values.forEach(l)
|
mappingsByName.values.forEach(l)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toTypeParameterMappings() = TypeParameterMappings().also { result ->
|
fun toTypeParameterMappings() = TypeParameterMappings<IrType>().also { result ->
|
||||||
mappingsByName.forEach { (_, value) ->
|
mappingsByName.forEach { (_, value) ->
|
||||||
if (value.asmType == null) {
|
if (value.asmType == null) {
|
||||||
result.addParameterMappingForFurtherReification(
|
result.addParameterMappingForFurtherReification(
|
||||||
value.name,
|
value.name,
|
||||||
value.type.toKotlinType(),
|
value.type,
|
||||||
value.reificationArgument!!.toReificationArgument(),
|
value.reificationArgument!!.toReificationArgument(),
|
||||||
value.isReified
|
value.isReified
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
result.addParameterMappingToType(
|
result.addParameterMappingToType(value.name, value.type, value.asmType, value.signature!!, value.isReified)
|
||||||
value.name,
|
|
||||||
value.type.toKotlinType(),
|
|
||||||
value.asmType,
|
|
||||||
value.signature!!,
|
|
||||||
value.isReified
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-4
@@ -33,10 +33,11 @@ class IrInlineCodegen(
|
|||||||
function: FunctionDescriptor,
|
function: FunctionDescriptor,
|
||||||
methodOwner: Type,
|
methodOwner: Type,
|
||||||
signature: JvmMethodSignature,
|
signature: JvmMethodSignature,
|
||||||
typeParameterMappings: IrTypeParameterMappings,
|
typeParameterMappings: TypeParameterMappings<IrType>,
|
||||||
sourceCompiler: SourceCompilerForInline
|
sourceCompiler: SourceCompilerForInline,
|
||||||
|
reifiedTypeInliner: ReifiedTypeInliner<IrType>
|
||||||
) : InlineCodegen<ExpressionCodegen>(
|
) : InlineCodegen<ExpressionCodegen>(
|
||||||
codegen, state, function, methodOwner, signature, typeParameterMappings.toTypeParameterMappings(), sourceCompiler
|
codegen, state, function, methodOwner, signature, typeParameterMappings, sourceCompiler, reifiedTypeInliner
|
||||||
), IrCallGenerator {
|
), IrCallGenerator {
|
||||||
override fun generateAssertFieldIfNeeded(info: RootInliningContext) {
|
override fun generateAssertFieldIfNeeded(info: RootInliningContext) {
|
||||||
// TODO: JVM assertions are not implemented yet in IR backend
|
// TODO: JVM assertions are not implemented yet in IR backend
|
||||||
@@ -141,7 +142,7 @@ class IrExpressionLambdaImpl(
|
|||||||
val reference: IrFunctionReference,
|
val reference: IrFunctionReference,
|
||||||
val function: IrFunction,
|
val function: IrFunction,
|
||||||
private val typeMapper: IrTypeMapper,
|
private val typeMapper: IrTypeMapper,
|
||||||
private val methodSignatureMapper: MethodSignatureMapper,
|
methodSignatureMapper: MethodSignatureMapper,
|
||||||
isCrossInline: Boolean,
|
isCrossInline: Boolean,
|
||||||
override val isBoundCallableReference: Boolean,
|
override val isBoundCallableReference: Boolean,
|
||||||
override val isExtensionLambda: Boolean
|
override val isExtensionLambda: Boolean
|
||||||
|
|||||||
@@ -267,6 +267,12 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon
|
|||||||
override fun createErrorTypeWithCustomConstructor(debugName: String, constructor: TypeConstructorMarker): KotlinTypeMarker =
|
override fun createErrorTypeWithCustomConstructor(debugName: String, constructor: TypeConstructorMarker): KotlinTypeMarker =
|
||||||
TODO("IrTypeSystemContext doesn't support constraint system resolution")
|
TODO("IrTypeSystemContext doesn't support constraint system resolution")
|
||||||
|
|
||||||
|
override fun nullableAnyType(): SimpleTypeMarker =
|
||||||
|
irBuiltIns.anyNType as IrSimpleType
|
||||||
|
|
||||||
|
override fun arrayType(componentType: KotlinTypeMarker): SimpleTypeMarker =
|
||||||
|
irBuiltIns.arrayClass.typeWith(componentType as IrType)
|
||||||
|
|
||||||
override fun TypeConstructorMarker.isFinalClassOrEnumEntryOrAnnotationClassConstructor(): Boolean {
|
override fun TypeConstructorMarker.isFinalClassOrEnumEntryOrAnnotationClassConstructor(): Boolean {
|
||||||
val symbol = this as IrClassifierSymbol
|
val symbol = this as IrClassifierSymbol
|
||||||
return symbol is IrClassSymbol && symbol.owner.let {
|
return symbol is IrClassSymbol && symbol.owner.let {
|
||||||
@@ -340,6 +346,9 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon
|
|||||||
override fun TypeParameterMarker.getName(): Name =
|
override fun TypeParameterMarker.getName(): Name =
|
||||||
(this as IrTypeParameterSymbol).owner.name
|
(this as IrTypeParameterSymbol).owner.name
|
||||||
|
|
||||||
|
override fun TypeParameterMarker.isReified(): Boolean =
|
||||||
|
(this as IrTypeParameterSymbol).owner.isReified
|
||||||
|
|
||||||
override fun KotlinTypeMarker.isInterfaceOrAnnotationClass(): Boolean {
|
override fun KotlinTypeMarker.isInterfaceOrAnnotationClass(): Boolean {
|
||||||
val irClass = (this as IrType).classOrNull?.owner
|
val irClass = (this as IrType).classOrNull?.owner
|
||||||
return irClass != null && (irClass.isInterface || irClass.isAnnotationClass)
|
return irClass != null && (irClass.isInterface || irClass.isAnnotationClass)
|
||||||
|
|||||||
@@ -12,6 +12,9 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
import org.jetbrains.kotlin.types.model.*
|
import org.jetbrains.kotlin.types.model.*
|
||||||
|
|
||||||
interface TypeSystemCommonBackendContext : TypeSystemContext {
|
interface TypeSystemCommonBackendContext : TypeSystemContext {
|
||||||
|
fun nullableAnyType(): SimpleTypeMarker
|
||||||
|
fun arrayType(componentType: KotlinTypeMarker): SimpleTypeMarker
|
||||||
|
|
||||||
fun TypeConstructorMarker.isFinalClassOrEnumEntryOrAnnotationClassConstructor(): Boolean
|
fun TypeConstructorMarker.isFinalClassOrEnumEntryOrAnnotationClassConstructor(): Boolean
|
||||||
|
|
||||||
fun KotlinTypeMarker.hasAnnotation(fqName: FqName): Boolean
|
fun KotlinTypeMarker.hasAnnotation(fqName: FqName): Boolean
|
||||||
@@ -44,6 +47,7 @@ interface TypeSystemCommonBackendContext : TypeSystemContext {
|
|||||||
fun TypeConstructorMarker.getClassFqNameUnsafe(): FqNameUnsafe?
|
fun TypeConstructorMarker.getClassFqNameUnsafe(): FqNameUnsafe?
|
||||||
|
|
||||||
fun TypeParameterMarker.getName(): Name
|
fun TypeParameterMarker.getName(): Name
|
||||||
|
fun TypeParameterMarker.isReified(): Boolean
|
||||||
|
|
||||||
fun KotlinTypeMarker.isInterfaceOrAnnotationClass(): Boolean
|
fun KotlinTypeMarker.isInterfaceOrAnnotationClass(): Boolean
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-1
@@ -341,7 +341,8 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy
|
|||||||
return builtIns.anyType
|
return builtIns.anyType
|
||||||
}
|
}
|
||||||
|
|
||||||
val builtIns: KotlinBuiltIns get() = throw UnsupportedOperationException("Not supported")
|
open val builtIns: KotlinBuiltIns
|
||||||
|
get() = throw UnsupportedOperationException("Not supported")
|
||||||
|
|
||||||
override fun KotlinTypeMarker.makeDefinitelyNotNullOrNotNull(): KotlinTypeMarker {
|
override fun KotlinTypeMarker.makeDefinitelyNotNullOrNotNull(): KotlinTypeMarker {
|
||||||
require(this is UnwrappedType, this::errorMessage)
|
require(this is UnwrappedType, this::errorMessage)
|
||||||
@@ -502,6 +503,11 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy
|
|||||||
return this is NewCapturedTypeConstructor
|
return this is NewCapturedTypeConstructor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun arrayType(componentType: KotlinTypeMarker): SimpleTypeMarker {
|
||||||
|
require(componentType is KotlinType, this::errorMessage)
|
||||||
|
return builtIns.getArrayType(Variance.INVARIANT, componentType)
|
||||||
|
}
|
||||||
|
|
||||||
override fun KotlinTypeMarker.hasAnnotation(fqName: FqName): Boolean {
|
override fun KotlinTypeMarker.hasAnnotation(fqName: FqName): Boolean {
|
||||||
require(this is KotlinType, this::errorMessage)
|
require(this is KotlinType, this::errorMessage)
|
||||||
return annotations.hasAnnotation(fqName)
|
return annotations.hasAnnotation(fqName)
|
||||||
@@ -557,6 +563,11 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy
|
|||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun TypeParameterMarker.isReified(): Boolean {
|
||||||
|
require(this is TypeParameterDescriptor, this::errorMessage)
|
||||||
|
return isReified
|
||||||
|
}
|
||||||
|
|
||||||
override fun KotlinTypeMarker.isInterfaceOrAnnotationClass(): Boolean {
|
override fun KotlinTypeMarker.isInterfaceOrAnnotationClass(): Boolean {
|
||||||
require(this is KotlinType, this::errorMessage)
|
require(this is KotlinType, this::errorMessage)
|
||||||
val descriptor = constructor.declarationDescriptor
|
val descriptor = constructor.declarationDescriptor
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.types.checker
|
package org.jetbrains.kotlin.types.checker
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
|
import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
|
||||||
import org.jetbrains.kotlin.resolve.OverridingUtil
|
import org.jetbrains.kotlin.resolve.OverridingUtil
|
||||||
@@ -31,6 +32,8 @@ import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
|||||||
|
|
||||||
object SimpleClassicTypeSystemContext : ClassicTypeSystemContext
|
object SimpleClassicTypeSystemContext : ClassicTypeSystemContext
|
||||||
|
|
||||||
|
class ClassicTypeSystemContextImpl(override val builtIns: KotlinBuiltIns) : ClassicTypeSystemContext
|
||||||
|
|
||||||
object StrictEqualityTypeChecker {
|
object StrictEqualityTypeChecker {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user