PRIMITIVE VALUE vm_get_const(VALUE outer, void *cache_p, ID path, int flags) { struct ccache *cache = (struct ccache *)cache_p; rb_vm_outer_t *outer_stack = rb_vm_get_outer_stack(); GC_RETAIN(outer_stack); const bool lexical_lookup = (flags & CONST_LOOKUP_LEXICAL); const bool dynamic_class = (flags & CONST_LOOKUP_DYNAMIC_CLASS); if (dynamic_class && lexical_lookup) { outer = rb_vm_get_const_base(); } VALUE val; if (cache->outer == outer && cache->outer_stack == outer_stack && cache->val != Qundef) { val = cache->val; } else { val = rb_vm_const_lookup_level(outer, path, lexical_lookup, false, outer_stack); cache->outer = outer; GC_RELEASE(cache->outer_stack); cache->outer_stack = outer_stack; GC_RETAIN(cache->outer_stack); cache->val = val; } GC_RELEASE(outer_stack); return val; }
void Init_var_tables(void) { rb_global_tbl = st_init_numtable(); GC_RETAIN(rb_global_tbl); rb_class_tbl = st_init_numtable(); GC_RETAIN(rb_class_tbl); autoload = rb_intern("__autoload__"); classpath = rb_intern("__classpath__"); tmp_classpath = rb_intern("__tmp_classpath__"); selRequire = sel_registerName("require:"); }
force_inline rb_vm_block_t * RoxorVM::uncache_or_create_block(void *key, bool *cached, int dvars_size) { std::map<void *, rb_vm_block_t *>::iterator iter = blocks.find(key); rb_vm_block_t *b; const int create_block_mask = VM_BLOCK_ACTIVE | VM_BLOCK_PROC | VM_BLOCK_IFUNC; if ((iter == blocks.end()) || (iter->second->flags & create_block_mask)) { const bool is_ifunc = (iter != blocks.end()) && ((iter->second->flags & VM_BLOCK_IFUNC) == VM_BLOCK_IFUNC); b = (rb_vm_block_t *)xmalloc(sizeof(rb_vm_block_t) + (sizeof(VALUE *) * dvars_size)); if (!is_ifunc) { if (iter != blocks.end()) { GC_RELEASE(iter->second); } GC_RETAIN(b); blocks[key] = b; } *cached = false; } else { b = iter->second; *cached = true; } return b; }
static VALUE rb_source_init(VALUE self, SEL sel, VALUE type, VALUE handle, VALUE mask, VALUE queue) { Check_Queue(queue); rb_source_t *src = RSource(self); src->source_enum = (source_enum_t) NUM2LONG(type); dispatch_source_type_t c_type = rb_source_enum2type(src->source_enum); assert(c_type != NULL); uintptr_t c_handle = NUM2UINT(rb_Integer(handle)); unsigned long c_mask = NUM2LONG(mask); dispatch_queue_t c_queue = RQueue(queue)->queue; src->source = dispatch_source_create(c_type, c_handle, c_mask, c_queue); assert(src->source != NULL); rb_vm_block_t *block = get_prepared_block(); GC_WB(&src->event_handler, block); GC_RETAIN(self); // apparently needed to ensure consistent counting dispatch_set_context(src->source, (void *)self); dispatch_source_set_event_handler_f(src->source, rb_source_event_handler); GC_WB(&src->handle, handle); if (rb_source_is_file(src) && rb_obj_is_kind_of(handle, rb_cIO)) { dispatch_source_set_cancel_handler_f(src->source, rb_source_close_handler); } rb_dispatch_resume(self, 0); return self; }
static void add_encoding( unsigned int encoding_index, // index of the encoding in the encodings // array unsigned int rb_encoding_type, const char *public_name, // public name for the encoding unsigned char min_char_size, bool single_byte_encoding, // in the encoding a character takes only // one byte bool ascii_compatible, // is the encoding ASCII compatible or not bool little_endian, // for UTF-16/32, if the encoding is little endian ... // aliases for the encoding (should no include the public name) // - must end with a NULL ) { assert(encoding_index < ENCODINGS_COUNT); // create an array for the aliases unsigned int aliases_count = 0; va_list va_aliases; va_start(va_aliases, little_endian); while (va_arg(va_aliases, const char *) != NULL) { ++aliases_count; } va_end(va_aliases); const char **aliases = (const char **) malloc(sizeof(const char *) * aliases_count); va_start(va_aliases, little_endian); for (unsigned int i = 0; i < aliases_count; ++i) { aliases[i] = va_arg(va_aliases, const char *); } va_end(va_aliases); // create the MacRuby object NEWOBJ(encoding, rb_encoding_t); encoding->basic.flags = 0; encoding->basic.klass = rb_cEncoding; rb_encodings[encoding_index] = encoding; GC_RETAIN(encoding); // it should never be deallocated // fill the fields encoding->index = encoding_index; encoding->public_name = public_name; encoding->min_char_size = min_char_size; encoding->single_byte_encoding = single_byte_encoding; encoding->ascii_compatible = ascii_compatible; encoding->little_endian = little_endian; encoding->aliases_count = aliases_count; encoding->aliases = aliases; switch (rb_encoding_type) { case ENCODING_TYPE_SPECIAL: break; case ENCODING_TYPE_UCNV: enc_init_ucnv_encoding(encoding); break; default: abort(); } }
void Init_jump(void) { rb_objc_define_module_function(rb_mKernel, "at_exit", rb_f_at_exit, 0); at_exit_procs = rb_ary_new(); GC_RETAIN(at_exit_procs); }
VALUE rb_range_new2(VALUE beg, VALUE end, int exclude_end, int retain) { VALUE range = rb_range_new(beg, end, exclude_end); if (retain) { GC_RETAIN(range); } return range; }
static VALUE rb_queue_from_dispatch(dispatch_queue_t dq, bool should_retain) { VALUE q = rb_queue_alloc(cQueue, 0); if (should_retain) { GC_RETAIN(q); } RQueue(q)->queue = dq; return q; }
static VALUE protect_rescue(VALUE obj, VALUE exc) { int *state = (int *)obj; if (state != NULL) { *state = 1; } GC_RETAIN(exc); protect_exc = exc; return Qnil; }
static void rb_objc_add_method(VALUE klass, const char *name, void *imp, const int arity, const int noex, bool direct) { if (!direct) { assert(name[strlen(name) - 1] != ':'); } NODE *body = rb_vm_cfunc_node_from_imp((Class)klass, arity, (IMP)imp, noex); GC_RETAIN(body); rb_vm_define_method((Class)klass, rb_vm_name_to_sel(name, arity), (IMP)imp, body, direct); }
static VALUE thread_initialize(VALUE thread, SEL sel, int argc, const VALUE *argv) { if (!rb_block_given_p()) { rb_raise(rb_eThreadError, "must be called with a block"); } rb_vm_block_t *b = rb_vm_current_block(); assert(b != NULL); rb_vm_thread_t *t = GetThreadPtr(thread); if (t->thread != 0) { rb_raise(rb_eThreadError, "already initialized thread"); } rb_vm_thread_pre_init(t, b, argc, argv, rb_vm_create_vm()); // The thread's group is always the parent's one. // The parent group might be nil (ex. if created from GCD). VALUE group = GetThreadPtr(rb_vm_current_thread())->group; if (group != Qnil) { thgroup_add_m(group, thread, false); } // Retain the Thread object to avoid a potential GC, the corresponding // release is done in rb_vm_thread_run(). GC_RETAIN(thread); // Prepare attributes for the thread. pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED); pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); // Register the thread to the core. We are doing this before actually // running it because the current thread might perform a method poking at // the current registered threads (such as Kernel#sleep) right after that. rb_vm_register_thread(thread); // Launch it. if (pthread_create(&t->thread, &attr, (void *(*)(void *))rb_vm_thread_run, (void *)thread) != 0) { rb_sys_fail("pthread_create() failed"); } pthread_attr_destroy(&attr); return thread; }
void Init_eval(void) { rb_define_virtual_variable("$@", errat_getter, errat_setter); rb_define_virtual_variable("$!", errinfo_getter, 0); rb_objc_define_module_function(rb_mKernel, "eval", rb_f_eval, -1); rb_objc_define_module_function(rb_mKernel, "iterator?", rb_f_block_given_p, 0); rb_objc_define_module_function(rb_mKernel, "block_given?", rb_f_block_given_p, 0); rb_objc_define_module_function(rb_mKernel, "fail", rb_f_raise, -1); rb_objc_define_module_function(rb_mKernel, "raise", rb_f_raise, -1); rb_objc_define_module_function(rb_mKernel, "global_variables", rb_f_global_variables, 0); /* in variable.c */ rb_objc_define_module_function(rb_mKernel, "local_variables", rb_f_local_variables, 0); rb_objc_define_method(rb_mKernel, "__method__", rb_f_method_name, 0); rb_objc_define_method(rb_mKernel, "__callee__", rb_f_method_name, 0); rb_objc_define_private_method(rb_cModule, "append_features", rb_mod_append_features, 1); rb_objc_define_private_method(rb_cModule, "extend_object", rb_mod_extend_object, 1); rb_objc_define_private_method(rb_cModule, "include", rb_mod_include, -1); rb_objc_define_method(rb_cModule, "module_eval", rb_mod_module_eval, -1); rb_objc_define_method(rb_cModule, "class_eval", rb_mod_module_eval, -1); rb_undef_method(rb_cClass, "module_function"); Init_vm_eval(); Init_eval_method(); rb_objc_define_method(*(VALUE *)rb_cModule, "nesting", rb_mod_nesting, -3); rb_objc_define_method(*(VALUE *)rb_cModule, "constants", rb_mod_s_constants, -1); VALUE cTopLevel = *(VALUE *)rb_vm_top_self(); rb_objc_define_method(cTopLevel, "include", top_include, -1); rb_objc_define_method(rb_mKernel, "extend", rb_obj_extend, -1); rb_objc_define_module_function(rb_mKernel, "trace_var", rb_f_trace_var, -1); /* in variable.c */ rb_objc_define_module_function(rb_mKernel, "untrace_var", rb_f_untrace_var, -1); /* in variable.c */ rb_define_virtual_variable("$SAFE", safe_getter, safe_setter); exception_error = rb_exc_new2(rb_eFatal, "exception reentered"); //rb_ivar_set(exception_error, idThrowState, INT2FIX(TAG_FATAL)); GC_RETAIN(exception_error); }
NODE* rb_node_newnode(enum node_type type, VALUE a0, VALUE a1, VALUE a2) { NODE *n = xmalloc(sizeof(struct RNode)); n->flags |= T_NODE; nd_set_type(n, type); GC_WB(&n->u1.value, a0); GC_WB(&n->u2.value, a1); GC_WB(&n->u3.value, a2); // FIXME this retain is added because the parser is NOT GC-safe at this point GC_RETAIN(n); return n; }
rb_vm_block_t * RoxorVM::uncache_or_dup_block(rb_vm_block_t *b) { void *key = (void *)b->imp; std::map<void *, rb_vm_block_t *>::iterator iter = blocks.find(key); if (iter == blocks.end() || iter->second->self != b->self) { if (iter != blocks.end()) { GC_RELEASE(iter->second); } b = dup_block(b); GC_RETAIN(b); blocks[key] = b; } else { b = iter->second; } return b; }
static rb_vm_block_t * get_prepared_block() { rb_vm_block_t *block = rb_vm_current_block(); if (block == NULL) { rb_raise(rb_eArgError, "block not given"); } #if GCD_BLOCKS_COPY_DVARS block = rb_vm_dup_block(block); for (int i = 0; i < block->dvars_size; i++) { VALUE *slot = block->dvars[i]; VALUE *new_slot = xmalloc(sizeof(VALUE)); GC_WB(new_slot, *slot); GC_WB(&block->dvars[i], new_slot); } #else rb_vm_block_make_detachable_proc(block); #endif GC_RETAIN(block); return block; }
void Init_GC(void) { VALUE rb_mObSpace; rb_mGC = rb_define_module("GC"); rb_objc_define_module_function(rb_mGC, "start", rb_gc_start, 0); rb_objc_define_module_function(rb_mGC, "enable", rb_gc_enable, 0); rb_objc_define_module_function(rb_mGC, "disable", rb_gc_disable, 0); rb_objc_define_module_function(rb_mGC, "stress", gc_stress_get, 0); rb_objc_define_module_function(rb_mGC, "stress=", gc_stress_set, 1); rb_objc_define_module_function(rb_mGC, "count", gc_count, 0); rb_objc_define_method(rb_mGC, "garbage_collect", rb_gc_start, 0); rb_mObSpace = rb_define_module("ObjectSpace"); rb_objc_define_module_function(rb_mObSpace, "each_object", os_each_obj, -1); rb_objc_define_module_function(rb_mObSpace, "garbage_collect", rb_gc_start, 0); rb_objc_define_module_function(rb_mObSpace, "define_finalizer", define_final, -1); rb_objc_define_module_function(rb_mObSpace, "undefine_finalizer", undefine_final, 1); rb_objc_define_module_function(rb_mObSpace, "_id2ref", id2ref, 1); nomem_error = rb_exc_new2(rb_eNoMemError, "failed to allocate memory"); GC_RETAIN(nomem_error); rb_objc_define_method(rb_mKernel, "__id__", rb_obj_id, 0); rb_objc_define_method(rb_mKernel, "object_id", rb_obj_id, 0); rb_objc_define_module_function(rb_mObSpace, "count_objects", count_objects, -1); rb_cFinalizer = rb_define_class("__Finalizer", rb_cObject); rb_objc_finalizer_finalize_super = rb_objc_install_method2((Class)rb_cFinalizer, "finalize", (IMP)rb_objc_finalizer_finalize); }
void rb_register_mark_object(VALUE obj) { GC_RETAIN(obj); }
static const void * retain_cb(CFAllocatorRef allocator, const void *v) { GC_RETAIN(v); return v; }
void Init_Proc(void) { /* Proc */ rb_cProc = rb_define_class("Proc", rb_cObject); rb_undef_alloc_func(rb_cProc); rb_objc_define_method(*(VALUE *)rb_cProc, "new", rb_proc_s_new, -1); rb_objc_define_method(rb_cProc, "call", proc_call, -1); rb_objc_define_method(rb_cProc, "[]", proc_call, -1); rb_objc_define_method(rb_cProc, "===", proc_call, -1); rb_objc_define_method(rb_cProc, "yield", proc_call, -1); rb_objc_define_method(rb_cProc, "to_proc", proc_to_proc, 0); rb_objc_define_method(rb_cProc, "arity", proc_arity, 0); rb_objc_define_method(rb_cProc, "clone", proc_clone, 0); rb_objc_define_method(rb_cProc, "dup", proc_dup, 0); rb_objc_define_method(rb_cProc, "==", proc_eq, 1); rb_objc_define_method(rb_cProc, "eql?", proc_eq, 1); rb_objc_define_method(rb_cProc, "hash", proc_hash, 0); rb_objc_define_method(rb_cProc, "to_s", proc_to_s, 0); rb_objc_define_method(rb_cProc, "lambda?", proc_lambda_p, 0); rb_objc_define_method(rb_cProc, "binding", proc_binding, 0); rb_objc_define_method(rb_cProc, "curry", proc_curry, -1); /* Exceptions */ rb_eLocalJumpError = rb_define_class("LocalJumpError", rb_eStandardError); rb_objc_define_method(rb_eLocalJumpError, "exit_value", localjump_xvalue, 0); rb_objc_define_method(rb_eLocalJumpError, "reason", localjump_reason, 0); rb_eSysStackError = rb_define_class("SystemStackError", rb_eException); sysstack_error = rb_exc_new2(rb_eSysStackError, "stack level too deep"); OBJ_TAINT(sysstack_error); GC_RETAIN(sysstack_error); /* utility functions */ rb_objc_define_module_function(rb_mKernel, "proc", rb_block_proc_imp, 0); rb_objc_define_module_function(rb_mKernel, "lambda", proc_lambda, 0); /* Method */ rb_cMethod = rb_define_class("Method", rb_cObject); rb_undef_alloc_func(rb_cMethod); rb_undef_method(CLASS_OF(rb_cMethod), "new"); rb_objc_define_method(rb_cMethod, "==", method_eq, 1); rb_objc_define_method(rb_cMethod, "eql?", method_eq, 1); rb_objc_define_method(rb_cMethod, "hash", method_hash, 0); rb_objc_define_method(rb_cMethod, "clone", method_clone, 0); rb_objc_define_method(rb_cMethod, "call", rb_method_call, -1); rb_objc_define_method(rb_cMethod, "[]", rb_method_call, -1); rb_objc_define_method(rb_cMethod, "arity", method_arity_m, 0); rb_objc_define_method(rb_cMethod, "inspect", method_inspect, 0); rb_objc_define_method(rb_cMethod, "to_s", method_inspect, 0); rb_objc_define_method(rb_cMethod, "to_proc", method_proc, 0); rb_objc_define_method(rb_cMethod, "receiver", method_receiver, 0); rb_objc_define_method(rb_cMethod, "name", method_name, 0); rb_objc_define_method(rb_cMethod, "owner", method_owner, 0); rb_objc_define_method(rb_cMethod, "unbind", method_unbind, 0); rb_objc_define_method(rb_mKernel, "method", rb_obj_method, 1); rb_objc_define_method(rb_mKernel, "public_method", rb_obj_public_method, 1); /* UnboundMethod */ rb_cUnboundMethod = rb_define_class("UnboundMethod", rb_cObject); rb_undef_alloc_func(rb_cUnboundMethod); rb_undef_method(CLASS_OF(rb_cUnboundMethod), "new"); rb_objc_define_method(rb_cUnboundMethod, "==", method_eq, 1); rb_objc_define_method(rb_cUnboundMethod, "eql?", method_eq, 1); rb_objc_define_method(rb_cUnboundMethod, "hash", method_hash, 0); rb_objc_define_method(rb_cUnboundMethod, "clone", method_clone, 0); rb_objc_define_method(rb_cUnboundMethod, "arity", method_arity_m, 0); rb_objc_define_method(rb_cUnboundMethod, "inspect", method_inspect, 0); rb_objc_define_method(rb_cUnboundMethod, "to_s", method_inspect, 0); rb_objc_define_method(rb_cUnboundMethod, "name", method_name, 0); rb_objc_define_method(rb_cUnboundMethod, "owner", method_owner, 0); rb_objc_define_method(rb_cUnboundMethod, "bind", umethod_bind, 1); /* Module#*_method */ rb_objc_define_method(rb_cModule, "instance_method", rb_mod_instance_method, 1); rb_objc_define_method(rb_cModule, "public_instance_method", rb_mod_public_instance_method, 1); rb_objc_define_private_method(rb_cModule, "define_method", rb_mod_define_method, -1); /* Kernel */ rb_objc_define_method(rb_mKernel, "define_singleton_method", rb_obj_define_method, -1); }
void Init_Exception(void) { rb_eException = rb_define_class("Exception", rb_cObject); rb_objc_define_method(*(VALUE *)rb_eException, "exception", rb_class_new_instance_imp, -1); rb_objc_define_method(rb_eException, "exception", exc_exception, -1); rb_objc_define_method(rb_eException, "initialize", exc_initialize, -1); rb_objc_define_method(rb_eException, "==", exc_equal, 1); rb_objc_define_method(rb_eException, "to_s", exc_to_s, 0); rb_objc_define_method(rb_eException, "message", exc_message, 0); rb_objc_define_method(rb_eException, "inspect", exc_inspect, 0); rb_objc_define_method(rb_eException, "backtrace", exc_backtrace, 0); rb_objc_define_method(rb_eException, "set_backtrace", exc_set_backtrace, 1); rb_eSystemExit = rb_define_class("SystemExit", rb_eException); rb_objc_define_method(rb_eSystemExit, "initialize", exit_initialize, -1); rb_objc_define_method(rb_eSystemExit, "status", exit_status, 0); rb_objc_define_method(rb_eSystemExit, "success?", exit_success_p, 0); rb_eFatal = rb_define_class("fatal", rb_eException); rb_eSignal = rb_define_class("SignalException", rb_eException); rb_eInterrupt = rb_define_class("Interrupt", rb_eSignal); rb_eStandardError = rb_define_class("StandardError", rb_eException); rb_eTypeError = rb_define_class("TypeError", rb_eStandardError); rb_eArgError = rb_define_class("ArgumentError", rb_eStandardError); rb_eIndexError = rb_define_class("IndexError", rb_eStandardError); rb_eKeyError = rb_define_class("KeyError", rb_eIndexError); rb_eRangeError = rb_define_class("RangeError", rb_eStandardError); rb_eScriptError = rb_define_class("ScriptError", rb_eException); rb_eSyntaxError = rb_define_class("SyntaxError", rb_eScriptError); rb_eLoadError = rb_define_class("LoadError", rb_eScriptError); rb_eNotImpError = rb_define_class("NotImplementedError", rb_eScriptError); rb_eNameError = rb_define_class("NameError", rb_eStandardError); rb_objc_define_method(rb_eNameError, "initialize", name_err_initialize, -1); rb_objc_define_method(rb_eNameError, "name", name_err_name, 0); rb_objc_define_method(rb_eNameError, "to_s", name_err_to_s, 0); rb_cNameErrorMesg = rb_define_class_under(rb_eNameError, "message", rb_cData); rb_objc_define_method(*(VALUE *)rb_cNameErrorMesg, "!", name_err_mesg_new, 3); rb_objc_define_method(rb_cNameErrorMesg, "==", name_err_mesg_equal, 1); rb_objc_define_method(rb_cNameErrorMesg, "to_str", name_err_mesg_to_str, 0); rb_objc_define_method(rb_cNameErrorMesg, "_dump", name_err_mesg_to_str, 1); rb_objc_define_method(*(VALUE *)rb_cNameErrorMesg, "_load", name_err_mesg_load, 1); rb_eNoMethodError = rb_define_class("NoMethodError", rb_eNameError); rb_objc_define_method(rb_eNoMethodError, "initialize", nometh_err_initialize, -1); rb_objc_define_method(rb_eNoMethodError, "args", nometh_err_args, 0); rb_eRuntimeError = rb_define_class("RuntimeError", rb_eStandardError); rb_eSecurityError = rb_define_class("SecurityError", rb_eException); rb_eNoMemError = rb_define_class("NoMemoryError", rb_eException); rb_eEncodingError = rb_define_class("EncodingError", rb_eStandardError); rb_eEncCompatError = rb_define_class_under(rb_cEncoding, "CompatibilityError", rb_eEncodingError); rb_eUndefinedConversionError = rb_define_class_under(rb_cEncoding, "UndefinedConversionError", rb_eEncodingError); rb_eInvalidByteSequenceError = rb_define_class_under(rb_cEncoding, "InvalidByteSequenceError", rb_eEncodingError); rb_eConverterNotFoundError = rb_define_class_under(rb_cEncoding, "ConverterNotFoundError", rb_eEncodingError); syserr_tbl = st_init_numtable(); GC_RETAIN(syserr_tbl); rb_eSystemCallError = rb_define_class("SystemCallError", rb_eStandardError); rb_objc_define_method(rb_eSystemCallError, "initialize", syserr_initialize, -1); rb_objc_define_method(rb_eSystemCallError, "errno", syserr_errno, 0); rb_objc_define_method(*(VALUE *)rb_eSystemCallError, "===", syserr_eqq, 1); rb_mErrno = rb_define_module("Errno"); rb_objc_define_method(*(VALUE *)rb_mErrno, "const_missing", errno_missing, 1); rb_objc_define_method(*(VALUE *)rb_mErrno, "code", errno_code, 0); rb_objc_define_module_function(rb_mKernel, "warn", rb_warn_m, 1); }