aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Wagner <mail@lukewagner.name>2015-05-18 23:41:49 -0500
committerLuke Wagner <mail@lukewagner.name>2015-05-20 19:54:17 -0500
commit09866685a2e20d20bfb6f2203fde81ebd0e004bc (patch)
tree786dc2d776e9509c981e09d842c471dcc0fc45fa
parent8587eca9aac9ffb5388abcdd720fbb8885a6fd4c (diff)
downloadnanowasm-design-09866685a2e20d20bfb6f2203fde81ebd0e004bc.tar.gz
Improve code loading and modules section
-rw-r--r--V1.md66
1 files changed, 48 insertions, 18 deletions
diff --git a/V1.md b/V1.md
index ae7a6d0..bc41709 100644
--- a/V1.md
+++ b/V1.md
@@ -10,6 +10,50 @@ precise descriptions of:
* the [AST semantics](AstSemantics.md)
* the [binary encoding](BinaryEncoding.md)
+## Modules
+* The primary unit of loadable, executable code is a *module*.
+ * In a host environment with ES6 modules (browser, node.js), a WebAssembly
+ module is loaded in the same way as an ES6 module (`import` statements,
+ `Reflect` API, `Worker` constructor, etc) and the result is reflected to
+ JS as an ES6 module object.
+* A module can declare a subset of its functions and global variables to be
+ *exports*. The meaning of exports (how and when they are called) is defined by
+ the host environment.
+ * In an environment with ES6 modules, the WebAssembly exports would be the
+ ES6 module object exports.
+ * A minimal shell environment might define `main` to be the only
+ meaningful export.
+ * We may want to define an `init` method in the spec that is always called
+ after loading a module and before any other exports are called.
+* A module can declare a set of *imports*. An import is a tuple containing a
+ module name, export name, and the type to use for the import within the
+ module. The host environment controls the mapping from module name to which module
+ is loaded.
+ * In an environment with ES6 modules, an import first passes the
+ module name to the [module loader pipeline](http://whatwg.github.io/loader)
+ and resulting ES6 module (which could be implemented in JS or WebAssembly)
+ is queried for the export name.
+* The spec defines the semantics of loading and calling exports of a
+ *single* module. The meaning of a call to an import is defined by
+ the host environment.
+ * In an environment with ES6 modules, there is no special case for when one
+ WebAssembly module imports another: they have separate [heaps](V1.md#heap)
+ and pointers cannot be passed between the two. Module imports encapsulate
+ the importer and importee.
+ * In a minimal shell environment, imports could be limited to
+ builtin modules (implemented by the shell) and/or shell scripts.
+ * The [dynamic linking](FutureFeatures.md#dynamic-linking) post-v.1 feature
+ would extend the semantics to include multiple modules and thus allow heap
+ and pointer sharing. Dynamic linking would be semantically distinct from
+ importing, though.
+* When compiling from C++, imports would be generated for unresolved
+ `extern` functions and calls to those `extern` functions would call the import.
+ * Thus, in an environment with ES6 modules, to synchronously call into JS from
+ C++, the C++ code would declare and call an unndefined `extern` function and
+ the target JS function would be given the (mangled) name of the `extern` and
+ put inside the imported ES6 module.
+* TODO: there is more to discuss here concerning APIs.
+
## Module structure
* At the top level, a module is ELF-like: a sequence of sections which declare their type and byte-length.
* Sections with unknown types would be skipped without error.
@@ -81,20 +125,6 @@ precise descriptions of:
directly into JS.
* TODO: there is no real proposal yet
-## Code loading and imports
- * The loadable unit of WebAssembly code is a *module*.
- * WebAssembly modules can be loaded declaratively (via import on page load) or imperatively (via API call)
- and can be compiled dynamically (from bytes, as defined by the binary format).
- * A natural integration point with JS would be to have WebAssembly modules be reflected to JS
- as ES6 Modules.
- * The module interface would mostly hide whether the module was JS or WebAssembly (except for things
- like `fun.toSource()`) and allow webapps to be naturally composed of both JS and WebAssembly modules.
- * ES6 Modules can be loaded declaratively (via imports) or imperatively (via API calls at runtime).
- * The ES6 Module API also allows dynamically generated modules (a JS module can be compiled from a string);
- building on this, WebAssembly modules could be dynamically compiled from an ArrayBuffer.
- * Just like ES6 modules, WebAssembly modules could import other modules (JS or WebAssembly); this would
- replace asm.js [FFIs](http://asmjs.org/spec/latest/index.html#external-code-and-data).
-
## Heap
* In v.1, when a WebAssembly module is loaded, it creates a new heap.
* The [dynamic linking](FutureFeatures.md#dynamic-linking) feature will be necessary for two
@@ -123,8 +153,8 @@ precise descriptions of:
for portable C/C++ code.
## Non-browser embedding
- * Host environments can define builtin modules that are implemented natively and thus be imported
- directly by WebAssembly modules.
+ * Host environments can define builtin modules that are implemented natively but can otherwise
+ be imported like [other modules](V1.md#code-loading-and-imports).
* For example, a WebAssembly shell might define a builtin `stdio` library with an export `puts`.
* Another example, in the browser, would be the WebIDL support mentioned in [future features](FutureFeatures.md).
* Where there is overlap between the browser and popular non-browser environments, a shared spec could be
@@ -135,8 +165,8 @@ precise descriptions of:
on core APIs like network and file I/O.
* To allow writing portable POSIX-like code (that ran in both browser and other environments), the
WebAssembly community would develop a shared repository of WebAssembly code that mapped between a
- POSIX-like interface and the host's builtin modules at either compile-time (#ifdefs) or run-time
- (feature-testing and conditional loading; both v.1 features).
+ POSIX-like interface and the host's builtin modules using compile-time #ifdefs or, after
+ [dynamic linking](FutureFeatures.md#dynamic-linking) was added, client-side dynamic feature testing.
* A symmetric example in JS would be the [ES6 Module Loader polyfill](https://github.com/ModuleLoader/es6-module-loader) library.
* The WebAssembly spec would thus not try to define any large portable libc-like library.
* However, certain features that are core to WebAssembly semantics that are found in native libc