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)
|
el <- MVector.unsafeRead fromEls (src + off)
|
||||||
MVector.unsafeWrite toEls (dst + off) el
|
MVector.unsafeWrite toEls (dst + off) el
|
||||||
return $ Done ctx { stack = rest }
|
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
|
step ctx@EvalCtx{ stack } (TableSize tableIdx) = do
|
||||||
let tableAddr = tableaddrs moduleInstance ! fromIntegral tableIdx
|
let tableAddr = tableaddrs moduleInstance ! fromIntegral tableIdx
|
||||||
let TableInstance { items } = tableInstances store ! tableAddr
|
let TableInstance { items } = tableInstances store ! tableAddr
|
||||||
|
|||||||
@@ -482,6 +482,7 @@ plaininstr :: { PlainInstr }
|
|||||||
| 'table.get' opt(index) { TableGet (fromMaybe (Index 0) $2) }
|
| 'table.get' opt(index) { TableGet (fromMaybe (Index 0) $2) }
|
||||||
| 'table.set' opt(index) { TableSet (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.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.size' opt(index) { TableSize (fromMaybe (Index 0) $2) }
|
||||||
| 'table.grow' opt(index) { TableGrow (fromMaybe (Index 0) $2) }
|
| 'table.grow' opt(index) { TableGrow (fromMaybe (Index 0) $2) }
|
||||||
| 'elem.drop' index { ElemDrop $2 }
|
| 'elem.drop' index { ElemDrop $2 }
|
||||||
@@ -1736,6 +1737,10 @@ desugarize fields = do
|
|||||||
case getTableIndex ctxMod tableIdx of
|
case getTableIndex ctxMod tableIdx of
|
||||||
Just tableIdx -> return $ S.TableSize tableIdx
|
Just tableIdx -> return $ S.TableSize tableIdx
|
||||||
Nothing -> Left "unknown table"
|
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)) =
|
synInstrToStruct FunCtx { ctxMod } (PlainInstr (TableGrow tableIdx)) =
|
||||||
case getTableIndex ctxMod tableIdx of
|
case getTableIndex ctxMod tableIdx of
|
||||||
Just tableIdx -> return $ S.TableGrow tableIdx
|
Just tableIdx -> return $ S.TableGrow tableIdx
|
||||||
|
|||||||
@@ -393,6 +393,11 @@ getInstrType (TableCopy toIdx fromIdx) = do
|
|||||||
let TableType _ toType = tables !! to
|
let TableType _ toType = tables !! to
|
||||||
when (fromType /= toType) $ throwError (RefTypeMismatch fromType toType)
|
when (fromType /= toType) $ throwError (RefTypeMismatch fromType toType)
|
||||||
return $ [I32, I32, I32] ==> empty
|
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
|
getInstrType (TableSize tableIdx) = do
|
||||||
Ctx { tables } <- ask
|
Ctx { tables } <- ask
|
||||||
when (length tables <= fromIntegral tableIdx) $ throwError (TableIndexOutOfRange tableIdx)
|
when (length tables <= fromIntegral tableIdx) $ throwError (TableIndexOutOfRange tableIdx)
|
||||||
|
|||||||
+1
-1
@@ -19,7 +19,7 @@ main = do
|
|||||||
files <-
|
files <-
|
||||||
filter (not . List.isPrefixOf "simd") . filter (List.isSuffixOf ".wast")
|
filter (not . List.isPrefixOf "simd") . filter (List.isSuffixOf ".wast")
|
||||||
<$> Directory.listDirectory "tests/spec"
|
<$> Directory.listDirectory "tests/spec"
|
||||||
-- let files = ["ref_func.wast"]
|
-- let files = ["table_fill.wast"]
|
||||||
scriptTestCases <- (`mapM` files) $ \file -> do
|
scriptTestCases <- (`mapM` files) $ \file -> do
|
||||||
test <- LBS.readFile ("tests/spec/" ++ file)
|
test <- LBS.readFile ("tests/spec/" ++ file)
|
||||||
return $ testCase file $ do
|
return $ testCase file $ do
|
||||||
|
|||||||
Reference in New Issue
Block a user