📄 jsemit.h
字号:
if (!js_SetJumpOffset(cx, cg, pc, off)) \ return JS_FALSE; \ JS_END_MACRO#define CHECK_AND_SET_JUMP_OFFSET_AT(cx,cg,off) \ CHECK_AND_SET_JUMP_OFFSET(cx, cg, CG_CODE(cg,off), CG_OFFSET(cg) - (off))extern JSBooljs_SetJumpOffset(JSContext *cx, JSCodeGenerator *cg, jsbytecode *pc, ptrdiff_t off);/* Test whether we're in a with statement. */extern JSBooljs_InWithStatement(JSTreeContext *tc);/* Test whether we're in a catch block with exception named by atom. */extern JSBooljs_InCatchBlock(JSTreeContext *tc, JSAtom *atom);/* * Push the C-stack-allocated struct at stmt onto the stmtInfo stack. */extern voidjs_PushStatement(JSTreeContext *tc, JSStmtInfo *stmt, JSStmtType type, ptrdiff_t top);/* * Pop tc->topStmt. If the top JSStmtInfo struct is not stack-allocated, it * is up to the caller to free it. */extern voidjs_PopStatement(JSTreeContext *tc);/* * Like js_PopStatement(&cg->treeContext), also patch breaks and continues. * May fail if a jump offset overflows. */extern JSBooljs_PopStatementCG(JSContext *cx, JSCodeGenerator *cg);/* * Define and lookup a primitive jsval associated with the const named by atom. * js_DefineCompileTimeConstant analyzes the constant-folded initializer at pn * and saves the const's value in cg->constList, if it can be used at compile * time. It returns true unless an error occurred. * * If the initializer's value could not be saved, js_LookupCompileTimeConstant * calls will return the undefined value. js_LookupCompileTimeConstant tries * to find a const value memorized for atom, returning true with *vp set to a * value other than undefined if the constant was found, true with *vp set to * JSVAL_VOID if not found, and false on error. */extern JSBooljs_DefineCompileTimeConstant(JSContext *cx, JSCodeGenerator *cg, JSAtom *atom, JSParseNode *pn);extern JSBooljs_LookupCompileTimeConstant(JSContext *cx, JSCodeGenerator *cg, JSAtom *atom, jsval *vp);/* * Emit code into cg for the tree rooted at pn. */extern JSBooljs_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn);/* * Emit code into cg for the tree rooted at body, then create a persistent * script for fun from cg. */extern JSBooljs_EmitFunctionBody(JSContext *cx, JSCodeGenerator *cg, JSParseNode *body, JSFunction *fun);/* * Source notes generated along with bytecode for decompiling and debugging. * A source note is a uint8 with 5 bits of type and 3 of offset from the pc of * the previous note. If 3 bits of offset aren't enough, extended delta notes * (SRC_XDELTA) consisting of 2 set high order bits followed by 6 offset bits * are emitted before the next note. Some notes have operand offsets encoded * immediately after them, in note bytes or byte-triples. * * Source Note Extended Delta * +7-6-5-4-3+2-1-0+ +7-6-5+4-3-2-1-0+ * |note-type|delta| |1 1| ext-delta | * +---------+-----+ +---+-----------+ * * At most one "gettable" note (i.e., a note of type other than SRC_NEWLINE, * SRC_SETLINE, and SRC_XDELTA) applies to a given bytecode. * * NB: the js_SrcNoteSpec array in jsemit.c is indexed by this enum, so its * initializers need to match the order here. */typedef enum JSSrcNoteType { SRC_NULL = 0, /* terminates a note vector */ SRC_IF = 1, /* JSOP_IFEQ bytecode is from an if-then */ SRC_IF_ELSE = 2, /* JSOP_IFEQ bytecode is from an if-then-else */ SRC_WHILE = 3, /* JSOP_IFEQ is from a while loop */ SRC_FOR = 4, /* JSOP_NOP or JSOP_POP in for loop head */ SRC_CONTINUE = 5, /* JSOP_GOTO is a continue, not a break; also used on JSOP_ENDINIT if extra comma at end of array literal: [1,2,,] */ SRC_VAR = 6, /* JSOP_NAME/SETNAME/FORNAME in a var decl */ SRC_PCDELTA = 7, /* offset from comma-operator to next POP, or from CONDSWITCH to first CASE opcode */ SRC_ASSIGNOP = 8, /* += or another assign-op follows */ SRC_COND = 9, /* JSOP_IFEQ is from conditional ?: operator */ SRC_RESERVED0 = 10, /* reserved for future use */ SRC_HIDDEN = 11, /* opcode shouldn't be decompiled */ SRC_PCBASE = 12, /* offset of first obj.prop.subprop bytecode */ SRC_LABEL = 13, /* JSOP_NOP for label: with atomid immediate */ SRC_LABELBRACE = 14, /* JSOP_NOP for label: {...} begin brace */ SRC_ENDBRACE = 15, /* JSOP_NOP for label: {...} end brace */ SRC_BREAK2LABEL = 16, /* JSOP_GOTO for 'break label' with atomid */ SRC_CONT2LABEL = 17, /* JSOP_GOTO for 'continue label' with atomid */ SRC_SWITCH = 18, /* JSOP_*SWITCH with offset to end of switch, 2nd off to first JSOP_CASE if condswitch */ SRC_FUNCDEF = 19, /* JSOP_NOP for function f() with atomid */ SRC_CATCH = 20, /* catch block has guard */ SRC_CONST = 21, /* JSOP_SETCONST in a const decl */ SRC_NEWLINE = 22, /* bytecode follows a source newline */ SRC_SETLINE = 23, /* a file-absolute source line number note */ SRC_XDELTA = 24 /* 24-31 are for extended delta notes */} JSSrcNoteType;#define SN_TYPE_BITS 5#define SN_DELTA_BITS 3#define SN_XDELTA_BITS 6#define SN_TYPE_MASK (JS_BITMASK(SN_TYPE_BITS) << SN_DELTA_BITS)#define SN_DELTA_MASK ((ptrdiff_t)JS_BITMASK(SN_DELTA_BITS))#define SN_XDELTA_MASK ((ptrdiff_t)JS_BITMASK(SN_XDELTA_BITS))#define SN_MAKE_NOTE(sn,t,d) (*(sn) = (jssrcnote) \ (((t) << SN_DELTA_BITS) \ | ((d) & SN_DELTA_MASK)))#define SN_MAKE_XDELTA(sn,d) (*(sn) = (jssrcnote) \ ((SRC_XDELTA << SN_DELTA_BITS) \ | ((d) & SN_XDELTA_MASK)))#define SN_IS_XDELTA(sn) ((*(sn) >> SN_DELTA_BITS) >= SRC_XDELTA)#define SN_TYPE(sn) (SN_IS_XDELTA(sn) ? SRC_XDELTA \ : *(sn) >> SN_DELTA_BITS)#define SN_SET_TYPE(sn,type) SN_MAKE_NOTE(sn, type, SN_DELTA(sn))#define SN_IS_GETTABLE(sn) (SN_TYPE(sn) < SRC_NEWLINE)#define SN_DELTA(sn) ((ptrdiff_t)(SN_IS_XDELTA(sn) \ ? *(sn) & SN_XDELTA_MASK \ : *(sn) & SN_DELTA_MASK))#define SN_SET_DELTA(sn,delta) (SN_IS_XDELTA(sn) \ ? SN_MAKE_XDELTA(sn, delta) \ : SN_MAKE_NOTE(sn, SN_TYPE(sn), delta))#define SN_DELTA_LIMIT ((ptrdiff_t)JS_BIT(SN_DELTA_BITS))#define SN_XDELTA_LIMIT ((ptrdiff_t)JS_BIT(SN_XDELTA_BITS))/* * Offset fields follow certain notes and are frequency-encoded: an offset in * [0,0x7f] consumes one byte, an offset in [0x80,0x7fffff] takes three, and * the high bit of the first byte is set. */#define SN_3BYTE_OFFSET_FLAG 0x80#define SN_3BYTE_OFFSET_MASK 0x7ftypedef struct JSSrcNoteSpec { const char *name; /* name for disassembly/debugging output */ uint8 arity; /* number of offset operands */ uint8 offsetBias; /* bias of offset(s) from annotated pc */ int8 isSpanDep; /* 1 or -1 if offsets could span extended ops, 0 otherwise; sign tells span direction */} JSSrcNoteSpec;extern JS_FRIEND_DATA(JSSrcNoteSpec) js_SrcNoteSpec[];extern JS_FRIEND_API(uintN) js_SrcNoteLength(jssrcnote *sn);#define SN_LENGTH(sn) ((js_SrcNoteSpec[SN_TYPE(sn)].arity == 0) ? 1 \ : js_SrcNoteLength(sn))#define SN_NEXT(sn) ((sn) + SN_LENGTH(sn))/* A source note array is terminated by an all-zero element. */#define SN_MAKE_TERMINATOR(sn) (*(sn) = SRC_NULL)#define SN_IS_TERMINATOR(sn) (*(sn) == SRC_NULL)/* * Append a new source note of the given type (and therefore size) to cg's * notes dynamic array, updating cg->noteCount. Return the new note's index * within the array pointed at by cg->current->notes. Return -1 if out of * memory. */extern intNjs_NewSrcNote(JSContext *cx, JSCodeGenerator *cg, JSSrcNoteType type);extern intNjs_NewSrcNote2(JSContext *cx, JSCodeGenerator *cg, JSSrcNoteType type, ptrdiff_t offset);extern intNjs_NewSrcNote3(JSContext *cx, JSCodeGenerator *cg, JSSrcNoteType type, ptrdiff_t offset1, ptrdiff_t offset2);/* * NB: this function can add at most one extra extended delta note. */extern jssrcnote *js_AddToSrcNoteDelta(JSContext *cx, JSCodeGenerator *cg, jssrcnote *sn, ptrdiff_t delta);/* * Get and set the offset operand identified by which (0 for the first, etc.). */extern JS_FRIEND_API(ptrdiff_t)js_GetSrcNoteOffset(jssrcnote *sn, uintN which);extern JSBooljs_SetSrcNoteOffset(JSContext *cx, JSCodeGenerator *cg, uintN index, uintN which, ptrdiff_t offset);/* * Finish taking source notes in cx's notePool, copying final notes to the new * stable store allocated by the caller and passed in via notes. Return false * on malloc failure, which means this function reported an error. * * To compute the number of jssrcnotes to allocate and pass in via notes, use * the CG_COUNT_FINAL_SRCNOTES macro. This macro knows a lot about details of * js_FinishTakingSrcNotes, SO DON'T CHANGE jsemit.c's js_FinishTakingSrcNotes * FUNCTION WITHOUT CHECKING WHETHER THIS MACRO NEEDS CORRESPONDING CHANGES! */#define CG_COUNT_FINAL_SRCNOTES(cg, cnt) \ JS_BEGIN_MACRO \ ptrdiff_t diff_ = CG_PROLOG_OFFSET(cg) - (cg)->prolog.lastNoteOffset; \ cnt = (cg)->prolog.noteCount + (cg)->main.noteCount + 1; \ if ((cg)->prolog.noteCount && \ (cg)->prolog.currentLine != (cg)->firstLine) { \ if (diff_ > SN_DELTA_MASK) \ cnt += JS_HOWMANY(diff_ - SN_DELTA_MASK, SN_XDELTA_MASK); \ cnt += 2 + (((cg)->firstLine > SN_3BYTE_OFFSET_MASK) << 1); \ } else if (diff_ > 0) { \ if (cg->main.noteCount) { \ jssrcnote *sn_ = (cg)->main.notes; \ diff_ -= SN_IS_XDELTA(sn_) \ ? SN_XDELTA_MASK - (*sn_ & SN_XDELTA_MASK) \ : SN_DELTA_MASK - (*sn_ & SN_DELTA_MASK); \ } \ if (diff_ > 0) \ cnt += JS_HOWMANY(diff_, SN_XDELTA_MASK); \ } \ JS_END_MACROextern JSBooljs_FinishTakingSrcNotes(JSContext *cx, JSCodeGenerator *cg, jssrcnote *notes);/* * Allocate cg->treeContext.tryCount notes (plus one for the end sentinel) * from cx->tempPool and set up cg->tryBase/tryNext for exactly tryCount * js_NewTryNote calls. The storage is freed by js_FinishCodeGenerator. */extern JSBooljs_AllocTryNotes(JSContext *cx, JSCodeGenerator *cg);/* * Grab the next trynote slot in cg, filling it in appropriately. */extern JSTryNote *js_NewTryNote(JSContext *cx, JSCodeGenerator *cg, ptrdiff_t start, ptrdiff_t end, ptrdiff_t catchStart);/* * Finish generating exception information into the space at notes. As with * js_FinishTakingSrcNotes, the caller must use CG_COUNT_FINAL_TRYNOTES(cg) to * preallocate enough space in a JSTryNote[] to pass as the notes parameter of * js_FinishTakingTryNotes. */#define CG_COUNT_FINAL_TRYNOTES(cg, cnt) \ JS_BEGIN_MACRO \ cnt = ((cg)->tryNext > (cg)->tryBase) \ ? PTRDIFF(cg->tryNext, cg->tryBase, JSTryNote) + 1 \ : 0; \ JS_END_MACROextern voidjs_FinishTakingTryNotes(JSContext *cx, JSCodeGenerator *cg, JSTryNote *notes);JS_END_EXTERN_C#endif /* jsemit_h___ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -