Skip to content

Commit 8ec91ff

Browse files
alexmarkovCommit Bot
authored and
Commit Bot
committed
[vm] Support absent 'values' field in enum classes
VM queries the list of enum elements during class finalization in order to be prepared for the future hot reload. This is done by reading 'values' field. However, 'values' field can be missing if running from a dill file which was tree-shaken. This change avoids crash in that case and handles missing 'values' field as if it was declared with an empty list. TEST=Manually tested in g3. Issue: #47861 Bug: b/213584901 Change-Id: Ic7271476ee115aa93a73a824af3a867784b820eb Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/226981 Reviewed-by: Ryan Macnak <[email protected]> Commit-Queue: Alexander Markov <[email protected]>
1 parent 4475267 commit 8ec91ff

File tree

2 files changed

+22
-13
lines changed

2 files changed

+22
-13
lines changed

runtime/vm/class_finalizer.cc

+8-7
Original file line numberDiff line numberDiff line change
@@ -1226,15 +1226,16 @@ void ClassFinalizer::AllocateEnumValues(const Class& enum_cls) {
12261226

12271227
const auto& values_field =
12281228
Field::Handle(zone, enum_cls.LookupStaticField(Symbols::Values()));
1229-
ASSERT(!values_field.IsNull() && values_field.is_static() &&
1230-
values_field.is_const());
1229+
if (!values_field.IsNull()) {
1230+
ASSERT(values_field.is_static() && values_field.is_const());
12311231

1232-
const auto& values =
1233-
Object::Handle(zone, values_field.StaticConstFieldValue());
1234-
if (values.IsError()) {
1235-
ReportError(Error::Cast(values));
1232+
const auto& values =
1233+
Object::Handle(zone, values_field.StaticConstFieldValue());
1234+
if (values.IsError()) {
1235+
ReportError(Error::Cast(values));
1236+
}
1237+
ASSERT(values.IsArray());
12361238
}
1237-
ASSERT(values.IsArray());
12381239

12391240
// The enum_cls is the actual declared class.
12401241
// The shared super-class holds the fields for index and name.

runtime/vm/object_reload.cc

+14-6
Original file line numberDiff line numberDiff line change
@@ -325,9 +325,13 @@ void Class::ReplaceEnum(ProgramReloadContext* reload_context,
325325

326326
{
327327
field = old_enum.LookupStaticField(Symbols::Values());
328-
ASSERT(!field.IsNull() && field.is_static() && field.is_const());
329-
old_enum_values ^= field.StaticConstFieldValue();
330-
ASSERT(!old_enum_values.IsNull());
328+
if (!field.IsNull()) {
329+
ASSERT(field.is_static() && field.is_const());
330+
old_enum_values ^= field.StaticConstFieldValue();
331+
ASSERT(!old_enum_values.IsNull());
332+
} else {
333+
old_enum_values = Array::empty_array().ptr();
334+
}
331335

332336
field = old_enum.LookupStaticField(Symbols::_DeletedEnumSentinel());
333337
ASSERT(!field.IsNull() && field.is_static() && field.is_const());
@@ -357,9 +361,13 @@ void Class::ReplaceEnum(ProgramReloadContext* reload_context,
357361
bool enums_deleted = false;
358362
{
359363
field = LookupStaticField(Symbols::Values());
360-
ASSERT(!field.IsNull() && field.is_static() && field.is_const());
361-
enum_values ^= field.StaticConstFieldValue();
362-
ASSERT(!enum_values.IsNull());
364+
if (!field.IsNull()) {
365+
ASSERT(field.is_static() && field.is_const());
366+
enum_values ^= field.StaticConstFieldValue();
367+
ASSERT(!enum_values.IsNull());
368+
} else {
369+
enum_values = Array::empty_array().ptr();
370+
}
363371

364372
field = LookupStaticField(Symbols::_DeletedEnumSentinel());
365373
ASSERT(!field.IsNull() && field.is_static() && field.is_const());

0 commit comments

Comments
 (0)