Rework reified markers format
Use integer operation identifier instead of method name to differentiate reified operations
This commit is contained in:
Generated
+7
@@ -0,0 +1,7 @@
|
|||||||
|
<component name="ProjectDictionaryState">
|
||||||
|
<dictionary name="dzharkov">
|
||||||
|
<words>
|
||||||
|
<w>insn</w>
|
||||||
|
</words>
|
||||||
|
</dictionary>
|
||||||
|
</component>
|
||||||
@@ -2780,7 +2780,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
"Non-reified type parameter under ::class should be rejected by type checker: " + typeParameterDescriptor;
|
"Non-reified type parameter under ::class should be rejected by type checker: " + typeParameterDescriptor;
|
||||||
assert codegen != null :
|
assert codegen != null :
|
||||||
"Reference to member of reified type should be rejected by type checker " + typeParameterDescriptor;
|
"Reference to member of reified type should be rejected by type checker " + typeParameterDescriptor;
|
||||||
codegen.putReifierMarkerIfTypeIsReifiedParameter(type, ReifiedTypeInliner.JAVA_CLASS_MARKER_METHOD_NAME);
|
codegen.putReifiedOperationMarkerIfTypeIsReifiedParameter(type, ReifiedTypeInliner.OperationKind.JAVA_CLASS);
|
||||||
}
|
}
|
||||||
|
|
||||||
putJavaLangClassInstance(v, classAsmType);
|
putJavaLangClassInstance(v, classAsmType);
|
||||||
@@ -3394,9 +3394,9 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
public void newArrayInstruction(@NotNull KotlinType arrayType) {
|
public void newArrayInstruction(@NotNull KotlinType arrayType) {
|
||||||
if (KotlinBuiltIns.isArray(arrayType)) {
|
if (KotlinBuiltIns.isArray(arrayType)) {
|
||||||
KotlinType elementJetType = arrayType.getArguments().get(0).getType();
|
KotlinType elementJetType = arrayType.getArguments().get(0).getType();
|
||||||
putReifierMarkerIfTypeIsReifiedParameter(
|
putReifiedOperationMarkerIfTypeIsReifiedParameter(
|
||||||
elementJetType,
|
elementJetType,
|
||||||
ReifiedTypeInliner.NEW_ARRAY_MARKER_METHOD_NAME
|
ReifiedTypeInliner.OperationKind.NEW_ARRAY
|
||||||
);
|
);
|
||||||
v.newarray(boxType(asmType(elementJetType)));
|
v.newarray(boxType(asmType(elementJetType)));
|
||||||
}
|
}
|
||||||
@@ -3753,32 +3753,35 @@ The "returned" value of try expression with no finally is either the last expres
|
|||||||
|
|
||||||
private void generateInstanceOfInstruction(@NotNull KotlinType jetType) {
|
private void generateInstanceOfInstruction(@NotNull KotlinType jetType) {
|
||||||
Type type = boxType(asmType(jetType));
|
Type type = boxType(asmType(jetType));
|
||||||
putReifierMarkerIfTypeIsReifiedParameter(jetType, ReifiedTypeInliner.INSTANCEOF_MARKER_METHOD_NAME);
|
putReifiedOperationMarkerIfTypeIsReifiedParameter(jetType, ReifiedTypeInliner.OperationKind.INSTANCEOF);
|
||||||
TypeIntrinsics.instanceOf(v, jetType, type);
|
TypeIntrinsics.instanceOf(v, jetType, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private StackValue generateCheckCastInstruction(@NotNull KotlinType jetType, boolean safeAs) {
|
private StackValue generateCheckCastInstruction(@NotNull KotlinType jetType, boolean safeAs) {
|
||||||
Type type = boxType(asmType(jetType));
|
Type type = boxType(asmType(jetType));
|
||||||
putReifierMarkerIfTypeIsReifiedParameter(jetType,
|
putReifiedOperationMarkerIfTypeIsReifiedParameter(jetType,
|
||||||
safeAs ? ReifiedTypeInliner.SAFE_CHECKCAST_MARKER_METHOD_NAME
|
safeAs ? ReifiedTypeInliner.OperationKind.SAFE_CHECKCAST
|
||||||
: ReifiedTypeInliner.CHECKCAST_MARKER_METHOD_NAME);
|
: ReifiedTypeInliner.OperationKind.CHECKCAST);
|
||||||
TypeIntrinsics.checkcast(v, jetType, type, safeAs);
|
TypeIntrinsics.checkcast(v, jetType, type, safeAs);
|
||||||
return StackValue.onStack(type);
|
return StackValue.onStack(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void putReifierMarkerIfTypeIsReifiedParameter(@NotNull KotlinType type, @NotNull String markerMethodName) {
|
public void putReifiedOperationMarkerIfTypeIsReifiedParameter(
|
||||||
|
@NotNull KotlinType type, @NotNull ReifiedTypeInliner.OperationKind operationKind
|
||||||
|
) {
|
||||||
TypeParameterDescriptor typeParameterDescriptor = TypeUtils.getTypeParameterDescriptorOrNull(type);
|
TypeParameterDescriptor typeParameterDescriptor = TypeUtils.getTypeParameterDescriptorOrNull(type);
|
||||||
if (typeParameterDescriptor != null && typeParameterDescriptor.isReified()) {
|
if (typeParameterDescriptor != null && typeParameterDescriptor.isReified()) {
|
||||||
if (typeParameterDescriptor.getContainingDeclaration() != context.getContextDescriptor()) {
|
if (typeParameterDescriptor.getContainingDeclaration() != context.getContextDescriptor()) {
|
||||||
parentCodegen.getReifiedTypeParametersUsages().
|
parentCodegen.getReifiedTypeParametersUsages().
|
||||||
addUsedReifiedParameter(typeParameterDescriptor.getName().asString());
|
addUsedReifiedParameter(typeParameterDescriptor.getName().asString());
|
||||||
}
|
}
|
||||||
boolean putNullableFlag = ReifiedTypeInliner.isNullableMarkerInstruction(markerMethodName) && type.isMarkedNullable();
|
v.iconst(operationKind.getId());
|
||||||
|
boolean putNullableFlag = operationKind.isTypeNullabilityAware() && type.isMarkedNullable();
|
||||||
v.visitLdcInsn(typeParameterDescriptor.getName().asString() + (putNullableFlag ? "?" : ""));
|
v.visitLdcInsn(typeParameterDescriptor.getName().asString() + (putNullableFlag ? "?" : ""));
|
||||||
v.invokestatic(
|
v.invokestatic(
|
||||||
IntrinsicMethods.INTRINSICS_CLASS_NAME, markerMethodName,
|
IntrinsicMethods.INTRINSICS_CLASS_NAME, ReifiedTypeInliner.REIFIED_OPERATION_MARKER_METHOD_NAME,
|
||||||
Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(String.class)), false
|
Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE, Type.getType(String.class)), false
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,12 +16,12 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.codegen.inline
|
package org.jetbrains.kotlin.codegen.inline
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet
|
|
||||||
import org.jetbrains.kotlin.codegen.context.MethodContext
|
import org.jetbrains.kotlin.codegen.context.MethodContext
|
||||||
import org.jetbrains.kotlin.codegen.generateIsCheck
|
import org.jetbrains.kotlin.codegen.generateIsCheck
|
||||||
import org.jetbrains.kotlin.codegen.generateNullCheckForNonSafeAs
|
import org.jetbrains.kotlin.codegen.generateNullCheckForNonSafeAs
|
||||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
|
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
|
||||||
import org.jetbrains.kotlin.codegen.intrinsics.TypeIntrinsics
|
import org.jetbrains.kotlin.codegen.intrinsics.TypeIntrinsics
|
||||||
|
import org.jetbrains.kotlin.codegen.optimization.common.intConstant
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.TypeUtils
|
import org.jetbrains.kotlin.types.TypeUtils
|
||||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||||
@@ -36,22 +36,21 @@ private class ParameterNameAndNullability(val name: String, val nullable: Boolea
|
|||||||
|
|
||||||
public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParameterMappings?) {
|
public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParameterMappings?) {
|
||||||
|
|
||||||
|
enum class OperationKind {
|
||||||
|
NEW_ARRAY, CHECKCAST, SAFE_CHECKCAST, INSTANCEOF, JAVA_CLASS;
|
||||||
|
|
||||||
|
val id: Int get() = ordinal
|
||||||
|
val isTypeNullabilityAware: Boolean get() = this == CHECKCAST || this == INSTANCEOF
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
public val NEW_ARRAY_MARKER_METHOD_NAME: String = "reifyNewArray"
|
@JvmField
|
||||||
public val CHECKCAST_MARKER_METHOD_NAME: String = "reifyCheckcast"
|
public val REIFIED_OPERATION_MARKER_METHOD_NAME = "reifiedOperationMarker"
|
||||||
public val SAFE_CHECKCAST_MARKER_METHOD_NAME: String = "reifySafeCheckcast"
|
@JvmField
|
||||||
public val INSTANCEOF_MARKER_METHOD_NAME: String = "reifyInstanceof"
|
public val NEED_CLASS_REIFICATION_MARKER_METHOD_NAME = "needClassReification"
|
||||||
public val JAVA_CLASS_MARKER_METHOD_NAME: String = "reifyJavaClass"
|
|
||||||
public val NEED_CLASS_REIFICATION_MARKER_METHOD_NAME: String = "needClassReification"
|
|
||||||
|
|
||||||
private val PARAMETRISED_MARKERS = ImmutableSet.of(
|
private fun isOperationReifiedMarker(insn: AbstractInsnNode) =
|
||||||
NEW_ARRAY_MARKER_METHOD_NAME,
|
isReifiedMarker(insn) { it == REIFIED_OPERATION_MARKER_METHOD_NAME }
|
||||||
CHECKCAST_MARKER_METHOD_NAME, SAFE_CHECKCAST_MARKER_METHOD_NAME,
|
|
||||||
INSTANCEOF_MARKER_METHOD_NAME, JAVA_CLASS_MARKER_METHOD_NAME
|
|
||||||
)
|
|
||||||
|
|
||||||
private fun isParametrisedReifiedMarker(insn: AbstractInsnNode) =
|
|
||||||
isReifiedMarker(insn) { PARAMETRISED_MARKERS.contains(it) }
|
|
||||||
|
|
||||||
private fun isReifiedMarker(insn: AbstractInsnNode, namePredicate: (String) -> Boolean): Boolean {
|
private fun isReifiedMarker(insn: AbstractInsnNode, namePredicate: (String) -> Boolean): Boolean {
|
||||||
if (insn.getOpcode() != Opcodes.INVOKESTATIC || insn !is MethodInsnNode) return false
|
if (insn.getOpcode() != Opcodes.INVOKESTATIC || insn !is MethodInsnNode) return false
|
||||||
@@ -70,10 +69,6 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame
|
|||||||
Type.getMethodDescriptor(Type.VOID_TYPE), false
|
Type.getMethodDescriptor(Type.VOID_TYPE), false
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
public fun isNullableMarkerInstruction(marker: String) = INSTANCEOF_MARKER_METHOD_NAME == marker ||
|
|
||||||
CHECKCAST_MARKER_METHOD_NAME == marker
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private var maxStackSize = 0
|
private var maxStackSize = 0
|
||||||
@@ -89,7 +84,7 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame
|
|||||||
maxStackSize = 0
|
maxStackSize = 0
|
||||||
var result = ReifiedTypeParametersUsages()
|
var result = ReifiedTypeParametersUsages()
|
||||||
for (insn in instructions.toArray()) {
|
for (insn in instructions.toArray()) {
|
||||||
if (isParametrisedReifiedMarker(insn)) {
|
if (isOperationReifiedMarker(insn)) {
|
||||||
val newName: String? = processReifyMarker(insn as MethodInsnNode, instructions)
|
val newName: String? = processReifyMarker(insn as MethodInsnNode, instructions)
|
||||||
if (newName != null) {
|
if (newName != null) {
|
||||||
result.addUsedReifiedParameter(newName)
|
result.addUsedReifiedParameter(newName)
|
||||||
@@ -142,10 +137,11 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame
|
|||||||
* or null if it shouldn't
|
* or null if it shouldn't
|
||||||
*/
|
*/
|
||||||
private fun processReifyMarker(insn: MethodInsnNode, instructions: InsnList): String? {
|
private fun processReifyMarker(insn: MethodInsnNode, instructions: InsnList): String? {
|
||||||
val parameter = getParameter(insn) ?: return null
|
val operationKind = insn.operationKind ?: return null
|
||||||
|
val parameter = insn.parameterNameAndNullability ?: return null
|
||||||
val mapping = parametersMapping?.get(parameter.name) ?: return null
|
val mapping = parametersMapping?.get(parameter.name) ?: return null
|
||||||
val kotlinType =
|
val kotlinType =
|
||||||
if (isNullableMarkerInstruction(insn.name) && parameter.nullable)
|
if (operationKind.isTypeNullabilityAware && parameter.nullable)
|
||||||
TypeUtils.makeNullable(mapping.type)
|
TypeUtils.makeNullable(mapping.type)
|
||||||
else
|
else
|
||||||
mapping.type
|
mapping.type
|
||||||
@@ -156,21 +152,21 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame
|
|||||||
// 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
|
||||||
if (when (insn.name) {
|
if (when (operationKind) {
|
||||||
NEW_ARRAY_MARKER_METHOD_NAME -> processNewArray(insn, asmType)
|
OperationKind.NEW_ARRAY -> processNewArray(insn, asmType)
|
||||||
CHECKCAST_MARKER_METHOD_NAME -> processCheckcast(insn, instructions, kotlinType, asmType, safe = false)
|
OperationKind.CHECKCAST -> processCheckcast(insn, instructions, kotlinType, asmType, safe = false)
|
||||||
SAFE_CHECKCAST_MARKER_METHOD_NAME -> processCheckcast(insn, instructions, kotlinType, asmType, safe = true)
|
OperationKind.SAFE_CHECKCAST -> processCheckcast(insn, instructions, kotlinType, asmType, safe = true)
|
||||||
INSTANCEOF_MARKER_METHOD_NAME -> processInstanceof(insn, instructions, kotlinType, asmType)
|
OperationKind.INSTANCEOF -> processInstanceof(insn, instructions, kotlinType, asmType)
|
||||||
JAVA_CLASS_MARKER_METHOD_NAME -> processJavaClass(insn, asmType)
|
OperationKind.JAVA_CLASS -> processJavaClass(insn, asmType)
|
||||||
else -> false
|
|
||||||
}) {
|
}) {
|
||||||
instructions.remove(insn.getPrevious()!!)
|
instructions.remove(insn.previous.previous!!) // PUSH operation ID
|
||||||
instructions.remove(insn)
|
instructions.remove(insn.previous!!) // PUSH type parameter
|
||||||
|
instructions.remove(insn) // INVOKESTATIC marker method
|
||||||
}
|
}
|
||||||
|
|
||||||
return null
|
return null
|
||||||
} else {
|
} else {
|
||||||
val nullableSuffix = if (isNullableMarkerInstruction(insn.name) && kotlinType.isMarkedNullable) "?" else ""
|
val nullableSuffix = if (operationKind.isTypeNullabilityAware && kotlinType.isMarkedNullable) "?" else ""
|
||||||
instructions.set(insn.previous!!, LdcInsnNode(mapping.newName + nullableSuffix))
|
instructions.set(insn.previous!!, LdcInsnNode(mapping.newName + nullableSuffix))
|
||||||
return mapping.newName
|
return mapping.newName
|
||||||
}
|
}
|
||||||
@@ -187,7 +183,7 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame
|
|||||||
rewriteNextTypeInsn(insn, Opcodes.CHECKCAST) { instanceofInsn: AbstractInsnNode ->
|
rewriteNextTypeInsn(insn, Opcodes.CHECKCAST) { instanceofInsn: AbstractInsnNode ->
|
||||||
if (instanceofInsn !is TypeInsnNode) return false
|
if (instanceofInsn !is TypeInsnNode) return false
|
||||||
|
|
||||||
addNullCheckForAsIfNeeded(insn.previous!!, instructions, jetType, safe)
|
addNullCheckForAsIfNeeded(insn.previous.previous, instructions, jetType, safe)
|
||||||
TypeIntrinsics.checkcast(instanceofInsn, instructions, jetType, asmType, safe)
|
TypeIntrinsics.checkcast(instanceofInsn, instructions, jetType, asmType, safe)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -214,7 +210,7 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame
|
|||||||
private fun addNullCheckForIsIfNeeded(insn: AbstractInsnNode, instructions: InsnList, type: KotlinType) {
|
private fun addNullCheckForIsIfNeeded(insn: AbstractInsnNode, instructions: InsnList, type: KotlinType) {
|
||||||
if (TypeUtils.isNullableType(type)) {
|
if (TypeUtils.isNullableType(type)) {
|
||||||
val instanceOf = insn.next
|
val instanceOf = insn.next
|
||||||
insertNullCheckAround(instructions, insn.previous!!, instanceOf)
|
insertNullCheckAround(instructions, insn.previous.previous, instanceOf)
|
||||||
maxStackSize = Math.max(maxStackSize, 2)
|
maxStackSize = Math.max(maxStackSize, 2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -262,10 +258,13 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getParameter(insn: MethodInsnNode): ParameterNameAndNullability? {
|
}
|
||||||
val prev = insn.getPrevious()!!
|
|
||||||
|
|
||||||
val parameterNameWithFlag = when (prev.getOpcode()) {
|
private val MethodInsnNode.parameterNameAndNullability: ParameterNameAndNullability?
|
||||||
|
get() {
|
||||||
|
val prev = previous!!
|
||||||
|
|
||||||
|
val parameterNameWithFlag = when (prev.opcode) {
|
||||||
Opcodes.LDC -> (prev as LdcInsnNode).cst as String
|
Opcodes.LDC -> (prev as LdcInsnNode).cst as String
|
||||||
else -> return null
|
else -> return null
|
||||||
}
|
}
|
||||||
@@ -273,7 +272,11 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame
|
|||||||
val parameterName = if (parameterNameWithFlag.endsWith("?")) parameterNameWithFlag.dropLast(1) else parameterNameWithFlag
|
val parameterName = if (parameterNameWithFlag.endsWith("?")) parameterNameWithFlag.dropLast(1) else parameterNameWithFlag
|
||||||
return ParameterNameAndNullability(parameterName, parameterName !== parameterNameWithFlag)
|
return ParameterNameAndNullability(parameterName, parameterName !== parameterNameWithFlag)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
private val MethodInsnNode.operationKind: ReifiedTypeInliner.OperationKind? get() =
|
||||||
|
previous?.previous?.intConstant?.let {
|
||||||
|
ReifiedTypeInliner.OperationKind.values().getOrNull(it)
|
||||||
|
}
|
||||||
|
|
||||||
public class ReifiedTypeParameterMappings() {
|
public class ReifiedTypeParameterMappings() {
|
||||||
private val mappingsByName = hashMapOf<String, ReifiedTypeParameterMapping>()
|
private val mappingsByName = hashMapOf<String, ReifiedTypeParameterMapping>()
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ public class JavaClassFunction : IntrinsicMethod() {
|
|||||||
val javaClass = resolvedCall.getResultingDescriptor().getReturnType()!!.getArguments().first().getType()
|
val javaClass = resolvedCall.getResultingDescriptor().getReturnType()!!.getArguments().first().getType()
|
||||||
return object : IntrinsicCallable(getType(javaClass<Class<Any>>()), listOf(), null, null) {
|
return object : IntrinsicCallable(getType(javaClass<Class<Any>>()), listOf(), null, null) {
|
||||||
override fun invokeIntrinsic(v: InstructionAdapter) {
|
override fun invokeIntrinsic(v: InstructionAdapter) {
|
||||||
codegen.putReifierMarkerIfTypeIsReifiedParameter(javaClass, ReifiedTypeInliner.JAVA_CLASS_MARKER_METHOD_NAME)
|
codegen.putReifiedOperationMarkerIfTypeIsReifiedParameter(javaClass, ReifiedTypeInliner.OperationKind.JAVA_CLASS)
|
||||||
putJavaLangClassInstance(v, codegen.getState().typeMapper.mapType(javaClass))
|
putJavaLangClassInstance(v, codegen.getState().typeMapper.mapType(javaClass))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ public class KClassJavaProperty : IntrinsicPropertyGetter() {
|
|||||||
return when {
|
return when {
|
||||||
isReifiedTypeParameter(type) -> {
|
isReifiedTypeParameter(type) -> {
|
||||||
StackValue.operation(returnType) { iv ->
|
StackValue.operation(returnType) { iv ->
|
||||||
codegen.putReifierMarkerIfTypeIsReifiedParameter(type, ReifiedTypeInliner.JAVA_CLASS_MARKER_METHOD_NAME)
|
codegen.putReifiedOperationMarkerIfTypeIsReifiedParameter(type, ReifiedTypeInliner.OperationKind.JAVA_CLASS)
|
||||||
AsmUtil.putJavaLangClassInstance(iv, asmType)
|
AsmUtil.putJavaLangClassInstance(iv, asmType)
|
||||||
coerceToJavaLangClass(iv, returnType)
|
coerceToJavaLangClass(iv, returnType)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,9 +16,8 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.codegen.optimization.common
|
package org.jetbrains.kotlin.codegen.optimization.common
|
||||||
|
|
||||||
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
|
import org.jetbrains.org.objectweb.asm.Opcodes.*
|
||||||
import org.jetbrains.org.objectweb.asm.tree.InsnList
|
import org.jetbrains.org.objectweb.asm.tree.*
|
||||||
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
|
||||||
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue
|
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue
|
||||||
|
|
||||||
val AbstractInsnNode.isMeaningful: Boolean get() =
|
val AbstractInsnNode.isMeaningful: Boolean get() =
|
||||||
@@ -97,3 +96,24 @@ inline fun AbstractInsnNode.findPreviousOrNull(predicate: (AbstractInsnNode) ->
|
|||||||
|
|
||||||
fun AbstractInsnNode.hasOpcode(): Boolean =
|
fun AbstractInsnNode.hasOpcode(): Boolean =
|
||||||
getOpcode() >= 0
|
getOpcode() >= 0
|
||||||
|
|
||||||
|
// See InstructionAdapter
|
||||||
|
//
|
||||||
|
// public void iconst(final int cst) {
|
||||||
|
// if (cst >= -1 && cst <= 5) {
|
||||||
|
// mv.visitInsn(Opcodes.ICONST_0 + cst);
|
||||||
|
// } else if (cst >= Byte.MIN_VALUE && cst <= Byte.MAX_VALUE) {
|
||||||
|
// mv.visitIntInsn(Opcodes.BIPUSH, cst);
|
||||||
|
// } else if (cst >= Short.MIN_VALUE && cst <= Short.MAX_VALUE) {
|
||||||
|
// mv.visitIntInsn(Opcodes.SIPUSH, cst);
|
||||||
|
// } else {
|
||||||
|
// mv.visitLdcInsn(new Integer(cst));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
val AbstractInsnNode.intConstant: Int? get() =
|
||||||
|
when (opcode) {
|
||||||
|
in ICONST_M1..ICONST_5 -> opcode - ICONST_0
|
||||||
|
BIPUSH, SIPUSH -> (this as IntInsnNode).operand
|
||||||
|
LDC -> (this as LdcInsnNode).cst as? Int
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|||||||
@@ -173,35 +173,11 @@ public class Intrinsics {
|
|||||||
throw new UnsupportedOperationException(message);
|
throw new UnsupportedOperationException(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void reifyNewArray(String typeParameterIdentifier) {
|
public static void reifiedOperationMarker(int id, String typeParameterIdentifier) {
|
||||||
throwUndefinedForReified();
|
throwUndefinedForReified();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void reifyNewArray(String typeParameterIdentifier, String message) {
|
public static void reifiedOperationMarker(int id, String typeParameterIdentifier, String message) {
|
||||||
throwUndefinedForReified(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void reifyCheckcast(String typeParameterIdentifier) {
|
|
||||||
throwUndefinedForReified();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void reifyCheckcast(String typeParameterIdentifier, String message) {
|
|
||||||
throwUndefinedForReified(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void reifyInstanceof(String typeParameterIdentifier) {
|
|
||||||
throwUndefinedForReified();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void reifyInstanceof(String typeParameterIdentifier, String message) {
|
|
||||||
throwUndefinedForReified(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void reifyJavaClass(String typeParameterIdentifier) {
|
|
||||||
throwUndefinedForReified();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void reifyJavaClass(String typeParameterIdentifier, String message) {
|
|
||||||
throwUndefinedForReified(message);
|
throwUndefinedForReified(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user