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 #ifndef V8_INTERPRETER_BYTECODE_LABEL_H_
      6 #define V8_INTERPRETER_BYTECODE_LABEL_H_
      7 
      8 #include "src/zone/zone-containers.h"
      9 
     10 namespace v8 {
     11 namespace internal {
     12 namespace interpreter {
     13 
     14 class BytecodeArrayBuilder;
     15 
     16 // A label representing a branch target in a bytecode array. When a
     17 // label is bound, it represents a known position in the bytecode
     18 // array. For labels that are forward references there can be at most
     19 // one reference whilst it is unbound.
     20 class V8_EXPORT_PRIVATE BytecodeLabel final {
     21  public:
     22   BytecodeLabel() : bound_(false), offset_(kInvalidOffset) {}
     23 
     24   bool is_bound() const { return bound_; }
     25   size_t offset() const { return offset_; }
     26 
     27  private:
     28   static const size_t kInvalidOffset = static_cast<size_t>(-1);
     29 
     30   void bind_to(size_t offset) {
     31     DCHECK(!bound_ && offset != kInvalidOffset);
     32     offset_ = offset;
     33     bound_ = true;
     34   }
     35 
     36   void set_referrer(size_t offset) {
     37     DCHECK(!bound_ && offset != kInvalidOffset && offset_ == kInvalidOffset);
     38     offset_ = offset;
     39   }
     40 
     41   bool is_forward_target() const {
     42     return offset() != kInvalidOffset && !is_bound();
     43   }
     44 
     45   // There are three states for a label:
     46   //                    bound_   offset_
     47   //  UNSET             false    kInvalidOffset
     48   //  FORWARD_TARGET    false    Offset of referring jump
     49   //  BACKWARD_TARGET    true    Offset of label in bytecode array when bound
     50   bool bound_;
     51   size_t offset_;
     52 
     53   friend class BytecodeArrayWriter;
     54 };
     55 
     56 // Class representing a branch target of multiple jumps.
     57 class V8_EXPORT_PRIVATE BytecodeLabels {
     58  public:
     59   explicit BytecodeLabels(Zone* zone) : labels_(zone) {}
     60 
     61   BytecodeLabel* New();
     62 
     63   void Bind(BytecodeArrayBuilder* builder);
     64 
     65   void BindToLabel(BytecodeArrayBuilder* builder, const BytecodeLabel& target);
     66 
     67   bool is_bound() const {
     68     bool is_bound = !labels_.empty() && labels_.at(0).is_bound();
     69     DCHECK(!is_bound ||
     70            std::all_of(labels_.begin(), labels_.end(),
     71                        [](const BytecodeLabel& l) { return l.is_bound(); }));
     72     return is_bound;
     73   }
     74 
     75   bool empty() const { return labels_.empty(); }
     76 
     77  private:
     78   ZoneVector<BytecodeLabel> labels_;
     79 
     80   DISALLOW_COPY_AND_ASSIGN(BytecodeLabels);
     81 };
     82 
     83 }  // namespace interpreter
     84 }  // namespace internal
     85 }  // namespace v8
     86 
     87 #endif  // V8_INTERPRETER_BYTECODE_LABEL_H_
     88