subagent transcript

session 18e25685 · workflow wf_23df5b1c
delegated task
You are an adversarial verifier for a FreeCAD-wasm code review. A reviewer claims: SEVERITY: info CATEGORY: latent-inconsistency FILE: /home/magik6k/l
▸ Magik
You are an adversarial verifier for a FreeCAD-wasm code review. A reviewer claims: SEVERITY: info CATEGORY: latent-inconsistency FILE: /home/magik6k/lcad-wasm/freecad-port/FreeCAD/src/Gui/WasmGLFixedFunc.cpp SUMMARY: WasmGLFixedFunc strong-defines glEnable/glDisable/glDrawArrays/glDrawElements, but emscripten_GetProcAddress resolves the emscripten originals, so dynamic resolution bypasses the fixed-function filtering. DETAIL/EVIDENCE: WasmGLFixedFunc.cpp:342-343,397-406 override glEnable/glDisable/glDrawArrays/glDrawElements with strong C symbols so Coin/Qt direct (link-time) calls hit the filtering/passthrough wrappers. However cc_glglue_getprocaddress tries emscripten_GetProcAddress first (gl.cpp:620), which returns emscripten's OWN glDrawArrays/glEnable, not these overrides. Any code path that resolves these names dynamically would get the unfiltered emscripten versions, splitting behavior between direct and resolved calls. Coin calls these directly today so rendering is unaffected, but it is a fragile split worth being aware of if a future path resolves them via the glue. RECOMMENDATION: If any consumer starts resolving these via cc_glglue_getprocaddress, add them to fcWasmResolveGL and short-circuit them ahead of emscripten_GetProcAddress, or document that these four must only be called via direct linkage. Independently verify by reading the actual file(s) and running git/grep as needed (repo at /home/magik6k/lcad-wasm/freecad-port/FreeCAD, toolchain at /opt/toolchains, deploy at /home/magik6k/lcad-wasm/freecad-port/deploy-gui). Default to REFUTED if you cannot confirm the evidence. Adjust severity to what the evidence actually supports.
Fable
thinking
I should verify this claim by examining the file and checking what evidence supports it.
Fable
⚙ Read {"file_path": "/home/magik6k/lcad-wasm/freecad-port/FreeCAD/src/Gui/WasmGLFixedFunc.cpp"}
tool result
1	/* SPDX-License-Identifier: LGPL-2.1-or-later
2	 *
3	 * WebAssembly build only. A compact fixed-function OpenGL 1.x emulation over
4	 * WebGL2/GLES3, so Coin3D (which renders FreeCAD geometry with legacy GL) can
5	 * draw into the WebGL2 context Qt hands us. Emscripten's LEGACY_GL_EMULATION
6	 * is WebGL1-only and conflicts with Qt's forced WebGL2, so we implement the
7	 * subset Coin actually exercises ourselves.
8	 *
9	 * Design: the legacy entry points are C functions here; the state and dr  …[truncated]
Fable
⚙ Bash {"command": "cd /home/magik6k/lcad-wasm/freecad-port/FreeCAD && grep -n \"emscripten_GetProcAddress\\|cc_glglue_getprocaddress\\|fcWasmResolveGL\" src/3rdParty/salomesmesh/src/*/*.cpp 2>/dev/null; echo \"---gl.cpp---\"; grep -rn \"emscripte…
tool result
---gl.cpp---
src/3rdParty/coin/src/glue/gl_wgl.cpp:171:#define PROC(_glue_, _func_) cc_glglue_getprocaddress(_glue_, SO__QUOTE(_func_))
src/3rdParty/coin/src/glue/gl_glx.cpp:374:#define PROC(_glue_, _func_) cc_glglue_getprocaddress(_glue_, SO__QUOTE(_func_))
src/3rdParty/coin/src/glue/gl.cpp:609:cc_glglue_getprocaddress(const cc_glglue * glue, const char * symname)
src/3rdParty/coin/src/glue/gl.cpp:619:    extern void * emscripten_GetProcAddress(const char *);
src/3rdParty/coin/src/glue/gl.cpp:6  …[truncated]
Fable
thinking
I'm looking at the getprocaddress function in gl.cpp, specifically the section around lines 609-650.
Fable
⚙ Read {"file_path": "/home/magik6k/lcad-wasm/freecad-port/FreeCAD/src/3rdParty/coin/src/glue/gl.cpp", "offset": 605, "limit": 50}
tool result
605	}
606	
607	/* doc in header file */
608	void *
609	cc_glglue_getprocaddress(const cc_glglue * glue, const char * symname)
610	{
611	  void * ptr = NULL;
612	
613	#ifdef __EMSCRIPTEN__
614	  // On WebAssembly there is no WGL/EGL/GLX/dlsym; resolve GL entry points
615	  // (both emscripten's real WebGL2 functions and our fixed-function emulation
616	  // in Gui/WasmGLFixedFunc.cpp) through emscripten's own resolver.
617	  {
618	    /* This file is compiled as C; these are C-linkage symbols. */  …[truncated]
Fable
thinking
I'm verifying the structural claims about the WebAssembly GL implementation. The first two points check out—WasmGLFixedFunc.cpp does define the GL functions directly, and the proc address lookup tries the Emscripten function first before falling back. But the third point about fcWasmResolveGL appears to be cut off mid-sentence.

Looking at the broader context, the key insight is that while the strong C symbols in WasmGLFixedFunc.cpp override Emscripten's weak symbols at link time, emscripten_GetProcAddress bypasses this by using an internal function table that maps directly to Emscripten's implementations. This creates a latent inconsistency where dynamic resolution would return different fu  …
Fable
All evidence checks out. Let me verify the exact line references and the fcWasmResolveGL table contents once more against the claim. The findings are fully confirmed: 1. **Strong overrides exist** (WasmGLFixedFunc.cpp): `glEnable`/`glDisable` at lines 342-343, `glDrawArrays`/`glDrawElements` at lines 397-406 — plain `extern "C"` strong symbols that win at link time over emscripten's library symbols. 2. **emscripten_GetProcAddress is tried first** (gl.cpp:620): `ptr = emscripten_GetProcAddress(symname); if (ptr) goto returnpoint;` — and only if that returns null does it fall through to `fcWasmResolveGL` (line 627). Since `glEnable`, `glDisable`, `glDrawArrays`, `glDrawElements` are all standard functions in emscripten's GL name table, `emscripten_GetProcAddress` returns emscripten's own implementations, short-circuiting before `fcWasmResolveGL` is ever consulted. 3. **fcWasmResolveGL (lines 508-525) does NOT list these four** — its table only contains multitexture, matrix-stack, immediate-mode, and client-array entry points. So even the fallback wouldn't return the overrides. The consequence is exactly as described: a name resolved via `cc_glglue_getprocaddress` yields the unfiltered emscripten function, whereas direct (link-time) calls hit the filtering wrappers — a behavioral split. The reviewer correctly qualifies this as latent: Coin calls these four directly (they are core GL 1.1, not extension entry points that Coin resolves via glue), so today's rendering is unaffected. The info severity is appropriate — no active defect, just a fragile inconsistency that would bite a future consumer.
Fable
⚙ StructuredOutput {"verdict": "CONFIRMED", "reason": "All cited evidence verified against the source. WasmGLFixedFunc.cpp strong-defines glEnable/glDisable (lines 342-343) and glDrawArrays/glDrawElements (lines 397-406) as extern \"C\" symbols that win at li…
tool result
Structured output provided successfully