Skip to content

Commit d7a5bb4

Browse files
mkustermannCommit Queue
authored andcommitted
[dart2wasm] Check in tests for interop calls
This checks in tests on how JS interop calls with primitive types look like. Issue #60928 Change-Id: I988edbb8102490f08e130ca7cd1c16ec72e796c3 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/455420 Reviewed-by: Srujan Gaddam <[email protected]> Commit-Queue: Martin Kustermann <[email protected]>
1 parent 82144f0 commit d7a5bb4

File tree

11 files changed

+1031
-3
lines changed

11 files changed

+1031
-3
lines changed

pkg/dart2wasm/test/ir_test.dart

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ void main(List<String> args) async {
2020
final help = result.flag('help');
2121
final write = result.flag('write');
2222
final runFromSource = result.flag('src');
23+
final filter = result.option('filter');
2324

2425
if (help) {
2526
print('Usage:\n${argParser.usage}');
@@ -31,8 +32,14 @@ void main(List<String> args) async {
3132
io.exit(1);
3233
}
3334

35+
final filterRegExp = filter != null ? RegExp(filter) : null;
36+
3437
await withTempDir((String tempDir) async {
3538
for (final dartFilename in listIrTests()) {
39+
if (filterRegExp != null && !filterRegExp.hasMatch(dartFilename)) {
40+
continue;
41+
}
42+
3643
void failTest() {
3744
print('-> test "$dartFilename" failed\n');
3845
io.exitCode = 254;
@@ -43,7 +50,7 @@ void main(List<String> args) async {
4350
final wasmFile = File(path.join(
4451
tempDir, path.setExtension(path.basename(dartFilename), '.wasm')));
4552

46-
print('Testing $dartFilename');
53+
print('\nTesting $dartFilename');
4754

4855
final result = await Process.run('/usr/bin/env', [
4956
'bash',
@@ -62,12 +69,11 @@ void main(List<String> args) async {
6269
continue;
6370
}
6471

65-
print('Compiled to ${wasmFile.path}');
66-
6772
final wasmBytes = wasmFile.readAsBytesSync();
6873
final wat =
6974
moduleToString(parseModule(wasmBytes), parseNameFilters(dartCode));
7075
if (write) {
76+
print('-> Updated expectation file: ${watFile.path}');
7177
watFile.writeAsStringSync(wat);
7278
continue;
7379
}
@@ -92,6 +98,8 @@ final argParser = ArgParser()
9298
..addFlag('help',
9399
abbr: 'h', defaultsTo: false, help: 'Prints available options.')
94100
..addFlag('src', defaultsTo: false, help: 'Runs the compiler from source.')
101+
..addOption('filter',
102+
abbr: 'f', help: 'Runs only tests that match the filter.')
95103
..addFlag('write',
96104
abbr: 'w', defaultsTo: false, help: 'Writes new expectation files.');
97105

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
// functionFilter=test|roundTrip
6+
7+
import 'dart:js_interop';
8+
9+
@JS()
10+
external bool roundTripBool(bool b);
11+
12+
@JS()
13+
external bool? roundTripBoolNullable(bool? b);
14+
15+
final ktrue = int.parse('1') == 1;
16+
17+
final boolValue = ktrue;
18+
final boolValueNullable = ktrue ? boolValue : null;
19+
20+
@pragma('wasm:never-inline')
21+
void main() {
22+
testBoolConstant();
23+
testBoolConstantNullable();
24+
testBoolValue();
25+
testBoolValueNullable();
26+
}
27+
28+
@pragma('wasm:never-inline')
29+
void testBoolConstant() {
30+
sinkBool(roundTripBool(true));
31+
}
32+
33+
@pragma('wasm:never-inline')
34+
void testBoolConstantNullable() {
35+
sinkBoolNullable(roundTripBoolNullable(null));
36+
}
37+
38+
@pragma('wasm:never-inline')
39+
void testBoolValue() {
40+
sinkBool(roundTripBool(boolValue));
41+
}
42+
43+
@pragma('wasm:never-inline')
44+
void testBoolValueNullable() {
45+
sinkBoolNullable(roundTripBoolNullable(boolValueNullable));
46+
}
47+
48+
@pragma('wasm:never-inline')
49+
void sinkBool(bool b) => print(b);
50+
51+
@pragma('wasm:never-inline')
52+
void sinkBoolNullable(bool? b) => print(b);
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
(module $module0
2+
(type $#Top (struct (field $field0 i32)))
3+
(func $"dart2wasm._274 (import)"(import "dart2wasm" "_274") (param externref) (result externref))
4+
(func $"dart2wasm._275 (import)"(import "dart2wasm" "_275") (param externref) (result externref))
5+
(func $"dart2wasm._149 (import)"(import "dart2wasm" "_149") (param externref) (result i32))
6+
(func $"dart2wasm._150 (import)"(import "dart2wasm" "_150") (param i32) (result externref))
7+
(global $"C2 false" (ref $#Top) (i32.const 3) (struct.new $#Top))
8+
(global $"C40 true" (ref $#Top) (i32.const 3) (struct.new $#Top))
9+
(global $"boolValueNullable initialized" (mut i32) (i32.const 0))
10+
(global $boolValueNullable (mut (ref null $#Top)) (ref.null none))
11+
(global $"ktrue initialized" (mut i32) (i32.const 0))
12+
(global $ktrue (mut i32) (i32.const 0))
13+
(global $"boolValue initialized" (mut i32) (i32.const 0))
14+
(global $boolValue (mut i32) (i32.const 0))
15+
(func $"testBoolConstant <noInline>"
16+
(local $var0 externref)
17+
i32.const 1
18+
call $"dart2wasm._150 (import)"
19+
call $"dart2wasm._274 (import)"
20+
local.tee $var0
21+
call $isDartNull
22+
if (result i32)
23+
call $"_throwArgumentNullError <noInline>"
24+
unreachable
25+
else
26+
local.get $var0
27+
call $"dart2wasm._149 (import)"
28+
end
29+
call $"sinkBool <noInline>"
30+
)
31+
(func $"testBoolConstantNullable <noInline>"
32+
(local $var0 externref)
33+
ref.null noextern
34+
call $"dart2wasm._275 (import)"
35+
local.tee $var0
36+
call $isDartNull
37+
if (result (ref null $#Top))
38+
ref.null none
39+
else
40+
global.get $"C40 true"
41+
global.get $"C2 false"
42+
local.get $var0
43+
call $"dart2wasm._149 (import)"
44+
select (ref $#Top)
45+
end
46+
call $"sinkBoolNullable <noInline>"
47+
)
48+
(func $"testBoolValue <noInline>"
49+
(local $var0 externref)
50+
global.get $"boolValue initialized"
51+
if (result i32)
52+
global.get $boolValue
53+
else
54+
call $"boolValue implicit getter"
55+
end
56+
call $"dart2wasm._150 (import)"
57+
call $"dart2wasm._274 (import)"
58+
local.tee $var0
59+
call $isDartNull
60+
if (result i32)
61+
call $"_throwArgumentNullError <noInline>"
62+
unreachable
63+
else
64+
local.get $var0
65+
call $"dart2wasm._149 (import)"
66+
end
67+
call $"sinkBool <noInline>"
68+
)
69+
(func $"testBoolValueNullable <noInline>"
70+
(local $var0 (ref null $#Top))
71+
(local $var1 externref)
72+
global.get $"boolValueNullable initialized"
73+
i32.eqz
74+
if
75+
global.get $"ktrue initialized"
76+
if (result i32)
77+
global.get $ktrue
78+
else
79+
call $"ktrue implicit getter"
80+
end
81+
if (result (ref null $#Top))
82+
global.get $"C40 true"
83+
global.get $"C2 false"
84+
global.get $"boolValue initialized"
85+
if (result i32)
86+
global.get $boolValue
87+
else
88+
call $"boolValue implicit getter"
89+
end
90+
select (ref $#Top)
91+
else
92+
ref.null none
93+
end
94+
global.set $boolValueNullable
95+
i32.const 1
96+
global.set $"boolValueNullable initialized"
97+
end
98+
global.get $boolValueNullable
99+
local.tee $var0
100+
ref.is_null
101+
if (result externref)
102+
ref.null noextern
103+
else
104+
local.get $var0
105+
call $jsifyRaw
106+
end
107+
call $"dart2wasm._275 (import)"
108+
local.tee $var1
109+
call $isDartNull
110+
if (result (ref null $#Top))
111+
ref.null none
112+
else
113+
global.get $"C40 true"
114+
global.get $"C2 false"
115+
local.get $var1
116+
call $"dart2wasm._149 (import)"
117+
select (ref $#Top)
118+
end
119+
call $"sinkBoolNullable <noInline>"
120+
)
121+
(func $jsifyRaw (param $var0 (ref null $#Top)) (result externref))
122+
(func $isDartNull (param $var0 externref) (result i32))
123+
(func $sinkBoolNullable <noInline> (param $var0 (ref null $#Top)))
124+
(func $_throwArgumentNullError <noInline> )
125+
(func $ktrue implicit getter (result i32))
126+
(func $boolValue implicit getter (result i32))
127+
(func $sinkBool <noInline> (param $var0 i32))
128+
)
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
// functionFilter=test|roundTrip
6+
7+
import 'dart:js_interop';
8+
9+
@JS()
10+
external double roundTripDouble(double d);
11+
12+
@JS()
13+
external double? roundTripDoubleNullable(double? d);
14+
15+
final ktrue = int.parse('1') == 1;
16+
17+
final doubleValue = ktrue ? 1.1 : 2.1;
18+
final doubleValueNullable = ktrue ? doubleValue : null;
19+
20+
@pragma('wasm:never-inline')
21+
void main() {
22+
testDoubleConstant();
23+
testDoubleConstantNullable();
24+
testDoubleValue();
25+
testDoubleValueNullable();
26+
}
27+
28+
@pragma('wasm:never-inline')
29+
void testDoubleConstant() {
30+
sinkDouble(roundTripDouble(1.1));
31+
}
32+
33+
@pragma('wasm:never-inline')
34+
void testDoubleConstantNullable() {
35+
sinkDoubleNullable(roundTripDoubleNullable(null));
36+
}
37+
38+
@pragma('wasm:never-inline')
39+
void testDoubleValue() {
40+
sinkDouble(roundTripDouble(doubleValue));
41+
}
42+
43+
@pragma('wasm:never-inline')
44+
void testDoubleValueNullable() {
45+
sinkDoubleNullable(roundTripDoubleNullable(doubleValueNullable));
46+
}
47+
48+
@pragma('wasm:never-inline')
49+
void sinkDouble(double b) => print(b);
50+
51+
@pragma('wasm:never-inline')
52+
void sinkDoubleNullable(double? b) => print(b);

0 commit comments

Comments
 (0)