Skip to content
 
 

Repository files navigation

=== lcc-wasm fork: a WebAssembly back end for lcc ===

This fork of drh/lcc adds a WebAssembly target, so lcc can compile C to a
runnable .wasm module. The goal is an in-browser C compiler small enough to
ship into a web page (unlike the multi-megabyte clang/emscripten toolchain).

It works today: real C -- arithmetic, loops, if/switch, recursion, pointers,
arrays, structs, function pointers -- compiles and runs in node AND the browser.
See examples/hello-world for a complete, runnable demo (199-byte module).

--- Quick start -------------------------------------------------------

  # 1. build the compiler (clang needs relaxed flags for K&R-era source;
  #    they live in custom.mk, so a plain make works)
  make BUILDDIR=build rcc

  # 2. compile C -> WebAssembly text -> binary
  build/rcc -target=wasm foo.c > foo.wat   # our back end emits .wat
  wat2wasm foo.wat -o foo.wasm             # WABT assembles to .wasm
                                           # (brew install wabt)

  # 3. run it -- see examples/hello-world
  cd examples/hello-world && ./build.sh
  node run-node.js                         # -> Hello, world from lcc-wasm!
  node serve.js                            # then open http://localhost:8080/

There is no libc yet: a program reaches the outside world by calling functions
IMPORTED from the host (node/browser JS), exactly as a winweb app calls its
runtime. hello.c imports putchar(); the JS host supplies it.

--- How the back end works --------------------------------------------

src/wasm.c (registered in bind.c) emits .wat text and leaves binary encoding to
wat2wasm. It follows the bytecode.c model -- wants_dag=0, no lburg/register
allocation -- because lcc emits its IR in post-order, which is already
WebAssembly's stack-machine evaluation order. Scalar, non-address-taken
locals/params become wasm locals; address-taken/aggregate locals live on a
shadow stack in linear memory (global $sp); globals/strings become (data)
segments; goto-style control flow becomes a br_table "giant loop" dispatch;
function pointers use an indirect (table) + call_indirect. Output is buffered
into import/memory/table/func/export/data so it assembles in module order.

For the full opcode-by-opcode mapping (LCC IR <-> WAT) with worked, verified
examples, see doc/wasm-codegen.md.

--- Status (milestones; see PLAN.md in the repo root) -----------------

  M1 DONE  arithmetic/bitwise/shift/casts, scalar locals, direct calls, return
  M2 DONE  control flow: for/while/if/switch/recursion (br_table dispatch)
  M3 DONE  linear memory + shadow stack; globals/strings; loads/stores;
           pointers, arrays, struct fields
  M4 DONE  function pointers (call_indirect), struct copy, struct-by-value,
           varargs (shadow-stack arg-buffer ABI)
  M6 DONE  self-host: lcc compiled to wasm (rcc.wasm) compiles + runs C in node
           AND the browser, byte-identical to native -- see examples/self-host
  M7 DONE  direct binary emit: -target=wasm-bin writes .wasm with no wat2wasm
           (drops the in-browser wabt dependency)
  M5 next  winweb integration: wire rcc.wasm into the in-page Win32 runtime

Upstream lcc README follows.

----------------------------------------------------------------------

This hierarchy is the distribution for lcc version 4.2.

lcc version 3.x is described in the book "A Retargetable C Compiler:
Design and Implementation" (Addison-Wesley, 1995, ISBN 0-8053-1670-1).
There are significant differences between 3.x and 4.x, most notably in
the intermediate code. For details, see
https://drh.github.io/lcc/documents/interface4.pdf.

VERSION 4.2 IS INCOMPATIBLE WITH EARLIER VERSIONS OF LCC. DO NOT
UNLOAD THIS DISTRIBUTION ON TOP OF A 3.X DISTRIBUTION.

LCC is a C89 ("ANSI C") compiler designed to be highly retargetable.

LOG describes the changes since the last release.

CPYRIGHT describes the conditions under you can use, copy, modify, and
distribute lcc or works derived from lcc.

doc/install.html is an HTML file that gives a complete description of
the distribution and installation instructions.

Chris Fraser / cwf@aya.yale.edu
David Hanson / drh@drhanson.net

About

The lcc retargetable ANSI C compiler

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages