[cfe] Add test folder for dart2wasm

This adds support for testing how the dart2wasm target implementation
integrates with the CFE. The added tests show the current state of
the for-in and yield transformations performed by wasm.

Change-Id: I7fc1efab22311667dcf4357ba54fa45321581074
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/278000
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Aske Simon Christensen <askesc@google.com>
This commit is contained in:
Johnni Winther 2023-01-02 15:43:58 +00:00 committed by Commit Queue
parent ece7da8009
commit e42bb83d32
14 changed files with 212 additions and 1 deletions

View file

@ -64,6 +64,17 @@ String? computePlatformDillName(
return "vm_platform_strong.dill";
case 'none':
return "vm_platform_strong.dill";
case 'wasm':
switch (nnbdMode) {
case NnbdMode.Strong:
return 'dart2wasm_outline.dill';
//TODO(johnniwinther): Support using the full dill.
//return 'dart2wasm_platform.dill';
case NnbdMode.Weak:
case NnbdMode.Agnostic:
break;
}
break;
default:
break;
}

View file

@ -17,6 +17,7 @@ import 'package:_fe_analyzer_shared/src/util/options.dart';
import 'package:compiler/src/kernel/dart2js_target.dart';
import 'package:compiler/src/options.dart' as dart2jsOptions
show CompilerOptions;
import 'package:dart2wasm/target.dart';
import 'package:dev_compiler/src/kernel/target.dart';
import 'package:front_end/src/api_prototype/compiler_options.dart'
show
@ -866,7 +867,8 @@ class Run extends Step<ComponentResult, ComponentResult, FastaContext> {
case "none":
case "dart2js":
case "dartdevc":
// TODO(johnniwinther): Support running dart2js and/or dartdevc.
case "wasm":
// TODO(johnniwinther): Support running dart2js, dartdevc and/or wasm.
return pass(result);
default:
throw new ArgumentError(
@ -2198,6 +2200,9 @@ Target createTarget(FolderOptions folderOptions, FastaContext context) {
case "dartdevc":
target = new TestDevCompilerTarget(targetFlags);
break;
case "wasm":
target = new TestWasmTarget(targetFlags);
break;
default:
throw new ArgumentError(
"Unsupported test target '${folderOptions.target}'.");
@ -2559,6 +2564,13 @@ class TestVmTarget extends VmTarget with TestTarget, TestTargetMixin {
TestVmTarget(this.flags) : super(flags);
}
class TestWasmTarget extends WasmTarget with TestTarget, TestTargetMixin {
@override
final TestTargetFlags flags;
TestWasmTarget(this.flags);
}
class EnsureNoErrors
extends Step<ComponentResult, ComponentResult, FastaContext> {
const EnsureNoErrors();

View file

@ -0,0 +1 @@
--target=wasm

View file

@ -0,0 +1,15 @@
// Copyright (c) 2023, 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.
method(Iterable<int> iterable) {
for (int i in iterable) {
print(i);
}
}
asyncMethod(Stream<int> stream) async {
await for (int i in stream) {
print(i);
}
}

View file

@ -0,0 +1,15 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
import "dart:async" as asy;
static method method(core::Iterable<core::int> iterable) → dynamic {
for (core::int i in iterable) {
core::print(i);
}
}
static method asyncMethod(asy::Stream<core::int> stream) → dynamic async /* futureValueType= dynamic */ {
await for (core::int i in stream) {
core::print(i);
}
}

View file

@ -0,0 +1,38 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
import "dart:async" as asy;
static method method(core::Iterable<core::int> iterable) → dynamic {
{
core::Iterator<core::int> #forIterator = iterable.{core::Iterable::iterator}{core::Iterator<core::int>};
for (; #forIterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
core::int i = #forIterator.{core::Iterator::current}{core::int};
{
core::print(i);
}
}
}
}
static method asyncMethod(asy::Stream<core::int> stream) → dynamic async /* futureValueType= dynamic */ {
{
asy::_StreamIterator<core::int> #forIterator = new asy::_StreamIterator::•<core::int>(stream);
core::bool #jumpSentinel = #C1;
try {
for (; #jumpSentinel = await #forIterator.{asy::_StreamIterator::moveNext}(){() → asy::Future<core::bool>}; ) {
core::int i = #forIterator.{asy::_StreamIterator::current}{core::int};
{
core::print(i);
}
}
}
finally {
if(#jumpSentinel)
await #forIterator.{asy::_StreamIterator::cancel}(){() → asy::Future<dynamic>};
}
}
}
constants {
#C1 = false
}

View file

@ -0,0 +1,2 @@
method(Iterable<int> iterable) {}
asyncMethod(Stream<int> stream) async {}

View file

@ -0,0 +1,2 @@
asyncMethod(Stream<int> stream) async {}
method(Iterable<int> iterable) {}

View file

@ -0,0 +1,15 @@
// Copyright (c) 2023, 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.
Iterable<int> method(Iterable<int> iterable) sync* {
yield 1;
yield 2;
yield* iterable;
}
Stream<int> asyncMethod(Stream<int> stream) async* {
yield 1;
yield 2;
yield* stream;
}

View file

@ -0,0 +1,15 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
import "dart:async" as asy;
static method method(core::Iterable<core::int> iterable) → core::Iterable<core::int> sync* {
yield 1;
yield 2;
yield* iterable;
}
static method asyncMethod(asy::Stream<core::int> stream) → asy::Stream<core::int> async* {
yield 1;
yield 2;
yield* stream;
}

View file

@ -0,0 +1,78 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
import "dart:async" as asy;
static method method(core::Iterable<core::int> iterable) → core::Iterable<core::int> sync* {
yield 1;
yield 2;
yield* iterable;
}
static method asyncMethod(asy::Stream<core::int> stream) → asy::Stream<core::int> {
asy::StreamController<core::Object?> #controller = asy::StreamController::•<core::Object?>();
() → asy::Future<void> #body = () → asy::Future<void> async /* futureValueType= void */ {
asy::Completer<core::bool> #completer = asy::Completer::•<core::bool>();
#controller.{asy::StreamController::add}(#completer){(core::Object?) → void};
await #completer.{asy::Completer::future}{() → asy::Future<core::bool>};
{
{
#controller.{asy::StreamController::add}(1){(core::Object?) → void};
#completer = asy::Completer::•<core::bool>();
#controller.{asy::StreamController::add}(#completer){(core::Object?) → void};
await #completer.{asy::Completer::future}{() → asy::Future<core::bool>};
}
{
#controller.{asy::StreamController::add}(2){(core::Object?) → void};
#completer = asy::Completer::•<core::bool>();
#controller.{asy::StreamController::add}(#completer){(core::Object?) → void};
await #completer.{asy::Completer::future}{() → asy::Future<core::bool>};
}
{
asy::_StreamIterator<core::int> #forIterator = new asy::_StreamIterator::•<core::int>(stream);
core::bool #jumpSentinel = #C1;
try {
for (; #jumpSentinel = await #forIterator.{asy::_StreamIterator::moveNext}(){() → asy::Future<core::bool>}; ) {
core::int #awaitForVar = #forIterator.{asy::_StreamIterator::current}{core::int};
{
#controller.{asy::StreamController::add}(#awaitForVar){(core::Object?) → void};
#completer = asy::Completer::•<core::bool>();
#controller.{asy::StreamController::add}(#completer){(core::Object?) → void};
await #completer.{asy::Completer::future}{() → asy::Future<core::bool>};
}
}
}
finally {
if(#jumpSentinel)
await #forIterator.{asy::_StreamIterator::cancel}(){() → asy::Future<dynamic>};
}
}
}
#controller.{asy::StreamController::close}(){() → asy::Future<dynamic>};
};
core::bool #isFirst = #C2;
core::bool #isEven = #C1;
#controller.{asy::StreamController::add}(#C3){(core::Object?) → void};
return #controller.{asy::StreamController::stream}{() → asy::Stream<core::Object?>}.{asy::Stream::asyncMap}<core::Object?>((core::Object? value) → FutureOr<core::Object?> async /* futureValueType= core::Object? */ {
if(#isFirst) {
#body(){() → asy::Future<void>};
return #C3;
}
if(value is asy::Completer<core::bool>)
value.{asy::Completer::complete}(#C2){([FutureOr<core::bool>?]) → void};
return value;
}){((core::Object?) → FutureOr<core::Object?>) → asy::Stream<core::Object?>}.{asy::Stream::where}((core::Object? value) → core::Object? {
if(#isFirst) {
#isFirst = #C1;
return #C1;
}
core::bool keep = #isEven;
#isEven = !#isEven;
return keep;
}){((core::Object?) → core::bool) → asy::Stream<core::Object?>}.{asy::Stream::cast}<core::int>(){() → asy::Stream<core::int>};
}
constants {
#C1 = false
#C2 = true
#C3 = null
}

View file

@ -0,0 +1,2 @@
Iterable<int> method(Iterable<int> iterable) sync* {}
Stream<int> asyncMethod(Stream<int> stream) async* {}

View file

@ -0,0 +1,2 @@
Iterable<int> method(Iterable<int> iterable) sync* {}
Stream<int> asyncMethod(Stream<int> stream) async* {}

View file

@ -44,6 +44,7 @@
"/testcases/.*_part[0-9]*\\.dart$",
"/testcases/.*_lib[0-9]*\\.dart$",
"/testcases/dartino/",
"/testcases/dart2wasm/",
"/testcases/expression/"
]
},
@ -79,6 +80,7 @@
"/testcases/.*_part[0-9]*\\.dart$",
"/testcases/.*_lib[0-9]*\\.dart$",
"/testcases/dartino/",
"/testcases/dart2wasm/",
"/testcases/expression/"
]
},
@ -96,6 +98,7 @@
"/testcases/.*_part[0-9]*\\.dart$",
"/testcases/.*_lib[0-9]*\\.dart$",
"/testcases/dartino/",
"/testcases/dart2wasm/",
"/testcases/expression/"
]
},