13 #include <hashtable.h>
14 #include <ptr_array.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
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 */
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
;
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
80 struct rubinius_state
;
82 typedef struct rubinius_state
* rstate
;
84 rstate
rubinius_state_new();
85 void state_destroy(rstate
);
91 #define STATE rstate state
93 typedef void (*state_cleanup_func
)(STATE
, OBJECT
);
96 /* IF the type is a ByteArray, how many fields at the front are
97 * OBJECT's that need to be GC'd */
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
{
115 struct method_cache method_cache
[CPU_CACHE_SIZE
+ CPU_CACHE_TOLERANCE
];
121 int cache_collisions
;
122 int cache_inline_hit
;
123 int cache_inline_stale
;
124 int cache_inline_const_hit
;
127 struct rubinius_globals
*global
;
129 /* Used to pass information down to the garbage collectors */
130 OBJECT
*current_stack
;
132 int ac_on_stack
, home_on_stack
, sender_on_stack
;
135 CInvContext
*c_context
;
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
;
148 unsigned int event_id
;
150 /* Stuff sampling profiler uses, not critical for VM operations */
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
];
165 uint64_t system_start
;
166 uint64_t lookup_time
;
171 void cpu_show_lookup_time(STATE
);
172 uint64_t get_cpu_frequency();
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
194 #define FIRE_ASSERT 4
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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)
306 #define xassert(cond)
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__ */