forked from GitHub/haskell-wasm
implement table.fill
This commit is contained in:
@@ -952,6 +952,23 @@ eval budget store FunctionInstance { funcType, moduleInstance, code = Function {
|
||||
el <- MVector.unsafeRead fromEls (src + off)
|
||||
MVector.unsafeWrite toEls (dst + off) el
|
||||
return $ Done ctx { stack = rest }
|
||||
step ctx@EvalCtx{ stack = (VI32 n:ref:VI32 i:rest) } (TableFill tableIdx) = do
|
||||
let tableAddr = tableaddrs moduleInstance ! fromIntegral tableIdx
|
||||
let TableInstance { items, t } = tableInstances store ! tableAddr
|
||||
let TableType (Limit _ max) _ = t
|
||||
let inc = fromIntegral n
|
||||
let from = fromIntegral i
|
||||
let val = case ref of
|
||||
RE extRef -> fromIntegral <$> extRef
|
||||
RF fnRef -> (funcaddrs moduleInstance !) . fromIntegral <$> fnRef
|
||||
v -> error "Impossible due to validation"
|
||||
els <- readIORef items
|
||||
if from + inc > MVector.length els
|
||||
then return Trap
|
||||
else do
|
||||
Monad.forM_ [0..inc - 1] $ \off ->
|
||||
MVector.unsafeWrite els (from + off) val
|
||||
return $ Done ctx { stack = rest }
|
||||
step ctx@EvalCtx{ stack } (TableSize tableIdx) = do
|
||||
let tableAddr = tableaddrs moduleInstance ! fromIntegral tableIdx
|
||||
let TableInstance { items } = tableInstances store ! tableAddr
|
||||
|
||||
@@ -482,6 +482,7 @@ plaininstr :: { PlainInstr }
|
||||
| 'table.get' opt(index) { TableGet (fromMaybe (Index 0) $2) }
|
||||
| 'table.set' opt(index) { TableSet (fromMaybe (Index 0) $2) }
|
||||
| 'table.copy' opt(index) opt(index) { TableCopy (fromMaybe (Index 0) $2) (fromMaybe (Index 0) $3) }
|
||||
| 'table.fill' opt(index) { TableFill (fromMaybe (Index 0) $2) }
|
||||
| 'table.size' opt(index) { TableSize (fromMaybe (Index 0) $2) }
|
||||
| 'table.grow' opt(index) { TableGrow (fromMaybe (Index 0) $2) }
|
||||
| 'elem.drop' index { ElemDrop $2 }
|
||||
@@ -1736,6 +1737,10 @@ desugarize fields = do
|
||||
case getTableIndex ctxMod tableIdx of
|
||||
Just tableIdx -> return $ S.TableSize tableIdx
|
||||
Nothing -> Left "unknown table"
|
||||
synInstrToStruct FunCtx { ctxMod } (PlainInstr (TableFill tableIdx)) =
|
||||
case getTableIndex ctxMod tableIdx of
|
||||
Just tableIdx -> return $ S.TableFill tableIdx
|
||||
Nothing -> Left "unknown table"
|
||||
synInstrToStruct FunCtx { ctxMod } (PlainInstr (TableGrow tableIdx)) =
|
||||
case getTableIndex ctxMod tableIdx of
|
||||
Just tableIdx -> return $ S.TableGrow tableIdx
|
||||
|
||||
@@ -393,6 +393,11 @@ getInstrType (TableCopy toIdx fromIdx) = do
|
||||
let TableType _ toType = tables !! to
|
||||
when (fromType /= toType) $ throwError (RefTypeMismatch fromType toType)
|
||||
return $ [I32, I32, I32] ==> empty
|
||||
getInstrType (TableFill tableIdx) = do
|
||||
Ctx { tables } <- ask
|
||||
when (length tables <= fromIntegral tableIdx) $ throwError (TableIndexOutOfRange tableIdx)
|
||||
let TableType _ tableType = tables !! fromIntegral tableIdx
|
||||
return $ [I32, elemTypeToRefType tableType, I32] ==> empty
|
||||
getInstrType (TableSize tableIdx) = do
|
||||
Ctx { tables } <- ask
|
||||
when (length tables <= fromIntegral tableIdx) $ throwError (TableIndexOutOfRange tableIdx)
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ main = do
|
||||
files <-
|
||||
filter (not . List.isPrefixOf "simd") . filter (List.isSuffixOf ".wast")
|
||||
<$> Directory.listDirectory "tests/spec"
|
||||
-- let files = ["ref_func.wast"]
|
||||
-- let files = ["table_fill.wast"]
|
||||
scriptTestCases <- (`mapM` files) $ \file -> do
|
||||
test <- LBS.readFile ("tests/spec/" ++ file)
|
||||
return $ testCase file $ do
|
||||
|
||||
Reference in New Issue
Block a user