check validity of all data and elem segments before updating store on initialization
This commit is contained in:
@@ -482,7 +482,9 @@ allocMems mems = Vector.fromList <$> mapM allocMem mems
|
|||||||
|
|
||||||
initialize :: ModuleInstance -> Module -> Store -> IO (Either String Store)
|
initialize :: ModuleInstance -> Module -> Store -> IO (Either String Store)
|
||||||
initialize inst Module {elems, datas, start} store = do
|
initialize inst Module {elems, datas, start} store = do
|
||||||
storeWithTables <- Monad.foldM initElem (Right store) elems
|
checkedMems <- Monad.foldM checkData (Right store) datas
|
||||||
|
checkedTables <- Monad.foldM checkElem checkedMems elems
|
||||||
|
storeWithTables <- Monad.foldM initElem checkedMems elems
|
||||||
storeWithMems <- Monad.foldM initData storeWithTables datas
|
storeWithMems <- Monad.foldM initData storeWithTables datas
|
||||||
case storeWithMems of
|
case storeWithMems of
|
||||||
Right st -> do
|
Right st -> do
|
||||||
@@ -494,6 +496,20 @@ initialize inst Module {elems, datas, start} store = do
|
|||||||
Nothing -> return $ Right st
|
Nothing -> return $ Right st
|
||||||
Left reason -> return $ Left reason
|
Left reason -> return $ Left reason
|
||||||
where
|
where
|
||||||
|
checkElem :: Either String Store -> ElemSegment -> IO (Either String Store)
|
||||||
|
checkElem (Left err) _ = return $ Left err
|
||||||
|
checkElem (Right st) ElemSegment {tableIndex, offset, funcIndexes} = do
|
||||||
|
VI32 val <- evalConstExpr inst st offset
|
||||||
|
let from = fromIntegral val
|
||||||
|
let funcs = map ((funcaddrs inst !) . fromIntegral) funcIndexes
|
||||||
|
let idx = tableaddrs inst ! fromIntegral tableIndex
|
||||||
|
let last = from + length funcs
|
||||||
|
let TableInstance lim elems = tableInstances st ! idx
|
||||||
|
let len = Vector.length elems
|
||||||
|
if last > len
|
||||||
|
then return $ Left "elements segment does not fit"
|
||||||
|
else return $ Right st
|
||||||
|
|
||||||
initElem :: Either String Store -> ElemSegment -> IO (Either String Store)
|
initElem :: Either String Store -> ElemSegment -> IO (Either String Store)
|
||||||
initElem (Left err) _ = return $ Left err
|
initElem (Left err) _ = return $ Left err
|
||||||
initElem (Right st) ElemSegment {tableIndex, offset, funcIndexes} = do
|
initElem (Right st) ElemSegment {tableIndex, offset, funcIndexes} = do
|
||||||
@@ -510,9 +526,9 @@ initialize inst Module {elems, datas, start} store = do
|
|||||||
let table = TableInstance lim (elems // zip [from..] (map Just funcs))
|
let table = TableInstance lim (elems // zip [from..] (map Just funcs))
|
||||||
return $ Right st { tableInstances = tableInstances st Vector.// [(idx, table)] }
|
return $ Right st { tableInstances = tableInstances st Vector.// [(idx, table)] }
|
||||||
|
|
||||||
initData :: Either String Store -> DataSegment -> IO (Either String Store)
|
checkData :: Either String Store -> DataSegment -> IO (Either String Store)
|
||||||
initData (Left err) _ = return $ Left err
|
checkData (Left err) _ = return $ Left err
|
||||||
initData (Right st) DataSegment {memIndex, offset, chunk} = do
|
checkData (Right st) DataSegment {memIndex, offset, chunk} = do
|
||||||
VI32 val <- evalConstExpr inst st offset
|
VI32 val <- evalConstExpr inst st offset
|
||||||
let from = fromIntegral val
|
let from = fromIntegral val
|
||||||
let idx = memaddrs inst ! fromIntegral memIndex
|
let idx = memaddrs inst ! fromIntegral memIndex
|
||||||
@@ -522,9 +538,19 @@ initialize inst Module {elems, datas, start} store = do
|
|||||||
let len = IOVector.length mem
|
let len = IOVector.length mem
|
||||||
if last > len
|
if last > len
|
||||||
then return $ Left "data segment does not fit"
|
then return $ Left "data segment does not fit"
|
||||||
else do
|
else return $ Right st
|
||||||
mapM_ (\(i,b) -> IOVector.write mem i b) $ zip [from..] $ LBS.unpack chunk
|
|
||||||
return $ Right st
|
initData :: Either String Store -> DataSegment -> IO (Either String Store)
|
||||||
|
initData (Left err) _ = return $ Left err
|
||||||
|
initData (Right st) DataSegment {memIndex, offset, chunk} = do
|
||||||
|
VI32 val <- evalConstExpr inst st offset
|
||||||
|
let from = fromIntegral val
|
||||||
|
let idx = memaddrs inst ! fromIntegral memIndex
|
||||||
|
let last = from + (fromIntegral $ LBS.length chunk)
|
||||||
|
let MemoryInstance _ memory = memInstances st ! idx
|
||||||
|
mem <- readIORef memory
|
||||||
|
mapM_ (\(i,b) -> IOVector.write mem i b) $ zip [from..] $ LBS.unpack chunk
|
||||||
|
return $ Right st
|
||||||
|
|
||||||
instantiate :: Store -> Imports -> Module -> IO (Either String (ModuleInstance, Store))
|
instantiate :: Store -> Imports -> Module -> IO (Either String (ModuleInstance, Store))
|
||||||
instantiate st imps m =
|
instantiate st imps m =
|
||||||
|
|||||||
Reference in New Issue
Block a user