OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
260 obj = [1,2,3]; | 260 obj = [1,2,3]; |
261 Object.seal(obj); | 261 Object.seal(obj); |
262 assertDoesNotThrow(function() { obj.splice(0,1,100); }); | 262 assertDoesNotThrow(function() { obj.splice(0,1,100); }); |
263 assertEquals(100, obj[0]); | 263 assertEquals(100, obj[0]); |
264 assertDoesNotThrow(function() { obj.splice(0,2,1,2); }); | 264 assertDoesNotThrow(function() { obj.splice(0,2,1,2); }); |
265 assertDoesNotThrow(function() { obj.splice(1,2,1,2); }); | 265 assertDoesNotThrow(function() { obj.splice(1,2,1,2); }); |
266 // Count of items to delete is clamped by length. | 266 // Count of items to delete is clamped by length. |
267 assertDoesNotThrow(function() { obj.splice(1,2000,1,2); }); | 267 assertDoesNotThrow(function() { obj.splice(1,2000,1,2); }); |
268 assertThrows(function() { obj.splice(0,0,1); }, TypeError); | 268 assertThrows(function() { obj.splice(0,0,1); }, TypeError); |
269 assertThrows(function() { obj.splice(1,2000,1,2,3); }, TypeError); | 269 assertThrows(function() { obj.splice(1,2000,1,2,3); }, TypeError); |
| 270 |
| 271 // Test that the enumerable attribute is unperturbed by sealing. |
| 272 obj = { x: 42, y: 'foo' }; |
| 273 Object.defineProperty(obj, 'y', {enumerable: false}); |
| 274 Object.seal(obj); |
| 275 assertTrue(Object.isSealed(obj)); |
| 276 assertFalse(Object.isFrozen(obj)); |
| 277 desc = Object.getOwnPropertyDescriptor(obj, 'x'); |
| 278 assertTrue(desc.enumerable); |
| 279 desc = Object.getOwnPropertyDescriptor(obj, 'y'); |
| 280 assertFalse(desc.enumerable); |
| 281 |
| 282 // Fast properties should remain fast |
| 283 obj = { x: 42, y: 'foo' }; |
| 284 assertTrue(%HasFastProperties(obj)); |
| 285 Object.seal(obj); |
| 286 assertTrue(Object.isSealed(obj)); |
| 287 assertFalse(Object.isFrozen(obj)); |
| 288 assertTrue(%HasFastProperties(obj)); |
| 289 |
| 290 // Sealed objects should share maps where possible |
| 291 obj = { prop1: 1, prop2: 2 }; |
| 292 obj2 = { prop1: 3, prop2: 4 }; |
| 293 assertTrue(%HaveSameMap(obj, obj2)); |
| 294 Object.seal(obj); |
| 295 Object.seal(obj2); |
| 296 assertTrue(Object.isSealed(obj)); |
| 297 assertTrue(Object.isSealed(obj2)); |
| 298 assertFalse(Object.isFrozen(obj)); |
| 299 assertFalse(Object.isFrozen(obj2)); |
| 300 assertTrue(%HaveSameMap(obj, obj2)); |
| 301 |
| 302 // Sealed objects should share maps even when they have elements |
| 303 obj = { prop1: 1, prop2: 2, 75: 'foo' }; |
| 304 obj2 = { prop1: 3, prop2: 4, 150: 'bar' }; |
| 305 assertTrue(%HaveSameMap(obj, obj2)); |
| 306 Object.seal(obj); |
| 307 Object.seal(obj2); |
| 308 assertTrue(Object.isSealed(obj)); |
| 309 assertTrue(Object.isSealed(obj2)); |
| 310 assertFalse(Object.isFrozen(obj)); |
| 311 assertFalse(Object.isFrozen(obj)); |
| 312 assertTrue(%HaveSameMap(obj, obj2)); |
| 313 |
| 314 // Setting elements after sealing should not be allowed |
| 315 obj = { prop: 'thing' }; |
| 316 Object.seal(obj); |
| 317 assertTrue(Object.isSealed(obj)); |
| 318 assertFalse(Object.isFrozen(obj)); |
| 319 obj[0] = 'hello'; |
| 320 assertFalse(obj.hasOwnProperty(0)); |
| 321 |
| 322 // Sealing an object in dictionary mode should work |
| 323 // Also testing that getter/setter properties work after sealing |
| 324 obj = { }; |
| 325 for (var i = 0; i < 100; ++i) { |
| 326 obj['x' + i] = i; |
| 327 } |
| 328 var accessorDidRun = false; |
| 329 Object.defineProperty(obj, 'accessor', { |
| 330 get: function() { return 42 }, |
| 331 set: function() { accessorDidRun = true }, |
| 332 configurable: true, |
| 333 enumerable: true |
| 334 }); |
| 335 |
| 336 assertFalse(%HasFastProperties(obj)); |
| 337 Object.seal(obj); |
| 338 assertFalse(%HasFastProperties(obj)); |
| 339 assertTrue(Object.isSealed(obj)); |
| 340 assertFalse(Object.isFrozen(obj)); |
| 341 assertFalse(Object.isExtensible(obj)); |
| 342 for (var i = 0; i < 100; ++i) { |
| 343 desc = Object.getOwnPropertyDescriptor(obj, 'x' + i); |
| 344 assertFalse(desc.configurable); |
| 345 } |
| 346 assertEquals(42, obj.accessor); |
| 347 assertFalse(accessorDidRun); |
| 348 obj.accessor = 'ignored value'; |
| 349 assertTrue(accessorDidRun); |
| 350 |
| 351 // Sealing arguments should work |
| 352 var func = function(arg) { |
| 353 Object.seal(arguments); |
| 354 assertTrue(Object.isSealed(arguments)); |
| 355 }; |
| 356 func('hello', 'world'); |
| 357 func('goodbye', 'world'); |
| 358 |
| 359 // Sealing sparse arrays |
| 360 var sparseArr = [0, 1]; |
| 361 sparseArr[10000] = 10000; |
| 362 Object.seal(sparseArr); |
| 363 assertTrue(Object.isSealed(sparseArr)); |
| 364 |
| 365 // Accessors on fast object should behavior properly after sealing |
| 366 obj = {}; |
| 367 Object.defineProperty(obj, 'accessor', { |
| 368 get: function() { return 42 }, |
| 369 set: function() { accessorDidRun = true }, |
| 370 configurable: true, |
| 371 enumerable: true |
| 372 }); |
| 373 assertTrue(%HasFastProperties(obj)); |
| 374 Object.seal(obj); |
| 375 assertTrue(Object.isSealed(obj)); |
| 376 assertTrue(%HasFastProperties(obj)); |
| 377 assertEquals(42, obj.accessor); |
| 378 accessorDidRun = false; |
| 379 obj.accessor = 'ignored value'; |
| 380 assertTrue(accessorDidRun); |
| 381 |
| 382 // Test for regression in mixed accessor/data property objects. |
| 383 // The strict function is one such object. |
| 384 assertTrue(Object.isSealed(Object.seal(function(){"use strict";}))); |
| 385 |
| 386 // Also test a simpler case |
| 387 obj = {}; |
| 388 Object.defineProperty(obj, 'accessor2', { |
| 389 get: function() { return 42 }, |
| 390 set: function() { accessorDidRun = true }, |
| 391 configurable: true, |
| 392 enumerable: true |
| 393 }); |
| 394 obj.data = 'foo'; |
| 395 assertTrue(%HasFastProperties(obj)); |
| 396 Object.seal(obj); |
| 397 assertTrue(%HasFastProperties(obj)); |
| 398 assertTrue(Object.isSealed(obj)); |
OLD | NEW |