コード例 #1
0
ファイル: thread.cpp プロジェクト: JesseChavez/rubinius
  Object* run_function(STATE) {
    NativeMethodEnvironment* env = NativeMethodEnvironment::get();

    Thread* thread = state->vm()->thread();

    NativeMethod* nm = capi::c_as<NativeMethod>(
        thread->variable_get(state, state->symbol("function")));
    Pointer* ptr = capi::c_as<Pointer>(
        thread->variable_get(state, state->symbol("argument")));

    NativeMethodFrame nmf(env, 0, nm);
    CallFrame call_frame;
    call_frame.previous = NULL;
    call_frame.lexical_scope_ = 0;
    call_frame.dispatch_data = (void*)&nmf;
    call_frame.compiled_code = 0;
    call_frame.flags = CallFrame::cNativeMethod;
    call_frame.top_scope_ = 0;
    call_frame.scope = 0;
    call_frame.arguments = 0;

    env->set_current_call_frame(&call_frame);
    env->set_current_native_frame(&nmf);

    state->vm()->set_call_frame(&call_frame);

    nmf.setup(
        env->get_handle(thread),
        env->get_handle(cNil),
        env->get_handle(nm),
        env->get_handle(nm->module()));

    ENTER_CAPI(state);

    Object* value = NULL;

    ExceptionPoint ep(env);

    PLACE_EXCEPTION_POINT(ep);

    if(unlikely(ep.jumped_to())) {
      LEAVE_CAPI(state);

      // Set exception in thread so it's raised when joining.
      state->vm()->thread()->exception(state,
          capi::c_as<Exception>(state->vm()->thread_state()->current_exception()));
    } else {
      value = env->get_object(nm->func()(ptr->pointer));
    }

    LEAVE_CAPI(state);

    env->set_current_call_frame(NULL);
    env->set_current_native_frame(NULL);
    ep.pop(env);

    return value;
  }
コード例 #2
0
ファイル: nativemethod.cpp プロジェクト: dziulius/rubinius
  NativeMethod* NativeMethod::create(State* state, String* file_name,
                                     Module* module, Symbol* method_name,
                                     void* func, Fixnum* arity)
  {
    NativeMethod* nmethod = state->new_object<NativeMethod>(G(nmethod));

    nmethod->arity(state, arity);
    nmethod->file(state, file_name);
    nmethod->name(state, method_name);
    nmethod->module(state, module);

    nmethod->func_ = func;

    switch(arity->to_native()) {
    case 0:
      nmethod->set_executor(&NativeMethod::executor_implementation<ZeroArguments>);
      break;

    case 1:
      nmethod->set_executor(&NativeMethod::executor_implementation<OneArgument>);
      break;

    case 2:
      nmethod->set_executor(&NativeMethod::executor_implementation<TwoArguments>);
      break;

    case 3:
      nmethod->set_executor(&NativeMethod::executor_implementation<ThreeArguments>);
      break;

    default:
      nmethod->set_executor(&NativeMethod::executor_implementation<GenericArguments>);
      break;
    }

    nmethod->primitive(state, state->symbol("nativemethod_call"));
    nmethod->serial(state, Fixnum::from(0));
    nmethod->inliners_ = 0;

    return nmethod;
  }
コード例 #3
0
ファイル: nativemethod.hpp プロジェクト: gustin/rubinius
      static NativeMethod* create(VM* state,
                                  String* file_name = as<String>(Qnil),
                                  Module* module = as<Module>(Qnil),
                                  Symbol* method_name = as<Symbol>(Qnil),
                                  FunctorType functor = static_cast<GenericFunctor>(NULL),
                                  Fixnum* arity = as<Fixnum>(Qnil))
      {
        NativeMethod* nmethod = state->new_object<NativeMethod>(G(nmethod));

        nmethod->arity(state, arity);
        nmethod->file_name(state, file_name);
        nmethod->method_name(state, method_name);
        nmethod->module(state, module);

        nmethod->functor(state, MemoryPointer::create(state, reinterpret_cast<void*>(functor)));

        nmethod->set_executor(&NativeMethod::executor_implementation);

        nmethod->primitive(state, state->symbol("nativemethod_call"));
        nmethod->serial(state, Fixnum::from(0));

        return nmethod;
      }
コード例 #4
0
ファイル: thread.cpp プロジェクト: Locke23rus/rubinius
  Object* run_function(STATE) {
    NativeMethodEnvironment* env = NativeMethodEnvironment::get();

    Thread* self = state->vm()->thread.get();

    NativeMethod* nm = capi::c_as<NativeMethod>(self->locals_aref(state, state->symbol("function")));
    Pointer* ptr = capi::c_as<Pointer>(self->locals_aref(state, state->symbol("argument")));

    self->locals_remove(state, state->symbol("function"));
    self->locals_remove(state, state->symbol("argument"));

    GCTokenImpl gct;

    NativeMethodFrame nmf(env, 0, nm);
    CallFrame cf;
    cf.previous = 0;
    cf.constant_scope_ = 0;
    cf.dispatch_data = (void*)&nmf;
    cf.compiled_code = 0;
    cf.flags = CallFrame::cNativeMethod;
    cf.optional_jit_data = 0;
    cf.top_scope_ = 0;
    cf.scope = 0;
    cf.arguments = 0;

    CallFrame* saved_frame = env->current_call_frame();
    env->set_current_call_frame(&cf);
    env->set_current_native_frame(&nmf);

    nmf.setup(
        env->get_handle(self),
        env->get_handle(cNil),
        env->get_handle(nm),
        env->get_handle(nm->module()));

    {
      OnStack<3> os(state, self, nm, ptr);
      self->hard_unlock(state, gct, &cf);
    }

    ENTER_CAPI(state);

    Object* ret = NULL;

    ExceptionPoint ep(env);

    PLACE_EXCEPTION_POINT(ep);

    if(unlikely(ep.jumped_to())) {
      // Setup exception in thread so it's raised when joining
      // Reload self because it might have been moved
      self = state->vm()->thread.get();
      CallFrame* call_frame = env->current_call_frame();

      {
        OnStack<1> os(state, self);
        self->hard_lock(state, gct, call_frame, false);
        Exception* exc = capi::c_as<Exception>(self->current_exception(state));
        self->exception(state, exc);
        self->alive(state, cFalse);
        self->hard_unlock(state, gct, call_frame);
      }
      return NULL;
    } else {
      ret = env->get_object(nm->func()(ptr->pointer));
    }

    LEAVE_CAPI(state);

    env->set_current_call_frame(saved_frame);
    env->set_current_native_frame(nmf.previous());
    ep.pop(env);

    self = state->vm()->thread.get();

    OnStack<1> os(state, self);

    self->hard_lock(state, gct, &cf, false);
    self->alive(state, cFalse);
    self->hard_unlock(state, gct, &cf);

    return ret;
  }