Skip to content

Commit bf4183d

Browse files
cmake: define NDEBUG on the QuickJS library target
QuickJS asserts list_empty(rt->gc_obj_list) at the end of JS_FreeRuntime. On embedders that legitimately have non-cycle-collected refs to JS values held by long-lived native code, the cycle collector cannot break those pins and the assertion aborts the process at shutdown. After the assert, QuickJS' own fallback code in JS_FreeRuntime walks gc_obj_list itself and frees what's still there, so disabling the assert is safe. Define NDEBUG only on the qjs (and qjs-libc) targets so the rest of the project keeps assertions enabled in Debug builds. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent a98aabf commit bf4183d

1 file changed

Lines changed: 12 additions & 0 deletions

File tree

CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,18 @@ endif()
151151
if(NAPI_JAVASCRIPT_ENGINE STREQUAL "QuickJS")
152152
option(QJS_BUILD_LIBC "Build QuickJS with libc support." ON)
153153
FetchContent_MakeAvailable_With_Message(quickjs-ng)
154+
# Always disable assert() inside the QuickJS library, including in Debug
155+
# builds. QuickJS asserts that rt->gc_obj_list is empty in JS_FreeRuntime,
156+
# which can fire on teardown when external (non-cycle-collected) refs from
157+
# the embedder pin objects. Defining NDEBUG turns those asserts into no-ops
158+
# and lets QuickJS's own free-everything fallback path run without aborting
159+
# the process. This only affects the quickjs/qjs targets; our own code is
160+
# still built with asserts enabled.
161+
foreach(_qjs_target qjs qjs-libc)
162+
if(TARGET ${_qjs_target})
163+
target_compile_definitions(${_qjs_target} PRIVATE NDEBUG)
164+
endif()
165+
endforeach()
154166
endif()
155167

156168
if(NAPI_JAVASCRIPT_ENGINE STREQUAL "V8" AND JSRUNTIMEHOST_CORE_APPRUNTIME_V8_INSPECTOR)

0 commit comments

Comments
 (0)