Core-Language Primitives


Defines

#define afun   void
#define wfun   void
#define ifun   void

Typedefs

typedef struct modref_s modref_t
 Modifiable references.

Functions

void scope ()
 Creates a new scope and makes it active.
void * alloc (uintptr_t size,...)
 Allocate and initialize memory blocks.
modref_tmodref ()
 Creates a new, empty modifiable reference and returns a pointer to it.
void * read (modref_t *m)
 Reads and returns the current value of a modifiable reference.
void write (modref_t *m, void *val)
 Writes the given modifiable reference m with the given value val.

Detailed Description

See Language Primitives for a high-level explanation of how these primitives are used.

See Limitations for an overview of associated caveats.


Function Documentation

void* alloc ( uintptr_t  size,
  ... 
)

Allocate and initialize memory blocks.

The variadic arguments of alloc correspond to an initialization function and series of zero or more initialization values. After allocating a block of memory of the requested size (in bytes) this primitive invokes the given initialization function, supplying the address of the allocated block and any additional initialization values.

As an example, consider the following usage to allocate memory for a pair of integers:

   int* pair = alloc(2 * sizeof(int), pair_initfn, 1, 2);
   printf("(%d, %d)", pair[0], pair[1]);

Where pair_initfn is the following:

   void pair_initfn(int *pair, int fst, int snd) {
     pair[0] = fst;
     pair[1] = snd;
   }

In example uage above, the alloc primitive allocates a block large enough to hold two integers. Say p points at the new block. Next, the primtive effectively executes initfn(p,1,2) to initialize this block. Last, it returns p, whose value is then assigned to pair in the example code.

In core programs we use the alloc primitive instead of a conventional allocation function (e.g., malloc) since uses of the alloc primitive are included in the trace of a core computation. This is significant for several reasons:

  • Automatic Garbage Collection: When the core program is re-evaluated by change propagation some of the old trace may be thrown away and replaced with a new computation. When the thrown-away computation contains memory allocations performed by alloc, change propagation automatically reclaims them as garbage.

  • Reuse of Previous Allocations: When the core program is re-evaluated and performs new allocations, the alloc primitive attempts to reuse allocations from the trace when they're available. This is crucial for writing stable programs.

  • Correctness of Change Propagation: Change propagation relies on the assumption that only the contents of modrefs change value as a core program runs, and that the core program treats all other memory as immutable. In practical terms, this means that the core program cannot change the value of (non-modref) memory locations after allocating them. In particular, if a block of memory is reused during the re-evaluation of a core program, the core program should not initialize it a second time. By combining the memory's initialization with allocation, the core program avoids this problem: when a block of memory is freshly allocated, the system runs the associated intialization function; and when an allocation is reused, the associated initialization function is not rerun.

void* read ( modref_t m  ) 

Reads and returns the current value of a modifiable reference.

Warning:
Reading an unwritten modref is an error.

Unlike the other core primitives, read may only be used inside core functions (i.e., those with return type afun)

void scope (  ) 

Creates a new scope and makes it active.

It will remain active until the currently-executing function is complete, or until its replaced with another scope. Support for this primitive (currently) has some important caveats. See Limitations for details.


Generated on Thu Mar 5 14:27:55 2009 for CEAL by  doxygen 1.5.6