VALUE rb_iterate(VALUE(*ifunc)(VALUE), VALUE ary, VALUE(*cb)(ANYARGS), VALUE cb_data) { NativeMethodEnvironment* env = NativeMethodEnvironment::get(); // Minor optimization. if(ifunc == rb_each && kind_of<Array>(env->get_object(ary))) { for(size_t i = 0; i < rb_ary_size(ary); i++) { (*cb)(rb_ary_entry(ary, i), cb_data, Qnil); } return ary; } NativeMethod* nm = NativeMethod::create(env->state(), (String*)Qnil, env->state()->shared.globals.rubinius.get(), env->state()->symbol("call"), (void*)cb, Fixnum::from(ITERATE_BLOCK)); nm->set_ivar(env->state(), env->state()->symbol("cb_data"), env->get_object(cb_data)); Proc* prc = Proc::create(env->state(), env->state()->shared.globals.proc.get()); prc->bound_method(env->state(), nm); env->set_outgoing_block(env->get_handle(prc)); return (*ifunc)(ary); }
VALUE rb_ary_new2(unsigned long length) { NativeMethodEnvironment* env = NativeMethodEnvironment::get(); Array* array = Array::create(env->state(), length); return env->get_handle(array); }
VALUE rb_thread_current(void) { NativeMethodEnvironment* env = NativeMethodEnvironment::get(); GlobalLock::UnlockGuard guard(env); Thread* thread = env->state()->thread.get(); return env->get_handle(thread); }
ID rb_frame_last_func() { NativeMethodEnvironment* env = NativeMethodEnvironment::get(); CallFrame* rcf = env->current_call_frame()->previous->top_ruby_frame(); return env->get_handle(rcf->name()); }
VALUE rb_apply(VALUE recv, ID mid, VALUE args) { NativeMethodEnvironment* env = NativeMethodEnvironment::get(); env->flush_cached_data(); Array* ary = capi::c_as<Array>(env->get_object(args)); Object* obj = env->get_object(recv); // Unlock, we're leaving extension code. env->state()->shared.leave_capi(env->state()); Object* ret = obj->send(env->state(), env->current_call_frame(), reinterpret_cast<Symbol*>(mid), ary, RBX_Qnil); // We need to get the handle for the return value before getting // the GEL so that ret isn't accidentally GCd while we wait. VALUE ret_handle = 0; if(ret) ret_handle = env->get_handle(ret); // Re-entering extension code env->state()->shared.enter_capi(env->state()); env->update_cached_data(); // An exception occurred if(!ret) env->current_ep()->return_to(env); return ret_handle; }
const char* rb_class2name(VALUE module_handle) { NativeMethodEnvironment* env = NativeMethodEnvironment::get(); Module* module_object = c_as<Module>(env->get_object(module_handle)); String* str = module_object->name()->to_str(env->state()); return RSTRING_PTR(env->get_handle(str)); }
VALUE rb_obj_instance_eval(int argc, VALUE* argv, VALUE self) { NativeMethodEnvironment* env = NativeMethodEnvironment::get(); VALUE block = env->get_handle(env->block()); return rb_funcall2b(self, rb_intern("instance_eval"), argc, (const VALUE*)argv, block); }
VALUE rb_hash(VALUE obj) { NativeMethodEnvironment* env = NativeMethodEnvironment::get(); Object* hash = env->get_object(rb_funcall(obj, rb_intern("hash"), 0)); retry: if(try_as<Fixnum>(hash)) { return env->get_handle(hash); } else if(Bignum* big = try_as<Bignum>(hash)) { return LONG2FIX(big->to_native()); } else { hash = env->get_object(rb_to_int(env->get_handle(hash))); goto retry; } }
VALUE rb_hash_delete_if(VALUE self) { NativeMethodEnvironment* env = NativeMethodEnvironment::get(); VALUE block_handle = env->get_handle(env->block()); return rb_funcall2b(self, rb_intern("delete_if"), 0, 0, block_handle); }
VALUE capi_thread_create(VALUE (*func)(ANYARGS), void* arg, const char* name, const char* file) { NativeMethodEnvironment* env = NativeMethodEnvironment::get(); State* state = env->state(); NativeMethod* nm = NativeMethod::create(state, String::create(state, file), G(thread), state->symbol(name), (void*)func, Fixnum::from(1), 0); Pointer* ptr = Pointer::create(state, arg); Thread* thr = Thread::create(env->state(), G(thread), run_function); thr->locals_store(state, state->symbol("function"), nm); thr->locals_store(state, state->symbol("argument"), ptr); thr->group(state, state->vm()->thread.get()->group()); VALUE thr_handle = env->get_handle(thr); thr->fork(state); GCTokenImpl gct; // We do a lock and unlock here so we wait until the started // thread is actually ready. This is to prevent we GC stuff on // the stack in the C-API caller that might be stuffed in the void* argument thr->hard_lock(state, gct, env->current_call_frame()); thr->hard_unlock(state, gct, env->current_call_frame()); return thr_handle; }
VALUE rb_cvar_get(VALUE module_handle, ID name) { NativeMethodEnvironment* env = NativeMethodEnvironment::get(); return rb_funcall(module_handle, rb_intern("class_variable_get"), 1, env->get_handle(prefixed_by(env->state(), "@@", 2, name))); }
VALUE rb_file_open(const char* name, const char* mode) { NativeMethodEnvironment* env = NativeMethodEnvironment::get(); VALUE n = env->get_handle(String::create(env->state(), name)); VALUE m = env->get_handle(String::create(env->state(), mode)); return rb_funcall(rb_cFile, rb_intern("open"), 2, n, m); }
VALUE rb_const_get_at(VALUE module_handle, ID id_name) { NativeMethodEnvironment* env = NativeMethodEnvironment::get(); Symbol* name = reinterpret_cast<Symbol*>(id_name); Module* module = c_as<Module>(env->get_object(module_handle)); bool found = false; Object* val = module->get_const(env->state(), name, &found); if(!found) return const_missing(module_handle, id_name); if(Autoload* autoload = try_as<Autoload>(val)) { return capi_fast_call(env->get_handle(autoload), rb_intern("call"), 0); } return env->get_handle(val); }
VALUE rb_ivar_get(VALUE self_handle, ID ivar_name) { NativeMethodEnvironment* env = NativeMethodEnvironment::get(); Object* object = env->get_object(self_handle); return env->get_handle(object->get_ivar(env->state(), prefixed_by("@", ivar_name))); }
VALUE rb_cvar_set(VALUE module_handle, ID name, VALUE value, int unused) { NativeMethodEnvironment* env = NativeMethodEnvironment::get(); return rb_funcall(module_handle, rb_intern("class_variable_set"), 2, env->get_handle(prefixed_by("@@", name)), value); }
void test_native_method_environment_get_Symbol_handle() { NativeMethodEnvironment* nme = create_native_method_environment(); Symbol* sym = state->symbol("capi_symbol"); TS_ASSERT_EQUALS(sym, reinterpret_cast<Symbol*>(nme->get_handle(sym))); destroy_native_method_environment(nme); }
void test_native_method_environment_get_Fixnum_handle() { NativeMethodEnvironment* nme = create_native_method_environment(); Fixnum* fix = Fixnum::from(28); TS_ASSERT_EQUALS(fix, reinterpret_cast<Fixnum*>(nme->get_handle(fix))); destroy_native_method_environment(nme); }
VALUE rb_ivar_get(VALUE self_handle, ID ivar_name) { NativeMethodEnvironment* env = NativeMethodEnvironment::get(); Object* object = env->get_object(self_handle); Symbol* sym = reinterpret_cast<Symbol*>(ivar_name); return env->get_handle(object->get_ivar(env->state(), sym)); }
VALUE rb_str_buf_new(long capacity) { NativeMethodEnvironment* env = NativeMethodEnvironment::get(); String* str = String::create(env->state(), Fixnum::from(capacity)); str->num_bytes(env->state(), Fixnum::from(0)); return env->get_handle(str); }
VALUE rb_gv_get(const char* name) { NativeMethodEnvironment* env = NativeMethodEnvironment::get(); long len; len = strlen(name); if((len == 1 && name[0] == '~') || (len == 2 && name[0] == '$' && name[1] == '~')) { return env->get_handle(Regexp::last_match_result(env->state(), Fixnum::from(0), Fixnum::from(0), env->current_call_frame())); } VALUE Globals = rb_const_get(rb_mRubinius, rb_intern("Globals")); return rb_funcall(Globals, rb_intern("[]"), 1, env->get_handle(prefixed_by(env->state(), '$', rb_intern(name)))); }
VALUE rb_tainted_str_new(const char* string, long size) { NativeMethodEnvironment* env = NativeMethodEnvironment::get(); String* str = String::create(env->state(), string, size); str->taint(env->state()); return env->get_handle(str); }
VALUE rb_proc_new(VALUE (*func)(ANYARGS), VALUE val) { NativeMethodEnvironment* env = NativeMethodEnvironment::get(); int arity = ITERATE_BLOCK; Proc* prc = capi::wrap_c_function((void*)func, val, arity); return env->get_handle(prc); }
VALUE rb_proc_new(VALUE (*func)(ANYARGS), VALUE val) { NativeMethodEnvironment* env = NativeMethodEnvironment::get(); int arity = LANGUAGE_18_ENABLED(env->state()) ? C_LAMBDA : ITERATE_BLOCK; Proc* prc = capi::wrap_c_function((void*)func, val, arity); return env->get_handle(prc); }
VALUE rb_const_get(VALUE module_handle, ID name) { NativeMethodEnvironment* env = NativeMethodEnvironment::get(); Module* module = c_as<Module>(env->get_object(module_handle)); return env->get_handle(module->get_const(env->state(), reinterpret_cast<Symbol*>(name))); }
VALUE rb_cstr_to_inum(const char* str, int base, int badcheck) { NativeMethodEnvironment* env = NativeMethodEnvironment::get(); Integer* i = Integer::from_cstr(env->state(), str, str + strlen(str), base, RBOOL(badcheck)); if(i->nil_p()) { rb_raise(rb_eArgError, "invalid string for Integer"); } return env->get_handle(i); }
VALUE rb_ivar_defined(VALUE obj_handle, ID ivar_name) { NativeMethodEnvironment* env = NativeMethodEnvironment::get(); Symbol* ivar = reinterpret_cast<Symbol*>(ivar_name); Object* obj = env->get_object(obj_handle); Object* ret = obj->ivar_defined(env->state(), ivar); return env->get_handle(ret); }
void rb_str_update(VALUE self, long beg, long end, VALUE replacement) { NativeMethodEnvironment* env = NativeMethodEnvironment::get(); String* string = capi_get_string(env, self); Class* klass = Module::mirror(env->state(), string); VALUE mirror = capi_fast_call(env->get_handle(klass), rb_intern("new"), 1, self); capi_fast_call(mirror, rb_intern("splice"), 3, LONG2FIX(beg), LONG2FIX(end), replacement); }
VALUE rb_ary_shift(VALUE self) { NativeMethodEnvironment* env = NativeMethodEnvironment::get(); Array* array = capi_get_array(env, self); Object* obj = array->shift(env->state()); capi_update_array(env, self); return env->get_handle(obj); }
VALUE rb_ary_pop(VALUE self_handle) { NativeMethodEnvironment* env = NativeMethodEnvironment::get(); Array* self = capi_get_array(env, self_handle); Object* obj = self->pop(env->state()); capi_update_array(env, self_handle); return env->get_handle(obj); }
void test_native_method_environment_get_object() { NativeMethodEnvironment* nme = create_native_method_environment(); String* str = String::create(state, "test"); Integer* id = str->id(state); VALUE handle = nme->get_handle(str); TS_ASSERT_EQUALS(id, nme->get_object(handle)->id(state)); destroy_native_method_environment(nme); }