fix implicit type extraction

This commit is contained in:
Ilya Rezvov
2018-04-08 10:25:05 -07:00
parent 43feccbf08
commit d7641bcee2
3 changed files with 23 additions and 16 deletions
+8 -2
View File
@@ -1421,7 +1421,7 @@ data FunCtx = FunCtx {
desugarize :: [ModuleField] -> S.Module desugarize :: [ModuleField] -> S.Module
desugarize fields = desugarize fields =
let mod = Module { let mod = Module {
types = extract extractTypeDef fields, types = reverse $ foldl' extractTypeDef (explicitTypeDefs fields) fields,
functions = extract extractFunction fields, functions = extract extractFunction fields,
tables = extract extractTable fields, tables = extract extractTable fields,
imports = extract extractImport fields, imports = extract extractImport fields,
@@ -1457,8 +1457,14 @@ desugarize fields =
synTypeDefToStruct (TypeDef _ FuncType { params, results }) = synTypeDefToStruct (TypeDef _ FuncType { params, results }) =
S.FuncType (map paramType params) results S.FuncType (map paramType params) results
explicitTypeDefs :: [ModuleField] -> [TypeDef]
explicitTypeDefs = map (\(MFType def) -> def) . filter isTypeDef
where
isTypeDef (MFType _) = True
isTypeDef _ = False
extractTypeDef :: [TypeDef] -> ModuleField -> [TypeDef] extractTypeDef :: [TypeDef] -> ModuleField -> [TypeDef]
extractTypeDef defs (MFType def) = def : defs extractTypeDef defs (MFType _) = defs -- should be extracted before implicit defs
extractTypeDef defs (MFImport Import { desc = ImportFunc _ typeUse }) = extractTypeDef defs (MFImport Import { desc = ImportFunc _ typeUse }) =
matchTypeUse defs typeUse matchTypeUse defs typeUse
extractTypeDef defs (MFFunc Function { funcType, body }) = extractTypeDef defs (MFFunc Function { funcType, body }) =
+14 -14
View File
@@ -32,7 +32,7 @@ data ValidationResult =
| ResultTypeDoesntMatch | ResultTypeDoesntMatch
| NoTableInModule | NoTableInModule
| NoMemoryInModule | NoMemoryInModule
| TypeMismatch | TypeMismatch { actual :: Arrow, expected :: Arrow }
| InvalidConstantExpr | InvalidConstantExpr
| InvalidStartFunctionType | InvalidStartFunctionType
| ImportedGlobalIsNotConst | ImportedGlobalIsNotConst
@@ -169,20 +169,20 @@ getInstrType Block { result, body } = do
t <- withLabel result $ getExpressionType body t <- withLabel result $ getExpressionType body
if isArrowMatch t blockType if isArrowMatch t blockType
then return $ empty ==> result then return $ empty ==> result
else throwError TypeMismatch else throwError $ TypeMismatch t blockType
getInstrType Loop { result, body } = do getInstrType Loop { result, body } = do
let blockType = empty ==> result let blockType = empty ==> result
t <- withLabel result $ getExpressionType body t <- withLabel result $ getExpressionType body
if isArrowMatch t blockType if isArrowMatch t blockType
then return $ empty ==> result then return $ empty ==> result
else throwError TypeMismatch else throwError $ TypeMismatch t blockType
getInstrType If { result, true, false } = do getInstrType If { result, true, false } = do
let blockType = empty ==> result let blockType = empty ==> result
l <- withLabel result $ getExpressionType true l <- withLabel result $ getExpressionType true
r <- withLabel result $ getExpressionType false r <- withLabel result $ getExpressionType false
if isArrowMatch l blockType && isArrowMatch r blockType if isArrowMatch l blockType
then return $ I32 ==> result then (if isArrowMatch r blockType then (return $ I32 ==> result) else (throwError $ TypeMismatch r blockType))
else throwError TypeMismatch else throwError $ TypeMismatch l blockType
getInstrType (Br lbl) = do getInstrType (Br lbl) = do
r <- map Val . maybeToList <$> getLabel lbl r <- map Val . maybeToList <$> getLabel lbl
return $ (Any : r) ==> Any return $ (Any : r) ==> Any
@@ -373,7 +373,7 @@ unify (from `Arrow` to) (from' `Arrow` to') =
unify' (f `Arrow` (Val v':t)) ((Val v:f') `Arrow` t') = unify' (f `Arrow` (Val v':t)) ((Val v:f') `Arrow` t') =
if v == v' if v == v'
then unify' (f `Arrow` t) (f' `Arrow` t') then unify' (f `Arrow` t) (f' `Arrow` t')
else throwError TypeMismatch else throwError $ TypeMismatch (from `Arrow` to) (from' `Arrow` to')
unify' (f `Arrow` (Var r:t)) ((Val v:f') `Arrow` t') = unify' (f `Arrow` (Var r:t)) ((Val v:f') `Arrow` t') =
let subst = replace (Var r) (Val v) in let subst = replace (Var r) (Val v) in
unify' (subst f `Arrow` subst t) (f' `Arrow` t') unify' (subst f `Arrow` subst t) (f' `Arrow` t')
@@ -463,7 +463,7 @@ isFunctionValid Function {funcType, localTypes = locals, body} mod@Module {types
Right arr -> Right arr ->
if isArrowMatch arr (empty ==> results) if isArrowMatch arr (empty ==> results)
then Valid then Valid
else TypeMismatch else TypeMismatch arr (empty ==> results)
functionsShouldBeValid :: Validator functionsShouldBeValid :: Validator
functionsShouldBeValid mod@Module {functions} = functionsShouldBeValid mod@Module {functions} =
@@ -510,11 +510,11 @@ 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 $ isArrowMatch (empty ==> getGlobalType gt) t return $ if isArrowMatch (empty ==> I32) t then Valid else TypeMismatch (empty ==> I32) t
in in
case check of case check of
Left err -> err Left err -> err
Right eq -> if eq then Valid else TypeMismatch Right res -> res
elemsShouldBeValid :: Validator elemsShouldBeValid :: Validator
elemsShouldBeValid m@Module { elems, functions, tables, imports } = elemsShouldBeValid m@Module { elems, functions, tables, imports } =
@@ -526,11 +526,11 @@ 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 $ isArrowMatch (empty ==> I32) t return $ if isArrowMatch (empty ==> I32) t then Valid else TypeMismatch (empty ==> I32) t
in in
let isIniterValid = case check of let isIniterValid = case check of
Left err -> err Left err -> err
Right eq -> if eq then Valid else TypeMismatch Right res -> res
in in
let tableImports = filter isTableImport imports in let tableImports = filter isTableImport imports in
let isTableIndexValid = let isTableIndexValid =
@@ -552,11 +552,11 @@ 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 $ isArrowMatch (empty ==> I32) t return $ if isArrowMatch (empty ==> I32) t then Valid else TypeMismatch (empty ==> I32) t
in in
let isOffsetValid = case check of let isOffsetValid = case check of
Left err -> err Left err -> err
Right eq -> if eq then Valid else TypeMismatch Right res -> res
in in
let memImports = filter isMemImport imports in let memImports = filter isMemImport imports in
if memIdx < (fromIntegral $ length memImports + length mems) if memIdx < (fromIntegral $ length memImports + length mems)
+1
View File
@@ -34,6 +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 = ["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