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