Browse Source

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.
v0.11.12-release
Ben Noordhuis 11 years ago
committed by Timothy J Fontaine
parent
commit
1f2f3fa83a
  1. 125
      src/node.cc
  2. 10
      src/node.h
  3. 12
      src/node_internals.h

125
src/node.cc

@ -940,7 +940,7 @@ void SetupNextTick(const FunctionCallbackInfo<Value>& args) {
Handle<Value> MakeDomainCallback(Environment* env, Handle<Value> MakeDomainCallback(Environment* env,
Handle<Object> object, Handle<Value> recv,
const Handle<Function> callback, const Handle<Function> callback,
int argc, int argc,
Handle<Value> argv[]) { Handle<Value> argv[]) {
@ -948,42 +948,51 @@ Handle<Value> MakeDomainCallback(Environment* env,
assert(env->context() == env->isolate()->GetCurrentContext()); assert(env->context() == env->isolate()->GetCurrentContext());
Local<Object> process = env->process_object(); Local<Object> process = env->process_object();
Local<Value> domain_v = object->Get(env->domain_string()); Local<Object> object, domain;
Local<Object> domain; Local<Value> domain_v;
TryCatch try_catch; TryCatch try_catch;
try_catch.SetVerbose(true); try_catch.SetVerbose(true);
// TODO(trevnorris): This is sucky for performance. Fix it. bool has_async_queue = false;
bool has_async_queue = object->Has(env->async_queue_string());
if (has_async_queue) {
Local<Value> argv[] = { object };
env->async_listener_load_function()->Call(process, ARRAY_SIZE(argv), argv);
if (try_catch.HasCaught()) if (recv->IsObject()) {
return Undefined(node_isolate); object = recv.As<Object>();
// 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(); bool has_domain = false;
if (has_domain) {
domain = domain_v.As<Object>();
if (domain->Get(env->disposed_string())->IsTrue()) { if (!object.IsEmpty()) {
// domain has been disposed of. domain_v = object->Get(env->domain_string());
return Undefined(node_isolate); has_domain = domain_v->IsObject();
} if (has_domain) {
domain = domain_v.As<Object>();
Local<Function> enter = if (domain->Get(env->disposed_string())->IsTrue()) {
domain->Get(env->enter_string()).As<Function>(); // domain has been disposed of.
assert(enter->IsFunction()); return Undefined(node_isolate);
enter->Call(domain, 0, NULL); }
if (try_catch.HasCaught()) { Local<Function> enter =
return Undefined(node_isolate); domain->Get(env->enter_string()).As<Function>();
assert(enter->IsFunction());
enter->Call(domain, 0, NULL);
if (try_catch.HasCaught()) {
return Undefined(node_isolate);
}
} }
} }
Local<Value> ret = callback->Call(object, argc, argv); Local<Value> ret = callback->Call(recv, argc, argv);
if (try_catch.HasCaught()) { if (try_catch.HasCaught()) {
return Undefined(node_isolate); return Undefined(node_isolate);
@ -1001,8 +1010,7 @@ Handle<Value> MakeDomainCallback(Environment* env,
} }
if (has_async_queue) { if (has_async_queue) {
Local<Value> val = object.As<Value>(); env->async_listener_unload_function()->Call(process, 1, &recv);
env->async_listener_unload_function()->Call(process, 1, &val);
if (try_catch.HasCaught()) if (try_catch.HasCaught())
return Undefined(node_isolate); return Undefined(node_isolate);
@ -1040,12 +1048,12 @@ Handle<Value> MakeDomainCallback(Environment* env,
Handle<Value> MakeCallback(Environment* env, Handle<Value> MakeCallback(Environment* env,
Handle<Object> object, Handle<Value> recv,
const Handle<Function> callback, const Handle<Function> callback,
int argc, int argc,
Handle<Value> argv[]) { Handle<Value> argv[]) {
if (env->using_domains()) 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. // If you hit this assertion, you forgot to enter the v8::Context first.
assert(env->context() == env->isolate()->GetCurrentContext()); assert(env->context() == env->isolate()->GetCurrentContext());
@ -1056,24 +1064,22 @@ Handle<Value> MakeCallback(Environment* env,
try_catch.SetVerbose(true); try_catch.SetVerbose(true);
// TODO(trevnorris): This is sucky for performance. Fix it. // 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<Object>()->Has(env->async_queue_string());
if (has_async_queue) { if (has_async_queue) {
Local<Value> argv[] = { object }; env->async_listener_load_function()->Call(process, 1, &recv);
env->async_listener_load_function()->Call(process, ARRAY_SIZE(argv), argv);
if (try_catch.HasCaught()) if (try_catch.HasCaught())
return Undefined(node_isolate); return Undefined(node_isolate);
} }
Local<Value> ret = callback->Call(object, argc, argv); Local<Value> ret = callback->Call(recv, argc, argv);
if (try_catch.HasCaught()) { if (try_catch.HasCaught()) {
return Undefined(node_isolate); return Undefined(node_isolate);
} }
if (has_async_queue) { if (has_async_queue) {
Local<Value> val = object.As<Value>(); env->async_listener_unload_function()->Call(process, 1, &recv);
env->async_listener_unload_function()->Call(process, 1, &val);
if (try_catch.HasCaught()) if (try_catch.HasCaught())
return Undefined(node_isolate); return Undefined(node_isolate);
@ -1108,84 +1114,85 @@ Handle<Value> MakeCallback(Environment* env,
// Internal only. // Internal only.
Handle<Value> MakeCallback(Environment* env, Handle<Value> MakeCallback(Environment* env,
const Handle<Object> object, Handle<Object> recv,
uint32_t index, uint32_t index,
int argc, int argc,
Handle<Value> argv[]) { Handle<Value> argv[]) {
Local<Function> callback = object->Get(index).As<Function>(); Local<Function> callback = recv->Get(index).As<Function>();
assert(callback->IsFunction()); assert(callback->IsFunction());
return MakeCallback(env, object, callback, argc, argv); return MakeCallback(env, recv.As<Value>(), callback, argc, argv);
} }
Handle<Value> MakeCallback(Environment* env, Handle<Value> MakeCallback(Environment* env,
const Handle<Object> object, Handle<Object> recv,
const Handle<String> symbol, Handle<String> symbol,
int argc, int argc,
Handle<Value> argv[]) { Handle<Value> argv[]) {
Local<Function> callback = object->Get(symbol).As<Function>(); Local<Function> callback = recv->Get(symbol).As<Function>();
assert(callback->IsFunction()); assert(callback->IsFunction());
return MakeCallback(env, object, callback, argc, argv); return MakeCallback(env, recv.As<Value>(), callback, argc, argv);
} }
Handle<Value> MakeCallback(Environment* env, Handle<Value> MakeCallback(Environment* env,
const Handle<Object> object, Handle<Object> recv,
const char* method, const char* method,
int argc, int argc,
Handle<Value> argv[]) { Handle<Value> argv[]) {
Local<String> method_string = OneByteString(node_isolate, method); Local<String> method_string = OneByteString(node_isolate, method);
return MakeCallback(env, object, method_string, argc, argv); return MakeCallback(env, recv, method_string, argc, argv);
} }
Handle<Value> MakeCallback(const Handle<Object> object, Handle<Value> MakeCallback(Handle<Object> recv,
const char* method, const char* method,
int argc, int argc,
Handle<Value> argv[]) { Handle<Value> argv[]) {
Local<Context> context = object->CreationContext(); Local<Context> context = recv->CreationContext();
Environment* env = Environment::GetCurrent(context); Environment* env = Environment::GetCurrent(context);
Context::Scope context_scope(context); Context::Scope context_scope(context);
HandleScope handle_scope(env->isolate()); 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<Value> MakeCallback(const Handle<Object> object, Handle<Value> MakeCallback(Handle<Object> recv,
const Handle<String> symbol, Handle<String> symbol,
int argc, int argc,
Handle<Value> argv[]) { Handle<Value> argv[]) {
Local<Context> context = object->CreationContext(); Local<Context> context = recv->CreationContext();
Environment* env = Environment::GetCurrent(context); Environment* env = Environment::GetCurrent(context);
Context::Scope context_scope(context); Context::Scope context_scope(context);
HandleScope handle_scope(env->isolate()); 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<Value> MakeCallback(const Handle<Object> object, Handle<Value> MakeCallback(Handle<Object> recv,
const Handle<Function> callback, Handle<Function> callback,
int argc, int argc,
Handle<Value> argv[]) { Handle<Value> argv[]) {
Local<Context> context = object->CreationContext(); Local<Context> context = recv->CreationContext();
Environment* env = Environment::GetCurrent(context); Environment* env = Environment::GetCurrent(context);
Context::Scope context_scope(context); Context::Scope context_scope(context);
HandleScope handle_scope(env->isolate()); HandleScope handle_scope(env->isolate());
return handle_scope.Close(MakeCallback(env, object, callback, argc, argv)); return handle_scope.Close(
MakeCallback(env, recv.As<Value>(), callback, argc, argv));
} }
Handle<Value> MakeDomainCallback(const Handle<Object> object, Handle<Value> MakeDomainCallback(Handle<Object> recv,
const Handle<Function> callback, Handle<Function> callback,
int argc, int argc,
Handle<Value> argv[]) { Handle<Value> argv[]) {
Local<Context> context = object->CreationContext(); Local<Context> context = recv->CreationContext();
Environment* env = Environment::GetCurrent(context); Environment* env = Environment::GetCurrent(context);
Context::Scope context_scope(context); Context::Scope context_scope(context);
HandleScope handle_scope(env->isolate()); HandleScope handle_scope(env->isolate());
return handle_scope.Close( return handle_scope.Close(
MakeDomainCallback(env, object, callback, argc, argv)); MakeDomainCallback(env, recv, callback, argc, argv));
} }

10
src/node.h

@ -86,18 +86,18 @@ NODE_EXTERN v8::Local<v8::Value> UVException(int errorno,
*/ */
NODE_EXTERN v8::Handle<v8::Value> MakeCallback( NODE_EXTERN v8::Handle<v8::Value> MakeCallback(
const v8::Handle<v8::Object> recv, v8::Handle<v8::Object> recv,
const char* method, const char* method,
int argc, int argc,
v8::Handle<v8::Value>* argv); v8::Handle<v8::Value>* argv);
NODE_EXTERN v8::Handle<v8::Value> MakeCallback( NODE_EXTERN v8::Handle<v8::Value> MakeCallback(
const v8::Handle<v8::Object> object, v8::Handle<v8::Object> recv,
const v8::Handle<v8::String> symbol, v8::Handle<v8::String> symbol,
int argc, int argc,
v8::Handle<v8::Value>* argv); v8::Handle<v8::Value>* argv);
NODE_EXTERN v8::Handle<v8::Value> MakeCallback( NODE_EXTERN v8::Handle<v8::Value> MakeCallback(
const v8::Handle<v8::Object> object, v8::Handle<v8::Object> recv,
const v8::Handle<v8::Function> callback, v8::Handle<v8::Function> callback,
int argc, int argc,
v8::Handle<v8::Value>* argv); v8::Handle<v8::Value>* argv);

12
src/node_internals.h

@ -49,29 +49,29 @@ inline v8::Local<TypeName> PersistentToLocal(
// Call with valid HandleScope and while inside Context scope. // Call with valid HandleScope and while inside Context scope.
v8::Handle<v8::Value> MakeCallback(Environment* env, v8::Handle<v8::Value> MakeCallback(Environment* env,
v8::Handle<v8::Object> object, v8::Handle<v8::Object> recv,
const char* method, const char* method,
int argc = 0, int argc = 0,
v8::Handle<v8::Value>* argv = NULL); v8::Handle<v8::Value>* argv = NULL);
// Call with valid HandleScope and while inside Context scope. // Call with valid HandleScope and while inside Context scope.
v8::Handle<v8::Value> MakeCallback(Environment* env, v8::Handle<v8::Value> MakeCallback(Environment* env,
const v8::Handle<v8::Object> object, v8::Handle<v8::Object> recv,
uint32_t index, uint32_t index,
int argc = 0, int argc = 0,
v8::Handle<v8::Value>* argv = NULL); v8::Handle<v8::Value>* argv = NULL);
// Call with valid HandleScope and while inside Context scope. // Call with valid HandleScope and while inside Context scope.
v8::Handle<v8::Value> MakeCallback(Environment* env, v8::Handle<v8::Value> MakeCallback(Environment* env,
const v8::Handle<v8::Object> object, v8::Handle<v8::Object> recv,
const v8::Handle<v8::String> symbol, v8::Handle<v8::String> symbol,
int argc = 0, int argc = 0,
v8::Handle<v8::Value>* argv = NULL); v8::Handle<v8::Value>* argv = NULL);
// Call with valid HandleScope and while inside Context scope. // Call with valid HandleScope and while inside Context scope.
v8::Handle<v8::Value> MakeCallback(Environment* env, v8::Handle<v8::Value> MakeCallback(Environment* env,
const v8::Handle<v8::Object> object, v8::Handle<v8::Value> recv,
const v8::Handle<v8::Function> callback, v8::Handle<v8::Function> callback,
int argc = 0, int argc = 0,
v8::Handle<v8::Value>* argv = NULL); v8::Handle<v8::Value>* argv = NULL);

Loading…
Cancel
Save