StaticMethod MethodInfo | -- for static calls
VirtualMethod Bool MethodInfo | -- for virtual calls
InterfaceMethod Bool MethodInfo | -- for interface calls
+ InstanceOf B.ByteString | -- class name
StaticField StaticFieldInfo deriving Show
data StaticFieldInfo = StaticFieldInfo {
mov eax (Addr 0x00000000) -- it's a trap
push eax
return $ Just (trapaddr, StaticField $ buildStaticFieldID cls cpidx)
+ emit' (INSTANCEOF cpidx) = do
+ pop eax
+ mov eax (Disp 0, eax) -- mtable of objectref
+ trapaddr <- getCurrentOffset
+ -- place something like `mov edx $mtable_of_objref' instead
+ emit32 (0x9090ffff :: Word32) >> emit8 (0x90 :: Word8)
+ cmp eax edx
+ sete al
+ movzxb eax al
+ push eax
+ return $ Just (trapaddr, InstanceOf $ buildClassID cls cpidx)
emit' insn = emit insn >> return Nothing
emit :: J.Instruction -> CodeGen e s ()
mtable <- liftIO $ getMethodTable objname
mov (Disp 0, eax) mtable
emit (CHECKCAST _) = nop -- TODO(bernhard): ...
- -- TODO(bernhard): ...
- emit (INSTANCEOF _) = do
- pop eax
- push (1 :: Word32)
emit ATHROW = -- TODO(bernhard): ...
emit32 (0xffffffff :: Word32)
emit I2C = do
) where
import qualified Data.Map as M
+import qualified Data.ByteString.Lazy as B
import Foreign
import Foreign.C.Types
| StaticFieldAccess
| VirtualMethodCall Bool
| InterfaceMethodCall Bool
+ | InstanceOfMiss B.ByteString
getTrapType :: TrapMap -> CPtrdiff -> CPtrdiff -> TrapType
getTrapType tmap signal_from from2 =
case M.lookup (fromIntegral signal_from) tmap of
(Just (StaticMethod _)) -> StaticMethodCall
(Just (StaticField _)) -> StaticFieldAccess
+ (Just (InstanceOf cn)) -> InstanceOfMiss cn
(Just _) -> error "getTrapMap: doesn't happen"
-- maybe we've a hit on the second `from' value
Nothing -> case M.lookup (fromIntegral from2) tmap of
case getTrapType tmap eip callerAddr of
StaticMethodCall -> staticCallHandler eip
StaticFieldAccess -> staticFieldHandler eip
+ (InstanceOfMiss cn) -> instanceOfMissHandler eip cn
VirtualMethodCall imm8 -> invokeHandler eax eax esp imm8
InterfaceMethodCall imm8 -> invokeHandler eax ebx esp imm8
return eip
else error "staticFieldHandler: something is wrong here. abort.\n"
+instanceOfMissHandler :: CPtrdiff -> B.ByteString -> IO CPtrdiff
+instanceOfMissHandler eip classname = do
+ -- first byte is going to be the opcode
+ let insn_ptr = intPtrToPtr (fromIntegral eip) :: Ptr CUChar
+ -- the next four bytes are the immediate
+ let imm_ptr = intPtrToPtr (fromIntegral (eip + 1)) :: Ptr CPtrdiff
+ checkMe <- peek imm_ptr
+ if checkMe == 0x909090ff then -- safety check...
+ do
+ mtable <- getMethodTable classname
+ poke imm_ptr (fromIntegral mtable)
+ poke insn_ptr 0xba -- `mov edx' opcode
+ return eip
+ else error "instanceOfMissHandler: something is wrong here. abort.\n"
+
invokeHandler :: CPtrdiff -> CPtrdiff -> CPtrdiff -> Bool -> IO CPtrdiff
invokeHandler method_table table2patch esp imm8 = do
-- table2patch: note, that can be a method-table or a interface-table
--- /dev/null
+package tests;
+
+public class InstanceOf1 {
+ public static void main(String []args) {
+ Instance1 x = new Instance1();
+ if (x instanceof Instance1) {
+ System.out.printf("x is instance of Instance1 :-)\n");
+ } else {
+ System.out.printf("x is *not* instance of Instance1 :-(\n");
+ }
+ if (x instanceof Instance2) {
+ System.out.printf("x is instance of Instance2 :-)\n");
+ } else {
+ System.out.printf("x is *not* instance of Instance2 :-(\n");
+ }
+ }
+}