Added spec:commit task to commit changes to spec/ruby sources.
[rbx.git] / shotgun / lib / state.h
blob2b51a78c93d42843df2502890dc145528c260e9e
1 #ifndef RBS_STATE_H
2 #define RBS_STATE_H
4 #ifndef TRUE
5 #define TRUE 1
6 #endif
8 #ifndef FALSE
9 #define FALSE 0
10 #endif
13 #include <hashtable.h>
14 #include <ptr_array.h>
16 #include <termios.h>
18 #include "shotgun/lib/shotgun.h"
19 #include "shotgun/lib/memutil.h"
20 #include "shotgun/lib/subtend/PortableUContext.h"
22 /* These are for custom literals. We'll need an API to set it
23 eventually. */
24 #define CUSTOM_CLASS Qnil
26 #define SPECIAL_CLASS_MASK 0x1f
27 #define SPECIAL_CLASS_SIZE 32
29 struct rubinius_globals {
31 /* classes for the core 'types' */
32 OBJECT blokctx, cmethod, tuple, module, object, array;
33 OBJECT class, hash, methtbl, bytearray, methctx, blank;
34 OBJECT blokenv, bignum, regexp, regexpdata, matchdata;
35 OBJECT string, symbol, io, metaclass, symtbl, autoload;
36 OBJECT nil_class, true_class, false_class, fixnum_class, undef_class;
37 OBJECT floatpoint, fastctx, data, nmethod, nmc, task, list, list_node;
38 OBJECT channel, thread, staticscope, send_site, selector, lookuptable;
40 /* the primary symbol table */
41 OBJECT symbols;
42 OBJECT method_missing;
43 OBJECT sym_inherited, sym_opened_class;
44 OBJECT sym_from_literal, sym_method_added, sym_s_method_added, sym_init_copy;
45 OBJECT sym_plus, sym_minus, sym_equal, sym_nequal, sym_tequal, sym_lt, sym_gt;
46 OBJECT exc_arg, exc_segfault;
47 OBJECT exc_loe, exc_type, exc_rex;
48 OBJECT exc_stack_explosion;
49 OBJECT exc_primitive_failure, sym_initialize;
51 OBJECT external_ivars, scheduled_threads, errno_mapping;
52 OBJECT config, ffi_ptr, ffi_func, sym_send;
53 OBJECT sym_public, sym_private, sym_protected, sym_const_missing;
54 OBJECT sym_object_id, sym_call;
55 OBJECT exception, iseq, icache;
56 OBJECT top_scope, on_gc_channel;
57 OBJECT selectors;
59 OBJECT special_classes[SPECIAL_CLASS_SIZE];
63 #define NUM_OF_GLOBALS ((unsigned int)(sizeof(struct rubinius_globals) / SIZE_OF_OBJECT))
65 #define CPU_CACHE_MASK 0xfff
66 #define CPU_CACHE_HASH(c,m) ((((uintptr_t)(c)>>3)^((uintptr_t)m)) & CPU_CACHE_MASK)
67 #define CPU_CACHE_TOLERANCE 3
69 /* size is mask + 1 + tolerance */
70 #define CPU_CACHE_SIZE 0x1003
72 struct method_cache {
73 OBJECT klass;
74 OBJECT name;
75 OBJECT module;
76 OBJECT method;
77 int is_public;
80 struct rubinius_state;
82 typedef struct rubinius_state* rstate;
84 rstate rubinius_state_new();
85 void state_destroy(rstate);
87 #ifdef STATE
88 #undef STATE
89 #endif
91 #define STATE rstate state
93 typedef void (*state_cleanup_func)(STATE, OBJECT);
95 struct type_info {
96 /* IF the type is a ByteArray, how many fields at the front are
97 * OBJECT's that need to be GC'd */
98 int object_fields;
99 state_cleanup_func cleanup;
103 #define FASTCTX_FIELDS 19
104 #define FASTCTX_NORMAL 1
105 #define FASTCTX_BLOCK 3
106 #define FASTCTX_NMC 4
108 #include "shotgun/lib/cpu.h"
109 #include "shotgun/lib/object_memory.h"
110 #include "shotgun/lib/subtend/handle.h"
112 struct rubinius_state {
113 object_memory om;
115 struct method_cache method_cache[CPU_CACHE_SIZE + CPU_CACHE_TOLERANCE];
117 #ifdef TRACK_STATS
118 int cache_hits;
119 int cache_misses;
120 int cache_used;
121 int cache_collisions;
122 int cache_inline_hit;
123 int cache_inline_stale;
124 int cache_inline_const_hit;
125 #endif
127 struct rubinius_globals *global;
129 /* Used to pass information down to the garbage collectors */
130 OBJECT *current_stack;
131 OBJECT *current_sp;
132 int ac_on_stack, home_on_stack, sender_on_stack;
134 #ifdef USE_CINVOKE
135 CInvContext *c_context;
136 #endif
138 rni_handle_table *handle_tbl;
140 /* pointer to bottom of the stack */
141 unsigned long *stack_bottom;
143 struct hashtable *cleanup;
144 struct hashtable *config;
146 void *event_base;
147 void *thread_infos;
148 unsigned int event_id;
150 /* Stuff sampling profiler uses, not critical for VM operations */
151 OBJECT *samples;
152 int max_samples, cur_sample;
153 /* again, profiler stats */
154 int excessive_tracing, gc_stats;
155 int check_events, pending_threads, pending_events;
157 struct termios *termios;
159 /* Used to store the value of c->ip_ptr while cpu_run isn't running */
160 IP_TYPE* external_ip;
162 struct type_info type_info[LastObjectType];
164 #ifdef TIME_LOOKUP
165 uint64_t system_start;
166 uint64_t lookup_time;
167 #endif
170 #ifdef TIME_LOOKUP
171 void cpu_show_lookup_time(STATE);
172 uint64_t get_cpu_frequency();
173 #endif
175 #define BASIC_CLASS(kind) state->global->kind
176 #define NEW_OBJECT(kls, size) object_memory_new_object(state->om, kls, size)
177 #define NEW_STRUCT(obj, str, kls, kind) \
178 obj = object_memory_new_opaque(state, kls, sizeof(kind)); \
179 str = (kind * )BYTES_OF(obj)
181 #define NEW_OBJECT_MATURE(kls, size) object_memory_new_object_mature(state->om, kls, size)
183 #define DATA_STRUCT(obj, kind) ((kind)BYTES_OF(obj))
184 #define BYTES2FIELDS(bytes) (bytes % 4 == 0 ? bytes : ((bytes + 4) - ((bytes + 4) % 4)))
186 #include "shotgun/lib/bignum.h"
187 #include "shotgun/lib/float.h"
188 #include "shotgun/lib/array.h"
189 #include "shotgun/lib/machine.h"
191 #define FIRE_ACCESS 1
192 #define FIRE_NULL 2
193 #define FIRE_STACK 3
194 #define FIRE_ASSERT 4
195 #define FIRE_TYPE 5
197 OBJECT rbs_const_set(STATE, OBJECT module, const char *name, OBJECT obj);
198 OBJECT rbs_const_get(STATE, OBJECT module, const char *name);
199 OBJECT rbs_class_new(STATE, const char *name, int fields, OBJECT obj);
200 OBJECT rbs_class_new_with_namespace(STATE, const char *name, int fields, OBJECT obj, OBJECT ns);
201 const char *rbs_symbol_to_cstring(STATE, OBJECT sym);
202 OBJECT rbs_symbol_to_string(STATE, OBJECT sym);
203 const char *rbs_inspect(STATE, OBJECT obj);
204 const char *rbs_inspect_verbose(STATE, OBJECT obj);
205 const char *_inspect(OBJECT obj);
206 OBJECT rbs_module_new(STATE, const char *name, OBJECT ns);
207 OBJECT rbs_class_new_instance(STATE, OBJECT cls);
209 void *XMALLOC(size_t n);
210 void *XREALLOC(void *p, size_t n);
211 void *XCALLOC(size_t n, size_t s);
212 void XFREE(void *p);
214 #define ALLOC_N(t,n) (t*)XCALLOC(n, sizeof(t))
215 #define ALLOC(t) (t*)XMALLOC(sizeof(t))
216 #define REALLOC_N(v,t,n) (v)=(t*)XREALLOC((void*)(v), sizeof(t)*n)
217 #define FREE(v) XFREE(v)
219 static inline native_int rbs_to_int(OBJECT obj) {
220 return (native_int)STRIP_TAG(obj);
223 static inline OBJECT rbs_int_to_numeric(STATE, native_int num) {
224 /* Number is too big for Fixnum. Use Bignum. */
225 if(num > FIXNUM_MAX || num < FIXNUM_MIN) {
226 return bignum_new(state, num);
227 } else {
228 return APPLY_TAG((native_int)num, TAG_FIXNUM);
232 /* Do NOT use the APPLY_TAG/STRIP_TAG test in the unsigned cases.
233 * C doesn't let you cast from a unsigned to signed type and remove
234 * the sign bit, so for large unsigned ints, the test is a false
235 * positive for it fitting properly. */
236 static inline OBJECT rbs_uint_to_numeric(STATE, unsigned int num) {
237 /* No need to check what 'num' is if it will always fit into a Fixnum */
238 #if (CONFIG_WORDSIZE != 64)
239 if(num > FIXNUM_MAX) {
240 /* Number is too big for Fixnum. Use Bignum. */
241 return bignum_new_unsigned(state, num);
243 #endif
244 return APPLY_TAG((native_int)num, TAG_FIXNUM);
247 static inline OBJECT rbs_ll_to_numeric(STATE, long long num) {
248 /* Number is too big for Fixnum. Use Bignum. */
249 if(num > FIXNUM_MAX || num < FIXNUM_MIN) {
250 return bignum_from_ll(state, num);
251 } else {
252 return APPLY_TAG((native_int)num, TAG_FIXNUM);
256 /* See comment before rbs_uint_to_numeric */
257 static inline OBJECT rbs_ull_to_numeric(STATE, unsigned long long num) {
258 /* Number is too big for Fixnum. Use Bignum. */
259 if(num > FIXNUM_MAX) {
260 return bignum_from_ull(state, num);
261 } else {
262 return APPLY_TAG((native_int)num, TAG_FIXNUM);
266 static inline OBJECT rbs_max_long_to_numeric(STATE, long long num) {
267 /* Number is too big for Fixnum. Use Bignum. */
268 if(num > FIXNUM_MAX || num < FIXNUM_MIN) {
269 return bignum_from_ll(state, num);
270 } else {
271 return APPLY_TAG((native_int)num, TAG_FIXNUM);
275 static inline double rbs_fixnum_to_double(OBJECT obj) {
276 double val = rbs_to_int(obj);
277 return val;
282 * These macros convert between native (C) types and Ruby types
283 * 'N' means a Numeric (e.g. Fixnum), 'I' means native_int (C)
285 #define N2I(obj) ((native_int)STRIP_TAG(obj))
286 #define I2N(i) rbs_int_to_numeric(state, i)
287 #define UI2N(i) rbs_uint_to_numeric(state, i)
288 #define ULL2N(i) rbs_ull_to_numeric(state, i)
289 #define LL2N(i) rbs_ll_to_numeric(state, i)
290 /* Convert the longest supported integer type to a Numeric */
291 #define ML2N(i) rbs_max_long_to_numeric(state, (long long)i)
293 #define FIXNUM_TO_DOUBLE(obj) rbs_fixnum_to_double(obj)
294 #define FLOAT_TO_DOUBLE(k) (*DATA_STRUCT(k, double*))
296 void object_memory_check_ptr(void *ptr, OBJECT obj);
298 // #define XDEBUG 1
300 #ifdef XDEBUG
301 /* Copied from assert.h */
302 #define xassert(cond) ((void)((cond) ? 0 : xassert_message(#cond, __FILE__, __LINE__)))
303 #define xassert_message(str, file, line) \
304 (printf("%s:%u: failed assertion '%s'\n", file, line, str), abort(), 0)
305 #else
306 #define xassert(cond)
307 #endif
309 #define sassert(cond) ((void)((cond) ? 0 : machine_handle_assert(#cond, __FILE__, __LINE__)))
311 // #define CHECK_PTR(obj) object_memory_check_ptr(current_machine->om, obj)
312 #define CHECK_PTR(obj)
314 void machine_handle_fire(int);
315 void machine_handle_assert(const char *reason, const char *file, int line);
316 void machine_handle_type_error(OBJECT, const char *message);
318 #include "shotgun/lib/environment.h"
320 #define current_machine (environment_current_machine())
323 #include "shotgun/lib/object_memory-inline.h"
325 void state_add_cleanup(STATE, OBJECT cls, state_cleanup_func func);
326 void state_run_cleanup(STATE, OBJECT obj);
327 void state_setup_type(STATE, int type, struct type_info *info);
330 #endif /* __STATE__ */