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