Line data Source code
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 : #include <stdlib.h>
6 :
7 : #include "src/objects/scope-info.h"
8 :
9 : #include "src/ast/scopes.h"
10 : #include "src/ast/variables.h"
11 : #include "src/bootstrapper.h"
12 :
13 : #include "src/objects-inl.h"
14 : #include "src/objects/module-inl.h"
15 :
16 : namespace v8 {
17 : namespace internal {
18 :
19 : // An entry in ModuleVariableEntries consists of several slots:
20 : enum ModuleVariableEntryOffset {
21 : kModuleVariableNameOffset,
22 : kModuleVariableIndexOffset,
23 : kModuleVariablePropertiesOffset,
24 : kModuleVariableEntryLength // Sentinel value.
25 : };
26 :
27 : #ifdef DEBUG
28 : bool ScopeInfo::Equals(ScopeInfo other) const {
29 : if (length() != other->length()) return false;
30 : for (int index = 0; index < length(); ++index) {
31 : Object entry = get(index);
32 : Object other_entry = other->get(index);
33 : if (entry->IsSmi()) {
34 : if (entry != other_entry) return false;
35 : } else {
36 : if (HeapObject::cast(entry)->map()->instance_type() !=
37 : HeapObject::cast(other_entry)->map()->instance_type()) {
38 : return false;
39 : }
40 : if (entry->IsString()) {
41 : if (!String::cast(entry)->Equals(String::cast(other_entry))) {
42 : return false;
43 : }
44 : } else if (entry->IsScopeInfo()) {
45 : if (!ScopeInfo::cast(entry)->Equals(ScopeInfo::cast(other_entry))) {
46 : return false;
47 : }
48 : } else if (entry->IsModuleInfo()) {
49 : if (!ModuleInfo::cast(entry)->Equals(ModuleInfo::cast(other_entry))) {
50 : return false;
51 : }
52 : } else {
53 : UNREACHABLE();
54 : }
55 : }
56 : }
57 : return true;
58 : }
59 : #endif
60 :
61 : // static
62 19685365 : Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, Scope* scope,
63 : MaybeHandle<ScopeInfo> outer_scope) {
64 : // Collect variables.
65 : int context_local_count = 0;
66 : int module_vars_count = 0;
67 : // Stack allocated block scope variables are allocated in the parent
68 : // declaration scope, but are recorded in the block scope's scope info. First
69 : // slot index indicates at which offset a particular scope starts in the
70 : // parent declaration scope.
71 14578070 : for (Variable* var : *scope->locals()) {
72 10148080 : switch (var->location()) {
73 : case VariableLocation::CONTEXT:
74 1909603 : context_local_count++;
75 1909603 : break;
76 : case VariableLocation::MODULE:
77 17986 : module_vars_count++;
78 17986 : break;
79 : default:
80 : break;
81 : }
82 : }
83 : DCHECK(module_vars_count == 0 || scope->is_module_scope());
84 :
85 : // Make sure we allocate the correct amount.
86 : DCHECK_EQ(scope->ContextLocalCount(), context_local_count);
87 :
88 : // Determine use and location of the "this" binding if it is present.
89 : VariableAllocationInfo receiver_info;
90 4307592 : if (scope->is_declaration_scope() &&
91 2092600 : scope->AsDeclarationScope()->has_this_declaration()) {
92 892218 : Variable* var = scope->AsDeclarationScope()->receiver();
93 892218 : if (!var->is_used()) {
94 : receiver_info = UNUSED;
95 180331 : } else if (var->IsContextSlot()) {
96 : receiver_info = CONTEXT;
97 : } else {
98 : DCHECK(var->IsParameter());
99 : receiver_info = STACK;
100 : }
101 : } else {
102 : receiver_info = NONE;
103 : }
104 :
105 : const bool has_new_target =
106 4307609 : scope->is_declaration_scope() &&
107 2092604 : scope->AsDeclarationScope()->new_target_var() != nullptr;
108 : // TODO(cbruni): Don't always waste a field for the inferred name.
109 : const bool has_inferred_function_name = scope->is_function_scope();
110 :
111 : // Determine use and location of the function variable if it is present.
112 : VariableAllocationInfo function_name_info;
113 2215005 : if (scope->is_function_scope()) {
114 1082829 : if (scope->AsDeclarationScope()->function_var() != nullptr) {
115 24677 : Variable* var = scope->AsDeclarationScope()->function_var();
116 24677 : if (!var->is_used()) {
117 : function_name_info = UNUSED;
118 24677 : } else if (var->IsContextSlot()) {
119 : function_name_info = CONTEXT;
120 : } else {
121 : DCHECK(var->IsStackLocal());
122 : function_name_info = STACK;
123 : }
124 : } else {
125 : // Always reserve space for the debug name in the scope info.
126 : function_name_info = UNUSED;
127 : }
128 1132176 : } else if (scope->is_module_scope() || scope->is_script_scope() ||
129 : scope->is_eval_scope()) {
130 : // Always reserve space for the debug name in the scope info.
131 : function_name_info = UNUSED;
132 : } else {
133 : function_name_info = NONE;
134 : }
135 :
136 2215001 : const bool has_function_name = function_name_info != NONE;
137 : const bool has_position_info = NeedsPositionInfo(scope->scope_type());
138 2215001 : const bool has_receiver = receiver_info == STACK || receiver_info == CONTEXT;
139 2215001 : const int parameter_count = scope->num_parameters();
140 2215007 : const bool has_outer_scope_info = !outer_scope.is_null();
141 2215007 : const int length = kVariablePartIndex + 2 * context_local_count +
142 2215007 : (has_receiver ? 1 : 0) +
143 2215007 : (has_function_name ? kFunctionNameEntries : 0) +
144 2215007 : (has_inferred_function_name ? 1 : 0) +
145 2215007 : (has_position_info ? kPositionInfoEntries : 0) +
146 2216105 : (has_outer_scope_info ? 1 : 0) +
147 : (scope->is_module_scope()
148 1098 : ? 2 + kModuleVariableEntryLength * module_vars_count
149 2215007 : : 0);
150 :
151 : Factory* factory = isolate->factory();
152 2215007 : Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length);
153 :
154 : bool has_simple_parameters = false;
155 : bool is_asm_module = false;
156 : bool calls_sloppy_eval = false;
157 2215012 : if (scope->is_function_scope()) {
158 1082838 : DeclarationScope* function_scope = scope->AsDeclarationScope();
159 : has_simple_parameters = function_scope->has_simple_parameters();
160 : is_asm_module = function_scope->is_asm_module();
161 : }
162 : FunctionKind function_kind = kNormalFunction;
163 2215014 : if (scope->is_declaration_scope()) {
164 2092614 : function_kind = scope->AsDeclarationScope()->function_kind();
165 2092615 : calls_sloppy_eval = scope->AsDeclarationScope()->calls_sloppy_eval();
166 : }
167 :
168 : // Encode the flags.
169 : int flags =
170 2215017 : ScopeTypeField::encode(scope->scope_type()) |
171 2215017 : CallsSloppyEvalField::encode(calls_sloppy_eval) |
172 2215017 : LanguageModeField::encode(scope->language_mode()) |
173 2215017 : DeclarationScopeField::encode(scope->is_declaration_scope()) |
174 2215017 : ReceiverVariableField::encode(receiver_info) |
175 2215017 : HasNewTargetField::encode(has_new_target) |
176 2215017 : FunctionVariableField::encode(function_name_info) |
177 2215017 : HasInferredFunctionNameField::encode(has_inferred_function_name) |
178 2215017 : IsAsmModuleField::encode(is_asm_module) |
179 2215017 : HasSimpleParametersField::encode(has_simple_parameters) |
180 2215017 : FunctionKindField::encode(function_kind) |
181 2215017 : HasOuterScopeInfoField::encode(has_outer_scope_info) |
182 2215017 : IsDebugEvaluateScopeField::encode(scope->is_debug_evaluate_scope()) |
183 2215017 : ForceContextAllocationField::encode(scope->ForceContextForLanguageMode());
184 : scope_info->SetFlags(flags);
185 :
186 : scope_info->SetParameterCount(parameter_count);
187 : scope_info->SetContextLocalCount(context_local_count);
188 :
189 : int index = kVariablePartIndex;
190 :
191 : // Add context locals' names and info, module variables' names and info.
192 : // Context locals are added using their index.
193 : int context_local_base = index;
194 2215022 : int context_local_info_base = context_local_base + context_local_count;
195 4430052 : int module_var_entry = scope_info->ModuleVariablesIndex();
196 :
197 18451519 : for (Variable* var : *scope->locals()) {
198 10148309 : switch (var->location()) {
199 : case VariableLocation::CONTEXT: {
200 : // Due to duplicate parameters, context locals aren't guaranteed to come
201 : // in order.
202 1909590 : int local_index = var->index() - Context::MIN_CONTEXT_SLOTS;
203 : DCHECK_LE(0, local_index);
204 : DCHECK_LT(local_index, context_local_count);
205 : uint32_t info =
206 1909590 : VariableModeField::encode(var->mode()) |
207 1909590 : InitFlagField::encode(var->initialization_flag()) |
208 : MaybeAssignedFlagField::encode(var->maybe_assigned()) |
209 1909590 : ParameterNumberField::encode(ParameterNumberField::kMax);
210 3819216 : scope_info->set(context_local_base + local_index, *var->name());
211 : scope_info->set(context_local_info_base + local_index,
212 3819216 : Smi::FromInt(info));
213 1909608 : break;
214 : }
215 : case VariableLocation::MODULE: {
216 35972 : scope_info->set(module_var_entry + kModuleVariableNameOffset,
217 53958 : *var->name());
218 : scope_info->set(module_var_entry + kModuleVariableIndexOffset,
219 : Smi::FromInt(var->index()));
220 : uint32_t properties =
221 17986 : VariableModeField::encode(var->mode()) |
222 17986 : InitFlagField::encode(var->initialization_flag()) |
223 : MaybeAssignedFlagField::encode(var->maybe_assigned()) |
224 17986 : ParameterNumberField::encode(ParameterNumberField::kMax);
225 : scope_info->set(module_var_entry + kModuleVariablePropertiesOffset,
226 17986 : Smi::FromInt(properties));
227 : module_var_entry += kModuleVariableEntryLength;
228 17986 : break;
229 : }
230 : default:
231 : break;
232 : }
233 : }
234 :
235 2215045 : if (scope->is_declaration_scope()) {
236 : // Mark contexts slots with the parameter number they represent. We walk the
237 : // list of parameters. That can include duplicate entries if a parameter
238 : // name is repeated. By walking upwards, we'll automatically mark the
239 : // context slot with the highest parameter number that uses this variable.
240 : // That will be the parameter number that is represented by the context
241 : // slot. All lower parameters will only be available on the stack through
242 : // the arguments object.
243 2335970 : for (int i = 0; i < parameter_count; i++) {
244 4712923 : Variable* parameter = scope->AsDeclarationScope()->parameter(i);
245 2335970 : if (parameter->location() != VariableLocation::CONTEXT) continue;
246 40982 : int index = parameter->index() - Context::MIN_CONTEXT_SLOTS;
247 40982 : int info_index = context_local_info_base + index;
248 40982 : int info = Smi::ToInt(scope_info->get(info_index));
249 81964 : info = ParameterNumberField::update(info, i);
250 : scope_info->set(info_index, Smi::FromInt(info));
251 : }
252 : }
253 :
254 : index += 2 * context_local_count;
255 :
256 : // If the receiver is allocated, add its index.
257 : DCHECK_EQ(index, scope_info->ReceiverInfoIndex());
258 2215044 : if (has_receiver) {
259 180339 : int var_index = scope->AsDeclarationScope()->receiver()->index();
260 180339 : scope_info->set(index++, Smi::FromInt(var_index));
261 : // ?? DCHECK(receiver_info != CONTEXT || var_index ==
262 : // scope_info->ContextLength() - 1);
263 : }
264 :
265 : // If present, add the function variable name and its index.
266 : DCHECK_EQ(index, scope_info->FunctionNameInfoIndex());
267 2215047 : if (has_function_name) {
268 : DisallowHeapAllocation no_gc;
269 2114833 : Variable* var = scope->AsDeclarationScope()->function_var();
270 : int var_index = -1;
271 2090163 : Object name = Smi::kZero;
272 2090163 : if (var != nullptr) {
273 : var_index = var->index();
274 24677 : name = *var->name();
275 : }
276 4180329 : scope_info->set(index++, name);
277 2090142 : scope_info->set(index++, Smi::FromInt(var_index));
278 : DCHECK(function_name_info != CONTEXT ||
279 : var_index == scope_info->ContextLength() - 1);
280 : }
281 :
282 : DCHECK_EQ(index, scope_info->InferredFunctionNameIndex());
283 2215032 : if (has_inferred_function_name) {
284 : // The inferred function name is taken from the SFI.
285 1082840 : index++;
286 : }
287 :
288 : DCHECK_EQ(index, scope_info->PositionInfoIndex());
289 2215032 : if (has_position_info) {
290 2090143 : scope_info->set(index++, Smi::FromInt(scope->start_position()));
291 2090146 : scope_info->set(index++, Smi::FromInt(scope->end_position()));
292 : }
293 :
294 : // If present, add the outer scope info.
295 : DCHECK(index == scope_info->OuterScopeInfoIndex());
296 2215035 : if (has_outer_scope_info) {
297 2190668 : scope_info->set(index++, *outer_scope.ToHandleChecked());
298 : }
299 :
300 : // Module-specific information (only for module scopes).
301 2215039 : if (scope->is_module_scope()) {
302 : Handle<ModuleInfo> module_info =
303 1098 : ModuleInfo::New(isolate, zone, scope->AsModuleScope()->module());
304 : DCHECK_EQ(index, scope_info->ModuleInfoIndex());
305 2196 : scope_info->set(index++, *module_info);
306 : DCHECK_EQ(index, scope_info->ModuleVariableCountIndex());
307 : scope_info->set(index++, Smi::FromInt(module_vars_count));
308 : DCHECK_EQ(index, scope_info->ModuleVariablesIndex());
309 : // The variable entries themselves have already been written above.
310 : index += kModuleVariableEntryLength * module_vars_count;
311 : }
312 :
313 : DCHECK_EQ(index, scope_info->length());
314 : DCHECK_EQ(scope->num_parameters(), scope_info->ParameterCount());
315 : DCHECK_EQ(scope->num_heap_slots(), scope_info->ContextLength());
316 2215039 : return scope_info;
317 : }
318 :
319 : // static
320 12424 : Handle<ScopeInfo> ScopeInfo::CreateForWithScope(
321 : Isolate* isolate, MaybeHandle<ScopeInfo> outer_scope) {
322 12424 : const bool has_outer_scope_info = !outer_scope.is_null();
323 12424 : const int length = kVariablePartIndex + (has_outer_scope_info ? 1 : 0);
324 :
325 : Factory* factory = isolate->factory();
326 12424 : Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length);
327 :
328 : // Encode the flags.
329 : int flags =
330 : ScopeTypeField::encode(WITH_SCOPE) | CallsSloppyEvalField::encode(false) |
331 : LanguageModeField::encode(LanguageMode::kSloppy) |
332 : DeclarationScopeField::encode(false) |
333 : ReceiverVariableField::encode(NONE) | HasNewTargetField::encode(false) |
334 : FunctionVariableField::encode(NONE) | IsAsmModuleField::encode(false) |
335 : HasSimpleParametersField::encode(true) |
336 12424 : FunctionKindField::encode(kNormalFunction) |
337 : HasOuterScopeInfoField::encode(has_outer_scope_info) |
338 12424 : IsDebugEvaluateScopeField::encode(false);
339 : scope_info->SetFlags(flags);
340 :
341 : scope_info->SetParameterCount(0);
342 : scope_info->SetContextLocalCount(0);
343 :
344 : int index = kVariablePartIndex;
345 : DCHECK_EQ(index, scope_info->ReceiverInfoIndex());
346 : DCHECK_EQ(index, scope_info->FunctionNameInfoIndex());
347 : DCHECK_EQ(index, scope_info->InferredFunctionNameIndex());
348 : DCHECK_EQ(index, scope_info->PositionInfoIndex());
349 : DCHECK(index == scope_info->OuterScopeInfoIndex());
350 12424 : if (has_outer_scope_info) {
351 4708 : scope_info->set(index++, *outer_scope.ToHandleChecked());
352 : }
353 : DCHECK_EQ(index, scope_info->length());
354 : DCHECK_EQ(0, scope_info->ParameterCount());
355 : DCHECK_EQ(Context::MIN_CONTEXT_SLOTS, scope_info->ContextLength());
356 12424 : return scope_info;
357 : }
358 :
359 : // static
360 111 : Handle<ScopeInfo> ScopeInfo::CreateGlobalThisBinding(Isolate* isolate) {
361 111 : return CreateForBootstrapping(isolate, SCRIPT_SCOPE);
362 : }
363 :
364 : // static
365 113 : Handle<ScopeInfo> ScopeInfo::CreateForEmptyFunction(Isolate* isolate) {
366 113 : return CreateForBootstrapping(isolate, FUNCTION_SCOPE);
367 : }
368 :
369 : // static
370 224 : Handle<ScopeInfo> ScopeInfo::CreateForBootstrapping(Isolate* isolate,
371 : ScopeType type) {
372 : DCHECK(type == SCRIPT_SCOPE || type == FUNCTION_SCOPE);
373 :
374 : const int parameter_count = 0;
375 224 : const bool is_empty_function = type == FUNCTION_SCOPE;
376 224 : const int context_local_count = is_empty_function ? 0 : 1;
377 : const bool has_receiver = !is_empty_function;
378 : const bool has_inferred_function_name = is_empty_function;
379 : const bool has_position_info = true;
380 224 : const int length = kVariablePartIndex + 2 * context_local_count +
381 224 : (has_receiver ? 1 : 0) +
382 224 : (is_empty_function ? kFunctionNameEntries : 0) +
383 : (has_inferred_function_name ? 1 : 0) +
384 224 : (has_position_info ? kPositionInfoEntries : 0);
385 :
386 : Factory* factory = isolate->factory();
387 224 : Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length);
388 :
389 : // Encode the flags.
390 : int flags =
391 : ScopeTypeField::encode(type) | CallsSloppyEvalField::encode(false) |
392 224 : LanguageModeField::encode(LanguageMode::kSloppy) |
393 224 : DeclarationScopeField::encode(true) |
394 224 : ReceiverVariableField::encode(is_empty_function ? UNUSED : CONTEXT) |
395 224 : HasNewTargetField::encode(false) |
396 448 : FunctionVariableField::encode(is_empty_function ? UNUSED : NONE) |
397 : HasInferredFunctionNameField::encode(has_inferred_function_name) |
398 224 : IsAsmModuleField::encode(false) | HasSimpleParametersField::encode(true) |
399 : FunctionKindField::encode(FunctionKind::kNormalFunction) |
400 : HasOuterScopeInfoField::encode(false) |
401 224 : IsDebugEvaluateScopeField::encode(false);
402 : scope_info->SetFlags(flags);
403 : scope_info->SetParameterCount(parameter_count);
404 : scope_info->SetContextLocalCount(context_local_count);
405 :
406 : int index = kVariablePartIndex;
407 :
408 : // Here we add info for context-allocated "this".
409 : DCHECK_EQ(index, scope_info->ContextLocalNamesIndex());
410 224 : if (context_local_count) {
411 222 : scope_info->set(index++, ReadOnlyRoots(isolate).this_string());
412 : }
413 : DCHECK_EQ(index, scope_info->ContextLocalInfosIndex());
414 224 : if (context_local_count) {
415 : const uint32_t value =
416 : VariableModeField::encode(VariableMode::kConst) |
417 : InitFlagField::encode(kCreatedInitialized) |
418 : MaybeAssignedFlagField::encode(kNotAssigned) |
419 : ParameterNumberField::encode(ParameterNumberField::kMax);
420 111 : scope_info->set(index++, Smi::FromInt(value));
421 : }
422 :
423 : // And here we record that this scopeinfo binds a receiver.
424 : DCHECK_EQ(index, scope_info->ReceiverInfoIndex());
425 : const int receiver_index = Context::MIN_CONTEXT_SLOTS + 0;
426 224 : if (!is_empty_function) {
427 111 : scope_info->set(index++, Smi::FromInt(receiver_index));
428 : }
429 :
430 : DCHECK_EQ(index, scope_info->FunctionNameInfoIndex());
431 224 : if (is_empty_function) {
432 226 : scope_info->set(index++, *isolate->factory()->empty_string());
433 226 : scope_info->set(index++, Smi::kZero);
434 : }
435 : DCHECK_EQ(index, scope_info->InferredFunctionNameIndex());
436 224 : if (has_inferred_function_name) {
437 226 : scope_info->set(index++, *isolate->factory()->empty_string());
438 : }
439 : DCHECK_EQ(index, scope_info->PositionInfoIndex());
440 : // Store dummy position to be in sync with the {scope_type}.
441 448 : scope_info->set(index++, Smi::kZero);
442 224 : scope_info->set(index++, Smi::kZero);
443 : DCHECK_EQ(index, scope_info->OuterScopeInfoIndex());
444 : DCHECK_EQ(index, scope_info->length());
445 : DCHECK_EQ(scope_info->ParameterCount(), parameter_count);
446 : if (type == FUNCTION_SCOPE) {
447 : DCHECK_EQ(scope_info->ContextLength(), 0);
448 : } else {
449 : DCHECK_EQ(scope_info->ContextLength(), Context::MIN_CONTEXT_SLOTS + 1);
450 : }
451 :
452 224 : return scope_info;
453 : }
454 :
455 4099293 : ScopeInfo ScopeInfo::Empty(Isolate* isolate) {
456 4099292 : return ReadOnlyRoots(isolate).empty_scope_info();
457 : }
458 :
459 4517590 : ScopeType ScopeInfo::scope_type() const {
460 : DCHECK_LT(0, length());
461 18471552 : return ScopeTypeField::decode(Flags());
462 : }
463 :
464 1089038 : bool ScopeInfo::CallsSloppyEval() const {
465 : bool calls_sloppy_eval =
466 2178086 : length() > 0 && CallsSloppyEvalField::decode(Flags());
467 : DCHECK_IMPLIES(calls_sloppy_eval, is_sloppy(language_mode()));
468 : DCHECK_IMPLIES(calls_sloppy_eval, is_declaration_scope());
469 1089043 : return calls_sloppy_eval;
470 : }
471 :
472 5036108 : LanguageMode ScopeInfo::language_mode() const {
473 5036125 : return length() > 0 ? LanguageModeField::decode(Flags())
474 10072245 : : LanguageMode::kSloppy;
475 : }
476 :
477 182122 : bool ScopeInfo::is_declaration_scope() const {
478 369053 : return DeclarationScopeField::decode(Flags());
479 : }
480 :
481 1315539 : int ScopeInfo::ContextLength() const {
482 1315540 : if (length() > 0) {
483 1315543 : int context_locals = ContextLocalCount();
484 : bool function_name_context_slot =
485 2631092 : FunctionVariableField::decode(Flags()) == CONTEXT;
486 1315545 : bool force_context = ForceContextAllocationField::decode(Flags());
487 1337360 : bool has_context = context_locals > 0 || force_context ||
488 21700 : function_name_context_slot ||
489 6482 : scope_type() == WITH_SCOPE ||
490 9602 : (scope_type() == BLOCK_SCOPE && CallsSloppyEval() &&
491 1681 : is_declaration_scope()) ||
492 2404 : (scope_type() == FUNCTION_SCOPE && CallsSloppyEval()) ||
493 1316409 : (scope_type() == FUNCTION_SCOPE && IsAsmModule()) ||
494 : scope_type() == MODULE_SCOPE;
495 :
496 1315537 : if (has_context) {
497 1315396 : return Context::MIN_CONTEXT_SLOTS + context_locals +
498 1315396 : (function_name_context_slot ? 1 : 0);
499 : }
500 : }
501 : return 0;
502 : }
503 :
504 0 : bool ScopeInfo::HasReceiver() const {
505 0 : if (length() == 0) return false;
506 0 : return NONE != ReceiverVariableField::decode(Flags());
507 : }
508 :
509 18490924 : bool ScopeInfo::HasAllocatedReceiver() const {
510 18490938 : if (length() == 0) return false;
511 18490963 : VariableAllocationInfo allocation = ReceiverVariableField::decode(Flags());
512 18490966 : return allocation == STACK || allocation == CONTEXT;
513 : }
514 :
515 0 : bool ScopeInfo::HasNewTarget() const {
516 0 : return HasNewTargetField::decode(Flags());
517 : }
518 :
519 13210047 : bool ScopeInfo::HasFunctionName() const {
520 13210047 : if (length() == 0) return false;
521 26417743 : return NONE != FunctionVariableField::decode(Flags());
522 : }
523 :
524 10836896 : bool ScopeInfo::HasInferredFunctionName() const {
525 10836899 : if (length() == 0) return false;
526 21673812 : return HasInferredFunctionNameField::decode(Flags());
527 : }
528 :
529 12969946 : bool ScopeInfo::HasPositionInfo() const {
530 12969942 : if (length() == 0) return false;
531 9405605 : return NeedsPositionInfo(scope_type());
532 : }
533 :
534 : // static
535 0 : bool ScopeInfo::NeedsPositionInfo(ScopeType type) {
536 14632591 : return type == FUNCTION_SCOPE || type == SCRIPT_SCOPE || type == EVAL_SCOPE ||
537 3011985 : type == MODULE_SCOPE;
538 : }
539 :
540 3162963 : bool ScopeInfo::HasSharedFunctionName() const {
541 6325928 : return FunctionName() != SharedFunctionInfo::kNoSharedNameSentinel;
542 : }
543 :
544 2089483 : void ScopeInfo::SetFunctionName(Object name) {
545 : DCHECK(HasFunctionName());
546 : DCHECK(name->IsString() || name == SharedFunctionInfo::kNoSharedNameSentinel);
547 2089483 : set(FunctionNameInfoIndex(), name);
548 2089484 : }
549 :
550 53050 : void ScopeInfo::SetInferredFunctionName(String name) {
551 : DCHECK(HasInferredFunctionName());
552 53050 : set(InferredFunctionNameIndex(), name);
553 53050 : }
554 :
555 3405238 : bool ScopeInfo::HasOuterScopeInfo() const {
556 3405250 : if (length() == 0) return false;
557 6810514 : return HasOuterScopeInfoField::decode(Flags());
558 : }
559 :
560 14727 : bool ScopeInfo::IsDebugEvaluateScope() const {
561 14727 : if (length() == 0) return false;
562 29454 : return IsDebugEvaluateScopeField::decode(Flags());
563 : }
564 :
565 12400 : void ScopeInfo::SetIsDebugEvaluateScope() {
566 12400 : if (length() > 0) {
567 : DCHECK_EQ(scope_type(), WITH_SCOPE);
568 12400 : SetFlags(Flags() | IsDebugEvaluateScopeField::encode(true));
569 : } else {
570 0 : UNREACHABLE();
571 : }
572 12400 : }
573 :
574 0 : bool ScopeInfo::HasContext() const { return ContextLength() > 0; }
575 :
576 6284888 : Object ScopeInfo::FunctionName() const {
577 : DCHECK(HasFunctionName());
578 12569779 : return get(FunctionNameInfoIndex());
579 : }
580 :
581 619314 : Object ScopeInfo::InferredFunctionName() const {
582 : DCHECK(HasInferredFunctionName());
583 1238628 : return get(InferredFunctionNameIndex());
584 : }
585 :
586 18191 : String ScopeInfo::FunctionDebugName() const {
587 18191 : Object name = FunctionName();
588 36382 : if (name->IsString() && String::cast(name)->length() > 0) {
589 : return String::cast(name);
590 : }
591 9765 : if (HasInferredFunctionName()) {
592 1884 : name = InferredFunctionName();
593 1884 : if (name->IsString()) return String::cast(name);
594 : }
595 18676 : return GetReadOnlyRoots().empty_string();
596 : }
597 :
598 6286722 : int ScopeInfo::StartPosition() const {
599 : DCHECK(HasPositionInfo());
600 12573448 : return Smi::ToInt(get(PositionInfoIndex()));
601 : }
602 :
603 483135 : int ScopeInfo::EndPosition() const {
604 : DCHECK(HasPositionInfo());
605 966270 : return Smi::ToInt(get(PositionInfoIndex() + 1));
606 : }
607 :
608 1067 : void ScopeInfo::SetPositionInfo(int start, int end) {
609 : DCHECK(HasPositionInfo());
610 : DCHECK_LE(start, end);
611 1067 : set(PositionInfoIndex(), Smi::FromInt(start));
612 1067 : set(PositionInfoIndex() + 1, Smi::FromInt(end));
613 1067 : }
614 :
615 435447 : ScopeInfo ScopeInfo::OuterScopeInfo() const {
616 : DCHECK(HasOuterScopeInfo());
617 870904 : return ScopeInfo::cast(get(OuterScopeInfoIndex()));
618 : }
619 :
620 12928 : ModuleInfo ScopeInfo::ModuleDescriptorInfo() const {
621 : DCHECK(scope_type() == MODULE_SCOPE);
622 25856 : return ModuleInfo::cast(get(ModuleInfoIndex()));
623 : }
624 :
625 1587302 : String ScopeInfo::ContextLocalName(int var) const {
626 : DCHECK_LE(0, var);
627 : DCHECK_LT(var, ContextLocalCount());
628 1587302 : int info_index = ContextLocalNamesIndex() + var;
629 1587302 : return String::cast(get(info_index));
630 : }
631 :
632 3058891 : VariableMode ScopeInfo::ContextLocalMode(int var) const {
633 : DCHECK_LE(0, var);
634 : DCHECK_LT(var, ContextLocalCount());
635 3058894 : int info_index = ContextLocalInfosIndex() + var;
636 3058894 : int value = Smi::ToInt(get(info_index));
637 3058897 : return VariableModeField::decode(value);
638 : }
639 :
640 2177595 : InitializationFlag ScopeInfo::ContextLocalInitFlag(int var) const {
641 : DCHECK_LE(0, var);
642 : DCHECK_LT(var, ContextLocalCount());
643 2177598 : int info_index = ContextLocalInfosIndex() + var;
644 2177598 : int value = Smi::ToInt(get(info_index));
645 4355196 : return InitFlagField::decode(value);
646 : }
647 :
648 129 : bool ScopeInfo::ContextLocalIsParameter(int var) const {
649 : DCHECK_LE(0, var);
650 : DCHECK_LT(var, ContextLocalCount());
651 129 : int info_index = ContextLocalInfosIndex() + var;
652 129 : int value = Smi::ToInt(get(info_index));
653 258 : return ParameterNumberField::decode(value) != ParameterNumberField::kMax;
654 : }
655 :
656 129 : uint32_t ScopeInfo::ContextLocalParameterNumber(int var) const {
657 : DCHECK(ContextLocalIsParameter(var));
658 129 : int info_index = ContextLocalInfosIndex() + var;
659 129 : int value = Smi::ToInt(get(info_index));
660 258 : return ParameterNumberField::decode(value);
661 : }
662 :
663 2179444 : MaybeAssignedFlag ScopeInfo::ContextLocalMaybeAssignedFlag(int var) const {
664 : DCHECK_LE(0, var);
665 : DCHECK_LT(var, ContextLocalCount());
666 2179446 : int info_index = ContextLocalInfosIndex() + var;
667 2179446 : int value = Smi::ToInt(get(info_index));
668 4358892 : return MaybeAssignedFlagField::decode(value);
669 : }
670 :
671 : // static
672 7189530 : bool ScopeInfo::VariableIsSynthetic(String name) {
673 : // There's currently no flag stored on the ScopeInfo to indicate that a
674 : // variable is a compiler-introduced temporary. However, to avoid conflict
675 : // with user declarations, the current temporaries like .generator_object and
676 : // .result start with a dot, so we can use that as a flag. It's a hack!
677 21443035 : return name->length() == 0 || name->Get(0) == '.' ||
678 21322242 : name->Equals(name->GetReadOnlyRoots().this_string());
679 : }
680 :
681 2282 : int ScopeInfo::ModuleIndex(Handle<String> name, VariableMode* mode,
682 : InitializationFlag* init_flag,
683 : MaybeAssignedFlag* maybe_assigned_flag) {
684 : DCHECK(name->IsInternalizedString());
685 : DCHECK_EQ(scope_type(), MODULE_SCOPE);
686 : DCHECK_NOT_NULL(mode);
687 : DCHECK_NOT_NULL(init_flag);
688 : DCHECK_NOT_NULL(maybe_assigned_flag);
689 :
690 2282 : int module_vars_count = Smi::ToInt(get(ModuleVariableCountIndex()));
691 : int entry = ModuleVariablesIndex();
692 6559 : for (int i = 0; i < module_vars_count; ++i) {
693 4951 : String var_name = String::cast(get(entry + kModuleVariableNameOffset));
694 4951 : if (name->Equals(var_name)) {
695 : int index;
696 674 : ModuleVariable(i, nullptr, &index, mode, init_flag, maybe_assigned_flag);
697 674 : return index;
698 : }
699 4277 : entry += kModuleVariableEntryLength;
700 : }
701 :
702 : return 0;
703 : }
704 :
705 : // static
706 20066430 : int ScopeInfo::ContextSlotIndex(Handle<ScopeInfo> scope_info,
707 : Handle<String> name, VariableMode* mode,
708 : InitializationFlag* init_flag,
709 : MaybeAssignedFlag* maybe_assigned_flag) {
710 : DCHECK(name->IsInternalizedString());
711 : DCHECK_NOT_NULL(mode);
712 : DCHECK_NOT_NULL(init_flag);
713 : DCHECK_NOT_NULL(maybe_assigned_flag);
714 :
715 20066447 : if (scope_info->length() == 0) return -1;
716 :
717 : int start = scope_info->ContextLocalNamesIndex();
718 20066448 : int end = start + scope_info->ContextLocalCount();
719 134146100 : for (int i = start; i < end; ++i) {
720 116257242 : if (*name == scope_info->get(i)) {
721 2177594 : int var = i - start;
722 2177595 : *mode = scope_info->ContextLocalMode(var);
723 2177596 : *init_flag = scope_info->ContextLocalInitFlag(var);
724 2177598 : *maybe_assigned_flag = scope_info->ContextLocalMaybeAssignedFlag(var);
725 2177594 : int result = Context::MIN_CONTEXT_SLOTS + var;
726 :
727 : DCHECK_LT(result, scope_info->ContextLength());
728 2177594 : return result;
729 : }
730 : }
731 :
732 : return -1;
733 : }
734 :
735 394497 : int ScopeInfo::ReceiverContextSlotIndex() const {
736 788996 : if (length() > 0 && ReceiverVariableField::decode(Flags()) == CONTEXT) {
737 259522 : return Smi::ToInt(get(ReceiverInfoIndex()));
738 : }
739 : return -1;
740 : }
741 :
742 3941758 : int ScopeInfo::FunctionContextSlotIndex(String name) const {
743 : DCHECK(name->IsInternalizedString());
744 3941761 : if (length() > 0) {
745 15767061 : if (FunctionVariableField::decode(Flags()) == CONTEXT &&
746 3962453 : FunctionName() == name) {
747 2404 : return Smi::ToInt(get(FunctionNameInfoIndex() + 1));
748 : }
749 : }
750 : return -1;
751 : }
752 :
753 873450 : FunctionKind ScopeInfo::function_kind() const {
754 1746901 : return FunctionKindField::decode(Flags());
755 : }
756 :
757 0 : int ScopeInfo::ContextLocalNamesIndex() const {
758 : DCHECK_LT(0, length());
759 0 : return kVariablePartIndex;
760 : }
761 :
762 0 : int ScopeInfo::ContextLocalInfosIndex() const {
763 26036864 : return ContextLocalNamesIndex() + ContextLocalCount();
764 : }
765 :
766 18620676 : int ScopeInfo::ReceiverInfoIndex() const {
767 18620685 : return ContextLocalInfosIndex() + ContextLocalCount();
768 : }
769 :
770 18490914 : int ScopeInfo::FunctionNameInfoIndex() const {
771 18490914 : return ReceiverInfoIndex() + (HasAllocatedReceiver() ? 1 : 0);
772 : }
773 :
774 10115344 : int ScopeInfo::InferredFunctionNameIndex() const {
775 20230734 : return FunctionNameInfoIndex() +
776 20230773 : (HasFunctionName() ? kFunctionNameEntries : 0);
777 : }
778 :
779 9442975 : int ScopeInfo::PositionInfoIndex() const {
780 9442975 : return InferredFunctionNameIndex() + (HasInferredFunctionName() ? 1 : 0);
781 : }
782 :
783 2670989 : int ScopeInfo::OuterScopeInfoIndex() const {
784 2670989 : return PositionInfoIndex() + (HasPositionInfo() ? kPositionInfoEntries : 0);
785 : }
786 :
787 2235539 : int ScopeInfo::ModuleInfoIndex() const {
788 2235539 : return OuterScopeInfoIndex() + (HasOuterScopeInfo() ? 1 : 0);
789 : }
790 :
791 753 : int ScopeInfo::ModuleVariableCountIndex() const {
792 2222621 : return ModuleInfoIndex() + 1;
793 : }
794 :
795 0 : int ScopeInfo::ModuleVariablesIndex() const {
796 2219588 : return ModuleVariableCountIndex() + 1;
797 : }
798 :
799 2279 : void ScopeInfo::ModuleVariable(int i, String* name, int* index,
800 : VariableMode* mode,
801 : InitializationFlag* init_flag,
802 : MaybeAssignedFlag* maybe_assigned_flag) {
803 : DCHECK_LE(0, i);
804 : DCHECK_LT(i, Smi::ToInt(get(ModuleVariableCountIndex())));
805 :
806 2279 : int entry = ModuleVariablesIndex() + i * kModuleVariableEntryLength;
807 4558 : int properties = Smi::ToInt(get(entry + kModuleVariablePropertiesOffset));
808 :
809 2279 : if (name != nullptr) {
810 1605 : *name = String::cast(get(entry + kModuleVariableNameOffset));
811 : }
812 2279 : if (index != nullptr) {
813 4558 : *index = Smi::ToInt(get(entry + kModuleVariableIndexOffset));
814 : DCHECK_NE(*index, 0);
815 : }
816 2279 : if (mode != nullptr) {
817 674 : *mode = VariableModeField::decode(properties);
818 : }
819 2279 : if (init_flag != nullptr) {
820 1348 : *init_flag = InitFlagField::decode(properties);
821 : }
822 2279 : if (maybe_assigned_flag != nullptr) {
823 1348 : *maybe_assigned_flag = MaybeAssignedFlagField::decode(properties);
824 : }
825 2279 : }
826 :
827 0 : std::ostream& operator<<(std::ostream& os,
828 : ScopeInfo::VariableAllocationInfo var_info) {
829 0 : switch (var_info) {
830 : case ScopeInfo::VariableAllocationInfo::NONE:
831 0 : return os << "NONE";
832 : case ScopeInfo::VariableAllocationInfo::STACK:
833 0 : return os << "STACK";
834 : case ScopeInfo::VariableAllocationInfo::CONTEXT:
835 0 : return os << "CONTEXT";
836 : case ScopeInfo::VariableAllocationInfo::UNUSED:
837 0 : return os << "UNUSED";
838 : }
839 0 : UNREACHABLE();
840 : return os;
841 : }
842 :
843 723 : Handle<ModuleInfoEntry> ModuleInfoEntry::New(Isolate* isolate,
844 : Handle<Object> export_name,
845 : Handle<Object> local_name,
846 : Handle<Object> import_name,
847 : int module_request, int cell_index,
848 : int beg_pos, int end_pos) {
849 : Handle<ModuleInfoEntry> result = Handle<ModuleInfoEntry>::cast(
850 723 : isolate->factory()->NewStruct(MODULE_INFO_ENTRY_TYPE, TENURED));
851 723 : result->set_export_name(*export_name);
852 723 : result->set_local_name(*local_name);
853 723 : result->set_import_name(*import_name);
854 : result->set_module_request(module_request);
855 : result->set_cell_index(cell_index);
856 : result->set_beg_pos(beg_pos);
857 : result->set_end_pos(end_pos);
858 723 : return result;
859 : }
860 :
861 1098 : Handle<ModuleInfo> ModuleInfo::New(Isolate* isolate, Zone* zone,
862 : ModuleDescriptor* descr) {
863 : // Serialize module requests.
864 1098 : int size = static_cast<int>(descr->module_requests().size());
865 1098 : Handle<FixedArray> module_requests = isolate->factory()->NewFixedArray(size);
866 : Handle<FixedArray> module_request_positions =
867 1098 : isolate->factory()->NewFixedArray(size);
868 2810 : for (const auto& elem : descr->module_requests()) {
869 1842 : module_requests->set(elem.second.index, *elem.first->string());
870 : module_request_positions->set(elem.second.index,
871 1228 : Smi::FromInt(elem.second.position));
872 : }
873 :
874 : // Serialize special exports.
875 : Handle<FixedArray> special_exports = isolate->factory()->NewFixedArray(
876 2196 : static_cast<int>(descr->special_exports().size()));
877 : {
878 : int i = 0;
879 2351 : for (auto entry : descr->special_exports()) {
880 155 : Handle<ModuleInfoEntry> serialized_entry = entry->Serialize(isolate);
881 310 : special_exports->set(i++, *serialized_entry);
882 : }
883 : }
884 :
885 : // Serialize namespace imports.
886 : Handle<FixedArray> namespace_imports = isolate->factory()->NewFixedArray(
887 2196 : static_cast<int>(descr->namespace_imports().size()));
888 : {
889 : int i = 0;
890 2326 : for (auto entry : descr->namespace_imports()) {
891 130 : Handle<ModuleInfoEntry> serialized_entry = entry->Serialize(isolate);
892 260 : namespace_imports->set(i++, *serialized_entry);
893 : }
894 : }
895 :
896 : // Serialize regular exports.
897 : Handle<FixedArray> regular_exports =
898 1098 : descr->SerializeRegularExports(isolate, zone);
899 :
900 : // Serialize regular imports.
901 : Handle<FixedArray> regular_imports = isolate->factory()->NewFixedArray(
902 1098 : static_cast<int>(descr->regular_imports().size()));
903 : {
904 : int i = 0;
905 2634 : for (const auto& elem : descr->regular_imports()) {
906 : Handle<ModuleInfoEntry> serialized_entry =
907 438 : elem.second->Serialize(isolate);
908 876 : regular_imports->set(i++, *serialized_entry);
909 : }
910 : }
911 :
912 1098 : Handle<ModuleInfo> result = isolate->factory()->NewModuleInfo();
913 2196 : result->set(kModuleRequestsIndex, *module_requests);
914 2196 : result->set(kSpecialExportsIndex, *special_exports);
915 2196 : result->set(kRegularExportsIndex, *regular_exports);
916 2196 : result->set(kNamespaceImportsIndex, *namespace_imports);
917 2196 : result->set(kRegularImportsIndex, *regular_imports);
918 2196 : result->set(kModuleRequestPositionsIndex, *module_request_positions);
919 1098 : return result;
920 : }
921 :
922 8176 : int ModuleInfo::RegularExportCount() const {
923 : DCHECK_EQ(regular_exports()->length() % kRegularExportLength, 0);
924 16352 : return regular_exports()->length() / kRegularExportLength;
925 : }
926 :
927 3754 : String ModuleInfo::RegularExportLocalName(int i) const {
928 : return String::cast(regular_exports()->get(i * kRegularExportLength +
929 7508 : kRegularExportLocalNameOffset));
930 : }
931 :
932 35083 : int ModuleInfo::RegularExportCellIndex(int i) const {
933 35083 : return Smi::ToInt(regular_exports()->get(i * kRegularExportLength +
934 70166 : kRegularExportCellIndexOffset));
935 : }
936 :
937 35083 : FixedArray ModuleInfo::RegularExportExportNames(int i) const {
938 : return FixedArray::cast(regular_exports()->get(
939 70166 : i * kRegularExportLength + kRegularExportExportNamesOffset));
940 : }
941 :
942 : } // namespace internal
943 183867 : } // namespace v8
|