Skip to content

Commit e3b5158

Browse files
authored
Merge pull request #76 from torch2424/type-embed-readme
Update README for type embeds
2 parents d50a8d0 + 6365cb9 commit e3b5158

File tree

4 files changed

+71
-125
lines changed

4 files changed

+71
-125
lines changed

README.md

Lines changed: 21 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,13 @@ Isomorphic library to handle passing high-level data structures between Assembly
3333

3434
## Features
3535

36-
- The library is Isomorphic. Meaning it supports both the Browser, and Node! And has ESM, CommonJS, and IIFE bundles! 🌐
36+
- The library is isomorphic. Meaning it supports both the Browser, and Node! And has ESM, AMD, CommonJS, and IIFE bundles! 🌐
3737
- Wraps around the [AssemblyScript Loader](https://github.com/AssemblyScript/assemblyscript/tree/master/lib/loader). The loader handles all the heavy-lifting of passing data into WebAssembly linear memory. 💪
3838
- Wraps around imported JavaScript functions, and exported AssemblyScript functions of the AssemblyScript Wasm Module. This allows high-level data types to be passed directly to exported AssemblyScript functions! 🤯
39-
- The library works at runtime, so no generated code that you have to maintain and make it play nicely in your environment. 🏃
40-
- Maintains great performance (relative to generating the corresponding JavaScript code), by using [Speculative Execution](https://en.wikipedia.org/wiki/Speculative_execution), and caching types passed between functions. 🤔
39+
- Moves a lot of work to compile-time using [AssemblyScript Transforms](https://www.assemblyscript.org/transforms.html#transforms) and completely avoids module-specific “glue code”. 🏃
4140
- Installable from package managers (npm), with a modern JavaScript API syntax. 📦
42-
- The library is [< 5KB (minified and gzip'd)](https://bundlephobia.com/result?p=as-bind) and tree-shakeable! 🌲
43-
- This library is currently (as of January, 2020) the [wasm-bindgen](https://github.com/rustwasm/wasm-bindgen) in the Rust/Wasm ecosystem, for AssemblyScript. 😀
41+
- The library is [< 4KB (minified and gzip'd)](https://bundlephobia.com/result?p=as-bind), _including_ the AssemblyScript Loader ! 🌲
42+
- This library is currently (as of January, 2020) the [wasm-bindgen](https://github.com/rustwasm/wasm-bindgen) of AssemblyScript. 😀
4443

4544
## Installation
4645

@@ -52,15 +51,14 @@ You can install as-bind in your project by running the following:
5251

5352
**1. Compiling your Assemblyscript**
5453

55-
To enable as-bind for your AssemblyScript Wasm modules, add the as-bind entrypoint when compiling your module:
54+
To enable as-bind for your AssemblyScript Wasm modules, add the as-bind transform when compiling your module:
5655

57-
`asc ./node_modules/as-bind/lib/assembly/as-bind.ts your-entryfile.ts --runtime incremental --exportRuntime [...other cli options...]`
56+
`asc your-entryfile.ts --exportRuntime --transform as-bind [...other cli options...]`
5857

5958
The things to notice are:
6059

61-
- `./node_modules/as-bind/lib/assembly/as-bind.ts` - This is the as-bind entryfile, used for exporting IDs of AssemblyScript classes so we can use them for instantiating new classes
62-
- `--runtime incremental` - This specifies that we are using the incremental runtime / garbage collection option (The AssemblyScript default). However, [all the runtime options](https://www.assemblyscript.org/garbage-collection.html) are supported (incremental, minimal, and stub).
63-
- `--exportRuntime` - This allows us to use the [AssemblyScript Garbage Collection functions added in 0.18.x](https://www.assemblyscript.org/garbage-collection.html)
60+
- `--transform as-bind` - This is the as-bind transform that runs at compile time. It embeds all the required type information into the WebAssembly Module.
61+
- `--exportRuntime` - This is required for the AssemblyScript Loader to work properly. It [exposes functions](https://www.assemblyscript.org/garbage-collection.html#runtime-interface) on the module to allocate memory from JavaScript.
6462

6563
For **optional testing purposes** , let's export an example function we can try in `your-entryfile.ts`:
6664

@@ -167,22 +165,9 @@ asyncTask();
167165

168166
## Supported Data Types
169167

170-
**TL;DR:** Currently Numbers, Strings, Typed Arrays, and common Array<T> types are supported. Returning a high-level data type from an imported JavaScript function, and better AssemblyScript Class support will be coming later. For more detailed type support information, please see the [`lib/asbind-instance/supported-ref-types.js`](./lib/asbind-instance/supported-ref-types.js) and [`test/assembly/test.ts`](./test/assembly/test.ts).
168+
All primitive types, ie. Numbers (`u8`, `f32`, ...) , Strings, Typed Arrays (`Uint8Array`, `Float32Array`, ...) are supported. All of those types can also be used with `Array<T>`.
171169

172-
<!-- Generated from: https://www.tablesgenerator.com/markdown_tables# -->
173-
174-
| Function Direction & AssemblyScript Type | Exported AssemblyScript Function Parameters | Exported AssemblyScript Function Return | Imported JavaScript Function Paramters | Imported JavaScript Function Return |
175-
| ------------------------------------------------------------------------------------------------------- | ------------------------------------------- | --------------------------------------- | -------------------------------------- | ----------------------------------- |
176-
| [Number (32-bit Integers and 32-bit / 64-bit Floats)](https://www.assemblyscript.org/types.html#types) | ✔️ | ✔️ | ✔️ | ✔️ |
177-
| [Strings](https://www.assemblyscript.org/stdlib/string.html#string) | ✔️ | ✔️ | ✔️ ||
178-
| [TypedArray](https://www.assemblyscript.org/stdlib/typedarray.html#typedarray) | ✔️ | ✔️ | ✔️ ||
179-
| [Array<T> (Numbers, strings, booleans, etc...)](https://www.assemblyscript.org/stdlib/array.html#array) | ✔️ | ✔️ | ✔️ ||
180-
181-
## Supported AssemblyScript Runtime Variants
182-
183-
as-bind only supports AssemblyScript modules compiled with the `--runtime full` (default), and `--runtime stub` flags. These should be the only supported modes, because these runtime variants specify that you would like types / objects to be created externally as well as internally. Other runtime variants would mean that you DO NOT want anything externally created for your wasm module.
184-
185-
Please see the [AssemblyScript Docs on runtime variants](https://docs.assemblyscript.org/details/runtime) for more information.
170+
Custom classes are currently not support, but planned.
186171

187172
## Reference API
188173

@@ -192,34 +177,14 @@ The default exported ESM class of `as-bind`, also available as `import { AsBind
192177

193178
#### Class Properties
194179

195-
The `AsBind` class is meant to vaugely act as the [WebAssembly](https://developer.mozilla.org/en-US/docs/WebAssembly) Object exposed to JavaScript environments.
180+
The `AsBind` class is meant to _vaguely_ act as the [WebAssembly](https://developer.mozilla.org/en-US/docs/WebAssembly) Object exposed to JavaScript environments.
196181

197182
##### version
198183

199184
`AsBind.version: string`
200185

201186
Value that is the current version of your imported AsBind.
202187

203-
##### RETURN_TYPES
204-
205-
`AsBind.RETURN_TYPES`
206-
207-
Constants (represented as JSON) of the supported return types on bound export functions. This is useful for forcing the return type on [bound export functions](#exports).
208-
209-
For example, this could be used like:
210-
211-
```typescript
212-
// Force our return type to our expected string
213-
asBindInstance.exports.myExportedFunctionThatReturnsAString.returnType =
214-
AsBind.RETURN_TYPES.STRING;
215-
const myString = asBindInstance.exports.myExportedFunctionThatReturnsAString();
216-
217-
// Force our return type to return a number (The pointer to the string)
218-
asBindInstance.exports.myExportedFunctionThatReturnsAString.returnType =
219-
AsBind.RETURN_TYPES.NUMBER;
220-
const myNumber = asBindInstance.exports.myExportedFunctionThatReturnsAString();
221-
```
222-
223188
##### instantiate
224189

225190
```typescript
@@ -256,55 +221,19 @@ This is a synchronous version of `AsBind.instantiate`. This does not accept a pr
256221
257222
#### Instance Properties
258223
259-
An AsBindInstance is vaugley similar to a [WebAssembly instance](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Instance).
260-
261-
##### exports
262-
263-
Similar to to [WebAssembly.Instance.prototype.exports](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Instance/exports), this is an object containing all of the exported fields from the WebAssembly module. However, **exported functions** are bound / wrapped in which they will handle passing the supported high-level data types to the exported AssemblyScript function.
224+
An AsBindInstance is vaguely similar to a [WebAssembly instance](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Instance).
264225
265-
Each **exported function** has the properties:
226+
##### loadedModule
266227
267-
- `shouldCacheTypes`
268-
- If you would like to disable type caching (speculative execution) for a particular function, you can do: `asBindInstance.exports.myFunction.shouldCacheTypes = false;`. Or set to true, to re-enable type caching.
269-
- `returnType`
270-
- (Reccomended for production usage) Set this value on a bound export function, to force it's return type. This should be set to a constant found on: [`AsBind.RETURN_TYPES`](#return_types). Defaults to `null`.
271-
- `unsafeReturnValue`
272-
- By default, all values (in particular [TypedArrays](https://www.assemblyscript.org/stdlib/typedarray.html#typedarray)) will be copied out of Wasm Memory, instead of giving direct read/write access. If you would like to use a view of the returned memory, you can do: `asBindInstance.exports.myFunction.unsafeReturnValue = true;`. For More context, please see the [AssemblyScript loader documentation](https://www.assemblyscript.org/loader.html#module-instance-utility) on array views.
273-
- After settings this flag on a function, it will then return it's values wrapped in an object, like so: `{ptr: /* The pointer or index in wasm memory the view is reffering to */, value: /* The returned value (TypedArray) that is backed directly by Wasm Memory */}`
228+
The raw, untouched instance of the WebAssembly Module.
274229
275-
##### unboundExports
230+
##### exports
276231
277-
This is essentially the same as the [WebAssembly.Instance.prototype.exports](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Instance/exports), this is an object containing all of the exported fields from the WebAssembly module. These are not bound / wrapped, so you can access the original exported functions.
232+
Similar to to [WebAssembly.Instance.prototype.exports](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Instance/exports), this is an object containing all of the exported fields from the WebAssembly module. However, **exported functions** are bound / wrapped in which they will handle passing the supported high-level data types to the exported AssemblyScript function.
278233
279234
##### importObject
280235
281-
Similar to to [WebAssembly.instantiateStreaming() importObject](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiateStreaming), This is the original passed importObject on instantiation, after the **importObject functions** are bound / wrapped by as-bind.
282-
283-
Each wrapped **importObject function** has the property: `shouldCacheTypes`. If you would like to disable type caching (speculative execution) for a particular function, you can do: `asBindInstance.importObject.myFunction.shouldCacheTypes = false;`. Or set to true, to re-enable type caching.
284-
285-
##### enableExportFunctionTypeCaching
286-
287-
Calling this method will (re-)enable type caching (speculative execution) for ALL exported functions on the AsBindInstance.
288-
289-
##### disableExportFunctionTypeCaching
290-
291-
Calling this method will disable type caching (speculative execution) for ALL exported functions on the AsBindInstance.
292-
293-
##### enableExportFunctionUnsafeReturnValue
294-
295-
Calling this method will (re-)enable unsafe return types for ALL exported functions on the AsBindInstance.
296-
297-
##### disableExportFunctionUnsafeReturnValue
298-
299-
Calling this method will disable unsafe return types for ALL exported functions on the AsBindInstance.
300-
301-
##### enableImportFunctionTypeCaching
302-
303-
Calling this method will (re-)enable type caching (speculative execution) for ALL importObject functions on the AsBindInstance.
304-
305-
##### disableImportFunctionTypeCaching
306-
307-
Calling this method will disable type caching (speculative execution) for ALL importObject functions on the AsBindInstance.
236+
Similar to to [WebAssembly.instantiateStreaming() importObject](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiateStreaming), this is the augmented `importObject`. It’s based on the original that was passed to one of the instantiation functions, but functions have been wrapped to handle high-level types.
308237
309238
## Motivation
310239
@@ -314,27 +243,15 @@ This library was inspired by several chats I had with some awesome buddies of mi
314243
315244
- While I was building [WasmByExample](https://wasmbyexample.dev/?programmingLanguage=assemblyscript) I wanted to start building the "High Level Data Structures" section. I then realized how much work it would be to maintain code for passing data between WebAssembly Linear memory would be for each data type, and how much work it would be to created each individual example. Then, my buddy [Ashley Williams](https://twitter.com/ag_dubs) helped me realize, if your docs are becoming too complex, it may be a good idea to write a tool. That way you have less docs to write, and users will have an easier time using your stuff!
316245
317-
Thus, this library was made to help AssemblyScript/JavaScript users build awesome things! I also want to give a huge thanks to the [AssemblyScript team](https://github.com/AssemblyScript/meta) and communitty for the help they provided me. I'm super appreciative of you all! 😄🎉
246+
Thus, this library was made to help AssemblyScript/JavaScript users build awesome things! I also want to give a huge thanks to the [AssemblyScript team](https://github.com/AssemblyScript/meta) and community for the help they provided me. I'm super appreciative of you all! 😄🎉
318247
319248
## Performance
320249
321-
**TL;DR** This library should be fast, but depending on your project you may want some more careful consideration. 🤔
250+
**TL;DR** This library should be pretty darn fast. 🤔
322251
323-
as-bind does all of its data passing at runtime. Meaning this will be slower than a code generated bindings generator, such as something like [wasm-bindgen](https://github.com/rustwasm/wasm-bindgen). This is because, as-bind needs to cycle through every supported type on every paremeter or return value for each function, whenever the function is called. However, this is mitigated due to the Speculative execution that the library implements.
252+
The transform embeds all the required type information of imported and exported functions into a custom section of the WebAssembly module. All the runtime does is utilize the AssemblyScript Loader to convert these types from JS to ASC and vice-versa. Apart from `Array<T>`, which needs to be handled recursively, the overhead is fairly static and minimal.
324253
325-
Which in this case means, the library by default will assume the type of value being passed to, or returned by a function will not change. Thus, the library will only have to cycle through the params once, cache the types, and then for calls to the functions after this it would be as fast as a code generated solution (in theory). This speculative execution can be turned off as specified in the Reference API.
326-
327-
If your project is doing one-off processing using a high level data type, this project should have a very small impact on performance of your project. However, if you project is doing its processing in a very time constrained loop (such as a game running at 60fps), you may want to be more considerate when choosing this library. The speculative execution should greatly help in the amount of time to pass high level data types, but if your game is already not running as fast as you would like, you may want to avoid this library, or even not using high level data types, for passing memory to your WebAssembly module. However, the library also exposes all original exports under the `AsBindInstance.unboundExports` as covered in the Reference API, so you could, in theory, still access the non-bound exports without any of the performance overhead if you don't require any of the binding / wrapping that AsBind does for you.
328-
329-
Eventually for the most performant option, we would want to do some JavaScript code generation in the AssemblyScript compiler itself, as part of an `as-bindgen` project for the most performant data passing.
330-
331-
In the future, these types of high-level data passing tools will not be needed for WebAssembly toolchains, once the [WebAssembly Inteface Types proposal](https://github.com/WebAssembly/interface-types/blob/master/proposals/interface-types/Explainer.md) lands, and this functionality is handled by the runtime / toolchain.
332-
333-
## Production
334-
335-
`as-bind` works by abstracting away using the [AssemblyScript Loader](https://www.assemblyscript.org/loader.html). For passing values into your AssemblyScript, it uses the Loader on your half to allocate memory, and then passes the pointer to the allocated memory. However, to pass a value back from AssemblyScript to JavaScript, AsBind will iterate through all the supported types until it finds a match (or doesn't in which case it just returns the number). However, returning a value _can sometimes_ conflict with something in AssemblyScript memory, as discovered in [#50](https://github.com/torch2424/as-bind/issues/50).
336-
337-
Thus, for production usage we highly reccomend that you set the [`returnType` property on your bound export functions](#exports) to ensure that this conflict does not happen. 😄
254+
In the future, these types of high-level data passing tools might not be needed at all, as the [WebAssembly Inteface Types proposal](https://github.com/WebAssembly/interface-types/blob/master/proposals/interface-types/Explainer.md) aims to give WebAssembly an understanding of higher-level types.
338255
339256
## Projects using as-bind
340257
@@ -344,14 +261,6 @@ Thus, for production usage we highly reccomend that you set the [`returnType` pr
344261
345262
_If you're project is using as-bind, and you would like to be featured here. Please open a README with links to your project, and if appropriate, explaining how as-bind is being used._ 😊
346263
347-
## FAQ and Common Issues
348-
349-
> I am calling my exports, but it is not returning the types that I am returning? It seems to be returning pointers?
350-
351-
This is probably because you are not adding the as-bind entry file. Please see the [Quick Start](#quick-start) on how to compile your AssemblyScript module with this entry file. If this still does not work, please take a look at the [Supported Types](#supported-types) to ensure what type you are trying to pass will work.
352-
353-
_Didn't find a solution to your problem? Feel free to open an issue!_
354-
355264
## Contributing
356265
357266
Contributions are definitely welcome! Feel free to open a PR for small fixes such as typos and things. Larger fixes, or new features should start out as an issue for discussion, in which then a PR should be made. 🥳

0 commit comments

Comments
 (0)