Wasm Emscripten

mohitmishra786/low-level-dev-skills/skills/runtimes/wasm-emscripten

作者 mohitmishra786bdc58472fa9f无许可证253 个星标收录于 2026年10月9日更新于 2026年10月9日仓库3个月前更新

WebAssembly with Emscripten skill for C/C++ to WASM compilation. Use when compiling C/C++ to WebAssembly with emcc, configuring EXPORTED_FUNCTIONS, understanding the WASM memory model, using Asyncify for async C code, debugging .wasm with browser devtools or wasm-opt, or targeting WASI vs browser environments. Activates on queries about Emscripten, emcc, WebAssembly from C/C++, WASM memory model, Asyncify, EXPORTED_FUNCTIONS, WASI, or wasm-opt.

AI 生成的概览

指导使用 Emscripten 将 C/C++ 编译为 WebAssembly,涵盖 emcc 参数、导出、内存、Asyncify 与调试。

功能
该技能提供使用 Emscripten 工具链将 C 和 C++ 代码编译为 WebAssembly 的指导。内容涵盖 emcc 参数选择、向 JavaScript 导出函数、线性内存模型、用于异步 C 代码的 Asyncify、使用 wasm-opt 优化、调试 .wasm 二进制文件,以及在 WASI 与浏览器目标之间做选择。它还指向一份随附的 Emscripten 链接器参数参考文件。
适用场景
适用于使用 emcc 将 C 或 C++ 编译为 WebAssembly、配置导出函数或运行时方法,或理解 WASM 内存模型的场景。也适合关于 Asyncify、调试 .wasm 文件、wasm-opt 优化以及 WASI 与浏览器目标对比的问题。
运行要求
需要 Emscripten SDK(emcc),部分步骤还需要 wasm-opt/Binaryen、wasmtime 或 wasi-sdk,以及用于浏览器测试的本地 HTTP 服务器。不附带脚本,仅为说明文档,另有一份参考 markdown 文件。

WebAssembly with Emscripten

Purpose

Guide agents through compiling C/C++ to WebAssembly using Emscripten: emcc flag selection, function exports, memory model configuration, Asyncify for asynchronous C code, debugging WASM binaries, and targeting WASI vs browser.

Triggers

  • "How do I compile C to WebAssembly with Emscripten?"
  • "How do I export a C function to JavaScript?"
  • "How does WebAssembly memory work with Emscripten?"
  • "How do I debug a .wasm file?"
  • "How do I use Asyncify to make synchronous C code async?"
  • "What's the difference between WASI and Emscripten browser target?"

Workflow

1. Setup and first build

bash
# Install Emscripten SDKgit clone https://github.com/emscripten-core/emsdk.gitcd emsdk./emsdk install latest./emsdk activate latestsource ./emsdk_env.sh    # add emcc to PATH
# Verifyemcc --version
# Compile C to WASM (browser target)emcc hello.c -o hello.html          # generates hello.html + hello.js + hello.wasmemcc hello.c -o hello.js            # just JS + WASM (no HTML shell)
# Serve locally (WASM requires HTTP, not file://)python3 -m http.server 8080# Open: http://localhost:8080/hello.html

2. Exporting functions to JavaScript

c
// math.c#include <emscripten.h>
// EMSCRIPTEN_KEEPALIVE prevents dead-code eliminationEMSCRIPTEN_KEEPALIVEint add(int a, int b) {    return a + b;}
EMSCRIPTEN_KEEPALIVEdouble sqrt_approx(double x) {    return x * 0.5 + 1.0;}
bash
# Export specific functionsemcc math.c -o math.js \  -s EXPORTED_FUNCTIONS='["_add","_sqrt_approx"]' \  -s EXPORTED_RUNTIME_METHODS='["ccall","cwrap"]' \  -s MODULARIZE=1 \  -s EXPORT_NAME=MathModule
# The leading underscore is required for C functions
javascript
// Using exported functions in JSconst Module = await MathModule();
// Direct callconst result = Module._add(3, 4);
// Via ccall (type-safe)const result2 = Module.ccall('add', 'number', ['number', 'number'], [3, 4]);
// Via cwrap (creates a callable JS function)const add = Module.cwrap('add', 'number', ['number', 'number']);console.log(add(3, 4));  // 7

3. Memory model

Emscripten provides a linear memory heap accessible from both C and JS:

bash
# Configure initial and maximum heapemcc prog.c -o prog.js \  -s INITIAL_MEMORY=16MB \  -s MAXIMUM_MEMORY=256MB \  -s ALLOW_MEMORY_GROWTH=1    # allow dynamic growth
# Stack size (default 64KB)emcc prog.c -o prog.js -s STACK_SIZE=1MB
# Shared memory (for SharedArrayBuffer / threads)emcc prog.c -o prog.js -s SHARED_MEMORY=1 -s USE_PTHREADS=1
javascript
// Accessing C memory from JSconst ptr = Module._malloc(1024);     // allocateModule.HEAPU8.set([1, 2, 3], ptr);   // write bytesModule._free(ptr);                     // free
// Read a C stringconst strPtr = Module.ccall('get_message', 'number', [], []);const str = Module.UTF8ToString(strPtr);
// Write a string to Cconst jsStr = "hello";const cStr = Module.stringToNewUTF8(jsStr);  // malloc + copyModule._process_string(cStr);Module._free(cStr);

4. Asyncify — synchronous C in async environments

Asyncify lets synchronous C code suspend and resume for async operations (like fetch(), sleep, etc.):

c
// async.c#include <emscripten.h>
// Synchronous sleep in C (blocks C, but yields to JS event loop)EM_JS(void, do_fetch, (const char *url), {    // Emscripten generates wrappers to suspend C while JS runs    Asyncify.handleAsync(async () => {        const resp = await fetch(UTF8ToString(url));        const text = await resp.text();        console.log(text);    });});
void process_url(const char *url) {    do_fetch(url);     // looks synchronous in C    printf("fetch complete\n");}
bash
# Enable Asyncifyemcc async.c -o async.js \  -s ASYNCIFY \  -s ASYNCIFY_STACK_SIZE=16384 \  -O2   # Asyncify works better with optimization

5. Optimization and wasm-opt

bash
# Optimization levelsemcc prog.c -O0 -o prog.js    # no optimization (fastest build)emcc prog.c -O2 -o prog.js    # balancedemcc prog.c -O3 -o prog.js    # aggressiveemcc prog.c -Os -o prog.js    # optimize for sizeemcc prog.c -Oz -o prog.js    # aggressive size (Emscripten's smallest)
# Post-process with wasm-opt (Binaryen)wasm-opt -Oz -o prog.opt.wasm prog.wasm    # optimize for sizewasm-opt -O4 -o prog.opt.wasm prog.wasm    # optimize for speed
# Compare sizesls -lh prog.wasm prog.opt.wasm

6. Debugging WASM

bash
# Build with debug infoemcc prog.c -g -O0 -o prog.html \  -s ASSERTIONS=1 \  -s SAFE_HEAP=1      # catch misaligned accesses
# In Chrome DevTools:# Sources → prog.wasm → line-by-line C source debugging# (requires -g and browser with WASM debugging support)
# LLDB with WASM (wasmtime)# See skills/runtimes/wasm-wasmtime for CLI WASM debugging
bash
# Emscripten debug helpersemcc prog.c -o prog.js \  -s ASSERTIONS=2       # extensive runtime checks  -s SAFE_HEAP=1        # sanitize heap accesses  -s STACK_OVERFLOW_CHECK=1
# Print generated JSemcc prog.c -o prog.js && cat prog.js | head -100

7. WASI vs browser target

FeatureBrowser (Emscripten)WASI
Host APIsWeb APIs (fetch, WebGL, etc.)POSIX subset (files, stdin/stdout)
RuntimeBrowser JS enginewasmtime, wasmer, WAMR, Node.js
ThreadsSharedArrayBuffer + pthreadswasi-threads (limited)
Networkingfetch(), WebSocketwasi-http (preview2)
Use caseWeb applicationsServer-side, CLI tools, edge
bash
# Build for WASI (no browser JS, pure WASM)emcc prog.c -o prog.wasm --target=wasi
# Or use wasi-sdk (better WASI support than Emscripten)/opt/wasi-sdk/bin/clang --sysroot=/opt/wasi-sdk/share/wasi-sysroot \  prog.c -o prog.wasmwasmtime prog.wasm

For Emscripten linker flags reference, see references/emscripten-linker-flags.md [blocked].

Related skills

  • Use skills/runtimes/wasm-wasmtime for server-side WASM with wasmtime CLI and Rust embedding
  • Use skills/compilers/clang for Clang-based WASM compilation with WASI SDK
  • Use skills/binaries/elf-inspection for inspecting WASM binary structure

来源与署名

来源:mohitmishra786/low-level-dev-skills位于skills/runtimes/wasm-emscripten提交bdc5847

许可证: 无许可证

内容归原作者所有。SourceWeft 从公开仓库中收录这些内容。

举报或申请下架