Merge mozilla-central and tracemonkey. (a=blockers)
[mozilla-central.git] / js / src / jsscript.h
blob7394abe95f3c37743cadd2c5dbe7a685d8407421
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: set ts=4 sw=4 et tw=79 ft=cpp:
4 * ***** BEGIN LICENSE BLOCK *****
5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
15 * License.
17 * The Original Code is Mozilla Communicator client code, released
18 * March 31, 1998.
20 * The Initial Developer of the Original Code is
21 * Netscape Communications Corporation.
22 * Portions created by the Initial Developer are Copyright (C) 1998
23 * the Initial Developer. All Rights Reserved.
25 * Contributor(s):
27 * Alternatively, the contents of this file may be used under the terms of
28 * either of the GNU General Public License Version 2 or later (the "GPL"),
29 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 * in which case the provisions of the GPL or the LGPL are applicable instead
31 * of those above. If you wish to allow use of your version of this file only
32 * under the terms of either the GPL or the LGPL, and not to allow others to
33 * use your version of this file under the terms of the MPL, indicate your
34 * decision by deleting the provisions above and replace them with the notice
35 * and other provisions required by the GPL or the LGPL. If you do not delete
36 * the provisions above, a recipient may use your version of this file under
37 * the terms of any one of the MPL, the GPL or the LGPL.
39 * ***** END LICENSE BLOCK ***** */
41 #ifndef jsscript_h___
42 #define jsscript_h___
44 * JS script descriptor.
46 #include "jsatom.h"
47 #include "jsprvtd.h"
48 #include "jsdbgapi.h"
49 #include "jsclist.h"
52 * Type of try note associated with each catch or finally block, and also with
53 * for-in loops.
55 typedef enum JSTryNoteKind {
56 JSTRY_CATCH,
57 JSTRY_FINALLY,
58 JSTRY_ITER
59 } JSTryNoteKind;
61 namespace js {
64 * Indicates a location in the stack that an upvar value can be retrieved from
65 * as a two tuple of (level, slot).
67 * Some existing client code uses the level value as a delta, or level "skip"
68 * quantity. We could probably document that through use of more types at some
69 * point in the future.
71 * Existing XDR code wants this to be backed by a 32b integer for serialization,
72 * so we oblige.
74 * TODO: consider giving more bits to the slot value and takings ome from the level.
76 class UpvarCookie
78 uint32 value;
80 static const uint32 FREE_VALUE = 0xfffffffful;
82 void checkInvariants() {
83 JS_STATIC_ASSERT(sizeof(UpvarCookie) == sizeof(uint32));
84 JS_STATIC_ASSERT(UPVAR_LEVEL_LIMIT < FREE_LEVEL);
87 public:
89 * All levels above-and-including FREE_LEVEL are reserved so that
90 * FREE_VALUE can be used as a special value.
92 static const uint16 FREE_LEVEL = 0x3fff;
95 * If a function has a higher static level than this limit, we will not
96 * optimize it using UPVAR opcodes.
98 static const uint16 UPVAR_LEVEL_LIMIT = 16;
99 static const uint16 CALLEE_SLOT = 0xffff;
100 static bool isLevelReserved(uint16 level) { return level >= FREE_LEVEL; }
102 bool isFree() const { return value == FREE_VALUE; }
103 uint32 asInteger() const { return value; }
104 /* isFree check should be performed before using these accessors. */
105 uint16 level() const { JS_ASSERT(!isFree()); return uint16(value >> 16); }
106 uint16 slot() const { JS_ASSERT(!isFree()); return uint16(value); }
108 void set(const UpvarCookie &other) { set(other.level(), other.slot()); }
109 void set(uint16 newLevel, uint16 newSlot) { value = (uint32(newLevel) << 16) | newSlot; }
110 void makeFree() { set(0xffff, 0xffff); JS_ASSERT(isFree()); }
111 void fromInteger(uint32 u32) { value = u32; }
117 * Exception handling record.
119 struct JSTryNote {
120 uint8 kind; /* one of JSTryNoteKind */
121 uint8 padding; /* explicit padding on uint16 boundary */
122 uint16 stackDepth; /* stack depth upon exception handler entry */
123 uint32 start; /* start of the try statement or for-in loop
124 relative to script->main */
125 uint32 length; /* length of the try statement or for-in loop */
128 typedef struct JSTryNoteArray {
129 JSTryNote *vector; /* array of indexed try notes */
130 uint32 length; /* count of indexed try notes */
131 } JSTryNoteArray;
133 typedef struct JSObjectArray {
134 JSObject **vector; /* array of indexed objects */
135 uint32 length; /* count of indexed objects */
136 } JSObjectArray;
138 typedef struct JSUpvarArray {
139 js::UpvarCookie *vector; /* array of indexed upvar cookies */
140 uint32 length; /* count of indexed upvar cookies */
141 } JSUpvarArray;
143 typedef struct JSConstArray {
144 js::Value *vector; /* array of indexed constant values */
145 uint32 length;
146 } JSConstArray;
148 struct JSArenaPool;
150 namespace js {
152 struct GlobalSlotArray {
153 struct Entry {
154 uint32 atomIndex; /* index into atom table */
155 uint32 slot; /* global obj slot number */
157 Entry *vector;
158 uint32 length;
161 struct Shape;
163 enum BindingKind { NONE, ARGUMENT, VARIABLE, CONSTANT, UPVAR };
166 * Formal parameters, local variables, and upvars are stored in a shape tree
167 * path encapsulated within this class. This class represents bindings for
168 * both function and top-level scripts (the latter is needed to track names in
169 * strict mode eval code, to give such code its own lexical environment).
171 class Bindings {
172 js::Shape *lastBinding;
173 uint16 nargs;
174 uint16 nvars;
175 uint16 nupvars;
177 public:
178 inline Bindings(JSContext *cx);
181 * Transfers ownership of bindings data from bindings into this fresh
182 * Bindings instance. Once such a transfer occurs, the old bindings must
183 * not be used again.
185 inline void transfer(JSContext *cx, Bindings *bindings);
188 * Clones bindings data from bindings, which must be immutable, into this
189 * fresh Bindings instance. A Bindings instance may be cloned multiple
190 * times.
192 inline void clone(JSContext *cx, Bindings *bindings);
194 uint16 countArgs() const { return nargs; }
195 uint16 countVars() const { return nvars; }
196 uint16 countUpvars() const { return nupvars; }
198 uintN countArgsAndVars() const { return nargs + nvars; }
200 uintN countLocalNames() const { return nargs + nvars + nupvars; }
202 bool hasUpvars() const { return nupvars > 0; }
203 bool hasLocalNames() const { return countLocalNames() > 0; }
205 /* Returns the shape lineage generated for these bindings. */
206 inline const js::Shape *lastShape() const;
208 enum {
210 * A script may have no more than this many arguments, variables, or
211 * upvars.
213 BINDING_COUNT_LIMIT = 0xFFFF
217 * Add a local binding for the given name, of the given type, for the code
218 * being compiled. If fun is non-null, this binding set is being created
219 * for that function, so adjust corresponding metadata in that function
220 * while adding. Otherwise this set must correspond to a top-level script.
222 * A binding may be added twice with different kinds; the last one for a
223 * given name prevails. (We preserve both bindings for the decompiler,
224 * which must deal with such cases.) Pass null for name when indicating a
225 * destructuring argument. Return true on success.
227 * The parser builds shape paths for functions, usable by Call objects at
228 * runtime, by calling an "add" method. All ARGUMENT bindings must be added
229 * before before any VARIABLE or CONSTANT bindings, which themselves must
230 * be added before all UPVAR bindings.
232 bool add(JSContext *cx, JSAtom *name, BindingKind kind);
234 /* Convenience specializations. */
235 bool addVariable(JSContext *cx, JSAtom *name) {
236 return add(cx, name, VARIABLE);
238 bool addConstant(JSContext *cx, JSAtom *name) {
239 return add(cx, name, CONSTANT);
241 bool addUpvar(JSContext *cx, JSAtom *name) {
242 return add(cx, name, UPVAR);
244 bool addArgument(JSContext *cx, JSAtom *name, uint16 *slotp) {
245 JS_ASSERT(name != NULL); /* not destructuring */
246 *slotp = nargs;
247 return add(cx, name, ARGUMENT);
249 bool addDestructuring(JSContext *cx, uint16 *slotp) {
250 *slotp = nargs;
251 return add(cx, NULL, ARGUMENT);
255 * Look up an argument or variable name, returning its kind when found or
256 * NONE when no such name exists. When indexp is not null and the name
257 * exists, *indexp will receive the index of the corresponding argument or
258 * variable.
260 BindingKind lookup(JSContext *cx, JSAtom *name, uintN *indexp) const;
262 /* Convenience method to check for any binding for a name. */
263 bool hasBinding(JSContext *cx, JSAtom *name) const {
264 return lookup(cx, name, NULL) != NONE;
268 * Function and macros to work with local names as an array of words.
269 * getLocalNameArray returns the array, or null if we are out of memory.
270 * This function must be called only when hasLocalNames().
272 * The supplied pool is used to allocate the returned array, so the caller
273 * is obligated to mark and release to free it.
275 * The elements of the array with index less than nargs correspond to the
276 * the names of arguments. An index >= nargs addresses a var binding. Use
277 * JS_LOCAL_NAME_TO_ATOM to convert array's element to an atom pointer.
278 * This pointer can be null when the element is for an argument
279 * corresponding to a destructuring pattern.
281 * If nameWord does not name an argument, use JS_LOCAL_NAME_IS_CONST to
282 * check if nameWord corresponds to the const declaration.
284 jsuword *
285 getLocalNameArray(JSContext *cx, JSArenaPool *pool);
288 * Returns the slot where the sharp array is stored, or a value < 0 if no
289 * sharps are present or in case of failure.
291 int sharpSlotBase(JSContext *cx);
294 * Protect stored bindings from mutation. Subsequent attempts to add
295 * bindings will copy the existing bindings before adding to them, allowing
296 * the original bindings to be safely shared.
298 void makeImmutable();
301 * These methods provide direct access to the shape path normally
302 * encapsulated by js::Bindings. These methods may be used to make a
303 * Shape::Range for iterating over the relevant shapes from youngest to
304 * oldest (i.e., last or right-most to first or left-most in source order).
306 * Sometimes iteration order must be from oldest to youngest, however. For
307 * such cases, use js::Bindings::getLocalNameArray. The RAII class
308 * js::AutoLocalNameArray, defined in jscntxt.h, should be used where
309 * possible instead of direct calls to getLocalNameArray.
311 const js::Shape *lastArgument() const;
312 const js::Shape *lastVariable() const;
313 const js::Shape *lastUpvar() const;
315 void trace(JSTracer *trc);
318 } /* namespace js */
320 #define JS_OBJECT_ARRAY_SIZE(length) \
321 (offsetof(JSObjectArray, vector) + sizeof(JSObject *) * (length))
323 #if defined DEBUG && defined JS_THREADSAFE
324 # define CHECK_SCRIPT_OWNER 1
325 #endif
327 #ifdef JS_METHODJIT
328 namespace JSC {
329 class ExecutablePool;
332 #define JS_UNJITTABLE_SCRIPT (reinterpret_cast<void*>(1))
334 enum JITScriptStatus {
335 JITScript_None,
336 JITScript_Invalid,
337 JITScript_Valid
340 namespace js {
341 namespace mjit {
343 struct JITScript;
347 #endif
349 struct JSScript {
351 * Two successively less primitive ways to make a new JSScript. The first
352 * does *not* call a non-null cx->runtime->newScriptHook -- only the second,
353 * NewScriptFromCG, calls this optional debugger hook.
355 * The NewScript function can't know whether the script it creates belongs
356 * to a function, or is top-level or eval code, but the debugger wants access
357 * to the newly made script's function, if any -- so callers of NewScript
358 * are responsible for notifying the debugger after successfully creating any
359 * kind (function or other) of new JSScript.
361 static JSScript *NewScript(JSContext *cx, uint32 length, uint32 nsrcnotes, uint32 natoms,
362 uint32 nobjects, uint32 nupvars, uint32 nregexps,
363 uint32 ntrynotes, uint32 nconsts, uint32 nglobals,
364 uint16 nClosedArgs, uint16 nClosedVars, JSVersion version);
366 static JSScript *NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg);
368 /* FIXME: bug 586181 */
369 JSCList links; /* Links for compartment script list */
370 jsbytecode *code; /* bytecodes and their immediate operands */
371 uint32 length; /* length of code vector */
373 private:
374 uint16 version; /* JS version under which script was compiled */
376 size_t callCount_; /* Number of times the script has been called. */
378 public:
379 uint16 nfixed; /* number of slots besides stack operands in
380 slot array */
383 * Offsets to various array structures from the end of this script, or
384 * JSScript::INVALID_OFFSET if the array has length 0.
386 uint8 objectsOffset; /* offset to the array of nested function,
387 block, scope, xml and one-time regexps
388 objects */
389 uint8 upvarsOffset; /* offset of the array of display ("up")
390 closure vars */
391 uint8 regexpsOffset; /* offset to the array of to-be-cloned
392 regexps */
393 uint8 trynotesOffset; /* offset to the array of try notes */
394 uint8 globalsOffset; /* offset to the array of global slots */
395 uint8 constOffset; /* offset to the array of constants */
397 bool noScriptRval:1; /* no need for result value of last
398 expression statement */
399 bool savedCallerFun:1; /* object 0 is caller function */
400 bool hasSharps:1; /* script uses sharp variables */
401 bool strictModeCode:1; /* code is in strict mode */
402 bool compileAndGo:1; /* script was compiled with TCF_COMPILE_N_GO */
403 bool usesEval:1; /* script uses eval() */
404 bool usesArguments:1; /* script uses arguments */
405 bool warnedAboutTwoArgumentEval:1; /* have warned about use of
406 obsolete eval(s, o) in
407 this script */
408 bool hasSingletons:1; /* script has singleton objects */
409 #ifdef JS_METHODJIT
410 bool debugMode:1; /* script was compiled in debug mode */
411 bool singleStepMode:1; /* compile script in single-step mode */
412 #endif
414 jsbytecode *main; /* main entry point, after predef'ing prolog */
415 JSAtomMap atomMap; /* maps immediate index to literal struct */
416 JSCompartment *compartment; /* compartment the script was compiled for */
417 const char *filename; /* source filename or null */
418 uint32 lineno; /* base line number of script */
419 uint16 nslots; /* vars plus maximum stack depth */
420 uint16 staticLevel;/* static level for display maintenance */
421 uint16 nClosedArgs; /* number of args which are closed over. */
422 uint16 nClosedVars; /* number of vars which are closed over. */
423 js::Bindings bindings; /* names of top-level variables in this script
424 (and arguments if this is a function script) */
425 JSPrincipals *principals;/* principals for this script */
426 union {
428 * A script object of class js_ScriptClass, to ensure the script is GC'd.
429 * - All scripts returned by JSAPI functions (JS_CompileScript,
430 * JS_CompileFile, etc.) have these objects.
431 * - Function scripts never have script objects; such scripts are owned
432 * by their function objects.
433 * - Temporary scripts created by obj_eval, JS_EvaluateScript, and
434 * similar functions never have these objects; such scripts are
435 * explicitly destroyed by the code that created them.
436 * Debugging API functions (JSDebugHooks::newScriptHook;
437 * JS_GetFunctionScript) may reveal sans-script-object Function and
438 * temporary scripts to clients, but clients must never call
439 * JS_NewScriptObject on such scripts: doing so would double-free them,
440 * once from the explicit call to js_DestroyScript, and once when the
441 * script object is garbage collected.
443 JSObject *object;
444 JSScript *nextToGC; /* next to GC in rt->scriptsToGC list */
445 } u;
447 #ifdef CHECK_SCRIPT_OWNER
448 JSThread *owner; /* for thread-safe life-cycle assertions */
449 #endif
451 uint32 *closedSlots; /* vector of closed slots; args first, then vars. */
453 public:
454 #ifdef JS_METHODJIT
455 // Fast-cached pointers to make calls faster. These are also used to
456 // quickly test whether there is JIT code; a NULL value means no
457 // compilation has been attempted. A JS_UNJITTABLE_SCRIPT value means
458 // compilation failed. Any value is the arity-check entry point.
459 void *jitArityCheckNormal;
460 void *jitArityCheckCtor;
462 js::mjit::JITScript *jitNormal; /* Extra JIT info for normal scripts */
463 js::mjit::JITScript *jitCtor; /* Extra JIT info for constructors */
465 bool hasJITCode() {
466 return jitNormal || jitCtor;
469 // These methods are implemented in MethodJIT.h.
470 inline void **nativeMap(bool constructing);
471 inline void *maybeNativeCodeForPC(bool constructing, jsbytecode *pc);
472 inline void *nativeCodeForPC(bool constructing, jsbytecode *pc);
474 js::mjit::JITScript *getJIT(bool constructing) {
475 return constructing ? jitCtor : jitNormal;
478 size_t callCount() const { return callCount_; }
479 size_t incCallCount() { return ++callCount_; }
481 JITScriptStatus getJITStatus(bool constructing) {
482 void *addr = constructing ? jitArityCheckCtor : jitArityCheckNormal;
483 if (addr == NULL)
484 return JITScript_None;
485 if (addr == JS_UNJITTABLE_SCRIPT)
486 return JITScript_Invalid;
487 return JITScript_Valid;
489 #endif
491 /* Script notes are allocated right after the code. */
492 jssrcnote *notes() { return (jssrcnote *)(code + length); }
494 static const uint8 INVALID_OFFSET = 0xFF;
495 static bool isValidOffset(uint8 offset) { return offset != INVALID_OFFSET; }
497 JSObjectArray *objects() {
498 JS_ASSERT(isValidOffset(objectsOffset));
499 return (JSObjectArray *)((uint8 *) (this + 1) + objectsOffset);
502 JSUpvarArray *upvars() {
503 JS_ASSERT(isValidOffset(upvarsOffset));
504 return (JSUpvarArray *) ((uint8 *) (this + 1) + upvarsOffset);
507 JSObjectArray *regexps() {
508 JS_ASSERT(isValidOffset(regexpsOffset));
509 return (JSObjectArray *) ((uint8 *) (this + 1) + regexpsOffset);
512 JSTryNoteArray *trynotes() {
513 JS_ASSERT(isValidOffset(trynotesOffset));
514 return (JSTryNoteArray *) ((uint8 *) (this + 1) + trynotesOffset);
517 js::GlobalSlotArray *globals() {
518 JS_ASSERT(isValidOffset(globalsOffset));
519 return (js::GlobalSlotArray *) ((uint8 *) (this + 1) + globalsOffset);
522 JSConstArray *consts() {
523 JS_ASSERT(isValidOffset(constOffset));
524 return (JSConstArray *) ((uint8 *) (this + 1) + constOffset);
527 JSAtom *getAtom(size_t index) {
528 JS_ASSERT(index < atomMap.length);
529 return atomMap.vector[index];
532 JSObject *getObject(size_t index) {
533 JSObjectArray *arr = objects();
534 JS_ASSERT(index < arr->length);
535 return arr->vector[index];
538 uint32 getGlobalSlot(size_t index) {
539 js::GlobalSlotArray *arr = globals();
540 JS_ASSERT(index < arr->length);
541 return arr->vector[index].slot;
544 JSAtom *getGlobalAtom(size_t index) {
545 js::GlobalSlotArray *arr = globals();
546 JS_ASSERT(index < arr->length);
547 return getAtom(arr->vector[index].atomIndex);
550 JSVersion getVersion() const {
551 return JSVersion(version);
554 inline JSFunction *getFunction(size_t index);
556 inline JSObject *getRegExp(size_t index);
558 const js::Value &getConst(size_t index) {
559 JSConstArray *arr = consts();
560 JS_ASSERT(index < arr->length);
561 return arr->vector[index];
565 * The isEmpty method tells whether this script has code that computes any
566 * result (not return value, result AKA normal completion value) other than
567 * JSVAL_VOID, or any other effects.
569 inline bool isEmpty() const;
571 uint32 getClosedArg(uint32 index) {
572 JS_ASSERT(index < nClosedArgs);
573 return closedSlots[index];
576 uint32 getClosedVar(uint32 index) {
577 JS_ASSERT(index < nClosedVars);
578 return closedSlots[nClosedArgs + index];
581 void copyClosedSlotsTo(JSScript *other);
584 #define SHARP_NSLOTS 2 /* [#array, #depth] slots if the script
585 uses sharp variables */
587 static JS_INLINE uintN
588 StackDepth(JSScript *script)
590 return script->nslots - script->nfixed;
594 * If pc_ does not point within script_'s bytecode, then it must point into an
595 * imacro body, so we use cx->runtime common atoms instead of script_'s atoms.
596 * This macro uses cx from its callers' environments in the pc-in-imacro case.
598 #define JS_GET_SCRIPT_ATOM(script_, pc_, index, atom) \
599 JS_BEGIN_MACRO \
600 if ((pc_) < (script_)->code || \
601 (script_)->code + (script_)->length <= (pc_)) { \
602 JS_ASSERT((size_t)(index) < js_common_atom_count); \
603 (atom) = COMMON_ATOMS_START(&cx->runtime->atomState)[index]; \
604 } else { \
605 (atom) = script_->getAtom(index); \
607 JS_END_MACRO
609 extern JS_FRIEND_DATA(js::Class) js_ScriptClass;
611 extern JSObject *
612 js_InitScriptClass(JSContext *cx, JSObject *obj);
615 * On first new context in rt, initialize script runtime state, specifically
616 * the script filename table and its lock.
618 extern JSBool
619 js_InitRuntimeScriptState(JSRuntime *rt);
622 * On JS_DestroyRuntime(rt), forcibly free script filename prefixes and any
623 * script filename table entries that have not been GC'd.
625 * This allows script filename prefixes to outlive any context in rt.
627 extern void
628 js_FreeRuntimeScriptState(JSRuntime *rt);
630 extern const char *
631 js_SaveScriptFilename(JSContext *cx, const char *filename);
633 extern const char *
634 js_SaveScriptFilenameRT(JSRuntime *rt, const char *filename, uint32 flags);
636 extern uint32
637 js_GetScriptFilenameFlags(const char *filename);
639 extern void
640 js_MarkScriptFilename(const char *filename);
642 extern void
643 js_MarkScriptFilenames(JSRuntime *rt);
645 extern void
646 js_SweepScriptFilenames(JSRuntime *rt);
649 * New-script-hook calling is factored from js_NewScriptFromCG so that it
650 * and callers of js_XDRScript can share this code. In the case of callers
651 * of js_XDRScript, the hook should be invoked only after successful decode
652 * of any owning function (the fun parameter) or script object (null fun).
654 extern JS_FRIEND_API(void)
655 js_CallNewScriptHook(JSContext *cx, JSScript *script, JSFunction *fun);
657 extern void
658 js_CallDestroyScriptHook(JSContext *cx, JSScript *script);
661 * The function must be used only outside the GC for a script that was run
662 * only on the current thread.
664 extern void
665 js_DestroyScript(JSContext *cx, JSScript *script);
667 extern void
668 js_DestroyScriptFromGC(JSContext *cx, JSScript *script);
671 * Script objects may be cached and reused, in which case their JSD-visible
672 * lifetimes may be shorter than their actual lifetimes. Destroy one such
673 * script for real as part of a GC pass. From JSD's point of view, the script
674 * is already dead.
676 extern void
677 js_DestroyCachedScript(JSContext *cx, JSScript *script);
679 extern void
680 js_TraceScript(JSTracer *trc, JSScript *script);
682 extern JSBool
683 js_NewScriptObject(JSContext *cx, JSScript *script);
686 * To perturb as little code as possible, we introduce a js_GetSrcNote lookup
687 * cache without adding an explicit cx parameter. Thus js_GetSrcNote becomes
688 * a macro that uses cx from its calls' lexical environments.
690 #define js_GetSrcNote(script,pc) js_GetSrcNoteCached(cx, script, pc)
692 extern jssrcnote *
693 js_GetSrcNoteCached(JSContext *cx, JSScript *script, jsbytecode *pc);
696 * NOTE: use js_FramePCToLineNumber(cx, fp) when you have an active fp, in
697 * preference to js_PCToLineNumber (cx, fp->script fp->regs->pc), because
698 * fp->imacpc may be non-null, indicating an active imacro.
700 extern uintN
701 js_FramePCToLineNumber(JSContext *cx, JSStackFrame *fp);
703 extern uintN
704 js_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc);
706 extern jsbytecode *
707 js_LineNumberToPC(JSScript *script, uintN lineno);
709 extern JS_FRIEND_API(uintN)
710 js_GetScriptLineExtent(JSScript *script);
712 static JS_INLINE JSOp
713 js_GetOpcode(JSContext *cx, JSScript *script, jsbytecode *pc)
715 JSOp op = (JSOp) *pc;
716 if (op == JSOP_TRAP)
717 op = JS_GetTrapOpcode(cx, script, pc);
718 return op;
721 extern JSScript *
722 js_CloneScript(JSContext *cx, JSScript *script);
725 * If magic is non-null, js_XDRScript succeeds on magic number mismatch but
726 * returns false in *magic; it reflects a match via a true *magic out param.
727 * If magic is null, js_XDRScript returns false on bad magic number errors,
728 * which it reports.
730 * NB: after a successful JSXDR_DECODE, js_XDRScript callers must do any
731 * required subsequent set-up of owning function or script object and then call
732 * js_CallNewScriptHook.
734 extern JSBool
735 js_XDRScript(JSXDRState *xdr, JSScript **scriptp, JSBool *hasMagic);
737 #endif /* jsscript_h___ */