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 */