Giter Site home page Giter Site logo

w2c2's Introduction

w2c2

Translates WebAssembly modules to portable C. Inspired by wabt's wasm2c.

Working towards WebAssembly as the Elusive Universal Binary:

                                          ↗ different
  source code     →  WebAssembly  →  C89  → OSes,
(C++, Rust, ...)                          ↘ CPUs

Features

  • Implements the WebAssembly Core Specification 1.0
  • Implements several extensions:
  • Passes 99.9% of the WebAssembly core semantics test suite
  • Written in C89 and generates C89
  • Support for many operating systems (e.g. Mac OS X, Mac OS 9, Haiku, Rhapsody, OPENSTEP, NeXTSTEP, DOS, Windows XP, etc.)
  • Support for many architectures (e.g. x86, ARM, PowerPC, SPARC, PA-RISC, etc.)
  • Support for big-endian systems (e.g. PowerPC, SPARC, PA-RISC, etc.)
  • Streaming/single-pass compilation, low memory usage
  • Separate compilation into multiple files
  • Parallel compilation
  • Assist with incremental compilation: Separate static and dynamic functions by comparing with another module
  • Support for multiple modules and instances
  • Support for generating debug information:
  • WASI implementation
    • Able to run clang and Python
    • Support for many operating systems and architectures, support for big-endian systems
    • Implements the threads proposal

Performance

  • Coremark 1.0: ~7% slower than native

Compilation

If your system is supported by at least CMake 2.8.12, prefer using CMake to detect features. On systems without CMake you can also use Make.

w2c2

cd w2c2
cmake -B build
cmake --build build

wasi

cd wasi
cmake -B build
cmake --build build

Usage

For example, to compile module.wasm to module.c (and module.h):

./w2c2 module.wasm module.c

Separate Compilation

w2c2 is able to compile a module into separate C files. This is recommended when compiling large modules and on hosts with limited resources.

For example, to compile module.wasm (and module.h), into multiple files with 100 functions each:

./w2c2 -f 100 module.wasm module.c

Parallel Compilation

When w2c2 was built with threading support, it is able to compile a module in parallel. By default, w2c2 spawns as many worker threads as CPU cores are available.

To manually specify the number of worker threads, pass the number using the -t flag.

For example, to compile using 2 threads:

./w2c2 -t 2 module.wasm module.c

Examples

Coremark:

cd examples/coremark
make
./coremark

Testing

Requires Python 3 and wabt (for wast2json).

cd tests
make gen
make run-tests

WASI Status

  • args_get
  • args_sizes_get
  • clock_res_get
  • clock_time_get
  • environ_get
  • environ_sizes_get
  • fd_advise
  • fd_allocate
  • fd_close
  • fd_datasync
  • fd_fdstat_get
  • fd_fdstat_set_flags
  • fd_fdstat_set_rights
  • fd_filestat_get
  • fd_filestat_set_size
  • fd_filestat_set_times
  • fd_pread
  • fd_prestat_get
  • fd_prestat_dir_name
  • fd_pwrite
  • fd_read
  • fd_readdir
  • fd_renumber
  • fd_seek
  • fd_sync
  • fd_tell
  • fd_write
  • path_create_directory
  • path_filestat_get
  • path_filestat_set_times
  • path_link
  • path_open
  • path_readlink
  • path_remove_directory
  • path_rename
  • path_symlink
  • path_unlink_file
  • poll_oneoff
  • proc_exit
  • random_get
  • sched_yield
  • sock_recv
  • sock_send
  • sock_shutdown
  • thread-spawn (from the threads proposal)

Development

To build a debug release, pass BUILD=debug to make.

To enable sanitizers, list them in the SANITIZERS variable passed to make, e.g. make BUILD=debug SANITIZERS="base clang address thread".

Installing libdwarf (required for source line mapping)

  • On Linux, try installing a package named like libdwarf-dev

  • On macOS, you can use Homebrew and install libdwarf (not dwarf!)

  • w2c2 currently defaults to using the libdwarf API of >=v0.4.2. v0.6.0 has been tested to work successfully too.

  • If using a version <0.4.2, try passing -DDWARF_OLD=1 to CMake. Version 20200114 is known to work.

  • Since version 0.1.1, libdwarf ships with a pkg-config file, which CMake should be able to detect automatically.

    If libdwarf cannot be automatically found by CMake, you get the following message:

    -- Checking for module 'libdwarf'
    --   No package 'libdwarf' found
    

    In that case you can still provide the necessary information manually by passing a variation of the following options:

    -DDWARF_FOUND=1 -DDWARF_LIBRARIES=-ldwarf -DDWARF_LIBRARY_DIRS=/usr/lib -DDWARF_INCLUDE_DIRS=/usr/include/libdwarf
    

w2c2's People

Contributors

alula avatar asiekierka avatar felix-el avatar heath123 avatar samuraicrow avatar tekknolagi avatar turbolent avatar vshymanskyy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

w2c2's Issues

SIGFPE (Floating point exception)

Running w2c2 on this file:

(module
  (table $T0 1 1 funcref)
  (memory $memory 0)
  (global $g0 i32 (i32.const 8))
  (global $g1 (mut i32) (i32.const 16392))
  (global $g2 i32 (i32.const 16392))
  (export "memory" (memory 0))
  (elem $e0 (i32.const 1)))

gives me:
fish: Job 1, 'w2c2 test.wasm test.c' terminated by signal SIGFPE (Floating point exception)
It's happening here:

w2c2/w2c2/c.c

Line 4808 in 48efea5

U32 fileCount = 1 + (functionCount - 1) / functionsPerFile;

I think it's a division by zero

Are module instances thread-safe?

I asked this question in the wasm2c project, but I’m also curious what w2c2’s semantics are when it comes to this type of usage.

Basically, is it undefined behavior to instantiate a module in thread A and then call into the instance in threads B, C, D, etc.? We can assume only one thread ever calls into the instance at any time.

I’m currently using a runtime in which this behavior is supported and well-defined, but I want to switch to either wasm2c or w2c2.

For the sake of understanding what this project supports (or at least intends to support), we can ignore the fact that pre-C11 multithreading is undefined and assume the compiler enforces a well-defined C11-like memory model anyway.

Thank you!

Doesn't fully work on big-endian architectures

I have a Casio CG50 calculator, which can be programmed in C(++).
However, when I compile this AssemblScript code, convert it and compile it for the calculator I get all 0s back.

export function fac2(n: i32): i32 {
  if (n == 0) {
    return 1;
  }
  return n * fac2(n - 1);
}

export function fac(n: i32): string {
  // Create an i32 to i32 map
  let map = new Map<i32, i32>();
  map.set(n, fac2(n));
  return `The factorial of ${n} is ${map.get(n)}\nMap: ${map}`;
}

I did make some modifications to the header file but I compiled the same thing on native Linux and it worked fine. An idea what I can try? The calculator uses a big-endian SuperH 4 CPU and I'm compiling with GCC. Any idea what I can try to debug it?

Separated compilation sections in -fPIC?

In Haiku, the parallel build mode fails to build complaining of unsupported section types. Haiku uses a version of ELF binary that only works in Position Independent Code. I think each binary executable is just a shared object that is called by the operating system's true executable. Is the problem in the linker options? Normally the internal GCC compilation just works by setting -fPIC in the compiler options and linker options automatically. Does the W2C2 version of WASI call the ELF loader directly?

I've set an issue for myself on my fork at SamuraiCrow#2 if interested.

Implications of a shared runtime library

On Haiku, open source runtimes are preferred to be shared to save on memory (reentrant position-independent code) and to improve debugging maintainability at the package manager also. I've already added a boolean option to the CMakefiles.txt on my fork for a shared runtime easily. Apart from needing to change the name to something like libw2c2runtime.dll/so/dylib/whatever to avoid a name collision with WABT's implementation, are there any negative impacts to consider when using shared libraries on other platforms?

Converting floats to ints doesn't work

If you compile this AssemblyScript code with optimizations off:

export function returnFive(n: i32): i32 {
  return i32(5.0)
}

you get this:

;; INFO asc module.ts --textFile module.wat --outFile module.wasm --bindings raw --runtime stub
(module
 (type $i32_=>_i32 (func (param i32) (result i32)))
 (memory $0 0)
 (table $0 1 1 funcref)
 (elem $0 (i32.const 1))
 (export "returnFive" (func $module/returnFive))
 (export "memory" (memory $0))
 (func $module/returnFive (param $0 i32) (result i32)
  f64.const 5
  i32.trunc_sat_f64_s
  return
 )
)

and the following C code:

U32 as_f0(moduleInstance *i) {
  U32 si0;
  F64 sd0;
  sd0 = 5;
  goto L0;
L0:;
  return si0;
}

This looks... obviously wrong, it's returning an uninitialised value

Attempting to run w2c2 on an optimized WASI C# binary causes missing opcode error

WasiTest.wasm.zip
OptimizedWasiTest.wasm.tar.gz
(optimized with wasm-opt build/WasiTest.wasm --enable-bulk-memory -o OptimizedWasiTest.wasm -O)

┌─[beyley@arch] - [~/w2c2/w2c2] - [2023-01-22 11:25:14]
└─[0] <git:(main 1244998✈) > build/w2c2 OptimizedWasiTest.wasm OptimizedWasiTest.c                         
w2c2: skipping unsupported unknown section
w2c2: unsupported export: __heap_base (global)
w2c2: unsupported export: __data_end (global)
w2c2: unsupported opcode unknown (0xC1)
w2c2: failed to compile

the remaining WASI function calls

I'm willing to help implement the remaining WASI function calls if you need me to. I see that one of the incomplete ones is sched/yield which yields the current time slice in a multitasking OS. It seems WASI preview 2 specification is coming up soon also. Would you like to coordinate or would just submitting pull requests suffice?

call_indirect not sandboxed properly

I noticed that the translation of call_indirect has no dynamic checking needed to enforce sandboxing. For example, this program causes a segmentation fault:

(module
    (memory (;0;) 2)
    (export "memory" (memory 0))
    (type $fntype (func (result i32)))
    (table 32 funcref)
    (func (export "_start") (type $fntype)
        (call_indirect (type $fntype) (i32.const 33))
    )
)

The indirect call gets translated to this:

#define TF(table, index, t) ((t)((table).data[index]))
U32 f0(testInstance*i) {
U32 si0;
si0=33U;
si0=TF(i->t0,si0,U32 (*)(testInstance*))(i);
L0:;
return si0;
}

which directly accesses the function in the table at the requested index and calls it without any checking.

I think there should be several checks:

  • The index must be in the bounds of the table.
  • The function at the requested index must not be null.
  • The type of the function being called must match the requested call_indirect signature.

I think the indirect call tests may be getting skipped due to an unsupported global export, but haven't looked into it.

If w2c2 is intended to be used for sandboxing then this is a vulnerability (if not, then the readme should clearly indicate that this tool is not safe to use for sandboxing).

It also looks like w2c2 does not support indirect calls across multiple modules, even in multi-module mode. Is that correct?

Thanks!

Support for WASM generated by GHC

GHC has recently introduced support for the WASM backend.
Unfortunately, w2c2 will throw the following error when trying to generate C code:

$./w2c2 hi.wasm hi.c
w2c2: failed to read module: invalid code section local declarations

I have absolutely no knowledge of wasm, but as far as I understand it's about supporting WASM or WASI standards?

Use alignment hints

(you might already know all this but I'll explain it just in case:

I did a fancy expandable box (click)

Currently loads and stores use memcpy, which on most platforms can be optimised into a normal memory access. However on platforms that don't support unaligned access like SuperH4 the compiler can't do this as it would cause the CPU to raise an exception if an unaligned access is performed. This means that there is a memcpy call for every memory access.

An option that would be faster in most situations would be to access the memory directly by type punning but use an exception handler to emulate unaligned access. This means you only pay a performance penalty when unaligned access actually happens, but that penalty will be much worse.

WebAssembly has a solution for this; alignment hints! This means you can tell the runtime when a memory is likely to be unaligned so it can emulate the access without causing a CPU exception, for example through a memcpy like w2c2 does now.

So, I'd like a way to have to have alignment hints passed through to the load and store functions so I can use them in a custom version of the header. I imagine this use case is too niche for it to be worth having a default implementation of this in w2c2_base.h but having it exposed would let me implement this myself.

I might do a PR for this like I did for #59 if you want it (should it be behind a flag to not bloat code size when it's not used?)

DWARF doesn't work

I tried with a minimal file:

#include <stdio.h>

int a() {
	return 42;
}

int b() {
	return a();
}

int c() {
	return b();
}

int main() {
	printf("%d\n", c());
}

built with WASI SDK with debug info and regenerated via w2c2 with debug info:

$ /opt/wasi-sdk/bin/clang mini.cpp -o mini.wasm -g
$ ~/w2c2/w2c2/build/w2c2 -g mini.wasm mini.c

I checked that mini.wasm has DWARF info as expected via llvm-dwarfdump, but the resulting mini.c doesn't have any #line directives that w2c2 -h says would be emitted.

Regular names are still emitted via __asm__, but the 2nd problem is that one of them looks corrupted (?):

...
U32 wasi_snapshot_preview1__fd_write(struct miniInstance*,U32,U32,U32,U32);

void wasi_snapshot_preview1__proc_exit(struct miniInstance*,U32);

void f5(miniInstance*) __asm__("mini_�{��mU");

void f6(miniInstance*) __asm__("mini___imported_wasi_snapshot_preview1_fd_fdstat_get");

U32 f7(miniInstance*) __asm__("mini___imported_wasi_snapshot_preview1_fd_seek");

U32 f8(miniInstance*) __asm__("mini___imported_wasi_snapshot_preview1_fd_write");
...

Comparison with `wasm2c` + some ideas

Just performed a quick test to understand how it compares to wasm2c.
For this test I took a ~25 MB wasm (WASI) file, clang.wasm

  • w2c2 finishes in 5.1s, RAM usage: 193 Mb. Output: 1.3 GiB file (34.8 Mb zipped)
  • wasm2c finishes in 1m23s, RAM usage: 1432 Mb. Output: 301 MiB file (22 Mb zipped)

Clearly, speed and RAM usage are really good 🎉 🚀
Wondering if file size can be reduced 🧑‍🔬

This also brings another question. C compilers are not very efficient when working with huge C files, so monsters like clang.wasm will take ages to compile. This is mentioned in my wasm2native tool: https://github.com/vshymanskyy/wasm2native#todo
One of the possible solutions is to split output into smaller chunks (which also enables parallel build).

skipping unsupported unknown section, unsupported export on C# WASI

WasiTest.wasm.zip
OptimizedWasiTest.wasm.tar.gz
(optimized with wasm-opt build/WasiTest.wasm --enable-bulk-memory -o OptimizedWasiTest.wasm -O)

┌─[beyley@arch] - [~/w2c2/w2c2/build] - [2023-01-23 07:15:05]
└─[0] <git:(main 383c63b✈) > ./w2c2 OptimizedWasiTest.wasm OptimizedWasiTest.c    
w2c2: skipping unsupported unknown section
w2c2: unsupported export: __heap_base (global)
w2c2: unsupported export: __data_end (global)
w2c2: unsupported export: __heap_base (global)
w2c2: unsupported export: __data_end (global)

after that, compilation fails with

┌─[beyley@arch] - [~/w2c2/w2c2] - [2023-01-23 07:17:16]
└─[1] <git:(main 383c63b✈) > clang OptimizedWasiTest.c -O2 -lm -o wasm-opt
/usr/bin/ld: /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.2.1/../../../../lib64/Scrt1.o: in function `_start':
(.text+0x1b): undefined reference to `main'
/usr/bin/ld: /tmp/OptimizedWasiTest-d895da.o: in function `OptimizedWasiTest_f34':
OptimizedWasiTest.c:(.text+0x296): undefined reference to `trap'
/usr/bin/ld: /tmp/OptimizedWasiTest-d895da.o: in function `OptimizedWasiTest_f3596':
OptimizedWasiTest.c:(.text+0x2492): undefined reference to `trap'
/usr/bin/ld: /tmp/OptimizedWasiTest-d895da.o: in function `OptimizedWasiTest_f3610':
OptimizedWasiTest.c:(.text+0x313a): undefined reference to `trap'
/usr/bin/ld: /tmp/OptimizedWasiTest-d895da.o: in function `OptimizedWasiTest_f757':
OptimizedWasiTest.c:(.text+0x3334a): undefined reference to `trap'
/usr/bin/ld: /tmp/OptimizedWasiTest-d895da.o: in function `OptimizedWasiTest_f122':
OptimizedWasiTest.c:(.text+0x55b78): undefined reference to `trap'
/usr/bin/ld: /tmp/OptimizedWasiTest-d895da.o:OptimizedWasiTest.c:(.text+0x55beb): more undefined references to `trap' follow

MODE=gnu-ld produces broken .c files

When trying to build the included python example:

$ ../../w2c2/w2c2 -d gnu-ld -f 100 python.wasm python.c
w2c2: skipping custom section 'producers' (size 85)
w2c2: skipping custom section 'target_features' (size 28)
make -fSubmake CC="cc" CFLAGS="-I../../w2c2 -O0 -g" LDFLAGS="-lm -L../../wasi -lw2c2wasi" OBJS="datasegments.o"
cc -I.. -I../../w2c2 -O0 -g -c python.c -o python.o
ld -r -b binary -o datasegments.o datasegments
python.c:8:17: error: invalid suffix "const" on integer constant
    8 | const U8* d0=ds+0const U8* d1=ds+5const U8* d2=ds+18const U8* d3=ds+29const U8* d4=ds+48const U8* d5=ds+83const U8* d6=ds+88const U8* d7=ds+169const U8* d8=ds+176const U8* d9=ds+177const U8* d10=ds+190const U8* d11=ds+191const U8* d12=ds+209const U8* d13=ds+218const U8* d14=ds+228const U8* d15=ds+239const U8* d16=ds+258const U8* d17=ds+293const U8* d18=ds+297const U8* d19=ds+417const U8* d20=ds+419const U8* d21=ds+420const U8* d22=ds+438const U8* d23=ds+447const U8* d24=ds+453const U8* d25=ds+464const U8* d26=ds+483const U8* d27=ds+518const U8* d28=ds+523const U8* d29=ds+560const U8* d30=ds+637const U8* d31=ds+639const U8* d32=ds+640const U8* d33=ds+658const U8* d34=ds+667const U8* d35=ds+677const U8* d36=ds+680constU8* d37=ds+689const U8* d38=ds+692const U8* d39=ds+708const U8* d40=ds+713const U8* 

Confirmed on Ubuntu and macOS.

undefined reference to trap and wasiMemory

Hello!👋 I'm a new user and I'm experiencing some issues using w2c2. I hope to learn how I can solve it (whether I need to provide extra implementation or I'm not using it correctly). Thanks!

Describe the bug

I have written a C++ program doing simple matrix multiplication. I am attempting to compile it first to mat.wasm using clang++ in wasi-sdk-19.0 (clang version 15.0.7) and then compile the mat.wasm to mat.c and mat.h using the latest compiled w2c2. Finally, I want to compile the mat.c to a native x86-64 binary.

In the last step, I'm using clang 15.07 to compile the mat.c, with the wasi implementation provided in w2c2 repo.

clang -O2 mat.c -I $W2C2/w2c2 -lw2c2wasi -L $W2C2/wasi/build -o mat

The error I got:

/usr/bin/ld: /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/13.1.1/../../../../lib64/Scrt1.o: in function `_start':
(.text+0x1b): undefined reference to `main'
/usr/bin/ld: /tmp/mat-71e822.o: in function `f15':
mat.c:(.text+0x294): undefined reference to `trap'
/usr/bin/ld: /tmp/mat-71e822.o: in function `f16':
mat.c:(.text+0x2a4): undefined reference to `trap'
/usr/bin/ld: /tmp/mat-71e822.o: in function `f17':
mat.c:(.text+0x398): undefined reference to `trap'
/usr/bin/ld: /tmp/mat-71e822.o: in function `f1620':
mat.c:(.text+0x589): undefined reference to `trap'
/usr/bin/ld: /tmp/mat-71e822.o: in function `f1621':
mat.c:(.text+0x3c24): undefined reference to `trap'
/usr/bin/ld: /tmp/mat-71e822.o:mat.c:(.text+0x18107): more undefined references to `trap' follow

/usr/bin/ld: /home/jinli/projects/w2c2/wasi/build/libw2c2wasi.a(wasi.c.o): in function `wasiFDReaddir':
wasi.c:(.text+0x35): undefined reference to `wasiMemory'
/usr/bin/ld: /home/jinli/projects/w2c2/wasi/build/libw2c2wasi.a(wasi.c.o): in function `wasiFdFdstatGet':
wasi.c:(.text+0x439): undefined reference to `wasiMemory'
/usr/bin/ld: /home/jinli/projects/w2c2/wasi/build/libw2c2wasi.a(wasi.c.o): in function `wasiPathReadlink':
wasi.c:(.text+0x922): undefined reference to `wasiMemory'
/usr/bin/ld: /home/jinli/projects/w2c2/wasi/build/libw2c2wasi.a(wasi.c.o): in function `wasiPathRename':
wasi.c:(.text+0xa53): undefined reference to `wasiMemory'
/usr/bin/ld: /home/jinli/projects/w2c2/wasi/build/libw2c2wasi.a(wasi.c.o): in function `wasiPathSymlink':
wasi.c:(.text+0xbd0): undefined reference to `wasiMemory'
/usr/bin/ld: /home/jinli/projects/w2c2/wasi/build/libw2c2wasi.a(wasi.c.o):wasi.c:(.text+0xd46): more undefined references to `wasiMemory' follow
clang-15: error: linker command failed with exit code 1 (use -v to see invocation)

Expected behavior

The mat.c can be compiled to a native binary using either gcc or clang.

Actual behavior

Undefined references to wasiMemory and trap

Additional context

I'm doing the experiment on an Arch Linux PC with uname 6.3.5-arch1-1.
The full compiling process:

  1. compile mat.cpp to mat.wasm
    wasi-sdk-19.0/bin/clang++ --sysroot=wasi-sdk-19.0/share/wasi-sysroot/ source/mat.cpp -fno-exceptions -O2 -o mat.wasm
  2. compile mat.wasm to mat.c
    $W2C2/build/w2c2 -p mat.wasm mat.c
  3. compile mat.c to native binary
    clang -O2 mat.c -I $W2C2/w2c2 -lw2c2wasi -L $W2C2/wasi/build -o mat

Segfault when compiling module which exports imported function

If you compile the AssemblyScript program:

export declare function test(): void

into WebAssembly (or use this one I already compiled):

asc test.ts --binaryFile test.wasm

Then into C:

w2c2 -o test.c test.wasm

you get a segfault:

fish: Job 1, '~/w2c2/w2c2 -o test.c test.wasm' terminated by signal SIGSEGV (Address boundary error)

Backtrace:

(gdb) backtrace
#0  wasmCWriteExports (file=0x5615678c32a0, module=0x5615678c3480, pretty=false, external=true) at c.c:3187
#1  0x0000561565bb8338 in wasmCWriteModuleDeclarations (file=0x5615678c32a0, module=0x5615678c3480, parallel=false, pretty=false) at c.c:3626
#2  0x0000561565bb8566 in wasmCWriteDeclarations (module=0x5615678c3480, singleFile=0x5615678c32a0, pretty=false) at c.c:3687
#3  0x0000561565bb8960 in wasmCWriteModule (module=0x5615678c3480, options=...) at c.c:4100
#4  0x0000561565bba9f2 in main (argc=4, argv=0x7ffcf43a12f8) at main.c:184
(gdb) 

Happens here:
https://github.com/turbolent/w2c2/blob/main/c.c#L3187

Directly linking against imports

The function pointer method for calling exports seems like it could interfere with inlining etc. if the compiler can't prove that they always have the same value. Could there be an option to directly link against them instead so that link time optimisation can speed the calls up, especially for small function like plotting individual pixels?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.