mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-20 16:55:40 +00:00
Object.defineProperty should avoid JS API inside engine, plus a few other cleanups (598176, r=jorendorff).
This commit is contained in:
parent
c7afa7d50c
commit
836aec0df5
@ -1743,8 +1743,9 @@ js_GetOwnPropertyDescriptor(JSContext *cx, JSObject *obj, jsid id, Value *vp)
|
||||
roots[1] = shape->setterValue();
|
||||
}
|
||||
JS_UNLOCK_OBJ(cx, pobj);
|
||||
} else if (!pobj->getAttributes(cx, id, &attrs)) {
|
||||
return false;
|
||||
} else {
|
||||
if (!pobj->getAttributes(cx, id, &attrs))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (doGet && !obj->getProperty(cx, id, &roots[2]))
|
||||
@ -1829,16 +1830,23 @@ obj_keys(JSContext *cx, uintN argc, Value *vp)
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
HasProperty(JSContext* cx, JSObject* obj, jsid id, Value* vp, JSBool* answerp)
|
||||
static bool
|
||||
HasProperty(JSContext* cx, JSObject* obj, jsid id, Value* vp, bool *foundp)
|
||||
{
|
||||
if (!JS_HasPropertyById(cx, obj, id, answerp))
|
||||
return JS_FALSE;
|
||||
if (!*answerp) {
|
||||
if (!obj->hasProperty(cx, id, foundp, JSRESOLVE_QUALIFIED | JSRESOLVE_DETECTING))
|
||||
return false;
|
||||
if (!*foundp) {
|
||||
vp->setUndefined();
|
||||
return JS_TRUE;
|
||||
return true;
|
||||
}
|
||||
return JS_GetPropertyById(cx, obj, id, Jsvalify(vp));
|
||||
|
||||
/*
|
||||
* We must go through the method read barrier in case id is 'get' or 'set'.
|
||||
* There is no obvious way to defer cloning a joined function object whose
|
||||
* identity will be used by DefinePropertyOnObject, e.g., or reflected via
|
||||
* js_GetOwnPropertyDescriptor, as the getter or setter callable object.
|
||||
*/
|
||||
return !!obj->getProperty(cx, id, vp);
|
||||
}
|
||||
|
||||
PropDesc::PropDesc()
|
||||
@ -1876,51 +1884,47 @@ PropDesc::initialize(JSContext* cx, jsid id, const Value &origval)
|
||||
/* Start with the proper defaults. */
|
||||
attrs = JSPROP_PERMANENT | JSPROP_READONLY;
|
||||
|
||||
JSBool hasProperty;
|
||||
bool found;
|
||||
|
||||
/* 8.10.5 step 3 */
|
||||
if (!HasProperty(cx, desc, ATOM_TO_JSID(cx->runtime->atomState.enumerableAtom), &v,
|
||||
&hasProperty)) {
|
||||
if (!HasProperty(cx, desc, ATOM_TO_JSID(cx->runtime->atomState.enumerableAtom), &v, &found))
|
||||
return false;
|
||||
}
|
||||
if (hasProperty) {
|
||||
if (found) {
|
||||
hasEnumerable = JS_TRUE;
|
||||
if (js_ValueToBoolean(v))
|
||||
attrs |= JSPROP_ENUMERATE;
|
||||
}
|
||||
|
||||
/* 8.10.5 step 4 */
|
||||
if (!HasProperty(cx, desc, ATOM_TO_JSID(cx->runtime->atomState.configurableAtom), &v,
|
||||
&hasProperty)) {
|
||||
if (!HasProperty(cx, desc, ATOM_TO_JSID(cx->runtime->atomState.configurableAtom), &v, &found))
|
||||
return false;
|
||||
}
|
||||
if (hasProperty) {
|
||||
if (found) {
|
||||
hasConfigurable = JS_TRUE;
|
||||
if (js_ValueToBoolean(v))
|
||||
attrs &= ~JSPROP_PERMANENT;
|
||||
}
|
||||
|
||||
/* 8.10.5 step 5 */
|
||||
if (!HasProperty(cx, desc, ATOM_TO_JSID(cx->runtime->atomState.valueAtom), &v, &hasProperty))
|
||||
if (!HasProperty(cx, desc, ATOM_TO_JSID(cx->runtime->atomState.valueAtom), &v, &found))
|
||||
return false;
|
||||
if (hasProperty) {
|
||||
if (found) {
|
||||
hasValue = true;
|
||||
value = v;
|
||||
}
|
||||
|
||||
/* 8.10.6 step 6 */
|
||||
if (!HasProperty(cx, desc, ATOM_TO_JSID(cx->runtime->atomState.writableAtom), &v, &hasProperty))
|
||||
if (!HasProperty(cx, desc, ATOM_TO_JSID(cx->runtime->atomState.writableAtom), &v, &found))
|
||||
return false;
|
||||
if (hasProperty) {
|
||||
if (found) {
|
||||
hasWritable = JS_TRUE;
|
||||
if (js_ValueToBoolean(v))
|
||||
attrs &= ~JSPROP_READONLY;
|
||||
}
|
||||
|
||||
/* 8.10.7 step 7 */
|
||||
if (!HasProperty(cx, desc, ATOM_TO_JSID(cx->runtime->atomState.getAtom), &v, &hasProperty))
|
||||
if (!HasProperty(cx, desc, ATOM_TO_JSID(cx->runtime->atomState.getAtom), &v, &found))
|
||||
return false;
|
||||
if (hasProperty) {
|
||||
if (found) {
|
||||
if ((v.isPrimitive() || !js_IsCallable(v)) && !v.isUndefined()) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_GET_SET_FIELD,
|
||||
js_getter_str);
|
||||
@ -1932,9 +1936,9 @@ PropDesc::initialize(JSContext* cx, jsid id, const Value &origval)
|
||||
}
|
||||
|
||||
/* 8.10.7 step 8 */
|
||||
if (!HasProperty(cx, desc, ATOM_TO_JSID(cx->runtime->atomState.setAtom), &v, &hasProperty))
|
||||
if (!HasProperty(cx, desc, ATOM_TO_JSID(cx->runtime->atomState.setAtom), &v, &found))
|
||||
return false;
|
||||
if (hasProperty) {
|
||||
if (found) {
|
||||
if ((v.isPrimitive() || !js_IsCallable(v)) && !v.isUndefined()) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_GET_SET_FIELD,
|
||||
js_setter_str);
|
||||
|
@ -153,9 +153,6 @@ struct PropDesc {
|
||||
return js::CastAsPropertyOp(setterObject());
|
||||
}
|
||||
|
||||
static void traceDescriptorArray(JSTracer* trc, JSObject* obj);
|
||||
static void finalizeDescriptorArray(JSContext* cx, JSObject* obj);
|
||||
|
||||
js::Value pd;
|
||||
jsid id;
|
||||
js::Value value, get, set;
|
||||
|
@ -42,5 +42,8 @@ script regress-596103.js
|
||||
script regress-596805-1.js
|
||||
script regress-596805-2.js
|
||||
script regress-597870.js
|
||||
script regress-597945-1.js
|
||||
script regress-597945-2.js
|
||||
script regress-598176.js
|
||||
fails-if(!xulRuntime.shell) script regress-597945-1.js
|
||||
script regress-597945-2.js
|
||||
|
27
js/src/tests/js1_8_5/regress/regress-598176.js
Normal file
27
js/src/tests/js1_8_5/regress/regress-598176.js
Normal file
@ -0,0 +1,27 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/licenses/publicdomain/
|
||||
*/
|
||||
|
||||
function make() {
|
||||
var r = {};
|
||||
r.desc = {get: function() {}};
|
||||
r.a = Object.defineProperty({}, "prop", r.desc);
|
||||
r.info = Object.getOwnPropertyDescriptor(r.a, "prop");
|
||||
return r;
|
||||
}
|
||||
|
||||
r1 = make();
|
||||
assertEq(r1.desc.get, r1.info.get);
|
||||
|
||||
// Distinct evaluations of an object literal make distinct methods.
|
||||
r2 = make();
|
||||
assertEq(r1.desc.get === r2.desc.get, false);
|
||||
|
||||
r1.info.get.foo = 42;
|
||||
|
||||
assertEq(r1.desc.get.hasOwnProperty('foo'), !r2.desc.get.hasOwnProperty('foo'));
|
||||
assertEq(r1.info.get.hasOwnProperty('foo'), !r2.info.get.hasOwnProperty('foo'));
|
||||
|
||||
reportCompare(0, 0, "ok");
|
Loading…
Reference in New Issue
Block a user