mirror of
https://github.com/dart-lang/sdk
synced 2024-09-18 20:11:19 +00:00
[kernel,vm] First-class kernel serialization of FutureOrType and NullType
TEST=ci Fixes https://github.com/dart-lang/sdk/issues/52565 Change-Id: I9906f2d10c7ed51d11a0c402b51c8189ac3b6298 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/306901 Commit-Queue: Alexander Markov <alexmarkov@google.com> Reviewed-by: Chloe Stefantsova <cstefantsova@google.com> Reviewed-by: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
parent
8d29829271
commit
5ff0821b27
|
@ -147,7 +147,7 @@ type CanonicalName {
|
|||
|
||||
type ComponentFile {
|
||||
UInt32 magic = 0x90ABCDEF;
|
||||
UInt32 formatVersion = 102;
|
||||
UInt32 formatVersion = 103;
|
||||
Byte[10] shortSdkHash;
|
||||
List<String> problemsAsJson; // Described in problems.md.
|
||||
Library[] libraries;
|
||||
|
@ -1540,6 +1540,10 @@ type VoidType extends DartType {
|
|||
Byte tag = 92;
|
||||
}
|
||||
|
||||
type NullType extends DartType {
|
||||
Byte tag = 152;
|
||||
}
|
||||
|
||||
type InterfaceType extends DartType {
|
||||
Byte tag = 93;
|
||||
Byte nullability; // Index into the Nullability enum above.
|
||||
|
@ -1633,6 +1637,12 @@ type TypedefType {
|
|||
List<DartType> typeArguments;
|
||||
}
|
||||
|
||||
type FutureOrType extends DartType {
|
||||
Byte tag = 107;
|
||||
Byte nullability; // Index into the Nullability enum above.
|
||||
DartType typeArgument;
|
||||
}
|
||||
|
||||
type TypeParameter {
|
||||
// Note: there is no tag on TypeParameter
|
||||
Byte flags (isCovariantByClass);
|
||||
|
|
|
@ -3817,6 +3817,8 @@ class BinaryBuilder {
|
|||
return _readInvalidType();
|
||||
case Tag.NeverType:
|
||||
return _readNeverType();
|
||||
case Tag.NullType:
|
||||
return _readNullType();
|
||||
case Tag.InlineType:
|
||||
return _readInlineType();
|
||||
case Tag.FunctionType:
|
||||
|
@ -3825,6 +3827,8 @@ class BinaryBuilder {
|
|||
return _readIntersectionType();
|
||||
case Tag.RecordType:
|
||||
return _readRecordType();
|
||||
case Tag.FutureOrType:
|
||||
return _readFutureOrType();
|
||||
default:
|
||||
throw fail('unexpected dart type tag: $tag');
|
||||
}
|
||||
|
@ -3853,19 +3857,14 @@ class BinaryBuilder {
|
|||
return NeverType.fromNullability(Nullability.values[nullabilityIndex]);
|
||||
}
|
||||
|
||||
DartType _readNullType() {
|
||||
return const NullType();
|
||||
}
|
||||
|
||||
DartType _readInterfaceType() {
|
||||
int nullabilityIndex = readByte();
|
||||
Reference reference = readNonNullClassReference();
|
||||
List<DartType> typeArguments = readDartTypeList();
|
||||
CanonicalName? canonicalName = reference.canonicalName;
|
||||
if (canonicalName != null &&
|
||||
canonicalName.name == "FutureOr" &&
|
||||
canonicalName.parent!.name == "dart:async" &&
|
||||
canonicalName.parent!.parent != null &&
|
||||
canonicalName.parent!.parent!.isRoot) {
|
||||
return new FutureOrType(
|
||||
typeArguments.single, Nullability.values[nullabilityIndex]);
|
||||
}
|
||||
return new InterfaceType.byReference(
|
||||
reference, Nullability.values[nullabilityIndex], typeArguments);
|
||||
}
|
||||
|
@ -3879,15 +3878,6 @@ class BinaryBuilder {
|
|||
throw 'Expected a class reference to be valid but was `null`.';
|
||||
}
|
||||
|
||||
// We check this before the cache to not return a wrong cached value for
|
||||
// this special case.
|
||||
if (!forSupertype &&
|
||||
canonicalName.name == "Null" &&
|
||||
canonicalName.parent!.name == "dart:core" &&
|
||||
canonicalName.parent!.parent!.isRoot) {
|
||||
return const NullType();
|
||||
}
|
||||
|
||||
// Check cache.
|
||||
final int cacheIndex =
|
||||
(classReferenceIndex - 1) * Nullability.values.length +
|
||||
|
@ -3905,6 +3895,12 @@ class BinaryBuilder {
|
|||
return result;
|
||||
}
|
||||
|
||||
DartType _readFutureOrType() {
|
||||
int nullabilityIndex = readByte();
|
||||
DartType typeArgument = readDartType();
|
||||
return new FutureOrType(typeArgument, Nullability.values[nullabilityIndex]);
|
||||
}
|
||||
|
||||
DartType _readInlineType() {
|
||||
int nullabilityIndex = readByte();
|
||||
Reference reference = readNonNullInlineClassReference();
|
||||
|
|
|
@ -2477,38 +2477,14 @@ class BinaryPrinter implements Visitor<void>, BinarySink {
|
|||
|
||||
@override
|
||||
void visitFutureOrType(FutureOrType node) {
|
||||
// TODO(cstefantsova): Remove special treatment of FutureOr when the VM
|
||||
// supports the new encoding: just write the tag.
|
||||
assert(_knownCanonicalNameNonRootTops.isNotEmpty);
|
||||
CanonicalName root = _knownCanonicalNameNonRootTops.first;
|
||||
while (!root.isRoot) {
|
||||
root = root.parent!;
|
||||
}
|
||||
CanonicalName canonicalNameOfFutureOr =
|
||||
root.getChild("dart:async").getChild("FutureOr");
|
||||
writeByte(Tag.InterfaceType);
|
||||
writeByte(Tag.FutureOrType);
|
||||
writeByte(node.declaredNullability.index);
|
||||
checkCanonicalName(canonicalNameOfFutureOr);
|
||||
writeUInt30(canonicalNameOfFutureOr.index + 1);
|
||||
writeUInt30(1); // Type argument count.
|
||||
writeNode(node.typeArgument);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitNullType(NullType node) {
|
||||
// TODO(cstefantsova): Remove special treatment of Null when the VM
|
||||
// supports the new encoding: just write the tag.
|
||||
assert(_knownCanonicalNameNonRootTops.isNotEmpty);
|
||||
CanonicalName root = _knownCanonicalNameNonRootTops.first;
|
||||
while (!root.isRoot) {
|
||||
root = root.parent!;
|
||||
}
|
||||
CanonicalName canonicalNameOfNull =
|
||||
root.getChild("dart:core").getChild("Null");
|
||||
writeByte(Tag.SimpleInterfaceType);
|
||||
writeByte(node.declaredNullability.index);
|
||||
checkCanonicalName(canonicalNameOfNull);
|
||||
writeUInt30(canonicalNameOfNull.index + 1);
|
||||
writeByte(Tag.NullType);
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -158,6 +158,7 @@ class Tag {
|
|||
// 104 is occupied by [RecordLiteral] (expression).
|
||||
// 105 is occupied by [ConstRecordLiteral] (expression).
|
||||
// 106 is occupied by [ConstantExpression].
|
||||
static const int FutureOrType = 107;
|
||||
|
||||
// 108 is occupied by [RedirectingFactory] (member).
|
||||
// 109 is occupied by [SetLiteral] (expression).
|
||||
|
@ -206,6 +207,8 @@ class Tag {
|
|||
static const int PatternAssignment = 150;
|
||||
static const int PatternVariableDeclaration = 151;
|
||||
|
||||
static const int NullType = 152;
|
||||
|
||||
static const int SpecializedTagHighBits = 0xE0; // 0b11100000
|
||||
static const int SpecializedTagMask = 0xF8; // 0b11111000
|
||||
static const int SpecializedPayloadMask = 0x7; // 0b00000111
|
||||
|
@ -222,7 +225,7 @@ class Tag {
|
|||
/// Internal version of kernel binary format.
|
||||
/// Bump it when making incompatible changes in kernel binaries.
|
||||
/// Keep in sync with runtime/vm/kernel_binary.h, pkg/kernel/binary.md.
|
||||
static const int BinaryFormatVersion = 102;
|
||||
static const int BinaryFormatVersion = 103;
|
||||
}
|
||||
|
||||
abstract class ConstantTag {
|
||||
|
|
|
@ -233,6 +233,7 @@ void KernelFingerprintHelper::CalculateDartTypeFingerprint() {
|
|||
case kInvalidType:
|
||||
case kDynamicType:
|
||||
case kVoidType:
|
||||
case kNullType:
|
||||
// those contain nothing.
|
||||
break;
|
||||
case kNeverType:
|
||||
|
@ -280,6 +281,10 @@ void KernelFingerprintHelper::CalculateDartTypeFingerprint() {
|
|||
CalculateDartTypeFingerprint(); // read instantiated representation type.
|
||||
break;
|
||||
}
|
||||
case kFutureOrType:
|
||||
BuildHash(static_cast<uint32_t>(ReadNullability()));
|
||||
CalculateDartTypeFingerprint(); // read type argument.
|
||||
break;
|
||||
default:
|
||||
ReportUnexpectedTag("type", tag);
|
||||
UNREACHABLE();
|
||||
|
|
|
@ -2244,6 +2244,7 @@ void KernelReaderHelper::SkipDartType() {
|
|||
case kInvalidType:
|
||||
case kDynamicType:
|
||||
case kVoidType:
|
||||
case kNullType:
|
||||
// those contain nothing.
|
||||
return;
|
||||
case kNeverType:
|
||||
|
@ -2292,6 +2293,10 @@ void KernelReaderHelper::SkipDartType() {
|
|||
SkipDartType(); // read left.
|
||||
SkipDartType(); // read right.
|
||||
return;
|
||||
case kFutureOrType:
|
||||
ReadNullability();
|
||||
SkipDartType(); // read type argument.
|
||||
break;
|
||||
default:
|
||||
ReportUnexpectedTag("type", tag);
|
||||
UNREACHABLE();
|
||||
|
@ -3205,6 +3210,9 @@ void TypeTranslator::BuildTypeInternal() {
|
|||
.ToNullability(nullability, Heap::kOld);
|
||||
break;
|
||||
}
|
||||
case kNullType:
|
||||
result_ = IG->object_store()->null_type();
|
||||
break;
|
||||
case kInterfaceType:
|
||||
BuildInterfaceType(false);
|
||||
break;
|
||||
|
@ -3229,6 +3237,9 @@ void TypeTranslator::BuildTypeInternal() {
|
|||
case kInlineType:
|
||||
BuildInlineType();
|
||||
break;
|
||||
case kFutureOrType:
|
||||
BuildFutureOrType();
|
||||
break;
|
||||
default:
|
||||
helper_->ReportUnexpectedTag("type", tag);
|
||||
UNREACHABLE();
|
||||
|
@ -3275,6 +3286,27 @@ void TypeTranslator::BuildInterfaceType(bool simple) {
|
|||
}
|
||||
}
|
||||
|
||||
void TypeTranslator::BuildFutureOrType() {
|
||||
Nullability nullability = helper_->ReadNullability();
|
||||
if (apply_canonical_type_erasure_ && nullability != Nullability::kNullable) {
|
||||
nullability = Nullability::kLegacy;
|
||||
}
|
||||
|
||||
const TypeArguments& type_arguments =
|
||||
TypeArguments::Handle(Z, TypeArguments::New(1));
|
||||
BuildTypeInternal(); // read type argument.
|
||||
type_arguments.SetTypeAt(0, result_);
|
||||
|
||||
const Class& klass = Class::Handle(Z, IG->object_store()->future_or_class());
|
||||
ASSERT(!klass.IsNull());
|
||||
|
||||
result_ = Type::New(klass, type_arguments, nullability);
|
||||
result_ = result_.NormalizeFutureOrType(Heap::kOld);
|
||||
if (finalize_) {
|
||||
result_ = ClassFinalizer::FinalizeType(result_);
|
||||
}
|
||||
}
|
||||
|
||||
void TypeTranslator::BuildFunctionType(bool simple) {
|
||||
const intptr_t num_enclosing_type_arguments =
|
||||
active_class_->enclosing != nullptr
|
||||
|
|
|
@ -1576,6 +1576,7 @@ class TypeTranslator {
|
|||
void BuildTypeParameterType();
|
||||
void BuildIntersectionType();
|
||||
void BuildInlineType();
|
||||
void BuildFutureOrType();
|
||||
|
||||
class TypeParameterScope {
|
||||
public:
|
||||
|
|
|
@ -1375,6 +1375,7 @@ void ScopeBuilder::VisitDartType() {
|
|||
case kInvalidType:
|
||||
case kDynamicType:
|
||||
case kVoidType:
|
||||
case kNullType:
|
||||
// those contain nothing.
|
||||
return;
|
||||
case kNeverType:
|
||||
|
@ -1404,6 +1405,9 @@ void ScopeBuilder::VisitDartType() {
|
|||
case kInlineType:
|
||||
VisitInlineType();
|
||||
return;
|
||||
case kFutureOrType:
|
||||
VisitFutureOrType();
|
||||
return;
|
||||
default:
|
||||
ReportUnexpectedTag("type", tag);
|
||||
UNREACHABLE();
|
||||
|
@ -1525,6 +1529,11 @@ void ScopeBuilder::VisitInlineType() {
|
|||
VisitDartType(); // read instantiated representation type.
|
||||
}
|
||||
|
||||
void ScopeBuilder::VisitFutureOrType() {
|
||||
helper_.ReadNullability();
|
||||
VisitDartType(); // read type argument.
|
||||
}
|
||||
|
||||
void ScopeBuilder::HandleLocalFunction(intptr_t parent_kernel_offset) {
|
||||
// "Peek" ahead into the function node
|
||||
const intptr_t offset = helper_.ReaderOffset();
|
||||
|
|
|
@ -52,6 +52,7 @@ class ScopeBuilder {
|
|||
void VisitTypeParameterType();
|
||||
void VisitIntersectionType();
|
||||
void VisitInlineType();
|
||||
void VisitFutureOrType();
|
||||
void HandleLocalFunction(intptr_t parent_kernel_offset);
|
||||
|
||||
AbstractType& BuildAndVisitVariableType();
|
||||
|
|
|
@ -132,7 +132,7 @@ namespace dart {
|
|||
0xc40903ac) \
|
||||
V(_SuspendState, _clone, SuspendState_clone, 0xae1a40a0) \
|
||||
V(_SuspendState, _createAsyncCallbacks, SuspendState_createAsyncCallbacks, \
|
||||
0x5e84c091) \
|
||||
0x86343257) \
|
||||
V(_SuspendState, _createAsyncStarCallback, \
|
||||
SuspendState_createAsyncStarCallback, 0x98fb897c) \
|
||||
V(_SuspendState, _resume, SuspendState_resume, 0x5d7a8489) \
|
||||
|
@ -319,10 +319,10 @@ namespace dart {
|
|||
V(::, _getNativeField, GetNativeField, 0xa0139b85) \
|
||||
V(::, reachabilityFence, ReachabilityFence, 0x730f2b7f) \
|
||||
V(_Utf8Decoder, _scan, Utf8DecoderScan, 0xb99d2ee1) \
|
||||
V(_Future, timeout, FutureTimeout, 0xe21f0bf8) \
|
||||
V(Future, wait, FutureWait, 0x22f98225) \
|
||||
V(_Future, timeout, FutureTimeout, 0xa0f743d4) \
|
||||
V(Future, wait, FutureWait, 0x295fe957) \
|
||||
V(_RootZone, runUnary, RootZoneRunUnary, 0x64397ecb) \
|
||||
V(_FutureListener, handleValue, FutureListenerHandleValue, 0xbf5d3892) \
|
||||
V(_FutureListener, handleValue, FutureListenerHandleValue, 0xec25d1b2) \
|
||||
V(::, has63BitSmis, Has63BitSmis, 0xf61b56f1) \
|
||||
V(::, get:extensionStreamHasListener, ExtensionStreamHasListener, 0xfab46343)\
|
||||
V(_Smi, get:hashCode, Smi_hashCode, 0x75e0ccd2) \
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -18,7 +18,7 @@ namespace kernel {
|
|||
// package:kernel/binary.md.
|
||||
|
||||
static const uint32_t kMagicProgramFile = 0x90ABCDEFu;
|
||||
static const uint32_t kSupportedKernelFormatVersion = 102;
|
||||
static const uint32_t kSupportedKernelFormatVersion = 103;
|
||||
|
||||
// Keep in sync with package:kernel/lib/binary/tag.dart
|
||||
#define KERNEL_TAG_LIST(V) \
|
||||
|
@ -136,6 +136,7 @@ static const uint32_t kSupportedKernelFormatVersion = 102;
|
|||
V(RecordType, 100) \
|
||||
V(InlineType, 103) \
|
||||
V(ConstantExpression, 106) \
|
||||
V(FutureOrType, 107) \
|
||||
V(InstanceGet, 118) \
|
||||
V(InstanceSet, 119) \
|
||||
V(InstanceInvocation, 120) \
|
||||
|
@ -171,6 +172,7 @@ static const uint32_t kSupportedKernelFormatVersion = 102;
|
|||
V(IfCaseStatement, 149) \
|
||||
V(PatternAssignment, 150) \
|
||||
V(PatternVariableDeclaration, 151) \
|
||||
V(NullType, 152) \
|
||||
V(SpecializedVariableGet, 224) \
|
||||
V(SpecializedVariableSet, 232) \
|
||||
V(SpecializedIntLiteral, 240)
|
||||
|
|
|
@ -2123,6 +2123,7 @@ ErrorPtr Object::Init(IsolateGroup* isolate_group,
|
|||
cls.set_num_type_arguments_unsafe(1);
|
||||
RegisterClass(cls, Symbols::FutureOr(), lib);
|
||||
pending_classes.Add(cls);
|
||||
object_store->set_future_or_class(cls);
|
||||
|
||||
cls = Class::New<SuspendState, RTN::SuspendState>(isolate_group);
|
||||
RegisterPrivateClass(cls, Symbols::_SuspendState(), lib);
|
||||
|
@ -2674,6 +2675,7 @@ ErrorPtr Object::Init(IsolateGroup* isolate_group,
|
|||
cls = Class::New<MirrorReference, RTN::MirrorReference>(isolate_group);
|
||||
cls = Class::New<UserTag, RTN::UserTag>(isolate_group);
|
||||
cls = Class::New<FutureOr, RTN::FutureOr>(isolate_group);
|
||||
object_store->set_future_or_class(cls);
|
||||
cls = Class::New<TransferableTypedData, RTN::TransferableTypedData>(
|
||||
isolate_group);
|
||||
}
|
||||
|
|
|
@ -114,6 +114,7 @@ class ObjectPointerVisitor;
|
|||
RW(Field, pragma_name) \
|
||||
RW(Field, pragma_options) \
|
||||
RW(Class, future_class) \
|
||||
RW(Class, future_or_class) \
|
||||
RW(Class, completer_class) \
|
||||
RW(Class, one_byte_string_class) \
|
||||
RW(Class, two_byte_string_class) \
|
||||
|
|
Loading…
Reference in a new issue