4#if !defined(DART_PRECOMPILED_RUNTIME)
18 share_enclosing_context,
20 "Allocate captured variables in the existing context of an "
21 "enclosing scope (up to innermost loop) and spare the allocation "
22 "of a local context.");
28 function_level_(function_level),
29 loop_level_(loop_level),
30 context_level_(
LocalScope::kUninitializedContextLevel),
35 context_slots_(new(
Thread::Current()->zone())
48 while (current_scope !=
nullptr) {
49 if (current_scope == scope) {
52 current_scope = current_scope->
parent();
58 ASSERT(variable !=
nullptr);
63 variables_.Add(variable);
64 if (variable->
owner() ==
nullptr) {
73 ASSERT(parameter !=
nullptr);
78 variables_.InsertAt(
pos, parameter);
85void LocalScope::AllocateContextVariable(
LocalVariable* variable,
92 if ((*context_owner) ==
nullptr) {
96 *context_owner =
this;
97 }
else if (!FLAG_share_enclosing_context && ((*context_owner) !=
this)) {
104 *context_owner =
this;
105 }
else if ((*context_owner)->loop_level() <
loop_level()) {
106 ASSERT(FLAG_share_enclosing_context);
112 *context_owner =
this;
123 (*context_owner)->AddContextVariable(variable);
128 context_variables_.Add(variable);
138 bool* found_captured_variables) {
142 ASSERT(num_parameters >= 0);
147 first_parameter_index;
152 if (variable->
owner() ==
this &&
153 variable->
name().
Equals(Symbols::SuspendStateVar())) {
155 suspend_state_var = variable;
159 if (suspend_state_var !=
nullptr) {
165 while (
pos < num_parameters) {
178 AllocateContextVariable(parameter, &context_owner);
179 *found_captured_variables =
true;
187 next_index = first_local_index;
190 if (variable == suspend_state_var) {
194 if (variable->
owner() ==
this) {
196 AllocateContextVariable(variable, &context_owner);
197 *found_captured_variables =
true;
207 while (child !=
nullptr) {
212 const int num_parameters_in_child = 0;
214 function, dummy_parameter_index, num_parameters_in_child, next_index,
215 context_owner, found_captured_variables);
216 if (child_next_index.
value() < min_index.
value()) {
217 min_index = child_next_index;
228 intptr_t kernel_offset)
240bool LocalVariable::IsFilteredIdentifier(
const String&
name) {
242 if (
name.
ptr() == Symbols::FunctionTypeArgumentsVar().ptr()) {
253 vars.AddDeoptIdToContextLevelMappings(context_level_array);
258 if (!context_scope.
IsNull()) {
261 if (context_scope.IsInvisibleAt(
i)) {
265 ASSERT(!LocalVariable::IsFilteredIdentifier(
name));
274 ASSERT((
desc.info.begin_pos.IsReal() !=
desc.info.end_pos.IsReal()) ||
275 (
desc.info.begin_pos <=
desc.info.end_pos));
281 int16_t scope_id = 0;
282 CollectLocalVariables(&
vars, &scope_id);
292 for (
int i = 0;
i < this->variables_.length();
i++) {
294 if (var->
owner() ==
this) {
295 if (var->
name().
ptr() == Symbols::CurrentContextVar().ptr()) {
301 desc.info.scope_id = 0;
308 ASSERT(!LocalVariable::IsFilteredIdentifier(var->
name()));
310 LocalVarDescriptorsBuilder::VarDesc
desc;
319 desc.info.scope_id = *scope_id;
330 while (child !=
nullptr) {
331 child->CollectLocalVariables(
vars, scope_id);
337 intptr_t kernel_offset)
const {
339 for (intptr_t
i = 0;
i < variables_.length();
i++) {
351 intptr_t kernel_offset,
354 while (current_scope !=
nullptr) {
358 if ((var !=
nullptr) && (!var->
is_invisible() || test_only)) {
364 current_scope = current_scope->
parent();
372 for (intptr_t
i = 0, n = scope->variables_.length();
i < n; ++
i) {
384 ASSERT(variable !=
nullptr);
394 while ((parent_scope !=
nullptr) &&
396 scope = parent_scope;
397 parent_scope = scope->
parent();
405 scope = parent_scope;
420 int num_captured = 0;
435 intptr_t current_context_level)
const {
456 int captured_idx = 0;
466 context_scope.SetIsFinalAt(captured_idx, variable->
is_final());
467 context_scope.SetIsLateAt(captured_idx, variable->
is_late());
473 context_scope.
SetTypeAt(captured_idx, *
type->ToAbstractType());
474 context_scope.
SetCidAt(captured_idx,
type->ToNullableCid());
475 context_scope.SetIsNullableAt(captured_idx,
type->is_nullable());
476 context_scope.SetIsInvisibleAt(captured_idx, variable->
is_invisible());
481 intptr_t adjusted_context_level =
488 context_scope.SetIsAwaiterLinkAt(captured_idx, is_awaiter_link);
489 if (is_awaiter_link) {
490 awaiter_link = variable;
497 if (awaiter_link !=
nullptr) {
498 const intptr_t depth =
500 const intptr_t index = awaiter_link->
index().
value();
503 {
static_cast<uint8_t
>(depth),
static_cast<uint8_t
>(index)});
504 }
else if (FLAG_precompiled_mode) {
506 "Warning: @pragma('vm:awaiter-link') marked variable %s is visible "
507 "from the function %s but the link {%" Pd ", %" Pd
508 "} can't be encoded\n",
515 return context_scope.
ptr();
524 const bool is_late = context_scope.IsLateAt(
i);
528 context_scope.
CidAt(
i), &static_type);
536 if (context_scope.IsFinalAt(
i)) {
543 if (context_scope.IsInvisibleAt(
i)) {
561 while (scope != top_scope->
parent()) {
565 (variable->
name().
ptr() == Symbols::ExceptionVar().ptr()) ||
566 (variable->
name().
ptr() == Symbols::SavedTryContextVar().ptr()) ||
567 (variable->
name().
ptr() == Symbols::ArgDescVar().ptr()) ||
569 Symbols::FunctionTypeArgumentsVar().ptr())) {
581 const intptr_t kNumCapturedVars = 1;
592 context_scope.SetIsFinalAt(0,
true);
600 return context_scope.
ptr();
604 if (is_awaiter_link_ == IsAwaiterLink::kUnknown) {
614 return is_awaiter_link_ == IsAwaiterLink::kLink;
633 for (intptr_t
i = 0, n = var_descs.
Length();
i < n; ++
i) {
647 intptr_t start_deopt_id = (*context_level_array)[
start];
648 intptr_t start_context_level = (*context_level_array)[
start + 1];
650 intptr_t end_deopt_id = start_deopt_id;
651 for (intptr_t peek =
start + 2; peek < context_level_array->
length();
653 intptr_t peek_deopt_id = (*context_level_array)[peek];
654 intptr_t peek_context_level = (*context_level_array)[peek + 1];
656 ASSERT(peek_deopt_id > end_deopt_id);
657 if (peek_context_level != start_context_level)
break;
659 end_deopt_id = peek_deopt_id;
665 desc.info.scope_id = 0;
669 desc.info.set_index(start_context_level);
677 if (vars_.is_empty()) {
678 return Object::empty_var_descriptors().ptr();
682 for (
int i = 0;
i < vars_.length();
i++) {
685 return var_desc.
ptr();
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
#define RELEASE_ASSERT(cond)
intptr_t KernelOffsetAt(intptr_t scope_index) const
StringPtr NameAt(intptr_t scope_index) const
AbstractTypePtr TypeAt(intptr_t scope_index) const
intptr_t LateInitOffsetAt(intptr_t scope_index) const
intptr_t ContextLevelAt(intptr_t scope_index) const
void SetCidAt(intptr_t scope_index, intptr_t cid) const
TokenPosition DeclarationTokenIndexAt(intptr_t scope_index) const
intptr_t CidAt(intptr_t scope_index) const
void ClearFlagsAt(intptr_t scope_index) const
intptr_t ContextIndexAt(intptr_t scope_index) const
TokenPosition TokenIndexAt(intptr_t scope_index) const
void SetContextLevelAt(intptr_t scope_index, intptr_t context_level) const
void SetTypeAt(intptr_t scope_index, const AbstractType &type) const
void SetContextIndexAt(intptr_t scope_index, intptr_t context_index) const
void SetTokenIndexAt(intptr_t scope_index, TokenPosition token_pos) const
void SetLateInitOffsetAt(intptr_t scope_index, intptr_t late_init_offset) const
void SetNameAt(intptr_t scope_index, const String &name) const
intptr_t num_variables() const
void SetKernelOffsetAt(intptr_t scope_index, intptr_t kernel_offset) const
void SetDeclarationTokenIndexAt(intptr_t scope_index, TokenPosition declaration_token_pos) const
static ContextScopePtr New(intptr_t num_variables, bool is_implicit)
TokenPosition token_pos() const
AbstractTypePtr ParameterTypeAt(intptr_t index) const
ContextScopePtr context_scope() const
int context_level() const
LocalScope * parent() const
LocalScope(LocalScope *parent, int function_level, int loop_level)
bool IsNestedWithin(LocalScope *scope) const
TokenPosition end_token_pos() const
LocalScope * sibling() const
static ContextScopePtr CreateImplicitClosureScope(const Function &func)
int NumCapturedVariables() const
int function_level() const
static LocalScope * RestoreOuterScope(const ContextScope &context_scope)
VariableIndex AllocateVariables(const Function &function, VariableIndex first_parameter_index, int num_parameters, VariableIndex first_local_index, LocalScope *context_owner, bool *found_captured_variables)
LocalVarDescriptorsPtr GetVarDescriptors(const Function &func, ZoneGrowableArray< intptr_t > *context_level_array)
LocalVariable * LookupVariableByName(const String &name)
LocalVariable * VariableAt(intptr_t index) const
intptr_t num_variables() const
bool HasContextLevel() const
TokenPosition begin_token_pos() const
LocalVariable * LookupVariable(const String &name, intptr_t kernel_offset, bool test_only)
bool AddVariable(LocalVariable *variable)
LocalScope * child() const
void CaptureVariable(LocalVariable *variable)
bool InsertParameterAt(intptr_t pos, LocalVariable *parameter)
int num_context_variables() const
ContextScopePtr PreserveOuterScope(const Function &function, intptr_t current_context_level) const
LocalVariable * LocalLookupVariable(const String &name, intptr_t kernel_offset) const
void set_context_level(int context_level)
void AddContextVariable(LocalVariable *var)
void CaptureLocalVariables(LocalScope *top_scope)
void AddAll(Zone *zone, const LocalVarDescriptors &var_descs)
LocalVarDescriptorsPtr Done()
void Add(const VarDesc &var_desc)
void AddDeoptIdToContextLevelMappings(ZoneGrowableArray< intptr_t > *context_level_array)
static LocalVarDescriptorsPtr New(intptr_t num_variables)
void SetVar(intptr_t var_index, const String &name, UntaggedLocalVarDescriptors::VarInfo *info) const
StringPtr GetName(intptr_t var_index) const
void GetInfo(intptr_t var_index, UntaggedLocalVarDescriptors::VarInfo *info) const
CompileType * inferred_type() const
VariableIndex index() const
void set_late_init_offset(intptr_t late_init_offset)
LocalScope * owner() const
bool ComputeIfIsAwaiterLink(const Library &library)
bool is_forced_stack() const
TokenPosition declaration_token_pos() const
TokenPosition token_pos() const
void set_index(VariableIndex index)
void set_invisible(bool value)
bool is_invisible() const
intptr_t kernel_offset() const
bool Equals(const LocalVariable &other) const
static constexpr intptr_t kNoKernelOffset
intptr_t late_init_offset() const
const String & name() const
void set_is_awaiter_link(bool value)
void set_owner(LocalScope *owner)
LocalVariable(TokenPosition declaration_pos, TokenPosition token_pos, const String &name, const AbstractType &static_type, intptr_t kernel_offset=kNoKernelOffset)
static void static void PrintErr(const char *format,...) PRINTF_ATTRIBUTE(1
static Object & ZoneHandle()
static const Slot & GetContextVariableSlotFor(Thread *thread, const LocalVariable &var)
bool Equals(const String &str) const
uint16_t CharAt(intptr_t index) const
static const char * ToCString(Thread *thread, StringPtr ptr)
static constexpr intptr_t kSuspendStateVarIndex
static const String & This()
static const String & Empty()
static Thread * Current()
static TokenPosition Deserialize(int32_t value)
static const TokenPosition kMinSource
static bool IsUint(intptr_t N, T value)
Dart_NativeFunction function
ObjectPtr EvaluateMetadata(const Library &library, intptr_t kernel_offset, bool is_annotations_offset)
bool FindPragmaInMetadata(Thread *T, const Object &metadata_obj, const String &pragma_name, bool multiple, Object *options)
DEFINE_FLAG(bool, print_cluster_information, false, "Print information about clusters written to snapshot")