Remove unsafe cast function usages from JVM backend modules
This commit is contained in:
committed by
Space Team
parent
2cd16f055a
commit
1418423423
@@ -21,7 +21,6 @@ import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import org.jetbrains.org.objectweb.asm.Label
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
@@ -159,13 +158,13 @@ fun generateAssertionsDisabledFieldInitialization(classBuilder: ClassBuilder, cl
|
||||
}
|
||||
|
||||
fun rewriteAssertionsDisabledFieldInitialization(methodNode: MethodNode, className: String) {
|
||||
InsnSequence(methodNode.instructions).firstOrNull {
|
||||
val node = InsnSequence(methodNode.instructions).firstOrNull {
|
||||
it is FieldInsnNode && it.opcode == Opcodes.PUTSTATIC && it.name == ASSERTIONS_DISABLED_FIELD_NAME
|
||||
}?.findPreviousOrNull {
|
||||
it is MethodInsnNode && it.opcode == Opcodes.INVOKEVIRTUAL
|
||||
&& it.owner == "java/lang/Class" && it.name == "desiredAssertionStatus" && it.desc == "()Z"
|
||||
}?.previous?.safeAs<LdcInsnNode>()?.cst =
|
||||
Type.getObjectType(className)
|
||||
}?.previous
|
||||
(node as? LdcInsnNode)?.cst = Type.getObjectType(className)
|
||||
}
|
||||
|
||||
private fun <D : FunctionDescriptor> ResolvedCall<D>.replaceAssertWithAssertInner(): ResolvedCall<D> {
|
||||
|
||||
+6
-4
@@ -12,7 +12,6 @@ import org.jetbrains.kotlin.codegen.optimization.common.removeAll
|
||||
import org.jetbrains.kotlin.codegen.optimization.fixStack.top
|
||||
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
|
||||
import org.jetbrains.org.objectweb.asm.tree.LabelNode
|
||||
@@ -73,8 +72,9 @@ private class UnitSourceInterpreter(private val localVariables: Set<Int>) : Basi
|
||||
// Map from unit values to ASTORE/POP use-sites.
|
||||
val unitUsageInformation = mutableMapOf<AbstractInsnNode, MutableSet<AbstractInsnNode>>()
|
||||
|
||||
private fun markUnspillable(value: BasicValue?) =
|
||||
value?.safeAs<UnitValue>()?.let { unspillableUnitValues += it.insns }
|
||||
private fun markUnspillable(value: BasicValue?) {
|
||||
(value as? UnitValue)?.let { unspillableUnitValues += it.insns }
|
||||
}
|
||||
|
||||
private fun collectUnitUsage(use: AbstractInsnNode, value: UnitValue) {
|
||||
for (def in value.insns) {
|
||||
@@ -90,7 +90,9 @@ private class UnitSourceInterpreter(private val localVariables: Set<Int>) : Basi
|
||||
for ((insn, frame) in methodNode.instructions.asSequence().zip(frames.asSequence())) {
|
||||
if (frame != null && insn.opcode == Opcodes.POP) {
|
||||
val value = frame.top()
|
||||
value.safeAs<UnitValue>()?.let { collectUnitUsage(insn, it) }
|
||||
if (value is UnitValue) {
|
||||
collectUnitUsage(insn, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
return frames
|
||||
|
||||
+2
-3
@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOrigin
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
@@ -109,8 +108,8 @@ class SuspendFunctionGenerationStrategy(
|
||||
return bfs(this)
|
||||
}
|
||||
|
||||
private fun containingClassInternalNameOrNull() =
|
||||
originalSuspendDescriptor.containingDeclaration.safeAs<ClassDescriptor>()?.let(state.typeMapper::mapClass)?.internalName
|
||||
private fun containingClassInternalNameOrNull(): String? =
|
||||
(originalSuspendDescriptor.containingDeclaration as? ClassDescriptor)?.let(state.typeMapper::mapClass)?.internalName
|
||||
|
||||
override fun doGenerateBody(codegen: ExpressionCodegen, signature: JvmMethodSignature) {
|
||||
this.codegen = codegen
|
||||
|
||||
+6
-8
@@ -39,12 +39,11 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.resolveTopLevelClass
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.error.ErrorUtils
|
||||
import org.jetbrains.kotlin.types.error.ErrorTypeKind
|
||||
import org.jetbrains.kotlin.types.error.ErrorUtils
|
||||
import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
|
||||
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import org.jetbrains.org.objectweb.asm.Label
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
@@ -187,9 +186,9 @@ fun ResolvedCall<*>.isSuspensionPoint(codegen: ExpressionCodegen): SuspensionPoi
|
||||
if (functionDescriptor.isBuiltInSuspendCoroutineUninterceptedOrReturnInJvm()) return SuspensionPointKind.ALWAYS
|
||||
if (functionDescriptor.isInline) return SuspensionPointKind.NEVER
|
||||
|
||||
val isInlineLambda = this.safeAs<VariableAsFunctionResolvedCall>()
|
||||
?.variableCall?.resultingDescriptor?.safeAs<ValueParameterDescriptor>()
|
||||
?.let { it.isCrossinline || (!it.isNoinline && codegen.context.functionDescriptor.isInline) } == true
|
||||
val parameter = (this as? VariableAsFunctionResolvedCall)?.variableCall?.resultingDescriptor as? ValueParameterDescriptor
|
||||
val isInlineLambda = parameter != null &&
|
||||
(parameter.isCrossinline || (!parameter.isNoinline && codegen.context.functionDescriptor.isInline))
|
||||
return if (isInlineLambda) SuspensionPointKind.NOT_INLINE else SuspensionPointKind.ALWAYS
|
||||
}
|
||||
|
||||
@@ -225,7 +224,7 @@ fun <D : FunctionDescriptor> getOrCreateJvmSuspendFunctionView(
|
||||
annotations = Annotations.EMPTY,
|
||||
name = CONTINUATION_PARAMETER_NAME,
|
||||
// Add j.l.Object to invoke(), because that is the type of parameters we have in FunctionN+1
|
||||
outType = if (function.containingDeclaration.safeAs<ClassDescriptor>()?.isBuiltinFunctionalClassDescriptor == true)
|
||||
outType = if ((function.containingDeclaration as? ClassDescriptor)?.isBuiltinFunctionalClassDescriptor == true)
|
||||
function.builtIns.nullableAnyType
|
||||
else
|
||||
function.getContinuationParameterTypeOfSuspendFunction(),
|
||||
@@ -363,8 +362,7 @@ private fun InstructionAdapter.invokeGetContext() {
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <D : CallableDescriptor?> D.unwrapInitialDescriptorForSuspendFunction(): D =
|
||||
this.safeAs<SimpleFunctionDescriptor>()?.getUserData(INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION) as D ?: this
|
||||
|
||||
(this as? SimpleFunctionDescriptor)?.getUserData(INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION) as D ?: this
|
||||
|
||||
fun FunctionDescriptor.getOriginalSuspendFunctionView(bindingContext: BindingContext): FunctionDescriptor =
|
||||
if (isSuspend)
|
||||
|
||||
@@ -24,7 +24,6 @@ import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
import org.jetbrains.kotlin.utils.SmartSet
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import org.jetbrains.org.objectweb.asm.Label
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
@@ -697,7 +696,7 @@ class MethodInliner(
|
||||
if (lambdaInfo !is PsiExpressionLambda || !lambdaInfo.invokeMethodDescriptor.isSuspend) return
|
||||
val sources = analyzeMethodNodeWithInterpreter(processingNode, Aload0Interpreter(processingNode))
|
||||
val cfg = ControlFlowGraph.build(processingNode)
|
||||
val aload0s = processingNode.instructions.asSequence().filter { it.opcode == Opcodes.ALOAD && it.safeAs<VarInsnNode>()?.`var` == 0 }
|
||||
val aload0s = processingNode.instructions.asSequence().filter { it.opcode == Opcodes.ALOAD && (it as? VarInsnNode)?.`var` == 0 }
|
||||
|
||||
val visited = hashSetOf<AbstractInsnNode>()
|
||||
fun findMeaningfulSuccs(insn: AbstractInsnNode): Collection<AbstractInsnNode> {
|
||||
|
||||
@@ -11,7 +11,6 @@ import org.jetbrains.kotlin.codegen.ASSERTIONS_DISABLED_FIELD_NAME
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.codegen.SamWrapperCodegen.SAM_WRAPPER_SUFFIX
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.codegen.`when`.WhenByEnumsMapping
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
||||
import org.jetbrains.kotlin.codegen.context.CodegenContext
|
||||
import org.jetbrains.kotlin.codegen.context.CodegenContextUtil
|
||||
@@ -25,6 +24,7 @@ import org.jetbrains.kotlin.codegen.optimization.common.intConstant
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapperBase
|
||||
import org.jetbrains.kotlin.codegen.`when`.WhenByEnumsMapping
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
@@ -39,7 +39,6 @@ import org.jetbrains.kotlin.types.TypeProjectionImpl
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import org.jetbrains.org.objectweb.asm.*
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
import org.jetbrains.org.objectweb.asm.commons.Method
|
||||
@@ -577,7 +576,7 @@ private fun addAfterUnboxInlineClassMarker(v: InstructionAdapter) {
|
||||
}
|
||||
|
||||
internal fun addReturnsUnitMarkerIfNecessary(v: InstructionAdapter, resolvedCall: ResolvedCall<*>) {
|
||||
val wrapperDescriptor = resolvedCall.candidateDescriptor.safeAs<FunctionDescriptor>() ?: return
|
||||
val wrapperDescriptor = resolvedCall.candidateDescriptor as? FunctionDescriptor ?: return
|
||||
val unsubstitutedDescriptor = wrapperDescriptor.unwrapInitialDescriptorForSuspendFunction()
|
||||
|
||||
val typeSubstitutor = TypeSubstitutor.create(
|
||||
|
||||
+2
-3
@@ -23,7 +23,6 @@ import org.jetbrains.kotlin.codegen.optimization.fixStack.peek
|
||||
import org.jetbrains.kotlin.codegen.optimization.fixStack.top
|
||||
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.tree.*
|
||||
@@ -143,8 +142,8 @@ class CapturedVarsOptimizationMethodTransformer : MethodTransformer() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun BasicValue.getCapturedVarOrNull() =
|
||||
safeAs<ProperTrackedReferenceValue>()?.descriptor?.safeAs<CapturedVarDescriptor>()
|
||||
private fun BasicValue.getCapturedVarOrNull(): CapturedVarDescriptor? =
|
||||
(this as? ProperTrackedReferenceValue)?.descriptor as? CapturedVarDescriptor
|
||||
|
||||
private fun assignLocalVars(frames: Array<out Frame<BasicValue>?>) {
|
||||
for (localVar in methodNode.localVariables) {
|
||||
|
||||
+3
-5
@@ -23,8 +23,6 @@ import org.jetbrains.kotlin.codegen.optimization.common.removeAll
|
||||
import org.jetbrains.kotlin.codegen.optimization.fixStack.peek
|
||||
import org.jetbrains.kotlin.codegen.optimization.fixStack.top
|
||||
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.tree.*
|
||||
@@ -96,7 +94,7 @@ class ConstantConditionEliminationMethodTransformer : MethodTransformer() {
|
||||
}
|
||||
|
||||
private fun tryRewriteComparisonWithZero(insn: JumpInsnNode, frame: Frame<BasicValue>, actions: ArrayList<() -> Unit>) {
|
||||
val top = frame.top()!!.safeAs<IConstValue>() ?: return
|
||||
val top = frame.top()!! as? IConstValue ?: return
|
||||
|
||||
val constCondition = when (insn.opcode) {
|
||||
Opcodes.IFEQ -> top.value == 0
|
||||
@@ -199,9 +197,9 @@ class ConstantConditionEliminationMethodTransformer : MethodTransformer() {
|
||||
in Opcodes.ICONST_M1..Opcodes.ICONST_5 ->
|
||||
IConstValue.of(insn.opcode - Opcodes.ICONST_0)
|
||||
Opcodes.BIPUSH, Opcodes.SIPUSH ->
|
||||
IConstValue.of(insn.cast<IntInsnNode>().operand)
|
||||
IConstValue.of((insn as IntInsnNode).operand)
|
||||
Opcodes.LDC -> {
|
||||
val operand = insn.cast<LdcInsnNode>().cst
|
||||
val operand = (insn as LdcInsnNode).cst
|
||||
if (operand is Int)
|
||||
IConstValue.of(operand)
|
||||
else
|
||||
|
||||
@@ -20,7 +20,6 @@ import org.jetbrains.kotlin.codegen.inline.MaxStackFrameSizeAndLocalsCalculator
|
||||
import org.jetbrains.kotlin.codegen.inline.insnText
|
||||
import org.jetbrains.kotlin.codegen.optimization.removeNodeGetNext
|
||||
import org.jetbrains.kotlin.codegen.pseudoInsns.PseudoInsn
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes.*
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
@@ -244,7 +243,7 @@ internal inline fun <reified T : AbstractInsnNode> AbstractInsnNode.isInsn(opcod
|
||||
takeInsnIf(opcode, condition) != null
|
||||
|
||||
internal inline fun <reified T : AbstractInsnNode> AbstractInsnNode.takeInsnIf(opcode: Int, condition: T.() -> Boolean): T? =
|
||||
takeIf { it.opcode == opcode }?.safeAs<T>()?.takeIf { it.condition() }
|
||||
(takeIf { it.opcode == opcode } as? T)?.takeIf { it.condition() }
|
||||
|
||||
fun InsnList.removeAll(nodes: Collection<AbstractInsnNode>) {
|
||||
for (node in nodes) remove(node)
|
||||
|
||||
+2
-3
@@ -34,9 +34,8 @@ import org.jetbrains.kotlin.psi.KtForExpression
|
||||
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.constants.*
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
|
||||
abstract class PrimitiveNumberRangeIntrinsicRangeValue(
|
||||
rangeCall: ResolvedCall<out CallableDescriptor>
|
||||
@@ -100,7 +99,7 @@ abstract class PrimitiveNumberRangeIntrinsicRangeValue(
|
||||
step: Int,
|
||||
isStartInclusive: Boolean = true
|
||||
): ForLoopGenerator? {
|
||||
val endConstValue = codegen.getCompileTimeConstant(endExpression).safeAs<IntegerValueConstant<*>>() ?: return null
|
||||
val endConstValue = codegen.getCompileTimeConstant(endExpression) as? IntegerValueConstant<*> ?: return null
|
||||
|
||||
return when (endConstValue) {
|
||||
is ByteValue -> {
|
||||
|
||||
+3
-5
@@ -17,7 +17,6 @@
|
||||
package org.jetbrains.kotlin.codegen.range
|
||||
|
||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.codegen.generateCallReceiver
|
||||
import org.jetbrains.kotlin.codegen.generateCallSingleArgument
|
||||
import org.jetbrains.kotlin.codegen.range.comparison.getComparisonGeneratorForKotlinType
|
||||
@@ -25,11 +24,10 @@ import org.jetbrains.kotlin.codegen.range.forLoop.ForInSimpleProgressionLoopGene
|
||||
import org.jetbrains.kotlin.codegen.range.forLoop.ForLoopGenerator
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.util.getFirstArgumentExpression
|
||||
import org.jetbrains.kotlin.resolve.calls.util.getReceiverExpression
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.constants.IntegerValueConstant
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
|
||||
class PrimitiveNumberRangeLiteralRangeValue(
|
||||
@@ -109,8 +107,8 @@ private fun ExpressionCodegen.isArraySizeMinusOne(expression: KtExpression): Boo
|
||||
isConstantOne(expression.right!!)
|
||||
|
||||
private fun ExpressionCodegen.isConstantOne(expression: KtExpression): Boolean {
|
||||
val constantValue = getCompileTimeConstant(expression).safeAs<IntegerValueConstant<*>>() ?: return false
|
||||
return constantValue.value == 1
|
||||
val constantValue = getCompileTimeConstant(expression)
|
||||
return constantValue is IntegerValueConstant<*> && constantValue.value == 1
|
||||
}
|
||||
|
||||
private fun ExpressionCodegen.isArraySizeAccess(expression: KtExpression): Boolean {
|
||||
|
||||
Reference in New Issue
Block a user