V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
ast-value-factory.h
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/conversions.h"
35 #include "src/globals.h"
36 #include "src/heap/factory.h"
37 #include "src/isolate.h"
38 #include "src/utils.h"
39 
40 // Ast(Raw|Cons)String and AstValueFactory are for storing strings and
41 // values independent of the V8 heap and internalizing them later. During
42 // parsing, they are created and stored outside the heap, in AstValueFactory.
43 // After parsing, the strings and values are internalized (moved into the V8
44 // heap).
45 namespace v8 {
46 namespace internal {
47 
48 class AstRawString final : public ZoneObject {
49  public:
50  bool IsEmpty() const { return literal_bytes_.length() == 0; }
51  int length() const {
52  return is_one_byte() ? literal_bytes_.length()
53  : literal_bytes_.length() / 2;
54  }
55  bool AsArrayIndex(uint32_t* index) const;
56  bool IsOneByteEqualTo(const char* data) const;
57  uint16_t FirstCharacter() const;
58 
59  void Internalize(Isolate* isolate);
60 
61  // Access the physical representation:
62  bool is_one_byte() const { return is_one_byte_; }
63  int byte_length() const { return literal_bytes_.length(); }
64  const unsigned char* raw_data() const {
65  return literal_bytes_.start();
66  }
67 
68  // For storing AstRawStrings in a hash map.
69  uint32_t hash_field() const { return hash_field_; }
70  uint32_t Hash() const { return hash_field_ >> Name::kHashShift; }
71 
72  // This function can be called after internalizing.
73  V8_INLINE Handle<String> string() const {
74  DCHECK_NOT_NULL(string_);
75  DCHECK(has_string_);
76  return Handle<String>(string_);
77  }
78 
79  private:
80  friend class AstRawStringInternalizationKey;
81  friend class AstStringConstants;
82  friend class AstValueFactory;
83 
84  // Members accessed only by the AstValueFactory & related classes:
85  static bool Compare(void* a, void* b);
86  AstRawString(bool is_one_byte, const Vector<const byte>& literal_bytes,
87  uint32_t hash_field)
88  : next_(nullptr),
89  literal_bytes_(literal_bytes),
90  hash_field_(hash_field),
91  is_one_byte_(is_one_byte) {}
92  AstRawString* next() {
93  DCHECK(!has_string_);
94  return next_;
95  }
96  AstRawString** next_location() {
97  DCHECK(!has_string_);
98  return &next_;
99  }
100 
101  void set_string(Handle<String> string) {
102  DCHECK(!string.is_null());
103  DCHECK(!has_string_);
104  string_ = string.location();
105 #ifdef DEBUG
106  has_string_ = true;
107 #endif
108  }
109 
110  // {string_} is stored as Address* instead of a Handle<String> so it can be
111  // stored in a union with {next_}.
112  union {
113  AstRawString* next_;
114  Address* string_;
115  };
116 
117  Vector<const byte> literal_bytes_; // Memory owned by Zone.
118  uint32_t hash_field_;
119  bool is_one_byte_;
120 #ifdef DEBUG
121  // (Debug-only:) Verify the object life-cylce: Some functions may only be
122  // called after internalization (that is, after a v8::internal::String has
123  // been set); some only before.
124  bool has_string_ = false;
125 #endif
126 };
127 
128 class AstConsString final : public ZoneObject {
129  public:
130  AstConsString* AddString(Zone* zone, const AstRawString* s) {
131  if (s->IsEmpty()) return this;
132  if (!IsEmpty()) {
133  // We're putting the new string to the head of the list, meaning
134  // the string segments will be in reverse order.
135  Segment* tmp = new (zone->New(sizeof(Segment))) Segment;
136  *tmp = segment_;
137  segment_.next = tmp;
138  }
139  segment_.string = s;
140  return this;
141  }
142 
143  bool IsEmpty() const {
144  DCHECK_IMPLIES(segment_.string == nullptr, segment_.next == nullptr);
145  DCHECK_IMPLIES(segment_.string != nullptr, !segment_.string->IsEmpty());
146  return segment_.string == nullptr;
147  }
148 
149  void Internalize(Isolate* isolate);
150 
151  V8_INLINE Handle<String> string() const {
152  DCHECK_NOT_NULL(string_);
153  return Handle<String>(string_);
154  }
155 
156  std::forward_list<const AstRawString*> ToRawStrings() const;
157 
158  private:
159  friend class AstValueFactory;
160 
161  AstConsString() : next_(nullptr), segment_({nullptr, nullptr}) {}
162 
163  AstConsString* next() const { return next_; }
164  AstConsString** next_location() { return &next_; }
165 
166  // {string_} is stored as Address* instead of a Handle<String> so it can be
167  // stored in a union with {next_}.
168  void set_string(Handle<String> string) { string_ = string.location(); }
169  union {
170  AstConsString* next_;
171  Address* string_;
172  };
173 
174  struct Segment {
175  const AstRawString* string;
176  AstConsString::Segment* next;
177  };
178  Segment segment_;
179 };
180 
181 enum class AstSymbol : uint8_t { kHomeObjectSymbol };
182 
183 class AstBigInt {
184  public:
185  // |bigint| must be a NUL-terminated string of ASCII characters
186  // representing a BigInt (suitable for passing to BigIntLiteral()
187  // from conversions.h).
188  explicit AstBigInt(const char* bigint) : bigint_(bigint) {}
189 
190  const char* c_str() const { return bigint_; }
191 
192  private:
193  const char* bigint_;
194 };
195 
196 // For generating constants.
197 #define AST_STRING_CONSTANTS(F) \
198  F(anonymous, "anonymous") \
199  F(anonymous_function, "(anonymous function)") \
200  F(arguments, "arguments") \
201  F(as, "as") \
202  F(async, "async") \
203  F(await, "await") \
204  F(bigint, "bigint") \
205  F(boolean, "boolean") \
206  F(constructor, "constructor") \
207  F(default, "default") \
208  F(done, "done") \
209  F(dot, ".") \
210  F(dot_for, ".for") \
211  F(dot_generator_object, ".generator_object") \
212  F(dot_iterator, ".iterator") \
213  F(dot_promise, ".promise") \
214  F(dot_result, ".result") \
215  F(dot_switch_tag, ".switch_tag") \
216  F(dot_catch, ".catch") \
217  F(empty, "") \
218  F(eval, "eval") \
219  F(from, "from") \
220  F(function, "function") \
221  F(get, "get") \
222  F(get_space, "get ") \
223  F(length, "length") \
224  F(let, "let") \
225  F(meta, "meta") \
226  F(name, "name") \
227  F(native, "native") \
228  F(new_target, ".new.target") \
229  F(next, "next") \
230  F(number, "number") \
231  F(object, "object") \
232  F(of, "of") \
233  F(private_constructor, "#constructor") \
234  F(proto, "__proto__") \
235  F(prototype, "prototype") \
236  F(return, "return") \
237  F(set, "set") \
238  F(set_space, "set ") \
239  F(star_default_star, "*default*") \
240  F(string, "string") \
241  F(symbol, "symbol") \
242  F(target, "target") \
243  F(this, "this") \
244  F(this_function, ".this_function") \
245  F(throw, "throw") \
246  F(undefined, "undefined") \
247  F(value, "value")
248 
249 class AstStringConstants final {
250  public:
251  AstStringConstants(Isolate* isolate, uint64_t hash_seed);
252 
253 #define F(name, str) \
254  const AstRawString* name##_string() const { return name##_string_; }
255  AST_STRING_CONSTANTS(F)
256 #undef F
257 
258  uint64_t hash_seed() const { return hash_seed_; }
259  const base::CustomMatcherHashMap* string_table() const {
260  return &string_table_;
261  }
262 
263  private:
264  Zone zone_;
265  base::CustomMatcherHashMap string_table_;
266  uint64_t hash_seed_;
267 
268 #define F(name, str) AstRawString* name##_string_;
269  AST_STRING_CONSTANTS(F)
270 #undef F
271 
272  DISALLOW_COPY_AND_ASSIGN(AstStringConstants);
273 };
274 
276  public:
277  AstValueFactory(Zone* zone, const AstStringConstants* string_constants,
278  uint64_t hash_seed)
279  : string_table_(string_constants->string_table()),
280  strings_(nullptr),
281  strings_end_(&strings_),
282  cons_strings_(nullptr),
283  cons_strings_end_(&cons_strings_),
284  string_constants_(string_constants),
285  empty_cons_string_(nullptr),
286  zone_(zone),
287  hash_seed_(hash_seed) {
288  DCHECK_EQ(hash_seed, string_constants->hash_seed());
289  std::fill(one_character_strings_,
290  one_character_strings_ + arraysize(one_character_strings_),
291  nullptr);
292  empty_cons_string_ = NewConsString();
293  }
294 
295  Zone* zone() const { return zone_; }
296 
297  const AstRawString* GetOneByteString(Vector<const uint8_t> literal) {
298  return GetOneByteStringInternal(literal);
299  }
300  const AstRawString* GetOneByteString(const char* string) {
301  return GetOneByteString(Vector<const uint8_t>(
302  reinterpret_cast<const uint8_t*>(string), StrLength(string)));
303  }
304  const AstRawString* GetTwoByteString(Vector<const uint16_t> literal) {
305  return GetTwoByteStringInternal(literal);
306  }
307  const AstRawString* GetString(Handle<String> literal);
308 
309  // Clones an AstRawString from another ast value factory, adding it to this
310  // factory and returning the clone.
311  const AstRawString* CloneFromOtherFactory(const AstRawString* raw_string);
312 
313  V8_EXPORT_PRIVATE AstConsString* NewConsString();
314  V8_EXPORT_PRIVATE AstConsString* NewConsString(const AstRawString* str);
315  V8_EXPORT_PRIVATE AstConsString* NewConsString(const AstRawString* str1,
316  const AstRawString* str2);
317 
318  V8_EXPORT_PRIVATE void Internalize(Isolate* isolate);
319 
320 #define F(name, str) \
321  const AstRawString* name##_string() const { \
322  return string_constants_->name##_string(); \
323  }
324  AST_STRING_CONSTANTS(F)
325 #undef F
326  const AstConsString* empty_cons_string() const { return empty_cons_string_; }
327 
328  private:
329  AstRawString* AddString(AstRawString* string) {
330  *strings_end_ = string;
331  strings_end_ = string->next_location();
332  return string;
333  }
334  AstConsString* AddConsString(AstConsString* string) {
335  *cons_strings_end_ = string;
336  cons_strings_end_ = string->next_location();
337  return string;
338  }
339  void ResetStrings() {
340  strings_ = nullptr;
341  strings_end_ = &strings_;
342  cons_strings_ = nullptr;
343  cons_strings_end_ = &cons_strings_;
344  }
345  V8_EXPORT_PRIVATE AstRawString* GetOneByteStringInternal(
346  Vector<const uint8_t> literal);
347  AstRawString* GetTwoByteStringInternal(Vector<const uint16_t> literal);
348  AstRawString* GetString(uint32_t hash, bool is_one_byte,
349  Vector<const byte> literal_bytes);
350 
351  // All strings are copied here, one after another (no zeroes inbetween).
352  base::CustomMatcherHashMap string_table_;
353 
354  // We need to keep track of strings_ in order since cons strings require their
355  // members to be internalized first.
356  AstRawString* strings_;
357  AstRawString** strings_end_;
358  AstConsString* cons_strings_;
359  AstConsString** cons_strings_end_;
360 
361  // Holds constant string values which are shared across the isolate.
362  const AstStringConstants* string_constants_;
363  const AstConsString* empty_cons_string_;
364 
365  // Caches one character lowercase strings (for minified code).
366  static const int kMaxOneCharStringValue = 128;
367  AstRawString* one_character_strings_[kMaxOneCharStringValue];
368 
369  Zone* zone_;
370 
371  uint64_t hash_seed_;
372 };
373 } // namespace internal
374 } // namespace v8
375 
376 #endif // V8_AST_AST_VALUE_FACTORY_H_
Definition: libplatform.h:13