Revision: 20136
Author: rossb...@chromium.org
Date: Thu Mar 20 16:13:09 2014 UTC
Log: 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=mstarzin...@chromium.org
BUG=
Review URL: https://codereview.chromium.org/204913006
http://code.google.com/p/v8/source/detail?r=20136
Modified:
/branches/bleeding_edge/include/v8.h
/branches/bleeding_edge/src/heap.cc
/branches/bleeding_edge/src/heap.h
/branches/bleeding_edge/src/messages.js
/branches/bleeding_edge/src/objects-inl.h
/branches/bleeding_edge/src/runtime.cc
/branches/bleeding_edge/src/runtime.h
/branches/bleeding_edge/src/symbol.js
/branches/bleeding_edge/test/mjsunit/harmony/private.js
/branches/bleeding_edge/test/mjsunit/harmony/symbols.js
=======================================
--- /branches/bleeding_edge/include/v8.h Thu Mar 20 12:56:41 2014 UTC
+++ /branches/bleeding_edge/include/v8.h Thu Mar 20 16:13:09 2014 UTC
@@ -5552,7 +5552,7 @@
static const int kNullValueRootIndex = 7;
static const int kTrueValueRootIndex = 8;
static const int kFalseValueRootIndex = 9;
- static const int kEmptyStringRootIndex = 144;
+ static const int kEmptyStringRootIndex = 145;
static const int kNodeClassIdOffset = 1 * kApiPointerSize;
static const int kNodeFlagsOffset = 1 * kApiPointerSize + 3;
=======================================
--- /branches/bleeding_edge/src/heap.cc Thu Mar 20 12:56:41 2014 UTC
+++ /branches/bleeding_edge/src/heap.cc Thu Mar 20 16:13:09 2014 UTC
@@ -3288,6 +3288,14 @@
}
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.
{ MaybeObject* maybe_obj = AllocateMap(JS_OBJECT_TYPE,
JSObject::kHeaderSize);
if (!maybe_obj->ToObject(&obj)) return false;
=======================================
--- /branches/bleeding_edge/src/heap.h Thu Mar 20 12:56:41 2014 UTC
+++ /branches/bleeding_edge/src/heap.h Thu Mar 20 16:13:09 2014 UTC
@@ -190,6 +190,7 @@
V(Cell, undefined_cell,
UndefineCell) \
V(JSObject, observation_state,
ObservationState) \
V(Map, external_map,
ExternalMap) \
+ V(JSObject, symbol_registry,
SymbolRegistry) \
V(Symbol, frozen_symbol,
FrozenSymbol) \
V(Symbol, nonexistent_symbol,
NonExistentSymbol) \
V(Symbol, elements_transition_symbol,
ElementsTransitionSymbol) \
=======================================
--- /branches/bleeding_edge/src/messages.js Thu Mar 20 13:37:26 2014 UTC
+++ /branches/bleeding_edge/src/messages.js Thu Mar 20 16:13:09 2014 UTC
@@ -103,6 +103,7 @@
invalid_argument: ["invalid_argument"],
data_view_not_array_buffer: ["First argument to DataView constructor
must be an ArrayBuffer"],
constructor_not_function: ["Constructor ", "%0", " requires 'new'"],
+ not_a_symbol: ["%0", " is not a symbol"],
not_a_promise: ["%0", " is not a promise"],
resolver_not_a_function: ["Promise resolver ", "%0", " is not a
function"],
promise_cyclic: ["Chaining cycle detected for
promise ", "%0"],
=======================================
--- /branches/bleeding_edge/src/objects-inl.h Thu Mar 20 12:22:13 2014 UTC
+++ /branches/bleeding_edge/src/objects-inl.h Thu Mar 20 16:13:09 2014 UTC
@@ -2116,6 +2116,7 @@
#if ENABLE_EXTRA_CHECKS
if (!(IsSmi() ||
IsString() ||
+ IsSymbol() ||
IsSpecObject() ||
IsHeapNumber() ||
IsUndefined() ||
=======================================
--- /branches/bleeding_edge/src/runtime.cc Thu Mar 20 13:40:08 2014 UTC
+++ /branches/bleeding_edge/src/runtime.cc Thu Mar 20 16:13:09 2014 UTC
@@ -634,6 +634,13 @@
CONVERT_ARG_CHECKED(Symbol, symbol, 0);
return symbol->name();
}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SymbolRegistry) {
+ SealHandleScope shs(isolate);
+ ASSERT(args.length() == 0);
+ return isolate->heap()->symbol_registry();
+}
RUNTIME_FUNCTION(MaybeObject*, Runtime_SymbolIsPrivate) {
=======================================
--- /branches/bleeding_edge/src/runtime.h Thu Mar 20 12:56:41 2014 UTC
+++ /branches/bleeding_edge/src/runtime.h Thu Mar 20 16:13:09 2014 UTC
@@ -314,6 +314,7 @@
F(CreatePrivateSymbol, 1, 1) \
F(NewSymbolWrapper, 1, 1) \
F(SymbolDescription, 1, 1) \
+ F(SymbolRegistry, 0, 1) \
F(SymbolIsPrivate, 1, 1) \
\
/* Harmony proxies */ \
=======================================
--- /branches/bleeding_edge/src/symbol.js Thu Mar 20 12:56:41 2014 UTC
+++ /branches/bleeding_edge/src/symbol.js Thu Mar 20 16:13:09 2014 UTC
@@ -61,6 +61,46 @@
}
return %_ValueOf(this);
}
+
+
+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
@@ -74,6 +114,17 @@
return ObjectGetOwnPropertyKeys(obj, true);
}
+
+
+//-------------------------------------------------------------------
+
+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");
//-------------------------------------------------------------------
@@ -84,6 +135,19 @@
%SetCode($Symbol, SymbolConstructor);
%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);
InstallFunctions($Symbol.prototype, DONT_ENUM, $Array(
"toString", SymbolToString,
=======================================
--- /branches/bleeding_edge/test/mjsunit/harmony/private.js Thu Mar 20
12:56:41 2014 UTC
+++ /branches/bleeding_edge/test/mjsunit/harmony/private.js Thu Mar 20
16:13:09 2014 UTC
@@ -328,3 +328,17 @@
}
}
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()
=======================================
--- /branches/bleeding_edge/test/mjsunit/harmony/symbols.js Thu Mar 20
12:56:41 2014 UTC
+++ /branches/bleeding_edge/test/mjsunit/harmony/symbols.js Thu Mar 20
16:13:09 2014 UTC
@@ -410,15 +410,42 @@
TestGetOwnPropertySymbolsWithProto()
-function TestGetOwnPropertySymbolsWithPrivateSymbols() {
- 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])
+function TestRegistry() {
+ assertFalse(Symbol.for("@@create") === Symbol.create)
+ assertFalse(Symbol.for("@@iterator") === Symbol.iterator)
+ assertTrue(Symbol.keyFor(Symbol.create) === undefined)
+ assertTrue(Symbol.keyFor(Symbol.iterator) === undefined)
+
+ var symbol1 = Symbol.for("x1")
+ var symbol2 = Symbol.for("x2")
+ assertFalse(symbol1 === symbol2)
+
+ 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()
--
--
v8-dev mailing list
v8-dev@googlegroups.com
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to v8-dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.