fix parsing of functions with incorrect type indexes

This commit is contained in:
Ilya Rezvov
2018-04-13 16:56:25 -07:00
parent 16bbc3d198
commit 23ed83a42e
4 changed files with 24 additions and 17 deletions
+4 -6
View File
@@ -1528,12 +1528,9 @@ desugarize fields =
getTypeIndex defs (IndexedTypeUse (Named ident) Nothing) = getTypeIndex defs (IndexedTypeUse (Named ident) Nothing) =
fromIntegral <$> findIndex (\(TypeDef i _) -> i == Just ident) defs fromIntegral <$> findIndex (\(TypeDef i _) -> i == Just ident) defs
getTypeIndex defs (IndexedTypeUse (Index n) (Just funcType)) = do getTypeIndex defs (IndexedTypeUse (Index n) (Just funcType)) = do
guard $ length defs > fromIntegral n
guard $ matchTypeFunc funcType $ defs !! fromIntegral n guard $ matchTypeFunc funcType $ defs !! fromIntegral n
return n return n
getTypeIndex defs (IndexedTypeUse (Index n) Nothing) = do getTypeIndex defs (IndexedTypeUse (Index n) Nothing) = return n
guard $ length defs > fromIntegral n
return n
-- imports -- imports
synImportToStruct :: [TypeDef] -> Import -> S.Import synImportToStruct :: [TypeDef] -> Import -> S.Import
@@ -1649,8 +1646,9 @@ desugarize fields =
IndexedTypeUse _ (Just FuncType { params }) -> params IndexedTypeUse _ (Just FuncType { params }) -> params
AnonimousTypeUse FuncType { params } -> params AnonimousTypeUse FuncType { params } -> params
_ -> _ ->
let TypeDef _ FuncType { params } = types mod !! fromIntegral typeIdx in if fromIntegral typeIdx < length (types mod)
params then let TypeDef _ FuncType { params } = types mod !! fromIntegral typeIdx in params
else []
in in
let ctx = FunCtx mod [] locals params in let ctx = FunCtx mod [] locals params in
S.Function { S.Function {
+2
View File
@@ -162,11 +162,13 @@ runScript onAssertFail script = do
getFailureString Validate.FunctionIndexOutOfRange = "unknown function" getFailureString Validate.FunctionIndexOutOfRange = "unknown function"
getFailureString Validate.GlobalIndexOutOfRange = "unknown global" getFailureString Validate.GlobalIndexOutOfRange = "unknown global"
getFailureString Validate.LabelIndexOutOfRange = "unknown label" getFailureString Validate.LabelIndexOutOfRange = "unknown label"
getFailureString Validate.TypeIndexOutOfRange = "unknown type"
getFailureString Validate.MinMoreThanMaxInMemoryLimit = "size minimum must not be greater than maximum" getFailureString Validate.MinMoreThanMaxInMemoryLimit = "size minimum must not be greater than maximum"
getFailureString Validate.MemoryLimitExceeded = "memory size must be at most 65536 pages (4GiB)" getFailureString Validate.MemoryLimitExceeded = "memory size must be at most 65536 pages (4GiB)"
getFailureString Validate.AlignmentOverflow = "alignment must not be larger than natural" getFailureString Validate.AlignmentOverflow = "alignment must not be larger than natural"
getFailureString (Validate.DuplicatedExportNames _) = "duplicate export name" getFailureString (Validate.DuplicatedExportNames _) = "duplicate export name"
getFailureString Validate.InvalidConstantExpr = "constant expression required" getFailureString Validate.InvalidConstantExpr = "constant expression required"
getFailureString Validate.InvalidResultArity = "invalid result arity"
-- getFailureString Validate.ImportedGlobalIsNotConst = "global is immutable" -- getFailureString Validate.ImportedGlobalIsNotConst = "global is immutable"
getFailureString _ = "not implemented" getFailureString _ = "not implemented"
+17 -10
View File
@@ -39,6 +39,7 @@ data ValidationResult =
| TypeIndexOutOfRange | TypeIndexOutOfRange
| ResultTypeDoesntMatch | ResultTypeDoesntMatch
| TypeMismatch { actual :: Arrow, expected :: Arrow } | TypeMismatch { actual :: Arrow, expected :: Arrow }
| InvalidResultArity
| InvalidConstantExpr | InvalidConstantExpr
| InvalidStartFunctionType | InvalidStartFunctionType
| ImportedGlobalIsNotConst | ImportedGlobalIsNotConst
@@ -402,7 +403,7 @@ unify (from `Arrow` to) (from' `Arrow` to') =
getExpressionType :: [Instruction] -> Checker Arrow getExpressionType :: [Instruction] -> Checker Arrow
getExpressionType instrs = getExpressionType instrs =
case reverse instrs of case reverse instrs of
[] -> return $ Any ==> Any [] -> return $ empty ==> empty
(i:rest) -> do (i:rest) -> do
arr <- getInstrType i arr <- getInstrType i
go arr rest go arr rest
@@ -466,15 +467,21 @@ ctxFromModule locals labels returns m@Module {types, tables, mems, globals, impo
isFunctionValid :: Function -> Validator isFunctionValid :: Function -> Validator
isFunctionValid Function {funcType, localTypes = locals, body} mod@Module {types} = isFunctionValid Function {funcType, localTypes = locals, body} mod@Module {types} =
let FuncType params results = types !! fromIntegral funcType in if fromIntegral funcType < length types
let r = safeHead results in then
let ctx = ctxFromModule (params ++ locals) [r] r mod in let FuncType params results = types !! fromIntegral funcType in
case runChecker ctx $ getExpressionType body of if length results > 1
Left err -> err then InvalidResultArity
Right arr -> else
if isArrowMatch arr (empty ==> results) let r = safeHead results in
then Valid let ctx = ctxFromModule (params ++ locals) [r] r mod in
else TypeMismatch arr (empty ==> results) case runChecker ctx $ getExpressionType body of
Left err -> err
Right arr ->
if isArrowMatch arr (empty ==> results)
then Valid
else TypeMismatch arr (empty ==> results)
else TypeIndexOutOfRange
functionsShouldBeValid :: Validator functionsShouldBeValid :: Validator
functionsShouldBeValid mod@Module {functions} = functionsShouldBeValid mod@Module {functions} =
+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 = ["func.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