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 jsopcode_h___ |
41 |
#define jsopcode_h___ |
42 |
/* |
43 |
* JS bytecode definitions. |
44 |
*/ |
45 |
#include <stddef.h> |
46 |
#include "jsprvtd.h" |
47 |
#include "jspubtd.h" |
48 |
#include "jsutil.h" |
49 |
|
50 |
JS_BEGIN_EXTERN_C |
51 |
|
52 |
/* |
53 |
* JS operation bytecodes. |
54 |
*/ |
55 |
typedef enum JSOp { |
56 |
#define OPDEF(op,val,name,token,length,nuses,ndefs,prec,format) \ |
57 |
op = val, |
58 |
#include "jsopcode.tbl" |
59 |
#undef OPDEF |
60 |
JSOP_LIMIT |
61 |
} JSOp; |
62 |
|
63 |
/* |
64 |
* JS bytecode formats. |
65 |
*/ |
66 |
#define JOF_BYTE 0 /* single bytecode, no immediates */ |
67 |
#define JOF_JUMP 1 /* signed 16-bit jump offset immediate */ |
68 |
#define JOF_ATOM 2 /* unsigned 16-bit constant index */ |
69 |
#define JOF_UINT16 3 /* unsigned 16-bit immediate operand */ |
70 |
#define JOF_TABLESWITCH 4 /* table switch */ |
71 |
#define JOF_LOOKUPSWITCH 5 /* lookup switch */ |
72 |
#define JOF_QARG 6 /* quickened get/set function argument ops */ |
73 |
#define JOF_LOCAL 7 /* var or block-local variable */ |
74 |
#define JOF_SLOTATOM 8 /* uint16 slot + constant index */ |
75 |
#define JOF_JUMPX 9 /* signed 32-bit jump offset immediate */ |
76 |
#define JOF_TABLESWITCHX 10 /* extended (32-bit offset) table switch */ |
77 |
#define JOF_LOOKUPSWITCHX 11 /* extended (32-bit offset) lookup switch */ |
78 |
#define JOF_UINT24 12 /* extended unsigned 24-bit literal (index) */ |
79 |
#define JOF_UINT8 13 /* uint8 immediate, e.g. top 8 bits of 24-bit |
80 |
atom index */ |
81 |
#define JOF_INT32 14 /* int32 immediate operand */ |
82 |
#define JOF_OBJECT 15 /* unsigned 16-bit object index */ |
83 |
#define JOF_SLOTOBJECT 16 /* uint16 slot index + object index */ |
84 |
#define JOF_REGEXP 17 /* unsigned 16-bit regexp index */ |
85 |
#define JOF_INT8 18 /* int8 immediate operand */ |
86 |
#define JOF_ATOMOBJECT 19 /* uint16 constant index + object index */ |
87 |
#define JOF_TYPEMASK 0x001f /* mask for above immediate types */ |
88 |
|
89 |
#define JOF_NAME (1U<<5) /* name operation */ |
90 |
#define JOF_PROP (2U<<5) /* obj.prop operation */ |
91 |
#define JOF_ELEM (3U<<5) /* obj[index] operation */ |
92 |
#define JOF_XMLNAME (4U<<5) /* XML name: *, a::b, @a, @a::b, etc. */ |
93 |
#define JOF_VARPROP (5U<<5) /* x.prop for this, arg, var, or local x */ |
94 |
#define JOF_MODEMASK (7U<<5) /* mask for above addressing modes */ |
95 |
#define JOF_SET (1U<<8) /* set (i.e., assignment) operation */ |
96 |
#define JOF_DEL (1U<<9) /* delete operation */ |
97 |
#define JOF_DEC (1U<<10) /* decrement (--, not ++) opcode */ |
98 |
#define JOF_INC (2U<<10) /* increment (++, not --) opcode */ |
99 |
#define JOF_INCDEC (3U<<10) /* increment or decrement opcode */ |
100 |
#define JOF_POST (1U<<12) /* postorder increment or decrement */ |
101 |
#define JOF_FOR (1U<<13) /* for-in property op (akin to JOF_SET) */ |
102 |
#define JOF_ASSIGNING JOF_SET /* hint for JSClass.resolve, used for ops |
103 |
that do simplex assignment */ |
104 |
#define JOF_DETECTING (1U<<14) /* object detection for JSNewResolveOp */ |
105 |
#define JOF_BACKPATCH (1U<<15) /* backpatch placeholder during codegen */ |
106 |
#define JOF_LEFTASSOC (1U<<16) /* left-associative operator */ |
107 |
#define JOF_DECLARING (1U<<17) /* var, const, or function declaration op */ |
108 |
#define JOF_INDEXBASE (1U<<18) /* atom segment base setting prefix op */ |
109 |
#define JOF_CALLOP (1U<<19) /* call operation that pushes function and |
110 |
this */ |
111 |
#define JOF_PARENHEAD (1U<<20) /* opcode consumes value of expression in |
112 |
parenthesized statement head */ |
113 |
#define JOF_INVOKE (1U<<21) /* JSOP_CALL, JSOP_NEW, JSOP_EVAL */ |
114 |
#define JOF_TMPSLOT (1U<<22) /* interpreter uses extra temporary slot |
115 |
to root intermediate objects besides |
116 |
the slots opcode uses */ |
117 |
#define JOF_TMPSLOT2 (2U<<22) /* interpreter uses extra 2 temporary slot |
118 |
besides the slots opcode uses */ |
119 |
#define JOF_TMPSLOT_SHIFT 22 |
120 |
#define JOF_TMPSLOT_MASK (JS_BITMASK(2) << JOF_TMPSLOT_SHIFT) |
121 |
|
122 |
/* Shorthands for type from format and type from opcode. */ |
123 |
#define JOF_TYPE(fmt) ((fmt) & JOF_TYPEMASK) |
124 |
#define JOF_OPTYPE(op) JOF_TYPE(js_CodeSpec[op].format) |
125 |
|
126 |
/* Shorthands for mode from format and mode from opcode. */ |
127 |
#define JOF_MODE(fmt) ((fmt) & JOF_MODEMASK) |
128 |
#define JOF_OPMODE(op) JOF_MODE(js_CodeSpec[op].format) |
129 |
|
130 |
#define JOF_TYPE_IS_EXTENDED_JUMP(t) \ |
131 |
((unsigned)((t) - JOF_JUMPX) <= (unsigned)(JOF_LOOKUPSWITCHX - JOF_JUMPX)) |
132 |
|
133 |
/* |
134 |
* Immediate operand getters, setters, and bounds. |
135 |
*/ |
136 |
|
137 |
/* Common uint16 immediate format helpers. */ |
138 |
#define UINT16_LEN 2 |
139 |
#define UINT16_HI(i) ((jsbytecode)((i) >> 8)) |
140 |
#define UINT16_LO(i) ((jsbytecode)(i)) |
141 |
#define GET_UINT16(pc) ((uintN)(((pc)[1] << 8) | (pc)[2])) |
142 |
#define SET_UINT16(pc,i) ((pc)[1] = UINT16_HI(i), (pc)[2] = UINT16_LO(i)) |
143 |
#define UINT16_LIMIT ((uintN)1 << 16) |
144 |
|
145 |
/* Short (2-byte signed offset) relative jump macros. */ |
146 |
#define JUMP_OFFSET_LEN 2 |
147 |
#define JUMP_OFFSET_HI(off) ((jsbytecode)((off) >> 8)) |
148 |
#define JUMP_OFFSET_LO(off) ((jsbytecode)(off)) |
149 |
#define GET_JUMP_OFFSET(pc) ((int16)GET_UINT16(pc)) |
150 |
#define SET_JUMP_OFFSET(pc,off) ((pc)[1] = JUMP_OFFSET_HI(off), \ |
151 |
(pc)[2] = JUMP_OFFSET_LO(off)) |
152 |
#define JUMP_OFFSET_MIN ((int16)0x8000) |
153 |
#define JUMP_OFFSET_MAX ((int16)0x7fff) |
154 |
|
155 |
/* |
156 |
* When a short jump won't hold a relative offset, its 2-byte immediate offset |
157 |
* operand is an unsigned index of a span-dependency record, maintained until |
158 |
* code generation finishes -- after which some (but we hope not nearly all) |
159 |
* span-dependent jumps must be extended (see OptimizeSpanDeps in jsemit.c). |
160 |
* |
161 |
* If the span-dependency record index overflows SPANDEP_INDEX_MAX, the jump |
162 |
* offset will contain SPANDEP_INDEX_HUGE, indicating that the record must be |
163 |
* found (via binary search) by its "before span-dependency optimization" pc |
164 |
* offset (from script main entry point). |
165 |
*/ |
166 |
#define GET_SPANDEP_INDEX(pc) ((uint16)GET_UINT16(pc)) |
167 |
#define SET_SPANDEP_INDEX(pc,i) ((pc)[1] = JUMP_OFFSET_HI(i), \ |
168 |
(pc)[2] = JUMP_OFFSET_LO(i)) |
169 |
#define SPANDEP_INDEX_MAX ((uint16)0xfffe) |
170 |
#define SPANDEP_INDEX_HUGE ((uint16)0xffff) |
171 |
|
172 |
/* Ultimately, if short jumps won't do, emit long (4-byte signed) offsets. */ |
173 |
#define JUMPX_OFFSET_LEN 4 |
174 |
#define JUMPX_OFFSET_B3(off) ((jsbytecode)((off) >> 24)) |
175 |
#define JUMPX_OFFSET_B2(off) ((jsbytecode)((off) >> 16)) |
176 |
#define JUMPX_OFFSET_B1(off) ((jsbytecode)((off) >> 8)) |
177 |
#define JUMPX_OFFSET_B0(off) ((jsbytecode)(off)) |
178 |
#define GET_JUMPX_OFFSET(pc) ((int32)(((pc)[1] << 24) | ((pc)[2] << 16) \ |
179 |
| ((pc)[3] << 8) | (pc)[4])) |
180 |
#define SET_JUMPX_OFFSET(pc,off)((pc)[1] = JUMPX_OFFSET_B3(off), \ |
181 |
(pc)[2] = JUMPX_OFFSET_B2(off), \ |
182 |
(pc)[3] = JUMPX_OFFSET_B1(off), \ |
183 |
(pc)[4] = JUMPX_OFFSET_B0(off)) |
184 |
#define JUMPX_OFFSET_MIN ((int32)0x80000000) |
185 |
#define JUMPX_OFFSET_MAX ((int32)0x7fffffff) |
186 |
|
187 |
/* |
188 |
* A literal is indexed by a per-script atom or object maps. Most scripts |
189 |
* have relatively few literals, so the standard JOF_ATOM, JOF_OBJECT and |
190 |
* JOF_REGEXP formats specifies a fixed 16 bits of immediate operand index. |
191 |
* A script with more than 64K literals must wrap the bytecode into |
192 |
* JSOP_INDEXBASE and JSOP_RESETBASE pair. |
193 |
*/ |
194 |
#define INDEX_LEN 2 |
195 |
#define INDEX_HI(i) ((jsbytecode)((i) >> 8)) |
196 |
#define INDEX_LO(i) ((jsbytecode)(i)) |
197 |
#define GET_INDEX(pc) GET_UINT16(pc) |
198 |
#define SET_INDEX(pc,i) ((pc)[1] = INDEX_HI(i), (pc)[2] = INDEX_LO(i)) |
199 |
|
200 |
#define GET_INDEXBASE(pc) (JS_ASSERT(*(pc) == JSOP_INDEXBASE), \ |
201 |
((uintN)((pc)[1])) << 16) |
202 |
#define INDEXBASE_LEN 1 |
203 |
|
204 |
#define UINT24_HI(i) ((jsbytecode)((i) >> 16)) |
205 |
#define UINT24_MID(i) ((jsbytecode)((i) >> 8)) |
206 |
#define UINT24_LO(i) ((jsbytecode)(i)) |
207 |
#define GET_UINT24(pc) ((jsatomid)(((pc)[1] << 16) | \ |
208 |
((pc)[2] << 8) | \ |
209 |
(pc)[3])) |
210 |
#define SET_UINT24(pc,i) ((pc)[1] = UINT24_HI(i), \ |
211 |
(pc)[2] = UINT24_MID(i), \ |
212 |
(pc)[3] = UINT24_LO(i)) |
213 |
|
214 |
#define GET_INT8(pc) ((jsint)(int8)(pc)[1]) |
215 |
|
216 |
#define GET_INT32(pc) ((jsint)(((uint32)((pc)[1]) << 24) | \ |
217 |
((uint32)((pc)[2]) << 16) | \ |
218 |
((uint32)((pc)[3]) << 8) | \ |
219 |
(uint32)(pc)[4])) |
220 |
#define SET_INT32(pc,i) ((pc)[1] = (jsbytecode)((uint32)(i) >> 24), \ |
221 |
(pc)[2] = (jsbytecode)((uint32)(i) >> 16), \ |
222 |
(pc)[3] = (jsbytecode)((uint32)(i) >> 8), \ |
223 |
(pc)[4] = (jsbytecode)(uint32)(i)) |
224 |
|
225 |
/* Index limit is determined by SN_3BYTE_OFFSET_FLAG, see jsemit.h. */ |
226 |
#define INDEX_LIMIT_LOG2 23 |
227 |
#define INDEX_LIMIT ((uint32)1 << INDEX_LIMIT_LOG2) |
228 |
|
229 |
/* Actual argument count operand format helpers. */ |
230 |
#define ARGC_HI(argc) UINT16_HI(argc) |
231 |
#define ARGC_LO(argc) UINT16_LO(argc) |
232 |
#define GET_ARGC(pc) GET_UINT16(pc) |
233 |
#define ARGC_LIMIT UINT16_LIMIT |
234 |
|
235 |
/* Synonyms for quick JOF_QARG and JOF_LOCAL bytecodes. */ |
236 |
#define GET_ARGNO(pc) GET_UINT16(pc) |
237 |
#define SET_ARGNO(pc,argno) SET_UINT16(pc,argno) |
238 |
#define ARGNO_LEN 2 |
239 |
#define ARGNO_LIMIT UINT16_LIMIT |
240 |
|
241 |
#define GET_SLOTNO(pc) GET_UINT16(pc) |
242 |
#define SET_SLOTNO(pc,varno) SET_UINT16(pc,varno) |
243 |
#define SLOTNO_LEN 2 |
244 |
#define SLOTNO_LIMIT UINT16_LIMIT |
245 |
|
246 |
struct JSCodeSpec { |
247 |
int8 length; /* length including opcode byte */ |
248 |
int8 nuses; /* arity, -1 if variadic */ |
249 |
int8 ndefs; /* number of stack results */ |
250 |
uint8 prec; /* operator precedence */ |
251 |
uint32 format; /* immediate operand format */ |
252 |
}; |
253 |
|
254 |
extern const JSCodeSpec js_CodeSpec[]; |
255 |
extern uintN js_NumCodeSpecs; |
256 |
extern const char *js_CodeName[]; |
257 |
extern const char js_EscapeMap[]; |
258 |
|
259 |
/* |
260 |
* Return a GC'ed string containing the chars in str, with any non-printing |
261 |
* chars or quotes (' or " as specified by the quote argument) escaped, and |
262 |
* with the quote character at the beginning and end of the result string. |
263 |
*/ |
264 |
extern JSString * |
265 |
js_QuoteString(JSContext *cx, JSString *str, jschar quote); |
266 |
|
267 |
/* |
268 |
* JSPrinter operations, for printf style message formatting. The return |
269 |
* value from js_GetPrinterOutput() is the printer's cumulative output, in |
270 |
* a GC'ed string. |
271 |
*/ |
272 |
|
273 |
#ifdef JS_ARENAMETER |
274 |
# define JS_NEW_PRINTER(cx, name, fun, indent, pretty) \ |
275 |
js_NewPrinter(cx, name, fun, indent, pretty) |
276 |
#else |
277 |
# define JS_NEW_PRINTER(cx, name, fun, indent, pretty) \ |
278 |
js_NewPrinter(cx, fun, indent, pretty) |
279 |
#endif |
280 |
|
281 |
extern JSPrinter * |
282 |
JS_NEW_PRINTER(JSContext *cx, const char *name, JSFunction *fun, |
283 |
uintN indent, JSBool pretty); |
284 |
|
285 |
extern void |
286 |
js_DestroyPrinter(JSPrinter *jp); |
287 |
|
288 |
extern JSString * |
289 |
js_GetPrinterOutput(JSPrinter *jp); |
290 |
|
291 |
extern int |
292 |
js_printf(JSPrinter *jp, const char *format, ...); |
293 |
|
294 |
extern JSBool |
295 |
js_puts(JSPrinter *jp, const char *s); |
296 |
|
297 |
/* |
298 |
* Get index operand from the bytecode using a bytecode analysis to deduce the |
299 |
* the index register. This function is infallible, in spite of taking cx as |
300 |
* its first parameter; it uses only cx->runtime when calling JS_GetTrapOpcode. |
301 |
* The GET_*_FROM_BYTECODE macros that call it pick up cx from their caller's |
302 |
* lexical environments. |
303 |
*/ |
304 |
uintN |
305 |
js_GetIndexFromBytecode(JSContext *cx, JSScript *script, jsbytecode *pc, |
306 |
ptrdiff_t pcoff); |
307 |
|
308 |
/* |
309 |
* A slower version of GET_ATOM when the caller does not want to maintain |
310 |
* the index segment register itself. |
311 |
*/ |
312 |
#define GET_ATOM_FROM_BYTECODE(script, pc, pcoff, atom) \ |
313 |
JS_BEGIN_MACRO \ |
314 |
uintN index_ = js_GetIndexFromBytecode(cx, (script), (pc), (pcoff)); \ |
315 |
JS_GET_SCRIPT_ATOM((script), index_, atom); \ |
316 |
JS_END_MACRO |
317 |
|
318 |
#define GET_OBJECT_FROM_BYTECODE(script, pc, pcoff, obj) \ |
319 |
JS_BEGIN_MACRO \ |
320 |
uintN index_ = js_GetIndexFromBytecode(cx, (script), (pc), (pcoff)); \ |
321 |
JS_GET_SCRIPT_OBJECT((script), index_, obj); \ |
322 |
JS_END_MACRO |
323 |
|
324 |
#define GET_FUNCTION_FROM_BYTECODE(script, pc, pcoff, fun) \ |
325 |
JS_BEGIN_MACRO \ |
326 |
uintN index_ = js_GetIndexFromBytecode(cx, (script), (pc), (pcoff)); \ |
327 |
JS_GET_SCRIPT_FUNCTION((script), index_, fun); \ |
328 |
JS_END_MACRO |
329 |
|
330 |
#define GET_REGEXP_FROM_BYTECODE(script, pc, pcoff, obj) \ |
331 |
JS_BEGIN_MACRO \ |
332 |
uintN index_ = js_GetIndexFromBytecode(cx, (script), (pc), (pcoff)); \ |
333 |
JS_GET_SCRIPT_REGEXP((script), index_, obj); \ |
334 |
JS_END_MACRO |
335 |
|
336 |
/* |
337 |
* Get the length of variable-length bytecode like JSOP_TABLESWITCH. |
338 |
*/ |
339 |
extern uintN |
340 |
js_GetVariableBytecodeLength(jsbytecode *pc); |
341 |
|
342 |
/* |
343 |
* Find the number of stack slots used by a variadic opcode such as JSOP_CALL |
344 |
* or JSOP_NEWARRAY (for such ops, JSCodeSpec.nuses is -1). |
345 |
*/ |
346 |
extern uintN |
347 |
js_GetVariableStackUses(JSOp op, jsbytecode *pc); |
348 |
|
349 |
/* |
350 |
* Find the number of stack slots defined by JSOP_ENTERBLOCK (for this op, |
351 |
* JSCodeSpec.ndefs is -1). |
352 |
*/ |
353 |
extern uintN |
354 |
js_GetEnterBlockStackDefs(JSContext *cx, JSScript *script, jsbytecode *pc); |
355 |
|
356 |
#ifdef __cplusplus /* Aargh, libgjs, bug 492720. */ |
357 |
static JS_INLINE uintN |
358 |
js_GetStackUses(const JSCodeSpec *cs, JSOp op, jsbytecode *pc) |
359 |
{ |
360 |
JS_ASSERT(cs == &js_CodeSpec[op]); |
361 |
if (cs->nuses >= 0) |
362 |
return cs->nuses; |
363 |
return js_GetVariableStackUses(op, pc); |
364 |
} |
365 |
|
366 |
static JS_INLINE uintN |
367 |
js_GetStackDefs(JSContext *cx, const JSCodeSpec *cs, JSOp op, JSScript *script, |
368 |
jsbytecode *pc) |
369 |
{ |
370 |
JS_ASSERT(cs == &js_CodeSpec[op]); |
371 |
if (cs->ndefs >= 0) |
372 |
return cs->ndefs; |
373 |
|
374 |
/* Only JSOP_ENTERBLOCK has a variable number of stack defs. */ |
375 |
JS_ASSERT(op == JSOP_ENTERBLOCK); |
376 |
return js_GetEnterBlockStackDefs(cx, script, pc); |
377 |
} |
378 |
#endif |
379 |
|
380 |
#ifdef DEBUG |
381 |
/* |
382 |
* Disassemblers, for debugging only. |
383 |
*/ |
384 |
#include <stdio.h> |
385 |
|
386 |
extern JS_FRIEND_API(JSBool) |
387 |
js_Disassemble(JSContext *cx, JSScript *script, JSBool lines, FILE *fp); |
388 |
|
389 |
extern JS_FRIEND_API(uintN) |
390 |
js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc, uintN loc, |
391 |
JSBool lines, FILE *fp); |
392 |
#endif /* DEBUG */ |
393 |
|
394 |
/* |
395 |
* Decompilers, for script, function, and expression pretty-printing. |
396 |
*/ |
397 |
extern JSBool |
398 |
js_DecompileScript(JSPrinter *jp, JSScript *script); |
399 |
|
400 |
extern JSBool |
401 |
js_DecompileFunctionBody(JSPrinter *jp); |
402 |
|
403 |
extern JSBool |
404 |
js_DecompileFunction(JSPrinter *jp); |
405 |
|
406 |
/* |
407 |
* Find the source expression that resulted in v, and return a newly allocated |
408 |
* C-string containing it. Fall back on v's string conversion (fallback) if we |
409 |
* can't find the bytecode that generated and pushed v on the operand stack. |
410 |
* |
411 |
* Search the current stack frame if spindex is JSDVG_SEARCH_STACK. Don't |
412 |
* look for v on the stack if spindex is JSDVG_IGNORE_STACK. Otherwise, |
413 |
* spindex is the negative index of v, measured from cx->fp->sp, or from a |
414 |
* lower frame's sp if cx->fp is native. |
415 |
* |
416 |
* The caller must call JS_free on the result after a succsesful call. |
417 |
*/ |
418 |
extern char * |
419 |
js_DecompileValueGenerator(JSContext *cx, intN spindex, jsval v, |
420 |
JSString *fallback); |
421 |
|
422 |
#define JSDVG_IGNORE_STACK 0 |
423 |
#define JSDVG_SEARCH_STACK 1 |
424 |
|
425 |
/* |
426 |
* Given bytecode address pc in script's main program code, return the operand |
427 |
* stack depth just before (JSOp) *pc executes. |
428 |
*/ |
429 |
extern uintN |
430 |
js_ReconstructStackDepth(JSContext *cx, JSScript *script, jsbytecode *pc); |
431 |
|
432 |
JS_END_EXTERN_C |
433 |
|
434 |
#endif /* jsopcode_h___ */ |