diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn index caf4eface21..87a69674317 100644 --- a/runtime/bin/BUILD.gn +++ b/runtime/bin/BUILD.gn @@ -457,6 +457,8 @@ template("build_gen_snapshot_dart_io") { sources = io_impl_sources sources += [ + "../include/bin/dart_io_api.h", + "dart_io_api_impl.cc", "io_natives.cc", "io_natives.h", ] @@ -604,7 +606,7 @@ template("dart_io") { } } -dart_io("dart_io_api") { +dart_io("common_embedder_dart_io") { extra_configs = [ "..:dart_maybe_product_config" ] extra_sources = [ "../include/bin/dart_io_api.h", @@ -614,7 +616,7 @@ dart_io("dart_io_api") { extra_deps = [ ":libdart_builtin" ] } -dart_io("dart_io_api_product") { +dart_io("common_embedder_dart_io_product") { extra_configs = [ "..:dart_product_config" ] extra_sources = [ "../include/bin/dart_io_api.h", @@ -624,18 +626,6 @@ dart_io("dart_io_api_product") { extra_deps = [ ":libdart_builtin_product" ] } -dart_io("standalone_dart_io") { - extra_configs = [ "..:dart_maybe_product_config" ] - extra_sources = [] - extra_deps = [ ":libdart_builtin" ] -} - -dart_io("standalone_dart_io_product") { - extra_configs = [ "..:dart_product_config" ] - extra_sources = [] - extra_deps = [ ":libdart_builtin_product" ] -} - gen_snapshot_action("generate_snapshot_bin") { deps = [ "../vm:vm_platform_stripped" ] vm_snapshot_data = "$target_gen_dir/vm_snapshot_data.bin" @@ -942,9 +932,9 @@ template("dart_executable") { deps = [ ":${target_name}_set" ] + extra_deps if (use_product_mode) { - deps += [ ":standalone_dart_io_product" ] + deps += [ ":common_embedder_dart_io_product" ] } else { - deps += [ ":standalone_dart_io" ] + deps += [ ":common_embedder_dart_io" ] } configs += [ ":export_api_symbols" ] @@ -974,7 +964,6 @@ dart_executable("dartvm") { "../platform:libdart_platform_jit", ] extra_sources = [ - "builtin.cc", "common_options.h", "dfe.cc", "dfe.h", @@ -1008,7 +997,6 @@ dart_executable("dartaotruntime") { "../platform:libdart_platform_aotruntime", ] extra_sources = [ - "builtin.cc", "common_options.h", "gzip.cc", "gzip.h", @@ -1045,7 +1033,6 @@ dart_executable("dartaotruntime_product") { "../platform:libdart_platform_aotruntime_product", ] extra_sources = [ - "builtin.cc", "common_options.h", "gzip.cc", "gzip.h", @@ -1077,7 +1064,6 @@ if (dart_target_arch != "ia32" && dart_target_arch != "x86") { "../platform:libdart_platform_aotruntime_product", ] extra_sources = [ - "builtin.cc", "common_options.h", "dartdev.cc", "dartdev.h", @@ -1120,7 +1106,6 @@ if (build_analyze_snapshot) { extra_sources = [ "analyze_snapshot.cc", - "builtin.cc", "common_options.h", "loader.cc", "loader.h", @@ -1188,7 +1173,6 @@ source_set("run_vm_tests_set") { regexp_tests = rebase_path(regexp_sources_tests, ".", "../vm/regexp") sources = [ - "builtin.cc", "dfe.cc", "dfe.h", "error_exit.cc", @@ -1224,11 +1208,11 @@ executable("run_vm_tests") { } deps = [ + ":common_embedder_dart_io", ":crashpad", ":dart_kernel_platform_cc", ":dart_snapshot_cc", ":run_vm_tests_set", - ":standalone_dart_io", "..:libdart_precompiler_testing", "//third_party/boringssl", # for secure_socket_utils_test "//third_party/perfetto:libprotozero", # for timeline_test @@ -1303,7 +1287,6 @@ if (defined(is_linux) && is_linux && defined(is_asan) && is_asan && extra_deps = [ "..:libdart_libfuzzer" ] extra_sources = [ "../vm/libfuzzer/dart_libfuzzer.cc", - "builtin.cc", "common_options.h", "dfe.cc", "dfe.h", @@ -1332,7 +1315,7 @@ source_set("dart_embedder_runtime_jit_set") { ] deps = [ - ":dart_io_api", + ":common_embedder_dart_io", ":dart_kernel_platform_cc", ":libdart_builtin", "..:libdart_jit", diff --git a/runtime/bin/builtin.cc b/runtime/bin/builtin.cc index 71b90e734f8..f1fe2b94986 100644 --- a/runtime/bin/builtin.cc +++ b/runtime/bin/builtin.cc @@ -26,21 +26,28 @@ const int Builtin::num_libs_ = sizeof(Builtin::builtin_libraries_) / sizeof(Builtin::builtin_lib_props); void Builtin::SetNativeResolver(BuiltinLibraryId id) { + Dart_Handle result = TrySetNativeResolver(id); + RELEASE_ASSERT(!Dart_IsError(result)); +} + +Dart_Handle Builtin::TrySetNativeResolver(BuiltinLibraryId id) { ASSERT(static_cast(id) >= 0); ASSERT(static_cast(id) < num_libs_); if (builtin_libraries_[id].has_natives_) { Dart_Handle url = DartUtils::NewString(builtin_libraries_[id].url_); Dart_Handle library = Dart_LookupLibrary(url); - ASSERT(!Dart_IsError(library)); + RETURN_IF_ERROR(library); // Setup the native resolver for built in library functions. Dart_Handle result = Dart_SetNativeResolver(library, NativeLookup, NativeSymbol); - ASSERT(!Dart_IsError(result)); + RETURN_IF_ERROR(result); // Setup the ffi native resolver for built in library functions. result = Dart_SetFfiNativeResolver(library, FfiNativeLookup); - ASSERT(!Dart_IsError(result)); + RETURN_IF_ERROR(result); } + + return Dart_Null(); } Dart_Handle Builtin::LoadAndCheckLibrary(BuiltinLibraryId id) { diff --git a/runtime/bin/builtin.h b/runtime/bin/builtin.h index 939e2dd741f..37a75c1e890 100644 --- a/runtime/bin/builtin.h +++ b/runtime/bin/builtin.h @@ -36,6 +36,11 @@ class Builtin { // Setup native resolver method built in library specified in 'id'. static void SetNativeResolver(BuiltinLibraryId id); + // Try setup native resolver method built in library specified in 'id'. + // + // Returns an error if it occurs otherwise `null`. + static Dart_Handle TrySetNativeResolver(BuiltinLibraryId id); + // Check if built in library specified in 'id' is already loaded, if not // load it. static Dart_Handle LoadAndCheckLibrary(BuiltinLibraryId id); diff --git a/runtime/bin/dart_embedder_api_impl.cc b/runtime/bin/dart_embedder_api_impl.cc index ce1b89ab34a..8be67eb330e 100644 --- a/runtime/bin/dart_embedder_api_impl.cc +++ b/runtime/bin/dart_embedder_api_impl.cc @@ -42,24 +42,13 @@ bool InitOnce(char** error) { err.message()); return false; } - bin::TimerUtils::InitOnce(); - bin::Process::Init(); -#if !defined(DART_IO_SECURE_SOCKET_DISABLED) - bin::SSLFilter::Init(); -#endif - bin::EventHandler::Start(); + bin::BootstrapDartIo(); return true; } void Cleanup() { bin::Process::ClearAllSignalHandlers(); - - bin::EventHandler::Stop(); -#if !defined(DART_IO_SECURE_SOCKET_DISABLED) - bin::SSLFilter::Cleanup(); -#endif - bin::Process::Cleanup(); - bin::IOService::Cleanup(); + bin::CleanupDartIo(); } Dart_Isolate CreateKernelServiceIsolate(const IsolateCreationData& data, @@ -81,9 +70,10 @@ Dart_Isolate CreateKernelServiceIsolate(const IsolateCreationData& data, Dart_ShutdownIsolate(); return nullptr; } - result = bin::DartUtils::PrepareForScriptLoading( + result = bin::DartUtils::SetupCoreLibraries( /*is_service_isolate=*/false, - /*trace_loading=*/false, /*flag_profile_microtasks=*/false); + /*trace_loading=*/false, /*flag_profile_microtasks=*/false, + bin::DartIoSettings{}); Dart_ExitScope(); Dart_ExitIsolate(); return kernel_isolate; diff --git a/runtime/bin/dart_io_api_impl.cc b/runtime/bin/dart_io_api_impl.cc index 1dec5afbeda..c64094469c7 100644 --- a/runtime/bin/dart_io_api_impl.cc +++ b/runtime/bin/dart_io_api_impl.cc @@ -94,5 +94,67 @@ const uint8_t* LookupIONativeSymbol(Dart_NativeFunction nf) { return IONativeSymbol(nf); } +Dart_Handle SetupDartIoLibrary(const DartIoSettings& settings) { + RETURN_IF_ERROR(Builtin::TrySetNativeResolver(Builtin::kIOLibrary)); + + // Configure dart:_http _httpConnectionHook is provided. + if (settings.http_connection_hook != nullptr) { + ASSIGN_OR_RETURN(Dart_Handle http_lib, + Builtin::LoadAndCheckLibrary(Builtin::kHttpLibrary)); + RETURN_IF_ERROR(Dart_SetField(http_lib, + DartUtils::NewString("_httpConnectionHook"), + settings.http_connection_hook)); + } + + Dart_Handle io_lib = Builtin::LoadAndCheckLibrary(Builtin::kIOLibrary); + + if (settings.namespace_root != nullptr) { + ASSIGN_OR_RETURN( + Dart_Handle namespc_type, + DartUtils::GetDartType(DartUtils::kIOLibURL, "_Namespace")); + Dart_Handle args[] = {settings.namespace_root}; + RETURN_IF_ERROR(args[0]); + RETURN_IF_ERROR(Dart_Invoke( + namespc_type, DartUtils::NewString("_setupNamespace"), 1, args)); + } + + if (settings.disable_exit) { + ASSIGN_OR_RETURN( + Dart_Handle embedder_config_type, + DartUtils::GetDartType(DartUtils::kIOLibURL, "_EmbedderConfig")); + RETURN_IF_ERROR(embedder_config_type); + RETURN_IF_ERROR(Dart_SetField( + embedder_config_type, DartUtils::NewString("_mayExit"), Dart_False())); + } + + ASSIGN_OR_RETURN(Dart_Handle platform_type, + DartUtils::GetDartType(DartUtils::kIOLibURL, "_Platform")); + + if (settings.script_uri != nullptr) { + RETURN_IF_ERROR(Dart_SetField(platform_type, + DartUtils::NewString("_nativeScript"), + DartUtils::NewString(settings.script_uri))); + } + + if (settings.locale_name_callback != nullptr) { + RETURN_IF_ERROR(Dart_SetField(platform_type, + DartUtils::NewString("_localeClosure"), + settings.locale_name_callback)); + } + + if (settings.enable_network_profiling) { +#if !defined(PRODUCT) + ASSIGN_OR_RETURN( + Dart_Handle network_profiling_type, + DartUtils::GetDartType(DartUtils::kIOLibURL, "_NetworkProfiling")); + RETURN_IF_ERROR(Dart_Invoke( + network_profiling_type, + DartUtils::NewString("_registerServiceExtension"), 0, nullptr)); +#endif // !defined(PRODUCT) + } + + return Dart_Invoke(io_lib, DartUtils::NewString("_setupHooks"), 0, nullptr); +} + } // namespace bin } // namespace dart diff --git a/runtime/bin/dartdev.cc b/runtime/bin/dartdev.cc index b5de1fd2242..3066a2275c0 100644 --- a/runtime/bin/dartdev.cc +++ b/runtime/bin/dartdev.cc @@ -108,7 +108,15 @@ static Dart_Handle SetupCoreLibraries(Dart_Isolate isolate, // Prepare builtin and other core libraries for use to resolve URIs. // Set up various closures, e.g: printing, timers etc. // Set up package configuration for URI resolution. - result = DartUtils::PrepareForScriptLoading(false, false, false); + result = DartUtils::SetupCoreLibraries( + /*is_service_isolate=*/false, /*trace_loading=*/false, + /*profile_microtasks=*/false, + DartIoSettings{ + .namespace_root = Options::namespc() != nullptr + ? DartUtils::NewString(Options::namespc()) + : nullptr, + .script_uri = script_uri, + .disable_exit = Options::exit_disabled()}); if (Dart_IsError(result)) return result; // Setup packages config if specified. @@ -124,16 +132,8 @@ static Dart_Handle SetupCoreLibraries(Dart_Isolate isolate, if (Dart_IsError(result)) return result; // Setup the native resolver as the snapshot does not carry it. - Builtin::SetNativeResolver(Builtin::kBuiltinLibrary); - Builtin::SetNativeResolver(Builtin::kIOLibrary); - Builtin::SetNativeResolver(Builtin::kCLILibrary); VmService::SetNativeResolver(); - const char* namespc = Options::namespc(); - result = - DartUtils::SetupIOLibrary(namespc, script_uri, Options::exit_disabled()); - if (Dart_IsError(result)) return result; - return Dart_Null(); } diff --git a/runtime/bin/dartutils.cc b/runtime/bin/dartutils.cc index 81e12be2f75..feaed748685 100644 --- a/runtime/bin/dartutils.cc +++ b/runtime/bin/dartutils.cc @@ -17,15 +17,6 @@ #include "platform/mach_o.h" #include "platform/utils.h" -// Return the error from the containing function if handle is in error handle. -#define RETURN_IF_ERROR(handle) \ - { \ - Dart_Handle __handle = handle; \ - if (Dart_IsError((__handle))) { \ - return __handle; \ - } \ - } - namespace dart { namespace bin { @@ -558,10 +549,6 @@ Dart_Handle DartUtils::PrepareAsyncLibrary(Dart_Handle async_lib, args); } -Dart_Handle DartUtils::PrepareIOLibrary(Dart_Handle io_lib) { - return Dart_Invoke(io_lib, NewString("_setupHooks"), 0, nullptr); -} - Dart_Handle DartUtils::PrepareIsolateLibrary(Dart_Handle isolate_lib) { return Dart_Invoke(isolate_lib, NewString("_setupHooks"), 0, nullptr); } @@ -585,36 +572,34 @@ Dart_Handle DartUtils::SetupPackageConfig(const char* packages_config) { return result; } -Dart_Handle DartUtils::PrepareForScriptLoading(bool is_service_isolate, - bool trace_loading, - bool flag_profile_microtasks) { +Dart_Handle DartUtils::SetupCoreLibraries( + bool is_service_isolate, + bool trace_loading, + bool flag_profile_microtasks, + const DartIoSettings& dart_io_settings) { // First ensure all required libraries are available. - Dart_Handle url = NewString(kCoreLibURL); - RETURN_IF_ERROR(url); - Dart_Handle core_lib = Dart_LookupLibrary(url); - RETURN_IF_ERROR(core_lib); - url = NewString(kAsyncLibURL); - RETURN_IF_ERROR(url); - Dart_Handle async_lib = Dart_LookupLibrary(url); - RETURN_IF_ERROR(async_lib); - url = NewString(kIsolateLibURL); - RETURN_IF_ERROR(url); - Dart_Handle isolate_lib = Dart_LookupLibrary(url); - RETURN_IF_ERROR(isolate_lib); - url = NewString(kInternalLibURL); - RETURN_IF_ERROR(url); - Dart_Handle internal_lib = Dart_LookupLibrary(url); - RETURN_IF_ERROR(internal_lib); - Dart_Handle builtin_lib = - Builtin::LoadAndCheckLibrary(Builtin::kBuiltinLibrary); - RETURN_IF_ERROR(builtin_lib); - Builtin::SetNativeResolver(Builtin::kBuiltinLibrary); - Dart_Handle io_lib = Builtin::LoadAndCheckLibrary(Builtin::kIOLibrary); - RETURN_IF_ERROR(io_lib); - Builtin::SetNativeResolver(Builtin::kIOLibrary); - Dart_Handle cli_lib = Builtin::LoadAndCheckLibrary(Builtin::kCLILibrary); - RETURN_IF_ERROR(cli_lib); - Builtin::SetNativeResolver(Builtin::kCLILibrary); + ASSIGN_OR_RETURN(Dart_Handle core_lib, + Dart_LookupLibrary(NewString(kCoreLibURL))); + ASSIGN_OR_RETURN(Dart_Handle async_lib, + Dart_LookupLibrary(NewString(kAsyncLibURL))); + ASSIGN_OR_RETURN(Dart_Handle isolate_lib, + Dart_LookupLibrary(NewString(kIsolateLibURL))); + ASSIGN_OR_RETURN(Dart_Handle internal_lib, + Dart_LookupLibrary(NewString(kInternalLibURL))); + ASSIGN_OR_RETURN(Dart_Handle builtin_lib, + Dart_LookupLibrary(NewString(kBuiltinLibURL))); + ASSIGN_OR_RETURN(Dart_Handle io_lib, + Dart_LookupLibrary(NewString(kIOLibURL))); + ASSIGN_OR_RETURN(Dart_Handle cli_lib, + Dart_LookupLibrary(NewString(kCLILibURL))); + + // Configure native resolvers for dart:_builtin and dart:cli. + for (auto id : {Builtin::kBuiltinLibrary, Builtin::kCLILibrary}) { + RETURN_IF_ERROR(Builtin::TrySetNativeResolver(id)); + } + + // Initialize dart:io library. + RETURN_IF_ERROR(SetupDartIoLibrary(dart_io_settings)); // We need to ensure that all the scripts loaded so far are finalized // as we are about to invoke some Dart code below to setup closures. @@ -629,61 +614,10 @@ Dart_Handle DartUtils::PrepareForScriptLoading(bool is_service_isolate, PrepareAsyncLibrary(async_lib, isolate_lib, flag_profile_microtasks)); RETURN_IF_ERROR(PrepareCoreLibrary(core_lib, io_lib, is_service_isolate)); RETURN_IF_ERROR(PrepareIsolateLibrary(isolate_lib)); - RETURN_IF_ERROR(PrepareIOLibrary(io_lib)); RETURN_IF_ERROR(PrepareCLILibrary(cli_lib)); return result; } -Dart_Handle DartUtils::SetupIOLibrary(const char* namespc_path, - const char* script_uri, - bool disable_exit) { - Dart_Handle io_lib_url = NewString(kIOLibURL); - RETURN_IF_ERROR(io_lib_url); - Dart_Handle io_lib = Dart_LookupLibrary(io_lib_url); - RETURN_IF_ERROR(io_lib); - - if (namespc_path != nullptr) { - Dart_Handle namespc_type = GetDartType(DartUtils::kIOLibURL, "_Namespace"); - RETURN_IF_ERROR(namespc_type); - Dart_Handle args[1]; - args[0] = NewString(namespc_path); - RETURN_IF_ERROR(args[0]); - Dart_Handle result = - Dart_Invoke(namespc_type, NewString("_setupNamespace"), 1, args); - RETURN_IF_ERROR(result); - } - - if (disable_exit) { - Dart_Handle embedder_config_type = - GetDartType(DartUtils::kIOLibURL, "_EmbedderConfig"); - RETURN_IF_ERROR(embedder_config_type); - Dart_Handle result = Dart_SetField(embedder_config_type, - NewString("_mayExit"), Dart_False()); - RETURN_IF_ERROR(result); - } - - Dart_Handle platform_type = GetDartType(DartUtils::kIOLibURL, "_Platform"); - RETURN_IF_ERROR(platform_type); - Dart_Handle script_name = NewString("_nativeScript"); - RETURN_IF_ERROR(script_name); - Dart_Handle dart_script = NewString(script_uri); - RETURN_IF_ERROR(dart_script); - Dart_Handle set_script_name = - Dart_SetField(platform_type, script_name, dart_script); - RETURN_IF_ERROR(set_script_name); - -#if !defined(PRODUCT) - Dart_Handle network_profiling_type = - GetDartType(DartUtils::kIOLibURL, "_NetworkProfiling"); - RETURN_IF_ERROR(network_profiling_type); - Dart_Handle result = - Dart_Invoke(network_profiling_type, - NewString("_registerServiceExtension"), 0, nullptr); - RETURN_IF_ERROR(result); -#endif // !defined(PRODUCT) - return Dart_Null(); -} - bool DartUtils::PostNull(Dart_Port port_id) { // Post a message with just the null object. return Dart_PostCObject(port_id, CObject::Null()->AsApiCObject()); diff --git a/runtime/bin/dartutils.h b/runtime/bin/dartutils.h index 89abdd97a0d..a7db208190e 100644 --- a/runtime/bin/dartutils.h +++ b/runtime/bin/dartutils.h @@ -6,6 +6,7 @@ #define RUNTIME_BIN_DARTUTILS_H_ #include "bin/isolate_data.h" +#include "include/bin/dart_io_api.h" #include "include/dart_api.h" #include "include/dart_native_api.h" #include "platform/assert.h" @@ -35,6 +36,26 @@ static inline Dart_Handle ThrowIfError(Dart_Handle handle) { return handle; } +// Return the error from the containing function if handle is in error handle. +#define RETURN_IF_ERROR(handle) \ + { \ + Dart_Handle __handle = handle; \ + if (Dart_IsError((__handle))) { \ + return __handle; \ + } \ + } + +#define TEMPVAR_IMPL(x, y) x##y +#define TEMPVAR(x, y) TEMPVAR_IMPL(x, y) + +// Return the error from the containing function if handle is in error handle. +#define ASSIGN_OR_RETURN(lhs, expr) \ + Dart_Handle TEMPVAR(_aor_handle, __LINE__) = expr; \ + if (Dart_IsError(TEMPVAR(_aor_handle, __LINE__))) { \ + return TEMPVAR(_aor_handle, __LINE__); \ + } \ + lhs = TEMPVAR(_aor_handle, __LINE__); + static inline void* GetHashmapKeyFromString(char* key) { return reinterpret_cast(key); } @@ -175,15 +196,12 @@ class DartUtils { static bool EntropySource(uint8_t* buffer, intptr_t length); static Dart_Handle ReadStringFromFile(const char* filename); static Dart_Handle MakeUint8Array(const void* buffer, intptr_t length); - static Dart_Handle PrepareForScriptLoading(bool is_service_isolate, - bool trace_loading, - bool flag_profile_microtasks); + static Dart_Handle SetupCoreLibraries(bool is_service_isolate, + bool trace_loading, + bool flag_profile_microtasks, + const DartIoSettings& dart_io_settings); static Dart_Handle SetupPackageConfig(const char* packages_file); - static Dart_Handle SetupIOLibrary(const char* namespc_path, - const char* script_uri, - bool disable_exit); - static bool PostNull(Dart_Port port_id); static bool PostInt32(Dart_Port port_id, int32_t value); static bool PostInt64(Dart_Port port_id, int64_t value); @@ -336,7 +354,6 @@ class DartUtils { static Dart_Handle PrepareAsyncLibrary(Dart_Handle async_lib, Dart_Handle isolate_lib, bool flag_profile_microtasks); - static Dart_Handle PrepareIOLibrary(Dart_Handle io_lib); static Dart_Handle PrepareIsolateLibrary(Dart_Handle isolate_lib); static Dart_Handle PrepareCLILibrary(Dart_Handle cli_lib); diff --git a/runtime/bin/eventhandler_win.cc b/runtime/bin/eventhandler_win.cc index f8d99699173..c7dc55f63ad 100644 --- a/runtime/bin/eventhandler_win.cc +++ b/runtime/bin/eventhandler_win.cc @@ -326,7 +326,8 @@ void Handle::ReadSyncCompleteAsync() { } char* buffer_start = pending_read_->GetBufferStart(); DWORD bytes_read = 0; - BOOL ok = ReadFile(handle_, buffer_start, buffer_size, &bytes_read, nullptr); + BOOL ok = + ::ReadFile(handle_, buffer_start, buffer_size, &bytes_read, nullptr); if (!ok) { bytes_read = 0; } @@ -349,8 +350,8 @@ bool Handle::IssueReadLocked(MonitorLocker* ml) { pending_read_ = buffer.get(); if (supports_overlapped_io()) { BOOL ok = - ReadFile(handle_, buffer->GetBufferStart(), buffer->GetBufferSize(), - nullptr, buffer->GetCleanOverlapped()); + ::ReadFile(handle_, buffer->GetBufferStart(), buffer->GetBufferSize(), + nullptr, buffer->GetCleanOverlapped()); if (ok || (GetLastError() == ERROR_IO_PENDING)) { // Completing asynchronously. buffer.release(); // HandleIOCompletion will take ownership. @@ -390,8 +391,8 @@ bool Handle::IssueWriteLocked(MonitorLocker* ml, // because completion will race with this code. pending_write_ = buffer.get(); BOOL ok = - WriteFile(handle_, buffer->GetBufferStart(), buffer->GetBufferSize(), - nullptr, buffer->GetCleanOverlapped()); + ::WriteFile(handle_, buffer->GetBufferStart(), buffer->GetBufferSize(), + nullptr, buffer->GetCleanOverlapped()); if (ok || (GetLastError() == ERROR_IO_PENDING)) { // Completing asynchronously. buffer.release(); // HandleIOCompletion will take ownership. @@ -765,8 +766,9 @@ void StdHandle::WriteSyncCompleteAsync() { ASSERT(HasPendingWrite()); DWORD bytes_written = -1; - BOOL ok = WriteFile(handle_, pending_write_->GetBufferStart(), - pending_write_->GetBufferSize(), &bytes_written, nullptr); + BOOL ok = + ::WriteFile(handle_, pending_write_->GetBufferStart(), + pending_write_->GetBufferSize(), &bytes_written, nullptr); if (!ok) { bytes_written = 0; } diff --git a/runtime/bin/file_win.cc b/runtime/bin/file_win.cc index 84349659449..e9d9431302a 100644 --- a/runtime/bin/file_win.cc +++ b/runtime/bin/file_win.cc @@ -159,7 +159,7 @@ int64_t File::Write(const void* buffer, int64_t num_bytes) { ASSERT(fd >= 0 && num_bytes <= MAXDWORD && num_bytes >= 0); HANDLE handle = reinterpret_cast(_get_osfhandle(fd)); DWORD written = 0; - BOOL result = WriteFile(handle, buffer, num_bytes, &written, nullptr); + BOOL result = ::WriteFile(handle, buffer, num_bytes, &written, nullptr); if (!result) { return -1; } diff --git a/runtime/bin/main_impl.cc b/runtime/bin/main_impl.cc index 656205dc4c2..e984475ebdf 100644 --- a/runtime/bin/main_impl.cc +++ b/runtime/bin/main_impl.cc @@ -167,8 +167,16 @@ static Dart_Handle SetupCoreLibraries(Dart_Isolate isolate, #else bool flag_profile_microtasks = Options::profile_microtasks(); #endif // defined(PRODUCT) - result = DartUtils::PrepareForScriptLoading(false, Options::trace_loading(), - flag_profile_microtasks); + result = DartUtils::SetupCoreLibraries( + /*is_service_isolate=*/false, Options::trace_loading(), + flag_profile_microtasks, + DartIoSettings{ + .namespace_root = is_kernel_isolate || (Options::namespc() == nullptr) + ? nullptr + : DartUtils::NewString(Options::namespc()), + .script_uri = script_uri, + .disable_exit = Options::exit_disabled(), + }); if (Dart_IsError(result)) return result; // Setup packages config if specified. @@ -193,16 +201,8 @@ static Dart_Handle SetupCoreLibraries(Dart_Isolate isolate, if (Dart_IsError(result)) return result; // Setup the native resolver as the snapshot does not carry it. - Builtin::SetNativeResolver(Builtin::kBuiltinLibrary); - Builtin::SetNativeResolver(Builtin::kIOLibrary); - Builtin::SetNativeResolver(Builtin::kCLILibrary); VmService::SetNativeResolver(); - const char* namespc = is_kernel_isolate ? nullptr : Options::namespc(); - result = - DartUtils::SetupIOLibrary(namespc, script_uri, Options::exit_disabled()); - if (Dart_IsError(result)) return result; - return Dart_Null(); } diff --git a/runtime/bin/process_win.cc b/runtime/bin/process_win.cc index fc61eba6872..902797b79e5 100644 --- a/runtime/bin/process_win.cc +++ b/runtime/bin/process_win.cc @@ -178,7 +178,7 @@ class ProcessInfoList { } int message[2] = {exit_code, negative}; DWORD written; - ok = WriteFile(exit_pipe, message, sizeof(message), &written, nullptr); + ok = ::WriteFile(exit_pipe, message, sizeof(message), &written, nullptr); // If the process has been closed, the read end of the exit // pipe has been closed. It is therefore not a problem that // WriteFile fails with a closed pipe error @@ -836,7 +836,7 @@ class OverlappedHandle { if (!buffer_.GetReadBuffer(&buffer, &buffer_size)) { return false; } - BOOL ok = ReadFile(handle_, buffer, buffer_size, nullptr, &overlapped_); + BOOL ok = ::ReadFile(handle_, buffer, buffer_size, nullptr, &overlapped_); if (!ok) { return (GetLastError() == ERROR_IO_PENDING); } diff --git a/runtime/bin/run_vm_tests.cc b/runtime/bin/run_vm_tests.cc index cb0010e7a4c..661267100ce 100644 --- a/runtime/bin/run_vm_tests.cc +++ b/runtime/bin/run_vm_tests.cc @@ -258,9 +258,9 @@ static Dart_Isolate CreateIsolateAndSetup(const char* script_uri, Dart_EnterScope(); bin::DartUtils::SetOriginalWorkingDirectory(); - Dart_Handle result = bin::DartUtils::PrepareForScriptLoading( + Dart_Handle result = bin::DartUtils::SetupCoreLibraries( /*is_service_isolate=*/false, /*trace_loading=*/false, - /*flag_profile_microtasks=*/false); + /*flag_profile_microtasks=*/false, bin::DartIoSettings{}); CHECK_RESULT(result); // Setup kernel service as the main script for this isolate. diff --git a/runtime/bin/secure_socket_filter.cc b/runtime/bin/secure_socket_filter.cc index 49114fd8607..992d95b7010 100644 --- a/runtime/bin/secure_socket_filter.cc +++ b/runtime/bin/secure_socket_filter.cc @@ -18,15 +18,6 @@ #include "platform/syslog.h" #include "platform/text_buffer.h" -// Return the error from the containing function if handle is an error handle. -#define RETURN_IF_ERROR(handle) \ - { \ - Dart_Handle __handle = handle; \ - if (Dart_IsError((__handle))) { \ - return __handle; \ - } \ - } - namespace dart { namespace bin { diff --git a/runtime/bin/security_context.cc b/runtime/bin/security_context.cc index 6af61162504..638a4f6672b 100644 --- a/runtime/bin/security_context.cc +++ b/runtime/bin/security_context.cc @@ -20,15 +20,6 @@ #include "bin/secure_socket_utils.h" #include "platform/syslog.h" -// Return the error from the containing function if handle is an error handle. -#define RETURN_IF_ERROR(handle) \ - { \ - Dart_Handle __handle = handle; \ - if (Dart_IsError((__handle))) { \ - return __handle; \ - } \ - } - namespace dart { namespace bin { diff --git a/runtime/bin/stdio_win.cc b/runtime/bin/stdio_win.cc index ddb1811c7e7..954d7b1e94f 100644 --- a/runtime/bin/stdio_win.cc +++ b/runtime/bin/stdio_win.cc @@ -24,7 +24,7 @@ bool Stdin::ReadByte(intptr_t fd, int* byte) { HANDLE h = GetStdHandle(STD_INPUT_HANDLE); uint8_t buffer[1]; DWORD read = 0; - BOOL success = ReadFile(h, buffer, 1, &read, nullptr); + BOOL success = ::ReadFile(h, buffer, 1, &read, nullptr); if (!success && (GetLastError() != ERROR_BROKEN_PIPE)) { return false; } diff --git a/runtime/bin/vmservice_impl.cc b/runtime/bin/vmservice_impl.cc index 4b040d18386..42208758425 100644 --- a/runtime/bin/vmservice_impl.cc +++ b/runtime/bin/vmservice_impl.cc @@ -134,12 +134,10 @@ bool VmService::Setup(const char* server_ip, Dart_Handle result; - // Prepare builtin and its dependent libraries for use to resolve URIs. - // Set up various closures, e.g: printing, timers etc. - // Set up 'package root' for URI resolution. - result = DartUtils::PrepareForScriptLoading( + // Prepare all core libraries for execution of Dart code. + result = DartUtils::SetupCoreLibraries( /*is_service_isolate=*/true, trace_loading, - /*flag_profile_microtasks=*/false); + /*flag_profile_microtasks=*/false, DartIoSettings{}); SHUTDOWN_ON_ERROR(result); Dart_Handle url = DartUtils::NewString(kVMServiceIOLibraryUri); diff --git a/runtime/engine/BUILD.gn b/runtime/engine/BUILD.gn index 6dd85e65876..36b9dbf6139 100644 --- a/runtime/engine/BUILD.gn +++ b/runtime/engine/BUILD.gn @@ -27,7 +27,7 @@ source_set("engine_jit_set") { deps = [ "..:libdart_jit", - "../bin:dart_io_api", + "../bin:common_embedder_dart_io", "../bin:dart_kernel_platform_cc", "../bin:libdart_builtin", ] @@ -59,7 +59,7 @@ source_set("engine_aot_set") { deps = [ "..:libdart_aotruntime", - "../bin:dart_io_api", + "../bin:common_embedder_dart_io", "../bin:libdart_builtin", ] } diff --git a/runtime/engine/engine.cc b/runtime/engine/engine.cc index 6d7c642c109..aefcfc92469 100644 --- a/runtime/engine/engine.cc +++ b/runtime/engine/engine.cc @@ -194,8 +194,9 @@ Dart_Isolate Engine::StartIsolate(DartEngine_SnapshotData snapshot, // In fact, this call initializes core libraries, (e.g. `print` doesn't work // without it). - Dart_Handle core_libs_result = bin::DartUtils::PrepareForScriptLoading( - false, false, /*flag_profile_microtasks=*/false); + Dart_Handle core_libs_result = bin::DartUtils::SetupCoreLibraries( + /*is_service_isolate=*/false, /*trace_loading=*/false, + /*flag_profile_microtasks=*/false, bin::DartIoSettings{}); if (Dart_IsError(core_libs_result)) { *error = Utils::StrDup(Dart_GetError(core_libs_result)); Dart_ShutdownIsolate(); diff --git a/runtime/include/bin/dart_io_api.h b/runtime/include/bin/dart_io_api.h index e6d117786f0..f2bd4944630 100644 --- a/runtime/include/bin/dart_io_api.h +++ b/runtime/include/bin/dart_io_api.h @@ -67,6 +67,40 @@ void* LookupIOFfiNative(const char* name, uintptr_t argument_count); // a valid I/O native function. const uint8_t* LookupIONativeSymbol(Dart_NativeFunction nf); +// Configuration for embedder extension points provided by `dart:io`. +struct DartIoSettings { + // Value for `dart:_http` `_httpConnectionHook`, `nullptr` means default. + // + // Must be a function of type `void Function(Uri)`. + Dart_Handle http_connection_hook = nullptr; + + // Callback to intercept `_Platform.localeName`, `nullptr` means default. + // + // Must be a function of type `String Function()`. + Dart_Handle locale_name_callback = nullptr; + + // Namespace root to pass to `_Namespace._setupNamespace`. + // + // Must be either an string (path) or an integer (dirfd). + Dart_Handle namespace_root = nullptr; + + // Value for `Platform.script`. + const char* script_uri = nullptr; + + // Setting this to `true` will disable `exit`. + // + // When disabled `exit` throws an `UnsupportedError`. + bool disable_exit = false; + + // Register service extensions for profiling networking traffic. + // + // See `_NetworkProfile` for the list of extensions. + bool enable_network_profiling = true; +}; + +// Prepare 'dart:io' library for running. +Dart_Handle SetupDartIoLibrary(const DartIoSettings& settings); + } // namespace bin } // namespace dart diff --git a/runtime/vm/benchmark_test.cc b/runtime/vm/benchmark_test.cc index 7661f487bdc..22174eee008 100644 --- a/runtime/vm/benchmark_test.cc +++ b/runtime/vm/benchmark_test.cc @@ -4,6 +4,8 @@ #include "vm/benchmark_test.h" +#include "include/bin/dart_io_api.h" + #include "bin/builtin.h" #include "bin/file.h" #include "bin/isolate_data.h" @@ -44,8 +46,8 @@ void Benchmark::RunAll(const char* executable) { // BENCHMARK(CorelibCompileAll) { bin::Builtin::SetNativeResolver(bin::Builtin::kBuiltinLibrary); - bin::Builtin::SetNativeResolver(bin::Builtin::kIOLibrary); bin::Builtin::SetNativeResolver(bin::Builtin::kCLILibrary); + bin::SetupDartIoLibrary({}); TransitionNativeToVM transition(thread); StackZone zone(thread); Timer timer; @@ -222,8 +224,8 @@ static Dart_NativeFunction NativeResolver(Dart_Handle name, BENCHMARK(KernelServiceCompileAll) { // kernel_service.dill is built with sound null safety. bin::Builtin::SetNativeResolver(bin::Builtin::kBuiltinLibrary); - bin::Builtin::SetNativeResolver(bin::Builtin::kIOLibrary); bin::Builtin::SetNativeResolver(bin::Builtin::kCLILibrary); + bin::SetupDartIoLibrary({}); char* dill_path = ComputeKernelServicePath(Benchmark::Executable()); File* file = File::Open(nullptr, dill_path, File::kRead); EXPECT(file != nullptr); diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc index 8817bb13d3b..a6c2e0c3f43 100644 --- a/runtime/vm/object_test.cc +++ b/runtime/vm/object_test.cc @@ -5,6 +5,7 @@ #include #include +#include "include/bin/dart_io_api.h" #include "include/dart_api.h" #include "bin/builtin.h" @@ -5903,8 +5904,8 @@ ISOLATE_UNIT_TEST_CASE(ToCString) { { TransitionVMToNative transition(thread); bin::Builtin::SetNativeResolver(bin::Builtin::kBuiltinLibrary); - bin::Builtin::SetNativeResolver(bin::Builtin::kIOLibrary); bin::Builtin::SetNativeResolver(bin::Builtin::kCLILibrary); + bin::SetupDartIoLibrary({}); bin::VmService::SetNativeResolver(); } @@ -5931,8 +5932,8 @@ ISOLATE_UNIT_TEST_CASE(PrintJSON) { { TransitionVMToNative transition(thread); bin::Builtin::SetNativeResolver(bin::Builtin::kBuiltinLibrary); - bin::Builtin::SetNativeResolver(bin::Builtin::kIOLibrary); bin::Builtin::SetNativeResolver(bin::Builtin::kCLILibrary); + bin::SetupDartIoLibrary({}); bin::VmService::SetNativeResolver(); } diff --git a/runtime/vm/unit_test.cc b/runtime/vm/unit_test.cc index 0e2e297b4fc..36fd4204b8a 100644 --- a/runtime/vm/unit_test.cc +++ b/runtime/vm/unit_test.cc @@ -152,9 +152,10 @@ void SetupCoreLibrariesForUnitTest() { Dart_EnterScope(); bool ok = bin::DartUtils::SetOriginalWorkingDirectory(); RELEASE_ASSERT(ok); - Dart_Handle result = bin::DartUtils::PrepareForScriptLoading( + Dart_Handle result = bin::DartUtils::SetupCoreLibraries( /*is_service_isolate=*/false, - /*trace_loading=*/false, /*flag_profile_microtasks=*/false); + /*trace_loading=*/false, + /*flag_profile_microtasks=*/false, bin::DartIoSettings{}); Dart_ExitScope(); RELEASE_ASSERT(!Dart_IsError(result)); diff --git a/sdk/lib/_internal/vm/bin/stdio_patch.dart b/sdk/lib/_internal/vm/bin/stdio_patch.dart index d97d5a03b92..ed7c436a389 100644 --- a/sdk/lib/_internal/vm/bin/stdio_patch.dart +++ b/sdk/lib/_internal/vm/bin/stdio_patch.dart @@ -88,9 +88,6 @@ class Stdin { @patch void set echoMode(bool enabled) { - if (!_EmbedderConfig._maySetEchoMode) { - throw UnsupportedError("This embedder disallows setting Stdin.echoMode"); - } var result = _setEchoMode(_fd, enabled); if (result is OSError) { throw StdinException("Error setting terminal echo mode", result); @@ -108,11 +105,6 @@ class Stdin { @patch void set echoNewlineMode(bool enabled) { - if (!_EmbedderConfig._maySetEchoNewlineMode) { - throw UnsupportedError( - "This embedder disallows setting Stdin.echoNewlineMode", - ); - } var result = _setEchoNewlineMode(_fd, enabled); if (result is OSError) { throw StdinException("Error setting terminal echo newline mode", result); @@ -130,9 +122,6 @@ class Stdin { @patch void set lineMode(bool enabled) { - if (!_EmbedderConfig._maySetLineMode) { - throw UnsupportedError("This embedder disallows setting Stdin.lineMode"); - } var result = _setLineMode(_fd, enabled); if (result is OSError) { throw StdinException("Error setting terminal line mode", result); diff --git a/sdk/lib/io/directory_impl.dart b/sdk/lib/io/directory_impl.dart index 82b89c2b4de..570128ebeef 100644 --- a/sdk/lib/io/directory_impl.dart +++ b/sdk/lib/io/directory_impl.dart @@ -70,11 +70,6 @@ class _Directory extends FileSystemEntity implements Directory { ), }; - if (!_EmbedderConfig._mayChdir) { - throw UnsupportedError( - "This embedder disallows setting Directory.current", - ); - } var result = _setCurrent(_Namespace._namespace, _rawPath); if (result is ArgumentError) throw result; if (result is OSError) { diff --git a/sdk/lib/io/embedder_config.dart b/sdk/lib/io/embedder_config.dart index 240a332a7d1..0afffc9014a 100644 --- a/sdk/lib/io/embedder_config.dart +++ b/sdk/lib/io/embedder_config.dart @@ -11,32 +11,13 @@ part of "dart:io"; /// permitted to use (e.g. [exit]). By default, the whole `dart:io` API is /// enabled. When a disallowed operation is attempted, an `UnsupportedError` is /// thrown. +/// +/// Embedders should not modify these flags directly and should instead +/// configure `dart:io` by passing appropriate settings to +/// `dart::bin::SetupDartIoLibrary`. @pragma('vm:entry-point') abstract class _EmbedderConfig { - /// Whether the isolate may set [Directory.current]. - static bool _mayChdir = true; - /// Whether the isolate may call [exit]. @pragma("vm:entry-point") static bool _mayExit = true; - - // Whether the isolate may set [Stdin.echoMode]. - @pragma('vm:entry-point') - static bool _maySetEchoMode = true; - - // Whether the isolate may set [Stdin.echoNewlineMode]. - @pragma('vm:entry-point') - static bool _maySetEchoNewlineMode = true; - - // Whether the isolate may set [Stdin.lineMode]. - @pragma('vm:entry-point') - static bool _maySetLineMode = true; - - /// Whether the isolate may call [sleep]. - @pragma('vm:entry-point') - static bool _maySleep = true; - - // TODO(zra): Consider adding: - // - an option to disallow modifying SecurityContext.defaultContext - // - an option to disallow closing stdout and stderr. } diff --git a/sdk/lib/io/process.dart b/sdk/lib/io/process.dart index 25576b090f4..c5aa00c66ed 100644 --- a/sdk/lib/io/process.dart +++ b/sdk/lib/io/process.dart @@ -102,11 +102,6 @@ void sleep(Duration duration) { if (milliseconds < 0) { throw new ArgumentError("sleep: duration cannot be negative"); } - if (!_EmbedderConfig._maySleep) { - throw new UnsupportedError( - "This embedder disallows calling dart:io's sleep()", - ); - } _ProcessUtils._sleep(milliseconds); }