X-Git-Url: http://nitlanguage.org diff --git a/clib/nit_common.h b/clib/nit_common.h index 2d4f9df..1652ea9 100644 --- a/clib/nit_common.h +++ b/clib/nit_common.h @@ -18,21 +18,14 @@ #include #include -#ifdef WITH_LIBGC -#include -#define malloc(x) GC_MALLOC((x)) -#define calloc(x,y) GC_MALLOC((x)*(y)) -#endif - - - /* *** Types *** */ typedef signed long int bigint; /* standard int value, must be larger that any poiner */ typedef bigint (*fun_t) (bigint); /* generic function pointer */ typedef bigint cid_t; /* class identifier */ +typedef char* cname_t; /* class name */ typedef bigint val_t; /* value (everything is a val_t) */ typedef union obj_tu {union classtable_elt_tu * vft; bigint object_id; val_t objectSize;} *obj_t; /* standard object */ -typedef union classtable_elt_tu { bigint i; fun_t f; cid_t cid;} classtable_elt_t; /* classtable element */ +typedef union classtable_elt_tu { bigint i; fun_t f; cid_t cid; cname_t cname;} classtable_elt_t; /* classtable element */ typedef struct Nit_NativeArray {const classtable_elt_t * vft; bigint object_id; bigint size; val_t val[1];} * Nit_NativeArray; typedef classtable_elt_t * classtable_t; /* classtable */ @@ -116,7 +109,11 @@ extern bigint object_id_counter; #define VAL_ISA(e, c, i) (VAL2VFT((e))[(c)].cid == (cid_t)(i)) -void * alloc(size_t); +/* GC and memory management */ +void *alloc(size_t); /* allocate memory to store an object with an object header */ +void *raw_alloc(size_t); /* allocate raw memory to store a raw stram of byte */ +void register_static_object(val_t*); /* mark that something is a global or once object */ + extern val_t G_args; extern val_t G_stdin; extern val_t G_stdout; @@ -126,18 +123,78 @@ extern val_t G_sys; extern int glob_argc; extern char ** glob_argv; -struct trace_t { - struct trace_t *prev; /* previous stack frame */ - const char *file; /* source filename */ - int line; /* line number */ - const char *meth; /* method name */ - int REG_size; - val_t **REG_pointer; +/* Native reference to Nit objects */ +/* This structure is used to represent every Nit type in extern methods and custom C code. */ +struct nitni_ref { + val_t val; /* reference to the real Nit object, is kept up-to-date by GC */ + struct nitni_ref *next, *prev; /* adjacent global references in global list */ + int count; /* number of time this global reference has been marked */ +}; + +/* This structure is used by extern methods to keep track of local references to Nit objects */ +/* These references make sure an object is not collected by the GC while + * this extern methods is on the call stack. */ +/* This takes the form of an array link, each link of size 8 to avoid multiple mallocs. */ +#define NITNI_REF_ARRAY_LINK_SIZE 8 +struct nitni_ref_array_link { + struct nitni_ref *reg[ NITNI_REF_ARRAY_LINK_SIZE ]; + int count; /* nubmer of elements in this link */ + struct nitni_ref_array_link *next; /* next link in the list */ +}; + +/* Register reference to Nit object with the latest extern method called. */ +extern void nitni_local_ref_add( struct nitni_ref *ref ); + +/* Clean all references associated to the current (but returning) extern method. */ +extern void nitni_local_ref_clean( void ); + +/* List of global references from C code to Nit objects */ +/* Instanciated empty at init of Nit system and filled explicitly by user in C code */ +struct nitni_global_ref_list_t { + struct nitni_ref *head, *tail; }; -extern struct trace_t *tracehead; +extern struct nitni_global_ref_list_t *nitni_global_ref_list; + +/* Initializer of global reference list */ +extern void nitni_global_ref_list_init(); + +/* Intern function to add a global reference to the list */ +extern void nitni_global_ref_add( struct nitni_ref *ref ); + +/* Intern function to remove a global reference from the list */ +extern void nitni_global_ref_remove( struct nitni_ref *ref ); + +/* Increase count on an existing global reference */ +extern void nitni_global_ref_incr( struct nitni_ref *ref ); + +/* Decrease count on an existing global reference */ +extern void nitni_global_ref_decr( struct nitni_ref *ref ); + +/* Stack frames. + * Are used to: + * - store local variables (REGS) of functions + * - store context for closure + * - provide information for stack dump + */ +struct stack_frame_t { + struct stack_frame_t *prev; /* previous stack frame */ + const char *file; /* source filename (.nit) */ + int line; /* line number (in the source) */ + const char *meth; /* human function name (usually the method name) */ + struct stack_frame_t *closure_ctx; /* closure context (for functions that have closure parameters) */ + fun_t *closure_funs; /* closure functions (for functions that have closure parameters) */ + int has_broke; /* has an escape occured? 0 if false, label_idx (>0) if true */ + struct nitni_ref_array_link *nitni_local_ref_head; /* points to head of array link contaning local variables used via nitni */ + int REG_size; /* number of local variables */ + val_t REG[1]; /* local variables (flexible array, this must be the last variable is extended in fra struct */ +}; +extern struct stack_frame_t *stack_frame_head; + + typedef enum {true = (1==1),false = (0==1)} bool; void nit_exit(int); +void nit_abort(const char*, const char*, const char*, int); #define CALL(r,c) ((VAL2VFT(r)[c].f)) #define ATTR(r,c) (*(val_t*)(VAL2OBJ(r)+c)) @@ -145,9 +202,5 @@ void nit_exit(int); void prepare_signals(void); extern classtable_t TAG2VFT[4]; - -/* This structure is used to store closure. - * Specific closure use a specific fun parameter. - */ -struct WBT_ {fun_t fun; val_t *has_broke; val_t broke_value; val_t *variable; struct WBT_ **closurevariable;}; +val_t NEW_NativeArray(size_t length, size_t size); #endif