mirror of
https://github.com/dart-lang/sdk
synced 2024-09-30 06:11:16 +00:00
[vm] Remove transition_sentinel and detection of cyclic initialization of legacy static fields
Since null safety, all static fields with initializers are implicitly late. This change cleans up transition_sentinel which was used in the detection of cyclic initialization of legacy static fields. TEST=ci Change-Id: I6a990dc8ba030f5bd40eb0b86706cbfb0f725e33 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/373520 Reviewed-by: Alexander Aprelev <aam@google.com> Commit-Queue: Alexander Markov <alexmarkov@google.com>
This commit is contained in:
parent
caffef2942
commit
00eac588c2
|
@ -2389,7 +2389,7 @@ abstract class SentinelKind {
|
|||
/// Indicates that a variable or field has not been initialized.
|
||||
static const String kNotInitialized = 'NotInitialized';
|
||||
|
||||
/// Indicates that a variable or field is in the process of being initialized.
|
||||
/// Deprecated, no longer used.
|
||||
static const String kBeingInitialized = 'BeingInitialized';
|
||||
|
||||
/// Indicates that a variable has been eliminated by the optimizing compiler.
|
||||
|
@ -2513,8 +2513,6 @@ class AllocationProfile extends Response {
|
|||
/// If the field is uninitialized, the `value` will be the `NotInitialized`
|
||||
/// [Sentinel].
|
||||
///
|
||||
/// If the field is being initialized, the `value` will be the
|
||||
/// `BeingInitialized` [Sentinel].
|
||||
class BoundField {
|
||||
static BoundField? parse(Map<String, dynamic>? json) =>
|
||||
json == null ? null : BoundField._fromJson(json);
|
||||
|
@ -2567,9 +2565,6 @@ class BoundField {
|
|||
/// If the variable is uninitialized, the `value` will be the `NotInitialized`
|
||||
/// [Sentinel].
|
||||
///
|
||||
/// If the variable is being initialized, the `value` will be the
|
||||
/// `BeingInitialized` [Sentinel].
|
||||
///
|
||||
/// If the variable has been optimized out by the compiler, the `value` will be
|
||||
/// the `OptimizedOut` [Sentinel].
|
||||
class BoundVariable extends Response {
|
||||
|
|
|
@ -55,8 +55,6 @@ class SentinelValueElement extends CustomElement implements Renderable {
|
|||
case M.SentinelKind.notInitialized:
|
||||
return 'This object will be initialized once it is accessed by '
|
||||
'the program.';
|
||||
case M.SentinelKind.initializing:
|
||||
return 'This object is currently being initialized.';
|
||||
case M.SentinelKind.optimizedOut:
|
||||
return 'This object is no longer needed and has been removed by the '
|
||||
'optimizing compiler.';
|
||||
|
|
|
@ -90,8 +90,6 @@ class SentinelViewElement extends CustomElement implements Renderable {
|
|||
case M.SentinelKind.notInitialized:
|
||||
return 'This object will be initialized once it is accessed by '
|
||||
'the program.';
|
||||
case M.SentinelKind.initializing:
|
||||
return 'This object is currently being initialized.';
|
||||
case M.SentinelKind.optimizedOut:
|
||||
return 'This object is no longer needed and has been removed by the '
|
||||
'optimizing compiler.';
|
||||
|
|
|
@ -14,9 +14,6 @@ enum SentinelKind {
|
|||
/// Indicates that a variable or field has not been initialized.
|
||||
notInitialized,
|
||||
|
||||
/// Indicates that a variable or field is in the process of being initialized.
|
||||
initializing,
|
||||
|
||||
/// Indicates that a variable has been eliminated by the optimizing compiler.
|
||||
optimizedOut,
|
||||
|
||||
|
|
|
@ -3319,8 +3319,6 @@ M.SentinelKind stringToSentinelKind(String s) {
|
|||
return M.SentinelKind.expired;
|
||||
case 'NotInitialized':
|
||||
return M.SentinelKind.notInitialized;
|
||||
case 'BeingInitialized':
|
||||
return M.SentinelKind.initializing;
|
||||
case 'OptimizedOut':
|
||||
return M.SentinelKind.optimizedOut;
|
||||
case 'Free':
|
||||
|
|
|
@ -6815,8 +6815,6 @@ class VMSerializationRoots : public SerializationRoots {
|
|||
|
||||
s->AddBaseObject(Object::null(), "Null", "null");
|
||||
s->AddBaseObject(Object::sentinel().ptr(), "Null", "sentinel");
|
||||
s->AddBaseObject(Object::transition_sentinel().ptr(), "Null",
|
||||
"transition_sentinel");
|
||||
s->AddBaseObject(Object::optimized_out().ptr(), "Null", "<optimized out>");
|
||||
s->AddBaseObject(Object::empty_array().ptr(), "Array", "<empty_array>");
|
||||
s->AddBaseObject(Object::empty_instantiations_cache_array().ptr(), "Array",
|
||||
|
@ -6940,7 +6938,6 @@ class VMDeserializationRoots : public DeserializationRoots {
|
|||
|
||||
d->AddBaseObject(Object::null());
|
||||
d->AddBaseObject(Object::sentinel().ptr());
|
||||
d->AddBaseObject(Object::transition_sentinel().ptr());
|
||||
d->AddBaseObject(Object::optimized_out().ptr());
|
||||
d->AddBaseObject(Object::empty_array().ptr());
|
||||
d->AddBaseObject(Object::empty_instantiations_cache_array().ptr());
|
||||
|
|
|
@ -1217,8 +1217,7 @@ void Precompiler::AddConstObject(const class Instance& instance) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (instance.ptr() == Object::sentinel().ptr() ||
|
||||
instance.ptr() == Object::transition_sentinel().ptr()) {
|
||||
if (instance.ptr() == Object::sentinel().ptr()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1332,8 +1331,6 @@ void Precompiler::AddField(const Field& field) {
|
|||
auto field_table = field.is_shared() ? IG->shared_initial_field_table()
|
||||
: IG->initial_field_table();
|
||||
const Object& value = Object::Handle(Z, field_table->At(field.field_id()));
|
||||
// Should not be in the middle of initialization while precompiling.
|
||||
ASSERT(value.ptr() != Object::transition_sentinel().ptr());
|
||||
|
||||
if (value.ptr() != Object::sentinel().ptr() &&
|
||||
value.ptr() != Object::null()) {
|
||||
|
|
|
@ -4571,22 +4571,18 @@ void LoadStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
|||
return;
|
||||
}
|
||||
ASSERT(field().has_initializer());
|
||||
ASSERT(field().is_late());
|
||||
auto object_store = compiler->isolate_group()->object_store();
|
||||
const Field& original_field = Field::ZoneHandle(field().Original());
|
||||
|
||||
compiler::Label no_call, call_initializer;
|
||||
compiler::Label no_call;
|
||||
__ CompareObject(result, Object::sentinel());
|
||||
if (!field().is_late()) {
|
||||
__ BranchIf(EQUAL, &call_initializer);
|
||||
__ CompareObject(result, Object::transition_sentinel());
|
||||
}
|
||||
__ BranchIf(NOT_EQUAL, &no_call);
|
||||
|
||||
auto& stub = Code::ZoneHandle(compiler->zone());
|
||||
__ Bind(&call_initializer);
|
||||
if (field().needs_load_guard()) {
|
||||
stub = object_store->init_static_field_stub();
|
||||
} else if (field().is_late()) {
|
||||
} else {
|
||||
// The stubs below call the initializer function directly, so make sure
|
||||
// one is created.
|
||||
original_field.EnsureInitializerFunction();
|
||||
|
@ -4598,11 +4594,6 @@ void LoadStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
|||
: (field().is_final()
|
||||
? object_store->init_late_final_static_field_stub()
|
||||
: object_store->init_late_static_field_stub());
|
||||
} else {
|
||||
// We call to runtime for non-late fields because the stub would need to
|
||||
// catch any exception generated by the initialization function to change
|
||||
// the value of the static field from the transition sentinel to null.
|
||||
stub = object_store->init_static_field_stub();
|
||||
}
|
||||
|
||||
__ LoadObject(InitStaticFieldABI::kFieldReg, original_field);
|
||||
|
|
|
@ -1692,8 +1692,6 @@ void FlowGraphSerializer::WriteObjectImpl(const Object& x,
|
|||
case kSentinelCid:
|
||||
if (x.ptr() == Object::sentinel().ptr()) {
|
||||
Write<uint8_t>(0);
|
||||
} else if (x.ptr() == Object::transition_sentinel().ptr()) {
|
||||
Write<uint8_t>(1);
|
||||
} else if (x.ptr() == Object::optimized_out().ptr()) {
|
||||
Write<uint8_t>(2);
|
||||
} else {
|
||||
|
@ -1978,8 +1976,6 @@ const Object& FlowGraphDeserializer::ReadObjectImpl(intptr_t cid,
|
|||
switch (Read<uint8_t>()) {
|
||||
case 0:
|
||||
return Object::sentinel();
|
||||
case 1:
|
||||
return Object::transition_sentinel();
|
||||
case 2:
|
||||
return Object::optimized_out();
|
||||
default:
|
||||
|
|
|
@ -1202,10 +1202,6 @@ ObjectPtr Exceptions::Create(ExceptionType type, const Array& arguments) {
|
|||
constructor_name = &Symbols::DotCreate();
|
||||
break;
|
||||
#endif
|
||||
case kCyclicInitializationError:
|
||||
library = Library::CoreLibrary();
|
||||
class_name = &Symbols::_CyclicInitializationError();
|
||||
break;
|
||||
case kCompileTimeError:
|
||||
library = Library::CoreLibrary();
|
||||
class_name = &Symbols::_CompileTimeError();
|
||||
|
|
|
@ -67,7 +67,6 @@ class Exceptions : AllStatic {
|
|||
kAssertion,
|
||||
kType,
|
||||
kAbstractClassInstantiation,
|
||||
kCyclicInitializationError,
|
||||
kCompileTimeError,
|
||||
kLateFieldAssignedDuringInitialization,
|
||||
kLateFieldNotInitialized,
|
||||
|
|
|
@ -100,7 +100,7 @@ struct WeakAcqRelStorageTraits : WeakArrayStorageTraits {
|
|||
|
||||
class HashTableBase : public ValueObject {
|
||||
public:
|
||||
static const Object& UnusedMarker() { return Object::transition_sentinel(); }
|
||||
static const Object& UnusedMarker() { return Object::sentinel(); }
|
||||
static const Object& DeletedMarker() { return Object::null_object(); }
|
||||
};
|
||||
|
||||
|
@ -156,7 +156,7 @@ class HashTableBase : public ValueObject {
|
|||
// Each entry contains a key, followed by zero or more payload components,
|
||||
// and has 3 possible states: unused, occupied, or deleted.
|
||||
// The header tracks the number of entries in each state.
|
||||
// Any object except the backing storage array and Object::transition_sentinel()
|
||||
// Any object except the backing storage array and Object::sentinel()
|
||||
// may be stored as a key. Any object may be stored in a payload.
|
||||
//
|
||||
// Parameters
|
||||
|
|
|
@ -2208,8 +2208,7 @@ class FieldInvalidator {
|
|||
// At that point it doesn't have the field table setup yet.
|
||||
if (field_table->IsReadyToUse()) {
|
||||
value_ = field_table->At(field_id);
|
||||
if ((value_.ptr() != Object::sentinel().ptr()) &&
|
||||
(value_.ptr() != Object::transition_sentinel().ptr())) {
|
||||
if (value_.ptr() != Object::sentinel().ptr()) {
|
||||
CheckValueType(value_, field);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,8 +27,6 @@
|
|||
namespace dart {
|
||||
|
||||
static Dart_CObject cobj_sentinel = {Dart_CObject_kUnsupported, {false}};
|
||||
static Dart_CObject cobj_transition_sentinel = {Dart_CObject_kUnsupported,
|
||||
{false}};
|
||||
static Dart_CObject cobj_dynamic_type = {Dart_CObject_kUnsupported, {false}};
|
||||
static Dart_CObject cobj_void_type = {Dart_CObject_kUnsupported, {false}};
|
||||
static Dart_CObject cobj_empty_type_arguments = {Dart_CObject_kUnsupported,
|
||||
|
@ -3216,7 +3214,6 @@ MessageDeserializationCluster* BaseDeserializer::ReadCluster() {
|
|||
void MessageSerializer::AddBaseObjects() {
|
||||
AddBaseObject(Object::null());
|
||||
AddBaseObject(Object::sentinel().ptr());
|
||||
AddBaseObject(Object::transition_sentinel().ptr());
|
||||
AddBaseObject(Object::empty_array().ptr());
|
||||
AddBaseObject(Object::dynamic_type().ptr());
|
||||
AddBaseObject(Object::void_type().ptr());
|
||||
|
@ -3228,7 +3225,6 @@ void MessageSerializer::AddBaseObjects() {
|
|||
void MessageDeserializer::AddBaseObjects() {
|
||||
AddBaseObject(Object::null());
|
||||
AddBaseObject(Object::sentinel().ptr());
|
||||
AddBaseObject(Object::transition_sentinel().ptr());
|
||||
AddBaseObject(Object::empty_array().ptr());
|
||||
AddBaseObject(Object::dynamic_type().ptr());
|
||||
AddBaseObject(Object::void_type().ptr());
|
||||
|
@ -3240,7 +3236,6 @@ void MessageDeserializer::AddBaseObjects() {
|
|||
void ApiMessageSerializer::AddBaseObjects() {
|
||||
AddBaseObject(PredefinedCObjects::cobj_null());
|
||||
AddBaseObject(&cobj_sentinel);
|
||||
AddBaseObject(&cobj_transition_sentinel);
|
||||
AddBaseObject(PredefinedCObjects::cobj_empty_array());
|
||||
AddBaseObject(&cobj_dynamic_type);
|
||||
AddBaseObject(&cobj_void_type);
|
||||
|
@ -3252,7 +3247,6 @@ void ApiMessageSerializer::AddBaseObjects() {
|
|||
void ApiMessageDeserializer::AddBaseObjects() {
|
||||
AddBaseObject(PredefinedCObjects::cobj_null());
|
||||
AddBaseObject(&cobj_sentinel);
|
||||
AddBaseObject(&cobj_transition_sentinel);
|
||||
AddBaseObject(PredefinedCObjects::cobj_empty_array());
|
||||
AddBaseObject(&cobj_dynamic_type);
|
||||
AddBaseObject(&cobj_void_type);
|
||||
|
|
|
@ -830,7 +830,6 @@ void Object::Init(IsolateGroup* isolate_group) {
|
|||
// Allocate and initialize the sentinel values.
|
||||
{
|
||||
*sentinel_ ^= Sentinel::New();
|
||||
*transition_sentinel_ ^= Sentinel::New();
|
||||
}
|
||||
|
||||
// Allocate and initialize optimizing compiler constants.
|
||||
|
@ -1316,8 +1315,6 @@ void Object::Init(IsolateGroup* isolate_group) {
|
|||
ASSERT(empty_async_exception_handlers_->IsExceptionHandlers());
|
||||
ASSERT(!sentinel_->IsSmi());
|
||||
ASSERT(sentinel_->IsSentinel());
|
||||
ASSERT(!transition_sentinel_->IsSmi());
|
||||
ASSERT(transition_sentinel_->IsSentinel());
|
||||
ASSERT(!unknown_constant_->IsSmi());
|
||||
ASSERT(unknown_constant_->IsSentinel());
|
||||
ASSERT(!non_constant_->IsSmi());
|
||||
|
@ -12311,7 +12308,6 @@ bool Field::IsUninitialized() const {
|
|||
Thread* thread = Thread::Current();
|
||||
const FieldTable* field_table = thread->isolate()->field_table();
|
||||
const ObjectPtr raw_value = field_table->At(field_id());
|
||||
ASSERT(raw_value != Object::transition_sentinel().ptr());
|
||||
return raw_value == Object::sentinel().ptr();
|
||||
}
|
||||
|
||||
|
@ -12399,40 +12395,25 @@ ErrorPtr Field::InitializeStatic() const {
|
|||
ASSERT(IsOriginal());
|
||||
ASSERT(is_static());
|
||||
if (StaticValue() == Object::sentinel().ptr()) {
|
||||
ASSERT(is_late());
|
||||
auto& value = Object::Handle();
|
||||
if (is_late()) {
|
||||
if (!has_initializer()) {
|
||||
Exceptions::ThrowLateFieldNotInitialized(String::Handle(name()));
|
||||
UNREACHABLE();
|
||||
}
|
||||
value = EvaluateInitializer();
|
||||
if (value.IsError()) {
|
||||
return Error::Cast(value).ptr();
|
||||
}
|
||||
if (is_final() && (StaticValue() != Object::sentinel().ptr())) {
|
||||
Exceptions::ThrowLateFieldAssignedDuringInitialization(
|
||||
String::Handle(name()));
|
||||
UNREACHABLE();
|
||||
}
|
||||
} else {
|
||||
SetStaticValue(Object::transition_sentinel());
|
||||
value = EvaluateInitializer();
|
||||
if (value.IsError()) {
|
||||
SetStaticValue(Object::null_instance());
|
||||
return Error::Cast(value).ptr();
|
||||
}
|
||||
if (!has_initializer()) {
|
||||
Exceptions::ThrowLateFieldNotInitialized(String::Handle(name()));
|
||||
UNREACHABLE();
|
||||
}
|
||||
value = EvaluateInitializer();
|
||||
if (value.IsError()) {
|
||||
return Error::Cast(value).ptr();
|
||||
}
|
||||
if (is_final() && (StaticValue() != Object::sentinel().ptr())) {
|
||||
Exceptions::ThrowLateFieldAssignedDuringInitialization(
|
||||
String::Handle(name()));
|
||||
UNREACHABLE();
|
||||
}
|
||||
ASSERT(value.IsNull() || value.IsInstance());
|
||||
SetStaticValue(value.IsNull() ? Instance::null_instance()
|
||||
: Instance::Cast(value));
|
||||
return Error::null();
|
||||
} else if (StaticValue() == Object::transition_sentinel().ptr()) {
|
||||
ASSERT(!is_late());
|
||||
const Array& ctor_args = Array::Handle(Array::New(1));
|
||||
const String& field_name = String::Handle(name());
|
||||
ctor_args.SetAt(0, field_name);
|
||||
Exceptions::ThrowByType(Exceptions::kCyclicInitializationError, ctor_args);
|
||||
UNREACHABLE();
|
||||
}
|
||||
return Error::null();
|
||||
}
|
||||
|
@ -12824,7 +12805,6 @@ StaticTypeExactnessState StaticTypeExactnessState::Compute(
|
|||
bool print_trace /* = false */) {
|
||||
ASSERT(!value.IsNull()); // Should be handled by the caller.
|
||||
ASSERT(value.ptr() != Object::sentinel().ptr());
|
||||
ASSERT(value.ptr() != Object::transition_sentinel().ptr());
|
||||
|
||||
Thread* thread = Thread::Current();
|
||||
Zone* const zone = thread->zone();
|
||||
|
@ -18754,8 +18734,6 @@ SentinelPtr Sentinel::New() {
|
|||
const char* Sentinel::ToCString() const {
|
||||
if (ptr() == Object::sentinel().ptr()) {
|
||||
return "sentinel";
|
||||
} else if (ptr() == Object::transition_sentinel().ptr()) {
|
||||
return "transition_sentinel";
|
||||
} else if (ptr() == Object::unknown_constant().ptr()) {
|
||||
return "unknown_constant";
|
||||
} else if (ptr() == Object::non_constant().ptr()) {
|
||||
|
|
|
@ -447,9 +447,6 @@ class Object {
|
|||
//
|
||||
// - sentinel is a value that cannot be produced by Dart code. It can be used
|
||||
// to mark special values, for example to distinguish "uninitialized" fields.
|
||||
// - transition_sentinel is a value marking that we are transitioning from
|
||||
// sentinel, e.g., computing a field value. Used to detect circular
|
||||
// initialization.
|
||||
// - unknown_constant and non_constant are optimizing compiler's constant
|
||||
// propagation constants.
|
||||
// - optimized_out results from deopt environment pruning or failure to
|
||||
|
@ -480,7 +477,6 @@ class Object {
|
|||
V(Array, synthetic_getter_parameter_types) \
|
||||
V(Array, synthetic_getter_parameter_names) \
|
||||
V(Sentinel, sentinel) \
|
||||
V(Sentinel, transition_sentinel) \
|
||||
V(Sentinel, unknown_constant) \
|
||||
V(Sentinel, non_constant) \
|
||||
V(Sentinel, optimized_out) \
|
||||
|
@ -7580,9 +7576,6 @@ class ContextScope : public Object {
|
|||
// - Object::sentinel() is a value that cannot be produced by Dart code.
|
||||
// It can be used to mark special values, for example to distinguish
|
||||
// "uninitialized" fields.
|
||||
// - Object::transition_sentinel() is a value marking that we are transitioning
|
||||
// from sentinel, e.g., computing a field value. Used to detect circular
|
||||
// initialization of static fields.
|
||||
// - Object::unknown_constant() and Object::non_constant() are optimizing
|
||||
// compiler's constant propagation constants.
|
||||
// - Object::optimized_out() result from deopt environment pruning or failure
|
||||
|
|
|
@ -1137,9 +1137,6 @@ class Pass2Visitor : public ObjectVisitor,
|
|||
if (obj == Object::sentinel().ptr()) {
|
||||
writer_->WriteUnsigned(kNameData);
|
||||
writer_->WriteUtf8("uninitialized");
|
||||
} else if (obj == Object::transition_sentinel().ptr()) {
|
||||
writer_->WriteUnsigned(kNameData);
|
||||
writer_->WriteUtf8("initializing");
|
||||
} else {
|
||||
writer_->WriteUnsigned(kNoData);
|
||||
}
|
||||
|
|
|
@ -1129,12 +1129,6 @@ void Sentinel::PrintJSONImpl(JSONStream* stream, bool ref) const {
|
|||
jsobj.AddProperty("kind", "NotInitialized");
|
||||
jsobj.AddProperty("valueAsString", "<not initialized>");
|
||||
return;
|
||||
} else if (ptr() == Object::transition_sentinel().ptr()) {
|
||||
JSONObject jsobj(stream);
|
||||
jsobj.AddProperty("type", "Sentinel");
|
||||
jsobj.AddProperty("kind", "BeingInitialized");
|
||||
jsobj.AddProperty("valueAsString", "<being initialized>");
|
||||
return;
|
||||
} else if (ptr() == Object::optimized_out().ptr()) {
|
||||
JSONObject jsobj(stream);
|
||||
jsobj.AddProperty("type", "Sentinel");
|
||||
|
|
|
@ -6367,16 +6367,6 @@ ISOLATE_UNIT_TEST_CASE(PrintJSONPrimitives) {
|
|||
"\"valueAsString\":\"<not initialized>\"}",
|
||||
js.ToCString());
|
||||
}
|
||||
// Transition sentinel reference
|
||||
{
|
||||
JSONStream js;
|
||||
Object::transition_sentinel().PrintJSON(&js, true);
|
||||
EXPECT_STREQ(
|
||||
"{\"type\":\"Sentinel\","
|
||||
"\"kind\":\"BeingInitialized\","
|
||||
"\"valueAsString\":\"<being initialized>\"}",
|
||||
js.ToCString());
|
||||
}
|
||||
}
|
||||
|
||||
#endif // !PRODUCT
|
||||
|
|
|
@ -3826,8 +3826,7 @@ DEFINE_RUNTIME_ENTRY(InitInstanceField, 2) {
|
|||
Object& result = Object::Handle(zone, field.InitializeInstance(instance));
|
||||
ThrowIfError(result);
|
||||
result = instance.GetField(field);
|
||||
ASSERT((result.ptr() != Object::sentinel().ptr()) &&
|
||||
(result.ptr() != Object::transition_sentinel().ptr()));
|
||||
ASSERT(result.ptr() != Object::sentinel().ptr());
|
||||
arguments.SetReturn(result);
|
||||
}
|
||||
|
||||
|
@ -3836,8 +3835,7 @@ DEFINE_RUNTIME_ENTRY(InitStaticField, 1) {
|
|||
Object& result = Object::Handle(zone, field.InitializeStatic());
|
||||
ThrowIfError(result);
|
||||
result = field.StaticValue();
|
||||
ASSERT((result.ptr() != Object::sentinel().ptr()) &&
|
||||
(result.ptr() != Object::transition_sentinel().ptr()));
|
||||
ASSERT(result.ptr() != Object::sentinel().ptr());
|
||||
arguments.SetReturn(result);
|
||||
}
|
||||
|
||||
|
|
|
@ -1891,9 +1891,6 @@ _Instance_.
|
|||
If the field is uninitialized, the _value_ will be the
|
||||
_NotInitialized_ [Sentinel](#sentinel).
|
||||
|
||||
If the field is being initialized, the _value_ will be the
|
||||
_BeingInitialized_ [Sentinel](#sentinel).
|
||||
|
||||
### BoundVariable
|
||||
|
||||
```
|
||||
|
@ -1918,9 +1915,6 @@ in a _Frame_.
|
|||
If the variable is uninitialized, the _value_ will be the
|
||||
_NotInitialized_ [Sentinel](#sentinel).
|
||||
|
||||
If the variable is being initialized, the _value_ will be the
|
||||
_BeingInitialized_ [Sentinel](#sentinel).
|
||||
|
||||
If the variable has been optimized out by the compiler, the _value_
|
||||
will be the _OptimizedOut_ [Sentinel](#sentinel).
|
||||
|
||||
|
@ -4188,7 +4182,7 @@ enum SentinelKind {
|
|||
// Indicates that a variable or field has not been initialized.
|
||||
NotInitialized,
|
||||
|
||||
// Indicates that a variable or field is in the process of being initialized.
|
||||
// Deprecated, no longer used.
|
||||
BeingInitialized,
|
||||
|
||||
// Indicates that a variable has been eliminated by the optimizing compiler.
|
||||
|
|
|
@ -291,7 +291,6 @@ class ObjectPointerVisitor;
|
|||
V(_ConstMap, "_ConstMap") \
|
||||
V(_ConstSet, "_ConstSet") \
|
||||
V(_ControllerSubscription, "_ControllerSubscription") \
|
||||
V(_CyclicInitializationError, "_CyclicInitializationError") \
|
||||
V(_DeletedEnumPrefix, "Deleted enum value from ") \
|
||||
V(_DeletedEnumSentinel, "_deleted_enum_sentinel") \
|
||||
V(_Double, "_Double") \
|
||||
|
|
|
@ -132,30 +132,6 @@ class StateError {
|
|||
}
|
||||
}
|
||||
|
||||
/// Error thrown when a lazily initialized variable cannot be initialized.
|
||||
///
|
||||
/// Cyclic dependencies are no longer detected at runtime in null safe code.
|
||||
/// Such code will fail in other ways instead,
|
||||
/// possibly with a [StackOverflowError].
|
||||
///
|
||||
/// Will be removed when support for non-null-safe code is discontinued.
|
||||
@Deprecated("Remove when no longer supporting non-null-safe code.")
|
||||
class _CyclicInitializationError extends Error {
|
||||
final String? variableName;
|
||||
@pragma("vm:entry-point")
|
||||
_CyclicInitializationError([this.variableName]);
|
||||
String toString() {
|
||||
var variableName = this.variableName;
|
||||
return variableName == null
|
||||
? "Reading static variable during its initialization"
|
||||
: "Reading static variable '$variableName' during its initialization";
|
||||
}
|
||||
|
||||
static _throwNew(String variableName) {
|
||||
throw new _CyclicInitializationError(variableName);
|
||||
}
|
||||
}
|
||||
|
||||
@patch
|
||||
class NoSuchMethodError {
|
||||
final Object? _receiver;
|
||||
|
|
Loading…
Reference in a new issue