aboutsummaryrefslogtreecommitdiff
path: root/Modules.md
diff options
context:
space:
mode:
authorLuke Wagner <luke@mozilla.com>2015-07-16 15:42:16 -1000
committerLuke Wagner <luke@mozilla.com>2015-07-24 10:53:59 -1000
commitcdaae53dc098de760b2784e45a99aae07e424e37 (patch)
tree2e478195f8f8e8b8239ccbd063c0e9c1c27cbb5d /Modules.md
parentf74c4a87968ecf73120cc4588e67c7ca06ab170f (diff)
downloadnanowasm-design-cdaae53dc098de760b2784e45a99aae07e424e37.tar.gz
Consolidate explanation of modules into a new Modules.md and improve explanation
Diffstat (limited to 'Modules.md')
-rw-r--r--Modules.md112
1 files changed, 112 insertions, 0 deletions
diff --git a/Modules.md b/Modules.md
new file mode 100644
index 0000000..6ccc29a
--- /dev/null
+++ b/Modules.md
@@ -0,0 +1,112 @@
+# Modules
+
+The distributable, loadable, and executable unit of code in WebAssembly
+is called a **module**. A module contains:
+* a set of [imports and exports](Modules.md#imports-and-exports);
+* a section defining the [initial state of linear memory](Modules.md#initial-state-of-linear-memory);
+* a section containing [code](Modules.md#code-section);
+* after the MVP, sections containing [debugging/symbol information](Tooling.md); and
+* possibly other sections in the future.
+
+While WebAssembly modules are designed to interoperate with ES6 modules
+in a Web environment (more details [below](Modules.md#integration-with-es6-modules)),
+WebAssembly modules are defined independently of JavaScript and do not require
+the host environment to include a JavaScript VM.
+
+## Imports and Exports
+
+A module defines a set of functions in its
+[code section](Modules.md#code-section) and can declare and name a subset of
+these functions to be **exports**. The meaning of exports (how and when they are
+called) is defined by the host environment. For example, a minimal shell
+environment might only probe for and call a `_start` export when given a module
+to execute.
+
+A module can declare a set of **imports**. An import is a tuple containing a
+module name, the name of an exported function to import from the named module,
+and the signature to use for that import within the importing module. Within a
+module, the import can be [directly called](AstSemantics.md#calls) like a
+function (according to its locally-declared signature).
+
+The WebAssembly spec does not define how imports are interpreted:
+* the host environment can interpret the module name as a file path, a URL,
+ a key in a fixed set of builtin modules or the host environment may invoke a
+ user-defined hook to resolve the module name to one of these;
+* the module name does not need to resolve to a WebAssembly module; it
+ could resolve to a builtin module (implemented by the host environment) or a
+ module written in another, compatible language; and
+* the meaning of calling an imported function is host-defined.
+
+The open-ended nature of module imports allow them to be used to expose
+arbitrary host environment functionality to WebAssembly code, similar to a
+native `syscall`. For example, a shell environment could define a builtin
+`stdio` module with an export `puts`.
+
+In C/C++, an undefined `extern` declaration could be compiled to an import and
+C/C++ calls to this `extern` would then be compiled to calls to this import. This
+is one way low-level C/C++ libraries could call out of WebAssembly in order to
+implement portable source-level interfaces (e.g., POSIX, OpenGL or SDL) in
+terms of host-specific functionality.
+
+### Integration with ES6 modules
+
+While ES6 defines how to parse, link and execute a module, ES6 does not
+define when this parsing/linking/execution occurs. An additional extension
+to the HTML spec is required to say when a script is parsed as a module instead
+of normal global code. This work is [ongoing](TODO). Currently, the following
+entry points for modules are being considered:
+* `<script type="module">`;
+* an overload to the `Worker` constructor;
+* an overload to the `importScripts` Worker API;
+
+Additionally, an ES6 module can recursively import other modules via `import`
+statements.
+
+For WebAssembly/ES6 module integration, the idea is that all the above module
+entry points could also load WebAssembly modules simply by passing the URL of a
+WebAssembly module. The distinction of whether the module was WebAssembly or ES6
+code could be made by namespacing or by content sniffing the first bytes of the
+fetched resource (which, for WebAssembly, would be a non-ASCII&mdash;and thus
+illegal as JavaScript&mdash;[magic number](https://en.wikipedia.org/wiki/Magic_number_%28programming%29)).
+Thus, the whole module-loading pipeline (resolving the name to a URL, fetching
+the URL, any other [loader hooks](http://whatwg.github.io/loader/)) would be
+shared and only the final stage would fork into either the JavaScript parser or
+the WebAssembly decoder.
+
+Any non-builtin imports from within a WebAssembly module would be treated as
+if they were `import` statements of an ES6 module. If an ES6 module `import`ed
+a WebAssembly module, the WebAssembly module's exports would be linked as if
+they were the exports of an ES6 module. Once parsing and linking phases
+were complete, a WebAssembly module would have its `_start` function called in
+place of executing the ES6 module top-level script.
+
+This integration strategy should allow WebAssembly modules to be fairly
+interchangeable with ES6 modules (ignoring
+[GC/Web API](FutureFeatures.md#gc/dom-integration) signature restrictions of the
+WebAssembly MVP) and thus it should be natural to compose a single application
+from both kinds of code. This goal motivates the
+[semantic design](AstSemantics.md#linear-memory) of giving each WebAssembly
+module its own disjoint linear memory. Otherwise, if all modules shared a single
+linear memory (all modules with the same realm? origin? window?&mdash;even the
+scope of "all" is a nuanced question), a single app using multiple
+independent libraries would have to hope that all the WebAssembly modules
+transitively used by those libraries "played well" together (e.g., explicitly
+shared `malloc` and coordinated global address ranges). Instead, the
+[dynamic linking future feature](FutureFeatures.md#dynamic-linking) is intended
+to allow *explicitly* sharing linear memory between multiple modules.
+
+## Initial state of linear memory
+
+A module will contain a section declaring the heap size (initial and maximum
+size allowed by `sbrk`) and the initial contents of memory (analogous to
+`.data`, `.rodata`, `.bss` sections in native executables).
+
+## Code section
+
+The WebAssembly spec defines the code section of a module in terms of an
+[Abstract Syntax Tree](AstSemantics.md) (AST). Additionally, the spec defines
+two concrete representations of the AST: a [binary format](BinaryEncoding.md)
+which is natively decoded by the browser and a [text format](TextFormat.md)
+which is intended to be read and written by humans. This design separates
+the concerns of specifying and reasoning about behavior, over-the-wire size
+and compilation speed, and ergonomic syntax.