Commit b3b6987b authored by rossberg@chromium.org's avatar rossberg@chromium.org

Reland "Implement ES6 symbol registry and predefined symbols"

Only change relative to original CL is the updated assertion condition at objects-inl.h:2119

R=mstarzinger@chromium.org
BUG=

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20136 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 2aadbc8f
...@@ -5552,7 +5552,7 @@ class Internals { ...@@ -5552,7 +5552,7 @@ class Internals {
static const int kNullValueRootIndex = 7; static const int kNullValueRootIndex = 7;
static const int kTrueValueRootIndex = 8; static const int kTrueValueRootIndex = 8;
static const int kFalseValueRootIndex = 9; static const int kFalseValueRootIndex = 9;
static const int kEmptyStringRootIndex = 144; static const int kEmptyStringRootIndex = 145;
static const int kNodeClassIdOffset = 1 * kApiPointerSize; static const int kNodeClassIdOffset = 1 * kApiPointerSize;
static const int kNodeFlagsOffset = 1 * kApiPointerSize + 3; static const int kNodeFlagsOffset = 1 * kApiPointerSize + 3;
......
...@@ -3288,6 +3288,14 @@ bool Heap::CreateInitialObjects() { ...@@ -3288,6 +3288,14 @@ bool Heap::CreateInitialObjects() {
} }
set_undefined_cell(Cell::cast(obj)); set_undefined_cell(Cell::cast(obj));
// Allocate objects to hold symbol registry.
{ MaybeObject* maybe_obj = AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
if (!maybe_obj->ToObject(&obj)) return false;
maybe_obj = AllocateJSObjectFromMap(Map::cast(obj));
if (!maybe_obj->ToObject(&obj)) return false;
}
set_symbol_registry(JSObject::cast(obj));
// Allocate object to hold object observation state. // Allocate object to hold object observation state.
{ MaybeObject* maybe_obj = AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); { MaybeObject* maybe_obj = AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
if (!maybe_obj->ToObject(&obj)) return false; if (!maybe_obj->ToObject(&obj)) return false;
......
...@@ -190,6 +190,7 @@ namespace internal { ...@@ -190,6 +190,7 @@ namespace internal {
V(Cell, undefined_cell, UndefineCell) \ V(Cell, undefined_cell, UndefineCell) \
V(JSObject, observation_state, ObservationState) \ V(JSObject, observation_state, ObservationState) \
V(Map, external_map, ExternalMap) \ V(Map, external_map, ExternalMap) \
V(JSObject, symbol_registry, SymbolRegistry) \
V(Symbol, frozen_symbol, FrozenSymbol) \ V(Symbol, frozen_symbol, FrozenSymbol) \
V(Symbol, nonexistent_symbol, NonExistentSymbol) \ V(Symbol, nonexistent_symbol, NonExistentSymbol) \
V(Symbol, elements_transition_symbol, ElementsTransitionSymbol) \ V(Symbol, elements_transition_symbol, ElementsTransitionSymbol) \
......
...@@ -103,6 +103,7 @@ var kMessages = { ...@@ -103,6 +103,7 @@ var kMessages = {
invalid_argument: ["invalid_argument"], invalid_argument: ["invalid_argument"],
data_view_not_array_buffer: ["First argument to DataView constructor must be an ArrayBuffer"], data_view_not_array_buffer: ["First argument to DataView constructor must be an ArrayBuffer"],
constructor_not_function: ["Constructor ", "%0", " requires 'new'"], constructor_not_function: ["Constructor ", "%0", " requires 'new'"],
not_a_symbol: ["%0", " is not a symbol"],
not_a_promise: ["%0", " is not a promise"], not_a_promise: ["%0", " is not a promise"],
resolver_not_a_function: ["Promise resolver ", "%0", " is not a function"], resolver_not_a_function: ["Promise resolver ", "%0", " is not a function"],
promise_cyclic: ["Chaining cycle detected for promise ", "%0"], promise_cyclic: ["Chaining cycle detected for promise ", "%0"],
......
...@@ -2116,6 +2116,7 @@ void Object::VerifyApiCallResultType() { ...@@ -2116,6 +2116,7 @@ void Object::VerifyApiCallResultType() {
#if ENABLE_EXTRA_CHECKS #if ENABLE_EXTRA_CHECKS
if (!(IsSmi() || if (!(IsSmi() ||
IsString() || IsString() ||
IsSymbol() ||
IsSpecObject() || IsSpecObject() ||
IsHeapNumber() || IsHeapNumber() ||
IsUndefined() || IsUndefined() ||
......
...@@ -636,6 +636,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SymbolDescription) { ...@@ -636,6 +636,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SymbolDescription) {
} }
RUNTIME_FUNCTION(MaybeObject*, Runtime_SymbolRegistry) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 0);
return isolate->heap()->symbol_registry();
}
RUNTIME_FUNCTION(MaybeObject*, Runtime_SymbolIsPrivate) { RUNTIME_FUNCTION(MaybeObject*, Runtime_SymbolIsPrivate) {
SealHandleScope shs(isolate); SealHandleScope shs(isolate);
ASSERT(args.length() == 1); ASSERT(args.length() == 1);
......
...@@ -314,6 +314,7 @@ namespace internal { ...@@ -314,6 +314,7 @@ namespace internal {
F(CreatePrivateSymbol, 1, 1) \ F(CreatePrivateSymbol, 1, 1) \
F(NewSymbolWrapper, 1, 1) \ F(NewSymbolWrapper, 1, 1) \
F(SymbolDescription, 1, 1) \ F(SymbolDescription, 1, 1) \
F(SymbolRegistry, 0, 1) \
F(SymbolIsPrivate, 1, 1) \ F(SymbolIsPrivate, 1, 1) \
\ \
/* Harmony proxies */ \ /* Harmony proxies */ \
......
...@@ -63,6 +63,46 @@ function SymbolValueOf() { ...@@ -63,6 +63,46 @@ function SymbolValueOf() {
} }
function GetSymbolRegistry() {
var registry = %SymbolRegistry();
if (!('internal' in registry)) {
registry.internal = {__proto__: null};
registry.for = {__proto__: null};
registry.keyFor = {__proto__: null};
}
return registry;
}
function InternalSymbol(key) {
var registry = GetSymbolRegistry();
if (!(key in registry.internal)) {
registry.internal[key] = %CreateSymbol(key);
}
return registry.internal[key];
}
function SymbolFor(key) {
key = TO_STRING_INLINE(key);
var registry = GetSymbolRegistry();
if (!(key in registry.for)) {
var symbol = %CreateSymbol(key);
registry.for[key] = symbol;
registry.keyFor[symbol] = key;
}
return registry.for[key];
}
function SymbolKeyFor(symbol) {
if (!IS_SYMBOL(symbol)) {
throw MakeTypeError("not_a_symbol", [symbol]);
}
return GetSymbolRegistry().keyFor[symbol];
}
// ES6 19.1.2.8 // ES6 19.1.2.8
function ObjectGetOwnPropertySymbols(obj) { function ObjectGetOwnPropertySymbols(obj) {
if (!IS_SPEC_OBJECT(obj)) { if (!IS_SPEC_OBJECT(obj)) {
...@@ -76,6 +116,17 @@ function ObjectGetOwnPropertySymbols(obj) { ...@@ -76,6 +116,17 @@ function ObjectGetOwnPropertySymbols(obj) {
} }
//-------------------------------------------------------------------
var symbolCreate = InternalSymbol("@@create");
var symbolHasInstance = InternalSymbol("@@hasInstance");
var symbolIsConcatSpreadable = InternalSymbol("@@isConcatSpreadable");
var symbolIsRegExp = InternalSymbol("@@isRegExp");
var symbolIterator = InternalSymbol("@@iterator");
var symbolToStringTag = InternalSymbol("@@toStringTag");
var symbolUnscopables = InternalSymbol("@@unscopables");
//------------------------------------------------------------------- //-------------------------------------------------------------------
function SetUpSymbol() { function SetUpSymbol() {
...@@ -84,6 +135,19 @@ function SetUpSymbol() { ...@@ -84,6 +135,19 @@ function SetUpSymbol() {
%SetCode($Symbol, SymbolConstructor); %SetCode($Symbol, SymbolConstructor);
%FunctionSetPrototype($Symbol, new $Object()); %FunctionSetPrototype($Symbol, new $Object());
%SetProperty($Symbol, "create", symbolCreate, DONT_ENUM);
%SetProperty($Symbol, "hasInstance", symbolHasInstance, DONT_ENUM);
%SetProperty($Symbol, "isConcatSpreadable",
symbolIsConcatSpreadable, DONT_ENUM);
%SetProperty($Symbol, "isRegExp", symbolIsRegExp, DONT_ENUM);
%SetProperty($Symbol, "iterator", symbolIterator, DONT_ENUM);
%SetProperty($Symbol, "toStringTag", symbolToStringTag, DONT_ENUM);
%SetProperty($Symbol, "unscopables", symbolUnscopables, DONT_ENUM);
InstallFunctions($Symbol, DONT_ENUM, $Array(
"for", SymbolFor,
"keyFor", SymbolKeyFor
));
%SetProperty($Symbol.prototype, "constructor", $Symbol, DONT_ENUM); %SetProperty($Symbol.prototype, "constructor", $Symbol, DONT_ENUM);
InstallFunctions($Symbol.prototype, DONT_ENUM, $Array( InstallFunctions($Symbol.prototype, DONT_ENUM, $Array(
"toString", SymbolToString, "toString", SymbolToString,
......
...@@ -328,3 +328,17 @@ function TestCachedKeyAfterScavenge() { ...@@ -328,3 +328,17 @@ function TestCachedKeyAfterScavenge() {
} }
} }
TestCachedKeyAfterScavenge(); TestCachedKeyAfterScavenge();
function TestGetOwnPropertySymbols() {
var privateSymbol = %CreatePrivateSymbol("private")
var publicSymbol = Symbol()
var publicSymbol2 = Symbol()
var obj = {}
obj[publicSymbol] = 1
obj[privateSymbol] = 2
obj[publicSymbol2] = 3
var syms = Object.getOwnPropertySymbols(obj)
assertEquals(syms, [publicSymbol, publicSymbol2])
}
TestGetOwnPropertySymbols()
...@@ -410,15 +410,42 @@ function TestGetOwnPropertySymbolsWithProto() { ...@@ -410,15 +410,42 @@ function TestGetOwnPropertySymbolsWithProto() {
TestGetOwnPropertySymbolsWithProto() TestGetOwnPropertySymbolsWithProto()
function TestGetOwnPropertySymbolsWithPrivateSymbols() { function TestRegistry() {
var privateSymbol = %CreatePrivateSymbol("private") assertFalse(Symbol.for("@@create") === Symbol.create)
var publicSymbol = Symbol() assertFalse(Symbol.for("@@iterator") === Symbol.iterator)
var publicSymbol2 = Symbol() assertTrue(Symbol.keyFor(Symbol.create) === undefined)
var obj = {} assertTrue(Symbol.keyFor(Symbol.iterator) === undefined)
obj[publicSymbol] = 1
obj[privateSymbol] = 2 var symbol1 = Symbol.for("x1")
obj[publicSymbol2] = 3 var symbol2 = Symbol.for("x2")
var syms = Object.getOwnPropertySymbols(obj) assertFalse(symbol1 === symbol2)
assertEquals(syms, [publicSymbol, publicSymbol2])
assertSame(symbol1, Symbol.for("x1"))
assertSame(symbol2, Symbol.for("x2"))
assertSame("x1", Symbol.keyFor(symbol1))
assertSame("x2", Symbol.keyFor(symbol2))
assertSame(Symbol.for("1"), Symbol.for(1))
assertThrows(function() { Symbol.keyFor("bla") }, TypeError)
assertThrows(function() { Symbol.keyFor({}) }, TypeError)
var realm = Realm.create()
assertFalse(Symbol === Realm.eval(realm, "Symbol"))
assertFalse(Symbol.for === Realm.eval(realm, "Symbol.for"))
assertFalse(Symbol.keyFor === Realm.eval(realm, "Symbol.keyFor"))
assertSame(Symbol.create, Realm.eval(realm, "Symbol.create"))
assertSame(Symbol.iterator, Realm.eval(realm, "Symbol.iterator"))
assertSame(symbol1, Realm.eval(realm, "Symbol.for")("x1"))
assertSame(symbol1, Realm.eval(realm, "Symbol.for('x1')"))
assertSame("x1", Realm.eval(realm, "Symbol.keyFor")(symbol1))
Realm.shared = symbol1
assertSame("x1", Realm.eval(realm, "Symbol.keyFor(Realm.shared)"))
var symbol3 = Realm.eval(realm, "Symbol.for('x3')")
assertFalse(symbol1 === symbol3)
assertFalse(symbol2 === symbol3)
assertSame(symbol3, Symbol.for("x3"))
assertSame("x3", Symbol.keyFor(symbol3))
} }
TestGetOwnPropertySymbolsWithPrivateSymbols() TestRegistry()
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