mirror of
https://github.com/encounter/engine.git
synced 2026-07-10 03:18:43 -07:00
343d9f2a03
The bug in the original CL was that we were not running replace_as_executable in OpenVmo if the namespace was not provided. This was a divergence in behavior for MappedResource::LoadFromNamespace compared to the current implementation.
211 lines
7.3 KiB
C++
211 lines
7.3 KiB
C++
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "service_isolate.h"
|
|
|
|
#include "runtime/dart/utils/inlines.h"
|
|
#include "third_party/dart/runtime/include/bin/dart_io_api.h"
|
|
#include "third_party/tonic/converter/dart_converter.h"
|
|
#include "third_party/tonic/dart_library_natives.h"
|
|
#include "third_party/tonic/dart_microtask_queue.h"
|
|
#include "third_party/tonic/dart_state.h"
|
|
#include "third_party/tonic/typed_data/typed_list.h"
|
|
|
|
#include "builtin_libraries.h"
|
|
#include "dart_component_controller.h"
|
|
#include "logging.h"
|
|
|
|
namespace dart_runner {
|
|
namespace {
|
|
|
|
dart_utils::ElfSnapshot elf_snapshot; // AOT snapshot
|
|
dart_utils::MappedResource mapped_isolate_snapshot_data; // JIT snapshot
|
|
dart_utils::MappedResource
|
|
mapped_isolate_snapshot_instructions; // JIT snapshot
|
|
tonic::DartLibraryNatives* service_natives = nullptr;
|
|
|
|
Dart_NativeFunction GetNativeFunction(Dart_Handle name,
|
|
int argument_count,
|
|
bool* auto_setup_scope) {
|
|
dart_utils::Check(service_natives, LOG_TAG);
|
|
return service_natives->GetNativeFunction(name, argument_count,
|
|
auto_setup_scope);
|
|
}
|
|
|
|
const uint8_t* GetSymbol(Dart_NativeFunction native_function) {
|
|
dart_utils::Check(service_natives, LOG_TAG);
|
|
return service_natives->GetSymbol(native_function);
|
|
}
|
|
|
|
#define SHUTDOWN_ON_ERROR(handle) \
|
|
if (Dart_IsError(handle)) { \
|
|
*error = strdup(Dart_GetError(handle)); \
|
|
FX_LOG(ERROR, LOG_TAG, *error); \
|
|
Dart_ExitScope(); \
|
|
Dart_ShutdownIsolate(); \
|
|
return nullptr; \
|
|
}
|
|
|
|
void NotifyServerState(Dart_NativeArguments args) {
|
|
// NOP.
|
|
}
|
|
|
|
void Shutdown(Dart_NativeArguments args) {
|
|
// NOP.
|
|
}
|
|
|
|
void EmbedderInformationCallback(Dart_EmbedderInformation* info) {
|
|
info->version = DART_EMBEDDER_INFORMATION_CURRENT_VERSION;
|
|
info->name = "dart_runner";
|
|
info->current_rss = -1;
|
|
info->max_rss = -1;
|
|
|
|
zx_info_task_stats_t task_stats;
|
|
zx_handle_t process = zx_process_self();
|
|
zx_status_t status = zx_object_get_info(
|
|
process, ZX_INFO_TASK_STATS, &task_stats, sizeof(task_stats), NULL, NULL);
|
|
if (status == ZX_OK) {
|
|
info->current_rss =
|
|
task_stats.mem_private_bytes + task_stats.mem_shared_bytes;
|
|
}
|
|
}
|
|
|
|
} // namespace
|
|
|
|
Dart_Isolate CreateServiceIsolate(const char* uri,
|
|
Dart_IsolateFlags* flags,
|
|
char** error) {
|
|
Dart_SetEmbedderInformationCallback(EmbedderInformationCallback);
|
|
|
|
const uint8_t *vmservice_data = nullptr, *vmservice_instructions = nullptr;
|
|
|
|
#if defined(AOT_RUNTIME)
|
|
// The VM service was compiled as a separate app.
|
|
const char* snapshot_path = "pkg/data/vmservice_snapshot.so";
|
|
if (elf_snapshot.Load(nullptr, snapshot_path)) {
|
|
vmservice_data = elf_snapshot.IsolateData();
|
|
vmservice_instructions = elf_snapshot.IsolateInstrs();
|
|
if (vmservice_data == nullptr || vmservice_instructions == nullptr) {
|
|
return nullptr;
|
|
}
|
|
} else {
|
|
// The VM service was compiled as a separate app.
|
|
const char* snapshot_data_path =
|
|
"pkg/data/vmservice_isolate_snapshot_data.bin";
|
|
const char* snapshot_instructions_path =
|
|
"pkg/data/vmservice_isolate_snapshot_instructions.bin";
|
|
#else
|
|
// The VM service is embedded in the core snapshot.
|
|
const char* snapshot_data_path = "pkg/data/isolate_core_snapshot_data.bin";
|
|
const char* snapshot_instructions_path =
|
|
"pkg/data/isolate_core_snapshot_instructions.bin";
|
|
#endif
|
|
|
|
if (!dart_utils::MappedResource::LoadFromNamespace(
|
|
nullptr, snapshot_data_path, mapped_isolate_snapshot_data)) {
|
|
*error = strdup("Failed to load snapshot for service isolate");
|
|
FX_LOG(ERROR, LOG_TAG, *error);
|
|
return nullptr;
|
|
}
|
|
if (!dart_utils::MappedResource::LoadFromNamespace(
|
|
nullptr, snapshot_instructions_path,
|
|
mapped_isolate_snapshot_instructions, true /* executable */)) {
|
|
*error = strdup("Failed to load snapshot for service isolate");
|
|
FX_LOG(ERROR, LOG_TAG, *error);
|
|
return nullptr;
|
|
}
|
|
|
|
vmservice_data = mapped_isolate_snapshot_data.address();
|
|
vmservice_instructions = mapped_isolate_snapshot_instructions.address();
|
|
#if defined(AOT_RUNTIME)
|
|
}
|
|
#endif
|
|
|
|
auto state = new std::shared_ptr<tonic::DartState>(new tonic::DartState());
|
|
Dart_Isolate isolate = Dart_CreateIsolateGroup(
|
|
uri, DART_VM_SERVICE_ISOLATE_NAME, vmservice_data, vmservice_instructions,
|
|
nullptr /* flags */, state, state, error);
|
|
if (!isolate) {
|
|
FX_LOGF(ERROR, LOG_TAG, "Dart_CreateIsolateGroup failed: %s", *error);
|
|
return nullptr;
|
|
}
|
|
|
|
state->get()->SetIsolate(isolate);
|
|
|
|
// Setup native entries.
|
|
service_natives = new tonic::DartLibraryNatives();
|
|
service_natives->Register({
|
|
{"VMServiceIO_NotifyServerState", NotifyServerState, 1, true},
|
|
{"VMServiceIO_Shutdown", Shutdown, 0, true},
|
|
});
|
|
|
|
Dart_EnterScope();
|
|
|
|
Dart_Handle library =
|
|
Dart_LookupLibrary(Dart_NewStringFromCString("dart:vmservice_io"));
|
|
SHUTDOWN_ON_ERROR(library);
|
|
Dart_Handle result = Dart_SetRootLibrary(library);
|
|
SHUTDOWN_ON_ERROR(result);
|
|
result = Dart_SetNativeResolver(library, GetNativeFunction, GetSymbol);
|
|
SHUTDOWN_ON_ERROR(result);
|
|
|
|
// _ip = '127.0.0.1'
|
|
result = Dart_SetField(library, Dart_NewStringFromCString("_ip"),
|
|
Dart_NewStringFromCString("127.0.0.1"));
|
|
SHUTDOWN_ON_ERROR(result);
|
|
|
|
// _port = 0
|
|
result = Dart_SetField(library, Dart_NewStringFromCString("_port"),
|
|
Dart_NewInteger(0));
|
|
SHUTDOWN_ON_ERROR(result);
|
|
|
|
// _autoStart = true
|
|
result = Dart_SetField(library, Dart_NewStringFromCString("_autoStart"),
|
|
Dart_NewBoolean(true));
|
|
SHUTDOWN_ON_ERROR(result);
|
|
|
|
// _originCheckDisabled = false
|
|
result =
|
|
Dart_SetField(library, Dart_NewStringFromCString("_originCheckDisabled"),
|
|
Dart_NewBoolean(false));
|
|
SHUTDOWN_ON_ERROR(result);
|
|
|
|
// _authCodesDisabled = false
|
|
result =
|
|
Dart_SetField(library, Dart_NewStringFromCString("_authCodesDisabled"),
|
|
Dart_NewBoolean(false));
|
|
SHUTDOWN_ON_ERROR(result);
|
|
|
|
InitBuiltinLibrariesForIsolate(std::string(uri), nullptr, fileno(stdout),
|
|
fileno(stderr), nullptr, zx::channel(), true);
|
|
|
|
// Make runnable.
|
|
Dart_ExitScope();
|
|
Dart_ExitIsolate();
|
|
*error = Dart_IsolateMakeRunnable(isolate);
|
|
if (*error != nullptr) {
|
|
FX_LOG(ERROR, LOG_TAG, *error);
|
|
Dart_EnterIsolate(isolate);
|
|
Dart_ShutdownIsolate();
|
|
return nullptr;
|
|
}
|
|
return isolate;
|
|
} // namespace dart_runner
|
|
|
|
Dart_Handle GetVMServiceAssetsArchiveCallback() {
|
|
dart_utils::MappedResource observatory_tar;
|
|
if (!dart_utils::MappedResource::LoadFromNamespace(
|
|
nullptr, "pkg/data/observatory.tar", observatory_tar)) {
|
|
FX_LOG(ERROR, LOG_TAG, "Failed to load Observatory assets");
|
|
return nullptr;
|
|
}
|
|
// TODO(rmacnak): Should we avoid copying the tar? Or does the service
|
|
// library not hold onto it anyway?
|
|
return tonic::DartConverter<tonic::Uint8List>::ToDart(
|
|
reinterpret_cast<const uint8_t*>(observatory_tar.address()),
|
|
observatory_tar.size());
|
|
}
|
|
|
|
} // namespace dart_runner
|