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>
diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md
index eff9f14..ad5e3f1 100644
--- a/pkg/kernel/binary.md
+++ b/pkg/kernel/binary.md
@@ -131,7 +131,7 @@
type ComponentFile {
UInt32 magic = 0x90ABCDEF;
- UInt32 formatVersion = 8;
+ UInt32 formatVersion = 9;
Library[] libraries;
UriSource sourceMap;
List<CanonicalName> canonicalNames;
@@ -406,6 +406,7 @@
type SuperInitializer extends Initializer {
Byte tag = 9;
Byte isSynthetic;
+ FileOffset fileOffset;
ConstructorReference target;
Arguments arguments;
}
@@ -413,6 +414,7 @@
type RedirectingInitializer extends Initializer {
Byte tag = 10;
Byte isSynthetic;
+ FileOffset fileOffset;
ConstructorReference target;
Arguments arguments;
}
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index c088723..5332ba5 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -1166,13 +1166,17 @@
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:
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index 84a6e59..b59903b 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -917,6 +917,7 @@
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 @@
void visitRedirectingInitializer(RedirectingInitializer node) {
writeByte(Tag.RedirectingInitializer);
writeByte(node.isSynthetic ? 1 : 0);
+ writeOffset(node.fileOffset);
writeReference(node.targetReference);
writeNode(node.arguments);
}
diff --git a/pkg/kernel/lib/binary/tag.dart b/pkg/kernel/lib/binary/tag.dart
index 44eb262..69a2c8fd 100644
--- a/pkg/kernel/lib/binary/tag.dart
+++ b/pkg/kernel/lib/binary/tag.dart
@@ -135,7 +135,7 @@
/// 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 {
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index 70d956b..9770a26 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -361,7 +361,7 @@
}
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 @@
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::EvaluateDirectMethodInvocation() {
- builder_->ReadPosition(); // read position.
+ TokenPosition position = builder_->ReadPosition(); // read position.
const Instance& receiver = Instance::Handle(
Z,
@@ -401,7 +401,7 @@
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 @@
}
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 @@
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::EvaluateStaticInvocation() {
- builder_->ReadPosition(); // read position.
+ TokenPosition position = builder_->ReadPosition(); // read position.
NameIndex procedure_reference =
builder_->ReadCanonicalNameReference(); // read procedure reference.
@@ -459,13 +459,13 @@
// 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 @@
}
// 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::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 @@
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 @@
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::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 @@
// 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 @@
// 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 @@
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& 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 @@
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 @@
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 @@
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 @@
break;
}
case kSuperInitializer: {
+ TokenPosition position = ReadPosition(); // read position.
NameIndex canonical_target =
ReadCanonicalNameReference(); // read target_reference.
@@ -2011,13 +2020,14 @@
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 @@
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;
}
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
index b352dea..cc258c8 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
@@ -86,16 +86,19 @@
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,
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
index ac65dec..99aa61f 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
@@ -1932,10 +1932,12 @@
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;
diff --git a/runtime/vm/compiler/frontend/scope_builder.cc b/runtime/vm/compiler/frontend/scope_builder.cc
index faf3885..21f2c04 100644
--- a/runtime/vm/compiler/frontend/scope_builder.cc
+++ b/runtime/vm/compiler/frontend/scope_builder.cc
@@ -574,10 +574,12 @@
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;
diff --git a/runtime/vm/kernel_binary.h b/runtime/vm/kernel_binary.h
index c0a6799..58ae9ca 100644
--- a/runtime/vm/kernel_binary.h
+++ b/runtime/vm/kernel_binary.h
@@ -17,7 +17,7 @@
// 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) \