Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for undefined ASSERTIONS variable in html output of emcc #5749

Merged
merged 2 commits into from
Nov 9, 2017
Merged

Fix for undefined ASSERTIONS variable in html output of emcc #5749

merged 2 commits into from
Nov 9, 2017

Conversation

nazar-pc
Copy link
Contributor

@nazar-pc nazar-pc commented Nov 8, 2017

It seems to be specific to HTML builds, since src/arrayUtils.js doesn't define ASSERTIONS anymore (https://github.com/kripken/emscripten/pull/5720/files#diff-86414f2ed951321c81d9a4aa55bb139cL13).

Also removed comment (left from the PR linked above): it indicated that previously the code didn't work at all, but should start working with this PR.

@buu700, did I interpret it correctly?

This is a response to 93479ec#commitcomment-25492064

nazar-pc referenced this pull request Nov 8, 2017
* Some new externs added to please Closure Compiler, small tweaks to resolve some issues with newer version

* Rewrite multiple `f.write()` calls into single call with more readable JavaScript code inside

* Google Closure Compiler updated to latest v20171023.0.0

* Fix for multiple duplicated `var ptr` declarations.
Fixes to externs (added File API externs).

* Suppress a lot of warnings that naturally occur in asm.js code

* Closure Compiler should run without errors now (warnings are present, but don't cause everything to fail)

* Fix JS optimizer to properly work with added suppression comment (resulted in corrupted JS build).
More externs fixes.

* WebIDL fixes for modern Closure Compiler

* Removed externs already included in latest Closure Compiler

* Fix for multiple declarations of `ASSERTION` variable.
Fix for `EmterpreterAsync` usage appearing in builds without `EmterpreterAsync` definition.
Suppress `FUNCTION_TABLE` undefined variable.
Fix for `getterReturnType` and `setterArgumentType` used while undefined (probably copy-paste typo, replaced with `rawFieldType`).

* Suppress errors about undefined variables
@buu700
Copy link
Contributor

buu700 commented Nov 8, 2017

Cool, that solution looks good to me, and seems to work as described for me locally.

As far as the comment, I think you may have misinterpreted it, but this diff from when it was added should clear up the meaning:

screen shot 2017-11-08 at 5 00 11 pm

tl;dr: One function with a simple #if ASSERTIONS had to be copied and pasted to temporarily work around the lack of a solution for invoking the preprocessor from Python, which we'll want to remember to revert when that is no longer the case.

@nazar-pc
Copy link
Contributor Author

nazar-pc commented Nov 8, 2017

But now having var ASSERTIONS on higher level the comment is not needed anymore, right?

@buu700
Copy link
Contributor

buu700 commented Nov 8, 2017

That comment was about intArrayToString being duplicated (the two function bodies in the ternary are identical aside from the assertion on line 20), not about var ASSERTIONS, so this change doesn't have anything to do with the comment.

It seems like it could be a lot more clear, though. Maybe change it to something like // TODO: After support is added for invoking the preprocessor from Python, use it on this file in emcc.py's generate_html and collapse intArrayToString into a single function with an #if directive.

@nazar-pc
Copy link
Contributor Author

nazar-pc commented Nov 8, 2017

Do we need #if now though? Is that function expected to be called very often?
If not, I can refactor it to be a single function with regular JS if condition. Also Closure Compiler will unwrap if when ASSSERTIONS variable is a constant anyway, so for main JavaScript build in production there will be no cost at all.

@nazar-pc
Copy link
Contributor Author

nazar-pc commented Nov 8, 2017

Well, it is an exceptional situation anyway, so I went ahead and simplified it even further to single function. Shouldn't make any real-world difference even without Closure Compiler post-processing.

Does it make sense?

@buu700
Copy link
Contributor

buu700 commented Nov 8, 2017

I'd originally written it pretty much the same way as you're suggesting, but @kripken specifically requested duplicating it: #5296 (comment)

That is an interesting point about Closure. I believe Closure output requires access to eval at run-time, though, unless either I'm mistaken or that's changed, in which case it's a nonstarter for many use cases since most Content Security Policies don't whitelist unsafe-eval and shouldn't be assumed to be used for every production build. (Am I correct on that? I'd love to be able to start using --closure.)


Edit: Since that link doesn't seem to work, here's the relevant comment:

The real problem is here though. This adds a function call at runtime for every iteration in the loop, which if it isn't optimized by the JIT, will make intArrayToString much slower, and we do care about speed there.

The only way around that is preprocessing, which we now want to avoid - so we need something else creative to get around this. Maybe just two copies of the code wouldn't be too bad.

@nazar-pc
Copy link
Contributor Author

nazar-pc commented Nov 8, 2017

Am I correct on that? I'd love to be able to start using --closure

I don't think it ever requires eval. All of the projects I've been using it with didn't have any eval added by Closure Compiler. Also here is a pretty big library compiled with Emscripten and Closure Compiler enabled and all 3 eval come from Emscripten itself: https://github.com/nazar-pc/noise-c.wasm/blob/master/noise-c.js
Also I think it should be possible to eliminate some of remaining eval() calls introduced by Emscripten too, will work on it separately.

If that was a performance concern, I've just prepared benchmark that compares performance of the example with if inside and without it: https://jsfiddle.net/fanLn4k4/

My Chromium Nightly and Firefox Nightly do not see any measurable difference. So either it is not the case at all or it was fixed in V8 and other JavaScript engines already.

@buu700
Copy link
Contributor

buu700 commented Nov 8, 2017

Awesome. I was just speaking about --closure specifically and didn't expect that Closure Compiler itself would introduce evals, but wasn't actually sure, so that's great to hear that you might be able to remove the evals from emscripten's output.

As far as the if, any thoughts @kripken? (It's at least an improvement over when I'd added a function invocation overhead in the form of maybeAssert.)

@kripken
Copy link
Member

kripken commented Nov 9, 2017

Yeah, this seems good. The benchmark doesn't actually reach the ASSERTIONS check (the variable isn't defined, so it would throw, unless I'm missing something), but that's fine as it's the expected case anyhow. So perhaps we were overly cautious before.

@kripken
Copy link
Member

kripken commented Nov 9, 2017

Looks good in local testing too. Just waiting on CI.

@kripken kripken merged commit ea67ec1 into emscripten-core:incoming Nov 9, 2017
@nazar-pc nazar-pc deleted the assertions-undefined-fix branch November 9, 2017 04:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants