Bug 1112778, part 3 - Rename JSObject::preventExtensions -> js::PreventExtensions and a few others, and move them to jsobj.cpp. Uninline several functions that have no business being inlined. r=Waldo.

--HG--
extra : rebase_source : 72a7c9c5fd60b20a66fb4c98c062e9c0d8cf4391
This commit is contained in:
Jason Orendorff 2014-12-18 05:26:42 -06:00
Родитель ef7a22ceb7
Коммит 3e2999a0e8
21 изменённых файлов: 289 добавлений и 226 удалений

Просмотреть файл

@ -615,7 +615,7 @@ Collator(JSContext *cx, CallArgs args, bool construct)
// 10.1.2.1 step 5
bool extensible;
if (!JSObject::isExtensible(cx, obj, &extensible))
if (!IsExtensible(cx, obj, &extensible))
return false;
if (!extensible)
return Throw(cx, obj, JSMSG_OBJECT_NOT_EXTENSIBLE);
@ -1101,7 +1101,7 @@ NumberFormat(JSContext *cx, CallArgs args, bool construct)
// 11.1.2.1 step 5
bool extensible;
if (!JSObject::isExtensible(cx, obj, &extensible))
if (!IsExtensible(cx, obj, &extensible))
return false;
if (!extensible)
return Throw(cx, obj, JSMSG_OBJECT_NOT_EXTENSIBLE);
@ -1558,7 +1558,7 @@ DateTimeFormat(JSContext *cx, CallArgs args, bool construct)
// 12.1.2.1 step 5
bool extensible;
if (!JSObject::isExtensible(cx, obj, &extensible))
if (!IsExtensible(cx, obj, &extensible))
return false;
if (!extensible)
return Throw(cx, obj, JSMSG_OBJECT_NOT_EXTENSIBLE);

Просмотреть файл

@ -421,7 +421,7 @@ js::obj_getPrototypeOf(JSContext *cx, unsigned argc, Value *vp)
/* Step 3. */
RootedObject proto(cx);
if (!JSObject::getProto(cx, obj, &proto))
if (!GetPrototype(cx, obj, &proto))
return false;
args.rval().setObjectOrNull(proto);
return true;
@ -467,7 +467,7 @@ obj_setPrototypeOf(JSContext *cx, unsigned argc, Value *vp)
RootedObject newProto(cx, args[1].toObjectOrNull());
bool success;
if (!JSObject::setProto(cx, obj, newProto, &success))
if (!SetPrototype(cx, obj, newProto, &success))
return false;
/* Step 7. */
@ -859,7 +859,7 @@ obj_isExtensible(JSContext *cx, unsigned argc, Value *vp)
// Step 2.
if (args.get(0).isObject()) {
RootedObject obj(cx, &args.get(0).toObject());
if (!JSObject::isExtensible(cx, obj, &extensible))
if (!IsExtensible(cx, obj, &extensible))
return false;
}
args.rval().setBoolean(extensible);
@ -881,7 +881,7 @@ obj_preventExtensions(JSContext *cx, unsigned argc, Value *vp)
RootedObject obj(cx, &args.get(0).toObject());
bool status;
if (!JSObject::preventExtensions(cx, obj, &status))
if (!PreventExtensions(cx, obj, &status))
return false;
// Step 4.
@ -978,7 +978,7 @@ ProtoGetter(JSContext *cx, unsigned argc, Value *vp)
RootedObject obj(cx, &args.thisv().toObject());
RootedObject proto(cx);
if (!JSObject::getProto(cx, obj, &proto))
if (!GetPrototype(cx, obj, &proto))
return false;
args.rval().setObjectOrNull(proto);
return true;
@ -1025,7 +1025,7 @@ ProtoSetter(JSContext *cx, unsigned argc, Value *vp)
Rooted<JSObject*> newProto(cx, args[0].toObjectOrNull());
bool success;
if (!JSObject::setProto(cx, obj, newProto, &success))
if (!SetPrototype(cx, obj, newProto, &success))
return false;
if (!success) {

Просмотреть файл

@ -2211,7 +2211,7 @@ SetImmutablePrototype(JSContext *cx, unsigned argc, Value *vp)
RootedObject obj(cx, &args[0].toObject());
bool succeeded;
if (!JSObject::setImmutablePrototype(cx, obj, &succeeded))
if (!js::SetImmutablePrototype(cx, obj, &succeeded))
return false;
args.rval().setBoolean(succeeded);

Просмотреть файл

@ -203,7 +203,7 @@ MutatePrototype(JSContext *cx, HandlePlainObject obj, HandleValue value)
RootedObject newProto(cx, value.toObjectOrNull());
bool succeeded;
if (!JSObject::setProto(cx, obj, newProto, &succeeded))
if (!SetPrototype(cx, obj, newProto, &succeeded))
return false;
MOZ_ASSERT(succeeded);
return true;

Просмотреть файл

@ -2018,7 +2018,7 @@ JS_GetInstancePrivate(JSContext *cx, HandleObject obj, const JSClass *clasp, Cal
JS_PUBLIC_API(bool)
JS_GetPrototype(JSContext *cx, JS::Handle<JSObject*> obj, JS::MutableHandle<JSObject*> protop)
{
return JSObject::getProto(cx, obj, protop);
return GetPrototype(cx, obj, protop);
}
JS_PUBLIC_API(bool)
@ -2029,7 +2029,7 @@ JS_SetPrototype(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<JSObject*>
assertSameCompartment(cx, obj, proto);
bool succeeded;
if (!JSObject::setProto(cx, obj, proto, &succeeded))
if (!SetPrototype(cx, obj, proto, &succeeded))
return false;
if (!succeeded) {
@ -2041,6 +2041,18 @@ JS_SetPrototype(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<JSObject*>
return true;
}
JS_PUBLIC_API(bool)
JS_IsExtensible(JSContext *cx, HandleObject obj, bool *extensible)
{
return IsExtensible(cx, obj, extensible);
}
JS_PUBLIC_API(bool)
JS_PreventExtensions(JSContext *cx, JS::HandleObject obj, bool *succeeded)
{
return PreventExtensions(cx, obj, succeeded);
}
JS_PUBLIC_API(JSObject *)
JS_GetParent(JSObject *obj)
{
@ -2218,12 +2230,6 @@ JS_NewObjectForConstructor(JSContext *cx, const JSClass *clasp, const CallArgs&
return CreateThis(cx, Valueify(clasp), obj);
}
JS_PUBLIC_API(bool)
JS_IsExtensible(JSContext *cx, HandleObject obj, bool *extensible)
{
return JSObject::isExtensible(cx, obj, extensible);
}
JS_PUBLIC_API(bool)
JS_IsNative(JSObject *obj)
{
@ -2254,7 +2260,7 @@ JS_DeepFreezeObject(JSContext *cx, HandleObject obj)
/* Assume that non-extensible objects are already deep-frozen, to avoid divergence. */
bool extensible;
if (!JSObject::isExtensible(cx, obj, &extensible))
if (!IsExtensible(cx, obj, &extensible))
return false;
if (!extensible)
return true;
@ -6119,12 +6125,6 @@ JS_DecodeInterpretedFunction(JSContext *cx, const void *data, uint32_t length)
return funobj;
}
JS_PUBLIC_API(bool)
JS_PreventExtensions(JSContext *cx, JS::HandleObject obj, bool *succeeded)
{
return JSObject::preventExtensions(cx, obj, succeeded);
}
JS_PUBLIC_API(void)
JS::SetAsmJSCacheOps(JSRuntime *rt, const JS::AsmJSCacheOps *ops)
{

Просмотреть файл

@ -453,7 +453,7 @@ array_length_getter(JSContext *cx, HandleObject obj_, HandleId id, MutableHandle
vp.setNumber(obj->as<ArrayObject>().length());
return true;
}
if (!JSObject::getProto(cx, obj, &obj))
if (!GetPrototype(cx, obj, &obj))
return false;
} while (obj);
return true;

Просмотреть файл

@ -894,7 +894,7 @@ CreateFunctionPrototype(JSContext *cx, JSProtoKey key)
bool succeeded;
RootedFunction throwTypeError(cx, NewFunction(cx, tte, ThrowTypeError, 0,
JSFunction::NATIVE_FUN, self, js::NullPtr()));
if (!throwTypeError || !JSObject::preventExtensions(cx, throwTypeError, &succeeded))
if (!throwTypeError || !PreventExtensions(cx, throwTypeError, &succeeded))
return nullptr;
if (!succeeded) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_CANT_CHANGE_EXTENSIBILITY);

Просмотреть файл

@ -352,7 +352,7 @@ Snapshot(JSContext *cx, HandleObject pobj_, unsigned flags, AutoIdVector *props)
if (flags & JSITER_OWNONLY)
break;
if (!JSObject::getProto(cx, pobj, &pobj))
if (!GetPrototype(cx, pobj, &pobj))
return false;
} while (pobj != nullptr);
@ -1163,7 +1163,7 @@ SuppressDeletedPropertyHelper(JSContext *cx, HandleObject obj, StringPredicate p
* became visible as a result of this deletion.
*/
RootedObject proto(cx);
if (!JSObject::getProto(cx, obj, &proto))
if (!GetPrototype(cx, obj, &proto))
return false;
if (proto) {
RootedObject obj2(cx);

Просмотреть файл

@ -606,7 +606,7 @@ DefinePropertyOnObject(JSContext *cx, HandleNativeObject obj, HandleId id, const
/* 8.12.9 steps 2-4. */
if (!shape) {
bool extensible;
if (!JSObject::isExtensible(cx, obj, &extensible))
if (!IsExtensible(cx, obj, &extensible))
return false;
if (!extensible)
return Reject(cx, obj, JSMSG_OBJECT_NOT_EXTENSIBLE, throwError, rval);
@ -1103,7 +1103,7 @@ JSObject::sealOrFreeze(JSContext *cx, HandleObject obj, ImmutabilityType it)
MOZ_ASSERT(it == SEAL || it == FREEZE);
bool succeeded;
if (!JSObject::preventExtensions(cx, obj, &succeeded))
if (!PreventExtensions(cx, obj, &succeeded))
return false;
if (!succeeded) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_CANT_CHANGE_EXTENSIBILITY);
@ -1202,7 +1202,7 @@ JSObject::sealOrFreeze(JSContext *cx, HandleObject obj, ImmutabilityType it)
JSObject::isSealedOrFrozen(JSContext *cx, HandleObject obj, ImmutabilityType it, bool *resultp)
{
bool extensible;
if (!JSObject::isExtensible(cx, obj, &extensible))
if (!IsExtensible(cx, obj, &extensible))
return false;
if (extensible) {
*resultp = false;
@ -2153,7 +2153,7 @@ js::XDRObjectLiteral(XDRState<mode> *xdr, MutableHandleNativeObject obj)
uint32_t frozen;
bool extensible;
if (mode == XDR_ENCODE) {
if (!JSObject::isExtensible(cx, obj, &extensible))
if (!IsExtensible(cx, obj, &extensible))
return false;
frozen = extensible ? 0 : 1;
}
@ -3229,6 +3229,135 @@ JSObject::reportNotExtensible(JSContext *cx, unsigned report)
nullptr, nullptr);
}
/*** ES6 standard internal methods ***************************************************************/
bool
js::SetPrototype(JSContext *cx, HandleObject obj, HandleObject proto, bool *succeeded)
{
/*
* If |obj| has a "lazy" [[Prototype]], it is 1) a proxy 2) whose handler's
* {get,set}PrototypeOf and setImmutablePrototype methods mediate access to
* |obj.[[Prototype]]|. The Proxy subsystem is responsible for responding
* to such attempts.
*/
if (obj->hasLazyPrototype()) {
MOZ_ASSERT(obj->is<ProxyObject>());
return Proxy::setPrototypeOf(cx, obj, proto, succeeded);
}
/* Disallow mutation of immutable [[Prototype]]s. */
if (obj->nonLazyPrototypeIsImmutable()) {
*succeeded = false;
return true;
}
/*
* Disallow mutating the [[Prototype]] on ArrayBuffer objects, which
* due to their complicated delegate-object shenanigans can't easily
* have a mutable [[Prototype]].
*/
if (obj->is<ArrayBufferObject>()) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_SETPROTOTYPEOF_FAIL,
"incompatible ArrayBuffer");
return false;
}
/*
* Disallow mutating the [[Prototype]] on Typed Objects, per the spec.
*/
if (obj->is<TypedObject>()) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_SETPROTOTYPEOF_FAIL,
"incompatible TypedObject");
return false;
}
/*
* Explicitly disallow mutating the [[Prototype]] of Location objects
* for flash-related security reasons.
*/
if (!strcmp(obj->getClass()->name, "Location")) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_SETPROTOTYPEOF_FAIL,
"incompatible Location object");
return false;
}
/* ES6 9.1.2 step 5 forbids changing [[Prototype]] if not [[Extensible]]. */
bool extensible;
if (!IsExtensible(cx, obj, &extensible))
return false;
if (!extensible) {
*succeeded = false;
return true;
}
/* ES6 9.1.2 step 6 forbids generating cyclical prototype chains. */
RootedObject obj2(cx);
for (obj2 = proto; obj2; ) {
if (obj2 == obj) {
*succeeded = false;
return true;
}
if (!GetPrototype(cx, obj2, &obj2))
return false;
}
Rooted<TaggedProto> taggedProto(cx, TaggedProto(proto));
*succeeded = SetClassAndProto(cx, obj, obj->getClass(), taggedProto);
return *succeeded;
}
bool
js::PreventExtensions(JSContext *cx, HandleObject obj, bool *succeeded)
{
if (obj->is<ProxyObject>())
return js::Proxy::preventExtensions(cx, obj, succeeded);
if (!obj->nonProxyIsExtensible()) {
*succeeded = true;
return true;
}
/*
* Force lazy properties to be resolved by iterating over the objects' own
* properties.
*/
AutoIdVector props(cx);
if (!js::GetPropertyKeys(cx, obj, JSITER_HIDDEN | JSITER_OWNONLY, &props))
return false;
/*
* Convert all dense elements to sparse properties. This will shrink the
* initialized length and capacity of the object to zero and ensure that no
* new dense elements can be added without calling growElements(), which
* checks isExtensible().
*/
if (obj->isNative() && !NativeObject::sparsifyDenseElements(cx, obj.as<NativeObject>()))
return false;
*succeeded = true;
return obj->setFlag(cx, BaseShape::NOT_EXTENSIBLE, JSObject::GENERATE_SHAPE);
}
/*** SpiderMonkey nonstandard internal methods ***************************************************/
bool
js::SetImmutablePrototype(ExclusiveContext *cx, HandleObject obj, bool *succeeded)
{
if (obj->hasLazyPrototype()) {
if (!cx->shouldBeJSContext())
return false;
return Proxy::setImmutablePrototype(cx->asJSContext(), obj, succeeded);
}
if (!obj->setFlag(cx, BaseShape::IMMUTABLE_PROTOTYPE))
return false;
*succeeded = true;
return true;
}
/* static */ bool
JSObject::defaultValue(JSContext *cx, HandleObject obj, JSType hint, MutableHandleValue vp)
{
@ -3307,6 +3436,9 @@ js::NativeUnwatch(JSContext *cx, JS::HandleObject obj, JS::HandleId id)
return UnwatchGuts(cx, obj, id);
}
/* * */
bool
js::HasDataProperty(JSContext *cx, NativeObject *obj, jsid id, Value *vp)
{
@ -3443,7 +3575,7 @@ js::IsDelegateOfObject(JSContext *cx, HandleObject protoObj, JSObject* obj, bool
{
RootedObject obj2(cx, obj);
for (;;) {
if (!JSObject::getProto(cx, obj2, &obj2))
if (!GetPrototype(cx, obj2, &obj2))
return false;
if (!obj2) {
*result = false;
@ -3627,6 +3759,9 @@ js_ReportGetterOnlyAssignment(JSContext *cx, bool strict)
JSMSG_GETTER_ONLY);
}
/*** Debugging routines **************************************************************************/
#ifdef DEBUG
/*
@ -3951,6 +4086,9 @@ js_DumpBacktrace(JSContext *cx)
#endif
}
/* * */
void
JSObject::addSizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf, JS::ClassInfo *info)
{

Просмотреть файл

@ -78,6 +78,10 @@ class NormalArgumentsObject;
class SetObject;
class StrictArgumentsObject;
// Forward declarations, required for later friend declarations.
bool PreventExtensions(JSContext *cx, JS::HandleObject obj, bool *succeeded);
bool SetImmutablePrototype(js::ExclusiveContext *cx, JS::HandleObject obj, bool *succeeded);
} /* namespace js */
/*
@ -113,6 +117,9 @@ class JSObject : public js::gc::Cell
friend class js::GCMarker;
friend class js::NewObjectCache;
friend class js::Nursery;
friend bool js::PreventExtensions(JSContext *cx, JS::HandleObject obj, bool *succeeded);
friend bool js::SetImmutablePrototype(js::ExclusiveContext *cx, JS::HandleObject obj,
bool *succeeded);
/* Make the type object to use for LAZY_TYPE objects. */
static js::types::TypeObject *makeLazyType(JSContext *cx, js::HandleObject obj);
@ -337,7 +344,7 @@ class JSObject : public js::gc::Cell
* 1. obj->getProto() returns the prototype, but asserts if obj is a proxy.
* 2. obj->getTaggedProto() returns a TaggedProto, which can be tested to
* check if the proto is an object, nullptr, or lazily computed.
* 3. JSObject::getProto(cx, obj, &proto) computes the proto of an object.
* 3. js::GetPrototype(cx, obj, &proto) computes the proto of an object.
* If obj is a proxy and the proto is lazy, this code may allocate or
* GC in order to compute the proto. Currently, it will not run JS code.
*/
@ -385,19 +392,6 @@ class JSObject : public js::gc::Cell
return lastProperty()->hasObjectFlag(js::BaseShape::IMMUTABLE_PROTOTYPE);
}
// Attempt to make |obj|'s [[Prototype]] immutable, such that subsequently
// trying to change it will not work. If an internal error occurred,
// returns false. Otherwise, |*succeeded| is set to true iff |obj|'s
// [[Prototype]] is now immutable.
static bool
setImmutablePrototype(js::ExclusiveContext *cx, JS::HandleObject obj, bool *succeeded);
static inline bool getProto(JSContext *cx, js::HandleObject obj,
js::MutableHandleObject protop);
// Returns false on error, success of operation in outparam.
static inline bool setProto(JSContext *cx, JS::HandleObject obj,
JS::HandleObject proto, bool *succeeded);
// uninlinedSetType() is the same as setType(), but not inlined.
inline void setType(js::types::TypeObject *newType);
void uninlinedSetType(js::types::TypeObject *newType);
@ -493,9 +487,6 @@ class JSObject : public js::gc::Cell
*/
public:
static inline bool
isExtensible(js::ExclusiveContext *cx, js::HandleObject obj, bool *extensible);
// Indicates whether a non-proxy is extensible. Don't call on proxies!
// This method really shouldn't exist -- but there are a few internal
// places that want it (JITs and the like), and it'd be a pain to mark them
@ -507,12 +498,6 @@ class JSObject : public js::gc::Cell
return !lastProperty()->hasObjectFlag(js::BaseShape::NOT_EXTENSIBLE);
}
// Attempt to change the [[Extensible]] bit on |obj| to false. Indicate
// success or failure through the |*succeeded| outparam, or actual error
// through the return value.
static bool
preventExtensions(JSContext *cx, js::HandleObject obj, bool *succeeded);
private:
enum ImmutabilityType { SEAL, FREEZE };
@ -891,8 +876,71 @@ class ValueArray {
namespace js {
/*** Standard internal methods ********************************************************************
*
* The functions below are the fundamental operations on objects.
*
* ES6 specifies 14 internal methods that define how objects behave. The spec
* is actually quite good on this topic, though you may have to read it a few
* times. See ES6 draft rev 29 (6 Dec 2014) 6.1.7.2 and 6.1.7.3.
*
* When 'obj' is an ordinary object, these functions have boring standard
* behavior as specified by ES6 draft rev 29 section 9.1; see the section about
* internal methods in vm/NativeObject.h.
*
* Proxies override the behavior of internal methods. So when 'obj' is a proxy,
* any one of the functions below could do just about anything. See jsproxy.h.
*/
/*
* ES6 [[GetPrototypeOf]]. Get obj's prototype, storing it in protop.
*
* If obj is definitely not a proxy, the infallible obj->getProto() can be used
* instead. See the comment on JSObject::getTaggedProto().
*/
inline bool
GetPrototype(JSContext *cx, HandleObject obj, MutableHandleObject protop);
/*
* ES6 [[SetPrototypeOf]]. Change obj's prototype to proto.
*
* Returns false on error, success of operation in outparam. For example, if
* obj is not extensible, its prototype is fixed. js::SetPrototype will return
* true, because no exception is thrown for this; but *succeeded will be false.
*/
extern bool
SetPrototype(JSContext *cx, HandleObject obj, HandleObject proto, bool *succeeded);
/*
* ES6 [[IsExtensible]]. Extensible objects can have new properties defined on
* them. Inextensible objects can't, and their [[Prototype]] slot is fixed as
* well.
*/
inline bool
IsExtensible(ExclusiveContext *cx, HandleObject obj, bool *extensible);
/*
* ES6 [[PreventExtensions]]. Attempt to change the [[Extensible]] bit on |obj|
* to false. Indicate success or failure through the |*succeeded| outparam, or
* actual error through the return value.
*/
extern bool
PreventExtensions(JSContext *cx, HandleObject obj, bool *succeeded);
/*** SpiderMonkey nonstandard internal methods ***************************************************/
/*
* Attempt to make |obj|'s [[Prototype]] immutable, such that subsequently
* trying to change it will not work. If an internal error occurred,
* returns false. Otherwise, |*succeeded| is set to true iff |obj|'s
* [[Prototype]] is now immutable.
*/
extern bool
SetImmutablePrototype(js::ExclusiveContext *cx, JS::HandleObject obj, bool *succeeded);
/* Set *resultp to tell whether obj has an own property with the given id. */
bool
extern bool
HasOwnProperty(JSContext *cx, HandleObject obj, HandleId id, bool *resultp);
template <AllowGC allowGC>

Просмотреть файл

@ -164,8 +164,8 @@ JSObject::setType(js::types::TypeObject *newType)
type_ = newType;
}
/* static */ inline bool
JSObject::getProto(JSContext *cx, js::HandleObject obj, js::MutableHandleObject protop)
inline bool
js::GetPrototype(JSContext *cx, js::HandleObject obj, js::MutableHandleObject protop)
{
if (obj->getTaggedProto().isLazy()) {
MOZ_ASSERT(obj->is<js::ProxyObject>());
@ -176,89 +176,13 @@ JSObject::getProto(JSContext *cx, js::HandleObject obj, js::MutableHandleObject
}
}
/* static */ inline bool
JSObject::setProto(JSContext *cx, JS::HandleObject obj, JS::HandleObject proto, bool *succeeded)
inline bool
js::IsExtensible(ExclusiveContext *cx, HandleObject obj, bool *extensible)
{
/*
* If |obj| has a "lazy" [[Prototype]], it is 1) a proxy 2) whose handler's
* {get,set}PrototypeOf and setImmutablePrototype methods mediate access to
* |obj.[[Prototype]]|. The Proxy subsystem is responsible for responding
* to such attempts.
*/
if (obj->hasLazyPrototype()) {
MOZ_ASSERT(obj->is<js::ProxyObject>());
return js::Proxy::setPrototypeOf(cx, obj, proto, succeeded);
}
/* Disallow mutation of immutable [[Prototype]]s. */
if (obj->nonLazyPrototypeIsImmutable()) {
*succeeded = false;
return true;
}
/*
* Disallow mutating the [[Prototype]] on ArrayBuffer objects, which
* due to their complicated delegate-object shenanigans can't easily
* have a mutable [[Prototype]].
*/
if (obj->is<js::ArrayBufferObject>()) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_SETPROTOTYPEOF_FAIL,
"incompatible ArrayBuffer");
return false;
}
/*
* Disallow mutating the [[Prototype]] on Typed Objects, per the spec.
*/
if (obj->is<js::TypedObject>()) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_SETPROTOTYPEOF_FAIL,
"incompatible TypedObject");
return false;
}
/*
* Explicitly disallow mutating the [[Prototype]] of Location objects
* for flash-related security reasons.
*/
if (!strcmp(obj->getClass()->name, "Location")) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_SETPROTOTYPEOF_FAIL,
"incompatible Location object");
return false;
}
/* ES6 9.1.2 step 5 forbids changing [[Prototype]] if not [[Extensible]]. */
bool extensible;
if (!JSObject::isExtensible(cx, obj, &extensible))
return false;
if (!extensible) {
*succeeded = false;
return true;
}
/* ES6 9.1.2 step 6 forbids generating cyclical prototype chains. */
js::RootedObject obj2(cx);
for (obj2 = proto; obj2; ) {
if (obj2 == obj) {
*succeeded = false;
return true;
}
if (!JSObject::getProto(cx, obj2, &obj2))
return false;
}
JS::Rooted<js::TaggedProto> taggedProto(cx, js::TaggedProto(proto));
*succeeded = SetClassAndProto(cx, obj, obj->getClass(), taggedProto);
return *succeeded;
}
/* static */ inline bool
JSObject::isExtensible(js::ExclusiveContext *cx, js::HandleObject obj, bool *extensible)
{
if (obj->is<js::ProxyObject>()) {
if (obj->is<ProxyObject>()) {
if (!cx->shouldBeJSContext())
return false;
return js::Proxy::isExtensible(cx->asJSContext(), obj, extensible);
return Proxy::isExtensible(cx->asJSContext(), obj, extensible);
}
*extensible = obj->nonProxyIsExtensible();

Просмотреть файл

@ -92,7 +92,7 @@ BaseProxyHandler::set(JSContext *cx, HandleObject proxy, HandleObject receiver,
// The spec calls this variable "parent", but that word has weird
// connotations in SpiderMonkey, so let's go with "proto".
RootedObject proto(cx);
if (!JSObject::getProto(cx, proxy, &proto))
if (!GetPrototype(cx, proxy, &proto))
return false;
if (proto)
return JSObject::setGeneric(cx, proto, receiver, id, vp, strict);

Просмотреть файл

@ -84,7 +84,7 @@ CrossCompartmentWrapper::getPrototypeOf(JSContext *cx, HandleObject wrapper,
{
RootedObject wrapped(cx, wrappedObject(wrapper));
AutoCompartment call(cx, wrapped);
if (!JSObject::getProto(cx, wrapped, protop))
if (!GetPrototype(cx, wrapped, protop))
return false;
if (protop)
protop->setDelegate(cx);

Просмотреть файл

@ -117,35 +117,35 @@ bool
DirectProxyHandler::getPrototypeOf(JSContext *cx, HandleObject proxy, MutableHandleObject protop) const
{
RootedObject target(cx, proxy->as<ProxyObject>().target());
return JSObject::getProto(cx, target, protop);
return GetPrototype(cx, target, protop);
}
bool
DirectProxyHandler::setPrototypeOf(JSContext *cx, HandleObject proxy, HandleObject proto, bool *bp) const
{
RootedObject target(cx, proxy->as<ProxyObject>().target());
return JSObject::setProto(cx, target, proto, bp);
return SetPrototype(cx, target, proto, bp);
}
bool
DirectProxyHandler::setImmutablePrototype(JSContext *cx, HandleObject proxy, bool *succeeded) const
{
RootedObject target(cx, proxy->as<ProxyObject>().target());
return JSObject::setImmutablePrototype(cx, target, succeeded);
return SetImmutablePrototype(cx, target, succeeded);
}
bool
DirectProxyHandler::preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded) const
{
RootedObject target(cx, proxy->as<ProxyObject>().target());
return JSObject::preventExtensions(cx, target, succeeded);
return PreventExtensions(cx, target, succeeded);
}
bool
DirectProxyHandler::isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) const
{
RootedObject target(cx, proxy->as<ProxyObject>().target());
return JSObject::isExtensible(cx, target, extensible);
return IsExtensible(cx, target, extensible);
}
bool

Просмотреть файл

@ -87,7 +87,7 @@ js::assertEnteredPolicy(JSContext *cx, JSObject *proxy, jsid id,
#define INVOKE_ON_PROTOTYPE(cx, handler, proxy, protoCall) \
JS_BEGIN_MACRO \
RootedObject proto(cx); \
if (!JSObject::getProto(cx, proxy, &proto)) \
if (!GetPrototype(cx, proxy, &proto)) \
return false; \
if (!proto) \
return true; \
@ -370,7 +370,7 @@ Proxy::enumerate(JSContext *cx, HandleObject proxy, MutableHandleObject objp)
return false;
RootedObject proto(cx);
if (!JSObject::getProto(cx, proxy, &proto))
if (!GetPrototype(cx, proxy, &proto))
return false;
if (!proto)
return EnumeratedIdVectorToIterator(cx, proxy, 0, props, objp);

Просмотреть файл

@ -204,7 +204,7 @@ ArrayToIdVector(JSContext *cx, HandleObject proxy, HandleObject target, HandleVa
// step v
bool extensible;
if (!JSObject::isExtensible(cx, target, &extensible))
if (!IsExtensible(cx, target, &extensible))
return false;
if (!extensible && !isFixed) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_CANT_REPORT_NEW);
@ -251,7 +251,7 @@ ArrayToIdVector(JSContext *cx, HandleObject proxy, HandleObject target, HandleVa
// step iii
bool extensible;
if (!JSObject::isExtensible(cx, target, &extensible))
if (!IsExtensible(cx, target, &extensible))
return false;
if (!extensible && isFixed) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_CANT_REPORT_E_AS_NE);
@ -345,7 +345,7 @@ ScriptedDirectProxyHandler::preventExtensions(JSContext *cx, HandleObject proxy,
// Step 11.
if (booleanTrapResult) {
bool extensible;
if (!JSObject::isExtensible(cx, target, &extensible))
if (!IsExtensible(cx, target, &extensible))
return false;
if (extensible) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_CANT_REPORT_AS_NON_EXTENSIBLE);
@ -396,7 +396,7 @@ ScriptedDirectProxyHandler::isExtensible(JSContext *cx, HandleObject proxy, bool
// step 10-11
bool targetResult;
if (!JSObject::isExtensible(cx, target, &targetResult))
if (!IsExtensible(cx, target, &targetResult))
return false;
// step 12
@ -423,7 +423,7 @@ ScriptedDirectProxyHandler::getPropertyDescriptor(JSContext *cx, HandleObject pr
if (desc.object())
return true;
RootedObject proto(cx);
if (!JSObject::getProto(cx, proxy, &proto))
if (!GetPrototype(cx, proxy, &proto))
return false;
if (!proto) {
MOZ_ASSERT(!desc.object());
@ -498,7 +498,7 @@ ScriptedDirectProxyHandler::getOwnPropertyDescriptor(JSContext *cx, HandleObject
// substep c-e
bool extensibleTarget;
if (!JSObject::isExtensible(cx, target, &extensibleTarget))
if (!IsExtensible(cx, target, &extensibleTarget))
return false;
if (!extensibleTarget) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_CANT_REPORT_E_AS_NE);
@ -512,7 +512,7 @@ ScriptedDirectProxyHandler::getOwnPropertyDescriptor(JSContext *cx, HandleObject
// step 14-15
bool extensibleTarget;
if (!JSObject::isExtensible(cx, target, &extensibleTarget))
if (!IsExtensible(cx, target, &extensibleTarget))
return false;
// step 16-17
@ -606,7 +606,7 @@ ScriptedDirectProxyHandler::defineProperty(JSContext *cx, HandleObject proxy, Ha
// step 16-17
bool extensibleTarget;
if (!JSObject::isExtensible(cx, target, &extensibleTarget))
if (!IsExtensible(cx, target, &extensibleTarget))
return false;
// step 18-19
@ -853,7 +853,7 @@ ScriptedDirectProxyHandler::has(JSContext *cx, HandleObject proxy, HandleId id,
}
bool extensible;
if (!JSObject::isExtensible(cx, target, &extensible))
if (!IsExtensible(cx, target, &extensible))
return false;
if (!extensible) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_CANT_REPORT_E_AS_NE);

Просмотреть файл

@ -6234,7 +6234,7 @@ DebuggerObject_getProto(JSContext *cx, unsigned argc, Value *vp)
RootedObject proto(cx);
{
AutoCompartment ac(cx, refobj);
if (!JSObject::getProto(cx, refobj, &proto))
if (!GetPrototype(cx, refobj, &proto))
return false;
}
RootedValue protov(cx, ObjectOrNullValue(proto));
@ -6708,7 +6708,7 @@ DebuggerObject_deleteProperty(JSContext *cx, unsigned argc, Value *vp)
return true;
}
enum SealHelperOp { Seal, Freeze, PreventExtensions };
enum SealHelperOp { OpSeal, OpFreeze, OpPreventExtensions };
static bool
DebuggerObject_sealHelper(JSContext *cx, unsigned argc, Value *vp, SealHelperOp op, const char *name)
@ -6719,14 +6719,14 @@ DebuggerObject_sealHelper(JSContext *cx, unsigned argc, Value *vp, SealHelperOp
ac.emplace(cx, obj);
ErrorCopier ec(ac);
bool ok;
if (op == Seal) {
if (op == OpSeal) {
ok = JSObject::seal(cx, obj);
} else if (op == Freeze) {
} else if (op == OpFreeze) {
ok = JSObject::freeze(cx, obj);
} else {
MOZ_ASSERT(op == PreventExtensions);
MOZ_ASSERT(op == OpPreventExtensions);
bool succeeded;
ok = JSObject::preventExtensions(cx, obj, &succeeded);
ok = PreventExtensions(cx, obj, &succeeded);
if (!ok)
return false;
if (!succeeded) {
@ -6743,19 +6743,19 @@ DebuggerObject_sealHelper(JSContext *cx, unsigned argc, Value *vp, SealHelperOp
static bool
DebuggerObject_seal(JSContext *cx, unsigned argc, Value *vp)
{
return DebuggerObject_sealHelper(cx, argc, vp, Seal, "seal");
return DebuggerObject_sealHelper(cx, argc, vp, OpSeal, "seal");
}
static bool
DebuggerObject_freeze(JSContext *cx, unsigned argc, Value *vp)
{
return DebuggerObject_sealHelper(cx, argc, vp, Freeze, "freeze");
return DebuggerObject_sealHelper(cx, argc, vp, OpFreeze, "freeze");
}
static bool
DebuggerObject_preventExtensions(JSContext *cx, unsigned argc, Value *vp)
{
return DebuggerObject_sealHelper(cx, argc, vp, PreventExtensions, "preventExtensions");
return DebuggerObject_sealHelper(cx, argc, vp, OpPreventExtensions, "preventExtensions");
}
static bool
@ -6768,14 +6768,14 @@ DebuggerObject_isSealedHelper(JSContext *cx, unsigned argc, Value *vp, SealHelpe
ac.emplace(cx, obj);
ErrorCopier ec(ac);
bool r;
if (op == Seal) {
if (op == OpSeal) {
if (!JSObject::isSealed(cx, obj, &r))
return false;
} else if (op == Freeze) {
} else if (op == OpFreeze) {
if (!JSObject::isFrozen(cx, obj, &r))
return false;
} else {
if (!JSObject::isExtensible(cx, obj, &r))
if (!IsExtensible(cx, obj, &r))
return false;
}
args.rval().setBoolean(r);
@ -6785,19 +6785,19 @@ DebuggerObject_isSealedHelper(JSContext *cx, unsigned argc, Value *vp, SealHelpe
static bool
DebuggerObject_isSealed(JSContext *cx, unsigned argc, Value *vp)
{
return DebuggerObject_isSealedHelper(cx, argc, vp, Seal, "isSealed");
return DebuggerObject_isSealedHelper(cx, argc, vp, OpSeal, "isSealed");
}
static bool
DebuggerObject_isFrozen(JSContext *cx, unsigned argc, Value *vp)
{
return DebuggerObject_isSealedHelper(cx, argc, vp, Freeze, "isFrozen");
return DebuggerObject_isSealedHelper(cx, argc, vp, OpFreeze, "isFrozen");
}
static bool
DebuggerObject_isExtensible(JSContext *cx, unsigned argc, Value *vp)
{
return DebuggerObject_isSealedHelper(cx, argc, vp, PreventExtensions, "isExtensible");
return DebuggerObject_isSealedHelper(cx, argc, vp, OpPreventExtensions, "isExtensible");
}
enum ApplyOrCallMode { ApplyMode, CallMode };

Просмотреть файл

@ -661,7 +661,7 @@ ProcessCallSiteObjOperation(JSContext *cx, RootedObject &cso, RootedObject &raw,
RootedValue &rawValue)
{
bool extensible;
if (!JSObject::isExtensible(cx, cso, &extensible))
if (!IsExtensible(cx, cso, &extensible))
return false;
if (extensible) {
JSAtom *name = cx->names().raw;

Просмотреть файл

@ -3157,7 +3157,7 @@ CASE(JSOP_MUTATEPROTO)
MOZ_ASSERT(obj->is<PlainObject>());
bool succeeded;
if (!JSObject::setProto(cx, obj, newProto, &succeeded))
if (!SetPrototype(cx, obj, newProto, &succeeded))
goto error;
MOZ_ASSERT(succeeded);
}

Просмотреть файл

@ -136,21 +136,6 @@ ObjectElements::MakeElementsCopyOnWrite(ExclusiveContext *cx, NativeObject *obj)
return true;
}
/* static */ bool
JSObject::setImmutablePrototype(ExclusiveContext *cx, HandleObject obj, bool *succeeded)
{
if (obj->hasLazyPrototype()) {
if (!cx->shouldBeJSContext())
return false;
return Proxy::setImmutablePrototype(cx->asJSContext(), obj, succeeded);
}
if (!obj->setFlag(cx, BaseShape::IMMUTABLE_PROTOTYPE))
return false;
*succeeded = true;
return true;
}
#ifdef DEBUG
void
js::NativeObject::checkShapeConsistency()
@ -1852,7 +1837,7 @@ SetPropertyByDefining(JSContext *cx, HandleNativeObject obj, HandleObject receiv
// enforced by [[DefineOwnProperty]], but we haven't implemented that yet.)
if (!existing) {
bool extensible;
if (!JSObject::isExtensible(cx, receiver, &extensible))
if (!IsExtensible(cx, receiver, &extensible))
return false;
if (!extensible) {
// Error in strict mode code, warn with extra warnings option,

Просмотреть файл

@ -496,7 +496,7 @@ NativeObject::addProperty(ExclusiveContext *cx, HandleNativeObject obj, HandleId
MOZ_ASSERT(setter != JS_StrictPropertyStub);
bool extensible;
if (!JSObject::isExtensible(cx, obj, &extensible))
if (!IsExtensible(cx, obj, &extensible))
return nullptr;
if (!extensible) {
if (cx->isJSContext())
@ -735,7 +735,7 @@ NativeObject::putProperty(ExclusiveContext *cx, HandleNativeObject obj, HandleId
*/
bool extensible;
if (!JSObject::isExtensible(cx, obj, &extensible))
if (!IsExtensible(cx, obj, &extensible))
return nullptr;
if (!extensible) {
@ -1230,38 +1230,6 @@ Shape::setObjectMetadata(JSContext *cx, JSObject *metadata, TaggedProto proto, S
return replaceLastProperty(cx, base, proto, lastRoot);
}
/* static */ bool
JSObject::preventExtensions(JSContext *cx, HandleObject obj, bool *succeeded)
{
if (obj->is<ProxyObject>())
return js::Proxy::preventExtensions(cx, obj, succeeded);
if (!obj->nonProxyIsExtensible()) {
*succeeded = true;
return true;
}
/*
* Force lazy properties to be resolved by iterating over the objects' own
* properties.
*/
AutoIdVector props(cx);
if (!js::GetPropertyKeys(cx, obj, JSITER_HIDDEN | JSITER_OWNONLY, &props))
return false;
/*
* Convert all dense elements to sparse properties. This will shrink the
* initialized length and capacity of the object to zero and ensure that no
* new dense elements can be added without calling growElements(), which
* checks isExtensible().
*/
if (obj->isNative() && !NativeObject::sparsifyDenseElements(cx, obj.as<NativeObject>()))
return false;
*succeeded = true;
return obj->setFlag(cx, BaseShape::NOT_EXTENSIBLE, GENERATE_SHAPE);
}
bool
JSObject::setFlag(ExclusiveContext *cx, /*BaseShape::Flag*/ uint32_t flag_,
GenerateShape generateShape)