@@ -462,6 +462,8 @@ ContextScopePtr LocalScope::PreserveOuterScope(
462462
463463 LocalVariable* awaiter_link = nullptr ;
464464
465+ bool does_capture_only_final_and_shared_vars = true ;
466+
465467 // Create a descriptor for each referenced captured variable of enclosing
466468 // functions to preserve its name and its context allocation information.
467469 int captured_idx = 0 ;
@@ -500,6 +502,13 @@ ContextScopePtr LocalScope::PreserveOuterScope(
500502 if (is_awaiter_link) {
501503 awaiter_link = variable;
502504 }
505+
506+ bool is_shared = variable->ComputeIfShared (library);
507+ context_scope.SetIsSharedAt (captured_idx, is_shared);
508+ if (!is_shared && !variable->is_final ()) {
509+ does_capture_only_final_and_shared_vars = false ;
510+ }
511+
503512 captured_idx++;
504513 }
505514 }
@@ -523,6 +532,11 @@ ContextScopePtr LocalScope::PreserveOuterScope(
523532 }
524533 }
525534
535+ if (!function.IsNull ()) {
536+ function.set_does_close_over_only_final_and_shared_vars (
537+ does_capture_only_final_and_shared_vars);
538+ }
539+
526540 return context_scope.ptr ();
527541}
528542
@@ -542,6 +556,7 @@ LocalScope* LocalScope::RestoreOuterScope(const ContextScope& context_scope) {
542556 String::ZoneHandle (context_scope.NameAt (i)), static_type,
543557 context_scope.KernelOffsetAt (i), inferred_type);
544558 variable->set_is_awaiter_link (context_scope.IsAwaiterLinkAt (i));
559+ variable->set_is_shared (context_scope.IsSharedAt (i));
545560 variable->set_is_captured ();
546561 variable->set_index (VariableIndex (context_scope.ContextIndexAt (i)));
547562 if (context_scope.IsFinalAt (i)) {
@@ -693,6 +708,19 @@ bool LocalVariable::ComputeIfIsAwaiterLink(const Library& library) {
693708 return is_awaiter_link_ == IsAwaiterLink::kLink ;
694709}
695710
711+ bool LocalVariable::ComputeIfShared (const Library& library) {
712+ if (is_shared_ == IsShared::kUnknown ) {
713+ RELEASE_ASSERT (annotations_offset_ != kNoKernelOffset );
714+ Thread* T = Thread::Current ();
715+ Zone* Z = T->zone ();
716+ const auto & metadata = Object::Handle (
717+ Z, kernel::EvaluateMetadata (library, annotations_offset_,
718+ /* is_annotations_offset = */ true ));
719+ set_is_shared (FindPragmaInMetadata (T, metadata, Symbols::vm_shared ()));
720+ }
721+ return is_shared_ == IsShared::kShared ;
722+ }
723+
696724bool LocalVariable::Equals (const LocalVariable& other) const {
697725 if (HasIndex () && other.HasIndex () && (index () == other.index ())) {
698726 if (is_captured () == other.is_captured ()) {
0 commit comments