Cheerp uses a few compiler intrinsic to improve the type safety of some operations on objects.

Clang intrinsics

void* __builtin_cheerp_pointer_base(const void* ptr);

See llvm.cheerp.pointer.base

size_t __builtin_cheerp_pointer_offset(const void* ptr);

See llvm.cheerp.pointer.offset

template<class R,class T,class O> R* __builtin_cheerp_create_closure(T* func, O* obj);

See llvm.cheerp.create.closure

template<class R,class T> R* __builtin_cheerp_make_complete_object(T*);

See llvm.cheerp.make.complete.object

template<class R,class T> R* __builtin_cheerp_make_regular(T*, int);

See llvm.cheerp.make.regular

LLVM intrinsics

LLVM supports the overloading of intrinsics based on operand types, but only for basic types. In Cheerp we have extended the support to any kind of object, the various methods are distinguished by including in the signature the a C++-like name mangling of the types.

LLVM Intrinsics for type conversions

Derived* llvm.cheerp.downcast(Base*, int32_t baseOffset)

Used to downcast a base class to a derived class. No dynamic check is done to verify that the cast is valid at runtime.

Base* llvm.cheerp.upcast.collapsed(Derived*)

Used to upcast a derived class to a base class in case the operation is a no-op. For example if the base class is empty or if the base class has been collapsed into the derived one.

Dst* llvm.cheerp.cast.user(Src*)

Used to signal to the backend which type casts are explicitly required by the user. This is useful to distinguish unsafe type casts which may be generated by LLVM transformations and clang code generation.

Intrinsics for type safe allocations

T* llvm.cheerp.allocate(int32_t sizeInBytes)

Used allocate memory which a definite type. The traditional pattern of allocating bytes and assigning a type later using a bitcast is fragile and may confuse the backend.

T* llvm.cheerp.reallocate(T*, int32_t newSizeInBytes)

Type safe realloc-like intrinsic, if possible it avoids making a copy of the original memory.

Intrinsics for pointer inspection


Returns the base component of the passed pointer.


Returns the offset component of the passed pointer.

Intrinsics for JavaScript integration

Func2* llvm.cheerp.create.closure(Func1* f, Obj* o)

Used to create a JavaScript closure using the following code

function cheerpCreateClosure(func, obj)
    return function(e) { func(obj,e); };

T* llvm.cheerp.make.complete.object(U*)

Change the type of the passed pointer while also forcing it to be a COMPLETE_OBJECT (i.e. a fast JavaScript reference)

T* llvm.cheerp.make.regular(U*, int32_t)

Create a slow REGULAR pointer. Also useful to convert typed arrays to C++ pointers.