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. 93
      src/node.cc
  2. 10
      src/node.h
  3. 12
      src/node_internals.h

93
src/node.cc

@ -940,7 +940,7 @@ void SetupNextTick(const FunctionCallbackInfo<Value>& args) {
Handle<Value> MakeDomainCallback(Environment* env,
Handle<Object> object,
Handle<Value> recv,
const Handle<Function> callback,
int argc,
Handle<Value> argv[]) {
@ -948,23 +948,31 @@ Handle<Value> MakeDomainCallback(Environment* env,
assert(env->context() == env->isolate()->GetCurrentContext());
Local<Object> process = env->process_object();
Local<Value> domain_v = object->Get(env->domain_string());
Local<Object> domain;
Local<Object> object, domain;
Local<Value> domain_v;
TryCatch try_catch;
try_catch.SetVerbose(true);
bool has_async_queue = false;
if (recv->IsObject()) {
object = recv.As<Object>();
// TODO(trevnorris): This is sucky for performance. Fix it.
bool has_async_queue = object->Has(env->async_queue_string());
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);
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 (!object.IsEmpty()) {
domain_v = object->Get(env->domain_string());
has_domain = domain_v->IsObject();
if (has_domain) {
domain = domain_v.As<Object>();
@ -982,8 +990,9 @@ Handle<Value> MakeDomainCallback(Environment* env,
return Undefined(node_isolate);
}
}
}
Local<Value> ret = callback->Call(object, argc, argv);
Local<Value> ret = callback->Call(recv, argc, argv);
if (try_catch.HasCaught()) {
return Undefined(node_isolate);
@ -1001,8 +1010,7 @@ Handle<Value> MakeDomainCallback(Environment* env,
}
if (has_async_queue) {
Local<Value> val = object.As<Value>();
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<Value> MakeDomainCallback(Environment* env,
Handle<Value> MakeCallback(Environment* env,
Handle<Object> object,
Handle<Value> recv,
const Handle<Function> callback,
int argc,
Handle<Value> 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<Value> 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<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);
env->async_listener_load_function()->Call(process, 1, &recv);
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()) {
return Undefined(node_isolate);
}
if (has_async_queue) {
Local<Value> val = object.As<Value>();
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<Value> MakeCallback(Environment* env,
// Internal only.
Handle<Value> MakeCallback(Environment* env,
const Handle<Object> object,
Handle<Object> recv,
uint32_t index,
int argc,
Handle<Value> argv[]) {
Local<Function> callback = object->Get(index).As<Function>();
Local<Function> callback = recv->Get(index).As<Function>();
assert(callback->IsFunction());
return MakeCallback(env, object, callback, argc, argv);
return MakeCallback(env, recv.As<Value>(), callback, argc, argv);
}
Handle<Value> MakeCallback(Environment* env,
const Handle<Object> object,
const Handle<String> symbol,
Handle<Object> recv,
Handle<String> symbol,
int argc,
Handle<Value> argv[]) {
Local<Function> callback = object->Get(symbol).As<Function>();
Local<Function> callback = recv->Get(symbol).As<Function>();
assert(callback->IsFunction());
return MakeCallback(env, object, callback, argc, argv);
return MakeCallback(env, recv.As<Value>(), callback, argc, argv);
}
Handle<Value> MakeCallback(Environment* env,
const Handle<Object> object,
Handle<Object> recv,
const char* method,
int argc,
Handle<Value> argv[]) {
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,
int argc,
Handle<Value> argv[]) {
Local<Context> context = object->CreationContext();
Local<Context> 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<Value> MakeCallback(const Handle<Object> object,
const Handle<String> symbol,
Handle<Value> MakeCallback(Handle<Object> recv,
Handle<String> symbol,
int argc,
Handle<Value> argv[]) {
Local<Context> context = object->CreationContext();
Local<Context> 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<Value> MakeCallback(const Handle<Object> object,
const Handle<Function> callback,
Handle<Value> MakeCallback(Handle<Object> recv,
Handle<Function> callback,
int argc,
Handle<Value> argv[]) {
Local<Context> context = object->CreationContext();
Local<Context> 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<Value>(), callback, argc, argv));
}
Handle<Value> MakeDomainCallback(const Handle<Object> object,
const Handle<Function> callback,
Handle<Value> MakeDomainCallback(Handle<Object> recv,
Handle<Function> callback,
int argc,
Handle<Value> argv[]) {
Local<Context> context = object->CreationContext();
Local<Context> 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));
}

10
src/node.h

@ -86,18 +86,18 @@ NODE_EXTERN v8::Local<v8::Value> UVException(int errorno,
*/
NODE_EXTERN v8::Handle<v8::Value> MakeCallback(
const v8::Handle<v8::Object> recv,
v8::Handle<v8::Object> recv,
const char* method,
int argc,
v8::Handle<v8::Value>* argv);
NODE_EXTERN v8::Handle<v8::Value> MakeCallback(
const v8::Handle<v8::Object> object,
const v8::Handle<v8::String> symbol,
v8::Handle<v8::Object> recv,
v8::Handle<v8::String> symbol,
int argc,
v8::Handle<v8::Value>* argv);
NODE_EXTERN v8::Handle<v8::Value> MakeCallback(
const v8::Handle<v8::Object> object,
const v8::Handle<v8::Function> callback,
v8::Handle<v8::Object> recv,
v8::Handle<v8::Function> callback,
int argc,
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.
v8::Handle<v8::Value> MakeCallback(Environment* env,
v8::Handle<v8::Object> object,
v8::Handle<v8::Object> recv,
const char* method,
int argc = 0,
v8::Handle<v8::Value>* argv = NULL);
// Call with valid HandleScope and while inside Context scope.
v8::Handle<v8::Value> MakeCallback(Environment* env,
const v8::Handle<v8::Object> object,
v8::Handle<v8::Object> recv,
uint32_t index,
int argc = 0,
v8::Handle<v8::Value>* argv = NULL);
// Call with valid HandleScope and while inside Context scope.
v8::Handle<v8::Value> MakeCallback(Environment* env,
const v8::Handle<v8::Object> object,
const v8::Handle<v8::String> symbol,
v8::Handle<v8::Object> recv,
v8::Handle<v8::String> symbol,
int argc = 0,
v8::Handle<v8::Value>* argv = NULL);
// Call with valid HandleScope and while inside Context scope.
v8::Handle<v8::Value> MakeCallback(Environment* env,
const v8::Handle<v8::Object> object,
const v8::Handle<v8::Function> callback,
v8::Handle<v8::Value> recv,
v8::Handle<v8::Function> callback,
int argc = 0,
v8::Handle<v8::Value>* argv = NULL);

Loading…
Cancel
Save