Skip to content

LLVM Types in JavaScript

kripken edited this page Oct 20, 2012 · 1 revision

This is an overview of how LLVM types are implemented in JS by Emscripten. This stuff has changed quite a bit over time (if you read this and it has not been updated in a while, better to check the source).

Overflow corrections:

i32: | 0
less: & (2^bits-1)

Sign corrections (done right before a math operation if necessary, and to extend):

i32 signed: | 0
i32 unsigned: >>> 0
less signed: << (32-bits) >> (32-bits)
less unsigned: & (2^bits-1)

Truncate:

& (2&bits-1)

Rounding the output of a division:

i32 or less, signed: & -1 (could be |0 as well)
unsigned: Math.floor(.)
>i32 or float-to-int: x >= 0 ? Math.floor(x) : Math.ceil(x)

Bitwise cast of float to int and vice versa:

Write to heap as int, read as float (and vice versa)

Note that there are some ugly optimizations for i64s as emulated doubles, e.g. a sign correction could look like

(x >= 0 ? x : (2^64)+x)

Also, if we do precise i64 (not with emulated doubles), we use [low,high] (i.e. a js array) as the representation in some cases.

LLVM has "non-C struct" types, that we implement as JS objects with fields. These are typically used only in odd things like exception handling, checking for explicit overflows, etc., so not usually performance sensitive.

Clone this wiki locally