📄 jsemit.h
字号:
JT_CLR_TAG((sd)->target))#define SD_SET_BPDELTA(sd,bp) ((sd)->target = BPDELTA_TO_JT(bp))#define SD_GET_BPDELTA(sd) (JS_ASSERT(!JT_HAS_TAG((sd)->target)), \ JT_TO_BPDELTA((sd)->target))/* Avoid asserting twice by expanding SD_GET_TARGET in the "then" clause. */#define SD_SPAN(sd,pivot) (SD_GET_TARGET(sd) \ ? JT_CLR_TAG((sd)->target)->offset - (pivot) \ : 0)struct JSCodeGenerator { JSTreeContext treeContext; /* base state: statement info stack, etc. */ JSArenaPool *codePool; /* pointer to thread code arena pool */ JSArenaPool *notePool; /* pointer to thread srcnote arena pool */ void *codeMark; /* low watermark in cg->codePool */ void *noteMark; /* low watermark in cg->notePool */ void *tempMark; /* low watermark in cx->tempPool */ struct { jsbytecode *base; /* base of JS bytecode vector */ jsbytecode *limit; /* one byte beyond end of bytecode */ jsbytecode *next; /* pointer to next free bytecode */ jssrcnote *notes; /* source notes, see below */ uintN noteCount; /* number of source notes so far */ uintN noteMask; /* growth increment for notes */ ptrdiff_t lastNoteOffset; /* code offset for last source note */ uintN currentLine; /* line number for tree-based srcnote gen */ } prolog, main, *current; const char *filename; /* null or weak link to source filename */ uintN firstLine; /* first line, for js_NewScriptFromCG */ JSPrincipals *principals; /* principals for constant folding eval */ JSAtomList atomList; /* literals indexed for mapping */ intN stackDepth; /* current stack depth in script frame */ uintN maxStackDepth; /* maximum stack depth so far */ JSTryNote *tryBase; /* first exception handling note */ JSTryNote *tryNext; /* next available note */ size_t tryNoteSpace; /* # of bytes allocated at tryBase */ JSSpanDep *spanDeps; /* span dependent instruction records */ JSJumpTarget *jumpTargets; /* AVL tree of jump target offsets */ JSJumpTarget *jtFreeList; /* JT_LEFT-linked list of free structs */ uintN numSpanDeps; /* number of span dependencies */ uintN numJumpTargets; /* number of jump targets */ ptrdiff_t spanDepTodo; /* offset from main.base of potentially unoptimized spandeps */ uintN arrayCompSlot; /* stack slot of array in comprehension */ uintN emitLevel; /* js_EmitTree recursion level */ JSAtomList constList; /* compile time constants */ JSCodeGenerator *parent; /* Enclosing function or global context */};#define CG_BASE(cg) ((cg)->current->base)#define CG_LIMIT(cg) ((cg)->current->limit)#define CG_NEXT(cg) ((cg)->current->next)#define CG_CODE(cg,offset) (CG_BASE(cg) + (offset))#define CG_OFFSET(cg) PTRDIFF(CG_NEXT(cg), CG_BASE(cg), jsbytecode)#define CG_NOTES(cg) ((cg)->current->notes)#define CG_NOTE_COUNT(cg) ((cg)->current->noteCount)#define CG_NOTE_MASK(cg) ((cg)->current->noteMask)#define CG_LAST_NOTE_OFFSET(cg) ((cg)->current->lastNoteOffset)#define CG_CURRENT_LINE(cg) ((cg)->current->currentLine)#define CG_PROLOG_BASE(cg) ((cg)->prolog.base)#define CG_PROLOG_LIMIT(cg) ((cg)->prolog.limit)#define CG_PROLOG_NEXT(cg) ((cg)->prolog.next)#define CG_PROLOG_CODE(cg,poff) (CG_PROLOG_BASE(cg) + (poff))#define CG_PROLOG_OFFSET(cg) PTRDIFF(CG_PROLOG_NEXT(cg), CG_PROLOG_BASE(cg),\ jsbytecode)#define CG_SWITCH_TO_MAIN(cg) ((cg)->current = &(cg)->main)#define CG_SWITCH_TO_PROLOG(cg) ((cg)->current = &(cg)->prolog)/* * Initialize cg to allocate bytecode space from codePool, source note space * from notePool, and all other arena-allocated temporaries from cx->tempPool. * Return true on success. Report an error and return false if the initial * code segment can't be allocated. */extern JS_FRIEND_API(JSBool)js_InitCodeGenerator(JSContext *cx, JSCodeGenerator *cg, JSArenaPool *codePool, JSArenaPool *notePool, const char *filename, uintN lineno, JSPrincipals *principals);/* * Release cg->codePool, cg->notePool, and cx->tempPool to marks set by * js_InitCodeGenerator. Note that cgs are magic: they own the arena pool * "tops-of-stack" space above their codeMark, noteMark, and tempMark points. * This means you cannot alloc from tempPool and save the pointer beyond the * next JS_FinishCodeGenerator. */extern JS_FRIEND_API(void)js_FinishCodeGenerator(JSContext *cx, JSCodeGenerator *cg);/* * Emit one bytecode. */extern ptrdiff_tjs_Emit1(JSContext *cx, JSCodeGenerator *cg, JSOp op);/* * Emit two bytecodes, an opcode (op) with a byte of immediate operand (op1). */extern ptrdiff_tjs_Emit2(JSContext *cx, JSCodeGenerator *cg, JSOp op, jsbytecode op1);/* * Emit three bytecodes, an opcode with two bytes of immediate operands. */extern ptrdiff_tjs_Emit3(JSContext *cx, JSCodeGenerator *cg, JSOp op, jsbytecode op1, jsbytecode op2);/* * Emit (1 + extra) bytecodes, for N bytes of op and its immediate operand. */extern ptrdiff_tjs_EmitN(JSContext *cx, JSCodeGenerator *cg, JSOp op, size_t extra);/* * Unsafe macro to call js_SetJumpOffset and return false if it does. */#define CHECK_AND_SET_JUMP_OFFSET(cx,cg,pc,off) \ JS_BEGIN_MACRO \ 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 statement of given type. */extern JSBooljs_InStatement(JSTreeContext *tc, JSStmtType type);/* Test whether we're in a with statement. */#define js_InWithStatement(tc) js_InStatement(tc, STMT_WITH)/* * Test whether atom refers to a global variable (or is a reference error). * Return true in *loopyp if any loops enclose the lexical reference, false * otherwise. */extern JSBooljs_IsGlobalReference(JSTreeContext *tc, JSAtom *atom, JSBool *loopyp);/* * Push the C-stack-allocated struct at stmt onto the stmtInfo stack. */extern voidjs_PushStatement(JSTreeContext *tc, JSStmtInfo *stmt, JSStmtType type, ptrdiff_t top);/* * Push a block scope statement and link blockAtom's object-valued key into * tc->blockChain. To pop this statement info record, use js_PopStatement as * usual, or if appropriate (if generating code), js_PopStatementCG. */extern voidjs_PushBlockScope(JSTreeContext *tc, JSStmtInfo *stmt, JSAtom *blockAtom, 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 * unless the top statement info record represents a try-catch-finally suite. * 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);/* * Find a lexically scoped variable (one declared by let, catch, or an array * comprehension) named by atom, looking in tc's compile-time scopes. * * If a WITH statement is reached along the scope stack, return its statement * info record, so callers can tell that atom is ambiguous. If slotp is not * null, then if atom is found, set *slotp to its stack slot, otherwise to -1. * This means that if slotp is not null, all the block objects on the lexical * scope chain must have had their depth slots computed by the code generator, * so the caller must be under js_EmitTree. * * In any event, directly return the statement info record in which atom was * found. Otherwise return null. */extern JSStmtInfo *js_LexicalLookup(JSTreeContext *tc, JSAtom *atom, jsint *slotp, JSBool letdecl);/* * Emit code into cg for the tree rooted at pn. */extern JSBooljs_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn);/* * Emit function code into cg for the tree rooted at body. */extern JSBooljs_EmitFunctionBytecode(JSContext *cx, JSCodeGenerator *cg, JSParseNode *body);/* * 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.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -