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