Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

src: upgrade to new v8::Private api #5045

Merged
merged 1 commit into from
Feb 3, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 36 additions & 12 deletions src/env-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,25 @@ inline Environment::IsolateData::IsolateData(v8::Isolate* isolate,
: event_loop_(loop),
isolate_(isolate),
#define V(PropertyName, StringValue) \
PropertyName ## _(isolate, \
v8::String::NewFromOneByte( \
isolate, \
reinterpret_cast<const uint8_t*>(StringValue), \
v8::NewStringType::kInternalized, \
sizeof(StringValue) - 1).ToLocalChecked()),
PropertyName ## _( \
isolate, \
v8::Private::ForApi( \
isolate, \
v8::String::NewFromOneByte( \
isolate, \
reinterpret_cast<const uint8_t*>(StringValue), \
v8::NewStringType::kInternalized, \
sizeof(StringValue) - 1).ToLocalChecked())),
PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(V)
#undef V
#define V(PropertyName, StringValue) \
PropertyName ## _( \
isolate, \
v8::String::NewFromOneByte( \
isolate, \
reinterpret_cast<const uint8_t*>(StringValue), \
v8::NewStringType::kInternalized, \
sizeof(StringValue) - 1).ToLocalChecked()),
PER_ISOLATE_STRING_PROPERTIES(V)
#undef V
ref_count_(0) {}
Expand Down Expand Up @@ -525,21 +538,31 @@ inline v8::Local<v8::Object> Environment::NewInternalFieldObject() {
return m_obj.ToLocalChecked();
}

#define V(PropertyName, StringValue) \
#define VP(PropertyName, StringValue) V(v8::Private, PropertyName, StringValue)
#define VS(PropertyName, StringValue) V(v8::String, PropertyName, StringValue)
#define V(TypeName, PropertyName, StringValue) \
inline \
v8::Local<v8::String> Environment::IsolateData::PropertyName() const { \
v8::Local<TypeName> Environment::IsolateData::PropertyName() const { \
/* Strings are immutable so casting away const-ness here is okay. */ \
return const_cast<IsolateData*>(this)->PropertyName ## _.Get(isolate()); \
}
PER_ISOLATE_STRING_PROPERTIES(V)
PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP)
PER_ISOLATE_STRING_PROPERTIES(VS)
#undef V
#undef VS
#undef VP

#define V(PropertyName, StringValue) \
inline v8::Local<v8::String> Environment::PropertyName() const { \
#define VP(PropertyName, StringValue) V(v8::Private, PropertyName, StringValue)
#define VS(PropertyName, StringValue) V(v8::String, PropertyName, StringValue)
#define V(TypeName, PropertyName, StringValue) \
inline v8::Local<TypeName> Environment::PropertyName() const { \
return isolate_data()->PropertyName(); \
}
PER_ISOLATE_STRING_PROPERTIES(V)
PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP)
PER_ISOLATE_STRING_PROPERTIES(VS)
#undef V
#undef VS
#undef VP

#define V(PropertyName, TypeName) \
inline v8::Local<TypeName> Environment::PropertyName() const { \
Expand All @@ -552,6 +575,7 @@ inline v8::Local<v8::Object> Environment::NewInternalFieldObject() {
#undef V

#undef ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES
#undef PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES
#undef PER_ISOLATE_STRING_PROPERTIES

} // namespace node
Expand Down
55 changes: 38 additions & 17 deletions src/env.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,24 @@ namespace node {
#define NODE_PUSH_VAL_TO_ARRAY_MAX 8
#endif

// Private symbols are per-isolate primitives but Environment proxies them
// for the sake of convenience. Strings should be ASCII-only and have a
// "node:" prefix to avoid name clashes with third-party code.
#define PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(V) \
V(alpn_buffer_private_symbol, "node:alpnBuffer") \
V(arrow_message_private_symbol, "node:arrowMessage") \
V(contextify_private_symbol, "node:contextify") \
V(decorated_private_symbol, "node:decorated") \
V(npn_buffer_private_symbol, "node:npnBuffer") \
V(processed_private_symbol, "node:processed") \
V(selected_npn_buffer_private_symbol, "node:selectedNpnBuffer") \

// Strings are per-isolate primitives but Environment proxies them
// for the sake of convenience. Strings should be ASCII-only.
#define PER_ISOLATE_STRING_PROPERTIES(V) \
V(address_string, "address") \
V(alpn_buffer_string, "alpnBuffer") \
V(args_string, "args") \
V(argv_string, "argv") \
V(arrow_message_string, "node:arrowMessage") \
V(async, "async") \
V(async_queue_string, "_asyncQueue") \
V(atime_string, "atime") \
Expand All @@ -73,7 +83,6 @@ namespace node {
V(cwd_string, "cwd") \
V(debug_port_string, "debugPort") \
V(debug_string, "debug") \
V(decorated_string, "node:decorated") \
V(dest_string, "dest") \
V(detached_string, "detached") \
V(dev_string, "dev") \
Expand Down Expand Up @@ -140,7 +149,6 @@ namespace node {
V(netmask_string, "netmask") \
V(nice_string, "nice") \
V(nlink_string, "nlink") \
V(npn_buffer_string, "npnBuffer") \
V(nsname_string, "nsname") \
V(ocsp_request_string, "OCSPRequest") \
V(offset_string, "offset") \
Expand Down Expand Up @@ -176,7 +184,6 @@ namespace node {
V(port_string, "port") \
V(preference_string, "preference") \
V(priority_string, "priority") \
V(processed_string, "processed") \
V(produce_cached_data_string, "produceCachedData") \
V(prototype_string, "prototype") \
V(raw_string, "raw") \
Expand All @@ -192,7 +199,6 @@ namespace node {
V(serial_string, "serial") \
V(scavenge_string, "scavenge") \
V(scopeid_string, "scopeid") \
V(selected_npn_buffer_string, "selectedNpnBuffer") \
V(sent_shutdown_string, "sentShutdown") \
V(serial_number_string, "serialNumber") \
V(service_string, "service") \
Expand Down Expand Up @@ -507,12 +513,17 @@ class Environment {

inline v8::Local<v8::Object> NewInternalFieldObject();

// Strings are shared across shared contexts. The getters simply proxy to
// the per-isolate primitive.
#define V(PropertyName, StringValue) \
inline v8::Local<v8::String> PropertyName() const;
PER_ISOLATE_STRING_PROPERTIES(V)
// Strings and private symbols are shared across shared contexts
// The getters simply proxy to the per-isolate primitive.
#define VP(PropertyName, StringValue) V(v8::Private, PropertyName, StringValue)
#define VS(PropertyName, StringValue) V(v8::String, PropertyName, StringValue)
#define V(TypeName, PropertyName, StringValue) \
inline v8::Local<TypeName> PropertyName() const;
PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP)
PER_ISOLATE_STRING_PROPERTIES(VS)
#undef V
#undef VS
#undef VP

#define V(PropertyName, TypeName) \
inline v8::Local<TypeName> PropertyName() const; \
Expand Down Expand Up @@ -585,10 +596,15 @@ class Environment {
inline void Put();
inline uv_loop_t* event_loop() const;

#define V(PropertyName, StringValue) \
inline v8::Local<v8::String> PropertyName() const;
PER_ISOLATE_STRING_PROPERTIES(V)
#define VP(PropertyName, StringValue) V(v8::Private, PropertyName, StringValue)
#define VS(PropertyName, StringValue) V(v8::String, PropertyName, StringValue)
#define V(TypeName, PropertyName, StringValue) \
inline v8::Local<TypeName> PropertyName() const;
PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP)
PER_ISOLATE_STRING_PROPERTIES(VS)
#undef V
#undef VS
#undef VP

private:
inline static IsolateData* Get(v8::Isolate* isolate);
Expand All @@ -598,10 +614,15 @@ class Environment {
uv_loop_t* const event_loop_;
v8::Isolate* const isolate_;

#define V(PropertyName, StringValue) \
v8::Eternal<v8::String> PropertyName ## _;
PER_ISOLATE_STRING_PROPERTIES(V)
#define VP(PropertyName, StringValue) V(v8::Private, PropertyName, StringValue)
#define VS(PropertyName, StringValue) V(v8::String, PropertyName, StringValue)
#define V(TypeName, PropertyName, StringValue) \
v8::Eternal<TypeName> PropertyName ## _;
PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP)
PER_ISOLATE_STRING_PROPERTIES(VS)
#undef V
#undef VS
#undef VP

unsigned int ref_count_;

Expand Down
35 changes: 23 additions & 12 deletions src/node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1402,8 +1402,10 @@ ssize_t DecodeWrite(Isolate* isolate,
bool IsExceptionDecorated(Environment* env, Local<Value> er) {
if (!er.IsEmpty() && er->IsObject()) {
Local<Object> err_obj = er.As<Object>();
Local<Value> decorated = err_obj->GetHiddenValue(env->decorated_string());
return !decorated.IsEmpty() && decorated->IsTrue();
auto maybe_value =
err_obj->GetPrivate(env->context(), env->decorated_private_symbol());
Local<Value> decorated;
return maybe_value.ToLocal(&decorated) && decorated->IsTrue();
}
return false;
}
Expand All @@ -1419,10 +1421,15 @@ void AppendExceptionLine(Environment* env,
if (!er.IsEmpty() && er->IsObject()) {
err_obj = er.As<Object>();

auto context = env->context();
auto processed_private_symbol = env->processed_private_symbol();
// Do it only once per message
if (!err_obj->GetHiddenValue(env->processed_string()).IsEmpty())
if (err_obj->HasPrivate(context, processed_private_symbol).FromJust())
return;
err_obj->SetHiddenValue(env->processed_string(), True(env->isolate()));
err_obj->SetPrivate(
context,
processed_private_symbol,
True(env->isolate()));
}

// Print (filename):(line number): (message).
Expand Down Expand Up @@ -1492,14 +1499,15 @@ void AppendExceptionLine(Environment* env,

Local<String> arrow_str = String::NewFromUtf8(env->isolate(), arrow);

// Allocation failed, just print it out
if (arrow_str.IsEmpty() || err_obj.IsEmpty() || !err_obj->IsNativeError())
goto print;

err_obj->SetHiddenValue(env->arrow_message_string(), arrow_str);
return;
if (!arrow_str.IsEmpty() && !err_obj.IsEmpty() && err_obj->IsNativeError()) {
err_obj->SetPrivate(
env->context(),
env->arrow_message_private_symbol(),
arrow_str);
return;
}

print:
// Allocation failed, just print it out.
if (env->printed_error())
return;
env->set_printed_error(true);
Expand All @@ -1525,7 +1533,10 @@ static void ReportException(Environment* env,
Local<Object> err_obj = er->ToObject(env->isolate());

trace_value = err_obj->Get(env->stack_string());
arrow = err_obj->GetHiddenValue(env->arrow_message_string());
arrow =
err_obj->GetPrivate(
env->context(),
env->arrow_message_private_symbol()).ToLocalChecked();
}

node::Utf8Value trace(env->isolate(), trace_value);
Expand Down
60 changes: 35 additions & 25 deletions src/node_contextify.cc
Original file line number Diff line number Diff line change
Expand Up @@ -288,11 +288,11 @@ class ContextifyContext {
}
Local<Object> sandbox = args[0].As<Object>();

Local<String> hidden_name =
FIXED_ONE_BYTE_STRING(env->isolate(), "_contextifyHidden");

// Don't allow contextifying a sandbox multiple times.
CHECK(sandbox->GetHiddenValue(hidden_name).IsEmpty());
CHECK(
!sandbox->HasPrivate(
env->context(),
env->contextify_private_symbol()).FromJust());

TryCatch try_catch;
ContextifyContext* context = new ContextifyContext(env, sandbox);
Expand All @@ -305,8 +305,10 @@ class ContextifyContext {
if (context->context().IsEmpty())
return;

Local<External> hidden_context = External::New(env->isolate(), context);
sandbox->SetHiddenValue(hidden_name, hidden_context);
sandbox->SetPrivate(
env->context(),
env->contextify_private_symbol(),
External::New(env->isolate(), context));
}


Expand All @@ -319,10 +321,9 @@ class ContextifyContext {
}
Local<Object> sandbox = args[0].As<Object>();

Local<String> hidden_name =
FIXED_ONE_BYTE_STRING(env->isolate(), "_contextifyHidden");

args.GetReturnValue().Set(!sandbox->GetHiddenValue(hidden_name).IsEmpty());
auto result =
sandbox->HasPrivate(env->context(), env->contextify_private_symbol());
args.GetReturnValue().Set(result.FromJust());
}


Expand All @@ -342,17 +343,17 @@ class ContextifyContext {


static ContextifyContext* ContextFromContextifiedSandbox(
Isolate* isolate,
Environment* env,
const Local<Object>& sandbox) {
Local<String> hidden_name =
FIXED_ONE_BYTE_STRING(isolate, "_contextifyHidden");
Local<Value> context_external_v = sandbox->GetHiddenValue(hidden_name);
if (context_external_v.IsEmpty() || !context_external_v->IsExternal()) {
return nullptr;
auto maybe_value =
sandbox->GetPrivate(env->context(), env->contextify_private_symbol());
Local<Value> context_external_v;
if (maybe_value.ToLocal(&context_external_v) &&
context_external_v->IsExternal()) {
Local<External> context_external = context_external_v.As<External>();
return static_cast<ContextifyContext*>(context_external->Value());
}
Local<External> context_external = context_external_v.As<External>();

return static_cast<ContextifyContext*>(context_external->Value());
return nullptr;
}


Expand Down Expand Up @@ -612,8 +613,7 @@ class ContextifyScript : public BaseObject {

// Get the context from the sandbox
ContextifyContext* contextify_context =
ContextifyContext::ContextFromContextifiedSandbox(env->isolate(),
sandbox);
ContextifyContext::ContextFromContextifiedSandbox(env, sandbox);
if (contextify_context == nullptr) {
return env->ThrowTypeError(
"sandbox argument must have been converted to a context.");
Expand Down Expand Up @@ -654,15 +654,25 @@ class ContextifyScript : public BaseObject {

AppendExceptionLine(env, exception, try_catch.Message());
Local<Value> stack = err_obj->Get(env->stack_string());
Local<Value> arrow = err_obj->GetHiddenValue(env->arrow_message_string());

if (!(stack->IsString() && arrow->IsString()))
auto maybe_value =
err_obj->GetPrivate(
env->context(),
env->arrow_message_private_symbol());

Local<Value> arrow;
if (!(maybe_value.ToLocal(&arrow) &&
arrow->IsString() &&
stack->IsString())) {
return;
}

Local<String> decorated_stack = String::Concat(arrow.As<String>(),
stack.As<String>());
err_obj->Set(env->stack_string(), decorated_stack);
err_obj->SetHiddenValue(env->decorated_string(), True(env->isolate()));
err_obj->SetPrivate(
env->context(),
env->decorated_private_symbol(),
True(env->isolate()));
}

static int64_t GetTimeoutArg(const FunctionCallbackInfo<Value>& args,
Expand Down
Loading