start binary format support

This commit is contained in:
Ilya Rezvov
2018-02-18 19:03:21 -08:00
parent f6a2daefcc
commit 75bdf0637f
5 changed files with 132 additions and 2 deletions
+120
View File
@@ -0,0 +1,120 @@
{-# LANGUAGE NamedFieldPuns #-}
module Language.Wasm.Binary (
) where
import Language.Wasm.Structure
import Numeric.Natural (Natural)
import Data.Bits
import Data.Word (Word8)
import Data.Serialize
import qualified Data.ByteString as BS
putULEB128 :: Natural -> Put
putULEB128 val =
if val < 128
then putWord8 $ fromIntegral val
else do
putWord8 $ 0x80 + (0x7F .&. fromIntegral val)
putULEB128 $ val `shiftR` 7
getULEB128 :: Get Natural
getULEB128 = do
val <- getWord8
if val < 2 ^ 7
then return $ fromIntegral val
else do
rest <- getULEB128
return $ (fromIntegral $ 0x7F .&. val) + 128 * rest
putVec :: Serialize a => [a] -> Put
putVec list = do
putULEB128 $ fromIntegral $ length list
mapM put list
return ()
getVec :: Serialize a => Get [a]
getVec = do
len <- getULEB128
sequence $ replicate (fromIntegral len) get
byteGuard :: Word8 -> Get ()
byteGuard expected = do
byte <- getWord8
if byte == expected
then return ()
else fail $ "Expected " ++ show expected ++ ", but encountered " ++ show byte
putSection :: Serialize a => SectionType -> a -> Put
putSection section content = do
put section
let payload = encode content
putULEB128 $ fromIntegral $ BS.length payload
putByteString payload
data SectionType =
CustomSection
| TypeSection
| ImportSection
| FunctionSection
| TableSection
| MemorySection
| GlobalSection
| ExportSection
| StartSection
| ElementSection
| CodeSection
| DataSection
deriving (Eq, Show, Enum)
instance Serialize SectionType where
put section = putWord8 $ fromIntegral $ fromEnum section
get = do
op <- fromIntegral `fmap` getWord8
if op <= fromEnum DataSection
then return $ toEnum op
else fail "Unexpected byte in section type position"
instance Serialize ValueType where
put I32 = putWord8 0x7F
put I64 = putWord8 0x7E
put F32 = putWord8 0x7D
put F64 = putWord8 0x7C
get = do
op <- getWord8
case op of
0x7F -> return I32
0x7E -> return I64
0x7D -> return F32
0x7C -> return F64
_ -> fail "unexpected byte in value type position"
instance Serialize FuncType where
put FuncType {params, results} = do
putWord8 0x60
putVec params
putVec results
get = do
byteGuard 0x60
params <- getVec
results <- getVec
return $ FuncType { params, results }
instance Serialize Module where
put mod = do
-- magic
putWord8 0x00
putWord8 0x61
putWord8 0x73
putWord8 0x6D
-- version
putWord8 0x01
putWord8 0x00
putWord8 0x00
putWord8 0x00
putSection TypeSection $ types mod
get = undefined
+1 -1
View File
@@ -1172,7 +1172,7 @@ desugarize fields =
start = extractStart fields,
exports = []
} in
S.emptyModule {
S.Module {
S.types = map synTypeDefToStruct $ types mod,
S.functions = map (synFunctionToStruct mod) $ functions mod,
S.tables = map synTableToStruct $ tables mod,
-1
View File
@@ -1,4 +1,3 @@
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DuplicateRecordFields #-}
module Language.Wasm.Structure (
+8
View File
@@ -0,0 +1,8 @@
module Language.Wasm.Validate (
validate
) where
import Language.Wasm.Structure
validate :: Module -> Either String Module
validate mod = Right mod