Since SameValue algorithm is defined formally in ECMA262 and V8 already
exported Equals and StrictEquals algorithms, SameValue should be exposed.
And in this issue, we fix the issue of Object::SameValue implementation,
SameValue(0.0, -0.0) returnes true.
BUG=v8:2909
TEST=cctest/test-api/Equality
R=mstarzinger@chromium.org
Review URL: https://codereview.chromium.org/
24360017
Patch from Yusuke Suzuki <yusukesuzuki@chromium.org>.
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16924
ce2b1a6d-e550-0410-aec6-
3dcde31c8c00
/** JS == */
bool Equals(Handle<Value> that) const;
bool StrictEquals(Handle<Value> that) const;
+ bool SameValue(Handle<Value> that) const;
template <class T> V8_INLINE static Value* Cast(T* value);
}
+bool Value::SameValue(Handle<Value> that) const {
+ i::Isolate* isolate = i::Isolate::Current();
+ if (EmptyCheck("v8::Value::SameValue()", this) ||
+ EmptyCheck("v8::Value::SameValue()", that)) {
+ return false;
+ }
+ LOG_API(isolate, "SameValue");
+ i::Handle<i::Object> obj = Utils::OpenHandle(this);
+ i::Handle<i::Object> other = Utils::OpenHandle(*that);
+ return obj->SameValue(*other);
+}
+
+
uint32_t Value::Uint32Value() const {
i::Handle<i::Object> obj = Utils::OpenHandle(this);
if (obj->IsSmi()) {
if (IsNumber() && other->IsNumber()) {
double this_value = Number();
double other_value = other->Number();
- return (this_value == other_value) ||
- (std::isnan(this_value) && std::isnan(other_value));
+ bool equal = this_value == other_value;
+ // SameValue(NaN, NaN) is true.
+ if (!equal) return std::isnan(this_value) && std::isnan(other_value);
+ // SameValue(0.0, -0.0) is false.
+ return (this_value != 0) || ((1 / this_value) == (1 / other_value));
}
if (IsString() && other->IsString()) {
return String::cast(this)->Equals(String::cast(other));
CHECK(!v8_str("5")->StrictEquals(v8_num(5)));
CHECK(v8_num(1)->StrictEquals(v8_num(1)));
CHECK(!v8_num(1)->StrictEquals(v8_num(2)));
- CHECK(v8_num(0)->StrictEquals(v8_num(-0)));
+ CHECK(v8_num(0.0)->StrictEquals(v8_num(-0.0)));
Local<Value> not_a_number = v8_num(i::OS::nan_value());
CHECK(!not_a_number->StrictEquals(not_a_number));
CHECK(v8::False()->StrictEquals(v8::False()));
v8::Persistent<v8::Object> alias(isolate, obj);
CHECK(v8::Local<v8::Object>::New(isolate, alias)->StrictEquals(obj));
alias.Dispose();
+
+ CHECK(v8_str("a")->SameValue(v8_str("a")));
+ CHECK(!v8_str("a")->SameValue(v8_str("b")));
+ CHECK(!v8_str("5")->SameValue(v8_num(5)));
+ CHECK(v8_num(1)->SameValue(v8_num(1)));
+ CHECK(!v8_num(1)->SameValue(v8_num(2)));
+ CHECK(!v8_num(0.0)->SameValue(v8_num(-0.0)));
+ CHECK(not_a_number->SameValue(not_a_number));
+ CHECK(v8::False()->SameValue(v8::False()));
+ CHECK(!v8::False()->SameValue(v8::Undefined()));
}