uintN i, dupflag;
uintN i, n, dupflag;
fun_xdrObject(JSXDRState *xdr, JSObject **objp){    JSContext *cx;    JSFunction *fun;    JSString *atomstr;    char *propname;    JSScopeProperty *sprop;    jsid userid;    JSAtom *atom;    uintN i, dupflag;    uint32 type;#ifdef DEBUG    uintN nvars = 0, nargs = 0;#endif    cx = xdr->cx;    if (xdr->mode == JSXDR_ENCODE) {        /*         * No valid function object should lack private data, but fail soft         * (return true, no error report) in case one does due to API pilot         * or internal error.         */        fun = (JSFunction *) JS_GetPrivate(cx, *objp);        if (!fun)            return JS_TRUE;        atomstr = fun->atom ? ATOM_TO_STRING(fun->atom) : NULL;    } else {        fun = js_NewFunction(cx, NULL, NULL, 0, 0, NULL, NULL);        if (!fun)            return JS_FALSE;        atomstr = NULL;    }    if (!JS_XDRStringOrNull(xdr, &atomstr) ||        !JS_XDRUint16(xdr, &fun->nargs) ||        !JS_XDRUint16(xdr, &fun->extra) ||        !JS_XDRUint16(xdr, &fun->nvars) ||        !JS_XDRUint8(xdr, &fun->flags)) {        return JS_FALSE;    }    /* do arguments and local vars */    if (fun->object) {        if (xdr->mode == JSXDR_ENCODE) {            JSScope *scope = OBJ_SCOPE(fun->object);            for (sprop = SCOPE_LAST_PROP(scope); sprop;                 sprop = sprop->parent) {                JSPropertyOp getter = sprop->getter;                if (getter == js_GetArgument) {                    type = JSXDR_FUNARG;                    JS_ASSERT(nargs++ <= fun->nargs);                } else if (getter == js_GetLocalVariable) {                    type = (sprop->attrs & JSPROP_READONLY)                           ? JSXDR_FUNCONST                           : JSXDR_FUNVAR;                    JS_ASSERT(nvars++ <= fun->nvars);                } else {                    continue;                }                JS_ASSERT(sprop->flags & SPROP_HAS_SHORTID);                userid = INT_TO_JSVAL(sprop->shortid);                propname = ATOM_BYTES((JSAtom *)sprop->id);                if (!JS_XDRUint32(xdr, &type) ||                    !JS_XDRUint32(xdr, (uint32 *)&userid) ||                    !JS_XDRCString(xdr, &propname)) {                    return JS_FALSE;                }            }        } else {            JSPropertyOp getter, setter;            i = fun->nvars + fun->nargs;            while (i--) {                uintN attrs = JSPROP_ENUMERATE | JSPROP_PERMANENT;                if (!JS_XDRUint32(xdr, &type) ||                    !JS_XDRUint32(xdr, (uint32 *)&userid) ||                    !JS_XDRCString(xdr, &propname)) {                    return JS_FALSE;                }                JS_ASSERT(type == JSXDR_FUNARG || type == JSXDR_FUNVAR ||                          type == JSXDR_FUNCONST);                if (type == JSXDR_FUNARG) {                    getter = js_GetArgument;                    setter = js_SetArgument;                    JS_ASSERT(nargs++ <= fun->nargs);                } else if (type == JSXDR_FUNVAR || type == JSXDR_FUNCONST) {                    getter = js_GetLocalVariable;                    setter = js_SetLocalVariable;                    if (type == JSXDR_FUNCONST)                        attrs |= JSPROP_READONLY;                    JS_ASSERT(nvars++ <= fun->nvars);                } else {                    getter = NULL;                    setter = NULL;                }                atom = js_Atomize(cx, propname, strlen(propname), 0);                JS_free(cx, propname);                if (!atom)                    return JS_FALSE;                /* Flag duplicate argument if atom is bound in fun->object. */                dupflag = SCOPE_GET_PROPERTY(OBJ_SCOPE(fun->object), (jsid)atom)                          ? SPROP_IS_DUPLICATE                          : 0;                if (!js_AddNativeProperty(cx, fun->object, (jsid)atom,                                          getter, setter, SPROP_INVALID_SLOT,                                          attrs | JSPROP_SHARED,                                          SPROP_HAS_SHORTID | dupflag,                                          JSVAL_TO_INT(userid))) {                    return JS_FALSE;                }            }        }    }    if (!js_XDRScript(xdr, &fun->script, NULL))        return JS_FALSE;    if (xdr->mode == JSXDR_DECODE) {        *objp = fun->object;        if (atomstr) {            fun->atom = js_AtomizeString(cx, atomstr, 0);            if (!fun->atom)                return JS_FALSE;            if (!OBJ_DEFINE_PROPERTY(cx, cx->globalObject,                                     (jsid)fun->atom, OBJECT_TO_JSVAL(*objp),                                     NULL, NULL, JSPROP_ENUMERATE,                                     NULL)) {                return JS_FALSE;            }        }        js_CallNewScriptHook(cx, fun->script, fun);    }    return JS_TRUE;}