Expose hasOwnProperty() through API.

BUG=http://code.google.com/p/v8/issues/detail?id=1342
TEST=test-api/HasOwnProperty

Review URL: http://codereview.chromium.org/6903059

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7699 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent bae61ba6
// Copyright 2007-2009 the V8 project authors. All rights reserved. // Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are // modification, are permitted provided that the following conditions are
// met: // met:
...@@ -1588,6 +1588,7 @@ class Object : public Value { ...@@ -1588,6 +1588,7 @@ class Object : public Value {
V8EXPORT void SetPointerInInternalField(int index, void* value); V8EXPORT void SetPointerInInternalField(int index, void* value);
// Testers for local properties. // Testers for local properties.
V8EXPORT bool HasOwnProperty(Handle<String> key);
V8EXPORT bool HasRealNamedProperty(Handle<String> key); V8EXPORT bool HasRealNamedProperty(Handle<String> key);
V8EXPORT bool HasRealIndexedProperty(uint32_t index); V8EXPORT bool HasRealIndexedProperty(uint32_t index);
V8EXPORT bool HasRealNamedCallbackProperty(Handle<String> key); V8EXPORT bool HasRealNamedCallbackProperty(Handle<String> key);
......
// Copyright 2010 the V8 project authors. All rights reserved. // Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are // modification, are permitted provided that the following conditions are
// met: // met:
...@@ -2751,6 +2751,15 @@ bool Object::SetAccessor(Handle<String> name, ...@@ -2751,6 +2751,15 @@ bool Object::SetAccessor(Handle<String> name,
} }
bool v8::Object::HasOwnProperty(Handle<String> key) {
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ON_BAILOUT(isolate, "v8::Object::HasOwnProperty()",
return false);
return Utils::OpenHandle(this)->HasLocalProperty(
*Utils::OpenHandle(*key));
}
bool v8::Object::HasRealNamedProperty(Handle<String> key) { bool v8::Object::HasRealNamedProperty(Handle<String> key) {
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ON_BAILOUT(isolate, "v8::Object::HasRealNamedProperty()", ON_BAILOUT(isolate, "v8::Object::HasRealNamedProperty()",
......
...@@ -202,8 +202,6 @@ THREADED_TEST(ReceiverSignature) { ...@@ -202,8 +202,6 @@ THREADED_TEST(ReceiverSignature) {
} }
THREADED_TEST(ArgumentSignature) { THREADED_TEST(ArgumentSignature) {
v8::HandleScope scope; v8::HandleScope scope;
LocalContext env; LocalContext env;
...@@ -13911,3 +13909,117 @@ THREADED_TEST(CreationContext) { ...@@ -13911,3 +13909,117 @@ THREADED_TEST(CreationContext) {
context2.Dispose(); context2.Dispose();
context3.Dispose(); context3.Dispose();
} }
Handle<Value> HasOwnPropertyIndexedPropertyGetter(uint32_t index,
const AccessorInfo& info) {
if (index == 42) return v8_str("yes");
return Handle<v8::Integer>();
}
Handle<Value> HasOwnPropertyNamedPropertyGetter(Local<String> property,
const AccessorInfo& info) {
if (property->Equals(v8_str("foo"))) return v8_str("yes");
return Handle<Value>();
}
Handle<v8::Integer> HasOwnPropertyIndexedPropertyQuery(
uint32_t index, const AccessorInfo& info) {
if (index == 42) return v8_num(1).As<v8::Integer>();
return Handle<v8::Integer>();
}
Handle<v8::Integer> HasOwnPropertyNamedPropertyQuery(
Local<String> property, const AccessorInfo& info) {
if (property->Equals(v8_str("foo"))) return v8_num(1).As<v8::Integer>();
return Handle<v8::Integer>();
}
Handle<v8::Integer> HasOwnPropertyNamedPropertyQuery2(
Local<String> property, const AccessorInfo& info) {
if (property->Equals(v8_str("bar"))) return v8_num(1).As<v8::Integer>();
return Handle<v8::Integer>();
}
Handle<Value> HasOwnPropertyAccessorGetter(Local<String> property,
const AccessorInfo& info) {
return v8_str("yes");
}
TEST(HasOwnProperty) {
v8::HandleScope scope;
LocalContext env;
{ // Check normal properties and defined getters.
Handle<Value> value = CompileRun(
"function Foo() {"
" this.foo = 11;"
" this.__defineGetter__('baz', function() { return 1; });"
"};"
"function Bar() { "
" this.bar = 13;"
" this.__defineGetter__('bla', function() { return 2; });"
"};"
"Bar.prototype = new Foo();"
"new Bar();");
CHECK(value->IsObject());
Handle<Object> object = value->ToObject();
CHECK(object->Has(v8_str("foo")));
CHECK(!object->HasOwnProperty(v8_str("foo")));
CHECK(object->HasOwnProperty(v8_str("bar")));
CHECK(object->Has(v8_str("baz")));
CHECK(!object->HasOwnProperty(v8_str("baz")));
CHECK(object->HasOwnProperty(v8_str("bla")));
}
{ // Check named getter interceptors.
Handle<ObjectTemplate> templ = ObjectTemplate::New();
templ->SetNamedPropertyHandler(HasOwnPropertyNamedPropertyGetter);
Handle<Object> instance = templ->NewInstance();
CHECK(!instance->HasOwnProperty(v8_str("42")));
CHECK(instance->HasOwnProperty(v8_str("foo")));
CHECK(!instance->HasOwnProperty(v8_str("bar")));
}
{ // Check indexed getter interceptors.
Handle<ObjectTemplate> templ = ObjectTemplate::New();
templ->SetIndexedPropertyHandler(HasOwnPropertyIndexedPropertyGetter);
Handle<Object> instance = templ->NewInstance();
CHECK(instance->HasOwnProperty(v8_str("42")));
CHECK(!instance->HasOwnProperty(v8_str("43")));
CHECK(!instance->HasOwnProperty(v8_str("foo")));
}
{ // Check named query interceptors.
Handle<ObjectTemplate> templ = ObjectTemplate::New();
templ->SetNamedPropertyHandler(0, 0, HasOwnPropertyNamedPropertyQuery);
Handle<Object> instance = templ->NewInstance();
CHECK(instance->HasOwnProperty(v8_str("foo")));
CHECK(!instance->HasOwnProperty(v8_str("bar")));
}
{ // Check indexed query interceptors.
Handle<ObjectTemplate> templ = ObjectTemplate::New();
templ->SetIndexedPropertyHandler(0, 0, HasOwnPropertyIndexedPropertyQuery);
Handle<Object> instance = templ->NewInstance();
CHECK(instance->HasOwnProperty(v8_str("42")));
CHECK(!instance->HasOwnProperty(v8_str("41")));
}
{ // Check callbacks.
Handle<ObjectTemplate> templ = ObjectTemplate::New();
templ->SetAccessor(v8_str("foo"), HasOwnPropertyAccessorGetter);
Handle<Object> instance = templ->NewInstance();
CHECK(instance->HasOwnProperty(v8_str("foo")));
CHECK(!instance->HasOwnProperty(v8_str("bar")));
}
{ // Check that query wins on disagreement.
Handle<ObjectTemplate> templ = ObjectTemplate::New();
templ->SetNamedPropertyHandler(HasOwnPropertyNamedPropertyGetter,
0,
HasOwnPropertyNamedPropertyQuery2);
Handle<Object> instance = templ->NewInstance();
CHECK(!instance->HasOwnProperty(v8_str("foo")));
CHECK(instance->HasOwnProperty(v8_str("bar")));
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment