Imported Upstream version 1.0.0
[platform/upstream/js.git] / js / src / jsfun.h
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 #include "jsopcode.h"
52
53 /*
54  * The high two bits of JSFunction.flags encode whether the function is native
55  * or interpreted, and if interpreted, what kind of optimized closure form (if
56  * any) it might be.
57  *
58  *   00   not interpreted
59  *   01   interpreted, neither flat nor null closure
60  *   10   interpreted, flat closure
61  *   11   interpreted, null closure
62  *
63  * FUN_FLAT_CLOSURE implies FUN_INTERPRETED and u.i.script->upvarsOffset != 0.
64  * FUN_NULL_CLOSURE implies FUN_INTERPRETED and u.i.script->upvarsOffset == 0.
65  *
66  * FUN_INTERPRETED but not FUN_FLAT_CLOSURE and u.i.script->upvarsOffset != 0
67  * is an Algol-like function expression or nested function, i.e., a function
68  * that never escapes upward or downward (heapward), and is only ever called.
69  *
70  * Finally, FUN_INTERPRETED and u.i.script->upvarsOffset == 0 could be either
71  * a non-closure (a global function definition, or any function that uses no
72  * outer names), or a closure of an escaping function that uses outer names
73  * whose values can't be snapshot (because the outer names could be reassigned
74  * after the closure is formed, or because assignments could not be analyzed
75  * due to with or eval).
76  *
77  * Such a hard-case function must use JSOP_NAME, etc., and reify outer function
78  * activations' call objects, etc. if it's not a global function.
79  *
80  * NB: JSFUN_EXPR_CLOSURE reuses JSFUN_STUB_GSOPS, which is an API request flag
81  * bit only, never stored in fun->flags.
82  *
83  * If we need more bits in the future, all flags for FUN_INTERPRETED functions
84  * can move to u.i.script->flags. For now we use function flag bits to minimize
85  * pointer-chasing.
86  */
87 #define JSFUN_JOINABLE      0x0001  /* function is null closure that does not
88                                        appear to call itself via its own name
89                                        or arguments.callee */
90
91 #define JSFUN_PROTOTYPE     0x0800  /* function is Function.prototype for some
92                                        global object */
93
94 #define JSFUN_EXPR_CLOSURE  0x1000  /* expression closure: function(x) x*x */
95 #define JSFUN_TRCINFO       0x2000  /* when set, u.n.trcinfo is non-null,
96                                        JSFunctionSpec::call points to a
97                                        JSNativeTraceInfo. */
98 #define JSFUN_INTERPRETED   0x4000  /* use u.i if kind >= this value else u.n */
99 #define JSFUN_FLAT_CLOSURE  0x8000  /* flag (aka "display") closure */
100 #define JSFUN_NULL_CLOSURE  0xc000  /* null closure entrains no scope chain */
101 #define JSFUN_KINDMASK      0xc000  /* encode interp vs. native and closure
102                                        optimization level -- see above */
103
104 #define FUN_OBJECT(fun)      (static_cast<JSObject *>(fun))
105 #define FUN_KIND(fun)        ((fun)->flags & JSFUN_KINDMASK)
106 #define FUN_SET_KIND(fun,k)  ((fun)->flags = ((fun)->flags & ~JSFUN_KINDMASK) | (k))
107 #define FUN_INTERPRETED(fun) (FUN_KIND(fun) >= JSFUN_INTERPRETED)
108 #define FUN_FLAT_CLOSURE(fun)(FUN_KIND(fun) == JSFUN_FLAT_CLOSURE)
109 #define FUN_NULL_CLOSURE(fun)(FUN_KIND(fun) == JSFUN_NULL_CLOSURE)
110 #define FUN_SCRIPT(fun)      (FUN_INTERPRETED(fun) ? (fun)->u.i.script : NULL)
111 #define FUN_CLASP(fun)       (JS_ASSERT(!FUN_INTERPRETED(fun)),               \
112                               fun->u.n.clasp)
113 #define FUN_TRCINFO(fun)     (JS_ASSERT(!FUN_INTERPRETED(fun)),               \
114                               JS_ASSERT((fun)->flags & JSFUN_TRCINFO),        \
115                               fun->u.n.trcinfo)
116
117 struct JSFunction : public JSObject_Slots2
118 {
119     /* Functions always have two fixed slots (FUN_CLASS_RESERVED_SLOTS). */
120
121     uint16          nargs;        /* maximum number of specified arguments,
122                                      reflected as f.length/f.arity */
123     uint16          flags;        /* flags, see JSFUN_* below and in jsapi.h */
124     union U {
125         struct {
126             js::Native  native;   /* native method pointer or null */
127             js::Class   *clasp;   /* class of objects constructed
128                                      by this function */
129             JSNativeTraceInfo *trcinfo;
130         } n;
131         struct Scripted {
132             JSScript    *script;  /* interpreted bytecode descriptor or null */
133             uint16       skipmin; /* net skip amount up (toward zero) from
134                                      script->staticLevel to nearest upvar,
135                                      including upvars in nested functions */
136             JSPackedBool wrapper; /* true if this function is a wrapper that
137                                      rewrites bytecode optimized for a function
138                                      judged non-escaping by the compiler, which
139                                      then escaped via the debugger or a rogue
140                                      indirect eval; if true, then this function
141                                      object's proto is the wrapped object */
142             js::Shape   *names;   /* argument and variable names */
143         } i;
144         void            *nativeOrScript;
145     } u;
146     JSAtom          *atom;        /* name for diagnostics and decompiling */
147
148     bool optimizedClosure()  const { return FUN_KIND(this) > JSFUN_INTERPRETED; }
149     bool needsWrapper()      const { return FUN_NULL_CLOSURE(this) && u.i.skipmin != 0; }
150     bool isInterpreted()     const { return FUN_INTERPRETED(this); }
151     bool isNative()          const { return !FUN_INTERPRETED(this); }
152     bool isConstructor()     const { return flags & JSFUN_CONSTRUCTOR; }
153     bool isHeavyweight()     const { return JSFUN_HEAVYWEIGHT_TEST(flags); }
154     bool isFlatClosure()     const { return FUN_KIND(this) == JSFUN_FLAT_CLOSURE; }
155
156     bool isFunctionPrototype() const { return flags & JSFUN_PROTOTYPE; }
157
158     /* Returns the strictness of this function, which must be interpreted. */
159     inline bool inStrictMode() const;
160
161     void setArgCount(uint16 nargs) {
162         JS_ASSERT(this->nargs == 0);
163         this->nargs = nargs;
164     }
165
166     /* uint16 representation bounds number of call object dynamic slots. */
167     enum { MAX_ARGS_AND_VARS = 2 * ((1U << 16) - 1) };
168
169 #define JS_LOCAL_NAME_TO_ATOM(nameWord)  ((JSAtom *) ((nameWord) & ~(jsuword) 1))
170 #define JS_LOCAL_NAME_IS_CONST(nameWord) ((((nameWord) & (jsuword) 1)) != 0)
171
172     bool mightEscape() const {
173         return isInterpreted() && (isFlatClosure() || !script()->bindings.hasUpvars());
174     }
175
176     bool joinable() const {
177         return flags & JSFUN_JOINABLE;
178     }
179
180     JSObject &compiledFunObj() {
181         return *this;
182     }
183
184   private:
185     /*
186      * js_FunctionClass reserves two slots, which are free in JSObject::fslots
187      * without requiring dslots allocation. Null closures that can be joined to
188      * a compiler-created function object use the first one to hold a mutable
189      * methodAtom() state variable, needed for correct foo.caller handling.
190      */
191     enum {
192         METHOD_ATOM_SLOT  = JSSLOT_FUN_METHOD_ATOM
193     };
194
195   public:
196     void setJoinable() {
197         JS_ASSERT(FUN_INTERPRETED(this));
198         getSlotRef(METHOD_ATOM_SLOT).setNull();
199         flags |= JSFUN_JOINABLE;
200     }
201
202     /*
203      * Method name imputed from property uniquely assigned to or initialized,
204      * where the function does not need to be cloned to carry a scope chain or
205      * flattened upvars.
206      */
207     JSAtom *methodAtom() const {
208         return (joinable() && getSlot(METHOD_ATOM_SLOT).isString())
209                ? STRING_TO_ATOM(getSlot(METHOD_ATOM_SLOT).toString())
210                : NULL;
211     }
212
213     void setMethodAtom(JSAtom *atom) {
214         JS_ASSERT(joinable());
215         getSlotRef(METHOD_ATOM_SLOT).setString(ATOM_TO_STRING(atom));
216     }
217
218     js::Native maybeNative() const {
219         return isInterpreted() ? NULL : u.n.native;
220     }
221
222     JSScript *script() const {
223         JS_ASSERT(isInterpreted());
224         return u.i.script;
225     }
226
227     static uintN offsetOfNativeOrScript() {
228         JS_STATIC_ASSERT(offsetof(U, n.native) == offsetof(U, i.script));
229         JS_STATIC_ASSERT(offsetof(U, n.native) == offsetof(U, nativeOrScript));
230         return offsetof(JSFunction, u.nativeOrScript);
231     }
232
233     /* Number of extra fixed function object slots. */
234     static const uint32 CLASS_RESERVED_SLOTS = JSObject::FUN_CLASS_RESERVED_SLOTS;
235 };
236
237 /*
238  * Trace-annotated native. This expands to a JSFunctionSpec initializer (like
239  * JS_FN in jsapi.h). fastcall is a FastNative; trcinfo is a
240  * JSNativeTraceInfo*.
241  */
242 #ifdef JS_TRACER
243 /* MSVC demands the intermediate (void *) cast here. */
244 # define JS_TN(name,fastcall,nargs,flags,trcinfo)                             \
245     JS_FN(name, JS_DATA_TO_FUNC_PTR(Native, trcinfo), nargs,                  \
246           (flags) | JSFUN_STUB_GSOPS | JSFUN_TRCINFO)
247 #else
248 # define JS_TN(name,fastcall,nargs,flags,trcinfo)                             \
249     JS_FN(name, fastcall, nargs, flags)
250 #endif
251
252 /*
253  * NB: the Arguments classes are uninitialized internal classes that masquerade
254  * (according to Object.prototype.toString.call(arguments)) as "Arguments",
255  * while having Object.getPrototypeOf(arguments) === Object.prototype.
256  *
257  * WARNING (to alert embedders reading this private .h file): arguments objects
258  * are *not* thread-safe and should not be used concurrently -- they should be
259  * used by only one thread at a time, preferably by only one thread over their
260  * lifetime (a JS worker that migrates from one OS thread to another but shares
261  * nothing is ok).
262  *
263  * Yes, this is an incompatible change, which prefigures the impending move to
264  * single-threaded objects and GC heaps.
265  */
266 extern js::Class js_ArgumentsClass;
267
268 namespace js {
269
270 extern Class StrictArgumentsClass;
271
272 struct ArgumentsData {
273     js::Value   callee;
274     js::Value   slots[1];
275 };
276
277 }
278
279 inline bool
280 JSObject::isNormalArguments() const
281 {
282     return getClass() == &js_ArgumentsClass;
283 }
284
285 inline bool
286 JSObject::isStrictArguments() const
287 {
288     return getClass() == &js::StrictArgumentsClass;
289 }
290
291 inline bool
292 JSObject::isArguments() const
293 {
294     return isNormalArguments() || isStrictArguments();
295 }
296
297 #define JS_ARGUMENTS_OBJECT_ON_TRACE ((void *)0xa126)
298
299 extern JS_PUBLIC_DATA(js::Class) js_CallClass;
300 extern JS_PUBLIC_DATA(js::Class) js_FunctionClass;
301 extern js::Class js_DeclEnvClass;
302
303 inline bool
304 JSObject::isCall() const
305 {
306     return getClass() == &js_CallClass;
307 }
308
309 inline bool
310 JSObject::isFunction() const
311 {
312     return getClass() == &js_FunctionClass;
313 }
314
315 inline JSFunction *
316 JSObject::getFunctionPrivate() const
317 {
318     JS_ASSERT(isFunction());
319     return reinterpret_cast<JSFunction *>(getPrivate());
320 }
321
322 namespace js {
323
324 /*
325  * Construct a call object for the given bindings.  If this is a call object
326  * for a function invocation, callee should be the function being called.
327  * Otherwise it must be a call object for eval of strict mode code, and callee
328  * must be null.
329  */
330 extern JSObject *
331 NewCallObject(JSContext *cx, js::Bindings *bindings, JSObject &scopeChain, JSObject *callee);
332
333 /*
334  * NB: jsapi.h and jsobj.h must be included before any call to this macro.
335  */
336 #define VALUE_IS_FUNCTION(cx, v)                                              \
337     (!JSVAL_IS_PRIMITIVE(v) && JSVAL_TO_OBJECT(v)->isFunction())
338
339 static JS_ALWAYS_INLINE bool
340 IsFunctionObject(const js::Value &v)
341 {
342     return v.isObject() && v.toObject().isFunction();
343 }
344
345 static JS_ALWAYS_INLINE bool
346 IsFunctionObject(const js::Value &v, JSObject **funobj)
347 {
348     return v.isObject() && (*funobj = &v.toObject())->isFunction();
349 }
350
351 static JS_ALWAYS_INLINE bool
352 IsFunctionObject(const js::Value &v, JSFunction **fun)
353 {
354     JSObject *funobj;
355     bool b = IsFunctionObject(v, &funobj);
356     if (b)
357         *fun = funobj->getFunctionPrivate();
358     return b;
359 }
360
361 extern JS_ALWAYS_INLINE bool
362 SameTraceType(const Value &lhs, const Value &rhs)
363 {
364     return SameType(lhs, rhs) &&
365            (lhs.isPrimitive() ||
366             lhs.toObject().isFunction() == rhs.toObject().isFunction());
367 }
368
369 /*
370  * Macro to access the private slot of the function object after the slot is
371  * initialized.
372  */
373 #define GET_FUNCTION_PRIVATE(cx, funobj)                                      \
374     (JS_ASSERT((funobj)->isFunction()),                                       \
375      (JSFunction *) (funobj)->getPrivate())
376
377 /*
378  * Return true if this is a compiler-created internal function accessed by
379  * its own object. Such a function object must not be accessible to script
380  * or embedding code.
381  */
382 inline bool
383 IsInternalFunctionObject(JSObject *funobj)
384 {
385     JS_ASSERT(funobj->isFunction());
386     JSFunction *fun = (JSFunction *) funobj->getPrivate();
387     return funobj == fun && (fun->flags & JSFUN_LAMBDA) && !funobj->getParent();
388 }
389     
390 /* Valueified JS_IsConstructing. */
391 static JS_ALWAYS_INLINE bool
392 IsConstructing(const Value *vp)
393 {
394 #ifdef DEBUG
395     JSObject *callee = &JS_CALLEE(cx, vp).toObject();
396     if (callee->isFunction()) {
397         JSFunction *fun = callee->getFunctionPrivate();
398         JS_ASSERT((fun->flags & JSFUN_CONSTRUCTOR) != 0);
399     } else {
400         JS_ASSERT(callee->getClass()->construct != NULL);
401     }
402 #endif
403     return vp[1].isMagic();
404 }
405
406 static JS_ALWAYS_INLINE bool
407 IsConstructing_PossiblyWithGivenThisObject(const Value *vp, JSObject **ctorThis)
408 {
409 #ifdef DEBUG
410     JSObject *callee = &JS_CALLEE(cx, vp).toObject();
411     if (callee->isFunction()) {
412         JSFunction *fun = callee->getFunctionPrivate();
413         JS_ASSERT((fun->flags & JSFUN_CONSTRUCTOR) != 0);
414     } else {
415         JS_ASSERT(callee->getClass()->construct != NULL);
416     }
417 #endif
418     bool isCtor = vp[1].isMagic();
419     if (isCtor)
420         *ctorThis = vp[1].getMagicObjectOrNullPayload();
421     return isCtor;
422 }
423
424 inline const char *
425 GetFunctionNameBytes(JSContext *cx, JSFunction *fun, JSAutoByteString *bytes)
426 {
427     if (fun->atom)
428         return bytes->encode(cx, ATOM_TO_STRING(fun->atom));
429     return js_anonymous_str;
430 }
431
432 extern JS_FRIEND_API(bool)
433 IsBuiltinFunctionConstructor(JSFunction *fun);
434
435 /*
436  * Preconditions: funobj->isInterpreted() && !funobj->isFunctionPrototype() &&
437  * !funobj->isBoundFunction(). This is sufficient to establish that funobj has
438  * a non-configurable non-method .prototype data property, thought it might not
439  * have been resolved yet, and its value could be anything.
440  *
441  * Return the shape of the .prototype property of funobj, resolving it if
442  * needed. On error, return NULL.
443  *
444  * This is not safe to call on trace because it defines properties, which can
445  * trigger lookups that could reenter.
446  */
447 const Shape *
448 LookupInterpretedFunctionPrototype(JSContext *cx, JSObject *funobj);
449
450 } /* namespace js */
451
452 extern JSString *
453 fun_toStringHelper(JSContext *cx, JSObject *obj, uintN indent);
454
455 extern JSFunction *
456 js_NewFunction(JSContext *cx, JSObject *funobj, js::Native native, uintN nargs,
457                uintN flags, JSObject *parent, JSAtom *atom);
458
459 extern JSObject *
460 js_InitFunctionClass(JSContext *cx, JSObject *obj);
461
462 extern JSObject *
463 js_InitArgumentsClass(JSContext *cx, JSObject *obj);
464
465 extern void
466 js_TraceFunction(JSTracer *trc, JSFunction *fun);
467
468 extern void
469 js_FinalizeFunction(JSContext *cx, JSFunction *fun);
470
471 extern JSObject * JS_FASTCALL
472 js_CloneFunctionObject(JSContext *cx, JSFunction *fun, JSObject *parent,
473                        JSObject *proto);
474
475 inline JSObject *
476 CloneFunctionObject(JSContext *cx, JSFunction *fun, JSObject *parent)
477 {
478     JS_ASSERT(parent);
479     JSObject *proto;
480     if (!js_GetClassPrototype(cx, parent, JSProto_Function, &proto))
481         return NULL;
482     return js_CloneFunctionObject(cx, fun, parent, proto);
483 }
484
485 extern JSObject * JS_FASTCALL
486 js_AllocFlatClosure(JSContext *cx, JSFunction *fun, JSObject *scopeChain);
487
488 extern JSObject *
489 js_NewFlatClosure(JSContext *cx, JSFunction *fun, JSOp op, size_t oplen);
490
491 extern JS_REQUIRES_STACK JSObject *
492 js_NewDebuggableFlatClosure(JSContext *cx, JSFunction *fun);
493
494 extern JSFunction *
495 js_DefineFunction(JSContext *cx, JSObject *obj, jsid id, js::Native native,
496                   uintN nargs, uintN flags);
497
498 /*
499  * Flags for js_ValueToFunction and js_ReportIsNotFunction.  We depend on the
500  * fact that JSINVOKE_CONSTRUCT (aka JSFRAME_CONSTRUCTING) is 1, and test that
501  * with #if/#error in jsfun.c.
502  */
503 #define JSV2F_CONSTRUCT         JSINVOKE_CONSTRUCT
504 #define JSV2F_SEARCH_STACK      0x10000
505
506 extern JSFunction *
507 js_ValueToFunction(JSContext *cx, const js::Value *vp, uintN flags);
508
509 extern JSObject *
510 js_ValueToFunctionObject(JSContext *cx, js::Value *vp, uintN flags);
511
512 extern JSObject *
513 js_ValueToCallableObject(JSContext *cx, js::Value *vp, uintN flags);
514
515 extern void
516 js_ReportIsNotFunction(JSContext *cx, const js::Value *vp, uintN flags);
517
518 extern JSObject *
519 js_GetCallObject(JSContext *cx, JSStackFrame *fp);
520
521 extern JSObject * JS_FASTCALL
522 js_CreateCallObjectOnTrace(JSContext *cx, JSFunction *fun, JSObject *callee, JSObject *scopeChain);
523
524 extern void
525 js_PutCallObject(JSContext *cx, JSStackFrame *fp);
526
527 extern JSBool JS_FASTCALL
528 js_PutCallObjectOnTrace(JSContext *cx, JSObject *scopeChain, uint32 nargs,
529                         js::Value *argv, uint32 nvars, js::Value *slots);
530
531 namespace js {
532
533 extern JSBool
534 GetCallArg(JSContext *cx, JSObject *obj, jsid id, js::Value *vp);
535
536 extern JSBool
537 GetCallVar(JSContext *cx, JSObject *obj, jsid id, js::Value *vp);
538
539 /*
540  * Slower version of js_GetCallVar used when call_resolve detects an attempt to
541  * leak an optimized closure via indirect or debugger eval.
542  */
543 extern JSBool
544 GetCallVarChecked(JSContext *cx, JSObject *obj, jsid id, js::Value *vp);
545
546 extern JSBool
547 GetCallUpvar(JSContext *cx, JSObject *obj, jsid id, js::Value *vp);
548
549 extern JSBool
550 SetCallArg(JSContext *cx, JSObject *obj, jsid id, JSBool strict, js::Value *vp);
551
552 extern JSBool
553 SetCallVar(JSContext *cx, JSObject *obj, jsid id, JSBool strict, js::Value *vp);
554
555 extern JSBool
556 SetCallUpvar(JSContext *cx, JSObject *obj, jsid id, JSBool strict, js::Value *vp);
557
558 } // namespace js
559
560 extern JSBool
561 js_GetArgsValue(JSContext *cx, JSStackFrame *fp, js::Value *vp);
562
563 extern JSBool
564 js_GetArgsProperty(JSContext *cx, JSStackFrame *fp, jsid id, js::Value *vp);
565
566 /*
567  * Get the arguments object for the given frame.  If the frame is strict mode
568  * code, its current arguments will be copied into the arguments object.
569  *
570  * NB: Callers *must* get the arguments object before any parameters are
571  *     mutated when the frame is strict mode code!  The emitter ensures this
572  *     occurs for strict mode functions containing syntax which might mutate a
573  *     named parameter by synthesizing an arguments access at the start of the
574  *     function.
575  */
576 extern JSObject *
577 js_GetArgsObject(JSContext *cx, JSStackFrame *fp);
578
579 extern void
580 js_PutArgsObject(JSContext *cx, JSStackFrame *fp);
581
582 inline bool
583 js_IsNamedLambda(JSFunction *fun) { return (fun->flags & JSFUN_LAMBDA) && fun->atom; }
584
585 /*
586  * Maximum supported value of arguments.length. It bounds the maximum number of
587  * arguments that can be supplied via the second (so-called |argArray|) param
588  * to Function.prototype.apply. This value also bounds the number of elements
589  * parsed in an array initialiser.
590  *
591  * The thread's stack is the limiting factor for this number. It is currently
592  * 2MB, which fits a little less than 2^19 arguments (once the stack frame,
593  * callstack, etc. are included). Pick a max args length that is a little less.
594  */
595 const uint32 JS_ARGS_LENGTH_MAX = JS_BIT(19) - 1024;
596
597 /*
598  * JSSLOT_ARGS_LENGTH stores ((argc << 1) | overwritten_flag) as an Int32
599  * Value.  Thus (JS_ARGS_LENGTH_MAX << 1) | 1 must be less than JSVAL_INT_MAX.
600  */
601 JS_STATIC_ASSERT(JS_ARGS_LENGTH_MAX <= JS_BIT(30));
602 JS_STATIC_ASSERT(((JS_ARGS_LENGTH_MAX << 1) | 1) <= JSVAL_INT_MAX);
603
604 extern JSBool
605 js_XDRFunctionObject(JSXDRState *xdr, JSObject **objp);
606
607 extern JSBool
608 js_fun_apply(JSContext *cx, uintN argc, js::Value *vp);
609
610 extern JSBool
611 js_fun_call(JSContext *cx, uintN argc, js::Value *vp);
612
613 #endif /* jsfun_h___ */