desugarize instructions

This commit is contained in:
Ilya Rezvov
2018-02-17 08:23:30 -08:00
parent 23d83cc3fe
commit 4630002e36
+91 -4
View File
@@ -55,7 +55,7 @@ import qualified Data.Text.Lazy.Encoding as TLEncoding
import qualified Data.Text.Lazy.Read as TLRead import qualified Data.Text.Lazy.Read as TLRead
import qualified Data.ByteString.Lazy as LBS import qualified Data.ByteString.Lazy as LBS
import Data.Maybe (fromMaybe) import Data.Maybe (fromMaybe, fromJust)
import Data.List (foldl', findIndex, find) import Data.List (foldl', findIndex, find)
import Control.Monad (guard) import Control.Monad (guard)
@@ -1149,6 +1149,15 @@ data Module = Module {
exports :: [Export] exports :: [Export]
} deriving (Show, Eq) } deriving (Show, Eq)
type Labels = [Maybe Ident]
data FunCtx = FunCtx {
ctxMod :: Module,
ctxLabels :: Labels,
ctxLocals :: [LocalType],
ctxParams :: [ParamType]
} deriving (Eq, Show)
desugarize :: [ModuleField] -> S.Module desugarize :: [ModuleField] -> S.Module
desugarize fields = desugarize fields =
let mod = Module { let mod = Module {
@@ -1163,8 +1172,8 @@ desugarize fields =
} in } in
S.emptyModule { S.emptyModule {
S.types = map synTypeDefToStruct $ types mod, S.types = map synTypeDefToStruct $ types mod,
S.imports = map (synImportToStruct $ types mod) $ imports mod,
S.tables = map synTableToStruct $ tables mod, S.tables = map synTableToStruct $ tables mod,
S.imports = map (synImportToStruct $ types mod) $ imports mod,
S.mems = map synMemoryToStruct $ mems mod S.mems = map synMemoryToStruct $ mems mod
} }
where where
@@ -1258,13 +1267,91 @@ desugarize fields =
extractImport imports _ = imports extractImport imports _ = imports
-- functions -- functions
synInstrToStruct :: Module -> Instruction -> S.Instruction synInstrToStruct :: FunCtx -> Instruction -> S.Instruction
synInstrToStruct mod (PlainInstr Unreachable) = S.Unreachable synInstrToStruct _ (PlainInstr Unreachable) = S.Unreachable
synInstrToStruct _ (PlainInstr Nop) = S.Nop
synInstrToStruct ctx (PlainInstr (Br labelIdx)) =
fromJust $ S.Br <$> getLabelIdx ctx labelIdx
synInstrToStruct ctx (PlainInstr (BrIf labelIdx)) =
fromJust $ S.BrIf <$> getLabelIdx ctx labelIdx
synInstrToStruct ctx (PlainInstr (BrTable lbls lbl)) =
S.BrTable (map (fromJust . getLabelIdx ctx) lbls) $ fromJust $ getLabelIdx ctx lbl
synInstrToStruct _ (PlainInstr Return) = S.Return
synInstrToStruct FunCtx { ctxMod } (PlainInstr (Call funIdx)) =
S.Call $ fromJust $ getFuncIndex ctxMod funIdx
synInstrToStruct FunCtx { ctxMod = Module { types } } (PlainInstr (CallIndirect typeUse)) =
fromJust $ S.CallIndirect <$> getTypeIndex types typeUse
synInstrToStruct _ (PlainInstr Drop) = S.Drop
synInstrToStruct _ (PlainInstr Select) = S.Select
synInstrToStruct ctx (PlainInstr (GetLocal localIdx)) =
S.GetLocal $ fromJust $ getLocalIndex ctx localIdx
synInstrToStruct ctx (PlainInstr (SetLocal localIdx)) =
S.SetLocal $ fromJust $ getLocalIndex ctx localIdx
synInstrToStruct ctx (PlainInstr (TeeLocal localIdx)) =
S.TeeLocal $ fromJust $ getLocalIndex ctx localIdx
synInstrToStruct FunCtx { ctxMod } (PlainInstr (GetGlobal globalIdx)) =
S.GetGlobal $ fromJust $ getGlobalIndex ctxMod globalIdx
synInstrToStruct FunCtx { ctxMod } (PlainInstr (SetGlobal globalIdx)) =
S.SetGlobal $ fromJust $ getGlobalIndex ctxMod globalIdx
synInstrToStruct _ (PlainInstr (I32Load memArg)) = S.I32Load memArg
synInstrToStruct _ (PlainInstr (I64Load memArg)) = S.I64Load memArg
synInstrToStruct _ (PlainInstr (F32Load memArg)) = S.F32Load memArg
synInstrToStruct _ (PlainInstr (F64Load memArg)) = S.F64Load memArg
synInstrToStruct _ (PlainInstr (I32Load8S memArg)) = S.I32Load8S memArg
synInstrToStruct _ (PlainInstr (I32Load8U memArg)) = S.I32Load8U memArg
synInstrToStruct _ (PlainInstr (I32Load16S memArg)) = S.I32Load16S memArg
synInstrToStruct _ (PlainInstr (I32Load16U memArg)) = S.I32Load16U memArg
synInstrToStruct _ (PlainInstr (I64Load8S memArg)) = S.I64Load8S memArg
synInstrToStruct _ (PlainInstr (I64Load8U memArg)) = S.I64Load8U memArg
synInstrToStruct _ (PlainInstr (I64Load16S memArg)) = S.I64Load16S memArg
synInstrToStruct _ (PlainInstr (I64Load16U memArg)) = S.I64Load16U memArg
synInstrToStruct _ (PlainInstr (I64Load32S memArg)) = S.I64Load32S memArg
synInstrToStruct _ (PlainInstr (I64Load32U memArg)) = S.I64Load32U memArg
synInstrToStruct _ (PlainInstr (I32Store memArg)) = S.I32Store memArg
synInstrToStruct _ (PlainInstr (I64Store memArg)) = S.I64Store memArg
synInstrToStruct _ (PlainInstr (F32Store memArg)) = S.F32Store memArg
synInstrToStruct _ (PlainInstr (F64Store memArg)) = S.F64Store memArg
synInstrToStruct _ (PlainInstr (I32Store8 memArg)) = S.I32Store8 memArg
synInstrToStruct _ (PlainInstr (I32Store16 memArg)) = S.I32Store16 memArg
synInstrToStruct _ (PlainInstr (I64Store8 memArg)) = S.I64Store8 memArg
synInstrToStruct _ (PlainInstr (I64Store16 memArg)) = S.I64Store16 memArg
synInstrToStruct _ (PlainInstr (I64Store32 memArg)) = S.I64Store32 memArg
synInstrToStruct _ (PlainInstr CurrentMemory) = S.CurrentMemory
synInstrToStruct _ (PlainInstr GrowMemory) = S.GrowMemory
synInstrToStruct ctx BlockInstr {label, resultType, body} =
let ctx' = ctx { ctxLabels = label : ctxLabels ctx } in
S.Block resultType $ map (synInstrToStruct ctx') body
synInstrToStruct ctx LoopInstr {label, resultType, body} =
let ctx' = ctx { ctxLabels = label : ctxLabels ctx } in
S.Loop resultType $ map (synInstrToStruct ctx') body
synInstrToStruct ctx IfInstr {label, resultType, trueBranch, falseBranch} =
let ctx' = ctx { ctxLabels = label : ctxLabels ctx } in
let trueBranch' = map (synInstrToStruct ctx') trueBranch in
let falseBranch' = map (synInstrToStruct ctx') falseBranch in
S.If resultType trueBranch' falseBranch'
extractFunction :: [Function] -> ModuleField -> [Function] extractFunction :: [Function] -> ModuleField -> [Function]
extractFunction funcs (MFFunc fun) = fun : funcs extractFunction funcs (MFFunc fun) = fun : funcs
extractFunction funcs _ = funcs extractFunction funcs _ = funcs
getLabelIdx :: FunCtx -> LabelIndex -> Maybe Natural
getLabelIdx FunCtx { ctxLabels } (Named id) =
fromIntegral <$> findIndex (\ident -> ident == Just id) ctxLabels
getLabelIdx FunCtx { ctxLabels } (Index idx) =
Just idx
getLocalIndex :: FunCtx -> LabelIndex -> Maybe Natural
getLocalIndex FunCtx {ctxParams, ctxLocals} (Named id) =
case findIndex (\(ParamType ident _) -> ident == Just id) ctxParams of
Just idx -> return $ fromIntegral idx
Nothing ->
let isIdent (LocalType ident _) = ident == Just id in
fromIntegral . (+ length ctxParams) <$> findIndex isIdent ctxLocals
getLocalIndex FunCtx {ctxParams, ctxLocals} (Index idx) =
if (length ctxParams + length ctxLocals > fromIntegral idx)
then Just idx
else Nothing
getFuncIndex :: Module -> FuncIndex -> Maybe Natural getFuncIndex :: Module -> FuncIndex -> Maybe Natural
getFuncIndex Module { imports, functions } (Named id) = getFuncIndex Module { imports, functions } (Named id) =
let funImports = filter (\(Import { desc = ImportFunc _ _ }) -> True) imports in let funImports = filter (\(Import { desc = ImportFunc _ _ }) -> True) imports in