js/src/jsfuninlines.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/js/src/jsfuninlines.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,90 @@
     1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     1.5 + * vim: set ts=8 sts=4 et sw=4 tw=99:
     1.6 + * This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +#ifndef jsfuninlines_h
    1.11 +#define jsfuninlines_h
    1.12 +
    1.13 +#include "jsfun.h"
    1.14 +
    1.15 +#include "vm/ScopeObject.h"
    1.16 +
    1.17 +namespace js {
    1.18 +
    1.19 +inline const char *
    1.20 +GetFunctionNameBytes(JSContext *cx, JSFunction *fun, JSAutoByteString *bytes)
    1.21 +{
    1.22 +    JSAtom *atom = fun->atom();
    1.23 +    if (atom)
    1.24 +        return bytes->encodeLatin1(cx, atom);
    1.25 +    return js_anonymous_str;
    1.26 +}
    1.27 +
    1.28 +static inline JSObject *
    1.29 +SkipScopeParent(JSObject *parent)
    1.30 +{
    1.31 +    if (!parent)
    1.32 +        return nullptr;
    1.33 +    while (parent->is<ScopeObject>())
    1.34 +        parent = &parent->as<ScopeObject>().enclosingScope();
    1.35 +    return parent;
    1.36 +}
    1.37 +
    1.38 +inline bool
    1.39 +CanReuseFunctionForClone(JSContext *cx, HandleFunction fun)
    1.40 +{
    1.41 +    if (!fun->hasSingletonType())
    1.42 +        return false;
    1.43 +    if (fun->isInterpretedLazy()) {
    1.44 +        LazyScript *lazy = fun->lazyScript();
    1.45 +        if (lazy->hasBeenCloned())
    1.46 +            return false;
    1.47 +        lazy->setHasBeenCloned();
    1.48 +    } else {
    1.49 +        JSScript *script = fun->nonLazyScript();
    1.50 +        if (script->hasBeenCloned())
    1.51 +            return false;
    1.52 +        script->setHasBeenCloned();
    1.53 +    }
    1.54 +    return true;
    1.55 +}
    1.56 +
    1.57 +inline JSFunction *
    1.58 +CloneFunctionObjectIfNotSingleton(JSContext *cx, HandleFunction fun, HandleObject parent,
    1.59 +                                  NewObjectKind newKind = GenericObject)
    1.60 +{
    1.61 +    /*
    1.62 +     * For attempts to clone functions at a function definition opcode,
    1.63 +     * try to avoid the the clone if the function has singleton type. This
    1.64 +     * was called pessimistically, and we need to preserve the type's
    1.65 +     * property that if it is singleton there is only a single object
    1.66 +     * with its type in existence.
    1.67 +     *
    1.68 +     * For functions inner to run once lambda, it may be possible that
    1.69 +     * the lambda runs multiple times and we repeatedly clone it. In these
    1.70 +     * cases, fall through to CloneFunctionObject, which will deep clone
    1.71 +     * the function's script.
    1.72 +     */
    1.73 +    if (CanReuseFunctionForClone(cx, fun)) {
    1.74 +        RootedObject obj(cx, SkipScopeParent(parent));
    1.75 +        if (!JSObject::setParent(cx, fun, obj))
    1.76 +            return nullptr;
    1.77 +        fun->setEnvironment(parent);
    1.78 +        return fun;
    1.79 +    }
    1.80 +
    1.81 +    // These intermediate variables are needed to avoid link errors on some
    1.82 +    // platforms.  Sigh.
    1.83 +    gc::AllocKind finalizeKind = JSFunction::FinalizeKind;
    1.84 +    gc::AllocKind extendedFinalizeKind = JSFunction::ExtendedFinalizeKind;
    1.85 +    gc::AllocKind kind = fun->isExtended()
    1.86 +                         ? extendedFinalizeKind
    1.87 +                         : finalizeKind;
    1.88 +    return CloneFunctionObject(cx, fun, parent, kind, newKind);
    1.89 +}
    1.90 +
    1.91 +} /* namespace js */
    1.92 +
    1.93 +#endif /* jsfuninlines_h */

mercurial