Change Has* and Get*Attributes to return Maybe<*>, indicating possible exceptions.
BUG= R=ishell@chromium.org Review URL: https://codereview.chromium.org/418383002 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22624 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
3c873c4305
commit
4a956ab1c2
@ -895,6 +895,13 @@ struct Maybe {
|
||||
};
|
||||
|
||||
|
||||
// Convenience wrapper.
|
||||
template <class T>
|
||||
inline Maybe<T> maybe(T t) {
|
||||
return Maybe<T>(t);
|
||||
}
|
||||
|
||||
|
||||
// --- Special objects ---
|
||||
|
||||
|
||||
|
52
src/api.cc
52
src/api.cc
@ -1905,7 +1905,11 @@ v8::Local<Value> v8::TryCatch::StackTrace() const {
|
||||
i::HandleScope scope(isolate_);
|
||||
i::Handle<i::JSObject> obj(i::JSObject::cast(raw_obj), isolate_);
|
||||
i::Handle<i::String> name = isolate_->factory()->stack_string();
|
||||
if (!i::JSReceiver::HasProperty(obj, name)) return v8::Local<Value>();
|
||||
EXCEPTION_PREAMBLE(isolate_);
|
||||
Maybe<bool> maybe = i::JSReceiver::HasProperty(obj, name);
|
||||
has_pending_exception = !maybe.has_value;
|
||||
EXCEPTION_BAILOUT_CHECK(isolate_, v8::Local<Value>());
|
||||
if (!maybe.value) return v8::Local<Value>();
|
||||
i::Handle<i::Object> value;
|
||||
if (!i::Object::GetProperty(obj, name).ToHandle(&value)) {
|
||||
return v8::Local<Value>();
|
||||
@ -3139,10 +3143,13 @@ PropertyAttribute v8::Object::GetPropertyAttributes(v8::Handle<Value> key) {
|
||||
EXCEPTION_BAILOUT_CHECK(isolate, static_cast<PropertyAttribute>(NONE));
|
||||
}
|
||||
i::Handle<i::Name> key_name = i::Handle<i::Name>::cast(key_obj);
|
||||
PropertyAttributes result =
|
||||
EXCEPTION_PREAMBLE(isolate);
|
||||
Maybe<PropertyAttributes> result =
|
||||
i::JSReceiver::GetPropertyAttributes(self, key_name);
|
||||
if (result == ABSENT) return static_cast<PropertyAttribute>(NONE);
|
||||
return static_cast<PropertyAttribute>(result);
|
||||
has_pending_exception = !result.has_value;
|
||||
EXCEPTION_BAILOUT_CHECK(isolate, static_cast<PropertyAttribute>(NONE));
|
||||
if (result.value == ABSENT) return static_cast<PropertyAttribute>(NONE);
|
||||
return static_cast<PropertyAttribute>(result.value);
|
||||
}
|
||||
|
||||
|
||||
@ -3399,7 +3406,11 @@ bool v8::Object::Has(uint32_t index) {
|
||||
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
|
||||
ON_BAILOUT(isolate, "v8::Object::HasProperty()", return false);
|
||||
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
|
||||
return i::JSReceiver::HasElement(self, index);
|
||||
EXCEPTION_PREAMBLE(isolate);
|
||||
Maybe<bool> maybe = i::JSReceiver::HasElement(self, index);
|
||||
has_pending_exception = !maybe.has_value;
|
||||
EXCEPTION_BAILOUT_CHECK(isolate, false);
|
||||
return maybe.value;
|
||||
}
|
||||
|
||||
|
||||
@ -3478,8 +3489,12 @@ bool v8::Object::HasOwnProperty(Handle<String> key) {
|
||||
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
|
||||
ON_BAILOUT(isolate, "v8::Object::HasOwnProperty()",
|
||||
return false);
|
||||
return i::JSReceiver::HasOwnProperty(
|
||||
Utils::OpenHandle(this), Utils::OpenHandle(*key));
|
||||
EXCEPTION_PREAMBLE(isolate);
|
||||
Maybe<bool> maybe = i::JSReceiver::HasOwnProperty(Utils::OpenHandle(this),
|
||||
Utils::OpenHandle(*key));
|
||||
has_pending_exception = !maybe.has_value;
|
||||
EXCEPTION_BAILOUT_CHECK(isolate, false);
|
||||
return maybe.value;
|
||||
}
|
||||
|
||||
|
||||
@ -3487,8 +3502,12 @@ bool v8::Object::HasRealNamedProperty(Handle<String> key) {
|
||||
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
|
||||
ON_BAILOUT(isolate, "v8::Object::HasRealNamedProperty()",
|
||||
return false);
|
||||
return i::JSObject::HasRealNamedProperty(Utils::OpenHandle(this),
|
||||
Utils::OpenHandle(*key));
|
||||
EXCEPTION_PREAMBLE(isolate);
|
||||
Maybe<bool> maybe = i::JSObject::HasRealNamedProperty(
|
||||
Utils::OpenHandle(this), Utils::OpenHandle(*key));
|
||||
has_pending_exception = !maybe.has_value;
|
||||
EXCEPTION_BAILOUT_CHECK(isolate, false);
|
||||
return maybe.value;
|
||||
}
|
||||
|
||||
|
||||
@ -3496,7 +3515,12 @@ bool v8::Object::HasRealIndexedProperty(uint32_t index) {
|
||||
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
|
||||
ON_BAILOUT(isolate, "v8::Object::HasRealIndexedProperty()",
|
||||
return false);
|
||||
return i::JSObject::HasRealElementProperty(Utils::OpenHandle(this), index);
|
||||
EXCEPTION_PREAMBLE(isolate);
|
||||
Maybe<bool> maybe =
|
||||
i::JSObject::HasRealElementProperty(Utils::OpenHandle(this), index);
|
||||
has_pending_exception = !maybe.has_value;
|
||||
EXCEPTION_BAILOUT_CHECK(isolate, false);
|
||||
return maybe.value;
|
||||
}
|
||||
|
||||
|
||||
@ -3506,8 +3530,12 @@ bool v8::Object::HasRealNamedCallbackProperty(Handle<String> key) {
|
||||
"v8::Object::HasRealNamedCallbackProperty()",
|
||||
return false);
|
||||
ENTER_V8(isolate);
|
||||
return i::JSObject::HasRealNamedCallbackProperty(Utils::OpenHandle(this),
|
||||
Utils::OpenHandle(*key));
|
||||
EXCEPTION_PREAMBLE(isolate);
|
||||
Maybe<bool> maybe = i::JSObject::HasRealNamedCallbackProperty(
|
||||
Utils::OpenHandle(this), Utils::OpenHandle(*key));
|
||||
has_pending_exception = !maybe.has_value;
|
||||
EXCEPTION_BAILOUT_CHECK(isolate, false);
|
||||
return maybe.value;
|
||||
}
|
||||
|
||||
|
||||
|
@ -106,15 +106,18 @@ Handle<Object> Context::Lookup(Handle<String> name,
|
||||
// Context extension objects needs to behave as if they have no
|
||||
// prototype. So even if we want to follow prototype chains, we need
|
||||
// to only do a local lookup for context extension objects.
|
||||
Maybe<PropertyAttributes> maybe;
|
||||
if ((flags & FOLLOW_PROTOTYPE_CHAIN) == 0 ||
|
||||
object->IsJSContextExtensionObject()) {
|
||||
*attributes = JSReceiver::GetOwnPropertyAttributes(object, name);
|
||||
maybe = JSReceiver::GetOwnPropertyAttributes(object, name);
|
||||
} else {
|
||||
*attributes = JSReceiver::GetPropertyAttributes(object, name);
|
||||
maybe = JSReceiver::GetPropertyAttributes(object, name);
|
||||
}
|
||||
if (isolate->has_pending_exception()) return Handle<Object>();
|
||||
if (!maybe.has_value) return Handle<Object>();
|
||||
ASSERT(!isolate->has_pending_exception());
|
||||
*attributes = maybe.value;
|
||||
|
||||
if (*attributes != ABSENT) {
|
||||
if (maybe.value != ABSENT) {
|
||||
if (FLAG_trace_contexts) {
|
||||
PrintF("=> found property in context object %p\n",
|
||||
reinterpret_cast<void*>(*object));
|
||||
|
24
src/i18n.cc
24
src/i18n.cc
@ -419,7 +419,9 @@ void SetResolvedNumberSettings(Isolate* isolate,
|
||||
|
||||
Handle<String> key =
|
||||
factory->NewStringFromStaticAscii("minimumSignificantDigits");
|
||||
if (JSReceiver::HasOwnProperty(resolved, key)) {
|
||||
Maybe<bool> maybe = JSReceiver::HasOwnProperty(resolved, key);
|
||||
CHECK(maybe.has_value);
|
||||
if (maybe.value) {
|
||||
JSObject::SetProperty(
|
||||
resolved,
|
||||
factory->NewStringFromStaticAscii("minimumSignificantDigits"),
|
||||
@ -428,7 +430,9 @@ void SetResolvedNumberSettings(Isolate* isolate,
|
||||
}
|
||||
|
||||
key = factory->NewStringFromStaticAscii("maximumSignificantDigits");
|
||||
if (JSReceiver::HasOwnProperty(resolved, key)) {
|
||||
maybe = JSReceiver::HasOwnProperty(resolved, key);
|
||||
CHECK(maybe.has_value);
|
||||
if (maybe.value) {
|
||||
JSObject::SetProperty(
|
||||
resolved,
|
||||
factory->NewStringFromStaticAscii("maximumSignificantDigits"),
|
||||
@ -783,7 +787,9 @@ icu::SimpleDateFormat* DateFormat::UnpackDateFormat(
|
||||
Handle<JSObject> obj) {
|
||||
Handle<String> key =
|
||||
isolate->factory()->NewStringFromStaticAscii("dateFormat");
|
||||
if (JSReceiver::HasOwnProperty(obj, key)) {
|
||||
Maybe<bool> maybe = JSReceiver::HasOwnProperty(obj, key);
|
||||
CHECK(maybe.has_value);
|
||||
if (maybe.value) {
|
||||
return reinterpret_cast<icu::SimpleDateFormat*>(
|
||||
obj->GetInternalField(0));
|
||||
}
|
||||
@ -857,7 +863,9 @@ icu::DecimalFormat* NumberFormat::UnpackNumberFormat(
|
||||
Handle<JSObject> obj) {
|
||||
Handle<String> key =
|
||||
isolate->factory()->NewStringFromStaticAscii("numberFormat");
|
||||
if (JSReceiver::HasOwnProperty(obj, key)) {
|
||||
Maybe<bool> maybe = JSReceiver::HasOwnProperty(obj, key);
|
||||
CHECK(maybe.has_value);
|
||||
if (maybe.value) {
|
||||
return reinterpret_cast<icu::DecimalFormat*>(obj->GetInternalField(0));
|
||||
}
|
||||
|
||||
@ -912,7 +920,9 @@ icu::Collator* Collator::InitializeCollator(
|
||||
icu::Collator* Collator::UnpackCollator(Isolate* isolate,
|
||||
Handle<JSObject> obj) {
|
||||
Handle<String> key = isolate->factory()->NewStringFromStaticAscii("collator");
|
||||
if (JSReceiver::HasOwnProperty(obj, key)) {
|
||||
Maybe<bool> maybe = JSReceiver::HasOwnProperty(obj, key);
|
||||
CHECK(maybe.has_value);
|
||||
if (maybe.value) {
|
||||
return reinterpret_cast<icu::Collator*>(obj->GetInternalField(0));
|
||||
}
|
||||
|
||||
@ -971,7 +981,9 @@ icu::BreakIterator* BreakIterator::UnpackBreakIterator(Isolate* isolate,
|
||||
Handle<JSObject> obj) {
|
||||
Handle<String> key =
|
||||
isolate->factory()->NewStringFromStaticAscii("breakIterator");
|
||||
if (JSReceiver::HasOwnProperty(obj, key)) {
|
||||
Maybe<bool> maybe = JSReceiver::HasOwnProperty(obj, key);
|
||||
CHECK(maybe.has_value);
|
||||
if (maybe.value) {
|
||||
return reinterpret_cast<icu::BreakIterator*>(obj->GetInternalField(0));
|
||||
}
|
||||
|
||||
|
@ -106,15 +106,18 @@ typedef ZoneList<Handle<Object> > ZoneObjectList;
|
||||
|
||||
// Macros for MaybeHandle.
|
||||
|
||||
#define RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, T) \
|
||||
#define RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, value) \
|
||||
do { \
|
||||
Isolate* __isolate__ = (isolate); \
|
||||
if (__isolate__->has_scheduled_exception()) { \
|
||||
__isolate__->PromoteScheduledException(); \
|
||||
return MaybeHandle<T>(); \
|
||||
return value; \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#define RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, T) \
|
||||
RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, MaybeHandle<T>())
|
||||
|
||||
#define ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, dst, call, value) \
|
||||
do { \
|
||||
if (!(call).ToHandle(&dst)) { \
|
||||
|
@ -1166,7 +1166,8 @@ MaybeHandle<Object> JSProxy::SetElementWithHandler(Handle<JSProxy> proxy,
|
||||
}
|
||||
|
||||
|
||||
bool JSProxy::HasElementWithHandler(Handle<JSProxy> proxy, uint32_t index) {
|
||||
Maybe<bool> JSProxy::HasElementWithHandler(Handle<JSProxy> proxy,
|
||||
uint32_t index) {
|
||||
Isolate* isolate = proxy->GetIsolate();
|
||||
Handle<String> name = isolate->factory()->Uint32ToString(index);
|
||||
return HasPropertyWithHandler(proxy, name);
|
||||
@ -6629,27 +6630,32 @@ Object* JSReceiver::GetConstructor() {
|
||||
}
|
||||
|
||||
|
||||
bool JSReceiver::HasProperty(Handle<JSReceiver> object,
|
||||
Maybe<bool> JSReceiver::HasProperty(Handle<JSReceiver> object,
|
||||
Handle<Name> name) {
|
||||
if (object->IsJSProxy()) {
|
||||
Handle<JSProxy> proxy = Handle<JSProxy>::cast(object);
|
||||
return JSProxy::HasPropertyWithHandler(proxy, name);
|
||||
}
|
||||
return GetPropertyAttributes(object, name) != ABSENT;
|
||||
Maybe<PropertyAttributes> result = GetPropertyAttributes(object, name);
|
||||
if (!result.has_value) return Maybe<bool>();
|
||||
return maybe(result.value != ABSENT);
|
||||
}
|
||||
|
||||
|
||||
bool JSReceiver::HasOwnProperty(Handle<JSReceiver> object, Handle<Name> name) {
|
||||
Maybe<bool> JSReceiver::HasOwnProperty(Handle<JSReceiver> object,
|
||||
Handle<Name> name) {
|
||||
if (object->IsJSProxy()) {
|
||||
Handle<JSProxy> proxy = Handle<JSProxy>::cast(object);
|
||||
return JSProxy::HasPropertyWithHandler(proxy, name);
|
||||
}
|
||||
return GetOwnPropertyAttributes(object, name) != ABSENT;
|
||||
Maybe<PropertyAttributes> result = GetOwnPropertyAttributes(object, name);
|
||||
if (!result.has_value) return Maybe<bool>();
|
||||
return maybe(result.value != ABSENT);
|
||||
}
|
||||
|
||||
|
||||
PropertyAttributes JSReceiver::GetPropertyAttributes(Handle<JSReceiver> object,
|
||||
Handle<Name> key) {
|
||||
Maybe<PropertyAttributes> JSReceiver::GetPropertyAttributes(
|
||||
Handle<JSReceiver> object, Handle<Name> key) {
|
||||
uint32_t index;
|
||||
if (object->IsJSObject() && key->AsArrayIndex(&index)) {
|
||||
return GetElementAttribute(object, index);
|
||||
@ -6659,8 +6665,8 @@ PropertyAttributes JSReceiver::GetPropertyAttributes(Handle<JSReceiver> object,
|
||||
}
|
||||
|
||||
|
||||
PropertyAttributes JSReceiver::GetElementAttribute(Handle<JSReceiver> object,
|
||||
uint32_t index) {
|
||||
Maybe<PropertyAttributes> JSReceiver::GetElementAttribute(
|
||||
Handle<JSReceiver> object, uint32_t index) {
|
||||
if (object->IsJSProxy()) {
|
||||
return JSProxy::GetElementAttributeWithHandler(
|
||||
Handle<JSProxy>::cast(object), object, index);
|
||||
@ -6696,27 +6702,32 @@ Object* JSReceiver::GetIdentityHash() {
|
||||
}
|
||||
|
||||
|
||||
bool JSReceiver::HasElement(Handle<JSReceiver> object, uint32_t index) {
|
||||
Maybe<bool> JSReceiver::HasElement(Handle<JSReceiver> object, uint32_t index) {
|
||||
if (object->IsJSProxy()) {
|
||||
Handle<JSProxy> proxy = Handle<JSProxy>::cast(object);
|
||||
return JSProxy::HasElementWithHandler(proxy, index);
|
||||
}
|
||||
return JSObject::GetElementAttributeWithReceiver(
|
||||
Handle<JSObject>::cast(object), object, index, true) != ABSENT;
|
||||
Maybe<PropertyAttributes> result = JSObject::GetElementAttributeWithReceiver(
|
||||
Handle<JSObject>::cast(object), object, index, true);
|
||||
if (!result.has_value) return Maybe<bool>();
|
||||
return maybe(result.value != ABSENT);
|
||||
}
|
||||
|
||||
|
||||
bool JSReceiver::HasOwnElement(Handle<JSReceiver> object, uint32_t index) {
|
||||
Maybe<bool> JSReceiver::HasOwnElement(Handle<JSReceiver> object,
|
||||
uint32_t index) {
|
||||
if (object->IsJSProxy()) {
|
||||
Handle<JSProxy> proxy = Handle<JSProxy>::cast(object);
|
||||
return JSProxy::HasElementWithHandler(proxy, index);
|
||||
}
|
||||
return JSObject::GetElementAttributeWithReceiver(
|
||||
Handle<JSObject>::cast(object), object, index, false) != ABSENT;
|
||||
Maybe<PropertyAttributes> result = JSObject::GetElementAttributeWithReceiver(
|
||||
Handle<JSObject>::cast(object), object, index, false);
|
||||
if (!result.has_value) return Maybe<bool>();
|
||||
return maybe(result.value != ABSENT);
|
||||
}
|
||||
|
||||
|
||||
PropertyAttributes JSReceiver::GetOwnElementAttribute(
|
||||
Maybe<PropertyAttributes> JSReceiver::GetOwnElementAttribute(
|
||||
Handle<JSReceiver> object, uint32_t index) {
|
||||
if (object->IsJSProxy()) {
|
||||
return JSProxy::GetElementAttributeWithHandler(
|
||||
|
239
src/objects.cc
239
src/objects.cc
@ -594,13 +594,15 @@ MaybeHandle<Object> JSObject::GetPropertyWithFailedAccessCheck(
|
||||
}
|
||||
|
||||
|
||||
PropertyAttributes JSObject::GetPropertyAttributesWithFailedAccessCheck(
|
||||
Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithFailedAccessCheck(
|
||||
LookupIterator* it) {
|
||||
Handle<JSObject> checked = it->GetHolder<JSObject>();
|
||||
if (FindAllCanReadHolder(it)) return it->property_details().attributes();
|
||||
if (FindAllCanReadHolder(it))
|
||||
return maybe(it->property_details().attributes());
|
||||
it->isolate()->ReportFailedAccessCheck(checked, v8::ACCESS_HAS);
|
||||
// TODO(yangguo): Issue 3269, check for scheduled exception missing?
|
||||
return ABSENT;
|
||||
RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(),
|
||||
Maybe<PropertyAttributes>());
|
||||
return maybe(ABSENT);
|
||||
}
|
||||
|
||||
|
||||
@ -3019,8 +3021,8 @@ MaybeHandle<Object> Object::SetProperty(LookupIterator* it,
|
||||
Maybe<PropertyAttributes> maybe_attributes =
|
||||
JSObject::GetPropertyAttributesWithInterceptor(
|
||||
it->GetHolder<JSObject>(), it->GetReceiver(), it->name());
|
||||
RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object);
|
||||
done = maybe_attributes.has_value;
|
||||
if (!maybe_attributes.has_value) return MaybeHandle<Object>();
|
||||
done = maybe_attributes.value != ABSENT;
|
||||
if (done && (maybe_attributes.value & READ_ONLY) != 0) {
|
||||
return WriteToReadOnlyProperty(it, value, strict_mode);
|
||||
}
|
||||
@ -3594,24 +3596,21 @@ void JSObject::LookupRealNamedPropertyInPrototypes(Handle<Name> name,
|
||||
}
|
||||
|
||||
|
||||
bool JSProxy::HasPropertyWithHandler(Handle<JSProxy> proxy, Handle<Name> name) {
|
||||
Maybe<bool> JSProxy::HasPropertyWithHandler(Handle<JSProxy> proxy,
|
||||
Handle<Name> name) {
|
||||
Isolate* isolate = proxy->GetIsolate();
|
||||
|
||||
// TODO(rossberg): adjust once there is a story for symbols vs proxies.
|
||||
if (name->IsSymbol()) return false;
|
||||
if (name->IsSymbol()) return maybe(false);
|
||||
|
||||
Handle<Object> args[] = { name };
|
||||
Handle<Object> result;
|
||||
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
|
||||
isolate, result,
|
||||
CallTrap(proxy,
|
||||
"has",
|
||||
isolate->derived_has_trap(),
|
||||
ARRAY_SIZE(args),
|
||||
args),
|
||||
false);
|
||||
isolate, result, CallTrap(proxy, "has", isolate->derived_has_trap(),
|
||||
ARRAY_SIZE(args), args),
|
||||
Maybe<bool>());
|
||||
|
||||
return result->BooleanValue();
|
||||
return maybe(result->BooleanValue());
|
||||
}
|
||||
|
||||
|
||||
@ -3779,62 +3778,58 @@ MaybeHandle<Object> JSProxy::DeleteElementWithHandler(
|
||||
}
|
||||
|
||||
|
||||
PropertyAttributes JSProxy::GetPropertyAttributesWithHandler(
|
||||
Handle<JSProxy> proxy,
|
||||
Handle<Object> receiver,
|
||||
Handle<Name> name) {
|
||||
Maybe<PropertyAttributes> JSProxy::GetPropertyAttributesWithHandler(
|
||||
Handle<JSProxy> proxy, Handle<Object> receiver, Handle<Name> name) {
|
||||
Isolate* isolate = proxy->GetIsolate();
|
||||
HandleScope scope(isolate);
|
||||
|
||||
// TODO(rossberg): adjust once there is a story for symbols vs proxies.
|
||||
if (name->IsSymbol()) return ABSENT;
|
||||
if (name->IsSymbol()) return maybe(ABSENT);
|
||||
|
||||
Handle<Object> args[] = { name };
|
||||
Handle<Object> result;
|
||||
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
|
||||
isolate, result,
|
||||
proxy->CallTrap(proxy,
|
||||
"getPropertyDescriptor",
|
||||
Handle<Object>(),
|
||||
ARRAY_SIZE(args),
|
||||
args),
|
||||
NONE);
|
||||
proxy->CallTrap(proxy, "getPropertyDescriptor", Handle<Object>(),
|
||||
ARRAY_SIZE(args), args),
|
||||
Maybe<PropertyAttributes>());
|
||||
|
||||
if (result->IsUndefined()) return ABSENT;
|
||||
if (result->IsUndefined()) return maybe(ABSENT);
|
||||
|
||||
Handle<Object> argv[] = { result };
|
||||
Handle<Object> desc;
|
||||
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
|
||||
isolate, desc,
|
||||
Execution::Call(isolate,
|
||||
isolate->to_complete_property_descriptor(),
|
||||
result,
|
||||
ARRAY_SIZE(argv),
|
||||
argv),
|
||||
NONE);
|
||||
Execution::Call(isolate, isolate->to_complete_property_descriptor(),
|
||||
result, ARRAY_SIZE(argv), argv),
|
||||
Maybe<PropertyAttributes>());
|
||||
|
||||
// Convert result to PropertyAttributes.
|
||||
Handle<String> enum_n = isolate->factory()->InternalizeOneByteString(
|
||||
STATIC_ASCII_VECTOR("enumerable_"));
|
||||
Handle<Object> enumerable;
|
||||
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
|
||||
isolate, enumerable, Object::GetProperty(desc, enum_n), NONE);
|
||||
ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, enumerable,
|
||||
Object::GetProperty(desc, enum_n),
|
||||
Maybe<PropertyAttributes>());
|
||||
Handle<String> conf_n = isolate->factory()->InternalizeOneByteString(
|
||||
STATIC_ASCII_VECTOR("configurable_"));
|
||||
Handle<Object> configurable;
|
||||
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
|
||||
isolate, configurable, Object::GetProperty(desc, conf_n), NONE);
|
||||
ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, configurable,
|
||||
Object::GetProperty(desc, conf_n),
|
||||
Maybe<PropertyAttributes>());
|
||||
Handle<String> writ_n = isolate->factory()->InternalizeOneByteString(
|
||||
STATIC_ASCII_VECTOR("writable_"));
|
||||
Handle<Object> writable;
|
||||
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
|
||||
isolate, writable, Object::GetProperty(desc, writ_n), NONE);
|
||||
ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, writable,
|
||||
Object::GetProperty(desc, writ_n),
|
||||
Maybe<PropertyAttributes>());
|
||||
if (!writable->BooleanValue()) {
|
||||
Handle<String> set_n = isolate->factory()->InternalizeOneByteString(
|
||||
STATIC_ASCII_VECTOR("set_"));
|
||||
Handle<Object> setter;
|
||||
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
|
||||
isolate, setter, Object::GetProperty(desc, set_n), NONE);
|
||||
ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, setter,
|
||||
Object::GetProperty(desc, set_n),
|
||||
Maybe<PropertyAttributes>());
|
||||
writable = isolate->factory()->ToBoolean(!setter->IsUndefined());
|
||||
}
|
||||
|
||||
@ -3846,21 +3841,19 @@ PropertyAttributes JSProxy::GetPropertyAttributesWithHandler(
|
||||
Handle<Object> error = isolate->factory()->NewTypeError(
|
||||
"proxy_prop_not_configurable", HandleVector(args, ARRAY_SIZE(args)));
|
||||
isolate->Throw(*error);
|
||||
return NONE;
|
||||
return maybe(NONE);
|
||||
}
|
||||
|
||||
int attributes = NONE;
|
||||
if (!enumerable->BooleanValue()) attributes |= DONT_ENUM;
|
||||
if (!configurable->BooleanValue()) attributes |= DONT_DELETE;
|
||||
if (!writable->BooleanValue()) attributes |= READ_ONLY;
|
||||
return static_cast<PropertyAttributes>(attributes);
|
||||
return maybe(static_cast<PropertyAttributes>(attributes));
|
||||
}
|
||||
|
||||
|
||||
PropertyAttributes JSProxy::GetElementAttributeWithHandler(
|
||||
Handle<JSProxy> proxy,
|
||||
Handle<JSReceiver> receiver,
|
||||
uint32_t index) {
|
||||
Maybe<PropertyAttributes> JSProxy::GetElementAttributeWithHandler(
|
||||
Handle<JSProxy> proxy, Handle<JSReceiver> receiver, uint32_t index) {
|
||||
Isolate* isolate = proxy->GetIsolate();
|
||||
Handle<String> name = isolate->factory()->Uint32ToString(index);
|
||||
return GetPropertyAttributesWithHandler(proxy, receiver, name);
|
||||
@ -4278,7 +4271,7 @@ Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithInterceptor(
|
||||
Handle<Object> receiver,
|
||||
Handle<Name> name) {
|
||||
// TODO(rossberg): Support symbols in the API.
|
||||
if (name->IsSymbol()) return Maybe<PropertyAttributes>();
|
||||
if (name->IsSymbol()) return maybe(ABSENT);
|
||||
|
||||
Isolate* isolate = holder->GetIsolate();
|
||||
HandleScope scope(isolate);
|
||||
@ -4299,8 +4292,7 @@ Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithInterceptor(
|
||||
args.Call(query, v8::Utils::ToLocal(Handle<String>::cast(name)));
|
||||
if (!result.IsEmpty()) {
|
||||
ASSERT(result->IsInt32());
|
||||
return Maybe<PropertyAttributes>(
|
||||
static_cast<PropertyAttributes>(result->Int32Value()));
|
||||
return maybe(static_cast<PropertyAttributes>(result->Int32Value()));
|
||||
}
|
||||
} else if (!interceptor->getter()->IsUndefined()) {
|
||||
v8::NamedPropertyGetterCallback getter =
|
||||
@ -4309,13 +4301,15 @@ Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithInterceptor(
|
||||
ApiNamedPropertyAccess("interceptor-named-get-has", *holder, *name));
|
||||
v8::Handle<v8::Value> result =
|
||||
args.Call(getter, v8::Utils::ToLocal(Handle<String>::cast(name)));
|
||||
if (!result.IsEmpty()) return Maybe<PropertyAttributes>(DONT_ENUM);
|
||||
if (!result.IsEmpty()) return maybe(DONT_ENUM);
|
||||
}
|
||||
return Maybe<PropertyAttributes>();
|
||||
|
||||
RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Maybe<PropertyAttributes>());
|
||||
return maybe(ABSENT);
|
||||
}
|
||||
|
||||
|
||||
PropertyAttributes JSReceiver::GetOwnPropertyAttributes(
|
||||
Maybe<PropertyAttributes> JSReceiver::GetOwnPropertyAttributes(
|
||||
Handle<JSReceiver> object, Handle<Name> name) {
|
||||
// Check whether the name is an array index.
|
||||
uint32_t index = 0;
|
||||
@ -4327,7 +4321,8 @@ PropertyAttributes JSReceiver::GetOwnPropertyAttributes(
|
||||
}
|
||||
|
||||
|
||||
PropertyAttributes JSReceiver::GetPropertyAttributes(LookupIterator* it) {
|
||||
Maybe<PropertyAttributes> JSReceiver::GetPropertyAttributes(
|
||||
LookupIterator* it) {
|
||||
for (; it->IsFound(); it->Next()) {
|
||||
switch (it->state()) {
|
||||
case LookupIterator::NOT_FOUND:
|
||||
@ -4339,25 +4334,26 @@ PropertyAttributes JSReceiver::GetPropertyAttributes(LookupIterator* it) {
|
||||
Maybe<PropertyAttributes> result =
|
||||
JSObject::GetPropertyAttributesWithInterceptor(
|
||||
it->GetHolder<JSObject>(), it->GetReceiver(), it->name());
|
||||
if (result.has_value) return result.value;
|
||||
if (!result.has_value) return result;
|
||||
if (result.value != ABSENT) return result;
|
||||
break;
|
||||
}
|
||||
case LookupIterator::ACCESS_CHECK:
|
||||
if (it->HasAccess(v8::ACCESS_HAS)) break;
|
||||
return JSObject::GetPropertyAttributesWithFailedAccessCheck(it);
|
||||
case LookupIterator::PROPERTY:
|
||||
if (it->HasProperty()) return it->property_details().attributes();
|
||||
if (it->HasProperty()) {
|
||||
return maybe(it->property_details().attributes());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ABSENT;
|
||||
return maybe(ABSENT);
|
||||
}
|
||||
|
||||
|
||||
PropertyAttributes JSObject::GetElementAttributeWithReceiver(
|
||||
Handle<JSObject> object,
|
||||
Handle<JSReceiver> receiver,
|
||||
uint32_t index,
|
||||
Maybe<PropertyAttributes> JSObject::GetElementAttributeWithReceiver(
|
||||
Handle<JSObject> object, Handle<JSReceiver> receiver, uint32_t index,
|
||||
bool check_prototype) {
|
||||
Isolate* isolate = object->GetIsolate();
|
||||
|
||||
@ -4365,14 +4361,14 @@ PropertyAttributes JSObject::GetElementAttributeWithReceiver(
|
||||
if (object->IsAccessCheckNeeded()) {
|
||||
if (!isolate->MayIndexedAccess(object, index, v8::ACCESS_HAS)) {
|
||||
isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS);
|
||||
// TODO(yangguo): Issue 3269, check for scheduled exception missing?
|
||||
return ABSENT;
|
||||
RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Maybe<PropertyAttributes>());
|
||||
return maybe(ABSENT);
|
||||
}
|
||||
}
|
||||
|
||||
if (object->IsJSGlobalProxy()) {
|
||||
PrototypeIterator iter(isolate, object);
|
||||
if (iter.IsAtEnd()) return ABSENT;
|
||||
if (iter.IsAtEnd()) return maybe(ABSENT);
|
||||
ASSERT(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
|
||||
return JSObject::GetElementAttributeWithReceiver(
|
||||
Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), receiver,
|
||||
@ -4390,10 +4386,8 @@ PropertyAttributes JSObject::GetElementAttributeWithReceiver(
|
||||
}
|
||||
|
||||
|
||||
PropertyAttributes JSObject::GetElementAttributeWithInterceptor(
|
||||
Handle<JSObject> object,
|
||||
Handle<JSReceiver> receiver,
|
||||
uint32_t index,
|
||||
Maybe<PropertyAttributes> JSObject::GetElementAttributeWithInterceptor(
|
||||
Handle<JSObject> object, Handle<JSReceiver> receiver, uint32_t index,
|
||||
bool check_prototype) {
|
||||
Isolate* isolate = object->GetIsolate();
|
||||
HandleScope scope(isolate);
|
||||
@ -4412,7 +4406,7 @@ PropertyAttributes JSObject::GetElementAttributeWithInterceptor(
|
||||
ApiIndexedPropertyAccess("interceptor-indexed-has", *object, index));
|
||||
v8::Handle<v8::Integer> result = args.Call(query, index);
|
||||
if (!result.IsEmpty())
|
||||
return static_cast<PropertyAttributes>(result->Int32Value());
|
||||
return maybe(static_cast<PropertyAttributes>(result->Int32Value()));
|
||||
} else if (!interceptor->getter()->IsUndefined()) {
|
||||
v8::IndexedPropertyGetterCallback getter =
|
||||
v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter());
|
||||
@ -4420,7 +4414,7 @@ PropertyAttributes JSObject::GetElementAttributeWithInterceptor(
|
||||
ApiIndexedPropertyAccess(
|
||||
"interceptor-indexed-get-has", *object, index));
|
||||
v8::Handle<v8::Value> result = args.Call(getter, index);
|
||||
if (!result.IsEmpty()) return NONE;
|
||||
if (!result.IsEmpty()) return maybe(NONE);
|
||||
}
|
||||
|
||||
return GetElementAttributeWithoutInterceptor(
|
||||
@ -4428,21 +4422,19 @@ PropertyAttributes JSObject::GetElementAttributeWithInterceptor(
|
||||
}
|
||||
|
||||
|
||||
PropertyAttributes JSObject::GetElementAttributeWithoutInterceptor(
|
||||
Handle<JSObject> object,
|
||||
Handle<JSReceiver> receiver,
|
||||
uint32_t index,
|
||||
Maybe<PropertyAttributes> JSObject::GetElementAttributeWithoutInterceptor(
|
||||
Handle<JSObject> object, Handle<JSReceiver> receiver, uint32_t index,
|
||||
bool check_prototype) {
|
||||
PropertyAttributes attr = object->GetElementsAccessor()->GetAttributes(
|
||||
receiver, object, index);
|
||||
if (attr != ABSENT) return attr;
|
||||
if (attr != ABSENT) return maybe(attr);
|
||||
|
||||
// Handle [] on String objects.
|
||||
if (object->IsStringObjectWithCharacterAt(index)) {
|
||||
return static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
|
||||
return maybe(static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE));
|
||||
}
|
||||
|
||||
if (!check_prototype) return ABSENT;
|
||||
if (!check_prototype) return maybe(ABSENT);
|
||||
|
||||
PrototypeIterator iter(object->GetIsolate(), object);
|
||||
if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
|
||||
@ -4451,7 +4443,7 @@ PropertyAttributes JSObject::GetElementAttributeWithoutInterceptor(
|
||||
Handle<JSProxy>::cast(PrototypeIterator::GetCurrent(iter)), receiver,
|
||||
index);
|
||||
}
|
||||
if (iter.IsAtEnd()) return ABSENT;
|
||||
if (iter.IsAtEnd()) return maybe(ABSENT);
|
||||
return GetElementAttributeWithReceiver(
|
||||
Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), receiver,
|
||||
index, true);
|
||||
@ -5031,7 +5023,10 @@ void JSObject::DeleteHiddenProperty(Handle<JSObject> object, Handle<Name> key) {
|
||||
bool JSObject::HasHiddenProperties(Handle<JSObject> object) {
|
||||
Handle<Name> hidden = object->GetIsolate()->factory()->hidden_string();
|
||||
LookupIterator it(object, hidden, LookupIterator::CHECK_OWN_REAL);
|
||||
return GetPropertyAttributes(&it) != ABSENT;
|
||||
Maybe<PropertyAttributes> maybe = GetPropertyAttributes(&it);
|
||||
// Cannot get an exception since the hidden_string isn't accessible to JS.
|
||||
ASSERT(maybe.has_value);
|
||||
return maybe.value != ABSENT;
|
||||
}
|
||||
|
||||
|
||||
@ -5254,7 +5249,9 @@ MaybeHandle<Object> JSObject::DeleteElement(Handle<JSObject> object,
|
||||
Handle<Object> old_value;
|
||||
bool should_enqueue_change_record = false;
|
||||
if (object->map()->is_observed()) {
|
||||
should_enqueue_change_record = HasOwnElement(object, index);
|
||||
Maybe<bool> maybe = HasOwnElement(object, index);
|
||||
if (!maybe.has_value) return MaybeHandle<Object>();
|
||||
should_enqueue_change_record = maybe.value;
|
||||
if (should_enqueue_change_record) {
|
||||
if (!GetOwnElementAccessorPair(object, index).is_null()) {
|
||||
old_value = Handle<Object>::cast(factory->the_hole_value());
|
||||
@ -5275,10 +5272,14 @@ MaybeHandle<Object> JSObject::DeleteElement(Handle<JSObject> object,
|
||||
Handle<Object> result;
|
||||
ASSIGN_RETURN_ON_EXCEPTION(isolate, result, maybe_result, Object);
|
||||
|
||||
if (should_enqueue_change_record && !HasOwnElement(object, index)) {
|
||||
if (should_enqueue_change_record) {
|
||||
Maybe<bool> maybe = HasOwnElement(object, index);
|
||||
if (!maybe.has_value) return MaybeHandle<Object>();
|
||||
if (!maybe.value) {
|
||||
Handle<String> name = factory->Uint32ToString(index);
|
||||
EnqueueChangeRecord(object, "delete", name, old_value);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -5355,9 +5356,13 @@ MaybeHandle<Object> JSObject::DeleteProperty(Handle<JSObject> object,
|
||||
result = DeleteNormalizedProperty(object, name, mode);
|
||||
}
|
||||
|
||||
if (is_observed && !HasOwnProperty(object, name)) {
|
||||
if (is_observed) {
|
||||
Maybe<bool> maybe = HasOwnProperty(object, name);
|
||||
if (!maybe.has_value) return MaybeHandle<Object>();
|
||||
if (!maybe.value) {
|
||||
EnqueueChangeRecord(object, "delete", name, old_value);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -5839,8 +5844,10 @@ MaybeHandle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
|
||||
for (int i = 0; i < names->length(); i++) {
|
||||
ASSERT(names->get(i)->IsString());
|
||||
Handle<String> key_string(String::cast(names->get(i)));
|
||||
PropertyAttributes attributes =
|
||||
Maybe<PropertyAttributes> maybe =
|
||||
JSReceiver::GetOwnPropertyAttributes(copy, key_string);
|
||||
ASSERT(maybe.has_value);
|
||||
PropertyAttributes attributes = maybe.value;
|
||||
// Only deep copy fields from the object literal expression.
|
||||
// In particular, don't try to copy the length attribute of
|
||||
// an array.
|
||||
@ -6588,7 +6595,7 @@ void JSObject::SetPropertyCallback(Handle<JSObject> object,
|
||||
}
|
||||
|
||||
|
||||
void JSObject::DefineAccessor(Handle<JSObject> object,
|
||||
MaybeHandle<Object> JSObject::DefineAccessor(Handle<JSObject> object,
|
||||
Handle<Name> name,
|
||||
Handle<Object> getter,
|
||||
Handle<Object> setter,
|
||||
@ -6598,17 +6605,17 @@ void JSObject::DefineAccessor(Handle<JSObject> object,
|
||||
if (object->IsAccessCheckNeeded() &&
|
||||
!isolate->MayNamedAccess(object, name, v8::ACCESS_SET)) {
|
||||
isolate->ReportFailedAccessCheck(object, v8::ACCESS_SET);
|
||||
// TODO(yangguo): Issue 3269, check for scheduled exception missing?
|
||||
return;
|
||||
RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
|
||||
return isolate->factory()->undefined_value();
|
||||
}
|
||||
|
||||
if (object->IsJSGlobalProxy()) {
|
||||
PrototypeIterator iter(isolate, object);
|
||||
if (iter.IsAtEnd()) return;
|
||||
if (iter.IsAtEnd()) return isolate->factory()->undefined_value();
|
||||
ASSERT(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
|
||||
DefineAccessor(Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)),
|
||||
name, getter, setter, attributes);
|
||||
return;
|
||||
return isolate->factory()->undefined_value();
|
||||
}
|
||||
|
||||
// Make sure that the top context does not change when doing callbacks or
|
||||
@ -6627,7 +6634,9 @@ void JSObject::DefineAccessor(Handle<JSObject> object,
|
||||
bool preexists = false;
|
||||
if (is_observed) {
|
||||
if (is_element) {
|
||||
preexists = HasOwnElement(object, index);
|
||||
Maybe<bool> maybe = HasOwnElement(object, index);
|
||||
ASSERT(maybe.has_value);
|
||||
preexists = maybe.value;
|
||||
if (preexists && GetOwnElementAccessorPair(object, index).is_null()) {
|
||||
old_value =
|
||||
Object::GetElement(isolate, object, index).ToHandleChecked();
|
||||
@ -6653,6 +6662,8 @@ void JSObject::DefineAccessor(Handle<JSObject> object,
|
||||
const char* type = preexists ? "reconfigure" : "add";
|
||||
EnqueueChangeRecord(object, type, name, old_value);
|
||||
}
|
||||
|
||||
return isolate->factory()->undefined_value();
|
||||
}
|
||||
|
||||
|
||||
@ -11655,10 +11666,11 @@ static bool GetOldValue(Isolate* isolate,
|
||||
uint32_t index,
|
||||
List<Handle<Object> >* old_values,
|
||||
List<uint32_t>* indices) {
|
||||
PropertyAttributes attributes =
|
||||
Maybe<PropertyAttributes> maybe =
|
||||
JSReceiver::GetOwnElementAttribute(object, index);
|
||||
ASSERT(attributes != ABSENT);
|
||||
if (attributes == DONT_DELETE) return false;
|
||||
ASSERT(maybe.has_value);
|
||||
ASSERT(maybe.value != ABSENT);
|
||||
if (maybe.value == DONT_DELETE) return false;
|
||||
Handle<Object> value;
|
||||
if (!JSObject::GetOwnElementAccessorPair(object, index).is_null()) {
|
||||
value = Handle<Object>::cast(isolate->factory()->the_hole_value());
|
||||
@ -12891,8 +12903,11 @@ MaybeHandle<Object> JSObject::SetElement(Handle<JSObject> object,
|
||||
strict_mode, check_prototype, set_mode);
|
||||
}
|
||||
|
||||
PropertyAttributes old_attributes =
|
||||
Maybe<PropertyAttributes> maybe =
|
||||
JSReceiver::GetOwnElementAttribute(object, index);
|
||||
if (!maybe.has_value) return MaybeHandle<Object>();
|
||||
PropertyAttributes old_attributes = maybe.value;
|
||||
|
||||
Handle<Object> old_value = isolate->factory()->the_hole_value();
|
||||
Handle<Object> old_length_handle;
|
||||
Handle<Object> new_length_handle;
|
||||
@ -12921,7 +12936,10 @@ MaybeHandle<Object> JSObject::SetElement(Handle<JSObject> object,
|
||||
Object);
|
||||
|
||||
Handle<String> name = isolate->factory()->Uint32ToString(index);
|
||||
PropertyAttributes new_attributes = GetOwnElementAttribute(object, index);
|
||||
maybe = GetOwnElementAttribute(object, index);
|
||||
if (!maybe.has_value) return MaybeHandle<Object>();
|
||||
PropertyAttributes new_attributes = maybe.value;
|
||||
|
||||
if (old_attributes == ABSENT) {
|
||||
if (object->IsJSArray() &&
|
||||
!old_length_handle->SameValue(
|
||||
@ -13691,7 +13709,7 @@ MaybeHandle<JSObject> JSObject::GetKeysForIndexedInterceptor(
|
||||
}
|
||||
|
||||
|
||||
bool JSObject::HasRealNamedProperty(Handle<JSObject> object,
|
||||
Maybe<bool> JSObject::HasRealNamedProperty(Handle<JSObject> object,
|
||||
Handle<Name> key) {
|
||||
Isolate* isolate = object->GetIsolate();
|
||||
SealHandleScope shs(isolate);
|
||||
@ -13699,44 +13717,47 @@ bool JSObject::HasRealNamedProperty(Handle<JSObject> object,
|
||||
if (object->IsAccessCheckNeeded()) {
|
||||
if (!isolate->MayNamedAccess(object, key, v8::ACCESS_HAS)) {
|
||||
isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS);
|
||||
// TODO(yangguo): Issue 3269, check for scheduled exception missing?
|
||||
return false;
|
||||
RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Maybe<bool>());
|
||||
return maybe(false);
|
||||
}
|
||||
}
|
||||
|
||||
LookupResult result(isolate);
|
||||
object->LookupOwnRealNamedProperty(key, &result);
|
||||
return result.IsFound() && !result.IsInterceptor();
|
||||
return maybe(result.IsFound() && !result.IsInterceptor());
|
||||
}
|
||||
|
||||
|
||||
bool JSObject::HasRealElementProperty(Handle<JSObject> object, uint32_t index) {
|
||||
Maybe<bool> JSObject::HasRealElementProperty(Handle<JSObject> object,
|
||||
uint32_t index) {
|
||||
Isolate* isolate = object->GetIsolate();
|
||||
HandleScope scope(isolate);
|
||||
// Check access rights if needed.
|
||||
if (object->IsAccessCheckNeeded()) {
|
||||
if (!isolate->MayIndexedAccess(object, index, v8::ACCESS_HAS)) {
|
||||
isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS);
|
||||
// TODO(yangguo): Issue 3269, check for scheduled exception missing?
|
||||
return false;
|
||||
RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Maybe<bool>());
|
||||
return maybe(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (object->IsJSGlobalProxy()) {
|
||||
HandleScope scope(isolate);
|
||||
PrototypeIterator iter(isolate, object);
|
||||
if (iter.IsAtEnd()) return false;
|
||||
if (iter.IsAtEnd()) return maybe(false);
|
||||
ASSERT(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
|
||||
return HasRealElementProperty(
|
||||
Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), index);
|
||||
}
|
||||
|
||||
return GetElementAttributeWithoutInterceptor(
|
||||
object, object, index, false) != ABSENT;
|
||||
Maybe<PropertyAttributes> result =
|
||||
GetElementAttributeWithoutInterceptor(object, object, index, false);
|
||||
if (!result.has_value) return Maybe<bool>();
|
||||
return maybe(result.value != ABSENT);
|
||||
}
|
||||
|
||||
|
||||
bool JSObject::HasRealNamedCallbackProperty(Handle<JSObject> object,
|
||||
Maybe<bool> JSObject::HasRealNamedCallbackProperty(Handle<JSObject> object,
|
||||
Handle<Name> key) {
|
||||
Isolate* isolate = object->GetIsolate();
|
||||
SealHandleScope shs(isolate);
|
||||
@ -13744,14 +13765,14 @@ bool JSObject::HasRealNamedCallbackProperty(Handle<JSObject> object,
|
||||
if (object->IsAccessCheckNeeded()) {
|
||||
if (!isolate->MayNamedAccess(object, key, v8::ACCESS_HAS)) {
|
||||
isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS);
|
||||
// TODO(yangguo): Issue 3269, check for scheduled exception missing?
|
||||
return false;
|
||||
RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Maybe<bool>());
|
||||
return maybe(false);
|
||||
}
|
||||
}
|
||||
|
||||
LookupResult result(isolate);
|
||||
object->LookupOwnRealNamedProperty(key, &result);
|
||||
return result.IsPropertyCallbacks();
|
||||
return maybe(result.IsPropertyCallbacks());
|
||||
}
|
||||
|
||||
|
||||
|
@ -1960,10 +1960,14 @@ class JSReceiver: public HeapObject {
|
||||
StrictMode strict_mode);
|
||||
|
||||
// Implementation of [[HasProperty]], ECMA-262 5th edition, section 8.12.6.
|
||||
static inline bool HasProperty(Handle<JSReceiver> object, Handle<Name> name);
|
||||
static inline bool HasOwnProperty(Handle<JSReceiver>, Handle<Name> name);
|
||||
static inline bool HasElement(Handle<JSReceiver> object, uint32_t index);
|
||||
static inline bool HasOwnElement(Handle<JSReceiver> object, uint32_t index);
|
||||
MUST_USE_RESULT static inline Maybe<bool> HasProperty(
|
||||
Handle<JSReceiver> object, Handle<Name> name);
|
||||
MUST_USE_RESULT static inline Maybe<bool> HasOwnProperty(Handle<JSReceiver>,
|
||||
Handle<Name> name);
|
||||
MUST_USE_RESULT static inline Maybe<bool> HasElement(
|
||||
Handle<JSReceiver> object, uint32_t index);
|
||||
MUST_USE_RESULT static inline Maybe<bool> HasOwnElement(
|
||||
Handle<JSReceiver> object, uint32_t index);
|
||||
|
||||
// Implementation of [[Delete]], ECMA-262 5th edition, section 8.12.7.
|
||||
MUST_USE_RESULT static MaybeHandle<Object> DeleteProperty(
|
||||
@ -1985,20 +1989,17 @@ class JSReceiver: public HeapObject {
|
||||
// function that was used to instantiate the object).
|
||||
String* constructor_name();
|
||||
|
||||
static inline PropertyAttributes GetPropertyAttributes(
|
||||
Handle<JSReceiver> object,
|
||||
Handle<Name> name);
|
||||
static PropertyAttributes GetPropertyAttributes(LookupIterator* it);
|
||||
static PropertyAttributes GetOwnPropertyAttributes(
|
||||
Handle<JSReceiver> object,
|
||||
Handle<Name> name);
|
||||
MUST_USE_RESULT static inline Maybe<PropertyAttributes> GetPropertyAttributes(
|
||||
Handle<JSReceiver> object, Handle<Name> name);
|
||||
MUST_USE_RESULT static Maybe<PropertyAttributes> GetPropertyAttributes(
|
||||
LookupIterator* it);
|
||||
MUST_USE_RESULT static Maybe<PropertyAttributes> GetOwnPropertyAttributes(
|
||||
Handle<JSReceiver> object, Handle<Name> name);
|
||||
|
||||
static inline PropertyAttributes GetElementAttribute(
|
||||
Handle<JSReceiver> object,
|
||||
uint32_t index);
|
||||
static inline PropertyAttributes GetOwnElementAttribute(
|
||||
Handle<JSReceiver> object,
|
||||
uint32_t index);
|
||||
MUST_USE_RESULT static inline Maybe<PropertyAttributes> GetElementAttribute(
|
||||
Handle<JSReceiver> object, uint32_t index);
|
||||
MUST_USE_RESULT static inline Maybe<PropertyAttributes>
|
||||
GetOwnElementAttribute(Handle<JSReceiver> object, uint32_t index);
|
||||
|
||||
// Return the constructor function (may be Heap::null_value()).
|
||||
inline Object* GetConstructor();
|
||||
@ -2198,17 +2199,16 @@ class JSObject: public JSReceiver {
|
||||
InterceptorInfo* GetIndexedInterceptor();
|
||||
|
||||
// Used from JSReceiver.
|
||||
static Maybe<PropertyAttributes> GetPropertyAttributesWithInterceptor(
|
||||
Handle<JSObject> holder,
|
||||
MUST_USE_RESULT static Maybe<PropertyAttributes>
|
||||
GetPropertyAttributesWithInterceptor(Handle<JSObject> holder,
|
||||
Handle<Object> receiver,
|
||||
Handle<Name> name);
|
||||
static PropertyAttributes GetPropertyAttributesWithFailedAccessCheck(
|
||||
LookupIterator* it);
|
||||
static PropertyAttributes GetElementAttributeWithReceiver(
|
||||
Handle<JSObject> object,
|
||||
MUST_USE_RESULT static Maybe<PropertyAttributes>
|
||||
GetPropertyAttributesWithFailedAccessCheck(LookupIterator* it);
|
||||
MUST_USE_RESULT static Maybe<PropertyAttributes>
|
||||
GetElementAttributeWithReceiver(Handle<JSObject> object,
|
||||
Handle<JSReceiver> receiver,
|
||||
uint32_t index,
|
||||
bool check_prototype);
|
||||
uint32_t index, bool check_prototype);
|
||||
|
||||
// Retrieves an AccessorPair property from the given object. Might return
|
||||
// undefined if the property doesn't exist or is of a different kind.
|
||||
@ -2218,9 +2218,8 @@ class JSObject: public JSReceiver {
|
||||
AccessorComponent component);
|
||||
|
||||
// Defines an AccessorPair property on the given object.
|
||||
// TODO(mstarzinger): Rename to SetAccessor() and return empty handle on
|
||||
// exception instead of letting callers check for scheduled exception.
|
||||
static void DefineAccessor(Handle<JSObject> object,
|
||||
// TODO(mstarzinger): Rename to SetAccessor().
|
||||
static MaybeHandle<Object> DefineAccessor(Handle<JSObject> object,
|
||||
Handle<Name> name,
|
||||
Handle<Object> getter,
|
||||
Handle<Object> setter,
|
||||
@ -2381,11 +2380,12 @@ class JSObject: public JSReceiver {
|
||||
Handle<JSReceiver> receiver);
|
||||
|
||||
// Support functions for v8 api (needed for correct interceptor behavior).
|
||||
static bool HasRealNamedProperty(Handle<JSObject> object,
|
||||
Handle<Name> key);
|
||||
static bool HasRealElementProperty(Handle<JSObject> object, uint32_t index);
|
||||
static bool HasRealNamedCallbackProperty(Handle<JSObject> object,
|
||||
Handle<Name> key);
|
||||
MUST_USE_RESULT static Maybe<bool> HasRealNamedProperty(
|
||||
Handle<JSObject> object, Handle<Name> key);
|
||||
MUST_USE_RESULT static Maybe<bool> HasRealElementProperty(
|
||||
Handle<JSObject> object, uint32_t index);
|
||||
MUST_USE_RESULT static Maybe<bool> HasRealNamedCallbackProperty(
|
||||
Handle<JSObject> object, Handle<Name> key);
|
||||
|
||||
// Get the header size for a JSObject. Used to compute the index of
|
||||
// internal fields as well as the number of internal fields.
|
||||
@ -2658,13 +2658,12 @@ class JSObject: public JSReceiver {
|
||||
uint32_t index,
|
||||
Handle<Object> holder);
|
||||
|
||||
static PropertyAttributes GetElementAttributeWithInterceptor(
|
||||
Handle<JSObject> object,
|
||||
MUST_USE_RESULT static Maybe<PropertyAttributes>
|
||||
GetElementAttributeWithInterceptor(Handle<JSObject> object,
|
||||
Handle<JSReceiver> receiver,
|
||||
uint32_t index,
|
||||
bool continue_search);
|
||||
static PropertyAttributes GetElementAttributeWithoutInterceptor(
|
||||
Handle<JSObject> object,
|
||||
uint32_t index, bool continue_search);
|
||||
MUST_USE_RESULT static Maybe<PropertyAttributes>
|
||||
GetElementAttributeWithoutInterceptor(Handle<JSObject> object,
|
||||
Handle<JSReceiver> receiver,
|
||||
uint32_t index,
|
||||
bool continue_search);
|
||||
@ -9947,12 +9946,12 @@ class JSProxy: public JSReceiver {
|
||||
Handle<JSProxy> proxy, Handle<Object> receiver, Handle<Name> name,
|
||||
Handle<Object> value, StrictMode strict_mode, bool* done);
|
||||
|
||||
static PropertyAttributes GetPropertyAttributesWithHandler(
|
||||
Handle<JSProxy> proxy,
|
||||
MUST_USE_RESULT static Maybe<PropertyAttributes>
|
||||
GetPropertyAttributesWithHandler(Handle<JSProxy> proxy,
|
||||
Handle<Object> receiver,
|
||||
Handle<Name> name);
|
||||
static PropertyAttributes GetElementAttributeWithHandler(
|
||||
Handle<JSProxy> proxy,
|
||||
MUST_USE_RESULT static Maybe<PropertyAttributes>
|
||||
GetElementAttributeWithHandler(Handle<JSProxy> proxy,
|
||||
Handle<JSReceiver> receiver,
|
||||
uint32_t index);
|
||||
MUST_USE_RESULT static MaybeHandle<Object> SetPropertyWithHandler(
|
||||
@ -10004,9 +10003,10 @@ class JSProxy: public JSReceiver {
|
||||
Handle<Object> value,
|
||||
StrictMode strict_mode);
|
||||
|
||||
static bool HasPropertyWithHandler(Handle<JSProxy> proxy, Handle<Name> name);
|
||||
static inline bool HasElementWithHandler(Handle<JSProxy> proxy,
|
||||
uint32_t index);
|
||||
MUST_USE_RESULT static Maybe<bool> HasPropertyWithHandler(
|
||||
Handle<JSProxy> proxy, Handle<Name> name);
|
||||
MUST_USE_RESULT static inline Maybe<bool> HasElementWithHandler(
|
||||
Handle<JSProxy> proxy, uint32_t index);
|
||||
|
||||
MUST_USE_RESULT static MaybeHandle<Object> DeletePropertyWithHandler(
|
||||
Handle<JSProxy> proxy,
|
||||
|
139
src/runtime.cc
139
src/runtime.cc
@ -1946,11 +1946,11 @@ MUST_USE_RESULT static MaybeHandle<Object> GetOwnProperty(Isolate* isolate,
|
||||
// LookupIterator.
|
||||
if (name->AsArrayIndex(&index)) {
|
||||
// Get attributes.
|
||||
attrs = JSReceiver::GetOwnElementAttribute(obj, index);
|
||||
if (attrs == ABSENT) {
|
||||
RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
|
||||
return factory->undefined_value();
|
||||
}
|
||||
Maybe<PropertyAttributes> maybe =
|
||||
JSReceiver::GetOwnElementAttribute(obj, index);
|
||||
if (!maybe.has_value) return MaybeHandle<Object>();
|
||||
attrs = maybe.value;
|
||||
if (attrs == ABSENT) return factory->undefined_value();
|
||||
|
||||
// Get AccessorPair if present.
|
||||
maybe_accessors = JSObject::GetOwnElementAccessorPair(obj, index);
|
||||
@ -1963,11 +1963,10 @@ MUST_USE_RESULT static MaybeHandle<Object> GetOwnProperty(Isolate* isolate,
|
||||
} else {
|
||||
// Get attributes.
|
||||
LookupIterator it(obj, name, LookupIterator::CHECK_OWN);
|
||||
attrs = JSObject::GetPropertyAttributes(&it);
|
||||
if (attrs == ABSENT) {
|
||||
RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
|
||||
return factory->undefined_value();
|
||||
}
|
||||
Maybe<PropertyAttributes> maybe = JSObject::GetPropertyAttributes(&it);
|
||||
if (!maybe.has_value) return MaybeHandle<Object>();
|
||||
attrs = maybe.value;
|
||||
if (attrs == ABSENT) return factory->undefined_value();
|
||||
|
||||
// Get AccessorPair if present.
|
||||
if (it.state() == LookupIterator::PROPERTY &&
|
||||
@ -1982,7 +1981,7 @@ MUST_USE_RESULT static MaybeHandle<Object> GetOwnProperty(Isolate* isolate,
|
||||
isolate, value, Object::GetProperty(&it), Object);
|
||||
}
|
||||
}
|
||||
ASSERT(!isolate->has_scheduled_exception());
|
||||
ASSERT(!isolate->has_pending_exception());
|
||||
Handle<FixedArray> elms = factory->NewFixedArray(DESCRIPTOR_SIZE);
|
||||
elms->set(ENUMERABLE_INDEX, heap->ToBoolean((attrs & DONT_ENUM) == 0));
|
||||
elms->set(CONFIGURABLE_INDEX, heap->ToBoolean((attrs & DONT_DELETE) == 0));
|
||||
@ -2143,7 +2142,9 @@ static Object* DeclareGlobals(Isolate* isolate, Handle<GlobalObject> global,
|
||||
bool is_const, bool is_function) {
|
||||
// Do the lookup own properties only, see ES5 erratum.
|
||||
LookupIterator it(global, name, LookupIterator::CHECK_HIDDEN);
|
||||
PropertyAttributes old_attributes = JSReceiver::GetPropertyAttributes(&it);
|
||||
Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
|
||||
ASSERT(maybe.has_value);
|
||||
PropertyAttributes old_attributes = maybe.value;
|
||||
|
||||
if (old_attributes != ABSENT) {
|
||||
// The name was declared before; check for conflicting re-declarations.
|
||||
@ -2271,7 +2272,9 @@ RUNTIME_FUNCTION(Runtime_InitializeConstGlobal) {
|
||||
|
||||
// Lookup the property as own on the global object.
|
||||
LookupIterator it(global, name, LookupIterator::CHECK_HIDDEN);
|
||||
PropertyAttributes old_attributes = JSReceiver::GetPropertyAttributes(&it);
|
||||
Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
|
||||
ASSERT(maybe.has_value);
|
||||
PropertyAttributes old_attributes = maybe.value;
|
||||
|
||||
PropertyAttributes attr =
|
||||
static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY);
|
||||
@ -2419,7 +2422,9 @@ RUNTIME_FUNCTION(Runtime_InitializeLegacyConstLookupSlot) {
|
||||
ASSERT(holder->IsJSGlobalObject() || holder->IsJSContextExtensionObject());
|
||||
|
||||
LookupIterator it(holder, name, LookupIterator::CHECK_HIDDEN);
|
||||
PropertyAttributes old_attributes = JSReceiver::GetPropertyAttributes(&it);
|
||||
Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
|
||||
if (!maybe.has_value) return isolate->heap()->exception();
|
||||
PropertyAttributes old_attributes = maybe.value;
|
||||
|
||||
// Ignore if we can't reconfigure the value.
|
||||
if ((old_attributes & DONT_DELETE) != 0) {
|
||||
@ -4747,17 +4752,21 @@ static MaybeHandle<Name> ToName(Isolate* isolate, Handle<Object> key) {
|
||||
MaybeHandle<Object> Runtime::HasObjectProperty(Isolate* isolate,
|
||||
Handle<JSReceiver> object,
|
||||
Handle<Object> key) {
|
||||
Maybe<bool> maybe;
|
||||
// Check if the given key is an array index.
|
||||
uint32_t index;
|
||||
if (key->ToArrayIndex(&index)) {
|
||||
return isolate->factory()->ToBoolean(JSReceiver::HasElement(object, index));
|
||||
}
|
||||
|
||||
maybe = JSReceiver::HasElement(object, index);
|
||||
} else {
|
||||
// Convert the key to a name - possibly by calling back into JavaScript.
|
||||
Handle<Name> name;
|
||||
ASSIGN_RETURN_ON_EXCEPTION(isolate, name, ToName(isolate, key), Object);
|
||||
|
||||
return isolate->factory()->ToBoolean(JSReceiver::HasProperty(object, name));
|
||||
maybe = JSReceiver::HasProperty(object, name);
|
||||
}
|
||||
|
||||
if (!maybe.has_value) return MaybeHandle<Object>();
|
||||
return isolate->factory()->ToBoolean(maybe.value);
|
||||
}
|
||||
|
||||
|
||||
@ -4939,9 +4948,8 @@ RUNTIME_FUNCTION(Runtime_DefineAccessorPropertyUnchecked) {
|
||||
PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
|
||||
|
||||
bool fast = obj->HasFastProperties();
|
||||
// DefineAccessor checks access rights.
|
||||
JSObject::DefineAccessor(obj, name, getter, setter, attr);
|
||||
RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
|
||||
RETURN_FAILURE_ON_EXCEPTION(
|
||||
isolate, JSObject::DefineAccessor(obj, name, getter, setter, attr));
|
||||
if (fast) JSObject::MigrateSlowToFast(obj, 0);
|
||||
return isolate->heap()->undefined_value();
|
||||
}
|
||||
@ -5279,7 +5287,9 @@ RUNTIME_FUNCTION(Runtime_AddPropertyForTemplate) {
|
||||
} else {
|
||||
uint32_t index = 0;
|
||||
RUNTIME_ASSERT(key->ToArrayIndex(&index));
|
||||
duplicate = JSReceiver::HasOwnElement(object, index);
|
||||
Maybe<bool> maybe = JSReceiver::HasOwnElement(object, index);
|
||||
if (!maybe.has_value) return isolate->heap()->exception();
|
||||
duplicate = maybe.value;
|
||||
}
|
||||
if (duplicate) {
|
||||
Handle<Object> args[1] = { key };
|
||||
@ -5501,9 +5511,9 @@ RUNTIME_FUNCTION(Runtime_DeleteProperty) {
|
||||
static Object* HasOwnPropertyImplementation(Isolate* isolate,
|
||||
Handle<JSObject> object,
|
||||
Handle<Name> key) {
|
||||
if (JSReceiver::HasOwnProperty(object, key)) {
|
||||
return isolate->heap()->true_value();
|
||||
}
|
||||
Maybe<bool> maybe = JSReceiver::HasOwnProperty(object, key);
|
||||
if (!maybe.has_value) return isolate->heap()->exception();
|
||||
if (maybe.value) return isolate->heap()->true_value();
|
||||
// Handle hidden prototypes. If there's a hidden prototype above this thing
|
||||
// then we have to check it for properties, because they are supposed to
|
||||
// look like they are on this object.
|
||||
@ -5513,7 +5523,7 @@ static Object* HasOwnPropertyImplementation(Isolate* isolate,
|
||||
->map()
|
||||
->is_hidden_prototype()) {
|
||||
// TODO(verwaest): The recursion is not necessary for keys that are array
|
||||
// indicies. Removing this.
|
||||
// indices. Removing this.
|
||||
return HasOwnPropertyImplementation(
|
||||
isolate, Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)),
|
||||
key);
|
||||
@ -5538,11 +5548,11 @@ RUNTIME_FUNCTION(Runtime_HasOwnProperty) {
|
||||
// Fast case: either the key is a real named property or it is not
|
||||
// an array index and there are no interceptors or hidden
|
||||
// prototypes.
|
||||
if (JSObject::HasRealNamedProperty(js_obj, key)) {
|
||||
ASSERT(!isolate->has_scheduled_exception());
|
||||
Maybe<bool> maybe = JSObject::HasRealNamedProperty(js_obj, key);
|
||||
if (!maybe.has_value) return isolate->heap()->exception();
|
||||
ASSERT(!isolate->has_pending_exception());
|
||||
if (maybe.value) {
|
||||
return isolate->heap()->true_value();
|
||||
} else {
|
||||
RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
|
||||
}
|
||||
Map* map = js_obj->map();
|
||||
if (!key_is_array_index &&
|
||||
@ -5571,10 +5581,9 @@ RUNTIME_FUNCTION(Runtime_HasProperty) {
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
|
||||
CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
|
||||
|
||||
bool result = JSReceiver::HasProperty(receiver, key);
|
||||
RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
|
||||
if (isolate->has_pending_exception()) return isolate->heap()->exception();
|
||||
return isolate->heap()->ToBoolean(result);
|
||||
Maybe<bool> maybe = JSReceiver::HasProperty(receiver, key);
|
||||
if (!maybe.has_value) return isolate->heap()->exception();
|
||||
return isolate->heap()->ToBoolean(maybe.value);
|
||||
}
|
||||
|
||||
|
||||
@ -5584,9 +5593,9 @@ RUNTIME_FUNCTION(Runtime_HasElement) {
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
|
||||
CONVERT_SMI_ARG_CHECKED(index, 1);
|
||||
|
||||
bool result = JSReceiver::HasElement(receiver, index);
|
||||
RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
|
||||
return isolate->heap()->ToBoolean(result);
|
||||
Maybe<bool> maybe = JSReceiver::HasElement(receiver, index);
|
||||
if (!maybe.has_value) return isolate->heap()->exception();
|
||||
return isolate->heap()->ToBoolean(maybe.value);
|
||||
}
|
||||
|
||||
|
||||
@ -5597,13 +5606,11 @@ RUNTIME_FUNCTION(Runtime_IsPropertyEnumerable) {
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
|
||||
CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
|
||||
|
||||
PropertyAttributes att = JSReceiver::GetOwnPropertyAttributes(object, key);
|
||||
if (att == ABSENT || (att & DONT_ENUM) != 0) {
|
||||
RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
|
||||
return isolate->heap()->false_value();
|
||||
}
|
||||
ASSERT(!isolate->has_scheduled_exception());
|
||||
return isolate->heap()->true_value();
|
||||
Maybe<PropertyAttributes> maybe =
|
||||
JSReceiver::GetOwnPropertyAttributes(object, key);
|
||||
if (!maybe.has_value) return isolate->heap()->exception();
|
||||
if (maybe.value == ABSENT) maybe.value = DONT_ENUM;
|
||||
return isolate->heap()->ToBoolean((maybe.value & DONT_ENUM) == 0);
|
||||
}
|
||||
|
||||
|
||||
@ -9196,7 +9203,13 @@ static ObjectPair LoadLookupSlotHelper(Arguments args, Isolate* isolate,
|
||||
// property from it.
|
||||
if (!holder.is_null()) {
|
||||
Handle<JSReceiver> object = Handle<JSReceiver>::cast(holder);
|
||||
ASSERT(object->IsJSProxy() || JSReceiver::HasProperty(object, name));
|
||||
#ifdef DEBUG
|
||||
if (!object->IsJSProxy()) {
|
||||
Maybe<bool> maybe = JSReceiver::HasProperty(object, name);
|
||||
ASSERT(maybe.has_value);
|
||||
ASSERT(maybe.value);
|
||||
}
|
||||
#endif
|
||||
// GetProperty below can cause GC.
|
||||
Handle<Object> receiver_handle(
|
||||
object->IsGlobalObject()
|
||||
@ -10183,16 +10196,19 @@ static bool IterateElements(Isolate* isolate,
|
||||
Handle<Object> element_value(elements->get(j), isolate);
|
||||
if (!element_value->IsTheHole()) {
|
||||
visitor->visit(j, element_value);
|
||||
} else if (JSReceiver::HasElement(receiver, j)) {
|
||||
} else {
|
||||
Maybe<bool> maybe = JSReceiver::HasElement(receiver, j);
|
||||
if (!maybe.has_value) return false;
|
||||
if (maybe.value) {
|
||||
// Call GetElement on receiver, not its prototype, or getters won't
|
||||
// have the correct receiver.
|
||||
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
|
||||
isolate, element_value,
|
||||
Object::GetElement(isolate, receiver, j),
|
||||
false);
|
||||
Object::GetElement(isolate, receiver, j), false);
|
||||
visitor->visit(j, element_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FAST_HOLEY_DOUBLE_ELEMENTS:
|
||||
@ -10216,17 +10232,20 @@ static bool IterateElements(Isolate* isolate,
|
||||
Handle<Object> element_value =
|
||||
isolate->factory()->NewNumber(double_value);
|
||||
visitor->visit(j, element_value);
|
||||
} else if (JSReceiver::HasElement(receiver, j)) {
|
||||
} else {
|
||||
Maybe<bool> maybe = JSReceiver::HasElement(receiver, j);
|
||||
if (!maybe.has_value) return false;
|
||||
if (maybe.value) {
|
||||
// Call GetElement on receiver, not its prototype, or getters won't
|
||||
// have the correct receiver.
|
||||
Handle<Object> element_value;
|
||||
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
|
||||
isolate, element_value,
|
||||
Object::GetElement(isolate, receiver, j),
|
||||
false);
|
||||
Object::GetElement(isolate, receiver, j), false);
|
||||
visitor->visit(j, element_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DICTIONARY_ELEMENTS: {
|
||||
@ -11539,7 +11558,9 @@ static bool SetLocalVariableValue(Isolate* isolate,
|
||||
!function_context->IsNativeContext()) {
|
||||
Handle<JSObject> ext(JSObject::cast(function_context->extension()));
|
||||
|
||||
if (JSReceiver::HasProperty(ext, variable_name)) {
|
||||
Maybe<bool> maybe = JSReceiver::HasProperty(ext, variable_name);
|
||||
ASSERT(maybe.has_value);
|
||||
if (maybe.value) {
|
||||
// We don't expect this to do anything except replacing
|
||||
// property value.
|
||||
Runtime::SetObjectProperty(isolate, ext, variable_name, new_value,
|
||||
@ -11623,7 +11644,9 @@ static bool SetClosureVariableValue(Isolate* isolate,
|
||||
// be variables introduced by eval.
|
||||
if (context->has_extension()) {
|
||||
Handle<JSObject> ext(JSObject::cast(context->extension()));
|
||||
if (JSReceiver::HasProperty(ext, variable_name)) {
|
||||
Maybe<bool> maybe = JSReceiver::HasProperty(ext, variable_name);
|
||||
ASSERT(maybe.has_value);
|
||||
if (maybe.value) {
|
||||
// We don't expect this to do anything except replacing property value.
|
||||
Runtime::DefineObjectProperty(
|
||||
ext, variable_name, new_value, NONE).Assert();
|
||||
@ -12700,11 +12723,11 @@ MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeArgumentsObject(
|
||||
Handle<JSFunction> function) {
|
||||
// Do not materialize the arguments object for eval or top-level code.
|
||||
// Skip if "arguments" is already taken.
|
||||
if (!function->shared()->is_function() ||
|
||||
JSReceiver::HasOwnProperty(
|
||||
target, isolate->factory()->arguments_string())) {
|
||||
return target;
|
||||
}
|
||||
if (!function->shared()->is_function()) return target;
|
||||
Maybe<bool> maybe = JSReceiver::HasOwnProperty(
|
||||
target, isolate->factory()->arguments_string());
|
||||
if (!maybe.has_value) return MaybeHandle<JSObject>();
|
||||
if (maybe.value) return target;
|
||||
|
||||
// FunctionGetArguments can't throw an exception.
|
||||
Handle<JSObject> arguments = Handle<JSObject>::cast(
|
||||
|
@ -210,7 +210,9 @@ TEST(HeapObjects) {
|
||||
|
||||
Handle<String> object_string = Handle<String>::cast(factory->Object_string());
|
||||
Handle<GlobalObject> global(CcTest::i_isolate()->context()->global_object());
|
||||
CHECK(JSReceiver::HasOwnProperty(global, object_string));
|
||||
v8::Maybe<bool> maybe = JSReceiver::HasOwnProperty(global, object_string);
|
||||
CHECK(maybe.has_value);
|
||||
CHECK(maybe.value);
|
||||
|
||||
// Check ToString for oddballs
|
||||
CheckOddball(isolate, heap->true_value(), "true");
|
||||
@ -277,7 +279,9 @@ TEST(GarbageCollection) {
|
||||
heap->CollectGarbage(NEW_SPACE);
|
||||
|
||||
// Function should be alive.
|
||||
CHECK(JSReceiver::HasOwnProperty(global, name));
|
||||
v8::Maybe<bool> maybe = JSReceiver::HasOwnProperty(global, name);
|
||||
CHECK(maybe.has_value);
|
||||
CHECK(maybe.value);
|
||||
// Check function is retained.
|
||||
Handle<Object> func_value =
|
||||
Object::GetProperty(global, name).ToHandleChecked();
|
||||
@ -295,7 +299,9 @@ TEST(GarbageCollection) {
|
||||
// After gc, it should survive.
|
||||
heap->CollectGarbage(NEW_SPACE);
|
||||
|
||||
CHECK(JSReceiver::HasOwnProperty(global, obj_name));
|
||||
maybe = JSReceiver::HasOwnProperty(global, obj_name);
|
||||
CHECK(maybe.has_value);
|
||||
CHECK(maybe.value);
|
||||
Handle<Object> obj =
|
||||
Object::GetProperty(global, obj_name).ToHandleChecked();
|
||||
CHECK(obj->IsJSObject());
|
||||
@ -652,55 +658,85 @@ TEST(ObjectProperties) {
|
||||
Handle<Smi> two(Smi::FromInt(2), isolate);
|
||||
|
||||
// check for empty
|
||||
CHECK(!JSReceiver::HasOwnProperty(obj, first));
|
||||
v8::Maybe<bool> maybe = JSReceiver::HasOwnProperty(obj, first);
|
||||
CHECK(maybe.has_value);
|
||||
CHECK(!maybe.value);
|
||||
|
||||
// add first
|
||||
JSReceiver::SetProperty(obj, first, one, SLOPPY).Check();
|
||||
CHECK(JSReceiver::HasOwnProperty(obj, first));
|
||||
maybe = JSReceiver::HasOwnProperty(obj, first);
|
||||
CHECK(maybe.has_value);
|
||||
CHECK(maybe.value);
|
||||
|
||||
// delete first
|
||||
JSReceiver::DeleteProperty(obj, first, JSReceiver::NORMAL_DELETION).Check();
|
||||
CHECK(!JSReceiver::HasOwnProperty(obj, first));
|
||||
maybe = JSReceiver::HasOwnProperty(obj, first);
|
||||
CHECK(maybe.has_value);
|
||||
CHECK(!maybe.value);
|
||||
|
||||
// add first and then second
|
||||
JSReceiver::SetProperty(obj, first, one, SLOPPY).Check();
|
||||
JSReceiver::SetProperty(obj, second, two, SLOPPY).Check();
|
||||
CHECK(JSReceiver::HasOwnProperty(obj, first));
|
||||
CHECK(JSReceiver::HasOwnProperty(obj, second));
|
||||
maybe = JSReceiver::HasOwnProperty(obj, first);
|
||||
CHECK(maybe.has_value);
|
||||
CHECK(maybe.value);
|
||||
maybe = JSReceiver::HasOwnProperty(obj, second);
|
||||
CHECK(maybe.has_value);
|
||||
CHECK(maybe.value);
|
||||
|
||||
// delete first and then second
|
||||
JSReceiver::DeleteProperty(obj, first, JSReceiver::NORMAL_DELETION).Check();
|
||||
CHECK(JSReceiver::HasOwnProperty(obj, second));
|
||||
maybe = JSReceiver::HasOwnProperty(obj, second);
|
||||
CHECK(maybe.has_value);
|
||||
CHECK(maybe.value);
|
||||
JSReceiver::DeleteProperty(obj, second, JSReceiver::NORMAL_DELETION).Check();
|
||||
CHECK(!JSReceiver::HasOwnProperty(obj, first));
|
||||
CHECK(!JSReceiver::HasOwnProperty(obj, second));
|
||||
maybe = JSReceiver::HasOwnProperty(obj, first);
|
||||
CHECK(maybe.has_value);
|
||||
CHECK(!maybe.value);
|
||||
maybe = JSReceiver::HasOwnProperty(obj, second);
|
||||
CHECK(maybe.has_value);
|
||||
CHECK(!maybe.value);
|
||||
|
||||
// add first and then second
|
||||
JSReceiver::SetProperty(obj, first, one, SLOPPY).Check();
|
||||
JSReceiver::SetProperty(obj, second, two, SLOPPY).Check();
|
||||
CHECK(JSReceiver::HasOwnProperty(obj, first));
|
||||
CHECK(JSReceiver::HasOwnProperty(obj, second));
|
||||
maybe = JSReceiver::HasOwnProperty(obj, first);
|
||||
CHECK(maybe.has_value);
|
||||
CHECK(maybe.value);
|
||||
maybe = JSReceiver::HasOwnProperty(obj, second);
|
||||
CHECK(maybe.has_value);
|
||||
CHECK(maybe.value);
|
||||
|
||||
// delete second and then first
|
||||
JSReceiver::DeleteProperty(obj, second, JSReceiver::NORMAL_DELETION).Check();
|
||||
CHECK(JSReceiver::HasOwnProperty(obj, first));
|
||||
maybe = JSReceiver::HasOwnProperty(obj, first);
|
||||
CHECK(maybe.has_value);
|
||||
CHECK(maybe.value);
|
||||
JSReceiver::DeleteProperty(obj, first, JSReceiver::NORMAL_DELETION).Check();
|
||||
CHECK(!JSReceiver::HasOwnProperty(obj, first));
|
||||
CHECK(!JSReceiver::HasOwnProperty(obj, second));
|
||||
maybe = JSReceiver::HasOwnProperty(obj, first);
|
||||
CHECK(maybe.has_value);
|
||||
CHECK(!maybe.value);
|
||||
maybe = JSReceiver::HasOwnProperty(obj, second);
|
||||
CHECK(maybe.has_value);
|
||||
CHECK(!maybe.value);
|
||||
|
||||
// check string and internalized string match
|
||||
const char* string1 = "fisk";
|
||||
Handle<String> s1 = factory->NewStringFromAsciiChecked(string1);
|
||||
JSReceiver::SetProperty(obj, s1, one, SLOPPY).Check();
|
||||
Handle<String> s1_string = factory->InternalizeUtf8String(string1);
|
||||
CHECK(JSReceiver::HasOwnProperty(obj, s1_string));
|
||||
maybe = JSReceiver::HasOwnProperty(obj, s1_string);
|
||||
CHECK(maybe.has_value);
|
||||
CHECK(maybe.value);
|
||||
|
||||
// check internalized string and string match
|
||||
const char* string2 = "fugl";
|
||||
Handle<String> s2_string = factory->InternalizeUtf8String(string2);
|
||||
JSReceiver::SetProperty(obj, s2_string, one, SLOPPY).Check();
|
||||
Handle<String> s2 = factory->NewStringFromAsciiChecked(string2);
|
||||
CHECK(JSReceiver::HasOwnProperty(obj, s2));
|
||||
maybe = JSReceiver::HasOwnProperty(obj, s2);
|
||||
CHECK(maybe.has_value);
|
||||
CHECK(maybe.value);
|
||||
}
|
||||
|
||||
|
||||
|
@ -167,7 +167,9 @@ TEST(MarkCompactCollector) {
|
||||
|
||||
{ HandleScope scope(isolate);
|
||||
Handle<String> func_name = factory->InternalizeUtf8String("theFunction");
|
||||
CHECK(JSReceiver::HasOwnProperty(global, func_name));
|
||||
v8::Maybe<bool> maybe = JSReceiver::HasOwnProperty(global, func_name);
|
||||
CHECK(maybe.has_value);
|
||||
CHECK(maybe.value);
|
||||
Handle<Object> func_value =
|
||||
Object::GetProperty(global, func_name).ToHandleChecked();
|
||||
CHECK(func_value->IsJSFunction());
|
||||
@ -185,7 +187,9 @@ TEST(MarkCompactCollector) {
|
||||
|
||||
{ HandleScope scope(isolate);
|
||||
Handle<String> obj_name = factory->InternalizeUtf8String("theObject");
|
||||
CHECK(JSReceiver::HasOwnProperty(global, obj_name));
|
||||
v8::Maybe<bool> maybe = JSReceiver::HasOwnProperty(global, obj_name);
|
||||
CHECK(maybe.has_value);
|
||||
CHECK(maybe.value);
|
||||
Handle<Object> object =
|
||||
Object::GetProperty(global, obj_name).ToHandleChecked();
|
||||
CHECK(object->IsJSObject());
|
||||
|
Loading…
Reference in New Issue
Block a user