зеркало из https://github.com/mozilla/gecko-dev.git
bug 627016 - remove JSProperty out param from DefineNativeProperty. r=jorendorff
--HG-- extra : rebase_source : 673c7471fc963cb59d11ab667bd9e8523297617a
This commit is contained in:
Родитель
9f083caecc
Коммит
e5076b0e39
|
@ -3257,7 +3257,7 @@ JS_LookupPropertyWithFlagsById(JSContext *cx, JSObject *obj, jsid id, uintN flag
|
|||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, obj, id);
|
||||
ok = obj->isNative()
|
||||
? js_LookupPropertyWithFlags(cx, obj, id, flags, objp, &prop) >= 0
|
||||
? LookupPropertyWithFlags(cx, obj, id, flags, objp, &prop)
|
||||
: obj->lookupProperty(cx, id, objp, &prop);
|
||||
return ok && LookupResult(cx, obj, *objp, id, prop, Valueify(vp));
|
||||
}
|
||||
|
@ -3360,8 +3360,8 @@ DefinePropertyById(JSContext *cx, JSObject *obj, jsid id, const Value &value,
|
|||
|
||||
JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED | JSRESOLVE_DECLARING);
|
||||
if (flags != 0 && obj->isNative()) {
|
||||
return !!js_DefineNativeProperty(cx, obj, id, value, getter, setter,
|
||||
attrs, flags, tinyid, NULL);
|
||||
return !!DefineNativeProperty(cx, obj, id, value, getter, setter,
|
||||
attrs, flags, tinyid);
|
||||
}
|
||||
return obj->defineProperty(cx, id, value, getter, setter, attrs);
|
||||
}
|
||||
|
|
|
@ -800,8 +800,7 @@ array_getProperty(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id, Val
|
|||
}
|
||||
|
||||
vp->setUndefined();
|
||||
if (js_LookupPropertyWithFlags(cx, proto, id, cx->resolveFlags,
|
||||
&obj2, &prop) < 0)
|
||||
if (!LookupPropertyWithFlags(cx, proto, id, cx->resolveFlags, &obj2, &prop))
|
||||
return JS_FALSE;
|
||||
|
||||
if (prop && obj2->isNative()) {
|
||||
|
|
|
@ -252,7 +252,7 @@ HasProperty(JSContext* cx, JSObject* obj, jsid id)
|
|||
|
||||
JSObject* obj2;
|
||||
JSProperty* prop;
|
||||
if (js_LookupPropertyWithFlags(cx, obj, id, JSRESOLVE_QUALIFIED, &obj2, &prop) < 0)
|
||||
if (!LookupPropertyWithFlags(cx, obj, id, JSRESOLVE_QUALIFIED, &obj2, &prop))
|
||||
return JS_NEITHER;
|
||||
return prop != NULL;
|
||||
}
|
||||
|
|
|
@ -1099,11 +1099,10 @@ JS_SetWatchPoint(JSContext *cx, JSObject *obj, jsid id,
|
|||
JSWatchPoint *wp = FindWatchPoint(rt, obj, propid);
|
||||
if (!wp) {
|
||||
/* Make a new property in obj so we can watch for the first set. */
|
||||
if (!js_DefineNativeProperty(cx, obj, propid, UndefinedValue(), NULL, NULL,
|
||||
JSPROP_ENUMERATE, 0, 0, &prop)) {
|
||||
shape = DefineNativeProperty(cx, obj, propid, UndefinedValue(), NULL, NULL,
|
||||
JSPROP_ENUMERATE, 0, 0);
|
||||
if (!shape)
|
||||
return false;
|
||||
}
|
||||
shape = (Shape *) prop;
|
||||
}
|
||||
} else if (pobj != obj) {
|
||||
/* Clone the prototype property so we can watch the right object. */
|
||||
|
@ -1141,12 +1140,10 @@ JS_SetWatchPoint(JSContext *cx, JSObject *obj, jsid id,
|
|||
}
|
||||
|
||||
/* Recall that obj is native, whether or not pobj is native. */
|
||||
if (!js_DefineNativeProperty(cx, obj, propid, valroot.value(),
|
||||
getter, setter, attrs, flags,
|
||||
shortid, &prop)) {
|
||||
shape = DefineNativeProperty(cx, obj, propid, valroot.value(), getter, setter,
|
||||
attrs, flags, shortid);
|
||||
if (!shape)
|
||||
return false;
|
||||
}
|
||||
shape = (Shape *) prop;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -4487,10 +4487,10 @@ JSParseNode::getConstantValue(JSContext *cx, bool strictChecks, Value *vp)
|
|||
JS_ASSERT(pnid->pn_type == TOK_NAME ||
|
||||
pnid->pn_type == TOK_STRING);
|
||||
jsid id = ATOM_TO_JSID(pnid->pn_atom);
|
||||
if (!((pnid->pn_atom == cx->runtime->atomState.protoAtom)
|
||||
? js_SetPropertyHelper(cx, obj, id, 0, &value, strictChecks)
|
||||
: js_DefineNativeProperty(cx, obj, id, value, NULL, NULL,
|
||||
JSPROP_ENUMERATE, 0, 0, NULL, 0))) {
|
||||
if ((pnid->pn_atom == cx->runtime->atomState.protoAtom)
|
||||
? !js_SetPropertyHelper(cx, obj, id, 0, &value, strictChecks)
|
||||
: !DefineNativeProperty(cx, obj, id, value, NULL, NULL,
|
||||
JSPROP_ENUMERATE, 0, 0)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -6988,10 +6988,10 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
|
|||
|
||||
if (obj) {
|
||||
JS_ASSERT(!obj->inDictionaryMode());
|
||||
if (!js_DefineNativeProperty(cx, obj, ATOM_TO_JSID(pn3->pn_atom),
|
||||
UndefinedValue(), NULL, NULL,
|
||||
JSPROP_ENUMERATE, 0, 0, NULL)) {
|
||||
return JS_FALSE;
|
||||
if (!DefineNativeProperty(cx, obj, ATOM_TO_JSID(pn3->pn_atom),
|
||||
UndefinedValue(), NULL, NULL,
|
||||
JSPROP_ENUMERATE, 0, 0)) {
|
||||
return false;
|
||||
}
|
||||
if (obj->inDictionaryMode())
|
||||
obj = NULL;
|
||||
|
|
|
@ -1043,18 +1043,14 @@ js_InitExceptionClasses(JSContext *cx, JSObject *obj)
|
|||
|
||||
/* Add properties to the prototype. */
|
||||
JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED | JSRESOLVE_DECLARING);
|
||||
if (!js_DefineNativeProperty(cx, proto, nameId, StringValue(atom),
|
||||
PropertyStub, StrictPropertyStub,
|
||||
0, 0, 0, NULL) ||
|
||||
!js_DefineNativeProperty(cx, proto, messageId, empty,
|
||||
PropertyStub, StrictPropertyStub,
|
||||
0, 0, 0, NULL) ||
|
||||
!js_DefineNativeProperty(cx, proto, fileNameId, empty,
|
||||
PropertyStub, StrictPropertyStub,
|
||||
JSPROP_ENUMERATE, 0, 0, NULL) ||
|
||||
!js_DefineNativeProperty(cx, proto, lineNumberId, Valueify(JSVAL_ZERO),
|
||||
PropertyStub, StrictPropertyStub,
|
||||
JSPROP_ENUMERATE, 0, 0, NULL)) {
|
||||
if (!DefineNativeProperty(cx, proto, nameId, StringValue(atom),
|
||||
PropertyStub, StrictPropertyStub, 0, 0, 0) ||
|
||||
!DefineNativeProperty(cx, proto, messageId, empty,
|
||||
PropertyStub, StrictPropertyStub, 0, 0, 0) ||
|
||||
!DefineNativeProperty(cx, proto, fileNameId, empty,
|
||||
PropertyStub, StrictPropertyStub, JSPROP_ENUMERATE, 0, 0) ||
|
||||
!DefineNativeProperty(cx, proto, lineNumberId, Valueify(JSVAL_ZERO),
|
||||
PropertyStub, StrictPropertyStub, JSPROP_ENUMERATE, 0, 0)) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1036,11 +1036,9 @@ CreateFunCallObject(JSContext *cx, StackFrame *fp)
|
|||
if (!scopeChain)
|
||||
return NULL;
|
||||
|
||||
if (!js_DefineNativeProperty(cx, scopeChain, ATOM_TO_JSID(lambdaName),
|
||||
ObjectValue(fp->callee()),
|
||||
CalleeGetter, NULL,
|
||||
JSPROP_PERMANENT | JSPROP_READONLY,
|
||||
0, 0, NULL)) {
|
||||
if (!DefineNativeProperty(cx, scopeChain, ATOM_TO_JSID(lambdaName),
|
||||
ObjectValue(fp->callee()), CalleeGetter, NULL,
|
||||
JSPROP_PERMANENT | JSPROP_READONLY, 0, 0)) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -1368,10 +1366,10 @@ call_resolve(JSContext *cx, JSObject *obj, jsid id, uintN flags,
|
|||
* rebinding-Call-property logic.
|
||||
*/
|
||||
if (callee && id == ATOM_TO_JSID(cx->runtime->atomState.argumentsAtom)) {
|
||||
if (!js_DefineNativeProperty(cx, obj, id, UndefinedValue(),
|
||||
GetCallArguments, SetCallArguments,
|
||||
JSPROP_PERMANENT | JSPROP_SHARED | JSPROP_ENUMERATE,
|
||||
0, 0, NULL, JSDNP_DONT_PURGE)) {
|
||||
if (!DefineNativeProperty(cx, obj, id, UndefinedValue(),
|
||||
GetCallArguments, SetCallArguments,
|
||||
JSPROP_PERMANENT | JSPROP_SHARED | JSPROP_ENUMERATE,
|
||||
0, 0, DNP_DONT_PURGE)) {
|
||||
return false;
|
||||
}
|
||||
*objp = obj;
|
||||
|
@ -1790,9 +1788,9 @@ fun_resolve(JSContext *cx, JSObject *obj, jsid id, uintN flags,
|
|||
|
||||
if (JSID_IS_ATOM(id, cx->runtime->atomState.lengthAtom)) {
|
||||
JS_ASSERT(!IsInternalFunctionObject(obj));
|
||||
if (!js_DefineNativeProperty(cx, obj, id, Int32Value(fun->nargs),
|
||||
PropertyStub, StrictPropertyStub,
|
||||
JSPROP_PERMANENT | JSPROP_READONLY, 0, 0, NULL)) {
|
||||
if (!DefineNativeProperty(cx, obj, id, Int32Value(fun->nargs),
|
||||
PropertyStub, StrictPropertyStub,
|
||||
JSPROP_PERMANENT | JSPROP_READONLY, 0, 0)) {
|
||||
return false;
|
||||
}
|
||||
*objp = obj;
|
||||
|
@ -1804,11 +1802,9 @@ fun_resolve(JSContext *cx, JSObject *obj, jsid id, uintN flags,
|
|||
|
||||
if (JSID_IS_ATOM(id, OFFSET_TO_ATOM(cx->runtime, lfp->atomOffset))) {
|
||||
JS_ASSERT(!IsInternalFunctionObject(obj));
|
||||
|
||||
if (!js_DefineNativeProperty(cx, obj, id, UndefinedValue(),
|
||||
fun_getProperty, StrictPropertyStub,
|
||||
lfp->attrs, Shape::HAS_SHORTID,
|
||||
lfp->tinyid, NULL)) {
|
||||
if (!DefineNativeProperty(cx, obj, id, UndefinedValue(),
|
||||
fun_getProperty, StrictPropertyStub,
|
||||
lfp->attrs, Shape::HAS_SHORTID, lfp->tinyid)) {
|
||||
return false;
|
||||
}
|
||||
*objp = obj;
|
||||
|
@ -1836,10 +1832,8 @@ fun_resolve(JSContext *cx, JSObject *obj, jsid id, uintN flags,
|
|||
setter = StrictPropertyStub;
|
||||
}
|
||||
|
||||
if (!js_DefineNativeProperty(cx, obj, id, UndefinedValue(),
|
||||
getter, setter,
|
||||
attrs, Shape::HAS_SHORTID,
|
||||
p.tinyid, NULL)) {
|
||||
if (!DefineNativeProperty(cx, obj, id, UndefinedValue(), getter, setter,
|
||||
attrs, Shape::HAS_SHORTID, p.tinyid)) {
|
||||
return false;
|
||||
}
|
||||
*objp = obj;
|
||||
|
|
|
@ -2138,7 +2138,7 @@ Interpret(JSContext *cx, StackFrame *entryFrame, uintN inlineCallCount, InterpMo
|
|||
#ifdef MOZ_TRACEVIS
|
||||
TraceVisStateObj tvso(cx, S_INTERP);
|
||||
#endif
|
||||
JSAutoResolveFlags rf(cx, JSRESOLVE_INFER);
|
||||
JSAutoResolveFlags rf(cx, RESOLVE_INFER);
|
||||
|
||||
# ifdef DEBUG
|
||||
/*
|
||||
|
@ -4361,11 +4361,11 @@ BEGIN_CASE(JSOP_SETMETHOD)
|
|||
if (entry && JS_LIKELY(!obj->getOps()->setProperty)) {
|
||||
uintN defineHow;
|
||||
if (op == JSOP_SETMETHOD)
|
||||
defineHow = JSDNP_CACHE_RESULT | JSDNP_SET_METHOD;
|
||||
defineHow = DNP_CACHE_RESULT | DNP_SET_METHOD;
|
||||
else if (op == JSOP_SETNAME)
|
||||
defineHow = JSDNP_CACHE_RESULT | JSDNP_UNQUALIFIED;
|
||||
defineHow = DNP_CACHE_RESULT | DNP_UNQUALIFIED;
|
||||
else
|
||||
defineHow = JSDNP_CACHE_RESULT;
|
||||
defineHow = DNP_CACHE_RESULT;
|
||||
if (!js_SetPropertyHelper(cx, obj, id, defineHow, &rval, script->strictModeCode))
|
||||
goto error;
|
||||
} else {
|
||||
|
@ -5244,8 +5244,8 @@ BEGIN_CASE(JSOP_DEFVAR)
|
|||
|
||||
/* Bind a variable only if it's not yet defined. */
|
||||
if (shouldDefine &&
|
||||
!js_DefineNativeProperty(cx, obj, id, UndefinedValue(),
|
||||
PropertyStub, StrictPropertyStub, attrs, 0, 0, NULL)) {
|
||||
!DefineNativeProperty(cx, obj, id, UndefinedValue(), PropertyStub, StrictPropertyStub,
|
||||
attrs, 0, 0)) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
@ -5850,13 +5850,12 @@ BEGIN_CASE(JSOP_INITMETHOD)
|
|||
jsid id = ATOM_TO_JSID(atom);
|
||||
|
||||
uintN defineHow = (op == JSOP_INITMETHOD)
|
||||
? JSDNP_CACHE_RESULT | JSDNP_SET_METHOD
|
||||
: JSDNP_CACHE_RESULT;
|
||||
if (!(JS_UNLIKELY(atom == cx->runtime->atomState.protoAtom)
|
||||
? js_SetPropertyHelper(cx, obj, id, defineHow, &rval, script->strictModeCode)
|
||||
: js_DefineNativeProperty(cx, obj, id, rval, NULL, NULL,
|
||||
JSPROP_ENUMERATE, 0, 0, NULL,
|
||||
defineHow))) {
|
||||
? DNP_CACHE_RESULT | DNP_SET_METHOD
|
||||
: DNP_CACHE_RESULT;
|
||||
if (JS_UNLIKELY(atom == cx->runtime->atomState.protoAtom)
|
||||
? !js_SetPropertyHelper(cx, obj, id, defineHow, &rval, script->strictModeCode)
|
||||
: !DefineNativeProperty(cx, obj, id, rval, NULL, NULL,
|
||||
JSPROP_ENUMERATE, 0, 0, defineHow)) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
|
231
js/src/jsobj.cpp
231
js/src/jsobj.cpp
|
@ -3119,7 +3119,7 @@ with_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
|
|||
{
|
||||
/* Fixes bug 463997 */
|
||||
uintN flags = cx->resolveFlags;
|
||||
if (flags == JSRESOLVE_INFER)
|
||||
if (flags == RESOLVE_INFER)
|
||||
flags = js_InferFlags(cx, flags);
|
||||
flags |= JSRESOLVE_WITH;
|
||||
JSAutoResolveFlags rf(cx, flags);
|
||||
|
@ -4263,19 +4263,19 @@ js_FindClassObject(JSContext *cx, JSObject *start, JSProtoKey protoKey,
|
|||
obj = cx->globalObject;
|
||||
if (!obj) {
|
||||
vp->setUndefined();
|
||||
return JS_TRUE;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
OBJ_TO_INNER_OBJECT(cx, obj);
|
||||
if (!obj)
|
||||
return JS_FALSE;
|
||||
return false;
|
||||
|
||||
if (protoKey != JSProto_Null) {
|
||||
JS_ASSERT(JSProto_Null < protoKey);
|
||||
JS_ASSERT(protoKey < JSProto_LIMIT);
|
||||
if (!js_GetClassObject(cx, obj, protoKey, &cobj))
|
||||
return JS_FALSE;
|
||||
return false;
|
||||
if (cobj) {
|
||||
vp->setObject(*cobj);
|
||||
return JS_TRUE;
|
||||
|
@ -4289,10 +4289,8 @@ js_FindClassObject(JSContext *cx, JSObject *start, JSProtoKey protoKey,
|
|||
}
|
||||
|
||||
JS_ASSERT(obj->isNative());
|
||||
if (js_LookupPropertyWithFlags(cx, obj, id, JSRESOLVE_CLASSNAME,
|
||||
&pobj, &prop) < 0) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
if (!LookupPropertyWithFlags(cx, obj, id, JSRESOLVE_CLASSNAME, &pobj, &prop))
|
||||
return false;
|
||||
Value v = UndefinedValue();
|
||||
if (prop && pobj->isNative()) {
|
||||
shape = (Shape *) prop;
|
||||
|
@ -4303,7 +4301,7 @@ js_FindClassObject(JSContext *cx, JSObject *start, JSProtoKey protoKey,
|
|||
}
|
||||
}
|
||||
*vp = v;
|
||||
return JS_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
JSObject *
|
||||
|
@ -4618,8 +4616,7 @@ JSBool
|
|||
js_DefineProperty(JSContext *cx, JSObject *obj, jsid id, const Value *value,
|
||||
PropertyOp getter, StrictPropertyOp setter, uintN attrs)
|
||||
{
|
||||
return js_DefineNativeProperty(cx, obj, id, *value, getter, setter, attrs,
|
||||
0, 0, NULL);
|
||||
return !!DefineNativeProperty(cx, obj, id, *value, getter, setter, attrs, 0, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -4644,13 +4641,14 @@ CallAddPropertyHook(JSContext *cx, Class *clasp, JSObject *obj, const Shape *sha
|
|||
return true;
|
||||
}
|
||||
|
||||
JSBool
|
||||
js_DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, const Value &value,
|
||||
PropertyOp getter, StrictPropertyOp setter, uintN attrs,
|
||||
uintN flags, intN shortid, JSProperty **propp,
|
||||
uintN defineHow /* = 0 */)
|
||||
namespace js {
|
||||
|
||||
const Shape *
|
||||
DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, const Value &value,
|
||||
PropertyOp getter, StrictPropertyOp setter, uintN attrs,
|
||||
uintN flags, intN shortid, uintN defineHow /* = 0 */)
|
||||
{
|
||||
JS_ASSERT((defineHow & ~(JSDNP_CACHE_RESULT | JSDNP_DONT_PURGE | JSDNP_SET_METHOD)) == 0);
|
||||
JS_ASSERT((defineHow & ~(DNP_CACHE_RESULT | DNP_DONT_PURGE | DNP_SET_METHOD)) == 0);
|
||||
LeaveTraceIfGlobalObject(cx, obj);
|
||||
|
||||
/* Convert string indices to integers if appropriate. */
|
||||
|
@ -4667,31 +4665,28 @@ js_DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, const Value &valu
|
|||
JSProperty *prop;
|
||||
|
||||
/*
|
||||
* If JS_THREADSAFE and id is found, js_LookupProperty returns with
|
||||
* shape non-null and pobj locked. If pobj == obj, the property is
|
||||
* already in obj and obj has its own (mutable) scope. So if we are
|
||||
* defining a getter whose setter was already defined, or vice versa,
|
||||
* finish the job via obj->changeProperty, and refresh the property
|
||||
* cache line for (obj, id) to map shape.
|
||||
* If we are defining a getter whose setter was already defined, or
|
||||
* vice versa, finish the job via obj->changeProperty, and refresh the
|
||||
* property cache line for (obj, id) to map shape.
|
||||
*/
|
||||
if (!js_LookupProperty(cx, obj, id, &pobj, &prop))
|
||||
return JS_FALSE;
|
||||
shape = (Shape *) prop;
|
||||
if (shape && pobj == obj && shape->isAccessorDescriptor()) {
|
||||
shape = obj->changeProperty(cx, shape, attrs,
|
||||
JSPROP_GETTER | JSPROP_SETTER,
|
||||
(attrs & JSPROP_GETTER)
|
||||
? getter
|
||||
: shape->getter(),
|
||||
(attrs & JSPROP_SETTER)
|
||||
? setter
|
||||
: shape->setter());
|
||||
|
||||
if (!shape)
|
||||
return false;
|
||||
} else if (prop) {
|
||||
prop = NULL;
|
||||
shape = NULL;
|
||||
return NULL;
|
||||
if (prop && pobj == obj) {
|
||||
shape = (const Shape *) prop;
|
||||
if (shape->isAccessorDescriptor()) {
|
||||
shape = obj->changeProperty(cx, shape, attrs,
|
||||
JSPROP_GETTER | JSPROP_SETTER,
|
||||
(attrs & JSPROP_GETTER)
|
||||
? getter
|
||||
: shape->getter(),
|
||||
(attrs & JSPROP_SETTER)
|
||||
? setter
|
||||
: shape->setter());
|
||||
if (!shape)
|
||||
return NULL;
|
||||
} else {
|
||||
shape = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4700,7 +4695,7 @@ js_DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, const Value &valu
|
|||
* to be shadowed in obj's scope chain unless it is known a priori that it
|
||||
* is not possible. We do this before locking obj to avoid nesting locks.
|
||||
*/
|
||||
if (!(defineHow & JSDNP_DONT_PURGE))
|
||||
if (!(defineHow & DNP_DONT_PURGE))
|
||||
js_PurgeScopeChain(cx, obj, id);
|
||||
|
||||
/*
|
||||
|
@ -4713,7 +4708,7 @@ js_DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, const Value &valu
|
|||
|
||||
/* Use the object's class getter and setter by default. */
|
||||
Class *clasp = obj->getClass();
|
||||
if (!(defineHow & JSDNP_SET_METHOD)) {
|
||||
if (!(defineHow & DNP_SET_METHOD)) {
|
||||
if (!getter && !(attrs & JSPROP_GETTER))
|
||||
getter = clasp->getProperty;
|
||||
if (!setter && !(attrs & JSPROP_SETTER))
|
||||
|
@ -4722,7 +4717,7 @@ js_DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, const Value &valu
|
|||
|
||||
/* Get obj's own scope if it has one, or create a new one for obj. */
|
||||
if (!obj->ensureClassReservedSlots(cx))
|
||||
return false;
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Make a local copy of value, in case a method barrier needs to update the
|
||||
|
@ -4733,7 +4728,7 @@ js_DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, const Value &valu
|
|||
|
||||
if (!shape) {
|
||||
/* Add a new property, or replace an existing one of the same id. */
|
||||
if (defineHow & JSDNP_SET_METHOD) {
|
||||
if (defineHow & DNP_SET_METHOD) {
|
||||
JS_ASSERT(clasp == &js_ObjectClass);
|
||||
JS_ASSERT(IsFunctionObject(value));
|
||||
JS_ASSERT(!(attrs & (JSPROP_GETTER | JSPROP_SETTER)));
|
||||
|
@ -4767,7 +4762,7 @@ js_DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, const Value &valu
|
|||
JS_ASSERT(existingShape->getter() != getter);
|
||||
|
||||
if (!obj->methodReadBarrier(cx, *existingShape, &valueCopy))
|
||||
return false;
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
adding = true;
|
||||
|
@ -4777,7 +4772,7 @@ js_DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, const Value &valu
|
|||
shape = obj->putProperty(cx, id, getter, setter, SHAPE_INVALID_SLOT,
|
||||
attrs, flags, shortid);
|
||||
if (!shape)
|
||||
return false;
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* If shape is a joined method, the above call to putProperty suffices
|
||||
|
@ -4803,28 +4798,26 @@ js_DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, const Value &valu
|
|||
/* XXXbe called with lock held */
|
||||
if (!CallAddPropertyHook(cx, clasp, obj, shape, &valueCopy)) {
|
||||
obj->removeProperty(cx, id);
|
||||
return false;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (defineHow & JSDNP_CACHE_RESULT) {
|
||||
if (defineHow & DNP_CACHE_RESULT) {
|
||||
JS_ASSERT_NOT_ON_TRACE(cx);
|
||||
if (adding) {
|
||||
JS_PROPERTY_CACHE(cx).fill(cx, obj, 0, 0, obj, shape, true);
|
||||
JS_PROPERTY_CACHE(cx).fill(cx, obj, 0, obj, shape, true);
|
||||
TRACE_1(AddProperty, obj);
|
||||
}
|
||||
}
|
||||
if (propp)
|
||||
*propp = (JSProperty *) shape;
|
||||
return true;
|
||||
return shape;
|
||||
|
||||
#ifdef JS_TRACER
|
||||
error: // TRACE_1 jumps here on error.
|
||||
error:
|
||||
/* TRACE_1 jumps here on error. */
|
||||
return NULL;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
#define SCOPE_DEPTH_ACCUM(bs,val) \
|
||||
JS_SCOPE_DEPTH_METERING(JS_BASIC_STATS_ACCUM(bs, val))
|
||||
} /* namespace js */
|
||||
|
||||
/*
|
||||
* Call obj's resolve hook.
|
||||
|
@ -4873,7 +4866,7 @@ CallResolveOp(JSContext *cx, JSObject *start, JSObject *obj, jsid id, uintN flag
|
|||
|
||||
if (clasp->flags & JSCLASS_NEW_RESOLVE) {
|
||||
JSNewResolveOp newresolve = reinterpret_cast<JSNewResolveOp>(resolve);
|
||||
if (flags == JSRESOLVE_INFER)
|
||||
if (flags == RESOLVE_INFER)
|
||||
flags = js_InferFlags(cx, 0);
|
||||
JSObject *obj2 = (clasp->flags & JSCLASS_NEW_RESOLVE_GETS_START) ? start : NULL;
|
||||
if (!newresolve(cx, obj, id, flags, &obj2))
|
||||
|
@ -4909,39 +4902,43 @@ CallResolveOp(JSContext *cx, JSObject *start, JSObject *obj, jsid id, uintN flag
|
|||
return true;
|
||||
}
|
||||
|
||||
static JS_ALWAYS_INLINE int
|
||||
js_LookupPropertyWithFlagsInline(JSContext *cx, JSObject *obj, jsid id, uintN flags,
|
||||
JSObject **objp, JSProperty **propp)
|
||||
#define SCOPE_DEPTH_ACCUM(bs,val) JS_SCOPE_DEPTH_METERING(JS_BASIC_STATS_ACCUM(bs, val))
|
||||
|
||||
static JS_ALWAYS_INLINE bool
|
||||
LookupPropertyWithFlagsInline(JSContext *cx, JSObject *obj, jsid id, uintN flags,
|
||||
JSObject **objp, JSProperty **propp)
|
||||
{
|
||||
/* We should not get string indices which aren't already integers here. */
|
||||
JS_ASSERT(id == js_CheckForStringIndex(id));
|
||||
|
||||
/* Search scopes starting with obj and following the prototype link. */
|
||||
JSObject *start = obj;
|
||||
int protoIndex;
|
||||
for (protoIndex = 0; ; protoIndex++) {
|
||||
#ifdef JS_SCOPE_DEPTH_METER
|
||||
int protoIndex = 0;
|
||||
#endif
|
||||
for (; ; JS_SCOPE_DEPTH_METERING(protoIndex++)) {
|
||||
const Shape *shape = obj->nativeLookup(id);
|
||||
if (shape) {
|
||||
SCOPE_DEPTH_ACCUM(&cx->runtime->protoLookupDepthStats, protoIndex);
|
||||
*objp = obj;
|
||||
*propp = (JSProperty *) shape;
|
||||
return protoIndex;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Try obj's class resolve hook if id was not found in obj's scope. */
|
||||
if (!shape && obj->getClass()->resolve != JS_ResolveStub) {
|
||||
if (obj->getClass()->resolve != JS_ResolveStub) {
|
||||
bool recursed;
|
||||
if (!CallResolveOp(cx, start, obj, id, flags, objp, propp, &recursed))
|
||||
return -1;
|
||||
return false;
|
||||
if (recursed)
|
||||
break;
|
||||
if (*propp) {
|
||||
/* Recalculate protoIndex in case it was resolved on some other object. */
|
||||
protoIndex = 0;
|
||||
for (JSObject *proto = start; proto && proto != *objp; proto = proto->getProto())
|
||||
protoIndex++;
|
||||
/*
|
||||
* For stats we do not recalculate protoIndex even if it was
|
||||
* resolved on some other object.
|
||||
*/
|
||||
SCOPE_DEPTH_ACCUM(&cx->runtime->protoLookupDepthStats, protoIndex);
|
||||
return protoIndex;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4950,7 +4947,7 @@ js_LookupPropertyWithFlagsInline(JSContext *cx, JSObject *obj, jsid id, uintN fl
|
|||
break;
|
||||
if (!proto->isNative()) {
|
||||
if (!proto->lookupProperty(cx, id, objp, propp))
|
||||
return -1;
|
||||
return false;
|
||||
#ifdef DEBUG
|
||||
/*
|
||||
* Non-native objects must have either non-native lookup results,
|
||||
|
@ -4966,7 +4963,7 @@ js_LookupPropertyWithFlagsInline(JSContext *cx, JSObject *obj, jsid id, uintN fl
|
|||
JS_ASSERT(proto);
|
||||
}
|
||||
#endif
|
||||
return protoIndex + 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
obj = proto;
|
||||
|
@ -4974,7 +4971,7 @@ js_LookupPropertyWithFlagsInline(JSContext *cx, JSObject *obj, jsid id, uintN fl
|
|||
|
||||
*objp = NULL;
|
||||
*propp = NULL;
|
||||
return protoIndex;
|
||||
return true;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSBool)
|
||||
|
@ -4984,26 +4981,30 @@ js_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
|
|||
/* Convert string indices to integers if appropriate. */
|
||||
id = js_CheckForStringIndex(id);
|
||||
|
||||
return js_LookupPropertyWithFlagsInline(cx, obj, id, cx->resolveFlags, objp, propp) >= 0;
|
||||
return LookupPropertyWithFlagsInline(cx, obj, id, cx->resolveFlags, objp, propp);
|
||||
}
|
||||
|
||||
int
|
||||
js_LookupPropertyWithFlags(JSContext *cx, JSObject *obj, jsid id, uintN flags,
|
||||
JSObject **objp, JSProperty **propp)
|
||||
namespace js {
|
||||
|
||||
bool
|
||||
LookupPropertyWithFlags(JSContext *cx, JSObject *obj, jsid id, uintN flags,
|
||||
JSObject **objp, JSProperty **propp)
|
||||
{
|
||||
/* Convert string indices to integers if appropriate. */
|
||||
id = js_CheckForStringIndex(id);
|
||||
|
||||
return js_LookupPropertyWithFlagsInline(cx, obj, id, flags, objp, propp);
|
||||
return LookupPropertyWithFlagsInline(cx, obj, id, flags, objp, propp);
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
PropertyCacheEntry *
|
||||
js_FindPropertyHelper(JSContext *cx, jsid id, JSBool cacheResult,
|
||||
JSObject **objp, JSObject **pobjp, JSProperty **propp)
|
||||
{
|
||||
JSObject *scopeChain, *obj, *parent, *pobj;
|
||||
PropertyCacheEntry *entry;
|
||||
int scopeIndex, protoIndex;
|
||||
int scopeIndex;
|
||||
JSProperty *prop;
|
||||
|
||||
JS_ASSERT_IF(cacheResult, !JS_ON_TRACE(cx));
|
||||
|
@ -5018,10 +5019,7 @@ js_FindPropertyHelper(JSContext *cx, jsid id, JSBool cacheResult,
|
|||
? IsCacheableNonGlobalScope(obj)
|
||||
: !obj->getOps()->lookupProperty;
|
||||
++scopeIndex) {
|
||||
protoIndex =
|
||||
js_LookupPropertyWithFlags(cx, obj, id, cx->resolveFlags,
|
||||
&pobj, &prop);
|
||||
if (protoIndex < 0)
|
||||
if (!LookupPropertyWithFlags(cx, obj, id, cx->resolveFlags, &pobj, &prop))
|
||||
return NULL;
|
||||
|
||||
if (prop) {
|
||||
|
@ -5032,17 +5030,16 @@ js_FindPropertyHelper(JSContext *cx, jsid id, JSBool cacheResult,
|
|||
JS_ASSERT(pobj->getClass() == clasp);
|
||||
if (clasp == &js_BlockClass) {
|
||||
/*
|
||||
* A block instance on the scope chain is immutable and it
|
||||
* shares its shapes with its compile-time prototype.
|
||||
* A block instance on the scope chain is immutable and
|
||||
* shares its shape with the compile-time prototype. Thus
|
||||
* we cannot find any property on the prototype.
|
||||
*/
|
||||
JS_ASSERT(pobj == obj);
|
||||
JS_ASSERT(pobj->isClonedBlock());
|
||||
JS_ASSERT(protoIndex == 0);
|
||||
} else {
|
||||
/* Call and DeclEnvClass objects have no prototypes. */
|
||||
JS_ASSERT(!obj->getProto());
|
||||
JS_ASSERT(protoIndex == 0);
|
||||
}
|
||||
JS_ASSERT(pobj == obj);
|
||||
} else {
|
||||
JS_ASSERT(obj->isNative());
|
||||
}
|
||||
|
@ -5052,8 +5049,7 @@ js_FindPropertyHelper(JSContext *cx, jsid id, JSBool cacheResult,
|
|||
* non-native prototype.
|
||||
*/
|
||||
if (cacheResult && pobj->isNative()) {
|
||||
entry = JS_PROPERTY_CACHE(cx).fill(cx, scopeChain, scopeIndex,
|
||||
protoIndex, pobj,
|
||||
entry = JS_PROPERTY_CACHE(cx).fill(cx, scopeChain, scopeIndex, pobj,
|
||||
(Shape *) prop);
|
||||
}
|
||||
SCOPE_DEPTH_ACCUM(&cx->runtime->scopeSearchDepthStats, scopeIndex);
|
||||
|
@ -5133,10 +5129,7 @@ js_FindIdentifierBase(JSContext *cx, JSObject *scopeChain, jsid id)
|
|||
scopeIndex++) {
|
||||
JSObject *pobj;
|
||||
JSProperty *prop;
|
||||
int protoIndex = js_LookupPropertyWithFlags(cx, obj, id,
|
||||
cx->resolveFlags,
|
||||
&pobj, &prop);
|
||||
if (protoIndex < 0)
|
||||
if (!LookupPropertyWithFlags(cx, obj, id, cx->resolveFlags, &pobj, &prop))
|
||||
return NULL;
|
||||
if (prop) {
|
||||
if (!pobj->isNative()) {
|
||||
|
@ -5145,8 +5138,7 @@ js_FindIdentifierBase(JSContext *cx, JSObject *scopeChain, jsid id)
|
|||
}
|
||||
JS_ASSERT_IF(obj->getParent(), pobj->getClass() == obj->getClass());
|
||||
DebugOnly<PropertyCacheEntry*> entry =
|
||||
JS_PROPERTY_CACHE(cx).fill(cx, scopeChain, scopeIndex, protoIndex, pobj,
|
||||
(Shape *) prop);
|
||||
JS_PROPERTY_CACHE(cx).fill(cx, scopeChain, scopeIndex, pobj, (Shape *) prop);
|
||||
JS_ASSERT(entry);
|
||||
return obj;
|
||||
}
|
||||
|
@ -5298,7 +5290,6 @@ js_GetPropertyHelperWithShapeInline(JSContext *cx, JSObject *obj, JSObject *rece
|
|||
const Shape **shapeOut, JSObject **holderOut)
|
||||
{
|
||||
JSObject *aobj, *obj2;
|
||||
int protoIndex;
|
||||
JSProperty *prop;
|
||||
const Shape *shape;
|
||||
|
||||
|
@ -5310,11 +5301,9 @@ js_GetPropertyHelperWithShapeInline(JSContext *cx, JSObject *obj, JSObject *rece
|
|||
id = js_CheckForStringIndex(id);
|
||||
|
||||
aobj = js_GetProtoIfDenseArray(obj);
|
||||
/* This call site is hot -- use the always-inlined variant of js_LookupPropertyWithFlags(). */
|
||||
protoIndex = js_LookupPropertyWithFlagsInline(cx, aobj, id, cx->resolveFlags,
|
||||
&obj2, &prop);
|
||||
if (protoIndex < 0)
|
||||
return JS_FALSE;
|
||||
/* This call site is hot -- use the always-inlined variant of LookupPropertyWithFlags(). */
|
||||
if (!LookupPropertyWithFlagsInline(cx, aobj, id, cx->resolveFlags, &obj2, &prop))
|
||||
return false;
|
||||
|
||||
*holderOut = obj2;
|
||||
|
||||
|
@ -5357,7 +5346,7 @@ js_GetPropertyHelperWithShapeInline(JSContext *cx, JSObject *obj, JSObject *rece
|
|||
return JS_TRUE;
|
||||
|
||||
/* Do not warn about tests like (obj[prop] == undefined). */
|
||||
if (cx->resolveFlags == JSRESOLVE_INFER) {
|
||||
if (cx->resolveFlags == RESOLVE_INFER) {
|
||||
LeaveTrace(cx);
|
||||
pc += js_CodeSpec[op].length;
|
||||
if (Detecting(cx, pc))
|
||||
|
@ -5390,7 +5379,7 @@ js_GetPropertyHelperWithShapeInline(JSContext *cx, JSObject *obj, JSObject *rece
|
|||
|
||||
if (getHow & JSGET_CACHE_RESULT) {
|
||||
JS_ASSERT_NOT_ON_TRACE(cx);
|
||||
JS_PROPERTY_CACHE(cx).fill(cx, aobj, 0, protoIndex, obj2, shape);
|
||||
JS_PROPERTY_CACHE(cx).fill(cx, aobj, 0, obj2, shape);
|
||||
}
|
||||
|
||||
/* This call site is hot -- use the always-inlined variant of js_NativeGet(). */
|
||||
|
@ -5436,7 +5425,7 @@ js::GetPropertyDefault(JSContext *cx, JSObject *obj, jsid id, const Value &def,
|
|||
{
|
||||
JSProperty *prop;
|
||||
JSObject *obj2;
|
||||
if (js_LookupPropertyWithFlags(cx, obj, id, JSRESOLVE_QUALIFIED, &obj2, &prop) < 0)
|
||||
if (!LookupPropertyWithFlags(cx, obj, id, JSRESOLVE_QUALIFIED, &obj2, &prop))
|
||||
return false;
|
||||
|
||||
if (!prop) {
|
||||
|
@ -5525,7 +5514,6 @@ JSBool
|
|||
js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uintN defineHow,
|
||||
Value *vp, JSBool strict)
|
||||
{
|
||||
int protoIndex;
|
||||
JSObject *pobj;
|
||||
JSProperty *prop;
|
||||
const Shape *shape;
|
||||
|
@ -5536,18 +5524,15 @@ js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uintN defineHow,
|
|||
StrictPropertyOp setter;
|
||||
bool added;
|
||||
|
||||
JS_ASSERT((defineHow &
|
||||
~(JSDNP_CACHE_RESULT | JSDNP_SET_METHOD | JSDNP_UNQUALIFIED)) == 0);
|
||||
if (defineHow & JSDNP_CACHE_RESULT)
|
||||
JS_ASSERT((defineHow & ~(DNP_CACHE_RESULT | DNP_SET_METHOD | DNP_UNQUALIFIED)) == 0);
|
||||
if (defineHow & DNP_CACHE_RESULT)
|
||||
JS_ASSERT_NOT_ON_TRACE(cx);
|
||||
|
||||
/* Convert string indices to integers if appropriate. */
|
||||
id = js_CheckForStringIndex(id);
|
||||
|
||||
protoIndex = js_LookupPropertyWithFlags(cx, obj, id, cx->resolveFlags,
|
||||
&pobj, &prop);
|
||||
if (protoIndex < 0)
|
||||
return JS_FALSE;
|
||||
if (!LookupPropertyWithFlags(cx, obj, id, cx->resolveFlags, &pobj, &prop))
|
||||
return false;
|
||||
if (prop) {
|
||||
if (!pobj->isNative()) {
|
||||
if (pobj->isProxy()) {
|
||||
|
@ -5576,7 +5561,7 @@ js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uintN defineHow,
|
|||
JS_ASSERT(!obj->isBlock());
|
||||
|
||||
if (!obj->getParent() &&
|
||||
(defineHow & JSDNP_UNQUALIFIED) &&
|
||||
(defineHow & DNP_UNQUALIFIED) &&
|
||||
!js_CheckUndeclaredVarAssignment(cx, JSID_TO_STRING(id))) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
@ -5620,8 +5605,8 @@ js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uintN defineHow,
|
|||
* We found id in a prototype object: prepare to share or shadow.
|
||||
*/
|
||||
if (!shape->shadowable()) {
|
||||
if (defineHow & JSDNP_CACHE_RESULT)
|
||||
JS_PROPERTY_CACHE(cx).fill(cx, obj, 0, protoIndex, pobj, shape);
|
||||
if (defineHow & DNP_CACHE_RESULT)
|
||||
JS_PROPERTY_CACHE(cx).fill(cx, obj, 0, pobj, shape);
|
||||
|
||||
if (shape->hasDefaultSetter() && !shape->hasGetterValue())
|
||||
return JS_TRUE;
|
||||
|
@ -5645,7 +5630,7 @@ js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uintN defineHow,
|
|||
* about to create in obj.
|
||||
*/
|
||||
if (!shape->hasSlot()) {
|
||||
defineHow &= ~JSDNP_SET_METHOD;
|
||||
defineHow &= ~DNP_SET_METHOD;
|
||||
if (shape->hasShortID()) {
|
||||
flags = Shape::HAS_SHORTID;
|
||||
shortid = shape->shortid;
|
||||
|
@ -5668,7 +5653,7 @@ js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uintN defineHow,
|
|||
JS_ASSERT_IF(shape && shape->isMethod(), pobj->hasMethodBarrier());
|
||||
JS_ASSERT_IF(shape && shape->isMethod(),
|
||||
pobj->getSlot(shape->slot).toObject() == shape->methodObject());
|
||||
if (shape && (defineHow & JSDNP_SET_METHOD)) {
|
||||
if (shape && (defineHow & DNP_SET_METHOD)) {
|
||||
/*
|
||||
* JSOP_SETMETHOD is assigning to an existing own property. If it
|
||||
* is an identical method property, do nothing. Otherwise downgrade
|
||||
|
@ -5720,7 +5705,7 @@ js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uintN defineHow,
|
|||
* Check for Object class here to avoid defining a method on a class
|
||||
* with magic resolve, addProperty, getProperty, etc. hooks.
|
||||
*/
|
||||
if ((defineHow & JSDNP_SET_METHOD) && obj->canHaveMethodBarrier()) {
|
||||
if ((defineHow & DNP_SET_METHOD) && obj->canHaveMethodBarrier()) {
|
||||
JS_ASSERT(IsFunctionObject(*vp));
|
||||
JS_ASSERT(!(attrs & (JSPROP_GETTER | JSPROP_SETTER)));
|
||||
|
||||
|
@ -5737,13 +5722,13 @@ js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uintN defineHow,
|
|||
if (!shape)
|
||||
return JS_FALSE;
|
||||
|
||||
if (defineHow & JSDNP_CACHE_RESULT)
|
||||
if (defineHow & DNP_CACHE_RESULT)
|
||||
TRACE_1(AddProperty, obj);
|
||||
|
||||
/*
|
||||
* Initialize the new property value (passed to setter) to undefined.
|
||||
* Note that we store before calling addProperty, to match the order
|
||||
* in js_DefineNativeProperty.
|
||||
* in DefineNativeProperty.
|
||||
*/
|
||||
if (obj->containsSlot(shape->slot))
|
||||
obj->nativeSetSlot(shape->slot, UndefinedValue());
|
||||
|
@ -5756,8 +5741,8 @@ js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uintN defineHow,
|
|||
added = true;
|
||||
}
|
||||
|
||||
if (defineHow & JSDNP_CACHE_RESULT)
|
||||
JS_PROPERTY_CACHE(cx).fill(cx, obj, 0, 0, obj, shape, added);
|
||||
if (defineHow & DNP_CACHE_RESULT)
|
||||
JS_PROPERTY_CACHE(cx).fill(cx, obj, 0, obj, shape, added);
|
||||
|
||||
return js_NativeSet(cx, obj, shape, added, strict, vp);
|
||||
|
||||
|
|
|
@ -209,10 +209,9 @@ enum {
|
|||
};
|
||||
|
||||
/*
|
||||
* Unlike js_DefineNativeProperty, propp must be non-null. On success, and if
|
||||
* id was found, return true with *objp non-null and with a property of *objp
|
||||
* stored in *propp. If successful but id was not found, return true with both
|
||||
* *objp and *propp null.
|
||||
* On success, and if id was found, return true with *objp non-null and with a
|
||||
* property of *objp stored in *propp. If successful but id was not found,
|
||||
* return true with both *objp and *propp null.
|
||||
*/
|
||||
extern JS_FRIEND_API(JSBool)
|
||||
js_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
|
||||
|
@ -1570,48 +1569,43 @@ extern JSBool
|
|||
js_DefineOwnProperty(JSContext *cx, JSObject *obj, jsid id,
|
||||
const js::Value &descriptor, JSBool *bp);
|
||||
|
||||
extern JS_FRIEND_DATA(js::Class) js_CallClass;
|
||||
extern JS_FRIEND_DATA(js::Class) js_DeclEnvClass;
|
||||
|
||||
namespace js {
|
||||
|
||||
/*
|
||||
* Flags for the defineHow parameter of js_DefineNativeProperty.
|
||||
*/
|
||||
const uintN JSDNP_CACHE_RESULT = 1; /* an interpreter call from JSOP_INITPROP */
|
||||
const uintN JSDNP_DONT_PURGE = 2; /* suppress js_PurgeScopeChain */
|
||||
const uintN JSDNP_SET_METHOD = 4; /* js_{DefineNativeProperty,SetPropertyHelper}
|
||||
const uintN DNP_CACHE_RESULT = 1; /* an interpreter call from JSOP_INITPROP */
|
||||
const uintN DNP_DONT_PURGE = 2; /* suppress js_PurgeScopeChain */
|
||||
const uintN DNP_SET_METHOD = 4; /* DefineNativeProperty,js_SetPropertyHelper
|
||||
must pass the js::Shape::METHOD
|
||||
flag on to JSObject::{add,put}Property */
|
||||
const uintN JSDNP_UNQUALIFIED = 8; /* Unqualified property set. Only used in
|
||||
const uintN DNP_UNQUALIFIED = 8; /* Unqualified property set. Only used in
|
||||
the defineHow argument of
|
||||
js_SetPropertyHelper. */
|
||||
|
||||
/*
|
||||
* On error, return false. On success, if propp is non-null, return true with
|
||||
* obj locked and with a held property in *propp; if propp is null, return true
|
||||
* but release obj's lock first.
|
||||
* Return successfully added or changed shape or NULL on error.
|
||||
*/
|
||||
extern JSBool
|
||||
js_DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, const js::Value &value,
|
||||
js::PropertyOp getter, js::StrictPropertyOp setter, uintN attrs,
|
||||
uintN flags, intN shortid, JSProperty **propp,
|
||||
uintN defineHow = 0);
|
||||
extern const Shape *
|
||||
DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, const js::Value &value,
|
||||
PropertyOp getter, StrictPropertyOp setter, uintN attrs,
|
||||
uintN flags, intN shortid, uintN defineHow = 0);
|
||||
|
||||
/*
|
||||
* Specialized subroutine that allows caller to preset JSRESOLVE_* flags and
|
||||
* returns the index along the prototype chain in which *propp was found, or
|
||||
* the last index if not found, or -1 on error.
|
||||
* Specialized subroutine that allows caller to preset JSRESOLVE_* flags.
|
||||
*/
|
||||
extern int
|
||||
js_LookupPropertyWithFlags(JSContext *cx, JSObject *obj, jsid id, uintN flags,
|
||||
JSObject **objp, JSProperty **propp);
|
||||
extern bool
|
||||
LookupPropertyWithFlags(JSContext *cx, JSObject *obj, jsid id, uintN flags,
|
||||
JSObject **objp, JSProperty **propp);
|
||||
|
||||
/*
|
||||
* Constant to pass to js_LookupPropertyWithFlags to infer bits from current
|
||||
* bytecode.
|
||||
*/
|
||||
static const uintN JSRESOLVE_INFER = 0xffff;
|
||||
|
||||
extern JS_FRIEND_DATA(js::Class) js_CallClass;
|
||||
extern JS_FRIEND_DATA(js::Class) js_DeclEnvClass;
|
||||
|
||||
namespace js {
|
||||
static const uintN RESOLVE_INFER = 0xffff;
|
||||
|
||||
/*
|
||||
* We cache name lookup results only for the global object or for native
|
||||
|
|
|
@ -777,8 +777,8 @@ js_Stringify(JSContext *cx, Value *vp, JSObject *replacer, Value space, StringBu
|
|||
|
||||
/* Step 10. */
|
||||
jsid emptyId = ATOM_TO_JSID(cx->runtime->atomState.emptyAtom);
|
||||
if (!js_DefineNativeProperty(cx, wrapper, emptyId, *vp, PropertyStub, StrictPropertyStub,
|
||||
JSPROP_ENUMERATE, 0, 0, NULL))
|
||||
if (!DefineNativeProperty(cx, wrapper, emptyId, *vp, PropertyStub, StrictPropertyStub,
|
||||
JSPROP_ENUMERATE, 0, 0))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -879,9 +879,8 @@ Walk(JSContext *cx, JSObject *holder, jsid name, const Value &reviver, Value *vp
|
|||
} else {
|
||||
/* Step 2b(ii)(3). */
|
||||
JS_ASSERT(obj->isNative());
|
||||
if (!js_DefineNativeProperty(cx, obj, id, newElement, PropertyStub,
|
||||
StrictPropertyStub, JSPROP_ENUMERATE, 0, 0,
|
||||
NULL))
|
||||
if (!DefineNativeProperty(cx, obj, id, newElement, PropertyStub,
|
||||
StrictPropertyStub, JSPROP_ENUMERATE, 0, 0))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -538,9 +538,9 @@ JSONSourceParser::parse(Value *vp)
|
|||
* js_CheckForStringIndex.
|
||||
*/
|
||||
jsid propid = ATOM_TO_JSID(&valueStack.popCopy().toString()->asAtom());
|
||||
if (!js_DefineNativeProperty(cx, &valueStack.back().toObject(), propid, v,
|
||||
PropertyStub, StrictPropertyStub, JSPROP_ENUMERATE,
|
||||
0, 0, NULL))
|
||||
if (!DefineNativeProperty(cx, &valueStack.back().toObject(), propid, v,
|
||||
PropertyStub, StrictPropertyStub, JSPROP_ENUMERATE,
|
||||
0, 0))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1199,15 +1199,11 @@ Compiler::defineGlobals(JSContext *cx, GlobalScope &globalScope, JSScript *scrip
|
|||
rval.setUndefined();
|
||||
}
|
||||
|
||||
JSProperty *prop;
|
||||
|
||||
if (!js_DefineNativeProperty(cx, globalObj, id, rval, PropertyStub, StrictPropertyStub,
|
||||
JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0, &prop)) {
|
||||
const Shape *shape =
|
||||
DefineNativeProperty(cx, globalObj, id, rval, PropertyStub, StrictPropertyStub,
|
||||
JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0);
|
||||
if (!shape)
|
||||
return false;
|
||||
}
|
||||
|
||||
JS_ASSERT(prop);
|
||||
const Shape *shape = (const Shape *)prop;
|
||||
def.knownSlot = shape->slot;
|
||||
}
|
||||
|
||||
|
@ -4381,11 +4377,11 @@ CheckDestructuring(JSContext *cx, BindData *data, JSParseNode *left, JSTreeConte
|
|||
if (data &&
|
||||
data->binder == BindLet &&
|
||||
OBJ_BLOCK_COUNT(cx, tc->blockChain()) == 0 &&
|
||||
!js_DefineNativeProperty(cx, tc->blockChain(),
|
||||
ATOM_TO_JSID(cx->runtime->atomState.emptyAtom),
|
||||
UndefinedValue(), NULL, NULL,
|
||||
JSPROP_ENUMERATE | JSPROP_PERMANENT,
|
||||
Shape::HAS_SHORTID, 0, NULL)) {
|
||||
!DefineNativeProperty(cx, tc->blockChain(),
|
||||
ATOM_TO_JSID(cx->runtime->atomState.emptyAtom),
|
||||
UndefinedValue(), NULL, NULL,
|
||||
JSPROP_ENUMERATE | JSPROP_PERMANENT,
|
||||
Shape::HAS_SHORTID, 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,8 +49,8 @@ using namespace js;
|
|||
JS_STATIC_ASSERT(sizeof(PCVal) == sizeof(jsuword));
|
||||
|
||||
JS_REQUIRES_STACK PropertyCacheEntry *
|
||||
PropertyCache::fill(JSContext *cx, JSObject *obj, uintN scopeIndex, uintN protoIndex,
|
||||
JSObject *pobj, const Shape *shape, JSBool adding)
|
||||
PropertyCache::fill(JSContext *cx, JSObject *obj, uintN scopeIndex, JSObject *pobj,
|
||||
const Shape *shape, JSBool adding)
|
||||
{
|
||||
jsbytecode *pc;
|
||||
jsuword kshape, vshape;
|
||||
|
@ -88,42 +88,34 @@ PropertyCache::fill(JSContext *cx, JSObject *obj, uintN scopeIndex, uintN protoI
|
|||
/*
|
||||
* Check for overdeep scope and prototype chain. Because resolve, getter,
|
||||
* and setter hooks can change the prototype chain using JS_SetPrototype
|
||||
* after js_LookupPropertyWithFlags has returned the nominal protoIndex,
|
||||
* we have to validate protoIndex if it is non-zero. If it is zero, then
|
||||
* we know thanks to the pobj->nativeContains test above, combined with the
|
||||
* fact that obj == pobj, that protoIndex is invariant.
|
||||
* after LookupPropertyWithFlags has returned, we calculate the protoIndex
|
||||
* here and not in LookupPropertyWithFlags.
|
||||
*
|
||||
* The scopeIndex can't be wrong. We require JS_SetParent calls to happen
|
||||
* before any running script might consult a parent-linked scope chain. If
|
||||
* this requirement is not satisfied, the fill in progress will never hit,
|
||||
* but vcap vs. scope shape tests ensure nothing malfunctions.
|
||||
*/
|
||||
JS_ASSERT_IF(scopeIndex == 0 && protoIndex == 0, obj == pobj);
|
||||
JS_ASSERT_IF(obj == pobj, scopeIndex == 0);
|
||||
|
||||
if (protoIndex != 0) {
|
||||
JSObject *tmp = obj;
|
||||
JSObject *tmp = obj;
|
||||
for (uintN i = 0; i != scopeIndex; i++)
|
||||
tmp = tmp->getParent();
|
||||
|
||||
for (uintN i = 0; i != scopeIndex; i++)
|
||||
tmp = tmp->getParent();
|
||||
JS_ASSERT(tmp != pobj);
|
||||
uintN protoIndex = 0;
|
||||
while (tmp != pobj) {
|
||||
tmp = tmp->getProto();
|
||||
|
||||
protoIndex = 1;
|
||||
for (;;) {
|
||||
tmp = tmp->getProto();
|
||||
|
||||
/*
|
||||
* We cannot cache properties coming from native objects behind
|
||||
* non-native ones on the prototype chain. The non-natives can
|
||||
* mutate in arbitrary way without changing any shapes.
|
||||
*/
|
||||
if (!tmp || !tmp->isNative()) {
|
||||
PCMETER(noprotos++);
|
||||
return JS_NO_PROP_CACHE_FILL;
|
||||
}
|
||||
if (tmp == pobj)
|
||||
break;
|
||||
++protoIndex;
|
||||
/*
|
||||
* We cannot cache properties coming from native objects behind
|
||||
* non-native ones on the prototype chain. The non-natives can
|
||||
* mutate in arbitrary way without changing any shapes.
|
||||
*/
|
||||
if (!tmp || !tmp->isNative()) {
|
||||
PCMETER(noprotos++);
|
||||
return JS_NO_PROP_CACHE_FILL;
|
||||
}
|
||||
++protoIndex;
|
||||
}
|
||||
|
||||
if (scopeIndex > PCVCAP_SCOPEMASK || protoIndex > PCVCAP_PROTOMASK) {
|
||||
|
|
|
@ -271,8 +271,8 @@ class PropertyCache
|
|||
* not possible.
|
||||
*/
|
||||
JS_REQUIRES_STACK PropertyCacheEntry *fill(JSContext *cx, JSObject *obj, uintN scopeIndex,
|
||||
uintN protoIndex, JSObject *pobj,
|
||||
const js::Shape *shape, JSBool adding = false);
|
||||
JSObject *pobj, const js::Shape *shape,
|
||||
JSBool adding = false);
|
||||
|
||||
void purge(JSContext *cx);
|
||||
void purgeForScript(JSContext *cx, JSScript *script);
|
||||
|
|
|
@ -2081,7 +2081,7 @@ FindReplaceLength(JSContext *cx, RegExpStatics *res, ReplaceData &rdata, size_t
|
|||
|
||||
JSObject *holder;
|
||||
JSProperty *prop = NULL;
|
||||
if (js_LookupPropertyWithFlags(cx, base, id, JSRESOLVE_QUALIFIED, &holder, &prop) < 0)
|
||||
if (!LookupPropertyWithFlags(cx, base, id, JSRESOLVE_QUALIFIED, &holder, &prop))
|
||||
return false;
|
||||
|
||||
/* Only handle the case where the property exists and is on this object. */
|
||||
|
|
|
@ -9520,22 +9520,17 @@ TraceRecorder::test_property_cache(JSObject* obj, LIns* obj_ins, JSObject*& obj2
|
|||
RETURN_STOP_A("cannot cache name");
|
||||
} else {
|
||||
TraceMonitor &localtm = *traceMonitor;
|
||||
int protoIndex = js_LookupPropertyWithFlags(cx, aobj, id,
|
||||
cx->resolveFlags,
|
||||
&obj2, &prop);
|
||||
if (!LookupPropertyWithFlags(cx, aobj, id, cx->resolveFlags, &obj2, &prop))
|
||||
RETURN_ERROR_A("error in LookupPropertyWithFlags");
|
||||
|
||||
if (protoIndex < 0)
|
||||
RETURN_ERROR_A("error in js_LookupPropertyWithFlags");
|
||||
|
||||
/* js_LookupPropertyWithFlags can reenter the interpreter and kill |this|. */
|
||||
/* LookupPropertyWithFlags can reenter the interpreter and kill |this|. */
|
||||
if (!localtm.recorder)
|
||||
return ARECORD_ABORTED;
|
||||
|
||||
if (prop) {
|
||||
if (!obj2->isNative())
|
||||
RETURN_STOP_A("property found on non-native object");
|
||||
entry = JS_PROPERTY_CACHE(cx).fill(cx, aobj, 0, protoIndex, obj2,
|
||||
(Shape*) prop);
|
||||
entry = JS_PROPERTY_CACHE(cx).fill(cx, aobj, 0, obj2, (Shape*) prop);
|
||||
JS_ASSERT(entry);
|
||||
if (entry == JS_NO_PROP_CACHE_FILL)
|
||||
entry = NULL;
|
||||
|
|
|
@ -542,7 +542,7 @@ class TypedArrayTemplate
|
|||
}
|
||||
|
||||
vp->setUndefined();
|
||||
if (js_LookupPropertyWithFlags(cx, proto, id, cx->resolveFlags, &obj2, &prop) < 0)
|
||||
if (!LookupPropertyWithFlags(cx, proto, id, cx->resolveFlags, &obj2, &prop))
|
||||
return false;
|
||||
|
||||
if (prop) {
|
||||
|
|
|
@ -1809,11 +1809,11 @@ mjit::Compiler::jsop_initprop()
|
|||
JSObject *holder;
|
||||
JSProperty *prop = NULL;
|
||||
#ifdef DEBUG
|
||||
int res =
|
||||
bool res =
|
||||
#endif
|
||||
js_LookupPropertyWithFlags(cx, baseobj, ATOM_TO_JSID(atom),
|
||||
JSRESOLVE_QUALIFIED, &holder, &prop);
|
||||
JS_ASSERT(res >= 0 && prop && holder == baseobj);
|
||||
LookupPropertyWithFlags(cx, baseobj, ATOM_TO_JSID(atom),
|
||||
JSRESOLVE_QUALIFIED, &holder, &prop);
|
||||
JS_ASSERT(res && prop && holder == baseobj);
|
||||
|
||||
RegisterID objReg = frame.copyDataIntoReg(obj);
|
||||
masm.loadPtr(Address(objReg, offsetof(JSObject, slots)), objReg);
|
||||
|
|
|
@ -681,7 +681,7 @@ mjit::EnterMethodJIT(JSContext *cx, StackFrame *fp, void *code, Value *stackLimi
|
|||
JSBool ok;
|
||||
{
|
||||
AssertCompartmentUnchanged pcc(cx);
|
||||
JSAutoResolveFlags rf(cx, JSRESOLVE_INFER);
|
||||
JSAutoResolveFlags rf(cx, RESOLVE_INFER);
|
||||
ok = JaegerTrampoline(cx, fp, code, stackLimit);
|
||||
}
|
||||
|
||||
|
|
|
@ -252,11 +252,11 @@ stubs::SetName(VMFrame &f, JSAtom *origAtom)
|
|||
uintN defineHow;
|
||||
JSOp op = JSOp(*f.regs.pc);
|
||||
if (op == JSOP_SETMETHOD)
|
||||
defineHow = JSDNP_CACHE_RESULT | JSDNP_SET_METHOD;
|
||||
defineHow = DNP_CACHE_RESULT | DNP_SET_METHOD;
|
||||
else if (op == JSOP_SETNAME)
|
||||
defineHow = JSDNP_CACHE_RESULT | JSDNP_UNQUALIFIED;
|
||||
defineHow = DNP_CACHE_RESULT | DNP_UNQUALIFIED;
|
||||
else
|
||||
defineHow = JSDNP_CACHE_RESULT;
|
||||
defineHow = DNP_CACHE_RESULT;
|
||||
if (!js_SetPropertyHelper(cx, obj, id, defineHow, &rval, strict))
|
||||
THROW();
|
||||
} else {
|
||||
|
@ -2109,13 +2109,12 @@ InitPropOrMethod(VMFrame &f, JSAtom *atom, JSOp op)
|
|||
jsid id = ATOM_TO_JSID(atom);
|
||||
|
||||
uintN defineHow = (op == JSOP_INITMETHOD)
|
||||
? JSDNP_CACHE_RESULT | JSDNP_SET_METHOD
|
||||
: JSDNP_CACHE_RESULT;
|
||||
if (!(JS_UNLIKELY(atom == cx->runtime->atomState.protoAtom)
|
||||
? js_SetPropertyHelper(cx, obj, id, defineHow, &rval, false)
|
||||
: js_DefineNativeProperty(cx, obj, id, rval, NULL, NULL,
|
||||
JSPROP_ENUMERATE, 0, 0, NULL,
|
||||
defineHow))) {
|
||||
? DNP_CACHE_RESULT | DNP_SET_METHOD
|
||||
: DNP_CACHE_RESULT;
|
||||
if (JS_UNLIKELY(atom == cx->runtime->atomState.protoAtom)
|
||||
? !js_SetPropertyHelper(cx, obj, id, defineHow, &rval, false)
|
||||
: !DefineNativeProperty(cx, obj, id, rval, NULL, NULL,
|
||||
JSPROP_ENUMERATE, 0, 0, defineHow)) {
|
||||
THROW();
|
||||
}
|
||||
}
|
||||
|
@ -2596,8 +2595,8 @@ stubs::DefVarOrConst(VMFrame &f, JSAtom *atom)
|
|||
|
||||
/* Bind a variable only if it's not yet defined. */
|
||||
if (shouldDefine &&
|
||||
!js_DefineNativeProperty(cx, obj, id, UndefinedValue(), PropertyStub, StrictPropertyStub,
|
||||
attrs, 0, 0, NULL)) {
|
||||
!DefineNativeProperty(cx, obj, id, UndefinedValue(), PropertyStub, StrictPropertyStub,
|
||||
attrs, 0, 0)) {
|
||||
THROW();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3721,7 +3721,7 @@ CopyProperty(JSContext *cx, JSObject *obj, JSObject *referent, jsid id,
|
|||
|
||||
*objp = NULL;
|
||||
if (referent->isNative()) {
|
||||
if (js_LookupPropertyWithFlags(cx, referent, id, lookupFlags, &obj2, &prop) < 0)
|
||||
if (!LookupPropertyWithFlags(cx, referent, id, lookupFlags, &obj2, &prop))
|
||||
return false;
|
||||
if (obj2 != referent)
|
||||
return true;
|
||||
|
@ -3768,9 +3768,8 @@ CopyProperty(JSContext *cx, JSObject *obj, JSObject *referent, jsid id,
|
|||
}
|
||||
|
||||
*objp = obj;
|
||||
return js_DefineNativeProperty(cx, obj, id, desc.value,
|
||||
desc.getter, desc.setter, desc.attrs, propFlags,
|
||||
desc.shortid, &prop);
|
||||
return !!DefineNativeProperty(cx, obj, id, desc.value, desc.getter, desc.setter,
|
||||
desc.attrs, propFlags, desc.shortid);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
|
|
Загрузка…
Ссылка в новой задаче