| Index: src/runtime.cc
|
| diff --git a/src/runtime.cc b/src/runtime.cc
|
| index 61e1069d0db35242be66e6f2031c9b098760b064..c1e01f884b0393dfc9620f998c01679677df5579 100644
|
| --- a/src/runtime.cc
|
| +++ b/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);
|
|
|
| - // 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);
|
| + maybe = JSReceiver::HasProperty(object, name);
|
| + }
|
|
|
| - return isolate->factory()->ToBoolean(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.
|
| @@ -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,14 +10196,17 @@ 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)) {
|
| - // 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);
|
| - visitor->visit(j, element_value);
|
| + } 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);
|
| + visitor->visit(j, element_value);
|
| + }
|
| }
|
| }
|
| break;
|
| @@ -10216,15 +10232,18 @@ 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)) {
|
| - // 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);
|
| - visitor->visit(j, element_value);
|
| + } 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);
|
| + visitor->visit(j, element_value);
|
| + }
|
| }
|
| }
|
| break;
|
| @@ -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(
|
|
|