Test whether obj IsCallable instead of VALUE_IS_FUNCTION for call and apply (547046, r=mrbkap).

This commit is contained in:
Andreas Gal 2010-02-22 14:07:50 -08:00
Родитель 6cd88e0d98
Коммит 37cbe1d2c4
4 изменённых файлов: 23 добавлений и 20 удалений

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

@ -1947,7 +1947,7 @@ js_fun_call(JSContext *cx, uintN argc, jsval *vp)
return JS_FALSE;
fval = vp[1];
if (!VALUE_IS_FUNCTION(cx, fval)) {
if (!js_IsCallable(cx, fval)) {
str = JS_ValueToString(cx, fval);
if (str) {
const char *bytes = js_GetStringBytes(cx, str);
@ -2015,7 +2015,7 @@ js_fun_apply(JSContext *cx, uintN argc, jsval *vp)
return JS_FALSE;
fval = vp[1];
if (!VALUE_IS_FUNCTION(cx, fval)) {
if (!js_IsCallable(cx, fval)) {
str = JS_ValueToString(cx, fval);
if (str) {
const char *bytes = js_GetStringBytes(cx, str);
@ -2627,7 +2627,7 @@ js_ValueToCallableObject(JSContext *cx, jsval *vp, uintN flags)
{
JSObject *callable = JSVAL_IS_OBJECT(*vp) ? JSVAL_TO_OBJECT(*vp) : NULL;
if (callable && js_IsCallable(callable, cx)) {
if (callable && callable->isCallable(cx)) {
*vp = OBJECT_TO_JSVAL(callable);
return callable;
}

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

@ -2175,7 +2175,7 @@ PropertyDescriptor::initialize(JSContext* cx, jsid id, jsval v)
if (!HasProperty(cx, desc, ATOM_TO_JSID(cx->runtime->atomState.getAtom), &v, &hasProperty))
return false;
if (hasProperty) {
if ((JSVAL_IS_PRIMITIVE(v) || !js_IsCallable(JSVAL_TO_OBJECT(v), cx)) &&
if ((JSVAL_IS_PRIMITIVE(v) || !js_IsCallable(cx, v)) &&
v != JSVAL_VOID) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_BAD_GETTER_OR_SETTER,
@ -2191,7 +2191,7 @@ PropertyDescriptor::initialize(JSContext* cx, jsid id, jsval v)
if (!HasProperty(cx, desc, ATOM_TO_JSID(cx->runtime->atomState.setAtom), &v, &hasProperty))
return false;
if (hasProperty) {
if ((JSVAL_IS_PRIMITIVE(v) || !js_IsCallable(JSVAL_TO_OBJECT(v), cx)) &&
if ((JSVAL_IS_PRIMITIVE(v) || !js_IsCallable(cx, v)) &&
v != JSVAL_VOID) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_BAD_GETTER_OR_SETTER,
@ -6762,17 +6762,17 @@ js_GetWrappedObject(JSContext *cx, JSObject *obj)
return obj;
}
JSBool
js_IsCallable(JSObject *obj, JSContext *cx)
bool
JSObject::isCallable(JSContext *cx)
{
if (!OBJ_IS_NATIVE(obj))
return obj->map->ops->call != NULL;
if (!isNative())
return map->ops->call;
JS_LOCK_OBJ(cx, obj);
JSBool callable = (obj->map->ops == &js_ObjectOps)
? HAS_FUNCTION_CLASS(obj) || STOBJ_GET_CLASS(obj)->call
: obj->map->ops->call != NULL;
JS_UNLOCK_OBJ(cx, obj);
JS_LOCK_OBJ(cx, this);
JSBool callable = (map->ops == &js_ObjectOps)
? isFunction() || getClass()->call
: map->ops->call != NULL;
JS_UNLOCK_OBJ(cx, this);
return callable;
}

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

@ -332,6 +332,8 @@ struct JSObject {
: JSVAL_VOID;
}
bool isCallable(JSContext *cx);
/* The map field is not initialized here and should be set separately. */
void init(JSClass *clasp, JSObject *proto, JSObject *parent,
jsval privateSlotValue) {
@ -1099,9 +1101,10 @@ extern const char *
js_ComputeFilename(JSContext *cx, JSStackFrame *caller,
JSPrincipals *principals, uintN *linenop);
/* Infallible, therefore cx is last parameter instead of first. */
extern JSBool
js_IsCallable(JSObject *obj, JSContext *cx);
static inline bool
js_IsCallable(JSContext *cx, jsval v) {
return !JSVAL_IS_PRIMITIVE(v) && JSVAL_TO_OBJECT(v)->isCallable(cx);
}
extern JSBool
js_ReportGetterOnlyAssignment(JSContext *cx);

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

@ -429,7 +429,7 @@ JA(JSContext *cx, jsval *vp, StringifyContext *scx)
static JSBool
CallReplacerFunction(JSContext *cx, jsid id, JSObject *holder, StringifyContext *scx, jsval *vp)
{
if (scx->replacer && js_IsCallable(scx->replacer, cx)) {
if (scx->replacer && scx->replacer->isCallable(cx)) {
jsval vec[2] = {ID_TO_VALUE(id), *vp};
if (!JS_CallFunctionValue(cx, holder, OBJECT_TO_JSVAL(scx->replacer), 2, vec, vp))
return JS_FALSE;
@ -586,7 +586,7 @@ Walk(JSContext *cx, jsid id, JSObject *holder, jsval reviver, jsval *vp)
JSObject *obj;
if (!JSVAL_IS_PRIMITIVE(*vp) && !js_IsCallable(obj = JSVAL_TO_OBJECT(*vp), cx)) {
if (!JSVAL_IS_PRIMITIVE(*vp) && !(obj = JSVAL_TO_OBJECT(*vp))->isCallable(cx)) {
jsval propValue = JSVAL_NULL;
JSAutoTempValueRooter tvr(cx, 1, &propValue);
@ -731,7 +731,7 @@ js_FinishJSONParse(JSContext *cx, JSONParser *jp, jsval reviver)
return JS_FALSE;
}
if (!JSVAL_IS_PRIMITIVE(reviver) && js_IsCallable(JSVAL_TO_OBJECT(reviver), cx))
if (!JSVAL_IS_PRIMITIVE(reviver) && js_IsCallable(cx, reviver))
ok = Revive(cx, reviver, vp);
return ok;