| |
| var propertyKey = { |
| toString() { |
| throw new Error("propertyKey.toString is called."); |
| } |
| }; |
| |
| function shouldThrow(func, message) { |
| var error = null; |
| try { |
| func(); |
| } catch (e) { |
| error = e; |
| } |
| if (!error) |
| throw new Error("not thrown."); |
| if (String(error) !== message) |
| throw new Error("bad error: " + String(error)); |
| } |
| |
| // GetByVal. |
| (function () { |
| var called = null; |
| var toStringCalled = false; |
| var property = { |
| toString() { |
| toStringCalled = true; |
| return "value"; |
| } |
| }; |
| var object = { |
| get value() { |
| }, |
| set value(val) { |
| } |
| }; |
| Object.defineProperty(object, '', { |
| get: function () { |
| called = "getter for '' is called."; |
| } |
| }); |
| |
| function test(object, property) { |
| object[property]; |
| } |
| noInline(test); |
| |
| shouldThrow(function () { test(object, propertyKey); }, "Error: propertyKey.toString is called."); |
| if (called) |
| throw new Error(called); |
| toStringCalled = false; |
| shouldThrow(function () { test(null, propertyKey); }, "TypeError: null is not an object (evaluating 'object[property]')"); |
| if (toStringCalled) |
| throw new Error("toString is called."); |
| }()); |
| |
| // GetByVal DFG. |
| (function () { |
| var called = null; |
| var toStringCalled = false; |
| var property = { |
| toString() { |
| toStringCalled = true; |
| return "value"; |
| } |
| }; |
| var object = { |
| get ""() { |
| called = "getter for '' is called."; |
| }, |
| set ""(val) { |
| called = "setter for '' is called."; |
| }, |
| |
| get value() { |
| }, |
| set value(val) { |
| } |
| }; |
| |
| function test(object, property) { |
| object[property]; |
| } |
| noInline(test); |
| |
| for (var i = 0; i < 10000; ++i) |
| test(object, property); |
| |
| shouldThrow(function () { test(object, propertyKey); }, "Error: propertyKey.toString is called."); |
| if (called) |
| throw new Error(called); |
| toStringCalled = false; |
| shouldThrow(function () { test(null, propertyKey); }, "TypeError: null is not an object (evaluating 'object[property]')"); |
| if (toStringCalled) |
| throw new Error("toString is called."); |
| }()); |
| |
| |
| // GetByValString. |
| (function () { |
| var called; |
| var toStringCalled = false; |
| var property = { |
| toString() { |
| toStringCalled = true; |
| return "value"; |
| } |
| }; |
| function test(array, length, property) { |
| var result = 0; |
| for (var i = 0; i < length; ++i) |
| result += array[property]; |
| return result; |
| } |
| noInline(test); |
| |
| Object.defineProperty(String.prototype, "", { |
| get: function () { |
| called = "getter for '' is called."; |
| } |
| }); |
| |
| var array = [1, 2, 3]; |
| for (var i = 0; i < 100000; ++i) |
| test(array, array.length, 0); |
| |
| var array = [1, false, 3]; |
| for (var i = 0; i < 100000; ++i) |
| test(array, array.length, 1); |
| |
| test("hello", "hello".length, 2); |
| shouldThrow(function () { test("hello", "hello".length, propertyKey); }, "Error: propertyKey.toString is called."); |
| if (called) |
| throw new Error(called); |
| toStringCalled = false; |
| shouldThrow(function () { test(null, 20, propertyKey); }, "TypeError: null is not an object (evaluating 'array[property]')"); |
| if (toStringCalled) |
| throw new Error("toString is called."); |
| }()); |