📄 nodes.cpp
字号:
{ NodeReleaser::releaseAllNodes(this);}void ReadModifyBracketNode::releaseNodes(NodeReleaser& releaser){ releaser.release(m_base); releaser.release(m_subscript); releaser.release(m_right);}RegisterID* ReadModifyBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst){ RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator)); RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript.get(), m_rightHasAssignments, m_right->isPure(generator)); generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset); RefPtr<RegisterID> value = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property.get()); RegisterID* change = generator.emitNode(m_right.get()); RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), change, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor())); generator.emitExpressionInfo(divot(), startOffset(), endOffset()); generator.emitPutByVal(base.get(), property.get(), updatedValue); return updatedValue;}// ------------------------------ CommaNode ------------------------------------CommaNode::~CommaNode(){ NodeReleaser::releaseAllNodes(this);}void CommaNode::releaseNodes(NodeReleaser& releaser){ releaser.release(m_expr1); releaser.release(m_expr2);}RegisterID* CommaNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst){ generator.emitNode(generator.ignoredResult(), m_expr1.get()); return generator.emitNode(dst, m_expr2.get());}// ------------------------------ ConstDeclNode ------------------------------------ConstDeclNode::~ConstDeclNode(){ NodeReleaser::releaseAllNodes(this);}void ConstDeclNode::releaseNodes(NodeReleaser& releaser){ releaser.release(m_next); releaser.release(m_init);}ConstDeclNode::ConstDeclNode(JSGlobalData* globalData, const Identifier& ident, ExpressionNode* init) : ExpressionNode(globalData) , m_ident(ident) , m_init(init){}RegisterID* ConstDeclNode::emitCodeSingle(BytecodeGenerator& generator){ if (RegisterID* local = generator.constRegisterFor(m_ident)) { if (!m_init) return local; return generator.emitNode(local, m_init.get()); } // FIXME: While this code should only be hit in eval code, it will potentially // assign to the wrong base if m_ident exists in an intervening dynamic scope. RefPtr<RegisterID> base = generator.emitResolveBase(generator.newTemporary(), m_ident); RegisterID* value = m_init ? generator.emitNode(m_init.get()) : generator.emitLoad(0, jsUndefined()); return generator.emitPutById(base.get(), m_ident, value);}RegisterID* ConstDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID*){ RegisterID* result = 0; for (ConstDeclNode* n = this; n; n = n->m_next.get()) result = n->emitCodeSingle(generator); return result;}// ------------------------------ ConstStatementNode -----------------------------ConstStatementNode::~ConstStatementNode(){ NodeReleaser::releaseAllNodes(this);}void ConstStatementNode::releaseNodes(NodeReleaser& releaser){ releaser.release(m_next);}RegisterID* ConstStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*){ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine()); return generator.emitNode(m_next.get());}// ------------------------------ Helper functions for handling Vectors of StatementNode -------------------------------static inline RegisterID* statementListEmitCode(const StatementVector& statements, BytecodeGenerator& generator, RegisterID* dst){ StatementVector::const_iterator end = statements.end(); for (StatementVector::const_iterator it = statements.begin(); it != end; ++it) { StatementNode* n = it->get(); generator.emitNode(dst, n); } return 0;}// ------------------------------ BlockNode ------------------------------------BlockNode::~BlockNode(){ NodeReleaser::releaseAllNodes(this);}void BlockNode::releaseNodes(NodeReleaser& releaser){ size_t size = m_children.size(); for (size_t i = 0; i < size; ++i) releaser.release(m_children[i]);}BlockNode::BlockNode(JSGlobalData* globalData, SourceElements* children) : StatementNode(globalData){ if (children) children->releaseContentsIntoVector(m_children);}RegisterID* BlockNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst){ return statementListEmitCode(m_children, generator, dst);}// ------------------------------ EmptyStatementNode ---------------------------RegisterID* EmptyStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst){ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine()); return dst;}// ------------------------------ DebuggerStatementNode ---------------------------RegisterID* DebuggerStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst){ generator.emitDebugHook(DidReachBreakpoint, firstLine(), lastLine()); return dst;}// ------------------------------ ExprStatementNode ----------------------------RegisterID* ExprStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst){ ASSERT(m_expr); generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine()); return generator.emitNode(dst, m_expr.get());}// ------------------------------ VarStatementNode ----------------------------VarStatementNode::~VarStatementNode(){ NodeReleaser::releaseAllNodes(this);}void VarStatementNode::releaseNodes(NodeReleaser& releaser){ releaser.release(m_expr);}RegisterID* VarStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*){ ASSERT(m_expr); generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine()); return generator.emitNode(m_expr.get());}// ------------------------------ IfNode ---------------------------------------IfNode::~IfNode(){ NodeReleaser::releaseAllNodes(this);}void IfNode::releaseNodes(NodeReleaser& releaser){ releaser.release(m_condition); releaser.release(m_ifBlock);}RegisterID* IfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst){ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine()); RefPtr<Label> afterThen = generator.newLabel(); RegisterID* cond = generator.emitNode(m_condition.get()); generator.emitJumpIfFalse(cond, afterThen.get()); generator.emitNode(dst, m_ifBlock.get()); generator.emitLabel(afterThen.get()); // FIXME: This should return the last statement executed so that it can be returned as a Completion. return 0;}// ------------------------------ IfElseNode ---------------------------------------IfElseNode::~IfElseNode(){ NodeReleaser::releaseAllNodes(this);}void IfElseNode::releaseNodes(NodeReleaser& releaser){ releaser.release(m_elseBlock); IfNode::releaseNodes(releaser);}RegisterID* IfElseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst){ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine()); RefPtr<Label> beforeElse = generator.newLabel(); RefPtr<Label> afterElse = generator.newLabel(); RegisterID* cond = generator.emitNode(m_condition.get()); generator.emitJumpIfFalse(cond, beforeElse.get()); generator.emitNode(dst, m_ifBlock.get()); generator.emitJump(afterElse.get()); generator.emitLabel(beforeElse.get()); generator.emitNode(dst, m_elseBlock.get()); generator.emitLabel(afterElse.get()); // FIXME: This should return the last statement executed so that it can be returned as a Completion. return 0;}// ------------------------------ DoWhileNode ----------------------------------DoWhileNode::~DoWhileNode(){ NodeReleaser::releaseAllNodes(this);}void DoWhileNode::releaseNodes(NodeReleaser& releaser){ releaser.release(m_statement); releaser.release(m_expr);}RegisterID* DoWhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst){ RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop); RefPtr<Label> topOfLoop = generator.newLabel(); generator.emitLabel(topOfLoop.get()); generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine()); RefPtr<RegisterID> result = generator.emitNode(dst, m_statement.get()); generator.emitLabel(scope->continueTarget()); generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo()); RegisterID* cond = generator.emitNode(m_expr.get()); generator.emitJumpIfTrue(cond, topOfLoop.get()); generator.emitLabel(scope->breakTarget()); return result.get();}// ------------------------------ WhileNode ------------------------------------WhileNode::~WhileNode(){ NodeReleaser::releaseAllNodes(this);}void WhileNode::releaseNodes(NodeReleaser& releaser){ releaser.release(m_expr); releaser.release(m_statement);}RegisterID* WhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst){ RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop); generator.emitJump(scope->continueTarget()); RefPtr<Label> topOfLoop = generator.newLabel(); generator.emitLabel(topOfLoop.get()); generator.emitNode(dst, m_statement.get()); generator.emitLabel(scope->continueTarget()); generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo()); RegisterID* cond = generator.emitNode(m_expr.get()); generator.emitJumpIfTrue(cond, topOfLoop.get()); generator.emitLabel(scope->breakTarget()); // FIXME: This should return the last statement executed so that it can be returned as a Completion return 0;}// ------------------------------ ForNode --------------------------------------ForNode::~ForNode(){ NodeReleaser::releaseAllNodes(this);}void ForNode::releaseNodes(NodeReleaser& releaser){ releaser.release(m_expr1); releaser.release(m_expr2); releaser.release(m_expr3); releaser.release(m_statement);}RegisterID* ForNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst){ if (dst == generator.ignoredResult()) dst = 0; RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop); generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine()); if (m_expr1) generator.emitNode(generator.ignoredResult(), m_expr1.get()); RefPtr<Label> condition = generator.newLabel(); generator.emitJump(condition.get()); RefPtr<Label> topOfLoop = generator.newLabel(); generator.emitLabel(topOfLoop.get()); RefPtr<RegisterID> result = generator.emitNode(dst, m_statement.get()); generator.emitLabel(scope->continueTarget()); generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine()); if (m_expr3) generator.emitNode(generator.ignoredResult(), m_expr3.get()); generator.emitLabel(condition.get()); if (m_expr2) { RegisterID* cond = generator.emitNode(m_expr2.get()); generator.emitJumpIfTrue(cond, topOfLoop.get());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -