Пример #1
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;
  }
Пример #2
0
 VM* VM::current() {
   return _current_vm.get();
 }
Пример #3
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, Location::from_call_stack(state, call_frame));
      state->thread_state()->raise_exception(exc);

      return NULL;
    }

    NativeMethodEnvironment* env = native_method_environment.get();

    // Optionally get the handles back to the proper state.
    if(state->shared.config.capi_global_flush) {
      capi::Handles* handles = state->shared.cached_handles();

      if(handles->size() > 0) {
        for(capi::Handles::Iterator i(*handles); i.more(); i.advance()) {
          i->update(env);
        }
      }
    }

    // Register the CallFrame, because we might GC below this.
    state->set_call_frame(call_frame);

    NativeMethodFrame nmf(env->current_native_frame());

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

    // Be sure to do this after installing nmf as the current
    // native frame.
    nmf.setup(
        env->get_handle(args.recv()),
        env->get_handle(args.block()),
        env->get_handle(msg.method),
        env->get_handle(msg.module));

    Object* ret;
    ExceptionPoint ep(env);

    PLACE_EXCEPTION_POINT(ep);

    if(unlikely(ep.jumped_to())) {
      ret = NULL;
    } else {
#ifdef RBX_PROFILER
      if(unlikely(state->tooling())) {
        tooling::MethodEntry method(state, msg, args);
        ret = ArgumentHandler::invoke(state, nm, env, args);
      } else {
        ret = ArgumentHandler::invoke(state, nm, env, args);
      }
#else
      ret = ArgumentHandler::invoke(state, nm, env, args);
#endif
    }

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

    // Handle any signals that occurred while the native method
    // was running.
    if(!state->check_async(call_frame)) return NULL;

    return ret;
  }
Пример #4
0
 NativeMethodEnvironment* NativeMethodEnvironment::get() {
   return native_method_environment.get();
 }
Пример #5
0
 void NativeMethod::cleanup_thread(STATE) {
   delete native_method_environment.get();
   native_method_environment.set(NULL);
 }
Пример #6
0
  Object* NativeMethod::executor_implementation(STATE,
      CallFrame* call_frame, Executable* exec, Module* mod, Arguments& args) {
    NativeMethod* nm = as<NativeMethod>(exec);

    int arity = nm->arity()->to_int();

    if(arity >= 0 && (size_t)arity != args.total()) {
      Exception* exc = Exception::make_argument_error(
          state, arity, args.total(), args.name());
      exc->locations(state, Location::from_call_stack(state, call_frame));
      state->raise_exception(exc);

      return NULL;
    }

    NativeMethodEnvironment* env = native_method_environment.get();

    // Optionally get the handles back to the proper state.
    if(state->shared().config.capi_global_flush) {
      capi::Handles* handles = state->shared().cached_handles();

      if(handles->size() > 0) {
        for(capi::Handles::Iterator i(*handles); i.more(); i.advance()) {
          i->update(env);
        }
      }
    }

    // Register the CallFrame, because we might GC below this.
    state->set_call_frame(call_frame);

    NativeMethodFrame nmf(env->current_native_frame());
    CallFrame cf;
    cf.previous = call_frame;
    cf.cm = 0;
    cf.scope = 0;
    cf.dispatch_data = (void*)&nmf;
    cf.flags = CallFrame::cNativeMethod;

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

    // Be sure to do this after installing nmf as the current
    // native frame.
    nmf.setup(
        env->get_handle(args.recv()),
        env->get_handle(args.block()),
        env->get_handle(exec),
        env->get_handle(mod));

    // We've got things setup (they can be GC'd properly), so we need to
    // wait before entering the extension code.
    ENTER_CAPI(state);

    Object* ret;
    ExceptionPoint ep(env);

    PLACE_EXCEPTION_POINT(ep);

    if(unlikely(ep.jumped_to())) {
      ret = NULL;
    } else {
#ifdef RBX_PROFILER
      if(unlikely(state->vm()->tooling())) {
        tooling::MethodEntry method(state, exec, mod, args);
        ret = ArgumentHandler::invoke(state, nm, env, args);
      } else {
        ret = ArgumentHandler::invoke(state, nm, env, args);
      }
#else
      ret = ArgumentHandler::invoke(state, nm, env, args);
#endif
    }

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

    LEAVE_CAPI(state);

    // Handle any signals that occurred while the native method
    // was running.
    if(!state->check_async(call_frame)) return NULL;

    return ret;
  }