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_yield_values(int n, ...) { NativeMethodEnvironment* env = NativeMethodEnvironment::get(); Object* blk = env->block(); if(!CBOOL(blk)) { rb_raise(rb_eLocalJumpError, "no block given", 0); } if(n == 0) { return capi_yield_backend(env, blk, 0, 0); } Object* vars[n]; va_list args; va_start(args, n); for(int i = 0; i < n; ++i) { vars[i] = env->get_object(va_arg(args, VALUE)); } va_end(args); return capi_yield_backend(env, blk, n, vars); }
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 rb_yield(VALUE argument_handle) { NativeMethodEnvironment* env = NativeMethodEnvironment::get(); if (!rb_block_given_p()) { rb_raise(rb_eLocalJumpError, "no block given", 0); } VALUE block_handle = env->get_handle(env->block()); return rb_funcall(block_handle, rb_intern("call"), 1, argument_handle); }
VALUE rb_block_call(VALUE obj, ID meth, int argc, VALUE* argv, VALUE(*cb)(ANYARGS), VALUE cb_data) { NativeMethodEnvironment* env = NativeMethodEnvironment::get(); if(cb) { Proc* prc = capi::wrap_c_function((void*)cb, cb_data, C_BLOCK_CALL); env->set_outgoing_block(env->get_handle(prc)); } else { env->set_outgoing_block(env->get_handle(env->block())); } return rb_funcall2(obj, meth, argc, argv); }
VALUE rb_yield(VALUE argument_handle) { NativeMethodEnvironment* env = NativeMethodEnvironment::get(); Object* blk = env->block(); if(!CBOOL(blk)) { rb_raise(rb_eLocalJumpError, "no block given", 0); } Object* arg = env->get_object(argument_handle); return capi_yield_backend(env, blk, 1, &arg); }
Object* NativeMethod::executor_implementation(STATE, CallFrame* call_frame, Dispatch& msg, Arguments& args) { NativeMethod* nm = as<NativeMethod>(msg.method); int arity = nm->arity()->to_int(); if(arity >= 0 && (size_t)arity != args.total()) { Exception* exc = Exception::make_argument_error( state, arity, args.total(), msg.name); exc->locations(state, System::vm_backtrace(state, Fixnum::from(1), call_frame)); state->thread_state()->raise_exception(exc); return NULL; } NativeMethodEnvironment* env = native_method_environment.get(); NativeMethodFrame nmf(env->current_native_frame()); CallFrame* saved_frame = env->current_call_frame(); Object* saved_block = env->block(); env->set_current_call_frame(call_frame); env->set_current_native_frame(&nmf); env->set_current_block(args.block()); Object* ret; ExceptionPoint ep(env); PLACE_EXCEPTION_POINT(ep); if(unlikely(ep.jumped_to())) { ret = NULL; } else { #ifdef RBX_PROFILER if(unlikely(state->shared.profiling())) { profiler::MethodEntry method(state, msg, args); ret = nm->call(state, env, args); } else { ret = nm->call(state, env, args); } #else ret = nm->call(state, env, args); #endif } env->set_current_block(saved_block); env->set_current_call_frame(saved_frame); env->set_current_native_frame(nmf.previous()); ep.pop(env); return ret; }
Proc* wrap_c_function(void* cb, VALUE cb_data, int arity) { NativeMethodEnvironment* env = NativeMethodEnvironment::get(); NativeMethod* nm = NativeMethod::create(env->state(), nil<String>(), env->state()->vm()->shared.globals.rubinius.get(), env->state()->symbol("call"), cb, Fixnum::from(arity), 0); nm->set_ivar(env->state(), env->state()->symbol("cb_data"), env->get_object(cb_data)); Object* current_block = env->block(); if(!current_block->nil_p()) { nm->set_ivar(env->state(), env->state()->symbol("original_block"), current_block); } Proc* prc = Proc::create(env->state(), env->state()->vm()->shared.globals.proc.get()); prc->bound_method(env->state(), nm); return prc; }
VALUE rb_yield_splat(VALUE array_handle) { NativeMethodEnvironment* env = NativeMethodEnvironment::get(); Object* blk = env->block(); if(!CBOOL(blk)) { rb_raise(rb_eLocalJumpError, "no block given", 0); } if(Array* ary = try_as<Array>(env->get_object(array_handle))) { int count = ary->size(); Object* vars[count]; for(int i = 0; i < count; i++) { vars[i] = ary->get(env->state(), i); } return capi_yield_backend(env, blk, count, vars); } return capi_yield_backend(env, blk, 0, 0); }
VALUE rb_block_proc() { NativeMethodEnvironment* env = NativeMethodEnvironment::get(); return rb_funcall(rb_cProc, rb_intern("__from_block__"), 1, env->get_handle(env->block())); }
int rb_block_given_p() { NativeMethodEnvironment* env = NativeMethodEnvironment::get(); return CBOOL(env->block()); }
VALUE rb_block_proc() { NativeMethodEnvironment* env = NativeMethodEnvironment::get(); return rb_funcall(rb_mCAPI, rb_intern("rb_block_proc"), 1, env->get_handle(env->block())); }