From 1f2f3fa83a93d7b21306f1fd0b1e1793cc3a5b2c Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Sun, 26 Jan 2014 18:58:16 -0800 Subject: [PATCH] src: update MakeCallback() function prototype Make it possible to invoke MakeCallback() on a v8::Value but only for the variant that takes a v8::Function as the thing to call. The const char* and v8::String variants still require a v8::Object because the function to call is looked up as a property on the receiver, but that only works when the receiver is an object, not a primitive. --- src/node.cc | 125 +++++++++++++++++++++++++++------------------------ src/node.h | 10 ++--- src/node_internals.h | 12 ++--- 3 files changed, 77 insertions(+), 70 deletions(-) diff --git a/src/node.cc b/src/node.cc index c1ecdcd..cd0c32f 100644 --- a/src/node.cc +++ b/src/node.cc @@ -940,7 +940,7 @@ void SetupNextTick(const FunctionCallbackInfo& args) { Handle MakeDomainCallback(Environment* env, - Handle object, + Handle recv, const Handle callback, int argc, Handle argv[]) { @@ -948,42 +948,51 @@ Handle MakeDomainCallback(Environment* env, assert(env->context() == env->isolate()->GetCurrentContext()); Local process = env->process_object(); - Local domain_v = object->Get(env->domain_string()); - Local domain; + Local object, domain; + Local domain_v; TryCatch try_catch; try_catch.SetVerbose(true); - // TODO(trevnorris): This is sucky for performance. Fix it. - bool has_async_queue = object->Has(env->async_queue_string()); - if (has_async_queue) { - Local argv[] = { object }; - env->async_listener_load_function()->Call(process, ARRAY_SIZE(argv), argv); + bool has_async_queue = false; - if (try_catch.HasCaught()) - return Undefined(node_isolate); + if (recv->IsObject()) { + object = recv.As(); + // TODO(trevnorris): This is sucky for performance. Fix it. + has_async_queue = object->Has(env->async_queue_string()); + if (has_async_queue) { + env->async_listener_load_function()->Call(process, 1, &recv); + + if (try_catch.HasCaught()) + return Undefined(node_isolate); + } } - bool has_domain = domain_v->IsObject(); - if (has_domain) { - domain = domain_v.As(); + bool has_domain = false; - if (domain->Get(env->disposed_string())->IsTrue()) { - // domain has been disposed of. - return Undefined(node_isolate); - } + if (!object.IsEmpty()) { + domain_v = object->Get(env->domain_string()); + has_domain = domain_v->IsObject(); + if (has_domain) { + domain = domain_v.As(); - Local enter = - domain->Get(env->enter_string()).As(); - assert(enter->IsFunction()); - enter->Call(domain, 0, NULL); + if (domain->Get(env->disposed_string())->IsTrue()) { + // domain has been disposed of. + return Undefined(node_isolate); + } - if (try_catch.HasCaught()) { - return Undefined(node_isolate); + Local enter = + domain->Get(env->enter_string()).As(); + assert(enter->IsFunction()); + enter->Call(domain, 0, NULL); + + if (try_catch.HasCaught()) { + return Undefined(node_isolate); + } } } - Local ret = callback->Call(object, argc, argv); + Local ret = callback->Call(recv, argc, argv); if (try_catch.HasCaught()) { return Undefined(node_isolate); @@ -1001,8 +1010,7 @@ Handle MakeDomainCallback(Environment* env, } if (has_async_queue) { - Local val = object.As(); - env->async_listener_unload_function()->Call(process, 1, &val); + env->async_listener_unload_function()->Call(process, 1, &recv); if (try_catch.HasCaught()) return Undefined(node_isolate); @@ -1040,12 +1048,12 @@ Handle MakeDomainCallback(Environment* env, Handle MakeCallback(Environment* env, - Handle object, + Handle recv, const Handle callback, int argc, Handle argv[]) { if (env->using_domains()) - return MakeDomainCallback(env, object, callback, argc, argv); + return MakeDomainCallback(env, recv, callback, argc, argv); // If you hit this assertion, you forgot to enter the v8::Context first. assert(env->context() == env->isolate()->GetCurrentContext()); @@ -1056,24 +1064,22 @@ Handle MakeCallback(Environment* env, try_catch.SetVerbose(true); // TODO(trevnorris): This is sucky for performance. Fix it. - bool has_async_queue = object->Has(env->async_queue_string()); + bool has_async_queue = + recv->IsObject() && recv.As()->Has(env->async_queue_string()); if (has_async_queue) { - Local argv[] = { object }; - env->async_listener_load_function()->Call(process, ARRAY_SIZE(argv), argv); - + env->async_listener_load_function()->Call(process, 1, &recv); if (try_catch.HasCaught()) return Undefined(node_isolate); } - Local ret = callback->Call(object, argc, argv); + Local ret = callback->Call(recv, argc, argv); if (try_catch.HasCaught()) { return Undefined(node_isolate); } if (has_async_queue) { - Local val = object.As(); - env->async_listener_unload_function()->Call(process, 1, &val); + env->async_listener_unload_function()->Call(process, 1, &recv); if (try_catch.HasCaught()) return Undefined(node_isolate); @@ -1108,84 +1114,85 @@ Handle MakeCallback(Environment* env, // Internal only. Handle MakeCallback(Environment* env, - const Handle object, + Handle recv, uint32_t index, int argc, Handle argv[]) { - Local callback = object->Get(index).As(); + Local callback = recv->Get(index).As(); assert(callback->IsFunction()); - return MakeCallback(env, object, callback, argc, argv); + return MakeCallback(env, recv.As(), callback, argc, argv); } Handle MakeCallback(Environment* env, - const Handle object, - const Handle symbol, + Handle recv, + Handle symbol, int argc, Handle argv[]) { - Local callback = object->Get(symbol).As(); + Local callback = recv->Get(symbol).As(); assert(callback->IsFunction()); - return MakeCallback(env, object, callback, argc, argv); + return MakeCallback(env, recv.As(), callback, argc, argv); } Handle MakeCallback(Environment* env, - const Handle object, + Handle recv, const char* method, int argc, Handle argv[]) { Local method_string = OneByteString(node_isolate, method); - return MakeCallback(env, object, method_string, argc, argv); + return MakeCallback(env, recv, method_string, argc, argv); } -Handle MakeCallback(const Handle object, +Handle MakeCallback(Handle recv, const char* method, int argc, Handle argv[]) { - Local context = object->CreationContext(); + Local context = recv->CreationContext(); Environment* env = Environment::GetCurrent(context); Context::Scope context_scope(context); HandleScope handle_scope(env->isolate()); - return handle_scope.Close(MakeCallback(env, object, method, argc, argv)); + return handle_scope.Close(MakeCallback(env, recv, method, argc, argv)); } -Handle MakeCallback(const Handle object, - const Handle symbol, +Handle MakeCallback(Handle recv, + Handle symbol, int argc, Handle argv[]) { - Local context = object->CreationContext(); + Local context = recv->CreationContext(); Environment* env = Environment::GetCurrent(context); Context::Scope context_scope(context); HandleScope handle_scope(env->isolate()); - return handle_scope.Close(MakeCallback(env, object, symbol, argc, argv)); + return handle_scope.Close(MakeCallback(env, recv, symbol, argc, argv)); } -Handle MakeCallback(const Handle object, - const Handle callback, +Handle MakeCallback(Handle recv, + Handle callback, int argc, Handle argv[]) { - Local context = object->CreationContext(); + Local context = recv->CreationContext(); Environment* env = Environment::GetCurrent(context); Context::Scope context_scope(context); HandleScope handle_scope(env->isolate()); - return handle_scope.Close(MakeCallback(env, object, callback, argc, argv)); + return handle_scope.Close( + MakeCallback(env, recv.As(), callback, argc, argv)); } -Handle MakeDomainCallback(const Handle object, - const Handle callback, +Handle MakeDomainCallback(Handle recv, + Handle callback, int argc, Handle argv[]) { - Local context = object->CreationContext(); + Local context = recv->CreationContext(); Environment* env = Environment::GetCurrent(context); Context::Scope context_scope(context); HandleScope handle_scope(env->isolate()); return handle_scope.Close( - MakeDomainCallback(env, object, callback, argc, argv)); + MakeDomainCallback(env, recv, callback, argc, argv)); } diff --git a/src/node.h b/src/node.h index 5dbf28f..2ab0cf1 100644 --- a/src/node.h +++ b/src/node.h @@ -86,18 +86,18 @@ NODE_EXTERN v8::Local UVException(int errorno, */ NODE_EXTERN v8::Handle MakeCallback( - const v8::Handle recv, + v8::Handle recv, const char* method, int argc, v8::Handle* argv); NODE_EXTERN v8::Handle MakeCallback( - const v8::Handle object, - const v8::Handle symbol, + v8::Handle recv, + v8::Handle symbol, int argc, v8::Handle* argv); NODE_EXTERN v8::Handle MakeCallback( - const v8::Handle object, - const v8::Handle callback, + v8::Handle recv, + v8::Handle callback, int argc, v8::Handle* argv); diff --git a/src/node_internals.h b/src/node_internals.h index e92aa2e..614ccbd 100644 --- a/src/node_internals.h +++ b/src/node_internals.h @@ -49,29 +49,29 @@ inline v8::Local PersistentToLocal( // Call with valid HandleScope and while inside Context scope. v8::Handle MakeCallback(Environment* env, - v8::Handle object, + v8::Handle recv, const char* method, int argc = 0, v8::Handle* argv = NULL); // Call with valid HandleScope and while inside Context scope. v8::Handle MakeCallback(Environment* env, - const v8::Handle object, + v8::Handle recv, uint32_t index, int argc = 0, v8::Handle* argv = NULL); // Call with valid HandleScope and while inside Context scope. v8::Handle MakeCallback(Environment* env, - const v8::Handle object, - const v8::Handle symbol, + v8::Handle recv, + v8::Handle symbol, int argc = 0, v8::Handle* argv = NULL); // Call with valid HandleScope and while inside Context scope. v8::Handle MakeCallback(Environment* env, - const v8::Handle object, - const v8::Handle callback, + v8::Handle recv, + v8::Handle callback, int argc = 0, v8::Handle* argv = NULL); -- 2.7.4