@ -21,16 +21,16 @@ private fun localIndex(access: Int, argTypes: Array<Type>, argIndex: Int): Int {
return localIndex
return localIndex
}
}
private fun remap ( i : Int , argType : Type , localIndex : Int ) : Int {
private fun remap ( i : Int , argType : Type , localIndex : Int , newLocalIndex : Int ) : Int {
return if ( i >= localIndex ) {
return when {
i - argType . size
i > localIndex -> i - argType . size
} else {
i == localIndex -> newLocalIndex
i
else -> i
}
}
}
}
private fun remapAll ( indexes : List < Int > , argType : Type , localIndex : Int ) : MutableList < Int > {
private fun remapAll ( indexes : List < Int > , argType : Type , localIndex : Int , newLocalIndex : Int ) : MutableList < Int > {
return indexes . mapTo ( mutableListOf ( ) ) { remap ( it , argType , localIndex ) }
return indexes . mapTo ( mutableListOf ( ) ) { remap ( it , argType , localIndex , newLocalIndex ) }
}
}
fun MethodNode . removeArgument ( argIndex : Int ) {
fun MethodNode . removeArgument ( argIndex : Int ) {
@ -68,36 +68,65 @@ fun MethodNode.removeArgument(argIndex: Int) {
// remap locals
// remap locals
val localIndex = localIndex ( access , argTypes , argIndex )
val localIndex = localIndex ( access , argTypes , argIndex )
maxLocals -= argType . size
val newLocalIndex = maxLocals - argType . size
if ( localVariables != null ) {
if ( localVariables != null ) {
localVariables . removeIf { it . index == localIndex }
for ( v in localVariables ) {
for ( v in localVariables ) {
v . index = remap ( v . index , argType , localIndex )
v . index = remap ( v . index , argType , localIndex , newLocalIndex )
}
}
}
}
if ( visibleLocalVariableAnnotations != null ) {
if ( visibleLocalVariableAnnotations != null ) {
visibleLocalVariableAnnotations . removeIf { localIndex in it . index }
for ( annotation in visibleLocalVariableAnnotations ) {
for ( annotation in visibleLocalVariableAnnotations ) {
annotation . index = remapAll ( annotation . index , argType , localIndex )
annotation . index = remapAll ( annotation . index , argType , localIndex , newLocalIndex )
}
}
}
}
if ( invisibleLocalVariableAnnotations != null ) {
if ( invisibleLocalVariableAnnotations != null ) {
invisibleLocalVariableAnnotations . removeIf { localIndex in it . index }
for ( annotation in invisibleLocalVariableAnnotations ) {
for ( annotation in invisibleLocalVariableAnnotations ) {
annotation . index = remapAll ( annotation . index , argType , localIndex )
annotation . index = remapAll ( annotation . index , argType , localIndex , newLocalIndex )
}
}
}
}
var newLocalIndexUsed = false
for ( insn in instructions ) {
for ( insn in instructions ) {
when ( insn ) {
when ( insn ) {
is VarInsnNode -> insn . `var` = remap ( insn . `var` , argType , localIndex )
is VarInsnNode -> {
is IincInsnNode -> insn . `var` = remap ( insn . `var` , argType , localIndex )
insn . `var` = remap ( insn . `var` , argType , localIndex , newLocalIndex )
if ( insn . `var` == newLocalIndex ) {
newLocalIndexUsed = true
}
}
is IincInsnNode -> {
insn . `var` = remap ( insn . `var` , argType , localIndex , newLocalIndex )
if ( insn . `var` == newLocalIndex ) {
newLocalIndexUsed = true
}
}
is FrameNode -> throw UnsupportedOperationException ( " SKIP_FRAMES and COMPUTE_FRAMES must be used " )
is FrameNode -> throw UnsupportedOperationException ( " SKIP_FRAMES and COMPUTE_FRAMES must be used " )
}
}
}
}
if ( newLocalIndexUsed ) {
return
}
maxLocals -= argType . size
if ( localVariables != null ) {
localVariables . removeIf { it . index == newLocalIndex }
}
if ( visibleLocalVariableAnnotations != null ) {
visibleLocalVariableAnnotations . removeIf { newLocalIndex in it . index }
}
if ( invisibleLocalVariableAnnotations != null ) {
invisibleLocalVariableAnnotations . removeIf { newLocalIndex in it . index }
}
}
}
fun MethodNode . removeDeadCode ( owner : String ) {
fun MethodNode . removeDeadCode ( owner : String ) {