Ejemplo n.º 1
0
  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);
  }
Ejemplo n.º 2
0
  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);
  }
Ejemplo n.º 3
0
  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);
  }
Ejemplo n.º 4
0
  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);
  }
Ejemplo n.º 5
0
  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);
  }
Ejemplo n.º 6
0
  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);
  }
Ejemplo n.º 7
0
  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;
  }
Ejemplo n.º 8
0
    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;
    }
Ejemplo n.º 9
0
  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);
  }
Ejemplo n.º 10
0
 VALUE rb_block_proc() {
   NativeMethodEnvironment* env = NativeMethodEnvironment::get();
   return rb_funcall(rb_cProc, rb_intern("__from_block__"), 1, env->get_handle(env->block()));
 }
Ejemplo n.º 11
0
 int rb_block_given_p() {
   NativeMethodEnvironment* env = NativeMethodEnvironment::get();
   return CBOOL(env->block());
 }
Ejemplo n.º 12
0
 VALUE rb_block_proc() {
   NativeMethodEnvironment* env = NativeMethodEnvironment::get();
   return rb_funcall(rb_mCAPI, rb_intern("rb_block_proc"), 1,
       env->get_handle(env->block()));
 }