9.4.1 Creating and Manipulating SP_term_refs

Normally, C functions only have indirect access to Prolog terms via SP_term_refs. C functions may receive arguments as unconverted Prolog terms, in which case the actual arguments received will have the type SP_term_ref. Also, a C function may return an unconverted Prolog term, in which case it must create an SP_term_ref. Finally, any temporary Prolog terms created by C code must be handled as SP_term_refs.

SP_term_refs are motivated by the fact that SICStus Prolog's memory manager must have a means of reaching all live Prolog terms for memory management purposes, including such terms that are being manipulated by the user's C code. Previous releases of SICStus Prolog provided direct access to Prolog terms and the ability to tell the memory manager that a given memory address points to a Prolog term, but this approach was too low level and highly error-prone. The current design is modeled after and largely compatible with Quintus Prolog release 3.

SP_term_refs are created dynamically. At any given time, an SP_term_ref has a value (a Prolog term, initially []). This value can be examined, accessed, and updated by the support functions described in this section.

It is important to understand the rules governing the scope of SP_term_refs in conjunction with calls from Prolog to C and vice versa:

See SPTerm and Memory, for a discussion (in the context of the Java interface) of the lifetime of term references.

A new SP_term_ref is created by calling:

     SP_term_ref SP_new_term_ref(void)

The value of the SP_term_ref to is set to the value of the SP_term_ref from by calling SP_put_term(to,from). The previous value of to is lost:

     void SP_put_term(SP_term_ref to, SP_term_ref from)

Each Prolog atom is represented internally by a unique integer, represented in C as an SP_atom. This mapping between atoms and integers depends on the execution history. Certain functions require this representation as opposed to an SP_term_ref. It can be obtained by a special argument type declaration when calling C from Prolog, by calling SP_get_atom(), or by looking up an encoded string s in the Prolog symbol table by calling SP_atom_from_string(s).

     SP_atom SP_atom_from_string(char *s)

which returns the atom, or zero if the given string is malformed (is not a valid sequence of UTF-8 encoded characters).

The encoded string containing the characters of a Prolog atom a can be obtained by calling:

     char *SP_string_from_atom(SP_atom a)

The length of the encoded string representing a Prolog atom a can be obtained by calling:

     int SP_atom_length(SP_atom a)

Same as strlen(SP_string_from_atom(a), but runs in O(1) time.

Prolog atoms, and the space occupied by their print names, are subject to garbage collection when the number of atoms has reached a certain threshold, under the control of the agc_margin Prolog flag (see State Info), or when the atom garbage collector is called explicitly. The atom garbage collector will find all references to atoms from the Prolog specific memory areas, including SP_term_refs and arguments passed from Prolog to foreign language functions. However, atoms created by SP_atom_from_string() and merely stored in a local variable are endangered by garbage collection. The following functions make it possible to protect an atom while it is in use. The operations are implemented using reference counters to cater for multiple, independent use of the same atom in different foreign resources:

     int SP_register_atom(SP_atom a)

Registers the atom a with the Prolog memory manager by incrementing its reference counter. Returns a nonzero value if the operation succeeds.

     int SP_unregister_atom(SP_atom a)

Unregisters the atom a with the Prolog memory manager by decrementing its reference counter. Returns a nonzero value if the operation succeeds.