From 78653b911c0ef23753d569bd63af3c755be2a37d Mon Sep 17 00:00:00 2001 From: Ilya Rezvov Date: Sun, 18 Feb 2018 22:46:19 -0800 Subject: [PATCH] write import section --- src/Language/Wasm/Binary.hs | 80 +++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/src/Language/Wasm/Binary.hs b/src/Language/Wasm/Binary.hs index 1a4929f..7937f11 100644 --- a/src/Language/Wasm/Binary.hs +++ b/src/Language/Wasm/Binary.hs @@ -11,6 +11,9 @@ import Data.Bits import Data.Word (Word8) import Data.Serialize import qualified Data.ByteString as BS +import qualified Data.ByteString.Lazy as LBS +import qualified Data.Text.Lazy as TL +import qualified Data.Text.Lazy.Encoding as TLEncoding putULEB128 :: Natural -> Put putULEB128 val = @@ -54,6 +57,18 @@ putSection section content = do putULEB128 $ fromIntegral $ BS.length payload putByteString payload +putName :: TL.Text -> Put +putName txt = do + let bs = TLEncoding.encodeUtf8 txt + putULEB128 $ fromIntegral $ LBS.length bs + putLazyByteString bs + +getName :: Get TL.Text +getName = do + len <- getULEB128 + bytes <- getLazyByteString $ fromIntegral len + return $ TLEncoding.decodeUtf8 bytes + data SectionType = CustomSection | TypeSection @@ -103,6 +118,70 @@ instance Serialize FuncType where results <- getVec return $ FuncType { params, results } +instance Serialize ElemType where + put AnyFunc = putWord8 0x70 + get = byteGuard 0x70 >> return AnyFunc + +instance Serialize Limit where + put (Limit min Nothing) = putWord8 0x00 >> putULEB128 min + put (Limit min (Just max)) = putWord8 0x01 >> putULEB128 min >> putULEB128 max + get = do + op <- getWord8 + case op of + 0x00 -> do + min <- getULEB128 + return $ Limit min Nothing + 0x01 -> do + min <- getULEB128 + max <- getULEB128 + return $ Limit min (Just max) + _ -> fail "Unexpected byte in place of Limit opcode" + +instance Serialize TableType where + put (TableType limit elemType) = do + put elemType + put limit + get = do + elemType <- get + limit <- get + return $ TableType limit elemType + +instance Serialize GlobalType where + put (Const valType) = put valType >> putWord8 0x00 + put (Mut valType) = put valType >> putWord8 0x01 + get = do + valType <- get + op <- getWord8 + case op of + 0x00 -> return $ Const valType + 0x01 -> return $ Mut valType + _ -> fail "Unexpected byte in place of Global type opcode" + +instance Serialize ImportDesc where + put (ImportFunc typeIdx) = putWord8 0x00 >> putULEB128 typeIdx + put (ImportTable tableType) = putWord8 0x01 >> put tableType + put (ImportMemory memType) = putWord8 0x02 >> put memType + put (ImportGlobal globalType) = putWord8 0x03 >> put globalType + get = do + op <- getWord8 + case op of + 0x00 -> ImportFunc <$> getULEB128 + 0x01 -> ImportTable <$> get + 0x02 -> ImportMemory <$> get + 0x03 -> ImportGlobal <$> get + _ -> fail "Unexpected byte in place of Import Declaration opcode" + +instance Serialize Import where + put (Import sourceModule name desc) = do + putName sourceModule + putName name + put desc + get = do + sourceModule <- getName + name <- getName + desc <- get + return $ Import sourceModule name desc + instance Serialize Module where put mod = do -- magic @@ -117,4 +196,5 @@ instance Serialize Module where putWord8 0x00 putSection TypeSection $ types mod + putSection ImportSection $ imports mod get = undefined \ No newline at end of file