@@ -58,21 +58,24 @@ object ASMConverters {
58
58
59
59
case class Method (instructions : List [Instruction ], handlers : List [ExceptionHandler ], localVars : List [LocalVariable ])
60
60
61
- case class Field (opcode : Int , owner : String , name : String , desc : String ) extends Instruction
62
- case class Incr (opcode : Int , `var` : Int , incr : Int ) extends Instruction
63
- case class Op (opcode : Int ) extends Instruction
64
- case class IntOp (opcode : Int , operand : Int ) extends Instruction
65
- case class Jump (opcode : Int , label : Label ) extends Instruction
66
- case class Ldc (opcode : Int , cst : Any ) extends Instruction
67
- case class LookupSwitch (opcode : Int , dflt : Label , keys : List [Int ], labels : List [Label ]) extends Instruction
68
- case class TableSwitch (opcode : Int , min : Int , max : Int , dflt : Label , labels : List [Label ]) extends Instruction
69
- case class Invoke (opcode : Int , owner : String , name : String , desc : String , itf : Boolean ) extends Instruction
70
- case class NewArray (opcode : Int , desc : String , dims : Int ) extends Instruction
71
- case class TypeOp (opcode : Int , desc : String ) extends Instruction
72
- case class VarOp (opcode : Int , `var` : Int ) extends Instruction
73
- case class Label (offset : Int ) extends Instruction { def opcode : Int = - 1 }
74
- case class FrameEntry (`type` : Int , local : List [Any ], stack : List [Any ]) extends Instruction { def opcode : Int = - 1 }
75
- case class LineNumber (line : Int , start : Label ) extends Instruction { def opcode : Int = - 1 }
61
+ case class Field (opcode : Int , owner : String , name : String , desc : String ) extends Instruction
62
+ case class Incr (opcode : Int , `var` : Int , incr : Int ) extends Instruction
63
+ case class Op (opcode : Int ) extends Instruction
64
+ case class IntOp (opcode : Int , operand : Int ) extends Instruction
65
+ case class Jump (opcode : Int , label : Label ) extends Instruction
66
+ case class Ldc (opcode : Int , cst : Any ) extends Instruction
67
+ case class LookupSwitch (opcode : Int , dflt : Label , keys : List [Int ], labels : List [Label ]) extends Instruction
68
+ case class TableSwitch (opcode : Int , min : Int , max : Int , dflt : Label , labels : List [Label ]) extends Instruction
69
+ case class Invoke (opcode : Int , owner : String , name : String , desc : String , itf : Boolean ) extends Instruction
70
+ case class InvokeDynamic (opcode : Int , name : String , desc : String , bsm : MethodHandle , bsmArgs : List [AnyRef ]) extends Instruction
71
+ case class NewArray (opcode : Int , desc : String , dims : Int ) extends Instruction
72
+ case class TypeOp (opcode : Int , desc : String ) extends Instruction
73
+ case class VarOp (opcode : Int , `var` : Int ) extends Instruction
74
+ case class Label (offset : Int ) extends Instruction { def opcode : Int = - 1 }
75
+ case class FrameEntry (`type` : Int , local : List [Any ], stack : List [Any ]) extends Instruction { def opcode : Int = - 1 }
76
+ case class LineNumber (line : Int , start : Label ) extends Instruction { def opcode : Int = - 1 }
77
+
78
+ case class MethodHandle (tag : Int , owner : String , name : String , desc : String )
76
79
77
80
case class ExceptionHandler (start : Label , end : Label , handler : Label , desc : Option [String ])
78
81
case class LocalVariable (name : String , desc : String , signature : Option [String ], start : Label , end : Label , index : Int )
@@ -111,6 +114,7 @@ object ASMConverters {
111
114
case i : t.LookupSwitchInsnNode => LookupSwitch (op(i), applyLabel(i.dflt), lst(i.keys) map (x => x : Int ), lst(i.labels) map applyLabel)
112
115
case i : t.TableSwitchInsnNode => TableSwitch (op(i), i.min, i.max, applyLabel(i.dflt), lst(i.labels) map applyLabel)
113
116
case i : t.MethodInsnNode => Invoke (op(i), i.owner, i.name, i.desc, i.itf)
117
+ case i : t.InvokeDynamicInsnNode => InvokeDynamic (op(i), i.name, i.desc, convertMethodHandle(i.bsm), convertBsmArgs(i.bsmArgs))
114
118
case i : t.MultiANewArrayInsnNode => NewArray (op(i), i.desc, i.dims)
115
119
case i : t.TypeInsnNode => TypeOp (op(i), i.desc)
116
120
case i : t.VarInsnNode => VarOp (op(i), i.`var`)
@@ -119,6 +123,13 @@ object ASMConverters {
119
123
case i : t.LineNumberNode => LineNumber (i.line, applyLabel(i.start))
120
124
}
121
125
126
+ private def convertBsmArgs (a : Array [Object ]): List [Object ] = a.map({
127
+ case h : asm.Handle => convertMethodHandle(h)
128
+ case _ => a // can be: Class, method Type, primitive constant
129
+ })(collection.breakOut)
130
+
131
+ private def convertMethodHandle (h : asm.Handle ): MethodHandle = MethodHandle (h.getTag, h.getOwner, h.getName, h.getDesc)
132
+
122
133
private def convertHandlers (method : t.MethodNode ): List [ExceptionHandler ] = {
123
134
method.tryCatchBlocks.asScala.map(h => ExceptionHandler (applyLabel(h.start), applyLabel(h.end), applyLabel(h.handler), Option (h.`type`)))(collection.breakOut)
124
135
}
@@ -197,21 +208,28 @@ object ASMConverters {
197
208
case x => x.asInstanceOf [Object ]
198
209
}
199
210
211
+ def unconvertMethodHandle (h : MethodHandle ): asm.Handle = new asm.Handle (h.tag, h.owner, h.name, h.desc)
212
+ def unconvertBsmArgs (a : List [Object ]): Array [Object ] = a.map({
213
+ case h : MethodHandle => unconvertMethodHandle(h)
214
+ case o => o
215
+ })(collection.breakOut)
216
+
200
217
private def visitMethod (method : t.MethodNode , instruction : Instruction , asmLabel : Map [Label , asm.Label ]): Unit = instruction match {
201
- case Field (op, owner, name, desc) => method.visitFieldInsn(op, owner, name, desc)
202
- case Incr (op, vr, incr) => method.visitIincInsn(vr, incr)
203
- case Op (op) => method.visitInsn(op)
204
- case IntOp (op, operand) => method.visitIntInsn(op, operand)
205
- case Jump (op, label) => method.visitJumpInsn(op, asmLabel(label))
206
- case Ldc (op, cst) => method.visitLdcInsn(cst)
207
- case LookupSwitch (op, dflt, keys, labels) => method.visitLookupSwitchInsn(asmLabel(dflt), keys.toArray, (labels map asmLabel).toArray)
208
- case TableSwitch (op, min, max, dflt, labels) => method.visitTableSwitchInsn(min, max, asmLabel(dflt), (labels map asmLabel).toArray: _* )
209
- case Invoke (op, owner, name, desc, itf) => method.visitMethodInsn(op, owner, name, desc, itf)
210
- case NewArray (op, desc, dims) => method.visitMultiANewArrayInsn(desc, dims)
211
- case TypeOp (op, desc) => method.visitTypeInsn(op, desc)
212
- case VarOp (op, vr) => method.visitVarInsn(op, vr)
213
- case l : Label => method.visitLabel(asmLabel(l))
214
- case FrameEntry (tp, local, stack) => method.visitFrame(tp, local.length, frameTypesToAsm(local, asmLabel).toArray, stack.length, frameTypesToAsm(stack, asmLabel).toArray)
215
- case LineNumber (line, start) => method.visitLineNumber(line, asmLabel(start))
218
+ case Field (op, owner, name, desc) => method.visitFieldInsn(op, owner, name, desc)
219
+ case Incr (op, vr, incr) => method.visitIincInsn(vr, incr)
220
+ case Op (op) => method.visitInsn(op)
221
+ case IntOp (op, operand) => method.visitIntInsn(op, operand)
222
+ case Jump (op, label) => method.visitJumpInsn(op, asmLabel(label))
223
+ case Ldc (op, cst) => method.visitLdcInsn(cst)
224
+ case LookupSwitch (op, dflt, keys, labels) => method.visitLookupSwitchInsn(asmLabel(dflt), keys.toArray, (labels map asmLabel).toArray)
225
+ case TableSwitch (op, min, max, dflt, labels) => method.visitTableSwitchInsn(min, max, asmLabel(dflt), (labels map asmLabel).toArray: _* )
226
+ case Invoke (op, owner, name, desc, itf) => method.visitMethodInsn(op, owner, name, desc, itf)
227
+ case InvokeDynamic (op, name, desc, bsm, bsmArgs) => method.visitInvokeDynamicInsn(name, desc, unconvertMethodHandle(bsm), unconvertBsmArgs(bsmArgs))
228
+ case NewArray (op, desc, dims) => method.visitMultiANewArrayInsn(desc, dims)
229
+ case TypeOp (op, desc) => method.visitTypeInsn(op, desc)
230
+ case VarOp (op, vr) => method.visitVarInsn(op, vr)
231
+ case l : Label => method.visitLabel(asmLabel(l))
232
+ case FrameEntry (tp, local, stack) => method.visitFrame(tp, local.length, frameTypesToAsm(local, asmLabel).toArray, stack.length, frameTypesToAsm(stack, asmLabel).toArray)
233
+ case LineNumber (line, start) => method.visitLineNumber(line, asmLabel(start))
216
234
}
217
235
}
0 commit comments