ddc-code-0.4.3.1: sea/primitive/Primitive.h
// Primitive operations that generated C code uses.
// These should all be static inlined so we can compile programs without
// linking against external code. Operations that need manifest object
// code should be defined somewhere else, and preferably imported
// by the foreign-function interface.
#pragma once
#include <stdio.h>
#include "Runtime.h"
// Error Primops --------------------------------------------------------------
// Fail ungracefully.
// Called when we find an internal runtime error.
static inline
void _FAIL(void)
{ abort();
}
// Store Primops --------------------------------------------------------------
extern addr_t _DDC__heapTop;
extern addr_t _DDC__heapMax;
// Create the initial store.
static inline
void _CREATE (nat_t bytes)
{
_DDC__heapTop = malloc (bytes);
_DDC__heapMax = _DDC__heapTop + bytes;
}
// Allocate some space in the store
static inline
addr_t _ALLOC (nat_t bytes)
{
addr_t obj = _DDC__heapTop;
_DDC__heapTop = _DDC__heapTop + bytes;
return obj;
}
// Check whether there is enough space on the heap to allocate
// an object of the given size in bytes.
static inline
bool_t _CHECK (nat_t bytes)
{
return (_DDC__heapTop + bytes < _DDC__heapMax);
}
// Get the size of a type.
#define _SIZE(type) \
sizeof(type)
// Get the log2 of the size of a type.
#define _SIZE2(type) \
(sizeof(unsigned int) * 8 - __builtin_clz (sizeof(type)))
// Read from a field of an Object.
// We use an explicit macro to make it easier to see what is happening in
// the generated code.
#define _READ(type,addr,offset) \
(*((type *)(addr + offset)))
// Write to a field of an Object.
// We use an explicit macro to make it easier to see what is happening in
// the generated code.
#define _WRITE(type,addr,offset,val) \
((*((type *)(addr + offset))) = val)
// Add two addresses.
#define _PLUSADDR(addr,offset) \
(addr + offset)
// Read from a pointer plus an offset in bytes.
#define _PEEK(type,ptr,offset) \
(*(type *)(((uint8_t *) ptr) + offset))
// Write to a pointer plus an offset in bytes.
#define _POKE(type,ptr,offset,val) \
(*((type *)( ((uint8_t*)ptr) + offset)) = val)
// Add an offset in bytes to a pointer.
#define _PLUSPTR(type,ptr,offset) \
((type *)( ((uint8_t *)ptr) + offset))
// Subtract an offset in bytes from a pointer.
#define _MINUSPTR(type,ptr,offset) \
((type *)( ((uint8_t *)ptr) - offset))
// Pointer to address conversions.
#define _MAKEPTR(type,addr) \
((type *)addr)
#define _TAKEPTR(type,ptr) \
((addr_t)ptr)
#define _CASTPTR(dstType,srcType,ptr) \
((dstType*)ptr)
// Other primitives -----------------------------------------------------------
// These are defined in C land and linked into the runtime library.
extern string_t* primShowInt (int i);
extern string_t* primShowNat (nat_t i);
extern void primPutTextLit (string_t* str);
extern void primPutString (string_t* str);