Skip to content

Commit bc48898

Browse files
authored
Update loader with what we've learned (AssemblyScript#810)
1 parent b479950 commit bc48898

File tree

4 files changed

+151
-237
lines changed

4 files changed

+151
-237
lines changed

lib/loader/README.md

+38-89
Original file line numberDiff line numberDiff line change
@@ -30,93 +30,23 @@ API
3030

3131
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:
3232

33-
* **I8**: `Int8Array`<br />
34-
An 8-bit signed integer view on the memory.
35-
36-
```ts
37-
var value = module.I8[ptr];
38-
```
39-
40-
* **U8**: `Uint8Array`<br />
41-
An 8-bit unsigned integer view on the memory.
42-
43-
```ts
44-
var value = module.U8[ptr];
45-
```
46-
47-
* **I16**: `Int16Array`<br />
48-
A 16-bit signed integer view on the memory.
49-
50-
```ts
51-
var value = module.I16[ptr >>> 1];
52-
```
53-
54-
* **U16**: `Uint16Array`<br />
55-
A 16-bit unsigned integer view on the memory.
56-
57-
```ts
58-
var value = module.U16[ptr >>> 1];
59-
```
60-
61-
* **I32**: `Int32Array`<br />
62-
A 32-bit signed integer view on the memory.
63-
64-
```ts
65-
var value = module.I32[ptr >>> 2];
66-
```
67-
68-
* **U32**: `Uint32Array`<br />
69-
A 32-bit unsigned integer view on the memory.
70-
71-
```ts
72-
var value = module.U32[ptr >>> 2];
73-
```
74-
75-
* **I64**: `BigInt64Array`<br />
76-
A 64-bit signed integer view on the memory, if supported by the VM.
77-
78-
```ts
79-
var value = module.I64[ptr >>> 3];
80-
```
81-
82-
* **U64**: `BigUint64Array`<br />
83-
A 64-bit unsigned integer view on the memory, if supported by the VM.
84-
85-
```ts
86-
var value = module.U64[ptr >>> 3];
87-
```
88-
89-
* **F32**: `Float32Array`<br />
90-
A 32-bit float view on the memory.
91-
92-
```ts
93-
var value = module.I32[ptr >>> 2];
94-
```
95-
96-
* **F64**: `Float64Array`<br />
97-
A 64-bit float view on the memory.
98-
99-
```ts
100-
var value = module.F64[ptr >>> 3];
101-
```
102-
10333
* **__start**(): `void`<br />
10434
Explicit start function if the `--explicitStart` option is used. Must be called before any other exports if present.
10535

10636
* **__allocString**(str: `string`): `number`<br />
10737
Allocates a new string in the module's memory and returns a reference (pointer) to it.
10838

10939
```ts
110-
var ref = module.__retain(module.__allocString("hello world"));
40+
var ptr = module.__retain(module.__allocString("hello world"));
11141
...
112-
module.__release(ref);
42+
module.__release(ptr);
11343
```
11444

115-
* **__getString**(ref: `number`): `string`<br />
45+
* **__getString**(ptr: `number`): `string`<br />
11646
Reads (copies) the value of a string from the module's memory.
11747

11848
```ts
119-
var str = module.__getString(ref);
49+
var str = module.__getString(ptr);
12050
...
12151
```
12252

@@ -125,44 +55,63 @@ Besides demangling classes exported from your entry file to a handy object struc
12555
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.
12656

12757
```ts
128-
var ref = module.__retain(module.__allocArray(module.INT32ARRAY, [1, 2, 3]));
58+
var ptr = module.__retain(module.__allocArray(module.INT32ARRAY, [1, 2, 3]));
12959
...
130-
module.__release(ref);
60+
module.__release(ptr);
13161
```
13262

133-
* **__getArray**(ref: `number`): `number[]`<br />
63+
* **__getArray**(ptr: `number`): `number[]`<br />
13464
Reads (copies) the values of an array from the module's memory.
13565

13666
```ts
137-
var arr = module.__getArray(ref);
67+
var arr = module.__getArray(ptr);
13868
...
13969
```
14070

141-
* **__getArrayView**(ref: `number`): `TypedArray`<br />
71+
* **__getArrayView**(ptr: `number`): `TypedArray`<br />
14272
Gets a view on the values of an array in the module's memory. 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.
14373

144-
* **__retain**(ref: `number`): `number`<br />
145-
Retains a reference externally, making sure that it doesn't become collected prematurely. Returns the reference.
74+
If the type of the array is known beforehand, the following even faster and even more unsafe helpers can be used that don't do any type checking:
75+
76+
**__getInt8Array**(ptr: `number`): `Int8Array`<br />
77+
**__getUint8Array**(ptr: `number`): `Uint8Array`<br />
78+
**__getUint8ClampedArray**(ptr: `number`): `Uint8ClampedArray`<br />
79+
**__getInt16Array**(ptr: `number`): `Int16Array`<br />
80+
**__getUint16Array**(ptr: `number`): `Uint16Array`<br />
81+
**__getInt32Array**(ptr: `number`): `Int32Array`<br />
82+
**__getUint32Array**(ptr: `number`): `Uint32Array`<br />
83+
**__getInt64Array**(ptr: `number`): `BigInt64Array`<br />
84+
**__getUint64Array**(ptr: `number`): `BigUint64Array`<br />
85+
**__getFloat32Array**(ptr: `number`): `Float32Array`<br />
86+
**__getFloat64Array**(ptr: `number`): `Float64Array`
87+
88+
* **__getArrayBuffer**(ptr: `number`): `ArrayBuffer`<br />
89+
Reads (copies) the data of an ArrayBuffer from the module's memory.
90+
91+
* **__retain**(ptr: `number`): `number`<br />
92+
Retains a reference to a managed object externally, making sure that it doesn't become collected prematurely. Returns the pointer.
14693

147-
* **__release**(ref: `number`): `void`<br />
148-
Releases a previously retained reference to an object, allowing the runtime to collect it once its reference count reaches zero.
94+
* **__release**(ptr: `number`): `void`<br />
95+
Releases a previously retained reference to a managed object, allowing the runtime to collect it once its reference count reaches zero.
14996

15097
* **__alloc**(size: `number`, id: `number`): `number`<br />
15198
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.
15299

153100
```ts
154-
var ref = module.__retain(module.__alloc(module.MYCLASS_SIZE, module.MYCLASS_ID));
155-
F32[ref + MYCLASS_BASICFIELD1_OFFSET >>> 2] = field1_value_f32;
156-
U32[ref + MYCLASS_MANAGEDFIELD2_OFFSET >>> 2] = module.__retain(field2_value_ref);
101+
var ptr = module.__retain(module.__alloc(module.MYCLASS_SIZE, module.MYCLASS_ID));
102+
const F32 = new Float32Array(module.memory.buffer);
103+
F32[ptr + MYCLASS_BASICFIELD1_OFFSET >>> 2] = field1_value_f32;
104+
const U32 = new Uint32Array(module.memory.buffer);
105+
U32[ptr + MYCLASS_MANAGEDFIELD2_OFFSET >>> 2] = module.__retain(field2_value_ptr);
157106
...
158-
module.__release(ref);
107+
module.__release(ptr);
159108
```
160109

161-
* **__instanceof**(ref: `number`, baseId: `number`): `boolean`<br />
110+
* **__instanceof**(ptr: `number`, baseId: `number`): `boolean`<br />
162111
Tests whether an object is an instance of the class represented by the specified base id.
163112

164113
```ts
165-
if (module.__instanceof(ref, module.MYCLASS_ID)) {
114+
if (module.__instanceof(ptr, module.MYCLASS_ID)) {
166115
...
167116
}
168117
```

lib/loader/index.d.ts

+32-40
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
/// <reference lib="esnext.bigint" />
2+
13
import "@types/webassembly-js-api";
24

35
/** WebAssembly imports with two levels of nesting. */
@@ -19,66 +21,56 @@ type TypedArray
1921
| Int32Array
2022
| Uint32Array
2123
| Float32Array
22-
| Float64Array;
24+
| Float64Array
25+
| BigInt64Array
26+
| BigUint64Array;
2327

2428
/** Utility mixed in by the loader. */
2529
interface ASUtil {
26-
/** An 8-bit signed integer view on the memory. */
27-
readonly I8: Uint8Array;
28-
/** An 8-bit unsigned integer view on the memory. */
29-
readonly U8: Uint8Array;
30-
/** A 16-bit signed integer view on the memory. */
31-
readonly I16: Uint16Array;
32-
/** A 16-bit unsigned integer view on the memory. */
33-
readonly U16: Uint16Array;
34-
/** A 32-bit signed integer view on the memory. */
35-
readonly I32: Uint32Array;
36-
/** A 32-bit unsigned integer view on the memory. */
37-
readonly U32: Uint32Array;
38-
/** A 64-bit signed integer view on the memory. */
39-
readonly I64: any; // BigInt64Array
40-
/** A 64-bit unsigned integer vieww on the memory. */
41-
readonly U64: any; // BigUint64Array
42-
/** A 32-bit float view on the memory. */
43-
readonly F32: Float32Array;
44-
/** A 64-bit float view on the memory. */
45-
readonly F64: Float64Array;
4630
/** Explicit start function, if requested. */
4731
__start(): void;
4832
/** Allocates a new string in the module's memory and returns a reference (pointer) to it. */
4933
__allocString(str: string): number;
5034
/** Reads (copies) the value of a string from the module's memory. */
51-
__getString(ref: number): string;
35+
__getString(ptr: number): string;
5236
/** Allocates a new array in the module's memory and returns a reference (pointer) to it. */
5337
__allocArray(id: number, values: number[]): number;
5438
/** Reads (copies) the values of an array from the module's memory. */
55-
__getArray(ref: number): number[];
39+
__getArray(ptr: number): number[];
5640
/** Gets a view on the values of an array in the module's memory. */
57-
__getArrayView(ref: number): TypedArray;
58-
/** Reads (copies) the values of Uint8Array from the module's memory. */
59-
__getUint8Array(ref: number): Uint8Array;
41+
__getArrayView(ptr: number): TypedArray;
6042
/** Reads (copies) the values of Int8Array from the module's memory. */
61-
__getInt8Array(ref: number): Int8Array;
62-
/** Reads (copies) the values of Uint16Array from the module's memory. */
63-
__getUint16Array(ref: number): Uint16Array;
43+
__getInt8Array(ptr: number): Int8Array;
44+
/** Reads (copies) the values of Uint8Array from the module's memory. */
45+
__getUint8Array(ptr: number): Uint8Array;
46+
/** Reads (copies) the values of Uint8Array from the module's memory. */
47+
__getUint8ClampedArray(ptr: number): Uint8ClampedArray;
6448
/** Reads (copies) the values of Int16Array from the module's memory. */
65-
__getInt16Array(ref: number): Int16Array;
49+
__getInt16Array(ptr: number): Int16Array;
50+
/** Reads (copies) the values of Uint16Array from the module's memory. */
51+
__getUint16Array(ptr: number): Uint16Array;
52+
/** Reads (copies) the values of Int32Array from the module's memory. */
53+
__getInt32Array(ptr: number): Int32Array;
6654
/** Reads (copies) the values of Uint32Array from the module's memory. */
67-
__getUint32Array(ref: number): Uint32Array;
55+
__getUint32Array(ptr: number): Uint32Array;
6856
/** Reads (copies) the values of Int32Array from the module's memory. */
69-
__getInt32Array(ref: number): Int32Array;
57+
__getInt64Array(ptr: number): BigInt32Array;
58+
/** Reads (copies) the values of Uint32Array from the module's memory. */
59+
__getUint64Array(ptr: number): BigUint32Array;
7060
/** Reads (copies) the values of Float32Array from the module's memory. */
71-
__getFloat32Array(ref: number): Float32Array;
61+
__getFloat32Array(ptr: number): Float32Array;
7262
/** Reads (copies) the values of Float64Array from the module's memory. */
73-
__getFloat64Array(ref: number): Float64Array;
74-
/** Retains a reference externally, making sure that it doesn't become collected prematurely. Returns the reference. */
75-
__retain(ref: number): number;
76-
/** Releases a previously retained reference to an object, allowing the runtime to collect it once its reference count reaches zero. */
77-
__release(ref: number): void;
63+
__getFloat64Array(ptr: number): Float64Array;
64+
/** Reads (copies) the data of an ArrayBuffer from the module's memory. */
65+
__getArrayBuffer(ptr: number): ArrayBuffer;
66+
/** Retains a reference to a managed object externally, making sure that it doesn't become collected prematurely. Returns the pointer. */
67+
__retain(ptr: number): number;
68+
/** Releases a previously retained reference to a managed object, allowing the runtime to collect it once its reference count reaches zero. */
69+
__release(ptr: number): void;
7870
/** Allocates an instance of the class represented by the specified id. */
7971
__alloc(size: number, id: number): number;
80-
/** Tests whether an object is an instance of the class represented by the specified base id. */
81-
__instanceof(ref: number, baseId: number): boolean;
72+
/** Tests whether a managed object is an instance of the class represented by the specified base id. */
73+
__instanceof(ptr: number, baseId: number): boolean;
8274
/** Forces a cycle collection. Only relevant if objects potentially forming reference cycles are used. */
8375
__collect(): void;
8476
}

0 commit comments

Comments
 (0)