diff --git a/scripts/common/inject-dyncall-shims.sh b/scripts/common/inject-dyncall-shims.sh index adb72a8..d89ea9b 100755 --- a/scripts/common/inject-dyncall-shims.sh +++ b/scripts/common/inject-dyncall-shims.sh @@ -112,3 +112,65 @@ mv "${JS_FILE}.tmp" "$JS_FILE" rm "$SHIM_FILE" echo "Successfully injected $SIG_COUNT dynCall shims into $JS_FILE" + +# Fix empty callback arrow functions generated by Emscripten with pthreads +# When pthreads is enabled, Emscripten generates empty {} for some direct-call paths +# because it assumes they won't be used. But they ARE used in certain cases. +# The dynCall_* functions exist (generated above), we just need to call them. +echo "Fixing empty callback arrow functions..." + +TOTAL_FIXED=0 + +# Fix 1: HTML5 event callbacks (3 args) - signature iiii +# Pattern: ((a1, a2, a3) => {})(eventTypeId, ... +# Function pointer is 'callbackfunc' in these contexts +COUNT_BEFORE=$(grep -c '((a1, a2, a3) => {})(eventTypeId,' "$JS_FILE" || true) +if [ "$COUNT_BEFORE" -gt 0 ]; then + sed -i '' 's/((a1, a2, a3) => {})(eventTypeId,/((a1, a2, a3) => dynCall_iiii(callbackfunc, a1, a2, a3))(eventTypeId,/g' "$JS_FILE" + COUNT_AFTER=$(grep -c '((a1, a2, a3) => {})(eventTypeId,' "$JS_FILE" || true) + FIXED=$((COUNT_BEFORE - COUNT_AFTER)) + echo " Fixed $FIXED HTML5 event callback(s) (dynCall_iiii)" + TOTAL_FIXED=$((TOTAL_FIXED + FIXED)) +fi + +# Fix 2: invokeEntryPoint pthread entry (1 arg) - signature ii (returns pointer) +# Pattern in invokeEntryPoint: var result = (a1 => {})(arg); +# Function pointer is 'ptr' +COUNT_BEFORE=$(grep -c 'var result = (a1 => {})(arg);' "$JS_FILE" || true) +if [ "$COUNT_BEFORE" -gt 0 ]; then + sed -i '' 's/var result = (a1 => {})(arg);/var result = dynCall_ii(ptr, arg);/g' "$JS_FILE" + COUNT_AFTER=$(grep -c 'var result = (a1 => {})(arg);' "$JS_FILE" || true) + FIXED=$((COUNT_BEFORE - COUNT_AFTER)) + echo " Fixed $FIXED pthread entry callback(s) (dynCall_ii)" + TOTAL_FIXED=$((TOTAL_FIXED + FIXED)) +fi + +# Fix 3: ___call_sighandler (1 arg) - signature vi (void return) +# Pattern: return (a1 => {})(sig); +# Function pointer is 'fp' +COUNT_BEFORE=$(grep -c 'return (a1 => {})(sig);' "$JS_FILE" || true) +if [ "$COUNT_BEFORE" -gt 0 ]; then + sed -i '' 's/return (a1 => {})(sig);/return dynCall_vi(fp, sig);/g' "$JS_FILE" + COUNT_AFTER=$(grep -c 'return (a1 => {})(sig);' "$JS_FILE" || true) + FIXED=$((COUNT_BEFORE - COUNT_AFTER)) + echo " Fixed $FIXED signal handler callback(s) (dynCall_vi)" + TOTAL_FIXED=$((TOTAL_FIXED + FIXED)) +fi + +# Fix 4: _emscripten_async_call timer (1 arg) - signature vi (void return) +# Pattern: var wrapper = () => (a1 => {})(arg); +# Function pointer is 'func' +COUNT_BEFORE=$(grep -c 'var wrapper = () => (a1 => {})(arg);' "$JS_FILE" || true) +if [ "$COUNT_BEFORE" -gt 0 ]; then + sed -i '' 's/var wrapper = () => (a1 => {})(arg);/var wrapper = () => dynCall_vi(func, arg);/g' "$JS_FILE" + COUNT_AFTER=$(grep -c 'var wrapper = () => (a1 => {})(arg);' "$JS_FILE" || true) + FIXED=$((COUNT_BEFORE - COUNT_AFTER)) + echo " Fixed $FIXED async timer callback(s) (dynCall_vi)" + TOTAL_FIXED=$((TOTAL_FIXED + FIXED)) +fi + +if [ "$TOTAL_FIXED" -gt 0 ]; then + echo "Total: Fixed $TOTAL_FIXED empty callback(s)" +else + echo "No empty callbacks found - nothing to fix" +fi diff --git a/scripts/common/logging.sh b/scripts/common/logging.sh index 0c09bd2..69cce2b 100644 --- a/scripts/common/logging.sh +++ b/scripts/common/logging.sh @@ -41,8 +41,18 @@ mkdir -p "${_LOGS_DIR}" # Show log path before re-exec echo "Logging to: ${_LOG_FILE}" -# Re-exec the calling script with output redirected +# Run the calling script with output redirected # This is equivalent to: ./script.sh > logfile 2>&1 # and reliably captures ALL output including docker compose TTY messages export KICAD_LOG_NESTED=1 -exec "${_CALLER_SCRIPT}" "$@" > "${_LOG_FILE}" 2>&1 +"${_CALLER_SCRIPT}" "$@" > "${_LOG_FILE}" 2>&1 +_EXIT_CODE=$? + +# Print completion message (this runs AFTER the script finishes) +if [[ ${_EXIT_CODE} -eq 0 ]]; then + echo "Done. Log: ${_LOG_FILE}" +else + echo "Failed (exit ${_EXIT_CODE}). Log: ${_LOG_FILE}" +fi + +exit ${_EXIT_CODE}