diff --git a/pkg/dart2wasm/lib/compile.dart b/pkg/dart2wasm/lib/compile.dart index d883ab3e073..95dbe11dbaa 100644 --- a/pkg/dart2wasm/lib/compile.dart +++ b/pkg/dart2wasm/lib/compile.dart @@ -20,6 +20,7 @@ import 'package:front_end/src/api_unstable/vm.dart' import 'package:kernel/ast.dart'; import 'package:kernel/class_hierarchy.dart'; +import 'package:kernel/library_index.dart'; import 'package:kernel/core_types.dart'; import 'package:kernel/kernel.dart' show writeComponentToText; import 'package:kernel/verifier.dart'; @@ -111,9 +112,21 @@ Future compileToModule(compiler.WasmCompilerOptions options, Component component = compilerResult.component!; CoreTypes coreTypes = compilerResult.coreTypes!; ClassHierarchy classHierarchy = compilerResult.classHierarchy!; + LibraryIndex libraryIndex = LibraryIndex(component, [ + "dart:_internal", + "dart:_js_helper", + "dart:_js_types", + "dart:_string", + "dart:_wasm", + "dart:async", + "dart:collection", + "dart:core", + "dart:ffi", + "dart:typed_data", + ]); - ConstantEvaluator constantEvaluator = - ConstantEvaluator(options, target, component, coreTypes, classHierarchy); + ConstantEvaluator constantEvaluator = ConstantEvaluator( + options, target, component, coreTypes, classHierarchy, libraryIndex); unreachable_code_elimination.transformComponent(target, component, constantEvaluator, options.translatorOptions.enableAsserts); @@ -150,8 +163,8 @@ Future compileToModule(compiler.WasmCompilerOptions options, return true; }()); - var translator = Translator( - component, coreTypes, recordClasses, options.translatorOptions); + var translator = Translator(component, coreTypes, libraryIndex, recordClasses, + options.translatorOptions); String? depFile = options.depFile; if (depFile != null) { diff --git a/pkg/dart2wasm/lib/constant_evaluator.dart b/pkg/dart2wasm/lib/constant_evaluator.dart index 91dea53f8fb..7122ef9f4af 100644 --- a/pkg/dart2wasm/lib/constant_evaluator.dart +++ b/pkg/dart2wasm/lib/constant_evaluator.dart @@ -5,6 +5,7 @@ import 'package:kernel/ast.dart'; import 'package:kernel/type_environment.dart'; import 'package:front_end/src/fasta/kernel/constant_evaluator.dart' as kernel; +import 'package:kernel/library_index.dart'; import 'package:kernel/core_types.dart'; import 'package:kernel/class_hierarchy.dart'; @@ -15,9 +16,21 @@ import 'package:dart2wasm/target.dart'; class ConstantEvaluator extends kernel.ConstantEvaluator implements VMConstantEvaluator { - ConstantEvaluator(WasmCompilerOptions options, WasmTarget target, - Component component, CoreTypes coreTypes, ClassHierarchy classHierarchy) - : super( + final bool _checkBounds; + + final Procedure _dartInternalCheckBoundsGetter; + + ConstantEvaluator( + WasmCompilerOptions options, + WasmTarget target, + Component component, + CoreTypes coreTypes, + ClassHierarchy classHierarchy, + LibraryIndex libraryIndex) + : _checkBounds = !options.translatorOptions.omitBoundsChecks, + _dartInternalCheckBoundsGetter = libraryIndex.getTopLevelProcedure( + "dart:_internal", "get:_checkBounds"), + super( target.dartLibrarySupport, target.constantsBackend, component, @@ -31,5 +44,20 @@ class ConstantEvaluator extends kernel.ConstantEvaluator ); @override - bool shouldEvaluateMember(Member node) => false; + Constant visitStaticGet(StaticGet node) { + final target = node.target; + if (target == _dartInternalCheckBoundsGetter) { + return canonicalize(BoolConstant(_checkBounds)); + } + + return super.visitStaticGet(node); + } + + // TODO: We may want consider (similar to the VM) supporting a + // `wasm:const-evaluate` pragma that we recognize here, and then make sure + // functions with the pragma are evaluated before TFA (raise a compile-time + // error if they are not). + @override + bool shouldEvaluateMember(Member node) => + node == _dartInternalCheckBoundsGetter; } diff --git a/pkg/dart2wasm/lib/dart2wasm.dart b/pkg/dart2wasm/lib/dart2wasm.dart index 3f93384f38d..b79098bfe22 100644 --- a/pkg/dart2wasm/lib/dart2wasm.dart +++ b/pkg/dart2wasm/lib/dart2wasm.dart @@ -54,6 +54,9 @@ final List