Reviewers: Mads Ager,
Message:
Mads,
may you have a look?
I am not quite satisfied with this CL: ideally I'd rather have 2-arguments
SAFE_EQUALS JS builtin or function which invokes EQUALS JS builtin (or vice
versa). However I didn't manage to make JS bultins call each other. And
if I
make SAFE_EQUALS a plain JS function, it might trigger GC when getting
lazily
compiled (which is no-no thanks to security checks). So I ended up with
this
special casing. Any other ideas are most appreciated.
Description:
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
Please review this at http://codereview.chromium.org/6287018/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files:
M src/api.cc
M test/cctest/test-api.cc
Index: src/api.cc
diff --git a/src/api.cc b/src/api.cc
index
93037822cf3553ca0b60b62b736430b96770520d..abc48ba1a0c160b76147b824de3a61c107dfb52f
100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -2200,6 +2200,12 @@ bool Value::Equals(Handle<Value> that) const {
ENTER_V8;
i::Handle<i::Object> obj = Utils::OpenHandle(this);
i::Handle<i::Object> 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<i::Object> result =
Index: test/cctest/test-api.cc
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index
9b9f469f60a7a4d434eed5ca7c5003487f0a4fad..3a58929e497d065bbf49dd2f5c0a37749746c342
100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -12201,6 +12201,25 @@ TEST(RegExp) {
}
+THREADED_TEST(EQUALS) {
+ v8::HandleScope handleScope;
+ LocalContext localContext;
+
+ v8::Handle<v8::Object> globalProxy = localContext->Global();
+ v8::Handle<Value> global = globalProxy->GetPrototype();
+
+ CHECK_EQ(1, global->StrictEquals(global));
+ CHECK_EQ(0, global->StrictEquals(globalProxy));
+ CHECK_EQ(0, globalProxy->StrictEquals(global));
+ CHECK_EQ(1, globalProxy->StrictEquals(globalProxy));
+
+ CHECK_EQ(1, global->Equals(global));
+ CHECK_EQ(0, global->Equals(globalProxy));
+ CHECK_EQ(0, globalProxy->Equals(global));
+ CHECK_EQ(1, globalProxy->Equals(globalProxy));
+}
+
+
static v8::Handle<v8::Value> Getter(v8::Local<v8::String> property,
const v8::AccessorInfo& info ) {
return v8_str("42!");
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev