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: BytecodeLabel()22 BytecodeLabel() : bound_(false), offset_(kInvalidOffset) {} 23 is_bound()24 bool is_bound() const { return bound_; } offset()25 size_t offset() const { return offset_; } 26 27 private: 28 static const size_t kInvalidOffset = static_cast<size_t>(-1); 29 bind_to(size_t offset)30 void bind_to(size_t offset) { 31 DCHECK(!bound_ && offset != kInvalidOffset); 32 offset_ = offset; 33 bound_ = true; 34 } 35 set_referrer(size_t offset)36 void set_referrer(size_t offset) { 37 DCHECK(!bound_ && offset != kInvalidOffset && offset_ == kInvalidOffset); 38 offset_ = offset; 39 } 40 is_forward_target()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: BytecodeLabels(Zone * zone)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 is_bound()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 empty()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