From fadf8fd85d50163ac82596c2648206b656aa16e4 Mon Sep 17 00:00:00 2001 From: Liam Appelbe Date: Fri, 13 Nov 2020 00:29:38 +0000 Subject: [PATCH] [vm] Get experimental flag default values from YAML Bug: https://github.com/dart-lang/sdk/issues/44053 Change-Id: Ia7ee5fe212cf0f5c619026d967e5747d71bf31ec Fixes: https://github.com/dart-lang/sdk/issues/44053 TEST=No behavior change, so just running existing tests. Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/171663 Commit-Queue: Liam Appelbe Reviewed-by: Alexander Markov --- runtime/vm/dart.cc | 2 +- runtime/vm/experimental_features.cc | 45 +++++++++ runtime/vm/experimental_features.h | 30 ++++++ runtime/vm/kernel_isolate.cc | 7 +- runtime/vm/kernel_isolate.h | 3 +- runtime/vm/unit_test.cc | 2 +- runtime/vm/vm_sources.gni | 2 + tools/experimental_features.yaml | 6 +- tools/generate_experimental_flags.dart | 125 +++++++++++++++++++++++++ 9 files changed, 216 insertions(+), 6 deletions(-) create mode 100644 runtime/vm/experimental_features.cc create mode 100644 runtime/vm/experimental_features.h create mode 100644 tools/generate_experimental_flags.dart diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc index f570648e901..1d9be24a7cd 100644 --- a/runtime/vm/dart.cc +++ b/runtime/vm/dart.cc @@ -806,7 +806,7 @@ bool Dart::DetectNullSafety(const char* script_uri, } // If we are loading from source, figure out the mode from the source. - if (!KernelIsolate::GetExperimentalFlag("no-non-nullable")) { + if (KernelIsolate::GetExperimentalFlag(ExperimentalFeature::non_nullable)) { return KernelIsolate::DetectNullSafety(script_uri, package_config, original_working_directory); } diff --git a/runtime/vm/experimental_features.cc b/runtime/vm/experimental_features.cc new file mode 100644 index 00000000000..1fffd1a1c55 --- /dev/null +++ b/runtime/vm/experimental_features.cc @@ -0,0 +1,45 @@ +// Copyright (c) 2020, 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. +// NOTE: THIS FILE IS GENERATED. DO NOT EDIT. +// +// Instead modify 'tools/experimental_features.yaml' and run +// 'dart tools/generate_experimental_flags.dart' to update. +// +// Current version: 2.12.0 + +#include "vm/experimental_features.h" + +#include +#include "platform/assert.h" +#include "vm/globals.h" + +namespace dart { + +bool GetExperimentalFeatureDefault(ExperimentalFeature feature) { + constexpr bool kFeatureValues[] = { + true, + true, + true, + true, + true, + true, + }; + ASSERT(static_cast(feature) < ARRAY_SIZE(kFeatureValues)); + return kFeatureValues[static_cast(feature)]; +} + +const char* GetExperimentalFeatureName(ExperimentalFeature feature) { + constexpr const char* kFeatureNames[] = { + "non-nullable", + "extension-methods", + "constant-update-2018", + "control-flow-collections", + "set-literals", + "spread-collections", + }; + ASSERT(static_cast(feature) < ARRAY_SIZE(kFeatureNames)); + return kFeatureNames[static_cast(feature)]; +} + +} // namespace dart diff --git a/runtime/vm/experimental_features.h b/runtime/vm/experimental_features.h new file mode 100644 index 00000000000..797b0d24961 --- /dev/null +++ b/runtime/vm/experimental_features.h @@ -0,0 +1,30 @@ +// Copyright (c) 2020, 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. +// NOTE: THIS FILE IS GENERATED. DO NOT EDIT. +// +// Instead modify 'tools/experimental_features.yaml' and run +// 'dart tools/generate_experimental_flags.dart' to update. +// +// Current version: 2.12.0 + +#ifndef RUNTIME_VM_EXPERIMENTAL_FEATURES_H_ +#define RUNTIME_VM_EXPERIMENTAL_FEATURES_H_ + +namespace dart { + +enum class ExperimentalFeature { + non_nullable, + extension_methods, + constant_update_2018, + control_flow_collections, + set_literals, + spread_collections, +}; + +bool GetExperimentalFeatureDefault(ExperimentalFeature feature); +const char* GetExperimentalFeatureName(ExperimentalFeature feature); + +} // namespace dart + +#endif // RUNTIME_VM_EXPERIMENTAL_FEATURES_H_ diff --git a/runtime/vm/kernel_isolate.cc b/runtime/vm/kernel_isolate.cc index f8f0d5475ae..9af2bd69981 100644 --- a/runtime/vm/kernel_isolate.cc +++ b/runtime/vm/kernel_isolate.cc @@ -417,13 +417,16 @@ void KernelIsolate::AddExperimentalFlag(const char* value) { free(temp); } -bool KernelIsolate::GetExperimentalFlag(const char* value) { +bool KernelIsolate::GetExperimentalFlag(ExperimentalFeature feature) { + const char* value = GetExperimentalFeatureName(feature); for (const char* str : *experimental_flags_) { if (strcmp(str, value) == 0) { return true; + } else if (strstr(str, "no-") == str && strcmp(str + 3, value) == 0) { + return false; } } - return false; + return GetExperimentalFeatureDefault(feature); } DEFINE_OPTION_HANDLER(KernelIsolate::AddExperimentalFlag, diff --git a/runtime/vm/kernel_isolate.h b/runtime/vm/kernel_isolate.h index e45022da7b4..0aa5221f955 100644 --- a/runtime/vm/kernel_isolate.h +++ b/runtime/vm/kernel_isolate.h @@ -12,6 +12,7 @@ #include "vm/allocation.h" #include "vm/dart.h" +#include "vm/experimental_features.h" #include "vm/os_thread.h" namespace dart { @@ -78,7 +79,7 @@ class KernelIsolate : public AllStatic { static void NotifyAboutIsolateShutdown(const Isolate* isolate); static void AddExperimentalFlag(const char* value); - static bool GetExperimentalFlag(const char* value); + static bool GetExperimentalFlag(ExperimentalFeature feature); protected: static void InitCallback(Isolate* I); diff --git a/runtime/vm/unit_test.cc b/runtime/vm/unit_test.cc index 528aeb9e3a0..52f46f8b016 100644 --- a/runtime/vm/unit_test.cc +++ b/runtime/vm/unit_test.cc @@ -220,7 +220,7 @@ const char* TestCase::GetTestLib(const char* url) { } bool TestCase::IsNNBD() { - return !KernelIsolate::GetExperimentalFlag("no-non-nullable"); + return KernelIsolate::GetExperimentalFlag(ExperimentalFeature::non_nullable); } #ifndef PRODUCT diff --git a/runtime/vm/vm_sources.gni b/runtime/vm/vm_sources.gni index a0e71ef1b98..fda79fbd2b1 100644 --- a/runtime/vm/vm_sources.gni +++ b/runtime/vm/vm_sources.gni @@ -98,6 +98,8 @@ vm_sources = [ "elf.h", "exceptions.cc", "exceptions.h", + "experimental_features.cc", + "experimental_features.h", "ffi_callback_trampolines.cc", "ffi_callback_trampolines.h", "field_table.cc", diff --git a/tools/experimental_features.yaml b/tools/experimental_features.yaml index e1403b824fd..99f8c15d712 100644 --- a/tools/experimental_features.yaml +++ b/tools/experimental_features.yaml @@ -10,7 +10,8 @@ # # ### Code Generation # -# When you change this file, run the following to update analyzer and kernel: +# When you change this file, run the following to update analyzer, kernel, and +# vm: # # analyzer: # dart pkg/analyzer/tool/experiments/generate.dart @@ -18,6 +19,9 @@ # kernel: # pkg/front_end/tool/fasta generate-experimental-flags # +# vm: +# dart tools/generate_experimental_flags.dart +# # ### Overview # # This document consists mostly of a map called "features". diff --git a/tools/generate_experimental_flags.dart b/tools/generate_experimental_flags.dart new file mode 100644 index 00000000000..bdb089eac96 --- /dev/null +++ b/tools/generate_experimental_flags.dart @@ -0,0 +1,125 @@ +// Copyright (c) 2020, 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. + +// @dart = 2.9 + +import 'dart:io' show File, Platform; +import 'package:yaml/yaml.dart' show YamlMap, loadYaml; + +void main() { + YamlMap yaml = + loadYaml(new File.fromUri(computeYamlFile()).readAsStringSync()); + final currentVersion = getAsVersionNumber(yaml['current-version']); + final enumNames = new StringBuffer(); + final featureValues = new StringBuffer(); + final featureNames = new StringBuffer(); + + YamlMap features = yaml['features']; + for (var entry in features.entries) { + final category = (entry.value as YamlMap)['category']; + if (category == null || category == "vm" || category == "language") { + final version = getAsVersionNumber((entry.value as YamlMap)['enabledIn']); + if (version != null) { + final value = isGreaterOrEqualVersion(currentVersion, version); + final name = entry.key.replaceAll('-', '_'); + enumNames.write(' $name,\n'); + featureValues.write(' $value,\n'); + featureNames.write(' "${entry.key}",\n'); + } + } + } + + final h = ''' +// Copyright (c) 2020, 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. +// NOTE: THIS FILE IS GENERATED. DO NOT EDIT. +// +// Instead modify 'tools/experimental_features.yaml' and run +// 'dart tools/generate_experimental_flags.dart' to update. +// +// Current version: ${currentVersion.join('.')} + +#ifndef RUNTIME_VM_EXPERIMENTAL_FEATURES_H_ +#define RUNTIME_VM_EXPERIMENTAL_FEATURES_H_ + +namespace dart { + +enum class ExperimentalFeature { +$enumNames}; + +bool GetExperimentalFeatureDefault(ExperimentalFeature feature); +const char* GetExperimentalFeatureName(ExperimentalFeature feature); + +} // namespace dart + +#endif // RUNTIME_VM_EXPERIMENTAL_FEATURES_H_ +'''; + + final cc = ''' +// Copyright (c) 2020, 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. +// NOTE: THIS FILE IS GENERATED. DO NOT EDIT. +// +// Instead modify 'tools/experimental_features.yaml' and run +// 'dart tools/generate_experimental_flags.dart' to update. +// +// Current version: ${currentVersion.join('.')} + +#include "vm/experimental_features.h" + +#include +#include "platform/assert.h" +#include "vm/globals.h" + +namespace dart { + +bool GetExperimentalFeatureDefault(ExperimentalFeature feature) { + constexpr bool kFeatureValues[] = { +$featureValues }; + ASSERT(static_cast(feature) < ARRAY_SIZE(kFeatureValues)); + return kFeatureValues[static_cast(feature)]; +} + +const char* GetExperimentalFeatureName(ExperimentalFeature feature) { + constexpr const char* kFeatureNames[] = { +$featureNames }; + ASSERT(static_cast(feature) < ARRAY_SIZE(kFeatureNames)); + return kFeatureNames[static_cast(feature)]; +} + +} // namespace dart +'''; + + File.fromUri(computeHFile()).writeAsStringSync(h); + File.fromUri(computeCcFile()).writeAsStringSync(cc); +} + +Uri computeYamlFile() { + return Platform.script.resolve("experimental_features.yaml"); +} + +Uri computeCcFile() { + return Platform.script.resolve("../runtime/vm/experimental_features.cc"); +} + +Uri computeHFile() { + return Platform.script.resolve("../runtime/vm/experimental_features.h"); +} + +List getAsVersionNumber(dynamic value) { + if (value == null) return null; + final version = List.of("$value".split(".").map(int.parse)); + while (version.length < 3) version.add(0); + return version; +} + +bool isGreaterOrEqualVersion(List left, List right) { + assert(left.length == right.length); + for (var i = 0; i < left.length; ++i) { + if (left[i] != right[i]) return left[i] > right[i]; + } + return true; +}