Hello,
I've found two inconsistencies with the closure code.
The problem is due to mixing calling functions by name, or as a key to a hash.
Test-case:
The c program (test.c) for all the tests below:
Problem 1: the "run" function is incorrectly closure'd.
The "post" code (post.js) calls "run"
console.log("The command below is Module.run()");
Module.run();
Compile and test
$ emcc -O2 --closure 1 --minify 0 -s INVOKE_RUN=0 --post-js post.js -o test
# run
$ node test.js
The command below is Module.run()
node.js:201
throw e; // process.nextTick error, or 'error' event on first tick
^
TypeError: Object #<Object> has no method 'j'
at Object.<anonymous> (/home/gordon/temp/emcc_bug/test.js:550:8)
at Module._compile (module.js:432:26)
at Object..js (module.js:450:10)
at Module.load (module.js:351:31)
at Function._load (module.js:310:12)
at Array.0 (module.js:470:10)
at EventEmitter._tickCallback (node.js:192:40)
The end of the compiled "test.js" reveals the problem:
$ tail test.js
}
}
W([]);
var la = i;
Module.noInitialRun && (la = i);
la && $();
console.log("The command below is Module.run()");
Module.j();
The "run()" function in the post was renamed to "j()", but in the generated javascript, it's actually different:
$ grep "^Module\.run" test.js
Module.run = $;
Problem 2: The important config keys in "Module" are incorrectly closure'd
The pre code (pre.js) sets a preRun callback:
var Module = {
"The Key below is PreRun": true,
preRun: function() {
console.log("Hello from preRun");
}
};
Compile and test
# Compile without closure
$ emcc -O2 --closure 0 --minify 0 --pre-js pre.js -o test.js test.c
# Test without closure
$ node test.js
Hello from preRun
# Compile with closure
$ emcc -O2 --closure 1 --minify 0 --pre-js pre.js -o test.js test.c
# Test with closure
$ node test.js
# [nothing is printed, "preRun" was not called]
The reason: the pre-script's "preRun" was renamed to "j":
$ head test.js
var b = !0, i = null, j = !1, k = {
"The Key below is PreRun": b,
j: (function() {
console.log("Hello from preRun");
})
};
try {
this.Module = k;
} catch (aa) {
this.Module = k = {};
but the rest of the generated code still looks for a "preRun" function:
$ grep preRun test.js
console.log("Hello from preRun");
k.preRun || (k.preRun = []);
if (k.preRun) {
typeof k.preRun == "function" && (k.preRun = [ k.preRun ]);
var d = k.preRun;
k.preRun = [];
Same thing happens with "noInitialRun" and other configuration keys.
temporary workaround:
- for the initialization keys, always use strings as keys:
var Module = {
"preRun" : function (...)
"NoInitialRun" : true }
- For the "run", a hack like this would work in the post.js script:
var f = Module['run'];
f();
Regards,
-gordon
Hello,
I've found two inconsistencies with the closure code.
The problem is due to mixing calling functions by name, or as a key to a hash.
Test-case:
The c program (test.c) for all the tests below:
Problem 1: the "run" function is incorrectly closure'd.
The "post" code (post.js) calls "run"
Compile and test
The end of the compiled "test.js" reveals the problem:
The "run()" function in the post was renamed to "j()", but in the generated javascript, it's actually different:
Problem 2: The important config keys in "Module" are incorrectly closure'd
The pre code (pre.js) sets a
preRuncallback:Compile and test
The reason: the pre-script's "preRun" was renamed to "j":
but the rest of the generated code still looks for a "preRun" function:
Same thing happens with "noInitialRun" and other configuration keys.
temporary workaround:
Regards,
-gordon