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