Revert "Run async functions immediately."

This reverts commit 67bac0bce6.

Reason for revert: broke the bot.

Original change's description:
> Run async functions immediately.
> 
> Migrated from https://codereview.chromium.org/2478703003/
> 
> Change-Id: I1d678c01ba5876490b12c676c500171328361d31
> Reviewed-on: https://dart-review.googlesource.com/5263
> Commit-Queue: Florian Loitsch <floitsch@google.com>
> Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
> Reviewed-by: Vijay Menon <vsm@google.com>
> Reviewed-by: William Hesse <whesse@google.com>
> Reviewed-by: Martin Kustermann <kustermann@google.com>
> Reviewed-by: Régis Crelier <regis@google.com>

TBR=whesse@google.com,rnystrom@google.com,vegorov@google.com,kustermann@google.com,zra@google.com,floitsch@google.com,jmesserly@google.com,vsm@google.com,regis@google.com,sigmund@google.com

Change-Id: I20c948057423c3fa5aa8c72843f8f2a17e086ad5
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://dart-review.googlesource.com/37981
Reviewed-by: Florian Loitsch <floitsch@google.com>
Reviewed-by: William Hesse <whesse@google.com>
This commit is contained in:
Florian Loitsch
2018-02-01 15:01:21 +00:00
parent c3b992dcd8
commit 032be73dbe
36 changed files with 116 additions and 698 deletions
-3
View File
@@ -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
@@ -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';
@@ -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");
-1
View File
@@ -355,7 +355,6 @@ Future<api.CompilationResult> compile(List<String> 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),
+7 -17
View File
@@ -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;
@@ -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 = <ClassEntity>[];
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;
-7
View File
@@ -276,9 +276,6 @@ class CompilerOptions implements DiagnosticOptions {
/// Strip option used by dart2dart.
final List<String> 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;
-7
View File
@@ -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) {
@@ -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_<T>(Function() initGenerator) {
onError = zone.registerUnaryCallback(onError);
}
var asyncFuture = new _Future<T>();
var body = () {
scheduleMicrotask(() {
try {
iter = JS('', '#[Symbol.iterator]()', initGenerator());
var iteratorValue = JS('', '#.next(null)', iter);
@@ -99,20 +97,9 @@ async_<T>(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;
}
@@ -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")');
+1 -5
View File
@@ -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(
+2 -6
View File
@@ -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<String> arguments) async {
if (arguments.isNotEmpty && arguments[0] == '--batch') {
@@ -72,7 +69,6 @@ Future<CompilerOutcome> runTransformation(List<String> 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<CompilerOutcome> runTransformation(List<String> 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(
-12
View File
@@ -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');
+5 -9
View File
@@ -15,20 +15,16 @@ import 'vmreify.dart' show VmGenericTypesReifiedTarget;
final List<String> targetNames = targets.keys.toList();
class TargetFlags {
final bool strongMode;
final bool treeShake;
/// Whether `async` functions start synchronously.
final bool syncAsync;
final List<ProgramRoot> programRoots;
final Uri kernelRuntime;
bool strongMode;
bool treeShake;
List<ProgramRoot> programRoots;
Uri kernelRuntime;
TargetFlags(
{this.strongMode: false,
this.treeShake: false,
this.syncAsync: false,
this.programRoots: const <ProgramRoot>[],
this.kernelRuntime});
this.kernelRuntime}) {}
}
typedef Target _TargetBuilder(TargetFlags flags);
+1 -1
View File
@@ -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");
}
+1 -1
View File
@@ -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);
+2 -2
View File
@@ -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);
}
}
@@ -12,34 +12,29 @@ import '../visitor.dart';
import 'async.dart';
void transformLibraries(
CoreTypes coreTypes, List<Library> libraries, bool syncAsync) {
void transformLibraries(CoreTypes coreTypes, List<Library> 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<Statement> 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 = <Statement>[];
@@ -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 = <Statement>[];
@@ -888,29 +877,16 @@ class AsyncFunctionRewriter extends AsyncRewriterBase {
final DartType returnType =
new InterfaceType(helper.futureOrClass, <DartType>[valueType]);
var completerTypeArguments = <DartType>[valueType];
var completerType =
new InterfaceType(helper.completerClass, completerTypeArguments);
if (syncAsync) {
final completerType = new InterfaceType(
helper.asyncAwaitCompleterClass, completerTypeArguments);
// final Completer<T> :completer = new _AsyncAwaitCompleter<T>();
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<T> :completer = new Completer<T>.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<T> :completer = new Completer<T>.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,
+10 -26
View File
@@ -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<Program> 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<Program> compileInternal(Uri script) async {
@@ -147,9 +138,7 @@ final Map<int, Compiler> isolateCompilers = new Map<int, Compiler>();
Future<Compiler> 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<Compiler> 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);
}
-37
View File
@@ -17,43 +17,6 @@ import "dart:_internal" show VMLibraryHooks, patch;
// Equivalent of calling FATAL from C++ code.
_fatal(msg) native "DartAsync_fatal";
class _AsyncAwaitCompleter<T> implements Completer<T> {
final _completer = new Completer<T>.sync();
bool isSync;
_AsyncAwaitCompleter() : isSync = false;
void complete([FutureOr<T> value]) {
if (isSync) {
_completer.complete(value);
} else if (value is Future<T>) {
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<T> 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.
-1
View File
@@ -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.") \
+1 -6
View File
@@ -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.
+24 -50
View File
@@ -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;
-3
View File
@@ -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.") \
@@ -132,53 +132,6 @@ class Timer {
}
}
class _AsyncAwaitCompleter<T> implements Completer<T> {
final _completer = new Completer<T>.sync();
bool isSync;
_AsyncAwaitCompleter() : isSync = false;
void complete([FutureOr<T> value]) {
if (isSync) {
_completer.complete(value);
} else if (value is Future<T>) {
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<T> 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.
+4 -3
View File
@@ -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());
});
+2 -4
View File
@@ -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();
}();
}
@@ -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();
}
@@ -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() {
+3 -10
View File
@@ -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;
}
@@ -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);
}
@@ -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);
-1
View File
@@ -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
-1
View File
@@ -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
+2 -3
View File
@@ -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() {});
+1 -31
View File
@@ -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 <String, dynamic>{
'sharedOptions': const ['--sync-async']
};
} else {
optionsFromFile = new Map<String, dynamic>.from(optionsFromFile);
var sharedOptions = optionsFromFile['sharedOptions'];
if (sharedOptions == null) {
sharedOptions = const <String>['--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 = <Command>[];