• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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