diff --git a/CHANGELOG.md b/CHANGELOG.md index a579da27e13..653c2971fb4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,9 +8,6 @@ This allows libraries with no library declarations (and therefore no name) to have parts, and it allows tools to easily find the library of a part file. -* Added support for starting `async` functions synchronously. All tools (VM, - dart2js, DDC) have now a flag `--sync-async` to enable this behavior. - Currently this behavior is opt-in. It will become the default. #### Strong Mode diff --git a/pkg/compiler/lib/src/commandline_options.dart b/pkg/compiler/lib/src/commandline_options.dart index 7a0b6de73fa..7a6f642c402 100644 --- a/pkg/compiler/lib/src/commandline_options.dart +++ b/pkg/compiler/lib/src/commandline_options.dart @@ -88,11 +88,6 @@ class Flags { // https://gist.github.com/eernstg/4353d7b4f669745bed3a5423e04a453c. static const String genericMethodSyntax = '--generic-method-syntax'; - // Starts `async` functions synchronously. - // - // This is the Dart 2.0 behavior. This flag is only used during the migration. - static const String syncAsync = '--sync-async'; - // Initializing-formal access is enabled by default and cannot be disabled. // For backward compatibility the option is still accepted, but it is ignored. static const String initializingFormalAccess = '--initializing-formal-access'; diff --git a/pkg/compiler/lib/src/common_elements.dart b/pkg/compiler/lib/src/common_elements.dart index 67f69101fbb..7163d401141 100644 --- a/pkg/compiler/lib/src/common_elements.dart +++ b/pkg/compiler/lib/src/common_elements.dart @@ -508,8 +508,6 @@ class CommonElements { FunctionEntity get asyncHelperStart => _findAsyncHelperFunction("_asyncStart"); - FunctionEntity get asyncHelperStartSync => - _findAsyncHelperFunction("_asyncStartSync"); FunctionEntity get asyncHelperAwait => _findAsyncHelperFunction("_asyncAwait"); FunctionEntity get asyncHelperReturn => @@ -552,12 +550,6 @@ class CommonElements { ConstructorEntity get syncCompleterConstructor => _env.lookupConstructor(_findAsyncHelperClass("Completer"), "sync"); - ConstructorEntity get asyncAwaitCompleterConstructor => - _env.lookupConstructor(asyncAwaitCompleter, ""); - - ClassEntity get asyncAwaitCompleter => - _findAsyncHelperClass("_AsyncAwaitCompleter"); - ClassEntity get asyncStarController => _findAsyncHelperClass("_AsyncStarStreamController"); diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart index bd2e4ce9011..b080d9108da 100644 --- a/pkg/compiler/lib/src/dart2js.dart +++ b/pkg/compiler/lib/src/dart2js.dart @@ -355,7 +355,6 @@ Future compile(List argv, new OptionHandler(Flags.allowMockCompilation, passThrough), new OptionHandler(Flags.fastStartup, passThrough), new OptionHandler(Flags.genericMethodSyntax, ignoreOption), - new OptionHandler(Flags.syncAsync, passThrough), new OptionHandler(Flags.initializingFormalAccess, ignoreOption), new OptionHandler('${Flags.minify}|-m', implyCompilation), new OptionHandler(Flags.preserveUris, passThrough), diff --git a/pkg/compiler/lib/src/js_backend/backend.dart b/pkg/compiler/lib/src/js_backend/backend.dart index 3209051061f..147a35ee08a 100644 --- a/pkg/compiler/lib/src/js_backend/backend.dart +++ b/pkg/compiler/lib/src/js_backend/backend.dart @@ -700,8 +700,7 @@ class JavaScriptBackend { NativeBasicData nativeBasicData = compiler.frontendStrategy.nativeBasicData; RuntimeTypesNeedBuilder rtiNeedBuilder = compiler.frontendStrategy.createRuntimeTypesNeedBuilder(); - BackendImpacts impacts = - new BackendImpacts(compiler.options, commonElements); + BackendImpacts impacts = new BackendImpacts(commonElements); TypeVariableResolutionAnalysis typeVariableResolutionAnalysis = new TypeVariableResolutionAnalysis( compiler.frontendStrategy.elementEnvironment, @@ -784,8 +783,7 @@ class JavaScriptBackend { CompilerTask task, Compiler compiler, ClosedWorld closedWorld) { ElementEnvironment elementEnvironment = closedWorld.elementEnvironment; CommonElements commonElements = closedWorld.commonElements; - BackendImpacts impacts = - new BackendImpacts(compiler.options, commonElements); + BackendImpacts impacts = new BackendImpacts(commonElements); _typeVariableCodegenAnalysis = new TypeVariableCodegenAnalysis( closedWorld.elementEnvironment, this, commonElements, mirrorsData); _mirrorsCodegenAnalysis = mirrorsResolutionAnalysis.close(); @@ -983,8 +981,7 @@ class JavaScriptBackend { emitter.createEmitter(namer, closedWorld, codegenWorldBuilder, sorter); // TODO(johnniwinther): Share the impact object created in // createCodegenEnqueuer. - BackendImpacts impacts = - new BackendImpacts(compiler.options, closedWorld.commonElements); + BackendImpacts impacts = new BackendImpacts(closedWorld.commonElements); if (compiler.options.disableRtiOptimization) { _rtiSubstitutions = new TrivialRuntimeTypesSubstitutions( closedWorld.elementEnvironment, closedWorld.dartTypes); @@ -1170,20 +1167,13 @@ class JavaScriptBackend { jsAst.Expression code, SourceInformation bodySourceInformation, SourceInformation exitSourceInformation) { - bool startAsyncSynchronously = compiler.options.startAsyncSynchronously; - AsyncRewriterBase rewriter = null; jsAst.Name name = namer.methodPropertyName(element); switch (element.asyncMarker) { case AsyncMarker.ASYNC: - var startFunction = startAsyncSynchronously - ? commonElements.asyncHelperStartSync - : commonElements.asyncHelperStart; - var completerConstructor = startAsyncSynchronously - ? commonElements.asyncAwaitCompleterConstructor - : commonElements.syncCompleterConstructor; rewriter = new AsyncRewriter(reporter, element, - asyncStart: emitter.staticFunctionAccess(startFunction), + asyncStart: + emitter.staticFunctionAccess(commonElements.asyncHelperStart), asyncAwait: emitter.staticFunctionAccess(commonElements.asyncHelperAwait), asyncReturn: @@ -1191,8 +1181,8 @@ class JavaScriptBackend { asyncRethrow: emitter.staticFunctionAccess(commonElements.asyncHelperRethrow), wrapBody: emitter.staticFunctionAccess(commonElements.wrapBody), - completerFactory: - emitter.staticFunctionAccess(completerConstructor), + completerFactory: emitter + .staticFunctionAccess(commonElements.syncCompleterConstructor), safeVariableName: namer.safeVariablePrefixForAsyncRewrite, bodyName: namer.deriveAsyncBodyName(name)); break; diff --git a/pkg/compiler/lib/src/js_backend/backend_impact.dart b/pkg/compiler/lib/src/js_backend/backend_impact.dart index 3d0fd4fffb9..28360bca8a4 100644 --- a/pkg/compiler/lib/src/js_backend/backend_impact.dart +++ b/pkg/compiler/lib/src/js_backend/backend_impact.dart @@ -8,7 +8,6 @@ import '../common/names.dart'; import '../common_elements.dart' show CommonElements, ElementEnvironment; import '../elements/types.dart' show InterfaceType; import '../elements/entities.dart'; -import '../options.dart' show CompilerOptions; import '../universe/selector.dart'; import '../universe/world_impact.dart' show WorldImpact, WorldImpactBuilder, WorldImpactBuilderImpl; @@ -89,10 +88,9 @@ class BackendImpact { /// The JavaScript backend dependencies for various features. class BackendImpacts { - final CompilerOptions _options; final CommonElements _commonElements; - BackendImpacts(this._options, this._commonElements); + BackendImpacts(this._commonElements); BackendImpact _getRuntimeTypeArgument; @@ -128,24 +126,15 @@ class BackendImpacts { BackendImpact _asyncBody; BackendImpact get asyncBody { - var staticUses = [ + return _asyncBody ??= new BackendImpact(staticUses: [ + _commonElements.asyncHelperStart, _commonElements.asyncHelperAwait, _commonElements.asyncHelperReturn, _commonElements.asyncHelperRethrow, + _commonElements.syncCompleterConstructor, _commonElements.streamIteratorConstructor, _commonElements.wrapBody - ]; - var instantiantedClasses = []; - if (_options.startAsyncSynchronously) { - staticUses.add(_commonElements.asyncAwaitCompleterConstructor); - staticUses.add(_commonElements.asyncHelperStartSync); - instantiantedClasses.add(_commonElements.asyncAwaitCompleter); - } else { - staticUses.add(_commonElements.syncCompleterConstructor); - staticUses.add(_commonElements.asyncHelperStart); - } - return _asyncBody ??= new BackendImpact( - staticUses: staticUses, instantiatedClasses: instantiantedClasses); + ]); } BackendImpact _syncStarBody; diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart index db380bc2962..129af4d1135 100644 --- a/pkg/compiler/lib/src/options.dart +++ b/pkg/compiler/lib/src/options.dart @@ -276,9 +276,6 @@ class CompilerOptions implements DiagnosticOptions { /// Strip option used by dart2dart. final List strips; - /// Whether to start `async` functions synchronously. - final bool startAsyncSynchronously; - /// Create an options object by parsing flags from [options]. factory CompilerOptions.parse( {Uri entryPoint, @@ -359,7 +356,6 @@ class CompilerOptions implements DiagnosticOptions { useMultiSourceInfo: _hasOption(options, Flags.useMultiSourceInfo), useNewSourceInfo: _hasOption(options, Flags.useNewSourceInfo), useStartupEmitter: _hasOption(options, Flags.fastStartup), - startAsyncSynchronously: _hasOption(options, Flags.syncAsync), verbose: _hasOption(options, Flags.verbose)); } @@ -425,7 +421,6 @@ class CompilerOptions implements DiagnosticOptions { bool useMultiSourceInfo: false, bool useNewSourceInfo: false, bool useStartupEmitter: false, - bool startAsyncSynchronously: false, bool verbose: false}) { // TODO(sigmund): should entrypoint be here? should we validate it is not // null? In unittests we use the same compiler to analyze or build multiple @@ -509,7 +504,6 @@ class CompilerOptions implements DiagnosticOptions { useMultiSourceInfo: useMultiSourceInfo, useNewSourceInfo: useNewSourceInfo, useStartupEmitter: useStartupEmitter, - startAsyncSynchronously: startAsyncSynchronously, verbose: verbose); } @@ -565,7 +559,6 @@ class CompilerOptions implements DiagnosticOptions { this.useMultiSourceInfo: false, this.useNewSourceInfo: false, this.useStartupEmitter: false, - this.startAsyncSynchronously: false, this.verbose: false}) : _shownPackageWarnings = shownPackageWarnings; diff --git a/pkg/dev_compiler/tool/ddc b/pkg/dev_compiler/tool/ddc index 9846cd68481..cc8f4106f71 100755 --- a/pkg/dev_compiler/tool/ddc +++ b/pkg/dev_compiler/tool/ddc @@ -60,12 +60,6 @@ if [ "$1" = "-k" ]; then shift fi -SYNC_ASYNC=false -if [ "$1" = "--sync-async" ]; then - SYNC_ASYNC=true - shift -fi - BASENAME=$( basename "${1%.*}") LIBROOT=$(cd $( dirname "${1%.*}") && pwd) @@ -110,7 +104,6 @@ echo " let sdk = require(\"dart_sdk\"); let main = require(\"./$BASENAME\").$BASENAME.main; sdk.dart.ignoreWhitelistedErrors(false); - if ($SYNC_ASYNC) sdk.dart.setStartAsyncSynchronously(); try { sdk._isolate_helper.startRootIsolate(main, []); } catch(e) { diff --git a/pkg/dev_compiler/tool/input_sdk/patch/async_patch.dart b/pkg/dev_compiler/tool/input_sdk/patch/async_patch.dart index a4889fd1b45..d773cda0f37 100644 --- a/pkg/dev_compiler/tool/input_sdk/patch/async_patch.dart +++ b/pkg/dev_compiler/tool/input_sdk/patch/async_patch.dart @@ -17,8 +17,6 @@ import 'dart:_isolate_helper' import 'dart:_foreign_helper' show JS, JSExportName; -import 'dart:_runtime' as dart; - typedef void _Callback(); typedef void _TakeCallback(_Callback callback); @@ -69,7 +67,7 @@ async_(Function() initGenerator) { onError = zone.registerUnaryCallback(onError); } var asyncFuture = new _Future(); - var body = () { + scheduleMicrotask(() { try { iter = JS('', '#[Symbol.iterator]()', initGenerator()); var iteratorValue = JS('', '#.next(null)', iter); @@ -99,20 +97,9 @@ async_(Function() initGenerator) { _Future._chainCoreFuture(onAwait(value), asyncFuture); } } catch (e, s) { - if (dart.startAsyncSynchronously) { - scheduleMicrotask(() { - _completeWithErrorCallback(asyncFuture, e, s); - }); - } else { - _completeWithErrorCallback(asyncFuture, e, s); - } + _completeWithErrorCallback(asyncFuture, e, s); } - }; - if (dart.startAsyncSynchronously) { - body(); - } else { - scheduleMicrotask(body); - } + }); return asyncFuture; } diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/generators.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/generators.dart index d8f20d7c623..dc2d82e5348 100644 --- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/generators.dart +++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/generators.dart @@ -11,12 +11,6 @@ /// stepping stone for proposed ES7 async/await, and uses ES6 Promises. part of dart._runtime; -// TODO(vsm): Remove once this flag is the default. -bool startAsyncSynchronously = false; -void setStartAsyncSynchronously() { - startAsyncSynchronously = true; -} - final _jsIterator = JS('', 'Symbol("_jsIterator")'); final _current = JS('', 'Symbol("_current")'); diff --git a/pkg/front_end/tool/_fasta/command_line.dart b/pkg/front_end/tool/_fasta/command_line.dart index a25d6bed0b8..aeb2bb56c65 100644 --- a/pkg/front_end/tool/_fasta/command_line.dart +++ b/pkg/front_end/tool/_fasta/command_line.dart @@ -228,13 +228,9 @@ ProcessedOptions analyzeCommandLine( final bool strongMode = options.containsKey("--strong-mode") || options.containsKey("--strong"); - final bool syncAsync = options.containsKey("--sync-async"); - final String targetName = options["-t"] ?? options["--target"] ?? "vm"; - final TargetFlags flags = - new TargetFlags(strongMode: strongMode, syncAsync: syncAsync); - + final TargetFlags flags = new TargetFlags(strongMode: strongMode); final Target target = getTarget(targetName, flags); if (target == null) { return throw new CommandLineProblem.deprecated( diff --git a/pkg/kernel/bin/transform.dart b/pkg/kernel/bin/transform.dart index aabac5ef8a8..399de1c174e 100755 --- a/pkg/kernel/bin/transform.dart +++ b/pkg/kernel/bin/transform.dart @@ -44,10 +44,7 @@ ArgParser parser = new ArgParser() ..addOption('transformation', abbr: 't', help: 'The transformation to apply.', - defaultsTo: 'continuation') - ..addFlag('sync-async', - help: 'Whether `async` functions start synchronously.', - defaultsTo: false); + defaultsTo: 'continuation'); main(List arguments) async { if (arguments.isNotEmpty && arguments[0] == '--batch') { @@ -72,7 +69,6 @@ Future runTransformation(List arguments) async { var output = options['out']; var format = options['format']; var verbose = options['verbose']; - var syncAsync = options['sync-async']; if (output == null) { output = '${input.substring(0, input.lastIndexOf('.'))}.transformed.dill'; @@ -89,7 +85,7 @@ Future runTransformation(List arguments) async { final hierarchy = new ClassHierarchy(program); switch (options['transformation']) { case 'continuation': - program = cont.transformProgram(coreTypes, program, syncAsync); + program = cont.transformProgram(coreTypes, program); break; case 'resolve-mixins': mix.transformLibraries( diff --git a/pkg/kernel/lib/core_types.dart b/pkg/kernel/lib/core_types.dart index fe1cd4b95e8..f23ccbf78a9 100644 --- a/pkg/kernel/lib/core_types.dart +++ b/pkg/kernel/lib/core_types.dart @@ -79,9 +79,7 @@ class CoreTypes { Class _stackTraceClass; Class _streamClass; Class _completerClass; - Class _asyncAwaitCompleterClass; Class _futureOrClass; - Constructor _asyncAwaitCompleterConstructor; Procedure _completerSyncConstructor; Procedure _completerComplete; Procedure _completerCompleteError; @@ -164,21 +162,11 @@ class CoreTypes { return _completerClass ??= _index.getClass('dart:async', 'Completer'); } - Class get asyncAwaitCompleterClass { - return _asyncAwaitCompleterClass ??= - _index.getClass('dart:async', '_AsyncAwaitCompleter'); - } - Procedure get completerSyncConstructor { return _completerSyncConstructor ??= _index.getMember('dart:async', 'Completer', 'sync'); } - Constructor get asyncAwaitCompleterConstructor { - return _asyncAwaitCompleterConstructor ??= - _index.getMember('dart:async', '_AsyncAwaitCompleter', ''); - } - Procedure get completerComplete { return _completerComplete ??= _index.getMember('dart:async', 'Completer', 'complete'); diff --git a/pkg/kernel/lib/target/targets.dart b/pkg/kernel/lib/target/targets.dart index 1d1e8c9a4df..342757e2456 100644 --- a/pkg/kernel/lib/target/targets.dart +++ b/pkg/kernel/lib/target/targets.dart @@ -15,20 +15,16 @@ import 'vmreify.dart' show VmGenericTypesReifiedTarget; final List targetNames = targets.keys.toList(); class TargetFlags { - final bool strongMode; - final bool treeShake; - - /// Whether `async` functions start synchronously. - final bool syncAsync; - final List programRoots; - final Uri kernelRuntime; + bool strongMode; + bool treeShake; + List programRoots; + Uri kernelRuntime; TargetFlags( {this.strongMode: false, this.treeShake: false, - this.syncAsync: false, this.programRoots: const [], - this.kernelRuntime}); + this.kernelRuntime}) {} } typedef Target _TargetBuilder(TargetFlags flags); diff --git a/pkg/kernel/lib/target/vm.dart b/pkg/kernel/lib/target/vm.dart index 5079c6520db..a30abbb6e07 100644 --- a/pkg/kernel/lib/target/vm.dart +++ b/pkg/kernel/lib/target/vm.dart @@ -64,7 +64,7 @@ class VmTarget extends Target { logger?.call("Transformed mixin applications"); // TODO(kmillikin): Make this run on a per-method basis. - transformAsync.transformLibraries(coreTypes, libraries, flags.syncAsync); + transformAsync.transformLibraries(coreTypes, libraries); logger?.call("Transformed async methods"); } diff --git a/pkg/kernel/lib/target/vmcc.dart b/pkg/kernel/lib/target/vmcc.dart index 3496882bb08..28522cf79cc 100644 --- a/pkg/kernel/lib/target/vmcc.dart +++ b/pkg/kernel/lib/target/vmcc.dart @@ -44,7 +44,7 @@ class VmClosureConvertedTarget extends vm_target.VmTarget { performTreeShaking(coreTypes, program); } - cont.transformProgram(coreTypes, program, flags.syncAsync); + cont.transformProgram(coreTypes, program); new SanitizeForVM().transform(program); diff --git a/pkg/kernel/lib/transformations/async.dart b/pkg/kernel/lib/transformations/async.dart index 8f8133e25cd..8539f2d548e 100644 --- a/pkg/kernel/lib/transformations/async.dart +++ b/pkg/kernel/lib/transformations/async.dart @@ -484,8 +484,8 @@ class ExpressionLifter extends Transformer { } visitFunctionNode(FunctionNode node) { - var nestedRewriter = new RecursiveContinuationRewriter( - continuationRewriter.helper, continuationRewriter.syncAsync); + var nestedRewriter = + new RecursiveContinuationRewriter(continuationRewriter.helper); return node.accept(nestedRewriter); } } diff --git a/pkg/kernel/lib/transformations/continuation.dart b/pkg/kernel/lib/transformations/continuation.dart index 9d8e50e6b74..2b77554415e 100644 --- a/pkg/kernel/lib/transformations/continuation.dart +++ b/pkg/kernel/lib/transformations/continuation.dart @@ -12,34 +12,29 @@ import '../visitor.dart'; import 'async.dart'; -void transformLibraries( - CoreTypes coreTypes, List libraries, bool syncAsync) { +void transformLibraries(CoreTypes coreTypes, List libraries) { var helper = new HelperNodes.fromCoreTypes(coreTypes); - var rewriter = new RecursiveContinuationRewriter(helper, syncAsync); + var rewriter = new RecursiveContinuationRewriter(helper); for (var library in libraries) { rewriter.rewriteLibrary(library); } } -Program transformProgram(CoreTypes coreTypes, Program program, bool syncAsync) { +Program transformProgram(CoreTypes coreTypes, Program program) { var helper = new HelperNodes.fromCoreTypes(coreTypes); - var rewriter = new RecursiveContinuationRewriter(helper, syncAsync); + var rewriter = new RecursiveContinuationRewriter(helper); return rewriter.rewriteProgram(program); } class RecursiveContinuationRewriter extends Transformer { final HelperNodes helper; - - /// Whether `async` functions should start synchronously. - final bool syncAsync; - final VariableDeclaration asyncJumpVariable = new VariableDeclaration( ":await_jump_var", initializer: new IntLiteral(0)); final VariableDeclaration asyncContextVariable = new VariableDeclaration(":await_ctx_var"); - RecursiveContinuationRewriter(this.helper, this.syncAsync); + RecursiveContinuationRewriter(this.helper); Program rewriteProgram(Program node) { return node.accept(this); @@ -57,15 +52,14 @@ class RecursiveContinuationRewriter extends Transformer { switch (node.asyncMarker) { case AsyncMarker.Sync: case AsyncMarker.SyncYielding: - node.transformChildren( - new RecursiveContinuationRewriter(helper, syncAsync)); + node.transformChildren(new RecursiveContinuationRewriter(helper)); return node; case AsyncMarker.SyncStar: - return new SyncStarFunctionRewriter(helper, node, syncAsync).rewrite(); + return new SyncStarFunctionRewriter(helper, node).rewrite(); case AsyncMarker.Async: - return new AsyncFunctionRewriter(helper, node, syncAsync).rewrite(); + return new AsyncFunctionRewriter(helper, node).rewrite(); case AsyncMarker.AsyncStar: - return new AsyncStarFunctionRewriter(helper, node, syncAsync).rewrite(); + return new AsyncStarFunctionRewriter(helper, node).rewrite(); } } } @@ -78,9 +72,8 @@ abstract class ContinuationRewriterBase extends RecursiveContinuationRewriter { int capturedTryDepth = 0; // Deepest yield point within a try-block. int capturedCatchDepth = 0; // Deepest yield point within a catch-block. - ContinuationRewriterBase( - HelperNodes helper, this.enclosingFunction, bool syncAsync) - : super(helper, syncAsync); + ContinuationRewriterBase(HelperNodes helper, this.enclosingFunction) + : super(helper); /// Given a container [type], which is an instantiation of the given /// [containerClass] extract its element type. @@ -164,14 +157,13 @@ abstract class ContinuationRewriterBase extends RecursiveContinuationRewriter { class SyncStarFunctionRewriter extends ContinuationRewriterBase { final VariableDeclaration iteratorVariable; - SyncStarFunctionRewriter( - HelperNodes helper, FunctionNode enclosingFunction, syncAsync) + SyncStarFunctionRewriter(HelperNodes helper, FunctionNode enclosingFunction) : iteratorVariable = new VariableDeclaration(':iterator') ..type = new InterfaceType(helper.syncIteratorClass, [ ContinuationRewriterBase.elementTypeFrom( helper.iterableClass, enclosingFunction.returnType) ]), - super(helper, enclosingFunction, syncAsync); + super(helper, enclosingFunction); FunctionNode rewrite() { // :sync_op(:iterator) { @@ -264,9 +256,8 @@ abstract class AsyncRewriterBase extends ContinuationRewriterBase { ExpressionLifter expressionRewriter; - AsyncRewriterBase( - HelperNodes helper, FunctionNode enclosingFunction, bool syncAsync) - : super(helper, enclosingFunction, syncAsync) {} + AsyncRewriterBase(helper, enclosingFunction) + : super(helper, enclosingFunction) {} void setupAsyncContinuations(List statements) { expressionRewriter = new ExpressionLifter(this); @@ -763,9 +754,8 @@ abstract class AsyncRewriterBase extends ContinuationRewriterBase { class AsyncStarFunctionRewriter extends AsyncRewriterBase { VariableDeclaration controllerVariable; - AsyncStarFunctionRewriter( - HelperNodes helper, FunctionNode enclosingFunction, bool syncAsync) - : super(helper, enclosingFunction, syncAsync); + AsyncStarFunctionRewriter(helper, enclosingFunction) + : super(helper, enclosingFunction); FunctionNode rewrite() { var statements = []; @@ -872,9 +862,8 @@ class AsyncFunctionRewriter extends AsyncRewriterBase { VariableDeclaration completerVariable; VariableDeclaration returnVariable; - AsyncFunctionRewriter( - HelperNodes helper, FunctionNode enclosingFunction, bool syncAsync) - : super(helper, enclosingFunction, syncAsync); + AsyncFunctionRewriter(helper, enclosingFunction) + : super(helper, enclosingFunction); FunctionNode rewrite() { var statements = []; @@ -888,29 +877,16 @@ class AsyncFunctionRewriter extends AsyncRewriterBase { final DartType returnType = new InterfaceType(helper.futureOrClass, [valueType]); var completerTypeArguments = [valueType]; + var completerType = + new InterfaceType(helper.completerClass, completerTypeArguments); - if (syncAsync) { - final completerType = new InterfaceType( - helper.asyncAwaitCompleterClass, completerTypeArguments); - // final Completer :completer = new _AsyncAwaitCompleter(); - completerVariable = new VariableDeclaration(":completer", - initializer: new ConstructorInvocation( - helper.asyncAwaitCompleterConstructor, - new Arguments([], types: completerTypeArguments)) - ..fileOffset = enclosingFunction.body?.fileOffset ?? -1, - isFinal: true, - type: completerType); - } else { - final completerType = - new InterfaceType(helper.completerClass, completerTypeArguments); - // final Completer :completer = new Completer.sync(); - completerVariable = new VariableDeclaration(":completer", - initializer: new StaticInvocation(helper.completerConstructor, - new Arguments([], types: completerTypeArguments)) - ..fileOffset = enclosingFunction.body?.fileOffset ?? -1, - isFinal: true, - type: completerType); - } + // final Completer :completer = new Completer.sync(); + completerVariable = new VariableDeclaration(":completer", + initializer: new StaticInvocation(helper.completerConstructor, + new Arguments([], types: completerTypeArguments)) + ..fileOffset = enclosingFunction.body?.fileOffset ?? -1, + isFinal: true, + type: completerType); statements.add(completerVariable); returnVariable = new VariableDeclaration(":return_value", type: returnType); @@ -918,23 +894,14 @@ class AsyncFunctionRewriter extends AsyncRewriterBase { setupAsyncContinuations(statements); - if (syncAsync) { - // :completer.start(:async_op); - var startStatement = new ExpressionStatement(new MethodInvocation( - new VariableGet(completerVariable), - new Name('start'), - new Arguments([new VariableGet(nestedClosureVariable)])) - ..fileOffset = enclosingFunction.fileOffset); - statements.add(startStatement); - } else { - // new Future.microtask(:async_op); - var newMicrotaskStatement = new ExpressionStatement(new StaticInvocation( - helper.futureMicrotaskConstructor, - new Arguments([new VariableGet(nestedClosureVariable)], - types: [const DynamicType()])) - ..fileOffset = enclosingFunction.fileOffset); - statements.add(newMicrotaskStatement); - } + // new Future.microtask(:async_op); + var newMicrotaskStatement = new ExpressionStatement(new StaticInvocation( + helper.futureMicrotaskConstructor, + new Arguments([new VariableGet(nestedClosureVariable)], + types: [const DynamicType()])) + ..fileOffset = enclosingFunction.fileOffset); + statements.add(newMicrotaskStatement); + // return :completer.future; var completerGet = new VariableGet(completerVariable); var returnStatement = new ReturnStatement(new PropertyGet(completerGet, @@ -997,11 +964,9 @@ class HelperNodes { final Procedure asyncThenWrapper; final Procedure awaitHelper; final Class completerClass; - final Class asyncAwaitCompleterClass; final Member completerComplete; final Member completerCompleteError; final Member completerConstructor; - final Member asyncAwaitCompleterConstructor; final Member completerFuture; final Library coreLibrary; final CoreTypes coreTypes; @@ -1036,11 +1001,9 @@ class HelperNodes { this.asyncThenWrapper, this.awaitHelper, this.completerClass, - this.asyncAwaitCompleterClass, this.completerComplete, this.completerCompleteError, this.completerConstructor, - this.asyncAwaitCompleterConstructor, this.completerFuture, this.coreLibrary, this.coreTypes, @@ -1076,11 +1039,9 @@ class HelperNodes { coreTypes.asyncThenWrapperHelperProcedure, coreTypes.awaitHelperProcedure, coreTypes.completerClass, - coreTypes.asyncAwaitCompleterClass, coreTypes.completerComplete, coreTypes.completerCompleteError, coreTypes.completerSyncConstructor, - coreTypes.asyncAwaitCompleterConstructor, coreTypes.completerFuture, coreTypes.coreLibrary, coreTypes, diff --git a/pkg/vm/bin/kernel_service.dart b/pkg/vm/bin/kernel_service.dart index f191501230d..da7207722bf 100644 --- a/pkg/vm/bin/kernel_service.dart +++ b/pkg/vm/bin/kernel_service.dart @@ -48,9 +48,7 @@ abstract class Compiler { CompilerOptions options; Compiler(this.fileSystem, Uri platformKernel, - {this.strongMode: false, - bool suppressWarnings: false, - bool syncAsync: false}) { + {this.strongMode: false, bool suppressWarnings: false}) { Uri packagesUri = (Platform.packageConfig != null) ? Uri.parse(Platform.packageConfig) : null; @@ -61,14 +59,12 @@ abstract class Compiler { print("DFE: Platform.resolvedExecutable: ${Platform.resolvedExecutable}"); print("DFE: platformKernel: ${platformKernel}"); print("DFE: strongMode: ${strongMode}"); - print("DFE: syncAsync: ${syncAsync}"); } options = new CompilerOptions() ..strongMode = strongMode ..fileSystem = fileSystem - ..target = new VmTarget( - new TargetFlags(strongMode: strongMode, syncAsync: syncAsync)) + ..target = new VmTarget(new TargetFlags(strongMode: strongMode)) ..packagesFileUri = packagesUri ..sdkSummary = platformKernel ..verbose = verbose @@ -103,11 +99,9 @@ class IncrementalCompiler extends Compiler { IncrementalKernelGenerator generator; IncrementalCompiler(FileSystem fileSystem, Uri platformKernel, - {bool strongMode: false, bool suppressWarnings: false, syncAsync: false}) + {bool strongMode: false, bool suppressWarnings: false}) : super(fileSystem, platformKernel, - strongMode: strongMode, - suppressWarnings: suppressWarnings, - syncAsync: syncAsync); + strongMode: strongMode, suppressWarnings: suppressWarnings); @override Future compileInternal(Uri script) async { @@ -128,12 +122,9 @@ class SingleShotCompiler extends Compiler { SingleShotCompiler(FileSystem fileSystem, Uri platformKernel, {this.requireMain: false, bool strongMode: false, - bool suppressWarnings: false, - bool syncAsync: false}) + bool suppressWarnings: false}) : super(fileSystem, platformKernel, - strongMode: strongMode, - suppressWarnings: suppressWarnings, - syncAsync: syncAsync); + strongMode: strongMode, suppressWarnings: suppressWarnings); @override Future compileInternal(Uri script) async { @@ -147,9 +138,7 @@ final Map isolateCompilers = new Map(); Future lookupOrBuildNewIncrementalCompiler( int isolateId, List sourceFiles, Uri platformKernel, - {bool strongMode: false, - bool suppressWarnings: false, - bool syncAsync: false}) async { + {bool strongMode: false, bool suppressWarnings: false}) async { IncrementalCompiler compiler; if (isolateCompilers.containsKey(isolateId)) { compiler = isolateCompilers[isolateId]; @@ -173,9 +162,7 @@ Future lookupOrBuildNewIncrementalCompiler( // isolate needs to receive a message indicating that particular // isolate was shut down. Message should be handled here in this script. compiler = new IncrementalCompiler(fileSystem, platformKernel, - strongMode: strongMode, - suppressWarnings: suppressWarnings, - syncAsync: syncAsync); + strongMode: strongMode, suppressWarnings: suppressWarnings); isolateCompilers[isolateId] = compiler; } return compiler; @@ -202,7 +189,6 @@ Future _processLoadRequest(request) async { final int isolateId = request[6]; final List sourceFiles = request[7]; final bool suppressWarnings = request[8]; - final bool syncAsync = request[9]; Compiler compiler; // TODO(aam): There should be no need to have an option to choose @@ -212,7 +198,7 @@ Future _processLoadRequest(request) async { if (incremental) { compiler = await lookupOrBuildNewIncrementalCompiler( isolateId, sourceFiles, platformKernel, - suppressWarnings: suppressWarnings, syncAsync: syncAsync); + suppressWarnings: suppressWarnings); } else { final FileSystem fileSystem = sourceFiles == null ? StandardFileSystem.instance @@ -220,8 +206,7 @@ Future _processLoadRequest(request) async { compiler = new SingleShotCompiler(fileSystem, platformKernel, requireMain: sourceFiles == null, strongMode: strong, - suppressWarnings: suppressWarnings, - syncAsync: syncAsync); + suppressWarnings: suppressWarnings); } CompilationResult result; @@ -308,7 +293,6 @@ train(String scriptUri, String platformKernel) { 1 /* isolateId chosen randomly */, null /* source files */, false /* suppress warnings */, - false /* synchronous async */, ]; _processLoadRequest(request); } diff --git a/runtime/lib/async_patch.dart b/runtime/lib/async_patch.dart index 19d5b6a51b5..de47bf20a10 100644 --- a/runtime/lib/async_patch.dart +++ b/runtime/lib/async_patch.dart @@ -17,43 +17,6 @@ import "dart:_internal" show VMLibraryHooks, patch; // Equivalent of calling FATAL from C++ code. _fatal(msg) native "DartAsync_fatal"; -class _AsyncAwaitCompleter implements Completer { - final _completer = new Completer.sync(); - bool isSync; - - _AsyncAwaitCompleter() : isSync = false; - - void complete([FutureOr value]) { - if (isSync) { - _completer.complete(value); - } else if (value is Future) { - value.then(_completer.complete, onError: _completer.completeError); - } else { - scheduleMicrotask(() { - _completer.complete(value); - }); - } - } - - void completeError(e, [st]) { - if (isSync) { - _completer.completeError(e, st); - } else { - scheduleMicrotask(() { - _completer.completeError(e, st); - }); - } - } - - void start(f) { - f(); - isSync = true; - } - - Future get future => _completer.future; - bool get isCompleted => _completer.isCompleted; -} - // We need to pass the value as first argument and leave the second and third // arguments empty (used for error handling). // See vm/ast_transformer.cc for usage. diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h index b8242e4bbd0..67d23d68126 100644 --- a/runtime/vm/flag_list.h +++ b/runtime/vm/flag_list.h @@ -157,7 +157,6 @@ C(stress_async_stacks, false, false, bool, false, \ "Stress test async stack traces") \ P(strong, bool, false, "Enable strong mode.") \ - P(sync_async, bool, false, "Start `async` functions synchronously.") \ R(support_ast_printer, false, bool, true, "Support the AST printer.") \ R(support_compiler_stats, false, bool, true, "Support compiler stats.") \ R(support_disassembler, false, bool, true, "Support the disassembler.") \ diff --git a/runtime/vm/kernel_isolate.cc b/runtime/vm/kernel_isolate.cc index 9d48243aa55..9b804c78e21 100644 --- a/runtime/vm/kernel_isolate.cc +++ b/runtime/vm/kernel_isolate.cc @@ -370,10 +370,6 @@ class KernelCompilationRequest : public ValueObject { suppress_warnings.type = Dart_CObject_kBool; suppress_warnings.value.as_bool = FLAG_suppress_fe_warnings; - Dart_CObject dart_sync_async; - dart_sync_async.type = Dart_CObject_kBool; - dart_sync_async.value.as_bool = FLAG_sync_async; - Dart_CObject* message_arr[] = {&tag, &send_port, &uri, @@ -382,8 +378,7 @@ class KernelCompilationRequest : public ValueObject { &dart_strong, &isolate_id, &files, - &suppress_warnings, - &dart_sync_async}; + &suppress_warnings}; message.value.as_array.values = message_arr; message.value.as_array.length = ARRAY_SIZE(message_arr); // Send the message. diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc index a144a86214d..6e2e6394c31 100644 --- a/runtime/vm/parser.cc +++ b/runtime/vm/parser.cc @@ -7574,42 +7574,30 @@ SequenceNode* Parser::CloseAsyncFunction(const Function& closure, Symbols::AsyncStackTraceVar(), false); ASSERT((existing_var != NULL) && existing_var->is_captured()); - // Create a completer that executes a closure with the current body and - // return the corresponding future. + // Create and return a new future that executes a closure with the current + // body. // No need to capture parameters or other variables, since they have already // been captured in the corresponding scope as the body has been parsed within // a nested block (contained in the async function's block). - - const Library& async_lib = Library::Handle(Z, Library::AsyncLibrary()); + const Class& future = Class::ZoneHandle(Z, I->object_store()->future_class()); + ASSERT(!future.IsNull()); + const Function& constructor = Function::ZoneHandle( + Z, future.LookupFunction(Symbols::FutureMicrotask())); + ASSERT(!constructor.IsNull()); + const Class& completer = + Class::ZoneHandle(Z, I->object_store()->completer_class()); + ASSERT(!completer.IsNull()); + const Function& completer_constructor = Function::ZoneHandle( + Z, completer.LookupFunction(Symbols::CompleterSyncConstructor())); + ASSERT(!completer_constructor.IsNull()); LocalVariable* async_completer = current_block_->scope->LookupVariable(Symbols::AsyncCompleter(), false); const TokenPosition token_pos = ST(closure_body->token_pos()); - - Function& completer_constructor = Function::ZoneHandle(Z); - if (FLAG_sync_async) { - const Class& completer_class = Class::Handle( - Z, async_lib.LookupClassAllowPrivate(Symbols::_AsyncAwaitCompleter())); - ASSERT(!completer_class.IsNull()); - completer_constructor = completer_class.LookupConstructorAllowPrivate( - Symbols::_AsyncAwaitCompleterConstructor()); - ASSERT(!completer_constructor.IsNull()); - - // Add to AST: - // :async_completer = new _AsyncAwaitCompleter(); - } else { - const Class& completer = - Class::Handle(Z, I->object_store()->completer_class()); - ASSERT(!completer.IsNull()); - completer_constructor = - completer.LookupFunction(Symbols::CompleterSyncConstructor()); - ASSERT(!completer_constructor.IsNull()); - - // Add to AST: - // :async_completer = new Completer.sync(); - } + // Add to AST: + // :async_completer = new Completer.sync(); ArgumentListNode* empty_args = new (Z) ArgumentListNode(token_pos); ConstructorCallNode* completer_constructor_node = new (Z) ConstructorCallNode(token_pos, TypeArguments::ZoneHandle(Z), @@ -7636,6 +7624,8 @@ SequenceNode* Parser::CloseAsyncFunction(const Function& closure, new (Z) StoreLocalNode(token_pos, async_op_var, cn); current_block_->statements->Add(store_async_op); + const Library& async_lib = Library::Handle(Library::AsyncLibrary()); + if (FLAG_causal_async_stacks) { // Add to AST: // :async_stack_trace = _asyncStackTraceHelper(); @@ -7699,29 +7689,13 @@ SequenceNode* Parser::CloseAsyncFunction(const Function& closure, current_block_->statements->Add(store_async_catch_error_callback); - if (FLAG_sync_async) { - // Add to AST: - // :async_completer.start(:async_op); - ArgumentListNode* arguments = new (Z) ArgumentListNode(token_pos); - arguments->Add(new (Z) LoadLocalNode(token_pos, async_op_var)); - InstanceCallNode* start_call = new (Z) InstanceCallNode( - token_pos, new (Z) LoadLocalNode(token_pos, async_completer), - Symbols::_AsyncAwaitStart(), arguments); - current_block_->statements->Add(start_call); - } else { - // Add to AST: - // new Future.microtask(:async_op); - const Class& future = Class::Handle(Z, I->object_store()->future_class()); - ASSERT(!future.IsNull()); - const Function& constructor = Function::ZoneHandle( - Z, future.LookupFunction(Symbols::FutureMicrotask())); - ASSERT(!constructor.IsNull()); - ArgumentListNode* arguments = new (Z) ArgumentListNode(token_pos); - arguments->Add(new (Z) LoadLocalNode(token_pos, async_op_var)); - ConstructorCallNode* future_node = new (Z) ConstructorCallNode( - token_pos, TypeArguments::ZoneHandle(Z), constructor, arguments); - current_block_->statements->Add(future_node); - } + // Add to AST: + // new Future.microtask(:async_op); + ArgumentListNode* arguments = new (Z) ArgumentListNode(token_pos); + arguments->Add(new (Z) LoadLocalNode(token_pos, async_op_var)); + ConstructorCallNode* future_node = new (Z) ConstructorCallNode( + token_pos, TypeArguments::ZoneHandle(Z), constructor, arguments); + current_block_->statements->Add(future_node); // Add to AST: // return :async_completer.future; diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h index 276657a005c..0d2dfcd79ed 100644 --- a/runtime/vm/symbols.h +++ b/runtime/vm/symbols.h @@ -145,9 +145,6 @@ class ObjectPointerVisitor; V(CompleterComplete, "complete") \ V(CompleterCompleteError, "completeError") \ V(CompleterSyncConstructor, "Completer.sync") \ - V(_AsyncAwaitCompleter, "_AsyncAwaitCompleter") \ - V(_AsyncAwaitCompleterConstructor, "_AsyncAwaitCompleter.") \ - V(_AsyncAwaitStart, "start") \ V(CompleterFuture, "future") \ V(StreamIterator, "StreamIterator") \ V(StreamIteratorConstructor, "StreamIterator.") \ diff --git a/sdk/lib/_internal/js_runtime/lib/async_patch.dart b/sdk/lib/_internal/js_runtime/lib/async_patch.dart index bec28e99632..be475bd7f36 100644 --- a/sdk/lib/_internal/js_runtime/lib/async_patch.dart +++ b/sdk/lib/_internal/js_runtime/lib/async_patch.dart @@ -132,53 +132,6 @@ class Timer { } } -class _AsyncAwaitCompleter implements Completer { - final _completer = new Completer.sync(); - bool isSync; - - _AsyncAwaitCompleter() : isSync = false; - - void complete([FutureOr value]) { - if (isSync) { - _completer.complete(value); - } else if (value is Future) { - value.then(_completer.complete, onError: _completer.completeError); - } else { - scheduleMicrotask(() { - _completer.complete(value); - }); - } - } - - void completeError(e, [st]) { - if (isSync) { - _completer.completeError(e, st); - } else { - scheduleMicrotask(() { - _completer.completeError(e, st); - }); - } - } - - Future get future => _completer.future; - bool get isCompleted => _completer.isCompleted; -} - -/// Initiates the computation of an `async` function and starts the body -/// synchronously. -/// -/// Used as part of the runtime support for the async/await transformation. -/// -/// This function sets up the first call into the transformed [bodyFunction]. -/// Independently, it takes the [completer] and returns the future of the -/// completer for convenience of the transformed code. -dynamic _asyncStartSync( - _WrappedAsyncBody bodyFunction, _AsyncAwaitCompleter completer) { - bodyFunction(async_error_codes.SUCCESS, null); - completer.isSync = true; - return completer.future; -} - /// Initiates the computation of an `async` function. /// /// Used as part of the runtime support for the async/await transformation. diff --git a/tests/language_2/async_await_test.dart b/tests/language_2/async_await_test.dart index 7c19b9c0a89..4048692401c 100644 --- a/tests/language_2/async_await_test.dart +++ b/tests/language_2/async_await_test.dart @@ -19,8 +19,8 @@ main() { return expect42(f()); }); - test("async starts synchronously", () { - // Calling an "async" function starts immediately. + test("async waits", () { + // Calling an "async" function won't do anything immediately. var result = []; f() async { result.add(1); @@ -31,7 +31,7 @@ main() { var future = f(); result.add(0); return future.whenComplete(() { - expect(result, equals([1, 0])); + expect(result, equals([0, 1])); }); }); @@ -184,6 +184,7 @@ main() { return new Future.error("err"); // Not awaited. } + ; return throwsErr(f()); }); diff --git a/tests/language_2/async_call_test.dart b/tests/language_2/async_call_test.dart index bc107b659e0..a3643f91263 100644 --- a/tests/language_2/async_call_test.dart +++ b/tests/language_2/async_call_test.dart @@ -14,8 +14,6 @@ foo() { bar() async { result += "bar"; - await null; - result += "bar2"; } main() { @@ -23,13 +21,13 @@ main() { () async { var f = new Future(foo); var b = bar(); - Expect.equals("bar", result); + Expect.equals("", result); scheduleMicrotask(() => result += "micro"); await b; await f; // Validates that bar is scheduled as a microtask, before foo. - Expect.equals("barbar2microfoo", result); + Expect.equals("barmicrofoo", result); asyncEnd(); }(); } diff --git a/tests/language_2/async_error_timing_test.dart b/tests/language_2/async_error_timing_test.dart deleted file mode 100644 index 4b840c75384..00000000000 --- a/tests/language_2/async_error_timing_test.dart +++ /dev/null @@ -1,264 +0,0 @@ -// Copyright (c) 2017, 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 'dart:async'; -import 'package:expect/expect.dart'; -import 'package:async_helper/async_helper.dart'; - -class AsyncTracker { - int runningAsyncs = 0; - List expectedEvents; - final List actualEvents = []; - - AsyncTracker() { - asyncStart(); - } - - void start(String event) { - actualEvents.add("start $event"); - runningAsyncs++; - } - - void stop(String event) { - actualEvents.add("stop $event"); - if (--runningAsyncs == 0) { - Expect.listEquals(expectedEvents, actualEvents); - asyncEnd(); - } - } - - void add(e) { - actualEvents.add(e); - } -} - -void test1() { - var tracker = new AsyncTracker(); - - Future foo() async { - tracker.add("error-foo"); - throw "foo"; - } - - tracker.start("micro1"); - scheduleMicrotask(() { - tracker.start("micro2"); - scheduleMicrotask(() { - tracker.stop("micro2"); - }); - tracker.stop("micro1"); - }); - - tracker.start("foo"); - foo().catchError((e) { - tracker.stop("foo"); - }); - tracker.start("micro3"); - scheduleMicrotask(() { - tracker.stop("micro3"); - }); - - tracker.expectedEvents = [ - "start micro1", - "start foo", - "error-foo", - "start micro3", - "start micro2", - "stop micro1", - "stop foo", - "stop micro3", - "stop micro2", - ]; -} - -void test2() { - var tracker = new AsyncTracker(); - - Future bar() async { - tracker.add("await null"); - await null; - tracker.add("error-bar"); - throw "bar"; - } - - tracker.start("micro1"); - scheduleMicrotask(() { - tracker.start("micro2"); - scheduleMicrotask(() { - tracker.start("micro3"); - scheduleMicrotask(() { - tracker.stop("micro3"); - }); - tracker.stop("micro2"); - }); - tracker.stop("micro1"); - }); - - tracker.start("bar"); - bar().catchError((e) { - tracker.stop("bar"); - }); - tracker.start("micro4"); - scheduleMicrotask(() { - tracker.start("micro5"); - scheduleMicrotask(() { - tracker.stop("micro5"); - }); - tracker.stop("micro4"); - }); - - tracker.expectedEvents = [ - "start micro1", - "start bar", - "await null", - "start micro4", - "start micro2", - "stop micro1", - "error-bar", - "stop bar", - "start micro5", - "stop micro4", - "start micro3", - "stop micro2", - "stop micro5", - "stop micro3", - ]; -} - -void test3() { - var tracker = new AsyncTracker(); - - Future gee() async { - tracker.add("error-gee"); - return new Future.error("gee"); - } - - tracker.start("micro1"); - scheduleMicrotask(() { - tracker.start("micro2"); - scheduleMicrotask(() { - tracker.stop("micro2"); - }); - tracker.stop("micro1"); - }); - - tracker.start("gee"); - gee().catchError((e) { - tracker.stop("gee"); - }); - tracker.start("micro3"); - scheduleMicrotask(() { - tracker.stop("micro3"); - }); - - tracker.expectedEvents = [ - "start micro1", - "start gee", - "error-gee", - "start micro3", - "start micro2", - "stop micro1", - "stop gee", - "stop micro3", - "stop micro2", - ]; -} - -void test4() { - var tracker = new AsyncTracker(); - - Future toto() async { - tracker.add("await null"); - await null; - tracker.add("error-toto"); - return new Future.error("toto"); - } - - tracker.start("micro1"); - scheduleMicrotask(() { - tracker.start("micro2"); - scheduleMicrotask(() { - tracker.start("micro3"); - scheduleMicrotask(() { - tracker.stop("micro3"); - }); - tracker.stop("micro2"); - }); - tracker.stop("micro1"); - }); - - tracker.start("toto"); - toto().catchError((e) { - tracker.stop("toto"); - }); - tracker.start("micro4"); - scheduleMicrotask(() { - tracker.start("micro5"); - scheduleMicrotask(() { - tracker.stop("micro5"); - }); - tracker.stop("micro4"); - }); - - tracker.expectedEvents = [ - "start micro1", - "start toto", - "await null", - "start micro4", - "start micro2", - "stop micro1", - "error-toto", - "start micro5", - "stop micro4", - "start micro3", - "stop micro2", - "stop toto", - "stop micro5", - "stop micro3", - ]; -} - -void test5() { - var tracker = new AsyncTracker(); - - Future foo() async { - tracker.add("throw"); - throw "foo"; - } - - bar() async { - tracker.start('micro'); - scheduleMicrotask(() { - tracker.stop('micro'); - }); - try { - tracker.start('foo'); - await foo(); - } catch (e) { - tracker.stop('foo'); - } - tracker.stop("bar"); - } - - tracker.start('bar'); - - tracker.expectedEvents = [ - "start bar", - "start micro", - "start foo", - "throw", - "stop micro", - "stop foo", - "stop bar", - ]; -} - -main() { - asyncStart(); - test1(); - test2(); - test3(); - test4(); - asyncEnd(); -} diff --git a/tests/language_2/asyncstar_throw_in_catch_test.dart b/tests/language_2/asyncstar_throw_in_catch_test.dart index 884b492c57e..e1a3a9550b7 100644 --- a/tests/language_2/asyncstar_throw_in_catch_test.dart +++ b/tests/language_2/asyncstar_throw_in_catch_test.dart @@ -40,9 +40,9 @@ foo1(Tracer tracer) async* { yield 3; tracer.trace("f"); } finally { - tracer.trace("g"); + tracer.trace("f"); } - tracer.trace("h"); + tracer.trace("g"); } foo2(Tracer tracer) async* { @@ -116,10 +116,10 @@ runTest(test, expectedTrace, expectedError, shouldCancel) { test() async { // TODO(sigurdm): These tests are too dependent on scheduling, and buffering // behavior. - await runTest(foo1, "abcYdgC", null, true); + await runTest(foo1, "abcdYefC", null, true); await runTest(foo2, "abcX", "Error", false); await runTest(foo3, "abcYX", "Error", false); - await runTest(foo4, "abcYdYefX", "Error2", false); + await runTest(foo4, "abcdYeYfX", "Error2", false); } void main() { diff --git a/tests/language_2/await_nonfuture_test.dart b/tests/language_2/await_nonfuture_test.dart index 1aa6855ff6d..739f73aa37f 100644 --- a/tests/language_2/await_nonfuture_test.dart +++ b/tests/language_2/await_nonfuture_test.dart @@ -5,23 +5,16 @@ // VMOptions=--optimization-counter-threshold=5 import 'package:expect/expect.dart'; -import 'package:async_helper/async_helper.dart'; var X = 0; foo() async { - Expect.equals(X, 0); - await 5; - Expect.equals(X, 10); - return await 499; + Expect.equals(X, 10); // foo runs after main returns. + return await 5; } main() { - asyncStart(); var f = foo(); - f.then((res) { - Expect.equals(499, res); - asyncEnd(); - }); + f.then((res) => print("f completed with $res")); X = 10; } diff --git a/tests/language_2/await_started_immediately_test.dart b/tests/language_2/await_not_started_immediately_test.dart similarity index 84% rename from tests/language_2/await_started_immediately_test.dart rename to tests/language_2/await_not_started_immediately_test.dart index c21591f5c0b..5101c58b697 100644 --- a/tests/language_2/await_started_immediately_test.dart +++ b/tests/language_2/await_not_started_immediately_test.dart @@ -2,7 +2,7 @@ // 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. -// Test that an async function does start immediately. +// Test that an async function does not start immediately. import "package:expect/expect.dart"; import "package:async_helper/async_helper.dart"; @@ -18,5 +18,5 @@ foo() async { void main() { asyncStart(); foo().then((_) => Expect.equals(2, x)).whenComplete(asyncEnd); - Expect.equals(1, x); + Expect.equals(0, x); } diff --git a/tests/lib_2/async/async_await_sync_completer_test.dart b/tests/lib_2/async/async_await_sync_completer_test.dart index 889632f04ba..b6887d6b2bf 100644 --- a/tests/lib_2/async/async_await_sync_completer_test.dart +++ b/tests/lib_2/async/async_await_sync_completer_test.dart @@ -13,10 +13,6 @@ var delayedValue = new Completer(); var delayedError = new Completer(); foo() async { - // Because of this `await null` the function returns and lets the caller - // install handlers. When the function finishes, it can then synchronously - // propagate the values. - await null; new Future.microtask(() => 'in microtask') .then(events.add) .then(delayedValue.complete); @@ -24,10 +20,6 @@ foo() async { } bar() async { - // Because of this `await null` the function returns and lets the caller - // install handlers. When the function finishes, it can then synchronously - // propagate the values. - await null; new Future.microtask(() => throw 'in microtask error') .catchError(events.add) .then(delayedError.complete); diff --git a/tests/lib_2/lib_2_dart2js.status b/tests/lib_2/lib_2_dart2js.status index e2f50327ffc..6cd6ce01b44 100644 --- a/tests/lib_2/lib_2_dart2js.status +++ b/tests/lib_2/lib_2_dart2js.status @@ -89,7 +89,6 @@ html/fileapi_directory_test: Fail # TODO(dart2js-team): Please triage this failu html/fileapi_entry_test: Pass, Fail # TODO(dart2js-team): Please triage this failure. html/fileapi_file_test: Fail # TODO(dart2js-team): Please triage this failure. html/media_stream_test: RuntimeError # Please triage. -html/notification_permission_test: Timeout # Issue 32002 html/speechrecognition_test: RuntimeError # Please triage. isolate/function_send_test: Skip # Crashes Chrome 62: https://bugs.chromium.org/p/chromium/issues/detail?id=775506 isolate/kill_self_synchronously_test: RuntimeError diff --git a/tests/lib_2/lib_2_dartdevc.status b/tests/lib_2/lib_2_dartdevc.status index dd36b163f5f..5881198e03c 100644 --- a/tests/lib_2/lib_2_dartdevc.status +++ b/tests/lib_2/lib_2_dartdevc.status @@ -104,7 +104,6 @@ html/js_util_test: RuntimeError # Issue 29922 html/media_stream_test: RuntimeError # Issue 29922 html/mediasource_test: RuntimeError # Issue 29922 html/no_linked_scripts_htmltest: Skip # Issue 29919 -html/notification_permission_test: Timeout # Issue 32002 html/scripts_htmltest: Skip # Issue 29919 html/transferables_test: CompileTimeError # Issue 30975 html/transition_event_test: Pass, RuntimeError, Timeout # Issue 29922, this test seems flaky diff --git a/tools/testing/dart/browser_test.dart b/tools/testing/dart/browser_test.dart index 19b39a73b45..011aa2d396d 100644 --- a/tools/testing/dart/browser_test.dart +++ b/tools/testing/dart/browser_test.dart @@ -40,8 +40,7 @@ String dart2jsHtml(String title, String scriptPath) { /// The [testName] is the short name of the test without any subdirectory path /// or extension, like "math_test". The [testJSDir] is the relative path to the /// build directory where the dartdevc-generated JS file is stored. -String dartdevcHtml(String testName, String testJSDir, String buildDir, - {bool syncAsync}) { +String dartdevcHtml(String testName, String testJSDir, String buildDir) { var packagePaths = testPackages .map((package) => ' "$package": "/root_dart/$buildDir/gen/utils/' 'dartdevc/pkg/$package",') @@ -87,7 +86,7 @@ window.ddcSettings = { requirejs(["$testName", "dart_sdk", "async_helper"], function($testName, sdk, async_helper) { sdk.dart.ignoreWhitelistedErrors(false); - if ($syncAsync) sdk.dart.setStartAsyncSynchronously(); + // TODO(rnystrom): This uses DDC's forked version of async_helper. Unfork // these packages when possible. async_helper.async_helper.asyncTestInitialize(function() {}); diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart index 2e16e4a75f5..62cee3fbd36 100644 --- a/tools/testing/dart/test_suite.dart +++ b/tools/testing/dart/test_suite.dart @@ -814,12 +814,6 @@ class StandardTestSuite extends TestSuite { var commonArguments = commonArgumentsFromFile(info.filePath, info.optionsFromFile); - // TODO(floitsch): Hack. When running the 2.0 tests always start - // async functions synchronously. - if (suiteName.endsWith("_2")) { - commonArguments.insert(0, "--sync-async"); - } - var vmOptionsList = getVmOptions(info.optionsFromFile); assert(!vmOptionsList.isEmpty); @@ -1032,37 +1026,13 @@ class StandardTestSuite extends TestSuite { } else { var jsDir = new Path(compilationTempDir).relativeTo(Repository.dir).toString(); - // Always run with synchronous starts of `async` functions. - // If we want to make this dependent on other parameters or flags, - // this flag could be become conditional. - content = dartdevcHtml(nameNoExt, jsDir, buildDir, syncAsync: true); + content = dartdevcHtml(nameNoExt, jsDir, buildDir); } } var htmlPath = '$tempDir/test.html'; new File(htmlPath).writeAsStringSync(content); - // TODO(floitsch): Hack. When running the 2.0 tests always start - // async functions synchronously. - if (suiteName.endsWith("_2") && - configuration.compiler == Compiler.dart2js) { - if (optionsFromFile == null) { - optionsFromFile = const { - 'sharedOptions': const ['--sync-async'] - }; - } else { - optionsFromFile = new Map.from(optionsFromFile); - var sharedOptions = optionsFromFile['sharedOptions']; - if (sharedOptions == null) { - sharedOptions = const ['--sync-async']; - } else { - sharedOptions = sharedOptions.toList(); - sharedOptions.insert(0, "--sync-async"); - } - optionsFromFile['sharedOptions'] = sharedOptions; - } - } - // Construct the command(s) that compile all the inputs needed by the // browser test. For running Dart in DRT, this will be noop commands. var commands = [];