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