Skip to content

Commit 5042ff9

Browse files
alexmarkovcommit-bot@chromium.org
authored andcommitted
[vm/bytecode] Add async/async*/sync* attributes to closures
Change-Id: Ibb0f202ada840ee112f46d5db3d8f9459817c358 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/106730 Reviewed-by: Régis Crelier <regis@google.com> Reviewed-by: Ryan Macnak <rmacnak@google.com>
1 parent 0f636f1 commit 5042ff9

7 files changed

Lines changed: 106 additions & 52 deletions

File tree

pkg/vm/lib/bytecode/dbc.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ library vm.bytecode.dbc;
1010
/// Before bumping current bytecode version format, make sure that
1111
/// all users have switched to a VM which is able to consume new
1212
/// version of bytecode.
13-
const int currentBytecodeFormatVersion = 10;
13+
const int currentBytecodeFormatVersion = 11;
1414

1515
/// Version of experimental / bleeding edge bytecode format.
1616
/// Produced by bytecode generator when --use-future-bytecode-format

pkg/vm/lib/bytecode/declarations.dart

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -890,7 +890,11 @@ class ClosureDeclaration {
890890
static const int hasOptionalNamedParamsFlag = 1 << 1;
891891
static const int hasTypeParamsFlag = 1 << 2;
892892
static const int hasSourcePositionsFlag = 1 << 3;
893+
static const int isAsyncFlag = 1 << 4;
894+
static const int isAsyncStarFlag = 1 << 5;
895+
static const int isSyncStarFlag = 1 << 6;
893896

897+
final int flags;
894898
final ObjectHandle parent;
895899
final ObjectHandle name;
896900
final int position;
@@ -903,6 +907,7 @@ class ClosureDeclaration {
903907
ClosureCode code;
904908

905909
ClosureDeclaration(
910+
this.flags,
906911
this.parent,
907912
this.name,
908913
this.position,
@@ -914,20 +919,6 @@ class ClosureDeclaration {
914919
this.returnType);
915920

916921
void write(BufferedWriter writer) {
917-
int flags = 0;
918-
if (numRequiredParams != parameters.length) {
919-
if (numNamedParams > 0) {
920-
flags |= hasOptionalNamedParamsFlag;
921-
} else {
922-
flags |= hasOptionalPositionalParamsFlag;
923-
}
924-
}
925-
if (typeParams.isNotEmpty) {
926-
flags |= hasTypeParamsFlag;
927-
}
928-
if (position != TreeNode.noOffset) {
929-
flags |= hasSourcePositionsFlag;
930-
}
931922
writer.writePackedUInt30(flags);
932923
writer.writePackedObject(parent);
933924
writer.writePackedObject(name);
@@ -996,14 +987,23 @@ class ClosureDeclaration {
996987
(_) => new NameAndType(
997988
reader.readPackedObject(), reader.readPackedObject()));
998989
final returnType = reader.readPackedObject();
999-
return new ClosureDeclaration(parent, name, position, endPosition,
990+
return new ClosureDeclaration(flags, parent, name, position, endPosition,
1000991
typeParams, numRequiredParams, numNamedParams, parameters, returnType);
1001992
}
1002993

1003994
@override
1004995
String toString() {
1005996
final StringBuffer sb = new StringBuffer();
1006997
sb.write('Closure $parent::$name');
998+
if ((flags & isAsyncFlag) != 0) {
999+
sb.write(' async');
1000+
}
1001+
if ((flags & isAsyncStarFlag) != 0) {
1002+
sb.write(' async*');
1003+
}
1004+
if ((flags & isSyncStarFlag) != 0) {
1005+
sb.write(' sync*');
1006+
}
10071007
if (position != TreeNode.noOffset) {
10081008
sb.write(' pos = $position, end-pos = $endPosition');
10091009
}

pkg/vm/lib/bytecode/gen_bytecode.dart

Lines changed: 70 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1852,7 +1852,8 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
18521852
}
18531853
}
18541854

1855-
int _genClosureBytecode(TreeNode node, String name, FunctionNode function) {
1855+
int _genClosureBytecode(
1856+
LocalFunction node, String name, FunctionNode function) {
18561857
_pushAssemblerState();
18571858

18581859
locals.enterScope(node);
@@ -1865,15 +1866,6 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
18651866
final savedLoopDepth = currentLoopDepth;
18661867
currentLoopDepth = 0;
18671868

1868-
int position = TreeNode.noOffset;
1869-
int endPosition = TreeNode.noOffset;
1870-
if (emitSourcePositions) {
1871-
position = (node is ast.FunctionDeclaration)
1872-
? node.fileOffset
1873-
: function.fileOffset;
1874-
endPosition = function.fileEndOffset;
1875-
}
1876-
18771869
if (function.typeParameters.isNotEmpty) {
18781870
functionTypeParameters ??= new List<TypeParameter>();
18791871
functionTypeParameters.addAll(function.typeParameters);
@@ -1890,27 +1882,8 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
18901882
locals.sortedNamedParameters.forEach(_evaluateDefaultParameterValue);
18911883

18921884
final int closureIndex = closures.length;
1893-
objectTable.declareClosure(function, enclosingMember, closureIndex);
1894-
final List<NameAndType> parameters = function.positionalParameters
1895-
.followedBy(function.namedParameters)
1896-
.map((v) => new NameAndType(objectTable.getNameHandle(null, v.name),
1897-
objectTable.getHandle(v.type)))
1898-
.toList();
1899-
final ClosureDeclaration closure = new ClosureDeclaration(
1900-
objectTable
1901-
.getHandle(savedIsClosure ? parentFunction : enclosingMember),
1902-
objectTable.getNameHandle(null, name),
1903-
position,
1904-
endPosition,
1905-
function.typeParameters
1906-
.map((tp) => new NameAndType(
1907-
objectTable.getNameHandle(null, tp.name),
1908-
objectTable.getHandle(tp.bound)))
1909-
.toList(),
1910-
function.requiredParameterCount,
1911-
function.namedParameters.length,
1912-
parameters,
1913-
objectTable.getHandle(function.returnType));
1885+
final closure = getClosureDeclaration(node, function, name, closureIndex,
1886+
savedIsClosure ? parentFunction : enclosingMember);
19141887
closures.add(closure);
19151888

19161889
final int closureFunctionIndex = cp.addClosureFunction(closureIndex);
@@ -1972,6 +1945,71 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
19721945
return closureFunctionIndex;
19731946
}
19741947

1948+
ClosureDeclaration getClosureDeclaration(LocalFunction node,
1949+
FunctionNode function, String name, int closureIndex, TreeNode parent) {
1950+
objectTable.declareClosure(function, enclosingMember, closureIndex);
1951+
1952+
int flags = 0;
1953+
int position = TreeNode.noOffset;
1954+
int endPosition = TreeNode.noOffset;
1955+
if (emitSourcePositions) {
1956+
position = (node is ast.FunctionDeclaration)
1957+
? node.fileOffset
1958+
: function.fileOffset;
1959+
endPosition = function.fileEndOffset;
1960+
if (position != TreeNode.noOffset) {
1961+
flags |= ClosureDeclaration.hasSourcePositionsFlag;
1962+
}
1963+
}
1964+
1965+
switch (function.dartAsyncMarker) {
1966+
case AsyncMarker.Async:
1967+
flags |= ClosureDeclaration.isAsyncFlag;
1968+
break;
1969+
case AsyncMarker.AsyncStar:
1970+
flags |= ClosureDeclaration.isAsyncStarFlag;
1971+
break;
1972+
case AsyncMarker.SyncStar:
1973+
flags |= ClosureDeclaration.isSyncStarFlag;
1974+
break;
1975+
default:
1976+
break;
1977+
}
1978+
1979+
final List<NameAndType> parameters = function.positionalParameters
1980+
.followedBy(function.namedParameters)
1981+
.map((v) => new NameAndType(objectTable.getNameHandle(null, v.name),
1982+
objectTable.getHandle(v.type)))
1983+
.toList();
1984+
if (function.requiredParameterCount != parameters.length) {
1985+
if (function.namedParameters.isNotEmpty) {
1986+
flags |= ClosureDeclaration.hasOptionalNamedParamsFlag;
1987+
} else {
1988+
flags |= ClosureDeclaration.hasOptionalPositionalParamsFlag;
1989+
}
1990+
}
1991+
1992+
final typeParams = function.typeParameters
1993+
.map((tp) => new NameAndType(objectTable.getNameHandle(null, tp.name),
1994+
objectTable.getHandle(tp.bound)))
1995+
.toList();
1996+
if (typeParams.isNotEmpty) {
1997+
flags |= ClosureDeclaration.hasTypeParamsFlag;
1998+
}
1999+
2000+
return new ClosureDeclaration(
2001+
flags,
2002+
objectTable.getHandle(parent),
2003+
objectTable.getNameHandle(null, name),
2004+
position,
2005+
endPosition,
2006+
typeParams,
2007+
function.requiredParameterCount,
2008+
function.namedParameters.length,
2009+
parameters,
2010+
objectTable.getHandle(function.returnType));
2011+
}
2012+
19752013
void _genSyncYieldingPrologue(FunctionNode function, Label continuationLabel,
19762014
int switchVarIndexInFrame) {
19772015
// switch_var = :await_jump_var
@@ -2045,7 +2083,7 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
20452083
asm.emitStoreFieldTOS(cp.addInstanceField(closureContext));
20462084
}
20472085

2048-
void _genClosure(TreeNode node, String name, FunctionNode function) {
2086+
void _genClosure(LocalFunction node, String name, FunctionNode function) {
20492087
final int closureFunctionIndex = _genClosureBytecode(node, name, function);
20502088
_genAllocateClosureInstance(node, closureFunctionIndex, function);
20512089
}

pkg/vm/testcases/bytecode/async.dart.expect

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ ConstantPool {
7575
[38] = Reserved
7676
[39] = EndClosureFunctionScope
7777
}
78-
Closure #lib::asyncInFieldInitializer (field)::'<anonymous closure>' (dart:async::Future < dart:core::int > x) -> dart:async::Future < dart:core::Null >
78+
Closure #lib::asyncInFieldInitializer (field)::'<anonymous closure>' async (dart:async::Future < dart:core::int > x) -> dart:async::Future < dart:core::Null >
7979
ClosureCode {
8080
EntryFixed 2, 4
8181
CheckStack 0
@@ -1708,7 +1708,7 @@ ConstantPool {
17081708
[38] = Reserved
17091709
[39] = EndClosureFunctionScope
17101710
}
1711-
Closure #lib::closure::'nested' () -> dart:async::Future < dart:core::int >
1711+
Closure #lib::closure::'nested' async () -> dart:async::Future < dart:core::int >
17121712
ClosureCode {
17131713
EntryFixed 1, 4
17141714
CheckStack 0

runtime/vm/compiler/frontend/bytecode_reader.cc

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,9 @@ void BytecodeReaderHelper::ReadClosureDeclaration(const Function& function,
472472
const int kHasOptionalNamedParamsFlag = 1 << 1;
473473
const int kHasTypeParamsFlag = 1 << 2;
474474
const int kHasSourcePositionsFlag = 1 << 3;
475+
const int kIsAsyncFlag = 1 << 4;
476+
const int kIsAsyncStarFlag = 1 << 5;
477+
const int kIsSyncStarFlag = 1 << 6;
475478

476479
const intptr_t flags = reader_.ReadUInt();
477480

@@ -499,6 +502,19 @@ void BytecodeReaderHelper::ReadClosureDeclaration(const Function& function,
499502
closure.set_is_declared_in_bytecode(true);
500503
closure.set_end_token_pos(end_position);
501504

505+
if ((flags & kIsSyncStarFlag) != 0) {
506+
closure.set_modifier(RawFunction::kSyncGen);
507+
} else if ((flags & kIsAsyncFlag) != 0) {
508+
closure.set_modifier(RawFunction::kAsync);
509+
closure.set_is_inlinable(!FLAG_causal_async_stacks);
510+
} else if ((flags & kIsAsyncStarFlag) != 0) {
511+
closure.set_modifier(RawFunction::kAsyncGen);
512+
closure.set_is_inlinable(!FLAG_causal_async_stacks);
513+
}
514+
if (Function::Cast(parent).IsAsyncOrGenerator()) {
515+
closure.set_is_generated_body(true);
516+
}
517+
502518
closures_->SetAt(closureIndex, closure);
503519

504520
Type& signature_type = Type::Handle(

runtime/vm/constants_kbc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -749,7 +749,7 @@ class KernelBytecode {
749749
// Maximum bytecode format version supported by VM.
750750
// The range of supported versions should include version produced by bytecode
751751
// generator (currentBytecodeFormatVersion in pkg/vm/lib/bytecode/dbc.dart).
752-
static const intptr_t kMaxSupportedBytecodeFormatVersion = 10;
752+
static const intptr_t kMaxSupportedBytecodeFormatVersion = 11;
753753

754754
enum Opcode {
755755
#define DECLARE_BYTECODE(name, encoding, kind, op1, op2, op3) k##name,

tools/VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,5 @@ MINOR 3
3535
PATCH 3
3636
PRERELEASE 0
3737
PRERELEASE_PATCH 0
38-
ABI_VERSION 5
38+
ABI_VERSION 6
3939
OLDEST_SUPPORTED_ABI_VERSION 3

0 commit comments

Comments
 (0)