Skip to content

Commit d3c317e

Browse files
bnoordhuisindutny
authored andcommitted
src: attach env directly to api functions
Attach the per-context execution environment directly to API functions. Rationale: * Gets node one step closer to multi-isolate readiness. * Avoids multi-context confusion, e.g. when the caller and callee live in different contexts. * Avoids expensive calls to pthread_getspecific() on platforms where V8 does not know how to use the thread-local storage directly. (Linux, the BSDs.) PR-URL: node-forward/node#18 Reviewed-By: Fedor Indutny <fedor@indutny.com>
1 parent b45d336 commit d3c317e

29 files changed

+655
-617
lines changed

src/cares_wrap.cc

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -840,7 +840,7 @@ class GetHostByNameWrap: public QueryWrap {
840840

841841
template <class Wrap>
842842
static void Query(const FunctionCallbackInfo<Value>& args) {
843-
Environment* env = Environment::GetCurrent(args.GetIsolate());
843+
Environment* env = Environment::GetCurrent(args);
844844

845845
CHECK_EQ(false, args.IsConstructCall());
846846
CHECK(args[0]->IsObject());
@@ -1003,7 +1003,7 @@ static void IsIP(const FunctionCallbackInfo<Value>& args) {
10031003

10041004

10051005
static void GetAddrInfo(const FunctionCallbackInfo<Value>& args) {
1006-
Environment* env = Environment::GetCurrent(args.GetIsolate());
1006+
Environment* env = Environment::GetCurrent(args);
10071007

10081008
CHECK(args[0]->IsObject());
10091009
CHECK(args[1]->IsString());
@@ -1055,7 +1055,7 @@ static void GetAddrInfo(const FunctionCallbackInfo<Value>& args) {
10551055

10561056

10571057
static void GetNameInfo(const FunctionCallbackInfo<Value>& args) {
1058-
Environment* env = Environment::GetCurrent(args.GetIsolate());
1058+
Environment* env = Environment::GetCurrent(args);
10591059

10601060
CHECK(args[0]->IsObject());
10611061
CHECK(args[1]->IsString());
@@ -1087,7 +1087,7 @@ static void GetNameInfo(const FunctionCallbackInfo<Value>& args) {
10871087

10881088

10891089
static void GetServers(const FunctionCallbackInfo<Value>& args) {
1090-
Environment* env = Environment::GetCurrent(args.GetIsolate());
1090+
Environment* env = Environment::GetCurrent(args);
10911091

10921092
Local<Array> server_array = Array::New(env->isolate());
10931093

@@ -1116,7 +1116,7 @@ static void GetServers(const FunctionCallbackInfo<Value>& args) {
11161116

11171117

11181118
static void SetServers(const FunctionCallbackInfo<Value>& args) {
1119-
Environment* env = Environment::GetCurrent(args.GetIsolate());
1119+
Environment* env = Environment::GetCurrent(args);
11201120

11211121
CHECK(args[0]->IsArray());
11221122

@@ -1184,7 +1184,7 @@ static void SetServers(const FunctionCallbackInfo<Value>& args) {
11841184

11851185

11861186
static void StrError(const FunctionCallbackInfo<Value>& args) {
1187-
Environment* env = Environment::GetCurrent(args.GetIsolate());
1187+
Environment* env = Environment::GetCurrent(args);
11881188
const char* errmsg = ares_strerror(args[0]->Int32Value());
11891189
args.GetReturnValue().Set(OneByteString(env->isolate(), errmsg));
11901190
}
@@ -1232,24 +1232,24 @@ static void Initialize(Handle<Object> target,
12321232
CaresTimerClose,
12331233
NULL);
12341234

1235-
NODE_SET_METHOD(target, "queryA", Query<QueryAWrap>);
1236-
NODE_SET_METHOD(target, "queryAaaa", Query<QueryAaaaWrap>);
1237-
NODE_SET_METHOD(target, "queryCname", Query<QueryCnameWrap>);
1238-
NODE_SET_METHOD(target, "queryMx", Query<QueryMxWrap>);
1239-
NODE_SET_METHOD(target, "queryNs", Query<QueryNsWrap>);
1240-
NODE_SET_METHOD(target, "queryTxt", Query<QueryTxtWrap>);
1241-
NODE_SET_METHOD(target, "querySrv", Query<QuerySrvWrap>);
1242-
NODE_SET_METHOD(target, "queryNaptr", Query<QueryNaptrWrap>);
1243-
NODE_SET_METHOD(target, "querySoa", Query<QuerySoaWrap>);
1244-
NODE_SET_METHOD(target, "getHostByAddr", Query<GetHostByAddrWrap>);
1245-
1246-
NODE_SET_METHOD(target, "getaddrinfo", GetAddrInfo);
1247-
NODE_SET_METHOD(target, "getnameinfo", GetNameInfo);
1248-
NODE_SET_METHOD(target, "isIP", IsIP);
1249-
1250-
NODE_SET_METHOD(target, "strerror", StrError);
1251-
NODE_SET_METHOD(target, "getServers", GetServers);
1252-
NODE_SET_METHOD(target, "setServers", SetServers);
1235+
env->SetMethod(target, "queryA", Query<QueryAWrap>);
1236+
env->SetMethod(target, "queryAaaa", Query<QueryAaaaWrap>);
1237+
env->SetMethod(target, "queryCname", Query<QueryCnameWrap>);
1238+
env->SetMethod(target, "queryMx", Query<QueryMxWrap>);
1239+
env->SetMethod(target, "queryNs", Query<QueryNsWrap>);
1240+
env->SetMethod(target, "queryTxt", Query<QueryTxtWrap>);
1241+
env->SetMethod(target, "querySrv", Query<QuerySrvWrap>);
1242+
env->SetMethod(target, "queryNaptr", Query<QueryNaptrWrap>);
1243+
env->SetMethod(target, "querySoa", Query<QuerySoaWrap>);
1244+
env->SetMethod(target, "getHostByAddr", Query<GetHostByAddrWrap>);
1245+
1246+
env->SetMethod(target, "getaddrinfo", GetAddrInfo);
1247+
env->SetMethod(target, "getnameinfo", GetNameInfo);
1248+
env->SetMethod(target, "isIP", IsIP);
1249+
1250+
env->SetMethod(target, "strerror", StrError);
1251+
env->SetMethod(target, "getServers", GetServers);
1252+
env->SetMethod(target, "setServers", SetServers);
12531253

12541254
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "AF_INET"),
12551255
Integer::New(env->isolate(), AF_INET));

src/env-inl.h

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,18 @@ inline Environment* Environment::GetCurrent(v8::Local<v8::Context> context) {
209209
context->GetAlignedPointerFromEmbedderData(kContextEmbedderDataIndex));
210210
}
211211

212+
inline Environment* Environment::GetCurrent(
213+
const v8::FunctionCallbackInfo<v8::Value>& info) {
214+
ASSERT(info.Data()->IsExternal());
215+
return static_cast<Environment*>(info.Data().As<v8::External>()->Value());
216+
}
217+
218+
inline Environment* Environment::GetCurrent(
219+
const v8::PropertyCallbackInfo<v8::Value>& info) {
220+
ASSERT(info.Data()->IsExternal());
221+
return static_cast<Environment*>(info.Data().As<v8::External>()->Value());
222+
}
223+
212224
inline Environment::Environment(v8::Local<v8::Context> context,
213225
uv_loop_t* loop)
214226
: isolate_(context->GetIsolate()),
@@ -437,6 +449,50 @@ inline void Environment::ThrowUVException(int errorno,
437449
UVException(isolate(), errorno, syscall, message, path));
438450
}
439451

452+
inline v8::Local<v8::FunctionTemplate>
453+
Environment::NewFunctionTemplate(v8::FunctionCallback callback,
454+
v8::Local<v8::Signature> signature) {
455+
v8::Local<v8::External> external;
456+
if (external_.IsEmpty()) {
457+
external = v8::External::New(isolate(), this);
458+
external_.Reset(isolate(), external);
459+
} else {
460+
external = StrongPersistentToLocal(external_);
461+
}
462+
return v8::FunctionTemplate::New(isolate(), callback, external, signature);
463+
}
464+
465+
inline void Environment::SetMethod(v8::Local<v8::Object> that,
466+
const char* name,
467+
v8::FunctionCallback callback) {
468+
v8::Local<v8::Function> function =
469+
NewFunctionTemplate(callback)->GetFunction();
470+
v8::Local<v8::String> name_string = v8::String::NewFromUtf8(isolate(), name);
471+
that->Set(name_string, function);
472+
function->SetName(name_string); // NODE_SET_METHOD() compatibility.
473+
}
474+
475+
inline void Environment::SetProtoMethod(v8::Local<v8::FunctionTemplate> that,
476+
const char* name,
477+
v8::FunctionCallback callback) {
478+
v8::Local<v8::Signature> signature = v8::Signature::New(isolate(), that);
479+
v8::Local<v8::Function> function =
480+
NewFunctionTemplate(callback, signature)->GetFunction();
481+
v8::Local<v8::String> name_string = v8::String::NewFromUtf8(isolate(), name);
482+
that->PrototypeTemplate()->Set(name_string, function);
483+
function->SetName(name_string); // NODE_SET_PROTOTYPE_METHOD() compatibility.
484+
}
485+
486+
inline void Environment::SetTemplateMethod(v8::Local<v8::FunctionTemplate> that,
487+
const char* name,
488+
v8::FunctionCallback callback) {
489+
v8::Local<v8::Function> function =
490+
NewFunctionTemplate(callback)->GetFunction();
491+
v8::Local<v8::String> name_string = v8::String::NewFromUtf8(isolate(), name);
492+
that->Set(name_string, function);
493+
function->SetName(name_string); // NODE_SET_METHOD() compatibility.
494+
}
495+
440496
#define V(PropertyName, StringValue) \
441497
inline \
442498
v8::Local<v8::String> Environment::IsolateData::PropertyName() const { \

src/env.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,10 @@ class Environment {
380380

381381
static inline Environment* GetCurrent(v8::Isolate* isolate);
382382
static inline Environment* GetCurrent(v8::Local<v8::Context> context);
383+
static inline Environment* GetCurrent(
384+
const v8::FunctionCallbackInfo<v8::Value>& info);
385+
static inline Environment* GetCurrent(
386+
const v8::PropertyCallbackInfo<v8::Value>& info);
383387

384388
// See CreateEnvironment() in src/node.cc.
385389
static inline Environment* New(v8::Local<v8::Context> context,
@@ -451,6 +455,23 @@ class Environment {
451455
inline static void ThrowTypeError(v8::Isolate* isolate, const char* errmsg);
452456
inline static void ThrowRangeError(v8::Isolate* isolate, const char* errmsg);
453457

458+
inline v8::Local<v8::FunctionTemplate>
459+
NewFunctionTemplate(v8::FunctionCallback callback,
460+
v8::Local<v8::Signature> signature =
461+
v8::Local<v8::Signature>());
462+
463+
// Convenience methods for NewFunctionTemplate().
464+
inline void SetMethod(v8::Local<v8::Object> that,
465+
const char* name,
466+
v8::FunctionCallback callback);
467+
inline void SetProtoMethod(v8::Local<v8::FunctionTemplate> that,
468+
const char* name,
469+
v8::FunctionCallback callback);
470+
inline void SetTemplateMethod(v8::Local<v8::FunctionTemplate> that,
471+
const char* name,
472+
v8::FunctionCallback callback);
473+
474+
454475
// Strings are shared across shared contexts. The getters simply proxy to
455476
// the per-isolate primitive.
456477
#define V(PropertyName, StringValue) \
@@ -509,6 +530,8 @@ class Environment {
509530
QUEUE handle_cleanup_queue_;
510531
int handle_cleanup_waiting_;
511532

533+
v8::Persistent<v8::External> external_;
534+
512535
#define V(PropertyName, TypeName) \
513536
v8::Persistent<TypeName> PropertyName ## _;
514537
ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES(V)

src/fs_event_wrap.cc

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,26 +83,26 @@ void FSEventWrap::Initialize(Handle<Object> target,
8383
Handle<Context> context) {
8484
Environment* env = Environment::GetCurrent(context);
8585

86-
Local<FunctionTemplate> t = FunctionTemplate::New(env->isolate(), New);
86+
Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
8787
t->InstanceTemplate()->SetInternalFieldCount(1);
8888
t->SetClassName(env->fsevent_string());
8989

90-
NODE_SET_PROTOTYPE_METHOD(t, "start", Start);
91-
NODE_SET_PROTOTYPE_METHOD(t, "close", Close);
90+
env->SetProtoMethod(t, "start", Start);
91+
env->SetProtoMethod(t, "close", Close);
9292

9393
target->Set(env->fsevent_string(), t->GetFunction());
9494
}
9595

9696

9797
void FSEventWrap::New(const FunctionCallbackInfo<Value>& args) {
9898
CHECK(args.IsConstructCall());
99-
Environment* env = Environment::GetCurrent(args.GetIsolate());
99+
Environment* env = Environment::GetCurrent(args);
100100
new FSEventWrap(env, args.This());
101101
}
102102

103103

104104
void FSEventWrap::Start(const FunctionCallbackInfo<Value>& args) {
105-
Environment* env = Environment::GetCurrent(args.GetIsolate());
105+
Environment* env = Environment::GetCurrent(args);
106106

107107
FSEventWrap* wrap = Unwrap<FSEventWrap>(args.Holder());
108108

src/handle_wrap.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ void HandleWrap::Unref(const FunctionCallbackInfo<Value>& args) {
6161

6262

6363
void HandleWrap::Close(const FunctionCallbackInfo<Value>& args) {
64-
Environment* env = Environment::GetCurrent(args.GetIsolate());
64+
Environment* env = Environment::GetCurrent(args);
6565

6666
HandleWrap* wrap = Unwrap<HandleWrap>(args.Holder());
6767

0 commit comments

Comments
 (0)