Skip to content

Commit 005699e

Browse files
authored
Optimize convertJsFunctionToWasm to avoid garbage. NFC (#17402)
Specifically, this change removes all the `Array.concat` calls in favor of `push`. Inspired by #17392
1 parent c8857a6 commit 005699e

File tree

1 file changed

+22
-25
lines changed

1 file changed

+22
-25
lines changed

src/library_addfunction.js

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@
77
mergeInto(LibraryManager.library, {
88
// This gives correct answers for everything less than 2^{14} = 16384
99
// I hope nobody is contemplating functions with 16384 arguments...
10-
$uleb128Encode: function(n) {
10+
$uleb128Encode: function(n, target) {
1111
#if ASSERTIONS
1212
assert(n < 16384);
1313
#endif
1414
if (n < 128) {
15-
return [n];
15+
target.push(n);
16+
} else {
17+
target.push((n % 128) | 128, n >> 7);
1618
}
17-
return [(n % 128) | 128, n >> 7];
1819
},
1920

2021
// Converts a signature like 'vii' into a description of the wasm types, like
@@ -61,7 +62,7 @@ mergeInto(LibraryManager.library, {
6162

6263
// The module is static, with the exception of the type section, which is
6364
// generated based on the signature passed in.
64-
var typeSection = [
65+
var typeSectionBody = [
6566
0x01, // count: 1
6667
0x60, // form: func
6768
];
@@ -80,50 +81,46 @@ mergeInto(LibraryManager.library, {
8081
};
8182

8283
// Parameters, length + signatures
83-
typeSection = typeSection.concat(uleb128Encode(sigParam.length));
84+
uleb128Encode(sigParam.length, typeSectionBody);
8485
for (var i = 0; i < sigParam.length; ++i) {
8586
#if ASSERTIONS
8687
assert(sigParam[i] in typeCodes, 'invalid signature char: ' + sigParam[i]);
8788
#endif
88-
typeSection.push(typeCodes[sigParam[i]]);
89+
typeSectionBody.push(typeCodes[sigParam[i]]);
8990
}
9091

9192
// Return values, length + signatures
9293
// With no multi-return in MVP, either 0 (void) or 1 (anything else)
9394
if (sigRet == 'v') {
94-
typeSection.push(0x00);
95+
typeSectionBody.push(0x00);
9596
} else {
96-
typeSection = typeSection.concat([0x01, typeCodes[sigRet]]);
97+
typeSectionBody.push(0x01, typeCodes[sigRet]);
9798
}
9899

99-
// Write the section code and overall length of the type section into the
100-
// section header
101-
typeSection = [0x01 /* Type section code */].concat(
102-
uleb128Encode(typeSection.length),
103-
typeSection
104-
);
105-
106100
// Rest of the module is static
107-
var bytes = new Uint8Array([
101+
var bytes = [
108102
0x00, 0x61, 0x73, 0x6d, // magic ("\0asm")
109103
0x01, 0x00, 0x00, 0x00, // version: 1
110-
].concat(typeSection, [
104+
0x01, // Type section code
105+
];
106+
// Write the overall length of the type section followed by the body
107+
uleb128Encode(typeSectionBody.length, bytes);
108+
bytes.push.apply(bytes, typeSectionBody);
109+
110+
// The rest of the module is static
111+
bytes.push(
111112
0x02, 0x07, // import section
112113
// (import "e" "f" (func 0 (type 0)))
113114
0x01, 0x01, 0x65, 0x01, 0x66, 0x00, 0x00,
114115
0x07, 0x05, // export section
115116
// (export "f" (func 0 (type 0)))
116117
0x01, 0x01, 0x66, 0x00, 0x00,
117-
]));
118+
);
118119

119-
// We can compile this wasm module synchronously because it is very small.
120+
// We can compile this wasm module synchronously because it is very small.
120121
// This accepts an import (at "e.f"), that it reroutes to an export (at "f")
121-
var module = new WebAssembly.Module(bytes);
122-
var instance = new WebAssembly.Instance(module, {
123-
'e': {
124-
'f': func
125-
}
126-
});
122+
var module = new WebAssembly.Module(new Uint8Array(bytes));
123+
var instance = new WebAssembly.Instance(module, { 'e': { 'f': func } });
127124
var wrappedFunc = instance.exports['f'];
128125
return wrappedFunc;
129126
#endif // WASM2JS

0 commit comments

Comments
 (0)