Skip to content

Commit 7f84b88

Browse files
authored
Fix dropping of arguments in JS library functions (#21062)
When the `__sig` for a function is shorter than the actual number of argument (i.e. when the native signature is shorter than the JS signature) we were dropping the extra arguments in handleI64Signatures. Specifically the `uuid_unparse` library function has a hidden third argument that is not exposed to native code (doesn't appear in the native signature). Fixes: #21056
1 parent ace4045 commit 7f84b88

File tree

2 files changed

+34
-9
lines changed

2 files changed

+34
-9
lines changed

src/jsifier.js

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -137,19 +137,22 @@ function runJSify() {
137137
const newArgs = [];
138138
let innerArgs = [];
139139
let argConvertions = '';
140-
for (let i = 1; i < sig.length; i++) {
141-
const name = argNames[i - 1];
142-
if (!name) {
143-
error(`handleI64Signatures: missing name for argument ${i} in ${symbol}`);
144-
return snippet;
145-
}
146-
if (WASM_BIGINT && ((MEMORY64 && sig[i] == 'p') || (i53abi && sig[i] == 'j'))) {
140+
if (sig.length > argNames.length + 1) {
141+
error(`handleI64Signatures: signature too long for ${symbol}`);
142+
return snippet;
143+
}
144+
for (let i = 0; i < argNames.length; i++) {
145+
const name = argNames[i];
146+
// If sig is shorter than argNames list then argType will be undefined
147+
// here, which will result in the default case below.
148+
const argType = sig[i + 1];
149+
if (WASM_BIGINT && ((MEMORY64 && argType == 'p') || (i53abi && argType == 'j'))) {
147150
argConvertions += ` ${receiveI64ParamAsI53(name, undefined, false)}\n`;
148151
} else {
149-
if (sig[i] == 'j' && i53abi) {
152+
if (argType == 'j' && i53abi) {
150153
argConvertions += ` ${receiveI64ParamAsI53(name, undefined, false)}\n`;
151154
newArgs.push(defineI64Param(name));
152-
} else if (sig[i] == 'p' && CAN_ADDRESS_2GB) {
155+
} else if (argType == 'p' && CAN_ADDRESS_2GB) {
153156
argConvertions += ` ${name} >>>= 0;\n`;
154157
newArgs.push(name);
155158
} else {

test/test_other.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4029,6 +4029,28 @@ def test_js_lib_missing_sig(self):
40294029
err = self.expect_fail([EMCC, 'some_func.c'] + self.get_emcc_args())
40304030
self.assertContained('some_func.js: __sig is missing for function: someFunc. Do not use checkSig if this is intended', err)
40314031

4032+
def test_js_lib_extra_args(self):
4033+
# Verify that extra arguments in addition to those listed in `__sig` are still present
4034+
# in the generated JS library function.
4035+
# See https://github.com/emscripten-core/emscripten/issues/21056
4036+
create_file('some_func.js', '''
4037+
addToLibrary({
4038+
someFunc: (arg1, arg2) => {
4039+
err('arg1:' + arg1);
4040+
err('arg2:' + arg2);
4041+
},
4042+
someFunc__sig: 'pp',
4043+
});
4044+
''')
4045+
create_file('test.c', '''
4046+
void someFunc(long p);
4047+
int main() {
4048+
someFunc(42);
4049+
}
4050+
''')
4051+
self.emcc_args += ['--js-library', 'some_func.js', '-sALLOW_MEMORY_GROWTH', '-sMAXIMUM_MEMORY=4Gb']
4052+
self.do_runf('test.c', 'arg1:42\narg2:undefined\n')
4053+
40324054
def test_js_lib_quoted_key(self):
40334055
create_file('lib.js', r'''
40344056
addToLibrary({

0 commit comments

Comments
 (0)