static JSBool
ArgGetter(JSContext *cx, HandleObject obj, HandleId id, MutableHandleValue vp)
{
    if (!obj->isNormalArguments())
        return true;

    NormalArgumentsObject &argsobj = obj->asNormalArguments();
    if (JSID_IS_INT(id)) {
        /*
         * arg can exceed the number of arguments if a script changed the
         * prototype to point to another Arguments object with a bigger argc.
         */
        unsigned arg = unsigned(JSID_TO_INT(id));
        if (arg < argsobj.initialLength() && !argsobj.isElementDeleted(arg))
            vp.set(argsobj.element(arg));
    } else if (JSID_IS_ATOM(id, cx->names().length)) {
        if (!argsobj.hasOverriddenLength())
            vp.setInt32(argsobj.initialLength());
    } else {
        JS_ASSERT(JSID_IS_ATOM(id, cx->names().callee));
        if (!argsobj.callee().isMagic(JS_OVERWRITTEN_CALLEE))
            vp.set(argsobj.callee());
    }
    return true;
}
Beispiel #2
0
static JSBool
ArgGetter(JSContext *cx, HandleObject obj, HandleId id, Value *vp)
{
    if (!obj->isNormalArguments())
        return true;

    NormalArgumentsObject &argsobj = obj->asNormalArguments();
    if (JSID_IS_INT(id)) {
        /*
         * arg can exceed the number of arguments if a script changed the
         * prototype to point to another Arguments object with a bigger argc.
         */
        unsigned arg = unsigned(JSID_TO_INT(id));
        if (arg < argsobj.initialLength() && !argsobj.isElementDeleted(arg)) {
            if (StackFrame *fp = argsobj.maybeStackFrame()) {
                JS_ASSERT_IF(arg < fp->numFormalArgs(), fp->script()->formalIsAliased(arg));
                *vp = fp->canonicalActualArg(arg);
            } else {
                *vp = argsobj.element(arg);
            }
        }
    } else if (JSID_IS_ATOM(id, cx->runtime->atomState.lengthAtom)) {
        if (!argsobj.hasOverriddenLength())
            vp->setInt32(argsobj.initialLength());
    } else {
        JS_ASSERT(JSID_IS_ATOM(id, cx->runtime->atomState.calleeAtom));
        const Value &v = argsobj.callee();
        if (!v.isMagic(JS_OVERWRITTEN_CALLEE))
            *vp = v;
    }
    return true;
}
static JSBool
ArgSetter(JSContext *cx, HandleObject obj, HandleId id, JSBool strict, MutableHandleValue vp)
{
    if (!obj->isNormalArguments())
        return true;

    unsigned attrs;
    if (!baseops::GetAttributes(cx, obj, id, &attrs))
        return false;
    JS_ASSERT(!(attrs & JSPROP_READONLY));
    attrs &= (JSPROP_ENUMERATE | JSPROP_PERMANENT); /* only valid attributes */

    NormalArgumentsObject &argsobj = obj->asNormalArguments();
    RootedScript script(cx, argsobj.containingScript());

    if (JSID_IS_INT(id)) {
        unsigned arg = unsigned(JSID_TO_INT(id));
        if (arg < argsobj.initialLength() && !argsobj.isElementDeleted(arg)) {
            argsobj.setElement(arg, vp);
            if (arg < script->function()->nargs) {
                if (!script->ensureHasTypes(cx))
                    return false;
                types::TypeScript::SetArgument(cx, script, arg, vp);
            }
            return true;
        }
    } else {
        JS_ASSERT(JSID_IS_ATOM(id, cx->names().length) || JSID_IS_ATOM(id, cx->names().callee));
    }

    /*
     * For simplicity we use delete/define to replace the property with one
     * backed by the default Object getter and setter. Note that we rely on
     * args_delProperty to clear the corresponding reserved slot so the GC can
     * collect its value. Note also that we must define the property instead
     * of setting it in case the user has changed the prototype to an object
     * that has a setter for this id.
     */
    RootedValue value(cx);
    return baseops::DeleteGeneric(cx, obj, id, &value, false) &&
           baseops::DefineGeneric(cx, obj, id, vp, NULL, NULL, attrs);
}
Beispiel #4
0
static JSBool
ArgSetter(JSContext *cx, HandleObject obj, HandleId id, JSBool strict, Value *vp)
{
    if (!obj->isNormalArguments())
        return true;

    NormalArgumentsObject &argsobj = obj->asNormalArguments();

    if (JSID_IS_INT(id)) {
        unsigned arg = unsigned(JSID_TO_INT(id));
        if (arg < argsobj.initialLength()) {
            if (StackFrame *fp = argsobj.maybeStackFrame()) {
                JSScript *script = fp->functionScript();
                JS_ASSERT(script->needsArgsObj());
                if (arg < fp->numFormalArgs()) {
                    JS_ASSERT(fp->script()->formalIsAliased(arg));
                    types::TypeScript::SetArgument(cx, script, arg, *vp);
                }
                fp->canonicalActualArg(arg) = *vp;
                return true;
            }
        }
    } else {
        JS_ASSERT(JSID_IS_ATOM(id, cx->runtime->atomState.lengthAtom) ||
                  JSID_IS_ATOM(id, cx->runtime->atomState.calleeAtom));
    }

    /*
     * For simplicity we use delete/define to replace the property with one
     * backed by the default Object getter and setter. Note that we rely on
     * args_delProperty to clear the corresponding reserved slot so the GC can
     * collect its value. Note also that we must define the property instead
     * of setting it in case the user has changed the prototype to an object
     * that has a setter for this id.
     */
    RootedVarValue value(cx);
    return baseops::DeleteGeneric(cx, obj, id, value.address(), false) &&
           baseops::DefineProperty(cx, obj, id, vp, NULL, NULL, JSPROP_ENUMERATE);
}