Remove OperationType.PLUGIN_DEFINED type:

instead, plugins should emit the code similar to the TYPE_OF one with
a special call to MagicApiIntrinsics.voidMagicApiCall directly afterwards.

This is required because old compiler need to correctly inline code
rewritten by plugin.
This commit is contained in:
Leonid Startsev
2022-08-31 19:36:06 +02:00
committed by Space
parent 763303fe97
commit ad2adadb36
9 changed files with 123 additions and 146 deletions
@@ -42,22 +42,6 @@ interface ExpressionCodegenExtension {
*/
fun applyFunction(receiver: StackValue, resolvedCall: ResolvedCall<*>, c: Context): StackValue? = null
/**
* Called when inliner encounters [ReifiedTypeInliner.OperationKind.PLUGIN_DEFINED] marker
* to perform extension-specific operation with reified type parameter.
*
* @return Required stack size for method after inlining is performed, 0 if the size is unknown, or -1 if extension ignores this marker
*/
fun applyPluginDefinedReifiedOperationMarker(
insn: MethodInsnNode,
instructions: InsnList,
type: KotlinType,
asmType: Type,
typeMapper: KotlinTypeMapper,
typeSystem: TypeSystemCommonBackendContext,
module: ModuleDescriptor
): Int = -1
fun generateClassSyntheticParts(codegen: ImplementationBodyCodegen) {}
val shouldGenerateClassSyntheticPartsInLightClassesMode: Boolean
@@ -86,21 +86,4 @@ class PsiInlineIntrinsicsSupport(
override fun reportNonReifiedTypeParameterWithRecursiveBoundUnsupported(typeParameterName: Name) {
state.diagnostics.report(TYPEOF_NON_REIFIED_TYPE_PARAMETER_WITH_RECURSIVE_BOUND.on(reportErrorsOn, typeParameterName.asString()))
}
override fun applyPluginDefinedReifiedOperationMarker(
insn: MethodInsnNode,
instructions: InsnList,
type: KotlinType,
asmType: Type
): Int = pluginExtensions.maxOfOrNull {
it.applyPluginDefinedReifiedOperationMarker(
insn,
instructions,
type,
asmType,
state.typeMapper,
typeSystem,
state.module
)
} ?: -1
}
@@ -46,7 +46,7 @@ class ReifiedTypeInliner<KT : KotlinTypeMarker>(
private val unifiedNullChecks: Boolean,
) {
enum class OperationKind {
NEW_ARRAY, AS, SAFE_AS, IS, JAVA_CLASS, ENUM_REIFIED, TYPE_OF, PLUGIN_DEFINED;
NEW_ARRAY, AS, SAFE_AS, IS, JAVA_CLASS, ENUM_REIFIED, TYPE_OF;
val id: Int get() = ordinal
}
@@ -66,21 +66,18 @@ class ReifiedTypeInliner<KT : KotlinTypeMarker>(
fun reportSuspendTypeUnsupported()
fun reportNonReifiedTypeParameterWithRecursiveBoundUnsupported(typeParameterName: Name)
/**
* @return Required stack size for method after inlining is performed, 0 if the size is unknown, or -1 if plugin was not applied
*/
fun applyPluginDefinedReifiedOperationMarker(
insn: MethodInsnNode,
instructions: InsnList,
type: KT,
asmType: Type
): Int = -1
fun rewritePluginDefinedOperationMarker(v: InstructionAdapter, next: AbstractInsnNode, instructions: InsnList, type: KT): Boolean =
false
}
companion object {
const val REIFIED_OPERATION_MARKER_METHOD_NAME = "reifiedOperationMarker"
const val NEED_CLASS_REIFICATION_MARKER_METHOD_NAME = "needClassReification"
const val pluginIntrinsicsMarkerOwner = "kotlin/jvm/internal/MagicApiIntrinsics"
const val pluginIntrinsicsMarkerMethod = "voidMagicApiCall"
const val pluginIntrinsicsMarkerSignature = "(Ljava/lang/Object;)V"
fun isOperationReifiedMarker(insn: AbstractInsnNode) =
isReifiedMarker(insn) { it == REIFIED_OPERATION_MARKER_METHOD_NAME }
@@ -180,8 +177,7 @@ class ReifiedTypeInliner<KT : KotlinTypeMarker>(
OperationKind.IS -> processIs(insn, instructions, kotlinType, asmType)
OperationKind.JAVA_CLASS -> processJavaClass(insn, asmType)
OperationKind.ENUM_REIFIED -> processSpecialEnumFunction(insn, instructions, asmType)
OperationKind.TYPE_OF -> processTypeOf(insn, instructions, type)
OperationKind.PLUGIN_DEFINED -> processPluginDefined(insn, instructions, type, asmType)
OperationKind.TYPE_OF -> processTypeOfOrPlugin(insn, instructions, type)
}
) {
instructions.remove(insn.previous.previous!!) // PUSH operation ID
@@ -197,23 +193,6 @@ class ReifiedTypeInliner<KT : KotlinTypeMarker>(
}
}
private fun processPluginDefined(
insn: MethodInsnNode,
instructions: InsnList,
type: KT,
asmType: Type
): Boolean {
val applyResult = intrinsicsSupport.applyPluginDefinedReifiedOperationMarker(
insn,
instructions,
type,
asmType
)
if (applyResult == -1) return false
maxStackSize = max(maxStackSize, applyResult)
return true
}
private fun reify(argument: ReificationArgument, replacementAsmType: Type, type: KT): Pair<Type, KT> =
with(typeSystem) {
val arrayType = type.arrayOf(argument.arrayDepth)
@@ -282,13 +261,21 @@ class ReifiedTypeInliner<KT : KotlinTypeMarker>(
return true
}
private fun processTypeOf(
private fun processTypeOfOrPlugin(
insn: MethodInsnNode,
instructions: InsnList,
type: KT
) = rewriteNextTypeInsn(insn, Opcodes.ACONST_NULL) { stubConstNull: AbstractInsnNode ->
val newMethodNode = newMethodNodeWithCorrectStackSize {
typeSystem.generateTypeOf(it, type, intrinsicsSupport)
if (!isPluginNext(stubConstNull) || !intrinsicsSupport.rewritePluginDefinedOperationMarker(
it,
stubConstNull,
instructions,
type,
)
) {
typeSystem.generateTypeOf(it, type, intrinsicsSupport)
}
}
instructions.insert(insn, newMethodNode.instructions)
@@ -298,6 +285,15 @@ class ReifiedTypeInliner<KT : KotlinTypeMarker>(
return true
}
private fun isPluginNext(insn: AbstractInsnNode): Boolean {
val magicInsn = insn.next?.next ?: return false
return magicInsn is MethodInsnNode && magicInsn.opcode == Opcodes.INVOKESTATIC
&& magicInsn.owner == pluginIntrinsicsMarkerOwner
&& magicInsn.name == pluginIntrinsicsMarkerMethod
&& magicInsn.desc == pluginIntrinsicsMarkerSignature
&& insn.next is LdcInsnNode
}
private inline fun rewriteNextTypeInsn(
marker: MethodInsnNode,
expectedNextOpcode: Int,