Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 // Flags: --harmony-symbols --harmony-collections | 28 // Flags: --harmony-symbols --harmony-collections |
| 29 // Flags: --expose-gc --allow-natives-syntax | 29 // Flags: --expose-gc --allow-natives-syntax |
| 30 | 30 |
| 31 var symbols = [] | 31 var symbols = [] |
| 32 | 32 |
| 33 | |
| 33 // Test different forms of constructor calls, all equivalent. | 34 // Test different forms of constructor calls, all equivalent. |
| 34 function TestNew() { | 35 function TestNew() { |
| 35 function IndirectSymbol() { return new Symbol } | 36 function IndirectSymbol() { return Symbol() } |
| 36 function indirect() { return new IndirectSymbol() } | 37 function indirect() { return IndirectSymbol() } |
| 37 for (var i = 0; i < 2; ++i) { | 38 for (var i = 0; i < 2; ++i) { |
| 38 for (var j = 0; j < 5; ++j) { | 39 for (var j = 0; j < 5; ++j) { |
| 39 symbols.push(Symbol()) | 40 symbols.push(Symbol()) |
| 40 symbols.push(Symbol(undefined)) | 41 symbols.push(Symbol(undefined)) |
| 41 symbols.push(Symbol("66")) | 42 symbols.push(Symbol("66")) |
| 42 symbols.push(Symbol(66)) | 43 symbols.push(Symbol(66)) |
| 43 symbols.push(Symbol(Symbol())) | |
| 44 symbols.push((new Symbol).valueOf()) | |
| 45 symbols.push((new Symbol()).valueOf()) | |
| 46 symbols.push((new Symbol(Symbol())).valueOf()) | |
| 47 symbols.push(Object(Symbol()).valueOf()) | 44 symbols.push(Object(Symbol()).valueOf()) |
| 48 symbols.push((indirect()).valueOf()) | 45 symbols.push((indirect())) |
| 49 } | 46 } |
| 50 %OptimizeFunctionOnNextCall(indirect) | 47 %OptimizeFunctionOnNextCall(indirect) |
| 51 indirect() // Call once before GC throws away type feedback. | 48 indirect() // Call once before GC throws away type feedback. |
| 52 gc() // Promote existing symbols and then allocate some more. | 49 gc() // Promote existing symbols and then allocate some more. |
| 53 } | 50 } |
| 54 } | 51 } |
| 55 TestNew() | 52 TestNew() |
| 56 | 53 |
| 57 | 54 |
| 55 function TestRepeatedApplication() { | |
| 56 assertThrows(function () { Symbol(Symbol()); }, TypeError) | |
| 57 } | |
| 58 TestRepeatedApplication() | |
| 59 | |
| 60 | |
| 58 function TestType() { | 61 function TestType() { |
| 59 for (var i in symbols) { | 62 for (var i in symbols) { |
| 60 assertEquals("symbol", typeof symbols[i]) | 63 assertEquals("symbol", typeof symbols[i]) |
| 61 assertTrue(typeof symbols[i] === "symbol") | 64 assertTrue(typeof symbols[i] === "symbol") |
| 62 assertFalse(%SymbolIsPrivate(symbols[i])) | 65 assertFalse(%SymbolIsPrivate(symbols[i])) |
| 63 assertEquals(null, %_ClassOf(symbols[i])) | 66 assertEquals(null, %_ClassOf(symbols[i])) |
| 64 assertEquals("Symbol", %_ClassOf(new Symbol(symbols[i]))) | |
| 65 assertEquals("Symbol", %_ClassOf(Object(symbols[i]))) | 67 assertEquals("Symbol", %_ClassOf(Object(symbols[i]))) |
| 66 } | 68 } |
| 67 } | 69 } |
| 68 TestType() | 70 TestType() |
| 69 | 71 |
| 70 | 72 |
| 71 function TestPrototype() { | 73 function TestPrototype() { |
| 74 var symbolPrototype = Object.getPrototypeOf(Object(Symbol())) | |
| 75 assertSame(Function.prototype, Symbol.prototype) | |
|
rossberg
2014/01/08 17:52:25
That seems wrong. Symbol.prototype is an ordinary
sof
2014/01/08 18:13:43
https://people.mozilla.org/~jorendorff/es6-draft.h
arv (Not doing code reviews)
2014/01/08 18:54:44
It says that "The value of the [[Prototype]] inter
rossberg
2014/01/09 10:35:53
Don't confuse .prototype and .[[Prototype]] (a.k.a
sof
2014/01/09 13:17:13
I made that only available on the "SymbolWrapper"
| |
| 72 assertSame(Object.prototype, Symbol.prototype.__proto__) | 76 assertSame(Object.prototype, Symbol.prototype.__proto__) |
| 73 assertSame(Symbol.prototype, Symbol().__proto__) | 77 assertSame(Symbol.prototype, Symbol().__proto__) |
| 74 assertSame(Symbol.prototype, Symbol(Symbol()).__proto__) | 78 assertSame(symbolPrototype, Object(Symbol()).__proto__) |
|
rossberg
2014/01/08 17:52:25
Is this different from Symbol.prototype? Why?
sof
2014/01/08 18:13:43
Yes, Object(Symbol()).__proto__ is the prototype o
arv (Not doing code reviews)
2014/01/08 18:54:44
The [[Prototype]] of a symbol wrapper should be Sy
| |
| 75 assertSame(Symbol.prototype, (new Symbol).__proto__) | 79 assertSame(Symbol.prototype, Symbol.__proto__) |
|
rossberg
2014/01/08 17:52:25
Shouldn't Symbol.__proto__ be Function.prototype?
| |
| 76 assertSame(Symbol.prototype, (new Symbol()).__proto__) | 80 // FIXME: what should __proto__ be for a Symbol value? |
| 77 assertSame(Symbol.prototype, (new Symbol(Symbol())).__proto__) | 81 assertSame(Function.prototype, (Symbol()).__proto__) |
|
rossberg
2014/01/08 17:52:25
And Symbol().__proto__ should be Symbol.prototype
sof
2014/01/08 18:13:43
Definitely not.
arv (Not doing code reviews)
2014/01/08 18:54:44
When you do a [[Get]] on a non object a temporary
rossberg
2014/01/09 10:35:53
See above.
| |
| 78 assertSame(Symbol.prototype, Object(Symbol()).__proto__) | 82 assertTrue(typeof ((Symbol()).prototype) === "undefined") |
|
rossberg
2014/01/08 17:52:25
Not sure why this test is necessary.
sof
2014/01/08 18:13:43
Just testing that typeof over this .prototype is b
rossberg
2014/01/09 10:35:53
Well, it just tests that the symbol wrapper object
| |
| 79 for (var i in symbols) { | 83 for (var i in symbols) { |
| 80 assertSame(Symbol.prototype, symbols[i].__proto__) | 84 assertSame(Symbol.prototype, symbols[i].__proto__) |
| 81 } | 85 } |
| 82 } | 86 } |
| 83 TestPrototype() | 87 TestPrototype() |
| 84 | 88 |
| 85 | 89 |
| 86 function TestConstructor() { | 90 function TestConstructor() { |
| 87 assertFalse(Object === Symbol.prototype.constructor) | 91 assertFalse(Object === Symbol.prototype.constructor) |
|
rossberg
2014/01/08 17:52:25
This should be true now.
sof
2014/01/08 18:13:43
No, I believe this is correct.
arv (Not doing code reviews)
2014/01/08 18:54:44
Looks correct to me too:
assertSame(Symbol.protot
rossberg
2014/01/09 10:35:53
Oops, you are both right, sorry.
| |
| 88 assertFalse(Symbol === Object.prototype.constructor) | 92 assertFalse(Symbol === Object.prototype.constructor) |
| 89 assertSame(Symbol, Symbol.prototype.constructor) | 93 assertSame(Function, Symbol.prototype.constructor) |
|
rossberg
2014/01/08 17:52:25
This should be Object, not Function
sof
2014/01/08 18:13:43
Same; are we reading the same draft version of the
arv (Not doing code reviews)
2014/01/08 18:54:44
This should be
assertSame(Symbol.prototype.constr
rossberg
2014/01/09 10:35:53
Arv is correct.
| |
| 90 assertSame(Symbol, Symbol().__proto__.constructor) | 94 assertSame(Function, Symbol().__proto__.constructor) |
|
rossberg
2014/01/08 17:52:25
Dito
arv (Not doing code reviews)
2014/01/08 18:54:44
Should be
assertSame(Symbol, Symbol().__proto__.c
| |
| 91 assertSame(Symbol, Symbol(Symbol()).__proto__.constructor) | 95 assertSame(Function, Object(Symbol()).valueOf().__proto__.constructor) |
|
rossberg
2014/01/08 17:52:25
Dito here. And why the redundant valueOf()?
| |
| 92 assertSame(Symbol, (new Symbol).__proto__.constructor) | 96 assertSame(Function, (Symbol).__proto__.constructor) |
|
rossberg
2014/01/08 17:52:25
This is an unrelated test, since it tests the cons
| |
| 93 assertSame(Symbol, (new Symbol()).__proto__.constructor) | 97 assertSame(Function, (Symbol()).__proto__.constructor) |
|
rossberg
2014/01/08 17:52:25
This is repeating line 94
| |
| 94 assertSame(Symbol, (new Symbol(Symbol())).__proto__.constructor) | 98 assertSame(Symbol, (Object(Symbol())).__proto__.constructor) |
|
rossberg
2014/01/08 17:52:25
Nit: redundant parens (here and above)
| |
| 95 assertSame(Symbol, Object(Symbol()).__proto__.constructor) | 99 assertSame(Symbol, Object(Symbol()).__proto__.constructor) |
| 96 for (var i in symbols) { | 100 for (var i in symbols) { |
| 97 assertSame(Symbol, symbols[i].__proto__.constructor) | 101 assertSame(Function, symbols[i].__proto__.constructor) |
|
rossberg
2014/01/08 17:52:25
Should also be Symbol
| |
| 98 } | 102 } |
| 99 } | 103 } |
| 100 TestConstructor() | 104 TestConstructor() |
| 101 | 105 |
| 102 | 106 |
| 103 function TestName() { | 107 function TestValueOf() { |
| 104 for (var i in symbols) { | 108 for (var i in symbols) { |
| 105 var name = symbols[i].name | 109 var value = Object(symbols[i]).valueOf() |
|
rossberg
2014/01/08 17:52:25
Why the redundant Object()?
| |
| 106 assertTrue(name === undefined || name === "66") | 110 assertTrue(value === symbols[i]) |
| 107 } | 111 } |
| 108 } | 112 } |
| 109 TestName() | 113 TestValueOf() |
| 110 | 114 |
| 111 | 115 |
| 112 function TestToString() { | 116 function TestToString() { |
| 113 for (var i in symbols) { | 117 for (var i in symbols) { |
| 118 var stringified; | |
| 119 assertDoesNotThrow(function () { stringified = String(Object(symbols[i])); } ) | |
|
rossberg
2014/01/08 17:52:25
Nit: line length (just remove the space after 'fun
| |
| 120 assertTrue(stringified == "Symbol(66)" || stringified == "Symbol()") | |
| 114 assertThrows(function() { String(symbols[i]) }, TypeError) | 121 assertThrows(function() { String(symbols[i]) }, TypeError) |
| 115 assertThrows(function() { symbols[i] + "" }, TypeError) | 122 assertThrows(function() { symbols[i] + "" }, TypeError) |
| 116 assertThrows(function() { symbols[i].toString() }, TypeError) | 123 assertThrows(function() { symbols[i].toString() }, TypeError) |
| 117 assertThrows(function() { (new Symbol(symbols[i])).toString() }, TypeError) | 124 assertThrows(function() { (Symbol(symbols[i])).toString() }, TypeError) |
| 118 assertThrows(function() { Object(symbols[i]).toString() }, TypeError) | 125 assertDoesNotThrow(function() { Object(symbols[i]).toString() }) |
|
rossberg
2014/01/08 17:52:25
Why not check the expected result?
| |
| 119 assertEquals("[object Symbol]", Object.prototype.toString.call(symbols[i])) | 126 assertEquals("[object Symbol]", Object.prototype.toString.call(symbols[i])) |
| 120 } | 127 } |
| 121 } | 128 } |
| 122 TestToString() | 129 TestToString() |
| 123 | 130 |
| 124 | 131 |
| 125 function TestToBoolean() { | 132 function TestToBoolean() { |
| 126 for (var i in symbols) { | 133 for (var i in symbols) { |
| 127 assertTrue(Boolean(symbols[i]).valueOf()) | 134 assertTrue(Boolean(symbols[i]).valueOf()) |
| 128 assertFalse(!symbols[i]) | 135 assertFalse(!symbols[i]) |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 149 | 156 |
| 150 | 157 |
| 151 function TestEquality() { | 158 function TestEquality() { |
| 152 // Every symbol should equal itself, and non-strictly equal its wrapper. | 159 // Every symbol should equal itself, and non-strictly equal its wrapper. |
| 153 for (var i in symbols) { | 160 for (var i in symbols) { |
| 154 assertSame(symbols[i], symbols[i]) | 161 assertSame(symbols[i], symbols[i]) |
| 155 assertEquals(symbols[i], symbols[i]) | 162 assertEquals(symbols[i], symbols[i]) |
| 156 assertTrue(Object.is(symbols[i], symbols[i])) | 163 assertTrue(Object.is(symbols[i], symbols[i])) |
| 157 assertTrue(symbols[i] === symbols[i]) | 164 assertTrue(symbols[i] === symbols[i]) |
| 158 assertTrue(symbols[i] == symbols[i]) | 165 assertTrue(symbols[i] == symbols[i]) |
| 159 assertFalse(symbols[i] === new Symbol(symbols[i])) | 166 assertTrue(symbols[i] === Object(symbols[i]).valueOf()) |
|
rossberg
2014/01/08 17:52:25
The original test was to ensure that symbols are d
| |
| 160 assertFalse(new Symbol(symbols[i]) === symbols[i]) | 167 assertTrue(Object(symbols[i]).valueOf() === symbols[i]) |
|
rossberg
2014/01/08 17:52:25
Likewise
| |
| 161 assertTrue(symbols[i] == new Symbol(symbols[i])) | 168 assertTrue(symbols[i] == Object(symbols[i]).valueOf()) |
| 162 assertTrue(new Symbol(symbols[i]) == symbols[i]) | 169 assertTrue(Object(symbols[i]).valueOf() == symbols[i]) |
| 170 assertEquals(Object(symbols[i]), Object(symbols[i])) | |
|
rossberg
2014/01/08 17:52:25
This is surprising. Why are the two objects equal?
| |
| 171 assertEquals(Object(symbols[i]).valueOf(), Object(symbols[i]).valueOf()) | |
| 172 // Comparing Symbol wrappers via equality should be done without | |
| 173 // invoking ToPrimitive() (which throws for Symbol wrappers.) | |
| 174 var sym1 = Object(symbols[i]) | |
| 175 assertFalse(sym1 == Object(symbols[i])) | |
|
rossberg
2014/01/08 17:52:25
That seems to contradict line 170 -- I'm really co
| |
| 176 assertTrue(sym1 == sym1) | |
| 163 } | 177 } |
| 164 | 178 |
| 165 // All symbols should be distinct. | 179 // All symbols should be distinct. |
| 166 for (var i = 0; i < symbols.length; ++i) { | 180 for (var i = 0; i < symbols.length; ++i) { |
| 167 for (var j = i + 1; j < symbols.length; ++j) { | 181 for (var j = i + 1; j < symbols.length; ++j) { |
| 168 assertFalse(Object.is(symbols[i], symbols[j])) | 182 assertFalse(Object.is(symbols[i], symbols[j])) |
| 169 assertFalse(symbols[i] === symbols[j]) | 183 assertFalse(symbols[i] === symbols[j]) |
| 170 assertFalse(symbols[i] == symbols[j]) | 184 assertFalse(symbols[i] == symbols[j]) |
| 171 } | 185 } |
| 172 } | 186 } |
| 173 | 187 |
| 174 // Symbols should not be equal to any other value (and the test terminates). | 188 // Symbols should not be equal to any other value (and the test terminates). |
| 175 var values = [347, 1.275, NaN, "string", null, undefined, {}, function() {}] | 189 var values = [347, 1.275, NaN, "string", null, undefined, {}, function() {}] |
| 176 for (var i in symbols) { | 190 for (var i in symbols) { |
| 177 for (var j in values) { | 191 for (var j in values) { |
| 178 assertFalse(symbols[i] === values[j]) | 192 assertFalse(symbols[i] === values[j]) |
| 179 assertFalse(values[j] === symbols[i]) | 193 assertFalse(values[j] === symbols[i]) |
| 180 assertFalse(symbols[i] == values[j]) | 194 assertFalse(symbols[i] == values[j]) |
| 181 assertFalse(values[j] == symbols[i]) | 195 assertFalse(values[j] == symbols[i]) |
| 182 } | 196 } |
| 183 } | 197 } |
| 184 } | 198 } |
| 185 TestEquality() | 199 TestEquality() |
| 186 | 200 |
| 187 | 201 |
| 188 function TestGet() { | 202 function TestGet() { |
| 189 for (var i in symbols) { | 203 for (var i in symbols) { |
| 190 assertThrows(function() { symbols[i].toString() }, TypeError) | 204 assertThrows(function() { symbols[i].toString() }, TypeError) |
| 191 assertEquals(symbols[i], symbols[i].valueOf()) | 205 assertEquals(symbols[i], Object(symbols[i]).valueOf()) |
|
rossberg
2014/01/08 17:52:25
Why is Object() needed?
sof
2014/01/08 18:13:43
To test that the wrapper object's valueOf() return
rossberg
2014/01/09 10:35:53
But the wrapper is supposed to be created implicit
sof
2014/01/10 10:53:52
Where is that requirement given? Symbol.prototype.
| |
| 192 assertEquals(undefined, symbols[i].a) | 206 assertEquals(undefined, symbols[i].a) |
| 193 assertEquals(undefined, symbols[i]["a" + "b"]) | 207 assertEquals(undefined, symbols[i]["a" + "b"]) |
| 194 assertEquals(undefined, symbols[i]["" + "1"]) | 208 assertEquals(undefined, symbols[i]["" + "1"]) |
| 195 assertEquals(undefined, symbols[i][62]) | 209 assertEquals(undefined, symbols[i][62]) |
| 196 } | 210 } |
| 197 } | 211 } |
| 198 TestGet() | 212 TestGet() |
| 199 | 213 |
| 200 | 214 |
| 201 function TestSet() { | 215 function TestSet() { |
| 202 for (var i in symbols) { | 216 for (var i in symbols) { |
| 203 symbols[i].toString = 0 | 217 symbols[i].toString = 0 |
| 204 assertThrows(function() { symbols[i].toString() }, TypeError) | 218 assertThrows(function() { symbols[i].toString() }, TypeError) |
| 205 symbols[i].valueOf = 0 | 219 symbols[i].valueOf = 0 |
| 206 assertEquals(symbols[i], symbols[i].valueOf()) | 220 assertEquals(symbols[i], Object(symbols[i]).valueOf()) |
|
rossberg
2014/01/08 17:52:25
Dito
| |
| 207 symbols[i].a = 0 | 221 symbols[i].a = 0 |
| 208 assertEquals(undefined, symbols[i].a) | 222 assertEquals(undefined, symbols[i].a) |
| 209 symbols[i]["a" + "b"] = 0 | 223 symbols[i]["a" + "b"] = 0 |
| 210 assertEquals(undefined, symbols[i]["a" + "b"]) | 224 assertEquals(undefined, symbols[i]["a" + "b"]) |
| 211 symbols[i][62] = 0 | 225 symbols[i][62] = 0 |
| 212 assertEquals(undefined, symbols[i][62]) | 226 assertEquals(undefined, symbols[i][62]) |
| 213 } | 227 } |
| 214 } | 228 } |
| 215 TestSet() | 229 TestSet() |
| 216 | 230 |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 343 // but not between scavenges. This must also apply for symbol keys. | 357 // but not between scavenges. This must also apply for symbol keys. |
| 344 var key = Symbol("key"); | 358 var key = Symbol("key"); |
| 345 var a = {}; | 359 var a = {}; |
| 346 a[key] = "abc"; | 360 a[key] = "abc"; |
| 347 | 361 |
| 348 for (var i = 0; i < 100000; i++) { | 362 for (var i = 0; i < 100000; i++) { |
| 349 a[key] += "a"; // Allocations cause a scavenge. | 363 a[key] += "a"; // Allocations cause a scavenge. |
| 350 } | 364 } |
| 351 } | 365 } |
| 352 TestCachedKeyAfterScavenge(); | 366 TestCachedKeyAfterScavenge(); |
| OLD | NEW |