blob: 15ee29f9fcae96624189ccda06e77edc839b6fa4 [file] [log] [blame]
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001// Copyright 2011 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#include <stdlib.h>
29
30#include "v8.h"
31
32#include "scopeinfo.h"
33#include "scopes.h"
34
whesse@chromium.org030d38e2011-07-13 13:23:34 +000035#include "allocation-inl.h"
36
kasperl@chromium.org71affb52009-05-26 05:44:31 +000037namespace v8 {
38namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000039
40
mmassi@chromium.org7028c052012-06-13 11:51:58 +000041Handle<ScopeInfo> ScopeInfo::Create(Scope* scope, Zone* zone) {
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000042 // Collect stack and context locals.
mmassi@chromium.org7028c052012-06-13 11:51:58 +000043 ZoneList<Variable*> stack_locals(scope->StackLocalCount(), zone);
44 ZoneList<Variable*> context_locals(scope->ContextLocalCount(), zone);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000045 scope->CollectStackAndContextLocals(&stack_locals, &context_locals);
46 const int stack_local_count = stack_locals.length();
47 const int context_local_count = context_locals.length();
48 // Make sure we allocate the correct amount.
49 ASSERT(scope->StackLocalCount() == stack_local_count);
50 ASSERT(scope->ContextLocalCount() == context_local_count);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000051
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000052 // Determine use and location of the function variable if it is present.
53 FunctionVariableInfo function_name_info;
54 VariableMode function_variable_mode;
55 if (scope->is_function_scope() && scope->function() != NULL) {
erik.corry@gmail.comed49e962012-04-17 11:57:53 +000056 Variable* var = scope->function()->proxy()->var();
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000057 if (!var->is_used()) {
58 function_name_info = UNUSED;
59 } else if (var->IsContextSlot()) {
60 function_name_info = CONTEXT;
61 } else {
62 ASSERT(var->IsStackLocal());
63 function_name_info = STACK;
64 }
65 function_variable_mode = var->mode();
66 } else {
67 function_name_info = NONE;
68 function_variable_mode = VAR;
69 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000070
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000071 const bool has_function_name = function_name_info != NONE;
72 const int parameter_count = scope->num_parameters();
73 const int length = kVariablePartIndex
74 + parameter_count + stack_local_count + 2 * context_local_count
75 + (has_function_name ? 2 : 0);
76
77 Handle<ScopeInfo> scope_info = FACTORY->NewScopeInfo(length);
78
79 // Encode the flags.
80 int flags = TypeField::encode(scope->type()) |
81 CallsEvalField::encode(scope->calls_eval()) |
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +000082 LanguageModeField::encode(scope->language_mode()) |
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000083 FunctionVariableField::encode(function_name_info) |
84 FunctionVariableMode::encode(function_variable_mode);
85 scope_info->SetFlags(flags);
86 scope_info->SetParameterCount(parameter_count);
87 scope_info->SetStackLocalCount(stack_local_count);
88 scope_info->SetContextLocalCount(context_local_count);
89
90 int index = kVariablePartIndex;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000091 // Add parameters.
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000092 ASSERT(index == scope_info->ParameterEntriesIndex());
93 for (int i = 0; i < parameter_count; ++i) {
94 scope_info->set(index++, *scope->parameter(i)->name());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000095 }
96
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000097 // Add stack locals' names. We are assuming that the stack locals'
98 // slots are allocated in increasing order, so we can simply add
99 // them to the ScopeInfo object.
100 ASSERT(index == scope_info->StackLocalEntriesIndex());
101 for (int i = 0; i < stack_local_count; ++i) {
102 ASSERT(stack_locals[i]->index() == i);
103 scope_info->set(index++, *stack_locals[i]->name());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000104 }
105
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000106 // Due to usage analysis, context-allocated locals are not necessarily in
107 // increasing order: Some of them may be parameters which are allocated before
108 // the non-parameter locals. When the non-parameter locals are sorted
109 // according to usage, the allocated slot indices may not be in increasing
110 // order with the variable list anymore. Thus, we first need to sort them by
111 // context slot index before adding them to the ScopeInfo object.
112 context_locals.Sort(&Variable::CompareIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000113
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000114 // Add context locals' names.
115 ASSERT(index == scope_info->ContextLocalNameEntriesIndex());
116 for (int i = 0; i < context_local_count; ++i) {
117 scope_info->set(index++, *context_locals[i]->name());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000118 }
119
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000120 // Add context locals' info.
121 ASSERT(index == scope_info->ContextLocalInfoEntriesIndex());
122 for (int i = 0; i < context_local_count; ++i) {
123 Variable* var = context_locals[i];
124 uint32_t value = ContextLocalMode::encode(var->mode()) |
125 ContextLocalInitFlag::encode(var->initialization_flag());
126 scope_info->set(index++, Smi::FromInt(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000127 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000128
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000129 // If present, add the function variable name and its index.
130 ASSERT(index == scope_info->FunctionNameEntryIndex());
131 if (has_function_name) {
erik.corry@gmail.comed49e962012-04-17 11:57:53 +0000132 int var_index = scope->function()->proxy()->var()->index();
133 scope_info->set(index++, *scope->function()->proxy()->name());
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000134 scope_info->set(index++, Smi::FromInt(var_index));
135 ASSERT(function_name_info != STACK ||
136 (var_index == scope_info->StackLocalCount() &&
137 var_index == scope_info->StackSlotCount() - 1));
138 ASSERT(function_name_info != CONTEXT ||
139 var_index == scope_info->ContextLength() - 1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000140 }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000141
142 ASSERT(index == scope_info->length());
143 ASSERT(scope->num_parameters() == scope_info->ParameterCount());
144 ASSERT(scope->num_stack_slots() == scope_info->StackSlotCount());
erik.corry@gmail.comed49e962012-04-17 11:57:53 +0000145 ASSERT(scope->num_heap_slots() == scope_info->ContextLength() ||
146 (scope->num_heap_slots() == kVariablePartIndex &&
147 scope_info->ContextLength() == 0));
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000148 return scope_info;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000149}
150
151
hpayer@chromium.org8432c912013-02-28 15:55:26 +0000152ScopeInfo* ScopeInfo::Empty(Isolate* isolate) {
153 return reinterpret_cast<ScopeInfo*>(isolate->heap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000154}
155
156
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000157ScopeType ScopeInfo::Type() {
ager@chromium.orgb5737492010-07-15 09:29:43 +0000158 ASSERT(length() > 0);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000159 return TypeField::decode(Flags());
ager@chromium.orgb5737492010-07-15 09:29:43 +0000160}
161
162
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000163bool ScopeInfo::CallsEval() {
164 return length() > 0 && CallsEvalField::decode(Flags());
ager@chromium.orgb5737492010-07-15 09:29:43 +0000165}
166
167
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000168LanguageMode ScopeInfo::language_mode() {
169 return length() > 0 ? LanguageModeField::decode(Flags()) : CLASSIC_MODE;
ager@chromium.orgb5737492010-07-15 09:29:43 +0000170}
171
172
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000173int ScopeInfo::LocalCount() {
174 return StackLocalCount() + ContextLocalCount();
175}
176
177
178int ScopeInfo::StackSlotCount() {
ager@chromium.orgb5737492010-07-15 09:29:43 +0000179 if (length() > 0) {
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000180 bool function_name_stack_slot =
181 FunctionVariableField::decode(Flags()) == STACK;
182 return StackLocalCount() + (function_name_stack_slot ? 1 : 0);
ager@chromium.orgb5737492010-07-15 09:29:43 +0000183 }
184 return 0;
185}
186
187
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000188int ScopeInfo::ContextLength() {
ager@chromium.orgb5737492010-07-15 09:29:43 +0000189 if (length() > 0) {
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000190 int context_locals = ContextLocalCount();
191 bool function_name_context_slot =
192 FunctionVariableField::decode(Flags()) == CONTEXT;
193 bool has_context = context_locals > 0 ||
194 function_name_context_slot ||
195 Type() == WITH_SCOPE ||
danno@chromium.org81cac2b2012-07-10 11:28:27 +0000196 (Type() == FUNCTION_SCOPE && CallsEval()) ||
197 Type() == MODULE_SCOPE;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000198 if (has_context) {
199 return Context::MIN_CONTEXT_SLOTS + context_locals +
200 (function_name_context_slot ? 1 : 0);
201 }
ager@chromium.orgb5737492010-07-15 09:29:43 +0000202 }
203 return 0;
204}
205
206
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000207bool ScopeInfo::HasFunctionName() {
ager@chromium.orgb5737492010-07-15 09:29:43 +0000208 if (length() > 0) {
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000209 return NONE != FunctionVariableField::decode(Flags());
210 } else {
211 return false;
ager@chromium.orgb5737492010-07-15 09:29:43 +0000212 }
ager@chromium.orgb5737492010-07-15 09:29:43 +0000213}
214
215
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000216bool ScopeInfo::HasHeapAllocatedLocals() {
217 if (length() > 0) {
218 return ContextLocalCount() > 0;
219 } else {
220 return false;
221 }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000222}
223
224
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000225bool ScopeInfo::HasContext() {
danno@chromium.org81cac2b2012-07-10 11:28:27 +0000226 return ContextLength() > 0;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000227}
228
229
230String* ScopeInfo::FunctionName() {
231 ASSERT(HasFunctionName());
232 return String::cast(get(FunctionNameEntryIndex()));
233}
234
235
236String* ScopeInfo::ParameterName(int var) {
237 ASSERT(0 <= var && var < ParameterCount());
238 int info_index = ParameterEntriesIndex() + var;
239 return String::cast(get(info_index));
240}
241
242
243String* ScopeInfo::LocalName(int var) {
244 ASSERT(0 <= var && var < LocalCount());
245 ASSERT(StackLocalEntriesIndex() + StackLocalCount() ==
246 ContextLocalNameEntriesIndex());
247 int info_index = StackLocalEntriesIndex() + var;
248 return String::cast(get(info_index));
249}
250
251
252String* ScopeInfo::StackLocalName(int var) {
253 ASSERT(0 <= var && var < StackLocalCount());
254 int info_index = StackLocalEntriesIndex() + var;
255 return String::cast(get(info_index));
256}
257
258
259String* ScopeInfo::ContextLocalName(int var) {
260 ASSERT(0 <= var && var < ContextLocalCount());
261 int info_index = ContextLocalNameEntriesIndex() + var;
262 return String::cast(get(info_index));
263}
264
265
266VariableMode ScopeInfo::ContextLocalMode(int var) {
267 ASSERT(0 <= var && var < ContextLocalCount());
268 int info_index = ContextLocalInfoEntriesIndex() + var;
269 int value = Smi::cast(get(info_index))->value();
270 return ContextLocalMode::decode(value);
271}
272
273
274InitializationFlag ScopeInfo::ContextLocalInitFlag(int var) {
275 ASSERT(0 <= var && var < ContextLocalCount());
276 int info_index = ContextLocalInfoEntriesIndex() + var;
277 int value = Smi::cast(get(info_index))->value();
278 return ContextLocalInitFlag::decode(value);
279}
280
281
282int ScopeInfo::StackSlotIndex(String* name) {
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000283 ASSERT(name->IsInternalizedString());
ager@chromium.orgb5737492010-07-15 09:29:43 +0000284 if (length() > 0) {
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000285 int start = StackLocalEntriesIndex();
286 int end = StackLocalEntriesIndex() + StackLocalCount();
287 for (int i = start; i < end; ++i) {
288 if (name == get(i)) {
289 return i - start;
290 }
ager@chromium.orgb5737492010-07-15 09:29:43 +0000291 }
292 }
293 return -1;
294}
295
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000296
297int ScopeInfo::ContextSlotIndex(String* name,
298 VariableMode* mode,
299 InitializationFlag* init_flag) {
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000300 ASSERT(name->IsInternalizedString());
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000301 ASSERT(mode != NULL);
302 ASSERT(init_flag != NULL);
ager@chromium.orgb5737492010-07-15 09:29:43 +0000303 if (length() > 0) {
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000304 ContextSlotCache* context_slot_cache = GetIsolate()->context_slot_cache();
305 int result = context_slot_cache->Lookup(this, name, mode, init_flag);
306 if (result != ContextSlotCache::kNotFound) {
307 ASSERT(result < ContextLength());
308 return result;
309 }
310
311 int start = ContextLocalNameEntriesIndex();
312 int end = ContextLocalNameEntriesIndex() + ContextLocalCount();
313 for (int i = start; i < end; ++i) {
314 if (name == get(i)) {
315 int var = i - start;
316 *mode = ContextLocalMode(var);
317 *init_flag = ContextLocalInitFlag(var);
318 result = Context::MIN_CONTEXT_SLOTS + var;
319 context_slot_cache->Update(this, name, *mode, *init_flag, result);
320 ASSERT(result < ContextLength());
ager@chromium.orgb5737492010-07-15 09:29:43 +0000321 return result;
322 }
ager@chromium.orgb5737492010-07-15 09:29:43 +0000323 }
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000324 // Cache as not found. Mode and init flag don't matter.
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000325 context_slot_cache->Update(this, name, INTERNAL, kNeedsInitialization, -1);
ager@chromium.orgb5737492010-07-15 09:29:43 +0000326 }
ager@chromium.orgb5737492010-07-15 09:29:43 +0000327 return -1;
328}
329
330
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000331int ScopeInfo::ParameterIndex(String* name) {
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000332 ASSERT(name->IsInternalizedString());
ager@chromium.orgb5737492010-07-15 09:29:43 +0000333 if (length() > 0) {
334 // We must read parameters from the end since for
335 // multiply declared parameters the value of the
336 // last declaration of that parameter is used
337 // inside a function (and thus we need to look
338 // at the last index). Was bug# 1110337.
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000339 int start = ParameterEntriesIndex();
340 int end = ParameterEntriesIndex() + ParameterCount();
341 for (int i = end - 1; i >= start; --i) {
342 if (name == get(i)) {
343 return i - start;
344 }
ager@chromium.orgb5737492010-07-15 09:29:43 +0000345 }
346 }
347 return -1;
348}
349
350
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000351int ScopeInfo::FunctionContextSlotIndex(String* name, VariableMode* mode) {
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000352 ASSERT(name->IsInternalizedString());
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000353 ASSERT(mode != NULL);
ager@chromium.orgb5737492010-07-15 09:29:43 +0000354 if (length() > 0) {
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000355 if (FunctionVariableField::decode(Flags()) == CONTEXT &&
356 FunctionName() == name) {
357 *mode = FunctionVariableMode::decode(Flags());
358 return Smi::cast(get(FunctionNameEntryIndex() + 1))->value();
ager@chromium.orgb5737492010-07-15 09:29:43 +0000359 }
360 }
361 return -1;
362}
363
364
mstarzinger@chromium.org71fc3462013-02-27 09:34:27 +0000365bool ScopeInfo::CopyContextLocalsToScopeObject(
366 Isolate* isolate,
367 Handle<Context> context,
368 Handle<JSObject> scope_object) {
369 int local_count = ContextLocalCount();
370 if (local_count == 0) return true;
371 // Fill all context locals to the context extension.
372 int start = ContextLocalNameEntriesIndex();
373 int end = start + local_count;
374 for (int i = start; i < end; ++i) {
375 int context_index = Context::MIN_CONTEXT_SLOTS + i - start;
376 RETURN_IF_EMPTY_HANDLE_VALUE(
377 isolate,
378 SetProperty(isolate,
379 scope_object,
380 Handle<String>(String::cast(get(i))),
381 Handle<Object>(context->get(context_index), isolate),
382 ::NONE,
383 kNonStrictMode),
384 false);
385 }
386 return true;
387}
388
389
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000390int ScopeInfo::ParameterEntriesIndex() {
391 ASSERT(length() > 0);
392 return kVariablePartIndex;
393}
394
395
396int ScopeInfo::StackLocalEntriesIndex() {
397 return ParameterEntriesIndex() + ParameterCount();
398}
399
400
401int ScopeInfo::ContextLocalNameEntriesIndex() {
402 return StackLocalEntriesIndex() + StackLocalCount();
403}
404
405
406int ScopeInfo::ContextLocalInfoEntriesIndex() {
407 return ContextLocalNameEntriesIndex() + ContextLocalCount();
408}
409
410
411int ScopeInfo::FunctionNameEntryIndex() {
412 return ContextLocalInfoEntriesIndex() + ContextLocalCount();
413}
414
415
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +0000416int ContextSlotCache::Hash(Object* data, String* name) {
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000417 // Uses only lower 32 bits if pointers are larger.
418 uintptr_t addr_hash =
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +0000419 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(data)) >> 2;
fschneider@chromium.orgb95b98b2010-02-23 10:34:29 +0000420 return static_cast<int>((addr_hash ^ name->Hash()) % kLength);
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000421}
422
423
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +0000424int ContextSlotCache::Lookup(Object* data,
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000425 String* name,
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000426 VariableMode* mode,
427 InitializationFlag* init_flag) {
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +0000428 int index = Hash(data, name);
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000429 Key& key = keys_[index];
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +0000430 if ((key.data == data) && key.name->Equals(name)) {
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000431 Value result(values_[index]);
432 if (mode != NULL) *mode = result.mode();
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000433 if (init_flag != NULL) *init_flag = result.initialization_flag();
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000434 return result.index() + kNotFound;
435 }
436 return kNotFound;
437}
438
439
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +0000440void ContextSlotCache::Update(Object* data,
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000441 String* name,
rossberg@chromium.orgb4b2aa62011-10-13 09:49:59 +0000442 VariableMode mode,
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000443 InitializationFlag init_flag,
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000444 int slot_index) {
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000445 String* internalized_name;
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000446 ASSERT(slot_index > kNotFound);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000447 if (HEAP->InternalizeStringIfExists(name, &internalized_name)) {
448 int index = Hash(data, internalized_name);
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000449 Key& key = keys_[index];
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +0000450 key.data = data;
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000451 key.name = internalized_name;
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000452 // Please note value only takes a uint as index.
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000453 values_[index] = Value(mode, init_flag, slot_index - kNotFound).raw();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000454#ifdef DEBUG
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000455 ValidateEntry(data, name, mode, init_flag, slot_index);
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000456#endif
457 }
458}
459
460
461void ContextSlotCache::Clear() {
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +0000462 for (int index = 0; index < kLength; index++) keys_[index].data = NULL;
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000463}
464
465
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000466#ifdef DEBUG
467
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +0000468void ContextSlotCache::ValidateEntry(Object* data,
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000469 String* name,
rossberg@chromium.orgb4b2aa62011-10-13 09:49:59 +0000470 VariableMode mode,
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000471 InitializationFlag init_flag,
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000472 int slot_index) {
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000473 String* internalized_name;
474 if (HEAP->InternalizeStringIfExists(name, &internalized_name)) {
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +0000475 int index = Hash(data, name);
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000476 Key& key = keys_[index];
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +0000477 ASSERT(key.data == data);
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000478 ASSERT(key.name->Equals(name));
479 Value result(values_[index]);
480 ASSERT(result.mode() == mode);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000481 ASSERT(result.initialization_flag() == init_flag);
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000482 ASSERT(result.index() + kNotFound == slot_index);
483 }
484}
485
486
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000487static void PrintList(const char* list_name,
488 int nof_internal_slots,
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000489 int start,
490 int end,
491 ScopeInfo* scope_info) {
492 if (start < end) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000493 PrintF("\n // %s\n", list_name);
494 if (nof_internal_slots > 0) {
495 PrintF(" %2d - %2d [internal slots]\n", 0 , nof_internal_slots - 1);
496 }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000497 for (int i = nof_internal_slots; start < end; ++i, ++start) {
498 PrintF(" %2d ", i);
499 String::cast(scope_info->get(start))->ShortPrint();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000500 PrintF("\n");
501 }
502 }
503}
504
505
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000506void ScopeInfo::Print() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000507 PrintF("ScopeInfo ");
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000508 if (HasFunctionName()) {
509 FunctionName()->ShortPrint();
510 } else {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000511 PrintF("/* no function name */");
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000512 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000513 PrintF("{");
514
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000515 PrintList("parameters", 0,
516 ParameterEntriesIndex(),
517 ParameterEntriesIndex() + ParameterCount(),
518 this);
519 PrintList("stack slots", 0,
520 StackLocalEntriesIndex(),
521 StackLocalEntriesIndex() + StackLocalCount(),
522 this);
523 PrintList("context slots",
524 Context::MIN_CONTEXT_SLOTS,
525 ContextLocalNameEntriesIndex(),
526 ContextLocalNameEntriesIndex() + ContextLocalCount(),
527 this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000528
529 PrintF("}\n");
530}
531#endif // DEBUG
532
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000533
534//---------------------------------------------------------------------------
535// ModuleInfo.
536
537Handle<ModuleInfo> ModuleInfo::Create(
538 Isolate* isolate, Interface* interface, Scope* scope) {
539 Handle<ModuleInfo> info = Allocate(isolate, interface->Length());
540 info->set_host_index(interface->Index());
541 int i = 0;
542 for (Interface::Iterator it = interface->iterator();
543 !it.done(); it.Advance(), ++i) {
544 Variable* var = scope->LocalLookup(it.name());
545 info->set_name(i, *it.name());
546 info->set_mode(i, var->mode());
547 ASSERT((var->mode() == MODULE) == (it.interface()->IsModule()));
548 if (var->mode() == MODULE) {
549 ASSERT(it.interface()->IsFrozen());
550 ASSERT(it.interface()->Index() >= 0);
551 info->set_index(i, it.interface()->Index());
552 } else {
553 ASSERT(var->index() >= 0);
554 info->set_index(i, var->index());
555 }
556 }
557 ASSERT(i == info->length());
558 return info;
559}
560
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000561} } // namespace v8::internal