зеркало из https://github.com/mozilla/pjs.git
Bug 645468 - Remove js_TryMethod: its semantics aren't what most of its users want, and its utility is limited. r=luke
This commit is contained in:
Родитель
809c5784c4
Коммит
6a5baa1c5b
|
@ -1280,16 +1280,14 @@ array_toString_sub(JSContext *cx, JSObject *obj, JSBool locale,
|
|||
}
|
||||
|
||||
/* Get element's character string. */
|
||||
if (!(hole || rval->isNullOrUndefined())) {
|
||||
if (!hole && !rval->isNullOrUndefined()) {
|
||||
if (locale) {
|
||||
/* Work on obj.toLocalString() instead. */
|
||||
JSObject *robj;
|
||||
|
||||
if (!js_ValueToObjectOrNull(cx, *rval, &robj))
|
||||
JSObject *robj = ToObject(cx, rval);
|
||||
if (!robj)
|
||||
goto out;
|
||||
rval->setObjectOrNull(robj);
|
||||
JSAtom *atom = cx->runtime->atomState.toLocaleStringAtom;
|
||||
if (!js_TryMethod(cx, robj, atom, 0, NULL, rval))
|
||||
jsid id = ATOM_TO_JSID(cx->runtime->atomState.toLocaleStringAtom);
|
||||
if (!robj->callMethod(cx, id, 0, NULL, rval))
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
|
@ -5480,6 +5480,14 @@ JSObject::reportNotExtensible(JSContext *cx, uintN report)
|
|||
NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
bool
|
||||
JSObject::callMethod(JSContext *cx, jsid id, uintN argc, Value *argv, Value *vp)
|
||||
{
|
||||
Value fval;
|
||||
return js_GetMethod(cx, this, id, JSGET_NO_METHOD_BARRIER, &fval) &&
|
||||
ExternalInvoke(cx, ObjectValue(*this), fval, argc, argv, vp);
|
||||
}
|
||||
|
||||
JSBool
|
||||
js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uintN defineHow,
|
||||
Value *vp, JSBool strict)
|
||||
|
@ -5899,12 +5907,21 @@ DefaultValue(JSContext *cx, JSObject *obj, JSType hint, Value *vp)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (!js_TryMethod(cx, obj, cx->runtime->atomState.toStringAtom, 0, NULL, &v))
|
||||
Value fval;
|
||||
jsid id = ATOM_TO_JSID(cx->runtime->atomState.toStringAtom);
|
||||
if (!js_GetMethod(cx, obj, id, JSGET_NO_METHOD_BARRIER, &fval))
|
||||
return false;
|
||||
if (!v.isPrimitive()) {
|
||||
if (!obj->getClass()->convert(cx, obj, hint, &v))
|
||||
if (js_IsCallable(fval)) {
|
||||
if (!ExternalInvoke(cx, ObjectValue(*obj), fval, 0, NULL, &v))
|
||||
return false;
|
||||
if (v.isPrimitive()) {
|
||||
*vp = v;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!obj->getClass()->convert(cx, obj, hint, &v))
|
||||
return false;
|
||||
} else {
|
||||
/* Optimize (new String(...)).valueOf(). */
|
||||
Class *clasp = obj->getClass();
|
||||
|
@ -5924,8 +5941,18 @@ DefaultValue(JSContext *cx, JSObject *obj, JSType hint, Value *vp)
|
|||
return false;
|
||||
if (v.isObject()) {
|
||||
JS_ASSERT(hint != TypeOfValue(cx, v));
|
||||
if (!js_TryMethod(cx, obj, cx->runtime->atomState.toStringAtom, 0, NULL, &v))
|
||||
Value fval;
|
||||
jsid id = ATOM_TO_JSID(cx->runtime->atomState.toStringAtom);
|
||||
if (!js_GetMethod(cx, obj, id, JSGET_NO_METHOD_BARRIER, &fval))
|
||||
return false;
|
||||
if (js_IsCallable(fval)) {
|
||||
if (!ExternalInvoke(cx, ObjectValue(*obj), fval, 0, NULL, &v))
|
||||
return false;
|
||||
if (v.isPrimitive()) {
|
||||
*vp = v;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (v.isObject()) {
|
||||
|
@ -6243,35 +6270,21 @@ js_ValueToNonNullObject(JSContext *cx, const Value &v)
|
|||
JSBool
|
||||
js_TryValueOf(JSContext *cx, JSObject *obj, JSType type, Value *rval)
|
||||
{
|
||||
Value argv[1];
|
||||
|
||||
argv[0].setString(cx->runtime->atomState.typeAtoms[type]);
|
||||
return js_TryMethod(cx, obj, cx->runtime->atomState.valueOfAtom,
|
||||
1, argv, rval);
|
||||
}
|
||||
|
||||
JSBool
|
||||
js_TryMethod(JSContext *cx, JSObject *obj, JSAtom *atom,
|
||||
uintN argc, Value *argv, Value *rval)
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return JS_FALSE);
|
||||
|
||||
/*
|
||||
* Report failure only if an appropriate method was found, and calling it
|
||||
* returned failure. We propagate failure in this case to make exceptions
|
||||
* behave properly.
|
||||
*/
|
||||
JSErrorReporter older = JS_SetErrorReporter(cx, NULL);
|
||||
jsid id = ATOM_TO_JSID(atom);
|
||||
Value fval;
|
||||
JSBool ok = js_GetMethod(cx, obj, id, JSGET_NO_METHOD_BARRIER, &fval);
|
||||
JS_SetErrorReporter(cx, older);
|
||||
if (!ok)
|
||||
jsid id = ATOM_TO_JSID(cx->runtime->atomState.valueOfAtom);
|
||||
if (!js_GetMethod(cx, obj, id, JSGET_NO_METHOD_BARRIER, &fval))
|
||||
return false;
|
||||
|
||||
if (fval.isPrimitive())
|
||||
return JS_TRUE;
|
||||
return ExternalInvoke(cx, ObjectValue(*obj), fval, argc, argv, rval);
|
||||
if (js_IsCallable(fval)) {
|
||||
Value v;
|
||||
Value argv[] = { StringValue(cx->runtime->atomState.typeAtoms[type]) };
|
||||
if (!ExternalInvoke(cx, ObjectValue(*obj), fval, JS_ARRAY_LENGTH(argv), argv, &v))
|
||||
return false;
|
||||
if (v.isPrimitive()) {
|
||||
*rval = v;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#if JS_HAS_XDR
|
||||
|
|
|
@ -1186,6 +1186,14 @@ struct JSObject : js::gc::Cell {
|
|||
bool reportNotConfigurable(JSContext* cx, jsid id, uintN report = JSREPORT_ERROR);
|
||||
bool reportNotExtensible(JSContext *cx, uintN report = JSREPORT_ERROR);
|
||||
|
||||
/*
|
||||
* Get the property with the given id, then call it as a function with the
|
||||
* given arguments, providing this object as |this|. If the property isn't
|
||||
* callable a TypeError will be thrown. On success the value returned by
|
||||
* the call is stored in *vp.
|
||||
*/
|
||||
bool callMethod(JSContext *cx, jsid id, uintN argc, js::Value *argv, js::Value *vp);
|
||||
|
||||
private:
|
||||
js::Shape *getChildProperty(JSContext *cx, js::Shape *parent, js::Shape &child);
|
||||
|
||||
|
@ -1884,10 +1892,6 @@ js_ValueToNonNullObject(JSContext *cx, const js::Value &v);
|
|||
extern JSBool
|
||||
js_TryValueOf(JSContext *cx, JSObject *obj, JSType type, js::Value *rval);
|
||||
|
||||
extern JSBool
|
||||
js_TryMethod(JSContext *cx, JSObject *obj, JSAtom *atom,
|
||||
uintN argc, js::Value *argv, js::Value *rval);
|
||||
|
||||
extern JSBool
|
||||
js_XDRObject(JSXDRState *xdr, JSObject **objp);
|
||||
|
||||
|
|
|
@ -170,15 +170,19 @@ js_json_stringify(JSContext *cx, uintN argc, Value *vp)
|
|||
JSBool
|
||||
js_TryJSON(JSContext *cx, Value *vp)
|
||||
{
|
||||
// Checks whether the return value implements toJSON()
|
||||
JSBool ok = JS_TRUE;
|
||||
if (!vp->isObject())
|
||||
return true;
|
||||
|
||||
if (vp->isObject()) {
|
||||
JSObject *obj = &vp->toObject();
|
||||
ok = js_TryMethod(cx, obj, cx->runtime->atomState.toJSONAtom, 0, NULL, vp);
|
||||
JSObject *obj = &vp->toObject();
|
||||
Value fval;
|
||||
jsid id = ATOM_TO_JSID(cx->runtime->atomState.toJSONAtom);
|
||||
if (!js_GetMethod(cx, obj, id, JSGET_NO_METHOD_BARRIER, &fval))
|
||||
return false;
|
||||
if (js_IsCallable(fval)) {
|
||||
if (!ExternalInvoke(cx, ObjectValue(*obj), fval, 0, NULL, vp))
|
||||
return false;
|
||||
}
|
||||
|
||||
return ok;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -3875,11 +3875,17 @@ js_ValueToSource(JSContext *cx, const Value &v)
|
|||
return js_ValueToString(cx, v);
|
||||
}
|
||||
|
||||
JSAtom *atom = cx->runtime->atomState.toSourceAtom;
|
||||
AutoValueRooter tvr(cx);
|
||||
if (!js_TryMethod(cx, &v.toObject(), atom, 0, NULL, tvr.addr()))
|
||||
return NULL;
|
||||
return js_ValueToString(cx, tvr.value());
|
||||
Value rval = NullValue();
|
||||
Value fval;
|
||||
jsid id = ATOM_TO_JSID(cx->runtime->atomState.toSourceAtom);
|
||||
if (!js_GetMethod(cx, &v.toObject(), id, JSGET_NO_METHOD_BARRIER, &fval))
|
||||
return false;
|
||||
if (js_IsCallable(fval)) {
|
||||
if (!ExternalInvoke(cx, v, fval, 0, NULL, &rval))
|
||||
return false;
|
||||
}
|
||||
|
||||
return js_ValueToString(cx, rval);
|
||||
}
|
||||
|
||||
namespace js {
|
||||
|
|
|
@ -4867,7 +4867,11 @@ xml_deleteProperty(JSContext *cx, JSObject *obj, jsid id, Value *rval, JSBool st
|
|||
JSBool
|
||||
xml_convert(JSContext *cx, JSObject *obj, JSType type, Value *rval)
|
||||
{
|
||||
return js_TryMethod(cx, obj, cx->runtime->atomState.toStringAtom, 0, NULL, rval);
|
||||
JSString *str = js_ValueToString(cx, ObjectValue(*obj));
|
||||
if (!str)
|
||||
return false;
|
||||
*rval = StringValue(str);
|
||||
return true;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
|
|
|
@ -80,7 +80,7 @@ catch(ex)
|
|||
}
|
||||
reportCompare(expect, actual, summary + ': 3');
|
||||
|
||||
expect = 'TypeError: ({}) is not a function';
|
||||
expect = "TypeError: can't convert ({toString:{}}) to primitive type";
|
||||
try
|
||||
{
|
||||
3 + ({toString:({}) }) ;
|
||||
|
|
|
@ -84,7 +84,7 @@ function test()
|
|||
}
|
||||
reportCompare(expect, actual, summary + ': 3');
|
||||
|
||||
expect = 'TypeError: ({}) is not a function';
|
||||
expect = "TypeError: can't convert ({toString:{}}) to primitive type";
|
||||
try
|
||||
{
|
||||
3 + ({toString:({}) }) ;
|
||||
|
|
Загрузка…
Ссылка в новой задаче