Home | History | Annotate | Download | only in interpreter
      1 // Copyright 2015 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "src/interpreter/control-flow-builders.h"
      6 
      7 namespace v8 {
      8 namespace internal {
      9 namespace interpreter {
     10 
     11 
     12 BreakableControlFlowBuilder::~BreakableControlFlowBuilder() {
     13   DCHECK(break_sites_.empty());
     14 }
     15 
     16 
     17 void BreakableControlFlowBuilder::SetBreakTarget(const BytecodeLabel& target) {
     18   BindLabels(target, &break_sites_);
     19 }
     20 
     21 
     22 void BreakableControlFlowBuilder::EmitJump(ZoneVector<BytecodeLabel>* sites) {
     23   sites->push_back(BytecodeLabel());
     24   builder()->Jump(&sites->back());
     25 }
     26 
     27 
     28 void BreakableControlFlowBuilder::EmitJumpIfTrue(
     29     ZoneVector<BytecodeLabel>* sites) {
     30   sites->push_back(BytecodeLabel());
     31   builder()->JumpIfTrue(&sites->back());
     32 }
     33 
     34 
     35 void BreakableControlFlowBuilder::EmitJumpIfFalse(
     36     ZoneVector<BytecodeLabel>* sites) {
     37   sites->push_back(BytecodeLabel());
     38   builder()->JumpIfFalse(&sites->back());
     39 }
     40 
     41 
     42 void BreakableControlFlowBuilder::EmitJumpIfUndefined(
     43     ZoneVector<BytecodeLabel>* sites) {
     44   sites->push_back(BytecodeLabel());
     45   builder()->JumpIfUndefined(&sites->back());
     46 }
     47 
     48 
     49 void BreakableControlFlowBuilder::EmitJumpIfNull(
     50     ZoneVector<BytecodeLabel>* sites) {
     51   sites->push_back(BytecodeLabel());
     52   builder()->JumpIfNull(&sites->back());
     53 }
     54 
     55 
     56 void BreakableControlFlowBuilder::EmitJump(ZoneVector<BytecodeLabel>* sites,
     57                                            int index) {
     58   builder()->Jump(&sites->at(index));
     59 }
     60 
     61 
     62 void BreakableControlFlowBuilder::EmitJumpIfTrue(
     63     ZoneVector<BytecodeLabel>* sites, int index) {
     64   builder()->JumpIfTrue(&sites->at(index));
     65 }
     66 
     67 
     68 void BreakableControlFlowBuilder::EmitJumpIfFalse(
     69     ZoneVector<BytecodeLabel>* sites, int index) {
     70   builder()->JumpIfFalse(&sites->at(index));
     71 }
     72 
     73 
     74 void BreakableControlFlowBuilder::BindLabels(const BytecodeLabel& target,
     75                                              ZoneVector<BytecodeLabel>* sites) {
     76   for (size_t i = 0; i < sites->size(); i++) {
     77     BytecodeLabel& site = sites->at(i);
     78     builder()->Bind(target, &site);
     79   }
     80   sites->clear();
     81 }
     82 
     83 
     84 void BlockBuilder::EndBlock() {
     85   builder()->Bind(&block_end_);
     86   SetBreakTarget(block_end_);
     87 }
     88 
     89 
     90 LoopBuilder::~LoopBuilder() { DCHECK(continue_sites_.empty()); }
     91 
     92 
     93 void LoopBuilder::LoopHeader(ZoneVector<BytecodeLabel>* additional_labels) {
     94   // Jumps from before the loop header into the loop violate ordering
     95   // requirements of bytecode basic blocks. The only entry into a loop
     96   // must be the loop header. Surely breaks is okay? Not if nested
     97   // and misplaced between the headers.
     98   DCHECK(break_sites_.empty() && continue_sites_.empty());
     99   builder()->Bind(&loop_header_);
    100   for (auto& label : *additional_labels) {
    101     builder()->Bind(loop_header_, &label);
    102   }
    103 }
    104 
    105 
    106 void LoopBuilder::EndLoop() {
    107   // Loop must have closed form, i.e. all loop elements are within the loop,
    108   // the loop header precedes the body and next elements in the loop.
    109   DCHECK(loop_header_.is_bound());
    110   builder()->Bind(&loop_end_);
    111   SetBreakTarget(loop_end_);
    112 }
    113 
    114 void LoopBuilder::SetContinueTarget() {
    115   BytecodeLabel target;
    116   builder()->Bind(&target);
    117   BindLabels(target, &continue_sites_);
    118 }
    119 
    120 
    121 SwitchBuilder::~SwitchBuilder() {
    122 #ifdef DEBUG
    123   for (auto site : case_sites_) {
    124     DCHECK(site.is_bound());
    125   }
    126 #endif
    127 }
    128 
    129 
    130 void SwitchBuilder::SetCaseTarget(int index) {
    131   BytecodeLabel& site = case_sites_.at(index);
    132   builder()->Bind(&site);
    133 }
    134 
    135 
    136 void TryCatchBuilder::BeginTry(Register context) {
    137   builder()->MarkTryBegin(handler_id_, context);
    138 }
    139 
    140 
    141 void TryCatchBuilder::EndTry() {
    142   builder()->MarkTryEnd(handler_id_);
    143   builder()->Jump(&exit_);
    144   builder()->Bind(&handler_);
    145   builder()->MarkHandler(handler_id_, true);
    146 }
    147 
    148 
    149 void TryCatchBuilder::EndCatch() { builder()->Bind(&exit_); }
    150 
    151 
    152 void TryFinallyBuilder::BeginTry(Register context) {
    153   builder()->MarkTryBegin(handler_id_, context);
    154 }
    155 
    156 
    157 void TryFinallyBuilder::LeaveTry() {
    158   finalization_sites_.push_back(BytecodeLabel());
    159   builder()->Jump(&finalization_sites_.back());
    160 }
    161 
    162 
    163 void TryFinallyBuilder::EndTry() {
    164   builder()->MarkTryEnd(handler_id_);
    165 }
    166 
    167 
    168 void TryFinallyBuilder::BeginHandler() {
    169   builder()->Bind(&handler_);
    170   builder()->MarkHandler(handler_id_, will_catch_);
    171 }
    172 
    173 
    174 void TryFinallyBuilder::BeginFinally() {
    175   for (size_t i = 0; i < finalization_sites_.size(); i++) {
    176     BytecodeLabel& site = finalization_sites_.at(i);
    177     builder()->Bind(&site);
    178   }
    179 }
    180 
    181 
    182 void TryFinallyBuilder::EndFinally() {
    183   // Nothing to be done here.
    184 }
    185 
    186 }  // namespace interpreter
    187 }  // namespace internal
    188 }  // namespace v8
    189