implement call_indirect

This commit is contained in:
Ilya Rezvov
2018-03-15 19:52:57 -07:00
parent 6561ed0264
commit d5324acb40
+14 -4
View File
@@ -82,7 +82,7 @@ emptyStore = Store {
} }
data ModuleInstance = ModuleInstance { data ModuleInstance = ModuleInstance {
types :: Vector FuncType, funcTypes :: Vector FuncType,
funcaddrs :: Vector Address, funcaddrs :: Vector Address,
tableaddrs :: Vector Address, tableaddrs :: Vector Address,
memaddrs :: Vector Address, memaddrs :: Vector Address,
@@ -120,7 +120,7 @@ calcInstance (Store fs ts ms gs) imps Module {functions, types, tables, mems, gl
ExportInstance name $ ExternGlobal $ globs ! fromIntegral idx ExportInstance name $ ExternGlobal $ globs ! fromIntegral idx
in in
ModuleInstance { ModuleInstance {
types = Vector.fromList types, funcTypes = Vector.fromList types,
funcaddrs = funs, funcaddrs = funs,
tableaddrs = tbls, tableaddrs = tbls,
memaddrs = memories, memaddrs = memories,
@@ -131,8 +131,8 @@ calcInstance (Store fs ts ms gs) imps Module {functions, types, tables, mems, gl
type Imports = Map.Map (TL.Text, TL.Text) ExternalValue type Imports = Map.Map (TL.Text, TL.Text) ExternalValue
allocFunctions :: ModuleInstance -> [Function] -> Vector FunctionInstance allocFunctions :: ModuleInstance -> [Function] -> Vector FunctionInstance
allocFunctions inst@ModuleInstance {types} funs = allocFunctions inst@ModuleInstance {funcTypes} funs =
let mkFuncInst f@Function {funcType} = FunctionInstance (types ! (fromIntegral funcType)) inst f in let mkFuncInst f@Function {funcType} = FunctionInstance (funcTypes ! (fromIntegral funcType)) inst f in
Vector.fromList $ map mkFuncInst funs Vector.fromList $ map mkFuncInst funs
getGlobalValue :: ModuleInstance -> Store -> Natural -> IO Value getGlobalValue :: ModuleInstance -> Store -> Natural -> IO Value
@@ -340,6 +340,16 @@ eval store FunctionInstance { funcType, moduleInstance, code = Function { localT
let args = params funcType let args = params funcType
res <- eval store funInst (zipWith checkValType args $ take (length args) $ stack ctx) res <- eval store funInst (zipWith checkValType args $ take (length args) $ stack ctx)
return $ Done ctx { stack = reverse res ++ (drop (length args) $ stack ctx) } return $ Done ctx { stack = reverse res ++ (drop (length args) $ stack ctx) }
step ctx@EvalCtx{ stack = (VI32 v): rest } (CallIndirect typeIdx) = do
let funcType = funcTypes moduleInstance ! fromIntegral typeIdx
let TableInstance { elements } = tableInstances store ! (tableaddrs moduleInstance ! fromIntegral v)
let funcAddr = elements !? fromIntegral v
case funcAddr of
Just (Just addr) -> do
let args = params funcType
res <- invoke store addr (zipWith checkValType args $ take (length args) rest)
return $ Done ctx { stack = reverse res ++ (drop (length args) rest) }
_ -> return Trap
step ctx@EvalCtx{ stack = (_:rest) } Drop = return $ Done ctx { stack = rest } step ctx@EvalCtx{ stack = (_:rest) } Drop = return $ Done ctx { stack = rest }
step ctx@EvalCtx{ stack = (VI32 test:val2:val1:rest) } Select = step ctx@EvalCtx{ stack = (VI32 test:val2:val1:rest) } Select =
if test == 0 if test == 0