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) \