// Copyright 2014 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#ifndef V8_AST_AST_VALUE_FACTORY_H_
#define V8_AST_AST_VALUE_FACTORY_H_

#include <forward_list>

#include "src/base/hashmap.h"
#include "src/conversions.h"
#include "src/factory.h"
#include "src/globals.h"
#include "src/isolate.h"
#include "src/utils.h"

// Ast(Raw|Cons)String and AstValueFactory are for storing strings and
// values independent of the V8 heap and internalizing them later. During
// parsing, they are created and stored outside the heap, in AstValueFactory.
// After parsing, the strings and values are internalized (moved into the V8
// heap).
namespace v8 {
namespace internal {

class AstRawString final : public ZoneObject {
 public:
  bool IsEmpty() const { return literal_bytes_.length() == 0; }
  int length() const {
    return is_one_byte() ? literal_bytes_.length()
                         : literal_bytes_.length() / 2;
  }
  bool AsArrayIndex(uint32_t* index) const;
  bool IsOneByteEqualTo(const char* data) const;
  uint16_t FirstCharacter() const;

  void Internalize(Isolate* isolate);

  // Access the physical representation:
  bool is_one_byte() const { return is_one_byte_; }
  int byte_length() const { return literal_bytes_.length(); }
  const unsigned char* raw_data() const {
    return literal_bytes_.start();
  }

  // For storing AstRawStrings in a hash map.
  uint32_t hash_field() const { return hash_field_; }
  uint32_t Hash() const { return hash_field_ >> Name::kHashShift; }

  // This function can be called after internalizing.
  V8_INLINE Handle<String> string() const {
    DCHECK_NOT_NULL(string_);
    DCHECK(has_string_);
    return Handle<String>(string_);
  }

 private:
  friend class AstRawStringInternalizationKey;
  friend class AstStringConstants;
  friend class AstValueFactory;

  // Members accessed only by the AstValueFactory & related classes:
  static bool Compare(void* a, void* b);
  AstRawString(bool is_one_byte, const Vector<const byte>& literal_bytes,
               uint32_t hash_field)
      : next_(nullptr),
        literal_bytes_(literal_bytes),
        hash_field_(hash_field),
        is_one_byte_(is_one_byte) {}
  AstRawString* next() {
    DCHECK(!has_string_);
    return next_;
  }
  AstRawString** next_location() {
    DCHECK(!has_string_);
    return &next_;
  }

  void set_string(Handle<String> string) {
    DCHECK(!string.is_null());
    DCHECK(!has_string_);
    string_ = string.location();
#ifdef DEBUG
    has_string_ = true;
#endif
  }

  // {string_} is stored as String** instead of a Handle<String> so it can be
  // stored in a union with {next_}.
  union {
    AstRawString* next_;
    String** string_;
  };

  Vector<const byte> literal_bytes_;  // Memory owned by Zone.
  uint32_t hash_field_;
  bool is_one_byte_;
#ifdef DEBUG
  // (Debug-only:) Verify the object life-cylce: Some functions may only be
  // called after internalization (that is, after a v8::internal::String has
  // been set); some only before.
  bool has_string_ = false;
#endif
};

class AstConsString final : public ZoneObject {
 public:
  AstConsString* AddString(Zone* zone, const AstRawString* s) {
    if (s->IsEmpty()) return this;
    if (!IsEmpty()) {
      // We're putting the new string to the head of the list, meaning
      // the string segments will be in reverse order.
      Segment* tmp = new (zone->New(sizeof(Segment))) Segment;
      *tmp = segment_;
      segment_.next = tmp;
    }
    segment_.string = s;
    return this;
  }

  bool IsEmpty() const {
    DCHECK_IMPLIES(segment_.string == nullptr, segment_.next == nullptr);
    DCHECK_IMPLIES(segment_.string != nullptr, !segment_.string->IsEmpty());
    return segment_.string == nullptr;
  }

  void Internalize(Isolate* isolate);

  V8_INLINE Handle<String> string() const {
    DCHECK_NOT_NULL(string_);
    return Handle<String>(string_);
  }

  std::forward_list<const AstRawString*> ToRawStrings() const;

 private:
  friend class AstValueFactory;

  AstConsString() : next_(nullptr), segment_({nullptr, nullptr}) {}

  AstConsString* next() const { return next_; }
  AstConsString** next_location() { return &next_; }

  // {string_} is stored as String** instead of a Handle<String> so it can be
  // stored in a union with {next_}.
  void set_string(Handle<String> string) { string_ = string.location(); }
  union {
    AstConsString* next_;
    String** string_;
  };

  struct Segment {
    const AstRawString* string;
    AstConsString::Segment* next;
  };
  Segment segment_;
};

enum class AstSymbol : uint8_t { kHomeObjectSymbol };

class AstBigInt {
 public:
  // |bigint| must be a NUL-terminated string of ASCII characters
  // representing a BigInt (suitable for passing to BigIntLiteral()
  // from conversions.h).
  explicit AstBigInt(const char* bigint) : bigint_(bigint) {}

  const char* c_str() const { return bigint_; }

 private:
  const char* bigint_;
};

// For generating constants.
#define AST_STRING_CONSTANTS(F)                                      \
  F(anonymous_function, "(anonymous function)")                      \
  F(arguments, "arguments")                                          \
  F(async, "async")                                                  \
  F(await, "await")                                                  \
  F(bigint, "bigint")                                                \
  F(boolean, "boolean")                                              \
  F(constructor, "constructor")                                      \
  F(default, "default")                                              \
  F(done, "done")                                                    \
  F(dot, ".")                                                        \
  F(dot_for, ".for")                                                 \
  F(dot_generator_object, ".generator_object")                       \
  F(dot_iterator, ".iterator")                                       \
  F(dot_result, ".result")                                           \
  F(dot_switch_tag, ".switch_tag")                                   \
  F(dot_catch, ".catch")                                             \
  F(empty, "")                                                       \
  F(eval, "eval")                                                    \
  F(function, "function")                                            \
  F(get_space, "get ")                                               \
  F(length, "length")                                                \
  F(let, "let")                                                      \
  F(name, "name")                                                    \
  F(native, "native")                                                \
  F(new_target, ".new.target")                                       \
  F(next, "next")                                                    \
  F(number, "number")                                                \
  F(object, "object")                                                \
  F(proto, "__proto__")                                              \
  F(prototype, "prototype")                                          \
  F(return, "return")                                                \
  F(set_space, "set ")                                               \
  F(star_default_star, "*default*")                                  \
  F(string, "string")                                                \
  F(symbol, "symbol")                                                \
  F(this, "this")                                                    \
  F(this_function, ".this_function")                                 \
  F(throw, "throw")                                                  \
  F(undefined, "undefined")                                          \
  F(use_asm, "use asm")                                              \
  F(use_strict, "use strict")                                        \
  F(value, "value")

class AstStringConstants final {
 public:
  AstStringConstants(Isolate* isolate, uint32_t hash_seed);

#define F(name, str) \
  const AstRawString* name##_string() const { return name##_string_; }
  AST_STRING_CONSTANTS(F)
#undef F

  uint32_t hash_seed() const { return hash_seed_; }
  const base::CustomMatcherHashMap* string_table() const {
    return &string_table_;
  }

 private:
  Zone zone_;
  base::CustomMatcherHashMap string_table_;
  uint32_t hash_seed_;

#define F(name, str) AstRawString* name##_string_;
  AST_STRING_CONSTANTS(F)
#undef F

  DISALLOW_COPY_AND_ASSIGN(AstStringConstants);
};

class AstValueFactory {
 public:
  AstValueFactory(Zone* zone, const AstStringConstants* string_constants,
                  uint32_t hash_seed)
      : string_table_(string_constants->string_table()),
        strings_(nullptr),
        strings_end_(&strings_),
        cons_strings_(nullptr),
        cons_strings_end_(&cons_strings_),
        string_constants_(string_constants),
        empty_cons_string_(nullptr),
        zone_(zone),
        hash_seed_(hash_seed) {
    DCHECK_EQ(hash_seed, string_constants->hash_seed());
    std::fill(one_character_strings_,
              one_character_strings_ + arraysize(one_character_strings_),
              nullptr);
    empty_cons_string_ = NewConsString();
  }

  Zone* zone() const { return zone_; }

  const AstRawString* GetOneByteString(Vector<const uint8_t> literal) {
    return GetOneByteStringInternal(literal);
  }
  const AstRawString* GetOneByteString(const char* string) {
    return GetOneByteString(Vector<const uint8_t>(
        reinterpret_cast<const uint8_t*>(string), StrLength(string)));
  }
  const AstRawString* GetTwoByteString(Vector<const uint16_t> literal) {
    return GetTwoByteStringInternal(literal);
  }
  const AstRawString* GetString(Handle<String> literal);
  V8_EXPORT_PRIVATE AstConsString* NewConsString();
  AstConsString* NewConsString(const AstRawString* str);
  AstConsString* NewConsString(const AstRawString* str1,
                               const AstRawString* str2);

  V8_EXPORT_PRIVATE void Internalize(Isolate* isolate);

#define F(name, str)                           \
  const AstRawString* name##_string() const {  \
    return string_constants_->name##_string(); \
  }
  AST_STRING_CONSTANTS(F)
#undef F
  const AstConsString* empty_cons_string() const { return empty_cons_string_; }

 private:
  AstRawString* AddString(AstRawString* string) {
    *strings_end_ = string;
    strings_end_ = string->next_location();
    return string;
  }
  AstConsString* AddConsString(AstConsString* string) {
    *cons_strings_end_ = string;
    cons_strings_end_ = string->next_location();
    return string;
  }
  void ResetStrings() {
    strings_ = nullptr;
    strings_end_ = &strings_;
    cons_strings_ = nullptr;
    cons_strings_end_ = &cons_strings_;
  }
  V8_EXPORT_PRIVATE AstRawString* GetOneByteStringInternal(
      Vector<const uint8_t> literal);
  AstRawString* GetTwoByteStringInternal(Vector<const uint16_t> literal);
  AstRawString* GetString(uint32_t hash, bool is_one_byte,
                          Vector<const byte> literal_bytes);

  // All strings are copied here, one after another (no zeroes inbetween).
  base::CustomMatcherHashMap string_table_;

  // We need to keep track of strings_ in order since cons strings require their
  // members to be internalized first.
  AstRawString* strings_;
  AstRawString** strings_end_;
  AstConsString* cons_strings_;
  AstConsString** cons_strings_end_;

  // Holds constant string values which are shared across the isolate.
  const AstStringConstants* string_constants_;
  const AstConsString* empty_cons_string_;

  // Caches one character lowercase strings (for minified code).
  AstRawString* one_character_strings_[26];

  Zone* zone_;

  uint32_t hash_seed_;
};
}  // namespace internal
}  // namespace v8

#endif  // V8_AST_AST_VALUE_FACTORY_H_
