Merge: doc: fixed some typos and other misc. corrections
[nit.git] / clib / nit_common.h
1 #ifndef NIT_COMMON_H
2 #define NIT_COMMON_H
3
4 /* This file is part of NIT ( http://www.nitlanguage.org ).
5 *
6 * Copyright 2006-2009 Jean Privat <jean@pryen.org>
7 *
8 * This file is free software, which comes along with NIT. This software is
9 * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
10 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
11 * PARTICULAR PURPOSE. You can modify it is you want, provided this header
12 * is kept unaltered, and a notification of the changes is added.
13 * You are allowed to redistribute it and sell it, alone or is a part of
14 * another product.
15 */
16
17 #include <stdlib.h>
18 #include <stdio.h>
19 #include <string.h>
20
21 /* *** Types *** */
22 typedef signed long int bigint; /* standard int value, must be larger that any poiner */
23 typedef bigint (*fun_t) (bigint); /* generic function pointer */
24 typedef bigint cid_t; /* class identifier */
25 typedef char* cname_t; /* class name */
26 typedef bigint val_t; /* value (everything is a val_t) */
27 typedef union obj_tu {union classtable_elt_tu * vft; bigint object_id; val_t objectSize;} *obj_t; /* standard object */
28 typedef union classtable_elt_tu { bigint i; fun_t f; cid_t cid; cname_t cname;} classtable_elt_t; /* classtable element */
29 typedef struct Nit_NativeArray {const classtable_elt_t * vft; bigint object_id; bigint size; val_t val[1];} * Nit_NativeArray;
30
31 typedef classtable_elt_t * classtable_t; /* classtable */
32
33 extern bigint object_id_counter;
34
35 /*****************************************************************************
36 * Types macros (primitive and less primitives) ******************************
37 *****************************************************************************
38 *
39 * ** types are: **
40 *
41 * OBJ (obj_t) : standard object representation (including boxes + NIL)
42 * Int (int) : integers
43 * Char (car) : characters
44 * Bool (int) : booleans (true or false)
45 *
46 * X (x_t) : generic representatio of the previous four types
47 *
48 * ** macros are: **
49 *
50 * int ISX(val_t v) : true if v is a X
51 * x_t VAL2X(val_t v) : convert a val_t to a primitive type (you should check ISX before)
52 * val_t X2VAL(x_t x) : convert a type to a val_t
53 * int XTAG : numeric identifier of a type
54 * int TAG(val_t v) : return the XTAG (ie TAG(Char2VAL('e')) == CharTag)
55 *
56 * classtable_t VAL2VFT(val_t v): the virtual function table of a value
57 *
58 * val_t NIT_NULL : the instance of the None class
59 *****************************************************************************/
60
61 #define TAG(x) ((int)(x) & 3)
62 #ifndef IntTAG
63 # define IntTAG 1
64 #endif
65 #define TAG_Int(x) ((val_t)(((x)<<2)|IntTAG))
66 #define UNTAG_Int(x) ((bigint)(x)>>2)
67 #ifndef CharTAG
68 # define CharTAG 2
69 #endif
70 #define TAG_Char(x) ((val_t)((((int)(x))<<2)|CharTAG))
71 #define UNTAG_Char(x) ((char)((int)(x)>>2))
72 #ifndef BoolTAG
73 # define BoolTAG 3
74 #endif
75 #define TAG_Bool(x) ((val_t)(((x)<<2)|BoolTAG))
76 #define UNTAG_Bool(x) ((int)(x)>>2)
77 #ifndef OBJTAG
78 # define OBJTAG 0
79 #endif
80
81 #define ISOBJ(x) (TAG((x)) == OBJTAG)
82 #define VAL2OBJ(x) ((obj_t)(x))
83 #define VAL2ARRAY(x) ((Nit_NativeArray)(x))
84 #define OBJ2VAL(o) ((val_t)(o))
85 #define VAL2VFT(x) (ISOBJ(x) ? VAL2OBJ(x)->vft : TAG2VFT[TAG(x)])
86 /*#define VAL2CID(x) (ISOBJ(x) ? (VAL2OBJ(x)->vft->cid) : (-TAG(x)))*/
87 #define VAL2CID(x) (VAL2OBJ(x)->vft->cid)
88
89 #define NIT_NULL ((val_t)0)
90 #define ISNULL(x) ((x)==NIT_NULL)
91
92 /* Equal comparaison */
93 /* O = Non nil object ; N = Object or nil ; P = Primitive */
94 #define OBJ_IS_BOX(x) ((VAL2OBJ(x)->vft->i) < 0)
95 #define OBJ_IS_ARRAY(x) ((VAL2ARRAY(x)->vft[1].i) == -1)
96 #define IS_BOX(x) (ISOBJ(x) && OBJ_IS_BOX(x))
97 #define IS_EQUAL_BOX(x, y) (ISOBJ(y) && (VAL2OBJ(x)[2].vft==VAL2OBJ(y)[2].vft) && (VAL2OBJ(x)->vft==VAL2OBJ(y)->vft))
98 #define IS_EQUAL_OO(x, y) ((x)==(y) || (IS_BOX(x) && IS_EQUAL_BOX((x), (y))))
99 #define IS_EQUAL_ON(x, y) ((x)==(y) || (IS_BOX(x) && !ISNULL(y) && IS_EQUAL_BOX((x), (y))))
100 #define IS_EQUAL_NN(x, y) ((x)==(y) || (!ISNULL(x) && IS_BOX(x) && !ISNULL(y) && IS_EQUAL_BOX((x), (y))))
101
102 /* Subclass comparaison */
103 /* check is e is a subtype of c2 */
104 /* Warning, only subclasse comparaison is performed, not subtype */
105 /* e is a val (not nil) */
106 /* c a class name (eg: Int) */
107 #define VALISA(e, c) (VAL2VFT(e)[COLOR_ ## c].cid == (cid_t) ID_ ## c)
108 #define OBJISA(e, c) (VAL2OBJ(e)->vft[COLOR_ ## c].cid == (cid_t) ID_ ## c)
109
110 #define VAL_ISA(e, c, i) (VAL2VFT((e))[(c)].cid == (cid_t)(i))
111
112 /* GC and memory management */
113 void *alloc(size_t); /* allocate memory to store an object with an object header */
114 void *raw_alloc(size_t); /* allocate raw memory to store a raw stram of byte */
115 void register_static_object(val_t*); /* mark that something is a global or once object */
116
117 extern val_t G_args;
118 extern val_t G_stdin;
119 extern val_t G_stdout;
120 extern val_t G_stderr;
121 extern val_t G_sys;
122
123 extern int glob_argc;
124 extern char ** glob_argv;
125
126 /* Native reference to Nit objects */
127 /* This structure is used to represent every Nit type in extern methods and custom C code. */
128 struct nitni_ref {
129 val_t val; /* reference to the real Nit object, is kept up-to-date by GC */
130 struct nitni_ref *next, *prev; /* adjacent global references in global list */
131 int count; /* number of time this global reference has been marked */
132 };
133
134 /* This structure is used by extern methods to keep track of local references to Nit objects */
135 /* These references make sure an object is not collected by the GC while
136 * this extern methods is on the call stack. */
137 /* This takes the form of an array link, each link of size 8 to avoid multiple mallocs. */
138 #define NITNI_REF_ARRAY_LINK_SIZE 8
139 struct nitni_ref_array_link {
140 struct nitni_ref *reg[ NITNI_REF_ARRAY_LINK_SIZE ];
141 int count; /* nubmer of elements in this link */
142 struct nitni_ref_array_link *next; /* next link in the list */
143 };
144
145 /* Register reference to Nit object with the latest extern method called. */
146 extern void nitni_local_ref_add( struct nitni_ref *ref );
147
148 /* Clean all references associated to the current (but returning) extern method. */
149 extern void nitni_local_ref_clean( void );
150
151 /* List of global references from C code to Nit objects */
152 /* Instanciated empty at init of Nit system and filled explicitly by user in C code */
153 struct nitni_global_ref_list_t {
154 struct nitni_ref *head, *tail;
155 };
156 extern struct nitni_global_ref_list_t *nitni_global_ref_list;
157
158 /* Initializer of global reference list */
159 extern void nitni_global_ref_list_init();
160
161 /* Intern function to add a global reference to the list */
162 extern void nitni_global_ref_add( struct nitni_ref *ref );
163
164 /* Intern function to remove a global reference from the list */
165 extern void nitni_global_ref_remove( struct nitni_ref *ref );
166
167 /* Increase count on an existing global reference */
168 extern void nitni_global_ref_incr( struct nitni_ref *ref );
169
170 /* Decrease count on an existing global reference */
171 extern void nitni_global_ref_decr( struct nitni_ref *ref );
172
173 /* Stack frames.
174 * Are used to:
175 * - store local variables (REGS) of functions
176 * - store context for closure
177 * - provide information for stack dump
178 */
179 struct stack_frame_t {
180 struct stack_frame_t *prev; /* previous stack frame */
181 const char *file; /* source filename (.nit) */
182 int line; /* line number (in the source) */
183 const char *meth; /* human function name (usually the method name) */
184 struct stack_frame_t *closure_ctx; /* closure context (for functions that have closure parameters) */
185 fun_t *closure_funs; /* closure functions (for functions that have closure parameters) */
186 int has_broke; /* has an escape occured? 0 if false, label_idx (>0) if true */
187 struct nitni_ref_array_link *nitni_local_ref_head; /* points to head of array link contaning local variables used via nitni */
188 int REG_size; /* number of local variables */
189 val_t REG[1]; /* local variables (flexible array, this must be the last variable is extended in fra struct */
190 };
191 extern struct stack_frame_t *stack_frame_head;
192
193
194 typedef enum {true = (1==1),false = (0==1)} bool;
195
196 void nit_exit(int);
197 void nit_abort(const char*, const char*, const char*, int);
198
199 #define CALL(r,c) ((VAL2VFT(r)[c].f))
200 #define ATTR(r,c) (*(val_t*)(VAL2OBJ(r)+c))
201 #define ATTRS(r,c,o) ((VAL2OBJ(r)+VAL2VFT(r)[c].i)[o].attr)
202
203 void prepare_signals(void);
204 extern classtable_t TAG2VFT[4];
205 val_t NEW_NativeArray(size_t length, size_t size);
206 #endif