Commit 8394975e authored by rossberg@chromium.org's avatar rossberg@chromium.org

Expose well-known Symbols to C++ API.

BUG=341423
LOG=Y
R=arv@chromium.org, dcarney@chromium.org, rossberg@chromium.org

Review URL: https://codereview.chromium.org/483173002

Patch from Yutaka Hirano <yhirano@chromium.org>.

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23196 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent ed668b8f
...@@ -1960,7 +1960,12 @@ class V8_EXPORT Symbol : public Primitive { ...@@ -1960,7 +1960,12 @@ class V8_EXPORT Symbol : public Primitive {
// registry that is not accessible by (and cannot clash with) JavaScript code. // registry that is not accessible by (and cannot clash with) JavaScript code.
static Local<Symbol> ForApi(Isolate *isolate, Local<String> name); static Local<Symbol> ForApi(Isolate *isolate, Local<String> name);
// Well-known symbols
static Local<Symbol> GetIterator(Isolate* isolate);
static Local<Symbol> GetUnscopables(Isolate* isolate);
V8_INLINE static Symbol* Cast(v8::Value* obj); V8_INLINE static Symbol* Cast(v8::Value* obj);
private: private:
Symbol(); Symbol();
static void CheckCast(v8::Value* obj); static void CheckCast(v8::Value* obj);
......
...@@ -6152,43 +6152,57 @@ Local<Symbol> v8::Symbol::New(Isolate* isolate, Local<String> name) { ...@@ -6152,43 +6152,57 @@ Local<Symbol> v8::Symbol::New(Isolate* isolate, Local<String> name) {
} }
Local<Symbol> v8::Symbol::For(Isolate* isolate, Local<String> name) { static i::Handle<i::Symbol> SymbolFor(i::Isolate* isolate,
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); i::Handle<i::String> name,
i::Handle<i::String> i_name = Utils::OpenHandle(*name); i::Handle<i::String> part) {
i::Handle<i::JSObject> registry = i_isolate->GetSymbolRegistry(); i::Handle<i::JSObject> registry = isolate->GetSymbolRegistry();
i::Handle<i::String> part = i_isolate->factory()->for_string();
i::Handle<i::JSObject> symbols = i::Handle<i::JSObject> symbols =
i::Handle<i::JSObject>::cast( i::Handle<i::JSObject>::cast(
i::Object::GetPropertyOrElement(registry, part).ToHandleChecked()); i::Object::GetPropertyOrElement(registry, part).ToHandleChecked());
i::Handle<i::Object> symbol = i::Handle<i::Object> symbol =
i::Object::GetPropertyOrElement(symbols, i_name).ToHandleChecked(); i::Object::GetPropertyOrElement(symbols, name).ToHandleChecked();
if (!symbol->IsSymbol()) { if (!symbol->IsSymbol()) {
DCHECK(symbol->IsUndefined()); DCHECK(symbol->IsUndefined());
symbol = i_isolate->factory()->NewSymbol(); symbol = isolate->factory()->NewSymbol();
i::Handle<i::Symbol>::cast(symbol)->set_name(*i_name); i::Handle<i::Symbol>::cast(symbol)->set_name(*name);
i::JSObject::SetProperty(symbols, i_name, symbol, i::STRICT).Assert(); i::JSObject::SetProperty(symbols, name, symbol, i::STRICT).Assert();
} }
return Utils::ToLocal(i::Handle<i::Symbol>::cast(symbol)); return i::Handle<i::Symbol>::cast(symbol);
}
Local<Symbol> v8::Symbol::For(Isolate* isolate, Local<String> name) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
i::Handle<i::String> i_name = Utils::OpenHandle(*name);
i::Handle<i::String> part = i_isolate->factory()->for_string();
return Utils::ToLocal(SymbolFor(i_isolate, i_name, part));
} }
Local<Symbol> v8::Symbol::ForApi(Isolate* isolate, Local<String> name) { Local<Symbol> v8::Symbol::ForApi(Isolate* isolate, Local<String> name) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
i::Handle<i::String> i_name = Utils::OpenHandle(*name); i::Handle<i::String> i_name = Utils::OpenHandle(*name);
i::Handle<i::JSObject> registry = i_isolate->GetSymbolRegistry();
i::Handle<i::String> part = i_isolate->factory()->for_api_string(); i::Handle<i::String> part = i_isolate->factory()->for_api_string();
i::Handle<i::JSObject> symbols = return Utils::ToLocal(SymbolFor(i_isolate, i_name, part));
i::Handle<i::JSObject>::cast( }
i::Object::GetPropertyOrElement(registry, part).ToHandleChecked());
i::Handle<i::Object> symbol =
i::Object::GetPropertyOrElement(symbols, i_name).ToHandleChecked(); static Local<Symbol> GetWellKnownSymbol(Isolate* isolate, const char* name) {
if (!symbol->IsSymbol()) { i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
DCHECK(symbol->IsUndefined()); i::Handle<i::String> i_name =
symbol = i_isolate->factory()->NewSymbol(); Utils::OpenHandle(*String::NewFromUtf8(isolate, name));
i::Handle<i::Symbol>::cast(symbol)->set_name(*i_name); i::Handle<i::String> part = i_isolate->factory()->for_intern_string();
i::JSObject::SetProperty(symbols, i_name, symbol, i::STRICT).Assert(); return Utils::ToLocal(SymbolFor(i_isolate, i_name, part));
} }
return Utils::ToLocal(i::Handle<i::Symbol>::cast(symbol));
Local<Symbol> v8::Symbol::GetIterator(Isolate* isolate) {
return GetWellKnownSymbol(isolate, "Symbol.iterator");
}
Local<Symbol> v8::Symbol::GetUnscopables(Isolate* isolate) {
return GetWellKnownSymbol(isolate, "Symbol.unscopables");
} }
......
...@@ -294,6 +294,7 @@ namespace internal { ...@@ -294,6 +294,7 @@ namespace internal {
V(Symbol_string, "Symbol") \ V(Symbol_string, "Symbol") \
V(for_string, "for") \ V(for_string, "for") \
V(for_api_string, "for_api") \ V(for_api_string, "for_api") \
V(for_intern_string, "for_intern") \
V(private_api_string, "private_api") \ V(private_api_string, "private_api") \
V(private_intern_string, "private_intern") \ V(private_intern_string, "private_intern") \
V(Date_string, "Date") \ V(Date_string, "Date") \
......
...@@ -2924,6 +2924,29 @@ THREADED_TEST(GlobalSymbols) { ...@@ -2924,6 +2924,29 @@ THREADED_TEST(GlobalSymbols) {
} }
static void CheckWellKnownSymbol(v8::Local<v8::Symbol>(*getter)(v8::Isolate*),
const char* name) {
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope scope(isolate);
v8::Local<v8::Symbol> symbol = getter(isolate);
std::string script = std::string("var sym = ") + name;
CompileRun(script.c_str());
v8::Local<Value> value = env->Global()->Get(v8_str("sym"));
CHECK(!value.IsEmpty());
CHECK(!symbol.IsEmpty());
CHECK(value->SameValue(symbol));
}
THREADED_TEST(WellKnownSymbols) {
CheckWellKnownSymbol(v8::Symbol::GetIterator, "Symbol.iterator");
CheckWellKnownSymbol(v8::Symbol::GetUnscopables, "Symbol.unscopables");
}
THREADED_TEST(GlobalPrivates) { THREADED_TEST(GlobalPrivates) {
LocalContext env; LocalContext env;
v8::Isolate* isolate = env->GetIsolate(); v8::Isolate* isolate = env->GetIsolate();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment