#endif
-foreign import ccall "dynamic"
- code_int :: FunPtr (CInt -> CInt -> IO CInt) -> CInt -> CInt -> IO CInt
-
-foreign import ccall "getMallocObjectAddr"
- getMallocObjectAddr :: CUInt
+foreign import ccall "&mallocObject"
+ mallocObjectAddr :: FunPtr (Int -> IO CUInt)
type EntryPoint = Ptr Word8
type EntryPointOffset = Int
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))
+ invokeEpilog :: Word16 -> Word32 -> (Bool -> TrapCause) -> CodeGen e s (Maybe (Word32, TrapCause))
+ invokeEpilog cpidx offset trapcause = do
+ -- make actual (indirect) call
+ calladdr <- getCurrentOffset
+ call (Disp offset, eax)
+ -- discard arguments on stack (+4 for "this")
+ let argcnt = 4 + 4 * methodGetArgsCount cls cpidx
+ when (argcnt > 0) (add esp argcnt)
+ -- push result on stack if method has a return value
+ when (methodHaveReturnValue cls cpidx) (push eax)
+ let imm8 = is8BitOffset offset
+ return $ Just (calladdr + (if imm8 then 3 else 6), trapcause imm8)
+
+ 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
mov ebx (Disp 0, eax)
-- get method offset
offset <- liftIO $ getInterfaceMethodOffset ifacename methodname (encode msig)
- -- make actual (indirect) call
- calladdr <- getCurrentOffset
- call (Disp offset, ebx)
- -- discard arguments on stack (+4 for "this")
- let argcnt = 4 + 4 * methodGetArgsCount cls cpidx
- when (argcnt > 0) (add esp argcnt)
- -- push result on stack if method has a return value
- when (methodHaveReturnValue cls cpidx) (push eax)
- -- note, the "mi" has the wrong class reference here.
+ -- note, that "mi" has the wrong class reference here.
-- 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)
+ invokeEpilog cpidx offset (\x -> InterfaceMethod x mi)
emit' (INVOKEVIRTUAL cpidx) = do
-- get methodInfo entry
let mi@(MethodInfo methodname objname msig@(MethodSignature args _)) = buildMethodID cls cpidx
-- get method offset
let nameAndSig = methodname `B.append` encode msig
offset <- liftIO $ getMethodOffset objname nameAndSig
- -- make actual (indirect) call
- calladdr <- getCurrentOffset
- call (Disp offset, eax)
- -- discard arguments on stack (+4 for "this")
- let argcnt = 4 + 4 * methodGetArgsCount cls cpidx
- when (argcnt > 0) (add esp argcnt)
- -- push result on stack if method has a return value
- when (methodHaveReturnValue cls cpidx) (push eax)
- -- note, the "mi" has the wrong class reference here.
+ -- note, that "mi" has the wrong class reference here.
-- 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)
+ invokeEpilog cpidx offset (\x -> VirtualMethod x 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 ()
callMalloc :: CodeGen e s ()
callMalloc = do
- calladdr <- getCurrentOffset
- let w32_calladdr = 5 + calladdr
- let malloaddr = fromIntegral getMallocObjectAddr :: Word32
- call (malloaddr - w32_calladdr)
+ call mallocObjectAddr
add esp (4 :: Word32)
push eax