From b09c048f693d280052ac63c7d6b3baf27b3bf271 Mon Sep 17 00:00:00 2001 From: caitpotter88 Date: Tue, 21 Apr 2015 14:46:11 -0700 Subject: [PATCH] [es6] don't throw if argument is non-object (O.freeze, O.seal, O.preventExtensions) BUG=v8:3965, v8:3966 R=arv@chromium.org LOG=N Review URL: https://codereview.chromium.org/1011823003 Cr-Commit-Position: refs/heads/master@{#27985} --- src/v8natives.js | 24 +++------- test/mjsunit/messages.js | 5 --- test/mjsunit/object-freeze.js | 88 ++++++++++++++++++++++++++++--------- test/mjsunit/object-seal.js | 33 ++++++-------- test/test262-es6/test262-es6.status | 26 ----------- test/test262/test262.status | 30 +++++++++++++ 6 files changed, 117 insertions(+), 89 deletions(-) diff --git a/src/v8natives.js b/src/v8natives.js index 8ff6f40..9eaf5d4 100644 --- a/src/v8natives.js +++ b/src/v8natives.js @@ -1255,9 +1255,7 @@ function ProxyFix(obj) { // ES5 section 15.2.3.8. function ObjectSealJS(obj) { - if (!IS_SPEC_OBJECT(obj)) { - throw MakeTypeError(kCalledOnNonObject, "Object.seal"); - } + if (!IS_SPEC_OBJECT(obj)) return obj; var isProxy = %_IsJSProxy(obj); if (isProxy || %HasSloppyArgumentsElements(obj) || %IsObserved(obj)) { if (isProxy) { @@ -1284,9 +1282,7 @@ function ObjectSealJS(obj) { // ES5 section 15.2.3.9. function ObjectFreezeJS(obj) { - if (!IS_SPEC_OBJECT(obj)) { - throw MakeTypeError(kCalledOnNonObject, "Object.freeze"); - } + if (!IS_SPEC_OBJECT(obj)) return obj; var isProxy = %_IsJSProxy(obj); if (isProxy || %HasSloppyArgumentsElements(obj) || %IsObserved(obj)) { if (isProxy) { @@ -1314,9 +1310,7 @@ function ObjectFreezeJS(obj) { // ES5 section 15.2.3.10 function ObjectPreventExtension(obj) { - if (!IS_SPEC_OBJECT(obj)) { - throw MakeTypeError(kCalledOnNonObject, "Object.preventExtension"); - } + if (!IS_SPEC_OBJECT(obj)) return obj; if (%_IsJSProxy(obj)) { ProxyFix(obj); } @@ -1327,9 +1321,7 @@ function ObjectPreventExtension(obj) { // ES5 section 15.2.3.11 function ObjectIsSealed(obj) { - if (!IS_SPEC_OBJECT(obj)) { - throw MakeTypeError(kCalledOnNonObject, "Object.isSealed"); - } + if (!IS_SPEC_OBJECT(obj)) return true; if (%_IsJSProxy(obj)) { return false; } @@ -1350,9 +1342,7 @@ function ObjectIsSealed(obj) { // ES5 section 15.2.3.12 function ObjectIsFrozen(obj) { - if (!IS_SPEC_OBJECT(obj)) { - throw MakeTypeError(kCalledOnNonObject, "Object.isFrozen"); - } + if (!IS_SPEC_OBJECT(obj)) return true; if (%_IsJSProxy(obj)) { return false; } @@ -1372,9 +1362,7 @@ function ObjectIsFrozen(obj) { // ES5 section 15.2.3.13 function ObjectIsExtensible(obj) { - if (!IS_SPEC_OBJECT(obj)) { - throw MakeTypeError(kCalledOnNonObject, "Object.isExtensible"); - } + if (!IS_SPEC_OBJECT(obj)) return false; if (%_IsJSProxy(obj)) { return true; } diff --git a/test/mjsunit/messages.js b/test/mjsunit/messages.js index d148063..30920a1 100644 --- a/test/mjsunit/messages.js +++ b/test/mjsunit/messages.js @@ -37,11 +37,6 @@ test(function() { [].forEach(1); }, "1 is not a function", TypeError); -// kCalledOnNonObject -test(function() { - Object.freeze(1) -}, "Object.freeze called on non-object", TypeError); - // kCannotConvertToPrimitive test(function() { [].join(Object(Symbol(1))); diff --git a/test/mjsunit/object-freeze.js b/test/mjsunit/object-freeze.js index 5d1f8b7..23f5af0 100644 --- a/test/mjsunit/object-freeze.js +++ b/test/mjsunit/object-freeze.js @@ -25,33 +25,20 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Tests the Object.freeze and Object.isFrozen methods - ES 15.2.3.9 and -// ES 15.2.3.12 +// Tests the Object.freeze and Object.isFrozen methods - ES 19.1.2.5 and +// ES 19.1.2.12 // Flags: --allow-natives-syntax -// 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); +// Test that we return obj if non-object is passed as argument +var non_objects = new Array(undefined, null, 1, -1, 0, 42.43, Symbol("test")); for (var key in non_objects) { - var exception = false; - try { - Object.freeze(non_objects[key]); - } catch(e) { - exception = true; - assertTrue(/Object.freeze called on non-object/.test(e)); - } - assertTrue(exception); + assertSame(non_objects[key], Object.freeze(non_objects[key])); } +// Test that isFrozen always returns true for non-objects for (var key in non_objects) { - exception = false; - try { - Object.isFrozen(non_objects[key]); - } catch(e) { - exception = true; - assertTrue(/Object.isFrozen called on non-object/.test(e)); - } - assertTrue(exception); + assertTrue(Object.isFrozen(non_objects[key])); } // Test normal data properties. @@ -348,3 +335,64 @@ assertFalse(Object.isFrozen(obj)); Object.freeze(obj); assertTrue(Object.isSealed(obj)); assertTrue(Object.isFrozen(obj)); + + +(function propertiesOfFrozenObjectNotFrozen() { + function Frozen() {} + Object.freeze(Frozen); + assertDoesNotThrow(function() { return new Frozen(); }); + Frozen.prototype.prototypeExists = true; + assertTrue((new Frozen()).prototypeExists); +})(); + + +(function frozenPrototypePreventsPUT() { + // A read-only property on the prototype should prevent a [[Put]] . + function Constructor() {} + Constructor.prototype.foo = 1; + Object.freeze(Constructor.prototype); + var obj = new Constructor(); + obj.foo = 2; + assertSame(1, obj.foo); +})(); + + +(function frozenFunctionSloppy() { + // Check that freezing a function works correctly. + var func = Object.freeze(function foo(){}); + assertTrue(Object.isFrozen(func)); + func.prototype = 42; + assertFalse(func.prototype === 42); + assertFalse(Object.getOwnPropertyDescriptor(func, "prototype").writable); +})(); + + +(function frozenFunctionStrict() { + // Check that freezing a strict function works correctly. + var func = Object.freeze(function foo(){ "use strict"; }); + assertTrue(Object.isFrozen(func)); + func.prototype = 42; + assertFalse(func.prototype === 42); + assertFalse(Object.getOwnPropertyDescriptor(func, "prototype").writable); +})(); + + +(function frozenArrayObject() { + // Check that freezing array objects works correctly. + var array = Object.freeze([0,1,2]); + assertTrue(Object.isFrozen(array)); + array[0] = 3; + assertEquals(0, array[0]); + assertFalse(Object.getOwnPropertyDescriptor(array, "length").writable); +})(); + + +(function frozenArgumentsObject() { + // Check that freezing arguments objects works correctly. + var args = Object.freeze((function(){ return arguments; })(0,1,2)); + assertTrue(Object.isFrozen(args)); + args[0] = 3; + assertEquals(0, args[0]); + assertFalse(Object.getOwnPropertyDescriptor(args, "length").writable); + assertFalse(Object.getOwnPropertyDescriptor(args, "callee").writable); +})(); diff --git a/test/mjsunit/object-seal.js b/test/mjsunit/object-seal.js index 3c46ab2..ef1b16d 100644 --- a/test/mjsunit/object-seal.js +++ b/test/mjsunit/object-seal.js @@ -25,33 +25,20 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Tests the Object.seal and Object.isSealed methods - ES 15.2.3.9 and -// ES 15.2.3.12 +// Tests the Object.seal and Object.isSealed methods - ES 19.1.2.17 and +// ES 19.1.2.13 // 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); +// Test that we return obj if non-object is passed as argument +var non_objects = new Array(undefined, null, 1, -1, 0, 42.43, Symbol("test")); for (var key in non_objects) { - var exception = false; - try { - Object.seal(non_objects[key]); - } catch(e) { - exception = true; - assertTrue(/Object.seal called on non-object/.test(e)); - } - assertTrue(exception); + assertSame(non_objects[key], Object.seal(non_objects[key])); } +// Test that isFrozen always returns true for non-objects for (var key in non_objects) { - exception = false; - try { - Object.isSealed(non_objects[key]); - } catch(e) { - exception = true; - assertTrue(/Object.isSealed called on non-object/.test(e)); - } - assertTrue(exception); + assertTrue(Object.isSealed(non_objects[key])); } // Test normal data properties. @@ -396,3 +383,9 @@ assertTrue(%HasFastProperties(obj)); Object.seal(obj); assertTrue(%HasFastProperties(obj)); assertTrue(Object.isSealed(obj)); + +function Sealed() {} +Object.seal(Sealed); +assertDoesNotThrow(function() { return new Sealed(); }); +Sealed.prototype.prototypeExists = true; +assertTrue((new Sealed()).prototypeExists); diff --git a/test/test262-es6/test262-es6.status b/test/test262-es6/test262-es6.status index d93dd2f..31bb60b 100644 --- a/test/test262-es6/test262-es6.status +++ b/test/test262-es6/test262-es6.status @@ -260,36 +260,10 @@ 'built-ins/Date/prototype/setFullYear/15.9.5.40_1': [FAIL], 'built-ins/Error/prototype/S15.11.4_A2': [FAIL], 'built-ins/Object/defineProperty/15.2.3.6-4-293-4': [FAIL], - 'built-ins/Object/freeze/15.2.3.9-1': [FAIL], - 'built-ins/Object/freeze/15.2.3.9-1-1': [FAIL], - 'built-ins/Object/freeze/15.2.3.9-1-2': [FAIL], - 'built-ins/Object/freeze/15.2.3.9-1-3': [FAIL], - 'built-ins/Object/freeze/15.2.3.9-1-4': [FAIL], 'built-ins/Object/getOwnPropertyDescriptor/15.2.3.3-4-212': [FAIL], 'built-ins/Object/getOwnPropertyDescriptor/15.2.3.3-4-213': [FAIL], 'built-ins/Object/getOwnPropertyDescriptor/15.2.3.3-4-214': [FAIL], 'built-ins/Object/getOwnPropertyDescriptor/15.2.3.3-4-215': [FAIL], - 'built-ins/Object/isExtensible/15.2.3.13-1': [FAIL], - 'built-ins/Object/isExtensible/15.2.3.13-1-1': [FAIL], - 'built-ins/Object/isExtensible/15.2.3.13-1-2': [FAIL], - 'built-ins/Object/isExtensible/15.2.3.13-1-3': [FAIL], - 'built-ins/Object/isExtensible/15.2.3.13-1-4': [FAIL], - 'built-ins/Object/isFrozen/15.2.3.12-1': [FAIL], - 'built-ins/Object/isFrozen/15.2.3.12-1-1': [FAIL], - 'built-ins/Object/isFrozen/15.2.3.12-1-2': [FAIL], - 'built-ins/Object/isFrozen/15.2.3.12-1-3': [FAIL], - 'built-ins/Object/isFrozen/15.2.3.12-1-4': [FAIL], - 'built-ins/Object/isSealed/15.2.3.11-1': [FAIL], - 'built-ins/Object/preventExtensions/15.2.3.10-1': [FAIL], - 'built-ins/Object/preventExtensions/15.2.3.10-1-1': [FAIL], - 'built-ins/Object/preventExtensions/15.2.3.10-1-2': [FAIL], - 'built-ins/Object/preventExtensions/15.2.3.10-1-3': [FAIL], - 'built-ins/Object/preventExtensions/15.2.3.10-1-4': [FAIL], - 'built-ins/Object/seal/15.2.3.8-1': [FAIL], - 'built-ins/Object/seal/15.2.3.8-1-1': [FAIL], - 'built-ins/Object/seal/15.2.3.8-1-2': [FAIL], - 'built-ins/Object/seal/15.2.3.8-1-3': [FAIL], - 'built-ins/Object/seal/15.2.3.8-1-4': [FAIL], 'built-ins/Promise/S25.4.3.1_A5.1_T2': [FAIL], 'built-ins/Promise/prototype/then/S25.4.2.1_A3.1_T2': [FAIL], 'built-ins/Promise/prototype/then/S25.4.2.1_A3.2_T2': [FAIL], diff --git a/test/test262/test262.status b/test/test262/test262.status index d08deac..4ae13da 100644 --- a/test/test262/test262.status +++ b/test/test262/test262.status @@ -226,6 +226,36 @@ '15.3.4.5-21-4': [FAIL], '15.3.4.5-21-5': [FAIL], + # Object.freeze(O), Object.seal(O), and Object.preventExtensions(O), + # Object.isFrozen(O), Object.isSealed(O), and Object.isExtensible(O) no longer + # throw when passed a non-object value in ES6. + '15.2.3.8-1': [FAIL], + '15.2.3.8-1-1': [FAIL], + '15.2.3.8-1-2': [FAIL], + '15.2.3.8-1-3': [FAIL], + '15.2.3.8-1-4': [FAIL], + '15.2.3.9-1': [FAIL], + '15.2.3.9-1-1': [FAIL], + '15.2.3.9-1-2': [FAIL], + '15.2.3.9-1-3': [FAIL], + '15.2.3.9-1-4': [FAIL], + '15.2.3.10-1': [FAIL], + '15.2.3.10-1-1': [FAIL], + '15.2.3.10-1-2': [FAIL], + '15.2.3.10-1-3': [FAIL], + '15.2.3.10-1-4': [FAIL], + '15.2.3.11-1': [FAIL], + '15.2.3.12-1': [FAIL], + '15.2.3.12-1-1': [FAIL], + '15.2.3.12-1-2': [FAIL], + '15.2.3.12-1-3': [FAIL], + '15.2.3.12-1-4': [FAIL], + '15.2.3.13-1': [FAIL], + '15.2.3.13-1-1': [FAIL], + '15.2.3.13-1-2': [FAIL], + '15.2.3.13-1-3': [FAIL], + '15.2.3.13-1-4': [FAIL], + ######################## NEEDS INVESTIGATION ########################### # These test failures are specific to the intl402 suite and need investigation -- 2.7.4