Emscripten Compiler Toolchain

repository·main·Indexed 12 days ago

https://github.com/emscripten-core/emscripten

A compiler toolchain that translates C and C++ code into WebAssembly using LLVM and Binaryen. It enables high-performance native applications, including those using OpenGL or SDL2, to run on the Web, Node.js, and various WebAssembly runtimes. The toolchain includes the emcc compiler interface, a customized musl libc implementation, and a patched fork of LLVM's libc++.

Tokens
185.4K
Snippets
564
Records
820
Agent score
93%

What's inside Emscripten

  1. What is Emscripten?

    main

    Emscripten is an open-source compiler toolchain that targets WebAssembly (Wasm). It allows you to compile C and C++ code (or any language using LLVM) into WebAssembly to run on the Web, Node.js, or other Wasm runtimes.

    Key capabilities include:

    • Compiling portable C/C++ codebases (e.g., games, application frameworks like Qt) into high-performance WebAssembly.
    • Compiling C/C++ runtimes for other languages (e.g., Python, Lua) into WebAssembly to enable indirect execution of those languages.
    • Automatic optimization through integration with LLVM, Binaryen, and Closure Compiler to produce small, fast, and safe code.
  2. Overview of the Emscripten toolchain

    main

    The Emscripten toolchain consists of several key tools used for compiling C/C++ code to WebAssembly and managing the development environment:

    • emcc: The primary compiler command used to call the Emscripten compiler from the command line. It acts as a drop-in replacement for standard compilers like gcc or clang.
    • emsdk: The Emscripten SDK management tool. It is used for all SDK maintenance, including downloading, installing, activating, and removing SDKs and tools. It also allows you to build and use the latest compiler from source.
    • emcmdprompt: A specialized command prompt for Windows users that is pre-configured with the correct system paths and settings to point to the active Emscripten SDK and tools.
  3. Overview of connecting C++ and JavaScript in Emscripten

    main

    Emscripten offers multiple mechanisms to bridge the gap between compiled C/C++ code and standard JavaScript. These methods allow for:

    • Calling compiled C/C++ functions from JavaScript.
    • Calling JavaScript functions from compiled C/C++ code.
    • Accessing JavaScript environment variables from within compiled code.

    Depending on your requirements, you can use high-level binding tools like Embind or WebIDL-Binder, or use more direct interaction methods. For specific details on how compiled code interacts with the browser environment or the file system, refer to the Emscripten runtime environment and file system documentation.

  4. Overview of mimalloc

    main

    mimalloc (pronounced "me-malloc") is a general-purpose allocator designed for high performance and low latency. It is a drop-in replacement for malloc and can be used without code changes in many environments.

    Key design features include:

    • Free list sharding & multi-sharding: Reduces fragmentation and contention by using many small free lists per page, including dedicated lists for thread-local and concurrent free operations.
    • Eager page purging: Marks empty pages as unused to the OS to reduce memory pressure.
    • First-class heaps: Allows efficient creation and destruction of multiple heaps. In v3, these heaps are true first-class heaps that can be allocated from any thread.
    • Security: Can be built in a secure mode with guard pages, randomized allocation, and encrypted free lists.
    • Boundedness: Provides bounded worst-case allocation times, bounded space overhead (~0.2% metadata), and no internal points of contention using only atomic operations.
  5. Overview of Emscripten

    main

    Emscripten is a complete compiler toolchain that uses LLVM to compile C, C++, or any LLVM-based language to WebAssembly. It is optimized for speed, size, and the Web platform.

    Key Capabilities:

    • Porting: Compile existing C/C++ projects to run in web browsers, Node.js, or standalone WebAssembly runtimes.
    • API Support: Converts OpenGL to WebGL and provides support for SDL, pthreads, POSIX, Web APIs, and JavaScript.
    • Performance: Leverages LLVM, Binaryen, and WebAssembly to produce compact output that runs at near-native speeds.
  6. Overview of Emscripten File Systems

    main

    Emscripten provides support for file operations within compiled code through a virtual file system. Users can interact with this system using either the JavaScript Filesystem API or the C/C++ asynchronous file system API. Key capabilities include:

    • Packaging files: Using the emcc compiler to bundle files directly into the compiled output.
    • Lazy loading: Setting up a synchronous virtual XHR-backed file system to load binary data from HTTP servers on demand.
  7. Overview of Emscripten's public API surface

    main

    Emscripten provides a wide range of APIs to bridge the gap between C/C++ code and the web environment. The public API is organized into several functional categories:

    • Browser Integration: Use emscripten.h for high-level browser environment integration.
    • HTML5 Interop: Use html5.h for low-level glue bindings to interface with HTML5 APIs from native code.
    • Console & I/O: Use console.h for writing to the console, stdout, and stderr.
    • JavaScript Interop:
      • Use preamble.js APIs to work with compiled code from the JavaScript side.
      • Use val.h (Embind) to transliterate JavaScript code to C++.
      • Use bind.h (Embind) to bind C++ functions and classes so they can be called naturally from JavaScript.
    • Filesystem & Networking:
      • Use the Filesystem API (library_fs.js) for managing file systems and synchronous file operations.
      • Use the Fetch API for managing network XHR and IndexedDB access.
    • Concurrency & Multithreading:
      • Use the Wasm Workers API to write multithreaded programs using a web-like API.
      • Use fiber.h for working with Fibers (co-operative threads).
      • Use proxying.h to synchronously or asynchronously proxy work to a target pthread.
    • Specialized APIs:
      • Audio: wasm_audio_worklets for implementing audio processing nodes in a dedicated real-time thread.
      • Memory/Stack: trace.h for memory usage analysis and stack.h for inspecting the WebAssembly data stack.
    • Execution Control: The Module global JavaScript object is used to control code execution and access exported methods.
  8. Use the Itanium Name Demangler Library

    main

    The Itanium Name Demangler library is used to convert mangled C++ symbols (e.g., _Z1fv) into human-readable demangled names (e.g., f()).

    Depending on your requirements, you can interact with the library in three ways:

    1. Standard Demangling: Convert a mangled string into its demangled representation.
    2. Symbol Analysis: Use the ManglingParser (via the CRTP base) to perform simple analysis on a mangled name.
    3. AST Querying (LLVM only): Use the ItaniumPartialDemangler to query the demangled Abstract Syntax Tree (AST).

    Note: If you are working within the libcxxabi context, all code must be declared in an anonymous namespace using DEMANGLE_NAMESPACE_BEGIN, and you must not introduce dependencies on the libcxx dylib.

  9. Understand the Emscripten open source licenses

    main

    Emscripten is distributed under two permissive open source licenses:

    1. MIT license: Widely known and understood.
    2. University of Illinois/NCSA Open Source License: Provided to facilitate potential upstream integration into LLVM.

    There is little practical difference between the two for most users. The full license text is available in the root of the Emscripten SDK or on the project's GitHub repository.

  10. What is the Module object?

    main

    The Module object is a global JavaScript object used by Emscripten-generated code to interact with the JavaScript environment. It serves two primary purposes:

    1. Control Execution: Developers can implement attributes on Module to define how the application behaves (e.g., how stdout is handled or how files are loaded).
    2. API Access: It provides a safe way to access exported Emscripten API functions (like ccall) and runtime methods. Functions exported via EXPORTED_FUNCTIONS or EXPORTED_RUNTIME_METHODS are attached to the Module object and are protected from minification and optimizer removal.

    Important: You must define or extend Module before the Emscripten runtime starts. Changing these values after startup generally will not work and may trigger errors if ASSERTIONS are enabled.

  11. Overview of Emscripten debugging information

    main

    Emscripten provides debugging information in several formats to support different workflows:

    • DWARF: Detailed debug info stored in Wasm object/binary files or as sidecar files. Best for interactive, source-level debugging.
    • Wasm Name Section: Includes function names for better stack traces in browser developer tools.
    • Source Maps: Maps compiled JS/Wasm locations back to original source code. Widely supported by browser DevTools.
    • Symbol Maps: Used for symbolication.

    Crucial Note on Link-Time Flags: Unlike standard C toolchains, you must pass debugging flags at link time to ensure information is preserved or generated in the final output. If you only pass -g at compile time, emcc may strip the debug info during the linking stage.