Emscripten: _emscripten_glUniform1f$legalf32 is not defined

Created on 5 Aug 2017  Â·  15Comments  Â·  Source: emscripten-core/emscripten

When I run

touch null.cc
EMCC_FORCE_STDLIBS=1 em++ -s WASM=1 -s MAIN_MODULE=1 -o null.js null.cc
node null

I get the following error

null.js:110
      throw ex;
      ^

ReferenceError: _emscripten_glUniform1f$legalf32 is not defined
    at Object.<anonymous> (/home/michael/Local/test/cout2/null.js:56848:388)
    at Module._compile (module.js:569:30)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:503:32)
    at tryModuleLoad (module.js:466:12)
    at Function.Module._load (module.js:458:3)
    at Function.Module.runMain (module.js:605:10)
    at startup (bootstrap_node.js:158:16)
    at bootstrap_node.js:575:3

This can be prevented by explicitly specifying the forced libraries, especially

touch null.cc
EMCC_FORCE_STDLIBS=libc em++ -s WASM=1 -s MAIN_MODULE=1 -o null.js null.cc
node null

works, however, there seem to be some other issues w.r.t. side modules, compare #5034 resp. https://gist.github.com/xor2k/6fae4abcb4d8c4b4f456dad39256f9a3.

wontfix

Most helpful comment

Any news? This bug seems to be the only thing blocking me from switching from asmjs to wasm.

All 15 comments

I'm able to reproduce. In the generated code, FUNCTION_TABLE_X receives the following symbols:

var FUNCTION_TABLE_X = [.....,
_emscripten_glPixelStorei,_emscripten_glGetString,_emscripten_glGetIntegerv,_emscripten_glGetFloatv,_emscripten_glGetBooleanv,_emscripten_glGenTextures,_emscripten_glDeleteTextures,_emscripten_glCompressedTexImage2D,_emscripten_glCompressedTexSubImage2D,_emscripten_glTexImage2D,_emscripten_glTexSubImage2D,_emscripten_glReadPixels,_emscripten_glBindTexture,_emscripten_glGetTexParameterfv,_emscripten_glGetTexParameteriv,_emscripten_glTexParameterfv,_emscripten_glTexParameteriv,_emscripten_glIsTexture,_emscripten_glGenBuffers,_emscripten_glDeleteBuffers,_emscripten_glGetBufferParameteriv,_emscripten_glBufferData,_emscripten_glBufferSubData,_emscripten_glIsBuffer
,_emscripten_glGenRenderbuffers,_emscripten_glDeleteRenderbuffers,_emscripten_glBindRenderbuffer,_emscripten_glGetRenderbufferParameteriv,_emscripten_glIsRenderbuffer,_emscripten_glGetUniformfv,_emscripten_glGetUniformiv,_emscripten_glGetUniformLocation,_emscripten_glGetVertexAttribfv,_emscripten_glGetVertexAttribiv,_emscripten_glGetVertexAttribPointerv,_emscripten_glGetActiveUniform,_emscripten_glUniform1f$legalf32,_emscripten_glUniform2f$legalf32,_emscripten_glUniform3f$legalf32,_emscripten_glUniform4f$legalf32,_emscripten_glUniform1i,_emscripten_glUniform2i,_emscripten_glUniform3i,_emscripten_glUniform4i,_emscripten_glUniform1iv,_emscripten_glUniform2iv,_emscripten_glUniform3iv,_emscripten_glUniform4iv,_emscripten_glUniform1fv,_emscripten_glUniform2fv,_emscripten_glUniform3fv,_emscripten_glUniform4fv,_emscripten_glUniformMatrix2fv,_emscripten_glUniformMatrix3fv
,_emscripten_glUniformMatrix4fv,_emscripten_glBindBuffer,_emscripten_glVertexAttrib1fv,_emscripten_glVertexAttrib2fv,_emscripten_glVertexAttrib3fv,_emscripten_glVertexAttrib4fv,_emscripten_glGetAttribLocation,_emscripten_glGetActiveAttrib,_emscripten_glCreateShader,_emscripten_glDeleteShader,_emscripten_glGetAttachedShaders,_emscripten_glShaderSource,_emscripten_glGetShaderSource,_emscripten_glCompileShader,_emscripten_glGetShaderInfoLog,_emscripten_glGetShaderiv,_emscripten_glGetProgramiv,_emscripten_glIsShader,_emscripten_glCreateProgram,_emscripten_glDeleteProgram,_emscripten_glAttachShader,_emscripten_glDetachShader,_emscripten_glGetShaderPrecisionFormat,_emscripten_glLinkProgram,_emscripten_glGetProgramInfoLog,_emscripten_glUseProgram,_emscripten_glValidateProgram,_emscripten_glIsProgram,_emscripten_glBindAttribLocation,_emscripten_glBindFramebuffer
,_emscripten_glGenFramebuffers,_emscripten_glDeleteFramebuffers,_emscripten_glFramebufferRenderbuffer,_emscripten_glFramebufferTexture2D,_emscripten_glGetFramebufferAttachmentParameteriv,_emscripten_glIsFramebuffer,_emscripten_glDeleteObjectARB,_emscripten_glGetObjectParameterivARB,_emscripten_glGetInfoLogARB,_emscripten_glBindProgramARB,_emscripten_glGetPointerv,_emscripten_glDrawRangeElements,_emscripten_glEnableClientState,_emscripten_glVertexPointer,_emscripten_glTexCoordPointer,_emscripten_glNormalPointer,_emscripten_glColorPointer,_emscripten_glClientActiveTexture,_emscripten_glGenVertexArrays,_emscripten_glDeleteVertexArrays,_emscripten_glBindVertexArray,_emscripten_glMatrixMode,_emscripten_glLoadIdentity,_emscripten_glLoadMatrixf,_emscripten_glFrustum,_emscripten_glRotatef$legalf32,_emscripten_glVertexAttribPointer,_emscripten_glEnableVertexAttribArray,_emscripten_glDisableVertexAttribArray,_emscripten_glDrawArrays
,_emscripten_glDrawElements,_emscripten_glShaderBinary,_emscripten_glReleaseShaderCompiler,_emscripten_glGetError,_emscripten_glVertexAttribDivisor,_emscripten_glDrawArraysInstanced,_emscripten_glDrawElementsInstanced,_emscripten_glFinish,_emscripten_glFlush,_emscripten_glClearDepth,_emscripten_glClearDepthf$legalf32,_emscripten_glDepthFunc,_emscripten_glEnable,_emscripten_glDisable,_emscripten_glFrontFace,_emscripten_glCullFace,_emscripten_glClear,_emscripten_glLineWidth$legalf32,_emscripten_glClearStencil,_emscripten_glDepthMask,_emscripten_glStencilMask,_emscripten_glCheckFramebufferStatus,_emscripten_glGenerateMipmap,_emscripten_glActiveTexture,_emscripten_glBlendEquation,_emscripten_glIsEnabled,_emscripten_glBlendFunc,_emscripten_glBlendEquationSeparate,_emscripten_glDepthRange,_emscripten_glDepthRangef$legalf32
,_emscripten_glStencilMaskSeparate,_emscripten_glHint,_emscripten_glPolygonOffset$legalf32,_emscripten_glVertexAttrib1f$legalf32,_emscripten_glSampleCoverage$legalf32,_emscripten_glTexParameteri,_emscripten_glTexParameterf$legalf32,_emscripten_glVertexAttrib2f$legalf32,_emscripten_glStencilFunc,_emscripten_glStencilOp,_emscripten_glViewport,_emscripten_glClearColor$legalf32,_emscripten_glScissor,_emscripten_glVertexAttrib3f$legalf32,_emscripten_glColorMask,_emscripten_glRenderbufferStorage,_emscripten_glBlendFuncSeparate,_emscripten_glBlendColor$legalf32,_emscripten_glStencilFuncSeparate,_emscripten_glStencilOpSeparate,_emscripten_glVertexAttrib4f$legalf32,_emscripten_glCopyTexImage2D,_emscripten_glCopyTexSubImage2D,_emscripten_glDrawBuffers,
.....]

but we don't have implementations of any of the functions of name _emscripten_glUniform1f$legalf32 and so on, but these are present under the names _emscripten_glUniform1f etc. In Fastcomp in JSBackend.cpp, there's makeFloat32Legalizer() which generates these missing functions, but for some reason those are not getting included in the build. I wonder if this might be MAIN_MODULE=1 specific?

Sounds like this is v8-specific, like https://github.com/kripken/emscripten/issues/5034#issuecomment-320533368 ?

Then, in Chrome (v59) and node.js (v8.2.1, installed for Ubuntu 16.4 from https://nodejs.org/en/download/package-manager, compare comment in build.sh) an error occurs at runtime [..] Firefox (v54) seems to be fine.

Err sorry, mismatched formatting made part of my above reply unreadable.

Sounds like this is v8-specific

It reproduces on current Emscripten incoming and when building to html and running in Firefox. The issue is that the above compilation command line EMCC_FORCE_STDLIBS=1 em++ -s WASM=1 -s MAIN_MODULE=1 -o null.js null.cc creates an output js file that references nonexisting symbols such as _emscripten_glUniform1f$legalf32, which are not being emitted to the output file.

Thanks. Looking into this, the issue is when we force-include the gl library (which 1 forces since it forces them all, as opposed to listing the specific libs). When it's included, the backend emits _emscripten_glUniform1f$legalf32, which is implemented inside the wasm module, but we try to access it outside directly (by name, without looking on the "asm" object).

This is wrong for 2 reasons,

  • The main-module code is not aware of wasm async compilation. That code needs some rewriting to support that, right now it assumes sync compilation. Perhaps we should add a warning or error for this?
  • it should access asm['..'] of that function, and not the name directly. That might be a straightforward fix in emscripten.py, where it emits the tables to emulated function pointer tables.

The issue can also be worked around with https://github.com/kripken/emscripten-fastcomp/pull/195 , since really we don't even need the legalization here.

I hit this bug as soon as I added -s USE_SDL=2 in my application that uses dynamic loading. It happened when loading the main module which was not using SDL or GL (such code was in the dynamic modules) - so it happened before any of my SDL or GL code was even loaded. Fiddling with EMCC_FORCE_STDLIBS didn't help.
The fastcomp patch got rid of the issue. I'll post a comment if it breaks anything else for me.

No issues to report so far.
I just remembered I was testing the patch when I upgraded and emscripten complained again about _emscripten_glUniform1f$legalf32 ^_^

The tricky thing is that that patch did break a test (see https://github.com/kripken/emscripten-fastcomp/pull/195#issuecomment-321380195 ). That needs to be looked into before we land it.

Any news? This bug seems to be the only thing blocking me from switching from asmjs to wasm.

FWIW it popped out again today after linking with -g3:

ReferenceError: _emscripten_glTexParameterf$legalf32 is not defined

I thought I wasn't impacted anymore, weird. Patched again.
I need to take some time and look further into this.

For info the above occurred while running a WASM program with only static linking (no dynamic linking option involved).
The affected function changes, although it's always GL-related.

ReferenceError: _emscripten_glClearIndex$legalf32 is not defined

FWIW I made some further investigation at https://github.com/kripken/emscripten-fastcomp/pull/195#issuecomment-439354461 though the root cause is probably too far for my current understanding of emscripten.

Meanwhile, rather than applying the bug-introducing patch I'm just:

sed -i -e 's/$$legalf32//g' index.js
¯\_(ツ)_/¯

what's the solution finally?

We are close to switching to the LLVM wasm backend by default, which should not have this bug. Can test with it now, but we only have emsdk builds for linux so far, with emsdk update latest-upstream (that's why we didn't make an announcement yet, still working on builders).

This issue has been automatically marked as stale because there has been no activity in the past year. It will be closed automatically if no further activity occurs in the next 7 days. Feel free to re-open at any time if this issue is still relevant.

Was this page helpful?
0 / 5 - 0 ratings