pass tests in elem.wat test suit
This commit is contained in:
@@ -216,7 +216,16 @@ data FunctionInstance =
|
|||||||
hostCode :: HostFunction
|
hostCode :: HostFunction
|
||||||
}
|
}
|
||||||
|
|
||||||
data ElemInstance = ElemInstance ElemType (Vector Value) (IORef Bool)
|
data ElemInstance = ElemInstance {
|
||||||
|
eiMode :: ElemMode,
|
||||||
|
eiType :: ElemType,
|
||||||
|
eiItems :: Vector Value,
|
||||||
|
isDropped :: IORef Bool
|
||||||
|
}
|
||||||
|
|
||||||
|
isDeclarative :: ElemMode -> Bool
|
||||||
|
isDeclarative Declarative = True
|
||||||
|
isDeclarative _ = False
|
||||||
|
|
||||||
data DataInstance = DataInstance
|
data DataInstance = DataInstance
|
||||||
|
|
||||||
@@ -499,8 +508,8 @@ allocElems :: ModuleInstance -> Store -> [ElemSegment] -> IO (Vector ElemInstanc
|
|||||||
allocElems inst st = fmap Vector.fromList . mapM allocElem
|
allocElems inst st = fmap Vector.fromList . mapM allocElem
|
||||||
where
|
where
|
||||||
allocElem :: ElemSegment -> IO ElemInstance
|
allocElem :: ElemSegment -> IO ElemInstance
|
||||||
allocElem (ElemSegment t _mode refs) =
|
allocElem (ElemSegment t mode refs) =
|
||||||
ElemInstance t
|
ElemInstance mode t
|
||||||
<$> (Vector.fromList <$> mapM (evalConstExpr inst st) refs)
|
<$> (Vector.fromList <$> mapM (evalConstExpr inst st) refs)
|
||||||
<*> newIORef False -- is dropped
|
<*> newIORef False -- is dropped
|
||||||
|
|
||||||
@@ -551,7 +560,7 @@ initialize inst Module {elems, datas, start} = do
|
|||||||
initElem (tableIdx, elemIdx, from, funcs) = do
|
initElem (tableIdx, elemIdx, from, funcs) = do
|
||||||
Store {tableInstances, elemInstances} <- State.get
|
Store {tableInstances, elemInstances} <- State.get
|
||||||
let elems = items $ tableInstances ! tableIdx
|
let elems = items $ tableInstances ! tableIdx
|
||||||
let ElemInstance _ _ isDropped = elemInstances ! elemIdx
|
let ElemInstance {isDropped} = elemInstances ! elemIdx
|
||||||
liftIO $ writeIORef isDropped True
|
liftIO $ writeIORef isDropped True
|
||||||
Monad.forM_ (zip [from..] funcs) $ uncurry $ MVector.unsafeWrite elems
|
Monad.forM_ (zip [from..] funcs) $ uncurry $ MVector.unsafeWrite elems
|
||||||
|
|
||||||
@@ -893,12 +902,19 @@ eval budget store FunctionInstance { funcType, moduleInstance, code = Function {
|
|||||||
let tableAddr = tableaddrs moduleInstance ! fromIntegral tableIdx
|
let tableAddr = tableaddrs moduleInstance ! fromIntegral tableIdx
|
||||||
let TableInstance { items } = tableInstances store ! tableAddr
|
let TableInstance { items } = tableInstances store ! tableAddr
|
||||||
let elemAddr = elemaddrs moduleInstance ! fromIntegral elemIdx
|
let elemAddr = elemaddrs moduleInstance ! fromIntegral elemIdx
|
||||||
let ElemInstance _ refs dropFlag = elemInstances store ! elemAddr
|
let ElemInstance {
|
||||||
|
eiItems = refs,
|
||||||
|
eiMode = mode,
|
||||||
|
isDropped = dropFlag
|
||||||
|
} = elemInstances store ! elemAddr
|
||||||
let src = fromIntegral s
|
let src = fromIntegral s
|
||||||
let dst = fromIntegral d
|
let dst = fromIntegral d
|
||||||
let len = fromIntegral n
|
let len = fromIntegral n
|
||||||
isDropped <- readIORef dropFlag
|
isDropped <- readIORef dropFlag
|
||||||
if src + len > Vector.length refs || dst + len > MVector.length items || isDropped
|
if src + len > Vector.length refs
|
||||||
|
|| dst + len > MVector.length items
|
||||||
|
|| isDropped
|
||||||
|
|| isDeclarative mode
|
||||||
then return Trap
|
then return Trap
|
||||||
else do
|
else do
|
||||||
Vector.iforM_ (Vector.slice src len refs) $ \idx (RF fn) ->
|
Vector.iforM_ (Vector.slice src len refs) $ \idx (RF fn) ->
|
||||||
|
|||||||
@@ -173,6 +173,7 @@ runScript onAssertFail script = do
|
|||||||
|
|
||||||
getFailureString :: Validate.ValidationError -> [TL.Text]
|
getFailureString :: Validate.ValidationError -> [TL.Text]
|
||||||
getFailureString (Validate.TypeMismatch _ _) = ["type mismatch"]
|
getFailureString (Validate.TypeMismatch _ _) = ["type mismatch"]
|
||||||
|
getFailureString (Validate.RefTypeMismatch _ _) = ["type mismatch"]
|
||||||
getFailureString Validate.ResultTypeDoesntMatch = ["type mismatch"]
|
getFailureString Validate.ResultTypeDoesntMatch = ["type mismatch"]
|
||||||
getFailureString Validate.MoreThanOneMemory = ["multiple memories"]
|
getFailureString Validate.MoreThanOneMemory = ["multiple memories"]
|
||||||
getFailureString Validate.MoreThanOneTable = ["multiple tables"]
|
getFailureString Validate.MoreThanOneTable = ["multiple tables"]
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import Language.Wasm.Structure
|
|||||||
import qualified Data.Set as Set
|
import qualified Data.Set as Set
|
||||||
import Data.List (foldl')
|
import Data.List (foldl')
|
||||||
import qualified Data.Text.Lazy as TL
|
import qualified Data.Text.Lazy as TL
|
||||||
import Data.Maybe (fromMaybe, maybeToList, catMaybes)
|
import Data.Maybe (fromMaybe, catMaybes)
|
||||||
import Numeric.Natural (Natural)
|
import Numeric.Natural (Natural)
|
||||||
import Prelude hiding ((<>))
|
import Prelude hiding ((<>))
|
||||||
|
|
||||||
@@ -269,7 +269,7 @@ getInstrType RefIsNull = do
|
|||||||
getInstrType (RefFunc funIdx) = do
|
getInstrType (RefFunc funIdx) = do
|
||||||
Ctx { funcs } <- ask
|
Ctx { funcs } <- ask
|
||||||
if fromIntegral funIdx < length funcs
|
if fromIntegral funIdx < length funcs
|
||||||
then return $ empty ==> Val I32
|
then return $ empty ==> Val Func
|
||||||
else throwError FunctionIndexOutOfRange
|
else throwError FunctionIndexOutOfRange
|
||||||
getInstrType (GetLocal local) = do
|
getInstrType (GetLocal local) = do
|
||||||
Ctx { locals } <- ask
|
Ctx { locals } <- ask
|
||||||
@@ -583,8 +583,10 @@ elemsShouldBeValid m@Module { elems, functions, tables, imports } =
|
|||||||
isElemValid :: Ctx -> ElemSegment -> ValidationResult
|
isElemValid :: Ctx -> ElemSegment -> ValidationResult
|
||||||
isElemValid ctx (ElemSegment elemType mode elements) = do
|
isElemValid ctx (ElemSegment elemType mode elements) = do
|
||||||
forM_ elements $ \elem -> runChecker ctx $ do
|
forM_ elements $ \elem -> runChecker ctx $ do
|
||||||
getExpressionType elem
|
arr <- getExpressionType elem
|
||||||
isConstExpression elem
|
isConstExpression elem
|
||||||
|
unless (isValidRef elemType arr)
|
||||||
|
$ throwError $ RefTypeMismatch elemType elemType
|
||||||
case mode of
|
case mode of
|
||||||
Active tableIdx offset -> runChecker ctx $ do
|
Active tableIdx offset -> runChecker ctx $ do
|
||||||
isConstExpression offset
|
isConstExpression offset
|
||||||
@@ -595,6 +597,11 @@ elemsShouldBeValid m@Module { elems, functions, tables, imports } =
|
|||||||
when (tableIdx >= fromIntegral (length tableImports + length tables)) $ do
|
when (tableIdx >= fromIntegral (length tableImports + length tables)) $ do
|
||||||
throwError $ TableIndexOutOfRange tableIdx
|
throwError $ TableIndexOutOfRange tableIdx
|
||||||
_ -> return ()
|
_ -> return ()
|
||||||
|
|
||||||
|
isValidRef :: ElemType -> Arrow -> Bool
|
||||||
|
isValidRef FuncRef arr | arr == (empty ==> Func) = True
|
||||||
|
isValidRef ExternRef arr | arr == (empty ==> Extern) = True
|
||||||
|
isValidRef _ _ = False
|
||||||
|
|
||||||
datasShouldBeValid :: Validator
|
datasShouldBeValid :: Validator
|
||||||
datasShouldBeValid m@Module { datas, mems, imports } =
|
datasShouldBeValid m@Module { datas, mems, imports } =
|
||||||
|
|||||||
Reference in New Issue
Block a user