forked from GitHub/haskell-wasm
implement table.copy
This commit is contained in:
@@ -925,9 +925,25 @@ eval budget store FunctionInstance { funcType, moduleInstance, code = Function {
|
||||
|| isDeclarative mode
|
||||
then return Trap
|
||||
else do
|
||||
Vector.iforM_ (Vector.slice src len refs) $ \idx (RF fn) ->
|
||||
Vector.iforM_ (Vector.slice src len refs) $ \idx (RF fn) -> do
|
||||
MVector.unsafeWrite items (dst + idx) (fromIntegral <$> fn)
|
||||
return $ Done ctx { stack = rest }
|
||||
step ctx@EvalCtx{ stack = (VI32 n:VI32 s:VI32 d:rest) } (TableCopy toIdx fromIdx) = do
|
||||
let fromAddr = tableaddrs moduleInstance ! fromIntegral fromIdx
|
||||
let TableInstance { items = fromItems } = tableInstances store ! fromAddr
|
||||
let toAddr = tableaddrs moduleInstance ! fromIntegral toIdx
|
||||
let TableInstance { items = toItems } = tableInstances store ! toAddr
|
||||
let src = fromIntegral s
|
||||
let dst = fromIntegral d
|
||||
let len = fromIntegral n
|
||||
if src + len > MVector.length fromItems || dst + len > MVector.length toItems
|
||||
then return Trap
|
||||
else do
|
||||
let range = if dst <= src then [0..len - 1] else reverse [0..len - 1]
|
||||
flip mapM_ range $ \off -> do
|
||||
el <- MVector.unsafeRead fromItems (src + off)
|
||||
MVector.unsafeWrite toItems (dst + off) el
|
||||
return $ Done ctx { stack = rest }
|
||||
step ctx@EvalCtx{ stack = (ref:VI32 offset:rest) } (TableSet tableIdx) = do
|
||||
let tableAddr = tableaddrs moduleInstance ! fromIntegral tableIdx
|
||||
let TableInstance { items } = tableInstances store ! tableAddr
|
||||
|
||||
@@ -1722,11 +1722,11 @@ desugarize fields = do
|
||||
Just elemIdx -> return $ S.TableInit tableIdx elemIdx
|
||||
Nothing -> Left "unknown elem"
|
||||
Nothing -> Left "unknown table"
|
||||
synInstrToStruct FunCtx { ctxMod } (PlainInstr (TableCopy fromIdx toIdx)) =
|
||||
synInstrToStruct FunCtx { ctxMod } (PlainInstr (TableCopy toIdx fromIdx)) =
|
||||
case getTableIndex ctxMod fromIdx of
|
||||
Just fromIdx ->
|
||||
case getTableIndex ctxMod toIdx of
|
||||
Just toIdx -> return $ S.TableCopy fromIdx toIdx
|
||||
Just toIdx -> return $ S.TableCopy toIdx fromIdx
|
||||
Nothing -> Left "unknown table"
|
||||
Nothing -> Left "unknown table"
|
||||
synInstrToStruct FunCtx { ctxMod } (PlainInstr (TableSet tableIdx)) =
|
||||
|
||||
@@ -379,7 +379,7 @@ getInstrType (TableInit tableIdx elemIdx) = do
|
||||
let elemType = elems !! fromIntegral elemIdx
|
||||
when (elemType /= tableType) $ throwError (RefTypeMismatch tableType elemType)
|
||||
return $ [I32, I32, I32] ==> empty
|
||||
getInstrType (TableCopy fromIdx toIdx) = do
|
||||
getInstrType (TableCopy toIdx fromIdx) = do
|
||||
Ctx { tables } <- ask
|
||||
let (from, to) = (fromIntegral fromIdx, fromIntegral toIdx)
|
||||
when (length tables <= from) $ throwError (TableIndexOutOfRange fromIdx)
|
||||
|
||||
Reference in New Issue
Block a user