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