Skip to content

Commit

Permalink
Version 3.4.0-50.0.dev
Browse files Browse the repository at this point in the history
Merge 3e46b91 into dev
  • Loading branch information
Dart CI committed Jan 19, 2024
2 parents 7914dae + 3e46b91 commit 80f5952
Show file tree
Hide file tree
Showing 461 changed files with 2,267 additions and 3,034 deletions.
1 change: 0 additions & 1 deletion BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,6 @@ if (is_fuchsia) {
]
resource_files = [
".dart_tool/package_config.json",
"pkg/testing/test/hello_test.dart",
"tools/addlatexhash.dart",
]
resource_dirs = [
Expand Down
5 changes: 4 additions & 1 deletion pkg/dart2wasm/tool/compile_benchmark
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ PROG_NAME="$(follow_links "$BASH_SOURCE")"
PROG_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)"
SDK_DIR="$(cd "${PROG_DIR}/../../.." ; pwd -P)"

# Use same binaryen flags as `dart compile exe`
BINARYEN_FLAGS="$(sed -n '/binaryenFlags =/,/end of binaryenFlags/ p' $SDK_DIR/pkg/dartdev/lib/src/commands/compile.dart | sed '1d' | sed '$d' | tr '\n' ' ')"

# Locate build directory, containing executables, snapshots and platform dill.
if [[ `uname` == 'Darwin' ]]; then
OUT_DIR="$SDK_DIR/xcodebuild"
Expand Down Expand Up @@ -62,7 +65,7 @@ function measure_size() {
dart2wasm_command=("$DART2WASM" "$1" "$2" $COMPILE_FLAGS)

# Keep in sync with sdk/bin/dart2wasm.
binaryen_command=("$BINARYEN" -all --closed-world -tnh --type-unfinalizing -O3 --type-ssa --gufa -O3 --type-merging -O1 --type-finalizing "$2" -o "$2")
binaryen_command=("$BINARYEN" $BINARYEN_FLAGS "$2" -o "$2")

if [ -n "$COMPILE_BENCHMARK_BASE_NAME" ]; then
measure ${dart2wasm_command[@]}
Expand Down
49 changes: 39 additions & 10 deletions pkg/dartdev/lib/src/commands/compile.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,28 @@ import '../sdk.dart';
import '../utils.dart';
import '../vm_interop_handler.dart';

// The unique place where we store dart2wasm binaryen flags.
//
// Other uses (e.g. in shell scripts) will grep in this file for the flags. So
// please keep it as a simple multi-line string of flags.
final List<String> binaryenFlags = '''
--all-features
--closed-world
--traps-never-happen
--type-unfinalizing
-O3
--type-ssa
--gufa
-O3
--type-merging
-O1
--type-finalizing
''' // end of binaryenFlags
.split('\n')
.map((line) => line.trim())
.where((line) => line.isNotEmpty)
.toList();

const int compileErrorExitCode = 64;

class Option {
Expand Down Expand Up @@ -394,11 +416,6 @@ class CompileWasmCommand extends CompileSubcommandCommand {

final String optimizer = path.join(
binDir.path, 'utils', Platform.isWindows ? 'wasm-opt.exe' : 'wasm-opt');
String optimizerFlags(bool outputNames) =>
'-all --closed-world -tnh --type-unfinalizing -O3 --type-ssa'
' --gufa -O3 --type-merging -O1 --type-finalizing'
'${outputNames ? ' -g' : ''}';
static const String unoptExtension = '.unopt';

CompileWasmCommand({bool verbose = false})
: super(commandName, help, verbose, hidden: !verbose) {
Expand Down Expand Up @@ -512,6 +529,14 @@ class CompileWasmCommand extends CompileSubcommandCommand {
outputFile = '$inputWithoutDart.wasm';
}

if (!outputFile.endsWith('.wasm')) {
log.stderr(
'Error: The output file "$outputFile" does not end with ".wasm"');
return 255;
}
final outputFileBasename =
outputFile.substring(0, outputFile.length - '.wasm'.length);

final options = WasmCompilerOptions(
mainUri: Uri.file(path.absolute(sourcePath)),
outputFile: outputFile,
Expand Down Expand Up @@ -556,15 +581,20 @@ class CompileWasmCommand extends CompileSubcommandCommand {
}

if (args['optimize']) {
final unoptFile = outputFile + unoptExtension;
final flags = optimizerFlags(args['name-section']);
final unoptFile = '$outputFileBasename.unopt.wasm';
File(outputFile).renameSync(unoptFile);

final flags = [
...binaryenFlags,
if (args['name-section']) '-g',
];

if (verbose) {
log.stdout('Optimizing output with: $optimizer $flags');
}
final processResult = Process.runSync(
optimizer,
[...flags.split(' '), '-o', outputFile, unoptFile],
[...flags, '-o', outputFile, unoptFile],
);
if (processResult.exitCode != 0) {
log.stderr('Error: Wasm compilation failed while optimizing output');
Expand All @@ -573,8 +603,7 @@ class CompileWasmCommand extends CompileSubcommandCommand {
}
}

final mjsFile =
'${options.outputFile.substring(0, options.outputFile.lastIndexOf('.'))}.mjs';
final mjsFile = '$outputFileBasename.mjs';
log.stdout(
"Generated wasm module '$outputFile', and JS init file '$mjsFile'.");
return result;
Expand Down
22 changes: 20 additions & 2 deletions pkg/dartdev/test/commands/compile_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -791,6 +791,24 @@ void main() {
expect(result.exitCode, 0);
}, skip: isRunningOnIA32);

test('Compile wasm with wrong output filename', () async {
final p = project(mainSrc: 'void main() {}');
final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
final result = await p.run(
[
'compile',
'wasm',
'-o',
'foo',
inFile,
],
);

expect(result.stderr,
contains('Error: The output file "foo" does not end with ".wasm"'));
expect(result.exitCode, 255);
}, skip: isRunningOnIA32);

test('Compile wasm with error', () async {
final p = project(mainSrc: '''
void main() {
Expand All @@ -799,7 +817,7 @@ void main() {
}
''');
final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
final outFile = path.canonicalize(path.join(p.dirPath, 'mywasm'));
final outFile = path.canonicalize(path.join(p.dirPath, 'my.wasm'));

final result = await p.run(
[
Expand Down Expand Up @@ -867,7 +885,7 @@ void main() {
expect(result.exitCode, 0);
expect(File(outFile).existsSync(), true,
reason: 'File not found: $outFile');
});
}, skip: isRunningOnIA32);

test('Compile JS with unsound null safety', () async {
final p = project(mainSrc: '''
Expand Down
3 changes: 2 additions & 1 deletion pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3798,7 +3798,8 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
node.name,
unevaluatedArguments(
positionalArguments, {}, node.arguments.types))
..fileOffset = node.fileOffset);
..fileOffset = node.fileOffset
..flags = node.flags);
}

return _handleInvocation(node, node.name, receiver, positionalArguments,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2391,6 +2391,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
assert(name != equalsName);
Expression expression = new DynamicInvocation(
DynamicAccessKind.Dynamic, receiver, name, arguments)
..isImplicitCall = isImplicitCall
..fileOffset = fileOffset;
return createNullAwareExpressionInferenceResult(
result.inferredType, result.applyResult(expression), nullAwareGuards);
Expand Down Expand Up @@ -2741,6 +2742,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
// the parameters.
expression = new DynamicInvocation(
DynamicAccessKind.Dynamic, receiver, methodName, arguments)
..isImplicitCall = isImplicitCall
..fileOffset = fileOffset;
} else if (result.isInapplicable) {
// This was a method invocation whose arguments didn't match
Expand Down
3 changes: 3 additions & 0 deletions pkg/front_end/test/text_representation/data/expressions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,9 @@ exprGenericInvocation2b(Class variable) =>
/*member: exprDynamicInvocation:variable.method1()*/
exprDynamicInvocation(variable) => variable.method1();

/*member: exprDynamicInvocationImplicitCall:variable()*/
exprDynamicInvocationImplicitCall(variable) => variable();

/*normal|limited.member: exprObjectInvocation:variable.{Object.toString}()*/
/*verbose.member: exprObjectInvocation:variable.{dart.core::Object.toString}()*/
exprObjectInvocation(variable) => variable.toString();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ library;
import self as self;

static const field dynamic a = null;
static const field dynamic b = self::a{dynamic}.call();
static const field dynamic b = self::a{dynamic}();
static method main() → dynamic
;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ static method testInferred() → dynamic {
^" in "" as{TypeError} core::int){(core::int) → self::Class1};
};
dynamic f1b = #C1;
dynamic c1b = f1b{dynamic}.call(0);
dynamic c1b = f1b{dynamic}(0);
self::expect(true, c1b is self::Class1);
self::throws(() → dynamic => f1b{dynamic}.call(""));
self::throws(() → dynamic => f1b{dynamic}(""));
(core::int) → self::Class2 f2a = #C2;
self::expect(true, f2a is (core::int) → self::Class2);
self::expect(false, f2a is (core::String) → self::Class2);
Expand All @@ -64,9 +64,9 @@ static method testInferred() → dynamic {
^" in "" as{TypeError} core::int){(core::int) → self::Class2};
};
dynamic f2b = #C2;
dynamic c2b = f2b{dynamic}.call(0);
dynamic c2b = f2b{dynamic}(0);
self::expect(true, c2b is self::Class2);
self::throws(() → dynamic => f2b{dynamic}.call(""));
self::throws(() → dynamic => f2b{dynamic}(""));
}
static method expect(dynamic expected, dynamic actual) → dynamic {
if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ static method testInferred() → dynamic {
^" in "" as{TypeError} core::int){(core::int) → self::Class1};
};
dynamic f1b = #C1;
dynamic c1b = f1b{dynamic}.call(0);
dynamic c1b = f1b{dynamic}(0);
self::expect(true, c1b is self::Class1);
self::throws(() → dynamic => f1b{dynamic}.call(""));
self::throws(() → dynamic => f1b{dynamic}(""));
(core::int) → self::Class2 f2a = #C2;
self::expect(true, f2a is (core::int) → self::Class2);
self::expect(false, f2a is (core::String) → self::Class2);
Expand All @@ -64,9 +64,9 @@ static method testInferred() → dynamic {
^" in "" as{TypeError} core::int){(core::int) → self::Class2};
};
dynamic f2b = #C2;
dynamic c2b = f2b{dynamic}.call(0);
dynamic c2b = f2b{dynamic}(0);
self::expect(true, c2b is self::Class2);
self::throws(() → dynamic => f2b{dynamic}.call(""));
self::throws(() → dynamic => f2b{dynamic}(""));
}
static method expect(dynamic expected, dynamic actual) → dynamic {
if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ static method testInferred() → dynamic {
^" in "" as{TypeError} core::int){(core::int) → self::Class1};
};
dynamic f1b = #C1;
dynamic c1b = f1b{dynamic}.call(0);
dynamic c1b = f1b{dynamic}(0);
self::expect(true, c1b is self::Class1);
self::throws(() → dynamic => f1b{dynamic}.call(""));
self::throws(() → dynamic => f1b{dynamic}(""));
(core::int) → self::Class2 f2a = #C2;
self::expect(true, f2a is (core::int) → self::Class2);
self::expect(false, f2a is (core::String) → self::Class2);
Expand All @@ -64,9 +64,9 @@ static method testInferred() → dynamic {
^" in "" as{TypeError} core::int){(core::int) → self::Class2};
};
dynamic f2b = #C2;
dynamic c2b = f2b{dynamic}.call(0);
dynamic c2b = f2b{dynamic}(0);
self::expect(true, c2b is self::Class2);
self::throws(() → dynamic => f2b{dynamic}.call(""));
self::throws(() → dynamic => f2b{dynamic}(""));
}
static method expect(dynamic expected, dynamic actual) → dynamic {
if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ static method testInferred() → dynamic {
^" in "" as{TypeError} core::int){(core::int) → self::Class1};
};
dynamic f1b = #C1;
dynamic c1b = f1b{dynamic}.call(0);
dynamic c1b = f1b{dynamic}(0);
self::expect(true, c1b is self::Class1);
self::throws(() → dynamic => f1b{dynamic}.call(""));
self::throws(() → dynamic => f1b{dynamic}(""));
(core::int) → self::Class2 f2a = #C2;
self::expect(true, f2a is (core::int) → self::Class2);
self::expect(false, f2a is (core::String) → self::Class2);
Expand All @@ -64,9 +64,9 @@ static method testInferred() → dynamic {
^" in "" as{TypeError} core::int){(core::int) → self::Class2};
};
dynamic f2b = #C2;
dynamic c2b = f2b{dynamic}.call(0);
dynamic c2b = f2b{dynamic}(0);
self::expect(true, c2b is self::Class2);
self::throws(() → dynamic => f2b{dynamic}.call(""));
self::throws(() → dynamic => f2b{dynamic}(""));
}
static method expect(dynamic expected, dynamic actual) → dynamic {
if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ static method testInferred() → dynamic {
^" in "" as{TypeError} core::int){(core::int) → self::Class1};
};
dynamic f1b = #C1;
dynamic c1b = f1b{dynamic}.call(0);
dynamic c1b = f1b{dynamic}(0);
self::expect(true, c1b is self::Class1);
self::throws(() → dynamic => f1b{dynamic}.call(""));
self::throws(() → dynamic => f1b{dynamic}(""));
(core::int) → self::Class2 f2a = #C2;
self::expect(true, f2a is (core::int) → self::Class2);
self::expect(false, f2a is (core::String) → self::Class2);
Expand All @@ -64,9 +64,9 @@ static method testInferred() → dynamic {
^" in "" as{TypeError} core::int){(core::int) → self::Class2};
};
dynamic f2b = #C2;
dynamic c2b = f2b{dynamic}.call(0);
dynamic c2b = f2b{dynamic}(0);
self::expect(true, c2b is self::Class2);
self::throws(() → dynamic => f2b{dynamic}.call(""));
self::throws(() → dynamic => f2b{dynamic}(""));
}
static method expect(dynamic expected, dynamic actual) → dynamic {
if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,14 @@ static method testNoArgs() → dynamic {
self::Class1 c1a = f1a(){() → self::Class1};
self::expect(true, c1a is self::Class1);
dynamic f1b = #C2;
dynamic c1b = f1b{dynamic}.call();
dynamic c1b = f1b{dynamic}();
self::expect(true, c1b is self::Class1);
self::expect(true, core::identical(f1a, f1b));
() → self::Class2 f2a = #C3;
self::Class2 c2a = f2a(){() → self::Class2};
self::expect(true, c2a is self::Class2);
dynamic f2b = #C3;
dynamic c2b = f2b{dynamic}.call();
dynamic c2b = f2b{dynamic}();
self::expect(true, c2b is self::Class2);
self::expect(true, core::identical(f2a, f2b));
}
Expand All @@ -130,10 +130,10 @@ Try removing the extra positional arguments.
^" in f3a{<inapplicable>}.(42, 87);
};
dynamic f3b = #C4;
dynamic c3b = f3b{dynamic}.call(87);
dynamic c3b = f3b{dynamic}(87);
self::expect(87, c3b{dynamic}.field);
self::throws(() → dynamic => f3b{dynamic}.call());
self::throws(() → dynamic => f3b{dynamic}.call(42, 87));
self::throws(() → dynamic => f3b{dynamic}());
self::throws(() → dynamic => f3b{dynamic}(42, 87));
([core::int?]) → self::Class4 f4a = #C5;
self::Class4 c4a = f4a(){([core::int?]) → self::Class4};
self::expect(null, c4a.{self::Class4::field}{core::int?});
Expand All @@ -146,7 +146,7 @@ Try removing the extra positional arguments.
^" in f4a{<inapplicable>}.(42, 87);
};
dynamic f4b = #C5;
self::throws(() → dynamic => f4b{dynamic}.call(42, 87));
self::throws(() → dynamic => f4b{dynamic}(42, 87));
(core::int, [core::int?]) → self::Class5 f5a = #C6;
self::Class5 c5a = f5a(42){(core::int, [core::int?]) → self::Class5};
self::expect(42, c5a.{self::Class5::field1}{core::int});
Expand All @@ -164,8 +164,8 @@ Try removing the extra positional arguments.
^" in f5a{<inapplicable>}.(42, 87, 123);
};
dynamic f5b = #C6;
self::throws(() → dynamic => f5b{dynamic}.call());
self::throws(() → dynamic => f5b{dynamic}.call(42, 87, 123));
self::throws(() → dynamic => f5b{dynamic}());
self::throws(() → dynamic => f5b{dynamic}(42, 87, 123));
(core::int, {field2: core::int?, required field3: core::int}) → self::Class6 f6a = #C7;
self::Class6 c6a = f6a(42, field3: 87){(core::int, {field2: core::int?, required field3: core::int}) → self::Class6};
self::expect(42, c6a.{self::Class6::field1}{core::int});
Expand Down Expand Up @@ -195,10 +195,10 @@ Try removing the extra positional arguments.
self::expect(123, c6c.{self::Class6::field2}{core::int?});
self::expect(42, c6c.{self::Class6::field3}{core::int});
dynamic f6b = #C7;
self::throws(() → dynamic => f6b{dynamic}.call());
self::throws(() → dynamic => f6b{dynamic}.call(42), inSoundModeOnly: true);
self::throws(() → dynamic => f6b{dynamic}.call(42, 87), inSoundModeOnly: true);
self::throws(() → dynamic => f6b{dynamic}.call(field1: 87, field2: 87));
self::throws(() → dynamic => f6b{dynamic}());
self::throws(() → dynamic => f6b{dynamic}(42), inSoundModeOnly: true);
self::throws(() → dynamic => f6b{dynamic}(42, 87), inSoundModeOnly: true);
self::throws(() → dynamic => f6b{dynamic}(field1: 87, field2: 87));
}
static method expect(dynamic expected, dynamic actual) → dynamic {
if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
Expand Down
Loading

0 comments on commit 80f5952

Please sign in to comment.