Support plugin-defined instrinsics that can be non-typeOf operation types.
This commit is contained in:
+2
-2
@@ -127,7 +127,7 @@ class IrInlineIntrinsicsSupport(
|
||||
.report(JvmBackendErrors.TYPEOF_NON_REIFIED_TYPE_PARAMETER_WITH_RECURSIVE_BOUND, typeParameterName.asString())
|
||||
}
|
||||
|
||||
override fun rewritePluginDefinedOperationMarker(v: InstructionAdapter, stubConstNull: AbstractInsnNode, instructions: InsnList, type: IrType): Boolean {
|
||||
return pluginExtensions.any { it.rewritePluginDefinedOperationMarker(v, stubConstNull, instructions, type) }
|
||||
override fun rewritePluginDefinedOperationMarker(v: InstructionAdapter, reifiedInsn: AbstractInsnNode, instructions: InsnList, type: IrType): Boolean {
|
||||
return pluginExtensions.any { it.rewritePluginDefinedOperationMarker(v, reifiedInsn, instructions, type) }
|
||||
}
|
||||
}
|
||||
|
||||
+32
-4
@@ -14,17 +14,45 @@ import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
|
||||
import org.jetbrains.org.objectweb.asm.tree.InsnList
|
||||
|
||||
interface JvmIrIntrinsicExtension : IrIntrinsicExtension {
|
||||
/**
|
||||
* Returns [IntrinsicMethod] that should emit specific bytecode instead of a regular bytecode for calling [symbol],
|
||||
* or `null` if [symbol]'s call should not be replaced.
|
||||
*/
|
||||
fun getIntrinsic(symbol: IrFunctionSymbol): IntrinsicMethod?
|
||||
|
||||
/**
|
||||
* Should return `true` if marker was processed.
|
||||
* If this method returns `false`, a regular `TYPE_OF` intrinsic would be inserted.
|
||||
* Allows to process plugin-defined reified operation marker.
|
||||
* Reified operation marker is an INVOKESTATIC call to IntrinsicsSupport.reifiedOperationMarker(operationType, typeVariableName) followed
|
||||
* by actual operation to be reified.
|
||||
* For marker to be determined as plugin-defined, another special call should be inserted directly afterwards the operation.
|
||||
* This call is MagicApiIntrinsics.voidMagicApiCall(object). Object should be a string loaded by LDC instruction. Contents of the string is plugin-defined
|
||||
* and recommended way to pass data to a plugin.
|
||||
*
|
||||
* This is plugin's responsibility to remove any calls to MagicApiIntrinsics.voidMagicApiCall and its arguments.
|
||||
* This function must return `true` if marker was processed.
|
||||
* If this method returns `false`, other plugins would be queried, and if others also return `false`, a regular intrinsic determined by operationType would be inserted.
|
||||
*
|
||||
* If marker was processed, this is plugin's responsibility to remove any calls to MagicApiIntrinsics.voidMagicApiCall and its arguments.
|
||||
*
|
||||
* Example of plugin-defined reified operation marker:
|
||||
*
|
||||
* ```
|
||||
* iconst(6) // operationType=6
|
||||
* aconst(T) // typeParamName=T
|
||||
* invokestatic(kotlin/jvm/internal/Intrinsics.reifiedOperationMarker)
|
||||
* aconst(null) // This is operation to be reified. In case of operationType=6, this is typeOf<T>().
|
||||
* // A KType instance would normally be generated on stack instead of null.
|
||||
* aconst("pluginDataString") // arbitrary constant string
|
||||
* invokestatic(kotlin/jvm/internal/MagicApiIntrinsics.voidMagicApiCall(Ljava/lang/Object;)V) // plugin marker call
|
||||
* ```
|
||||
*
|
||||
* Such approach with two markers was chosen mainly for compatibility reasons:
|
||||
* Call to voidMagicApiCall should be inserted directly after operationType-specific instruction (aconst(null) in the example with typeOf).
|
||||
* If we form bytecode this way, old compilers would be able to correctly inline normal reified operation here, even if they do not know anything about plugin reifications.
|
||||
* They won't remove invokestatic(voidMagicApiCall), but it is not a problem, since kotlin-stdlib has this function, and it is a no-op.
|
||||
*/
|
||||
fun rewritePluginDefinedOperationMarker(
|
||||
v: InstructionAdapter,
|
||||
stubConstNull: AbstractInsnNode,
|
||||
reifiedInsn: AbstractInsnNode,
|
||||
instructions: InsnList,
|
||||
type: IrType
|
||||
): Boolean
|
||||
|
||||
Reference in New Issue
Block a user