@@ -183,7 +183,9 @@ KernelLoader::KernelLoader(Program* program)
183183 external_name_field_(Field::Handle(Z)),
184184 potential_natives_(GrowableObjectArray::Handle(Z)),
185185 potential_extension_libraries_(GrowableObjectArray::Handle(Z)),
186- pragma_class_(Class::Handle(Z)) {
186+ pragma_class_(Class::Handle(Z)),
187+ expression_evaluation_library_(Library::Handle(Z)),
188+ expression_evaluation_function_(Function::Handle(Z)) {
187189 if (!program->is_single_program ()) {
188190 FATAL (
189191 " Trying to load a concatenated dill file at a time where that is "
@@ -344,7 +346,9 @@ KernelLoader::KernelLoader(const Script& script,
344346 external_name_field_(Field::Handle(Z)),
345347 potential_natives_(GrowableObjectArray::Handle(Z)),
346348 potential_extension_libraries_(GrowableObjectArray::Handle(Z)),
347- pragma_class_(Class::Handle(Z)) {
349+ pragma_class_(Class::Handle(Z)),
350+ expression_evaluation_library_(Library::Handle(Z)),
351+ expression_evaluation_function_(Function::Handle(Z)) {
348352 ASSERT (T.active_class_ == &active_class_);
349353 T.finalize_ = false ;
350354
@@ -617,6 +621,49 @@ RawObject* KernelLoader::LoadProgram(bool process_pending_classes) {
617621 return error;
618622}
619623
624+ RawObject* KernelLoader::LoadExpressionEvaluationFunction (
625+ const String& library_url,
626+ const String& klass) {
627+ // Find the original context, i.e. library/class, in which the evaluation will
628+ // happen.
629+ const Library& real_library = Library::Handle (
630+ Z, Library::LookupLibrary (Thread::Current (), library_url));
631+ ASSERT (!real_library.IsNull ());
632+ const Class& real_class = Class::Handle (
633+ Z, klass.IsNull () ? real_library.toplevel_class ()
634+ : real_library.LookupClassAllowPrivate (klass));
635+ ASSERT (!real_class.IsNull ());
636+
637+ const intptr_t num_cids = I->class_table ()->NumCids ();
638+ const intptr_t num_libs =
639+ GrowableObjectArray::Handle (I->object_store ()->libraries ()).Length ();
640+
641+ // Load the "evaluate:source" expression evaluation library.
642+ ASSERT (expression_evaluation_library_.IsNull ());
643+ ASSERT (expression_evaluation_function_.IsNull ());
644+ const Object& result = Object::Handle (Z, LoadProgram (true ));
645+ if (result.IsError ()) {
646+ return result.raw ();
647+ }
648+ ASSERT (!expression_evaluation_library_.IsNull ());
649+ ASSERT (!expression_evaluation_function_.IsNull ());
650+ ASSERT (GrowableObjectArray::Handle (I->object_store ()->libraries ()).Length () ==
651+ num_libs);
652+ ASSERT (I->class_table ()->NumCids () == num_cids);
653+
654+ // Make the expression evaluation function have the right kernel data and
655+ // parent.
656+ auto & eval_data = ExternalTypedData::Handle (
657+ Z, expression_evaluation_library_.kernel_data ());
658+ auto & eval_script =
659+ Script::Handle (Z, expression_evaluation_function_.script ());
660+ expression_evaluation_function_.SetKernelDataAndScript (
661+ eval_script, eval_data, expression_evaluation_library_.kernel_offset ());
662+ expression_evaluation_function_.set_owner (real_class);
663+
664+ return expression_evaluation_function_.raw ();
665+ }
666+
620667void KernelLoader::FindModifiedLibraries (Program* program,
621668 Isolate* isolate,
622669 BitVector* modified_libs,
@@ -780,9 +827,16 @@ RawLibrary* KernelLoader::LoadLibrary(intptr_t index) {
780827 library_helper.SetJustRead (LibraryHelper::kAnnotations );
781828
782829 // Setup toplevel class (which contains library fields/procedures).
830+
831+ // We do not register expression evaluation classes with the VM:
832+ // The expression evaluation functions should be GC-able as soon as
833+ // they are not reachable anymore and we never look them up by name.
834+ const bool register_class =
835+ library.raw () != expression_evaluation_library_.raw ();
836+
783837 Class& toplevel_class =
784838 Class::Handle (Z, Class::New (library, Symbols::TopLevel (), script,
785- TokenPosition::kNoSource ));
839+ TokenPosition::kNoSource , register_class ));
786840 toplevel_class.set_is_cycle_free ();
787841 library.set_toplevel_class (toplevel_class);
788842
@@ -801,8 +855,10 @@ RawLibrary* KernelLoader::LoadLibrary(intptr_t index) {
801855 for (intptr_t i = 0 ; i < class_count; ++i) {
802856 helper_.SetOffset (next_class_offset);
803857 next_class_offset = library_index.ClassOffset (i + 1 );
804- classes.Add (LoadClass (library, toplevel_class, next_class_offset),
805- Heap::kOld );
858+ const Class& klass = LoadClass (library, toplevel_class, next_class_offset);
859+ if (register_class) {
860+ classes.Add (klass, Heap::kOld );
861+ }
806862 }
807863 helper_.SetOffset (next_class_offset);
808864
@@ -881,7 +937,9 @@ RawLibrary* KernelLoader::LoadLibrary(intptr_t index) {
881937 }
882938
883939 toplevel_class.SetFunctions (Array::Handle (MakeFunctionsArray ()));
884- classes.Add (toplevel_class, Heap::kOld );
940+ if (register_class) {
941+ classes.Add (toplevel_class, Heap::kOld );
942+ }
885943 if (!library.Loaded ()) library.SetLoaded ();
886944
887945 return library.raw ();
@@ -1161,7 +1219,13 @@ Class& KernelLoader::LoadClass(const Library& library,
11611219 class_offset - correction_offset_);
11621220 }
11631221
1164- if (loading_native_wrappers_library_) {
1222+ // We do not register expression evaluation classes with the VM:
1223+ // The expression evaluation functions should be GC-able as soon as
1224+ // they are not reachable anymore and we never look them up by name.
1225+ const bool register_class =
1226+ library.raw () != expression_evaluation_library_.raw ();
1227+
1228+ if (loading_native_wrappers_library_ || !register_class) {
11651229 FinishClassLoading (klass, library, toplevel_class, class_offset,
11661230 class_index, &class_helper);
11671231 }
@@ -1514,6 +1578,12 @@ void KernelLoader::LoadProcedure(const Library& library,
15141578 const Object& script_class =
15151579 ClassForScriptAt (owner, procedure_helper.source_uri_index_ );
15161580 RawFunction::Kind kind = GetFunctionType (procedure_helper.kind_ );
1581+
1582+ // We do not register expression evaluation libraries with the VM:
1583+ // The expression evaluation functions should be GC-able as soon as
1584+ // they are not reachable anymore and we never look them up by name.
1585+ const bool register_function = !name.Equals (Symbols::DebugProcedureName ());
1586+
15171587 Function& function = Function::ZoneHandle (
15181588 Z, Function::New (name, kind,
15191589 !is_method, // is_static
@@ -1523,7 +1593,11 @@ void KernelLoader::LoadProcedure(const Library& library,
15231593 script_class, procedure_helper.start_position_ ));
15241594 function.set_has_pragma (has_pragma_annotation);
15251595 function.set_end_token_pos (procedure_helper.end_position_ );
1526- functions_.Add (&function);
1596+ if (register_function) {
1597+ functions_.Add (&function);
1598+ } else {
1599+ expression_evaluation_function_ = function.raw ();
1600+ }
15271601 function.set_kernel_offset (procedure_offset);
15281602
15291603 ActiveMemberScope active_member (&active_class_, &function);
@@ -1787,11 +1861,23 @@ Library& KernelLoader::LookupLibraryOrNull(NameIndex library) {
17871861Library& KernelLoader::LookupLibrary (NameIndex library) {
17881862 Library* handle = NULL ;
17891863 if (!libraries_.Lookup (library, &handle)) {
1790- const String& url = H.DartString (H.CanonicalNameString (library));
1791- handle = &Library::Handle (Z, Library::LookupLibrary (thread_, url));
1792- if (handle->IsNull ()) {
1793- *handle = Library::New (url);
1794- handle->Register (thread_);
1864+ handle = &Library::Handle (Z);
1865+ const String& url = H.DartSymbolPlain (H.CanonicalNameString (library));
1866+
1867+ // We do not register expression evaluation libraries with the VM:
1868+ // The expression evaluation functions should be GC-able as soon as
1869+ // they are not reachable anymore and we never look them up by name.
1870+ if (url.Equals (Symbols::EvalSourceUri ())) {
1871+ if (handle->IsNull ()) {
1872+ *handle = Library::New (url);
1873+ expression_evaluation_library_ = handle->raw ();
1874+ }
1875+ } else {
1876+ *handle = Library::LookupLibrary (thread_, url);
1877+ if (handle->IsNull ()) {
1878+ *handle = Library::New (url);
1879+ handle->Register (thread_);
1880+ }
17951881 }
17961882 ASSERT (!handle->IsNull ());
17971883 libraries_.Insert (library, handle);
@@ -1806,9 +1892,17 @@ Class& KernelLoader::LookupClass(NameIndex klass) {
18061892 const String& name = H.DartClassName (klass);
18071893 handle = &Class::Handle (Z, library.LookupLocalClass (name));
18081894 if (handle->IsNull ()) {
1895+ // We do not register expression evaluation classes with the VM:
1896+ // The expression evaluation functions should be GC-able as soon as
1897+ // they are not reachable anymore and we never look them up by name.
1898+ const bool register_class =
1899+ library.raw () != expression_evaluation_library_.raw ();
1900+
18091901 *handle = Class::New (library, name, Script::Handle (Z),
1810- TokenPosition::kNoSource );
1811- library.AddClass (*handle);
1902+ TokenPosition::kNoSource , register_class);
1903+ if (register_class) {
1904+ library.AddClass (*handle);
1905+ }
18121906 }
18131907 // Insert the class in the cache before calling ReadPreliminaryClass so
18141908 // we do not risk allocating the class again by calling LookupClass
0 commit comments