1257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Copyright 2011 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_SCOPEINFO_H_
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_SCOPEINFO_H_
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/allocation.h"
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/variables.h"
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/zone-inl.h"
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
153bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch// Cache for mapping (data, property name) into context slot index.
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The cache contains both positive and negative results.
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Slot index equals -1 means the property is absent.
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Cleared at startup and prior to mark sweep collection.
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass ContextSlotCache {
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
213bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  // Lookup context slot index for (data, name).
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If absent, kNotFound is returned.
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int Lookup(Object* data, String* name, VariableMode* mode,
24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             InitializationFlag* init_flag,
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             MaybeAssignedFlag* maybe_assigned_flag);
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Update an element in the cache.
28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Update(Handle<Object> data, Handle<String> name, VariableMode mode,
293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch              InitializationFlag init_flag,
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              MaybeAssignedFlag maybe_assigned_flag, int slot_index);
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Clear the cache.
3344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void Clear();
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kNotFound = -2;
36589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
3844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ContextSlotCache() {
3944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    for (int i = 0; i < kLength; ++i) {
4044f0eee88ff00398ff7f715fab053374d808c90dSteve Block      keys_[i].data = NULL;
4144f0eee88ff00398ff7f715fab053374d808c90dSteve Block      keys_[i].name = NULL;
4244f0eee88ff00398ff7f715fab053374d808c90dSteve Block      values_[i] = kNotFound;
4344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    }
4444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
4544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
463bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  inline static int Hash(Object* data, String* name);
47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void ValidateEntry(Handle<Object> data, Handle<String> name,
50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                     VariableMode mode, InitializationFlag init_flag,
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                     MaybeAssignedFlag maybe_assigned_flag, int slot_index);
52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kLength = 256;
55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  struct Key {
563bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch    Object* data;
57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    String* name;
58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  };
59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  struct Value {
61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Value(VariableMode mode, InitializationFlag init_flag,
62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          MaybeAssignedFlag maybe_assigned_flag, int index) {
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(ModeField::is_valid(mode));
64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(InitField::is_valid(init_flag));
65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(MaybeAssignedField::is_valid(maybe_assigned_flag));
66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(IndexField::is_valid(index));
67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      value_ = ModeField::encode(mode) | IndexField::encode(index) |
68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch               InitField::encode(init_flag) |
69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch               MaybeAssignedField::encode(maybe_assigned_flag);
70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(mode == this->mode());
71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(init_flag == this->initialization_flag());
72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(maybe_assigned_flag == this->maybe_assigned_flag());
73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(index == this->index());
74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
768b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    explicit inline Value(uint32_t value) : value_(value) {}
77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    uint32_t raw() { return value_; }
79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    VariableMode mode() { return ModeField::decode(value_); }
813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    InitializationFlag initialization_flag() {
833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      return InitField::decode(value_);
843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    MaybeAssignedFlag maybe_assigned_flag() {
87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return MaybeAssignedField::decode(value_);
88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int index() { return IndexField::decode(value_); }
91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Bit fields in value_ (type, shift, size). Must be public so the
93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // constants can be embedded in generated code.
94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    class ModeField : public BitField<VariableMode, 0, 4> {};
95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    class InitField : public BitField<InitializationFlag, 4, 1> {};
96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    class MaybeAssignedField : public BitField<MaybeAssignedFlag, 5, 1> {};
97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    class IndexField : public BitField<int, 6, 32 - 6> {};
983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block   private:
100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    uint32_t value_;
101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  };
102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
10344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Key keys_[kLength];
10444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  uint32_t values_[kLength];
10544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
10644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  friend class Isolate;
10744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  DISALLOW_COPY_AND_ASSIGN(ContextSlotCache);
108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//---------------------------------------------------------------------------
114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Auxiliary class used for the description of module instances.
115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Used by Runtime_DeclareModules.
116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass ModuleInfo: public FixedArray {
118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static ModuleInfo* cast(Object* description) {
120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return static_cast<ModuleInfo*>(FixedArray::cast(description));
121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Handle<ModuleInfo> Create(
124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Isolate* isolate, Interface* interface, Scope* scope);
125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Index of module's context in host context.
127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int host_index() { return Smi::cast(get(HOST_OFFSET))->value(); }
128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Name, mode, and index of the i-th export, respectively.
130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // For value exports, the index is the slot of the value in the module
131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // context, for exported modules it is the slot index of the
132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // referred module's context in the host context.
133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(rossberg): This format cannot yet handle exports of modules declared
134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // in earlier scripts.
135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  String* name(int i) { return String::cast(get(name_offset(i))); }
136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VariableMode mode(int i) {
137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return static_cast<VariableMode>(Smi::cast(get(mode_offset(i)))->value());
138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int index(int i) { return Smi::cast(get(index_offset(i)))->value(); }
140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int length() { return (FixedArray::length() - HEADER_SIZE) / ITEM_SIZE; }
142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The internal format is: Index, (Name, VariableMode, Index)*
145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  enum {
146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HOST_OFFSET,
147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    NAME_OFFSET,
148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    MODE_OFFSET,
149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    INDEX_OFFSET,
150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HEADER_SIZE = NAME_OFFSET,
151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ITEM_SIZE = INDEX_OFFSET - NAME_OFFSET + 1
152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline int name_offset(int i) { return NAME_OFFSET + i * ITEM_SIZE; }
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline int mode_offset(int i) { return MODE_OFFSET + i * ITEM_SIZE; }
155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline int index_offset(int i) { return INDEX_OFFSET + i * ITEM_SIZE; }
156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Handle<ModuleInfo> Allocate(Isolate* isolate, int length) {
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Handle<ModuleInfo>::cast(
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        isolate->factory()->NewFixedArray(HEADER_SIZE + ITEM_SIZE * length));
160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_host_index(int index) { set(HOST_OFFSET, Smi::FromInt(index)); }
162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_name(int i, String* name) { set(name_offset(i), name); }
163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_mode(int i, VariableMode mode) {
164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set(mode_offset(i), Smi::FromInt(mode));
165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_index(int i, int index) {
167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set(index_offset(i), Smi::FromInt(index));
168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif  // V8_SCOPEINFO_H_
175