Exemple #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);
    }
Exemple #2
0
    VALUE capi_funcall_backend_native(NativeMethodEnvironment* env,
                                      const char* file, int line,
                                      Object* recv, Symbol* method,
                                      size_t arg_count,
                                      Object** args, Object* block)
    {
      int marker = 0;
      if(!env->state()->check_stack(env->current_call_frame(), &marker)) {
        env->current_ep()->return_to(env);
      }

      env->flush_cached_data();

      LookupData lookup(recv, recv->lookup_begin(env->state()), true);
      Arguments args_o(recv, block, arg_count, args);
      Dispatch dis(method);

      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);
    }
Exemple #3
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;
    }
Exemple #4
0
    VALUE capi_fast_call(VALUE receiver, ID method_name, int arg_count, ...) {
      NativeMethodEnvironment* env = NativeMethodEnvironment::get();

      va_list varargs;
      va_start(varargs, arg_count);

      Object* args[arg_count];

      for(int i = 0; i < arg_count; i++) {
        args[i] = env->get_object(va_arg(varargs, VALUE));
      }

      va_end(varargs);

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

      Object* recv = env->get_object(receiver);
      Symbol* method = (Symbol*)method_name;

      Object* ret = cNil;
      // Run in block so we properly deconstruct objects allocated
      // on the stack if we do a longjmp because of an exception.
      {
        LookupData lookup(recv, recv->lookup_begin(env->state()), env->state()->globals().sym_private.get());
        Arguments args_o(method, recv, cNil, arg_count, args);
        Dispatch dis(method);

        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());

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

      return ret_handle;
    }
Exemple #5
0
    VALUE capi_funcall_backend_native(NativeMethodEnvironment* env,
                                      const char* file, int line,
                                      Object* recv, Symbol* method,
                                      size_t arg_count,
                                      Object** args, Object* block)
    {
      int marker = 0;
      if(!capi_check_interrupts(env->state(), env->current_call_frame(), &marker)) {
        env->current_ep()->return_to(env);
      }

      env->flush_cached_data();

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

      Object* ret = cNil;

      // Run in a block so objects are properly deconstructed when we
      // do a longjmp because of an exception.
      {
        LookupData lookup(recv, recv->lookup_begin(env->state()), env->state()->globals().sym_private.get());
        Arguments args_o(method, recv, block, arg_count, args);
        Dispatch dis(method);

        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;
    }
Exemple #6
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;
    }
Exemple #7
0
    VALUE capi_funcall_backend_native(NativeMethodEnvironment* env,
                                      const char* file, int line,
                                      Object* recv, Symbol* method,
                                      size_t arg_count,
                                      Object** args, Object* block)
    {
      int marker = 0;
      if(!env->state()->check_stack(env->current_call_frame(), &marker)) {
        env->current_ep()->return_to(env);
      }

      env->flush_cached_data();

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

      LookupData lookup(recv, recv->lookup_begin(env->state()), true);
      Arguments args_o(method, recv, block, arg_count, args);
      Dispatch dis(method);

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