calculate module instance

This commit is contained in:
Ilya Rezvov
2018-03-07 14:40:19 -08:00
parent a073456a63
commit 1dab371720
3 changed files with 66 additions and 22 deletions
+45 -13
View File
@@ -9,7 +9,8 @@ import qualified Data.Map as Map
import qualified Data.Text.Lazy as TL
import qualified Data.ByteString.Lazy as LBS
import Data.Vector (Vector)
import Data.Vector (Vector, (!))
import Data.Maybe (fromJust)
import qualified Data.Vector as Vector
import Data.IORef (IORef)
import Data.Array.IO (IOArray, newArray, readArray, writeArray)
@@ -51,9 +52,9 @@ data MemoryInstance = MemoryInstance {
data GlobalInstance = GIConst Value | GIMut (IORef Value)
data ExportInstance = ExportInstance TL.Text ExternalVal deriving (Eq, Show)
data ExportInstance = ExportInstance TL.Text ExternalValue deriving (Eq, Show)
data ExternalVal =
data ExternalValue =
ExternFunction Address
| ExternTable Address
| ExternMemory Address
@@ -79,8 +80,8 @@ data Store = Store {
globals :: Vector GlobalInstance
}
initialStore :: Store
initialStore = Store {
emptyStore :: Store
emptyStore = Store {
functions = Vector.empty,
tables = Vector.empty,
mems = Vector.empty,
@@ -96,11 +97,42 @@ data ModuleInstance = ModuleInstance {
exports :: Vector ExportInstance
} deriving (Eq, Show)
instantiate :: Store -> Module -> IO (ModuleInstance, Store)
instantiate st mod = do
return $ (
ModuleInstance {
types = Vector.fromList $ Struct.types mod
},
st
)
calcInstance :: Store -> Imports -> Module -> ModuleInstance
calcInstance (Store fs ts ms gs) imps Module {functions, types, tables, mems, globals, exports, imports} =
let funLen = length fs in
let tableLen = length ts in
let memLen = length ms in
let globalLen = length gs in
let getImpIdx (Import m n _) = fromJust $ Map.lookup (m, n) imps in
let funImps = map getImpIdx $ filter isFuncImport imports in
let tableImps = map getImpIdx $ filter isTableImport imports in
let memImps = map getImpIdx $ filter isMemImport imports in
let globalImps = map getImpIdx $ filter isGlobalImport imports in
let funs = Vector.fromList $ map (\(ExternFunction i) -> i) funImps ++ [funLen..funLen + length functions - 1] in
let tbls = Vector.fromList $ map (\(ExternTable i) -> i) tableImps ++ [tableLen..tableLen + length tables - 1] in
let memories = Vector.fromList $ map (\(ExternMemory i) -> i) memImps ++ [memLen..memLen + length mems - 1] in
let globs = Vector.fromList $ map (\(ExternGlobal i) -> i) globalImps ++ [globalLen..globalLen + length globals - 1] in
let
refExport (Export name (ExportFunc idx)) =
ExportInstance name $ ExternFunction $ funs ! fromIntegral idx
refExport (Export name (ExportTable idx)) =
ExportInstance name $ ExternTable $ tbls ! fromIntegral idx
refExport (Export name (ExportMemory idx)) =
ExportInstance name $ ExternMemory $ memories ! fromIntegral idx
refExport (Export name (ExportGlobal idx)) =
ExportInstance name $ ExternGlobal $ globs ! fromIntegral idx
in
ModuleInstance {
types = Vector.fromList types,
functions = funs,
tables = tbls,
mems = memories,
globals = globs,
exports = Vector.fromList $ map refExport exports
}
type Imports = Map.Map (TL.Text, TL.Text) ExternalValue
instantiate :: Store -> Imports -> Module -> IO (ModuleInstance, Store)
instantiate st imps m = do
return $ (calcInstance st imps m, st)