LCOV - app.info - js/src/jsfun.h

LCOV - code coverage report
| Current view: | directory - js/src - jsfun.h (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 42 | 42 | 100.0 %
| Date: | 2012-04-07 | Functions: | 21 | 21 | 100.0 %

           1                 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
           2                 :  *
           3                 :  * ***** BEGIN LICENSE BLOCK *****
           4                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
           5                 :  *
           6                 :  * The contents of this file are subject to the Mozilla Public License Version
           7                 :  * 1.1 (the "License"); you may not use this file except in compliance with
           8                 :  * the License. You may obtain a copy of the License at
           9                 :  * http://www.mozilla.org/MPL/
          10                 :  *
          11                 :  * Software distributed under the License is distributed on an "AS IS" basis,
          12                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
          13                 :  * for the specific language governing rights and limitations under the
          14                 :  * License.
          15                 :  *
          16                 :  * The Original Code is Mozilla Communicator client code, released
          17                 :  * March 31, 1998.
          18                 :  *
          19                 :  * The Initial Developer of the Original Code is
          20                 :  * Netscape Communications Corporation.
          21                 :  * Portions created by the Initial Developer are Copyright (C) 1998
          22                 :  * the Initial Developer. All Rights Reserved.
          23                 :  *
          24                 :  * Contributor(s):
          25                 :  *
          26                 :  * Alternatively, the contents of this file may be used under the terms of
          27                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
          28                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
          29                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
          30                 :  * of those above. If you wish to allow use of your version of this file only
          31                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
          32                 :  * use your version of this file under the terms of the MPL, indicate your
          33                 :  * decision by deleting the provisions above and replace them with the notice
          34                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
          35                 :  * the provisions above, a recipient may use your version of this file under
          36                 :  * the terms of any one of the MPL, the GPL or the LGPL.
          37                 :  *
          38                 :  * ***** END LICENSE BLOCK ***** */
          39                 :
          40                 : #ifndef jsfun_h___
          41                 : #define jsfun_h___
          42                 : /*
          43                 :  * JS function definitions.
          44                 :  */
          45                 : #include "jsprvtd.h"
          46                 : #include "jspubtd.h"
          47                 : #include "jsobj.h"
          48                 : #include "jsatom.h"
          49                 : #include "jsscript.h"
          50                 : #include "jsstr.h"
          51                 :
          52                 : #include "gc/Barrier.h"
          53                 :
          54                 : /*
          55                 :  * The high two bits of JSFunction.flags encode whether the function is native
          56                 :  * or interpreted, and if interpreted, what kind of optimized closure form (if
          57                 :  * any) it might be.
          58                 :  *
          59                 :  *   00   not interpreted
          60                 :  *   01   interpreted, not null closure
          61                 :  *   11   interpreted, null closure
          62                 :  *
          63                 :  * NB: JSFUN_EXPR_CLOSURE reuses JSFUN_STUB_GSOPS, which is an API request flag
          64                 :  * bit only, never stored in fun->flags.
          65                 :  *
          66                 :  * If we need more bits in the future, all flags for interpreted functions can
          67                 :  * move to u.i.script->flags. For now we use function flag bits to minimize
          68                 :  * pointer-chasing.
          69                 :  */
          70                 : #define JSFUN_PROTOTYPE     0x0800  /* function is Function.prototype for some
          71                 :                                        global object */
          72                 :
          73                 : #define JSFUN_EXPR_CLOSURE  0x1000  /* expression closure: function(x) x*x */
          74                 : #define JSFUN_EXTENDED      0x2000  /* structure is FunctionExtended */
          75                 : #define JSFUN_INTERPRETED   0x4000  /* use u.i if kind >= this value else u.native */
          76                 : #define JSFUN_NULL_CLOSURE  0x8000  /* null closure entrains no scope chain */
          77                 : #define JSFUN_KINDMASK      0xc000  /* encode interp vs. native and closure
          78                 :                                        optimization level -- see above */
          79                 :
          80                 : namespace js { class FunctionExtended; }
          81                 :
          82                 : struct JSFunction : public JSObject
          83                 : {
          84                 :     uint16_t        nargs;        /* maximum number of specified arguments,
          85                 :                                      reflected as f.length/f.arity */
          86                 :     uint16_t        flags;        /* flags, see JSFUN_* below and in jsapi.h */
          87                 :     union U {
          88                 :         js::Native  native;       /* native method pointer or null */
          89                 :         struct Scripted {
          90                 :             JSScript    *script_; /* interpreted bytecode descriptor or null;
          91                 :                                      use the accessor! */
          92                 :             JSObject    *env_;    /* environment for new activations;
          93                 :                                      use the accessor! */
          94                 :         } i;
          95                 :         void            *nativeOrScript;
          96                 :     } u;
          97                 :     js::HeapPtrAtom  atom;        /* name for diagnostics and decompiling */
          98                 :
          99                 :     bool optimizedClosure()  const { return kind() > JSFUN_INTERPRETED; }
         100      1390850588 :     bool isInterpreted()     const { return kind() >= JSFUN_INTERPRETED; }
         101        36140374 :     bool isNative()          const { return !isInterpreted(); }
         102          217580 :     bool isNativeConstructor() const { return flags & JSFUN_CONSTRUCTOR; }
         103        32819539 :     bool isHeavyweight()     const { return JSFUN_HEAVYWEIGHT_TEST(flags); }
         104         1066085 :     bool isNullClosure()     const { return kind() == JSFUN_NULL_CLOSURE; }
         105        10655467 :     bool isFunctionPrototype() const { return flags & JSFUN_PROTOTYPE; }
         106        17004254 :     bool isInterpretedConstructor() const { return isInterpreted() && !isFunctionPrototype(); }
         107                 :
         108      1392233566 :     uint16_t kind()          const { return flags & JSFUN_KINDMASK; }
         109          131003 :     void setKind(uint16_t k) {
         110          131003 :         JS_ASSERT(!(k & ~JSFUN_KINDMASK));
         111          131003 :         flags = (flags & ~JSFUN_KINDMASK) | k;
         112          131003 :     }
         113                 :
         114                 :     /* Returns the strictness of this function, which must be interpreted. */
         115                 :     inline bool inStrictMode() const;
         116                 :
         117          167182 :     void setArgCount(uint16_t nargs) {
         118          167182 :         JS_ASSERT(this->nargs == 0);
         119          167182 :         this->nargs = nargs;
         120          167182 :     }
         121                 :
         122                 :     /* uint16_t representation bounds number of call object dynamic slots. */
         123                 :     enum { MAX_ARGS_AND_VARS = 2 * ((1U << 16) - 1) };
         124                 :
         125                 : #define JS_LOCAL_NAME_TO_ATOM(nameWord)  ((JSAtom *) ((nameWord) & ~uintptr_t(1)))
         126                 : #define JS_LOCAL_NAME_IS_CONST(nameWord) ((((nameWord) & uintptr_t(1))) != 0)
         127                 :
         128                 :     /*
         129                 :      * For an interpreted function, accessors for the initial scope object of
         130                 :      * activations (stack frames) of the function.
         131                 :      */
         132                 :     inline JSObject *environment() const;
         133                 :     inline void setEnvironment(JSObject *obj);
         134                 :     inline void initEnvironment(JSObject *obj);
         135                 :
         136           13848 :     static inline size_t offsetOfEnvironment() { return offsetof(JSFunction, u.i.env_); }
         137                 :
         138      1232152902 :     js::HeapPtrScript &script() const {
         139      1232152902 :         JS_ASSERT(isInterpreted());
         140      1232152902 :         return *(js::HeapPtrScript *)&u.i.script_;
         141                 :     }
         142                 :
         143                 :     inline void setScript(JSScript *script_);
         144                 :     inline void initScript(JSScript *script_);
         145                 :
         146             476 :     JSScript *maybeScript() const {
         147             476 :         return isInterpreted() ? script().get() : NULL;
         148                 :     }
         149                 :
         150        14953801 :     JSNative native() const {
         151        14953801 :         JS_ASSERT(isNative());
         152        14953801 :         return u.native;
         153                 :     }
         154                 :
         155          494910 :     JSNative maybeNative() const {
         156          494910 :         return isInterpreted() ? NULL : native();
         157                 :     }
         158                 :
         159            4235 :     static unsigned offsetOfNativeOrScript() {
         160                 :         JS_STATIC_ASSERT(offsetof(U, native) == offsetof(U, i.script_));
         161                 :         JS_STATIC_ASSERT(offsetof(U, native) == offsetof(U, nativeOrScript));
         162            4235 :         return offsetof(JSFunction, u.nativeOrScript);
         163                 :     }
         164                 :
         165                 : #if JS_BITS_PER_WORD == 32
         166                 : # ifdef JS_THREADSAFE
         167                 :     static const js::gc::AllocKind FinalizeKind = js::gc::FINALIZE_OBJECT2_BACKGROUND;
         168                 :     static const js::gc::AllocKind ExtendedFinalizeKind = js::gc::FINALIZE_OBJECT4_BACKGROUND;
         169                 : # else
         170                 :     static const js::gc::AllocKind FinalizeKind = js::gc::FINALIZE_OBJECT2;
         171                 :     static const js::gc::AllocKind ExtendedFinalizeKind = js::gc::FINALIZE_OBJECT4;
         172                 : # endif
         173                 : #else
         174                 : # ifdef JS_THREADSAFE
         175                 :     static const js::gc::AllocKind FinalizeKind = js::gc::FINALIZE_OBJECT4_BACKGROUND;
         176                 :     static const js::gc::AllocKind ExtendedFinalizeKind = js::gc::FINALIZE_OBJECT8_BACKGROUND;
         177                 : # else
         178                 :     static const js::gc::AllocKind FinalizeKind = js::gc::FINALIZE_OBJECT4;
         179                 :     static const js::gc::AllocKind ExtendedFinalizeKind = js::gc::FINALIZE_OBJECT8;
         180                 : # endif
         181                 : #endif
         182                 :
         183                 :     inline void trace(JSTracer *trc);
         184                 :
         185                 :     /* Bound function accessors. */
         186                 :
         187                 :     inline bool initBoundFunction(JSContext *cx, const js::Value &thisArg,
         188                 :                                   const js::Value *args, unsigned argslen);
         189                 :
         190                 :     inline JSObject *getBoundFunctionTarget() const;
         191                 :     inline const js::Value &getBoundFunctionThis() const;
         192                 :     inline const js::Value &getBoundFunctionArgument(unsigned which) const;
         193                 :     inline size_t getBoundFunctionArgumentCount() const;
         194                 :
         195                 :   private:
         196                 :     inline js::FunctionExtended *toExtended();
         197                 :     inline const js::FunctionExtended *toExtended() const;
         198                 :
         199        18616857 :     inline bool isExtended() const {
         200                 :         JS_STATIC_ASSERT(FinalizeKind != ExtendedFinalizeKind);
         201        18616857 :         JS_ASSERT(!!(flags & JSFUN_EXTENDED) == (getAllocKind() == ExtendedFinalizeKind));
         202        18616857 :         return !!(flags & JSFUN_EXTENDED);
         203                 :     }
         204                 :
         205                 :   public:
         206                 :     /* Accessors for data stored in extended functions. */
         207                 :     inline void initializeExtended();
         208                 :     inline void setExtendedSlot(size_t which, const js::Value &val);
         209                 :     inline const js::Value &getExtendedSlot(size_t which) const;
         210                 :
         211                 :   private:
         212                 :     /*
         213                 :      * These member functions are inherited from JSObject, but should never be applied to
         214                 :      * a value statically known to be a JSFunction.
         215                 :      */
         216                 :     inline JSFunction *toFunction() MOZ_DELETE;
         217                 :     inline const JSFunction *toFunction() const MOZ_DELETE;
         218                 : };
         219                 :
         220                 : inline JSFunction *
         221       138113956 : JSObject::toFunction()
         222                 : {
         223       138113956 :     JS_ASSERT(JS_ObjectIsFunction(NULL, this));
         224       138113956 :     return static_cast<JSFunction *>(this);
         225                 : }
         226                 :
         227                 : inline const JSFunction *
         228                 : JSObject::toFunction() const
         229                 : {
         230                 :     JS_ASSERT(JS_ObjectIsFunction(NULL, const_cast<JSObject *>(this)));
         231                 :     return static_cast<const JSFunction *>(this);
         232                 : }
         233                 :
         234                 : extern JSString *
         235                 : fun_toStringHelper(JSContext *cx, JSObject *obj, unsigned indent);
         236                 :
         237                 : extern JSFunction *
         238                 : js_NewFunction(JSContext *cx, JSObject *funobj, JSNative native, unsigned nargs,
         239                 :                unsigned flags, js::HandleObject parent, JSAtom *atom,
         240                 :                js::gc::AllocKind kind = JSFunction::FinalizeKind);
         241                 :
         242                 : extern JSFunction * JS_FASTCALL
         243                 : js_CloneFunctionObject(JSContext *cx, JSFunction *fun, JSObject *parent, JSObject *proto,
         244                 :                        js::gc::AllocKind kind = JSFunction::FinalizeKind);
         245                 :
         246                 : extern JSFunction *
         247                 : js_DefineFunction(JSContext *cx, js::HandleObject obj, jsid id, JSNative native,
         248                 :                   unsigned nargs, unsigned flags,
         249                 :                   js::gc::AllocKind kind = JSFunction::FinalizeKind);
         250                 :
         251                 : /*
         252                 :  * Flags for js_ValueToFunction and js_ReportIsNotFunction.
         253                 :  */
         254                 : #define JSV2F_CONSTRUCT         INITIAL_CONSTRUCT
         255                 : #define JSV2F_SEARCH_STACK      0x10000
         256                 :
         257                 : extern JSFunction *
         258                 : js_ValueToFunction(JSContext *cx, const js::Value *vp, unsigned flags);
         259                 :
         260                 : extern JSObject *
         261                 : js_ValueToCallableObject(JSContext *cx, js::Value *vp, unsigned flags);
         262                 :
         263                 : extern void
         264                 : js_ReportIsNotFunction(JSContext *cx, const js::Value *vp, unsigned flags);
         265                 :
         266                 : extern void
         267                 : js_PutCallObject(js::StackFrame *fp);
         268                 :
         269                 : namespace js {
         270                 :
         271                 : /*
         272                 :  * Function extended with reserved slots for use by various kinds of functions.
         273                 :  * Most functions do not have these extensions, but enough are that efficient
         274                 :  * storage is required (no malloc'ed reserved slots).
         275                 :  */
         276                 : class FunctionExtended : public JSFunction
         277                 : {
         278                 :     friend struct JSFunction;
         279                 :
         280                 :     /* Reserved slots available for storage by particular native functions. */
         281                 :     HeapValue extendedSlots[2];
         282                 : };
         283                 :
         284                 : } // namespace js
         285                 :
         286                 : inline js::FunctionExtended *
         287         4760142 : JSFunction::toExtended()
         288                 : {
         289         4760142 :     JS_ASSERT(isExtended());
         290         4760142 :     return static_cast<js::FunctionExtended *>(this);
         291                 : }
         292                 :
         293                 : inline const js::FunctionExtended *
         294           10506 : JSFunction::toExtended() const
         295                 : {
         296           10506 :     JS_ASSERT(isExtended());
         297           10506 :     return static_cast<const js::FunctionExtended *>(this);
         298                 : }
         299                 :
         300                 : extern void
         301                 : js_PutArgsObject(js::StackFrame *fp);
         302                 :
         303                 : inline bool
         304          743853 : js_IsNamedLambda(JSFunction *fun) { return (fun->flags & JSFUN_LAMBDA) && fun->atom; }
         305                 :
         306                 : namespace js {
         307                 :
         308                 : template<XDRMode mode>
         309                 : bool
         310                 : XDRInterpretedFunction(XDRState<mode> *xdr, JSObject **objp, JSScript *parentScript);
         311                 :
         312                 : } /* namespace js */
         313                 :
         314                 : extern JSBool
         315                 : js_fun_apply(JSContext *cx, unsigned argc, js::Value *vp);
         316                 :
         317                 : extern JSBool
         318                 : js_fun_call(JSContext *cx, unsigned argc, js::Value *vp);
         319                 :
         320                 : extern JSObject*
         321                 : js_fun_bind(JSContext *cx, js::HandleObject target, js::Value thisArg,
         322                 :             js::Value *boundArgs, unsigned argslen);
         323                 :
         324                 : #endif /* jsfun_h___ */

Generated by: LCOV version 1.7