diff --git a/js/src/jsdbgapi.c b/js/src/jsdbgapi.c index 3b5493a8e802..1e13596ff0c0 100644 --- a/js/src/jsdbgapi.c +++ b/js/src/jsdbgapi.c @@ -1353,28 +1353,17 @@ JS_GetPropertyDesc(JSContext *cx, JSObject *obj, JSScopeProperty *sprop, pd->flags |= ((sprop->attrs & JSPROP_ENUMERATE) ? JSPD_ENUMERATE : 0) | ((sprop->attrs & JSPROP_READONLY) ? JSPD_READONLY : 0) - | ((sprop->attrs & JSPROP_PERMANENT) ? JSPD_PERMANENT : 0) - | ((sprop->getter == js_GetCallVariable) ? JSPD_VARIABLE : 0); - - /* for Call Object 'real' getter isn't passed in to us */ - if (OBJ_GET_CLASS(cx, obj) == &js_CallClass && - sprop->getter == js_CallClass.getProperty) { - /* - * Property of a heavyweight function's variable object having the - * class-default getter. It's either an argument if permanent, or a - * nested function if impermanent. Local variables have a special - * getter (js_GetCallVariable, tested above) and setter, and not the - * class default. - */ - pd->flags |= (sprop->attrs & JSPROP_PERMANENT) - ? JSPD_ARGUMENT - : JSPD_VARIABLE; - } - + | ((sprop->attrs & JSPROP_PERMANENT) ? JSPD_PERMANENT : 0); pd->spare = 0; - pd->slot = (pd->flags & (JSPD_ARGUMENT | JSPD_VARIABLE)) - ? sprop->shortid - : 0; + if (sprop->getter == js_GetCallArg) { + pd->slot = sprop->shortid; + pd->flags |= JSPD_ARGUMENT; + } else if (sprop->getter == js_GetCallVar) { + pd->slot = sprop->shortid; + pd->flags |= JSPD_VARIABLE; + } else { + pd->slot = 0; + } pd->alias = JSVAL_VOID; scope = OBJ_SCOPE(obj); if (SPROP_HAS_VALID_SLOT(sprop, scope)) { diff --git a/js/src/jsfun.c b/js/src/jsfun.c index a1893152f1a2..43e7f52eac52 100644 --- a/js/src/jsfun.c +++ b/js/src/jsfun.c @@ -658,93 +658,6 @@ js_PutCallObject(JSContext *cx, JSStackFrame *fp) return ok; } -static JSBool -call_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) -{ - JSStackFrame *fp; - jsint slot; - - if (!JSVAL_IS_INT(id)) - return JS_TRUE; - fp = (JSStackFrame *) JS_GetPrivate(cx, obj); - if (!fp) - return JS_TRUE; - JS_ASSERT(fp->fun); - - slot = JSVAL_TO_INT(id); - switch (slot) { - case CALL_ARGUMENTS: - if (!TEST_OVERRIDE_BIT(fp, slot)) { - JSObject *argsobj = js_GetArgsObject(cx, fp); - if (!argsobj) - return JS_FALSE; - *vp = OBJECT_TO_JSVAL(argsobj); - } - break; - - default: - if ((uintN)slot < JS_MAX(fp->argc, fp->fun->nargs)) - *vp = fp->argv[slot]; - break; - } - return JS_TRUE; -} - -static JSBool -call_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) -{ - JSStackFrame *fp; - jsint slot; - - if (!JSVAL_IS_INT(id)) - return JS_TRUE; - fp = (JSStackFrame *) JS_GetPrivate(cx, obj); - if (!fp) - return JS_TRUE; - JS_ASSERT(fp->fun); - - slot = JSVAL_TO_INT(id); - switch (slot) { - case CALL_ARGUMENTS: - SET_OVERRIDE_BIT(fp, slot); - break; - - default: - if ((uintN)slot < JS_MAX(fp->argc, fp->fun->nargs)) - fp->argv[slot] = *vp; - break; - } - return JS_TRUE; -} - -JSBool -js_GetCallVariable(JSContext *cx, JSObject *obj, jsval id, jsval *vp) -{ - JSStackFrame *fp; - - JS_ASSERT(JSVAL_IS_INT(id)); - fp = (JSStackFrame *) JS_GetPrivate(cx, obj); - if (fp) { - JS_ASSERT((uintN) JSVAL_TO_INT(id) < fp->nvars); - *vp = fp->vars[JSVAL_TO_INT(id)]; - } - return JS_TRUE; -} - -JSBool -js_SetCallVariable(JSContext *cx, JSObject *obj, jsval id, jsval *vp) -{ - JSStackFrame *fp; - - JS_ASSERT(JSVAL_IS_INT(id)); - fp = (JSStackFrame *) JS_GetPrivate(cx, obj); - if (fp) { - JS_ASSERT((uintN) JSVAL_TO_INT(id) < fp->nvars); - fp->vars[JSVAL_TO_INT(id)] = *vp; - } - return JS_TRUE; -} - static JSBool call_enumerate(JSContext *cx, JSObject *obj) { @@ -815,11 +728,102 @@ call_enumerate(JSContext *cx, JSObject *obj) return ok; } +typedef enum JSCallPropertyKind { + JSCPK_ARGUMENTS, + JSCPK_ARG, + JSCPK_VAR +} JSCallPropertyKind; + +static JSBool +CallPropertyOp(JSContext *cx, JSObject *obj, jsid id, jsval *vp, + JSCallPropertyKind kind, JSBool setter) +{ + JSStackFrame *fp; + JSFunction *fun; + uintN i; + jsval *array; + + fp = (JSStackFrame *) JS_GetPrivate(cx, obj); + if (!fp) + return JS_TRUE; + fun = fp->fun; + JS_ASSERT(fun && FUN_INTERPRETED(fun)); + + if (kind == JSCPK_ARGUMENTS) { + if (setter) { + SET_OVERRIDE_BIT(fp, CALL_ARGUMENTS); + } else if (!TEST_OVERRIDE_BIT(fp, CALL_ARGUMENTS)) { + JSObject *argsobj; + + argsobj = js_GetArgsObject(cx, fp); + if (!argsobj) + return JS_FALSE; + *vp = OBJECT_TO_JSVAL(argsobj); + } + return JS_TRUE; + } + + JS_ASSERT((int16) JSVAL_TO_INT(id) == JSVAL_TO_INT(id)); + i = (uint16) JSVAL_TO_INT(id); + JS_ASSERT_IF(kind == JSCPK_ARG, i < fun->nargs); + JS_ASSERT_IF(kind == JSCPK_VAR, i < fun->u.i.nvars); + + JS_ASSERT(fun->u.i.nvars == fp->nvars); + if (kind == JSCPK_ARG) { + array = fp->argv; + } else { + JS_ASSERT(kind == JSCPK_VAR); + array = fp->vars; + } + if (setter) + array[i] = *vp; + else + *vp = array[i]; + return JS_TRUE; +} + +static JSBool +GetCallArguments(JSContext *cx, JSObject *obj, jsid id, jsval *vp) +{ + return CallPropertyOp(cx, obj, id, vp, JSCPK_ARGUMENTS, JS_FALSE); +} + +static JSBool +SetCallArguments(JSContext *cx, JSObject *obj, jsid id, jsval *vp) +{ + return CallPropertyOp(cx, obj, id, vp, JSCPK_ARGUMENTS, JS_TRUE); +} + +JSBool +js_GetCallArg(JSContext *cx, JSObject *obj, jsid id, jsval *vp) +{ + return CallPropertyOp(cx, obj, id, vp, JSCPK_ARG, JS_FALSE); +} + +static JSBool +SetCallArg(JSContext *cx, JSObject *obj, jsid id, jsval *vp) +{ + return CallPropertyOp(cx, obj, id, vp, JSCPK_ARG, JS_TRUE); +} + +JSBool +js_GetCallVar(JSContext *cx, JSObject *obj, jsid id, jsval *vp) +{ + return CallPropertyOp(cx, obj, id, vp, JSCPK_VAR, JS_FALSE); +} + +static JSBool +SetCallVar(JSContext *cx, JSObject *obj, jsid id, jsval *vp) +{ + return CallPropertyOp(cx, obj, id, vp, JSCPK_VAR, JS_TRUE); +} + static JSBool call_resolve(JSContext *cx, JSObject *obj, jsval idval, uintN flags, JSObject **objp) { JSStackFrame *fp; + JSFunction *fun; jsid id; JSLocalKind localKind; JSPropertyOp getter, setter; @@ -829,8 +833,9 @@ call_resolve(JSContext *cx, JSObject *obj, jsval idval, uintN flags, fp = (JSStackFrame *) JS_GetPrivate(cx, obj); if (!fp) return JS_TRUE; - JS_ASSERT(fp->fun); - JS_ASSERT(GET_FUNCTION_PRIVATE(cx, fp->callee) == fp->fun); + fun = fp->fun; + JS_ASSERT(fun); + JS_ASSERT(GET_FUNCTION_PRIVATE(cx, fp->callee) == fun); if (!JSVAL_IS_STRING(idval)) return JS_TRUE; @@ -838,26 +843,28 @@ call_resolve(JSContext *cx, JSObject *obj, jsval idval, uintN flags, if (!js_ValueToStringId(cx, idval, &id)) return JS_FALSE; - localKind = js_LookupLocal(cx, fp->fun, JSID_TO_ATOM(id), &slot); + localKind = js_LookupLocal(cx, fun, JSID_TO_ATOM(id), &slot); if (localKind != JSLOCAL_NONE) { + JS_ASSERT((uint16) slot == slot); if (localKind == JSLOCAL_ARG) { - JS_ASSERT(slot < fp->fun->nargs); + JS_ASSERT(slot < fun->nargs); vp = fp->argv; - getter = setter = NULL; + getter = js_GetCallArg; + setter = SetCallArg; attrs = JSPROP_PERMANENT; } else { JS_ASSERT(localKind == JSLOCAL_VAR || localKind == JSLOCAL_CONST); - JS_ASSERT(fp->fun->u.i.nvars == fp->nvars); - JS_ASSERT(slot < fp->nvars); + JS_ASSERT(fun->u.i.nvars == fp->nvars); + JS_ASSERT(slot < fun->u.i.nvars); vp = fp->vars; - getter = js_GetCallVariable; - setter = js_SetCallVariable; + getter = js_GetCallVar; + setter = SetCallVar; attrs = (localKind == JSLOCAL_CONST) ? JSPROP_PERMANENT | JSPROP_READONLY : JSPROP_PERMANENT; } if (!js_DefineNativeProperty(cx, obj, id, vp[slot], getter, setter, - attrs, SPROP_HAS_SHORTID, (int) slot, + attrs, SPROP_HAS_SHORTID, (int16) slot, NULL)) { return JS_FALSE; } @@ -871,9 +878,8 @@ call_resolve(JSContext *cx, JSObject *obj, jsval idval, uintN flags, */ if (id == ATOM_TO_JSID(cx->runtime->atomState.argumentsAtom)) { if (!js_DefineNativeProperty(cx, obj, id, JSVAL_VOID, - NULL, NULL, JSPROP_PERMANENT, - SPROP_HAS_SHORTID, CALL_ARGUMENTS, - NULL)) { + GetCallArguments, SetCallArguments, + JSPROP_PERMANENT, 0, 0, NULL)) { return JS_FALSE; } *objp = obj; @@ -902,7 +908,7 @@ JS_FRIEND_DATA(JSClass) js_CallClass = { JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE | JSCLASS_IS_ANONYMOUS | JSCLASS_MARK_IS_TRACE | JSCLASS_HAS_CACHED_PROTO(JSProto_Call), JS_PropertyStub, JS_PropertyStub, - call_getProperty, call_setProperty, + JS_PropertyStub, JS_PropertyStub, call_enumerate, (JSResolveOp)call_resolve, call_convert, JS_FinalizeStub, NULL, NULL, diff --git a/js/src/jsfun.h b/js/src/jsfun.h index fce8c783d121..3f1f03b25382 100644 --- a/js/src/jsfun.h +++ b/js/src/jsfun.h @@ -179,10 +179,10 @@ extern JS_FRIEND_API(JSBool) js_PutCallObject(JSContext *cx, JSStackFrame *fp); extern JSBool -js_GetCallVariable(JSContext *cx, JSObject *obj, jsval id, jsval *vp); +js_GetCallArg(JSContext *cx, JSObject *obj, jsid id, jsval *vp); extern JSBool -js_SetCallVariable(JSContext *cx, JSObject *obj, jsval id, jsval *vp); +js_GetCallVar(JSContext *cx, JSObject *obj, jsval id, jsval *vp); extern JSBool js_GetArgsValue(JSContext *cx, JSStackFrame *fp, jsval *vp);