fix implicit type extraction
This commit is contained in:
@@ -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 }) =
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user