From 47a22dcecdad8e4c52efb98453aadd54716e7f08 Mon Sep 17 00:00:00 2001 From: "antonm@chromium.org" Date: Wed, 9 Feb 2011 19:09:26 +0000 Subject: [PATCH] Reapply http://code.google.com/p/v8/source/detail?r=6555 Compare JSObjects by identity immediately. When invoking EQUALS JS builtin, 1st argument is passed as a receiver and if it's a global object, it gets overwritten with global proxy object and thus one gets incorrect results. BUG=v8:1082 TBR=ricow@chromium.org Review URL: http://codereview.chromium.org/6461028 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6708 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/api.cc | 6 ++++++ test/cctest/test-api.cc | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/api.cc b/src/api.cc index 80a53bf..188047b 100644 --- a/src/api.cc +++ b/src/api.cc @@ -2206,6 +2206,12 @@ bool Value::Equals(Handle that) const { ENTER_V8; i::Handle obj = Utils::OpenHandle(this); i::Handle other = Utils::OpenHandle(*that); + // If both obj and other are JSObjects, we'd better compare by identity + // immediately when going into JS builtin. The reason is Invoke + // would overwrite global object receiver with global proxy. + if (obj->IsJSObject() && other->IsJSObject()) { + return *obj == *other; + } i::Object** args[1] = { other.location() }; EXCEPTION_PREAMBLE(); i::Handle result = diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc index 970fdaa..2410d09 100644 --- a/test/cctest/test-api.cc +++ b/test/cctest/test-api.cc @@ -12523,6 +12523,25 @@ TEST(RegExp) { } +THREADED_TEST(Equals) { + v8::HandleScope handleScope; + LocalContext localContext; + + v8::Handle globalProxy = localContext->Global(); + v8::Handle global = globalProxy->GetPrototype(); + + CHECK(global->StrictEquals(global)); + CHECK(!global->StrictEquals(globalProxy)); + CHECK(!globalProxy->StrictEquals(global)); + CHECK(globalProxy->StrictEquals(globalProxy)); + + CHECK(global->Equals(global)); + CHECK(!global->Equals(globalProxy)); + CHECK(!globalProxy->Equals(global)); + CHECK(globalProxy->Equals(globalProxy)); +} + + static v8::Handle Getter(v8::Local property, const v8::AccessorInfo& info ) { return v8_str("42!"); -- 2.7.4