Files
sdk/pkg/dart2wasm/lib/reference_extensions.dart
T
Aske Simon Christensen bde8430b97 [dart2wasm] Initial async/await support based on Promise integration
This implementation has a number of limitations:

- Returning a Future from an async function is not supported.
- Every async call switches to a new stack. A later optimization will
  stay on the same stack if the call is directly awaited.
- Exceptions that cross async boundaries do not receive full stack
  traces including the async suspension points. The stack trace of the
  final exception just reflects the stack trace for the outermost
  async call.

Change-Id: I2a5d5e30d6e955999ba55842c8b2ca3427cbf954
Cq-Include-Trybots: luci.dart.try:dart2wasm-linux-x64-d8-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/241010
Reviewed-by: William Hesse <whesse@google.com>
Reviewed-by: Joshua Litt <joshualitt@google.com>
2022-08-19 07:11:18 +00:00

76 lines
2.5 KiB
Dart

// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:kernel/ast.dart';
// Extend references with flags to more easily identify getters and setters.
extension GetterSetterReference on Reference {
bool get isImplicitGetter {
Member member = asMember;
return member is Field && member.getterReference == this;
}
bool get isImplicitSetter {
Member member = asMember;
return member is Field && member.setterReference == this;
}
bool get isGetter {
Member member = asMember;
return member is Procedure && member.isGetter || isImplicitGetter;
}
bool get isSetter {
Member member = asMember;
return member is Procedure && member.isSetter || isImplicitSetter;
}
}
// Extend procedures with a tearOffReference that refers to the tear-off
// implementation for that procedure. This enables a Reference to refer to any
// implementation relating to a member, including its tear-off, which it can't
// do in plain kernel.
// Also add an asyncInnerReference that refers to the inner, suspendable
// body of an async function, which returns the value to be put into a future.
// This can be called directly from other async functions if the result is
// directly awaited.
// Use Expandos to avoid keeping the procedure alive.
final Expando<Reference> _tearOffReference = Expando();
final Expando<Reference> _asyncInnerReference = Expando();
extension CustomReference on Procedure {
Reference get tearOffReference =>
_tearOffReference[this] ??= Reference()..node = this;
Reference get asyncInnerReference =>
_asyncInnerReference[this] ??= Reference()..node = this;
}
extension IsCustomReference on Reference {
bool get isTearOffReference {
Member member = asMember;
return member is Procedure && _tearOffReference[member] == this;
}
bool get isAsyncInnerReference {
Member member = asMember;
return member is Procedure && _asyncInnerReference[member] == this;
}
}
extension ReferenceAs on Member {
Reference referenceAs({required bool getter, required bool setter}) {
Member member = this;
return member is Field
? setter
? member.setterReference!
: member.getterReference
: getter && member is Procedure && member.kind == ProcedureKind.Method
? member.tearOffReference
: member.reference;
}
}