Fix function dependecy handling in library_gl.js#7112
Fix function dependecy handling in library_gl.js#7112kripken merged 2 commits intoemscripten-core:incomingfrom mosra:gl-function-dependency-handling-fix
Conversation
This reverts commit f6ba411, which in turn reverts commit 4ce2875 from 2015. Turns out glDrawRangeElements() *is* fixed now in Firefox, but is broken in Emscripten because their function dependency handling doesn't work correctly. Related PR: emscripten-core/emscripten#7112 Reverting this until the Emscripten PR is integrated and a version released with this patch is widespread enough (assuming a year-long delay could do).
|
Very strange. So what that code is doing is this: (edit: oops, I had that reversed) That is, it adds a function name instead of leaving it unnamed (the name helps in stack traces). Not sure how that code could break things for you, though - we do have a test with it, If it fails, maybe add logging like this: I'm curious to see how it's different on your machine. I'm guessing it's the JS engine which somehow renders functions to text differently - are you not using node.js as the compiler JS engine? Maybe we need to be more careful about the parsing there. |
|
Thanks for the explanation!
Yes, but there is no space in front of the parenthesis anywhere: glDeleteObject: function(id) {... so you get what I'm seeing here: The test fails for me without the fix and passes with the fix, the before/after results are consistent with the above. I hope I can assume I'm using the ArchLinux emscripten package and it seems to be just using the default node.js. Though I didn't update my system in a while and I'm not on the latest and greatest version of it (v10.4.1, latest in the repos is 10.10.1, but it shouldn't have such breaking changes, right?). I can try again after fully updating my system, but so far what I'm seeing is consistent with what the code looks like it should be doing. For yout the test does pass? Is there some lint / code style pass run over the So, based on the above, I think the following would be a proper fix instead, working independently on whether the space is there or not ... does it look okay? diff --git a/src/library_gl.js b/src/library_gl.js
index 5a8b1634e..93eb8d9be 100644
--- a/src/library_gl.js
+++ b/src/library_gl.js
@@ -7971,7 +7971,7 @@ keys(LibraryGL).forEach(function(x) {
var orig = dep;
dep = 'emscripten_' + dep;
var fixed = LibraryGL[x].toString().replace(new RegExp('_' + orig + '\\(', 'g'), '_' + dep + '(');
- fixed = fixed.substr(0, 9) + '_' + y + fixed.substr(9);
+ // `function` is 8 characters, add an explicit name after
+ fixed = fixed.substr(0, 8) + ' _' + y + fixed.substr(8);
LibraryGL[x] = eval('(function() { return ' + fixed + ' })()');
}
return dep; |
|
Yeah, the test passes for me (also passes on CI here). I suspect your version of node.js is either very old or very new, and the toString() of functions has changed..? In any case, yeah, changing the 9 to 8 (and adding a space before |
This is how code generated for WebGL 2 glDrawRangeElements() looked
before this fix:
function _glDrawElements(mode, count, type, indices) {
GLctx.drawElements(mode, count, type, indices)
}
function _glDrawElementsInstanced(mode, count, type, indices, primcount)
{
GLctx["drawElementsInstanced"](mode, count, type, indices, primcount)
}
function _emscripten_glDrawElements(mode, count, type, indices) {
GLctx.drawElements(mode, count, type, indices)
}
function _glDrawRangeElements(_emscripten_glDrawRangeElementsmode, start, end, count, type, indices) {
_emscripten_glDrawElements(mode, count, type, indices)
}
(Note the _emscripten_glDrawRangeElementsmode, which should be just
mode).
|
Ah! After a while of digging, I managed to find out that the That in turn is a change in V8 6.6, which is mentioned here: https://v8project.blogspot.com/2018/03/v8-release-66.html I tried running I updated the PR with the above patch to make it ready for a merge. |
|
Interesting, thanks for investigating. I see the CI failures locally too. It seems like sometimes there is already a name there. It works for me with this: Hopefully that fixes it for you too? |
|
Yes, this works too 👍 |
|
Great, please push that to this PR then and we should be green and can merge. |
|
Pushed. |
|
Thanks! |
|
Thank you for the merge! 👍 |
I tried to use the
glDrawRangeElements()function that's available on WebGL 2 but the generated code looks like this:Note the
_emscripten_glDrawRangeElementsprepended beforemode. That obviously fails at runtime withThis seems to be because
glDrawRangeElements()is one of the very few functions that depend on other GL functions and the code that handles the dependencies is broken. SinceglDrawRangeElements()is a WebGL2-only function that caused a crash on Firefox until relatively recently and all the other functions with dependencies are either emulating legacy GL or non-standard and (so I assume) very seldom used, I think the dependency handling code never really worked to begin with. The code originates in 72c0b9e back from February 2014 and was not changed since. To me at least, the line I removed doesn't seem to serve any purpose other than breaking the code.Note: I don't have any means to test the legacy GL emulation, so I can't verify it really didn't break anything there. Nevertheless, I can't find any purpose that the removed line could have in the legacy emulation code either.