Skip to content

Commit 1f2f3fa

Browse files
bnoordhuistjfontaine
authored andcommitted
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.
1 parent 528a3ce commit 1f2f3fa

3 files changed

Lines changed: 77 additions & 70 deletions

File tree

src/node.cc

Lines changed: 66 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -940,50 +940,59 @@ void SetupNextTick(const FunctionCallbackInfo<Value>& args) {
940940

941941

942942
Handle<Value> MakeDomainCallback(Environment* env,
943-
Handle<Object> object,
943+
Handle<Value> recv,
944944
const Handle<Function> callback,
945945
int argc,
946946
Handle<Value> argv[]) {
947947
// If you hit this assertion, you forgot to enter the v8::Context first.
948948
assert(env->context() == env->isolate()->GetCurrentContext());
949949

950950
Local<Object> process = env->process_object();
951-
Local<Value> domain_v = object->Get(env->domain_string());
952-
Local<Object> domain;
951+
Local<Object> object, domain;
952+
Local<Value> domain_v;
953953

954954
TryCatch try_catch;
955955
try_catch.SetVerbose(true);
956956

957-
// TODO(trevnorris): This is sucky for performance. Fix it.
958-
bool has_async_queue = object->Has(env->async_queue_string());
959-
if (has_async_queue) {
960-
Local<Value> argv[] = { object };
961-
env->async_listener_load_function()->Call(process, ARRAY_SIZE(argv), argv);
957+
bool has_async_queue = false;
962958

963-
if (try_catch.HasCaught())
964-
return Undefined(node_isolate);
959+
if (recv->IsObject()) {
960+
object = recv.As<Object>();
961+
// TODO(trevnorris): This is sucky for performance. Fix it.
962+
has_async_queue = object->Has(env->async_queue_string());
963+
if (has_async_queue) {
964+
env->async_listener_load_function()->Call(process, 1, &recv);
965+
966+
if (try_catch.HasCaught())
967+
return Undefined(node_isolate);
968+
}
965969
}
966970

967-
bool has_domain = domain_v->IsObject();
968-
if (has_domain) {
969-
domain = domain_v.As<Object>();
971+
bool has_domain = false;
970972

971-
if (domain->Get(env->disposed_string())->IsTrue()) {
972-
// domain has been disposed of.
973-
return Undefined(node_isolate);
974-
}
973+
if (!object.IsEmpty()) {
974+
domain_v = object->Get(env->domain_string());
975+
has_domain = domain_v->IsObject();
976+
if (has_domain) {
977+
domain = domain_v.As<Object>();
975978

976-
Local<Function> enter =
977-
domain->Get(env->enter_string()).As<Function>();
978-
assert(enter->IsFunction());
979-
enter->Call(domain, 0, NULL);
979+
if (domain->Get(env->disposed_string())->IsTrue()) {
980+
// domain has been disposed of.
981+
return Undefined(node_isolate);
982+
}
980983

981-
if (try_catch.HasCaught()) {
982-
return Undefined(node_isolate);
984+
Local<Function> enter =
985+
domain->Get(env->enter_string()).As<Function>();
986+
assert(enter->IsFunction());
987+
enter->Call(domain, 0, NULL);
988+
989+
if (try_catch.HasCaught()) {
990+
return Undefined(node_isolate);
991+
}
983992
}
984993
}
985994

986-
Local<Value> ret = callback->Call(object, argc, argv);
995+
Local<Value> ret = callback->Call(recv, argc, argv);
987996

988997
if (try_catch.HasCaught()) {
989998
return Undefined(node_isolate);
@@ -1001,8 +1010,7 @@ Handle<Value> MakeDomainCallback(Environment* env,
10011010
}
10021011

10031012
if (has_async_queue) {
1004-
Local<Value> val = object.As<Value>();
1005-
env->async_listener_unload_function()->Call(process, 1, &val);
1013+
env->async_listener_unload_function()->Call(process, 1, &recv);
10061014

10071015
if (try_catch.HasCaught())
10081016
return Undefined(node_isolate);
@@ -1040,12 +1048,12 @@ Handle<Value> MakeDomainCallback(Environment* env,
10401048

10411049

10421050
Handle<Value> MakeCallback(Environment* env,
1043-
Handle<Object> object,
1051+
Handle<Value> recv,
10441052
const Handle<Function> callback,
10451053
int argc,
10461054
Handle<Value> argv[]) {
10471055
if (env->using_domains())
1048-
return MakeDomainCallback(env, object, callback, argc, argv);
1056+
return MakeDomainCallback(env, recv, callback, argc, argv);
10491057

10501058
// If you hit this assertion, you forgot to enter the v8::Context first.
10511059
assert(env->context() == env->isolate()->GetCurrentContext());
@@ -1056,24 +1064,22 @@ Handle<Value> MakeCallback(Environment* env,
10561064
try_catch.SetVerbose(true);
10571065

10581066
// TODO(trevnorris): This is sucky for performance. Fix it.
1059-
bool has_async_queue = object->Has(env->async_queue_string());
1067+
bool has_async_queue =
1068+
recv->IsObject() && recv.As<Object>()->Has(env->async_queue_string());
10601069
if (has_async_queue) {
1061-
Local<Value> argv[] = { object };
1062-
env->async_listener_load_function()->Call(process, ARRAY_SIZE(argv), argv);
1063-
1070+
env->async_listener_load_function()->Call(process, 1, &recv);
10641071
if (try_catch.HasCaught())
10651072
return Undefined(node_isolate);
10661073
}
10671074

1068-
Local<Value> ret = callback->Call(object, argc, argv);
1075+
Local<Value> ret = callback->Call(recv, argc, argv);
10691076

10701077
if (try_catch.HasCaught()) {
10711078
return Undefined(node_isolate);
10721079
}
10731080

10741081
if (has_async_queue) {
1075-
Local<Value> val = object.As<Value>();
1076-
env->async_listener_unload_function()->Call(process, 1, &val);
1082+
env->async_listener_unload_function()->Call(process, 1, &recv);
10771083

10781084
if (try_catch.HasCaught())
10791085
return Undefined(node_isolate);
@@ -1108,84 +1114,85 @@ Handle<Value> MakeCallback(Environment* env,
11081114

11091115
// Internal only.
11101116
Handle<Value> MakeCallback(Environment* env,
1111-
const Handle<Object> object,
1117+
Handle<Object> recv,
11121118
uint32_t index,
11131119
int argc,
11141120
Handle<Value> argv[]) {
1115-
Local<Function> callback = object->Get(index).As<Function>();
1121+
Local<Function> callback = recv->Get(index).As<Function>();
11161122
assert(callback->IsFunction());
11171123

1118-
return MakeCallback(env, object, callback, argc, argv);
1124+
return MakeCallback(env, recv.As<Value>(), callback, argc, argv);
11191125
}
11201126

11211127

11221128
Handle<Value> MakeCallback(Environment* env,
1123-
const Handle<Object> object,
1124-
const Handle<String> symbol,
1129+
Handle<Object> recv,
1130+
Handle<String> symbol,
11251131
int argc,
11261132
Handle<Value> argv[]) {
1127-
Local<Function> callback = object->Get(symbol).As<Function>();
1133+
Local<Function> callback = recv->Get(symbol).As<Function>();
11281134
assert(callback->IsFunction());
1129-
return MakeCallback(env, object, callback, argc, argv);
1135+
return MakeCallback(env, recv.As<Value>(), callback, argc, argv);
11301136
}
11311137

11321138

11331139
Handle<Value> MakeCallback(Environment* env,
1134-
const Handle<Object> object,
1140+
Handle<Object> recv,
11351141
const char* method,
11361142
int argc,
11371143
Handle<Value> argv[]) {
11381144
Local<String> method_string = OneByteString(node_isolate, method);
1139-
return MakeCallback(env, object, method_string, argc, argv);
1145+
return MakeCallback(env, recv, method_string, argc, argv);
11401146
}
11411147

11421148

1143-
Handle<Value> MakeCallback(const Handle<Object> object,
1149+
Handle<Value> MakeCallback(Handle<Object> recv,
11441150
const char* method,
11451151
int argc,
11461152
Handle<Value> argv[]) {
1147-
Local<Context> context = object->CreationContext();
1153+
Local<Context> context = recv->CreationContext();
11481154
Environment* env = Environment::GetCurrent(context);
11491155
Context::Scope context_scope(context);
11501156
HandleScope handle_scope(env->isolate());
1151-
return handle_scope.Close(MakeCallback(env, object, method, argc, argv));
1157+
return handle_scope.Close(MakeCallback(env, recv, method, argc, argv));
11521158
}
11531159

11541160

1155-
Handle<Value> MakeCallback(const Handle<Object> object,
1156-
const Handle<String> symbol,
1161+
Handle<Value> MakeCallback(Handle<Object> recv,
1162+
Handle<String> symbol,
11571163
int argc,
11581164
Handle<Value> argv[]) {
1159-
Local<Context> context = object->CreationContext();
1165+
Local<Context> context = recv->CreationContext();
11601166
Environment* env = Environment::GetCurrent(context);
11611167
Context::Scope context_scope(context);
11621168
HandleScope handle_scope(env->isolate());
1163-
return handle_scope.Close(MakeCallback(env, object, symbol, argc, argv));
1169+
return handle_scope.Close(MakeCallback(env, recv, symbol, argc, argv));
11641170
}
11651171

11661172

1167-
Handle<Value> MakeCallback(const Handle<Object> object,
1168-
const Handle<Function> callback,
1173+
Handle<Value> MakeCallback(Handle<Object> recv,
1174+
Handle<Function> callback,
11691175
int argc,
11701176
Handle<Value> argv[]) {
1171-
Local<Context> context = object->CreationContext();
1177+
Local<Context> context = recv->CreationContext();
11721178
Environment* env = Environment::GetCurrent(context);
11731179
Context::Scope context_scope(context);
11741180
HandleScope handle_scope(env->isolate());
1175-
return handle_scope.Close(MakeCallback(env, object, callback, argc, argv));
1181+
return handle_scope.Close(
1182+
MakeCallback(env, recv.As<Value>(), callback, argc, argv));
11761183
}
11771184

11781185

1179-
Handle<Value> MakeDomainCallback(const Handle<Object> object,
1180-
const Handle<Function> callback,
1186+
Handle<Value> MakeDomainCallback(Handle<Object> recv,
1187+
Handle<Function> callback,
11811188
int argc,
11821189
Handle<Value> argv[]) {
1183-
Local<Context> context = object->CreationContext();
1190+
Local<Context> context = recv->CreationContext();
11841191
Environment* env = Environment::GetCurrent(context);
11851192
Context::Scope context_scope(context);
11861193
HandleScope handle_scope(env->isolate());
11871194
return handle_scope.Close(
1188-
MakeDomainCallback(env, object, callback, argc, argv));
1195+
MakeDomainCallback(env, recv, callback, argc, argv));
11891196
}
11901197

11911198

src/node.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,18 +86,18 @@ NODE_EXTERN v8::Local<v8::Value> UVException(int errorno,
8686
*/
8787

8888
NODE_EXTERN v8::Handle<v8::Value> MakeCallback(
89-
const v8::Handle<v8::Object> recv,
89+
v8::Handle<v8::Object> recv,
9090
const char* method,
9191
int argc,
9292
v8::Handle<v8::Value>* argv);
9393
NODE_EXTERN v8::Handle<v8::Value> MakeCallback(
94-
const v8::Handle<v8::Object> object,
95-
const v8::Handle<v8::String> symbol,
94+
v8::Handle<v8::Object> recv,
95+
v8::Handle<v8::String> symbol,
9696
int argc,
9797
v8::Handle<v8::Value>* argv);
9898
NODE_EXTERN v8::Handle<v8::Value> MakeCallback(
99-
const v8::Handle<v8::Object> object,
100-
const v8::Handle<v8::Function> callback,
99+
v8::Handle<v8::Object> recv,
100+
v8::Handle<v8::Function> callback,
101101
int argc,
102102
v8::Handle<v8::Value>* argv);
103103

src/node_internals.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,29 +49,29 @@ inline v8::Local<TypeName> PersistentToLocal(
4949

5050
// Call with valid HandleScope and while inside Context scope.
5151
v8::Handle<v8::Value> MakeCallback(Environment* env,
52-
v8::Handle<v8::Object> object,
52+
v8::Handle<v8::Object> recv,
5353
const char* method,
5454
int argc = 0,
5555
v8::Handle<v8::Value>* argv = NULL);
5656

5757
// Call with valid HandleScope and while inside Context scope.
5858
v8::Handle<v8::Value> MakeCallback(Environment* env,
59-
const v8::Handle<v8::Object> object,
59+
v8::Handle<v8::Object> recv,
6060
uint32_t index,
6161
int argc = 0,
6262
v8::Handle<v8::Value>* argv = NULL);
6363

6464
// Call with valid HandleScope and while inside Context scope.
6565
v8::Handle<v8::Value> MakeCallback(Environment* env,
66-
const v8::Handle<v8::Object> object,
67-
const v8::Handle<v8::String> symbol,
66+
v8::Handle<v8::Object> recv,
67+
v8::Handle<v8::String> symbol,
6868
int argc = 0,
6969
v8::Handle<v8::Value>* argv = NULL);
7070

7171
// Call with valid HandleScope and while inside Context scope.
7272
v8::Handle<v8::Value> MakeCallback(Environment* env,
73-
const v8::Handle<v8::Object> object,
74-
const v8::Handle<v8::Function> callback,
73+
v8::Handle<v8::Value> recv,
74+
v8::Handle<v8::Function> callback,
7575
int argc = 0,
7676
v8::Handle<v8::Value>* argv = NULL);
7777

0 commit comments

Comments
 (0)