| Index: test/mjsunit/object-seal.js | 
| diff --git a/test/mjsunit/object-seal.js b/test/mjsunit/object-seal.js | 
| index f21baed37711d954d309bc9009d534c998583778..f31f0b7dd2649513ce1a153bb358e05c95eb6091 100644 | 
| --- a/test/mjsunit/object-seal.js | 
| +++ b/test/mjsunit/object-seal.js | 
| @@ -28,6 +28,7 @@ | 
| // Tests the Object.seal and Object.isSealed methods - ES 15.2.3.9 and | 
| // ES 15.2.3.12 | 
|  | 
| +// Flags: --allow-natives-syntax --noalways-opt | 
|  | 
| // Test that we throw an error if an object is not passed as argument. | 
| var non_objects = new Array(undefined, null, 1, -1, 0, 42.43); | 
| @@ -192,3 +193,78 @@ assertFalse(Object.isSealed(obj4)); | 
| // Make sure that Object.seal returns the sealed object. | 
| var obj4 = {}; | 
| assertTrue(obj4 === Object.seal(obj4)); | 
| + | 
| +// | 
| +// Test that built-in array functions can't modify a sealed array. | 
| +// | 
| +obj = [1, 2, 3]; | 
| +var objControl = [4, 5, 6]; | 
| + | 
| +// Allow these functions to set up monomorphic calls, using custom built-ins. | 
| +var push_call = function(a) { a.push(10); return a; } | 
| +var pop_call = function(a) { return a.pop(); } | 
| +for (var i = 0; i < 3; i++) { | 
| +  push_call(obj); | 
| +  pop_call(obj); | 
| +} | 
| + | 
| +Object.seal(obj); | 
| +assertThrows(function() { push_call(obj); }, TypeError); | 
| +assertThrows(function() { pop_call(obj); }, TypeError); | 
| + | 
| +// But the control object is fine at these sites. | 
| +assertDoesNotThrow(function() { push_call(objControl); }); | 
| +assertDoesNotThrow(function() { pop_call(objControl); }); | 
| + | 
| +assertDoesNotThrow(function() { obj.push(); }); | 
| +assertThrows(function() { obj.push(3); }, TypeError); | 
| +assertThrows(function() { obj.pop(); }, TypeError); | 
| +assertThrows(function() { obj.shift(3); }, TypeError); | 
| +assertDoesNotThrow(function() { obj.unshift(); }); | 
| +assertThrows(function() { obj.unshift(1); }, TypeError); | 
| +assertThrows(function() { obj.splice(0, 0, 100, 101, 102); }, TypeError); | 
| +assertDoesNotThrow(function() { obj.splice(0,0); }); | 
| + | 
| +assertDoesNotThrow(function() { objControl.push(3); }); | 
| +assertDoesNotThrow(function() { objControl.pop(); }); | 
| +assertDoesNotThrow(function() { objControl.shift(3); }); | 
| +assertDoesNotThrow(function() { objControl.unshift(); }); | 
| +assertDoesNotThrow(function() { objControl.splice(0, 0, 100, 101, 102); }); | 
| + | 
| +// Verify that crankshaft still does the right thing. | 
| +obj = [1, 2, 3]; | 
| + | 
| +push_call = function(a) { a.push(1000); return a; } | 
| +// Include a call site that doesn't have a custom built-in. | 
| +var shift_call = function(a) { a.shift(1000); return a; } | 
| +for (var i = 0; i < 3; i++) { | 
| +  push_call(obj); | 
| +  shift_call(obj); | 
| +} | 
| + | 
| +%OptimizeFunctionOnNextCall(push_call); | 
| +%OptimizeFunctionOnNextCall(shift_call); | 
| +push_call(obj); | 
| +shift_call(obj); | 
| +assertOptimized(push_call); | 
| +assertOptimized(shift_call); | 
| +Object.seal(obj); | 
| +assertThrows(function() { push_call(obj); }, TypeError); | 
| +assertThrows(function() { shift_call(obj); }, TypeError); | 
| +assertOptimized(push_call); | 
| +// shift() doesn't have a custom call generator, so deopt will occur. | 
| +assertUnoptimized(shift_call); | 
| +assertDoesNotThrow(function() { push_call(objControl); }); | 
| +assertDoesNotThrow(function() { shift_call(objControl); }); | 
| + | 
| +// Verify special behavior of splice on sealed objects. | 
| +obj = [1,2,3]; | 
| +Object.seal(obj); | 
| +assertDoesNotThrow(function() { obj.splice(0,1,100); }); | 
| +assertEquals(100, obj[0]); | 
| +assertDoesNotThrow(function() { obj.splice(0,2,1,2); }); | 
| +assertDoesNotThrow(function() { obj.splice(1,2,1,2); }); | 
| +// Count of items to delete is clamped by length. | 
| +assertDoesNotThrow(function() { obj.splice(1,2000,1,2); }); | 
| +assertThrows(function() { obj.splice(0,0,1); }, TypeError); | 
| +assertThrows(function() { obj.splice(1,2000,1,2,3); }, TypeError); | 
|  |