stabilize inline exports extraction algorithm
This commit is contained in:
+98
-124
@@ -857,30 +857,34 @@ importdesc :: { ImportDesc }
|
|||||||
| 'global' opt(ident) globaltype ')' { ImportGlobal $2 $3 }
|
| 'global' opt(ident) globaltype ')' { ImportGlobal $2 $3 }
|
||||||
|
|
||||||
import :: { Import }
|
import :: { Import }
|
||||||
: 'import' name name '(' importdesc ')' { Import $2 $3 $5 }
|
: 'import' name name '(' importdesc ')' { Import [] $2 $3 $5 }
|
||||||
|
|
||||||
-- FUNCTION --
|
-- FUNCTION --
|
||||||
function :: { [ModuleField] }
|
function :: { ModuleField }
|
||||||
: 'func' opt(ident) export_import_typeuse_locals_body { $3 $2 }
|
: 'func' opt(ident) export_import_typeuse_locals_body { $3 $2 }
|
||||||
|
|
||||||
export_import_typeuse_locals_body :: { Maybe Ident -> [ModuleField] }
|
export_import_typeuse_locals_body :: { Maybe Ident -> ModuleField }
|
||||||
: ')' { \i -> [MFFunc Nothing $ emptyFunction { ident = i }] }
|
: ')' { \i -> MFFunc emptyFunction { ident = i } }
|
||||||
| raw_instr list(instruction) ')' {
|
| raw_instr list(instruction) ')' {
|
||||||
\i -> [MFFunc Nothing $ emptyFunction { ident = i, body = $1 ++ concat $2 }]
|
\i -> MFFunc emptyFunction { ident = i, body = $1 ++ concat $2 }
|
||||||
}
|
}
|
||||||
| '(' export_import_typeuse_locals_body1 { $2 }
|
| '(' export_import_typeuse_locals_body1 { $2 }
|
||||||
|
|
||||||
export_import_typeuse_locals_body1 :: { Maybe Ident -> [ModuleField] }
|
export_import_typeuse_locals_body1 :: { Maybe Ident -> ModuleField }
|
||||||
: 'export' name ')' export_import_typeuse_locals_body {
|
: 'export' name ')' export_import_typeuse_locals_body {
|
||||||
\ident -> (MFExport $ Export $2 $ ExportFunc (Named `fmap` ident)) : ($4 ident)
|
\ident ->
|
||||||
|
case $4 ident of
|
||||||
|
MFImport imp -> MFImport imp { reExportAs = $2 : reExportAs imp }
|
||||||
|
MFFunc func -> MFFunc func { exportFuncAs = $2 : exportFuncAs func }
|
||||||
|
_ -> error "unexpected field"
|
||||||
}
|
}
|
||||||
| import_typeuse_locals_body1 { \ident -> [$1 ident] }
|
| import_typeuse_locals_body1 { $1 }
|
||||||
|
|
||||||
import_typeuse_locals_body1 :: { Maybe Ident -> ModuleField }
|
import_typeuse_locals_body1 :: { Maybe Ident -> ModuleField }
|
||||||
: 'import' name name ')' typeuse ')' {
|
: 'import' name name ')' typeuse ')' {
|
||||||
\ident -> MFImport $ Import $2 $3 $ ImportFunc ident $5
|
\ident -> MFImport $ Import [] $2 $3 $ ImportFunc ident $5
|
||||||
}
|
}
|
||||||
| typeuse_locals_body1 { MFFunc Nothing . $1 }
|
| typeuse_locals_body1 { MFFunc . $1 }
|
||||||
|
|
||||||
typeuse_locals_body1 :: { Maybe Ident -> Function }
|
typeuse_locals_body1 :: { Maybe Ident -> Function }
|
||||||
: 'type' index ')' signature_locals_body {
|
: 'type' index ')' signature_locals_body {
|
||||||
@@ -931,24 +935,28 @@ locals_body1 :: { ([LocalType], [Instruction]) }
|
|||||||
|
|
||||||
-- GLOBAL --
|
-- GLOBAL --
|
||||||
|
|
||||||
global :: { [ModuleField] }
|
global :: { ModuleField }
|
||||||
: 'global' opt(ident) global_type_export_import { $3 $2 }
|
: 'global' opt(ident) global_type_export_import { $3 $2 }
|
||||||
|
|
||||||
globaltype :: { GlobalType }
|
globaltype :: { GlobalType }
|
||||||
: valtype { Const $1 }
|
: valtype { Const $1 }
|
||||||
| '(' 'mut' valtype ')' { Mut $3 }
|
| '(' 'mut' valtype ')' { Mut $3 }
|
||||||
|
|
||||||
global_type_export_import :: { Maybe Ident -> [ModuleField] }
|
global_type_export_import :: { Maybe Ident -> ModuleField }
|
||||||
: valtype list(instruction) ')' { \ident -> [MFGlobal $ Global ident (Const $1) $ concat $2] }
|
: valtype list(instruction) ')' { \ident -> MFGlobal $ Global [] ident (Const $1) $ concat $2 }
|
||||||
| '(' global_mut_export_import { $2 }
|
| '(' global_mut_export_import { $2 }
|
||||||
|
|
||||||
global_mut_export_import :: { Maybe Ident -> [ModuleField] }
|
global_mut_export_import :: { Maybe Ident -> ModuleField }
|
||||||
: 'mut' valtype ')' list(instruction) ')' { \ident -> [MFGlobal $ Global ident (Mut $2) $ concat $4] }
|
: 'mut' valtype ')' list(instruction) ')' { \ident -> MFGlobal $ Global [] ident (Mut $2) $ concat $4 }
|
||||||
| 'export' name ')' global_type_export_import {
|
| 'export' name ')' global_type_export_import {
|
||||||
\ident -> (MFExport $ Export $2 $ ExportGlobal $ Named `fmap` ident) : ($4 ident)
|
\ident ->
|
||||||
|
case $4 ident of
|
||||||
|
MFImport imp -> MFImport imp { reExportAs = $2 : reExportAs imp }
|
||||||
|
MFGlobal global -> MFGlobal global { exportGlobalAs = $2 : exportGlobalAs global }
|
||||||
|
_ -> error "unexpected field"
|
||||||
}
|
}
|
||||||
| 'import' name name ')' globaltype ')' {
|
| 'import' name name ')' globaltype ')' {
|
||||||
\ident -> [MFImport $ Import $2 $3 $ ImportGlobal ident $5]
|
\ident -> MFImport $ Import [] $2 $3 $ ImportGlobal ident $5
|
||||||
}
|
}
|
||||||
|
|
||||||
-- GLOBAL END --
|
-- GLOBAL END --
|
||||||
@@ -967,22 +975,26 @@ datastring :: { LBS.ByteString }
|
|||||||
|
|
||||||
memory_limits_export_import1 :: { Maybe Ident -> [ModuleField] }
|
memory_limits_export_import1 :: { Maybe Ident -> [ModuleField] }
|
||||||
: 'export' name ')' memory_limits_export_import {
|
: 'export' name ')' memory_limits_export_import {
|
||||||
\ident -> (MFExport $ Export $2 $ ExportMemory $ Named `fmap` ident) : $4 ident
|
\ident ->
|
||||||
|
case $4 ident of
|
||||||
|
[MFImport imp] -> [MFImport imp { reExportAs = $2 : reExportAs imp }]
|
||||||
|
(MFMem (Memory exps i l)):rest -> (MFMem (Memory ($2:exps) i l)):rest
|
||||||
|
_ -> error "unexpected field"
|
||||||
}
|
}
|
||||||
| 'import' name name ')' limits ')' {
|
| 'import' name name ')' limits ')' {
|
||||||
\ident -> [MFImport $ Import $2 $3 $ ImportMemory ident $5]
|
\ident -> [MFImport $ Import [] $2 $3 $ ImportMemory ident $5]
|
||||||
}
|
}
|
||||||
| 'data' datastring ')' ')' {
|
| 'data' datastring ')' ')' {
|
||||||
\ident ->
|
\ident ->
|
||||||
let m = fromIntegral $ LBS.length $2 in
|
let m = fromIntegral $ LBS.length $2 in
|
||||||
[
|
[
|
||||||
MFMem $ Memory ident $ Limit m $ Just m,
|
MFMem $ Memory [] ident $ Limit m $ Just m,
|
||||||
MFData $ DataSegment (fromMaybe (Index 0) $ Named `fmap` ident) [PlainInstr $ I32Const 0] $2
|
MFData $ DataSegment (fromMaybe (Index 0) $ Named `fmap` ident) [PlainInstr $ I32Const 0] $2
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
memory_limits :: { Maybe Ident -> [ModuleField] }
|
memory_limits :: { Maybe Ident -> [ModuleField] }
|
||||||
: limits ')' { \ident -> [MFMem $ Memory ident $1] }
|
: limits ')' { \ident -> [MFMem $ Memory [] ident $1] }
|
||||||
|
|
||||||
-- MEMOTY END --
|
-- MEMOTY END --
|
||||||
|
|
||||||
@@ -1000,11 +1012,11 @@ table :: { [ModuleField] }
|
|||||||
: 'table' opt(ident) limits_elemtype_elem { $3 $2 }
|
: 'table' opt(ident) limits_elemtype_elem { $3 $2 }
|
||||||
|
|
||||||
limits_elemtype_elem :: { Maybe Ident -> [ModuleField] }
|
limits_elemtype_elem :: { Maybe Ident -> [ModuleField] }
|
||||||
: tabletype ')' { \ident -> [MFTable $ Table ident $1] }
|
: tabletype ')' { \ident -> [MFTable $ Table [] ident $1] }
|
||||||
| elemtype '(' 'elem' list(index) ')' ')' {
|
| elemtype '(' 'elem' list(index) ')' ')' {
|
||||||
\ident ->
|
\ident ->
|
||||||
let funcsLen = fromIntegral $ length $4 in [
|
let funcsLen = fromIntegral $ length $4 in [
|
||||||
MFTable $ Table ident $ TableType (Limit funcsLen (Just funcsLen)) $1,
|
MFTable $ Table [] ident $ TableType (Limit funcsLen (Just funcsLen)) $1,
|
||||||
MFElem $ ElemSegment (fromMaybe (Index 0) $ Named `fmap` ident) [PlainInstr $ I32Const 0] $4
|
MFElem $ ElemSegment (fromMaybe (Index 0) $ Named `fmap` ident) [PlainInstr $ I32Const 0] $4
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -1012,19 +1024,23 @@ limits_elemtype_elem :: { Maybe Ident -> [ModuleField] }
|
|||||||
|
|
||||||
import_export_table :: { Maybe Ident -> [ModuleField] }
|
import_export_table :: { Maybe Ident -> [ModuleField] }
|
||||||
: 'import' name name ')' tabletype ')' {
|
: 'import' name name ')' tabletype ')' {
|
||||||
\ident -> [MFImport $ Import $2 $3 $ ImportTable ident $5]
|
\ident -> [MFImport $ Import [] $2 $3 $ ImportTable ident $5]
|
||||||
}
|
}
|
||||||
| 'export' name ')' limits_elemtype_elem {
|
| 'export' name ')' limits_elemtype_elem {
|
||||||
\ident -> (MFExport $ Export $2 $ ExportTable $ Named `fmap` ident) : ($4 ident)
|
\ident ->
|
||||||
|
case $4 ident of
|
||||||
|
[MFImport imp] -> [MFImport imp { reExportAs = $2 : reExportAs imp }]
|
||||||
|
(MFTable (Table exps i t)):rest -> (MFTable (Table ($2:exps) i t)):rest
|
||||||
|
_ -> error "unexpected field"
|
||||||
}
|
}
|
||||||
|
|
||||||
-- TABLE END --
|
-- TABLE END --
|
||||||
|
|
||||||
exportdesc :: { ExportDesc }
|
exportdesc :: { ExportDesc }
|
||||||
: 'func' index ')' { ExportFunc (Just $2) }
|
: 'func' index ')' { ExportFunc $2 }
|
||||||
| 'table' index ')' { ExportTable (Just $2) }
|
| 'table' index ')' { ExportTable $2 }
|
||||||
| 'memory' index ')' { ExportMemory (Just $2) }
|
| 'memory' index ')' { ExportMemory $2 }
|
||||||
| 'global' index ')' { ExportGlobal (Just $2) }
|
| 'global' index ')' { ExportGlobal $2 }
|
||||||
|
|
||||||
export :: { Export }
|
export :: { Export }
|
||||||
: 'export' name '(' exportdesc ')' { Export $2 $4 }
|
: 'export' name '(' exportdesc ')' { Export $2 $4 }
|
||||||
@@ -1052,12 +1068,12 @@ modulefield1_single :: { ModuleField }
|
|||||||
| start { MFStart $1 }
|
| start { MFStart $1 }
|
||||||
| elemsegment { MFElem $1 }
|
| elemsegment { MFElem $1 }
|
||||||
| datasegment { MFData $1 }
|
| datasegment { MFData $1 }
|
||||||
|
| function { $1 }
|
||||||
|
| global { $1 }
|
||||||
|
|
||||||
modulefield1_multi :: { [ModuleField] }
|
modulefield1_multi :: { [ModuleField] }
|
||||||
: function { $1 }
|
: table { $1 }
|
||||||
| table { $1 }
|
|
||||||
| memory { $1 }
|
| memory { $1 }
|
||||||
| global { $1 }
|
|
||||||
|
|
||||||
modulefield1 :: { [ModuleField] }
|
modulefield1 :: { [ModuleField] }
|
||||||
: modulefield1_single { [$1] }
|
: modulefield1_single { [$1] }
|
||||||
@@ -1309,6 +1325,7 @@ data Instruction =
|
|||||||
deriving (Show, Eq, Generic, NFData)
|
deriving (Show, Eq, Generic, NFData)
|
||||||
|
|
||||||
data Import = Import {
|
data Import = Import {
|
||||||
|
reExportAs :: [TL.Text],
|
||||||
sourceModule :: TL.Text,
|
sourceModule :: TL.Text,
|
||||||
name :: TL.Text,
|
name :: TL.Text,
|
||||||
desc :: ImportDesc
|
desc :: ImportDesc
|
||||||
@@ -1327,6 +1344,7 @@ data LocalType = LocalType {
|
|||||||
} deriving (Show, Eq, Generic, NFData)
|
} deriving (Show, Eq, Generic, NFData)
|
||||||
|
|
||||||
data Function = Function {
|
data Function = Function {
|
||||||
|
exportFuncAs :: [TL.Text],
|
||||||
ident :: Maybe Ident,
|
ident :: Maybe Ident,
|
||||||
funcType :: TypeUse,
|
funcType :: TypeUse,
|
||||||
locals :: [LocalType],
|
locals :: [LocalType],
|
||||||
@@ -1337,6 +1355,7 @@ data Function = Function {
|
|||||||
emptyFunction :: Function
|
emptyFunction :: Function
|
||||||
emptyFunction =
|
emptyFunction =
|
||||||
Function {
|
Function {
|
||||||
|
exportFuncAs = [],
|
||||||
ident = Nothing,
|
ident = Nothing,
|
||||||
funcType = AnonimousTypeUse emptyFuncType,
|
funcType = AnonimousTypeUse emptyFuncType,
|
||||||
locals = [],
|
locals = [],
|
||||||
@@ -1344,21 +1363,22 @@ emptyFunction =
|
|||||||
}
|
}
|
||||||
|
|
||||||
data Global = Global {
|
data Global = Global {
|
||||||
|
exportGlobalAs :: [TL.Text],
|
||||||
ident :: Maybe Ident,
|
ident :: Maybe Ident,
|
||||||
globalType :: GlobalType,
|
globalType :: GlobalType,
|
||||||
initializer :: [Instruction]
|
initializer :: [Instruction]
|
||||||
}
|
}
|
||||||
deriving (Show, Eq, Generic, NFData)
|
deriving (Show, Eq, Generic, NFData)
|
||||||
|
|
||||||
data Memory = Memory (Maybe Ident) Limit deriving (Show, Eq, Generic, NFData)
|
data Memory = Memory [TL.Text] (Maybe Ident) Limit deriving (Show, Eq, Generic, NFData)
|
||||||
|
|
||||||
data Table = Table (Maybe Ident) TableType deriving (Show, Eq, Generic, NFData)
|
data Table = Table [TL.Text] (Maybe Ident) TableType deriving (Show, Eq, Generic, NFData)
|
||||||
|
|
||||||
data ExportDesc =
|
data ExportDesc =
|
||||||
ExportFunc (Maybe FuncIndex)
|
ExportFunc FuncIndex
|
||||||
| ExportTable (Maybe TableIndex)
|
| ExportTable TableIndex
|
||||||
| ExportMemory (Maybe MemoryIndex)
|
| ExportMemory MemoryIndex
|
||||||
| ExportGlobal (Maybe GlobalIndex)
|
| ExportGlobal GlobalIndex
|
||||||
deriving (Show, Eq, Generic, NFData)
|
deriving (Show, Eq, Generic, NFData)
|
||||||
|
|
||||||
data Export = Export {
|
data Export = Export {
|
||||||
@@ -1386,7 +1406,7 @@ data DataSegment = DataSegment {
|
|||||||
data ModuleField =
|
data ModuleField =
|
||||||
MFType TypeDef
|
MFType TypeDef
|
||||||
| MFImport Import
|
| MFImport Import
|
||||||
| MFFunc (Maybe Int) Function
|
| MFFunc Function
|
||||||
| MFTable Table
|
| MFTable Table
|
||||||
| MFMem Memory
|
| MFMem Memory
|
||||||
| MFGlobal Global
|
| MFGlobal Global
|
||||||
@@ -1505,7 +1525,7 @@ desugarize fields = do
|
|||||||
S.mems = map synMemoryToStruct $ mems mod,
|
S.mems = map synMemoryToStruct $ mems mod,
|
||||||
S.globals = globs,
|
S.globals = globs,
|
||||||
S.start = fmap (synStartToStruct mod) $ start mod,
|
S.start = fmap (synStartToStruct mod) $ start mod,
|
||||||
S.exports = synExportsToStruct mod $ appendIndexToFuncs fields
|
S.exports = synExportsToStruct mod $ extractExports mod fields
|
||||||
}
|
}
|
||||||
where
|
where
|
||||||
-- utils
|
-- utils
|
||||||
@@ -1533,7 +1553,7 @@ desugarize fields = do
|
|||||||
if nonImportOccured
|
if nonImportOccured
|
||||||
then Left "Import sections have to be before any definition"
|
then Left "Import sections have to be before any definition"
|
||||||
else Right False
|
else Right False
|
||||||
checkDef _ (MFFunc _ _) = return True
|
checkDef _ (MFFunc _) = return True
|
||||||
checkDef _ (MFGlobal _) = return True
|
checkDef _ (MFGlobal _) = return True
|
||||||
checkDef _ (MFMem _) = return True
|
checkDef _ (MFMem _) = return True
|
||||||
checkDef _ (MFTable _) = return True
|
checkDef _ (MFTable _) = return True
|
||||||
@@ -1543,7 +1563,7 @@ desugarize fields = do
|
|||||||
extractTypeDef defs (MFType _) = defs -- should be extracted before implicit defs
|
extractTypeDef defs (MFType _) = defs -- should be extracted before implicit defs
|
||||||
extractTypeDef defs (MFImport Import { desc = ImportFunc _ typeUse }) =
|
extractTypeDef defs (MFImport Import { desc = ImportFunc _ typeUse }) =
|
||||||
matchTypeUse defs typeUse
|
matchTypeUse defs typeUse
|
||||||
extractTypeDef defs (MFFunc _ Function { funcType, body }) =
|
extractTypeDef defs (MFFunc Function { funcType, body }) =
|
||||||
extractTypeDefFromInstructions (matchTypeUse defs funcType) body
|
extractTypeDefFromInstructions (matchTypeUse defs funcType) body
|
||||||
extractTypeDef defs (MFGlobal Global { initializer }) =
|
extractTypeDef defs (MFGlobal Global { initializer }) =
|
||||||
extractTypeDefFromInstructions defs initializer
|
extractTypeDefFromInstructions defs initializer
|
||||||
@@ -1598,15 +1618,15 @@ desugarize fields = do
|
|||||||
|
|
||||||
-- imports
|
-- imports
|
||||||
synImportToStruct :: [TypeDef] -> Import -> S.Import
|
synImportToStruct :: [TypeDef] -> Import -> S.Import
|
||||||
synImportToStruct defs (Import mod name (ImportFunc _ typeUse)) =
|
synImportToStruct defs (Import _ mod name (ImportFunc _ typeUse)) =
|
||||||
case getTypeIndex defs typeUse of
|
case getTypeIndex defs typeUse of
|
||||||
Just idx -> S.Import mod name $ S.ImportFunc idx
|
Just idx -> S.Import mod name $ S.ImportFunc idx
|
||||||
Nothing -> error $ "cannot find type index for function import: " ++ show typeUse
|
Nothing -> error $ "cannot find type index for function import: " ++ show typeUse
|
||||||
synImportToStruct _ (Import mod name (ImportTable _ tableType)) =
|
synImportToStruct _ (Import _ mod name (ImportTable _ tableType)) =
|
||||||
S.Import mod name $ S.ImportTable tableType
|
S.Import mod name $ S.ImportTable tableType
|
||||||
synImportToStruct _ (Import mod name (ImportMemory _ limit)) =
|
synImportToStruct _ (Import _ mod name (ImportMemory _ limit)) =
|
||||||
S.Import mod name $ S.ImportMemory limit
|
S.Import mod name $ S.ImportMemory limit
|
||||||
synImportToStruct _ (Import mod name (ImportGlobal _ globalType)) =
|
synImportToStruct _ (Import _ mod name (ImportGlobal _ globalType)) =
|
||||||
S.Import mod name $ S.ImportGlobal globalType
|
S.Import mod name $ S.ImportGlobal globalType
|
||||||
|
|
||||||
extractImport :: [Import] -> ModuleField -> [Import]
|
extractImport :: [Import] -> ModuleField -> [Import]
|
||||||
@@ -1746,7 +1766,7 @@ desugarize fields = do
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 -> LabelIndex -> Maybe Natural
|
||||||
@@ -1780,7 +1800,7 @@ desugarize fields = do
|
|||||||
|
|
||||||
-- tables
|
-- tables
|
||||||
synTableToStruct :: Table -> S.Table
|
synTableToStruct :: Table -> S.Table
|
||||||
synTableToStruct (Table _ tableType) = S.Table tableType
|
synTableToStruct (Table _ _ tableType) = S.Table tableType
|
||||||
|
|
||||||
extractTable :: [Table] -> ModuleField -> [Table]
|
extractTable :: [Table] -> ModuleField -> [Table]
|
||||||
extractTable tables (MFTable table) = table : tables
|
extractTable tables (MFTable table) = table : tables
|
||||||
@@ -1796,13 +1816,13 @@ desugarize fields = do
|
|||||||
case findIndex (\(Import { desc = ImportTable ident _ }) -> ident == Just id) tableImports of
|
case findIndex (\(Import { desc = ImportTable ident _ }) -> ident == Just id) tableImports of
|
||||||
Just idx -> return $ fromIntegral idx
|
Just idx -> return $ fromIntegral idx
|
||||||
Nothing ->
|
Nothing ->
|
||||||
let isIdent (Table (Just id) _) = True in
|
let isIdent (Table _ (Just id) _) = True in
|
||||||
fromIntegral . (+ length tableImports) <$> findIndex isIdent tables
|
fromIntegral . (+ length tableImports) <$> findIndex isIdent tables
|
||||||
getTableIndex Module { imports, tables } (Index idx) = Just idx
|
getTableIndex Module { imports, tables } (Index idx) = Just idx
|
||||||
|
|
||||||
-- memory
|
-- memory
|
||||||
synMemoryToStruct :: Memory -> S.Memory
|
synMemoryToStruct :: Memory -> S.Memory
|
||||||
synMemoryToStruct (Memory _ limits) = S.Memory limits
|
synMemoryToStruct (Memory _ _ limits) = S.Memory limits
|
||||||
|
|
||||||
extractMemory :: [Memory] -> ModuleField -> [Memory]
|
extractMemory :: [Memory] -> ModuleField -> [Memory]
|
||||||
extractMemory mems (MFMem mem) = mem : mems
|
extractMemory mems (MFMem mem) = mem : mems
|
||||||
@@ -1818,7 +1838,7 @@ desugarize fields = do
|
|||||||
case findIndex (\(Import { desc = ImportMemory ident _ }) -> ident == Just id) memImports of
|
case findIndex (\(Import { desc = ImportMemory ident _ }) -> ident == Just id) memImports of
|
||||||
Just idx -> return $ fromIntegral idx
|
Just idx -> return $ fromIntegral idx
|
||||||
Nothing ->
|
Nothing ->
|
||||||
let isIdent (Memory (Just id) _) = True in
|
let isIdent (Memory _ (Just id) _) = True in
|
||||||
fromIntegral . (+ length memImports) <$> findIndex isIdent mems
|
fromIntegral . (+ length memImports) <$> findIndex isIdent mems
|
||||||
getMemIndex Module { imports, mems } (Index idx) = Just idx
|
getMemIndex Module { imports, mems } (Index idx) = Just idx
|
||||||
|
|
||||||
@@ -1884,88 +1904,42 @@ desugarize fields = do
|
|||||||
extractStart' start _ = start
|
extractStart' start _ = start
|
||||||
|
|
||||||
-- exports
|
-- exports
|
||||||
appendIndexToFuncs :: [ModuleField] -> [ModuleField]
|
extractExports :: Module -> [ModuleField] -> [ModuleField]
|
||||||
appendIndexToFuncs mf = reverse $ snd $ foldl' appendIndexToFunc (0, []) mf
|
extractExports mod mf =
|
||||||
|
let initial = (funcImportLength, globImportLength, memImportLength, tableImportLength, []) in
|
||||||
|
let (_, _, _, _, result) = foldl' extractExport initial mf in
|
||||||
|
reverse result
|
||||||
where
|
where
|
||||||
appendIndexToFunc :: (Int, [ModuleField]) -> ModuleField -> (Int, [ModuleField])
|
funcImportLength = fromIntegral $ length $ filter isFuncImport $ imports mod
|
||||||
appendIndexToFunc (idx, mf) (MFFunc _ fun) = (idx + 1, (MFFunc (Just idx) fun):mf)
|
globImportLength = fromIntegral $ length $ filter isGlobalImport $ imports mod
|
||||||
appendIndexToFunc (idx, mf) f = (idx, f:mf)
|
memImportLength = fromIntegral $ length $ filter isMemImport $ imports mod
|
||||||
|
tableImportLength = fromIntegral $ length $ filter isTableImport $ imports mod
|
||||||
|
|
||||||
|
extractExport (fidx, gidx, midx, tidx, mf) (MFFunc fun@Function{ exportFuncAs }) =
|
||||||
|
let exports = map (\name -> MFExport $ Export name $ ExportFunc $ Index fidx) exportFuncAs in
|
||||||
|
(fidx + 1, gidx, midx, tidx, [MFFunc fun] ++ exports ++ mf)
|
||||||
|
extractExport (fidx, gidx, midx, tidx, mf) (MFGlobal glob@Global{ exportGlobalAs }) =
|
||||||
|
let exports = map (\name -> MFExport $ Export name $ ExportGlobal $ Index gidx) exportGlobalAs in
|
||||||
|
(fidx, gidx + 1, midx, tidx, [MFGlobal glob] ++ exports ++ mf)
|
||||||
|
extractExport (fidx, gidx, midx, tidx, mf) (MFMem (Memory exps i l)) =
|
||||||
|
let exports = map (\name -> MFExport $ Export name $ ExportMemory $ Index midx) exps in
|
||||||
|
(fidx, gidx, midx + 1, tidx, [MFMem (Memory exps i l)] ++ exports ++ mf)
|
||||||
|
extractExport (fidx, gidx, midx, tidx, mf) (MFTable (Table exps i t)) =
|
||||||
|
let exports = map (\name -> MFExport $ Export name $ ExportTable $ Index tidx) exps in
|
||||||
|
(fidx, gidx, midx, tidx + 1, [MFTable (Table exps i t)] ++ exports ++ mf)
|
||||||
|
extractExport (fidx, gidx, midx, tidx, mf) f = (fidx, gidx, midx, tidx, f:mf)
|
||||||
|
|
||||||
synExportsToStruct :: Module -> [ModuleField] -> [S.Export]
|
synExportsToStruct :: Module -> [ModuleField] -> [S.Export]
|
||||||
synExportsToStruct mod (MFExport Export { name, desc = ExportFunc Nothing } : rest) =
|
synExportsToStruct mod (MFExport Export { name, desc = ExportFunc idx } : rest) =
|
||||||
let
|
|
||||||
isFuncExport (MFExport Export { desc = ExportFunc Nothing }) = True
|
|
||||||
isFuncExport _ = False
|
|
||||||
in
|
|
||||||
let getName (MFExport Export { name }) = name in
|
|
||||||
let names = name : (map getName $ takeWhile isFuncExport rest) in
|
|
||||||
let funImports = filter isFuncImport $ imports mod in
|
|
||||||
let rest' = dropWhile isFuncExport rest in
|
|
||||||
let
|
|
||||||
idx = fromIntegral $ case head rest' of
|
|
||||||
MFImport imp -> fromJust $ findIndex (== imp) funImports
|
|
||||||
MFFunc (Just idx) fun -> length funImports + idx
|
|
||||||
_ -> error "export statement without index has to be followed with import or function"
|
|
||||||
in
|
|
||||||
map (\name -> S.Export name $ S.ExportFunc idx) names ++ synExportsToStruct mod rest'
|
|
||||||
synExportsToStruct mod (MFExport Export { name, desc = ExportFunc (Just idx) } : rest) =
|
|
||||||
let exp = S.Export name $ S.ExportFunc $ fromJust $ getFuncIndex mod idx in
|
let exp = S.Export name $ S.ExportFunc $ fromJust $ getFuncIndex mod idx in
|
||||||
exp : synExportsToStruct mod rest
|
exp : synExportsToStruct mod rest
|
||||||
synExportsToStruct mod (MFExport Export { name, desc = ExportTable Nothing } : rest) =
|
synExportsToStruct mod (MFExport Export { name, desc = ExportTable idx } : rest) =
|
||||||
let
|
|
||||||
isTableExport (MFExport Export { desc = ExportTable Nothing }) = True
|
|
||||||
isTableExport _ = False
|
|
||||||
in
|
|
||||||
let getName (MFExport Export { name }) = name in
|
|
||||||
let names = name : (map getName $ takeWhile isTableExport rest) in
|
|
||||||
let tableImports = filter isTableImport $ imports mod in
|
|
||||||
let rest' = dropWhile isTableExport rest in
|
|
||||||
let
|
|
||||||
idx = fromIntegral $ case head rest' of
|
|
||||||
MFImport imp -> fromJust $ findIndex (== imp) tableImports
|
|
||||||
MFTable tab -> length tableImports + (fromJust $ findIndex (== tab) $ tables mod)
|
|
||||||
_ -> error "export statement without index has to be followed with import or table"
|
|
||||||
in
|
|
||||||
map (\name -> S.Export name $ S.ExportTable idx) names ++ synExportsToStruct mod rest'
|
|
||||||
synExportsToStruct mod (MFExport Export { name, desc = ExportTable (Just idx) } : rest) =
|
|
||||||
let exp = S.Export name $ S.ExportTable $ fromJust $ getTableIndex mod idx in
|
let exp = S.Export name $ S.ExportTable $ fromJust $ getTableIndex mod idx in
|
||||||
exp : synExportsToStruct mod rest
|
exp : synExportsToStruct mod rest
|
||||||
synExportsToStruct mod (MFExport Export { name, desc = ExportMemory Nothing } : rest) =
|
synExportsToStruct mod (MFExport Export { name, desc = ExportMemory idx } : rest) =
|
||||||
let
|
|
||||||
isMemExport (MFExport Export { desc = ExportMemory Nothing }) = True
|
|
||||||
isMemExport _ = False
|
|
||||||
in
|
|
||||||
let getName (MFExport Export { name }) = name in
|
|
||||||
let names = name : (map getName $ takeWhile isMemExport rest) in
|
|
||||||
let memImports = filter isMemImport $ imports mod in
|
|
||||||
let rest' = dropWhile isMemExport rest in
|
|
||||||
let
|
|
||||||
idx = fromIntegral $ case head rest' of
|
|
||||||
MFImport imp -> fromJust $ findIndex (== imp) memImports
|
|
||||||
MFMem mem -> length memImports + (fromJust $ findIndex (== mem) $ mems mod)
|
|
||||||
_ -> error "export statement without index has to be followed with import or memory"
|
|
||||||
in
|
|
||||||
map (\name -> S.Export name $ S.ExportMemory idx) names ++ synExportsToStruct mod rest'
|
|
||||||
synExportsToStruct mod (MFExport Export { name, desc = ExportMemory (Just idx) } : rest) =
|
|
||||||
let exp = S.Export name $ S.ExportMemory $ fromJust $ getMemIndex mod idx in
|
let exp = S.Export name $ S.ExportMemory $ fromJust $ getMemIndex mod idx in
|
||||||
exp : synExportsToStruct mod rest
|
exp : synExportsToStruct mod rest
|
||||||
synExportsToStruct mod (MFExport Export { name, desc = ExportGlobal Nothing } : rest) =
|
synExportsToStruct mod (MFExport Export { name, desc = ExportGlobal idx } : rest) =
|
||||||
let
|
|
||||||
isGlobalExport (MFExport Export { desc = ExportGlobal Nothing }) = True
|
|
||||||
isGlobalExport _ = False
|
|
||||||
in
|
|
||||||
let getName (MFExport Export { name }) = name in
|
|
||||||
let names = name : (map getName $ takeWhile isGlobalExport rest) in
|
|
||||||
let globalImports = filter isGlobalImport $ imports mod in
|
|
||||||
let rest' = dropWhile isGlobalExport rest in
|
|
||||||
let
|
|
||||||
idx = fromIntegral $ case head rest' of
|
|
||||||
MFImport imp -> fromJust $ findIndex (== imp) globalImports
|
|
||||||
MFGlobal global -> length globalImports + (fromJust $ findIndex (== global) $ globals mod)
|
|
||||||
_ -> error "export statement without index has to be followed with import or memory"
|
|
||||||
in
|
|
||||||
map (\name -> S.Export name $ S.ExportGlobal idx) names ++ synExportsToStruct mod rest'
|
|
||||||
synExportsToStruct mod (MFExport Export { name, desc = ExportGlobal (Just idx) } : rest) =
|
|
||||||
let exp = S.Export name $ S.ExportGlobal $ fromJust $ getGlobalIndex mod idx in
|
let exp = S.Export name $ S.ExportGlobal $ fromJust $ getGlobalIndex mod idx in
|
||||||
exp : synExportsToStruct mod rest
|
exp : synExportsToStruct mod rest
|
||||||
synExportsToStruct mod (_ : rest) = synExportsToStruct mod rest
|
synExportsToStruct mod (_ : rest) = synExportsToStruct mod rest
|
||||||
|
|||||||
Reference in New Issue
Block a user