diff --git a/engine/src/flutter/shell/platform/fuchsia/dart-pkg/fuchsia/lib/fuchsia.dart b/engine/src/flutter/shell/platform/fuchsia/dart-pkg/fuchsia/lib/fuchsia.dart index e2619c5c39..ff0ade3a36 100644 --- a/engine/src/flutter/shell/platform/fuchsia/dart-pkg/fuchsia/lib/fuchsia.dart +++ b/engine/src/flutter/shell/platform/fuchsia/dart-pkg/fuchsia/lib/fuchsia.dart @@ -65,3 +65,24 @@ void exit(int returnCode) { _setReturnCode(returnCode); Isolate.current.kill(priority: Isolate.immediate); } + +// ignore: always_declare_return_types, prefer_generic_function_type_aliases +typedef _ListStringArgFunction(List args); + +// This function is used as the entry point for code in the dart runner and is +// not meant to be called directly outside of that context. The code will invoke +// the given main entry point and pass the args if the function takes args. This +// function is needed because without it the snapshot compiler will tree shake +// the function away unless the user marks it as being an entry point. +// +// The code does not catch any exceptions since this is handled in the dart +// runner calling code. +@pragma('vm:entry-point') +void _runUserMainForDartRunner(Function userMainFunction, + List args) { + if (userMainFunction is _ListStringArgFunction) { + (userMainFunction as dynamic)(args); + } else { + userMainFunction(); + } +} diff --git a/engine/src/flutter/shell/platform/fuchsia/dart_runner/dart_component_controller.cc b/engine/src/flutter/shell/platform/fuchsia/dart_runner/dart_component_controller.cc index 7af29d793a..2f29dc4ea2 100644 --- a/engine/src/flutter/shell/platform/fuchsia/dart_runner/dart_component_controller.cc +++ b/engine/src/flutter/shell/platform/fuchsia/dart_runner/dart_component_controller.cc @@ -34,6 +34,7 @@ #include "third_party/tonic/dart_microtask_queue.h" #include "third_party/tonic/dart_state.h" #include "third_party/tonic/logging/dart_error.h" +#include "third_party/tonic/logging/dart_invoke.h" #include "builtin_libraries.h" #include "logging.h" @@ -414,12 +415,28 @@ bool DartComponentController::Main() { Dart_ListSetAt(dart_arguments, i, ToDart(arguments.at(i)))); } - Dart_Handle argv[] = { - dart_arguments, - }; + Dart_Handle user_main = Dart_GetField(Dart_RootLibrary(), ToDart("main")); + + if (Dart_IsError(user_main)) { + FX_LOGF(ERROR, LOG_TAG, + "Failed to locate user_main in the root library: %s", + Dart_GetError(user_main)); + Dart_ExitScope(); + return false; + } + + Dart_Handle fuchsia_lib = Dart_LookupLibrary(tonic::ToDart("dart:fuchsia")); + + if (Dart_IsError(fuchsia_lib)) { + FX_LOGF(ERROR, LOG_TAG, "Failed to locate dart:fuchsia: %s", + Dart_GetError(fuchsia_lib)); + Dart_ExitScope(); + return false; + } + + Dart_Handle main_result = tonic::DartInvokeField( + fuchsia_lib, "_runUserMainForDartRunner", {user_main, dart_arguments}); - Dart_Handle main_result = Dart_Invoke(Dart_RootLibrary(), ToDart("main"), - dart_utils::ArraySize(argv), argv); if (Dart_IsError(main_result)) { auto dart_state = tonic::DartState::Current(); if (!dart_state->has_set_return_code()) { diff --git a/engine/src/flutter/shell/platform/fuchsia/dart_runner/dart_component_controller_v2.cc b/engine/src/flutter/shell/platform/fuchsia/dart_runner/dart_component_controller_v2.cc index 23ea928817..e7d1065b5c 100644 --- a/engine/src/flutter/shell/platform/fuchsia/dart_runner/dart_component_controller_v2.cc +++ b/engine/src/flutter/shell/platform/fuchsia/dart_runner/dart_component_controller_v2.cc @@ -35,6 +35,7 @@ #include "third_party/tonic/dart_microtask_queue.h" #include "third_party/tonic/dart_state.h" #include "third_party/tonic/logging/dart_error.h" +#include "third_party/tonic/logging/dart_invoke.h" #include "builtin_libraries.h" #include "logging.h" @@ -402,13 +403,6 @@ bool DartComponentControllerV2::RunDartMain() { Dart_EnterScope(); // TODO(fxb/88383): Support argument passing. - // Note: Even though we do not support argument passing via the cml files - // at this time, we still need to create an argument list and pass it off - // to the invocation of main below. If we do not do this dart will look for - // a function with the signature `void main()` but existing dart components - // that run in the dart runner are written with main functions that have the - // signature `void main(List args)`. In order to ensure that these - // components do not break we need to have this stub argument list. Dart_Handle corelib = Dart_LookupLibrary(ToDart("dart:core")); Dart_Handle string_type = Dart_GetNonNullableType(corelib, ToDart("String"), 0, NULL); @@ -422,14 +416,27 @@ bool DartComponentControllerV2::RunDartMain() { return false; } - Dart_Handle argv[] = { - dart_arguments, - }; + Dart_Handle user_main = Dart_GetField(Dart_RootLibrary(), ToDart("main")); - Dart_Handle main_result = - Dart_Invoke(Dart_RootLibrary() /* target */, ToDart("main") /* name */, - dart_utils::ArraySize(argv) /* number_of_arguments */, - argv /* arguments */); + if (Dart_IsError(user_main)) { + FX_LOGF(ERROR, LOG_TAG, + "Failed to locate user_main in the root library: %s", + Dart_GetError(user_main)); + Dart_ExitScope(); + return false; + } + + Dart_Handle fuchsia_lib = Dart_LookupLibrary(tonic::ToDart("dart:fuchsia")); + + if (Dart_IsError(fuchsia_lib)) { + FX_LOGF(ERROR, LOG_TAG, "Failed to locate dart:fuchsia: %s", + Dart_GetError(fuchsia_lib)); + Dart_ExitScope(); + return false; + } + + Dart_Handle main_result = tonic::DartInvokeField( + fuchsia_lib, "_runUserMainForDartRunner", {user_main, dart_arguments}); if (Dart_IsError(main_result)) { auto dart_state = tonic::DartState::Current();