// Copyright 2006-2008 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.

#include <stdlib.h>

#include "v8.h"

#include "scopeinfo.h"
#include "scopes.h"

namespace v8 {
namespace internal {


static int CompareLocal(Variable* const* v, Variable* const* w) {
  Slot* s = (*v)->AsSlot();
  Slot* t = (*w)->AsSlot();
  // We may have rewritten parameters (that are in the arguments object)
  // and which may have a NULL slot... - find a better solution...
  int x = (s != NULL ? s->index() : 0);
  int y = (t != NULL ? t->index() : 0);
  // Consider sorting them according to type as well?
  return x - y;
}


template<class Allocator>
ScopeInfo<Allocator>::ScopeInfo(Scope* scope)
    : function_name_(Factory::empty_symbol()),
      calls_eval_(scope->calls_eval()),
      parameters_(scope->num_parameters()),
      stack_slots_(scope->num_stack_slots()),
      context_slots_(scope->num_heap_slots()),
      context_modes_(scope->num_heap_slots()) {
  // Add parameters.
  for (int i = 0; i < scope->num_parameters(); i++) {
    ASSERT(parameters_.length() == i);
    parameters_.Add(scope->parameter(i)->name());
  }

  // Add stack locals and collect heap locals.
  // We are assuming that the locals' slots are allocated in
  // increasing order, so we can simply add them to the
  // ScopeInfo lists. However, due to usage analysis, this is
  // not true for context-allocated locals: Some of them
  // may be parameters which are allocated before the
  // non-parameter locals. When the non-parameter locals are
  // sorted according to usage, the allocated slot indices may
  // not be in increasing order with the variable list anymore.
  // Thus, we first collect the context-allocated locals, and then
  // sort them by context slot index before adding them to the
  // ScopeInfo list.
  List<Variable*, Allocator> locals(32);  // 32 is a wild guess
  ASSERT(locals.is_empty());
  scope->CollectUsedVariables(&locals);
  locals.Sort(&CompareLocal);

  List<Variable*, Allocator> heap_locals(locals.length());
  for (int i = 0; i < locals.length(); i++) {
    Variable* var = locals[i];
    if (var->is_used()) {
      Slot* slot = var->AsSlot();
      if (slot != NULL) {
        switch (slot->type()) {
          case Slot::PARAMETER:
            // explicitly added to parameters_ above - ignore
            break;

          case Slot::LOCAL:
            ASSERT(stack_slots_.length() == slot->index());
            stack_slots_.Add(var->name());
            break;

          case Slot::CONTEXT:
            heap_locals.Add(var);
            break;

          case Slot::LOOKUP:
            // This is currently not used.
            UNREACHABLE();
            break;
        }
      }
    }
  }

  // Add heap locals.
  if (scope->num_heap_slots() > 0) {
    // Add user-defined slots.
    for (int i = 0; i < heap_locals.length(); i++) {
      ASSERT(heap_locals[i]->AsSlot()->index() - Context::MIN_CONTEXT_SLOTS ==
             context_slots_.length());
      ASSERT(heap_locals[i]->AsSlot()->index() - Context::MIN_CONTEXT_SLOTS ==
             context_modes_.length());
      context_slots_.Add(heap_locals[i]->name());
      context_modes_.Add(heap_locals[i]->mode());
    }

  } else {
    ASSERT(heap_locals.length() == 0);
  }

  // Add the function context slot, if present.
  // For now, this must happen at the very end because of the
  // ordering of the scope info slots and the respective slot indices.
  if (scope->is_function_scope()) {
    Variable* var = scope->function();
    if (var != NULL &&
        var->is_used() &&
        var->AsSlot()->type() == Slot::CONTEXT) {
      function_name_ = var->name();
      // Note that we must not find the function name in the context slot
      // list - instead it must be handled separately in the
      // Contexts::Lookup() function. Thus record an empty symbol here so we
      // get the correct number of context slots.
      ASSERT(var->AsSlot()->index() - Context::MIN_CONTEXT_SLOTS ==
             context_slots_.length());
      ASSERT(var->AsSlot()->index() - Context::MIN_CONTEXT_SLOTS ==
             context_modes_.length());
      context_slots_.Add(Factory::empty_symbol());
      context_modes_.Add(Variable::INTERNAL);
    }
  }
}


// Encoding format in a FixedArray object:
//
// - function name
//
// - number of variables in the context object (smi) (= function context
//   slot index + 1)
// - list of pairs (name, Var mode) of context-allocated variables (starting
//   with context slot 0)
// - NULL (sentinel)
//
// - number of parameters (smi)
// - list of parameter names (starting with parameter 0 first)
// - NULL (sentinel)
//
// - number of variables on the stack (smi)
// - list of names of stack-allocated variables (starting with stack slot 0)
// - NULL (sentinel)

// The ScopeInfo representation could be simplified and the ScopeInfo
// re-implemented (with almost the same interface). Here is a
// suggestion for the new format:
//
// - have a single list with all variable names (parameters, stack locals,
//   context locals), followed by a list of non-Object* values containing
//   the variables information (what kind, index, attributes)
// - searching the linear list of names is fast and yields an index into the
//   list if the variable name is found
// - that list index is then used to find the variable information in the
//   subsequent list
// - the list entries don't have to be in any particular order, so all the
//   current sorting business can go away
// - the ScopeInfo lookup routines can be reduced to perhaps a single lookup
//   which returns all information at once
// - when gathering the information from a Scope, we only need to iterate
//   through the local variables (parameters and context info is already
//   present)


static inline Object** ReadInt(Object** p, int* x) {
  *x = (reinterpret_cast<Smi*>(*p++))->value();
  return p;
}


static inline Object** ReadBool(Object** p, bool* x) {
  *x = (reinterpret_cast<Smi*>(*p++))->value() != 0;
  return p;
}


static inline Object** ReadSymbol(Object** p, Handle<String>* s) {
  *s = Handle<String>(reinterpret_cast<String*>(*p++));
  return p;
}


template <class Allocator>
static Object** ReadList(Object** p, List<Handle<String>, Allocator >* list) {
  ASSERT(list->is_empty());
  int n;
  p = ReadInt(p, &n);
  while (n-- > 0) {
    Handle<String> s;
    p = ReadSymbol(p, &s);
    list->Add(s);
  }
  return p;
}


template <class Allocator>
static Object** ReadList(Object** p,
                         List<Handle<String>, Allocator>* list,
                         List<Variable::Mode, Allocator>* modes) {
  ASSERT(list->is_empty());
  int n;
  p = ReadInt(p, &n);
  while (n-- > 0) {
    Handle<String> s;
    int m;
    p = ReadSymbol(p, &s);
    p = ReadInt(p, &m);
    list->Add(s);
    modes->Add(static_cast<Variable::Mode>(m));
  }
  return p;
}


template<class Allocator>
ScopeInfo<Allocator>::ScopeInfo(SerializedScopeInfo* data)
  : function_name_(Factory::empty_symbol()),
    parameters_(4),
    stack_slots_(8),
    context_slots_(8),
    context_modes_(8) {
  if (data->length() > 0) {
    Object** p0 = data->data_start();
    Object** p = p0;
    p = ReadSymbol(p, &function_name_);
    p = ReadBool(p, &calls_eval_);
    p = ReadList<Allocator>(p, &context_slots_, &context_modes_);
    p = ReadList<Allocator>(p, &parameters_);
    p = ReadList<Allocator>(p, &stack_slots_);
    ASSERT((p - p0) == FixedArray::cast(data)->length());
  }
}


static inline Object** WriteInt(Object** p, int x) {
  *p++ = Smi::FromInt(x);
  return p;
}


static inline Object** WriteBool(Object** p, bool b) {
  *p++ = Smi::FromInt(b ? 1 : 0);
  return p;
}


static inline Object** WriteSymbol(Object** p, Handle<String> s) {
  *p++ = *s;
  return p;
}


template <class Allocator>
static Object** WriteList(Object** p, List<Handle<String>, Allocator >* list) {
  const int n = list->length();
  p = WriteInt(p, n);
  for (int i = 0; i < n; i++) {
    p = WriteSymbol(p, list->at(i));
  }
  return p;
}


template <class Allocator>
static Object** WriteList(Object** p,
                          List<Handle<String>, Allocator>* list,
                          List<Variable::Mode, Allocator>* modes) {
  const int n = list->length();
  p = WriteInt(p, n);
  for (int i = 0; i < n; i++) {
    p = WriteSymbol(p, list->at(i));
    p = WriteInt(p, modes->at(i));
  }
  return p;
}


template<class Allocator>
Handle<SerializedScopeInfo> ScopeInfo<Allocator>::Serialize() {
  // function name, calls eval, length for 3 tables:
  const int extra_slots = 1 + 1 + 3;
  int length = extra_slots +
               context_slots_.length() * 2 +
               parameters_.length() +
               stack_slots_.length();

  Handle<SerializedScopeInfo> data(
      SerializedScopeInfo::cast(*Factory::NewFixedArray(length, TENURED)));
  AssertNoAllocation nogc;

  Object** p0 = data->data_start();
  Object** p = p0;
  p = WriteSymbol(p, function_name_);
  p = WriteBool(p, calls_eval_);
  p = WriteList(p, &context_slots_, &context_modes_);
  p = WriteList(p, &parameters_);
  p = WriteList(p, &stack_slots_);
  ASSERT((p - p0) == length);

  return data;
}


template<class Allocator>
Handle<String> ScopeInfo<Allocator>::LocalName(int i) const {
  // A local variable can be allocated either on the stack or in the context.
  // For variables allocated in the context they are always preceded by
  // Context::MIN_CONTEXT_SLOTS of fixed allocated slots in the context.
  if (i < number_of_stack_slots()) {
    return stack_slot_name(i);
  } else {
    return context_slot_name(i - number_of_stack_slots() +
                             Context::MIN_CONTEXT_SLOTS);
  }
}


template<class Allocator>
int ScopeInfo<Allocator>::NumberOfLocals() const {
  int number_of_locals = number_of_stack_slots();
  if (number_of_context_slots() > 0) {
    ASSERT(number_of_context_slots() >= Context::MIN_CONTEXT_SLOTS);
    number_of_locals += number_of_context_slots() - Context::MIN_CONTEXT_SLOTS;
  }
  return number_of_locals;
}


Handle<SerializedScopeInfo> SerializedScopeInfo::Create(Scope* scope) {
  ScopeInfo<ZoneListAllocationPolicy> sinfo(scope);
  return sinfo.Serialize();
}


SerializedScopeInfo* SerializedScopeInfo::Empty() {
  return reinterpret_cast<SerializedScopeInfo*>(Heap::empty_fixed_array());
}


Object** SerializedScopeInfo::ContextEntriesAddr() {
  ASSERT(length() > 0);
  return data_start() + 2;  // +2 for function name and calls eval.
}


Object** SerializedScopeInfo::ParameterEntriesAddr() {
  ASSERT(length() > 0);
  Object** p = ContextEntriesAddr();
  int number_of_context_slots;
  p = ReadInt(p, &number_of_context_slots);
  return p + number_of_context_slots*2;  // *2 for pairs
}


Object** SerializedScopeInfo::StackSlotEntriesAddr() {
  ASSERT(length() > 0);
  Object** p = ParameterEntriesAddr();
  int number_of_parameter_slots;
  p = ReadInt(p, &number_of_parameter_slots);
  return p + number_of_parameter_slots;
}


bool SerializedScopeInfo::CallsEval() {
  if (length() > 0) {
    Object** p = data_start() + 1;  // +1 for function name.
    bool calls_eval;
    p = ReadBool(p, &calls_eval);
    return calls_eval;
  }
  return true;
}


int SerializedScopeInfo::NumberOfStackSlots() {
  if (length() > 0) {
    Object** p = StackSlotEntriesAddr();
    int number_of_stack_slots;
    ReadInt(p, &number_of_stack_slots);
    return number_of_stack_slots;
  }
  return 0;
}


int SerializedScopeInfo::NumberOfContextSlots() {
  if (length() > 0) {
    Object** p = ContextEntriesAddr();
    int number_of_context_slots;
    ReadInt(p, &number_of_context_slots);
    return number_of_context_slots + Context::MIN_CONTEXT_SLOTS;
  }
  return 0;
}


bool SerializedScopeInfo::HasHeapAllocatedLocals() {
  if (length() > 0) {
    Object** p = ContextEntriesAddr();
    int number_of_context_slots;
    ReadInt(p, &number_of_context_slots);
    return number_of_context_slots > 0;
  }
  return false;
}


int SerializedScopeInfo::StackSlotIndex(String* name) {
  ASSERT(name->IsSymbol());
  if (length() > 0) {
    // Slots start after length entry.
    Object** p0 = StackSlotEntriesAddr();
    int number_of_stack_slots;
    p0 = ReadInt(p0, &number_of_stack_slots);
    Object** p = p0;
    Object** end = p0 + number_of_stack_slots;
    while (p != end) {
      if (*p == name) return static_cast<int>(p - p0);
      p++;
    }
  }
  return -1;
}

int SerializedScopeInfo::ContextSlotIndex(String* name, Variable::Mode* mode) {
  ASSERT(name->IsSymbol());
  int result = ContextSlotCache::Lookup(this, name, mode);
  if (result != ContextSlotCache::kNotFound) return result;
  if (length() > 0) {
    // Slots start after length entry.
    Object** p0 = ContextEntriesAddr();
    int number_of_context_slots;
    p0 = ReadInt(p0, &number_of_context_slots);
    Object** p = p0;
    Object** end = p0 + number_of_context_slots * 2;
    while (p != end) {
      if (*p == name) {
        ASSERT(((p - p0) & 1) == 0);
        int v;
        ReadInt(p + 1, &v);
        Variable::Mode mode_value = static_cast<Variable::Mode>(v);
        if (mode != NULL) *mode = mode_value;
        result = static_cast<int>((p - p0) >> 1) + Context::MIN_CONTEXT_SLOTS;
        ContextSlotCache::Update(this, name, mode_value, result);
        return result;
      }
      p += 2;
    }
  }
  ContextSlotCache::Update(this, name, Variable::INTERNAL, -1);
  return -1;
}


int SerializedScopeInfo::ParameterIndex(String* name) {
  ASSERT(name->IsSymbol());
  if (length() > 0) {
    // We must read parameters from the end since for
    // multiply declared parameters the value of the
    // last declaration of that parameter is used
    // inside a function (and thus we need to look
    // at the last index). Was bug# 1110337.
    //
    // Eventually, we should only register such parameters
    // once, with corresponding index. This requires a new
    // implementation of the ScopeInfo code. See also other
    // comments in this file regarding this.
    Object** p = ParameterEntriesAddr();
    int number_of_parameter_slots;
    Object** p0 = ReadInt(p, &number_of_parameter_slots);
    p = p0 + number_of_parameter_slots;
    while (p > p0) {
      p--;
      if (*p == name) return static_cast<int>(p - p0);
    }
  }
  return -1;
}


int SerializedScopeInfo::FunctionContextSlotIndex(String* name) {
  ASSERT(name->IsSymbol());
  if (length() > 0) {
    Object** p = data_start();
    if (*p == name) {
      p = ContextEntriesAddr();
      int number_of_context_slots;
      ReadInt(p, &number_of_context_slots);
      ASSERT(number_of_context_slots != 0);
      // The function context slot is the last entry.
      return number_of_context_slots + Context::MIN_CONTEXT_SLOTS - 1;
    }
  }
  return -1;
}


int ContextSlotCache::Hash(Object* data, String* name) {
  // Uses only lower 32 bits if pointers are larger.
  uintptr_t addr_hash =
      static_cast<uint32_t>(reinterpret_cast<uintptr_t>(data)) >> 2;
  return static_cast<int>((addr_hash ^ name->Hash()) % kLength);
}


int ContextSlotCache::Lookup(Object* data,
                             String* name,
                             Variable::Mode* mode) {
  int index = Hash(data, name);
  Key& key = keys_[index];
  if ((key.data == data) && key.name->Equals(name)) {
    Value result(values_[index]);
    if (mode != NULL) *mode = result.mode();
    return result.index() + kNotFound;
  }
  return kNotFound;
}


void ContextSlotCache::Update(Object* data,
                              String* name,
                              Variable::Mode mode,
                              int slot_index) {
  String* symbol;
  ASSERT(slot_index > kNotFound);
  if (Heap::LookupSymbolIfExists(name, &symbol)) {
    int index = Hash(data, symbol);
    Key& key = keys_[index];
    key.data = data;
    key.name = symbol;
    // Please note value only takes a uint as index.
    values_[index] = Value(mode, slot_index - kNotFound).raw();
#ifdef DEBUG
    ValidateEntry(data, name, mode, slot_index);
#endif
  }
}


void ContextSlotCache::Clear() {
  for (int index = 0; index < kLength; index++) keys_[index].data = NULL;
}


ContextSlotCache::Key ContextSlotCache::keys_[ContextSlotCache::kLength];


uint32_t ContextSlotCache::values_[ContextSlotCache::kLength];


#ifdef DEBUG

void ContextSlotCache::ValidateEntry(Object* data,
                                     String* name,
                                     Variable::Mode mode,
                                     int slot_index) {
  String* symbol;
  if (Heap::LookupSymbolIfExists(name, &symbol)) {
    int index = Hash(data, name);
    Key& key = keys_[index];
    ASSERT(key.data == data);
    ASSERT(key.name->Equals(name));
    Value result(values_[index]);
    ASSERT(result.mode() == mode);
    ASSERT(result.index() + kNotFound == slot_index);
  }
}


template <class Allocator>
static void PrintList(const char* list_name,
                      int nof_internal_slots,
                      List<Handle<String>, Allocator>& list) {
  if (list.length() > 0) {
    PrintF("\n  // %s\n", list_name);
    if (nof_internal_slots > 0) {
      PrintF("  %2d - %2d [internal slots]\n", 0 , nof_internal_slots - 1);
    }
    for (int i = 0; i < list.length(); i++) {
      PrintF("  %2d ", i + nof_internal_slots);
      list[i]->ShortPrint();
      PrintF("\n");
    }
  }
}


template<class Allocator>
void ScopeInfo<Allocator>::Print() {
  PrintF("ScopeInfo ");
  if (function_name_->length() > 0)
    function_name_->ShortPrint();
  else
    PrintF("/* no function name */");
  PrintF("{");

  PrintList<Allocator>("parameters", 0, parameters_);
  PrintList<Allocator>("stack slots", 0, stack_slots_);
  PrintList<Allocator>("context slots", Context::MIN_CONTEXT_SLOTS,
                       context_slots_);

  PrintF("}\n");
}
#endif  // DEBUG


// Make sure the classes get instantiated by the template system.
template class ScopeInfo<FreeStoreAllocationPolicy>;
template class ScopeInfo<PreallocatedStorage>;
template class ScopeInfo<ZoneListAllocationPolicy>;

} }  // namespace v8::internal
