Skip to content

Conversation

@superstructor
Copy link

Fixes runtime crash caused by fonts loading asynchronously after FcInit() call.

ROOT CAUSE:

  • Emscripten loads --preload-file fonts asynchronously via XHR
  • callMain() executes immediately after WASM runtime init
  • FcInit() runs before /fonts/*.ttf files are in virtual FS
  • Fontconfig initializes with empty font list (0 fonts found)
  • Pango crashes trying to create fontmap with no fonts (NULL vtable)

SOLUTION:
Implement ASYNCIFY-based polling for font availability before initializing fontconfig/Pango. This allows C code to "sleep" and yield to the JS event loop while fonts are being loaded.

CHANGES:

  1. main.c:

    • Add emscripten_sleep()-based polling in start_demo()
    • Poll for /fonts/Roboto-Regular.ttf existence with 10ms intervals
    • 1 second timeout (100 retries × 10ms)
    • Improved logging with [WASM] prefix for consistency
    • Enhanced font verification and error reporting
  2. build-final.sh (NEW):

    • Enable ASYNCIFY with -sASYNCIFY=1
    • Configure ASYNCIFY stack size (12KB)
    • Whitelist emscripten_sleep for ASYNCIFY imports
    • Automatic font download if missing
    • Smart detection of GTK installation location
    • Comprehensive build flags for production WASM output
  3. test-wasm-init.ts:

    • Add monitorRunDependencies callback to track file loading
    • Automatically call start_demo() when all files loaded (left === 0)
    • Proper wait logic with timeout
    • Better error handling for "unwind" exception

EXPECTED BEHAVIOR:
✅ Fonts load before FcInit() call
✅ FcInit() finds ≥4 fonts (Regular, Bold, Italic, BoldItalic) ✅ Pango initializes without NULL pointer crash
✅ Font rendering works in widget factory demo

Console output:
[WASM] Widget factory demo starting...
[WASM] Waiting for fonts to load...
[WASM] ✅ Fonts available after 0ms
[WASM] Initializing fontconfig...
[WASM] Found 4 fonts:
[WASM] Roboto Regular
[WASM] Roboto Bold
[WASM] Roboto Italic
[WASM] Roboto BoldItalic
[WASM] ✅ Fontconfig initialized with embedded fonts

ASYNCIFY OVERHEAD:

  • Binary size increase: ~13% (acceptable for demo)
  • Runtime overhead: minimal
  • Cleanest solution for async operations in synchronous C code

BUILD:
cd demos/webgpu-widget-factory
bash build-final.sh

TEST:
deno test --allow-read --allow-write --import-map=import_map.json test-wasm-init.ts

…y demo

Fixes runtime crash caused by fonts loading asynchronously after FcInit() call.

ROOT CAUSE:
- Emscripten loads --preload-file fonts asynchronously via XHR
- callMain() executes immediately after WASM runtime init
- FcInit() runs before /fonts/*.ttf files are in virtual FS
- Fontconfig initializes with empty font list (0 fonts found)
- Pango crashes trying to create fontmap with no fonts (NULL vtable)

SOLUTION:
Implement ASYNCIFY-based polling for font availability before initializing
fontconfig/Pango. This allows C code to "sleep" and yield to the JS event
loop while fonts are being loaded.

CHANGES:
1. main.c:
   - Add emscripten_sleep()-based polling in start_demo()
   - Poll for /fonts/Roboto-Regular.ttf existence with 10ms intervals
   - 1 second timeout (100 retries × 10ms)
   - Improved logging with [WASM] prefix for consistency
   - Enhanced font verification and error reporting

2. build-final.sh (NEW):
   - Enable ASYNCIFY with -sASYNCIFY=1
   - Configure ASYNCIFY stack size (12KB)
   - Whitelist emscripten_sleep for ASYNCIFY imports
   - Automatic font download if missing
   - Smart detection of GTK installation location
   - Comprehensive build flags for production WASM output

3. test-wasm-init.ts:
   - Add monitorRunDependencies callback to track file loading
   - Automatically call start_demo() when all files loaded (left === 0)
   - Proper wait logic with timeout
   - Better error handling for "unwind" exception

EXPECTED BEHAVIOR:
✅ Fonts load before FcInit() call
✅ FcInit() finds ≥4 fonts (Regular, Bold, Italic, BoldItalic)
✅ Pango initializes without NULL pointer crash
✅ Font rendering works in widget factory demo

Console output:
[WASM] Widget factory demo starting...
[WASM] Waiting for fonts to load...
[WASM] ✅ Fonts available after 0ms
[WASM] Initializing fontconfig...
[WASM] Found 4 fonts:
[WASM]   Roboto Regular
[WASM]   Roboto Bold
[WASM]   Roboto Italic
[WASM]   Roboto BoldItalic
[WASM] ✅ Fontconfig initialized with embedded fonts

ASYNCIFY OVERHEAD:
- Binary size increase: ~13% (acceptable for demo)
- Runtime overhead: minimal
- Cleanest solution for async operations in synchronous C code

BUILD:
cd demos/webgpu-widget-factory
bash build-final.sh

TEST:
deno test --allow-read --allow-write --import-map=import_map.json test-wasm-init.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants