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