diff --git a/src/utility.js b/src/utility.js index 7c218d9ec79cd..7a49bca4e7308 100644 --- a/src/utility.js +++ b/src/utility.js @@ -86,7 +86,23 @@ function sum(x) { return x.reduce((a, b) => a + b, 0); } -function mergeInto(obj, other) { +// options is optional input object containing mergeInto params +// currently, it can contain +// +// key: noOverride, value: true +// if it is set, it prevents symbol redefinition and shows error +// in case of redefinition +function mergeInto(obj, other, options = null) { + // check for unintended symbol redefinition + if (options && options.noOverride) { + for (const key of Object.keys(other)) { + if (obj.hasOwnProperty(key)) { + error('Symbol re-definition in JavaScript library: ' + key + '. Do not use noOverride if this is intended'); + return; + } + } + } + return Object.assign(obj, other); } diff --git a/tests/test_other.py b/tests/test_other.py index dbf447fe680db..5df44850d4c43 100644 --- a/tests/test_other.py +++ b/tests/test_other.py @@ -3404,6 +3404,38 @@ def test_compilation_database(self): self.run_process([EMCC, 'a.c', '-MJ', 'hello.json', '-c', '-o', 'test.o']) self.assertContained('"file": "a.c", "output": "test.o"', read_file('hello.json')) + def test_duplicate_js_functions(self): + create_file('duplicated_func.c', ''' + #include + extern int duplicatedFunc(); + + int main() { + int res = duplicatedFunc(); + printf("*%d*\\n", res); + return 0; + } + ''') + create_file('duplicated_func_1.js', ''' + mergeInto(LibraryManager.library, { + duplicatedFunc : function() { + return 1; + } + }, { noOverride: true } + ); + ''') + create_file('duplicated_func_2.js', ''' + mergeInto(LibraryManager.library, { + duplicatedFunc : function() { + return 2; + } + }, { noOverride: true } + ); + ''') + + self.emcc_args += ['--js-library', 'duplicated_func_1.js', '--js-library', 'duplicated_func_2.js'] + err = self.expect_fail([EMCC, 'duplicated_func.c'] + self.get_emcc_args()) + self.assertContained('error: Symbol re-definition in JavaScript library: duplicatedFunc. Do not use noOverride if this is intended', err) + def test_js_lib_quoted_key(self): create_file('lib.js', r''' mergeInto(LibraryManager.library, {