7 #include "src/objects/scope-info.h" 9 #include "src/ast/scopes.h" 10 #include "src/ast/variables.h" 11 #include "src/bootstrapper.h" 13 #include "src/objects-inl.h" 14 #include "src/objects/module-inl.h" 20 enum ModuleVariableEntryOffset {
21 kModuleVariableNameOffset,
22 kModuleVariableIndexOffset,
23 kModuleVariablePropertiesOffset,
24 kModuleVariableEntryLength
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);
34 if (entry != other_entry)
return false;
36 if (HeapObject::cast(entry)->map()->instance_type() !=
37 HeapObject::cast(other_entry)->map()->instance_type()) {
40 if (entry->IsString()) {
41 if (!String::cast(entry)->Equals(String::cast(other_entry))) {
44 }
else if (entry->IsScopeInfo()) {
45 if (!ScopeInfo::cast(entry)->Equals(ScopeInfo::cast(other_entry))) {
48 }
else if (entry->IsModuleInfo()) {
49 if (!ModuleInfo::cast(entry)->Equals(ModuleInfo::cast(other_entry))) {
62 Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, Scope* scope,
63 MaybeHandle<ScopeInfo> outer_scope) {
65 int context_local_count = 0;
66 int module_vars_count = 0;
71 for (Variable* var : *scope->locals()) {
72 switch (var->location()) {
73 case VariableLocation::CONTEXT:
74 context_local_count++;
76 case VariableLocation::MODULE:
83 DCHECK(module_vars_count == 0 || scope->is_module_scope());
86 DCHECK_EQ(scope->ContextLocalCount(), context_local_count);
89 VariableAllocationInfo receiver_info;
90 if (scope->is_declaration_scope() &&
91 scope->AsDeclarationScope()->has_this_declaration()) {
92 Variable* var = scope->AsDeclarationScope()->receiver();
93 if (!var->is_used()) {
94 receiver_info = UNUSED;
95 }
else if (var->IsContextSlot()) {
96 receiver_info = CONTEXT;
98 DCHECK(var->IsParameter());
99 receiver_info = STACK;
102 receiver_info = NONE;
105 const bool has_new_target =
106 scope->is_declaration_scope() &&
107 scope->AsDeclarationScope()->new_target_var() !=
nullptr;
109 const bool has_inferred_function_name = scope->is_function_scope();
112 VariableAllocationInfo function_name_info;
113 if (scope->is_function_scope()) {
114 if (scope->AsDeclarationScope()->function_var() !=
nullptr) {
115 Variable* var = scope->AsDeclarationScope()->function_var();
116 if (!var->is_used()) {
117 function_name_info = UNUSED;
118 }
else if (var->IsContextSlot()) {
119 function_name_info = CONTEXT;
121 DCHECK(var->IsStackLocal());
122 function_name_info = STACK;
126 function_name_info = UNUSED;
128 }
else if (scope->is_module_scope() || scope->is_script_scope() ||
129 scope->is_eval_scope()) {
131 function_name_info = UNUSED;
133 function_name_info = NONE;
136 const bool has_function_name = function_name_info != NONE;
137 const bool has_position_info = NeedsPositionInfo(scope->scope_type());
138 const bool has_receiver = receiver_info == STACK || receiver_info == CONTEXT;
139 const int parameter_count = scope->num_parameters();
140 const bool has_outer_scope_info = !outer_scope.is_null();
141 const int length = kVariablePartIndex + 2 * context_local_count +
142 (has_receiver ? 1 : 0) +
143 (has_function_name ? kFunctionNameEntries : 0) +
144 (has_inferred_function_name ? 1 : 0) +
145 (has_position_info ? kPositionInfoEntries : 0) +
146 (has_outer_scope_info ? 1 : 0) +
147 (scope->is_module_scope()
148 ? 2 + kModuleVariableEntryLength * module_vars_count
151 Factory* factory = isolate->factory();
152 Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length);
154 bool has_simple_parameters =
false;
155 bool asm_module =
false;
156 bool calls_sloppy_eval =
false;
157 if (scope->is_function_scope()) {
158 DeclarationScope* function_scope = scope->AsDeclarationScope();
159 has_simple_parameters = function_scope->has_simple_parameters();
160 asm_module = function_scope->asm_module();
162 FunctionKind function_kind = kNormalFunction;
163 if (scope->is_declaration_scope()) {
164 function_kind = scope->AsDeclarationScope()->function_kind();
165 calls_sloppy_eval = scope->AsDeclarationScope()->calls_sloppy_eval();
170 ScopeTypeField::encode(scope->scope_type()) |
171 CallsSloppyEvalField::encode(calls_sloppy_eval) |
172 LanguageModeField::encode(scope->language_mode()) |
173 DeclarationScopeField::encode(scope->is_declaration_scope()) |
174 ReceiverVariableField::encode(receiver_info) |
175 HasNewTargetField::encode(has_new_target) |
176 FunctionVariableField::encode(function_name_info) |
177 HasInferredFunctionNameField::encode(has_inferred_function_name) |
178 AsmModuleField::encode(asm_module) |
179 HasSimpleParametersField::encode(has_simple_parameters) |
180 FunctionKindField::encode(function_kind) |
181 HasOuterScopeInfoField::encode(has_outer_scope_info) |
182 IsDebugEvaluateScopeField::encode(scope->is_debug_evaluate_scope());
183 scope_info->SetFlags(flags);
185 scope_info->SetParameterCount(parameter_count);
186 scope_info->SetContextLocalCount(context_local_count);
188 int index = kVariablePartIndex;
192 int context_local_base = index;
193 int context_local_info_base = context_local_base + context_local_count;
194 int module_var_entry = scope_info->ModuleVariablesIndex();
196 for (Variable* var : *scope->locals()) {
197 switch (var->location()) {
198 case VariableLocation::CONTEXT: {
201 int local_index = var->index() - Context::MIN_CONTEXT_SLOTS;
202 DCHECK_LE(0, local_index);
203 DCHECK_LT(local_index, context_local_count);
205 VariableModeField::encode(var->mode()) |
206 InitFlagField::encode(var->initialization_flag()) |
207 MaybeAssignedFlagField::encode(var->maybe_assigned()) |
208 ParameterNumberField::encode(ParameterNumberField::kMax);
209 scope_info->set(context_local_base + local_index, *var->name());
210 scope_info->set(context_local_info_base + local_index,
214 case VariableLocation::MODULE: {
215 scope_info->set(module_var_entry + kModuleVariableNameOffset,
217 scope_info->set(module_var_entry + kModuleVariableIndexOffset,
218 Smi::FromInt(var->index()));
220 VariableModeField::encode(var->mode()) |
221 InitFlagField::encode(var->initialization_flag()) |
222 MaybeAssignedFlagField::encode(var->maybe_assigned()) |
223 ParameterNumberField::encode(ParameterNumberField::kMax);
224 scope_info->set(module_var_entry + kModuleVariablePropertiesOffset,
225 Smi::FromInt(properties));
226 module_var_entry += kModuleVariableEntryLength;
234 if (scope->is_declaration_scope()) {
242 for (
int i = 0;
i < parameter_count;
i++) {
243 Variable* parameter = scope->AsDeclarationScope()->parameter(
i);
244 if (parameter->location() != VariableLocation::CONTEXT)
continue;
245 int index = parameter->index() - Context::MIN_CONTEXT_SLOTS;
246 int info_index = context_local_info_base + index;
247 int info = Smi::ToInt(scope_info->get(info_index));
248 info = ParameterNumberField::update(info,
i);
249 scope_info->set(info_index, Smi::FromInt(info));
253 index += 2 * context_local_count;
256 DCHECK_EQ(index, scope_info->ReceiverInfoIndex());
258 int var_index = scope->AsDeclarationScope()->receiver()->index();
259 scope_info->set(index++, Smi::FromInt(var_index));
265 DCHECK_EQ(index, scope_info->FunctionNameInfoIndex());
266 if (has_function_name) {
267 DisallowHeapAllocation no_gc;
268 Variable* var = scope->AsDeclarationScope()->function_var();
270 Object* name = Smi::kZero;
271 if (var !=
nullptr) {
272 var_index = var->index();
275 scope_info->set(index++, name);
276 scope_info->set(index++, Smi::FromInt(var_index));
277 DCHECK(function_name_info != CONTEXT ||
278 var_index == scope_info->ContextLength() - 1);
281 DCHECK_EQ(index, scope_info->InferredFunctionNameIndex());
282 if (has_inferred_function_name) {
287 DCHECK_EQ(index, scope_info->PositionInfoIndex());
288 if (has_position_info) {
289 scope_info->set(index++, Smi::FromInt(scope->start_position()));
290 scope_info->set(index++, Smi::FromInt(scope->end_position()));
294 DCHECK(index == scope_info->OuterScopeInfoIndex());
295 if (has_outer_scope_info) {
296 scope_info->set(index++, *outer_scope.ToHandleChecked());
300 if (scope->is_module_scope()) {
301 Handle<ModuleInfo> module_info =
302 ModuleInfo::New(isolate, zone, scope->AsModuleScope()->module());
303 DCHECK_EQ(index, scope_info->ModuleInfoIndex());
304 scope_info->set(index++, *module_info);
305 DCHECK_EQ(index, scope_info->ModuleVariableCountIndex());
306 scope_info->set(index++, Smi::FromInt(module_vars_count));
307 DCHECK_EQ(index, scope_info->ModuleVariablesIndex());
309 index += kModuleVariableEntryLength * module_vars_count;
312 DCHECK_EQ(index, scope_info->length());
313 DCHECK_EQ(scope->num_parameters(), scope_info->ParameterCount());
314 DCHECK_EQ(scope->num_heap_slots(), scope_info->ContextLength());
319 Handle<ScopeInfo> ScopeInfo::CreateForWithScope(
320 Isolate* isolate, MaybeHandle<ScopeInfo> outer_scope) {
321 const bool has_outer_scope_info = !outer_scope.is_null();
322 const int length = kVariablePartIndex + (has_outer_scope_info ? 1 : 0);
324 Factory* factory = isolate->factory();
325 Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length);
329 ScopeTypeField::encode(WITH_SCOPE) | CallsSloppyEvalField::encode(
false) |
330 LanguageModeField::encode(LanguageMode::kSloppy) |
331 DeclarationScopeField::encode(
false) |
332 ReceiverVariableField::encode(NONE) | HasNewTargetField::encode(
false) |
333 FunctionVariableField::encode(NONE) | AsmModuleField::encode(
false) |
334 HasSimpleParametersField::encode(
true) |
335 FunctionKindField::encode(kNormalFunction) |
336 HasOuterScopeInfoField::encode(has_outer_scope_info) |
337 IsDebugEvaluateScopeField::encode(
false);
338 scope_info->SetFlags(flags);
340 scope_info->SetParameterCount(0);
341 scope_info->SetContextLocalCount(0);
343 int index = kVariablePartIndex;
344 DCHECK_EQ(index, scope_info->ReceiverInfoIndex());
345 DCHECK_EQ(index, scope_info->FunctionNameInfoIndex());
346 DCHECK_EQ(index, scope_info->InferredFunctionNameIndex());
347 DCHECK_EQ(index, scope_info->PositionInfoIndex());
348 DCHECK(index == scope_info->OuterScopeInfoIndex());
349 if (has_outer_scope_info) {
350 scope_info->set(index++, *outer_scope.ToHandleChecked());
352 DCHECK_EQ(index, scope_info->length());
353 DCHECK_EQ(0, scope_info->ParameterCount());
354 DCHECK_EQ(Context::MIN_CONTEXT_SLOTS, scope_info->ContextLength());
359 Handle<ScopeInfo> ScopeInfo::CreateGlobalThisBinding(Isolate* isolate) {
360 return CreateForBootstrapping(isolate, SCRIPT_SCOPE);
364 Handle<ScopeInfo> ScopeInfo::CreateForEmptyFunction(Isolate* isolate) {
365 return CreateForBootstrapping(isolate, FUNCTION_SCOPE);
369 Handle<ScopeInfo> ScopeInfo::CreateForBootstrapping(Isolate* isolate,
371 DCHECK(type == SCRIPT_SCOPE || type == FUNCTION_SCOPE);
373 const int parameter_count = 0;
374 const bool is_empty_function = type == FUNCTION_SCOPE;
375 const int context_local_count = is_empty_function ? 0 : 1;
376 const bool has_receiver = !is_empty_function;
377 const bool has_inferred_function_name = is_empty_function;
378 const bool has_position_info =
true;
379 const int length = kVariablePartIndex + 2 * context_local_count +
380 (has_receiver ? 1 : 0) +
381 (is_empty_function ? kFunctionNameEntries : 0) +
382 (has_inferred_function_name ? 1 : 0) +
383 (has_position_info ? kPositionInfoEntries : 0);
385 Factory* factory = isolate->factory();
386 Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length);
390 ScopeTypeField::encode(type) | CallsSloppyEvalField::encode(
false) |
391 LanguageModeField::encode(LanguageMode::kSloppy) |
392 DeclarationScopeField::encode(
true) |
393 ReceiverVariableField::encode(is_empty_function ? UNUSED : CONTEXT) |
394 HasNewTargetField::encode(
false) |
395 FunctionVariableField::encode(is_empty_function ? UNUSED : NONE) |
396 HasInferredFunctionNameField::encode(has_inferred_function_name) |
397 AsmModuleField::encode(
false) | HasSimpleParametersField::encode(
true) |
398 FunctionKindField::encode(FunctionKind::kNormalFunction) |
399 HasOuterScopeInfoField::encode(
false) |
400 IsDebugEvaluateScopeField::encode(
false);
401 scope_info->SetFlags(flags);
402 scope_info->SetParameterCount(parameter_count);
403 scope_info->SetContextLocalCount(context_local_count);
405 int index = kVariablePartIndex;
408 DCHECK_EQ(index, scope_info->ContextLocalNamesIndex());
409 if (context_local_count) {
410 scope_info->set(index++, ReadOnlyRoots(isolate).this_string());
412 DCHECK_EQ(index, scope_info->ContextLocalInfosIndex());
413 if (context_local_count) {
415 VariableModeField::encode(VariableMode::kConst) |
416 InitFlagField::encode(kCreatedInitialized) |
417 MaybeAssignedFlagField::encode(kNotAssigned) |
418 ParameterNumberField::encode(ParameterNumberField::kMax);
419 scope_info->set(index++, Smi::FromInt(value));
423 DCHECK_EQ(index, scope_info->ReceiverInfoIndex());
424 const int receiver_index = Context::MIN_CONTEXT_SLOTS + 0;
425 if (!is_empty_function) {
426 scope_info->set(index++, Smi::FromInt(receiver_index));
429 DCHECK_EQ(index, scope_info->FunctionNameInfoIndex());
430 if (is_empty_function) {
431 scope_info->set(index++, *isolate->factory()->empty_string());
432 scope_info->set(index++, Smi::kZero);
434 DCHECK_EQ(index, scope_info->InferredFunctionNameIndex());
435 if (has_inferred_function_name) {
436 scope_info->set(index++, *isolate->factory()->empty_string());
438 DCHECK_EQ(index, scope_info->PositionInfoIndex());
440 scope_info->set(index++, Smi::kZero);
441 scope_info->set(index++, Smi::kZero);
442 DCHECK_EQ(index, scope_info->OuterScopeInfoIndex());
443 DCHECK_EQ(index, scope_info->length());
444 DCHECK_EQ(scope_info->ParameterCount(), parameter_count);
445 if (type == FUNCTION_SCOPE) {
446 DCHECK_EQ(scope_info->ContextLength(), 0);
448 DCHECK_EQ(scope_info->ContextLength(), Context::MIN_CONTEXT_SLOTS + 1);
454 ScopeInfo ScopeInfo::Empty(Isolate* isolate) {
455 return ReadOnlyRoots(isolate).empty_scope_info();
458 ScopeType ScopeInfo::scope_type()
const {
459 DCHECK_LT(0, length());
460 return ScopeTypeField::decode(Flags());
463 bool ScopeInfo::CallsSloppyEval()
const {
464 bool calls_sloppy_eval =
465 length() > 0 && CallsSloppyEvalField::decode(Flags());
466 DCHECK_IMPLIES(calls_sloppy_eval, is_sloppy(language_mode()));
467 DCHECK_IMPLIES(calls_sloppy_eval, is_declaration_scope());
468 return calls_sloppy_eval;
471 LanguageMode ScopeInfo::language_mode()
const {
472 return length() > 0 ? LanguageModeField::decode(Flags())
473 : LanguageMode::kSloppy;
476 bool ScopeInfo::is_declaration_scope()
const {
477 return DeclarationScopeField::decode(Flags());
480 int ScopeInfo::ContextLength()
const {
482 int context_locals = ContextLocalCount();
483 bool function_name_context_slot =
484 FunctionVariableField::decode(Flags()) == CONTEXT;
485 bool has_context = context_locals > 0 || function_name_context_slot ||
486 scope_type() == WITH_SCOPE ||
487 (scope_type() == BLOCK_SCOPE && CallsSloppyEval() &&
488 is_declaration_scope()) ||
489 (scope_type() == FUNCTION_SCOPE && CallsSloppyEval()) ||
490 (scope_type() == FUNCTION_SCOPE && IsAsmModule()) ||
491 scope_type() == MODULE_SCOPE;
494 return Context::MIN_CONTEXT_SLOTS + context_locals +
495 (function_name_context_slot ? 1 : 0);
501 bool ScopeInfo::HasReceiver()
const {
502 if (length() == 0)
return false;
503 return NONE != ReceiverVariableField::decode(Flags());
506 bool ScopeInfo::HasAllocatedReceiver()
const {
507 if (length() == 0)
return false;
508 VariableAllocationInfo allocation = ReceiverVariableField::decode(Flags());
509 return allocation == STACK || allocation == CONTEXT;
512 bool ScopeInfo::HasNewTarget()
const {
513 return HasNewTargetField::decode(Flags());
516 bool ScopeInfo::HasFunctionName()
const {
517 if (length() == 0)
return false;
518 return NONE != FunctionVariableField::decode(Flags());
521 bool ScopeInfo::HasInferredFunctionName()
const {
522 if (length() == 0)
return false;
523 return HasInferredFunctionNameField::decode(Flags());
526 bool ScopeInfo::HasPositionInfo()
const {
527 if (length() == 0)
return false;
528 return NeedsPositionInfo(scope_type());
532 bool ScopeInfo::NeedsPositionInfo(ScopeType type) {
533 return type == FUNCTION_SCOPE || type == SCRIPT_SCOPE || type == EVAL_SCOPE ||
534 type == MODULE_SCOPE;
537 bool ScopeInfo::HasSharedFunctionName()
const {
538 return FunctionName() != SharedFunctionInfo::kNoSharedNameSentinel;
541 void ScopeInfo::SetFunctionName(Object* name) {
542 DCHECK(HasFunctionName());
543 DCHECK(name->IsString() || name == SharedFunctionInfo::kNoSharedNameSentinel);
544 set(FunctionNameInfoIndex(), name);
547 void ScopeInfo::SetInferredFunctionName(String name) {
548 DCHECK(HasInferredFunctionName());
549 set(InferredFunctionNameIndex(), name);
552 bool ScopeInfo::HasOuterScopeInfo()
const {
553 if (length() == 0)
return false;
554 return HasOuterScopeInfoField::decode(Flags());
557 bool ScopeInfo::IsDebugEvaluateScope()
const {
558 if (length() == 0)
return false;
559 return IsDebugEvaluateScopeField::decode(Flags());
562 void ScopeInfo::SetIsDebugEvaluateScope() {
564 DCHECK_EQ(scope_type(), WITH_SCOPE);
565 SetFlags(Flags() | IsDebugEvaluateScopeField::encode(
true));
571 bool ScopeInfo::HasContext()
const {
return ContextLength() > 0; }
573 Object* ScopeInfo::FunctionName()
const {
574 DCHECK(HasFunctionName());
575 return get(FunctionNameInfoIndex());
578 Object* ScopeInfo::InferredFunctionName()
const {
579 DCHECK(HasInferredFunctionName());
580 return get(InferredFunctionNameIndex());
583 String ScopeInfo::FunctionDebugName()
const {
584 Object* name = FunctionName();
585 if (name->IsString() && String::cast(name)->length() > 0) {
586 return String::cast(name);
588 if (HasInferredFunctionName()) {
589 name = InferredFunctionName();
590 if (name->IsString())
return String::cast(name);
592 return GetReadOnlyRoots().empty_string();
595 int ScopeInfo::StartPosition()
const {
596 DCHECK(HasPositionInfo());
597 return Smi::ToInt(
get(PositionInfoIndex()));
600 int ScopeInfo::EndPosition()
const {
601 DCHECK(HasPositionInfo());
602 return Smi::ToInt(
get(PositionInfoIndex() + 1));
605 void ScopeInfo::SetPositionInfo(
int start,
int end) {
606 DCHECK(HasPositionInfo());
607 DCHECK_LE(start, end);
608 set(PositionInfoIndex(), Smi::FromInt(start));
609 set(PositionInfoIndex() + 1, Smi::FromInt(end));
612 ScopeInfo ScopeInfo::OuterScopeInfo()
const {
613 DCHECK(HasOuterScopeInfo());
614 return ScopeInfo::cast(
get(OuterScopeInfoIndex()));
617 ModuleInfo ScopeInfo::ModuleDescriptorInfo()
const {
618 DCHECK(scope_type() == MODULE_SCOPE);
619 return ModuleInfo::cast(
get(ModuleInfoIndex()));
622 String ScopeInfo::ContextLocalName(
int var)
const {
624 DCHECK_LT(var, ContextLocalCount());
625 int info_index = ContextLocalNamesIndex() + var;
626 return String::cast(
get(info_index));
629 VariableMode ScopeInfo::ContextLocalMode(
int var)
const {
631 DCHECK_LT(var, ContextLocalCount());
632 int info_index = ContextLocalInfosIndex() + var;
633 int value = Smi::ToInt(
get(info_index));
634 return VariableModeField::decode(value);
637 InitializationFlag ScopeInfo::ContextLocalInitFlag(
int var)
const {
639 DCHECK_LT(var, ContextLocalCount());
640 int info_index = ContextLocalInfosIndex() + var;
641 int value = Smi::ToInt(
get(info_index));
642 return InitFlagField::decode(value);
645 bool ScopeInfo::ContextLocalIsParameter(
int var)
const {
647 DCHECK_LT(var, ContextLocalCount());
648 int info_index = ContextLocalInfosIndex() + var;
649 int value = Smi::ToInt(
get(info_index));
650 return ParameterNumberField::decode(value) != ParameterNumberField::kMax;
653 uint32_t ScopeInfo::ContextLocalParameterNumber(
int var)
const {
654 DCHECK(ContextLocalIsParameter(var));
655 int info_index = ContextLocalInfosIndex() + var;
656 int value = Smi::ToInt(
get(info_index));
657 return ParameterNumberField::decode(value);
660 MaybeAssignedFlag ScopeInfo::ContextLocalMaybeAssignedFlag(
int var)
const {
662 DCHECK_LT(var, ContextLocalCount());
663 int info_index = ContextLocalInfosIndex() + var;
664 int value = Smi::ToInt(
get(info_index));
665 return MaybeAssignedFlagField::decode(value);
669 bool ScopeInfo::VariableIsSynthetic(String name) {
674 return name->length() == 0 || name->Get(0) ==
'.' ||
675 name->Equals(name->GetReadOnlyRoots().this_string());
678 int ScopeInfo::ModuleIndex(Handle<String> name, VariableMode* mode,
679 InitializationFlag* init_flag,
680 MaybeAssignedFlag* maybe_assigned_flag) {
681 DCHECK(name->IsInternalizedString());
682 DCHECK_EQ(scope_type(), MODULE_SCOPE);
683 DCHECK_NOT_NULL(mode);
684 DCHECK_NOT_NULL(init_flag);
685 DCHECK_NOT_NULL(maybe_assigned_flag);
687 int module_vars_count = Smi::ToInt(
get(ModuleVariableCountIndex()));
688 int entry = ModuleVariablesIndex();
689 for (
int i = 0;
i < module_vars_count; ++
i) {
690 String var_name = String::cast(
get(entry + kModuleVariableNameOffset));
691 if (name->Equals(var_name)) {
693 ModuleVariable(
i,
nullptr, &index, mode, init_flag, maybe_assigned_flag);
696 entry += kModuleVariableEntryLength;
703 int ScopeInfo::ContextSlotIndex(Handle<ScopeInfo> scope_info,
704 Handle<String> name, VariableMode* mode,
705 InitializationFlag* init_flag,
706 MaybeAssignedFlag* maybe_assigned_flag) {
707 DCHECK(name->IsInternalizedString());
708 DCHECK_NOT_NULL(mode);
709 DCHECK_NOT_NULL(init_flag);
710 DCHECK_NOT_NULL(maybe_assigned_flag);
712 if (scope_info->length() == 0)
return -1;
714 int start = scope_info->ContextLocalNamesIndex();
715 int end = start + scope_info->ContextLocalCount();
716 for (
int i = start;
i < end; ++
i) {
717 if (*name == scope_info->get(
i)) {
719 *mode = scope_info->ContextLocalMode(var);
720 *init_flag = scope_info->ContextLocalInitFlag(var);
721 *maybe_assigned_flag = scope_info->ContextLocalMaybeAssignedFlag(var);
722 int result = Context::MIN_CONTEXT_SLOTS + var;
724 DCHECK_LT(result, scope_info->ContextLength());
732 int ScopeInfo::ReceiverContextSlotIndex()
const {
733 if (length() > 0 && ReceiverVariableField::decode(Flags()) == CONTEXT) {
734 return Smi::ToInt(
get(ReceiverInfoIndex()));
739 int ScopeInfo::FunctionContextSlotIndex(String name)
const {
740 DCHECK(name->IsInternalizedString());
742 if (FunctionVariableField::decode(Flags()) == CONTEXT &&
743 FunctionName() == name) {
744 return Smi::ToInt(
get(FunctionNameInfoIndex() + 1));
750 FunctionKind ScopeInfo::function_kind()
const {
751 return FunctionKindField::decode(Flags());
754 int ScopeInfo::ContextLocalNamesIndex()
const {
755 DCHECK_LT(0, length());
756 return kVariablePartIndex;
759 int ScopeInfo::ContextLocalInfosIndex()
const {
760 return ContextLocalNamesIndex() + ContextLocalCount();
763 int ScopeInfo::ReceiverInfoIndex()
const {
764 return ContextLocalInfosIndex() + ContextLocalCount();
767 int ScopeInfo::FunctionNameInfoIndex()
const {
768 return ReceiverInfoIndex() + (HasAllocatedReceiver() ? 1 : 0);
771 int ScopeInfo::InferredFunctionNameIndex()
const {
772 return FunctionNameInfoIndex() +
773 (HasFunctionName() ? kFunctionNameEntries : 0);
776 int ScopeInfo::PositionInfoIndex()
const {
777 return InferredFunctionNameIndex() + (HasInferredFunctionName() ? 1 : 0);
780 int ScopeInfo::OuterScopeInfoIndex()
const {
781 return PositionInfoIndex() + (HasPositionInfo() ? kPositionInfoEntries : 0);
784 int ScopeInfo::ModuleInfoIndex()
const {
785 return OuterScopeInfoIndex() + (HasOuterScopeInfo() ? 1 : 0);
788 int ScopeInfo::ModuleVariableCountIndex()
const {
789 return ModuleInfoIndex() + 1;
792 int ScopeInfo::ModuleVariablesIndex()
const {
793 return ModuleVariableCountIndex() + 1;
796 void ScopeInfo::ModuleVariable(
int i, String* name,
int* index,
798 InitializationFlag* init_flag,
799 MaybeAssignedFlag* maybe_assigned_flag) {
801 DCHECK_LT(
i, Smi::ToInt(
get(ModuleVariableCountIndex())));
803 int entry = ModuleVariablesIndex() +
i * kModuleVariableEntryLength;
804 int properties = Smi::ToInt(
get(entry + kModuleVariablePropertiesOffset));
806 if (name !=
nullptr) {
807 *name = String::cast(
get(entry + kModuleVariableNameOffset));
809 if (index !=
nullptr) {
810 *index = Smi::ToInt(
get(entry + kModuleVariableIndexOffset));
811 DCHECK_NE(*index, 0);
813 if (mode !=
nullptr) {
814 *mode = VariableModeField::decode(properties);
816 if (init_flag !=
nullptr) {
817 *init_flag = InitFlagField::decode(properties);
819 if (maybe_assigned_flag !=
nullptr) {
820 *maybe_assigned_flag = MaybeAssignedFlagField::decode(properties);
824 std::ostream& operator<<(std::ostream& os,
825 ScopeInfo::VariableAllocationInfo var_info) {
827 case ScopeInfo::VariableAllocationInfo::NONE:
829 case ScopeInfo::VariableAllocationInfo::STACK:
830 return os <<
"STACK";
831 case ScopeInfo::VariableAllocationInfo::CONTEXT:
832 return os <<
"CONTEXT";
833 case ScopeInfo::VariableAllocationInfo::UNUSED:
834 return os <<
"UNUSED";
840 Handle<ModuleInfoEntry> ModuleInfoEntry::New(Isolate* isolate,
841 Handle<Object> export_name,
842 Handle<Object> local_name,
843 Handle<Object> import_name,
844 int module_request,
int cell_index,
845 int beg_pos,
int end_pos) {
846 Handle<ModuleInfoEntry> result = Handle<ModuleInfoEntry>::cast(
847 isolate->factory()->NewStruct(MODULE_INFO_ENTRY_TYPE, TENURED));
848 result->set_export_name(*export_name);
849 result->set_local_name(*local_name);
850 result->set_import_name(*import_name);
851 result->set_module_request(module_request);
852 result->set_cell_index(cell_index);
853 result->set_beg_pos(beg_pos);
854 result->set_end_pos(end_pos);
858 Handle<ModuleInfo> ModuleInfo::New(Isolate* isolate, Zone* zone,
859 ModuleDescriptor* descr) {
861 int size =
static_cast<int>(descr->module_requests().size());
862 Handle<FixedArray> module_requests = isolate->factory()->NewFixedArray(size);
863 Handle<FixedArray> module_request_positions =
864 isolate->factory()->NewFixedArray(size);
865 for (
const auto& elem : descr->module_requests()) {
866 module_requests->set(elem.second.index, *elem.first->string());
867 module_request_positions->set(elem.second.index,
868 Smi::FromInt(elem.second.position));
872 Handle<FixedArray> special_exports = isolate->factory()->NewFixedArray(
873 static_cast<int>(descr->special_exports().size()));
876 for (
auto entry : descr->special_exports()) {
877 Handle<ModuleInfoEntry> serialized_entry = entry->Serialize(isolate);
878 special_exports->set(
i++, *serialized_entry);
883 Handle<FixedArray> namespace_imports = isolate->factory()->NewFixedArray(
884 static_cast<int>(descr->namespace_imports().size()));
887 for (
auto entry : descr->namespace_imports()) {
888 Handle<ModuleInfoEntry> serialized_entry = entry->Serialize(isolate);
889 namespace_imports->set(
i++, *serialized_entry);
894 Handle<FixedArray> regular_exports =
895 descr->SerializeRegularExports(isolate, zone);
898 Handle<FixedArray> regular_imports = isolate->factory()->NewFixedArray(
899 static_cast<int>(descr->regular_imports().size()));
902 for (
const auto& elem : descr->regular_imports()) {
903 Handle<ModuleInfoEntry> serialized_entry =
904 elem.second->Serialize(isolate);
905 regular_imports->set(
i++, *serialized_entry);
909 Handle<ModuleInfo> result = isolate->factory()->NewModuleInfo();
910 result->set(kModuleRequestsIndex, *module_requests);
911 result->set(kSpecialExportsIndex, *special_exports);
912 result->set(kRegularExportsIndex, *regular_exports);
913 result->set(kNamespaceImportsIndex, *namespace_imports);
914 result->set(kRegularImportsIndex, *regular_imports);
915 result->set(kModuleRequestPositionsIndex, *module_request_positions);
919 int ModuleInfo::RegularExportCount()
const {
920 DCHECK_EQ(regular_exports()->length() % kRegularExportLength, 0);
921 return regular_exports()->length() / kRegularExportLength;
924 String ModuleInfo::RegularExportLocalName(
int i)
const {
925 return String::cast(regular_exports()->
get(
i * kRegularExportLength +
926 kRegularExportLocalNameOffset));
929 int ModuleInfo::RegularExportCellIndex(
int i)
const {
930 return Smi::ToInt(regular_exports()->
get(
i * kRegularExportLength +
931 kRegularExportCellIndexOffset));
934 FixedArray ModuleInfo::RegularExportExportNames(
int i)
const {
935 return FixedArray::cast(regular_exports()->
get(
936 i * kRegularExportLength + kRegularExportExportNamesOffset));