���� JFIF �� � ( %"1"%)+...383,7(-.-
![]() Server : Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips PHP/7.4.20 System : Linux st2.domain.com 3.10.0-1127.10.1.el7.x86_64 #1 SMP Wed Jun 3 14:28:03 UTC 2020 x86_64 User : apache ( 48) PHP Version : 7.4.20 Disable Function : NONE Directory : /home/real/node-v13.0.1/deps/v8/src/interpreter/ |
// Copyright 2015 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "src/interpreter/control-flow-builders.h" #include "src/objects/objects-inl.h" namespace v8 { namespace internal { namespace interpreter { BreakableControlFlowBuilder::~BreakableControlFlowBuilder() { BindBreakTarget(); DCHECK(break_labels_.empty() || break_labels_.is_bound()); if (block_coverage_builder_ != nullptr) { block_coverage_builder_->IncrementBlockCounter( node_, SourceRangeKind::kContinuation); } } void BreakableControlFlowBuilder::BindBreakTarget() { break_labels_.Bind(builder()); } void BreakableControlFlowBuilder::EmitJump(BytecodeLabels* sites) { builder()->Jump(sites->New()); } void BreakableControlFlowBuilder::EmitJumpIfTrue( BytecodeArrayBuilder::ToBooleanMode mode, BytecodeLabels* sites) { builder()->JumpIfTrue(mode, sites->New()); } void BreakableControlFlowBuilder::EmitJumpIfFalse( BytecodeArrayBuilder::ToBooleanMode mode, BytecodeLabels* sites) { builder()->JumpIfFalse(mode, sites->New()); } void BreakableControlFlowBuilder::EmitJumpIfUndefined(BytecodeLabels* sites) { builder()->JumpIfUndefined(sites->New()); } void BreakableControlFlowBuilder::EmitJumpIfNull(BytecodeLabels* sites) { builder()->JumpIfNull(sites->New()); } LoopBuilder::~LoopBuilder() { DCHECK(continue_labels_.empty() || continue_labels_.is_bound()); } void LoopBuilder::LoopHeader() { // Jumps from before the loop header into the loop violate ordering // requirements of bytecode basic blocks. The only entry into a loop // must be the loop header. Surely breaks is okay? Not if nested // and misplaced between the headers. DCHECK(break_labels_.empty() && continue_labels_.empty()); builder()->Bind(&loop_header_); } void LoopBuilder::LoopBody() { if (block_coverage_builder_ != nullptr) { block_coverage_builder_->IncrementBlockCounter(block_coverage_body_slot_); } } void LoopBuilder::JumpToHeader(int loop_depth) { // Pass the proper loop nesting level to the backwards branch, to trigger // on-stack replacement when armed for the given loop nesting depth. int level = Min(loop_depth, AbstractCode::kMaxLoopNestingMarker - 1); // Loop must have closed form, i.e. all loop elements are within the loop, // the loop header precedes the body and next elements in the loop. builder()->JumpLoop(&loop_header_, level); } void LoopBuilder::BindContinueTarget() { continue_labels_.Bind(builder()); } SwitchBuilder::~SwitchBuilder() { #ifdef DEBUG for (auto site : case_sites_) { DCHECK(!site.has_referrer_jump() || site.is_bound()); } #endif } void SwitchBuilder::SetCaseTarget(int index, CaseClause* clause) { BytecodeLabel& site = case_sites_.at(index); builder()->Bind(&site); if (block_coverage_builder_) { block_coverage_builder_->IncrementBlockCounter(clause, SourceRangeKind::kBody); } } TryCatchBuilder::~TryCatchBuilder() { if (block_coverage_builder_ != nullptr) { block_coverage_builder_->IncrementBlockCounter( statement_, SourceRangeKind::kContinuation); } } void TryCatchBuilder::BeginTry(Register context) { builder()->MarkTryBegin(handler_id_, context); } void TryCatchBuilder::EndTry() { builder()->MarkTryEnd(handler_id_); builder()->Jump(&exit_); builder()->MarkHandler(handler_id_, catch_prediction_); if (block_coverage_builder_ != nullptr) { block_coverage_builder_->IncrementBlockCounter(statement_, SourceRangeKind::kCatch); } } void TryCatchBuilder::EndCatch() { builder()->Bind(&exit_); } TryFinallyBuilder::~TryFinallyBuilder() { if (block_coverage_builder_ != nullptr) { block_coverage_builder_->IncrementBlockCounter( statement_, SourceRangeKind::kContinuation); } } void TryFinallyBuilder::BeginTry(Register context) { builder()->MarkTryBegin(handler_id_, context); } void TryFinallyBuilder::LeaveTry() { builder()->Jump(finalization_sites_.New()); } void TryFinallyBuilder::EndTry() { builder()->MarkTryEnd(handler_id_); } void TryFinallyBuilder::BeginHandler() { builder()->Bind(&handler_); builder()->MarkHandler(handler_id_, catch_prediction_); } void TryFinallyBuilder::BeginFinally() { finalization_sites_.Bind(builder()); if (block_coverage_builder_ != nullptr) { block_coverage_builder_->IncrementBlockCounter(statement_, SourceRangeKind::kFinally); } } void TryFinallyBuilder::EndFinally() { // Nothing to be done here. } ConditionalControlFlowBuilder::~ConditionalControlFlowBuilder() { if (!else_labels_.is_bound()) else_labels_.Bind(builder()); end_labels_.Bind(builder()); DCHECK(end_labels_.empty() || end_labels_.is_bound()); DCHECK(then_labels_.empty() || then_labels_.is_bound()); DCHECK(else_labels_.empty() || else_labels_.is_bound()); // IfStatement requires a continuation counter, Conditional does not (as it // can only contain expressions). if (block_coverage_builder_ != nullptr && node_->IsIfStatement()) { block_coverage_builder_->IncrementBlockCounter( node_, SourceRangeKind::kContinuation); } } void ConditionalControlFlowBuilder::JumpToEnd() { DCHECK(end_labels_.empty()); // May only be called once. builder()->Jump(end_labels_.New()); } void ConditionalControlFlowBuilder::Then() { then_labels()->Bind(builder()); if (block_coverage_builder_ != nullptr) { block_coverage_builder_->IncrementBlockCounter(block_coverage_then_slot_); } } void ConditionalControlFlowBuilder::Else() { else_labels()->Bind(builder()); if (block_coverage_builder_ != nullptr) { block_coverage_builder_->IncrementBlockCounter(block_coverage_else_slot_); } } } // namespace interpreter } // namespace internal } // namespace v8