📄 bytecodegenerator.h
字号:
RegisterID* emitLoad(RegisterID* dst, const Identifier&); RegisterID* emitLoad(RegisterID* dst, JSValuePtr); RegisterID* emitUnexpectedLoad(RegisterID* dst, bool); RegisterID* emitUnexpectedLoad(RegisterID* dst, double); RegisterID* emitUnaryOp(OpcodeID, RegisterID* dst, RegisterID* src); RegisterID* emitBinaryOp(OpcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2, OperandTypes); RegisterID* emitEqualityOp(OpcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2); RegisterID* emitUnaryNoDstOp(OpcodeID, RegisterID* src); RegisterID* emitNewObject(RegisterID* dst); RegisterID* emitNewArray(RegisterID* dst, ElementNode*); // stops at first elision RegisterID* emitNewFunction(RegisterID* dst, FuncDeclNode* func); RegisterID* emitNewFunctionExpression(RegisterID* dst, FuncExprNode* func); RegisterID* emitNewRegExp(RegisterID* dst, RegExp* regExp); RegisterID* emitMove(RegisterID* dst, RegisterID* src); RegisterID* emitToJSNumber(RegisterID* dst, RegisterID* src) { return emitUnaryOp(op_to_jsnumber, dst, src); } RegisterID* emitPreInc(RegisterID* srcDst); RegisterID* emitPreDec(RegisterID* srcDst); RegisterID* emitPostInc(RegisterID* dst, RegisterID* srcDst); RegisterID* emitPostDec(RegisterID* dst, RegisterID* srcDst); RegisterID* emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* base, RegisterID* basePrototype); RegisterID* emitTypeOf(RegisterID* dst, RegisterID* src) { return emitUnaryOp(op_typeof, dst, src); } RegisterID* emitIn(RegisterID* dst, RegisterID* property, RegisterID* base) { return emitBinaryOp(op_in, dst, property, base, OperandTypes()); } RegisterID* emitResolve(RegisterID* dst, const Identifier& property); RegisterID* emitGetScopedVar(RegisterID* dst, size_t skip, int index, JSValuePtr globalObject); RegisterID* emitPutScopedVar(size_t skip, int index, RegisterID* value, JSValuePtr globalObject); RegisterID* emitResolveBase(RegisterID* dst, const Identifier& property); RegisterID* emitResolveWithBase(RegisterID* baseDst, RegisterID* propDst, const Identifier& property); RegisterID* emitResolveFunction(RegisterID* baseDst, RegisterID* funcDst, const Identifier& property); RegisterID* emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property); RegisterID* emitPutById(RegisterID* base, const Identifier& property, RegisterID* value); RegisterID* emitDeleteById(RegisterID* dst, RegisterID* base, const Identifier&); RegisterID* emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* property); RegisterID* emitPutByVal(RegisterID* base, RegisterID* property, RegisterID* value); RegisterID* emitDeleteByVal(RegisterID* dst, RegisterID* base, RegisterID* property); RegisterID* emitPutByIndex(RegisterID* base, unsigned index, RegisterID* value); RegisterID* emitPutGetter(RegisterID* base, const Identifier& property, RegisterID* value); RegisterID* emitPutSetter(RegisterID* base, const Identifier& property, RegisterID* value); RegisterID* emitCall(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset); RegisterID* emitCallEval(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset); RegisterID* emitReturn(RegisterID* src); RegisterID* emitEnd(RegisterID* src) { return emitUnaryNoDstOp(op_end, src); } RegisterID* emitConstruct(RegisterID* dst, RegisterID* func, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset); PassRefPtr<Label> emitLabel(Label*); PassRefPtr<Label> emitJump(Label* target); PassRefPtr<Label> emitJumpIfTrue(RegisterID* cond, Label* target); PassRefPtr<Label> emitJumpIfFalse(RegisterID* cond, Label* target); PassRefPtr<Label> emitJumpScopes(Label* target, int targetScopeDepth); PassRefPtr<Label> emitJumpSubroutine(RegisterID* retAddrDst, Label*); void emitSubroutineReturn(RegisterID* retAddrSrc); RegisterID* emitGetPropertyNames(RegisterID* dst, RegisterID* base) { return emitUnaryOp(op_get_pnames, dst, base); } RegisterID* emitNextPropertyName(RegisterID* dst, RegisterID* iter, Label* target); RegisterID* emitCatch(RegisterID*, Label* start, Label* end); void emitThrow(RegisterID* exc) { emitUnaryNoDstOp(op_throw, exc); } RegisterID* emitNewError(RegisterID* dst, ErrorType type, JSValuePtr message); void emitPushNewScope(RegisterID* dst, Identifier& property, RegisterID* value); RegisterID* emitPushScope(RegisterID* scope); void emitPopScope(); void emitDebugHook(DebugHookID, int firstLine, int lastLine); int scopeDepth() { return m_dynamicScopeDepth + m_finallyDepth; } void pushFinallyContext(Label* target, RegisterID* returnAddrDst); void popFinallyContext(); LabelScope* breakTarget(const Identifier&); LabelScope* continueTarget(const Identifier&); void beginSwitch(RegisterID*, SwitchInfo::SwitchType); void endSwitch(uint32_t clauseCount, RefPtr<Label>*, ExpressionNode**, Label* defaultLabel, int32_t min, int32_t range); CodeType codeType() const { return m_codeType; } void setRegeneratingForExceptionInfo(CodeBlock* originalCodeBlock) { m_regeneratingForExceptionInfo = true; m_codeBlockBeingRegeneratedFrom = originalCodeBlock; } private: void emitOpcode(OpcodeID); void retrieveLastBinaryOp(int& dstIndex, int& src1Index, int& src2Index); void retrieveLastUnaryOp(int& dstIndex, int& srcIndex); void rewindBinaryOp(); void rewindUnaryOp(); PassRefPtr<Label> emitComplexJumpScopes(Label* target, ControlFlowContext* topScope, ControlFlowContext* bottomScope); struct JSValueHashTraits : HashTraits<JSValueEncodedAsPointer*> { static void constructDeletedValue(JSValueEncodedAsPointer*& slot) { slot = JSValuePtr::encode(jsImpossibleValue()); } static bool isDeletedValue(JSValueEncodedAsPointer* value) { return value == JSValuePtr::encode(jsImpossibleValue()); } }; typedef HashMap<JSValueEncodedAsPointer*, unsigned, PtrHash<JSValueEncodedAsPointer*>, JSValueHashTraits> JSValueMap; struct IdentifierMapIndexHashTraits { typedef int TraitType; typedef IdentifierMapIndexHashTraits StorageTraits; static int emptyValue() { return std::numeric_limits<int>::max(); } static const bool emptyValueIsZero = false; static const bool needsDestruction = false; static const bool needsRef = false; }; typedef HashMap<RefPtr<UString::Rep>, int, IdentifierRepHash, HashTraits<RefPtr<UString::Rep> >, IdentifierMapIndexHashTraits> IdentifierMap; typedef HashMap<double, JSValuePtr> NumberMap; typedef HashMap<UString::Rep*, JSString*, IdentifierRepHash> IdentifierStringMap; RegisterID* emitCall(OpcodeID, RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset); RegisterID* newRegister(); // Returns the RegisterID corresponding to ident. RegisterID* addVar(const Identifier& ident, bool isConstant) { RegisterID* local; addVar(ident, isConstant, local); return local; } // Returns true if a new RegisterID was added, false if a pre-existing RegisterID was re-used. bool addVar(const Identifier&, bool isConstant, RegisterID*&); // Returns the RegisterID corresponding to ident. RegisterID* addGlobalVar(const Identifier& ident, bool isConstant) { RegisterID* local; addGlobalVar(ident, isConstant, local); return local; } // Returns true if a new RegisterID was added, false if a pre-existing RegisterID was re-used. bool addGlobalVar(const Identifier&, bool isConstant, RegisterID*&); RegisterID* addParameter(const Identifier&); void allocateConstants(size_t); RegisterID& registerFor(int index) { if (index >= 0) return m_calleeRegisters[index]; if (index == RegisterFile::OptionalCalleeArguments) return m_argumentsRegister; if (m_parameters.size()) { ASSERT(!m_globals.size()); return m_parameters[index + m_parameters.size() + RegisterFile::CallFrameHeaderSize]; } return m_globals[-index - 1]; } unsigned addConstant(FuncDeclNode*); unsigned addConstant(FuncExprNode*); unsigned addConstant(const Identifier&); RegisterID* addConstant(JSValuePtr); unsigned addUnexpectedConstant(JSValuePtr); unsigned addRegExp(RegExp*); Vector<Instruction>& instructions() { return m_codeBlock->instructions(); } SymbolTable& symbolTable() { return *m_symbolTable; } bool shouldOptimizeLocals() { return (m_codeType != EvalCode) && !m_dynamicScopeDepth; } bool canOptimizeNonLocals() { return (m_codeType == FunctionCode) && !m_dynamicScopeDepth && !m_codeBlock->usesEval(); } RegisterID* emitThrowExpressionTooDeepException(); bool m_shouldEmitDebugHooks; bool m_shouldEmitProfileHooks; const ScopeChain* m_scopeChain; SymbolTable* m_symbolTable; ScopeNode* m_scopeNode; CodeBlock* m_codeBlock; HashSet<RefPtr<UString::Rep>, IdentifierRepHash> m_functions; RegisterID m_ignoredResultRegister; RegisterID m_thisRegister; RegisterID m_argumentsRegister; int m_activationRegisterIndex; SegmentedVector<RegisterID, 512> m_calleeRegisters; SegmentedVector<RegisterID, 512> m_parameters; SegmentedVector<RegisterID, 512> m_globals; SegmentedVector<LabelScope, 256> m_labelScopes; SegmentedVector<Label, 256> m_labels; RefPtr<RegisterID> m_lastConstant; int m_finallyDepth; int m_dynamicScopeDepth; int m_baseScopeDepth; CodeType m_codeType; Vector<ControlFlowContext> m_scopeContextStack; Vector<SwitchInfo> m_switchContextStack; int m_nextGlobalIndex; int m_nextParameterIndex; int m_nextConstantIndex; int m_globalVarStorageOffset; // Constant pool IdentifierMap m_identifierMap; JSValueMap m_jsValueMap; NumberMap m_numberMap; IdentifierStringMap m_stringMap; JSGlobalData* m_globalData; OpcodeID m_lastOpcodeID; unsigned m_emitNodeDepth; bool m_regeneratingForExceptionInfo; CodeBlock* m_codeBlockBeingRegeneratedFrom; static const unsigned s_maxEmitNodeDepth = 10000; };}#endif // BytecodeGenerator_h
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -