Reviewers: Jakob,
Message:
PTAL
Description:
Always fail when trying to store to an undeclared global variable, even if
it
was found.
Finding a property, but not using an IC, indicates that the variable was
found on the prototype (in DOMWindow). Those properties need to be
ignored while storing global properties via the IC.
Please review this at https://chromiumcodereview.appspot.com/12040039/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files:
M src/ic.h
M src/ic.cc
M src/stub-cache.cc
M test/cctest/cctest.gyp
A + test/cctest/test-global-object.cc
Index: src/ic.cc
diff --git a/src/ic.cc b/src/ic.cc
index
b90436ae42c5f38feed72cf4d44be0d6f6b8b04f..17d2bb45ee5ce661cd516532ce18c8cbf273f8eb
100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -542,7 +542,7 @@ MaybeObject* CallICBase::LoadFunction(State state,
if (!lookup.IsFound()) {
// If the object does not have the requested property, check which
// exception we need to throw.
- return IsContextual(object)
+ return IsUndeclaredGlobal(object)
? ReferenceError("not_defined", name)
: TypeError("undefined_method", object, name);
}
@@ -561,7 +561,7 @@ MaybeObject* CallICBase::LoadFunction(State state,
if (lookup.IsInterceptor() && attr == ABSENT) {
// If the object does not have the requested property, check which
// exception we need to throw.
- return IsContextual(object)
+ return IsUndeclaredGlobal(object)
? ReferenceError("not_defined", name)
: TypeError("undefined_method", object, name);
}
@@ -933,7 +933,7 @@ MaybeObject* IC::Load(State state,
// If we did not find a property, check if we need to throw an exception.
if (!lookup.IsFound()) {
- if (IsContextual(object)) {
+ if (IsUndeclaredGlobal(object)) {
return ReferenceError("not_defined", name);
}
LOG(isolate(), SuspectReadEvent(*name, *object));
@@ -952,7 +952,7 @@ MaybeObject* IC::Load(State state,
RETURN_IF_EMPTY_HANDLE(isolate(), result);
// If the property is not present, check if we need to throw an
// exception.
- if (attr == ABSENT && IsContextual(object)) {
+ if (attr == ABSENT && IsUndeclaredGlobal(object)) {
return ReferenceError("not_defined", name);
}
return *result;
@@ -1390,11 +1390,8 @@ MaybeObject* IC::Store(State state,
if (FLAG_use_ic) {
UpdateStoreCaches(&lookup, state, strict_mode, receiver, name,
value);
}
- } else if (strict_mode == kStrictMode &&
- !lookup.IsFound() &&
- IsContextual(object)) {
- // Strict mode doesn't allow setting non-existent global property
- // or an assignment to a read only property.
+ } else if (strict_mode == kStrictMode && IsUndeclaredGlobal(object)) {
+ // Strict mode doesn't allow setting non-existent global property.
return ReferenceError("not_defined", name);
}
Index: src/ic.h
diff --git a/src/ic.h b/src/ic.h
index
784512a1c49f8b2f421495dc93cee5d1a1fafadb..04b0bb5a83a06962f788ea3e7347b364c0e3e542
100644
--- a/src/ic.h
+++ b/src/ic.h
@@ -110,16 +110,16 @@ class IC {
// Returns if this IC is for contextual (no explicit receiver)
// access to properties.
- bool IsContextual(Handle<Object> receiver) {
+ bool IsUndeclaredGlobal(Handle<Object> receiver) {
if (receiver->IsGlobalObject()) {
- return SlowIsContextual();
+ return SlowIsUndeclaredGlobal();
} else {
- ASSERT(!SlowIsContextual());
+ ASSERT(!SlowIsUndeclaredGlobal());
return false;
}
}
- bool SlowIsContextual() {
+ bool SlowIsUndeclaredGlobal() {
return ComputeMode() == RelocInfo::CODE_TARGET_CONTEXT;
}
Index: src/stub-cache.cc
diff --git a/src/stub-cache.cc b/src/stub-cache.cc
index
08954ba618ae7ef761a9e9a8df1fc8289fb9b9d9..0e8f755c9ff72612826d04f9be1aaf278bdefea5
100644
--- a/src/stub-cache.cc
+++ b/src/stub-cache.cc
@@ -1057,7 +1057,7 @@ static MaybeObject* ThrowReferenceError(String* name)
{
// can't use either LoadIC or KeyedLoadIC constructors.
IC ic(IC::NO_EXTRA_FRAME, Isolate::Current());
ASSERT(ic.target()->is_load_stub() || ic.target()->is_keyed_load_stub());
- if (!ic.SlowIsContextual()) return HEAP->undefined_value();
+ if (!ic.SlowIsUndeclaredGlobal()) return HEAP->undefined_value();
// Throw a reference error.
HandleScope scope;
Index: test/cctest/cctest.gyp
diff --git a/test/cctest/cctest.gyp b/test/cctest/cctest.gyp
index
80eecfd0316f2e87d8590bfdbdd0cc03c0a95072..18a116ab65641df60e6cd882cf04b10e28a513f7
100644
--- a/test/cctest/cctest.gyp
+++ b/test/cctest/cctest.gyp
@@ -69,6 +69,7 @@
'test-fixed-dtoa.cc',
'test-flags.cc',
'test-func-name-inference.cc',
+ 'test-global-object.cc',
'test-hashing.cc',
'test-hashmap.cc',
'test-heap.cc',
Index: test/cctest/test-global-object.cc
diff --git a/test/mjsunit/regress/regress-2499.js
b/test/cctest/test-global-object.cc
similarity index 65%
copy from test/mjsunit/regress/regress-2499.js
copy to test/cctest/test-global-object.cc
index
52aad874db6fcdc89f5ee1ae4db45304e64b0e77..049b53d117b61f7b918fca9e6e368aca6520ebb7
100644
--- a/test/mjsunit/regress/regress-2499.js
+++ b/test/cctest/test-global-object.cc
@@ -25,16 +25,29 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --allow-natives-syntax
+#include "v8.h"
-function foo(word, nBits) {
- return (word[1] >>> nBits) | (word[0] << (32 - nBits));
-}
+#include "cctest.h"
-word = [0x1001, 0];
+using namespace v8;
-var expected = foo(word, 1);
-foo(word, 1);
-%OptimizeFunctionOnNextCall(foo);
-var optimized = foo(word, 1);
-assertEquals(expected, optimized)
+// This test fails if properties on the prototype of the global object
appear
+// as declared globals.
+TEST(StrictUndeclaredGlobalVariable) {
+ HandleScope scope;
+ v8::Local<v8::String> var_name = v8_str("x");
+ v8::Local<v8::String> result_name = v8_str("z");
+ LocalContext context;
+ v8::Local<v8::Script> script =
+ v8_compile("\"use strict\";"
+ "var z;"
+ "try { x = 42; z = 10; } catch (e) { z = 20; };");
+ v8::Handle<v8::Object> proto = v8::Object::New();
+ v8::Handle<v8::Object> global =
+ context->Global()->GetPrototype().As<v8::Object>();
+ proto->Set(var_name, v8_num(100));
+ global->SetPrototype(proto);
+ script->Run();
+ v8::Local<v8::Value> result = context->Global()->Get(result_name);
+ CHECK_EQ(20, result->Int32Value());
+}
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev