[io] Provide dart::bin::SetupDartIoLibrary

Instead of requiring embedder to initialize dart:io by bits and pieces
by invoking various hooks and setting fields provide a structured C++
API for preparing dart:io for execution.

TEST=ci

CoreLibraryReviewExempt: VM specific changes only
Change-Id: I66e95c0a451d384b4f7582d1df059e506a6a6964
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/454062
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Slava Egorov <vegorov@google.com>
This commit is contained in:
Slava Egorov
2025-10-14 13:15:21 -07:00
committed by Commit Queue
parent afda7beb42
commit dec87b98f0
27 changed files with 232 additions and 253 deletions
+8 -25
View File
@@ -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",
+10 -3
View File
@@ -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<int>(id) >= 0);
ASSERT(static_cast<int>(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) {
+5
View File
@@ -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);
+5 -15
View File
@@ -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;
+62
View File
@@ -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
+9 -9
View File
@@ -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();
}
+27 -93
View File
@@ -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());
+25 -8
View File
@@ -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<void*>(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);
+9 -7
View File
@@ -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;
}
+1 -1
View File
@@ -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<HANDLE>(_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;
}
+10 -10
View File
@@ -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();
}
+2 -2
View File
@@ -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);
}
+2 -2
View File
@@ -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.
-9
View File
@@ -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 {
-9
View File
@@ -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 {
+1 -1
View File
@@ -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;
}
+3 -5
View File
@@ -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);
+2 -2
View File
@@ -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",
]
}
+3 -2
View File
@@ -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();
+34
View File
@@ -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
+4 -2
View File
@@ -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);
+3 -2
View File
@@ -5,6 +5,7 @@
#include <limits>
#include <memory>
#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();
}
+3 -2
View File
@@ -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));
-11
View File
@@ -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);
-5
View File
@@ -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) {
+4 -23
View File
@@ -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.
}
-5
View File
@@ -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);
}