fix parsing binary modules from text representation

This commit is contained in:
Ilya Rezvov
2018-04-08 11:54:29 -07:00
parent 87758b2789
commit 98d9ca2399
4 changed files with 15 additions and 9 deletions
+8 -4
View File
@@ -23,11 +23,11 @@ import qualified Data.Text.Lazy.Encoding as TLEncoding
getULEB128 :: (Integral a, Bits a) => Get a getULEB128 :: (Integral a, Bits a) => Get a
getULEB128 = do getULEB128 = do
val <- getWord8 val <- getWord8
if val < 2 ^ 7 if not (testBit val 7)
then return $ fromIntegral val then return $ fromIntegral val
else do else do
rest <- getULEB128 rest <- getULEB128
return $ (fromIntegral $ 0x7F .&. val) + 128 * rest return $ (fromIntegral $ val .&. 0x7F) .|. (rest `shiftL` 7)
putULEB128 :: (Integral a, Bits a) => a -> Put putULEB128 :: (Integral a, Bits a) => a -> Put
putULEB128 val = putULEB128 val =
@@ -101,8 +101,12 @@ skipCustomSection = do
getSection :: SectionType -> Get a -> a -> Get a getSection :: SectionType -> Get a -> a -> Get a
getSection sectionType parser def = do getSection sectionType parser def = do
nextByte <- lookAhead getWord8 empty <- isEmpty
parseSection $ fromIntegral nextByte if empty
then return def
else do
nextByte <- lookAhead getWord8
parseSection $ fromIntegral nextByte
where where
parseSection op parseSection op
| op == 0 = skipCustomSection >> getSection sectionType parser def | op == 0 = skipCustomSection >> getSection sectionType parser def
+2 -1
View File
@@ -63,6 +63,7 @@ import qualified Data.Text.Lazy.Encoding as TLEncoding
import qualified Data.Text.Lazy.Read as TLRead import qualified Data.Text.Lazy.Read as TLRead
import qualified Data.ByteString.Lazy as LBS import qualified Data.ByteString.Lazy as LBS
import qualified Data.ByteString.Lazy.Char8 as LBSChar8
import Data.Maybe (fromMaybe, fromJust) import Data.Maybe (fromMaybe, fromJust)
import Data.List (foldl', findIndex, find) import Data.List (foldl', findIndex, find)
import Control.Monad (guard) import Control.Monad (guard)
@@ -1024,7 +1025,7 @@ command1 :: { Command }
| meta1 { Meta $1 } | meta1 { Meta $1 }
module1 :: { ModuleDef } module1 :: { ModuleDef }
: 'module' opt(ident) 'binary' list(string) ')' { BinaryModDef $2 (TLEncoding.encodeUtf8 $ TL.concat $4) } : 'module' opt(ident) 'binary' list(string) ')' { BinaryModDef $2 (LBSChar8.pack $ TL.unpack $ TL.concat $4) }
| 'module' opt(ident) 'quote' list(string) ')' { TextModDef $2 (TL.concat $4) } | 'module' opt(ident) 'quote' list(string) ')' { TextModDef $2 (TL.concat $4) }
| 'module' opt(ident) list(modulefield) ')' { RawModDef $2 (desugarize $ concat $3) } | 'module' opt(ident) list(modulefield) ')' { RawModDef $2 (desugarize $ concat $3) }
| modulefield1 list(modulefield) { RawModDef Nothing (desugarize $ $1 ++ concat $2) } | modulefield1 list(modulefield) { RawModDef Nothing (desugarize $ $1 ++ concat $2) }
+4 -3
View File
@@ -510,7 +510,8 @@ globalsShouldBeValid m@Module { imports, globals } =
let check = runChecker ctx $ do let check = runChecker ctx $ do
isConstExpression init isConstExpression init
t <- getExpressionType init t <- getExpressionType init
return $ if isArrowMatch (empty ==> I32) t then Valid else TypeMismatch (empty ==> I32) t let expected = empty ==> getGlobalType gt
return $ if isArrowMatch expected t then Valid else TypeMismatch t expected
in in
case check of case check of
Left err -> err Left err -> err
@@ -526,7 +527,7 @@ elemsShouldBeValid m@Module { elems, functions, tables, imports } =
let check = runChecker ctx $ do let check = runChecker ctx $ do
isConstExpression offset isConstExpression offset
t <- getExpressionType offset t <- getExpressionType offset
return $ if isArrowMatch (empty ==> I32) t then Valid else TypeMismatch (empty ==> I32) t return $ if isArrowMatch (empty ==> I32) t then Valid else TypeMismatch t (empty ==> I32)
in in
let isIniterValid = case check of let isIniterValid = case check of
Left err -> err Left err -> err
@@ -552,7 +553,7 @@ datasShouldBeValid m@Module { datas, mems, imports } =
let check = runChecker ctx $ do let check = runChecker ctx $ do
isConstExpression offset isConstExpression offset
t <- getExpressionType offset t <- getExpressionType offset
return $ if isArrowMatch (empty ==> I32) t then Valid else TypeMismatch (empty ==> I32) t return $ if isArrowMatch (empty ==> I32) t then Valid else TypeMismatch t (empty ==> I32)
in in
let isOffsetValid = case check of let isOffsetValid = case check of
Left err -> err Left err -> err
+1 -1
View File
@@ -34,7 +34,7 @@ compile file = do
main :: IO () main :: IO ()
main = do main = do
files <- Directory.listDirectory "tests/samples" files <- Directory.listDirectory "tests/samples"
-- let files = ["memory.wast"] -- let files = ["binary.wast"]
scriptTestCases <- (`mapM` files) $ \file -> do scriptTestCases <- (`mapM` files) $ \file -> do
content <- LBS.readFile $ "tests/samples/" ++ file content <- LBS.readFile $ "tests/samples/" ++ file
let Right script = Parser.parseScript <$> Lexer.scanner content let Right script = Parser.parseScript <$> Lexer.scanner content