pass tests in elem.wat test suit

This commit is contained in:
Ilya Rezvov
2022-06-02 20:54:15 -06:00
parent e9140ae70c
commit 0b44ee13b8
3 changed files with 33 additions and 9 deletions
+22 -6
View File
@@ -220,7 +220,16 @@ data FunctionInstance =
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
@@ -503,8 +512,8 @@ allocElems :: ModuleInstance -> Store -> [ElemSegment] -> IO (Vector ElemInstanc
allocElems inst st = fmap Vector.fromList . mapM allocElem
where
allocElem :: ElemSegment -> IO ElemInstance
allocElem (ElemSegment t _mode refs) =
ElemInstance t
allocElem (ElemSegment t mode refs) =
ElemInstance mode t
<$> (Vector.fromList <$> mapM (evalConstExpr inst st) refs)
<*> newIORef False -- is dropped
@@ -555,7 +564,7 @@ initialize inst Module {elems, datas, start} = do
initElem (tableIdx, elemIdx, from, funcs) = do
Store {tableInstances, elemInstances} <- State.get
let elems = items $ tableInstances ! tableIdx
let ElemInstance _ _ isDropped = elemInstances ! elemIdx
let ElemInstance {isDropped} = elemInstances ! elemIdx
liftIO $ writeIORef isDropped True
Monad.forM_ (zip [from..] funcs) $ uncurry $ MVector.unsafeWrite elems
@@ -897,12 +906,19 @@ eval budget store FunctionInstance { funcType, moduleInstance, code = Function {
let tableAddr = tableaddrs moduleInstance ! fromIntegral tableIdx
let TableInstance { items } = tableInstances store ! tableAddr
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 dst = fromIntegral d
let len = fromIntegral n
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
else do
Vector.iforM_ (Vector.slice src len refs) $ \idx (RF fn) ->
+1
View File
@@ -173,6 +173,7 @@ runScript onAssertFail script = do
getFailureString :: Validate.ValidationError -> [TL.Text]
getFailureString (Validate.TypeMismatch _ _) = ["type mismatch"]
getFailureString (Validate.RefTypeMismatch _ _) = ["type mismatch"]
getFailureString Validate.ResultTypeDoesntMatch = ["type mismatch"]
getFailureString Validate.MoreThanOneMemory = ["multiple memories"]
getFailureString Validate.MoreThanOneTable = ["multiple tables"]
+10 -3
View File
@@ -15,7 +15,7 @@ import Language.Wasm.Structure
import qualified Data.Set as Set
import Data.List (foldl')
import qualified Data.Text.Lazy as TL
import Data.Maybe (fromMaybe, maybeToList, catMaybes)
import Data.Maybe (fromMaybe, catMaybes)
import Numeric.Natural (Natural)
import Prelude hiding ((<>))
@@ -269,7 +269,7 @@ getInstrType RefIsNull = do
getInstrType (RefFunc funIdx) = do
Ctx { funcs } <- ask
if fromIntegral funIdx < length funcs
then return $ empty ==> Val I32
then return $ empty ==> Val Func
else throwError FunctionIndexOutOfRange
getInstrType (GetLocal local) = do
Ctx { locals } <- ask
@@ -583,8 +583,10 @@ elemsShouldBeValid m@Module { elems, functions, tables, imports } =
isElemValid :: Ctx -> ElemSegment -> ValidationResult
isElemValid ctx (ElemSegment elemType mode elements) = do
forM_ elements $ \elem -> runChecker ctx $ do
getExpressionType elem
arr <- getExpressionType elem
isConstExpression elem
unless (isValidRef elemType arr)
$ throwError $ RefTypeMismatch elemType elemType
case mode of
Active tableIdx offset -> runChecker ctx $ do
isConstExpression offset
@@ -595,6 +597,11 @@ elemsShouldBeValid m@Module { elems, functions, tables, imports } =
when (tableIdx >= fromIntegral (length tableImports + length tables)) $ do
throwError $ TableIndexOutOfRange tableIdx
_ -> return ()
isValidRef :: ElemType -> Arrow -> Bool
isValidRef FuncRef arr | arr == (empty ==> Func) = True
isValidRef ExternRef arr | arr == (empty ==> Extern) = True
isValidRef _ _ = False
datasShouldBeValid :: Validator
datasShouldBeValid m@Module { datas, mems, imports } =