Put that CHECKCAST in the right place

This commit is contained in:
Chicken-Bones committed 2013-12-23 02:44:50 +10:00
1 parent 26da47d148
commit 71dbc0fed2
2 files changed
+43 -33

No files matched your search

@@ -362,7 +362,7 @@ object ASMMixinCompiler
if(minsn.owner.equals(oname)) return None//private this
stack.peek(Type.getType(minsn.desc).getArgumentTypes.length) match {
case This(o) =>
case Load(This(o)) =>
case _ => return None//have to be invoked on this
}
@@ -442,12 +442,6 @@ object ASMMixinCompiler
insn = newinsn
}
def insertBefore(newinsn:AbstractInsnNode)
{
insnList.insertBefore(insn, newinsn)
stack.visitInsn(newinsn)
}
//transform
while(insn != null)
{
@@ -470,7 +464,9 @@ object ASMMixinCompiler
if(methodSigs.contains(minsn.name+minsn.desc))//call the interface method
minsn.setOpcode(INVOKEINTERFACE)
else {//cast to parent class and call
insertBefore(new TypeInsnNode(CHECKCAST, cnode.superName))
val mType = Type.getMethodType(minsn.desc)
val instanceEntry = stack.peek(width(mType.getArgumentTypes))
insnList.insert(instanceEntry.insn, new TypeInsnNode(CHECKCAST, cnode.superName))
minsn.owner = cnode.superName
}
}
+39 -25
View File
@@ -13,20 +13,29 @@ object StackAnalyser
def width(s:String):Int = width(Type.getType(s))
def width(it:Iterable[Type]):Int = it.foldLeft(0)(_+width(_))
trait StackEntry
abstract class StackEntry(implicit val insn:AbstractInsnNode)
{
def getType:Type
}
case class This(owner:Type) extends StackEntry
abstract class LocalEntry
{
def getType:Type
}
case class This(owner:Type) extends LocalEntry
{
def getType = owner
}
case class Param(i:Int, t:Type) extends StackEntry
case class Param(i:Int, t:Type) extends LocalEntry
{
def getType = t
}
case class Const(c:Any) extends StackEntry
case class Store(e:StackEntry)(implicit val insn:AbstractInsnNode) extends LocalEntry
{
def getType = e.getType
}
case class Const(c:Any)(implicit insn:AbstractInsnNode) extends StackEntry
{
def getType = c match {
case o:Byte => BYTE_TYPE
@@ -42,55 +51,59 @@ object StackAnalyser
case _ => throw new IllegalArgumentException("Unknown const "+c)
}
}
case class UnaryOp(op:Int, e:StackEntry) extends StackEntry
case class Load(e:LocalEntry)(implicit insn:AbstractInsnNode) extends StackEntry
{
def getType = e.getType
}
case class BinaryOp(op:Int, e2:StackEntry, e1:StackEntry) extends StackEntry
case class UnaryOp(op:Int, e:StackEntry)(implicit insn:AbstractInsnNode) extends StackEntry
{
def getType = e.getType
}
case class BinaryOp(op:Int, e2:StackEntry, e1:StackEntry)(implicit insn:AbstractInsnNode) extends StackEntry
{
def getType = e1.getType
}
case class PrimitiveCast(e:StackEntry, t:Type) extends StackEntry
case class PrimitiveCast(e:StackEntry, t:Type)(implicit insn:AbstractInsnNode) extends StackEntry
{
def getType = t
}
case class ReturnAddress() extends StackEntry
case class ReturnAddress()(implicit insn:AbstractInsnNode) extends StackEntry
{
def getType = INT_TYPE
}
case class GetField(obj:StackEntry, field:FieldInsnNode) extends StackEntry
case class GetField(obj:StackEntry, field:FieldInsnNode)(implicit insn:AbstractInsnNode) extends StackEntry
{
def getType = Type.getType(field.desc)
}
case class Invoke(op:Int, params:Array[StackEntry], obj:StackEntry, method:MethodInsnNode) extends StackEntry
case class Invoke(op:Int, params:Array[StackEntry], obj:StackEntry, method:MethodInsnNode)(implicit insn:AbstractInsnNode) extends StackEntry
{
def getType = Type.getMethodType(method.desc).getReturnType
}
case class New(t:Type) extends StackEntry
case class New(t:Type)(implicit insn:AbstractInsnNode) extends StackEntry
{
def getType = t
}
case class NewArray(len:StackEntry, t:Type) extends StackEntry
case class NewArray(len:StackEntry, t:Type)(implicit insn:AbstractInsnNode) extends StackEntry
{
def getType = t
}
case class ArrayLength(array:StackEntry) extends StackEntry
case class ArrayLength(array:StackEntry)(implicit insn:AbstractInsnNode) extends StackEntry
{
def getType = INT_TYPE
}
case class ArrayLoad(index:StackEntry, e:StackEntry) extends StackEntry
case class ArrayLoad(index:StackEntry, e:StackEntry)(implicit insn:AbstractInsnNode) extends StackEntry
{
def getType = e.getType.getElementType
}
case class Cast(obj:StackEntry, t:Type) extends StackEntry
case class Cast(obj:StackEntry, t:Type)(implicit insn:AbstractInsnNode) extends StackEntry
{
def getType = t
}
case class NewMultiArray(sizes:Array[StackEntry], t:Type) extends StackEntry
case class NewMultiArray(sizes:Array[StackEntry], t:Type)(implicit insn:AbstractInsnNode) extends StackEntry
{
def getType = t
}
case class CaughtException(t:Type) extends StackEntry
case class CaughtException(t:Type)(implicit insn:AbstractInsnNode) extends StackEntry
{
def getType = t
}
@@ -101,7 +114,7 @@ class StackAnalyser(val owner:Type, val m:MethodNode)
import StackAnalyser._
val stack = MList[StackEntry]()
val locals = MList[StackEntry]()
val locals = MList[LocalEntry]()
private val catchHandlers = MMap[LabelNode, TryCatchBlockNode]()
{
@@ -115,9 +128,9 @@ class StackAnalyser(val owner:Type, val m:MethodNode)
m.tryCatchBlocks.foreach(b => catchHandlers.put(b.handler, b))
}
def pushL(entry:StackEntry) = setL(locals.size, entry)
def setL(i:Int, entry:StackEntry) =
def pushL(entry:LocalEntry) = setL(locals.size, entry)
def setL(i:Int, entry:LocalEntry) =
{
while(i+entry.getType.getSize > locals.size) locals += null
locals(i) = entry
@@ -162,6 +175,7 @@ class StackAnalyser(val owner:Type, val m:MethodNode)
def visitInsn(ainsn:AbstractInsnNode)
{
implicit val thisInsn = ainsn//passes to any StackEntry we create
ainsn match {
case insn:InsnNode => ainsn.getOpcode match
{
@@ -235,13 +249,13 @@ class StackAnalyser(val owner:Type, val m:MethodNode)
case vinsn:VarInsnNode => ainsn.getOpcode match
{
case i if i >= ILOAD && i <= ALOAD =>
push(locals(vinsn.`var`))
push(Load(locals(vinsn.`var`)))
case i if i >= ISTORE && i <= ASTORE =>
setL(vinsn.`var`, pop())
setL(vinsn.`var`, Store(pop()))
}
case incinsn:IincInsnNode => ainsn.getOpcode match
{
case IINC => setL(incinsn.`var`, BinaryOp(IINC, Const(incinsn.incr), locals(incinsn.`var`)))
case IINC => setL(incinsn.`var`, Store(BinaryOp(IINC, Const(incinsn.incr), Load(locals(incinsn.`var`)))))
}
case jinsn:JumpInsnNode => ainsn.getOpcode match
{