diff --git a/lvtrun/app/WasmMod/Leb128.hs b/lvtrun/app/WasmMod/Leb128.hs index c16d011..099cf99 100644 --- a/lvtrun/app/WasmMod/Leb128.hs +++ b/lvtrun/app/WasmMod/Leb128.hs @@ -14,7 +14,7 @@ where import Data.Binary.Get import Data.Bits -import Data.Int (Int32, Int64) +import Data.Int (Int64) import qualified Data.ByteString.Lazy as BS (ByteString, drop) getLEB128 :: Get Int @@ -32,12 +32,11 @@ extractLEB128' :: Get (Int64, Int64) extractLEB128' = do byte <- getWord8 let value = fromIntegral (byte .&. 0x7F) - if byte `testBit` 7 - then do + case byte `testBit` 7 of + True -> do (next, size) <- extractLEB128' return (value .|. (next `shiftL` 7), size + 1) - else - return (value, 1) + False -> return (value, 1) --function that returns the value and the rest of the bytestring extractLEB128 :: BS.ByteString -> (Int64, BS.ByteString) diff --git a/lvtrun/app/WasmMod/Sections/Types.hs b/lvtrun/app/WasmMod/Sections/Types.hs index fa41c2a..7ffb49a 100644 --- a/lvtrun/app/WasmMod/Sections/Types.hs +++ b/lvtrun/app/WasmMod/Sections/Types.hs @@ -19,6 +19,9 @@ import Data.Int import Errors import Control.Exception import qualified Data.ByteString.Lazy as Bs +import Data.Word + +import Debug.Trace data Type = I32 | I64 | F32 | F64 deriving (Show, Eq) @@ -32,9 +35,47 @@ instance Show FuncType where show funcType = "(type " ++ (show $ typeId funcType) ++ " (func " ++ (show $ params funcType) ++ ") " ++ (show $ results funcType) ++ ")" +--60 0 0 +--60 1 7f 0 +--60 2 7f 7f 1 7f +-- 7f = i32 7e = i64 7d = f32 7c = f64 + +getVectorSize :: Bs.ByteString -> (Int64, Bs.ByteString) +getVectorSize content = extractLEB128 content + +getTypeFromByte :: Word8 -> Type +getTypeFromByte 0x7f = I32 +getTypeFromByte 0x7e = I64 +getTypeFromByte 0x7d = F32 +getTypeFromByte 0x7c = F64 +getTypeFromByte _ = throw $ WasmError "GetTypeFromByte: bad type" + +extractParams :: (Int64, Bs.ByteString) -> ([Type], Bs.ByteString) +extractParams (0, content) = ([], content) +extractParams (idx, content) = (getTypeFromByte (head $ Bs.unpack content) : params, rest) + where (params, rest) = extractParams (idx - 1, Bs.drop 1 content) + +extractResults :: (Int64, Bs.ByteString) -> ([Type], Bs.ByteString) +extractResults (0, content) = ([], content) +extractResults (idx, content) = (getTypeFromByte (head $ Bs.unpack content) : results, rest) + where (results, rest) = extractResults (idx - 1, Bs.drop 1 content) + +extractTypes :: (Int64, Bs.ByteString) -> ([Type], Bs.ByteString) +extractTypes (0, content) = ([], content) + +parseFuncType :: Bs.ByteString -> (FuncType, Bs.ByteString) +parseFuncType content = do + let (params, rest) = extractParams $ getVectorSize content + let (results, rest2) = extractResults $ getVectorSize rest + ((FuncType 0 params results), rest2) + parseFuncTypes :: Int64 -> Bs.ByteString -> [FuncType] parseFuncTypes 0 _ = [] -parseFuncTypes idx content = throw $ (WasmError "Not implemented") +parseFuncTypes idx content + | head (Bs.unpack content) == 0x60 = do + let (funcType, rest) = parseFuncType content + funcType : parseFuncTypes (idx - 1) rest + | otherwise = throw $ WasmError "ParseFuncTypes: 0x60 expected for function" parseTypes :: Section -> [FuncType] parseTypes (Section TypeID _ content) = do diff --git a/lvtrun/test/HexFile b/lvtrun/test/HexFile index 70f2ff6..ec8a115 100644 Binary files a/lvtrun/test/HexFile and b/lvtrun/test/HexFile differ