diff --git a/V1.md b/V1.md index ae7a6d0b..bc417091 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