Пример #1
0
bool
js::XDRInterpretedFunction(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript enclosingScript,
                           MutableHandleObject objp)
{
    /* NB: Keep this in sync with CloneInterpretedFunction. */
    Rooted<JSAtom*> atom(xdr->cx());
    uint32_t firstword;           /* flag telling whether fun->atom is non-null,
                                   plus for fun->u.i.skipmin, fun->u.i.wrapper,
                                   and 14 bits reserved for future use */
    uint32_t flagsword;           /* word for argument count and fun->flags */

    JSContext *cx = xdr->cx();
    RootedFunction fun(cx);
    JSScript *script;
    if (mode == XDR_ENCODE) {
        fun = objp->toFunction();
        if (!fun->isInterpreted()) {
            JSAutoByteString funNameBytes;
            if (const char *name = GetFunctionNameBytes(cx, fun, &funNameBytes)) {
                JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NOT_SCRIPTED_FUNCTION,
                                     name);
            }
            return false;
        }
        firstword = !!fun->atom;
        flagsword = (fun->nargs << 16) | fun->flags;
        atom = fun->atom;
        script = fun->script();
    } else {
        RootedObject parent(cx, NULL);
        fun = js_NewFunction(cx, NULL, NULL, 0, JSFUN_INTERPRETED, parent, NULL);
        if (!fun)
            return false;
        if (!JSObject::clearParent(cx, fun))
            return false;
        if (!JSObject::clearType(cx, fun))
            return false;
        atom = NULL;
        script = NULL;
    }

    if (!xdr->codeUint32(&firstword))
        return false;
    if ((firstword & 1U) && !XDRAtom(xdr, atom.address()))
        return false;
    if (!xdr->codeUint32(&flagsword))
        return false;

    if (!XDRScript(xdr, enclosingScope, enclosingScript, fun, &script))
        return false;

    if (mode == XDR_DECODE) {
        fun->nargs = flagsword >> 16;
        fun->flags = uint16_t(flagsword);
        fun->atom.init(atom);
        fun->initScript(script);
        script->setFunction(fun);
        if (!fun->setTypeForScriptedFunction(cx))
            return false;
        JS_ASSERT(fun->nargs == fun->script()->bindings.numArgs());
        js_CallNewScriptHook(cx, fun->script(), fun);
        objp.set(fun);
    }