v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
ast-value-factory.h
Go to the documentation of this file.
1// Copyright 2014 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#ifndef V8_AST_AST_VALUE_FACTORY_H_
29#define V8_AST_AST_VALUE_FACTORY_H_
30
31#include <forward_list>
32
33#include "src/base/hashmap.h"
34#include "src/base/logging.h"
35#include "src/common/globals.h"
36#include "src/handles/handles.h"
38#include "src/objects/name.h"
39#include "src/zone/zone.h"
40
41// Ast(Raw|Cons)String and AstValueFactory are for storing strings and
42// values independent of the V8 heap and internalizing them later. During
43// parsing, they are created and stored outside the heap, in AstValueFactory.
44// After parsing, the strings and values are internalized (moved into the V8
45// heap).
46namespace v8 {
47namespace internal {
48
49class Isolate;
50
51class AstRawString final : public ZoneObject {
52 public:
53 static bool Equal(const AstRawString* lhs, const AstRawString* rhs);
54
55 // Returns 0 if lhs is equal to rhs.
56 // Returns <0 if lhs is less than rhs in code point order.
57 // Returns >0 if lhs is greater than than rhs in code point order.
58 static int Compare(const AstRawString* lhs, const AstRawString* rhs);
59
60 bool IsEmpty() const { return literal_bytes_.length() == 0; }
61 int length() const {
63 : literal_bytes_.length() / 2;
64 }
65 bool AsArrayIndex(uint32_t* index) const;
66 bool IsIntegerIndex() const;
67 V8_EXPORT_PRIVATE bool IsOneByteEqualTo(const char* data) const;
68 uint16_t FirstCharacter() const;
69
70 template <typename IsolateT>
71 void Internalize(IsolateT* isolate);
72
73 // Access the physical representation:
74 bool is_one_byte() const { return is_one_byte_; }
75 int byte_length() const { return literal_bytes_.length(); }
76 const unsigned char* raw_data() const { return literal_bytes_.begin(); }
77
78 bool IsPrivateName() const { return length() > 0 && FirstCharacter() == '#'; }
79
80 // For storing AstRawStrings in a hash map.
81 uint32_t raw_hash_field() const { return raw_hash_field_; }
82 uint32_t Hash() const {
83 // Hash field must be computed.
86 }
87
88 // This function can be called after internalizing.
90 DCHECK(has_string_);
91 return string_;
92 }
93
94#ifdef OBJECT_PRINT
95 void Print() const;
96#endif // OBJECT_PRINT
97
98 private:
100 friend class AstStringConstants;
101 friend class AstValueFactory;
102 friend Zone;
103
104 // Members accessed only by the AstValueFactory & related classes:
106 uint32_t raw_hash_field)
107 : next_(nullptr),
108 literal_bytes_(literal_bytes),
112 DCHECK(!has_string_);
113 return next_;
114 }
116 DCHECK(!has_string_);
117 return &next_;
118 }
119
121 DCHECK(!string.is_null());
122 DCHECK(!has_string_);
123 string_ = string;
124#ifdef DEBUG
125 has_string_ = true;
126#endif
127 }
128
129 union {
132 };
133
137#ifdef DEBUG
138 // (Debug-only:) Verify the object life-cylce: Some functions may only be
139 // called after internalization (that is, after a v8::internal::String has
140 // been set); some only before.
141 bool has_string_ = false;
142#endif
143};
144
145extern template EXPORT_TEMPLATE_DECLARE(
147extern template EXPORT_TEMPLATE_DECLARE(
149
150class AstConsString final : public ZoneObject {
151 public:
153 if (s->IsEmpty()) return this;
154 if (!IsEmpty()) {
155 // We're putting the new string to the head of the list, meaning
156 // the string segments will be in reverse order.
157 Segment* tmp = zone->New<Segment>(segment_);
158 segment_.next = tmp;
159 }
160 segment_.string = s;
161 return this;
162 }
163
164 bool IsEmpty() const {
165 DCHECK_IMPLIES(segment_.string == nullptr, segment_.next == nullptr);
166 DCHECK_IMPLIES(segment_.string != nullptr, !segment_.string->IsEmpty());
167 return segment_.string == nullptr;
168 }
169
170 template <typename IsolateT>
172 if (string_.is_null()) {
173 string_ = Allocate(isolate);
174 }
175 return string_;
176 }
177
178 template <typename IsolateT>
180 Handle<String> AllocateFlat(IsolateT* isolate) const;
181
182 std::forward_list<const AstRawString*> ToRawStrings() const;
183
184 const AstRawString* last() const { return segment_.string; }
185
186 private:
187 friend class AstValueFactory;
188 friend Zone;
189
190 AstConsString() : string_(), segment_({nullptr, nullptr}) {}
191
192 template <typename IsolateT>
194 Handle<String> Allocate(IsolateT* isolate) const;
195
197
198 // A linked list of AstRawStrings of the contents of this AstConsString.
199 // This list has several properties:
200 //
201 // * For empty strings the string pointer is null,
202 // * Appended raw strings are added to the head of the list, so they are in
203 // reverse order
209};
210
212 public:
213 // |bigint| must be a NUL-terminated string of ASCII characters
214 // representing a BigInt (suitable for passing to BigIntLiteral()
215 // from conversions.h).
216 explicit AstBigInt(const char* bigint) : bigint_(bigint) {}
217
218 const char* c_str() const { return bigint_; }
219
220 private:
221 const char* bigint_;
222};
223
225 bool operator()(uint32_t hash1, uint32_t hash2,
226 const AstRawString* lookup_key,
227 const AstRawString* entry_key) const {
228 return hash1 == hash2 && AstRawString::Equal(lookup_key, entry_key);
229 }
230};
231
236
237// For generating constants.
238#define AST_STRING_CONSTANTS_INTERNALIZED_STRING_LIST_ADAPTER(F, name, \
239 contents) \
240 F(name, contents)
241#define SINGLE_CHARACTER_ASCII_AST_STRING_CONSTANTS(F) \
242 SINGLE_CHARACTER_ASCII_INTERNALIZED_STRING_LIST_GENERATOR( \
243 AST_STRING_CONSTANTS_INTERNALIZED_STRING_LIST_ADAPTER, F)
244#define AST_STRING_CONSTANTS(F) \
245 SINGLE_CHARACTER_ASCII_AST_STRING_CONSTANTS(F) \
246 F(anonymous_string, "anonymous") \
247 F(arguments_string, "arguments") \
248 F(as_string, "as") \
249 F(assert_string, "assert") \
250 F(async_string, "async") \
251 F(bigint_string, "bigint") \
252 F(boolean_string, "boolean") \
253 F(computed_string, "<computed>") \
254 F(dot_brand_string, ".brand") \
255 F(constructor_string, "constructor") \
256 F(default_string, "default") \
257 F(done_string, "done") \
258 F(dot_default_string, ".default") \
259 F(dot_for_string, ".for") \
260 F(dot_generator_object_string, ".generator_object") \
261 F(dot_home_object_string, ".home_object") \
262 F(dot_result_string, ".result") \
263 F(dot_repl_result_string, ".repl_result") \
264 F(dot_static_home_object_string, ".static_home_object") \
265 F(dot_switch_tag_string, ".switch_tag") \
266 F(dot_catch_string, ".catch") \
267 F(empty_string, "") \
268 F(eval_string, "eval") \
269 F(from_string, "from") \
270 F(function_string, "function") \
271 F(get_space_string, "get ") \
272 F(length_string, "length") \
273 F(let_string, "let") \
274 F(meta_string, "meta") \
275 F(native_string, "native") \
276 F(new_target_string, ".new.target") \
277 F(next_string, "next") \
278 F(number_string, "number") \
279 F(object_string, "object") \
280 F(private_constructor_string, "#constructor") \
281 F(proto_string, "__proto__") \
282 F(prototype_string, "prototype") \
283 F(return_string, "return") \
284 F(set_space_string, "set ") \
285 F(source_string, "source") \
286 F(string_string, "string") \
287 F(symbol_string, "symbol") \
288 F(target_string, "target") \
289 F(this_string, "this") \
290 F(this_function_string, ".this_function") \
291 F(throw_string, "throw") \
292 F(undefined_string, "undefined") \
293 F(value_string, "value")
294
296 public:
297#define F(name, str) +1
298 static constexpr int kMaxOneCharStringValue =
300#undef F
301
302 AstStringConstants(Isolate* isolate, uint64_t hash_seed);
305
306#define F(name, str) \
307 const AstRawString* name() const { return name##_; }
309#undef F
310
311 uint64_t hash_seed() const { return hash_seed_; }
312 const AstRawStringMap* string_table() const { return &string_table_; }
313 const AstRawString* one_character_string(int c) const {
314 DCHECK_GE(c, 0);
316
317 // Make sure we can access the one character strings via an offset
318 // from ascii_nul_string_.
319#define F(name, str) \
320 static_assert(offsetof(AstStringConstants, name##_) == \
321 offsetof(AstStringConstants, ascii_nul_string_) + \
322 str[0] * sizeof(AstRawString*));
324#undef F
325
326 return (&ascii_nul_string_)[c];
327 }
328
329 private:
332 uint64_t hash_seed_;
333
334#define F(name, str) AstRawString* name##_;
336#undef F
337};
338
340 public:
341 AstValueFactory(Zone* zone, const AstStringConstants* string_constants,
342 uint64_t hash_seed)
343 : AstValueFactory(zone, zone, string_constants, hash_seed) {}
344
346 const AstStringConstants* string_constants,
347 uint64_t hash_seed)
348 : string_table_(string_constants->string_table()),
349 strings_(nullptr),
351 string_constants_(string_constants),
352 empty_cons_string_(nullptr),
355 hash_seed_(hash_seed) {
358 DCHECK_EQ(hash_seed, string_constants->hash_seed());
359
360 // Allocate the empty ConsString in the AstRawString Zone instead of the
361 // single parse Zone like other ConsStrings, because unlike those it can be
362 // reused across parses.
364 }
365
370
375
379 const AstRawString* GetOneByteString(const char* string) {
381 }
387
391 const AstRawString* str2);
392
393 // Internalize all the strings in the factory, and prevent any more from being
394 // allocated. Multiple calls to Internalize are allowed, for simplicity, where
395 // subsequent calls are a no-op.
396 template <typename IsolateT>
397 void Internalize(IsolateT* isolate);
398
399#define F(name, str) \
400 const AstRawString* name() const { return string_constants_->name(); }
402#undef F
404
405 private:
408 strings_end_ = string->next_location();
409 return string;
410 }
412 strings_ = nullptr;
414 }
419 const AstRawString* GetString(uint32_t raw_hash_field, bool is_one_byte,
420 base::Vector<const uint8_t> literal_bytes);
421
422 // All strings are copied here.
424
427
428 // Holds constant string values which are shared across the isolate.
430
432
435
436 uint64_t hash_seed_;
437};
438
439extern template EXPORT_TEMPLATE_DECLARE(
441 isolate);
442
443extern template EXPORT_TEMPLATE_DECLARE(
446
447} // namespace internal
448} // namespace v8
449
450#endif // V8_AST_AST_VALUE_FACTORY_H_
#define AST_STRING_CONSTANTS(F)
#define SINGLE_CHARACTER_ASCII_AST_STRING_CONSTANTS(F)
static constexpr T decode(U value)
Definition bit-field.h:66
int length() const
Definition vector.h:64
constexpr T * begin() const
Definition vector.h:96
AstBigInt(const char *bigint)
const char * c_str() const
AstConsString * AddString(Zone *zone, const AstRawString *s)
IndirectHandle< String > string_
IndirectHandle< String > GetString(IsolateT *isolate)
AstRawString(bool is_one_byte, base::Vector< const uint8_t > literal_bytes, uint32_t raw_hash_field)
V8_EXPORT_PRIVATE bool IsOneByteEqualTo(const char *data) const
base::Vector< const uint8_t > literal_bytes_
void Internalize(IsolateT *isolate)
const unsigned char * raw_data() const
V8_INLINE IndirectHandle< String > string() const
IndirectHandle< String > string_
static bool Equal(const AstRawString *lhs, const AstRawString *rhs)
bool AsArrayIndex(uint32_t *index) const
friend class AstRawStringInternalizationKey
static int Compare(const AstRawString *lhs, const AstRawString *rhs)
void set_string(IndirectHandle< String > string)
AstStringConstants(const AstStringConstants &)=delete
const AstRawString * one_character_string(int c) const
static constexpr int kMaxOneCharStringValue
const AstRawStringMap * string_table() const
AstStringConstants & operator=(const AstStringConstants &)=delete
AstStringConstants(Isolate *isolate, uint64_t hash_seed)
V8_EXPORT_PRIVATE const AstRawString * GetOneByteStringInternal(base::Vector< const uint8_t > literal)
AstConsString * empty_cons_string() const
const AstRawString * GetOneByteString(const char *string)
const AstRawString * GetString(uint32_t raw_hash_field, bool is_one_byte, base::Vector< const uint8_t > literal_bytes)
const AstStringConstants * string_constants_
const AstRawString * GetString(Tagged< String > literal, const SharedStringAccessGuardIfNeeded &)
const AstRawString * GetOneByteString(base::Vector< const uint8_t > literal)
void Internalize(IsolateT *isolate)
AstValueFactory(Zone *ast_raw_string_zone, Zone *single_parse_zone, const AstStringConstants *string_constants, uint64_t hash_seed)
const AstRawString * GetTwoByteString(base::Vector< const uint16_t > literal)
const AstRawString * GetTwoByteStringInternal(base::Vector< const uint16_t > literal)
AstValueFactory(Zone *zone, const AstStringConstants *string_constants, uint64_t hash_seed)
AstRawString * AddString(AstRawString *string)
V8_EXPORT_PRIVATE AstConsString * NewConsString()
static constexpr int kHashNotComputedMask
Definition name.h:131
T * New(Args &&... args)
Definition zone.h:114
DirectHandle< String > string_
#define EXPORT_TEMPLATE_DECLARE(export)
Register tmp
FunctionLiteral * literal
Definition liveedit.cc:294
int s
Definition mul-fft.cc:297
STL namespace.
Vector< const uint8_t > OneByteVector(const char *data, size_t length)
Definition vector.h:337
void Print(Tagged< Object > obj)
Definition objects.h:774
template const char * string
ReadOnlySegmentForSerialization *const segment_
#define DCHECK_NOT_NULL(val)
Definition logging.h:492
#define DCHECK_IMPLIES(v1, v2)
Definition logging.h:493
#define DCHECK_GE(v1, v2)
Definition logging.h:488
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_LT(v1, v2)
Definition logging.h:489
#define DCHECK_EQ(v1, v2)
Definition logging.h:485
#define V8_EXPORT_PRIVATE
Definition macros.h:460
bool operator()(uint32_t hash1, uint32_t hash2, const AstRawString *lookup_key, const AstRawString *entry_key) const
#define V8_INLINE
Definition v8config.h:500