let sfi = trapmap M.! w32_from
setTrapMap $ M.delete w32_from trapmap
case sfi of
- (SFI (StaticFieldInfo cls field)) -> getStaticFieldOffset cls field
- _ -> error "getFieldAddr: no trapInfo. abort"
+ (StaticField (StaticFieldInfo cls field)) -> getStaticFieldOffset cls field
+ _ -> error "getFieldAddr: no TrapCause found. abort"
-- interface + method + signature plz!
getInterfaceMethodOffset :: B.ByteString -> B.ByteString -> B.ByteString -> IO Word32
let mi = tmap M.! w32_from
let mi'@(MethodInfo method cm sig) =
case mi of
- (MI x) -> x
- (VI _(MethodInfo methname _ msig)) ->
- MethodInfo methname (vmap M.! fromIntegral methodtable) msig
- (II _ (MethodInfo methname _ msig)) ->
- MethodInfo methname (vmap M.! fromIntegral methodtable) msig
- _ -> error "getMethodEntry: no trapInfo. abort."
+ (StaticMethod x) -> x
+ (VirtualMethod _ (MethodInfo methname _ msig)) -> newMi methname msig
+ (InterfaceMethod _ (MethodInfo methname _ msig)) -> newMi methname msig
+ _ -> error "getMethodEntry: no TrapCause found. abort."
+ where newMi mn = MethodInfo mn (vmap M.! fromIntegral methodtable)
setTrapMap $ M.delete w32_from tmap
case M.lookup mi' mmap of
Nothing -> do
-- Word32 = point of method call in generated code
-- MethodInfo = relevant information about callee
-type TrapMap = M.Map Word32 TrapInfo
+type TrapMap = M.Map Word32 TrapCause
-data TrapInfo =
- MI MethodInfo | -- for static calls
- VI Bool MethodInfo | -- for virtual calls
- II Bool MethodInfo | -- for interface calls
- SFI StaticFieldInfo deriving Show
+data TrapCause =
+ StaticMethod MethodInfo | -- for static calls
+ VirtualMethod Bool MethodInfo | -- for virtual calls
+ InterfaceMethod Bool MethodInfo | -- for interface calls
+ StaticField StaticFieldInfo deriving Show
data StaticFieldInfo = StaticFieldInfo {
sfiClassName :: B.ByteString,
offset <- getCodeOffset
return $ w32_ep + fromIntegral offset
- emitInvoke :: Word16 -> Bool -> CodeGen e s (Maybe (Word32, TrapInfo))
+ emitInvoke :: Word16 -> Bool -> CodeGen e s (Maybe (Word32, TrapCause))
emitInvoke cpidx hasThis = do
let l = buildMethodID cls cpidx
calladdr <- getCurrentOffset
-- push result on stack if method has a return value
when (methodHaveReturnValue cls cpidx) (push eax)
-- +2 is for correcting eip in trap context
- return $ Just (calladdr + 2, MI l)
+ return $ Just (calladdr + 2, StaticMethod l)
- emit' :: J.Instruction -> CodeGen e s (Maybe (Word32, TrapInfo))
+ emit' :: J.Instruction -> CodeGen e s (Maybe (Word32, TrapCause))
emit' (INVOKESPECIAL cpidx) = emitInvoke cpidx True
emit' (INVOKESTATIC cpidx) = emitInvoke cpidx False
emit' (INVOKEINTERFACE cpidx _) = do
-- we figure that out at run-time, in the methodpool,
-- depending on the method-table-ptr
let imm8 = is8BitOffset offset
- return $ Just (calladdr + (if imm8 then 3 else 6), II imm8 mi)
+ return $ Just (calladdr + (if imm8 then 3 else 6), InterfaceMethod imm8 mi)
emit' (INVOKEVIRTUAL cpidx) = do
-- get methodInfo entry
let mi@(MethodInfo methodname objname msig@(MethodSignature args _)) = buildMethodID cls cpidx
-- we figure that out at run-time, in the methodpool,
-- depending on the method-table-ptr
let imm8 = is8BitOffset offset
- return $ Just (calladdr + (if imm8 then 3 else 6), VI imm8 mi)
+ return $ Just (calladdr + (if imm8 then 3 else 6), VirtualMethod imm8 mi)
emit' (PUTSTATIC cpidx) = do
pop eax
trapaddr <- getCurrentOffset
mov (Addr 0x00000000) eax -- it's a trap
- return $ Just (trapaddr, SFI $ buildStaticFieldID cls cpidx)
+ return $ Just (trapaddr, StaticField $ buildStaticFieldID cls cpidx)
emit' (GETSTATIC cpidx) = do
trapaddr <- getCurrentOffset
mov eax (Addr 0x00000000) -- it's a trap
push eax
- return $ Just (trapaddr, SFI $ buildStaticFieldID cls cpidx)
+ return $ Just (trapaddr, StaticField $ buildStaticFieldID cls cpidx)
emit' insn = emit insn >> return Nothing
emit :: J.Instruction -> CodeGen e s ()
getTrapType signal_from from2 = do
tmap <- getTrapMap
case M.lookup (fromIntegral signal_from) tmap of
- (Just (MI _)) -> return 0
- (Just (SFI _)) -> return 2
+ (Just (StaticMethod _)) -> return 0
+ (Just (StaticField _)) -> return 2
(Just _) -> error "getTrapMap: doesn't happen"
-- maybe we've a hit on the second `from' value
Nothing -> case M.lookup (fromIntegral from2) tmap of
- (Just (VI True _)) -> return 1
- (Just (VI False _)) -> return 5
- (Just (II True _)) -> return 4
- (Just (II False _)) -> return 8
+ (Just (VirtualMethod True _)) -> return 1
+ (Just (VirtualMethod False _)) -> return 5
+ (Just (InterfaceMethod True _)) -> return 4
+ (Just (InterfaceMethod False _)) -> return 8
(Just _) -> error "getTrapType: abort #1 :-("
Nothing -> error $ "getTrapType: abort #2 :-(" ++ show signal_from ++ ", " ++ show from2 ++ ", " ++ show tmap