Bug 1073842 - Move NativeObject manipulating methods into more appropriate files, sr=luke.

This commit is contained in:
Brian Hackett 2014-10-06 04:05:40 -07:00
Родитель 27ac5db9f7
Коммит 13d0a4b214
9 изменённых файлов: 2365 добавлений и 2354 удалений

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

@ -10,6 +10,7 @@
#include "jsobjinlines.h"
#include "vm/ObjectImpl-inl.h"
#include "vm/Symbol-inl.h"
using JS::Symbol;

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

@ -2150,29 +2150,6 @@ js::ReportIncompatible(JSContext *cx, CallReceiver call)
}
}
bool
JSObject::hasIdempotentProtoChain() const
{
// Return false if obj (or an object on its proto chain) is non-native or
// has a resolve or lookup hook.
JSObject *obj = const_cast<JSObject *>(this);
while (true) {
if (!obj->isNative())
return false;
JSResolveOp resolve = obj->getClass()->resolve;
if (resolve != JS_ResolveStub && resolve != (JSResolveOp) js::fun_resolve)
return false;
if (obj->getOps()->lookupProperty || obj->getOps()->lookupGeneric || obj->getOps()->lookupElement)
return false;
obj = obj->getProto();
if (!obj)
return true;
}
}
namespace JS {
namespace detail {

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

@ -35,6 +35,7 @@
#include "jsatominlines.h"
#include "vm/NumberObject-inl.h"
#include "vm/ObjectImpl-inl.h"
#include "vm/String-inl.h"
using namespace js;

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -1062,17 +1062,6 @@ CloneObject(JSContext *cx, HandleObject obj, Handle<js::TaggedProto> proto, Hand
extern NativeObject *
DeepCloneObjectLiteral(JSContext *cx, HandleNativeObject obj, NewObjectKind newKind = GenericObject);
/*
* Return successfully added or changed shape or nullptr on error.
*/
extern bool
DefineNativeProperty(ExclusiveContext *cx, HandleNativeObject obj, HandleId id, HandleValue value,
PropertyOp getter, StrictPropertyOp setter, unsigned attrs);
extern bool
LookupNativeProperty(ExclusiveContext *cx, HandleNativeObject obj, HandleId id,
js::MutableHandleObject objp, js::MutableHandleShape propp);
/*
* Call the [[DefineOwnProperty]] internal method of obj.
*
@ -1137,16 +1126,6 @@ js_FindVariableScope(JSContext *cx, JSFunction **funp);
namespace js {
bool
NativeGet(JSContext *cx, HandleObject obj, HandleNativeObject pobj,
HandleShape shape, MutableHandle<Value> vp);
template <ExecutionMode mode>
bool
NativeSet(typename ExecutionModeTraits<mode>::ContextType cx,
HandleNativeObject obj, HandleObject receiver,
HandleShape shape, bool strict, MutableHandleValue vp);
bool
LookupPropertyPure(JSObject *obj, jsid id, NativeObject **objp, Shape **propp);
@ -1169,19 +1148,6 @@ GetOwnPropertyDescriptor(JSContext *cx, HandleObject obj, HandleId id, MutableHa
bool
NewPropertyDescriptorObject(JSContext *cx, Handle<PropertyDescriptor> desc, MutableHandleValue vp);
/*
* If obj has an already-resolved data property for id, return true and
* store the property value in *vp.
*/
extern bool
HasDataProperty(JSContext *cx, NativeObject *obj, jsid id, Value *vp);
inline bool
HasDataProperty(JSContext *cx, NativeObject *obj, PropertyName *name, Value *vp)
{
return HasDataProperty(cx, obj, NameToId(name), vp);
}
extern bool
IsDelegate(JSContext *cx, HandleObject obj, const Value &v, bool *result);
@ -1262,6 +1228,16 @@ Throw(JSContext *cx, jsid id, unsigned errorNumber);
extern bool
Throw(JSContext *cx, JSObject *obj, unsigned errorNumber);
namespace baseops {
extern bool
Watch(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject callable);
extern bool
Unwatch(JSContext *cx, JS::HandleObject obj, JS::HandleId id);
} /* namespace baseops */
} /* namespace js */
#endif /* jsobj_h */

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

@ -797,15 +797,6 @@ NewObjectMetadata(ExclusiveContext *cxArg, JSObject **pmetadata)
return true;
}
inline bool
DefineNativeProperty(ExclusiveContext *cx, HandleNativeObject obj,
PropertyName *name, HandleValue value,
PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
{
Rooted<jsid> id(cx, NameToId(name));
return DefineNativeProperty(cx, obj, id, value, getter, setter, attrs);
}
namespace baseops {
inline bool
@ -826,6 +817,40 @@ DefineProperty(ExclusiveContext *cx, HandleNativeObject obj, PropertyName *name,
} /* namespace baseops */
static inline unsigned
ApplyAttributes(unsigned attrs, bool enumerable, bool writable, bool configurable)
{
/*
* Respect the fact that some callers may want to preserve existing attributes as much as
* possible, or install defaults otherwise.
*/
if (attrs & JSPROP_IGNORE_ENUMERATE) {
attrs &= ~JSPROP_IGNORE_ENUMERATE;
if (enumerable)
attrs |= JSPROP_ENUMERATE;
else
attrs &= ~JSPROP_ENUMERATE;
}
if (attrs & JSPROP_IGNORE_READONLY) {
attrs &= ~JSPROP_IGNORE_READONLY;
// Only update the writability if it's relevant
if (!(attrs & (JSPROP_GETTER | JSPROP_SETTER))) {
if (!writable)
attrs |= JSPROP_READONLY;
else
attrs &= ~JSPROP_READONLY;
}
}
if (attrs & JSPROP_IGNORE_PERMANENT) {
attrs &= ~JSPROP_IGNORE_PERMANENT;
if (!configurable)
attrs |= JSPROP_PERMANENT;
else
attrs &= ~JSPROP_PERMANENT;
}
return attrs;
}
} /* namespace js */
extern js::NativeObject *

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

@ -460,6 +460,226 @@ NewNativeObjectWithType(JSContext *cx, HandleTypeObject type, JSObject *parent,
return MaybeNativeObject(NewObjectWithType(cx, type, parent, newKind));
}
/*
* Call obj's resolve hook.
*
* cx, id, and flags are the parameters initially passed to the ongoing lookup;
* objp and propp are its out parameters. obj is an object along the prototype
* chain from where the lookup started.
*
* There are four possible outcomes:
*
* - On failure, report an error or exception and return false.
*
* - If we are already resolving a property of *curobjp, set *recursedp = true,
* and return true.
*
* - If the resolve hook finds or defines the sought property, set *objp and
* *propp appropriately, set *recursedp = false, and return true.
*
* - Otherwise no property was resolved. Set *propp = nullptr and
* *recursedp = false and return true.
*/
static MOZ_ALWAYS_INLINE bool
CallResolveOp(JSContext *cx, HandleNativeObject obj, HandleId id, MutableHandleObject objp,
MutableHandleShape propp, bool *recursedp)
{
const Class *clasp = obj->getClass();
JSResolveOp resolve = clasp->resolve;
/*
* Avoid recursion on (obj, id) already being resolved on cx.
*
* Once we have successfully added an entry for (obj, key) to
* cx->resolvingTable, control must go through cleanup: before
* returning. But note that JS_DHASH_ADD may find an existing
* entry, in which case we bail to suppress runaway recursion.
*/
AutoResolving resolving(cx, obj, id);
if (resolving.alreadyStarted()) {
/* Already resolving id in obj -- suppress recursion. */
*recursedp = true;
return true;
}
*recursedp = false;
propp.set(nullptr);
if (clasp->flags & JSCLASS_NEW_RESOLVE) {
JSNewResolveOp newresolve = reinterpret_cast<JSNewResolveOp>(resolve);
RootedObject obj2(cx, nullptr);
if (!newresolve(cx, obj, id, &obj2))
return false;
/*
* We trust the new style resolve hook to set obj2 to nullptr when
* the id cannot be resolved. But, when obj2 is not null, we do
* not assume that id must exist and do full nativeLookup for
* compatibility.
*/
if (!obj2)
return true;
if (!obj2->isNative()) {
/* Whoops, newresolve handed back a foreign obj2. */
MOZ_ASSERT(obj2 != obj);
return JSObject::lookupGeneric(cx, obj2, id, objp, propp);
}
objp.set(obj2);
} else {
if (!resolve(cx, obj, id))
return false;
objp.set(obj);
}
NativeObject *nobjp = &objp->as<NativeObject>();
if (JSID_IS_INT(id) && nobjp->containsDenseElement(JSID_TO_INT(id))) {
MarkDenseOrTypedArrayElementFound<CanGC>(propp);
return true;
}
Shape *shape;
if (!nobjp->empty() && (shape = nobjp->lookup(cx, id)))
propp.set(shape);
else
objp.set(nullptr);
return true;
}
template <AllowGC allowGC>
static MOZ_ALWAYS_INLINE bool
LookupOwnPropertyInline(ExclusiveContext *cx,
typename MaybeRooted<NativeObject*, allowGC>::HandleType obj,
typename MaybeRooted<jsid, allowGC>::HandleType id,
typename MaybeRooted<JSObject*, allowGC>::MutableHandleType objp,
typename MaybeRooted<Shape*, allowGC>::MutableHandleType propp,
bool *donep)
{
// Check for a native dense element.
if (JSID_IS_INT(id) && obj->containsDenseElement(JSID_TO_INT(id))) {
objp.set(obj);
MarkDenseOrTypedArrayElementFound<allowGC>(propp);
*donep = true;
return true;
}
// Check for a typed array element. Integer lookups always finish here
// so that integer properties on the prototype are ignored even for out
// of bounds accesses.
if (IsAnyTypedArray(obj)) {
uint64_t index;
if (IsTypedArrayIndex(id, &index)) {
if (index < AnyTypedArrayLength(obj)) {
objp.set(obj);
MarkDenseOrTypedArrayElementFound<allowGC>(propp);
} else {
objp.set(nullptr);
propp.set(nullptr);
}
*donep = true;
return true;
}
}
// Check for a native property.
if (Shape *shape = obj->lookup(cx, id)) {
objp.set(obj);
propp.set(shape);
*donep = true;
return true;
}
// id was not found in obj. Try obj's resolve hook, if any.
if (obj->getClass()->resolve != JS_ResolveStub) {
if (!cx->shouldBeJSContext() || !allowGC)
return false;
bool recursed;
if (!CallResolveOp(cx->asJSContext(),
MaybeRooted<NativeObject*, allowGC>::toHandle(obj),
MaybeRooted<jsid, allowGC>::toHandle(id),
MaybeRooted<JSObject*, allowGC>::toMutableHandle(objp),
MaybeRooted<Shape*, allowGC>::toMutableHandle(propp),
&recursed))
{
return false;
}
if (recursed) {
objp.set(nullptr);
propp.set(nullptr);
*donep = true;
return true;
}
if (propp) {
*donep = true;
return true;
}
}
*donep = false;
return true;
}
template <AllowGC allowGC>
static MOZ_ALWAYS_INLINE bool
LookupPropertyInline(ExclusiveContext *cx,
typename MaybeRooted<NativeObject*, allowGC>::HandleType obj,
typename MaybeRooted<jsid, allowGC>::HandleType id,
typename MaybeRooted<JSObject*, allowGC>::MutableHandleType objp,
typename MaybeRooted<Shape*, allowGC>::MutableHandleType propp)
{
/* NB: The logic of this procedure is implicitly reflected in
* BaselineIC.cpp's |EffectlesslyLookupProperty| logic.
* If this changes, please remember to update the logic there as well.
*/
/* Search scopes starting with obj and following the prototype link. */
typename MaybeRooted<NativeObject*, allowGC>::RootType current(cx, obj);
while (true) {
bool done;
if (!LookupOwnPropertyInline<allowGC>(cx, current, id, objp, propp, &done))
return false;
if (done)
return true;
typename MaybeRooted<JSObject*, allowGC>::RootType proto(cx, current->getProto());
if (!proto)
break;
if (!proto->isNative()) {
if (!cx->shouldBeJSContext() || !allowGC)
return false;
return JSObject::lookupGeneric(cx->asJSContext(),
MaybeRooted<JSObject*, allowGC>::toHandle(proto),
MaybeRooted<jsid, allowGC>::toHandle(id),
MaybeRooted<JSObject*, allowGC>::toMutableHandle(objp),
MaybeRooted<Shape*, allowGC>::toMutableHandle(propp));
}
current = &proto->template as<NativeObject>();
}
objp.set(nullptr);
propp.set(nullptr);
return true;
}
inline bool
DefineNativeProperty(ExclusiveContext *cx, HandleNativeObject obj,
PropertyName *name, HandleValue value,
PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
{
RootedId id(cx, NameToId(name));
return DefineNativeProperty(cx, obj, id, value, getter, setter, attrs);
}
} // namespace js
inline uint8_t *

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -1319,14 +1319,42 @@ SetAttributes(JSContext *cx, HandleNativeObject obj, HandleId id, unsigned *attr
extern bool
DeleteGeneric(JSContext *cx, HandleNativeObject obj, HandleId id, bool *succeeded);
extern bool
Watch(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject callable);
extern bool
Unwatch(JSContext *cx, JS::HandleObject obj, JS::HandleId id);
} /* namespace js::baseops */
/*
* Return successfully added or changed shape or nullptr on error.
*/
extern bool
DefineNativeProperty(ExclusiveContext *cx, HandleNativeObject obj, HandleId id, HandleValue value,
PropertyOp getter, StrictPropertyOp setter, unsigned attrs);
extern bool
LookupNativeProperty(ExclusiveContext *cx, HandleNativeObject obj, HandleId id,
js::MutableHandleObject objp, js::MutableHandleShape propp);
bool
NativeGet(JSContext *cx, HandleObject obj, HandleNativeObject pobj,
HandleShape shape, MutableHandle<Value> vp);
template <ExecutionMode mode>
bool
NativeSet(typename ExecutionModeTraits<mode>::ContextType cx,
HandleNativeObject obj, HandleObject receiver,
HandleShape shape, bool strict, MutableHandleValue vp);
/*
* If obj has an already-resolved data property for id, return true and
* store the property value in *vp.
*/
extern bool
HasDataProperty(JSContext *cx, NativeObject *obj, jsid id, Value *vp);
inline bool
HasDataProperty(JSContext *cx, NativeObject *obj, PropertyName *name, Value *vp)
{
return HasDataProperty(cx, obj, NameToId(name), vp);
}
} /* namespace js */
inline void *