2015-04-30 15:56:05 +00:00
/*
* $ Id $
*
Copyright ( c ) 2014 - 2015 Chung , Hyung - Hwan . All rights reserved .
Redistribution and use in source and binary forms , with or without
modification , are permitted provided that the following conditions
are met :
1. Redistributions of source code must retain the above copyright
notice , this list of conditions and the following disclaimer .
2. Redistributions in binary form must reproduce the above copyright
notice , this list of conditions and the following disclaimer in the
documentation and / or other materials provided with the distribution .
THIS SOFTWARE IS PROVIDED BY THE AUTHOR " AS IS " AND ANY EXPRESS OR
IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED .
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT , INDIRECT ,
INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT
NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
*/
# ifndef _STIX_H_
# define _STIX_H_
2015-05-15 14:55:12 +00:00
/* TODO: move this macro out to the build files.... */
# define STIX_INCLUDE_COMPILER
2015-05-16 07:31:16 +00:00
/* =========================================================================
* PRIMITIVE TYPE DEFINTIONS
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
2015-04-30 15:56:05 +00:00
/* TODO: define these types and macros using autoconf */
typedef unsigned char stix_uint8_t ;
2015-05-19 15:16:18 +00:00
typedef signed char stix_int8_t ;
2015-04-30 15:56:05 +00:00
typedef unsigned short int stix_uint16_t ;
2015-05-19 15:16:18 +00:00
typedef signed short int stix_int16_t ;
2015-05-15 14:55:12 +00:00
# if defined(__MSDOS__)
typedef unsigned long int stix_uint32_t ;
2015-05-19 15:16:18 +00:00
typedef signed long int stix_int32_t ;
2015-05-15 14:55:12 +00:00
# else
typedef unsigned int stix_uint32_t ;
2015-05-19 15:16:18 +00:00
typedef signed int stix_int32_t ;
2015-05-15 14:55:12 +00:00
# endif
2015-05-19 15:16:18 +00:00
2015-05-03 17:10:30 +00:00
typedef unsigned long int stix_uintptr_t ;
2015-06-04 18:34:37 +00:00
typedef signed long int stix_intptr_t ;
2015-05-03 17:10:30 +00:00
typedef unsigned long int stix_size_t ;
2015-05-19 15:16:18 +00:00
typedef signed long int stix_ssize_t ;
2015-04-30 15:56:05 +00:00
2015-05-26 16:31:47 +00:00
typedef stix_uint8_t stix_byte_t ;
2015-05-19 15:16:18 +00:00
typedef stix_uint16_t stix_uch_t ; /* TODO ... wchar_t??? */
typedef stix_int32_t stix_uci_t ;
typedef char stix_bch_t ;
2015-05-17 05:02:30 +00:00
struct stix_ucs_t
{
stix_uch_t * ptr ;
stix_size_t len ;
} ;
typedef struct stix_ucs_t stix_ucs_t ;
2015-04-30 15:56:05 +00:00
2015-05-16 07:31:16 +00:00
/* =========================================================================
* PRIMITIVE MACROS
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
2015-05-19 15:16:18 +00:00
# define STIX_UCI_EOF ((stix_uci_t)-1)
# define STIX_UCI_NL ((stix_uci_t)'\n')
2015-04-30 15:56:05 +00:00
# define STIX_SIZEOF(x) (sizeof(x))
# define STIX_COUNTOF(x) (sizeof(x) / sizeof(x[0]))
/**
* The STIX_OFFSETOF ( ) macro returns the offset of a field from the beginning
* of a structure .
*/
# define STIX_OFFSETOF(type,member) ((stix_uintptr_t)&((type*)0)->member)
/**
* The STIX_ALIGNOF ( ) macro returns the alignment size of a structure .
* Note that this macro may not work reliably depending on the type given .
*/
# define STIX_ALIGNOF(type) STIX_OFFSETOF(struct { stix_uint8_t d1; type d2; }, d2)
/*(sizeof(struct { stix_uint8_t d1; type d2; }) - sizeof(type))*/
# if defined(__cplusplus)
# if (__cplusplus >= 201103L) /* C++11 */
# define STIX_NULL nullptr
# else
# define STIX_NULL (0)
# endif
# else
# define STIX_NULL ((void*)0)
# endif
2015-05-03 17:10:30 +00:00
/* make a low bit mask that can mask off low n bits*/
# define STIX_LBMASK(type,n) (~(~((type)0) << (n)))
/* get 'length' bits starting from the bit at the 'offset' */
# define STIX_GETBITS(type,value,offset,length) \
2015-05-04 16:48:38 +00:00
( ( ( ( type ) ( value ) ) > > ( offset ) ) & STIX_LBMASK ( type , length ) )
2015-05-03 17:10:30 +00:00
# define STIX_SETBITS(type,value,offset,length,bits) \
2015-05-04 16:48:38 +00:00
( value = ( ( ( type ) ( value ) ) | ( ( ( bits ) & STIX_LBMASK ( type , length ) ) < < ( offset ) ) ) )
/**
* The STIX_BITS_MAX ( ) macros calculates the maximum value that the ' nbits '
* bits of an unsigned integer of the given ' type ' can hold .
* \ code
* printf ( " %u " , STIX_BITS_MAX ( unsigned int , 5 ) ) ;
* \ endcode
*/
/*#define STIX_BITS_MAX(type,nbits) ((((type)1) << (nbits)) - 1)*/
# define STIX_BITS_MAX(type,nbits) ((~(type)0) >> (STIX_SIZEOF(type) * 8 - (nbits)))
2015-05-03 17:10:30 +00:00
2015-05-16 07:31:16 +00:00
/* =========================================================================
* POINTER MANIPULATION MACROS
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
# if defined(__MSDOS__)
# define STIX_INCPTR(type,base,inc) (((type __huge*)base) + (inc))
# define STIX_DECPTR(type,base,inc) (((type __huge*)base) - (inc))
# define STIX_GTPTR(type,ptr1,ptr2) (((type __huge*)ptr1) > ((type __huge*)ptr2))
# define STIX_GEPTR(type,ptr1,ptr2) (((type __huge*)ptr1) >= ((type __huge*)ptr2))
# define STIX_LTPTR(type,ptr1,ptr2) (((type __huge*)ptr1) < ((type __huge*)ptr2))
# define STIX_LEPTR(type,ptr1,ptr2) (((type __huge*)ptr1) <= ((type __huge*)ptr2))
# define STIX_EQPTR(type,ptr1,ptr2) (((type __huge*)ptr1) == ((type __huge*)ptr2))
# define STIX_SUBPTR(type,ptr1,ptr2) (((type __huge*)ptr1) - ((type __huge*)ptr2))
# else
# define STIX_INCPTR(type,base,inc) (((type*)base) + (inc))
# define STIX_DECPTR(type,base,inc) (((type*)base) - (inc))
# define STIX_GTPTR(type,ptr1,ptr2) (((type*)ptr1) > ((type*)ptr2))
# define STIX_GEPTR(type,ptr1,ptr2) (((type*)ptr1) >= ((type*)ptr2))
# define STIX_LTPTR(type,ptr1,ptr2) (((type*)ptr1) < ((type*)ptr2))
# define STIX_LEPTR(type,ptr1,ptr2) (((type*)ptr1) <= ((type*)ptr2))
# define STIX_EQPTR(type,ptr1,ptr2) (((type*)ptr1) == ((type*)ptr2))
# define STIX_SUBPTR(type,ptr1,ptr2) (((type*)ptr1) - ((type*)ptr2))
# endif
/* =========================================================================
* MMGR
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
2015-04-30 15:56:05 +00:00
typedef struct stix_mmgr_t stix_mmgr_t ;
/**
* allocate a memory chunk of the size \ a n .
2015-05-16 07:31:16 +00:00
* \ return pointer to a memory chunk on success , # STIX_NULL on failure .
2015-04-30 15:56:05 +00:00
*/
typedef void * ( * stix_mmgr_alloc_t ) ( stix_mmgr_t * mmgr , stix_size_t n ) ;
/**
* resize a memory chunk pointed to by \ a ptr to the size \ a n .
2015-05-16 07:31:16 +00:00
* \ return pointer to a memory chunk on success , # STIX_NULL on failure .
2015-04-30 15:56:05 +00:00
*/
typedef void * ( * stix_mmgr_realloc_t ) ( stix_mmgr_t * mmgr , void * ptr , stix_size_t n ) ;
/**
* free a memory chunk pointed to by \ a ptr .
*/
typedef void ( * stix_mmgr_free_t ) ( stix_mmgr_t * mmgr , void * ptr ) ;
/**
* The stix_mmgr_t type defines the memory management interface .
* As the type is merely a structure , it is just used as a single container
* for memory management functions with a pointer to user - defined data .
* The user - defined data pointer \ a ctx is passed to each memory management
* function whenever it is called . You can allocate , reallocate , and free
* a memory chunk .
*
* For example , a stix_xxx_open ( ) function accepts a pointer of the stix_mmgr_t
* type and the xxx object uses it to manage dynamic data within the object .
*/
struct stix_mmgr_t
{
stix_mmgr_alloc_t alloc ; /**< allocation function */
stix_mmgr_realloc_t realloc ; /**< resizing function */
stix_mmgr_free_t free ; /**< disposal function */
void * ctx ; /**< user-defined data pointer */
} ;
/**
* The STIX_MMGR_ALLOC ( ) macro allocates a memory block of the \ a size bytes
* using the \ a mmgr memory manager .
*/
# define STIX_MMGR_ALLOC(mmgr,size) ((mmgr)->alloc(mmgr,size))
/**
* The STIX_MMGR_REALLOC ( ) macro resizes a memory block pointed to by \ a ptr
* to the \ a size bytes using the \ a mmgr memory manager .
*/
# define STIX_MMGR_REALLOC(mmgr,ptr,size) ((mmgr)->realloc(mmgr,ptr,size))
/**
* The STIX_MMGR_FREE ( ) macro deallocates the memory block pointed to by \ a ptr .
*/
# define STIX_MMGR_FREE(mmgr,ptr) ((mmgr)->free(mmgr,ptr))
2015-05-16 07:31:16 +00:00
/* =========================================================================
* CMGR
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
typedef struct stix_cmgr_t stix_cmgr_t ;
2015-05-17 05:02:30 +00:00
typedef stix_size_t ( * stix_cmgr_bctouc_t ) (
const stix_bch_t * mb ,
2015-05-16 07:31:16 +00:00
stix_size_t size ,
2015-05-17 05:02:30 +00:00
stix_uch_t * wc
2015-05-16 07:31:16 +00:00
) ;
2015-05-17 05:02:30 +00:00
typedef stix_size_t ( * stix_cmgr_uctobc_t ) (
stix_uch_t wc ,
stix_bch_t * mb ,
2015-05-16 07:31:16 +00:00
stix_size_t size
) ;
/**
* The stix_cmgr_t type defines the character - level interface to
* multibyte / wide - character conversion . This interface doesn ' t
* provide any facility to store conversion state in a context
* independent manner . This leads to the limitation that it can
* handle a stateless multibyte encoding only .
*/
struct stix_cmgr_t
{
2015-05-17 05:02:30 +00:00
stix_cmgr_bctouc_t bctouc ;
stix_cmgr_uctobc_t uctobc ;
2015-05-16 07:31:16 +00:00
} ;
/* =========================================================================
* MACROS THAT CHANGES THE BEHAVIORS OF THE C COMPILER / LINKER
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
2015-04-30 15:56:05 +00:00
# if defined(_WIN32) || defined(__WATCOMC__)
# define STIX_IMPORT __declspec(dllimport)
# define STIX_EXPORT __declspec(dllexport)
# define STIX_PRIVATE
# elif defined(__GNUC__) && (__GNUC__>=4)
# define STIX_IMPORT __attribute__((visibility("default")))
# define STIX_EXPORT __attribute__((visibility("default")))
# define STIX_PRIVATE __attribute__((visibility("hidden")))
/*# define STIX_PRIVATE __attribute__((visibility("internal")))*/
# else
# define STIX_IMPORT
# define STIX_EXPORT
# define STIX_PRIVATE
# endif
# if defined(__STDC_VERSION__) && (__STDC_VERSION__>=199901L)
# define STIX_INLINE inline
# define STIX_HAVE_INLINE
# elif defined(__GNUC__) && defined(__GNUC_GNU_INLINE__)
/* gcc disables inline when -std=c89 or -ansi is used.
* so use __inline__ supported by gcc regardless of the options */
# define STIX_INLINE /*extern*/ __inline__
# define STIX_HAVE_INLINE
# else
# define STIX_INLINE
# undef STIX_HAVE_INLINE
# endif
/* ========================================================================== */
/**
* The stix_errnum_t type defines the error codes .
*/
enum stix_errnum_t
{
STIX_ENOERR , /**< no error */
STIX_EOTHER , /**< other error */
STIX_ENOIMPL , /**< not implemented */
STIX_ESYSERR , /**< subsystem error */
STIX_EINTERN , /**< internal error */
STIX_ENOMEM , /**< insufficient memory */
STIX_EINVAL , /**< invalid parameter or data */
2015-05-15 14:55:12 +00:00
STIX_ENOENT , /**< no matching entry */
2015-05-17 05:02:30 +00:00
STIX_EIOERR , /**< I/O error */
2015-05-19 15:16:18 +00:00
STIX_EECERR , /**< encoding conversion error */
# if defined(STIX_INCLUDE_COMPILER)
STIX_ESYNTAX /** < syntax error */
# endif
2015-04-30 15:56:05 +00:00
} ;
typedef enum stix_errnum_t stix_errnum_t ;
enum stix_option_t
{
2015-05-07 15:58:04 +00:00
STIX_TRAIT ,
2015-05-08 14:29:35 +00:00
STIX_DFL_SYMTAB_SIZE ,
STIX_DFL_SYSDIC_SIZE
2015-04-30 15:56:05 +00:00
} ;
typedef enum stix_option_t stix_option_t ;
enum stix_trait_t
{
/* perform no garbage collection when the heap is full.
* you still can use stix_gc ( ) explicitly . */
STIX_NOGC = ( 1 < < 0 )
} ;
typedef enum stix_trait_t stix_trait_t ;
/* NOTE: sizeof(stix_oop_t) must be equal to sizeof(stix_oow_t) */
typedef stix_uintptr_t stix_oow_t ;
2015-06-04 18:34:37 +00:00
typedef stix_intptr_t stix_ooi_t ;
2015-04-30 15:56:05 +00:00
typedef struct stix_obj_t stix_obj_t ;
typedef struct stix_obj_t * stix_oop_t ;
/* these are more specialized types for stix_obj_t */
typedef struct stix_obj_oop_t stix_obj_oop_t ;
typedef struct stix_obj_char_t stix_obj_char_t ;
2015-05-31 16:44:56 +00:00
typedef struct stix_obj_byte_t stix_obj_byte_t ;
typedef struct stix_obj_word_t stix_obj_word_t ;
2015-04-30 15:56:05 +00:00
/* these are more specialized types for stix_oop_t */
typedef struct stix_obj_oop_t * stix_oop_oop_t ;
typedef struct stix_obj_char_t * stix_oop_char_t ;
2015-05-31 16:44:56 +00:00
typedef struct stix_obj_byte_t * stix_oop_byte_t ;
typedef struct stix_obj_word_t * stix_oop_word_t ;
2015-04-30 15:56:05 +00:00
2015-05-04 16:48:38 +00:00
# define STIX_OOW_BITS (STIX_SIZEOF(stix_oow_t) * 8)
# define STIX_OOP_BITS (STIX_SIZEOF(stix_oop_t) * 8)
2015-04-30 15:56:05 +00:00
/*
* OOP encoding
* An object pointer ( OOP ) is an ordinary pointer value to an object .
* but some simple numeric values are also encoded into OOP using a simple
* bit - shifting and masking .
*
* A real OOP is stored without any bit - shifting while a non - OOP value encoded
* in an OOP is bit - shifted to the left by 2 and the 2 least - significant bits
* are set to 1 or 2.
*
* This scheme works because the object allocators aligns the object size to
* a multiple of sizeof ( stix_oop_t ) . This way , the 2 least - significant bits
* of a real OOP are always 0 s .
*/
2015-05-04 16:48:38 +00:00
# define STIX_OOP_TAG_BITS 2
# define STIX_OOP_TAG_SMINT 1
# define STIX_OOP_TAG_CHAR 2
2015-04-30 15:56:05 +00:00
2015-05-04 16:48:38 +00:00
# define STIX_OOP_IS_NUMERIC(oop) (((stix_oow_t)oop) & (STIX_OOP_TAG_SMINT | STIX_OOP_TAG_CHAR))
2015-04-30 15:56:05 +00:00
# define STIX_OOP_IS_POINTER(oop) (!STIX_OOP_IS_NUMERIC(oop))
2015-05-07 15:58:04 +00:00
# define STIX_OOP_GET_TAG(oop) (((stix_oow_t)oop) & STIX_LBMASK(stix_oow_t, STIX_OOP_TAG_BITS))
2015-04-30 15:56:05 +00:00
2015-06-04 18:34:37 +00:00
# define STIX_OOP_IS_SMINT(oop) (((stix_ooi_t)oop) & STIX_OOP_TAG_SMINT)
2015-05-04 16:48:38 +00:00
# define STIX_OOP_IS_CHAR(oop) (((stix_oow_t)oop) & STIX_OOP_TAG_CHAR)
2015-06-04 18:34:37 +00:00
# define STIX_OOP_FROM_SMINT(num) ((stix_oop_t)((((stix_ooi_t)(num)) << STIX_OOP_TAG_BITS) | STIX_OOP_TAG_SMINT))
# define STIX_OOP_TO_SMINT(oop) (((stix_ooi_t)oop) >> STIX_OOP_TAG_BITS)
2015-05-04 16:48:38 +00:00
# define STIX_OOP_FROM_CHAR(num) ((stix_oop_t)((((stix_oow_t)(num)) << STIX_OOP_TAG_BITS) | STIX_OOP_TAG_CHAR))
# define STIX_OOP_TO_CHAR(oop) (((stix_oow_t)oop) >> STIX_OOP_TAG_BITS)
2015-04-30 15:56:05 +00:00
2015-06-04 18:34:37 +00:00
# define STIX_SMINT_BITS (STIX_SIZEOF(stix_ooi_t) * 8 - STIX_OOP_TAG_BITS)
# define STIX_SMINT_MAX ((stix_ooi_t)(~((stix_oow_t)0) >> (STIX_OOP_TAG_BITS + 1)))
# define STIX_SMINT_MIN (-STIX_SMINT_MAX - 1)
# define STIX_OOI_IN_SMINT_RANGE(ooi) ((ooi) >= STIX_SMINT_MIN && (ooi) <= STIX_SMINT_MAX)
/* TODO: There are untested code where smint is converted to stix_oow_t.
* for example , the spec making macro treats the number as stix_oow_t instead of stix_ooi_t .
* as of this writing , i skip testing that part with the spec value exceeding STIX_SMINT_MAX .
* later , please verify it works , probably by limiting the value ranges in such macros
*/
2015-04-30 15:56:05 +00:00
/*
* Object structure
*/
enum stix_obj_type_t
{
STIX_OBJ_TYPE_OOP ,
STIX_OBJ_TYPE_CHAR ,
2015-05-26 16:31:47 +00:00
STIX_OBJ_TYPE_BYTE ,
STIX_OBJ_TYPE_WORD ,
/*
STIX_OBJ_TYPE_UINT8 ,
STIX_OBJ_TYPE_UINT16 ,
STIX_OBJ_TYPE_UINT32 ,
*/
2015-04-30 15:56:05 +00:00
/* NOTE: you can have STIX_OBJ_SHORT, STIX_OBJ_INT
* STIX_OBJ_LONG , STIX_OBJ_FLOAT , STIX_OBJ_DOUBLE , etc
* type type field being 6 bits long , you can have up to 64 different types .
STIX_OBJ_TYPE_SHORT ,
STIX_OBJ_TYPE_INT ,
STIX_OBJ_TYPE_LONG ,
STIX_OBJ_TYPE_FLOAT ,
STIX_OBJ_TYPE_DOUBLE */
} ;
typedef enum stix_obj_type_t stix_obj_type_t ;
2015-05-16 07:31:16 +00:00
/* =========================================================================
2015-05-03 17:10:30 +00:00
* Object header structure
*
* _flags :
* type : the type of a payload item .
* one of STIX_OBJ_TYPE_OOP , STIX_OBJ_TYPE_CHAR ,
2015-05-26 16:31:47 +00:00
* STIX_OBJ_TYPE_BYTE , STIX_OBJ_TYPE_WORD
2015-05-03 17:10:30 +00:00
* unit : the size of a payload item in bytes .
* extra : 0 or 1. 1 indicates that the payload contains 1 more
* item than the value of the size field . mostly used for a
* terminating null in a variable - char object .
* kernel : 0 or 1. indicates that the object is a kernel object .
* VM disallows layout changes of a kernel object .
* moved : 0 or 1. used by GC .
*
* _size : the number of payload items in an object .
2015-05-07 15:58:04 +00:00
* it doesn ' t include the header size .
2015-04-30 15:56:05 +00:00
*
* The total number of bytes occupied by an object can be calculated
* with this fomula :
* sizeof ( stix_obj_t ) + ALIGN ( ( size + extra ) * unit ) , sizeof ( stix_oop_t ) )
*
* The ALIGN ( ) macro is used above since allocation adjusts the payload
* size to a multiple of sizeof ( stix_oop_t ) . it assumes that sizeof ( stix_obj_t )
* is a multiple of sizeof ( stix_oop_t ) . See the STIX_BYTESOF ( ) macro .
*
* Due to the header structure , an object can only contain items of
* homogeneous data types in the payload .
*
* It ' s actually possible to split the size field into 2. For example ,
* the upper half contains the number of oops and the lower half contains
* the number of bytes / chars . This way , a variable - byte class or a variable - char
* class can have normal instance variables . On the contrary , the actual byte
* size calculation and the access to the payload fields become more complex .
* Therefore , i ' ve dropped the idea .
2015-05-16 07:31:16 +00:00
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
2015-05-03 17:10:30 +00:00
# define STIX_OBJ_FLAGS_TYPE_BITS 6
2015-05-04 16:48:38 +00:00
# define STIX_OBJ_FLAGS_UNIT_BITS 5
2015-05-03 17:10:30 +00:00
# define STIX_OBJ_FLAGS_EXTRA_BITS 1
2015-05-25 17:10:49 +00:00
# define STIX_OBJ_FLAGS_KERNEL_BITS 2
2015-05-03 17:10:30 +00:00
# define STIX_OBJ_FLAGS_MOVED_BITS 1
# define STIX_OBJ_GET_FLAGS_TYPE(oop) STIX_GETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_UNIT_BITS + STIX_OBJ_FLAGS_EXTRA_BITS + STIX_OBJ_FLAGS_KERNEL_BITS + STIX_OBJ_FLAGS_MOVED_BITS), STIX_OBJ_FLAGS_TYPE_BITS)
# define STIX_OBJ_GET_FLAGS_UNIT(oop) STIX_GETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_EXTRA_BITS + STIX_OBJ_FLAGS_KERNEL_BITS + STIX_OBJ_FLAGS_MOVED_BITS), STIX_OBJ_FLAGS_UNIT_BITS)
# define STIX_OBJ_GET_FLAGS_EXTRA(oop) STIX_GETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_KERNEL_BITS + STIX_OBJ_FLAGS_MOVED_BITS), STIX_OBJ_FLAGS_EXTRA_BITS)
2015-05-07 15:58:04 +00:00
# define STIX_OBJ_GET_FLAGS_KERNEL(oop) STIX_GETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_MOVED_BITS), STIX_OBJ_FLAGS_KERNEL_BITS)
2015-05-03 17:10:30 +00:00
# define STIX_OBJ_GET_FLAGS_MOVED(oop) STIX_GETBITS(stix_oow_t, (oop)->_flags, 0, STIX_OBJ_FLAGS_MOVED_BITS)
# define STIX_OBJ_SET_FLAGS_TYPE(oop,v) STIX_SETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_UNIT_BITS + STIX_OBJ_FLAGS_EXTRA_BITS + STIX_OBJ_FLAGS_KERNEL_BITS + STIX_OBJ_FLAGS_MOVED_BITS), STIX_OBJ_FLAGS_TYPE_BITS, v)
# define STIX_OBJ_SET_FLAGS_UNIT(oop,v) STIX_SETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_EXTRA_BITS + STIX_OBJ_FLAGS_KERNEL_BITS + STIX_OBJ_FLAGS_MOVED_BITS), STIX_OBJ_FLAGS_UNIT_BITS, v)
# define STIX_OBJ_SET_FLAGS_EXTRA(oop,v) STIX_SETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_KERNEL_BITS + STIX_OBJ_FLAGS_MOVED_BITS), STIX_OBJ_FLAGS_EXTRA_BITS, v)
2015-05-07 15:58:04 +00:00
# define STIX_OBJ_SET_FLAGS_KERNEL(oop,v) STIX_SETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_MOVED_BITS), STIX_OBJ_FLAGS_KERNEL_BITS, v)
2015-05-03 17:10:30 +00:00
# define STIX_OBJ_SET_FLAGS_MOVED(oop,v) STIX_SETBITS(stix_oow_t, (oop)->_flags, 0, STIX_OBJ_FLAGS_MOVED_BITS, v)
2015-05-07 15:58:04 +00:00
# define STIX_OBJ_GET_SIZE(oop) ((oop)->_size)
# define STIX_OBJ_GET_CLASS(oop) ((oop)->_class)
2015-05-08 14:29:35 +00:00
# define STIX_OBJ_SET_SIZE(oop,v) ((oop)->_size = (v))
2015-05-07 15:58:04 +00:00
# define STIX_OBJ_SET_CLASS(oop,c) ((oop)->_class = (c))
2015-05-08 14:29:35 +00:00
# define STIX_OBJ_BYTESOF(oop) ((STIX_OBJ_GET_SIZE(oop) + STIX_OBJ_GET_FLAGS_EXTRA(oop)) * STIX_OBJ_GET_FLAGS_UNIT(oop))
2015-05-03 17:10:30 +00:00
/* this macro doesn't check the range of the actual value.
* make sure that the value of each bit fields given fall within the number
* of defined bits */
# define STIX_OBJ_MAKE_FLAGS(t,u,e,k,m) ( \
( ( ( stix_oow_t ) ( t ) ) < < ( STIX_OBJ_FLAGS_UNIT_BITS + STIX_OBJ_FLAGS_EXTRA_BITS + STIX_OBJ_FLAGS_KERNEL_BITS + STIX_OBJ_FLAGS_MOVED_BITS ) ) | \
( ( ( stix_oow_t ) ( u ) ) < < ( STIX_OBJ_FLAGS_EXTRA_BITS + STIX_OBJ_FLAGS_KERNEL_BITS + STIX_OBJ_FLAGS_MOVED_BITS ) ) | \
( ( ( stix_oow_t ) ( e ) ) < < ( STIX_OBJ_FLAGS_KERNEL_BITS + STIX_OBJ_FLAGS_MOVED_BITS ) ) | \
( ( ( stix_oow_t ) ( k ) ) < < ( STIX_OBJ_FLAGS_MOVED_BITS ) ) | \
( ( ( stix_oow_t ) ( m ) ) < < 0 ) \
)
2015-04-30 15:56:05 +00:00
# define STIX_OBJ_HEADER \
2015-05-03 17:10:30 +00:00
stix_oow_t _flags ; \
stix_oow_t _size ; \
2015-04-30 15:56:05 +00:00
stix_oop_t _class
struct stix_obj_t
{
STIX_OBJ_HEADER ;
} ;
struct stix_obj_oop_t
{
STIX_OBJ_HEADER ;
stix_oop_t slot [ 1 ] ;
} ;
struct stix_obj_char_t
{
STIX_OBJ_HEADER ;
2015-05-17 05:02:30 +00:00
stix_uch_t slot [ 1 ] ;
2015-04-30 15:56:05 +00:00
} ;
2015-05-31 16:44:56 +00:00
struct stix_obj_byte_t
2015-04-30 15:56:05 +00:00
{
STIX_OBJ_HEADER ;
2015-05-31 16:44:56 +00:00
stix_byte_t slot [ 1 ] ;
2015-04-30 15:56:05 +00:00
} ;
2015-05-31 16:44:56 +00:00
struct stix_obj_word_t
2015-04-30 15:56:05 +00:00
{
STIX_OBJ_HEADER ;
2015-05-31 16:44:56 +00:00
stix_oow_t slot [ 1 ] ;
2015-04-30 15:56:05 +00:00
} ;
2015-05-31 16:44:56 +00:00
# define STIX_SET_NAMED_INSTVARS 2
2015-06-04 18:34:37 +00:00
typedef struct stix_set_t stix_set_t ;
typedef struct stix_set_t * stix_oop_set_t ;
2015-05-31 16:44:56 +00:00
struct stix_set_t
{
STIX_OBJ_HEADER ;
stix_oop_t tally ; /* SmallInteger */
stix_oop_oop_t bucket ; /* Array */
} ;
2015-05-26 16:31:47 +00:00
# define STIX_CLASS_NAMED_INSTVARS 10
2015-06-04 18:34:37 +00:00
typedef struct stix_class_t stix_class_t ;
typedef struct stix_class_t * stix_oop_class_t ;
2015-05-07 15:58:04 +00:00
struct stix_class_t
{
STIX_OBJ_HEADER ;
2015-05-26 16:31:47 +00:00
stix_oop_t spec ; /* SmallInteger. instance specification */
stix_oop_t selfspec ; /* SmallInteger. specification of the class object itself */
2015-05-07 15:58:04 +00:00
2015-05-25 18:13:52 +00:00
stix_oop_t superclass ; /* Another class */
stix_oop_t subclasses ; /* Array of subclasses */
stix_oop_char_t name ; /* Symbol */
2015-05-27 17:16:50 +00:00
/* == NEVER CHANGE THIS ORDER OF 3 ITEMS BELOW == */
2015-05-25 18:13:52 +00:00
stix_oop_char_t instvars ; /* String */
stix_oop_char_t classvars ; /* String */
stix_oop_char_t classinstvars ; /* String */
2015-05-27 17:16:50 +00:00
/* == NEVER CHANGE THE ORDER OF 3 ITEMS ABOVE == */
2015-05-25 18:13:52 +00:00
2015-06-06 07:24:35 +00:00
/* [0] - instance methods, MethodDictionary
* [ 1 ] - class methods , MethodDictionary */
stix_oop_set_t mthdic [ 2 ] ;
2015-05-07 15:58:04 +00:00
/* indexed part afterwards */
2015-06-03 17:27:22 +00:00
stix_oop_t slot [ 1 ] ; /* class instance variables and class variables. */
2015-05-07 15:58:04 +00:00
} ;
2015-06-06 07:24:35 +00:00
# define STIX_CLASS_MTHDIC_INSTANCE 0
# define STIX_CLASS_MTHDIC_CLASS 1
2015-05-07 15:58:04 +00:00
# define STIX_ASSOCIATION_NAMED_INSTVARS 2
2015-06-04 18:34:37 +00:00
typedef struct stix_association_t stix_association_t ;
typedef struct stix_association_t * stix_oop_association_t ;
2015-05-07 15:58:04 +00:00
struct stix_association_t
{
STIX_OBJ_HEADER ;
stix_oop_t key ;
stix_oop_t value ;
} ;
2015-05-31 16:44:56 +00:00
# define STIX_METHOD_NAMED_INSTVARS 5
2015-06-04 18:34:37 +00:00
typedef struct stix_method_t stix_method_t ;
typedef struct stix_method_t * stix_oop_method_t ;
2015-05-31 16:44:56 +00:00
struct stix_method_t
{
STIX_OBJ_HEADER ;
stix_oop_class_t owner ; /* Class */
/* number of temporaries including arguments */
stix_oop_t tmpr_count ; /* SmallInteger */
/* number of arguments in temporaries */
stix_oop_t tmpr_nargs ; /* SmallInteger */
2015-05-15 14:55:12 +00:00
2015-06-06 07:24:35 +00:00
stix_oop_byte_t code ; /* ByteArray */
2015-05-31 16:44:56 +00:00
stix_oop_t source ; /* TODO: what should I put? */
/* variable indexed part */
2015-06-04 18:34:37 +00:00
stix_oop_t slot [ 1 ] ; /* it stores literals */
2015-05-31 16:44:56 +00:00
} ;
2015-06-04 18:34:37 +00:00
# define STIX_CONTEXT_NAMED_INSTVARS 6
typedef struct stix_context_t stix_context_t ;
typedef struct stix_context_t * stix_oop_context_t ;
struct stix_context_t
{
STIX_OBJ_HEADER ;
stix_oop_t sender ;
stix_oop_t ip ; /* instruction pointer */
stix_oop_t sp ; /* stack pointer */
stix_oop_method_t method ; /* CompiledMethod */
stix_oop_t unused ;
stix_oop_t receiver ;
/* variable indexed part */
stix_oop_t slot [ 1 ] ; /* stack contents */
} ;
# define STIX_BLOCK_CONTEXT_NAMED_INSTVARS 6
typedef struct stix_block_context_t stix_block_context_t ;
typedef struct stix_block_context_t * stix_oop_block_context_t ;
struct stix_block_context_t
{
STIX_OBJ_HEADER ;
stix_oop_t caller ;
stix_oop_t ip ; /* SmallInteger. instruction pointer */
stix_oop_t sp ; /* SmallInteger. stack pointer */
stix_oop_t nargs ; /* SmallInteger */
stix_oop_t iip ; /* SmallInteger. initial instruction pointer */
stix_oop_context_t home ;
/* variable indexed part */
stix_oop_t slot [ 1 ] ; /* stack */
} ;
#if 0
# define STIX_PROCESS_NAMED_INSTVARS 4
typedef struct stix_process_t stix_process_t ;
typedef struct stix_process_t * stix_oop_process_t ;
struct stix_process_t
{
STIX_OBJ_HEADER ;
stix_oop_context_t context ;
stix_oop_t state ; /* SmallInteger */
stix_oop_process_t prev ;
stix_oop_process_t next ;
} ;
# endif
2015-04-30 15:56:05 +00:00
2015-05-08 14:29:35 +00:00
/**
* The STIX_CLASSOF ( ) macro return the class of an object including a numeric
* object encoded into a pointer .
*/
2015-05-07 15:58:04 +00:00
# define STIX_CLASSOF(stix,oop) ( \
STIX_OOP_IS_SMINT ( oop ) ? ( stix ) - > _small_integer : \
2015-05-08 14:29:35 +00:00
STIX_OOP_IS_CHAR ( oop ) ? ( stix ) - > _character : STIX_OBJ_GET_CLASS ( oop ) \
2015-05-07 15:58:04 +00:00
)
2015-05-08 14:29:35 +00:00
/**
* The STIX_BYTESOF ( ) macro returns the size of the payload of
* an object in bytes . If the pointer given encodes a numeric value ,
* it returns the size of # stix_oow_t in bytes .
*/
2015-05-07 15:58:04 +00:00
# define STIX_BYTESOF(stix,oop) \
2015-05-08 14:29:35 +00:00
( STIX_OOP_IS_NUMERIC ( oop ) ? STIX_SIZEOF ( stix_oow_t ) : STIX_OBJ_BYTESOF ( oop ) )
2015-04-30 15:56:05 +00:00
2015-05-07 15:58:04 +00:00
typedef struct stix_heap_t stix_heap_t ;
2015-04-30 15:56:05 +00:00
2015-05-07 15:58:04 +00:00
struct stix_heap_t
2015-04-30 15:56:05 +00:00
{
2015-05-07 15:58:04 +00:00
stix_uint8_t * base ; /* start of a heap */
stix_uint8_t * limit ; /* end of a heap */
stix_uint8_t * ptr ; /* next allocation pointer */
} ;
2015-04-30 15:56:05 +00:00
2015-05-19 15:16:18 +00:00
typedef struct stix_t stix_t ;
typedef void ( * stix_cbimpl_t ) ( stix_t * stix ) ;
typedef struct stix_cb_t stix_cb_t ;
struct stix_cb_t
{
2015-05-25 17:10:49 +00:00
stix_cbimpl_t gc ;
2015-05-19 15:16:18 +00:00
stix_cbimpl_t fini ;
2015-05-31 16:44:56 +00:00
/* private below */
2015-05-19 15:16:18 +00:00
stix_cb_t * prev ;
stix_cb_t * next ;
} ;
2015-05-15 14:55:12 +00:00
# if defined(STIX_INCLUDE_COMPILER)
typedef struct stix_compiler_t stix_compiler_t ;
# endif
2015-05-07 15:58:04 +00:00
struct stix_t
{
stix_mmgr_t * mmgr ;
stix_errnum_t errnum ;
2015-04-30 15:56:05 +00:00
2015-05-07 15:58:04 +00:00
struct
{
int trait ;
2015-05-08 14:29:35 +00:00
stix_oow_t dfl_symtab_size ;
stix_oow_t dfl_sysdic_size ;
2015-05-07 15:58:04 +00:00
} option ;
2015-04-30 15:56:05 +00:00
2015-05-19 15:16:18 +00:00
stix_cb_t * cblist ;
2015-05-07 15:58:04 +00:00
/* ========================= */
2015-04-30 15:56:05 +00:00
2015-05-07 15:58:04 +00:00
stix_heap_t * permheap ; /* TODO: put kernel objects to here */
stix_heap_t * curheap ;
stix_heap_t * newheap ;
/* ========================= */
stix_oop_t _nil ; /* pointer to the nil object */
stix_oop_t _true ;
stix_oop_t _false ;
2015-05-11 16:08:09 +00:00
/* == NEVER CHANGE THE ORDER OF FIELDS BELOW == */
2015-05-31 18:43:37 +00:00
/* stix_ignite() assumes this order. make sure to update symnames in ignite_3() */
2015-05-07 15:58:04 +00:00
stix_oop_t _stix ; /* Stix */
stix_oop_t _nil_object ; /* NilObject */
stix_oop_t _class ; /* Class */
stix_oop_t _object ; /* Object */
2015-05-26 16:31:47 +00:00
stix_oop_t _string ; /* String */
2015-05-07 15:58:04 +00:00
stix_oop_t _symbol ; /* Symbol */
stix_oop_t _array ; /* Array */
2015-05-31 16:44:56 +00:00
stix_oop_t _byte_array ; /* ByteArray */
2015-05-07 15:58:04 +00:00
stix_oop_t _symbol_set ; /* SymbolSet */
stix_oop_t _system_dictionary ; /* SystemDictionary */
2015-05-28 16:51:37 +00:00
stix_oop_t _method_dictionary ; /* MethodDictionary */
2015-05-31 16:44:56 +00:00
stix_oop_t _method ; /* CompiledMethod */
2015-05-07 15:58:04 +00:00
stix_oop_t _association ; /* Association */
2015-06-04 18:34:37 +00:00
stix_oop_t _context ; /* MethodContext */
stix_oop_t _block_context ; /* BlockContext */
/*stix_oop_t _process; */ /* Process */
2015-05-11 16:08:09 +00:00
stix_oop_t _true_class ; /* True */
stix_oop_t _false_class ; /* False */
2015-05-07 15:58:04 +00:00
stix_oop_t _character ; /* Character */
stix_oop_t _small_integer ; /* SmallInteger */
2015-05-11 16:08:09 +00:00
/* == NEVER CHANGE THE ORDER OF FIELDS ABOVE == */
2015-05-07 15:58:04 +00:00
stix_oop_set_t symtab ; /* system-wide symbol table. instance of SymbolSet */
stix_oop_set_t sysdic ; /* system dictionary. instance of SystemDictionary */
2015-05-28 16:51:37 +00:00
stix_oop_t * tmp_stack [ 256 ] ; /* stack for temporaries */
2015-05-07 15:58:04 +00:00
stix_oow_t tmp_count ;
2015-05-15 14:55:12 +00:00
2015-06-04 18:34:37 +00:00
/* == EXECUTION REGISTERS == */
stix_oop_context_t active_context ; /* TODO: this could be either MethodContext or BlockContext. Some redefintion of stix_oop_context_t might be needed after having removed stix-oop_block-context. */
stix_oop_context_t home_context ;
stix_oop_t method ;
stix_oop_t receiver ;
stix_oop_t ip ; /* SmallInteger */
stix_oop_t sp ; /* SmallInteger */
/* == END EXECUTION REGISTERS == */
2015-05-15 14:55:12 +00:00
# if defined(STIX_INCLUDE_COMPILER)
stix_compiler_t * c ;
# endif
2015-04-30 15:56:05 +00:00
} ;
2015-05-07 15:58:04 +00:00
2015-04-30 15:56:05 +00:00
# if defined(__cplusplus)
extern " C " {
# endif
STIX_EXPORT stix_t * stix_open (
stix_mmgr_t * mmgr ,
stix_size_t xtnsize ,
stix_size_t heapsize ,
stix_errnum_t * errnum
) ;
STIX_EXPORT void stix_close (
stix_t * vm
) ;
STIX_EXPORT int stix_init (
stix_t * vm ,
stix_mmgr_t * mmgr ,
stix_size_t heapsz
) ;
STIX_EXPORT void stix_fini (
stix_t * vm
) ;
2015-05-15 14:55:12 +00:00
STIX_EXPORT stix_mmgr_t * stix_getmmgr (
stix_t * stix
) ;
STIX_EXPORT void * stix_getxtn (
stix_t * stix
) ;
STIX_EXPORT stix_errnum_t stix_geterrnum (
stix_t * stix
) ;
STIX_EXPORT void stix_seterrnum (
stix_t * stix ,
stix_errnum_t errnum
) ;
2015-04-30 15:56:05 +00:00
/**
* The stix_getoption ( ) function gets the value of an option
* specified by \ a id into the buffer pointed to by \ a value .
*
* \ return 0 on success , - 1 on failure
*/
STIX_EXPORT int stix_getoption (
2015-05-19 15:16:18 +00:00
stix_t * stix ,
2015-04-30 15:56:05 +00:00
stix_option_t id ,
void * value
) ;
/**
* The stix_setoption ( ) function sets the value of an option
* specified by \ a id to the value pointed to by \ a value .
*
* \ return 0 on success , - 1 on failure
*/
STIX_EXPORT int stix_setoption (
2015-05-19 15:16:18 +00:00
stix_t * stix ,
2015-04-30 15:56:05 +00:00
stix_option_t id ,
const void * value
) ;
2015-05-19 15:16:18 +00:00
STIX_EXPORT stix_cb_t * stix_regcb (
stix_t * stix ,
stix_cb_t * tmpl
) ;
STIX_EXPORT void stix_deregcb (
stix_t * stix ,
stix_cb_t * cb
) ;
2015-04-30 15:56:05 +00:00
/**
* The stix_gc ( ) function performs garbage collection .
* It is not affected by # STIX_NOGC .
*/
STIX_EXPORT void stix_gc (
2015-05-19 15:16:18 +00:00
stix_t * stix
2015-04-30 15:56:05 +00:00
) ;
/**
* The stix_instantiate ( ) function creates a new object of the class
* \ a _class . The size of the fixed part is taken from the information
* contained in the class defintion . The \ a vlen parameter specifies
* the length of the variable part . The \ a vptr parameter points to
* the memory area to copy into the variable part of the new object .
* If \ a vptr is # STIX_NULL , the variable part is initialized to 0 or
* an equivalent value depending on the type .
*/
STIX_EXPORT stix_oop_t stix_instantiate (
stix_t * stix ,
stix_oop_t _class ,
const void * vptr ,
stix_oow_t vlen
) ;
2015-05-03 17:10:30 +00:00
/**
* The stix_ignite ( ) function creates key initial objects .
*/
STIX_EXPORT int stix_ignite (
stix_t * stix
) ;
2015-05-07 15:58:04 +00:00
2015-06-04 18:34:37 +00:00
/**
2015-06-06 07:24:35 +00:00
* The stix_executes ( ) function XXXXXXXXXXXXXX
2015-06-04 18:34:37 +00:00
*/
STIX_EXPORT int stix_execute (
stix_t * stix
) ;
2015-06-06 07:24:35 +00:00
/**
* The stix_invoke ( ) function sends a message named \ a mthname to an object
* named \ a objname .
*/
STIX_EXPORT int stix_invoke (
stix_t * stix ,
const stix_ucs_t * objname ,
const stix_ucs_t * mthname
) ;
2015-05-15 14:55:12 +00:00
/* Temporary OOP management */
2015-05-07 15:58:04 +00:00
STIX_EXPORT void stix_pushtmp (
stix_t * stix ,
stix_oop_t * oop_ptr
) ;
STIX_EXPORT void stix_poptmp (
stix_t * stix
) ;
STIX_EXPORT void stix_poptmps (
stix_t * stix ,
stix_oow_t count
) ;
2015-05-15 14:55:12 +00:00
/* Memory allocation/deallocation functions using stix's MMGR */
STIX_EXPORT void * stix_allocmem (
2015-05-19 15:16:18 +00:00
stix_t * stix ,
2015-05-15 14:55:12 +00:00
stix_size_t size
) ;
STIX_EXPORT void * stix_callocmem (
2015-05-19 15:16:18 +00:00
stix_t * stix ,
stix_size_t size
) ;
STIX_EXPORT void * stix_reallocmem (
stix_t * stix ,
void * ptr ,
2015-05-15 14:55:12 +00:00
stix_size_t size
) ;
STIX_EXPORT void stix_freemem (
stix_t * stix ,
void * ptr
) ;
2015-04-30 15:56:05 +00:00
# if defined(__cplusplus)
}
# endif
# endif