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