[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]));
 }