Skip to content

Commit 35bc17a

Browse files
osa1Commit Queue
authored and
Commit Queue
committed
[dart2wasm] Check import/export pragmas in user code
Change-Id: I926d108a4571d685c67d3a174a8e506910cce8f7 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/369020 Commit-Queue: Ömer Ağacan <[email protected]> Reviewed-by: Martin Kustermann <[email protected]>
1 parent b56843d commit 35bc17a

File tree

6 files changed

+87
-1
lines changed

6 files changed

+87
-1
lines changed

pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart

+11
Original file line numberDiff line numberDiff line change
@@ -17641,6 +17641,17 @@ const MessageCode messageVoidWithTypeArguments = const MessageCode(
1764117641
correctionMessage: r"""Try removing the type arguments.""",
1764217642
);
1764317643

17644+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
17645+
const Code<Null> codeWasmImportOrExportInUserCode =
17646+
messageWasmImportOrExportInUserCode;
17647+
17648+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
17649+
const MessageCode messageWasmImportOrExportInUserCode = const MessageCode(
17650+
"WasmImportOrExportInUserCode",
17651+
problemMessage:
17652+
r"""Pragmas `wasm:import` and `wasm:export` are for internal use only and cannot be used by user code.""",
17653+
);
17654+
1764417655
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
1764517656
const Code<Null> codeWeakReferenceMismatchReturnAndArgumentTypes =
1764617657
messageWeakReferenceMismatchReturnAndArgumentTypes;

pkg/dart2wasm/lib/target.dart

+52-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// BSD-style license that can be found in the LICENSE file.
44

55
import 'package:_fe_analyzer_shared/src/messages/codes.dart'
6-
show Message, LocatedMessage;
6+
show Message, LocatedMessage, messageWasmImportOrExportInUserCode;
77
import 'package:_js_interop_checks/js_interop_checks.dart';
88
import 'package:_js_interop_checks/src/js_interop.dart' as jsInteropHelper;
99
import 'package:_js_interop_checks/src/transformations/shared_interop_transformer.dart';
@@ -243,6 +243,11 @@ class WasmTarget extends Target {
243243
ReferenceFromIndex? referenceFromIndex,
244244
{void Function(String msg)? logger,
245245
ChangedStructureNotifier? changedStructureNotifier}) {
246+
// Check `wasm:import` and `wasm:export` pragmas before FFI transforms as
247+
// FFI transforms convert JS interop annotations to these pragmas.
248+
_checkWasmImportExportPragmas(libraries, coreTypes,
249+
diagnosticReporter as DiagnosticReporter<Message, LocatedMessage>);
250+
246251
Set<Library> transitiveImportingJSInterop = {
247252
...?jsInteropHelper.calculateTransitiveImportsOfJsInteropIfUsed(
248253
component, Uri.parse("package:js/js.dart")),
@@ -518,3 +523,49 @@ class WasmVerification extends Verification {
518523
return false;
519524
}
520525
}
526+
527+
final _dartCoreUri = Uri.parse('dart:core');
528+
529+
/// Check that `wasm:import` and `wasm:export` pragmas are only used in `dart:`
530+
/// libraries and in tests, with the exception of
531+
/// `reject_import_export_pragmas` test.
532+
void _checkWasmImportExportPragmas(List<Library> libraries, CoreTypes coreTypes,
533+
DiagnosticReporter<Message, LocatedMessage> diagnosticReporter) {
534+
for (Library library in libraries) {
535+
final importUri = library.importUri;
536+
if (importUri.isScheme('dart') ||
537+
(importUri.path.contains('tests/web/wasm') &&
538+
!importUri.path.contains('reject_import_export_pragmas'))) {
539+
continue;
540+
}
541+
542+
for (Member member in library.members) {
543+
for (Expression annotation in member.annotations) {
544+
if (annotation is! ConstantExpression) {
545+
continue;
546+
}
547+
final annotationConstant = annotation.constant;
548+
if (annotationConstant is! InstanceConstant) {
549+
continue;
550+
}
551+
final cls = annotationConstant.classNode;
552+
if (cls.name == 'pragma' &&
553+
cls.enclosingLibrary.importUri == _dartCoreUri) {
554+
final pragmaName = annotationConstant
555+
.fieldValues[coreTypes.pragmaName.fieldReference];
556+
if (pragmaName is StringConstant) {
557+
if (pragmaName.value == 'wasm:import' ||
558+
pragmaName.value == 'wasm:export') {
559+
diagnosticReporter.report(
560+
messageWasmImportOrExportInUserCode,
561+
annotation.fileOffset,
562+
0,
563+
library.fileUri,
564+
);
565+
}
566+
}
567+
}
568+
}
569+
}
570+
}
571+
}

pkg/front_end/messages.status

+2
Original file line numberDiff line numberDiff line change
@@ -1115,6 +1115,8 @@ VarAsTypeName/part_wrapped_script1: Fail
11151115
VarAsTypeName/script1: Fail # Too many problems
11161116
VariableCouldBeNullDueToWrite/analyzerCode: Fail
11171117
VariableCouldBeNullDueToWrite/example: Fail
1118+
WasmImportOrExportInUserCode/analyzerCode: Fail
1119+
WasmImportOrExportInUserCode/example: Fail
11181120
WeakReferenceMismatchReturnAndArgumentTypes/analyzerCode: Fail
11191121
WeakReferenceMismatchReturnAndArgumentTypes/example: Fail
11201122
WeakReferenceNotOneArgument/analyzerCode: Fail

pkg/front_end/messages.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -7011,6 +7011,9 @@ ResourceIdentifiersNotStatic:
70117011
ResourceIdentifiersMultiple:
70127012
problemMessage: "Only one resource identifier pragma can be used at a time."
70137013

7014+
WasmImportOrExportInUserCode:
7015+
problemMessage: "Pragmas `wasm:import` and `wasm:export` are for internal use only and cannot be used by user code."
7016+
70147017
WeakReferenceNotStatic:
70157018
problemMessage: "Weak reference pragma can be used on a static method only."
70167019

pkg/front_end/test/spell_checking_list_messages.txt

+3
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ placing
114114
pointer`s
115115
pragma
116116
pragma('vm:deeply
117+
pragmas
117118
preexisting
118119
pubspec.yaml
119120
r
@@ -149,4 +150,6 @@ u
149150
unavailable
150151
unsound
151152
v
153+
wasm:export
154+
wasm:import
152155
x
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright (c) 2024, 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+
// Test that importing `dart:ffi` and using `wasm:import` and export pragmas
6+
// are not allowed.
7+
8+
import 'dart:ffi'; //# 01: compile-time error
9+
10+
@pragma('wasm:export', 'f') //# 02: compile-time error
11+
void f() {}
12+
13+
@pragma('wasm:import', 'g') //# 03: compile-time error
14+
external double g(double x);
15+
16+
void main() {}

0 commit comments

Comments
 (0)