Skip to content

Commit 9510a8b

Browse files
committed
Unify code a bit
1 parent d8c844a commit 9510a8b

File tree

3 files changed

+56
-61
lines changed

3 files changed

+56
-61
lines changed

lib/asbind-instance/asbind-instance.js

Lines changed: 42 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,17 @@ import { isReservedExportKey } from "./reserved-export-keys";
77
const SECTION_NAME = "as-bind_bindings";
88

99
// Need to traverse the importObject and bind all import functions
10-
function traverseObjectAndRunCallbackForFunctions(baseObject, keys, callback) {
11-
if (!baseObject) {
10+
function traverseObjectAndRunCallback(obj, callback, keys = [], baseObj = obj) {
11+
if (!obj) {
1212
return;
1313
}
14-
15-
Object.keys(baseObject).forEach(baseObjectKey => {
16-
if (typeof baseObject[baseObjectKey] === "function") {
17-
// Call the callback
18-
callback(baseObject, keys, baseObjectKey);
19-
} else if (typeof baseObject[baseObjectKey] === "object") {
20-
traverseObjectAndRunCallbackForFunctions(
21-
baseObject[baseObjectKey],
22-
[...keys, baseObjectKey],
23-
callback
24-
);
14+
for (const key of Object.keys(obj)) {
15+
if (obj[key] && Object.getPrototypeOf(obj[key]) === Object.prototype) {
16+
traverseObjectAndRunCallback(obj[key], callback, [...keys, key], baseObj);
17+
continue;
2518
}
26-
});
19+
callback(obj[key], [...keys, key], baseObj, key, obj);
20+
}
2721
}
2822

2923
async function compileStreaming(source) {
@@ -86,46 +80,43 @@ export default class AsbindInstance {
8680
}
8781

8882
async _instantiate(source, importObject) {
83+
this.importObject = importObject;
8984
this.module = await compileStreaming(source);
85+
9086
this._validate();
9187
this.typeDescriptor = extractTypeDescriptor(this.module);
92-
// Bind our import function
93-
this._instantiateBindImportFunctions(importObject);
94-
88+
this._instantiateBindImportFunctions();
9589
// Instantiate the module through the loader
9690
this.loadedModule = await asbindInstantiate(this.module, this.importObject);
97-
98-
// Bind our unbound exports
9991
this._instantiateBindUnboundExports();
10092
}
10193

10294
_instantiateSync(source, importObject) {
95+
this.importObject = importObject;
10396
this.module = new WebAssembly.Module(source);
97+
10498
this._validate();
10599
this.typeDescriptor = extractTypeDescriptor(this.module);
106100
this._instantiateBindImportFunctions(importObject);
107-
108101
this.loadedModule = asbindInstantiateSync(this.module, this.importObject);
109102
this._instantiateBindUnboundExports();
110103
}
111104

112105
_instantiateBindImportFunctions(importObject) {
113-
// Set our import object, as we will need it to store type caching
114-
this.importObject = importObject;
115-
116106
// Need to traverse the importObject and bind all import functions
117-
traverseObjectAndRunCallbackForFunctions(
107+
traverseObjectAndRunCallback(
118108
this.importObject,
119-
[],
120-
(baseObject, keys, baseObjectKey) => {
121-
// Wrap the original key, but then expose a new key for the unbound import
122-
let importFunction = baseObject[baseObjectKey];
123-
baseObject[`__asbind_unbound_${baseObjectKey}`] = importFunction;
124-
baseObject[baseObjectKey] = bindImportFunction(
125-
this,
126-
this.importObject,
127-
[...keys, baseObjectKey]
128-
);
109+
(importedFunction, keys, importObject, currentKey, currentObj) => {
110+
if (typeof importedFunction === "function") {
111+
// Save original function
112+
// TODO: Maybe use symbols here instead
113+
currentObj[`__asbind_unbound_${currentKey}`] = importedFunction;
114+
currentObj[currentKey] = bindImportFunction(
115+
this,
116+
importedFunction,
117+
keys
118+
);
119+
}
129120
}
130121
);
131122
}
@@ -135,19 +126,23 @@ export default class AsbindInstance {
135126
const unboundExports = this.loadedModule.exports;
136127
this.exports = {};
137128

138-
Object.keys(unboundExports).forEach(unboundExportKey => {
139-
if (
140-
typeof unboundExports[unboundExportKey] === "function" &&
141-
!isReservedExportKey(unboundExportKey)
142-
) {
143-
// Wrap the export
144-
this.exports[unboundExportKey] = bindExportFunction(
145-
this,
146-
unboundExportKey
147-
);
148-
} else {
149-
this.exports[unboundExportKey] = unboundExports[unboundExportKey];
129+
traverseObjectAndRunCallback(
130+
unboundExports,
131+
(exportedValue, keys, importObject, currentKey, currentObj) => {
132+
if (
133+
typeof exportedValue === "function" &&
134+
!isReservedExportKey(currentKey)
135+
) {
136+
// Wrap the export
137+
this.exports[currentKey] = bindExportFunction(
138+
this,
139+
exportedValue,
140+
currentKey
141+
);
142+
} else {
143+
this.exports[currentKey] = exportedValue;
144+
}
150145
}
151-
});
146+
);
152147
}
153148
}

lib/asbind-instance/bind-function.js

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -146,18 +146,14 @@ function getJsToAscConverterForType(typeName) {
146146
return getConverterForType(typeName)?.jsToAsc;
147147
}
148148

149-
// Function that takes in an asbindInstance, and importObject, and the path to the import function on the object
149+
// Function that takes in an asbindInstance, an imported function and the path to the imported function
150+
// on the import object.
150151
// (E.g ["env", "myObject", "myFunction"] for {env: myObject: {myFunction: () => {}}})
151-
// To find the importFunction, wrap it, re-assign it to the improt Object, and allow it to access itself later.
152152
export function bindImportFunction(
153153
asbindInstance,
154-
importObject,
154+
importedFunction,
155155
importObjectKeyPathToFunction
156156
) {
157-
const importedFunction = getFunctionFromKeyPath(
158-
importObject,
159-
importObjectKeyPathToFunction
160-
);
161157
const importedFunctionDescriptor = getFunctionFromKeyPath(
162158
asbindInstance.typeDescriptor.importedFunctions,
163159
importObjectKeyPathToFunction
@@ -166,13 +162,16 @@ export function bindImportFunction(
166162
throw Error(`Unknown function ${importObjectKeyPathToFunction.join(".")}`);
167163
}
168164

165+
// Grab type converter functions according to the type descriptor
169166
const argumentConverterFunctions = importedFunctionDescriptor.parameters.map(
170167
getAscToJsConverterForType
171168
);
172169
const returnValueConverterFunction = getJsToAscConverterForType(
173170
importedFunctionDescriptor.returnType
174171
);
175172

173+
// Create a wrapper function that applies the correct converter function to arguments and
174+
// return value respectively.
176175
return function(...args) {
177176
if (args.length != argumentConverterFunctions.length) {
178177
throw Error(
@@ -197,22 +196,27 @@ export function bindImportFunction(
197196

198197
// Function that takes in an asbind instance, and the key to the export function on the
199198
// abindInstance.exports object, to be wrapped and then re-assigned to the asbindInstance.exports.
200-
export function bindExportFunction(asbindInstance, exportFunctionKey) {
201-
const exportedFunction =
202-
asbindInstance.loadedModule.exports[exportFunctionKey];
199+
export function bindExportFunction(
200+
asbindInstance,
201+
exportedFunction,
202+
exportFunctionKey
203+
) {
203204
const exportedFunctionDescriptor =
204205
asbindInstance.typeDescriptor.exportedFunctions[exportFunctionKey];
205206
if (!exportedFunctionDescriptor) {
206207
throw Error(`Unknown function ${exportFunctionKey}`);
207208
}
208209

210+
// Grab type converter functions according to the type descriptor
209211
const argumentConverterFunctions = exportedFunctionDescriptor.parameters.map(
210212
getJsToAscConverterForType
211213
);
212214
const returnValueConverterFunction = getAscToJsConverterForType(
213215
exportedFunctionDescriptor.returnType
214216
);
215217

218+
// Create a wrapper function that applies the correct converter function to arguments and
219+
// return value respectively.
216220
return (...args) => {
217221
if (args.length != argumentConverterFunctions.length) {
218222
throw Error(

lib/asbind-instance/reserved-export-keys.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,6 @@ export const RESERVED_RUNTIME_EXPORT_KEYS = [
1919
];
2020

2121
export function isReservedExportKey(key) {
22-
if (key.startsWith("__asbind")) {
23-
return true;
24-
}
25-
2622
return RESERVED_RUNTIME_EXPORT_KEYS.some(reservedKey => {
2723
if (typeof reservedKey === "string") {
2824
return reservedKey === key;

0 commit comments

Comments
 (0)