From 15c979eeaa64777548cc95509947ce33d1111eec Mon Sep 17 00:00:00 2001 From: "jkummerow@chromium.org" Date: Mon, 1 Aug 2011 12:18:03 +0000 Subject: [PATCH] Make window.{undefined,NaN,Infinity} read-only as per ES5. BUG=89490 TEST=es5conform 15.1.*, 15.2.3.*; mjsunit/undeletable-functions Review URL: http://codereview.chromium.org/7538016 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@8766 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/runtime.cc | 9 ++++----- src/v8natives.js | 7 ++++--- test/cctest/test-decls.cc | 2 +- test/es5conform/es5conform.status | 10 ---------- test/mjsunit/undeletable-functions.js | 4 +++- test/sputnik/sputnik.status | 11 +++++++++++ 6 files changed, 23 insertions(+), 20 deletions(-) diff --git a/src/runtime.cc b/src/runtime.cc index f965276..ca83a10 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -1172,7 +1172,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) { return ThrowRedeclarationError(isolate, "const", name); } // Otherwise, we check for locally conflicting declarations. - if (is_local && (is_read_only || is_const_property)) { + if (is_local && is_const_property) { const char* type = (is_read_only) ? "const" : "var"; return ThrowRedeclarationError(isolate, type, name); } @@ -1406,12 +1406,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) { // make sure to introduce it. found = false; } else if ((intercepted & READ_ONLY) != 0) { - // The property is present, but read-only. Since we're trying to - // overwrite it with a variable declaration we must throw a - // re-declaration error. However if we found readonly property + // The property is present, but read-only, so we ignore the + // redeclaration. However if we found readonly property // on one of hidden prototypes, just shadow it. if (real_holder != isolate->context()->global()) break; - return ThrowRedeclarationError(isolate, "const", name); + return isolate->heap()->undefined_value(); } } diff --git a/src/v8natives.js b/src/v8natives.js index be9b297..7242506 100644 --- a/src/v8natives.js +++ b/src/v8natives.js @@ -162,13 +162,14 @@ function GlobalEval(x) { function SetupGlobal() { // ECMA 262 - 15.1.1.1. - %SetProperty(global, "NaN", $NaN, DONT_ENUM | DONT_DELETE); + %SetProperty(global, "NaN", $NaN, DONT_ENUM | DONT_DELETE | READ_ONLY); // ECMA-262 - 15.1.1.2. - %SetProperty(global, "Infinity", 1/0, DONT_ENUM | DONT_DELETE); + %SetProperty(global, "Infinity", 1/0, DONT_ENUM | DONT_DELETE | READ_ONLY); // ECMA-262 - 15.1.1.3. - %SetProperty(global, "undefined", void 0, DONT_ENUM | DONT_DELETE); + %SetProperty(global, "undefined", void 0, + DONT_ENUM | DONT_DELETE | READ_ONLY); // Setup non-enumerable function on the global object. InstallFunctions(global, DONT_ENUM, $Array( diff --git a/test/cctest/test-decls.cc b/test/cctest/test-decls.cc index 6198391..9f7340e 100644 --- a/test/cctest/test-decls.cc +++ b/test/cctest/test-decls.cc @@ -498,7 +498,7 @@ TEST(Reappearing) { 0, 2, // var declaration + const initialization 4, // 2 x declaration + 2 x initialization - EXPECT_EXCEPTION); // x has already been declared! + EXPECT_RESULT, Undefined()); // x = 0 fails for a const. } } diff --git a/test/es5conform/es5conform.status b/test/es5conform/es5conform.status index 55712ba..3a56f0b 100644 --- a/test/es5conform/es5conform.status +++ b/test/es5conform/es5conform.status @@ -41,16 +41,6 @@ chapter10/10.4/10.4.2/10.4.2-2-c-1: FAIL_OK # We are compatible with Safari and Firefox. chapter11/11.1/11.1.5: UNIMPLEMENTED -# We do not have a global object called 'global' as required by tests. -chapter15/15.1: FAIL_OK - -# NaN is writable. We are compatible with JSC. -chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-178: FAIL_OK -# Infinity is writable. We are compatible with JSC. -chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-179: FAIL_OK -# undefined is writable. We are compatible with JSC. -chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-180: FAIL_OK - # Our Function object has an "arguments" property which is used as a # non-property in the test. chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-183: FAIL_OK diff --git a/test/mjsunit/undeletable-functions.js b/test/mjsunit/undeletable-functions.js index 04fd060..bbb798f 100644 --- a/test/mjsunit/undeletable-functions.js +++ b/test/mjsunit/undeletable-functions.js @@ -76,6 +76,8 @@ array = [ "execScript"]; CheckEcmaSemantics(this, array, "Global"); CheckReadOnlyAttr(this, "Infinity"); +CheckReadOnlyAttr(this, "NaN"); +CheckReadOnlyAttr(this, "undefined"); array = ["exec", "test", "toString", "compile"]; CheckEcmaSemantics(RegExp.prototype, array, "RegExp prototype"); @@ -189,7 +191,7 @@ function CheckReadOnlyAttr(type, prop) { assertFalse(deleted, "delete operator returned true: " + prop); assertTrue(type.hasOwnProperty(prop), "not there after delete: " + prop); type[prop] = "foo"; - assertEquals("foo", type[prop], "overwritable: " + prop); + assertEquals(old, type[prop], "overwritable: " + prop); } print("OK"); diff --git a/test/sputnik/sputnik.status b/test/sputnik/sputnik.status index 82d8a61..02acec0 100644 --- a/test/sputnik/sputnik.status +++ b/test/sputnik/sputnik.status @@ -178,6 +178,17 @@ S15.5.4.13_A1_T3: FAIL_OK S15.5.4.14_A1_T3: FAIL_OK S15.5.4.15_A1_T3: FAIL_OK +# NaN, Infinity and undefined are read-only according to ES5. +S15.1.1.1_A2_T1: FAIL_OK # NaN +S15.1.1.1_A2_T2: FAIL_OK # NaN +S15.1.1.2_A2_T1: FAIL_OK # Infinity +# S15.1.1.2_A2_T2 would fail if it weren't bogus in r97. sputnik bug #45. +S15.1.1.3_A2_T1: FAIL_OK # undefined +S15.1.1.3_A2_T2: FAIL_OK # undefined +S8.1_A3: FAIL_OK # undefined (comment is correct, test itself is bogus/ES3) +S8.5_A4: FAIL_OK # NaN +S8.5_A10: FAIL_OK # Infinity + ##################### SKIPPED TESTS ##################### # These tests take a looong time to run in debug mode. -- 2.7.4