mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 04:06:59 +00:00
More positions in dart2 constant evaluator
Use positions already available in for instance AsExpressions, also adds new offsets in the kernel format to SuperInitializer and RedirectingInitializer. Bug: #33216 Change-Id: I542967ddc6ec782e6513d62fce038a49239e1622 Reviewed-on: https://dart-review.googlesource.com/63883 Commit-Queue: Jens Johansen <jensj@google.com> Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
This commit is contained in:
parent
eafc52aae7
commit
d26dba1619
|
@ -131,7 +131,7 @@ type CanonicalName {
|
|||
|
||||
type ComponentFile {
|
||||
UInt32 magic = 0x90ABCDEF;
|
||||
UInt32 formatVersion = 8;
|
||||
UInt32 formatVersion = 9;
|
||||
Library[] libraries;
|
||||
UriSource sourceMap;
|
||||
List<CanonicalName> canonicalNames;
|
||||
|
@ -406,6 +406,7 @@ type FieldInitializer extends Initializer {
|
|||
type SuperInitializer extends Initializer {
|
||||
Byte tag = 9;
|
||||
Byte isSynthetic;
|
||||
FileOffset fileOffset;
|
||||
ConstructorReference target;
|
||||
Arguments arguments;
|
||||
}
|
||||
|
@ -413,6 +414,7 @@ type SuperInitializer extends Initializer {
|
|||
type RedirectingInitializer extends Initializer {
|
||||
Byte tag = 10;
|
||||
Byte isSynthetic;
|
||||
FileOffset fileOffset;
|
||||
ConstructorReference target;
|
||||
Arguments arguments;
|
||||
}
|
||||
|
|
|
@ -1166,13 +1166,17 @@ class BinaryBuilder {
|
|||
return new FieldInitializer.byReference(reference, value)
|
||||
..isSynthetic = isSynthetic;
|
||||
case Tag.SuperInitializer:
|
||||
int offset = readOffset();
|
||||
var reference = readMemberReference();
|
||||
var arguments = readArguments();
|
||||
return new SuperInitializer.byReference(reference, arguments)
|
||||
..isSynthetic = isSynthetic;
|
||||
..isSynthetic = isSynthetic
|
||||
..fileOffset = offset;
|
||||
case Tag.RedirectingInitializer:
|
||||
int offset = readOffset();
|
||||
return new RedirectingInitializer.byReference(
|
||||
readMemberReference(), readArguments());
|
||||
readMemberReference(), readArguments())
|
||||
..fileOffset = offset;
|
||||
case Tag.LocalInitializer:
|
||||
return new LocalInitializer(readAndPushVariableDeclaration());
|
||||
case Tag.AssertInitializer:
|
||||
|
|
|
@ -917,6 +917,7 @@ class BinaryPrinter implements Visitor<void>, BinarySink {
|
|||
void visitSuperInitializer(SuperInitializer node) {
|
||||
writeByte(Tag.SuperInitializer);
|
||||
writeByte(node.isSynthetic ? 1 : 0);
|
||||
writeOffset(node.fileOffset);
|
||||
writeReference(node.targetReference);
|
||||
writeNode(node.arguments);
|
||||
}
|
||||
|
@ -925,6 +926,7 @@ class BinaryPrinter implements Visitor<void>, BinarySink {
|
|||
void visitRedirectingInitializer(RedirectingInitializer node) {
|
||||
writeByte(Tag.RedirectingInitializer);
|
||||
writeByte(node.isSynthetic ? 1 : 0);
|
||||
writeOffset(node.fileOffset);
|
||||
writeReference(node.targetReference);
|
||||
writeNode(node.arguments);
|
||||
}
|
||||
|
|
|
@ -135,7 +135,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 = 8;
|
||||
static const int BinaryFormatVersion = 9;
|
||||
}
|
||||
|
||||
abstract class ConstantTag {
|
||||
|
|
|
@ -361,7 +361,7 @@ void StreamingConstantEvaluator::EvaluateStaticGet() {
|
|||
}
|
||||
|
||||
void StreamingConstantEvaluator::EvaluateMethodInvocation() {
|
||||
builder_->ReadPosition(); // read position.
|
||||
TokenPosition position = builder_->ReadPosition(); // read position.
|
||||
// This method call wasn't cached, so receiver et al. isn't cached either.
|
||||
const Instance& receiver = Instance::Handle(
|
||||
Z,
|
||||
|
@ -380,7 +380,7 @@ void StreamingConstantEvaluator::EvaluateMethodInvocation() {
|
|||
ASSERT(!function.IsNull());
|
||||
|
||||
// Read arguments, run the method and canonicalize the result.
|
||||
const Object& result = RunMethodCall(function, &receiver);
|
||||
const Object& result = RunMethodCall(position, function, &receiver);
|
||||
result_ ^= result.raw();
|
||||
result_ = H.Canonicalize(result_);
|
||||
|
||||
|
@ -388,7 +388,7 @@ void StreamingConstantEvaluator::EvaluateMethodInvocation() {
|
|||
}
|
||||
|
||||
void StreamingConstantEvaluator::EvaluateDirectMethodInvocation() {
|
||||
builder_->ReadPosition(); // read position.
|
||||
TokenPosition position = builder_->ReadPosition(); // read position.
|
||||
|
||||
const Instance& receiver = Instance::Handle(
|
||||
Z,
|
||||
|
@ -401,7 +401,7 @@ void StreamingConstantEvaluator::EvaluateDirectMethodInvocation() {
|
|||
Z, H.LookupMethodByMember(kernel_name, H.DartProcedureName(kernel_name)));
|
||||
|
||||
// Read arguments, run the method and canonicalize the result.
|
||||
const Object& result = RunMethodCall(function, &receiver);
|
||||
const Object& result = RunMethodCall(position, function, &receiver);
|
||||
result_ ^= result.raw();
|
||||
result_ = H.Canonicalize(result_);
|
||||
}
|
||||
|
@ -415,7 +415,7 @@ Class& StreamingFlowGraphBuilder::GetSuperOrDie() {
|
|||
}
|
||||
|
||||
void StreamingConstantEvaluator::EvaluateSuperMethodInvocation() {
|
||||
builder_->ReadPosition(); // read position.
|
||||
TokenPosition position = builder_->ReadPosition(); // read position.
|
||||
|
||||
const LocalVariable* this_variable = builder_->scopes()->this_variable;
|
||||
ASSERT(this_variable->IsConst());
|
||||
|
@ -434,7 +434,7 @@ void StreamingConstantEvaluator::EvaluateSuperMethodInvocation() {
|
|||
ASSERT(!function.IsNull());
|
||||
|
||||
// Read arguments, run the method and canonicalize the result.
|
||||
const Object& result = RunMethodCall(function, &receiver);
|
||||
const Object& result = RunMethodCall(position, function, &receiver);
|
||||
result_ ^= result.raw();
|
||||
result_ = H.Canonicalize(result_);
|
||||
|
||||
|
@ -442,7 +442,7 @@ void StreamingConstantEvaluator::EvaluateSuperMethodInvocation() {
|
|||
}
|
||||
|
||||
void StreamingConstantEvaluator::EvaluateStaticInvocation() {
|
||||
builder_->ReadPosition(); // read position.
|
||||
TokenPosition position = builder_->ReadPosition(); // read position.
|
||||
NameIndex procedure_reference =
|
||||
builder_->ReadCanonicalNameReference(); // read procedure reference.
|
||||
|
||||
|
@ -459,13 +459,13 @@ void StreamingConstantEvaluator::EvaluateStaticInvocation() {
|
|||
|
||||
// read positional and named parameters.
|
||||
const Object& result =
|
||||
RunFunction(function, argument_count, NULL, type_arguments);
|
||||
RunFunction(position, function, argument_count, NULL, type_arguments);
|
||||
result_ ^= result.raw();
|
||||
result_ = H.Canonicalize(result_);
|
||||
}
|
||||
|
||||
void StreamingConstantEvaluator::EvaluateConstructorInvocationInternal() {
|
||||
builder_->ReadPosition(); // read position.
|
||||
TokenPosition position = builder_->ReadPosition(); // read position.
|
||||
|
||||
NameIndex target = builder_->ReadCanonicalNameReference(); // read target.
|
||||
const Function& constructor =
|
||||
|
@ -506,8 +506,8 @@ void StreamingConstantEvaluator::EvaluateConstructorInvocationInternal() {
|
|||
}
|
||||
|
||||
// read positional and named parameters.
|
||||
const Object& result = RunFunction(constructor, argument_count, receiver,
|
||||
type_arguments_argument);
|
||||
const Object& result = RunFunction(position, constructor, argument_count,
|
||||
receiver, type_arguments_argument);
|
||||
|
||||
if (constructor.IsFactory()) {
|
||||
// Factories return the new object.
|
||||
|
@ -547,14 +547,14 @@ void StreamingConstantEvaluator::EvaluateLogicalExpression() {
|
|||
}
|
||||
|
||||
void StreamingConstantEvaluator::EvaluateAsExpression() {
|
||||
builder_->ReadPosition();
|
||||
TokenPosition position = builder_->ReadPosition();
|
||||
const uint8_t flags = builder_->ReadFlags();
|
||||
const bool is_type_error = (flags & (1 << 0)) != 0;
|
||||
|
||||
// Check that this AsExpression was inserted by the front-end.
|
||||
if (!is_type_error) {
|
||||
H.ReportError(
|
||||
script_, TokenPosition::kNoSource,
|
||||
script_, position,
|
||||
"explicit as operator is not permitted in constant expression");
|
||||
}
|
||||
|
||||
|
@ -564,7 +564,7 @@ void StreamingConstantEvaluator::EvaluateAsExpression() {
|
|||
if (!type.IsInstantiated() || type.IsMalformed()) {
|
||||
const String& type_str = String::Handle(type.UserVisibleName());
|
||||
H.ReportError(
|
||||
script_, TokenPosition::kNoSource,
|
||||
script_, position,
|
||||
"Not a constant expression: right hand side of an implicit "
|
||||
"as-expression is expected to be an instantiated type, got %s",
|
||||
type_str.ToCString());
|
||||
|
@ -579,9 +579,10 @@ void StreamingConstantEvaluator::EvaluateAsExpression() {
|
|||
AbstractType::Handle(result_.GetType(Heap::kNew));
|
||||
const String& result_str = String::Handle(rtype.UserVisibleName());
|
||||
const String& type_str = String::Handle(type.UserVisibleName());
|
||||
H.ReportError(script_, TokenPosition::kNoSource,
|
||||
"Not a constant expression: %s is not an instance of %s",
|
||||
result_str.ToCString(), type_str.ToCString());
|
||||
H.ReportError(
|
||||
script_, position,
|
||||
"Not a constant expression: Type '%s' is not a subtype of type '%s'",
|
||||
result_str.ToCString(), type_str.ToCString());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -598,7 +599,7 @@ void StreamingConstantEvaluator::EvaluateConditionalExpression() {
|
|||
}
|
||||
|
||||
void StreamingConstantEvaluator::EvaluateStringConcatenation() {
|
||||
builder_->ReadPosition(); // read position.
|
||||
TokenPosition position = builder_->ReadPosition(); // read position.
|
||||
intptr_t length = builder_->ReadListLength(); // read list length.
|
||||
|
||||
bool all_string = true;
|
||||
|
@ -629,7 +630,7 @@ void StreamingConstantEvaluator::EvaluateStringConcatenation() {
|
|||
|
||||
// Run and canonicalize.
|
||||
const Object& result =
|
||||
RunFunction(func, interpolate_arg, Array::null_array());
|
||||
RunFunction(position, func, interpolate_arg, Array::null_array());
|
||||
result_ = H.Canonicalize(String::Cast(result));
|
||||
}
|
||||
}
|
||||
|
@ -808,6 +809,7 @@ void StreamingConstantEvaluator::EvaluateConstantExpression() {
|
|||
|
||||
// This depends on being about to read the list of positionals on arguments.
|
||||
const Object& StreamingConstantEvaluator::RunFunction(
|
||||
TokenPosition position,
|
||||
const Function& function,
|
||||
intptr_t argument_count,
|
||||
const Instance* receiver,
|
||||
|
@ -856,12 +858,14 @@ const Object& StreamingConstantEvaluator::RunFunction(
|
|||
arguments.SetAt(pos++, result_);
|
||||
}
|
||||
|
||||
return RunFunction(function, arguments, names);
|
||||
return RunFunction(position, function, arguments, names);
|
||||
}
|
||||
|
||||
const Object& StreamingConstantEvaluator::RunFunction(const Function& function,
|
||||
const Array& arguments,
|
||||
const Array& names) {
|
||||
const Object& StreamingConstantEvaluator::RunFunction(
|
||||
const TokenPosition position,
|
||||
const Function& function,
|
||||
const Array& arguments,
|
||||
const Array& names) {
|
||||
// We do not support generic methods yet.
|
||||
const int kTypeArgsLen = 0;
|
||||
const Array& args_descriptor = Array::Handle(
|
||||
|
@ -869,12 +873,14 @@ const Object& StreamingConstantEvaluator::RunFunction(const Function& function,
|
|||
const Object& result = Object::Handle(
|
||||
Z, DartEntry::InvokeFunction(function, arguments, args_descriptor));
|
||||
if (result.IsError()) {
|
||||
H.ReportError(Error::Cast(result), "error evaluating constant constructor");
|
||||
H.ReportError(Error::Cast(result), script_, position,
|
||||
"error evaluating constant constructor");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const Object& StreamingConstantEvaluator::RunMethodCall(
|
||||
const TokenPosition position,
|
||||
const Function& function,
|
||||
const Instance* receiver) {
|
||||
intptr_t argument_count = builder_->ReadUInt(); // read arguments count.
|
||||
|
@ -884,7 +890,7 @@ const Object& StreamingConstantEvaluator::RunMethodCall(
|
|||
builder_->SkipListOfDartTypes(); // read list of types.
|
||||
|
||||
// Run the method.
|
||||
return RunFunction(function, argument_count, receiver, NULL);
|
||||
return RunFunction(position, function, argument_count, receiver, NULL);
|
||||
}
|
||||
|
||||
RawObject* StreamingConstantEvaluator::EvaluateConstConstructorCall(
|
||||
|
@ -1151,10 +1157,12 @@ void KernelFingerprintHelper::CalculateInitializerFingerprint() {
|
|||
CalculateExpressionFingerprint(); // read value.
|
||||
return;
|
||||
case kSuperInitializer:
|
||||
ReadPosition(); // read position.
|
||||
CalculateCanonicalNameFingerprint(); // read target_reference
|
||||
CalculateArgumentsFingerprint(); // read arguments.
|
||||
return;
|
||||
case kRedirectingInitializer:
|
||||
ReadPosition(); // read position.
|
||||
CalculateCanonicalNameFingerprint(); // read target_reference
|
||||
CalculateArgumentsFingerprint(); // read arguments.
|
||||
return;
|
||||
|
@ -1976,7 +1984,7 @@ Fragment StreamingFlowGraphBuilder::BuildInitializers(
|
|||
intptr_t list_length = ReadListLength(); // read initializers list length.
|
||||
for (intptr_t i = 0; i < list_length; ++i) {
|
||||
Tag tag = ReadTag();
|
||||
ReadByte(); // read isSynthetic flag.
|
||||
bool isSynthetic = ReadBool(); // read isSynthetic flag.
|
||||
switch (tag) {
|
||||
case kInvalidInitializer:
|
||||
UNIMPLEMENTED();
|
||||
|
@ -1992,6 +2000,7 @@ Fragment StreamingFlowGraphBuilder::BuildInitializers(
|
|||
break;
|
||||
}
|
||||
case kSuperInitializer: {
|
||||
TokenPosition position = ReadPosition(); // read position.
|
||||
NameIndex canonical_target =
|
||||
ReadCanonicalNameReference(); // read target_reference.
|
||||
|
||||
|
@ -2011,13 +2020,14 @@ Fragment StreamingFlowGraphBuilder::BuildInitializers(
|
|||
const Function& target = Function::ZoneHandle(
|
||||
Z, H.LookupConstructorByKernelConstructor(
|
||||
parent_klass, H.CanonicalNameString(canonical_target)));
|
||||
instructions +=
|
||||
StaticCall(TokenPosition::kNoSource, target, argument_count,
|
||||
argument_names, ICData::kStatic);
|
||||
instructions += StaticCall(
|
||||
isSynthetic ? TokenPosition::kNoSource : position, target,
|
||||
argument_count, argument_names, ICData::kStatic);
|
||||
instructions += Drop();
|
||||
break;
|
||||
}
|
||||
case kRedirectingInitializer: {
|
||||
TokenPosition position = ReadPosition(); // read position.
|
||||
NameIndex canonical_target =
|
||||
ReadCanonicalNameReference(); // read target_reference.
|
||||
|
||||
|
@ -2034,9 +2044,9 @@ Fragment StreamingFlowGraphBuilder::BuildInitializers(
|
|||
|
||||
const Function& target = Function::ZoneHandle(
|
||||
Z, H.LookupConstructorByKernelConstructor(canonical_target));
|
||||
instructions +=
|
||||
StaticCall(TokenPosition::kNoSource, target, argument_count,
|
||||
argument_names, ICData::kStatic);
|
||||
instructions += StaticCall(
|
||||
isSynthetic ? TokenPosition::kNoSource : position, target,
|
||||
argument_count, argument_names, ICData::kStatic);
|
||||
instructions += Drop();
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -86,16 +86,19 @@ class StreamingConstantEvaluator {
|
|||
void EvaluateGetStringLength(intptr_t expression_offset,
|
||||
TokenPosition position);
|
||||
|
||||
const Object& RunFunction(const Function& function,
|
||||
const Object& RunFunction(const TokenPosition position,
|
||||
const Function& function,
|
||||
intptr_t argument_count,
|
||||
const Instance* receiver,
|
||||
const TypeArguments* type_args);
|
||||
|
||||
const Object& RunFunction(const Function& function,
|
||||
const Object& RunFunction(const TokenPosition position,
|
||||
const Function& function,
|
||||
const Array& arguments,
|
||||
const Array& names);
|
||||
|
||||
const Object& RunMethodCall(const Function& function,
|
||||
const Object& RunMethodCall(const TokenPosition position,
|
||||
const Function& function,
|
||||
const Instance* receiver);
|
||||
|
||||
RawObject* EvaluateConstConstructorCall(const Class& type_class,
|
||||
|
|
|
@ -1932,10 +1932,12 @@ void KernelReaderHelper::SkipInitializer() {
|
|||
SkipExpression(); // read value.
|
||||
return;
|
||||
case kSuperInitializer:
|
||||
ReadPosition(); // read position.
|
||||
SkipCanonicalNameReference(); // read target_reference.
|
||||
SkipArguments(); // read arguments.
|
||||
return;
|
||||
case kRedirectingInitializer:
|
||||
ReadPosition(); // read position.
|
||||
SkipCanonicalNameReference(); // read target_reference.
|
||||
SkipArguments(); // read arguments.
|
||||
return;
|
||||
|
|
|
@ -574,10 +574,12 @@ void ScopeBuilder::VisitInitializer() {
|
|||
VisitExpression(); // read value.
|
||||
return;
|
||||
case kSuperInitializer:
|
||||
helper_.ReadPosition(); // read position.
|
||||
helper_.SkipCanonicalNameReference(); // read target_reference.
|
||||
VisitArguments(); // read arguments.
|
||||
return;
|
||||
case kRedirectingInitializer:
|
||||
helper_.ReadPosition(); // read position.
|
||||
helper_.SkipCanonicalNameReference(); // read target_reference.
|
||||
VisitArguments(); // read arguments.
|
||||
return;
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace kernel {
|
|||
// package:kernel/binary.md.
|
||||
|
||||
static const uint32_t kMagicProgramFile = 0x90ABCDEFu;
|
||||
static const uint32_t kBinaryFormatVersion = 8;
|
||||
static const uint32_t kBinaryFormatVersion = 9;
|
||||
|
||||
// Keep in sync with package:kernel/lib/binary/tag.dart
|
||||
#define KERNEL_TAG_LIST(V) \
|
||||
|
|
Loading…
Reference in a new issue