X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=Mate%2FStrings.hs;h=f41f02265c91d31b4d4bb48e40001126248936ed;hb=13cf9f65321881050edb99776f29eea8580ec457;hp=74a0e1765ac13302428da694bc44970b18b7d58c;hpb=b3427c38e5e0b38e44df820e03cabf91613be1ce;p=mate.git diff --git a/Mate/Strings.hs b/Mate/Strings.hs index 74a0e17..f41f022 100644 --- a/Mate/Strings.hs +++ b/Mate/Strings.hs @@ -13,35 +13,73 @@ import qualified Data.ByteString.Internal as BI import Text.Printf #endif -import Foreign.Ptr -import Foreign.Marshal.Utils -import Foreign.Marshal.Array +import JVM.ClassFile + +import Foreign +import Foreign.C.Types import Mate.Types +import Mate.ClassPool import Mate.Debug import Mate.GarbageAlloc getUniqueStringAddr :: B.ByteString -> IO Word32 getUniqueStringAddr str = do - smap <- get_stringsmap >>= ptr2stringsmap + smap <- getStringMap case M.lookup str smap of Nothing -> do addr <- allocateJavaString str - let smap' = M.insert str addr smap - stringsmap2ptr smap' >>= set_stringsmap + setStringMap $ M.insert str addr smap return addr Just addr -> return addr allocateJavaString :: B.ByteString -> IO Word32 allocateJavaString str = do - -- TODO(bernhard): is this also true for UTF8 stuff? + {- we have to build a java object layout here, where String object looks like + - + - this -+ + - | + - v + - +-------------+-------+-------+----------------+--------+ + - | MethodTable | value | count | cachedhashcode | offset | + - +-------------+-------+-------+----------------+--------+ + - | | + - | +------------+ + - v v + - java/lang/String +--------+--------+--------+-----+------------------+ + - | length | str[0] | str[1] | ... | str [length - 1] | + - +--------+--------+--------+-----+------------------+ + - all cells are 32bit wide, except str[i] of course (they're 8bit [but + - should be 16bit, TODO]). + -} + -- build object layout + fsize <- getObjectSize "java/lang/String" + printfStr "string: fsize: %d (should be 4 * 5)\n" fsize + tblptr <- mallocObject $ fromIntegral fsize + let ptr = intPtrToPtr (fromIntegral tblptr) :: Ptr CPtrdiff + mtbl <- getMethodTable "java/lang/String" + poke ptr $ fromIntegral mtbl + + -- build array layout let strlen = fromIntegral $ B.length str + -- (+1) for \0, (+4) for length + newstr <- mallocString (strlen + 5) + BI.memset newstr 0 (fromIntegral $ strlen + 5) arr <- newArray ((map fromIntegral $ B.unpack str) :: [Word8]) - -- (+1) for \0 - newstr <- mallocString (strlen + 1) - BI.memset newstr 0 (fromIntegral $ strlen + 1) - copyBytes newstr arr strlen - let w32_ptr = fromIntegral $ ptrToIntPtr newstr - printfStr "new str ptr: 0x%08x (%s)@%d\n" w32_ptr (toString str) strlen - return w32_ptr + copyBytes (plusPtr newstr 4) arr strlen + printfStr "new str ptr: (%s)@%d\n" (toString str) strlen + + let newstr_length = castPtr newstr :: Ptr CPtrdiff + poke newstr_length $ fromIntegral strlen + + -- set value pointer + poke (plusPtr ptr 4) (fromIntegral (ptrToIntPtr newstr) :: CPtrdiff) + -- set count field + poke (plusPtr ptr 8) (fromIntegral strlen :: CPtrdiff) + -- set hash code (TODO) + poke (plusPtr ptr 12) (0 :: CPtrdiff) + -- set offset + poke (plusPtr ptr 16) (0 :: CPtrdiff) + + return $ fromIntegral tblptr