Add comprehensive installation and setup documentation

- Add GETTING_STARTED.md with quick start guide and development modes
- Add INSTALL.sh automated installation script
- Add INSTALLATION_CHECKLIST.md, INSTALLATION_SUCCESS.md, and INSTALLATION_SUMMARY.md
- Add QUICK_REFERENCE.md for common commands
- Add SETUP_GUIDE.md with detailed setup instructions
- Update README.md with improved project overview
- Add did-wallet app dependencies and node_modules
This commit is contained in:
Dorian
2026-01-27 17:18:21 +00:00
parent a81f655133
commit 0d073fa89e
22658 changed files with 4494151 additions and 6 deletions

View File

@@ -0,0 +1,191 @@
![AS](https://avatars1.githubusercontent.com/u/28916798?s=48) AssemblyScript Loader
======================
A convenient loader for AssemblyScript modules. Demangles module exports to a friendly object structure compatible with WebIDL and TypeScript definitions and provides some useful utility to read/write data from/to memory.
Usage
-----
```js
const loader = require("@assemblyscript/loader");
...
```
API
---
* **instantiate**<`T`>(moduleOrBuffer: `WebAssembly.Module | BufferSource | Response | PromiseLike<WebAssembly.Module | BufferSource | Response>`, imports?: `WasmImports`): `Promise<ASUtil & T>`<br />
Asynchronously instantiates an AssemblyScript module from anything that can be instantiated.
* **instantiateSync**<`T`>(moduleOrBuffer: `WebAssembly.Module | BufferSource`, imports?: `WasmImports`): `ASUtil & T`<br />
Synchronously instantiates an AssemblyScript module from a WebAssembly.Module or binary buffer.
* **instantiateStreaming**<`T`>(response: `Response | PromiseLike<Response>`, imports?: `WasmImports`): `Promise<ASUtil & T>`<br />
Asynchronously instantiates an AssemblyScript module from a response, i.e. as obtained by `fetch`.
* **demangle**<`T`>(exports: `WasmExports`, baseModule?: `Object`): `T`<br />
Demangles an AssemblyScript module's exports to a friendly object structure. You usually don't have to call this manually as instantiation does this implicitly.
**Note** that `T` above can either be omitted if the structure of the module is unknown, or can reference a `.d.ts` (i.e. `typeof MyModule`) as produced by the compiler with the `-d` option.
Besides demangling classes exported from your entry file to a handy object structure one can use like JS objects, instances are automatically populated with useful utility:
* **_start**(): `void`<br />
Explicit start function if the `--explicitStart` option is used. Must be called before any other exports if present.
* **__allocString**(str: `string`): `number`<br />
Allocates a new string in the module's memory and returns a reference (pointer) to it.
```ts
var ptr = module.__retain(module.__allocString("hello world"));
...
module.__release(ptr);
```
* **__getString**(ptr: `number`): `string`<br />
Copies a string's value from the module's memory.
```ts
var str = module.__getString(ptr);
...
```
* **__getArrayBuffer**(ptr: `number`): `ArrayBuffer`<br />
Copies an ArrayBuffer's value from the module's memory.
* **__getArray**(ptr: `number`): `number[]`<br />
Copies an array's values from the module's memory. Infers the array type from RTTI.
```ts
var arr = module.__getArray(ptr);
...
```
If the type of the array is known beforehand, the following slightly faster helpers that don't infer the type can be used:
**__getInt8Array**(ptr: `number`): `Int8Array`<br />
**__getUint8Array**(ptr: `number`): `Uint8Array`<br />
**__getUint8ClampedArray**(ptr: `number`): `Uint8ClampedArray`<br />
**__getInt16Array**(ptr: `number`): `Int16Array`<br />
**__getUint16Array**(ptr: `number`): `Uint16Array`<br />
**__getInt32Array**(ptr: `number`): `Int32Array`<br />
**__getUint32Array**(ptr: `number`): `Uint32Array`<br />
**__getInt64Array**(ptr: `number`): `BigInt64Array`<br />
**__getUint64Array**(ptr: `number`): `BigUint64Array`<br />
**__getFloat32Array**(ptr: `number`): `Float32Array`<br />
**__getFloat64Array**(ptr: `number`): `Float64Array`
* **__getArrayView**(ptr: `number`): `TypedArray`<br />
Gets a live view on the values of an array in the module's memory. Infers the array type from RTTI.
This differs from `__getArray` in that the data isn't copied but remains *live* in both directions. That's faster but also unsafe because if the array grows or becomes released, the view will no longer represent the correct memory region and modifying its values in this state will most likely corrupt memory. Use, but use with care.
If the type of the array is known beforehand, the following slightly faster helpers that don't infer the type can be used:
**__getInt8ArrayView**(ptr: `number`): `Int8Array`<br />
**__getUint8ArrayView**(ptr: `number`): `Uint8Array`<br />
**__getUint8ClampedArrayView**(ptr: `number`): `Uint8ClampedArray`<br />
**__getInt16ArrayView**(ptr: `number`): `Int16Array`<br />
**__getUint16ArrayView**(ptr: `number`): `Uint16Array`<br />
**__getInt32ArrayView**(ptr: `number`): `Int32Array`<br />
**__getUint32ArrayView**(ptr: `number`): `Uint32Array`<br />
**__getInt64ArrayView**(ptr: `number`): `BigInt64Array`<br />
**__getUint64ArrayView**(ptr: `number`): `BigUint64Array`<br />
**__getFloat32ArrayView**(ptr: `number`): `Float32Array`<br />
**__getFloat64ArrayView**(ptr: `number`): `Float64Array`
* **__retain**(ptr: `number`): `number`<br />
Retains a reference to a managed object externally, making sure that it doesn't become collected prematurely. Returns the pointer.
* **__release**(ptr: `number`): `void`<br />
Releases a previously retained reference to a managed object, allowing the runtime to collect it once its reference count reaches zero.
* **__alloc**(size: `number`, id: `number`): `number`<br />
Allocates an instance of the class represented by the specified id. If you are using `MyClass` for example, the best way to know the id and the necessary size is an `export const MYCLASS_ID = idof<MyClass>()` and an `export const MYCLASS_SIZE = offsetof<MyClass>()`. Afterwards, use the respective views to assign values to the class's memory while making sure to retain interior references to other managed objects once. When done with the class, make sure to release it, which will automatically release any interior references once the class becomes collected.
```ts
var ptr = module.__retain(module.__alloc(module.MYCLASS_SIZE, module.MYCLASS_ID));
const F32 = new Float32Array(module.memory.buffer);
F32[ptr + MYCLASS_BASICFIELD1_OFFSET >>> 2] = field1_value_f32;
const U32 = new Uint32Array(module.memory.buffer);
U32[ptr + MYCLASS_MANAGEDFIELD2_OFFSET >>> 2] = module.__retain(field2_value_ptr);
...
module.__release(ptr);
```
* **__allocArray**(id: `number`, values: `number[]`): `number`<br />
Allocates a new array in the module's memory and returns a reference (pointer) to it.
Automatically retains interior pointers. The `id` is the unique runtime id of the respective array class. If you are using `Int32Array` for example, the best way to know the id is an `export const INT32ARRAY_ID = idof<Int32Array>()`. When done with the array, make sure to release it.
```ts
var ptr = module.__retain(module.__allocArray(module.INT32ARRAY, [1, 2, 3]));
...
module.__release(ptr);
```
* **__instanceof**(ptr: `number`, baseId: `number`): `boolean`<br />
Tests whether an object is an instance of the class represented by the specified base id.
```ts
if (module.__instanceof(ptr, module.MYCLASS_ID)) {
...
}
```
* **__collect**(): `void`<br />
Forces a cycle collection. Only relevant if objects potentially forming reference cycles are used.
**Note** that the views like `I32` above will automatically be updated when the module's memory grows. Don't cache these if this can happen.
**Note** that the allocation and ownership features above require the `full` (this is the default) or the `stub` runtime to be present in your module. Other runtime variations do not export this functionality without further ado (so the compiler can eliminate what's dead code).
**Note** that references returned from exported functions have already been retained for you and the runtime expects that you release them once not needed anymore. This is also true for constructors and getters.
**Beware that your module is likely going to explode with seemingly random errors when using the allocation and ownership features incorrectly!**
* Use the correct ids, sizes and layouts (C-style non-packed, export `offsetof<MyClass>("myField")` in case of doubt)
* Clear unused memory to zero
* Retain what you allocate
* Retain interior pointers (except in `__allocArray`)
* Don't retain what's returned (is already retained for you)
* Release when you're done with something and don't ever use it again
Examples
--------
### Instantiating a module
The **asynchronous API** is analogous to [WebAssembly.instantiate](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiate) and [WebAssembly.instantiateStreaming](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiateStreaming)
```js
const myModule = await loader.instantiate(myModuleBuffer, myImports);
const myModule = await loader.instantiateStreaming(fetch("myModule.wasm"), myImports);
```
with `loader.instantiate` actually accepting anything that can be instantiated for convenience:
```js
const myModule = await loader.instantiate(fs.promises.readFile("myModule.wasm"), myImports);
const myModule = await loader.instantiate(fetch("myModule.wasm"), myImports);
...
```
If `WebAssembly.instantiateStreaming` is not supported by the environment a fallback is applied.
The **synchronous API** utilizes [new WebAssembly.Instance](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Instance#Constructor_Syntax) and [new WebAssembly.Module](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Module#Constructor_Syntax), which is useful if the goal is to immediately re-export as a node module for example:
```js
module.exports = loader.instantiateSync(fs.readFileSync("myModule.wasm"), myImports);
```
Note, though, that browsers have relatively tight limits for synchronous compilation and instantiation because these block the main thread, hence it is recommended to use the asynchronous API in browsers.
### Usage with TypeScript definitions produced by the compiler
The compiler is able to emit definitions using the `-d` command line option that are compatible with modules demangled by the loader, and these can be used for proper typings in development:
```ts
import MyModule from "myModule"; // pointing at the d.ts
const myModule = await loader.instatiate<typeof MyModule>(fs.promises.readFile("myModule.wasm"), myImports);
```

View File

@@ -0,0 +1,104 @@
/// <reference lib="esnext.bigint" />
/** WebAssembly imports with two levels of nesting. */
interface ImportsObject extends Record<string, any> {
env?: {
memory?: WebAssembly.Memory,
table?: WebAssembly.Table,
abort?(msg: number, file: number, line: number, column: number): void,
trace?(msg: number, numArgs?: number, ...args: number[]): void
};
}
/** Utility mixed in by the loader. */
interface ASUtil {
memory?: WebAssembly.Memory;
table?: WebAssembly.Table;
/** Explicit start function, if requested. */
_start(): void;
/** Allocates a new string in the module's memory and returns a reference (pointer) to it. */
__allocString(str: string): number;
/** Allocates a new array in the module's memory and returns a reference (pointer) to it. */
__allocArray(id: number, values: ArrayLike<number>): number;
/** Copies a string's value from the module's memory. */
__getString(ptr: number): string;
/** Copies an ArrayBuffer's value from the module's memory. */
__getArrayBuffer(ptr: number): ArrayBuffer;
/** Copies an array's values from the module's memory. Infers the array type from RTTI. */
__getArray(ptr: number): number[];
/** Copies an Int8Array's values from the module's memory. */
__getInt8Array(ptr: number): Int8Array;
/** Copies an Uint8Array's values from the module's memory. */
__getUint8Array(ptr: number): Uint8Array;
/** Copies an Uint8ClampedArray's values from the module's memory. */
__getUint8ClampedArray(ptr: number): Uint8ClampedArray;
/** Copies an Int16Array's values from the module's memory. */
__getInt16Array(ptr: number): Int16Array;
/** Copies an Uint16Array's values from the module's memory. */
__getUint16Array(ptr: number): Uint16Array;
/** Copies an Int32Array's values from the module's memory. */
__getInt32Array(ptr: number): Int32Array;
/** Copies an Uint32Array's values from the module's memory. */
__getUint32Array(ptr: number): Uint32Array;
/** Copies an Int32Array's values from the module's memory. */
__getInt64Array?(ptr: number): BigInt64Array;
/** Copies an Uint32Array's values from the module's memory. */
__getUint64Array?(ptr: number): BigUint64Array;
/** Copies a Float32Array's values from the module's memory. */
__getFloat32Array(ptr: number): Float32Array;
/** Copies a Float64Array's values from the module's memory. */
__getFloat64Array(ptr: number): Float64Array;
/** Gets a live view on an array's values in the module's memory. Infers the array type from RTTI. */
__getArrayView(ptr: number): ArrayBufferView;
/** Gets a live view on an Int8Array's values in the module's memory. */
__getInt8ArrayView(ptr: number): Int8Array;
/** Gets a live view on an Uint8Array's values in the module's memory. */
__getUint8ArrayView(ptr: number): Uint8Array;
/** Gets a live view on an Uint8ClampedArray's values in the module's memory. */
__getUint8ClampedArrayView(ptr: number): Uint8ClampedArray;
/** Gets a live view on an Int16Array's values in the module's memory. */
__getInt16ArrayView(ptr: number): Int16Array;
/** Gets a live view on an Uint16Array's values in the module's memory. */
__getUint16ArrayView(ptr: number): Uint16Array;
/** Gets a live view on an Int32Array's values in the module's memory. */
__getInt32ArrayView(ptr: number): Int32Array;
/** Gets a live view on an Uint32Array's values in the module's memory. */
__getUint32ArrayView(ptr: number): Uint32Array;
/** Gets a live view on an Int32Array's values in the module's memory. */
__getInt64ArrayView?(ptr: number): BigInt64Array;
/** Gets a live view on an Uint32Array's values in the module's memory. */
__getUint64ArrayView?(ptr: number): BigUint64Array;
/** Gets a live view on a Float32Array's values in the module's memory. */
__getFloat32ArrayView(ptr: number): Float32Array;
/** Gets a live view on a Float64Array's values in the module's memory. */
__getFloat64ArrayView(ptr: number): Float64Array;
/** Retains a reference to a managed object externally, making sure that it doesn't become collected prematurely. Returns the pointer. */
__retain(ptr: number): number;
/** Releases a previously retained reference to a managed object, allowing the runtime to collect it once its reference count reaches zero. */
__release(ptr: number): void;
/** Forcefully resets the heap to its initial offset, effectively clearing dynamic memory. Stub runtime only. */
__reset?(): void;
/** Allocates an instance of the class represented by the specified id. */
__alloc(size: number, id: number): number;
/** Tests whether a managed object is an instance of the class represented by the specified base id. */
__instanceof(ptr: number, baseId: number): boolean;
/** Forces a cycle collection. Only relevant if objects potentially forming reference cycles are used. */
__collect(): void;
}
/** Asynchronously instantiates an AssemblyScript module from anything that can be instantiated. */
export declare function instantiate<T extends {}>(source: WebAssembly.Module | BufferSource | Response | PromiseLike<WebAssembly.Module | BufferSource | Response>, imports?: ImportsObject): Promise<ASUtil & T>;
/** Synchronously instantiates an AssemblyScript module from a WebAssembly.Module or binary buffer. */
export declare function instantiateSync<T extends {}>(source: WebAssembly.Module | BufferSource, imports?: ImportsObject): ASUtil & T;
/** Asynchronously instantiates an AssemblyScript module from a response, i.e. as obtained by `fetch`. */
export declare function instantiateStreaming<T extends {}>(source: Response | PromiseLike<Response>, imports?: ImportsObject): Promise<ASUtil & T>;
/** Demangles an AssemblyScript module's exports to a friendly object structure. */
export declare function demangle<T extends {}>(exports: {}, baseModule?: {}): T;

View File

@@ -0,0 +1,417 @@
"use strict";
// Runtime header offsets
const ID_OFFSET = -8;
const SIZE_OFFSET = -4;
// Runtime ids
const ARRAYBUFFER_ID = 0;
const STRING_ID = 1;
const ARRAYBUFFERVIEW_ID = 2;
// Runtime type information
const ARRAYBUFFERVIEW = 1 << 0;
const ARRAY = 1 << 1;
const SET = 1 << 2;
const MAP = 1 << 3;
const VAL_ALIGN_OFFSET = 5;
const VAL_ALIGN = 1 << VAL_ALIGN_OFFSET;
const VAL_SIGNED = 1 << 10;
const VAL_FLOAT = 1 << 11;
const VAL_NULLABLE = 1 << 12;
const VAL_MANAGED = 1 << 13;
const KEY_ALIGN_OFFSET = 14;
const KEY_ALIGN = 1 << KEY_ALIGN_OFFSET;
const KEY_SIGNED = 1 << 19;
const KEY_FLOAT = 1 << 20;
const KEY_NULLABLE = 1 << 21;
const KEY_MANAGED = 1 << 22;
// Array(BufferView) layout
const ARRAYBUFFERVIEW_BUFFER_OFFSET = 0;
const ARRAYBUFFERVIEW_DATASTART_OFFSET = 4;
const ARRAYBUFFERVIEW_DATALENGTH_OFFSET = 8;
const ARRAYBUFFERVIEW_SIZE = 12;
const ARRAY_LENGTH_OFFSET = 12;
const ARRAY_SIZE = 16;
const BIGINT = typeof BigUint64Array !== "undefined";
const THIS = Symbol();
const CHUNKSIZE = 1024;
/** Gets a string from an U32 and an U16 view on a memory. */
function getStringImpl(buffer, ptr) {
const U32 = new Uint32Array(buffer);
const U16 = new Uint16Array(buffer);
var length = U32[(ptr + SIZE_OFFSET) >>> 2] >>> 1;
var offset = ptr >>> 1;
if (length <= CHUNKSIZE) return String.fromCharCode.apply(String, U16.subarray(offset, offset + length));
const parts = [];
do {
const last = U16[offset + CHUNKSIZE - 1];
const size = last >= 0xD800 && last < 0xDC00 ? CHUNKSIZE - 1 : CHUNKSIZE;
parts.push(String.fromCharCode.apply(String, U16.subarray(offset, offset += size)));
length -= size;
} while (length > CHUNKSIZE);
return parts.join("") + String.fromCharCode.apply(String, U16.subarray(offset, offset + length));
}
/** Prepares the base module prior to instantiation. */
function preInstantiate(imports) {
const baseModule = {};
function getString(memory, ptr) {
if (!memory) return "<yet unknown>";
return getStringImpl(memory.buffer, ptr);
}
// add common imports used by stdlib for convenience
const env = (imports.env = imports.env || {});
env.abort = env.abort || function abort(mesg, file, line, colm) {
const memory = baseModule.memory || env.memory; // prefer exported, otherwise try imported
throw Error("abort: " + getString(memory, mesg) + " at " + getString(memory, file) + ":" + line + ":" + colm);
}
env.trace = env.trace || function trace(mesg, n) {
const memory = baseModule.memory || env.memory;
console.log("trace: " + getString(memory, mesg) + (n ? " " : "") + Array.prototype.slice.call(arguments, 2, 2 + n).join(", "));
}
imports.Math = imports.Math || Math;
imports.Date = imports.Date || Date;
return baseModule;
}
/** Prepares the final module once instantiation is complete. */
function postInstantiate(baseModule, instance) {
const rawExports = instance.exports;
const memory = rawExports.memory;
const table = rawExports.table;
const alloc = rawExports["__alloc"];
const retain = rawExports["__retain"];
const rttiBase = rawExports["__rtti_base"] || ~0; // oob if not present
/** Gets the runtime type info for the given id. */
function getInfo(id) {
const U32 = new Uint32Array(memory.buffer);
const count = U32[rttiBase >>> 2];
if ((id >>>= 0) >= count) throw Error("invalid id: " + id);
return U32[(rttiBase + 4 >>> 2) + id * 2];
}
/** Gets the runtime base id for the given id. */
function getBase(id) {
const U32 = new Uint32Array(memory.buffer);
const count = U32[rttiBase >>> 2];
if ((id >>>= 0) >= count) throw Error("invalid id: " + id);
return U32[(rttiBase + 4 >>> 2) + id * 2 + 1];
}
/** Gets the runtime alignment of a collection's values. */
function getValueAlign(info) {
return 31 - Math.clz32((info >>> VAL_ALIGN_OFFSET) & 31); // -1 if none
}
/** Gets the runtime alignment of a collection's keys. */
function getKeyAlign(info) {
return 31 - Math.clz32((info >>> KEY_ALIGN_OFFSET) & 31); // -1 if none
}
/** Allocates a new string in the module's memory and returns its retained pointer. */
function __allocString(str) {
const length = str.length;
const ptr = alloc(length << 1, STRING_ID);
const U16 = new Uint16Array(memory.buffer);
for (var i = 0, p = ptr >>> 1; i < length; ++i) U16[p + i] = str.charCodeAt(i);
return ptr;
}
baseModule.__allocString = __allocString;
/** Reads a string from the module's memory by its pointer. */
function __getString(ptr) {
const buffer = memory.buffer;
const id = new Uint32Array(buffer)[ptr + ID_OFFSET >>> 2];
if (id !== STRING_ID) throw Error("not a string: " + ptr);
return getStringImpl(buffer, ptr);
}
baseModule.__getString = __getString;
/** Gets the view matching the specified alignment, signedness and floatness. */
function getView(alignLog2, signed, float) {
const buffer = memory.buffer;
if (float) {
switch (alignLog2) {
case 2: return new Float32Array(buffer);
case 3: return new Float64Array(buffer);
}
} else {
switch (alignLog2) {
case 0: return new (signed ? Int8Array : Uint8Array)(buffer);
case 1: return new (signed ? Int16Array : Uint16Array)(buffer);
case 2: return new (signed ? Int32Array : Uint32Array)(buffer);
case 3: return new (signed ? BigInt64Array : BigUint64Array)(buffer);
}
}
throw Error("unsupported align: " + alignLog2);
}
/** Allocates a new array in the module's memory and returns its retained pointer. */
function __allocArray(id, values) {
const info = getInfo(id);
if (!(info & (ARRAYBUFFERVIEW | ARRAY))) throw Error("not an array: " + id + " @ " + info);
const align = getValueAlign(info);
const length = values.length;
const buf = alloc(length << align, ARRAYBUFFER_ID);
const arr = alloc(info & ARRAY ? ARRAY_SIZE : ARRAYBUFFERVIEW_SIZE, id);
const U32 = new Uint32Array(memory.buffer);
U32[arr + ARRAYBUFFERVIEW_BUFFER_OFFSET >>> 2] = retain(buf);
U32[arr + ARRAYBUFFERVIEW_DATASTART_OFFSET >>> 2] = buf;
U32[arr + ARRAYBUFFERVIEW_DATALENGTH_OFFSET >>> 2] = length << align;
if (info & ARRAY) U32[arr + ARRAY_LENGTH_OFFSET >>> 2] = length;
const view = getView(align, info & VAL_SIGNED, info & VAL_FLOAT);
if (info & VAL_MANAGED) {
for (let i = 0; i < length; ++i) view[(buf >>> align) + i] = retain(values[i]);
} else {
view.set(values, buf >>> align);
}
return arr;
}
baseModule.__allocArray = __allocArray;
/** Gets a live view on an array's values in the module's memory. Infers the array type from RTTI. */
function __getArrayView(arr) {
const U32 = new Uint32Array(memory.buffer);
const id = U32[arr + ID_OFFSET >>> 2];
const info = getInfo(id);
if (!(info & ARRAYBUFFERVIEW)) throw Error("not an array: " + id);
const align = getValueAlign(info);
var buf = U32[arr + ARRAYBUFFERVIEW_DATASTART_OFFSET >>> 2];
const length = info & ARRAY
? U32[arr + ARRAY_LENGTH_OFFSET >>> 2]
: U32[buf + SIZE_OFFSET >>> 2] >>> align;
return getView(align, info & VAL_SIGNED, info & VAL_FLOAT)
.subarray(buf >>>= align, buf + length);
}
baseModule.__getArrayView = __getArrayView;
/** Copies an array's values from the module's memory. Infers the array type from RTTI. */
function __getArray(arr) {
const input = __getArrayView(arr);
const len = input.length;
const out = new Array(len);
for (let i = 0; i < len; i++) out[i] = input[i];
return out;
}
baseModule.__getArray = __getArray;
/** Copies an ArrayBuffer's value from the module's memory. */
function __getArrayBuffer(ptr) {
const buffer = memory.buffer;
const length = new Uint32Array(buffer)[ptr + SIZE_OFFSET >>> 2];
return buffer.slice(ptr, ptr + length);
}
baseModule.__getArrayBuffer = __getArrayBuffer;
/** Copies a typed array's values from the module's memory. */
function getTypedArray(Type, alignLog2, ptr) {
return new Type(getTypedArrayView(Type, alignLog2, ptr));
}
/** Gets a live view on a typed array's values in the module's memory. */
function getTypedArrayView(Type, alignLog2, ptr) {
const buffer = memory.buffer;
const U32 = new Uint32Array(buffer);
const bufPtr = U32[ptr + ARRAYBUFFERVIEW_DATASTART_OFFSET >>> 2];
return new Type(buffer, bufPtr, U32[bufPtr + SIZE_OFFSET >>> 2] >>> alignLog2);
}
baseModule.__getInt8Array = getTypedArray.bind(null, Int8Array, 0);
baseModule.__getInt8ArrayView = getTypedArrayView.bind(null, Int8Array, 0);
baseModule.__getUint8Array = getTypedArray.bind(null, Uint8Array, 0);
baseModule.__getUint8ArrayView = getTypedArrayView.bind(null, Uint8Array, 0);
baseModule.__getUint8ClampedArray = getTypedArray.bind(null, Uint8ClampedArray, 0);
baseModule.__getUint8ClampedArrayView = getTypedArrayView.bind(null, Uint8ClampedArray, 0);
baseModule.__getInt16Array = getTypedArray.bind(null, Int16Array, 1);
baseModule.__getInt16ArrayView = getTypedArrayView.bind(null, Int16Array, 1);
baseModule.__getUint16Array = getTypedArray.bind(null, Uint16Array, 1);
baseModule.__getUint16ArrayView = getTypedArrayView.bind(null, Uint16Array, 1);
baseModule.__getInt32Array = getTypedArray.bind(null, Int32Array, 2);
baseModule.__getInt32ArrayView = getTypedArrayView.bind(null, Int32Array, 2);
baseModule.__getUint32Array = getTypedArray.bind(null, Uint32Array, 2);
baseModule.__getUint32ArrayView = getTypedArrayView.bind(null, Uint32Array, 2);
if (BIGINT) {
baseModule.__getInt64Array = getTypedArray.bind(null, BigInt64Array, 3);
baseModule.__getInt64ArrayView = getTypedArrayView.bind(null, BigInt64Array, 3);
baseModule.__getUint64Array = getTypedArray.bind(null, BigUint64Array, 3);
baseModule.__getUint64ArrayView = getTypedArrayView.bind(null, BigUint64Array, 3);
}
baseModule.__getFloat32Array = getTypedArray.bind(null, Float32Array, 2);
baseModule.__getFloat32ArrayView = getTypedArrayView.bind(null, Float32Array, 2);
baseModule.__getFloat64Array = getTypedArray.bind(null, Float64Array, 3);
baseModule.__getFloat64ArrayView = getTypedArrayView.bind(null, Float64Array, 3);
/** Tests whether an object is an instance of the class represented by the specified base id. */
function __instanceof(ptr, baseId) {
const U32 = new Uint32Array(memory.buffer);
var id = U32[(ptr + ID_OFFSET) >>> 2];
if (id <= U32[rttiBase >>> 2]) {
do if (id == baseId) return true;
while (id = getBase(id));
}
return false;
}
baseModule.__instanceof = __instanceof;
// Pull basic exports to baseModule so code in preInstantiate can use them
baseModule.memory = baseModule.memory || memory;
baseModule.table = baseModule.table || table;
// Demangle exports and provide the usual utility on the prototype
return demangle(rawExports, baseModule);
}
function isResponse(o) {
return typeof Response !== "undefined" && o instanceof Response;
}
/** Asynchronously instantiates an AssemblyScript module from anything that can be instantiated. */
async function instantiate(source, imports) {
if (isResponse(source = await source)) return instantiateStreaming(source, imports);
return postInstantiate(
preInstantiate(imports || (imports = {})),
await WebAssembly.instantiate(
source instanceof WebAssembly.Module
? source
: await WebAssembly.compile(source),
imports
)
);
}
exports.instantiate = instantiate;
/** Synchronously instantiates an AssemblyScript module from a WebAssembly.Module or binary buffer. */
function instantiateSync(source, imports) {
return postInstantiate(
preInstantiate(imports || (imports = {})),
new WebAssembly.Instance(
source instanceof WebAssembly.Module
? source
: new WebAssembly.Module(source),
imports
)
)
}
exports.instantiateSync = instantiateSync;
/** Asynchronously instantiates an AssemblyScript module from a response, i.e. as obtained by `fetch`. */
async function instantiateStreaming(source, imports) {
if (!WebAssembly.instantiateStreaming) {
return instantiate(
isResponse(source = await source)
? source.arrayBuffer()
: source,
imports
);
}
return postInstantiate(
preInstantiate(imports || (imports = {})),
(await WebAssembly.instantiateStreaming(source, imports)).instance
);
}
exports.instantiateStreaming = instantiateStreaming;
/** Demangles an AssemblyScript module's exports to a friendly object structure. */
function demangle(exports, baseModule) {
var module = baseModule ? Object.create(baseModule) : {};
var setArgumentsLength = exports["__argumentsLength"]
? function(length) { exports["__argumentsLength"].value = length; }
: exports["__setArgumentsLength"] || exports["__setargc"] || function() {};
for (let internalName in exports) {
if (!Object.prototype.hasOwnProperty.call(exports, internalName)) continue;
const elem = exports[internalName];
let parts = internalName.split(".");
let curr = module;
while (parts.length > 1) {
let part = parts.shift();
if (!Object.prototype.hasOwnProperty.call(curr, part)) curr[part] = {};
curr = curr[part];
}
let name = parts[0];
let hash = name.indexOf("#");
if (hash >= 0) {
let className = name.substring(0, hash);
let classElem = curr[className];
if (typeof classElem === "undefined" || !classElem.prototype) {
let ctor = function(...args) {
return ctor.wrap(ctor.prototype.constructor(0, ...args));
};
ctor.prototype = {
valueOf: function valueOf() {
return this[THIS];
}
};
ctor.wrap = function(thisValue) {
return Object.create(ctor.prototype, { [THIS]: { value: thisValue, writable: false } });
};
if (classElem) Object.getOwnPropertyNames(classElem).forEach(name =>
Object.defineProperty(ctor, name, Object.getOwnPropertyDescriptor(classElem, name))
);
curr[className] = ctor;
}
name = name.substring(hash + 1);
curr = curr[className].prototype;
if (/^(get|set):/.test(name)) {
if (!Object.prototype.hasOwnProperty.call(curr, name = name.substring(4))) {
let getter = exports[internalName.replace("set:", "get:")];
let setter = exports[internalName.replace("get:", "set:")];
Object.defineProperty(curr, name, {
get: function() { return getter(this[THIS]); },
set: function(value) { setter(this[THIS], value); },
enumerable: true
});
}
} else {
if (name === 'constructor') {
(curr[name] = (...args) => {
setArgumentsLength(args.length);
return elem(...args);
}).original = elem;
} else { // instance method
(curr[name] = function(...args) { // !
setArgumentsLength(args.length);
return elem(this[THIS], ...args);
}).original = elem;
}
}
} else {
if (/^(get|set):/.test(name)) {
if (!Object.prototype.hasOwnProperty.call(curr, name = name.substring(4))) {
Object.defineProperty(curr, name, {
get: exports[internalName.replace("set:", "get:")],
set: exports[internalName.replace("get:", "set:")],
enumerable: true
});
}
} else if (typeof elem === "function" && elem !== setArgumentsLength) {
(curr[name] = (...args) => {
setArgumentsLength(args.length);
return elem(...args);
}).original = elem;
} else {
curr[name] = elem;
}
}
}
return module;
}
exports.demangle = demangle;

View File

@@ -0,0 +1,38 @@
{
"name": "@assemblyscript/loader",
"description": "A convenient loader for AssemblyScript modules.",
"keywords": [
"assemblyscript",
"loader",
"glue",
"interop",
"webassembly",
"wasm"
],
"version": "0.9.4",
"author": "Daniel Wirtz <dcode+assemblyscript@dcode.io>",
"license": "Apache-2.0",
"homepage": "https://assemblyscript.org",
"repository": {
"type": "git",
"url": "https://github.com/AssemblyScript/assemblyscript.git",
"directory": "lib/loader"
},
"bugs": {
"url": "https://github.com/AssemblyScript/assemblyscript/issues"
},
"main": "index.js",
"types": "index.d.ts",
"scripts": {
"asbuild": "npm run asbuild:default && npm run asbuild:legacy",
"asbuild:default": "node ../../bin/asc tests/assembly/index.ts -b tests/build/default.wasm",
"asbuild:legacy": "node ../../bin/asc tests/assembly/index.ts --disable mutable-globals -b tests/build/legacy.wasm",
"test": "node tests"
},
"files": [
"index.d.ts",
"index.js",
"package.json",
"README.md"
]
}