js/src/jsfun.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     2  * vim: set ts=8 sts=4 et sw=4 tw=99:
     3  * This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #ifndef jsfun_h
     8 #define jsfun_h
    10 /*
    11  * JS function definitions.
    12  */
    14 #include "jsobj.h"
    15 #include "jsscript.h"
    16 #include "jstypes.h"
    18 namespace js {
    19 class FunctionExtended;
    21 typedef JSNative           Native;
    22 typedef JSParallelNative   ParallelNative;
    23 typedef JSThreadSafeNative ThreadSafeNative;
    24 }
    26 struct JSAtomState;
    28 class JSFunction : public JSObject
    29 {
    30   public:
    31     static const js::Class class_;
    33     enum Flags {
    34         INTERPRETED      = 0x0001,  /* function has a JSScript and environment. */
    35         NATIVE_CTOR      = 0x0002,  /* native that can be called as a constructor */
    36         EXTENDED         = 0x0004,  /* structure is FunctionExtended */
    37         IS_FUN_PROTO     = 0x0010,  /* function is Function.prototype for some global object */
    38         EXPR_CLOSURE     = 0x0020,  /* expression closure: function(x) x*x */
    39         HAS_GUESSED_ATOM = 0x0040,  /* function had no explicit name, but a
    40                                        name was guessed for it anyway */
    41         LAMBDA           = 0x0080,  /* function comes from a FunctionExpression, ArrowFunction, or
    42                                        Function() call (not a FunctionDeclaration or nonstandard
    43                                        function-statement) */
    44         SELF_HOSTED      = 0x0100,  /* function is self-hosted builtin and must not be
    45                                        decompilable nor constructible. */
    46         SELF_HOSTED_CTOR = 0x0200,  /* function is self-hosted builtin constructor and
    47                                        must be constructible but not decompilable. */
    48         HAS_REST         = 0x0400,  /* function has a rest (...) parameter */
    49         // 0x0800 is available
    50         INTERPRETED_LAZY = 0x1000,  /* function is interpreted but doesn't have a script yet */
    51         ARROW            = 0x2000,  /* ES6 '(args) => body' syntax */
    53         /* Derived Flags values for convenience: */
    54         NATIVE_FUN = 0,
    55         NATIVE_LAMBDA_FUN = NATIVE_FUN | LAMBDA,
    56         INTERPRETED_LAMBDA = INTERPRETED | LAMBDA,
    57         INTERPRETED_LAMBDA_ARROW = INTERPRETED | LAMBDA | ARROW
    58     };
    60     static void staticAsserts() {
    61         JS_STATIC_ASSERT(INTERPRETED == JS_FUNCTION_INTERPRETED_BIT);
    62         static_assert(sizeof(JSFunction) == sizeof(js::shadow::Function),
    63                       "shadow interface must match actual interface");
    64     }
    66   private:
    67     uint16_t        nargs_;       /* number of formal arguments
    68                                      (including defaults and the rest parameter unlike f.length) */
    69     uint16_t        flags_;       /* bitfield composed of the above Flags enum */
    70     union U {
    71         class Native {
    72             friend class JSFunction;
    73             js::Native          native;       /* native method pointer or null */
    74             const JSJitInfo     *jitinfo;     /* Information about this function to be
    75                                                  used by the JIT;
    76                                                  use the accessor! */
    77         } n;
    78         struct Scripted {
    79             union {
    80                 JSScript *script_; /* interpreted bytecode descriptor or null;
    81                                       use the accessor! */
    82                 js::LazyScript *lazy_; /* lazily compiled script, or nullptr */
    83             } s;
    84             JSObject    *env_;    /* environment for new activations;
    85                                      use the accessor! */
    86         } i;
    87         void            *nativeOrScript;
    88     } u;
    89     js::HeapPtrAtom  atom_;       /* name for diagnostics and decompiling */
    91   public:
    93     /* Call objects must be created for each invocation of a heavyweight function. */
    94     bool isHeavyweight() const {
    95         JS_ASSERT(!isInterpretedLazy());
    97         if (isNative())
    98             return false;
   100         // Note: this should be kept in sync with FunctionBox::isHeavyweight().
   101         return nonLazyScript()->hasAnyAliasedBindings() ||
   102                nonLazyScript()->funHasExtensibleScope() ||
   103                nonLazyScript()->funNeedsDeclEnvObject() ||
   104                isGenerator();
   105     }
   107     size_t nargs() const {
   108         return nargs_;
   109     }
   111     uint16_t flags() const {
   112         return flags_;
   113     }
   115     /* A function can be classified as either native (C++) or interpreted (JS): */
   116     bool isInterpreted()            const { return flags() & (INTERPRETED | INTERPRETED_LAZY); }
   117     bool isNative()                 const { return !isInterpreted(); }
   119     /* Possible attributes of a native function: */
   120     bool isNativeConstructor()      const { return flags() & NATIVE_CTOR; }
   122     /* Possible attributes of an interpreted function: */
   123     bool isFunctionPrototype()      const { return flags() & IS_FUN_PROTO; }
   124     bool isExprClosure()            const { return flags() & EXPR_CLOSURE; }
   125     bool hasGuessedAtom()           const { return flags() & HAS_GUESSED_ATOM; }
   126     bool isLambda()                 const { return flags() & LAMBDA; }
   127     bool isSelfHostedBuiltin()      const { return flags() & SELF_HOSTED; }
   128     bool isSelfHostedConstructor()  const { return flags() & SELF_HOSTED_CTOR; }
   129     bool hasRest()                  const { return flags() & HAS_REST; }
   131     bool isInterpretedLazy()        const {
   132         return flags() & INTERPRETED_LAZY;
   133     }
   134     bool hasScript()                const {
   135         return flags() & INTERPRETED;
   136     }
   138     bool hasJITCode() const {
   139         if (!hasScript())
   140             return false;
   142         return nonLazyScript()->hasBaselineScript() || nonLazyScript()->hasIonScript();
   143     }
   145     // Arrow functions store their lexical |this| in the first extended slot.
   146     bool isArrow()                  const { return flags() & ARROW; }
   148     /* Compound attributes: */
   149     bool isBuiltin() const {
   150         return isNative() || isSelfHostedBuiltin();
   151     }
   152     bool isInterpretedConstructor() const {
   153         // Note: the JITs inline this check, so be careful when making changes
   154         // here. See IonMacroAssembler::branchIfNotInterpretedConstructor.
   155         return isInterpreted() && !isFunctionPrototype() && !isArrow() &&
   156                (!isSelfHostedBuiltin() || isSelfHostedConstructor());
   157     }
   158     bool isNamedLambda() const {
   159         return isLambda() && displayAtom() && !hasGuessedAtom();
   160     }
   161     bool hasParallelNative() const {
   162         return isNative() && jitInfo() && jitInfo()->hasParallelNative();
   163     }
   165     bool isBuiltinFunctionConstructor();
   167     /* Returns the strictness of this function, which must be interpreted. */
   168     bool strict() const {
   169         return nonLazyScript()->strict();
   170     }
   172     void setFlags(uint16_t flags) {
   173         this->flags_ = flags;
   174     }
   176     // Can be called multiple times by the parser.
   177     void setArgCount(uint16_t nargs) {
   178         this->nargs_ = nargs;
   179     }
   181     // Can be called multiple times by the parser.
   182     void setHasRest() {
   183         flags_ |= HAS_REST;
   184     }
   186     void setIsSelfHostedBuiltin() {
   187         JS_ASSERT(!isSelfHostedBuiltin());
   188         flags_ |= SELF_HOSTED;
   189     }
   191     void setIsSelfHostedConstructor() {
   192         JS_ASSERT(!isSelfHostedConstructor());
   193         flags_ |= SELF_HOSTED_CTOR;
   194     }
   196     void setIsFunctionPrototype() {
   197         JS_ASSERT(!isFunctionPrototype());
   198         flags_ |= IS_FUN_PROTO;
   199     }
   201     // Can be called multiple times by the parser.
   202     void setIsExprClosure() {
   203         flags_ |= EXPR_CLOSURE;
   204     }
   206     void setArrow() {
   207         flags_ |= ARROW;
   208     }
   210     JSAtom *atom() const { return hasGuessedAtom() ? nullptr : atom_.get(); }
   211     js::PropertyName *name() const { return hasGuessedAtom() || !atom_ ? nullptr : atom_->asPropertyName(); }
   212     void initAtom(JSAtom *atom) { atom_.init(atom); }
   214     JSAtom *displayAtom() const {
   215         return atom_;
   216     }
   218     void setGuessedAtom(JSAtom *atom) {
   219         JS_ASSERT(atom_ == nullptr);
   220         JS_ASSERT(atom != nullptr);
   221         JS_ASSERT(!hasGuessedAtom());
   222         atom_ = atom;
   223         flags_ |= HAS_GUESSED_ATOM;
   224     }
   226     /* uint16_t representation bounds number of call object dynamic slots. */
   227     enum { MAX_ARGS_AND_VARS = 2 * ((1U << 16) - 1) };
   229     /*
   230      * For an interpreted function, accessors for the initial scope object of
   231      * activations (stack frames) of the function.
   232      */
   233     JSObject *environment() const {
   234         JS_ASSERT(isInterpreted());
   235         return u.i.env_;
   236     }
   238     void setEnvironment(JSObject *obj) {
   239         JS_ASSERT(isInterpreted());
   240         *(js::HeapPtrObject *)&u.i.env_ = obj;
   241     }
   243     void initEnvironment(JSObject *obj) {
   244         JS_ASSERT(isInterpreted());
   245         ((js::HeapPtrObject *)&u.i.env_)->init(obj);
   246     }
   248     static inline size_t offsetOfNargs() { return offsetof(JSFunction, nargs_); }
   249     static inline size_t offsetOfFlags() { return offsetof(JSFunction, flags_); }
   250     static inline size_t offsetOfEnvironment() { return offsetof(JSFunction, u.i.env_); }
   251     static inline size_t offsetOfAtom() { return offsetof(JSFunction, atom_); }
   253     static bool createScriptForLazilyInterpretedFunction(JSContext *cx, js::HandleFunction fun);
   254     void relazify(JSTracer *trc);
   256     // Function Scripts
   257     //
   258     // Interpreted functions may either have an explicit JSScript (hasScript())
   259     // or be lazy with sufficient information to construct the JSScript if
   260     // necessary (isInterpretedLazy()).
   261     //
   262     // A lazy function will have a LazyScript if the function came from parsed
   263     // source, or nullptr if the function is a clone of a self hosted function.
   264     //
   265     // There are several methods to get the script of an interpreted function:
   266     //
   267     // - For all interpreted functions, getOrCreateScript() will get the
   268     //   JSScript, delazifying the function if necessary. This is the safest to
   269     //   use, but has extra checks, requires a cx and may trigger a GC.
   270     //
   271     // - For inlined functions which may have a LazyScript but whose JSScript
   272     //   is known to exist, existingScriptForInlinedFunction() will get the
   273     //   script and delazify the function if necessary.
   274     //
   275     // - For functions known to have a JSScript, nonLazyScript() will get it.
   277     JSScript *getOrCreateScript(JSContext *cx) {
   278         JS_ASSERT(isInterpreted());
   279         JS_ASSERT(cx);
   280         if (isInterpretedLazy()) {
   281             JS::RootedFunction self(cx, this);
   282             if (!createScriptForLazilyInterpretedFunction(cx, self))
   283                 return nullptr;
   284             return self->nonLazyScript();
   285         }
   286         return nonLazyScript();
   287     }
   289     JSScript *existingScriptForInlinedFunction() {
   290         MOZ_ASSERT(isInterpreted());
   291         if (isInterpretedLazy()) {
   292             // Get the script from the canonical function. Ion used the
   293             // canonical function to inline the script and because it has
   294             // Baseline code it has not been relazified. Note that we can't
   295             // use lazyScript->script_ here as it may be null in some cases,
   296             // see bug 976536.
   297             js::LazyScript *lazy = lazyScript();
   298             JSFunction *fun = lazy->functionNonDelazifying();
   299             MOZ_ASSERT(fun);
   300             JSScript *script = fun->nonLazyScript();
   302             if (shadowZone()->needsBarrier())
   303                 js::LazyScript::writeBarrierPre(lazy);
   305             flags_ &= ~INTERPRETED_LAZY;
   306             flags_ |= INTERPRETED;
   307             initScript(script);
   308         }
   309         return nonLazyScript();
   310     }
   312     JSScript *nonLazyScript() const {
   313         JS_ASSERT(hasScript());
   314         JS_ASSERT(u.i.s.script_);
   315         return u.i.s.script_;
   316     }
   318     // Returns non-callsited-clone version of this.  Use when return
   319     // value can flow to arbitrary JS (see Bug 944975).
   320     JSFunction* originalFunction() {
   321         if (this->hasScript() && this->nonLazyScript()->isCallsiteClone()) {
   322             return this->nonLazyScript()->donorFunction();
   323         } else {
   324             return this;
   325         }
   326     }
   328     js::HeapPtrScript &mutableScript() {
   329         JS_ASSERT(isInterpreted());
   330         return *(js::HeapPtrScript *)&u.i.s.script_;
   331     }
   333     js::LazyScript *lazyScript() const {
   334         JS_ASSERT(isInterpretedLazy() && u.i.s.lazy_);
   335         return u.i.s.lazy_;
   336     }
   338     js::LazyScript *lazyScriptOrNull() const {
   339         JS_ASSERT(isInterpretedLazy());
   340         return u.i.s.lazy_;
   341     }
   343     js::GeneratorKind generatorKind() const {
   344         if (!isInterpreted())
   345             return js::NotGenerator;
   346         if (hasScript())
   347             return nonLazyScript()->generatorKind();
   348         if (js::LazyScript *lazy = lazyScriptOrNull())
   349             return lazy->generatorKind();
   350         JS_ASSERT(isSelfHostedBuiltin());
   351         return js::NotGenerator;
   352     }
   354     bool isGenerator() const { return generatorKind() != js::NotGenerator; }
   356     bool isLegacyGenerator() const { return generatorKind() == js::LegacyGenerator; }
   358     bool isStarGenerator() const { return generatorKind() == js::StarGenerator; }
   360     void setScript(JSScript *script_) {
   361         JS_ASSERT(hasScript());
   362         mutableScript() = script_;
   363     }
   365     void initScript(JSScript *script_) {
   366         JS_ASSERT(hasScript());
   367         mutableScript().init(script_);
   368     }
   370     void setUnlazifiedScript(JSScript *script) {
   371         // Note: createScriptForLazilyInterpretedFunction triggers a barrier on
   372         // lazy script before it is overwritten here.
   373         JS_ASSERT(isInterpretedLazy());
   374         if (!lazyScript()->maybeScript())
   375             lazyScript()->initScript(script);
   376         flags_ &= ~INTERPRETED_LAZY;
   377         flags_ |= INTERPRETED;
   378         initScript(script);
   379     }
   381     void initLazyScript(js::LazyScript *lazy) {
   382         JS_ASSERT(isInterpreted());
   383         flags_ &= ~INTERPRETED;
   384         flags_ |= INTERPRETED_LAZY;
   385         u.i.s.lazy_ = lazy;
   386     }
   388     JSNative native() const {
   389         JS_ASSERT(isNative());
   390         return u.n.native;
   391     }
   393     JSNative maybeNative() const {
   394         return isInterpreted() ? nullptr : native();
   395     }
   397     JSParallelNative parallelNative() const {
   398         JS_ASSERT(hasParallelNative());
   399         return jitInfo()->parallelNative;
   400     }
   402     JSParallelNative maybeParallelNative() const {
   403         return hasParallelNative() ? parallelNative() : nullptr;
   404     }
   406     void initNative(js::Native native, const JSJitInfo *jitinfo) {
   407         JS_ASSERT(native);
   408         u.n.native = native;
   409         u.n.jitinfo = jitinfo;
   410     }
   412     const JSJitInfo *jitInfo() const {
   413         JS_ASSERT(isNative());
   414         return u.n.jitinfo;
   415     }
   417     void setJitInfo(const JSJitInfo *data) {
   418         JS_ASSERT(isNative());
   419         u.n.jitinfo = data;
   420     }
   422     static unsigned offsetOfNativeOrScript() {
   423         JS_STATIC_ASSERT(offsetof(U, n.native) == offsetof(U, i.s.script_));
   424         JS_STATIC_ASSERT(offsetof(U, n.native) == offsetof(U, nativeOrScript));
   425         return offsetof(JSFunction, u.nativeOrScript);
   426     }
   428 #if JS_BITS_PER_WORD == 32
   429     static const js::gc::AllocKind FinalizeKind = js::gc::FINALIZE_OBJECT2_BACKGROUND;
   430     static const js::gc::AllocKind ExtendedFinalizeKind = js::gc::FINALIZE_OBJECT4_BACKGROUND;
   431 #else
   432     static const js::gc::AllocKind FinalizeKind = js::gc::FINALIZE_OBJECT4_BACKGROUND;
   433     static const js::gc::AllocKind ExtendedFinalizeKind = js::gc::FINALIZE_OBJECT8_BACKGROUND;
   434 #endif
   436     inline void trace(JSTracer *trc);
   438     /* Bound function accessors. */
   440     inline bool initBoundFunction(JSContext *cx, js::HandleValue thisArg,
   441                                   const js::Value *args, unsigned argslen);
   443     JSObject *getBoundFunctionTarget() const {
   444         JS_ASSERT(isBoundFunction());
   446         /* Bound functions abuse |parent| to store their target function. */
   447         return getParent();
   448     }
   450     const js::Value &getBoundFunctionThis() const;
   451     const js::Value &getBoundFunctionArgument(unsigned which) const;
   452     size_t getBoundFunctionArgumentCount() const;
   454   private:
   455     inline js::FunctionExtended *toExtended();
   456     inline const js::FunctionExtended *toExtended() const;
   458   public:
   459     inline bool isExtended() const {
   460         JS_STATIC_ASSERT(FinalizeKind != ExtendedFinalizeKind);
   461         JS_ASSERT_IF(isTenured(), !!(flags() & EXTENDED) == (tenuredGetAllocKind() == ExtendedFinalizeKind));
   462         return !!(flags() & EXTENDED);
   463     }
   465     /*
   466      * Accessors for data stored in extended functions. Use setExtendedSlot if
   467      * the function has already been initialized. Otherwise use
   468      * initExtendedSlot.
   469      */
   470     inline void initializeExtended();
   471     inline void initExtendedSlot(size_t which, const js::Value &val);
   472     inline void setExtendedSlot(size_t which, const js::Value &val);
   473     inline const js::Value &getExtendedSlot(size_t which) const;
   475     /* Constructs a new type for the function if necessary. */
   476     static bool setTypeForScriptedFunction(js::ExclusiveContext *cx, js::HandleFunction fun,
   477                                            bool singleton = false);
   479     /* GC support. */
   480     js::gc::AllocKind getAllocKind() const {
   481         js::gc::AllocKind kind = FinalizeKind;
   482         if (isExtended())
   483             kind = ExtendedFinalizeKind;
   484         JS_ASSERT_IF(isTenured(), kind == tenuredGetAllocKind());
   485         return kind;
   486     }
   487 };
   489 extern JSString *
   490 fun_toStringHelper(JSContext *cx, js::HandleObject obj, unsigned indent);
   492 inline JSFunction::Flags
   493 JSAPIToJSFunctionFlags(unsigned flags)
   494 {
   495     return (flags & JSFUN_CONSTRUCTOR)
   496            ? JSFunction::NATIVE_CTOR
   497            : JSFunction::NATIVE_FUN;
   498 }
   500 namespace js {
   502 extern bool
   503 Function(JSContext *cx, unsigned argc, Value *vp);
   505 extern bool
   506 Generator(JSContext *cx, unsigned argc, Value *vp);
   508 extern JSFunction *
   509 NewFunction(ExclusiveContext *cx, HandleObject funobj, JSNative native, unsigned nargs,
   510             JSFunction::Flags flags, HandleObject parent, HandleAtom atom,
   511             gc::AllocKind allocKind = JSFunction::FinalizeKind,
   512             NewObjectKind newKind = GenericObject);
   514 // If proto is nullptr, Function.prototype is used instead.
   515 extern JSFunction *
   516 NewFunctionWithProto(ExclusiveContext *cx, HandleObject funobj, JSNative native, unsigned nargs,
   517                      JSFunction::Flags flags, HandleObject parent, HandleAtom atom,
   518                      JSObject *proto, gc::AllocKind allocKind = JSFunction::FinalizeKind,
   519                      NewObjectKind newKind = GenericObject);
   521 extern JSFunction *
   522 DefineFunction(JSContext *cx, HandleObject obj, HandleId id, JSNative native,
   523                unsigned nargs, unsigned flags,
   524                gc::AllocKind allocKind = JSFunction::FinalizeKind,
   525                NewObjectKind newKind = GenericObject);
   527 bool
   528 FunctionHasResolveHook(const JSAtomState &atomState, PropertyName *name);
   530 extern bool
   531 fun_resolve(JSContext *cx, HandleObject obj, HandleId id, MutableHandleObject objp);
   533 // ES6 9.2.5 IsConstructor
   534 bool IsConstructor(const Value &v);
   536 /*
   537  * Function extended with reserved slots for use by various kinds of functions.
   538  * Most functions do not have these extensions, but enough do that efficient
   539  * storage is required (no malloc'ed reserved slots).
   540  */
   541 class FunctionExtended : public JSFunction
   542 {
   543   public:
   544     static const unsigned NUM_EXTENDED_SLOTS = 2;
   546     /* Arrow functions store their lexical |this| in the first extended slot. */
   547     static const unsigned ARROW_THIS_SLOT = 0;
   549     static inline size_t offsetOfExtendedSlot(unsigned which) {
   550         MOZ_ASSERT(which < NUM_EXTENDED_SLOTS);
   551         return offsetof(FunctionExtended, extendedSlots) + which * sizeof(HeapValue);
   552     }
   553     static inline size_t offsetOfArrowThisSlot() {
   554         return offsetOfExtendedSlot(ARROW_THIS_SLOT);
   555     }
   557   private:
   558     friend class JSFunction;
   560     /* Reserved slots available for storage by particular native functions. */
   561     HeapValue extendedSlots[NUM_EXTENDED_SLOTS];
   562 };
   564 extern JSFunction *
   565 CloneFunctionObject(JSContext *cx, HandleFunction fun, HandleObject parent,
   566                     gc::AllocKind kind = JSFunction::FinalizeKind,
   567                     NewObjectKind newKindArg = GenericObject);
   570 extern bool
   571 FindBody(JSContext *cx, HandleFunction fun, ConstTwoByteChars chars, size_t length,
   572          size_t *bodyStart, size_t *bodyEnd);
   574 } // namespace js
   576 inline js::FunctionExtended *
   577 JSFunction::toExtended()
   578 {
   579     JS_ASSERT(isExtended());
   580     return static_cast<js::FunctionExtended *>(this);
   581 }
   583 inline const js::FunctionExtended *
   584 JSFunction::toExtended() const
   585 {
   586     JS_ASSERT(isExtended());
   587     return static_cast<const js::FunctionExtended *>(this);
   588 }
   590 inline void
   591 JSFunction::initializeExtended()
   592 {
   593     JS_ASSERT(isExtended());
   595     JS_ASSERT(mozilla::ArrayLength(toExtended()->extendedSlots) == 2);
   596     toExtended()->extendedSlots[0].init(js::UndefinedValue());
   597     toExtended()->extendedSlots[1].init(js::UndefinedValue());
   598 }
   600 inline void
   601 JSFunction::initExtendedSlot(size_t which, const js::Value &val)
   602 {
   603     JS_ASSERT(which < mozilla::ArrayLength(toExtended()->extendedSlots));
   604     toExtended()->extendedSlots[which].init(val);
   605 }
   607 inline void
   608 JSFunction::setExtendedSlot(size_t which, const js::Value &val)
   609 {
   610     JS_ASSERT(which < mozilla::ArrayLength(toExtended()->extendedSlots));
   611     toExtended()->extendedSlots[which] = val;
   612 }
   614 inline const js::Value &
   615 JSFunction::getExtendedSlot(size_t which) const
   616 {
   617     JS_ASSERT(which < mozilla::ArrayLength(toExtended()->extendedSlots));
   618     return toExtended()->extendedSlots[which];
   619 }
   621 namespace js {
   623 JSString *FunctionToString(JSContext *cx, HandleFunction fun, bool bodyOnly, bool lambdaParen);
   625 template<XDRMode mode>
   626 bool
   627 XDRInterpretedFunction(XDRState<mode> *xdr, HandleObject enclosingScope,
   628                        HandleScript enclosingScript, MutableHandleObject objp);
   630 extern JSObject *
   631 CloneFunctionAndScript(JSContext *cx, HandleObject enclosingScope, HandleFunction fun);
   633 /*
   634  * Report an error that call.thisv is not compatible with the specified class,
   635  * assuming that the method (clasp->name).prototype.<name of callee function>
   636  * is what was called.
   637  */
   638 extern void
   639 ReportIncompatibleMethod(JSContext *cx, CallReceiver call, const Class *clasp);
   641 /*
   642  * Report an error that call.thisv is not an acceptable this for the callee
   643  * function.
   644  */
   645 extern void
   646 ReportIncompatible(JSContext *cx, CallReceiver call);
   648 bool
   649 CallOrConstructBoundFunction(JSContext *, unsigned, js::Value *);
   651 extern const JSFunctionSpec function_methods[];
   653 } /* namespace js */
   655 extern bool
   656 js_fun_apply(JSContext *cx, unsigned argc, js::Value *vp);
   658 extern bool
   659 js_fun_call(JSContext *cx, unsigned argc, js::Value *vp);
   661 extern JSObject*
   662 js_fun_bind(JSContext *cx, js::HandleObject target, js::HandleValue thisArg,
   663             js::Value *boundArgs, unsigned argslen);
   665 #ifdef DEBUG
   666 namespace JS {
   667 namespace detail {
   669 JS_PUBLIC_API(void)
   670 CheckIsValidConstructible(Value calleev);
   672 } // namespace detail
   673 } // namespace JS
   674 #endif
   676 #endif /* jsfun_h */

mercurial