Skip to content

Commit a447a0b

Browse files
committed
Make it work
1 parent b54fd5a commit a447a0b

14 files changed

+1791
-3809
lines changed

lib/asbind-instance/asbind-instance.js

Lines changed: 65 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,10 @@ import { asbindInstantiate, asbindInstantiateSync } from "./instantiate";
44
import { bindImportFunction, bindExportFunction } from "./bind-function";
55
import { isReservedExportKey } from "./reserved-export-keys";
66

7+
const SECTION_NAME = "as-bind_bindings";
8+
79
// Need to traverse the importObject and bind all import functions
8-
const traverseObjectAndRunCallbackForFunctions = (
9-
baseObject,
10-
keys,
11-
callback
12-
) => {
10+
function traverseObjectAndRunCallbackForFunctions(baseObject, keys, callback) {
1311
if (!baseObject) {
1412
return;
1513
}
@@ -26,7 +24,32 @@ const traverseObjectAndRunCallbackForFunctions = (
2624
);
2725
}
2826
});
29-
};
27+
}
28+
29+
async function compileStreaming(source) {
30+
if (WebAssembly.compileStreaming) {
31+
return WebAssembly.compileStreaming(source);
32+
}
33+
source = await Promise.resolve(souce);
34+
if (source instanceof Response) {
35+
source = await source.arrayBuffer();
36+
}
37+
return WebAssembly.compile(source);
38+
}
39+
40+
function extractTypeDescriptor(module) {
41+
const sections = WebAssembly.Module.customSections(module, SECTION_NAME);
42+
console.assert(
43+
sections.length === 1,
44+
`Need exactly one custom section ${JSON.stringify(SECTION_NAME)}`
45+
);
46+
const str = new TextDecoder("utf8").decode(new Uint8Array(sections[0]));
47+
try {
48+
return JSON.parse(str);
49+
} catch (e) {
50+
throw Error(`Couldn’t decode type descriptor: ${e.message}`);
51+
}
52+
}
3053

3154
export default class AsbindInstance {
3255
constructor() {
@@ -35,26 +58,47 @@ export default class AsbindInstance {
3558
this.importObject = {};
3659
}
3760

61+
_validate() {
62+
if (
63+
!WebAssembly.Module.exports(this.module).find(exp => exp.name === "__new")
64+
) {
65+
throw Error(
66+
"The AssemblyScript wasm module was not built with --exportRuntime, which is required."
67+
);
68+
}
69+
if (
70+
!WebAssembly.Module.exports(this.module).find(
71+
exp => exp.name === "__asbind_entryfile_flaga"
72+
)
73+
) {
74+
throw new Error(
75+
"The AssemblyScript wasm module was not built with the as-bind entryfile. Please see the as-bind documentation (Quick Start), and rebuild your AssemblyScript wasm module."
76+
);
77+
}
78+
}
79+
3880
async _instantiate(source, importObject) {
81+
this.module = await compileStreaming(source);
82+
this._validate();
83+
this.typeDescriptor = extractTypeDescriptor(this.module);
3984
// Bind our import function
4085
this._instantiateBindImportFunctions(importObject);
4186

4287
// Instantiate the module through the loader
43-
const unboundExports = await asbindInstantiate(source, this.importObject);
88+
this.loadedModule = await asbindInstantiate(this.module, this.importObject);
4489

4590
// Bind our unbound exports
46-
this._instantiateBindUnboundExports(unboundExports);
91+
this._instantiateBindUnboundExports();
4792
}
4893

4994
_instantiateSync(source, importObject) {
50-
// Bind our import function
95+
this.module = new WebAssembly.Module(source);
96+
this._validate();
97+
this.typeDescriptor = extractTypeDescriptor(this.module);
5198
this._instantiateBindImportFunctions(importObject);
5299

53-
// Instantiate the module through the loader
54-
const unboundExports = asbindInstantiateSync(source, this.importObject);
55-
56-
// Bind our unbound exports
57-
this._instantiateBindUnboundExports(unboundExports);
100+
this.loadedModule = asbindInstantiateSync(this.module, this.importObject);
101+
this._instantiateBindUnboundExports();
58102
}
59103

60104
_instantiateBindImportFunctions(importObject) {
@@ -78,25 +122,18 @@ export default class AsbindInstance {
78122
);
79123
}
80124

81-
_instantiateBindUnboundExports(unboundExports) {
82-
// Set our unbound exports
83-
this.unboundExports = unboundExports;
84-
125+
_instantiateBindUnboundExports() {
85126
// Ensure that the AS Wasm was built with the as-bind entryfile
86-
if (
87-
!this.unboundExports.__asbind_entryfile_flag ||
88-
this.unboundExports.__asbind_entryfile_flag === 0
89-
) {
90-
throw new Error(
91-
"as-bind: The instantiated AssemblyScript wasm module was not built with the as-bind entryfile. Please see the as-bind documentation (Quick Start), and rebuild your AssemblyScript wasm module."
92-
);
127+
if (this.loadedModule.exports?.__asbind_entryfile_flag?.value !== 1) {
93128
}
94129

95130
// Wrap appropriate the appropriate export functions
131+
const unboundExports = this.loadedModule.exports;
96132
this.exports = {};
97-
Object.keys(this.unboundExports).forEach(unboundExportKey => {
133+
134+
Object.keys(unboundExports).forEach(unboundExportKey => {
98135
if (
99-
typeof this.unboundExports[unboundExportKey] === "function" &&
136+
typeof unboundExports[unboundExportKey] === "function" &&
100137
!isReservedExportKey(unboundExportKey)
101138
) {
102139
// Wrap the export
@@ -105,66 +142,8 @@ export default class AsbindInstance {
105142
unboundExportKey
106143
);
107144
} else {
108-
this.exports[unboundExportKey] = this.unboundExports[unboundExportKey];
109-
}
110-
});
111-
}
112-
113-
enableExportFunctionTypeCaching() {
114-
Object.keys(this.exports).forEach(exportKey => {
115-
if (this.exports[exportKey]) {
116-
this.exports[exportKey].shouldCacheTypes = true;
145+
this.exports[unboundExportKey] = unboundExports[unboundExportKey];
117146
}
118147
});
119148
}
120-
121-
disableExportFunctionTypeCaching() {
122-
Object.keys(this.exports).forEach(exportKey => {
123-
if (this.exports[exportKey]) {
124-
this.exports[exportKey].shouldCacheTypes = false;
125-
}
126-
});
127-
}
128-
129-
enableExportFunctionUnsafeReturnValue() {
130-
Object.keys(this.exports).forEach(exportKey => {
131-
if (this.exports[exportKey]) {
132-
this.exports[exportKey].unsafeReturnValue = true;
133-
}
134-
});
135-
}
136-
137-
disableExportFunctionUnsafeReturnValue() {
138-
Object.keys(this.exports).forEach(exportKey => {
139-
if (this.exports[exportKey]) {
140-
this.exports[exportKey].unsafeReturnValue = false;
141-
}
142-
});
143-
}
144-
145-
enableImportFunctionTypeCaching() {
146-
// Need to traverse the importObject and bind all import functions
147-
traverseObjectAndRunCallbackForFunctions(
148-
this.importObject,
149-
[],
150-
(baseObject, keys, baseObjectKey) => {
151-
// Wrap the original key, but then expose a new key for the unbound import
152-
let importFunction = baseObject[baseObjectKey];
153-
importFunction.shouldCacheTypes = true;
154-
}
155-
);
156-
}
157-
158-
disableImportFunctionTypeCaching() {
159-
// Need to traverse the importObject and bind all import functions
160-
traverseObjectAndRunCallbackForFunctions(
161-
this.importObject,
162-
[],
163-
(baseObject, keys, baseObjectKey) => {
164-
// Wrap the original key, but then expose a new key for the unbound import
165-
let importFunction = baseObject[baseObjectKey];
166-
importFunction.shouldCacheTypes = false;
167-
}
168-
);
169-
}
170149
}

0 commit comments

Comments
 (0)