1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2014 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Redistribution and use in source and binary forms, with or without
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// modification, are permitted provided that the following conditions are
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// met:
5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//     * Redistributions of source code must retain the above copyright
7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//       notice, this list of conditions and the following disclaimer.
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//     * Redistributions in binary form must reproduce the above
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//       copyright notice, this list of conditions and the following
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//       disclaimer in the documentation and/or other materials provided
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//       with the distribution.
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//     * Neither the name of Google Inc. nor the names of its
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//       contributors may be used to endorse or promote products derived
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//       from this software without specific prior written permission.
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#ifndef V8_AST_AST_VALUE_FACTORY_H_
29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define V8_AST_AST_VALUE_FACTORY_H_
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/api.h"
32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/hashmap.h"
33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/utils.h"
34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// AstString, AstValue and AstValueFactory are for storing strings and values
36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// independent of the V8 heap and internalizing them later. During parsing,
37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// AstStrings and AstValues are created and stored outside the heap, in
38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// AstValueFactory. After parsing, the strings and values are internalized
39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// (moved into the V8 heap).
40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 {
41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal {
42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass AstString : public ZoneObject {
44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual ~AstString() {}
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual int length() const = 0;
48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsEmpty() const { return length() == 0; }
49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Puts the string into the V8 heap.
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual void Internalize(Isolate* isolate) = 0;
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // This function can be called after internalizing.
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V8_INLINE Handle<String> string() const {
55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!string_.is_null());
56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return string_;
57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected:
60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // This is null until the string is internalized.
61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<String> string_;
62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass AstRawString final : public AstString {
66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int length() const override {
68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (is_one_byte_)
69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return literal_bytes_.length();
70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return literal_bytes_.length() / 2;
71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int byte_length() const { return literal_bytes_.length(); }
74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Internalize(Isolate* isolate) override;
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool AsArrayIndex(uint32_t* index) const;
78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The string is not null-terminated, use length() to find out the length.
80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const unsigned char* raw_data() const {
81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return literal_bytes_.start();
82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_one_byte() const { return is_one_byte_; }
84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsOneByteEqualTo(const char* data) const;
85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint16_t FirstCharacter() const {
86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (is_one_byte_)
87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return literal_bytes_[0];
88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const uint16_t* c =
89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        reinterpret_cast<const uint16_t*>(literal_bytes_.start());
90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return *c;
91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // For storing AstRawStrings in a hash map.
94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t hash() const {
95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return hash_;
96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
97958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  friend class AstValueFactory;
100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  friend class AstRawStringInternalizationKey;
101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AstRawString(bool is_one_byte, const Vector<const byte>& literal_bytes,
103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            uint32_t hash)
104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : is_one_byte_(is_one_byte), literal_bytes_(literal_bytes), hash_(hash) {}
105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AstRawString()
107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : is_one_byte_(true),
108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        hash_(0) {}
109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_one_byte_;
111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Points to memory owned by Zone.
113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Vector<const byte> literal_bytes_;
114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t hash_;
115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass AstConsString final : public AstString {
119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AstConsString(const AstString* left, const AstString* right)
121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : length_(left->length() + right->length()), left_(left), right_(right) {}
122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int length() const override { return length_; }
124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Internalize(Isolate* isolate) override;
126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const int length_;
129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const AstString* left_;
130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const AstString* right_;
131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// AstValue is either a string, a number, a string array, a boolean, or a
135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// special value (null, undefined, the hole).
136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass AstValue : public ZoneObject {
137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsString() const {
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return type_ == STRING;
140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsNumber() const {
143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return type_ == NUMBER || type_ == NUMBER_WITH_DOT || type_ == SMI;
144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool ContainsDot() const { return type_ == NUMBER_WITH_DOT; }
147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const AstRawString* AsString() const {
149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (type_ == STRING)
150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return string_;
151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    UNREACHABLE();
152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return 0;
153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  double AsNumber() const {
156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (type_ == NUMBER || type_ == NUMBER_WITH_DOT)
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return number_;
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (type_ == SMI)
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return smi_;
160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    UNREACHABLE();
161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return 0;
162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool EqualsString(const AstRawString* string) const {
165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return type_ == STRING && string_ == string;
166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsPropertyName() const;
169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool BooleanValue() const;
171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsTheHole() const { return type_ == THE_HOLE; }
173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Internalize(Isolate* isolate);
175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Can be called after Internalize has been called.
177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V8_INLINE Handle<Object> value() const {
178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (type_ == STRING) {
179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return string_->string();
180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!value_.is_null());
182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return value_;
183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  friend class AstValueFactory;
187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  enum Type {
189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    STRING,
190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SYMBOL,
191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    NUMBER,
192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    NUMBER_WITH_DOT,
193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SMI,
194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    BOOLEAN,
195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    NULL_TYPE,
196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    UNDEFINED,
197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    THE_HOLE
198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit AstValue(const AstRawString* s) : type_(STRING) { string_ = s; }
201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit AstValue(const char* name) : type_(SYMBOL) { symbol_name_ = name; }
203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  explicit AstValue(double n, bool with_dot) {
205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (with_dot) {
206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      type_ = NUMBER_WITH_DOT;
207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      type_ = NUMBER;
209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    number_ = n;
211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AstValue(Type t, int i) : type_(t) {
214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(type_ == SMI);
215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    smi_ = i;
216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit AstValue(bool b) : type_(BOOLEAN) { bool_ = b; }
219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit AstValue(Type t) : type_(t) {
221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(t == NULL_TYPE || t == UNDEFINED || t == THE_HOLE);
222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Type type_;
225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Uninternalized value.
227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  union {
228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const AstRawString* string_;
229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    double number_;
230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int smi_;
231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool bool_;
232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ZoneList<const AstRawString*>* strings_;
233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const char* symbol_name_;
234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Internalized value (empty before internalized).
237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Object> value_;
238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
241958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// For generating constants.
242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define STRING_CONSTANTS(F)                     \
243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(anonymous_function, "(anonymous function)") \
244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(arguments, "arguments")                     \
245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(constructor, "constructor")                 \
246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(default, "default")                         \
247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(done, "done")                               \
248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(dot, ".")                                   \
249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(dot_for, ".for")                            \
250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(dot_generator, ".generator")                \
251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(dot_generator_object, ".generator_object")  \
252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(dot_iterator, ".iterator")                  \
253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(dot_result, ".result")                      \
254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(dot_switch_tag, ".switch_tag")              \
255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(dot_catch, ".catch")                        \
256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(empty, "")                                  \
257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(eval, "eval")                               \
258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(get_space, "get ")                          \
259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(let, "let")                                 \
260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(native, "native")                           \
261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(new_target, ".new.target")                  \
262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(next, "next")                               \
263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(proto, "__proto__")                         \
264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(prototype, "prototype")                     \
265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(rest_parameter, ".rest_parameter")          \
266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(set_space, "set ")                          \
267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(this, "this")                               \
268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(this_function, ".this_function")            \
269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(undefined, "undefined")                     \
270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(use_asm, "use asm")                         \
271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(use_strong, "use strong")                   \
272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F(use_strict, "use strict")                   \
273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  F(value, "value")
274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
275958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define OTHER_CONSTANTS(F) \
276958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  F(true_value)            \
277958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  F(false_value)           \
278958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  F(null_value)            \
279958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  F(undefined_value)       \
280958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  F(the_hole_value)
281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass AstValueFactory {
283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AstValueFactory(Zone* zone, uint32_t hash_seed)
285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : string_table_(AstRawStringCompare),
286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        zone_(zone),
287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        isolate_(NULL),
288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        hash_seed_(hash_seed) {
289958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define F(name, str) name##_string_ = NULL;
290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    STRING_CONSTANTS(F)
291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef F
292958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define F(name) name##_ = NULL;
293958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    OTHER_CONSTANTS(F)
294958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#undef F
295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
297958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Zone* zone() const { return zone_; }
298958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
299958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  const AstRawString* GetOneByteString(Vector<const uint8_t> literal) {
300958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return GetOneByteStringInternal(literal);
301958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const AstRawString* GetOneByteString(const char* string) {
303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return GetOneByteString(Vector<const uint8_t>(
304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        reinterpret_cast<const uint8_t*>(string), StrLength(string)));
305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
306958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  const AstRawString* GetTwoByteString(Vector<const uint16_t> literal) {
307958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return GetTwoByteStringInternal(literal);
308958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const AstRawString* GetString(Handle<String> literal);
310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const AstConsString* NewConsString(const AstString* left,
311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     const AstString* right);
312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Internalize(Isolate* isolate);
314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsInternalized() {
315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return isolate_ != NULL;
316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
318958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define F(name, str)                                                    \
319958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  const AstRawString* name##_string() {                                 \
320958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (name##_string_ == NULL) {                                       \
321958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      const char* data = str;                                           \
322958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      name##_string_ = GetOneByteString(                                \
323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          Vector<const uint8_t>(reinterpret_cast<const uint8_t*>(data), \
324958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                static_cast<int>(strlen(data))));       \
325958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }                                                                   \
326958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return name##_string_;                                              \
327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STRING_CONSTANTS(F)
329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef F
330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const AstValue* NewString(const AstRawString* string);
332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // A JavaScript symbol (ECMA-262 edition 6).
333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const AstValue* NewSymbol(const char* name);
334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const AstValue* NewNumber(double number, bool with_dot = false);
335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const AstValue* NewSmi(int number);
336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const AstValue* NewBoolean(bool b);
337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const AstValue* NewStringList(ZoneList<const AstRawString*>* strings);
338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const AstValue* NewNull();
339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const AstValue* NewUndefined();
340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const AstValue* NewTheHole();
341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
343958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  AstRawString* GetOneByteStringInternal(Vector<const uint8_t> literal);
344958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  AstRawString* GetTwoByteStringInternal(Vector<const uint16_t> literal);
345958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  AstRawString* GetString(uint32_t hash, bool is_one_byte,
346958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                          Vector<const byte> literal_bytes);
347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static bool AstRawStringCompare(void* a, void* b);
349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // All strings are copied here, one after another (no NULLs inbetween).
351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HashMap string_table_;
352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // For keeping track of all AstValues and AstRawStrings we've created (so that
353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // they can be internalized later).
354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  List<AstValue*> values_;
355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  List<AstString*> strings_;
356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Zone* zone_;
357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Isolate* isolate_;
358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t hash_seed_;
360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
361958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define F(name, str) const AstRawString* name##_string_;
362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STRING_CONSTANTS(F)
363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef F
364958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
365958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define F(name) AstValue* name##_;
366958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  OTHER_CONSTANTS(F)
367958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#undef F
368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef STRING_CONSTANTS
373958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#undef OTHER_CONSTANTS
374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif  // V8_AST_AST_VALUE_FACTORY_H_
376