[vm, bytecode] Fix some source position discrepancies.
Fix most cases of accessing metadata; parameter annotations still missing.
Change-Id: Ie78c3d817a86a656548cdc5775f837250a710095
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/106967
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: RĂ©gis Crelier <regis@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
diff --git a/pkg/vm/bin/kernel_service.dart b/pkg/vm/bin/kernel_service.dart
index 7f93669..2ad49bc 100644
--- a/pkg/vm/bin/kernel_service.dart
+++ b/pkg/vm/bin/kernel_service.dart
@@ -149,13 +149,15 @@
// TODO(alexmarkov): disable source positions, local variables info
// and source files in VM PRODUCT mode.
// TODO(alexmarkov): disable asserts if they are not enabled in VM.
+ // TODO(rmacnak): disable annotations if mirrors are not enabled.
generateBytecode(component,
options: new BytecodeOptions(
enableAsserts: true,
environmentDefines: options.environmentDefines,
emitSourcePositions: true,
emitLocalVarInfo: true,
- emitSourceFiles: true));
+ emitSourceFiles: true,
+ emitAnnotations: true));
});
}
diff --git a/pkg/vm/lib/bytecode/gen_bytecode.dart b/pkg/vm/lib/bytecode/gen_bytecode.dart
index db0c918..a02eac3 100644
--- a/pkg/vm/lib/bytecode/gen_bytecode.dart
+++ b/pkg/vm/lib/bytecode/gen_bytecode.dart
@@ -291,7 +291,7 @@
int endPosition = TreeNode.noOffset;
if (options.emitSourcePositions && cls.fileOffset != TreeNode.noOffset) {
flags |= ClassDeclaration.hasSourcePositionsFlag;
- position = cls.fileOffset;
+ position = cls.startFileOffset;
endPosition = cls.fileEndOffset;
}
Annotations annotations = getAnnotations(cls.annotations);
@@ -550,7 +550,7 @@
int endPosition = TreeNode.noOffset;
if (options.emitSourcePositions && member.fileOffset != TreeNode.noOffset) {
flags |= FunctionDeclaration.hasSourcePositionsFlag;
- position = member.fileOffset;
+ position = (member as dynamic).startFileOffset;
endPosition = member.fileEndOffset;
}
Annotations annotations = getAnnotations(member.annotations);
@@ -1366,7 +1366,15 @@
locals.enterScope(node);
assert(!locals.isSyncYieldingFrame);
- _recordSourcePosition(node.fileOffset);
+ int position;
+ if (node is Procedure) {
+ position = node.startFileOffset;
+ } else if (node is Constructor) {
+ position = node.startFileOffset;
+ } else {
+ position = node.fileOffset;
+ }
+ _recordSourcePosition(position);
_genPrologue(node, node.function);
_setupInitialContext(node.function);
if (node is Procedure && node.isInstanceMember) {
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index beb978b..82bd670 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -132,7 +132,7 @@
// hence do not have a token position, and therefore cannot be reparsed.
has_extra_parameter_info = false;
}
- if (func.HasBytecode() && (func.kernel_offset() == 0)) {
+ if (func.is_declared_in_bytecode()) {
// Anonymous closures in bytecode cannot be reparsed.
has_extra_parameter_info = false;
}
@@ -1048,18 +1048,19 @@
GET_NON_NULL_NATIVE_ARGUMENT(Instance, owner_mirror,
arguments->NativeArgAt(0));
GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1));
- const Library& library = Library::Handle(ref.GetLibraryReferent());
+ const Library& library = Library::Handle(zone, ref.GetLibraryReferent());
library.EnsureTopLevelClassIsFinalized();
- Instance& member_mirror = Instance::Handle();
+ Instance& member_mirror = Instance::Handle(zone);
const GrowableObjectArray& member_mirrors =
- GrowableObjectArray::Handle(GrowableObjectArray::New());
+ GrowableObjectArray::Handle(zone, GrowableObjectArray::New());
- Object& entry = Object::Handle();
+ Object& entry = Object::Handle(zone);
DictionaryIterator entries(library);
- AbstractType& type = AbstractType::Handle();
+ Error& error = Error::Handle(zone);
+ AbstractType& type = AbstractType::Handle(zone);
while (entries.HasNext()) {
entry = entries.GetNext();
@@ -1068,6 +1069,10 @@
// We filter out dynamic.
// TODO(12478): Should not need to filter out dynamic.
if (!klass.IsDynamicClass()) {
+ error = klass.EnsureIsFinalized(thread);
+ if (!error.IsNull()) {
+ Exceptions::PropagateError(error);
+ }
type = klass.DeclarationType();
member_mirror = CreateClassMirror(klass, type,
Bool::True(), // is_declaration
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 59fd032..30938b5 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -143,7 +143,6 @@
dart/redirection_type_shuffling_test/00: MissingCompileTimeError
[ $runtime == vm && ($compiler == dartk || $compiler == dartkb) ]
-cc/Class_ComputeEndTokenPos: Crash
cc/DartAPI_LoadLibrary: Fail, Crash # Issue 33048.
cc/DebuggerAPI_BreakpointStubPatching: Fail
cc/DebuggerAPI_GetClosureInfo: Fail
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index ee36e81..37dce77 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -186,6 +186,7 @@
s->Write<int16_t>(cls->ptr()->num_type_arguments_);
s->Write<uint16_t>(cls->ptr()->num_native_fields_);
s->WriteTokenPosition(cls->ptr()->token_pos_);
+ s->WriteTokenPosition(cls->ptr()->end_token_pos_);
s->Write<uint32_t>(cls->ptr()->state_bits_);
}
@@ -247,6 +248,7 @@
cls->ptr()->num_type_arguments_ = d->Read<int16_t>();
cls->ptr()->num_native_fields_ = d->Read<uint16_t>();
cls->ptr()->token_pos_ = d->ReadTokenPosition();
+ cls->ptr()->end_token_pos_ = d->ReadTokenPosition();
cls->ptr()->state_bits_ = d->Read<uint32_t>();
}
@@ -273,6 +275,7 @@
cls->ptr()->num_type_arguments_ = d->Read<int16_t>();
cls->ptr()->num_native_fields_ = d->Read<uint16_t>();
cls->ptr()->token_pos_ = d->ReadTokenPosition();
+ cls->ptr()->end_token_pos_ = d->ReadTokenPosition();
cls->ptr()->state_bits_ = d->Read<uint32_t>();
table->AllocateIndex(class_id);
@@ -1611,7 +1614,7 @@
}
void WriteFill(Serializer* s) {
- ASSERT(s->kind() == Snapshot::kFullJIT);
+ ASSERT(s->kind() != Snapshot::kFullAOT);
intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawBytecode* bytecode = objects_[i];
@@ -1644,7 +1647,7 @@
}
void ReadFill(Deserializer* d) {
- ASSERT(d->kind() == Snapshot::kFullJIT);
+ ASSERT(d->kind() != Snapshot::kFullAOT);
for (intptr_t id = start_index_; id < stop_index_; id++) {
RawBytecode* bytecode = reinterpret_cast<RawBytecode*>(d->Ref(id));
diff --git a/runtime/vm/compiler/frontend/bytecode_reader.cc b/runtime/vm/compiler/frontend/bytecode_reader.cc
index d332a70..952b031 100644
--- a/runtime/vm/compiler/frontend/bytecode_reader.cc
+++ b/runtime/vm/compiler/frontend/bytecode_reader.cc
@@ -2233,10 +2233,12 @@
cls.set_script(script);
TokenPosition position = TokenPosition::kNoSource;
+ TokenPosition end_position = TokenPosition::kNoSource;
if ((flags & kHasSourcePositionsFlag) != 0) {
position = reader_.ReadPosition();
- reader_.ReadPosition(); // end_position
+ end_position = reader_.ReadPosition();
cls.set_token_pos(position);
+ cls.set_end_token_pos(end_position);
}
cls.set_has_pragma(has_pragma);
diff --git a/runtime/vm/compiler/runtime_offsets_extracted.h b/runtime/vm/compiler/runtime_offsets_extracted.h
index bf791bc..a3ceb18 100644
--- a/runtime/vm/compiler/runtime_offsets_extracted.h
+++ b/runtime/vm/compiler/runtime_offsets_extracted.h
@@ -74,10 +74,10 @@
static constexpr dart::compiler::target::word Class_declaration_type_offset =
56;
static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
- 102;
+ 106;
static constexpr dart::compiler::target::word Class_super_type_offset = 44;
static constexpr dart::compiler::target::word
- Class_type_arguments_field_offset_in_words_offset = 92;
+ Class_type_arguments_field_offset_in_words_offset = 96;
static constexpr dart::compiler::target::word
ClassHeapStats_TraceAllocationMask = 1;
static constexpr dart::compiler::target::word
@@ -427,10 +427,10 @@
static constexpr dart::compiler::target::word Class_declaration_type_offset =
112;
static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
- 186;
+ 190;
static constexpr dart::compiler::target::word Class_super_type_offset = 88;
static constexpr dart::compiler::target::word
- Class_type_arguments_field_offset_in_words_offset = 176;
+ Class_type_arguments_field_offset_in_words_offset = 180;
static constexpr dart::compiler::target::word
ClassHeapStats_TraceAllocationMask = 1;
static constexpr dart::compiler::target::word
@@ -781,10 +781,10 @@
static constexpr dart::compiler::target::word Class_declaration_type_offset =
56;
static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
- 102;
+ 106;
static constexpr dart::compiler::target::word Class_super_type_offset = 44;
static constexpr dart::compiler::target::word
- Class_type_arguments_field_offset_in_words_offset = 92;
+ Class_type_arguments_field_offset_in_words_offset = 96;
static constexpr dart::compiler::target::word
ClassHeapStats_TraceAllocationMask = 1;
static constexpr dart::compiler::target::word
@@ -1130,10 +1130,10 @@
static constexpr dart::compiler::target::word Class_declaration_type_offset =
112;
static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
- 186;
+ 190;
static constexpr dart::compiler::target::word Class_super_type_offset = 88;
static constexpr dart::compiler::target::word
- Class_type_arguments_field_offset_in_words_offset = 176;
+ Class_type_arguments_field_offset_in_words_offset = 180;
static constexpr dart::compiler::target::word
ClassHeapStats_TraceAllocationMask = 1;
static constexpr dart::compiler::target::word
@@ -1487,10 +1487,10 @@
static constexpr dart::compiler::target::word Class_declaration_type_offset =
112;
static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
- 186;
+ 190;
static constexpr dart::compiler::target::word Class_super_type_offset = 88;
static constexpr dart::compiler::target::word
- Class_type_arguments_field_offset_in_words_offset = 176;
+ Class_type_arguments_field_offset_in_words_offset = 180;
static constexpr dart::compiler::target::word
ClassHeapStats_TraceAllocationMask = 1;
static constexpr dart::compiler::target::word
@@ -1771,10 +1771,10 @@
static constexpr dart::compiler::target::word Class_declaration_type_offset =
56;
static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
- 102;
+ 106;
static constexpr dart::compiler::target::word Class_super_type_offset = 44;
static constexpr dart::compiler::target::word
- Class_type_arguments_field_offset_in_words_offset = 92;
+ Class_type_arguments_field_offset_in_words_offset = 96;
static constexpr dart::compiler::target::word
ClassHeapStats_TraceAllocationMask = 1;
static constexpr dart::compiler::target::word
diff --git a/runtime/vm/compiler_test.cc b/runtime/vm/compiler_test.cc
index 8bf0e39..e0b1193 100644
--- a/runtime/vm/compiler_test.cc
+++ b/runtime/vm/compiler_test.cc
@@ -202,8 +202,7 @@
Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
Dart_Handle obj_handle =
Dart_Invoke(lib, Dart_NewStringFromCString("makeObj"), 0, NULL);
- EXPECT(!Dart_IsNull(obj_handle));
- EXPECT(!Dart_IsError(obj_handle));
+ EXPECT_VALID(obj_handle);
TransitionNativeToVM transition(thread);
const Object& obj = Object::Handle(Api::UnwrapHandle(obj_handle));
EXPECT(!obj.IsNull());
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc
index df548c2..85b57b5 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -1390,8 +1390,9 @@
out_class->set_script(script);
}
if (out_class->token_pos() == TokenPosition::kNoSource) {
- class_helper.ReadUntilIncluding(ClassHelper::kStartPosition);
+ class_helper.ReadUntilIncluding(ClassHelper::kEndPosition);
out_class->set_token_pos(class_helper.start_position_);
+ out_class->set_end_token_pos(class_helper.end_position_);
}
class_helper.ReadUntilIncluding(ClassHelper::kFlags);
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 6fe3c0c..c817150 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -4,6 +4,8 @@
#include "vm/object.h"
+#include <memory>
+
#include "include/dart_api.h"
#include "platform/assert.h"
#include "platform/unicode.h"
@@ -2292,6 +2294,7 @@
FakeObject fake;
result.set_handle_vtable(fake.vtable());
result.set_token_pos(TokenPosition::kNoSource);
+ result.set_end_token_pos(TokenPosition::kNoSource);
result.set_instance_size(FakeObject::InstanceSize());
result.set_type_arguments_field_offset_in_words(kNoTypeArguments);
result.set_next_field_offset(FakeObject::NextFieldOffset());
@@ -3660,6 +3663,7 @@
ASSERT(fake.IsInstance());
result.set_handle_vtable(fake.vtable());
result.set_token_pos(TokenPosition::kNoSource);
+ result.set_end_token_pos(TokenPosition::kNoSource);
result.set_instance_size(FakeInstance::InstanceSize());
result.set_type_arguments_field_offset_in_words(kNoTypeArguments);
result.set_next_field_offset(FakeInstance::NextFieldOffset());
@@ -3975,69 +3979,16 @@
StoreNonPointer(&raw_ptr()->token_pos_, token_pos);
}
-TokenPosition Class::ComputeEndTokenPos() const {
-#if defined(DART_PRECOMPILED_RUNTIME)
- return TokenPosition::kNoSource;
-#else
- // Return the begin token for synthetic classes.
- if (is_synthesized_class() || IsTopLevel()) {
- return token_pos();
- }
-
- Thread* thread = Thread::Current();
- Zone* zone = thread->zone();
- const Script& scr = Script::Handle(zone, script());
- ASSERT(!scr.IsNull());
-
- if (scr.kind() == RawScript::kKernelTag) {
- if (is_declared_in_bytecode()) {
- // TODO(alexmarkov): keep end_token_pos in Class?
- UNIMPLEMENTED();
- return token_pos();
- }
- ASSERT(kernel_offset() > 0);
- const Library& lib = Library::Handle(zone, library());
- const ExternalTypedData& kernel_data =
- ExternalTypedData::Handle(zone, lib.kernel_data());
- ASSERT(!kernel_data.IsNull());
- const intptr_t library_kernel_offset = lib.kernel_offset();
- ASSERT(library_kernel_offset > 0);
- const intptr_t class_offset = kernel_offset();
-
- kernel::TranslationHelper translation_helper(thread);
- translation_helper.InitFromScript(scr);
-
- kernel::KernelReaderHelper kernel_reader_helper(zone, &translation_helper,
- scr, kernel_data, 0);
- kernel_reader_helper.SetOffset(class_offset);
- kernel::ClassHelper class_helper(&kernel_reader_helper);
- class_helper.ReadUntilIncluding(kernel::ClassHelper::kEndPosition);
- if (class_helper.end_position_.IsReal()) return class_helper.end_position_;
-
- TokenPosition largest_seen = token_pos();
-
- // Walk through all functions and get their end_tokens to find the classes
- // "end token".
- // TODO(jensj): Should probably walk though all fields as well.
- Function& function = Function::Handle(zone);
- const Array& arr = Array::Handle(functions());
- for (int i = 0; i < arr.Length(); i++) {
- function ^= arr.At(i);
- if (function.script() == script()) {
- if (largest_seen < function.end_token_pos()) {
- largest_seen = function.end_token_pos();
- }
- }
- }
- return TokenPosition(largest_seen);
- }
-
- UNREACHABLE();
-#endif
+void Class::set_end_token_pos(TokenPosition token_pos) const {
+ ASSERT(!token_pos.IsClassifying());
+ StoreNonPointer(&raw_ptr()->end_token_pos_, token_pos);
}
int32_t Class::SourceFingerprint() const {
#if !defined(DART_PRECOMPILED_RUNTIME)
+ if (is_declared_in_bytecode()) {
+ return 0; // TODO(37353): Implement or remove.
+ }
return kernel::KernelSourceFingerprintHelper::CalculateClassFingerprint(
*this);
#else
@@ -7943,6 +7894,9 @@
// arguments.
int32_t Function::SourceFingerprint() const {
#if !defined(DART_PRECOMPILED_RUNTIME)
+ if (is_declared_in_bytecode()) {
+ return 0; // TODO(37353): Implement or remove.
+ }
return kernel::KernelSourceFingerprintHelper::CalculateFunctionFingerprint(
*this);
#else
@@ -8588,6 +8542,9 @@
int32_t Field::SourceFingerprint() const {
#if !defined(DART_PRECOMPILED_RUNTIME)
+ if (is_declared_in_bytecode()) {
+ return 0; // TODO(37353): Implement or remove.
+ }
return kernel::KernelSourceFingerprintHelper::CalculateFieldFingerprint(
*this);
#else
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 05c750e..5091f1a 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -866,8 +866,11 @@
TokenPosition token_pos() const { return raw_ptr()->token_pos_; }
void set_token_pos(TokenPosition value) const;
-
- TokenPosition ComputeEndTokenPos() const;
+ TokenPosition end_token_pos() const {
+ ASSERT(is_declaration_loaded());
+ return raw_ptr()->end_token_pos_;
+ }
+ void set_end_token_pos(TokenPosition value) const;
int32_t SourceFingerprint() const;
diff --git a/runtime/vm/object_service.cc b/runtime/vm/object_service.cc
index 3786d8e..2ba49c8 100644
--- a/runtime/vm/object_service.cc
+++ b/runtime/vm/object_service.cc
@@ -116,7 +116,7 @@
jsobj.AddProperty("library", Object::Handle(library()));
const Script& script = Script::Handle(this->script());
if (!script.IsNull()) {
- jsobj.AddLocation(script, token_pos(), ComputeEndTokenPos());
+ jsobj.AddLocation(script, token_pos(), end_token_pos());
}
{
JSONArray interfaces_array(&jsobj, "interfaces");
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index 0921cc8..8e66ed7 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -168,7 +168,7 @@
EXPECT_EQ(type_arguments1.raw(), type_arguments3.raw());
}
-TEST_CASE(Class_ComputeEndTokenPos) {
+TEST_CASE(Class_EndTokenPos) {
const char* kScript =
"\n"
"class A {\n"
@@ -178,7 +178,6 @@
" foo(a) { return '''\"}'''; }\n"
" // }\n"
" var bar = '\\'}';\n"
- " var baz = \"${foo('}')}\";\n"
"}\n";
Dart_Handle lib_h = TestCase::LoadTestScript(kScript, NULL);
EXPECT_VALID(lib_h);
@@ -189,12 +188,15 @@
const Class& cls =
Class::Handle(lib.LookupClass(String::Handle(String::New("A"))));
EXPECT(!cls.IsNull());
- const TokenPosition end_token_pos = cls.ComputeEndTokenPos();
+ const Error& error = Error::Handle(cls.EnsureIsFinalized(thread));
+ EXPECT(error.IsNull());
+ const TokenPosition end_token_pos = cls.end_token_pos();
const Script& scr = Script::Handle(cls.script());
intptr_t line;
intptr_t col;
scr.GetTokenLocation(end_token_pos, &line, &col);
- EXPECT(line == 10 && col == 1);
+ EXPECT_EQ(9, line);
+ EXPECT_EQ(1, col);
}
ISOLATE_UNIT_TEST_CASE(InstanceClass) {
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index a13c5ba6..b052949 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -800,6 +800,7 @@
cpp_vtable handle_vtable_;
TokenPosition token_pos_;
+ TokenPosition end_token_pos_;
int32_t instance_size_in_words_; // Size if fixed len or 0 if variable len.
int32_t type_arguments_field_offset_in_words_; // Offset of type args fld.
int32_t next_field_offset_in_words_; // Offset of the next instance field.
diff --git a/runtime/vm/source_report.cc b/runtime/vm/source_report.cc
index db396d9..860b4a65 100644
--- a/runtime/vm/source_report.cc
+++ b/runtime/vm/source_report.cc
@@ -562,7 +562,7 @@
script = cls.script();
range.AddProperty("scriptIndex", GetScriptIndex(script));
range.AddProperty("startPos", cls.token_pos());
- range.AddProperty("endPos", cls.ComputeEndTokenPos());
+ range.AddProperty("endPos", cls.end_token_pos());
range.AddProperty("compiled", false);
range.AddProperty("error", err);
continue;
@@ -574,7 +574,7 @@
script = cls.script();
range.AddProperty("scriptIndex", GetScriptIndex(script));
range.AddProperty("startPos", cls.token_pos());
- range.AddProperty("endPos", cls.ComputeEndTokenPos());
+ range.AddProperty("endPos", cls.end_token_pos());
range.AddProperty("compiled", false);
continue;
}
diff --git a/tests/language_2/vm/reflect_core_vm_test.dart b/tests/language_2/vm/reflect_core_vm_test.dart
index e13f36e..75fff71 100644
--- a/tests/language_2/vm/reflect_core_vm_test.dart
+++ b/tests/language_2/vm/reflect_core_vm_test.dart
@@ -10,6 +10,6 @@
main() {
var s = "string";
var im = reflect(s);
- Expect.throwsNoSuchMethodError(
- () => im.invoke(const Symbol("_setAt"), [0, 65]));
+ Expect.throwsNoSuchMethodError(() =>
+ im.invoke(MirrorSystem.getSymbol("_setAt", im.type.owner), [0, 65]));
}