revise installing a license file
[platform/upstream/nodejs.git] / deps / v8 / src / 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_VALUE_FACTORY_H_
29 #define V8_AST_VALUE_FACTORY_H_
30
31 #include "src/api.h"
32 #include "src/hashmap.h"
33 #include "src/utils.h"
34
35 // AstString, AstValue and AstValueFactory are for storing strings and values
36 // independent of the V8 heap and internalizing them later. During parsing,
37 // AstStrings and AstValues are created and stored outside the heap, in
38 // AstValueFactory. After parsing, the strings and values are internalized
39 // (moved into the V8 heap).
40 namespace v8 {
41 namespace internal {
42
43 class AstString : public ZoneObject {
44  public:
45   virtual ~AstString() {}
46
47   virtual int length() const = 0;
48   bool IsEmpty() const { return length() == 0; }
49
50   // Puts the string into the V8 heap.
51   virtual void Internalize(Isolate* isolate) = 0;
52
53   // This function can be called after internalizing.
54   V8_INLINE Handle<String> string() const {
55     DCHECK(!string_.is_null());
56     return string_;
57   }
58
59  protected:
60   // This is null until the string is internalized.
61   Handle<String> string_;
62 };
63
64
65 class AstRawString : public AstString {
66  public:
67   int length() const override {
68     if (is_one_byte_)
69       return literal_bytes_.length();
70     return literal_bytes_.length() / 2;
71   }
72
73   int byte_length() const { return literal_bytes_.length(); }
74
75   void Internalize(Isolate* isolate) override;
76
77   bool AsArrayIndex(uint32_t* index) const;
78
79   // The string is not null-terminated, use length() to find out the length.
80   const unsigned char* raw_data() const {
81     return literal_bytes_.start();
82   }
83   bool is_one_byte() const { return is_one_byte_; }
84   bool IsOneByteEqualTo(const char* data) const;
85   uint16_t FirstCharacter() const {
86     if (is_one_byte_)
87       return literal_bytes_[0];
88     const uint16_t* c =
89         reinterpret_cast<const uint16_t*>(literal_bytes_.start());
90     return *c;
91   }
92
93   // For storing AstRawStrings in a hash map.
94   uint32_t hash() const {
95     return hash_;
96   }
97
98  private:
99   friend class AstValueFactory;
100   friend class AstRawStringInternalizationKey;
101
102   AstRawString(bool is_one_byte, const Vector<const byte>& literal_bytes,
103             uint32_t hash)
104       : is_one_byte_(is_one_byte), literal_bytes_(literal_bytes), hash_(hash) {}
105
106   AstRawString()
107       : is_one_byte_(true),
108         hash_(0) {}
109
110   bool is_one_byte_;
111
112   // Points to memory owned by Zone.
113   Vector<const byte> literal_bytes_;
114   uint32_t hash_;
115 };
116
117
118 class AstConsString : public AstString {
119  public:
120   AstConsString(const AstString* left, const AstString* right)
121       : left_(left),
122         right_(right) {}
123
124   int length() const override { return left_->length() + right_->length(); }
125
126   void Internalize(Isolate* isolate) override;
127
128  private:
129   friend class AstValueFactory;
130
131   const AstString* left_;
132   const AstString* right_;
133 };
134
135
136 // AstValue is either a string, a number, a string array, a boolean, or a
137 // special value (null, undefined, the hole).
138 class AstValue : public ZoneObject {
139  public:
140   bool IsString() const {
141     return type_ == STRING;
142   }
143
144   bool IsNumber() const {
145     return type_ == NUMBER || type_ == NUMBER_WITH_DOT || type_ == SMI;
146   }
147
148   bool ContainsDot() const { return type_ == NUMBER_WITH_DOT; }
149
150   const AstRawString* AsString() const {
151     if (type_ == STRING)
152       return string_;
153     UNREACHABLE();
154     return 0;
155   }
156
157   double AsNumber() const {
158     if (type_ == NUMBER || type_ == NUMBER_WITH_DOT)
159       return number_;
160     if (type_ == SMI)
161       return smi_;
162     UNREACHABLE();
163     return 0;
164   }
165
166   bool EqualsString(const AstRawString* string) const {
167     return type_ == STRING && string_ == string;
168   }
169
170   bool IsPropertyName() const;
171
172   bool BooleanValue() const;
173
174   bool IsTheHole() const { return type_ == THE_HOLE; }
175
176   void Internalize(Isolate* isolate);
177
178   // Can be called after Internalize has been called.
179   V8_INLINE Handle<Object> value() const {
180     if (type_ == STRING) {
181       return string_->string();
182     }
183     DCHECK(!value_.is_null());
184     return value_;
185   }
186
187  private:
188   friend class AstValueFactory;
189
190   enum Type {
191     STRING,
192     SYMBOL,
193     NUMBER,
194     NUMBER_WITH_DOT,
195     SMI,
196     BOOLEAN,
197     NULL_TYPE,
198     UNDEFINED,
199     THE_HOLE
200   };
201
202   explicit AstValue(const AstRawString* s) : type_(STRING) { string_ = s; }
203
204   explicit AstValue(const char* name) : type_(SYMBOL) { symbol_name_ = name; }
205
206   explicit AstValue(double n, bool with_dot) {
207     if (with_dot) {
208       type_ = NUMBER_WITH_DOT;
209     } else {
210       type_ = NUMBER;
211     }
212     number_ = n;
213   }
214
215   AstValue(Type t, int i) : type_(t) {
216     DCHECK(type_ == SMI);
217     smi_ = i;
218   }
219
220   explicit AstValue(bool b) : type_(BOOLEAN) { bool_ = b; }
221
222   explicit AstValue(Type t) : type_(t) {
223     DCHECK(t == NULL_TYPE || t == UNDEFINED || t == THE_HOLE);
224   }
225
226   Type type_;
227
228   // Uninternalized value.
229   union {
230     const AstRawString* string_;
231     double number_;
232     int smi_;
233     bool bool_;
234     ZoneList<const AstRawString*>* strings_;
235     const char* symbol_name_;
236   };
237
238   // Internalized value (empty before internalized).
239   Handle<Object> value_;
240 };
241
242
243 // For generating constants.
244 #define STRING_CONSTANTS(F)                                                \
245   F(anonymous_function, "(anonymous function)")                            \
246   F(arguments, "arguments")                                                \
247   F(concat_iterable_to_array, "$concatIterableToArray")                    \
248   F(constructor, "constructor")                                            \
249   F(default, "default")                                                    \
250   F(done, "done")                                                          \
251   F(dot, ".")                                                              \
252   F(dot_for, ".for")                                                       \
253   F(dot_generator, ".generator")                                           \
254   F(dot_generator_object, ".generator_object")                             \
255   F(dot_iterator, ".iterator")                                             \
256   F(dot_module, ".module")                                                 \
257   F(dot_result, ".result")                                                 \
258   F(empty, "")                                                             \
259   F(eval, "eval")                                                          \
260   F(get_template_callsite, "$getTemplateCallSite")                         \
261   F(initialize_const_global, "initializeConstGlobal")                      \
262   F(initialize_var_global, "initializeVarGlobal")                          \
263   F(is_construct_call, "_IsConstructCall")                                 \
264   F(is_spec_object, "_IsSpecObject")                                       \
265   F(let, "let")                                                            \
266   F(make_reference_error, "MakeReferenceError")                            \
267   F(make_syntax_error, "MakeSyntaxError")                                  \
268   F(make_type_error, "MakeTypeError")                                      \
269   F(native, "native")                                                      \
270   F(new_target, "new.target")                                              \
271   F(next, "next")                                                          \
272   F(proto, "__proto__")                                                    \
273   F(prototype, "prototype")                                                \
274   F(reflect_apply, "$reflectApply")                                        \
275   F(reflect_construct, "$reflectConstruct")                                \
276   F(spread_arguments, "$spreadArguments")                                  \
277   F(spread_iterable, "$spreadIterable")                                    \
278   F(this, "this")                                                          \
279   F(this_function, ".this_function")                                       \
280   F(throw_iterator_result_not_an_object, "ThrowIteratorResultNotAnObject") \
281   F(to_string, "$toString")                                                \
282   F(undefined, "undefined")                                                \
283   F(use_asm, "use asm")                                                    \
284   F(use_strong, "use strong")                                              \
285   F(use_strict, "use strict")                                              \
286   F(value, "value")
287
288 #define OTHER_CONSTANTS(F) \
289   F(true_value)            \
290   F(false_value)           \
291   F(null_value)            \
292   F(undefined_value)       \
293   F(the_hole_value)
294
295 class AstValueFactory {
296  public:
297   AstValueFactory(Zone* zone, uint32_t hash_seed)
298       : string_table_(AstRawStringCompare),
299         zone_(zone),
300         isolate_(NULL),
301         hash_seed_(hash_seed) {
302 #define F(name, str) name##_string_ = NULL;
303     STRING_CONSTANTS(F)
304 #undef F
305 #define F(name) name##_ = NULL;
306     OTHER_CONSTANTS(F)
307 #undef F
308   }
309
310   Zone* zone() const { return zone_; }
311
312   const AstRawString* GetOneByteString(Vector<const uint8_t> literal) {
313     return GetOneByteStringInternal(literal);
314   }
315   const AstRawString* GetOneByteString(const char* string) {
316     return GetOneByteString(Vector<const uint8_t>(
317         reinterpret_cast<const uint8_t*>(string), StrLength(string)));
318   }
319   const AstRawString* GetTwoByteString(Vector<const uint16_t> literal) {
320     return GetTwoByteStringInternal(literal);
321   }
322   const AstRawString* GetString(Handle<String> literal);
323   const AstConsString* NewConsString(const AstString* left,
324                                      const AstString* right);
325
326   void Internalize(Isolate* isolate);
327   bool IsInternalized() {
328     return isolate_ != NULL;
329   }
330
331 #define F(name, str)                                                    \
332   const AstRawString* name##_string() {                                 \
333     if (name##_string_ == NULL) {                                       \
334       const char* data = str;                                           \
335       name##_string_ = GetOneByteString(                                \
336           Vector<const uint8_t>(reinterpret_cast<const uint8_t*>(data), \
337                                 static_cast<int>(strlen(data))));       \
338     }                                                                   \
339     return name##_string_;                                              \
340   }
341   STRING_CONSTANTS(F)
342 #undef F
343
344   const AstValue* NewString(const AstRawString* string);
345   // A JavaScript symbol (ECMA-262 edition 6).
346   const AstValue* NewSymbol(const char* name);
347   const AstValue* NewNumber(double number, bool with_dot = false);
348   const AstValue* NewSmi(int number);
349   const AstValue* NewBoolean(bool b);
350   const AstValue* NewStringList(ZoneList<const AstRawString*>* strings);
351   const AstValue* NewNull();
352   const AstValue* NewUndefined();
353   const AstValue* NewTheHole();
354
355  private:
356   AstRawString* GetOneByteStringInternal(Vector<const uint8_t> literal);
357   AstRawString* GetTwoByteStringInternal(Vector<const uint16_t> literal);
358   AstRawString* GetString(uint32_t hash, bool is_one_byte,
359                           Vector<const byte> literal_bytes);
360
361   static bool AstRawStringCompare(void* a, void* b);
362
363   // All strings are copied here, one after another (no NULLs inbetween).
364   HashMap string_table_;
365   // For keeping track of all AstValues and AstRawStrings we've created (so that
366   // they can be internalized later).
367   List<AstValue*> values_;
368   List<AstString*> strings_;
369   Zone* zone_;
370   Isolate* isolate_;
371
372   uint32_t hash_seed_;
373
374 #define F(name, str) const AstRawString* name##_string_;
375   STRING_CONSTANTS(F)
376 #undef F
377
378 #define F(name) AstValue* name##_;
379   OTHER_CONSTANTS(F)
380 #undef F
381 };
382 } }  // namespace v8::internal
383
384 #undef STRING_CONSTANTS
385 #undef OTHER_CONSTANTS
386
387 #endif  // V8_AST_VALUE_FACTORY_H_