API Changes in 0.9.7


(For Japanese version: 0.9.7におけるAPIの変更)

We introduced several incompatible API changes in 0.9.7, to pave the way for cleaner API in 1.0 release.

All C extensions needs to be recompiled, and might be required to modify the code. The new Gauche header defines GAUCHE_API_0_97 preprocessor symbol. If you need your extensions to compile with both 0.9.7 and pre-0.9.7, you can switch it like this:

#if GAUCHE_API_0_97
   /* Using new API */
#else
   /* Using old API */
#endif

Types of sizes

We casually used int in some places that hold the size of strings and arrays. When Gauche was born, int and long are 32bits on most platforms that runs Gauche. Now that the world has moved on, 64bit architecture is norm and 32bit is not enough to hold sizes.

So we've rewritten APIs that takes or returns sizes with the following two types:

Since we limit Scheme string and vector length within fixnum range, C functions that deals with those Scheme objects take ScmSmallInt to represent sizes and lengths. Other places that generally requires size_t or ssize_t, we use ScmSize (we treat everything sigend).

If you call string or vector C API you'll likely to need to change them. Especially if you pass int*, you'll get compilation errors. (Passing int value as ScmSize isn't much a problem).

The following is a list of C functions that are changed.

/* pre-0.9.7 */                        /* 0.9.7 */

ScmObj Scm_ArrayToList(                ScmObj Scm_ArrayToList(
         ScmObj *elts,                          ScmObj *elts,
         int nelts)                             ScmSize nelts)

ScmObj Scm_AraryToListWithTail(        ScmObj Scm_AraryToListWithTail(
         ScmObj *elts,                          ScmObj *elts,
         int nelts,                             ScmSize netls,
         ScmObj tail)                           ScmObj tail)

ScmObj *Scm_ListToArray(               ScmObj *Scm_ListToArray(
         ScmObj list,                           ScmObj list,
         int *nelts,                            ScmSize *nelts,
         ScmObj *store,                         ScmObj *store,
         int alloc)                             int alloc)

int    Scm_Length(ScmObj obj)          ScmSize Scm_Length(ScmObj obj)

ScmObj Scm_CopyStringWithFlags(        ScmObj Scm_CopyStringWithFlags(
         ScmString *str,                        ScmString *str,
         int flags,                             u_long flags,
         int mask)                              u_long mask)

const char *Scm_GetStringContent(      const char *Scm_GetStringContent(
         ScmString *str,                        ScmString *str,
         u_int *psize,                          ScmSmallInt *psize,
         u_int *plen,                           ScmSmallInt *plen,
         u_int *pflags)                         u_long *pflags)

ScmObj Scm_CStringArrayToList(         ScmObj Scm_CStringArrayToList(
         const char **array,                    const char **array,
         int size,                              ScmSmallInt size,
         int flags)                             u_long flags)

int    Scm_DStringSize(                ScmSmallInt Scm_DStringSize(
         ScmDString *ds)                        ScmDString *ds)

ScmObj Scm_DStringGet(                 ScmObj Scm_DStringGet(
         ScmDString *ds,                        ScmDString *ds,
         int flags)                             u_long flags)

const char *Scm_DStringPeek(           const char *Scm_DStringPeek(
         ScmDString *ds,                        ScmDString *ds,
         int *size,                             ScmSmallInt *size,
         int *len)                              ScmSmallInt *len)

void   Scm_DStringPutz(                void   Scm_DStringPutz(
         ScmDString *ds,                        ScmDString *ds,
         const char *str,                       constr char *str,
         int siz)                               ScmSmallInt siz)

int    Scm_DStringTruncate(            int    Scm_DStringTruncate(
         ScmDString *ds,                        ScmDString *ds,
         int newsize)                           ScmSmallInt newsize)

const uint8_t *Scm_GetBytes(           const uint8_t *Scm_GetBytes(
         ScmObj str_or_vec,                     ScmObj str_or_vec,
         size_t *size)                          ScmSize *size)

long   Scm_ReadDigitsAsLong(           long   Scm_ReadDigitsAsLong(
         ScmPort *port,                         ScmPort *port,
         ScmChar ch,                            ScmChar ch,
         int radix,                             int radix,
         ScmChar *next,                         ScmChar *next,
         int *numread)                          ScmSize *numread)

long   Scm_ParseDigitsAsLong(          long   Scm_ParseDigitsAsLong(
         const char *buf,                       const char *buf,
         size_t len,                            ScmSize len,
         int radix,                             int radix,
         int *numread)                          ScmSize *numread)

void   Scm_Putz(const char *s,         void   Scm_Putz(const char *s,
         int len,                               ScmSize len,
         ScmPort *port)                         ScmPort *port)

void   Scm_PutzUnsafe(const char *s,   void   Scm_PutzUnsafe(const char *s,
         int len,                               ScmSize len,
         ScmPort *port)                         ScmPort *port)

int    Scm_Getz(char *buf,             ScmSize Scm_Getz(char *buf,
         int buflen,                            ScmSize buflen,
         ScmPort *port)                         ScmPort *port)

int    Scm_GetzUnsafe(char *buf,       ScmSize Scm_GetzUnsafe(char *buf,
         int buflen,                            ScmSize buflen,
         ScmPort *port)                         ScmPort *port)

Argument changes

We changed arguments of several procedures. The change has actually been in place for years if you define C preprocessor symbol GAUCHE_API_0_95 to be true. We just made it true by default.

The following is the list of changes. To port old code to new API, just pass 0 to flags argument, SCM_FALSE to src and describer, and SCM_OBJ(SCM_CURERR) to out argument, to get the same behavior.

/* pre-0.9.7 */                        /* 0.9.7 */

ScmObj Scm_MakeMacro(                  ScmObj Scm_MakeMacro(
         ScmSymbol *name,                       ScmObj name,
         ScmObj transformer)                    ScmObj transformer,
                                                ScmObj src,
                                                ScmObj describer)

ScmObj Scm_Raise(ScmObj exc)           ScmObj Scm_Raise(ScmObj exc,
                                                u_long flags)

ScmObj Scm_ReportError(ScmObj e)       ScmObj Scm_ReportError(ScmObj e,
                                                ScmObj out)

ScmObj Scm_VMThrowException(           ScmObj Scm_VMThrowException(
         ScmVM *vm,                             ScmVM *vm,
         ScmObj exc)                            ScmObj exc,
                                                u_long flags)

Deprecated Parameter API

We've had two layers of parameters; C API provides a basic thread-local storage, and Scheme layer is built on top of it to provide additional features such as filter procedure. To make it clear, we now call the lower-level parameter as ScmPrimitiveParameter, and provides new set of APIs.

We keep old API for a while, but urge extension modules to move to new API.

Old API:

void Scm_DefinePrimitiveParameter(ScmModule *mod,
                                  const char *name,
                                  ScmObj initval,
                                  ScmParameterLoc *location);

ScmObj Scm_ParameterRef(ScmVM *vm, const ScmParameterLoc *loc);

ScmObj Scm_ParameterSet(ScmVM *vm, const ScmParameterLoc *loc, ScmObj val);

ScmObj Scm_InitParameterLoc(ScmVM *vm, ScmParameterLoc *loc, ScmObj initval);

New API:

ScmPrimitiveParameter *ScmPMakePrimitiveParameter(ScmClass *klass,
                                                  ScmObj name,
                                                  ScmObj initval,
                                                  u_long flags);

ScmPrimitiveParameter *Scm_BindPrimitiveParameter(ScmModule *mod,
                                                  const char *name,
                                                  ScmObj initval,
                                                  u_long flags);

ScmObj Scm_PrimitiveParameterRef(ScmVM *vm,
                                 const ScmPrimitiveParameter *p);

ScmObj Scm_PrimitiveParameterSet(ScmVM *vm,
                                 const Scm_rimitiveParameter *p,
                                 ScmObj val);

Build changes

Boehm GC used to require a manual registration of data area of dynamically linked objects, and Gauche supports it by generating small files (*_head.c, *_tail.c). The gauche-config --fixup-extension command creates those files during build time.

Boehm GC doesn't need this handling for quite a while, so we finally drop gauche-config --fixup-extension feature (it accepts the argument but no longer generates files).

We removed references for generated files (*_head.c, *_tail.c) from the template Makefile.in long time ago. But if your extention predates that, your Makefile.in may still have the reference to those files. You need to remove them, or make fails complaining it can't find these files.


Last modified : 2018/12/22 09:00:15 UTC