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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
|
// Copyright 2016 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_CODEGEN_SOURCE_POSITION_TABLE_H_
#define V8_CODEGEN_SOURCE_POSITION_TABLE_H_
#include "src/base/export-template.h"
#include "src/codegen/source-position.h"
#include "src/common/assert-scope.h"
#include "src/common/checks.h"
#include "src/common/globals.h"
#include "src/utils/vector.h"
#include "src/zone/zone-containers.h"
namespace v8 {
namespace internal {
class ByteArray;
template <typename T>
class Handle;
class Isolate;
class Zone;
struct PositionTableEntry {
PositionTableEntry()
: code_offset(kFunctionEntryBytecodeOffset),
source_position(0),
is_statement(false) {}
PositionTableEntry(int offset, int64_t source, bool statement)
: code_offset(offset), source_position(source), is_statement(statement) {}
int code_offset;
int64_t source_position;
bool is_statement;
};
class V8_EXPORT_PRIVATE SourcePositionTableBuilder {
public:
enum RecordingMode {
// Indicates that source positions are never to be generated. (Resulting in
// an empty table).
OMIT_SOURCE_POSITIONS,
// Indicates that source positions are not currently required, but may be
// generated later.
LAZY_SOURCE_POSITIONS,
// Indicates that source positions should be immediately generated.
RECORD_SOURCE_POSITIONS
};
explicit SourcePositionTableBuilder(
RecordingMode mode = RECORD_SOURCE_POSITIONS);
void AddPosition(size_t code_offset, SourcePosition source_position,
bool is_statement);
template <typename LocalIsolate>
EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE)
Handle<ByteArray> ToSourcePositionTable(LocalIsolate* isolate);
OwnedVector<byte> ToSourcePositionTableVector();
inline bool Omit() const { return mode_ != RECORD_SOURCE_POSITIONS; }
inline bool Lazy() const { return mode_ == LAZY_SOURCE_POSITIONS; }
private:
void AddEntry(const PositionTableEntry& entry);
RecordingMode mode_;
std::vector<byte> bytes_;
#ifdef ENABLE_SLOW_DCHECKS
std::vector<PositionTableEntry> raw_entries_;
#endif
PositionTableEntry previous_; // Previously written entry, to compute delta.
};
class V8_EXPORT_PRIVATE SourcePositionTableIterator {
public:
// Filter that applies when advancing the iterator. If the filter isn't
// satisfied, we advance the iterator again.
enum IterationFilter { kJavaScriptOnly = 0, kExternalOnly = 1, kAll = 2 };
// Filter that applies only to the first entry of the source position table.
// If it is kSkipFunctionEntry, it will skip the FunctionEntry entry if it
// exists.
enum FunctionEntryFilter {
kSkipFunctionEntry = 0,
kDontSkipFunctionEntry = 1
};
// Used for saving/restoring the iterator.
struct IndexAndPositionState {
int index_;
PositionTableEntry position_;
IterationFilter iteration_filter_;
FunctionEntryFilter function_entry_filter_;
};
// We expose three flavours of the iterator, depending on the argument passed
// to the constructor:
// Handlified iterator allows allocation, but it needs a handle (and thus
// a handle scope). This is the preferred version.
explicit SourcePositionTableIterator(
Handle<ByteArray> byte_array,
IterationFilter iteration_filter = kJavaScriptOnly,
FunctionEntryFilter function_entry_filter = kSkipFunctionEntry);
// Non-handlified iterator does not need a handle scope, but it disallows
// allocation during its lifetime. This is useful if there is no handle
// scope around.
explicit SourcePositionTableIterator(
ByteArray byte_array, IterationFilter iteration_filter = kJavaScriptOnly,
FunctionEntryFilter function_entry_filter = kSkipFunctionEntry);
// Handle-safe iterator based on an a vector located outside the garbage
// collected heap, allows allocation during its lifetime.
explicit SourcePositionTableIterator(
Vector<const byte> bytes,
IterationFilter iteration_filter = kJavaScriptOnly,
FunctionEntryFilter function_entry_filter = kSkipFunctionEntry);
void Advance();
int code_offset() const {
DCHECK(!done());
return current_.code_offset;
}
SourcePosition source_position() const {
DCHECK(!done());
return SourcePosition::FromRaw(current_.source_position);
}
bool is_statement() const {
DCHECK(!done());
return current_.is_statement;
}
bool done() const { return index_ == kDone; }
IndexAndPositionState GetState() const {
return {index_, current_, iteration_filter_, function_entry_filter_};
}
void RestoreState(const IndexAndPositionState& saved_state) {
index_ = saved_state.index_;
current_ = saved_state.position_;
iteration_filter_ = saved_state.iteration_filter_;
function_entry_filter_ = saved_state.function_entry_filter_;
}
private:
// Initializes the source position interator with the first valid bytecode.
// Also sets the FunctionEntry SourcePosition if it exists.
void Initialize();
static const int kDone = -1;
Vector<const byte> raw_table_;
Handle<ByteArray> table_;
int index_ = 0;
PositionTableEntry current_;
IterationFilter iteration_filter_;
FunctionEntryFilter function_entry_filter_;
DISALLOW_HEAP_ALLOCATION(no_gc)
};
} // namespace internal
} // namespace v8
#endif // V8_CODEGEN_SOURCE_POSITION_TABLE_H_
|