Commit 09185f6e authored by neis's avatar neis Committed by Commit bot

Restructuring of JSObject::preventExtensions.

Now there are two functions, one corresponding to the spec's
[[PreventExtensions]] and one corresponding to Object.preventExtensions.
They differ in what they return.

This CL is in preparation of implementing Reflect.preventExtensions.

R=rossberg
BUG=

Review URL: https://codereview.chromium.org/1377103005

Cr-Commit-Position: refs/heads/master@{#31096}
parent e28183b5
......@@ -92,6 +92,7 @@ class CallSite {
T(CalledOnNonObject, "% called on non-object") \
T(CalledOnNullOrUndefined, "% called on null or undefined") \
T(CannotConvertToPrimitive, "Cannot convert object to primitive value") \
T(CannotPreventExt, "Cannot prevent extensions") \
T(CannotPreventExtExternalArray, \
"Cannot prevent extension of an object with external array elements") \
T(CircularStructure, "Converting circular structure to JSON") \
......
......@@ -5961,33 +5961,35 @@ bool JSObject::ReferencesObject(Object* obj) {
}
MaybeHandle<Object> JSObject::PreventExtensions(Handle<JSObject> object) {
if (!object->map()->is_extensible()) return object;
Maybe<bool> JSObject::PreventExtensionsInternal(Handle<JSObject> object) {
Isolate* isolate = object->GetIsolate();
if (!object->map()->is_extensible()) return Just(true);
if (!object->HasSloppyArgumentsElements() && !object->map()->is_observed()) {
return PreventExtensionsWithTransition<NONE>(object);
}
Isolate* isolate = object->GetIsolate();
if (object->IsAccessCheckNeeded() && !isolate->MayAccess(object)) {
isolate->ReportFailedAccessCheck(object);
RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
return isolate->factory()->false_value();
RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
UNREACHABLE();
return Just(false);
}
if (object->IsJSGlobalProxy()) {
PrototypeIterator iter(isolate, object);
if (iter.IsAtEnd()) return object;
if (iter.IsAtEnd()) return Just(true);
DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
return PreventExtensions(PrototypeIterator::GetCurrent<JSObject>(iter));
return PreventExtensionsInternal(
PrototypeIterator::GetCurrent<JSObject>(iter));
}
// It's not possible to seal objects with external array elements
if (object->HasFixedTypedArrayElements()) {
THROW_NEW_ERROR(
isolate, NewTypeError(MessageTemplate::kCannotPreventExtExternalArray),
Object);
isolate->Throw(*isolate->factory()->NewTypeError(
MessageTemplate::kCannotPreventExtExternalArray));
return Nothing<bool>();
}
// If there are fast elements we normalize.
......@@ -6007,13 +6009,28 @@ MaybeHandle<Object> JSObject::PreventExtensions(Handle<JSObject> object) {
DCHECK(!object->map()->is_extensible());
if (object->map()->is_observed()) {
RETURN_ON_EXCEPTION(
RETURN_ON_EXCEPTION_VALUE(
isolate,
EnqueueChangeRecord(object, "preventExtensions", Handle<Name>(),
isolate->factory()->the_hole_value()),
Object);
Nothing<bool>());
}
return object;
return Just(true);
}
static MaybeHandle<Object> ReturnObjectOrThrowTypeError(
Handle<JSObject> object, Maybe<bool> maybe, MessageTemplate::Template msg) {
if (!maybe.IsJust()) return MaybeHandle<Object>();
if (maybe.FromJust()) return object;
Isolate* isolate = object->GetIsolate();
THROW_NEW_ERROR(isolate, NewTypeError(msg), Object);
}
MaybeHandle<Object> JSObject::PreventExtensions(Handle<JSObject> object) {
return ReturnObjectOrThrowTypeError(object, PreventExtensionsInternal(object),
MessageTemplate::kCannotPreventExt);
}
......@@ -6057,8 +6074,7 @@ static void ApplyAttributesToDictionary(Dictionary* dictionary,
template <PropertyAttributes attrs>
MaybeHandle<Object> JSObject::PreventExtensionsWithTransition(
Handle<JSObject> object) {
Maybe<bool> JSObject::PreventExtensionsWithTransition(Handle<JSObject> object) {
STATIC_ASSERT(attrs == NONE || attrs == SEALED || attrs == FROZEN);
// Sealing/freezing sloppy arguments should be handled elsewhere.
......@@ -6068,13 +6084,13 @@ MaybeHandle<Object> JSObject::PreventExtensionsWithTransition(
Isolate* isolate = object->GetIsolate();
if (object->IsAccessCheckNeeded() && !isolate->MayAccess(object)) {
isolate->ReportFailedAccessCheck(object);
RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
return isolate->factory()->false_value();
RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
UNREACHABLE();
}
if (object->IsJSGlobalProxy()) {
PrototypeIterator iter(isolate, object);
if (iter.IsAtEnd()) return object;
if (iter.IsAtEnd()) return Just(true);
DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
return PreventExtensionsWithTransition<attrs>(
PrototypeIterator::GetCurrent<JSObject>(iter));
......@@ -6082,9 +6098,9 @@ MaybeHandle<Object> JSObject::PreventExtensionsWithTransition(
// It's not possible to seal or freeze objects with external array elements
if (object->HasFixedTypedArrayElements()) {
THROW_NEW_ERROR(
isolate, NewTypeError(MessageTemplate::kCannotPreventExtExternalArray),
Object);
isolate->Throw(*isolate->factory()->NewTypeError(
MessageTemplate::kCannotPreventExtExternalArray));
return Nothing<bool>();
}
Handle<SeededNumberDictionary> new_element_dictionary;
......@@ -6159,17 +6175,21 @@ MaybeHandle<Object> JSObject::PreventExtensionsWithTransition(
}
}
return object;
return Just(true);
}
MaybeHandle<Object> JSObject::Freeze(Handle<JSObject> object) {
return PreventExtensionsWithTransition<FROZEN>(object);
return ReturnObjectOrThrowTypeError(
object, PreventExtensionsWithTransition<FROZEN>(object),
MessageTemplate::kCannotPreventExt);
}
MaybeHandle<Object> JSObject::Seal(Handle<JSObject> object) {
return PreventExtensionsWithTransition<SEALED>(object);
return ReturnObjectOrThrowTypeError(
object, PreventExtensionsWithTransition<SEALED>(object),
MessageTemplate::kCannotPreventExt);
}
......
......@@ -2267,9 +2267,11 @@ class JSObject: public JSReceiver {
// Check whether this object references another object
bool ReferencesObject(Object* obj);
// Disalow further properties to be added to the oject.
// Disallow further properties to be added to the oject.
MUST_USE_RESULT static Maybe<bool> PreventExtensionsInternal(
Handle<JSObject> object); // ES [[PreventExtensions]]
MUST_USE_RESULT static MaybeHandle<Object> PreventExtensions(
Handle<JSObject> object);
Handle<JSObject> object); // ES Object.preventExtensions
static bool IsExtensible(Handle<JSObject> object);
......@@ -2461,7 +2463,7 @@ class JSObject: public JSReceiver {
// Helper for fast versions of preventExtensions, seal, and freeze.
// attrs is one of NONE, SEALED, or FROZEN (depending on the operation).
template <PropertyAttributes attrs>
MUST_USE_RESULT static MaybeHandle<Object> PreventExtensionsWithTransition(
MUST_USE_RESULT static Maybe<bool> PreventExtensionsWithTransition(
Handle<JSObject> object);
DISALLOW_IMPLICIT_CONSTRUCTORS(JSObject);
......
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