Ejemplo n.º 1
0
    VALUE capi_call_super_native(NativeMethodEnvironment* env,
                                 size_t arg_count, Object** args)
    {
      int marker = 0;
      if(!env->state()->check_stack(env->current_call_frame(), &marker)) {
        env->current_ep()->return_to(env);
      }

      env->flush_cached_data();

      NativeMethodFrame* frame = NativeMethodFrame::current();

      Object* recv = env->get_object(frame->receiver());
      Module* mod =  c_as<Module>(env->get_object(frame->module()));
      Symbol* name = c_as<NativeMethod>(env->get_object(frame->method()))->name();

      LookupData lookup(recv, mod->superclass(), true);
      Arguments args_o(recv, arg_count, args);
      Dispatch dis(name);

      Object* ret = dis.send(env->state(), env->current_call_frame(),
                             lookup, args_o);

      env->update_cached_data();

      // An exception occurred
      if(!ret) env->current_ep()->return_to(env);

      return env->get_handle(ret);
    }
Ejemplo n.º 2
0
    VALUE capi_call_super_native(NativeMethodEnvironment* env,
                                 size_t arg_count, Object** args)
    {
      int marker = 0;
      if(!capi_check_interrupts(env->state(), env->current_call_frame(), &marker)) {
        env->current_ep()->return_to(env);
      }

      env->flush_cached_data();

      NativeMethodFrame* frame = NativeMethodFrame::current();

      Object* recv = env->get_object(frame->receiver());
      Module* mod =  c_as<Module>(env->get_object(frame->module()));
      Symbol* name = c_as<NativeMethod>(env->get_object(frame->method()))->name();

      // Unlock, we're leaving extension code.
      LEAVE_CAPI(env->state());

      Object* ret = cNil;
      // Use a block objects on the stack are properly deconstructed when
      // we do a potential longjmp.
      {
        LookupData lookup(recv, mod->superclass(), env->state()->globals().sym_private.get());
        Arguments args_o(name, recv, arg_count, args);
        Dispatch dis(name);

        ret = dis.send(env->state(), env->current_call_frame(),
                       lookup, args_o);
      }

      // 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
      ENTER_CAPI(env->state());

      env->update_cached_data();

      // An exception occurred
      if(!ret) env->current_ep()->return_to(env);

      return ret_handle;
    }
Ejemplo n.º 3
0
    VALUE capi_call_super_native(NativeMethodEnvironment* env,
                                 size_t arg_count, Object** args)
    {
      int marker = 0;
      if(!env->state()->check_stack(env->current_call_frame(), &marker)) {
        env->current_ep()->return_to(env);
      }

      env->flush_cached_data();

      NativeMethodFrame* frame = NativeMethodFrame::current();

      Object* recv = env->get_object(frame->receiver());
      Module* mod =  c_as<Module>(env->get_object(frame->module()));
      Symbol* name = c_as<NativeMethod>(env->get_object(frame->method()))->name();

      // Unlock, we're leaving extension code.
      env->state()->shared.leave_capi(env->state());

      LookupData lookup(recv, mod->superclass(), true);
      Arguments args_o(name, recv, arg_count, args);
      Dispatch dis(name);

      Object* ret = dis.send(env->state(), env->current_call_frame(),
                             lookup, args_o);

      // 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;
    }