mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 21:30:17 +00:00
0bc92a4333
The type category table is a O(number-of-classes) sized byte array that maps from class-id to either a type category (function, record, ...) or a masqueraded class-id. * for flute this table takes up around 1 KB. * this prevents from making concrete class-ids come before all abstract class ids After recent changes the core RTT implementation no longer involves masqueraded types (i.e. `<obj> is/as <type>` and `<type> <: <type>` queries don't trigger masquerading functionality) This CL removes the type category table, the special casing in the class-id assignment and the compiler support for building the table. Instead we move the logic to pure dart code, which can use normal `is` checks to perform its function. We add one optimization: The compiler will provide the class-id from which one only non-masqueraded classes come. This makes the masquerading function have a fast path. * We use `Wasm{TypedData,String}Base` marker interfaces i `dart:_internal` to check for wasm-backed implementations * We use `-Ddart.wasm.js_compatibility` to provide JSCM mode We add a test that actually exercises the 2 modes. Change-Id: I051c35b17878950402a1336df871a686b649f732 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/349641 Reviewed-by: Slava Egorov <vegorov@google.com> Commit-Queue: Martin Kustermann <kustermann@google.com>
161 lines
6.6 KiB
Dart
161 lines
6.6 KiB
Dart
// 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.
|
|
|
|
import 'dart:io';
|
|
|
|
import 'package:args/args.dart' as args;
|
|
import 'package:front_end/src/api_unstable/vm.dart' show resolveInputUri;
|
|
import 'package:front_end/src/api_unstable/vm.dart' as fe;
|
|
|
|
import 'package:dart2wasm/generate_wasm.dart';
|
|
import 'package:dart2wasm/option.dart';
|
|
|
|
// Used to allow us to keep defaults on their respective option structs.
|
|
// Note: When adding new options, consider if CLI options should be add
|
|
// to `pkg/dartdev/lib/src/commands/compile.dart` too.
|
|
final WasmCompilerOptions _d = WasmCompilerOptions.defaultOptions();
|
|
|
|
final List<Option> options = [
|
|
Flag("help", (o, _) {}, abbr: "h", negatable: false, defaultsTo: false),
|
|
Flag("export-all", (o, value) => o.translatorOptions.exportAll = value,
|
|
defaultsTo: _d.translatorOptions.exportAll),
|
|
Flag("import-shared-memory",
|
|
(o, value) => o.translatorOptions.importSharedMemory = value,
|
|
defaultsTo: _d.translatorOptions.importSharedMemory),
|
|
Flag("inlining", (o, value) => o.translatorOptions.inlining = value,
|
|
defaultsTo: _d.translatorOptions.inlining),
|
|
Flag("name-section", (o, value) => o.translatorOptions.nameSection = value,
|
|
defaultsTo: _d.translatorOptions.nameSection),
|
|
Flag("minify", (o, value) => o.translatorOptions.minify = value,
|
|
defaultsTo: _d.translatorOptions.minify),
|
|
Flag("polymorphic-specialization",
|
|
(o, value) => o.translatorOptions.polymorphicSpecialization = value,
|
|
defaultsTo: _d.translatorOptions.polymorphicSpecialization),
|
|
Flag("print-kernel", (o, value) => o.translatorOptions.printKernel = value,
|
|
defaultsTo: _d.translatorOptions.printKernel),
|
|
Flag("print-wasm", (o, value) => o.translatorOptions.printWasm = value,
|
|
defaultsTo: _d.translatorOptions.printWasm),
|
|
Flag("js-compatibility", (o, value) {
|
|
o.translatorOptions.jsCompatibility = value;
|
|
o.environment['dart.wasm.js_compatibility'] = 'true';
|
|
}, defaultsTo: _d.translatorOptions.jsCompatibility),
|
|
Flag(
|
|
"enable-asserts", (o, value) => o.translatorOptions.enableAsserts = value,
|
|
defaultsTo: _d.translatorOptions.enableAsserts),
|
|
Flag("omit-explicit-checks",
|
|
(o, value) => o.translatorOptions.omitExplicitTypeChecks = value,
|
|
defaultsTo: _d.translatorOptions.omitExplicitTypeChecks),
|
|
Flag("omit-implicit-checks",
|
|
(o, value) => o.translatorOptions.omitImplicitTypeChecks = value,
|
|
defaultsTo: _d.translatorOptions.omitImplicitTypeChecks),
|
|
// TODO(http://dartbug.com/54675): Deprecate & Remove this one.
|
|
Flag("omit-type-checks", (o, value) {
|
|
o.translatorOptions.omitImplicitTypeChecks = value;
|
|
o.translatorOptions.omitExplicitTypeChecks = value;
|
|
},
|
|
defaultsTo: _d.translatorOptions.omitImplicitTypeChecks &&
|
|
_d.translatorOptions.omitExplicitTypeChecks),
|
|
Flag("verbose", (o, value) => o.translatorOptions.verbose = value,
|
|
defaultsTo: _d.translatorOptions.verbose),
|
|
Flag("verify-type-checks",
|
|
(o, value) => o.translatorOptions.verifyTypeChecks = value,
|
|
defaultsTo: _d.translatorOptions.verifyTypeChecks),
|
|
IntOption(
|
|
"inlining-limit", (o, value) => o.translatorOptions.inliningLimit = value,
|
|
defaultsTo: "${_d.translatorOptions.inliningLimit}"),
|
|
IntOption("shared-memory-max-pages",
|
|
(o, value) => o.translatorOptions.sharedMemoryMaxPages = value),
|
|
UriOption("dart-sdk", (o, value) => o.sdkPath = value,
|
|
defaultsTo: "${_d.sdkPath}"),
|
|
UriOption("packages", (o, value) => o.packagesPath = value),
|
|
UriOption("libraries-spec", (o, value) => o.librariesSpecPath = value),
|
|
UriOption("platform", (o, value) => o.platformPath = value),
|
|
IntMultiOption(
|
|
"watch", (o, values) => o.translatorOptions.watchPoints = values),
|
|
StringMultiOption(
|
|
"define", (o, values) => o.environment.addAll(processEnvironment(values)),
|
|
abbr: "D"),
|
|
StringMultiOption(
|
|
"enable-experiment",
|
|
(o, values) =>
|
|
o.feExperimentalFlags = processFeExperimentalFlags(values)),
|
|
StringOption("multi-root-scheme", (o, value) => o.multiRootScheme = value),
|
|
UriMultiOption("multi-root", (o, values) => o.multiRoots = values),
|
|
StringOption("depfile", (o, value) => o.depFile = value),
|
|
StringOption(
|
|
"js-runtime-output", (o, value) => o.outputJSRuntimeFile = value),
|
|
StringOption(
|
|
"dump-kernel-after-cfe", (o, value) => o.dumpKernelAfterCfe = value,
|
|
hide: true),
|
|
StringOption(
|
|
"dump-kernel-before-tfa", (o, value) => o.dumpKernelBeforeTfa = value,
|
|
hide: true),
|
|
StringOption(
|
|
"dump-kernel-after-tfa", (o, value) => o.dumpKernelAfterTfa = value,
|
|
hide: true),
|
|
];
|
|
|
|
Map<fe.ExperimentalFlag, bool> processFeExperimentalFlags(
|
|
List<String> experiments) =>
|
|
fe.parseExperimentalFlags(fe.parseExperimentalArguments(experiments),
|
|
onError: (error) => throw ArgumentError(error),
|
|
onWarning: (warning) => print(warning));
|
|
|
|
Map<String, String> processEnvironment(List<String> defines) =>
|
|
Map<String, String>.fromEntries(defines.map((d) {
|
|
List<String> keyAndValue = d.split('=');
|
|
if (keyAndValue.length != 2) {
|
|
throw ArgumentError('Bad define string: $d');
|
|
}
|
|
return MapEntry<String, String>(keyAndValue[0], keyAndValue[1]);
|
|
}));
|
|
|
|
WasmCompilerOptions parseArguments(List<String> arguments) {
|
|
args.ArgParser parser = args.ArgParser();
|
|
for (Option arg in options) {
|
|
arg.applyToParser(parser);
|
|
}
|
|
|
|
Never usage() {
|
|
print("Usage: dart2wasm [<options>] <infile.dart> <outfile.wasm>");
|
|
print("");
|
|
print("*NOTE*: Wasm compilation is experimental.");
|
|
print("The support may change, or be removed, with no advance notice.");
|
|
print("");
|
|
print("Options:");
|
|
for (String line in parser.usage.split('\n')) {
|
|
print('\t$line');
|
|
}
|
|
exit(64);
|
|
}
|
|
|
|
try {
|
|
args.ArgResults results = parser.parse(arguments);
|
|
if (results['help']) {
|
|
usage();
|
|
}
|
|
List<String> rest = results.rest;
|
|
if (rest.length != 2) {
|
|
throw ArgumentError('Requires two positional file arguments');
|
|
}
|
|
WasmCompilerOptions compilerOptions = WasmCompilerOptions(
|
|
mainUri: resolveInputUri(rest[0]), outputFile: rest[1]);
|
|
for (Option arg in options) {
|
|
if (results.wasParsed(arg.name)) {
|
|
arg.applyToOptions(compilerOptions, results[arg.name]);
|
|
}
|
|
}
|
|
return compilerOptions;
|
|
} catch (e, s) {
|
|
print(s);
|
|
print('Argument Error: ' + e.toString());
|
|
usage();
|
|
}
|
|
}
|
|
|
|
Future<int> main(List<String> args) async {
|
|
WasmCompilerOptions options = parseArguments(args);
|
|
return generateWasm(options, errorPrinter: stderr.writeln);
|
|
}
|