The ovm_extern_t type

The ovm_extern_t type is a catch-all OrchIDS type, for all foreign data structures.

It is defined this way in src/lang.h:

struct ovm_extern_s
{
  gc_header_t gc;
  void     *ptr;
  char	   *desc;
  void *(*copy)(gc_t *gc_ctx, void *ptr);
  void (*free)(void *ptr);
};

The ptr field points to the piece of foreign data. The only thing OrchIDS needs to know about it is how to copy it, and how to deallocate it.  You must provide a function copy, and a function free that do those tasks. The desc field points to an optional string descriptor. This should be a global static constant, typically. It won’t be deallocated or touched in any way by the garbage collector.

The type ovm_extern_t is a type of garbage-collectable data. To allocate a new object of type ovm_extern_t, the following function is provided:

ovm_var_t *ovm_extern_new(gc_t* gc_ctx, void *ptr, char *desc,
                          void *(*copy)(gc_t *gc_ctx, void *ptr),
                          void (*free) (gc_t *gc_ctx, void *ptr));

This creates a new ovm_extern_t object, pointing to ptr, with descriptor desc, copying function copy, and deallocating function free. Calling res the result, one always has TYPE(res)==T_EXTERN. One can access the ptr, desc, copy and free fields using EXTPTR(res), EXTDESC(res), EXTCOPY(res), and EXTFREE(res) respectively, all to write into or to read from.

The return type of ovm_extern_new() is the universal type ovm_var_t instead of ovm_extern_t, for practical reasons.

The result of ovm_extern_new() is created white, and much be gc_touch()ed before storing it into a garbage-collectable object.