| Modules |
| ------- |
| |
| :ref:`Modules <syntax-module>` are valid when all the components they contain are valid. |
| Furthermore, most definitions are themselves classified with a suitable type. |
| |
| |
| .. index:: function, local, function index, local index, type index, function type, value type, expression, import |
| pair: abstract syntax; function |
| single: abstract syntax; function |
| .. _valid-local: |
| .. _valid-func: |
| |
| Functions |
| ~~~~~~~~~ |
| |
| Functions :math:`\func` are classified by :ref:`function types <syntax-functype>` of the form :math:`[t_1^\ast] \to [t_2^?]`. |
| |
| |
| :math:`\{ \FTYPE~x, \FLOCALS~t^\ast, \FBODY~\expr \}` |
| ..................................................... |
| |
| * The type :math:`C.\CTYPES[x]` must be defined in the context. |
| |
| * Let :math:`[t_1^\ast] \to [t_2^?]` be the :ref:`function type <syntax-functype>` :math:`C.\CTYPES[x]`. |
| |
| * Let :math:`C'` be the same :ref:`context <context>` as :math:`C`, |
| but with: |
| |
| * |CLOCALS| set to the sequence of :ref:`value types <syntax-valtype>` :math:`t_1^\ast~t^\ast`, concatenating parameters and locals, |
| |
| * |CLABELS| set to the singular sequence containing only :ref:`result type <syntax-valtype>` :math:`[t_2^?]`. |
| |
| * |CRETURN| set to the :ref:`result type <syntax-valtype>` :math:`[t_2^?]`. |
| |
| * Under the context :math:`C'`, |
| the expression :math:`\expr` must be valid with type :math:`t_2^?`. |
| |
| * Then the function definition is valid with type :math:`[t_1^\ast] \to [t_2^?]`. |
| |
| .. math:: |
| \frac{ |
| C.\CTYPES[x] = [t_1^\ast] \to [t_2^?] |
| \qquad |
| C,\CLOCALS\,t_1^\ast~t^\ast,\CLABELS~[t_2^?],\CRETURN~[t_2^?] \vdashexpr \expr : [t_2^?] |
| }{ |
| C \vdashfunc \{ \FTYPE~x, \FLOCALS~t^\ast, \FBODY~\expr \} : [t_1^\ast] \to [t_2^?] |
| } |
| |
| .. note:: |
| The restriction on the length of the result types :math:`t_2^\ast` may be lifted in future versions of WebAssembly. |
| |
| |
| .. index:: table, table type |
| pair: validation; table |
| single: abstract syntax; table |
| .. _valid-table: |
| |
| Tables |
| ~~~~~~ |
| |
| Tables :math:`\table` are classified by :ref:`table types <syntax-tabletype>`. |
| |
| :math:`\{ \TTYPE~\tabletype \}` |
| ............................... |
| |
| * The :ref:`table type <syntax-tabletype>` :math:`\tabletype` must be :ref:`valid <valid-tabletype>`. |
| |
| * Then the table definition is valid with type :math:`\tabletype`. |
| |
| .. math:: |
| \frac{ |
| \vdashtabletype \tabletype \ok |
| }{ |
| C \vdashtable \{ \TTYPE~\tabletype \} : \tabletype |
| } |
| |
| |
| .. index:: memory, memory type |
| pair: validation; memory |
| single: abstract syntax; memory |
| .. _valid-mem: |
| |
| Memories |
| ~~~~~~~~ |
| |
| Memories :math:`\mem` are classified by :ref:`memory types <syntax-memtype>`. |
| |
| :math:`\{ \MTYPE~\memtype \}` |
| ............................. |
| |
| * The :ref:`memory type <syntax-memtype>` :math:`\memtype` must be :ref:`valid <valid-memtype>`. |
| |
| * Then the memory definition is valid with type :math:`\memtype`. |
| |
| .. math:: |
| \frac{ |
| \vdashmemtype \memtype \ok |
| }{ |
| C \vdashmem \{ \MTYPE~\memtype \} : \memtype |
| } |
| |
| |
| .. index:: global, global type, expression |
| pair: validation; global |
| single: abstract syntax; global |
| .. _valid-global: |
| |
| Globals |
| ~~~~~~~ |
| |
| Globals :math:`\global` are classified by :ref:`global types <syntax-globaltype>` of the form :math:`\mut~t`. |
| |
| |
| :math:`\{ \GTYPE~\mut~t, \GINIT~\expr \}` |
| ......................................... |
| |
| * The :ref:`global type <syntax-globaltype>` :math:`\mut~t` must be :ref:`valid <valid-globaltype>`. |
| |
| * The expression :math:`\expr` must be :ref:`valid <valid-expr>` with :ref:`result type <syntax-resulttype>` :math:`[t]`. |
| |
| * The expression :math:`\expr` must be :ref:`constant <valid-constant>`. |
| |
| * Then the global definition is valid with type :math:`\mut~t`. |
| |
| .. math:: |
| \frac{ |
| \vdashglobaltype \mut~t \ok |
| \qquad |
| C \vdashexpr \expr : [t] |
| \qquad |
| C \vdashexprconst \expr \const |
| }{ |
| C \vdashglobal \{ \GTYPE~\mut~t, \GINIT~\expr \} : \mut~t |
| } |
| |
| |
| .. index:: element, table, table index, expression, function index |
| pair: validation; element |
| single: abstract syntax; element |
| single: table; element |
| single: element; segment |
| .. _valid-elem: |
| |
| Element Segments |
| ~~~~~~~~~~~~~~~~ |
| |
| Element segments :math:`\elem` are not classified by a type. |
| |
| :math:`\{ \ETABLE~x, \EOFFSET~\expr, \EINIT~y^\ast \}` |
| ...................................................... |
| |
| * The table :math:`C.\CTABLES[x]` must be defined in the context. |
| |
| * Let :math:`\limits~\elemtype` be the :ref:`table type <syntax-tabletype>` :math:`C.\CTABLES[x]`. |
| |
| * The :ref:`element type <syntax-elemtype>` :math:`\elemtype` must be |FUNCREF|. |
| |
| * The expression :math:`\expr` must be :ref:`valid <valid-expr>` with :ref:`result type <syntax-resulttype>` :math:`[\I32]`. |
| |
| * The expression :math:`\expr` must be :ref:`constant <valid-constant>`. |
| |
| * For each :math:`y_i` in :math:`y^\ast`, |
| the function :math:`C.\CFUNCS[y]` must be defined in the context. |
| |
| * Then the element segment is valid. |
| |
| |
| .. math:: |
| \frac{ |
| C.\CTABLES[x] = \limits~\FUNCREF |
| \qquad |
| C \vdashexpr \expr : [\I32] |
| \qquad |
| C \vdashexprconst \expr \const |
| \qquad |
| (C.\CFUNCS[y] = \functype)^\ast |
| }{ |
| C \vdashelem \{ \ETABLE~x, \EOFFSET~\expr, \EINIT~y^\ast \} \ok |
| } |
| |
| |
| .. index:: data, memory, memory index, expression, byte |
| pair: validation; data |
| single: abstract syntax; data |
| single: memory; data |
| single: data; segment |
| .. _valid-data: |
| |
| Data Segments |
| ~~~~~~~~~~~~~ |
| |
| Data segments :math:`\data` are not classified by any type. |
| |
| :math:`\{ \DMEM~x, \DOFFSET~\expr, \DINIT~b^\ast \}` |
| .................................................... |
| |
| * The memory :math:`C.\CMEMS[x]` must be defined in the context. |
| |
| * The expression :math:`\expr` must be :ref:`valid <valid-expr>` with :ref:`result type <syntax-resulttype>` :math:`[\I32]`. |
| |
| * The expression :math:`\expr` must be :ref:`constant <valid-constant>`. |
| |
| * Then the data segment is valid. |
| |
| |
| .. math:: |
| \frac{ |
| C.\CMEMS[x] = \limits |
| \qquad |
| C \vdashexpr \expr : [\I32] |
| \qquad |
| C \vdashexprconst \expr \const |
| }{ |
| C \vdashdata \{ \DMEM~x, \DOFFSET~\expr, \DINIT~b^\ast \} \ok |
| } |
| |
| |
| .. index:: start function, function index |
| pair: validation; start function |
| single: abstract syntax; start function |
| .. _valid-start: |
| |
| Start Function |
| ~~~~~~~~~~~~~~ |
| |
| Start function declarations :math:`\start` are not classified by any type. |
| |
| :math:`\{ \SFUNC~x \}` |
| ...................... |
| |
| * The function :math:`C.\CFUNCS[x]` must be defined in the context. |
| |
| * The type of :math:`C.\CFUNCS[x]` must be :math:`[] \to []`. |
| |
| * Then the start function is valid. |
| |
| |
| .. math:: |
| \frac{ |
| C.\CFUNCS[x] = [] \to [] |
| }{ |
| C \vdashstart \{ \SFUNC~x \} \ok |
| } |
| |
| |
| .. index:: export, name, index, function index, table index, memory index, global index |
| pair: validation; export |
| single: abstract syntax; export |
| .. _valid-exportdesc: |
| .. _valid-export: |
| |
| Exports |
| ~~~~~~~ |
| |
| Exports :math:`\export` and export descriptions :math:`\exportdesc` are classified by their :ref:`external type <syntax-externtype>`. |
| |
| |
| :math:`\{ \ENAME~\name, \EDESC~\exportdesc \}` |
| .............................................. |
| |
| * The export description :math:`\exportdesc` must be valid with :ref:`external type <syntax-externtype>` :math:`\externtype`. |
| |
| * Then the export is valid with :ref:`external type <syntax-externtype>` :math:`\externtype`. |
| |
| .. math:: |
| \frac{ |
| C \vdashexportdesc \exportdesc : \externtype |
| }{ |
| C \vdashexport \{ \ENAME~\name, \EDESC~\exportdesc \} : \externtype |
| } |
| |
| |
| :math:`\EDFUNC~x` |
| ................. |
| |
| * The function :math:`C.\CFUNCS[x]` must be defined in the context. |
| |
| * Then the export description is valid with :ref:`external type <syntax-externtype>` :math:`\ETFUNC~C.\CFUNCS[x]`. |
| |
| .. math:: |
| \frac{ |
| C.\CFUNCS[x] = \functype |
| }{ |
| C \vdashexportdesc \EDFUNC~x : \ETFUNC~\functype |
| } |
| |
| |
| :math:`\EDTABLE~x` |
| .................. |
| |
| * The table :math:`C.\CTABLES[x]` must be defined in the context. |
| |
| * Then the export description is valid with :ref:`external type <syntax-externtype>` :math:`\ETTABLE~C.\CTABLES[x]`. |
| |
| .. math:: |
| \frac{ |
| C.\CTABLES[x] = \tabletype |
| }{ |
| C \vdashexportdesc \EDTABLE~x : \ETTABLE~\tabletype |
| } |
| |
| |
| :math:`\EDMEM~x` |
| ................ |
| |
| * The memory :math:`C.\CMEMS[x]` must be defined in the context. |
| |
| * Then the export description is valid with :ref:`external type <syntax-externtype>` :math:`\ETMEM~C.\CMEMS[x]`. |
| |
| .. math:: |
| \frac{ |
| C.\CMEMS[x] = \memtype |
| }{ |
| C \vdashexportdesc \EDMEM~x : \ETMEM~\memtype |
| } |
| |
| |
| :math:`\EDGLOBAL~x` |
| ................... |
| |
| * The global :math:`C.\CGLOBALS[x]` must be defined in the context. |
| |
| * Then the export description is valid with :ref:`external type <syntax-externtype>` :math:`\ETGLOBAL~C.\CGLOBALS[x]`. |
| |
| .. math:: |
| \frac{ |
| C.\CGLOBALS[x] = \globaltype |
| }{ |
| C \vdashexportdesc \EDGLOBAL~x : \ETGLOBAL~\globaltype |
| } |
| |
| |
| .. index:: import, name, function type, table type, memory type, global type |
| pair: validation; import |
| single: abstract syntax; import |
| .. _valid-importdesc: |
| .. _valid-import: |
| |
| Imports |
| ~~~~~~~ |
| |
| Imports :math:`\import` and import descriptions :math:`\importdesc` are classified by :ref:`external types <syntax-externtype>`. |
| |
| |
| :math:`\{ \IMODULE~\name_1, \INAME~\name_2, \IDESC~\importdesc \}` |
| .................................................................. |
| |
| * The import description :math:`\importdesc` must be valid with type :math:`\externtype`. |
| |
| * Then the import is valid with type :math:`\externtype`. |
| |
| .. math:: |
| \frac{ |
| C \vdashimportdesc \importdesc : \externtype |
| }{ |
| C \vdashimport \{ \IMODULE~\name_1, \INAME~\name_2, \IDESC~\importdesc \} : \externtype |
| } |
| |
| |
| :math:`\IDFUNC~x` |
| ................. |
| |
| * The function :math:`C.\CTYPES[x]` must be defined in the context. |
| |
| * Let :math:`[t_1^\ast] \to [t_2^\ast]` be the :ref:`function type <syntax-functype>` :math:`C.\CTYPES[x]`. |
| |
| * Then the import description is valid with type :math:`\ETFUNC~[t_1^\ast] \to [t_2^\ast]`. |
| |
| .. math:: |
| \frac{ |
| C.\CTYPES[x] = [t_1^\ast] \to [t_2^\ast] |
| }{ |
| C \vdashimportdesc \IDFUNC~x : \ETFUNC~[t_1^\ast] \to [t_2^\ast] |
| } |
| |
| |
| :math:`\IDTABLE~\tabletype` |
| ........................... |
| |
| * The table type :math:`\tabletype` must be :ref:`valid <valid-tabletype>`. |
| |
| * Then the import description is valid with type :math:`\ETTABLE~\tabletype`. |
| |
| .. math:: |
| \frac{ |
| \vdashtable \tabletype \ok |
| }{ |
| C \vdashimportdesc \IDTABLE~\tabletype : \ETTABLE~\tabletype |
| } |
| |
| |
| :math:`\IDMEM~\memtype` |
| ....................... |
| |
| * The memory type :math:`\memtype` must be :ref:`valid <valid-memtype>`. |
| |
| * Then the import description is valid with type :math:`\ETMEM~\memtype`. |
| |
| .. math:: |
| \frac{ |
| \vdashmemtype \memtype \ok |
| }{ |
| C \vdashimportdesc \IDMEM~\memtype : \ETMEM~\memtype |
| } |
| |
| |
| :math:`\IDGLOBAL~\globaltype` |
| ............................. |
| |
| * The global type :math:`\globaltype` must be :ref:`valid <valid-globaltype>`. |
| |
| * Then the import description is valid with type :math:`\ETGLOBAL~\globaltype`. |
| |
| .. math:: |
| \frac{ |
| \vdashglobaltype \globaltype \ok |
| }{ |
| C \vdashimportdesc \IDGLOBAL~\globaltype : \ETGLOBAL~\globaltype |
| } |
| |
| |
| .. index:: module, type definition, function type, function, table, memory, global, element, data, start function, import, export, context |
| pair: validation; module |
| single: abstract syntax; module |
| .. _valid-module: |
| |
| Modules |
| ~~~~~~~ |
| |
| Modules are classified by their mapping from the :ref:`external types <syntax-externtype>` of their :ref:`imports <syntax-import>` to those of their :ref:`exports <syntax-export>`. |
| |
| A module is entirely *closed*, |
| that is, its components can only refer to definitions that appear in the module itself. |
| Consequently, no initial :ref:`context <context>` is required. |
| Instead, the context :math:`C` for validation of the module's content is constructed from the definitions in the module. |
| |
| * Let :math:`\module` be the module to validate. |
| |
| * Let :math:`C` be a :ref:`context <context>` where: |
| |
| * :math:`C.\CTYPES` is :math:`\module.\MTYPES`, |
| |
| * :math:`C.\CFUNCS` is :math:`\etfuncs(\X{it}^\ast)` concatenated with :math:`\X{ft}^\ast`, |
| with the import's :ref:`external types <syntax-externtype>` :math:`\X{it}^\ast` and the internal :ref:`function types <syntax-functype>` :math:`\X{ft}^\ast` as determined below, |
| |
| * :math:`C.\CTABLES` is :math:`\ettables(\X{it}^\ast)` concatenated with :math:`\X{tt}^\ast`, |
| with the import's :ref:`external types <syntax-externtype>` :math:`\X{it}^\ast` and the internal :ref:`table types <syntax-tabletype>` :math:`\X{tt}^\ast` as determined below, |
| |
| * :math:`C.\CMEMS` is :math:`\etmems(\X{it}^\ast)` concatenated with :math:`\X{mt}^\ast`, |
| with the import's :ref:`external types <syntax-externtype>` :math:`\X{it}^\ast` and the internal :ref:`memory types <syntax-memtype>` :math:`\X{mt}^\ast` as determined below, |
| |
| * :math:`C.\CGLOBALS` is :math:`\etglobals(\X{it}^\ast)` concatenated with :math:`\X{gt}^\ast`, |
| with the import's :ref:`external types <syntax-externtype>` :math:`\X{it}^\ast` and the internal :ref:`global types <syntax-globaltype>` :math:`\X{gt}^\ast` as determined below, |
| |
| * :math:`C.\CLOCALS` is empty, |
| |
| * :math:`C.\CLABELS` is empty, |
| |
| * :math:`C.\CRETURN` is empty. |
| |
| * Let :math:`C'` be the :ref:`context <context>` where :math:`C'.\CGLOBALS` is the sequence :math:`\etglobals(\X{it}^\ast)` and all other fields are empty. |
| |
| * Under the context :math:`C`: |
| |
| * For each :math:`\functype_i` in :math:`\module.\MTYPES`, |
| the :ref:`function type <syntax-functype>` :math:`\functype_i` must be :ref:`valid <valid-functype>`. |
| |
| * For each :math:`\func_i` in :math:`\module.\MFUNCS`, |
| the definition :math:`\func_i` must be :ref:`valid <valid-func>` with a :ref:`function type <syntax-functype>` :math:`\X{ft}_i`. |
| |
| * For each :math:`\table_i` in :math:`\module.\MTABLES`, |
| the definition :math:`\table_i` must be :ref:`valid <valid-table>` with a :ref:`table type <syntax-tabletype>` :math:`\X{tt}_i`. |
| |
| * For each :math:`\mem_i` in :math:`\module.\MMEMS`, |
| the definition :math:`\mem_i` must be :ref:`valid <valid-mem>` with a :ref:`memory type <syntax-memtype>` :math:`\X{mt}_i`. |
| |
| * For each :math:`\global_i` in :math:`\module.\MGLOBALS`: |
| |
| * Under the context :math:`C'`, |
| the definition :math:`\global_i` must be :ref:`valid <valid-global>` with a :ref:`global type <syntax-globaltype>` :math:`\X{gt}_i`. |
| |
| * For each :math:`\elem_i` in :math:`\module.\MELEM`, |
| the segment :math:`\elem_i` must be :ref:`valid <valid-elem>`. |
| |
| * For each :math:`\data_i` in :math:`\module.\MDATA`, |
| the segment :math:`\data_i` must be :ref:`valid <valid-data>`. |
| |
| * If :math:`\module.\MSTART` is non-empty, |
| then :math:`\module.\MSTART` must be :ref:`valid <valid-start>`. |
| |
| * For each :math:`\import_i` in :math:`\module.\MIMPORTS`, |
| the segment :math:`\import_i` must be :ref:`valid <valid-import>` with an :ref:`external type <syntax-externtype>` :math:`\X{it}_i`. |
| |
| * For each :math:`\export_i` in :math:`\module.\MEXPORTS`, |
| the segment :math:`\export_i` must be :ref:`valid <valid-export>` with :ref:`external type <syntax-externtype>` :math:`\X{et}_i`. |
| |
| * The length of :math:`C.\CTABLES` must not be larger than :math:`1`. |
| |
| * The length of :math:`C.\CMEMS` must not be larger than :math:`1`. |
| |
| * All export names :math:`\export_i.\ENAME` must be different. |
| |
| * Let :math:`\X{ft}^\ast` be the concatenation of the internal :ref:`function types <syntax-functype>` :math:`\X{ft}_i`, in index order. |
| |
| * Let :math:`\X{tt}^\ast` be the concatenation of the internal :ref:`table types <syntax-tabletype>` :math:`\X{tt}_i`, in index order. |
| |
| * Let :math:`\X{mt}^\ast` be the concatenation of the internal :ref:`memory types <syntax-memtype>` :math:`\X{mt}_i`, in index order. |
| |
| * Let :math:`\X{gt}^\ast` be the concatenation of the internal :ref:`global types <syntax-globaltype>` :math:`\X{gt}_i`, in index order. |
| |
| * Let :math:`\X{it}^\ast` be the concatenation of :ref:`external types <syntax-externtype>` :math:`\X{it}_i` of the imports, in index order. |
| |
| * Let :math:`\X{et}^\ast` be the concatenation of :ref:`external types <syntax-externtype>` :math:`\X{et}_i` of the exports, in index order. |
| |
| * Then the module is valid with :ref:`external types <syntax-externtype>` :math:`\X{it}^\ast \to \X{et}^\ast`. |
| |
| .. math:: |
| \frac{ |
| \begin{array}{@{}c@{}} |
| (\vdashfunctype \functype \ok)^\ast |
| \quad |
| (C \vdashfunc \func : \X{ft})^\ast |
| \quad |
| (C \vdashtable \table : \X{tt})^\ast |
| \quad |
| (C \vdashmem \mem : \X{mt})^\ast |
| \quad |
| (C' \vdashglobal \global : \X{gt})^\ast |
| \\ |
| (C \vdashelem \elem \ok)^\ast |
| \quad |
| (C \vdashdata \data \ok)^\ast |
| \quad |
| (C \vdashstart \start \ok)^? |
| \quad |
| (C \vdashimport \import : \X{it})^\ast |
| \quad |
| (C \vdashexport \export : \X{et})^\ast |
| \\ |
| \X{ift}^\ast = \etfuncs(\X{it}^\ast) |
| \qquad |
| \X{itt}^\ast = \ettables(\X{it}^\ast) |
| \qquad |
| \X{imt}^\ast = \etmems(\X{it}^\ast) |
| \qquad |
| \X{igt}^\ast = \etglobals(\X{it}^\ast) |
| \\ |
| C = \{ \CTYPES~\functype^\ast, \CFUNCS~\X{ift}^\ast~\X{ft}^\ast, \CTABLES~\X{itt}^\ast~\X{tt}^\ast, \CMEMS~\X{imt}^\ast~\X{mt}^\ast, \CGLOBALS~\X{igt}^\ast~\X{gt}^\ast \} |
| \\ |
| C' = \{ \CGLOBALS~\X{igt}^\ast \} |
| \qquad |
| |C.\CTABLES| \leq 1 |
| \qquad |
| |C.\CMEMS| \leq 1 |
| \qquad |
| (\export.\ENAME)^\ast ~\F{disjoint} |
| \end{array} |
| }{ |
| \vdashmodule \{ |
| \begin{array}[t]{@{}l@{}} |
| \MTYPES~\functype^\ast, |
| \MFUNCS~\func^\ast, |
| \MTABLES~\table^\ast, |
| \MMEMS~\mem^\ast, |
| \MGLOBALS~\global^\ast, \\ |
| \MELEM~\elem^\ast, |
| \MDATA~\data^\ast, |
| \MSTART~\start^?, |
| \MIMPORTS~\import^\ast, |
| \MEXPORTS~\export^\ast \} : \X{it}^\ast \to \X{et}^\ast \\ |
| \end{array} |
| } |
| |
| .. note:: |
| Most definitions in a module -- particularly functions -- are mutually recursive. |
| Consequently, the definition of the :ref:`context <context>` :math:`C` in this rule is recursive: |
| it depends on the outcome of validation of the function, table, memory, and global definitions contained in the module, |
| which itself depends on :math:`C`. |
| However, this recursion is just a specification device. |
| All types needed to construct :math:`C` can easily be determined from a simple pre-pass over the module that does not perform any actual validation. |
| |
| Globals, however, are not recursive. |
| The effect of defining the limited context :math:`C'` for validating the module's globals is that their initialization expressions can only access imported globals and nothing else. |
| |
| .. note:: |
| The restriction on the number of tables and memories may be lifted in future versions of WebAssembly. |