зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1073842 - Move NativeObject manipulating methods into more appropriate files, sr=luke.
This commit is contained in:
Родитель
27ac5db9f7
Коммит
13d0a4b214
|
@ -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;
|
||||
|
|
2304
js/src/jsobj.cpp
2304
js/src/jsobj.cpp
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -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 *
|
||||
|
|
Загрузка…
Ссылка в новой задаче