Skip to content

Commit 0d4be85

Browse files
Merge branch 'main' into shared_memory
2 parents 2b73900 + afa356a commit 0d4be85

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+2375
-2319
lines changed

.circleci/config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -787,7 +787,7 @@ jobs:
787787
EMTEST_SKIP_NODE_CANARY: "1"
788788
EMTEST_SKIP_WASM64: "1"
789789
steps:
790-
- run: apt-get install -q -y ninja-build scons
790+
- run: apt-get install -q -y ninja-build scons ccache
791791
- run-tests-linux:
792792
# some native-dependent tests fail because of the lack of native
793793
# headers on emsdk-bundled clang

.github/workflows/tag-release.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ jobs:
2020
- name: Create Changelog PR
2121
uses: peter-evans/create-pull-request@v6
2222
with:
23+
token: ${{ secrets.EMSCRIPTEN_BOT_TOKEN }}
2324
title: Mark ${{ env.RELEASE_VERSION }} as released
25+
team-reviewers: release-reviewers
2426
delete-branch: true
2527
- name: Tag release sha
2628
uses: actions/github-script@v7

ChangeLog.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,11 @@ to browse the changes between the tags.
1818

1919
See docs/process.md for more on how version tagging works.
2020

21-
3.1.69 (in development)
21+
3.1.70 (in development)
2222
-----------------------
23+
24+
3.1.69 - 10/12/24
25+
-----------------
2326
- The usage of `EM_BOOL` in the emscripten API has been replaced with C/C++
2427
bool. This change should not be observable since `EM_BOOL` has been
2528
equivalent to `bool` since #22157. (#22155)

embuilder.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@
113113
'crtbegin',
114114
'libsanitizer_common_rt',
115115
'libubsan_rt',
116-
'libwasm_workers_stub-debug',
116+
'libwasm_workers-debug-stub',
117117
'libfetch',
118118
'libfetch-mt',
119119
'libwasmfs',

emcc.py

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -937,6 +937,28 @@ def get_clang_output_extension(state):
937937
return '.o'
938938

939939

940+
def filter_out_link_flags(args):
941+
rtn = []
942+
943+
def is_link_flag(flag):
944+
if flag in ('-nostdlib', '-nostartfiles', '-nolibc', '-nodefaultlibs', '-s'):
945+
return True
946+
return flag.startswith(('-l', '-L', '-Wl,', '-z'))
947+
948+
skip = False
949+
for arg in args:
950+
if skip:
951+
skip = False
952+
continue
953+
if is_link_flag(arg):
954+
continue
955+
if arg == '-Xlinker':
956+
skip = True
957+
continue
958+
rtn.append(arg)
959+
return rtn
960+
961+
940962
@ToolchainProfiler.profile_block('compile inputs')
941963
def phase_compile_inputs(options, state, newargs, input_files):
942964
if shared.run_via_emxx:
@@ -1016,13 +1038,7 @@ def get_clang_command_asm():
10161038

10171039
# In COMPILE_AND_LINK we need to compile source files too, but we also need to
10181040
# filter out the link flags
1019-
1020-
def is_link_flag(flag):
1021-
if flag in ('-nostdlib', '-nostartfiles', '-nolibc', '-nodefaultlibs', '-s'):
1022-
return True
1023-
return flag.startswith(('-l', '-L', '-Wl,', '-z'))
1024-
1025-
compile_args = [a for a in compile_args if a and not is_link_flag(a)]
1041+
compile_args = filter_out_link_flags(compile_args)
10261042
linker_inputs = []
10271043
seen_names = {}
10281044

emscripten-version.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
3.1.69-git
1+
3.1.70-git

site/source/docs/api_reference/wasm_audio_worklets.rst

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ processing graph as AudioWorkletNodes.
4545

4646
Once a class type is instantiated on the Web Audio graph and the graph is
4747
running, a C/C++ function pointer callback will be invoked for each 128
48-
samples of the processed audio stream that flows through the node.
48+
samples of the processed audio stream that flows through the node. Newer Web
49+
Audio API specs allow this to be changed, so for future compatibility use the
50+
``AudioSampleFrame``'s ``quantumSize`` to get the value.
4951

5052
This callback will be executed on a dedicated separate audio processing
5153
thread with real-time processing priority. Each Web Audio context will
@@ -157,7 +159,7 @@ which resumes the audio context when the user clicks on the DOM Canvas element t
157159
void *userData)
158160
{
159161
for(int i = 0; i < numOutputs; ++i)
160-
for(int j = 0; j < 128*outputs[i].numberOfChannels; ++j)
162+
for(int j = 0; j < outputs[i].quantumSize*outputs[i].numberOfChannels; ++j)
161163
outputs[i].data[j] = emscripten_random() * 0.2 - 0.1; // Warning: scale down audio volume by factor of 0.2, raw noise can be really loud otherwise
162164
163165
return true; // Keep the graph output going

src/audio_worklet.js

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ function createWasmAudioWorkletProcessor(audioParams) {
3131
let opts = args.processorOptions;
3232
this.callbackFunction = Module['wasmTable'].get(opts['cb']);
3333
this.userData = opts['ud'];
34+
// Plus the number of samples to process, fixed for the lifetime of the
35+
// context that created this processor. Note for when moving to Web Audio
36+
// 1.1: the typed array passed to process() should be the same size as the
37+
// the quantum size, and this exercise of passing in the value shouldn't
38+
// be required (to be verified).
39+
this.quantumSize = opts['qs'];
3440
}
3541

3642
static get parameterDescriptors() {
@@ -45,53 +51,59 @@ function createWasmAudioWorkletProcessor(audioParams) {
4551
let numInputs = inputList.length,
4652
numOutputs = outputList.length,
4753
numParams = 0, i, j, k, dataPtr,
48-
stackMemoryNeeded = (numInputs + numOutputs) * 8,
54+
quantumBytes = this.quantumSize * 4,
55+
stackMemoryNeeded = (numInputs + numOutputs) * {{{ C_STRUCTS.AudioSampleFrame.__size__ }}},
4956
oldStackPtr = stackSave(),
5057
inputsPtr, outputsPtr, outputDataPtr, paramsPtr,
5158
didProduceAudio, paramArray;
5259

5360
// Calculate how much stack space is needed.
54-
for (i of inputList) stackMemoryNeeded += i.length * 512;
55-
for (i of outputList) stackMemoryNeeded += i.length * 512;
56-
for (i in parameters) stackMemoryNeeded += parameters[i].byteLength + 8, ++numParams;
61+
for (i of inputList) stackMemoryNeeded += i.length * quantumBytes;
62+
for (i of outputList) stackMemoryNeeded += i.length * quantumBytes;
63+
for (i in parameters) stackMemoryNeeded += parameters[i].byteLength + {{{ C_STRUCTS.AudioParamFrame.__size__ }}}, ++numParams;
5764

5865
// Allocate the necessary stack space.
5966
inputsPtr = stackAlloc(stackMemoryNeeded);
6067

6168
// Copy input audio descriptor structs and data to Wasm
6269
k = inputsPtr >> 2;
63-
dataPtr = inputsPtr + numInputs * 8;
70+
dataPtr = inputsPtr + numInputs * {{{ C_STRUCTS.AudioSampleFrame.__size__ }}};
6471
for (i of inputList) {
6572
// Write the AudioSampleFrame struct instance
66-
HEAPU32[k++] = i.length;
67-
HEAPU32[k++] = dataPtr;
73+
HEAPU32[k + {{{ C_STRUCTS.AudioSampleFrame.numberOfChannels / 4 }}}] = i.length;
74+
HEAPU32[k + {{{ C_STRUCTS.AudioSampleFrame.quantumSize / 4 }}}] = this.quantumSize;
75+
HEAPU32[k + {{{ C_STRUCTS.AudioSampleFrame.data / 4 }}}] = dataPtr;
76+
k += {{{ C_STRUCTS.AudioSampleFrame.__size__ / 4 }}};
6877
// Marshal the input audio sample data for each audio channel of this input
6978
for (j of i) {
7079
HEAPF32.set(j, dataPtr>>2);
71-
dataPtr += 512;
80+
dataPtr += quantumBytes;
7281
}
7382
}
7483

7584
// Copy output audio descriptor structs to Wasm
7685
outputsPtr = dataPtr;
7786
k = outputsPtr >> 2;
78-
outputDataPtr = (dataPtr += numOutputs * 8) >> 2;
87+
outputDataPtr = (dataPtr += numOutputs * {{{ C_STRUCTS.AudioSampleFrame.__size__ }}}) >> 2;
7988
for (i of outputList) {
8089
// Write the AudioSampleFrame struct instance
81-
HEAPU32[k++] = i.length;
82-
HEAPU32[k++] = dataPtr;
90+
HEAPU32[k + {{{ C_STRUCTS.AudioSampleFrame.numberOfChannels / 4 }}}] = i.length;
91+
HEAPU32[k + {{{ C_STRUCTS.AudioSampleFrame.quantumSize / 4 }}}] = this.quantumSize;
92+
HEAPU32[k + {{{ C_STRUCTS.AudioSampleFrame.data / 4 }}}] = dataPtr;
93+
k += {{{ C_STRUCTS.AudioSampleFrame.__size__ / 4 }}};
8394
// Reserve space for the output data
84-
dataPtr += 512 * i.length;
95+
dataPtr += quantumBytes * i.length;
8596
}
8697

8798
// Copy parameters descriptor structs and data to Wasm
8899
paramsPtr = dataPtr;
89100
k = paramsPtr >> 2;
90-
dataPtr += numParams * 8;
101+
dataPtr += numParams * {{{ C_STRUCTS.AudioParamFrame.__size__ }}};
91102
for (i = 0; paramArray = parameters[i++];) {
92103
// Write the AudioParamFrame struct instance
93-
HEAPU32[k++] = paramArray.length;
94-
HEAPU32[k++] = dataPtr;
104+
HEAPU32[k + {{{ C_STRUCTS.AudioParamFrame.length / 4 }}}] = paramArray.length;
105+
HEAPU32[k + {{{ C_STRUCTS.AudioParamFrame.data / 4 }}}] = dataPtr;
106+
k += {{{ C_STRUCTS.AudioParamFrame.__size__ / 4 }}};
95107
// Marshal the audio parameters array
96108
HEAPF32.set(paramArray, dataPtr>>2);
97109
dataPtr += paramArray.length*4;
@@ -105,7 +117,7 @@ function createWasmAudioWorkletProcessor(audioParams) {
105117
// not have one, so manually copy all bytes in)
106118
for (i of outputList) {
107119
for (j of i) {
108-
for (k = 0; k < 128; ++k) {
120+
for (k = 0; k < this.quantumSize; ++k) {
109121
j[k] = HEAPF32[outputDataPtr++];
110122
}
111123
}
@@ -138,8 +150,7 @@ class BootstrapMessages extends AudioWorkletProcessor {
138150
// initialize the Wasm Module.
139151
globalThis.Module['instantiateWasm'] = (info, receiveInstance) => {
140152
var instance = new WebAssembly.Instance(Module['wasm'], info);
141-
receiveInstance(instance, Module['wasm']);
142-
return instance.exports;
153+
return receiveInstance(instance, Module['wasm']);
143154
};
144155
#endif
145156
#if WEBAUDIO_DEBUG
@@ -184,7 +195,12 @@ class BootstrapMessages extends AudioWorkletProcessor {
184195
// 'ud' the passed user data
185196
p.postMessage({'_wsc': d['cb'], 'x': [d['ch'], 1/*EM_TRUE*/, d['ud']] });
186197
} else if (d['_wsc']) {
187-
Module['wasmTable'].get(d['_wsc'])(...d['x']);
198+
#if MEMORY64
199+
var ptr = BigInt(d['_wsc']);
200+
#else
201+
var ptr = d['_wsc'];
202+
#endif
203+
Module['wasmTable'].get(ptr)(...d['x']);
188204
};
189205
}
190206
}

src/embind/embind.js

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -124,17 +124,14 @@ var LibraryEmbind = {
124124
// We are exposing a function with the same name as an existing function. Create an overload table and a function selector
125125
// that routes between the two.
126126
ensureOverloadTable(Module, name, name);
127-
if (Module.hasOwnProperty(numArguments)) {
127+
if (Module[name].overloadTable.hasOwnProperty(numArguments)) {
128128
throwBindingError(`Cannot register multiple overloads of a function with the same number of arguments (${numArguments})!`);
129129
}
130130
// Add the new function into the overload table.
131131
Module[name].overloadTable[numArguments] = value;
132-
}
133-
else {
132+
} else {
134133
Module[name] = value;
135-
if (undefined !== numArguments) {
136-
Module[name].numArguments = numArguments;
137-
}
134+
Module[name].argCount = numArguments;
138135
}
139136
},
140137

@@ -147,8 +144,7 @@ var LibraryEmbind = {
147144
// If there's an overload table for this symbol, replace the symbol in the overload table instead.
148145
if (undefined !== Module[name].overloadTable && undefined !== numArguments) {
149146
Module[name].overloadTable[numArguments] = value;
150-
}
151-
else {
147+
} else {
152148
Module[name] = value;
153149
Module[name].argCount = numArguments;
154150
}
@@ -2269,9 +2265,9 @@ var LibraryEmbind = {
22692265
$char_9: '9'.charCodeAt(0),
22702266
$makeLegalFunctionName__deps: ['$char_0', '$char_9'],
22712267
$makeLegalFunctionName: (name) => {
2272-
if (undefined === name) {
2273-
return '_unknown';
2274-
}
2268+
#if ASSERTIONS
2269+
assert(typeof name === 'string');
2270+
#endif
22752271
name = name.replace(/[^a-zA-Z0-9_]/g, '$');
22762272
var f = name.charCodeAt(0);
22772273
if (f >= char_0 && f <= char_9) {

src/jsifier.mjs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -284,17 +284,21 @@ ${argConversions}
284284

285285
// apply LIBRARY_DEBUG if relevant
286286
if (LIBRARY_DEBUG && !isJsOnlySymbol(symbol)) {
287-
snippet = modifyJSFunction(
288-
snippet,
289-
(args, body, async) => `\
287+
snippet = modifyJSFunction(snippet, (args, body, async, oneliner) => {
288+
var run_func;
289+
if (oneliner) {
290+
run_func = `var ret = ${body}`;
291+
} else {
292+
run_func = `var ret = (() => { ${body} })();`;
293+
}
294+
return `\
290295
function(${args}) {
291-
var ret = (() => { if (runtimeDebug) err("[library call:${mangled}: " + Array.prototype.slice.call(arguments).map(prettyPrint) + "]");
292-
${body}
293-
})();
294-
if (runtimeDebug && typeof ret != "undefined") err(" [ return:" + prettyPrint(ret));
296+
if (runtimeDebug) err("[library call:${mangled}: " + Array.prototype.slice.call(arguments).map(prettyPrint) + "]");
297+
${run_func}
298+
if (runtimeDebug) err(" [ return:" + prettyPrint(ret));
295299
return ret;
296-
}`,
297-
);
300+
}`;
301+
});
298302
}
299303

300304
const sig = LibraryManager.library[symbol + '__sig'];

0 commit comments

Comments
 (0)