/*
* Copyright (c) 1997-2024 Ross Cunniff
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/* Header file for OADL system library interface. An OADL system
* library is a dynamically loaded library in system-dependent format
* (e.g. a DLL on Win32, a .dynlib on MacOS, or a .so on Linux). When
* loaded (via a "using extern" statement) the library is first sought in a
* system-specific location (although the OADLSYS environment variable
* is widely recognized). It is then dynamically loaded, and
* the entry point "OADL_libname" is queried. This entry point must
* be of type OADL_SysInitProc, below. Once that entry point is
* determined, it is then called, passing in the OADL_FindProc routine.
* The SysInitProc can then use the FindProc routine to find various
* entry points required for operation. These entry points
* are documented below, but the most important one for a typical
* system library is OADL_AddExtern which will define and register an
* entry point of type OADL_SysCall - which all OADL extern procs
* are.
*
* On shutdown / reload / restart, the OADL_SysTermProc for your
* library is called. It is of type OADL_SysTermProc_fp, and is
* named "OADL_libname_term" in your syslib shared library.
*/
#ifndef _OADL_SYS_INCLUDED // [
#define _OADL_SYS_INCLUDED 1
/* version number for interface purposes */
#define OADL_SYS_VER 101
/* Generic function pointer prototype, since C does not have a
* function pointer equivalent to "void *"
*/
typedef int (*OADLproc)(void);
/* Used to find a named OADL procedure - see below for list. "name"
* is the name of the procedure (e.g. "OADL_AddExtern"). "version" is the
* interface version - pass in OADL_SYS_VER. The procedure
* is returned in rProc - you will want to put that in the appropriately
* typed pointer as defined below. Returns 1 if found, 0 otherwise.
* "ctx" should be passed the same context that SysInitProc was
* called with. Additionally, the "ctx" in all of these routines
* refers to the "ctx" that the system procedure was called with.
*/
typedef int (*OADL_FindProc_fp)(void *ctx, const char *name,
int version, OADLproc *rProc);
/* This is the typedef of your system library initialization proc.
* OADL queries the symbol from the dynamic library, as documented above.
* "ctx" is an opaque OADL ctx, which needs to be passed back to
* the various callback routines.
*/
typedef int (*OADL_SysInitProc_fp)(void *ctx, OADL_FindProc_fp findProc);
/* This is the typedef of your system library termination proc.
* OADL queries the symbol from the dynamic library, as documented above.
* "ctx" is an opaque OADL ctx, which needs to be passed back to
* the various callback routines.
*/
typedef void (*OADL_SysTermProc_fp)(void *ctx);
/* You should make sure that your system library procedures are
* compatible with this prototype. Each syslib proc takes a pointer
* to a result OadlVar "pRes", the number of arguments the OADL program
* passed in "nargs", and the array of arguments "args". Return
* value is generally 1. If return value is 0, some error
* occurred, and the syslib proc probably has called ThrowError.
* Returning 0 without calling ThrowError can cause OADL stack corruption.
*/
typedef int (*OADL_Extern_fp)(void *ctx, OadlVar *pRes,
int nargs, const OadlVar *args);
/* The routines that can be queried by FindProc. To find these routines,
* ask for the name without the "_fp" suffix. names are case-sensitive.
* Generally, if any of these routines return zero, it means an exception
* has been raised and the calling system library function should
* immediately return 0 (indicating aborted processing)
*/
/*****************************************************************************
* External library support functions
*****************************************************************************/
/* OADL_AddExtern(ctx, name, proc)
* The heart of the system library implementation. Tells OADL
* that the "proc" with the given "name" is implemented by this library.
* The "name" must include the namespace if it is intended to be part
* of that namespace - e.g. io::printf. Note that "name" may be a
* UTF-8 encoded wide string.
*/
typedef int (*OADL_AddExtern_fp)(void *ctx, const char *name,
OADL_Extern_fp proc);
/* OADL_FatalError(ctx, ErrNum)
* Raises fatal exception "ErrNum" from oadlerr.h
*/
typedef int (*OADL_FatalError_fp)(void *ctx, int ErrNum);
/* OADL_ThrowError(ctx, ErrNum)
* Throws exception "ErrNum" from oadlerr.h
*/
typedef int (*OADL_ThrowError_fp)(void *ctx, int ErrNum);
/* OADL_GetGcCounter(ctx)
* Returns the GC counter - if it changes a GC has happened
* and any local pointers to array/objects will be invalid
*/
typedef int (*OADL_GetGcCounter_fp)(void *ctx);
/* OADL_TypeOf(ctx, pRes, v)
* Returns "typeof(v)" in "*pRes"
*/
typedef int (*OADL_TypeOf_fp)(void *ctx, int *pRes, OadlVar v);
/* OADL_Writable(ctx, pRes, v)
* Returns "1" in *pRes if "v" is writable, and "0" if it is
* read-only.
*/
typedef int (*OADL_Writeable_fp)(void *ctx, int *pRes, OadlVar v);
/*****************************************************************************
* Object manipulation functions
*****************************************************************************/
/* Object flags */
#define OADL_OBJ_READONLY 0x00000001 // Object is read-only
#define OADL_OBJ_IS_CLASS 0x00000002 // Object is a class template
#define OADL_OBJ_ZOMBIE 0x00000004 // Object is a zombie
/* Public index access flags - top 2 bits of publicList[2*i+1] */
#define OADL_PUB_ACC_RW 0x00000000 // Public is read/write
#define OADL_PUB_ACC_PROTECTED 0x40000000 // Public is protected
#define OADL_PUB_ACC_READONLY 0x80000000 // Public is read-only
#define OADL_PUB_ACC_MASK 0xA0000000 // Mask for public access bits
/* Public index type flags - next 2 bits of publicList[2*i+1] */
#define OADL_PUB_TYPE_NONE 0x00000000 // Public is heterogenous
#define OADL_PUB_TYPE_TYPE 0x10000000 // Public has a simple (scalar) type
#define OADL_PUB_TYPE_ARRAY 0x20000000 // Public has an array type
#define OADL_PUB_TYPE_CLASS 0x30000000 // Public has a class type
#define OADL_PUB_TYPE_MASK 0x30000000 // Mask for pub type bits
/* Public offset bits */
#define OADL_PUB_OFFS_MASK 0x0FFFFFFF // Offset part of public index
/* Macros to access the publicList */
#define OADL_PUB_KEY(list,i) ((list)[2*(i)])
#define OADL_PUB_VAL(list,i) ((list)[2*(i)+1])
typedef struct {
uint32_t numProps; /* Total number of public/private properties */
uint32_t numPublics; /* Total number of public indexes */
uint32_t numTypes; /* Number of extra type words in pulicList */
uint32_t objFlags; /* From OADL_OBJ_*, above */
OadlVar *propList; /* List of object properties */
const uint32_t *publicList; /* Sorted list of [public idx,prop idx] pairs */
const uint32_t *typeList; /* Sorted list of [public idx,type info] pairs */
} OADL_ObjectInfo;
/* OADL_GetObjectInfo(ctx, pObj, vObj)
* Fills in an OADL_ObjectInfo structure with information about vObj
* Note that the pointers in an OADL_ObjectInfo may be invlidated
* by a GC cycle; see OADL_GetGcCounter()
*/
typedef int (*OADL_GetObjectInfo_fp)(void *ctx, OADL_ObjectInfo *pObj, OadlVar vObj);
/* OADL_FindPublicIndex(list, pubNum)
* Finds the index of pubNum in the sorted list, which contains
* [pubNum, pubVal] pairs, or -1 if it was not found. This is a
* binary search, so the list MUST be sorted.
*/
static inline int OADL_FindPublicIndex(const uint32_t *list, int numList, uint32_t pubNum)
{
int first = -1, last = numList;
while (first < (last - 1)) {
int curr = (first + last) / 2;
uint32_t currPub = OADL_PUB_KEY(list, curr);
if (currPub == pubNum) return curr;
else if (currPub < pubNum) first = curr;
else last = curr;
}
return -1;
}
/* OADL_PublicType(pRes, pObj, pub)
* Returns the OadlVar type of the public property of pObj. Note that, if
* no type was specified for pObj.pub, OADL_NIL is returned as the type.
*/
static inline int OADL_PublicType(OadlVar *pRes, const OADL_ObjectInfo *pObj, OadlVar pub)
{
uint32_t pubNum = pub.getVal(OADL_VT_PUBLIC);
int propIdx = OADL_FindPublicIndex(pObj->publicList, pObj->numPublics, pubNum);
if (propIdx < 0) return 0;
uint32_t pubType = OADL_PUB_VAL(pObj->publicList, propIdx) & OADL_PUB_TYPE_MASK;
int typeIdx = -1;
uint32_t pubVal = 0;
if (pubType != OADL_PUB_TYPE_NONE) {
typeIdx = OADL_FindPublicIndex(pObj->typeList, pObj->numTypes, pubNum);
if (typeIdx < 0) return 0;
pubVal = OADL_PUB_VAL(pObj->typeList, typeIdx);
}
switch (pubType) {
case OADL_PUB_TYPE_NONE : *pRes = OADL_NIL; break;
case OADL_PUB_TYPE_TYPE : *pRes = OadlVar(OADL_VT_TYPE, pubVal); break;
case OADL_PUB_TYPE_ARRAY : *pRes = OadlVar(OADL_VT_ARR_TYPE, pubVal); break;
case OADL_PUB_TYPE_CLASS : *pRes = OadlVar(OADL_VT_OBJECT, pubVal); break;
}
return 1;
}
/* OADL_GetProp(ctx, pRes, propNum)
* Gets the (possibly private) property index number "propNum" of the
* current "self" object and returns its value in "*pRes"
*/
typedef int (*OADL_GetProp_fp)(void *ctx, OadlVar *pRes, OadlVar propNum);
/* OADL_SetProp(ctx, pRes, propNum, val)
* Sets the (possibly private) property index number "propNum" of the
* current "self" object to the given "val"
*/
typedef int (*OADL_SetProp_fp)(void *ctx, OadlVar propNum, OadlVar val);
/* OADL_GetPublic(ctx, pRes, obj, pub)
* Returns "obj.pub" in *pRes
*/
typedef int (*OADL_GetPublic_fp)(void *ctx, OadlVar *pRes,
OadlVar obj, OadlVar pub);
/* Return values from OADL_SetPublic */
#define OADL_PUBLIC_OK 0 // Public was set OK
#define OADL_PUBLIC_ERROR 1 // An error was thrown
#define OADL_PUBLIC_OVERLOAD 2 // Needs a call to := operator - responsibility of caller
#define OADL_PUBLIC_DO_TC 3 // Needs intrinsic type conversion responsibilitiy of caller
/* OADL_SetPublic(ctx, obj, pub, v)
* Equivalent of "obj.pub = v"
* Returns one of PUBLIC_*, above
*/
typedef int (*OADL_SetPublic_fp)(void *ctx, OadlVar obj,
OadlVar pub, OadlVar v);
/* OADL_CreateObject(ctx, pRes, vClass)
* Creates a new instance of class vClass. Note that neither
* the create() nor the complete() method of the class will
* be invoked; this must be done manually by the syslib.
*/
typedef int (*OADL_CreateObject_fp)(void *ctx, OadlVar *pRes,
OadlVar vClass);
/* OADL_GetSelf(ctx, pRes)
* Returns the value of "self" in *pRes
*/
typedef int (*OADL_GetSelf_fp)(void *ctx, OadlVar *pSelf);
/* OADL_NewPublic(ctx, pVar, vName)
* Creates a new public with name vName. Returns result in *pVar.
*/
typedef int (*OADL_NewPublic_fp)(void *ctx, OadlVar *pVar, OadlVar vName);
/* OADL_NewClass(ctx, pVar, vName, vPublics)
* Creates a new class with name vName (which can be nil)
* and initial key-value pairs vPublics (which must be a List).
* Returns result in *pVar.
*/
typedef int (*OADL_NewClass_fp)(void *ctx, OadlVar *pVar,
OadlVar vName, OadlVar vPublics);
/*****************************************************************************
* Array manipulation functions
*****************************************************************************/
/* Structure for querying array information */
#define OADL_ARRAY_READONLY 0x01 /* Do not modify contents */
#define OADL_ARRAY_PERMANENT 0x02 /* Versus dyamic / GC memory */
#define OADL_ARRAY_USER_DATA 0x04 /* Points to user data, not OADL data */
#define OADL_ARRAY_ITERATOR 0x08 /* Iterator - only if not expanded */
/* If the array is an iterator and the caller requested the parameters,
* the arrData is a pointer to an array of the following items (in the
* type given by arrType):
*/
#define OADL_ARR_ITER_PARAM_FIRST 0
#define OADL_ARR_ITER_PARAM_LAST 1
#define OADL_ARR_ITER_PARAM_INCR 2
#define OADL_ARR_ITER_PARAM_COUNT 3 // Total size of iterator param array
typedef struct {
uint32_t arrSize; /* Total size of array, in elements */
uint8_t arrType; /* One of OADL_VT_* */
uint8_t elemSize; /* size of a single element, in bytes */
uint8_t arrRank; /* Rank - number of dimensions */
uint8_t pad0; /* Pad, ignored */
uint32_t arrFlags; /* flags from OADL_ARRAY_*, above */
uint32_t arrShape[OADL_MAX_RANK]; /* Shape of the array */
uint32_t arrStrides[OADL_MAX_RANK]; /* Dimension strides, in elements */
OadlVar arrVar; /* Only if iter. expanded to heap */
void *arrData; /* Pointer to array data or params */
void *arrAlloc; /* Only if iter. expanded to malloc */
} OADL_ArrayInfo;
/* Iterator flags for OADL_GetArrayInfo */
#define OADL_AIF_ITERATOR_EXPANSION 0x00000007 // Mask for AIF_ITERATOR*
#define OADL_AIF_ITERATOR_HEAP 0x00000001 // ...expand into heap
#define OADL_AIF_ITERATOR_MALLOC 0x00000002 // ...expand into malloc
#define OADL_AIF_ITERATOR_SCRATCH 0x00000003 // ...expand into scratch
#define OADL_AIF_ITERATOR_PARAMS 0x00000004 // ...raw params in arrData
/* OADL_GetArrayInfo(ctx, pArr, a)
* Returns info about a in OADL_ArrayInfo *pArr. flags are from
* OADL_AIF_*, above.
*
* If the OADL_AIF_ITERATOR_EXPANSION flags are set, one of the
* following actions are performed:
*
* OADL_AIF_ITERATOR_HEAP
* Allocates a new array from the heap and returns the
* newly created array expansion
*
* OADL_AIF_ITERATOR_MALLOC
* Allocates a new pseudo-array via OADL_malloc and
* returns the newly created array expansion. The caller
* must OADL_free the returned arrAlloc pointer
*
* OADL_AIF_ITERATOR_SCRATCH
* Allocates a new pseudo-array via OADL_AllocScratch and
* returns the newly created array expansion.
*/
typedef int (*OADL_GetArrayInfo_fp)(void *ctx, OADL_ArrayInfo *pArr, OadlVar a,
int flags);
/* OADL_CreateArray(ctx, pRes, pArr)
* Creates an array with parameters taken from OADL_ArrayInfo *pArr.
* Returns the resulting array in *pRes. This does allocate
* heap memory which could trigger a GC and invalidate any
* cached heap pointers.
*
* Note that if pArr->arrData and pArr->arrStrides are ignored
* unless OADL_ARRAY_USER_DATA is specified in pArr->arrFlags.
*
* pArr->arrSize and pArr->elemSize are always ignored, as they
* are calculated from the input in pArr->arrType and pArr->arrShape.
*
* The pArr structure is updated with the actual array created.
*/
typedef int (*OADL_CreateArray_fp)(void *ctx, OadlVar *pRes,
OADL_ArrayInfo *pArr);
/* OADL_ArrayIncr
* Increment a multidimensional array index and return the
* new offset to the current element. Note that a scalar may
* be aliased as an array by using a rank of 0. Note also
* that the proper offset to the next element (based on the
* contents of index[]) is computed if an offs of 0 is
* consistently provided in a loop over all elements.
*
* Inputs:
* offs Current offset (start at 0)
* rank Rank (dimensionality) of array
* strides[] Array of strides, from OADL_ArrayInfo
* shape[] Shape of array, from OADL_ArrayInfo
* index[] Current indices of array (start at {0})
* Result:
* Updated offs and index[] array
*/
static inline int OADL_ArrayIncr(int offs,
int rank,
const uint32_t strides[],
const uint32_t shape[],
uint32_t index[])
{
int i;
for (i = rank-1; i >= 0; i--) {
/* Increment to next element in this rank */
if (strides) offs += strides[i];
if (shape[i] > ++index[i]) {
/* We are done rolling up the odometer at this point */
break;
}
/* Roll over the odometer and continue with the next higher index */
index[i] = 0;
/* Decrement back to beginning of this rank */
if (strides) offs -= shape[i]*strides[i];
}
return offs;
}
/* OADL_IdxOffset
* Calculates the offset to an array element given an index, rank
* and strides. It is presumed that the index has been range-checked!
*/
static inline int OADL_IdxOffset(int rank,
const uint32_t index[],
const uint32_t strides[])
{
int offs = 0;
for (int i = 0; i < rank; i++) {
offs += index[i] * strides[i];
}
return offs;
}
/* OADL_GetIndex(ctx, pRes, v, nIdx, idx[])
* Returns "v[idx]" in "*pRes". Always safe even in the face
* of asynchronous GC
*/
typedef int (*OADL_GetIndex_fp)(void *ctx, OadlVar *pRes, OadlVar v,
int nIdx, int idx[]);
/* OADL_SetIndex(ctx, pRes, v, nIdx, idx, val)
* Equivalent of "v[idx0,idx1,...] = val". Always safe even in the face
* of asynchronous GC
*/
typedef int (*OADL_SetIndex_fp)(void *ctx, OadlVar v,
int nIdx, int idx[], OadlVar val);
/* OADL_GetSubr(ctx, pDst, v, nargs, args )
* Returns "v[v0:v1...vn:vm]" in *pDst. Note that this allocates memory
* and may result in an asynchronous GC which may invalidate any
* locally cached pointers to OADL heap objects.
*/
typedef int (*OADL_GetSubr_fp)(void *, OadlVar *, OadlVar, int, OadlVar *);
/* OADL_WriteCopy(ctx, pRes, v)
* To write directly into arrData (i.e., instead of calling
* OADL_SetIndex), one must first call WriteCopy. The integer at
* *pRes will be changed to 1 if a write copy was created, 0 otherwise.
* It is not necessary to call OADL_WriteCopy on arrays created
* by the current extern call. Note that OADL_WriteCopy can trigger
* a GC.
*/
typedef int (*OADL_WriteCopy_fp)(void *ctx, int *pRes, OadlVar v);
/*****************************************************************************
* Global variable manipulation functions
*****************************************************************************/
/* OADL_GetGlobal(ctx, pRes, idx)
* Gets the global variable at index idx and puts it in pRes
*/
typedef int (*OADL_GetGlobal_fp)(void *ctx, OadlVar *pRes, int idx);
/* OADL_SetGlobal(ctx, idx, val)
* Sets the global variable at index idx to val
*/
typedef int (*OADL_SetGlobal_fp)(void *ctx, int idx, OadlVar val);
/*****************************************************************************
* OADL machine and procedure functions
*****************************************************************************/
/* OADL_AllocMach(ctx, pRes, stackAlloc)
* Creates an OADL Machine capable of calling procedures
* immediately. It allocates "stackAlloc" entries
* for the execution stack.
*/
typedef int (*OADL_AllocMach_fp)(void *ctx, void **pRes, int stackAlloc);
/* OADL_FreeMach(ctx, pRes, stackAlloc)
* Frees a machine previously allocated by OADL_AllocMach()
*/
typedef int (*OADL_FreeMach_fp)(void *ctx, void *ptr);
/* OADL_CallProc(ctx, typ, pRes, mach, obj, proc, nargs, args)
* Makes an immediate or deferred call to the OADL procedure
* whose value is "proc", or to the method whose value
* is "obj.proc" if obj is not nil (proc must be of type
* Public in that case).
*
* The "typ" parameter defines how the call will be executed:
*
* OADL_CALL_IMMEDIATE
* Make an immediate call. The "mach" parameter must
* be allocated by OADL_AllocMach() OADL_CallProc will
* not return until the OADL procedure has completed
* execution. The return value of the immediate call
* will be placed in the OadlVar pointed to by the
* "pRes" parameter. Most OADL procedures allocate
* heap objects. This may trigger a GC cycle which
* will invalidate any cached heap pointers. The
* calling routine must revalidate any pointers to
* heap objects after OADL_CallProc returns.
*
* OADL_CALL_DEFERRED
* Make a deferred call (a call placed on the current
* executing mach stack). OADL_CallProc returns
* immediately. Note that deferred calls do not return
* any value to the calling context. This allows
* multiple deferred calls to be scheduled
* simultaneously without overflowing the stack with
* unused results. Since the call is deferred, no heap
* allocations will occur at the time of the
* OADL_CallProc call. The extern that defers one
* or more calls must return OADL_CALL_DEFERRED to
* OADL.
*
* OADL_CALL_CHAINED
* Make a chained call. Chained calls are also
* deferred; however, their results *are* returned to
* the calling context. The extern that chains a call
* must return OADL_CALL_CHAINED to OADL.
*
*
* OADL_CallProc returns 1 on success and 0 on failure.
*/
// These start at "2" so normal extern return values of 0 and 1 don't
// interfere
#define OADL_CALL_IMMEDIATE 2
#define OADL_CALL_DEFERRED 3
#define OADL_CALL_CHAINED 4
typedef int (*OADL_CallProc_fp)(void *ctx, OadlVar *pRes, int typ, void *mach,
OadlVar obj, OadlVar proc,
int nargs, const OadlVar *args);
/* OADL_AddProc(ctx, pVar, instrs, numInst)
* Adds a new proc based on the numInst instructions
* in instrs. The instrs/numInst are typically based on
* a cvtintr process. Result is returned in *pVar.
*/
typedef int (*OADL_AddProc_fp)(void *ctx, OadlVar *pVar,
const uint8_t instrs[], int numInst);
/* OADL_PushIntrinsic(ctx)
* Increments the intrinsic depth. Returns 1 on success, 0 if
* an error occured.
*/
typedef int (*OADL_PushIntrinsic_fp)(void *ctx);
/* OADL_PopIntrinsic(ctx)
* Decrements the intrinsic depth. Returns 1 on success, 0 if
* an error occured.
*/
typedef int (*OADL_PopIntrinsic_fp)(void *ctx);
/*****************************************************************************
* Dictionary manipulation functions
*****************************************************************************/
/* OADL_CreateDict(ctx, pRes, pList, nList)
* Creates a Dictionary holding exactly the key-value pairs found
* in the given list. nList must be a multiple of two.
*/
typedef int (*OADL_CreateDict_fp)(void *ctx, OadlVar *pRes,
OadlVar *pList, int nList);
/* OADL_EnumDict(ctx, dict, arg, func)
* Enumerates the contents of a dictionary, passing the
* arg to the func with each key/value pair. Note that
* a "nil" key or value indicates an undefined entry.
* Func should return 1 to terminate the enumeration
* early, and 0 otherwise.
*
* Returns 1 if an invocation of func returned 1,
* and 0 otherwise (this facilitates the search
* for a specific set of keys).
*
* func MUST NOT provoke a garbage collection cycle
*/
typedef int (*OADL_EnumDict_fp)(void *ctx, OadlVar dict,
void *arg,
int (*func)(void *, OadlVar, OadlVar));
/*****************************************************************************
* Pointer manipulation functions
*****************************************************************************/
/* OADL_MakePointer(ctx, pRes, ptr)
* Registers the given C pointer as an OADL pointer, returning
* the result in *pRes.
*/
typedef int (*OADL_MakePointer_fp)(void *ctx, OadlVar *pRes, void *ptr);
/* OADL_DelPointer(ctx, v)
* De-registers the given OADL pointer.
*/
typedef int (*OADL_DelPointer_fp)(void *ctx, OadlVar v);
/* OADL_FindPointer(pRes, v)
* Finds the C pointer referred to by OADL pointer v and returns
* it in *pRes
*/
typedef int (*OADL_FindPointer_fp)(void *ctx, void **pRes, OadlVar v);
/*****************************************************************************
* Named object query functions
*****************************************************************************/
/* OADL_GetPubName(ctx, pRes, v)
* Returns the name of the public v. Same as "pubname(v)"
* Note that "*pRes" will be UTF-8 encoded if the result is
* a wide string.
*/
typedef int (*OADL_GetPubName_fp)(void *ctx, char **pRes, OadlVar v);
/* OADL_GetExtName(ctx, pRes, v)
* Returns the name of the extern v.
* Note that "*pRes" will be UTF-8 encoded if the result is
* a wide string.
*/
typedef int (*OADL_GetExtName_fp)(void *ctx, char **pRes, OadlVar v);
/* OADL_GetObjName(ctx, pRes, v)
* Returns the name of the object v. Same as "objname(v)"
* Note that "*pRes" will be UTF-8 encoded if the result is
* a wide string.
*/
typedef int (*OADL_GetObjName_fp)(void *ctx, char **pRes, OadlVar v);
/* OADL_FindPublic(ctx, pRes, name)
* Find the public named "name" and returns its value in *pRes
* Note that "name" may be a UTF-8 encoded wide string.
*/
typedef int (*OADL_FindPublic_fp)(void *ctx, OadlVar *pRes,
const char *name);
/* OADL_FindExtern(ctx, pRes, name)
* Find the extern named "name" and returns its value in *pRes
* Note that "name" may be a UTF-8 encoded wide string.
*/
typedef int (*OADL_FindExtern_fp)(void *ctx, OadlVar *pRes,
const char *name);
/* OADL_FindGlobal(ctx, pRes, name)
* Returns the index of the global variable named "name" in *pRes
* Note that "name" may be a UTF-8 encoded wide string.
*/
typedef int (*OADL_FindGlobal_fp)(void *ctx, int *pRes,
const char *name);
/* OADL_FindObject(ctx, pRes, name)
* Find the object named "name" and returns its value in *pRes
* Note that "name" may be a UTF-8 encoded wide string.
*/
typedef int (*OADL_FindObject_fp)(void *ctx, OadlVar *pRes,
const char *name);
/* OADL_FindClass(ctx, pRes, name)
* Find the object named "name" and returns its value in *pRes
* Note that "name" may be a UTF-8 encoded wide string.
*/
typedef int (*OADL_FindClass_fp)(void *ctx, OadlVar *pRes,
const char *name);
/*****************************************************************************
* OADL I/O functions
*****************************************************************************/
/* OADL_fgets(ctx, pRes, f)
* Reads a string from the UTF8 stream f returning the resulting OADL
* String or WideString object in *pRes
*/
typedef int (*OADL_fgets_fp)(void *ctx, OadlVar *pRes, OadlVar f);
/* OADL_fgetc(ctx, f)
* Reads a UTF8 character from the UTF8 stream f and returns
* the character as *pRes (note - returns the int, not the OadlVar)
*/
typedef int (*OADL_fgetc_fp)(void *ctx, int *pRes, OadlVar f);
/* OADL_fputc(ctx, f, c)
* Puts the (possibly wide) character c into UTF8 stream f
*/
typedef int (*OADL_fputc_fp)(void *ctx, OadlVar f, int c);
/* OADL_fputs(ctx, f, s)
* Puts the 8-bit character string "s" into UTF8 stream f
*/
typedef int (*OADL_fputs_fp)(void *ctx, OadlVar f, const char *s, int len);
/* OADL_wfputs(ctx, f, s)
* Puts the 32-bit character string "s" into UTF8 stream f
*/
typedef int (*OADL_wfputs_fp)(void *ctx, OadlVar f, const OADL_WCH *s,
int len);
/* OADL_ungetc(ctx, f, c)
* Pushes the character "c" back onto UTF8 stream f to be
* returned by subsequent UTF8 reads
*/
typedef int (*OADL_ungetc_fp)(void *ctx, OadlVar f, int c);
/* OADL_fopen(ctx, pRes, name, access)
* Opens a UTF8 stream and returns the File result in *pRes
*/
typedef int (*OADL_fopen_fp)(void *ctx, OadlVar *pRes,
const char *name, const char *access);
/* OADL_fclose(ctx, f)
* Close the UTF8 stream "f"
*/
typedef int (*OADL_fclose_fp)(void *ctx, OadlVar f);
/* Other OADL equivalents to stdio routines. If you use
* OADL_fopen, you need to use these.
*/
typedef int (*OADL_fflush_fp)(void *ctx, OadlVar f);
typedef int64_t (*OADL_fseek_fp)(void *ctx, OadlVar, int64_t, int);
typedef int64_t (*OADL_ftell_fp)(void *ctx, OadlVar);
typedef int (*OADL_fread_fp)(void *ctx, void *p, int n, int s, OadlVar f);
typedef int (*OADL_fwrite_fp)(void *ctx, void *p, int n, int s, OadlVar f);
typedef int (*OADL_feof_fp)(void *ctx, OadlVar f);
typedef int (*OADL_ferror_fp)(void *ctx, OadlVar f);
typedef int (*OADL_clearerr_fp)(void *ctx, OadlVar f);
/* If the extern library wants to hook/intercept say() and read(), it should
* call this routine with the three entry points specified. Note that
* the OADL_GetChar, OADL_SayChar, OADL_SayStr, and OADL_SayLStr functions
* are NOT queryable via the normal OADL_FindProc mechanism; use the
* OADL_GetIoProcs() function to get them instead.
*/
typedef int (*OADL_GetChar_fp)(void *ctx, OadlVar vf);
typedef void (*OADL_SayChar_fp)(void *ctx, int wch);
typedef void (*OADL_SayStr_fp)(void *ctx, char *s, int n);
typedef void (*OADL_SayLStr_fp)(void *ctx, OADL_WCH *s, int n);
typedef int (*OADL_IoProcs_fp)(void *ctx,
OADL_GetChar_fp getChar,
OADL_SayChar_fp sayChar,
OADL_SayStr_fp sayStr,
OADL_SayLStr_fp sayLStr);
/* Retrieve the current IO procs */
typedef int (*OADL_GetIoProcs_fp)(void *ctx,
OADL_GetChar_fp *pGetChar,
OADL_SayChar_fp *pSayChar,
OADL_SayStr_fp *pSayStr,
OADL_SayLStr_fp *pSayLStr);
/*****************************************************************************
* OADL UTF-8 support functions
*****************************************************************************/
/* Determines the Unicode Character Type from a given widechar value
* between 0 and 0x110000. Returns -1 on error. See unicode.h for
* possible character types.
*/
typedef int (*OADL_ucCharType_fp)(int);
/* Converts a widechar value between 0 and 0x110000. Returns the
* original character if no single-character conversion is found.
*/
typedef int (*OADL_ucToUpper_fp)(int);
typedef int (*OADL_ucToLower_fp)(int);
/* OADL_utf8_bytelen(src, n)
* Returns the number of bytes that would be required to encode
* the 32-bit string src
*/
typedef int (*OADL_utf8_bytelen_fp)(OADL_WCH *src, int n);
/* OADL_utf8_wcharLen(src, n)
* Returns the number of WCHARS that would be required to decode
* the UTF-8 encoded string "src[n]"
*/
typedef int (*OADL_utf8_wcharlen_fp)(uint8_t *src, int n);
/* OADL_utf8_encode(ctx, dst, src, n)
* Copies the 32-bit string "src[n]" into the UTF8 string
* "dst" which must have enough space allocated to hold the
* complete string. Returns a pointer to the byte after
* the last byte placed.
*/
typedef uint8_t *(*OADL_utf8_encode_fp)(uint8_t *dst,
uint32_t *src, int n);
/* OADL_utf8_decode(dst, src, len)
* Decodes a UTF-8 encoded string "src[n]" into the
* 32-bit string "dst" which must have enough space allocated
* to hold the complete string. Returns a pointer to the
* uint32 after the last uint32 placed.
*/
typedef uint32_t *(*OADL_utf8_decode_fp)(uint32_t *dst,
uint8_t *src, int n);
/*****************************************************************************
* PCRE regular expression support functions
*****************************************************************************/
/* OADL_RegComp(ctx, pRE, pattStr)
* Compiles the PCRE pattern "pattStr" into *pRE for subsequent
* use with OADL_RegEx(). Options are standard PCRE options,
* found in oadlpcre.h
*/
typedef int (*OADL_RegComp_fp)(void *ctx, void **pRE, char *pattStr,
int options);
/* OADL_RegEx(ctx, pRes, re, str, first, len, options, patOffs, patOffSize)
* Executes the PCRE reg exp. machine with compiled expression "RE".
* The matches are returned in patOffs[]. patOffs will be
* an array of [begin,end+1] pairs indicating the captured
* substrings, with patOffs[0]/patOffs[1] indicating the entire
* match. first/len indicate the substring which is to be matched.
* Options are PCRE options, from the list found in oadlpcre.h.
* The number of pairs is returned in *pRes.
*/
typedef int (*OADL_RegEx_fp)(void *ctx, int *pRes, void *re,
char *str, int first, int len, int options,
int patOffs[], int patOffSize);
/* OADL_RegFree(ctx, re)
* Frees a PCRE regular expression previously created by OADL_RegComp()
*/
typedef int (*OADL_RegFree_fp)(void *ctx, void *re);
/*****************************************************************************
* Memory allocation and freeing
*****************************************************************************/
/* OADL_malloc / OADL_realloc / OADL_free
* Just like libc malloc/realloc/free but with OADL
* debugging hooks. Also more likely to work independent
* of how malloc pools are implemented with shared libraries.
*/
typedef int (*OADL_malloc_fp)(void *ctx, void **pRes, int nBytes);
typedef int (*OADL_realloc_fp)(void *ctx, void **pRes, void *ptr, int nBytes);
typedef int (*OADL_free_fp)(void *ctx, void *ptr);
/* OADL_AllocScratch - allocates scratch space that is only valid
* until the next OADL_AllocScratch. No need to free this memory;
* it is recycled by client of OADL_AllocScratch
*/
typedef int (*OADL_AllocScratch_fp)(void *ctx, void **pRes, int nBytes);
#endif // ] _OADL_SYS_INCLUDED