@@ -900,7 +900,6 @@ RawLibrary* KernelLoader::LoadLibrary(intptr_t index) {
900
900
901
901
LibraryIndex library_index (library_kernel_data_);
902
902
intptr_t class_count = library_index.class_count ();
903
- intptr_t procedure_count = library_index.procedure_count ();
904
903
905
904
library_helper.ReadUntilIncluding (LibraryHelper::kName );
906
905
library.SetName (H.DartSymbolObfuscate (library_helper.name_index_ ));
@@ -969,13 +968,47 @@ RawLibrary* KernelLoader::LoadLibrary(intptr_t index) {
969
968
classes.Add (klass, Heap::kOld );
970
969
}
971
970
}
972
- helper_.SetOffset (next_class_offset);
971
+
972
+ if (loading_native_wrappers_library_ || !register_class) {
973
+ FinishTopLevelClassLoading (toplevel_class, library, library_index);
974
+ }
975
+
976
+ if (FLAG_enable_mirrors && annotation_count > 0 ) {
977
+ ASSERT (annotations_kernel_offset > 0 );
978
+ library.AddLibraryMetadata (toplevel_class, TokenPosition::kNoSource ,
979
+ annotations_kernel_offset);
980
+ }
981
+
982
+ if (register_class) {
983
+ classes.Add (toplevel_class, Heap::kOld );
984
+ }
985
+ if (!library.Loaded ()) library.SetLoaded ();
986
+
987
+ return library.raw ();
988
+ }
989
+
990
+ void KernelLoader::FinishTopLevelClassLoading (
991
+ const Class& toplevel_class,
992
+ const Library& library,
993
+ const LibraryIndex& library_index) {
994
+ if (toplevel_class.is_loaded ()) {
995
+ return ;
996
+ }
997
+
998
+ TIMELINE_DURATION (Thread::Current (), Isolate, " FinishTopLevelClassLoading" );
999
+
1000
+ // Offsets within library index are whole program offsets and not
1001
+ // relative to the library.
1002
+ const intptr_t correction = correction_offset_ - library_kernel_offset_;
1003
+ helper_.SetOffset (library_index.ClassOffset (library_index.class_count ()) +
1004
+ correction);
973
1005
974
1006
fields_.Clear ();
975
1007
functions_.Clear ();
976
1008
ActiveClassScope active_class_scope (&active_class_, &toplevel_class);
1009
+
977
1010
// Load toplevel fields.
978
- intptr_t field_count = helper_.ReadListLength (); // read list length.
1011
+ const intptr_t field_count = helper_.ReadListLength (); // read list length.
979
1012
for (intptr_t i = 0 ; i < field_count; ++i) {
980
1013
intptr_t field_offset = helper_.ReaderOffset () - correction_offset_;
981
1014
ActiveMemberScope active_member_scope (&active_class_, NULL );
@@ -1002,7 +1035,7 @@ RawLibrary* KernelLoader::LoadLibrary(intptr_t index) {
1002
1035
// In the VM all const fields are implicitly final whereas in Kernel they
1003
1036
// are not final because they are not explicitly declared that way.
1004
1037
const bool is_final = field_helper.IsConst () || field_helper.IsFinal ();
1005
- Field& field = Field::Handle (
1038
+ const Field& field = Field::Handle (
1006
1039
Z,
1007
1040
Field::NewTopLevel (name, is_final, field_helper.IsConst (), script_class,
1008
1041
field_helper.position_ , field_helper.end_position_ ));
@@ -1026,31 +1059,45 @@ RawLibrary* KernelLoader::LoadLibrary(intptr_t index) {
1026
1059
library.AddFieldMetadata (field, TokenPosition::kNoSource , field_offset);
1027
1060
}
1028
1061
fields_.Add (&field);
1029
- library.AddObject (field, name);
1030
1062
}
1031
- toplevel_class.AddFields (fields_);
1063
+
1064
+ ASSERT (!toplevel_class.is_loaded ());
1032
1065
1033
1066
// Load toplevel procedures.
1034
- intptr_t next_procedure_offset = library_index.ProcedureOffset (0 );
1067
+ intptr_t next_procedure_offset =
1068
+ library_index.ProcedureOffset (0 ) + correction;
1069
+ const intptr_t procedure_count = library_index.procedure_count ();
1035
1070
for (intptr_t i = 0 ; i < procedure_count; ++i) {
1036
1071
helper_.SetOffset (next_procedure_offset);
1037
- next_procedure_offset = library_index.ProcedureOffset (i + 1 );
1072
+ next_procedure_offset = library_index.ProcedureOffset (i + 1 ) + correction ;
1038
1073
LoadProcedure (library, toplevel_class, false , next_procedure_offset);
1074
+ // LoadProcedure calls Library::GetMetadata which invokes Dart code
1075
+ // which may recursively trigger class finalization and
1076
+ // FinishTopLevelClassLoading.
1077
+ // In such case, return immediately and avoid overwriting already finalized
1078
+ // functions with freshly loaded and not yet finalized.
1079
+ if (toplevel_class.is_loaded ()) {
1080
+ return ;
1081
+ }
1039
1082
}
1040
1083
1041
- if (FLAG_enable_mirrors && annotation_count > 0 ) {
1042
- ASSERT (annotations_kernel_offset > 0 );
1043
- library.AddLibraryMetadata (toplevel_class, TokenPosition::kNoSource ,
1044
- annotations_kernel_offset);
1045
- }
1046
-
1084
+ toplevel_class.SetFields (Array::Handle (MakeFieldsArray ()));
1047
1085
toplevel_class.SetFunctions (Array::Handle (MakeFunctionsArray ()));
1048
- if (register_class) {
1049
- classes.Add (toplevel_class, Heap::kOld );
1086
+
1087
+ String& name = String::Handle (Z);
1088
+ for (intptr_t i = 0 , n = fields_.length (); i < n; ++i) {
1089
+ const Field* field = fields_.At (i);
1090
+ name = field->name ();
1091
+ library.AddObject (*field, name);
1092
+ }
1093
+ for (intptr_t i = 0 , n = functions_.length (); i < n; ++i) {
1094
+ const Function* function = functions_.At (i);
1095
+ name = function->name ();
1096
+ library.AddObject (*function, name);
1050
1097
}
1051
- if (!library.Loaded ()) library.SetLoaded ();
1052
1098
1053
- return library.raw ();
1099
+ ASSERT (!toplevel_class.is_loaded ());
1100
+ toplevel_class.set_is_loaded (true );
1054
1101
}
1055
1102
1056
1103
void KernelLoader::LoadLibraryImportsAndExports (Library* library,
@@ -1544,7 +1591,7 @@ void KernelLoader::FinishClassLoading(const Class& klass,
1544
1591
}
1545
1592
1546
1593
void KernelLoader::FinishLoading (const Class& klass) {
1547
- ASSERT (klass.kernel_offset () > 0 );
1594
+ ASSERT (klass.IsTopLevel () || (klass. kernel_offset () > 0 ) );
1548
1595
1549
1596
Zone* zone = Thread::Current ()->zone ();
1550
1597
const Script& script = Script::Handle (zone, klass.script ());
@@ -1556,10 +1603,17 @@ void KernelLoader::FinishLoading(const Class& klass) {
1556
1603
const intptr_t library_kernel_offset = library.kernel_offset ();
1557
1604
ASSERT (library_kernel_offset > 0 );
1558
1605
1559
- const intptr_t class_offset = klass.kernel_offset ();
1560
1606
KernelLoader kernel_loader (script, library_kernel_data,
1561
1607
library_kernel_offset);
1562
1608
LibraryIndex library_index (library_kernel_data);
1609
+
1610
+ if (klass.IsTopLevel ()) {
1611
+ ASSERT (klass.raw () == toplevel_class.raw ());
1612
+ kernel_loader.FinishTopLevelClassLoading (klass, library, library_index);
1613
+ return ;
1614
+ }
1615
+
1616
+ const intptr_t class_offset = klass.kernel_offset ();
1563
1617
ClassIndex class_index (
1564
1618
library_kernel_data, class_offset,
1565
1619
// Class offsets in library index are whole program offsets.
@@ -1790,14 +1844,6 @@ void KernelLoader::LoadProcedure(const Library& library,
1790
1844
// function_node_helper are no longer used.
1791
1845
helper_.SetOffset (procedure_end);
1792
1846
1793
- if (!in_class) {
1794
- library.AddObject (function, name);
1795
- ASSERT (!Object::Handle (
1796
- Z, library.LookupObjectAllowPrivate (
1797
- H.DartProcedureName (procedure_helper.canonical_name_ )))
1798
- .IsNull ());
1799
- }
1800
-
1801
1847
if (annotation_count > 0 ) {
1802
1848
library.AddFunctionMetadata (function, TokenPosition::kNoSource ,
1803
1849
procedure_offset);
0 commit comments