Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 1e9f997

Browse files
author
Dart CI
committed
Version 2.12.0-115.0.dev
Merge commit 'c7f364562cabef42a42869646b3246a1aaf58d2f' into 'dev'
2 parents 2d128ce + c7f3645 commit 1e9f997

File tree

6 files changed

+208
-11
lines changed

6 files changed

+208
-11
lines changed
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright (c) 2020, 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+
import 'package:test/test.dart';
6+
7+
import '../tool/fix_driver.dart';
8+
import 'utils.dart';
9+
10+
void main() {
11+
group('Driver', _driver);
12+
}
13+
14+
Future<FixOutput> runFix(List<String> args) async {
15+
var runner = FixRunner(logger: CapturingLogger());
16+
var result = await runner.runFix(args);
17+
return FixOutput(result);
18+
}
19+
20+
void _driver() {
21+
TestProject p;
22+
tearDown(() => p?.dispose());
23+
24+
test('no fixes', () async {
25+
p = project(mainSrc: 'int get foo => 1;\n');
26+
var result = await runFix(['--apply', p.dirPath]);
27+
expect(result.stdout, contains('Nothing to fix!'));
28+
expect(result.returnCode, 0);
29+
});
30+
}
31+
32+
class FixOutput {
33+
final FixResult<CapturingLogger> result;
34+
FixOutput(this.result);
35+
36+
int get returnCode => result.returnCode;
37+
String get stderr => result.logger.output.stderr.toString();
38+
String get stdout => result.logger.output.stdout.toString();
39+
}

pkg/dartdev/test/test_all.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import 'commands/run_test.dart' as run;
1818
import 'commands/test_test.dart' as test;
1919
import 'core_test.dart' as core;
2020
import 'experiments_test.dart' as experiments;
21+
import 'fix_driver_test.dart' as fix_driver;
2122
import 'no_such_file_test.dart' as no_such_file;
2223
import 'sdk_test.dart' as sdk;
2324
import 'smoke/implicit_smoke_test.dart' as implicit_smoke;
@@ -32,6 +33,7 @@ void main() {
3233
create.main();
3334
experiments.main();
3435
fix.main();
36+
fix_driver.main();
3537
flag.main();
3638
format.main();
3739
help.main();

pkg/dartdev/tool/fix_driver.dart

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
// Copyright (c) 2020, 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+
import 'package:args/args.dart';
6+
import 'package:args/command_runner.dart';
7+
import 'package:cli_util/cli_logging.dart';
8+
import 'package:dartdev/src/commands/fix.dart';
9+
import 'package:dartdev/src/core.dart';
10+
import 'package:dartdev/src/utils.dart';
11+
import 'package:meta/meta.dart';
12+
13+
Future<void> main(List<String> args) async {
14+
var runner = FixRunner(logger: Logger.standard());
15+
var result = await runner.runFix(args);
16+
return result.returnCode;
17+
}
18+
19+
class CapturedProgress extends Progress {
20+
final LoggerOutput output;
21+
22+
bool canceled = false;
23+
bool finished = false;
24+
25+
CapturedProgress(this.output, String message) : super(message) {
26+
output.progress.writeln(message);
27+
}
28+
29+
@override
30+
void cancel() {
31+
canceled = true;
32+
}
33+
34+
@override
35+
void finish({String message, bool showTiming = false}) {
36+
// todo (pq): consider capturing / tracking finish display updates.
37+
finished = true;
38+
}
39+
}
40+
41+
class CapturingLogger implements Logger {
42+
final LoggerOutput output = LoggerOutput();
43+
44+
@override
45+
final Ansi ansi = Ansi(Ansi.terminalSupportsAnsi);
46+
47+
@override
48+
bool isVerbose;
49+
50+
CapturingLogger({this.isVerbose = false});
51+
52+
@override
53+
void flush() {
54+
// deprecated.
55+
}
56+
57+
@override
58+
Progress progress(String message) => CapturedProgress(output, message);
59+
60+
@override
61+
void stderr(String message) {
62+
output.stderr.writeln(message);
63+
}
64+
65+
@override
66+
void stdout(String message) {
67+
output.stdout.writeln(message);
68+
}
69+
70+
@override
71+
void trace(String message) {
72+
output.trace.writeln(message);
73+
}
74+
75+
@override
76+
void write(String message) {
77+
output.stdout.write(message);
78+
}
79+
80+
@override
81+
void writeCharCode(int charCode) {
82+
output.stdout.writeCharCode(charCode);
83+
}
84+
}
85+
86+
class FixResult<T extends Logger> {
87+
/// The value returned by [FixCommand.run].
88+
final int returnCode;
89+
90+
/// The logger used in driving fixes.
91+
final T logger;
92+
93+
FixResult(this.logger, this.returnCode);
94+
}
95+
96+
class FixRunner<T extends Logger> extends CommandRunner<int> {
97+
final _supportedOptions = ['dry-run', 'apply'];
98+
99+
T logger;
100+
101+
@override
102+
final ArgParser argParser = ArgParser(
103+
usageLineLength: dartdevUsageLineLength,
104+
allowTrailingOptions: false,
105+
);
106+
107+
FixRunner({@required this.logger})
108+
: super('fix_runner',
109+
'A command-line utility for testing the `dart fix` command.') {
110+
addCommand(FixCommand());
111+
_supportedOptions.forEach(argParser.addOption);
112+
}
113+
114+
@override
115+
Future<int> runCommand(ArgResults topLevelResults) async {
116+
var result = await super.runCommand(topLevelResults);
117+
return result;
118+
}
119+
120+
Future<FixResult<T>> runFix(List<String> args) async {
121+
log = logger;
122+
var argResults = argParser.parse(['fix', ...?args]);
123+
var result = await runCommand(argResults);
124+
return FixResult(logger, result);
125+
}
126+
}
127+
128+
class LoggerOutput {
129+
/// Messages reported to progress.
130+
final StringBuffer progress = StringBuffer();
131+
132+
/// Messages reported to stdout.
133+
final StringBuffer stdout = StringBuffer();
134+
135+
/// Messages reported to stderr.
136+
final StringBuffer stderr = StringBuffer();
137+
138+
/// Messages reported to trace.
139+
final StringBuffer trace = StringBuffer();
140+
}

runtime/vm/compiler/backend/slot.cc

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,18 @@ static classid_t GetUnboxedNativeSlotCid(Representation rep) {
110110
return kIllegalCid;
111111
}
112112

113+
AcqRelAtomic<Slot*> Slot::native_fields_(nullptr);
114+
115+
enum NativeSlotsEnumeration {
116+
#define DECLARE_KIND(CN, __, FN, ___, ____) k##CN##_##FN,
117+
NATIVE_SLOTS_LIST(DECLARE_KIND)
118+
#undef DECLARE_KIND
119+
kNativeSlotsCount
120+
};
121+
113122
const Slot& Slot::GetNativeSlot(Kind kind) {
114-
// There is a fixed statically known number of native slots so we cache
115-
// them statically.
116-
static const Slot fields[] = {
123+
if (native_fields_.load() == nullptr) {
124+
Slot* new_value = new Slot[kNativeSlotsCount]{
117125
#define NULLABLE_FIELD_FINAL \
118126
(IsNullableBit::encode(true) | IsImmutableBit::encode(true))
119127
#define NULLABLE_FIELD_VAR (IsNullableBit::encode(true))
@@ -123,7 +131,7 @@ const Slot& Slot::GetNativeSlot(Kind kind) {
123131
k##cid##Cid, compiler::target::ClassName::FieldName##_offset(), \
124132
#ClassName "." #FieldName, nullptr, kTagged),
125133

126-
NULLABLE_BOXED_NATIVE_SLOTS_LIST(DEFINE_NULLABLE_BOXED_NATIVE_FIELD)
134+
NULLABLE_BOXED_NATIVE_SLOTS_LIST(DEFINE_NULLABLE_BOXED_NATIVE_FIELD)
127135

128136
#undef DEFINE_NULLABLE_BOXED_NATIVE_FIELD
129137
#undef NULLABLE_FIELD_FINAL
@@ -137,8 +145,8 @@ const Slot& Slot::GetNativeSlot(Kind kind) {
137145
k##cid##Cid, compiler::target::ClassName::FieldName##_offset(), \
138146
#ClassName "." #FieldName, nullptr, kTagged),
139147

140-
NONNULLABLE_BOXED_NATIVE_SLOTS_LIST(
141-
DEFINE_NONNULLABLE_BOXED_NATIVE_FIELD)
148+
NONNULLABLE_BOXED_NATIVE_SLOTS_LIST(
149+
DEFINE_NONNULLABLE_BOXED_NATIVE_FIELD)
142150

143151
#undef DEFINE_NONNULLABLE_BOXED_NATIVE_FIELD
144152
#define DEFINE_UNBOXED_NATIVE_FIELD(ClassName, UnderlyingType, FieldName, \
@@ -148,15 +156,20 @@ const Slot& Slot::GetNativeSlot(Kind kind) {
148156
compiler::target::ClassName::FieldName##_offset(), \
149157
#ClassName "." #FieldName, nullptr, kUnboxed##representation),
150158

151-
UNBOXED_NATIVE_SLOTS_LIST(DEFINE_UNBOXED_NATIVE_FIELD)
159+
UNBOXED_NATIVE_SLOTS_LIST(DEFINE_UNBOXED_NATIVE_FIELD)
152160

153161
#undef DEFINE_UNBOXED_NATIVE_FIELD
154162
#undef NONNULLABLE_FIELD_VAR
155163
#undef NONNULLABLE_FIELD_FINAL
156-
};
164+
};
165+
Slot* old_value = nullptr;
166+
if (!native_fields_.compare_exchange_strong(old_value, new_value)) {
167+
delete[] new_value;
168+
}
169+
}
157170

158-
ASSERT(static_cast<uint8_t>(kind) < ARRAY_SIZE(fields));
159-
return fields[static_cast<uint8_t>(kind)];
171+
ASSERT(static_cast<uint8_t>(kind) < kNativeSlotsCount);
172+
return native_fields_.load()[static_cast<uint8_t>(kind)];
160173
}
161174

162175
// Note: should only be called with cids of array-like classes.

runtime/vm/compiler/backend/slot.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,9 @@ class Slot : public ZoneAllocated {
295295
return static_cast<const T*>(data_);
296296
}
297297

298+
// There is a fixed statically known number of native slots so we cache
299+
// them statically.
300+
static AcqRelAtomic<Slot*> native_fields_;
298301
static const Slot& GetNativeSlot(Kind kind);
299302

300303
const Kind kind_;

tools/VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,5 @@ CHANNEL dev
2727
MAJOR 2
2828
MINOR 12
2929
PATCH 0
30-
PRERELEASE 114
30+
PRERELEASE 115
3131
PRERELEASE_PATCH 0

0 commit comments

Comments
 (0)