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
This commit is contained in:
parent
ed668b8f2c
commit
8394975ec7
@ -1960,7 +1960,12 @@ class V8_EXPORT Symbol : public Primitive {
|
||||
// registry that is not accessible by (and cannot clash with) JavaScript code.
|
||||
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);
|
||||
|
||||
private:
|
||||
Symbol();
|
||||
static void CheckCast(v8::Value* obj);
|
||||
|
60
src/api.cc
60
src/api.cc
@ -6152,43 +6152,57 @@ Local<Symbol> v8::Symbol::New(Isolate* isolate, Local<String> name) {
|
||||
}
|
||||
|
||||
|
||||
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::JSObject> registry = i_isolate->GetSymbolRegistry();
|
||||
i::Handle<i::String> part = i_isolate->factory()->for_string();
|
||||
static i::Handle<i::Symbol> SymbolFor(i::Isolate* isolate,
|
||||
i::Handle<i::String> name,
|
||||
i::Handle<i::String> part) {
|
||||
i::Handle<i::JSObject> registry = isolate->GetSymbolRegistry();
|
||||
i::Handle<i::JSObject> symbols =
|
||||
i::Handle<i::JSObject>::cast(
|
||||
i::Object::GetPropertyOrElement(registry, part).ToHandleChecked());
|
||||
i::Handle<i::Object> symbol =
|
||||
i::Object::GetPropertyOrElement(symbols, i_name).ToHandleChecked();
|
||||
i::Object::GetPropertyOrElement(symbols, name).ToHandleChecked();
|
||||
if (!symbol->IsSymbol()) {
|
||||
DCHECK(symbol->IsUndefined());
|
||||
symbol = i_isolate->factory()->NewSymbol();
|
||||
i::Handle<i::Symbol>::cast(symbol)->set_name(*i_name);
|
||||
i::JSObject::SetProperty(symbols, i_name, symbol, i::STRICT).Assert();
|
||||
symbol = isolate->factory()->NewSymbol();
|
||||
i::Handle<i::Symbol>::cast(symbol)->set_name(*name);
|
||||
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) {
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
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::JSObject> symbols =
|
||||
i::Handle<i::JSObject>::cast(
|
||||
i::Object::GetPropertyOrElement(registry, part).ToHandleChecked());
|
||||
i::Handle<i::Object> symbol =
|
||||
i::Object::GetPropertyOrElement(symbols, i_name).ToHandleChecked();
|
||||
if (!symbol->IsSymbol()) {
|
||||
DCHECK(symbol->IsUndefined());
|
||||
symbol = i_isolate->factory()->NewSymbol();
|
||||
i::Handle<i::Symbol>::cast(symbol)->set_name(*i_name);
|
||||
i::JSObject::SetProperty(symbols, i_name, symbol, i::STRICT).Assert();
|
||||
}
|
||||
return Utils::ToLocal(i::Handle<i::Symbol>::cast(symbol));
|
||||
return Utils::ToLocal(SymbolFor(i_isolate, i_name, part));
|
||||
}
|
||||
|
||||
|
||||
static Local<Symbol> GetWellKnownSymbol(Isolate* isolate, const char* name) {
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
i::Handle<i::String> i_name =
|
||||
Utils::OpenHandle(*String::NewFromUtf8(isolate, name));
|
||||
i::Handle<i::String> part = i_isolate->factory()->for_intern_string();
|
||||
return Utils::ToLocal(SymbolFor(i_isolate, i_name, part));
|
||||
}
|
||||
|
||||
|
||||
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 {
|
||||
V(Symbol_string, "Symbol") \
|
||||
V(for_string, "for") \
|
||||
V(for_api_string, "for_api") \
|
||||
V(for_intern_string, "for_intern") \
|
||||
V(private_api_string, "private_api") \
|
||||
V(private_intern_string, "private_intern") \
|
||||
V(Date_string, "Date") \
|
||||
|
@ -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) {
|
||||
LocalContext env;
|
||||
v8::Isolate* isolate = env->GetIsolate();
|
||||
|
Loading…
Reference in New Issue
Block a user