未验证 提交 96ffc893 编写于 作者: C Chinmay Garde 提交者: GitHub

Copy the Dart Runner from //topaz into the engine. (#8949)

上级 c83ec26f
......@@ -29,7 +29,7 @@ group("flutter") {
}
if (is_fuchsia && using_fuchsia_sdk) {
public_deps += [ "$flutter_root/shell/platform/fuchsia/flutter" ]
public_deps += [ "$flutter_root/shell/platform/fuchsia" ]
}
if (!is_fuchsia && !is_fuchsia_host) {
......
......@@ -785,6 +785,54 @@ FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon/sdk_ext/natives.cc
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon/sdk_ext/natives.h
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon/sdk_ext/system.cc
FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon/sdk_ext/system.h
FILE: ../../../flutter/shell/platform/fuchsia/dart/builtin_libraries.cc
FILE: ../../../flutter/shell/platform/fuchsia/dart/builtin_libraries.h
FILE: ../../../flutter/shell/platform/fuchsia/dart/dart_component_controller.cc
FILE: ../../../flutter/shell/platform/fuchsia/dart/dart_component_controller.h
FILE: ../../../flutter/shell/platform/fuchsia/dart/dart_runner.cc
FILE: ../../../flutter/shell/platform/fuchsia/dart/dart_runner.h
FILE: ../../../flutter/shell/platform/fuchsia/dart/embedder/builtin.dart
FILE: ../../../flutter/shell/platform/fuchsia/dart/embedder/script_runner_snapshot.dart
FILE: ../../../flutter/shell/platform/fuchsia/dart/embedder/shim.dart
FILE: ../../../flutter/shell/platform/fuchsia/dart/embedder/snapshot.cc.tmpl
FILE: ../../../flutter/shell/platform/fuchsia/dart/embedder/snapshot.dart
FILE: ../../../flutter/shell/platform/fuchsia/dart/embedder/snapshot.h
FILE: ../../../flutter/shell/platform/fuchsia/dart/examples/goodbye_dart/goodbye_dart.dart
FILE: ../../../flutter/shell/platform/fuchsia/dart/examples/goodbye_dart/goodbye_dart_test
FILE: ../../../flutter/shell/platform/fuchsia/dart/examples/goodbye_dart/meta/goodbye_dart_aot.cmx
FILE: ../../../flutter/shell/platform/fuchsia/dart/examples/goodbye_dart/meta/goodbye_dart_jit.cmx
FILE: ../../../flutter/shell/platform/fuchsia/dart/examples/greeting/greeting.dart
FILE: ../../../flutter/shell/platform/fuchsia/dart/examples/hello_app_dart/interfaces/hello.fidl
FILE: ../../../flutter/shell/platform/fuchsia/dart/examples/hello_app_dart/main.dart
FILE: ../../../flutter/shell/platform/fuchsia/dart/examples/hello_app_dart/meta/hello_app_dart_aot.cmx
FILE: ../../../flutter/shell/platform/fuchsia/dart/examples/hello_app_dart/meta/hello_app_dart_jit.cmx
FILE: ../../../flutter/shell/platform/fuchsia/dart/examples/hello_dart/bin/hello_dart.dart
FILE: ../../../flutter/shell/platform/fuchsia/dart/examples/hello_dart/meta/hello_dart_aot.cmx
FILE: ../../../flutter/shell/platform/fuchsia/dart/examples/hello_dart/meta/hello_dart_aot_product.cmx
FILE: ../../../flutter/shell/platform/fuchsia/dart/examples/hello_dart/meta/hello_dart_debug.cmx
FILE: ../../../flutter/shell/platform/fuchsia/dart/examples/hello_dart/meta/hello_dart_jit.cmx
FILE: ../../../flutter/shell/platform/fuchsia/dart/examples/hello_dart/meta/hello_dart_jit_product.cmx
FILE: ../../../flutter/shell/platform/fuchsia/dart/integration/main.dart
FILE: ../../../flutter/shell/platform/fuchsia/dart/integration/meta/dart_aot_runner_test.cmx
FILE: ../../../flutter/shell/platform/fuchsia/dart/integration/meta/dart_jit_runner_test.cmx
FILE: ../../../flutter/shell/platform/fuchsia/dart/kernel/libraries.json
FILE: ../../../flutter/shell/platform/fuchsia/dart/logging.h
FILE: ../../../flutter/shell/platform/fuchsia/dart/main.cc
FILE: ../../../flutter/shell/platform/fuchsia/dart/mapped_resource.cc
FILE: ../../../flutter/shell/platform/fuchsia/dart/mapped_resource.h
FILE: ../../../flutter/shell/platform/fuchsia/dart/meta/aot_product_runtime
FILE: ../../../flutter/shell/platform/fuchsia/dart/meta/aot_runtime
FILE: ../../../flutter/shell/platform/fuchsia/dart/meta/dart_aot_product_runner.cmx
FILE: ../../../flutter/shell/platform/fuchsia/dart/meta/dart_aot_runner.cmx
FILE: ../../../flutter/shell/platform/fuchsia/dart/meta/dart_jit_product_runner.cmx
FILE: ../../../flutter/shell/platform/fuchsia/dart/meta/dart_jit_runner.cmx
FILE: ../../../flutter/shell/platform/fuchsia/dart/meta/dart_zircon_test.cmx
FILE: ../../../flutter/shell/platform/fuchsia/dart/meta/jit_product_runtime
FILE: ../../../flutter/shell/platform/fuchsia/dart/meta/jit_runtime
FILE: ../../../flutter/shell/platform/fuchsia/dart/service_isolate.cc
FILE: ../../../flutter/shell/platform/fuchsia/dart/service_isolate.h
FILE: ../../../flutter/shell/platform/fuchsia/dart/vmservice/empty.dart
FILE: ../../../flutter/shell/platform/fuchsia/dart/vmservice/meta/vmservice.cmx
FILE: ../../../flutter/shell/platform/fuchsia/flutter/collect_traces.dart
FILE: ../../../flutter/shell/platform/fuchsia/flutter/component.cc
FILE: ../../../flutter/shell/platform/fuchsia/flutter/component.h
......
......@@ -27,10 +27,9 @@ group("platform") {
"windows",
]
} else if (is_fuchsia) {
# Fuchsia has its own runner implementation.
if (using_fuchsia_sdk) {
deps = [
"fuchsia/flutter",
"fuchsia",
]
}
} else {
......
# 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.
import("//build/fuchsia/sdk.gni")
if (using_fuchsia_sdk) {
group("fuchsia") {
deps = [
"dart",
"flutter",
]
}
}
# 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.
assert(is_fuchsia)
import("//build/fuchsia/sdk.gni")
if (using_fuchsia_sdk) {
import("//flutter/common/config.gni")
group("dart_io_api") {
visibility = [ ":*" ]
public_deps = []
if (flutter_runtime_mode == "debug") {
public_deps += [ "//third_party/dart/runtime/bin:dart_io_api" ]
} else {
public_deps += [ "//third_party/dart/runtime/bin:dart_io_api_product" ]
}
}
executable("dart") {
output_name = "dt_rush"
public = []
sources = [
"builtin_libraries.cc",
"builtin_libraries.h",
"dart_component_controller.cc",
"dart_component_controller.h",
"dart_runner.cc",
"dart_runner.h",
"logging.h",
"main.cc",
"mapped_resource.cc",
"mapped_resource.h",
"service_isolate.cc",
"service_isolate.h",
]
deps = [
":dart_io_api",
"$flutter_root/common",
"$flutter_root/fml",
"$flutter_root/runtime:libdart",
"$flutter_root/shell/platform/fuchsia/dart-pkg/fuchsia",
"$flutter_root/shell/platform/fuchsia/dart-pkg/zircon",
"$flutter_root/shell/platform/fuchsia/runtime/dart/utils",
"$fuchsia_sdk_root/pkg:async-cpp",
"$fuchsia_sdk_root/pkg:async-loop",
"$fuchsia_sdk_root/pkg:async-loop-cpp",
"$fuchsia_sdk_root/pkg:fidl_cpp",
"$fuchsia_sdk_root/pkg:syslog",
"$fuchsia_sdk_root/pkg/lib/sys/cpp",
"$fuchsia_sdk_root/pkg/lib/vfs/cpp",
"//third_party/tonic",
]
}
}
# Dart Application Runner
An Runner that runs Dart programs.
// 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 "builtin_libraries.h"
#include <lib/fdio/namespace.h>
#include <lib/zx/channel.h>
#include "dart-pkg/fuchsia/sdk_ext/fuchsia.h"
#include "flutter/fml/logging.h"
#include "runtime/dart/utils/inlines.h"
#include "third_party/dart/runtime/bin/io_natives.h"
#include "third_party/dart/runtime/include/dart_api.h"
#include "third_party/tonic/converter/dart_converter.h"
#include "third_party/tonic/dart_microtask_queue.h"
#include "third_party/tonic/logging/dart_error.h"
#include "logging.h"
using tonic::ToDart;
namespace dart_runner {
namespace {
#define REGISTER_FUNCTION(name, count) {#name, name, count},
#define DECLARE_FUNCTION(name, count) \
extern void name(Dart_NativeArguments args);
#define BUILTIN_NATIVE_LIST(V) \
V(Logger_PrintString, 1) \
V(ScheduleMicrotask, 1)
BUILTIN_NATIVE_LIST(DECLARE_FUNCTION);
const struct NativeEntry {
const char* name;
Dart_NativeFunction function;
int argument_count;
} kBuiltinEntries[] = {BUILTIN_NATIVE_LIST(REGISTER_FUNCTION)};
Dart_NativeFunction BuiltinNativeLookup(Dart_Handle name,
int argument_count,
bool* auto_setup_scope) {
const char* function_name = nullptr;
Dart_Handle result = Dart_StringToCString(name, &function_name);
if (Dart_IsError(result)) {
Dart_PropagateError(result);
}
FML_DCHECK(function_name != nullptr);
FML_DCHECK(auto_setup_scope != nullptr);
*auto_setup_scope = true;
size_t num_entries = dart_utils::ArraySize(kBuiltinEntries);
for (size_t i = 0; i < num_entries; i++) {
const NativeEntry& entry = kBuiltinEntries[i];
if (!strcmp(function_name, entry.name) &&
(entry.argument_count == argument_count)) {
return entry.function;
}
}
return nullptr;
}
const uint8_t* BuiltinNativeSymbol(Dart_NativeFunction native_function) {
size_t num_entries = dart_utils::ArraySize(kBuiltinEntries);
for (size_t i = 0; i < num_entries; i++) {
const NativeEntry& entry = kBuiltinEntries[i];
if (entry.function == native_function)
return reinterpret_cast<const uint8_t*>(entry.name);
}
return nullptr;
}
void Logger_PrintString(Dart_NativeArguments args) {
intptr_t length = 0;
uint8_t* chars = nullptr;
Dart_Handle str = Dart_GetNativeArgument(args, 0);
Dart_Handle result = Dart_StringToUTF8(str, &chars, &length);
if (Dart_IsError(result)) {
Dart_PropagateError(result);
} else {
fwrite(chars, 1, length, stdout);
fputc('\n', stdout);
fflush(stdout);
}
}
void ScheduleMicrotask(Dart_NativeArguments args) {
Dart_Handle closure = Dart_GetNativeArgument(args, 0);
if (tonic::LogIfError(closure) || !Dart_IsClosure(closure))
return;
tonic::DartMicrotaskQueue::GetForCurrentThread()->ScheduleMicrotask(closure);
}
} // namespace
void InitBuiltinLibrariesForIsolate(
const std::string& script_uri,
fdio_ns_t* namespc,
int stdoutfd,
int stderrfd,
fidl::InterfaceHandle<fuchsia::sys::Environment> environment,
zx::channel directory_request,
bool service_isolate) {
// dart:fuchsia --------------------------------------------------------------
if (!service_isolate) {
fuchsia::dart::Initialize(std::move(environment),
std::move(directory_request));
}
// dart:fuchsia.builtin ------------------------------------------------------
Dart_Handle builtin_lib = Dart_LookupLibrary(ToDart("dart:fuchsia.builtin"));
FML_CHECK(!tonic::LogIfError(builtin_lib));
Dart_Handle result = Dart_SetNativeResolver(builtin_lib, BuiltinNativeLookup,
BuiltinNativeSymbol);
FML_CHECK(!tonic::LogIfError(result));
// dart:io -------------------------------------------------------------------
Dart_Handle io_lib = Dart_LookupLibrary(ToDart("dart:io"));
FML_CHECK(!tonic::LogIfError(io_lib));
result = Dart_SetNativeResolver(io_lib, dart::bin::IONativeLookup,
dart::bin::IONativeSymbol);
FML_CHECK(!tonic::LogIfError(result));
// dart:zircon ---------------------------------------------------------------
Dart_Handle zircon_lib = Dart_LookupLibrary(ToDart("dart:zircon"));
FML_CHECK(!tonic::LogIfError(zircon_lib));
// NativeResolver already set by fuchsia::dart::Initialize().
// Core libraries ------------------------------------------------------------
Dart_Handle async_lib = Dart_LookupLibrary(ToDart("dart:async"));
FML_CHECK(!tonic::LogIfError(async_lib));
Dart_Handle core_lib = Dart_LookupLibrary(ToDart("dart:core"));
FML_CHECK(!tonic::LogIfError(core_lib));
Dart_Handle internal_lib = Dart_LookupLibrary(ToDart("dart:_internal"));
FML_CHECK(!tonic::LogIfError(internal_lib));
Dart_Handle isolate_lib = Dart_LookupLibrary(ToDart("dart:isolate"));
FML_CHECK(!tonic::LogIfError(isolate_lib));
#if !defined(AOT_RUNTIME)
// AOT: These steps already happened at compile time in gen_snapshot.
// 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.
result = Dart_FinalizeLoading(false);
FML_CHECK(!tonic::LogIfError(result));
#endif
// Setup the internal library's 'internalPrint' function.
Dart_Handle print =
Dart_Invoke(builtin_lib, ToDart("_getPrintClosure"), 0, nullptr);
FML_CHECK(!tonic::LogIfError(print));
result = Dart_SetField(internal_lib, ToDart("_printClosure"), print);
FML_CHECK(!tonic::LogIfError(result));
// Set up the 'scheduleImmediate' closure.
Dart_Handle schedule_immediate_closure;
if (service_isolate) {
// Running on dart::ThreadPool.
schedule_immediate_closure = Dart_Invoke(
isolate_lib, ToDart("_getIsolateScheduleImmediateClosure"), 0, nullptr);
} else {
// Running on async::Loop.
schedule_immediate_closure = Dart_Invoke(
builtin_lib, ToDart("_getScheduleMicrotaskClosure"), 0, nullptr);
}
FML_CHECK(!tonic::LogIfError(schedule_immediate_closure));
Dart_Handle schedule_args[1];
schedule_args[0] = schedule_immediate_closure;
result = Dart_Invoke(async_lib, ToDart("_setScheduleImmediateClosure"), 1,
schedule_args);
FML_CHECK(!tonic::LogIfError(result));
// Set up the namespace in dart:io.
Dart_Handle namespace_type =
Dart_GetType(io_lib, ToDart("_Namespace"), 0, nullptr);
FML_CHECK(!tonic::LogIfError(namespace_type));
Dart_Handle namespace_args[1];
namespace_args[0] = ToDart(reinterpret_cast<intptr_t>(namespc));
result =
Dart_Invoke(namespace_type, ToDart("_setupNamespace"), 1, namespace_args);
FML_CHECK(!tonic::LogIfError(result));
// Set up the namespace in dart:zircon.
namespace_type = Dart_GetType(zircon_lib, ToDart("_Namespace"), 0, nullptr);
FML_CHECK(!tonic::LogIfError(namespace_type));
result = Dart_SetField(namespace_type, ToDart("_namespace"),
ToDart(reinterpret_cast<intptr_t>(namespc)));
FML_CHECK(!tonic::LogIfError(result));
// Set up stdout and stderr.
Dart_Handle stdio_args[3];
stdio_args[0] = Dart_NewInteger(0);
stdio_args[1] = Dart_NewInteger(stdoutfd);
stdio_args[2] = Dart_NewInteger(stderrfd);
result = Dart_Invoke(io_lib, ToDart("_setStdioFDs"), 3, stdio_args);
FML_CHECK(!tonic::LogIfError(result));
// Disable some dart:io operations.
Dart_Handle embedder_config_type =
Dart_GetType(io_lib, ToDart("_EmbedderConfig"), 0, nullptr);
FML_CHECK(!tonic::LogIfError(embedder_config_type));
result =
Dart_SetField(embedder_config_type, ToDart("_mayExit"), Dart_False());
FML_CHECK(!tonic::LogIfError(result));
// Set the script location.
result = Dart_SetField(builtin_lib, ToDart("_rawScript"), ToDart(script_uri));
FML_CHECK(!tonic::LogIfError(result));
// Setup the uriBase with the base uri of the fidl app.
Dart_Handle uri_base =
Dart_Invoke(io_lib, ToDart("_getUriBaseClosure"), 0, nullptr);
FML_CHECK(!tonic::LogIfError(uri_base));
result = Dart_SetField(core_lib, ToDart("_uriBaseClosure"), uri_base);
FML_CHECK(!tonic::LogIfError(result));
Dart_Handle setup_hooks = ToDart("_setupHooks");
result = Dart_Invoke(builtin_lib, setup_hooks, 0, nullptr);
FML_CHECK(!tonic::LogIfError(result));
result = Dart_Invoke(io_lib, setup_hooks, 0, nullptr);
FML_CHECK(!tonic::LogIfError(result));
result = Dart_Invoke(isolate_lib, setup_hooks, 0, nullptr);
FML_CHECK(!tonic::LogIfError(result));
}
} // namespace dart_runner
// 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.
#ifndef TOPAZ_RUNTIME_DART_RUNNER_BUILTIN_LIBRARIES_H_
#define TOPAZ_RUNTIME_DART_RUNNER_BUILTIN_LIBRARIES_H_
#include <memory>
#include <string>
#include <lib/fdio/namespace.h>
#include <fuchsia/sys/cpp/fidl.h>
namespace dart_runner {
void InitBuiltinLibrariesForIsolate(
const std::string& script_uri,
fdio_ns_t* namespc,
int stdoutfd,
int stderrfd,
fidl::InterfaceHandle<fuchsia::sys::Environment> environment,
zx::channel directory_request,
bool service_isolate);
} // namespace dart_runner
#endif // TOPAZ_RUNTIME_DART_RUNNER_BUILTIN_LIBRARIES_H_
# 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.
import("//build/package.gni")
import("//build/tools/json_merge/json_merge.gni")
import("//third_party/dart/build/dart/dart_action.gni")
import("//topaz/runtime/dart/config.gni")
import("//topaz/runtime/dart/dart_component.gni")
import("//topaz/runtime/dart/dart_kernel.gni")
# Defines JIT runtime components to be further distributed in one package.
#
# Takes a set of dart components and puts them into one fuchsia package with
# the dart_jit_runner as its runtime. Also supports legacy calls where the
# components parameter isn't specified, in which we will create one default
# component for the package.
#
# Parameters
#
# components (required)
# [list of scopes] Defines the components in the package. Either main_dart
# or components must be defined, but not both.
#
# Entries in a scope in the resources list:
#
# component_name (required)
# Name of the component.
#
# main_dart (required)
# File containing the main function of the component.
#
# dart_package_name (optional)
# Name of the dart package for the component. If not provided, it will
# be inferred from the component name.
#
# package_root (optional)
# Path to the dart package for the component. If not provided, it will
# be assumed as ".".
#
# sources (optional)
# Relative path of source files to be included in the dart package for
# the component at $package_root/lib.
#
# main_dart (required)
# File containing the main function of the application. Either main_dart or
# components must be defined, but not both.
#
# package_name (optional)
# Name of the Dart package. This is used as an identifier in code that
# depends on the dart library that the *one and only* component generates.
# Only compatible when components is not specified (use
# components.dart_package_name).
#
template("_dart_jit_component") {
legacy_component = false
pkg_name = target_name
if (!defined(invoker.components)) {
# If components is not specified, we are fitting main_dart into a component
# scope, and using that for the package.
#
# TODO(CP-141): Remove support for legacy_component once all existing calls
# to dart_app() have a components parameter.
legacy_component = true
if (defined(invoker.fuchsia_package_name)) {
legacy_component_name = invoker.fuchsia_package_name
} else {
legacy_component_name = target_name
}
pkg_name = legacy_component_name
pkg_sources = []
if (defined(invoker.sources)) {
pkg_sources = invoker.sources
}
components = [
{
main_dart = invoker.main_dart
component_name = legacy_component_name
component_type = "dart"
package_root = "."
deps = invoker.deps
sources = pkg_sources
},
]
}
flutter_dart_jit_component(target_name) {
forward_variables_from(invoker, "*")
}
}
# Defines AOT runtime components to be further distributed in one package.
#
# Takes a set of dart components and puts them into one fuchsia package with
# the dart_aot_runner as its runtime. Also supports legacy calls where the
# components parameter isn't specified, in which we will create one default
# component for the package.
#
# Parameters
#
# components (required)
# [list of scopes] Defines the components in the package. Either main_dart
# or components must be defined, but not both.
#
# Entries in a scope in the resources list:
#
# component_name (required)
# Name of the component.
#
# main_dart (required)
# File containing the main function of the component.
#
# dart_package_name (optional)
# Name of the dart package for the component. If not provided, it will
# be inferred from the component name.
#
# package_root (optional)
# Path to the dart package for the component. If not provided, it will
# be assumed as ".".
#
# sources (optional)
# Relative path of source files to be included in the dart package for
# the component at $package_root/lib.
#
# main_dart (required)
# File containing the main function of the application. Either main_dart or
# components must be defined, but not both.
#
# package_name (optional)
# Name of the Dart package. This is used as an identifier in code that
# depends on the dart library that the *one and only* component generates.
# Only compatible when components is not specified (use
# components.dart_package_name).
#
template("_dart_aot_component") {
legacy_component = false
pkg_name = target_name
if (!defined(invoker.components)) {
# If components is not specified, we are fitting main_dart into a component
# scope, and using that for the package.
#
# TODO(CP-141): Remove support for legacy_component once all existing calls
# to dart_app() have a components parameter.
legacy_component = true
if (defined(invoker.fuchsia_package_name)) {
legacy_component_name = invoker.fuchsia_package_name
} else {
legacy_component_name = target_name
}
pkg_name = legacy_component_name
pkg_sources = []
if (defined(invoker.sources)) {
pkg_sources = invoker.sources
}
components = [
{
main_dart = invoker.main_dart
component_name = legacy_component_name
component_type = "dart"
package_root = "."
deps = invoker.deps
sources = pkg_sources
},
]
}
flutter_dart_aot_component(target_name) {
forward_variables_from(invoker, "*")
}
}
template("dart_jit_app") {
template_name = "_dart_jit_component"
if (dart_force_product) {
template_name = dart_product_app
}
target(template_name, target_name) {
forward_variables_from(invoker, "*")
}
}
template("dart_aot_app") {
template_name = "_dart_aot_component"
if (dart_force_product) {
template_name = dart_product_app
}
target(template_name, target_name) {
forward_variables_from(invoker, "*")
}
}
# Defines a Dart application that can be run in the Dart content handler
#
# Parameters
#
# main_dart (required)
# Name of the Dart file containing the main function. Either main_dart or
# components must be defined, but not both.
#
# package_name (optional)
# Name of the Dart package.
#
# fuchsia_package_name (optional)
# Name of the Fuchsia package.
#
# deps (optional)
# List of Dart packages the application depends on.
#
# disable_analysis (optional)
# Prevents analysis from being run on this target.
#
# product (optional)
# A boolean. Whether to build/run the app in a stripped-down Dart VM.
# Defaults to !is_debug.
#
# resources (optional)
# Resources for the package (see //build/package.gni)
#
# tests (optional)
# List of tests forwarded for the package. See the definition in //build/package.gni.
#
# components (required)
# [list of scopes] Defines the components in the package. Either main_dart
# or components must be defined, but not both.
#
# Entries in a scope in the resources list:
#
# component_name (required)
# Name of the component.
#
# main_dart (required)
# File containing the main function of the component.
#
# package_root (optional)
# Path to the dart package for the component. If not provided, it will
# be assumed as ".".
#
# sources (optional)
# Relative path of source files to be included in the dart package for
# the component at $package_root/lib.
#
template("dart_app") {
assert((defined(invoker.components) && !defined(invoker.main_dart)) ||
(!defined(invoker.components) && defined(invoker.main_dart)),
"Only one of components or main_dart should be defined")
target(dart_default_app, target_name) {
forward_variables_from(invoker, "*")
}
}
// 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 "dart_component_controller.h"
#include <fcntl.h>
#include <lib/async-loop/loop.h>
#include <lib/async/cpp/task.h>
#include <lib/async/default.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/namespace.h>
#include <lib/fidl/cpp/optional.h>
#include <lib/fidl/cpp/string.h>
#include <lib/sys/cpp/service_directory.h>
#include <lib/syslog/global.h>
#include <lib/zx/thread.h>
#include <lib/zx/time.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <zircon/status.h>
#include <regex>
#include <utility>
#include "runtime/dart/utils/handle_exception.h"
#include "runtime/dart/utils/inlines.h"
#include "runtime/dart/utils/tempfs.h"
#include "third_party/dart/runtime/include/dart_tools_api.h"
#include "third_party/tonic/converter/dart_converter.h"
#include "third_party/tonic/dart_message_handler.h"
#include "third_party/tonic/dart_microtask_queue.h"
#include "third_party/tonic/dart_state.h"
#include "third_party/tonic/logging/dart_error.h"
#include "builtin_libraries.h"
#include "logging.h"
using tonic::ToDart;
namespace dart_runner {
constexpr char kDataKey[] = "data";
namespace {
void AfterTask(async_loop_t*, void*) {
tonic::DartMicrotaskQueue* queue =
tonic::DartMicrotaskQueue::GetForCurrentThread();
// Verify that the queue exists, as this method could have been called back as
// part of the exit routine, after the destruction of the microtask queue.
if (queue) {
queue->RunMicrotasks();
}
}
constexpr async_loop_config_t kLoopConfig = {
.make_default_for_current_thread = true,
.epilogue = &AfterTask,
};
// Find the last path component.
// fuchsia-pkg://fuchsia.com/hello_dart#meta/hello_dart.cmx -> hello_dart.cmx
std::string GetLabelFromURL(const std::string& url) {
for (size_t i = url.length() - 1; i > 0; i--) {
if (url[i] == '/') {
return url.substr(i + 1, url.length() - 1);
}
}
return url;
}
} // namespace
DartComponentController::DartComponentController(
fuchsia::sys::Package package,
fuchsia::sys::StartupInfo startup_info,
std::shared_ptr<sys::ServiceDirectory> runner_incoming_services,
fidl::InterfaceRequest<fuchsia::sys::ComponentController> controller)
: loop_(new async::Loop(&kLoopConfig)),
label_(GetLabelFromURL(package.resolved_url)),
url_(std::move(package.resolved_url)),
package_(std::move(package)),
startup_info_(std::move(startup_info)),
runner_incoming_services_(runner_incoming_services),
binding_(this) {
for (size_t i = 0; i < startup_info_.program_metadata->size(); ++i) {
auto pg = startup_info_.program_metadata->at(i);
if (pg.key.compare(kDataKey) == 0) {
data_path_ = "pkg/" + pg.value;
}
}
if (data_path_.empty()) {
FX_LOGF(ERROR, LOG_TAG, "Could not find a /pkg/data directory for %s",
url_.c_str());
return;
}
if (controller.is_valid()) {
binding_.Bind(std::move(controller));
binding_.set_error_handler([this](zx_status_t status) { Kill(); });
}
zx_status_t status =
zx::timer::create(ZX_TIMER_SLACK_LATE, ZX_CLOCK_MONOTONIC, &idle_timer_);
if (status != ZX_OK) {
FX_LOGF(INFO, LOG_TAG, "Idle timer creation failed: %s",
zx_status_get_string(status));
} else {
idle_wait_.set_object(idle_timer_.get());
idle_wait_.set_trigger(ZX_TIMER_SIGNALED);
idle_wait_.Begin(async_get_default_dispatcher());
}
}
DartComponentController::~DartComponentController() {
if (namespace_) {
fdio_ns_destroy(namespace_);
namespace_ = nullptr;
}
close(stdoutfd_);
close(stderrfd_);
}
bool DartComponentController::Setup() {
// Name the thread after the url of the component being launched.
zx::thread::self()->set_property(ZX_PROP_NAME, label_.c_str(), label_.size());
Dart_SetThreadName(label_.c_str());
if (!SetupNamespace()) {
return false;
}
if (SetupFromAppSnapshot()) {
FX_LOGF(INFO, LOG_TAG, "%s is running from an app snapshot", url_.c_str());
} else if (SetupFromKernel()) {
FX_LOGF(INFO, LOG_TAG, "%s is running from kernel", url_.c_str());
} else {
FX_LOGF(ERROR, LOG_TAG,
"Could not find a program in %s. Was data specified"
" correctly in the component manifest?",
url_.c_str());
return false;
}
return true;
}
constexpr char kTmpPath[] = "/tmp";
constexpr char kServiceRootPath[] = "/svc";
bool DartComponentController::SetupNamespace() {
fuchsia::sys::FlatNamespace* flat = &startup_info_.flat_namespace;
zx_status_t status = fdio_ns_create(&namespace_);
if (status != ZX_OK) {
FX_LOG(ERROR, LOG_TAG, "Failed to create namespace");
return false;
}
dart_utils::SetupComponentTemp(namespace_);
for (size_t i = 0; i < flat->paths.size(); ++i) {
if (flat->paths.at(i) == kTmpPath) {
// /tmp is covered by the local memfs.
continue;
}
zx::channel dir;
if (flat->paths.at(i) == kServiceRootPath) {
// clone /svc so component_context can still use it below
dir = zx::channel(fdio_service_clone(flat->directories.at(i).get()));
} else {
dir = std::move(flat->directories.at(i));
}
zx_handle_t dir_handle = dir.release();
const char* path = flat->paths.at(i).data();
status = fdio_ns_bind(namespace_, path, dir_handle);
if (status != ZX_OK) {
FX_LOGF(ERROR, LOG_TAG, "Failed to bind %s to namespace: %s",
flat->paths.at(i).c_str(), zx_status_get_string(status));
zx_handle_close(dir_handle);
return false;
}
}
return true;
}
bool DartComponentController::SetupFromKernel() {
MappedResource manifest;
if (!MappedResource::LoadFromNamespace(
namespace_, data_path_ + "/app.dilplist", manifest)) {
return false;
}
if (!MappedResource::LoadFromNamespace(
nullptr, "pkg/data/isolate_core_snapshot_data.bin",
isolate_snapshot_data_)) {
return false;
}
if (!MappedResource::LoadFromNamespace(
nullptr, "pkg/data/isolate_core_snapshot_instructions.bin",
isolate_snapshot_instructions_, true /* executable */)) {
return false;
}
if (!CreateIsolate(isolate_snapshot_data_.address(),
isolate_snapshot_instructions_.address(), nullptr,
nullptr)) {
return false;
}
Dart_EnterScope();
std::string str(reinterpret_cast<const char*>(manifest.address()),
manifest.size());
Dart_Handle library = Dart_Null();
for (size_t start = 0; start < manifest.size();) {
size_t end = str.find("\n", start);
if (end == std::string::npos) {
FX_LOG(ERROR, LOG_TAG, "Malformed manifest");
Dart_ExitScope();
return false;
}
std::string path = data_path_ + "/" + str.substr(start, end - start);
start = end + 1;
MappedResource kernel;
if (!MappedResource::LoadFromNamespace(namespace_, path, kernel)) {
FX_LOGF(ERROR, LOG_TAG, "Failed to find kernel: %s", path.c_str());
Dart_ExitScope();
return false;
}
library = Dart_LoadLibraryFromKernel(kernel.address(), kernel.size());
if (Dart_IsError(library)) {
FX_LOGF(ERROR, LOG_TAG, "Failed to load kernel: %s",
Dart_GetError(library));
Dart_ExitScope();
return false;
}
kernel_peices_.emplace_back(std::move(kernel));
}
Dart_SetRootLibrary(library);
Dart_Handle result = Dart_FinalizeLoading(false);
if (Dart_IsError(result)) {
FX_LOGF(ERROR, LOG_TAG, "Failed to FinalizeLoading: %s",
Dart_GetError(result));
Dart_ExitScope();
return false;
}
return true;
}
bool DartComponentController::SetupFromAppSnapshot() {
#if !defined(AOT_RUNTIME)
// If we start generating app-jit snapshots, the code below should be able
// handle that case without modification.
return false;
#else
if (!MappedResource::LoadFromNamespace(
namespace_, data_path_ + "/isolate_snapshot_data.bin",
isolate_snapshot_data_)) {
return false;
}
if (!MappedResource::LoadFromNamespace(
namespace_, data_path_ + "/isolate_snapshot_instructions.bin",
isolate_snapshot_instructions_, true /* executable */)) {
return false;
}
if (!MappedResource::LoadFromNamespace(
namespace_, data_path_ + "/shared_snapshot_data.bin",
shared_snapshot_data_)) {
return false;
}
if (!MappedResource::LoadFromNamespace(
namespace_, data_path_ + "/shared_snapshot_instructions.bin",
shared_snapshot_instructions_, true /* executable */)) {
return false;
}
return CreateIsolate(isolate_snapshot_data_.address(),
isolate_snapshot_instructions_.address(),
shared_snapshot_data_.address(),
shared_snapshot_instructions_.address());
#endif // defined(AOT_RUNTIME)
}
int DartComponentController::SetupFileDescriptor(
fuchsia::sys::FileDescriptorPtr fd) {
if (!fd) {
return -1;
}
// fd->handle1 and fd->handle2 are no longer used.
int outfd = -1;
zx_status_t status = fdio_fd_create(fd->handle0.release(), &outfd);
if (status != ZX_OK) {
FX_LOGF(ERROR, LOG_TAG, "Failed to extract output fd: %s",
zx_status_get_string(status));
return -1;
}
return outfd;
}
bool DartComponentController::CreateIsolate(
const uint8_t* isolate_snapshot_data,
const uint8_t* isolate_snapshot_instructions,
const uint8_t* shared_snapshot_data,
const uint8_t* shared_snapshot_instructions) {
// Create the isolate from the snapshot.
char* error = nullptr;
// TODO(dart_runner): Pass if we start using tonic's loader.
intptr_t namespace_fd = -1;
// Freed in IsolateShutdownCallback.
auto state = new std::shared_ptr<tonic::DartState>(new tonic::DartState(
namespace_fd, [this](Dart_Handle result) { MessageEpilogue(result); }));
isolate_ = Dart_CreateIsolate(
url_.c_str(), label_.c_str(), isolate_snapshot_data,
isolate_snapshot_instructions, shared_snapshot_data,
shared_snapshot_instructions, nullptr /* flags */, state, &error);
if (!isolate_) {
FX_LOGF(ERROR, LOG_TAG, "Dart_CreateIsolate failed: %s", error);
return false;
}
state->get()->SetIsolate(isolate_);
tonic::DartMessageHandler::TaskDispatcher dispatcher =
[loop = loop_.get()](auto callback) {
async::PostTask(loop->dispatcher(), std::move(callback));
};
state->get()->message_handler().Initialize(dispatcher);
state->get()->SetReturnCodeCallback(
[this](uint32_t return_code) { return_code_ = return_code; });
return true;
}
void DartComponentController::Run() {
async::PostTask(loop_->dispatcher(), [loop = loop_.get(), app = this] {
if (!app->Main()) {
loop->Quit();
}
});
loop_->Run();
SendReturnCode();
}
bool DartComponentController::Main() {
Dart_EnterScope();
tonic::DartMicrotaskQueue::StartForCurrentThread();
std::vector<std::string> arguments =
std::move(startup_info_.launch_info.arguments);
stdoutfd_ = SetupFileDescriptor(std::move(startup_info_.launch_info.out));
stderrfd_ = SetupFileDescriptor(std::move(startup_info_.launch_info.err));
auto directory_request =
std::move(startup_info_.launch_info.directory_request);
auto* flat = &startup_info_.flat_namespace;
std::unique_ptr<sys::ServiceDirectory> svc;
for (size_t i = 0; i < flat->paths.size(); ++i) {
zx::channel dir;
if (flat->paths.at(i) == kServiceRootPath) {
svc = std::make_unique<sys::ServiceDirectory>(
std::move(flat->directories.at(i)));
break;
}
}
if (!svc) {
FX_LOG(ERROR, LOG_TAG, "Unable to get /svc for dart component");
return false;
}
fidl::InterfaceHandle<fuchsia::sys::Environment> environment;
svc->Connect(environment.NewRequest());
InitBuiltinLibrariesForIsolate(
url_, namespace_, stdoutfd_, stderrfd_, std::move(environment),
std::move(directory_request), false /* service_isolate */);
namespace_ = nullptr;
Dart_ExitScope();
Dart_ExitIsolate();
char* error = Dart_IsolateMakeRunnable(isolate_);
if (error != nullptr) {
Dart_EnterIsolate(isolate_);
Dart_ShutdownIsolate();
FX_LOGF(ERROR, LOG_TAG, "Unable to make isolate runnable: %s", error);
free(error);
return false;
}
Dart_EnterIsolate(isolate_);
Dart_EnterScope();
Dart_Handle dart_arguments =
Dart_NewListOf(Dart_CoreType_String, arguments.size());
if (Dart_IsError(dart_arguments)) {
FX_LOGF(ERROR, LOG_TAG, "Failed to allocate Dart arguments list: %s",
Dart_GetError(dart_arguments));
Dart_ExitScope();
return false;
}
for (size_t i = 0; i < arguments.size(); i++) {
tonic::LogIfError(
Dart_ListSetAt(dart_arguments, i, ToDart(arguments.at(i))));
}
Dart_Handle argv[] = {
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()) {
// The program hasn't set a return code meaning this exit is unexpected.
FX_LOG(ERROR, LOG_TAG, Dart_GetError(main_result));
return_code_ = tonic::GetErrorExitCode(main_result);
dart_utils::HandleIfException(runner_incoming_services_, url_,
main_result);
}
Dart_ExitScope();
return false;
}
Dart_ExitScope();
return true;
}
void DartComponentController::Kill() {
if (Dart_CurrentIsolate()) {
tonic::DartMicrotaskQueue::GetForCurrentThread()->Destroy();
loop_->Quit();
// TODO(rosswang): The docs warn of threading issues if doing this again,
// but without this, attempting to shut down the isolate finalizes app
// contexts that can't tell a shutdown is in progress and so fatal.
Dart_SetMessageNotifyCallback(nullptr);
Dart_ShutdownIsolate();
}
}
void DartComponentController::Detach() {
binding_.set_error_handler([](zx_status_t status) {});
}
void DartComponentController::SendReturnCode() {
binding_.events().OnTerminated(return_code_,
fuchsia::sys::TerminationReason::EXITED);
}
const zx::duration kIdleWaitDuration = zx::sec(2);
const zx::duration kIdleNotifyDuration = zx::msec(500);
const zx::duration kIdleSlack = zx::sec(1);
void DartComponentController::MessageEpilogue(Dart_Handle result) {
auto dart_state = tonic::DartState::Current();
// If the Dart program has set a return code, then it is intending to shut
// down by way of a fatal error, and so there is no need to override
// return_code_.
if (dart_state->has_set_return_code()) {
Dart_ShutdownIsolate();
return;
}
dart_utils::HandleIfException(runner_incoming_services_, url_, result);
// Otherwise, see if there was any other error.
return_code_ = tonic::GetErrorExitCode(result);
if (return_code_ != 0) {
Dart_ShutdownIsolate();
return;
}
idle_start_ = zx::clock::get_monotonic();
zx_status_t status =
idle_timer_.set(idle_start_ + kIdleWaitDuration, kIdleSlack);
if (status != ZX_OK) {
FX_LOGF(INFO, LOG_TAG, "Idle timer set failed: %s",
zx_status_get_string(status));
}
}
void DartComponentController::OnIdleTimer(async_dispatcher_t* dispatcher,
async::WaitBase* wait,
zx_status_t status,
const zx_packet_signal* signal) {
if ((status != ZX_OK) || !(signal->observed & ZX_TIMER_SIGNALED) ||
!Dart_CurrentIsolate()) {
// Timer closed or isolate shutdown.
return;
}
zx::time deadline = idle_start_ + kIdleWaitDuration;
zx::time now = zx::clock::get_monotonic();
if (now >= deadline) {
// No Dart message has been processed for kIdleWaitDuration: assume we'll
// stay idle for kIdleNotifyDuration.
Dart_NotifyIdle((now + kIdleNotifyDuration).get());
idle_start_ = zx::time(0);
idle_timer_.cancel(); // De-assert signal.
} else {
// Early wakeup or message pushed idle time forward: reschedule.
zx_status_t status = idle_timer_.set(deadline, kIdleSlack);
if (status != ZX_OK) {
FX_LOGF(INFO, LOG_TAG, "Idle timer set failed: %s",
zx_status_get_string(status));
}
}
wait->Begin(dispatcher); // ignore errors
}
} // namespace dart_runner
// 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.
#ifndef TOPAZ_RUNTIME_DART_RUNNER_DART_COMPONENT_CONTROLLER_H_
#define TOPAZ_RUNTIME_DART_RUNNER_DART_COMPONENT_CONTROLLER_H_
#include <memory>
#include <fuchsia/sys/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async/cpp/wait.h>
#include <lib/fdio/namespace.h>
#include <lib/sys/cpp/component_context.h>
#include <lib/sys/cpp/service_directory.h>
#include <lib/zx/timer.h>
#include "lib/fidl/cpp/binding.h"
#include "mapped_resource.h"
#include "third_party/dart/runtime/include/dart_api.h"
namespace dart_runner {
class DartComponentController : public fuchsia::sys::ComponentController {
public:
DartComponentController(
fuchsia::sys::Package package,
fuchsia::sys::StartupInfo startup_info,
std::shared_ptr<sys::ServiceDirectory> runner_incoming_services,
fidl::InterfaceRequest<fuchsia::sys::ComponentController> controller);
~DartComponentController() override;
bool Setup();
void Run();
bool Main();
void SendReturnCode();
private:
bool SetupNamespace();
bool SetupFromKernel();
bool SetupFromAppSnapshot();
bool CreateIsolate(const uint8_t* isolate_snapshot_data,
const uint8_t* isolate_snapshot_instructions,
const uint8_t* shared_snapshot_data,
const uint8_t* shared_snapshot_instructions);
int SetupFileDescriptor(fuchsia::sys::FileDescriptorPtr fd);
// |ComponentController|
void Kill() override;
void Detach() override;
// Idle notification.
void MessageEpilogue(Dart_Handle result);
void OnIdleTimer(async_dispatcher_t* dispatcher,
async::WaitBase* wait,
zx_status_t status,
const zx_packet_signal* signal);
// The loop must be the first declared member so that it gets destroyed after
// binding_ which expects the existence of a loop.
std::unique_ptr<async::Loop> loop_;
std::string label_;
std::string url_;
fuchsia::sys::Package package_;
fuchsia::sys::StartupInfo startup_info_;
std::shared_ptr<sys::ServiceDirectory> runner_incoming_services_;
std::string data_path_;
fidl::Binding<fuchsia::sys::ComponentController> binding_;
std::unique_ptr<sys::ComponentContext> context_;
fdio_ns_t* namespace_ = nullptr;
int stdoutfd_ = -1;
int stderrfd_ = -1;
MappedResource isolate_snapshot_data_;
MappedResource isolate_snapshot_instructions_;
MappedResource shared_snapshot_data_;
MappedResource shared_snapshot_instructions_;
std::vector<MappedResource> kernel_peices_;
Dart_Isolate isolate_;
int32_t return_code_ = 0;
zx::time idle_start_{0};
zx::timer idle_timer_;
async::WaitMethod<DartComponentController,
&DartComponentController::OnIdleTimer>
idle_wait_{this};
// Disallow copy and assignment.
DartComponentController(const DartComponentController&) = delete;
DartComponentController& operator=(const DartComponentController&) = delete;
};
} // namespace dart_runner
#endif // TOPAZ_RUNTIME_DART_RUNNER_DART_COMPONENT_CONTROLLER_H_
// 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 "dart_runner.h"
#include <errno.h>
#include <lib/async-loop/loop.h>
#include <lib/async/default.h>
#include <lib/syslog/global.h>
#include <sys/stat.h>
#include <zircon/status.h>
#include <zircon/syscalls.h>
#include <memory>
#include <thread>
#include <utility>
#include "dart_component_controller.h"
#include "flutter/fml/trace_event.h"
#include "logging.h"
#include "runtime/dart/utils/inlines.h"
#include "runtime/dart/utils/vmservice_object.h"
#include "service_isolate.h"
#include "third_party/dart/runtime/include/bin/dart_io_api.h"
#include "third_party/tonic/dart_microtask_queue.h"
#include "third_party/tonic/dart_state.h"
#if defined(AOT_RUNTIME)
extern "C" uint8_t _kDartVmSnapshotData[];
extern "C" uint8_t _kDartVmSnapshotInstructions[];
#endif
namespace dart_runner {
namespace {
const char* kDartVMArgs[] = {
// clang-format off
// TODO(FL-117): Re-enable causal async stack traces when this issue is
// addressed.
"--no_causal_async_stacks",
"--systrace_timeline",
"--timeline_streams=Compiler,Dart,Debugger,Embedder,GC,Isolate,VM",
#if defined(AOT_RUNTIME)
"--precompilation",
#else
"--enable_mirrors=false",
// The interpreter is enabled unconditionally. If an app is built for
// debugging (that is, with no bytecode), the VM will fall back on ASTs.
"--enable_interpreter",
#endif
// No asserts in debug or release product.
// No asserts in release with flutter_profile=true (non-product)
// Yes asserts in non-product debug.
#if !defined(DART_PRODUCT) && (!defined(FLUTTER_PROFILE) || !defined(NDEBUG))
"--enable_asserts",
#endif
// clang-format on
};
Dart_Isolate IsolateCreateCallback(const char* uri,
const char* name,
const char* package_root,
const char* package_config,
Dart_IsolateFlags* flags,
void* callback_data,
char** error) {
if (std::string(uri) == DART_VM_SERVICE_ISOLATE_NAME) {
#if defined(DART_PRODUCT)
*error = strdup("The service isolate is not implemented in product mode");
return NULL;
#else
return CreateServiceIsolate(uri, flags, error);
#endif
}
*error = strdup("Isolate spawning is not implemented in dart_runner");
return NULL;
}
void IsolateShutdownCallback(void* callback_data) {
// The service isolate (and maybe later the kernel isolate) doesn't have an
// async loop.
auto dispatcher = async_get_default_dispatcher();
auto loop = async_loop_from_dispatcher(dispatcher);
if (loop) {
tonic::DartMicrotaskQueue::GetForCurrentThread()->Destroy();
async_loop_quit(loop);
}
}
void IsolateCleanupCallback(void* callback_data) {
delete static_cast<std::shared_ptr<tonic::DartState>*>(callback_data);
}
void RunApplication(
DartRunner* runner,
fuchsia::sys::Package package,
fuchsia::sys::StartupInfo startup_info,
std::shared_ptr<sys::ServiceDirectory> runner_incoming_services,
::fidl::InterfaceRequest<fuchsia::sys::ComponentController> controller) {
int64_t start = Dart_TimelineGetMicros();
DartComponentController app(std::move(package), std::move(startup_info),
runner_incoming_services, std::move(controller));
bool success = app.Setup();
int64_t end = Dart_TimelineGetMicros();
Dart_TimelineEvent("DartComponentController::Setup", start, end,
Dart_Timeline_Event_Duration, 0, NULL, NULL);
if (success) {
app.Run();
}
if (Dart_CurrentIsolate()) {
Dart_ShutdownIsolate();
}
}
bool EntropySource(uint8_t* buffer, intptr_t count) {
zx_cprng_draw(buffer, count);
return true;
}
} // namespace
DartRunner::DartRunner() : context_(sys::ComponentContext::Create()) {
context_->outgoing()->AddPublicService<fuchsia::sys::Runner>(
[this](fidl::InterfaceRequest<fuchsia::sys::Runner> request) {
bindings_.AddBinding(this, std::move(request));
});
#if !defined(DART_PRODUCT)
// The VM service isolate uses the process-wide namespace. It writes the
// vm service protocol port under /tmp. The VMServiceObject exposes that
// port number to The Hub.
context_->outgoing()->debug_dir()->AddEntry(
dart_utils::VMServiceObject::kPortDirName,
std::make_unique<dart_utils::VMServiceObject>());
#endif // !defined(DART_PRODUCT)
dart::bin::BootstrapDartIo();
char* error =
Dart_SetVMFlags(dart_utils::ArraySize(kDartVMArgs), kDartVMArgs);
if (error) {
FX_LOGF(FATAL, LOG_TAG, "Dart_SetVMFlags failed: %s", error);
}
Dart_InitializeParams params = {};
params.version = DART_INITIALIZE_PARAMS_CURRENT_VERSION;
#if defined(AOT_RUNTIME)
params.vm_snapshot_data = ::_kDartVmSnapshotData;
params.vm_snapshot_instructions = ::_kDartVmSnapshotInstructions;
#else
if (!MappedResource::LoadFromNamespace(
nullptr, "pkg/data/vm_snapshot_data.bin", vm_snapshot_data_)) {
FX_LOG(FATAL, LOG_TAG, "Failed to load vm snapshot data");
}
if (!MappedResource::LoadFromNamespace(
nullptr, "pkg/data/vm_snapshot_instructions.bin",
vm_snapshot_instructions_, true /* executable */)) {
FX_LOG(FATAL, LOG_TAG, "Failed to load vm snapshot instructions");
}
params.vm_snapshot_data = vm_snapshot_data_.address();
params.vm_snapshot_instructions = vm_snapshot_instructions_.address();
#endif
params.create = IsolateCreateCallback;
params.shutdown = IsolateShutdownCallback;
params.cleanup = IsolateCleanupCallback;
params.entropy_source = EntropySource;
#if !defined(DART_PRODUCT)
params.get_service_assets = GetVMServiceAssetsArchiveCallback;
#endif
error = Dart_Initialize(&params);
if (error)
FX_LOGF(FATAL, LOG_TAG, "Dart_Initialize failed: %s", error);
}
DartRunner::~DartRunner() {
char* error = Dart_Cleanup();
if (error)
FX_LOGF(FATAL, LOG_TAG, "Dart_Cleanup failed: %s", error);
}
void DartRunner::StartComponent(
fuchsia::sys::Package package,
fuchsia::sys::StartupInfo startup_info,
::fidl::InterfaceRequest<fuchsia::sys::ComponentController> controller) {
TRACE_EVENT1("dart", "StartComponent", "url", package.resolved_url.c_str());
std::thread thread(RunApplication, this, std::move(package),
std::move(startup_info), context_->svc(),
std::move(controller));
thread.detach();
}
} // namespace dart_runner
// 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.
#ifndef TOPAZ_RUNTIME_DART_RUNNER_DART_RUNNER_H_
#define TOPAZ_RUNTIME_DART_RUNNER_DART_RUNNER_H_
#include <fuchsia/sys/cpp/fidl.h>
#include <lib/fidl/cpp/binding_set.h>
#include <lib/sys/cpp/component_context.h>
#include "mapped_resource.h"
namespace dart_runner {
class DartRunner : public fuchsia::sys::Runner {
public:
explicit DartRunner();
~DartRunner() override;
private:
// |fuchsia::sys::Runner| implementation:
void StartComponent(
fuchsia::sys::Package package,
fuchsia::sys::StartupInfo startup_info,
::fidl::InterfaceRequest<fuchsia::sys::ComponentController> controller)
override;
std::unique_ptr<sys::ComponentContext> context_;
fidl::BindingSet<fuchsia::sys::Runner> bindings_;
#if !defined(AOT_RUNTIME)
MappedResource vm_snapshot_data_;
MappedResource vm_snapshot_instructions_;
#endif
// Disallow copy and assignment.
DartRunner(const DartRunner&) = delete;
DartRunner& operator=(const DartRunner&) = delete;
};
} // namespace dart_runner
#endif // TOPAZ_RUNTIME_DART_RUNNER_DART_RUNNER_H_
# 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.
import("//build/dart/toolchain.gni")
import("//topaz/runtime/dart/dart_component.gni")
import("//topaz/runtime/dart/dart_kernel.gni")
dart_kernel("shim") {
platform_name = "dart_runner"
platform_deps = [ "//topaz/runtime/dart_runner/kernel:kernel_platform_files" ]
platform_path = "$root_out_dir/dart_runner_patched_sdk"
disable_analysis = true
main_dart = "shim.dart"
aot = true
product = false
visibility = [ ":*" ]
}
dart_kernel("shim_product") {
platform_name = "dart_runner"
platform_deps = [ "//topaz/runtime/dart_runner/kernel:kernel_platform_files" ]
platform_path = "$root_out_dir/dart_runner_patched_sdk"
disable_analysis = true
main_dart = "shim.dart"
aot = true
product = true
visibility = [ ":*" ]
}
template("create_aot_snapshot") {
assert(defined(invoker.product), "The parameter 'product' must be defined")
product_suffix = ""
if (invoker.product) {
product_suffix = "_product"
}
action("${target_name}_assembly") {
snapshot_assembly = "$target_gen_dir/aot${product_suffix}_vm_snapshot.S"
# gen_snapshot only needs this to go through the motions of setting up an isolate.
shim_target = ":shim${product_suffix}_kernel"
shim_kernel = get_label_info(shim_target, "target_gen_dir") +
"/shim${product_suffix}_kernel.dil"
inputs = [
shim_kernel,
]
outputs = [
snapshot_assembly,
]
deps = gen_snapshot_deps + [ shim_target ]
if (invoker.product) {
script = gen_snapshot_product
} else {
script = gen_snapshot
}
args = [
"--no_causal_async_stacks",
"--deterministic",
"--snapshot_kind=vm-aot-assembly",
"--assembly=" + rebase_path(snapshot_assembly),
]
# No asserts in debug or release product.
# No asserts in release with flutter_profile=true (non-product)
# Yes asserts in non-product debug.
if (!invoker.product && (!flutter_profile || is_debug)) {
args += [ "--enable_asserts" ]
}
args += [ rebase_path(shim_kernel) ]
}
source_set(target_name) {
deps = [
":${target_name}_assembly",
]
sources = [
"$target_gen_dir/aot${product_suffix}_vm_snapshot.S",
"snapshot.h",
]
}
}
create_aot_snapshot("dart_aot_snapshot_cc") {
product = false
}
create_aot_snapshot("dart_aot_product_snapshot_cc") {
product = true
}
// 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.
library fuchsia_builtin;
import 'dart:async';
import 'dart:io';
import 'dart:_internal' show VMLibraryHooks;
// Corelib 'print' implementation.
void _print(arg) {
_Logger._printString(arg.toString());
try {
// If stdout is connected, print to it as well.
stdout.writeln(arg);
} on FileSystemException catch (_) {
// Some Fuchsia applications will not have stdout connected.
}
}
class _Logger {
static void _printString(String s) native "Logger_PrintString";
}
@pragma('vm:entry-point')
String _rawScript;
Uri _scriptUri() {
if (_rawScript.startsWith('http:') ||
_rawScript.startsWith('https:') ||
_rawScript.startsWith('file:')) {
return Uri.parse(_rawScript);
} else {
return Uri.base.resolveUri(Uri.file(_rawScript));
}
}
void _scheduleMicrotask(void callback()) native "ScheduleMicrotask";
@pragma('vm:entry-point')
_getScheduleMicrotaskClosure() => _scheduleMicrotask;
@pragma('vm:entry-point')
_setupHooks() {
VMLibraryHooks.platformScript = _scriptUri;
}
@pragma('vm:entry-point')
_getPrintClosure() => _print;
# 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.
# The presence of this file is necessary in order to use the dart_library
# template in BUILD.gn.
// 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.
// Core SDK libraries.
import 'dart:async';
import 'dart:core';
import 'dart:collection';
import 'dart:convert';
import 'dart:io';
import 'dart:isolate';
import 'dart:math';
import 'dart:fuchsia.builtin';
import 'dart:zircon';
import 'dart:fuchsia';
import 'dart:typed_data';
// If new imports are added to this list, then it is also necessary to ensure
// that the dart_deps parameter in the rule
// gen_snapshot_cc("script_runner_snapshot") in the BUILD.gn file in this
// directory is updated with any new dependencies.
import 'package:fuchsia/fuchsia.dart';
import 'package:zircon/zircon.dart';
// FIDL bindings and application libraries.
import 'package:lib.app.dart/app.dart';
import 'package:fidl/fidl.dart';
// From //sdk/fidl/fuchsia.modular
import 'package:fidl_fuchsia_modular/fidl.dart';
// 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.
main() {}
// 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.
// This file is linked into the dart executable when it has a snapshot
// linked into it.
#include "embedder/snapshot.h"
namespace dart_runner {
// The string on the next line will be filled in with the contents of the
// generated snapshot binary file for the vm isolate. This string forms the
// content of the dart vm isolate snapshot which is loaded into the vm isolate.
static const uint8_t vm_isolate_snapshot_buffer_[] = { % s};
uint8_t const* const vm_isolate_snapshot_buffer = vm_isolate_snapshot_buffer_;
// The string on the next line will be filled in with the contents of the
// generated snapshot binary file for a regular dart isolate.
// This string forms the content of a regular dart isolate snapshot which
// is loaded into an isolate when it is created.
static const uint8_t isolate_snapshot_buffer_[] = { % s};
uint8_t const* const isolate_snapshot_buffer = isolate_snapshot_buffer_;
} // namespace dart_runner
// 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.
import 'dart:async';
import 'dart:core';
import 'dart:collection';
import 'dart:convert';
import 'dart:io';
import 'dart:isolate';
import 'dart:math';
import 'dart:fuchsia.builtin';
import 'dart:zircon';
import 'dart:fuchsia';
import 'dart:typed_data';
// 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 <stdint.h>
namespace dart_runner {
extern uint8_t const* const vm_isolate_snapshot_buffer;
extern uint8_t const* const isolate_snapshot_buffer;
} // namespace dart_runner
# 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.
import("//build/testing/environments.gni")
import("//topaz/runtime/dart_runner/dart_app.gni")
dart_jit_app("goodbye_dart_jit") {
sources = [
"goodbye_dart.dart",
]
main_dart = "goodbye_dart.dart"
source_dir = "."
deps = [
"//topaz/public/dart/fidl",
"//topaz/public/dart/fuchsia",
]
meta = [
{
path = "meta/goodbye_dart_jit.cmx"
dest = "goodbye_dart_jit.cmx"
},
]
}
dart_aot_app("goodbye_dart_aot") {
sources = [
"goodbye_dart.dart",
]
main_dart = "goodbye_dart.dart"
source_dir = "."
deps = [
"//topaz/public/dart/fidl",
"//topaz/public/dart/fuchsia",
]
meta = [
{
path = "meta/goodbye_dart_aot.cmx"
dest = "goodbye_dart_aot.cmx"
},
]
}
copy("copy_goodbye_dart_test") {
sources = [
"goodbye_dart_test",
]
outputs = [
"${root_build_dir}/goodbye_dart_test",
]
}
package("goodbye_dart_test") {
testonly = true
tests = [
{
name = "goodbye_dart_test"
environments = basic_envs
},
]
deps = [
":copy_goodbye_dart_test",
]
}
# 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: ../../../../tools/analysis_options.yaml
// 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.
import 'dart:async';
import 'package:fuchsia/fuchsia.dart' as fuchsia;
// ignore: unused_element
Timer _timer;
void main(List<String> args) {
print('Hello, Dart!');
if (args.isNotEmpty && args.first == '--now') {
print('Goodbye now!');
fuchsia.exit(23);
}
_timer = Timer(const Duration(seconds: 1), () {
print('Goodbye, Dart!');
fuchsia.exit(42);
});
}
#!/boot/bin/sh
run fuchsia-pkg://fuchsia.con/goodbye_dart_aot#meta/goodbye_dart_aot.cmx --now
if [ $? -ne 23 ]; then
echo "goodbye_dart_aot --now failed"
exit 1
fi
# run goodbye_dart_jit --now
# if [ $? -ne 23 ]; then
# echo "goodbye_dart_jit --now failed"
# exit 1
# fi
run fuchsia-pkg://fuchsia.con/goodbye_dart_aot#meta/goodbye_dart_aot.cmx
if [ $? -ne 42 ]; then
echo "goodbye_dart_aot failed"
exit 1
fi
# run goodbye_dart_jit
# if [ $? -ne 42 ]; then
# echo "goodbye_dart_jit failed"
# exit 1
# fi
{
"program": {
"data": "data/goodbye_dart_aot"
},
"sandbox": {
"features": [],
"services": [
"fuchsia.sys.Environment"
]
}
}
{
"program": {
"data": "data/goodbye_dart_jit"
},
"sandbox": {
"features": [],
"services": [
"fuchsia.sys.Environment"
]
}
}
# 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.
# 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.
import("//build/dart/dart_library.gni")
dart_library("greeting") {
infer_package_name = true
sources = [
"greeting.dart",
]
source_dir = "."
}
# 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: ../../../../tools/analysis_options.yaml
// 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.
/// Returns a greeting.
String greeting() {
return 'Hello';
}
# 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.
# 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.
import("//topaz/runtime/dart_runner/dart_app.gni")
dart_jit_app("hello_app_dart_jit") {
main_dart = "main.dart"
source_dir = "."
sources = []
deps = [
"//topaz/public/dart/fidl",
"//topaz/public/dart/fuchsia_services",
"//topaz/runtime/dart_runner/examples/hello_app_dart/interfaces:interfaces",
]
meta = [
{
path = "meta/hello_app_dart_jit.cmx"
dest = "hello_app_dart_jit.cmx"
},
]
}
dart_aot_app("hello_app_dart_aot") {
main_dart = "main.dart"
source_dir = "."
sources = []
deps = [
"//topaz/public/dart/fidl",
"//topaz/public/dart/fuchsia_services",
"//topaz/runtime/dart_runner/examples/hello_app_dart/interfaces:interfaces",
]
meta = [
{
path = "meta/hello_app_dart_aot.cmx"
dest = "hello_app_dart_aot.cmx"
},
]
}
# 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: ../../../../tools/analysis_options.yaml
# 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.
import("//build/fidl/fidl.gni")
fidl("interfaces") {
name = "fuchsia.examples.hello"
sources = [
"hello.fidl",
]
}
// 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.
library fuchsia.examples.hello;
[Discoverable]
protocol Hello {
Say(string request) -> (string response);
};
// 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.
import 'package:fidl/fidl.dart';
import 'package:fuchsia_services/services.dart';
import 'package:fidl_fuchsia_examples_hello/fidl_async.dart';
class _HelloImpl extends Hello {
final HelloBinding _binding = HelloBinding();
void bind(InterfaceRequest<Hello> request) {
_binding.bind(this, request);
}
@override
Future<String> say(String request) async {
return request == 'hello' ? 'hola from Dart!' : 'adios from Dart!';
}
}
void main(List<String> args) {
StartupContext context = StartupContext.fromStartupInfo();
context.outgoing
.addPublicService(_HelloImpl().bind, Hello.$serviceName);
}
{
"program": {
"data": "data/hello_app_dart_aot"
},
"sandbox": {
"features": [],
"services": [
"fuchsia.sys.Environment"
]
}
}
{
"program": {
"data": "data/hello_app_dart_jit"
},
"sandbox": {
"features": [],
"services": [
"fuchsia.sys.Environment"
]
}
}
# 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.
# 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.
import("//topaz/runtime/dart_runner/dart_app.gni")
dart_jit_app("hello_dart_debug") {
main_dart = "bin/hello_dart.dart"
source_dir = "."
product = false
space_dart = false
sources = []
deps = [
"//topaz/public/dart/zircon",
"//topaz/runtime/dart_runner/examples/greeting",
]
meta = [
{
path = "meta/hello_dart_debug.cmx"
dest = "hello_dart_debug.cmx"
},
]
}
dart_jit_app("hello_dart_jit") {
main_dart = "bin/hello_dart.dart"
source_dir = "."
product = false
sources = []
deps = [
"//topaz/public/dart/zircon",
"//topaz/runtime/dart_runner/examples/greeting",
]
meta = [
{
path = "meta/hello_dart_jit.cmx"
dest = "hello_dart_jit.cmx"
},
]
}
dart_jit_app("hello_dart_jit_product") {
main_dart = "bin/hello_dart.dart"
source_dir = "."
product = true
sources = []
deps = [
"//topaz/public/dart/zircon",
"//topaz/runtime/dart_runner/examples/greeting",
]
meta = [
{
path = "meta/hello_dart_jit_product.cmx"
dest = "hello_dart_jit_product.cmx"
},
]
}
dart_aot_app("hello_dart_aot") {
main_dart = "bin/hello_dart.dart"
source_dir = "."
product = false
sources = []
deps = [
"//topaz/public/dart/zircon",
"//topaz/runtime/dart_runner/examples/greeting",
]
meta = [
{
path = "meta/hello_dart_aot.cmx"
dest = "hello_dart_aot.cmx"
},
]
}
dart_aot_app("hello_dart_aot_product") {
main_dart = "bin/hello_dart.dart"
source_dir = "."
product = true
sources = []
deps = [
"//topaz/public/dart/zircon",
"//topaz/runtime/dart_runner/examples/greeting",
]
meta = [
{
path = "meta/hello_dart_aot_product.cmx"
dest = "hello_dart_aot_product.cmx"
},
]
}
# 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: ../../../../tools/analysis_options.yaml
// 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.
import 'package:topaz.runtime.dart_runner.examples.greeting/greeting.dart';
void main(List<String> args) {
print('${greeting()}, Dart!');
}
{
"program": {
"data": "data/hello_dart_aot"
},
"sandbox": {
"features": [],
"services": [
"fuchsia.sys.Environment"
]
}
}
{
"program": {
"data": "data/hello_dart_aot_product"
},
"sandbox": {
"features": [],
"services": [
"fuchsia.sys.Environment"
]
}
}
{
"program": {
"data": "data/hello_dart_debug"
},
"sandbox": {
"features": [],
"services": [
"fuchsia.sys.Environment"
]
}
}
{
"program": {
"data": "data/hello_dart_jit"
},
"sandbox": {
"features": [],
"services": [
"fuchsia.sys.Environment"
]
}
}
{
"program": {
"data": "data/hello_dart_jit_product"
},
"sandbox": {
"features": [],
"services": [
"fuchsia.sys.Environment"
]
}
}
# 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.
# 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.
import("//topaz/runtime/dart_runner/dart_app.gni")
dart_jit_app("dart_jit_runner_test") {
testonly = true
main_dart = "main.dart"
source_dir = "."
meta = [
{
path = rebase_path("meta/dart_jit_runner_test.cmx")
dest = "dart_jit_runner_test.cmx"
},
]
sources = []
deps = [
"//third_party/dart-pkg/pub/test",
"//topaz/public/dart/fuchsia_services",
"//topaz/runtime/dart_runner/examples/hello_app_dart/interfaces:interfaces",
"//zircon/public/fidl/fuchsia-io",
]
}
dart_aot_app("dart_aot_runner_test") {
testonly = true
main_dart = "main.dart"
source_dir = "."
meta = [
{
path = rebase_path("meta/dart_aot_runner_test.cmx")
dest = "dart_aot_runner_test.cmx"
},
]
sources = []
deps = [
"//third_party/dart-pkg/pub/test",
"//topaz/public/dart/fuchsia_services",
"//topaz/runtime/dart_runner/examples/hello_app_dart/interfaces:interfaces",
"//zircon/public/fidl/fuchsia-io",
]
}
# 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: ../../../tools/analysis_options.yaml
// 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.
import 'dart:async';
import 'dart:io' as io;
import 'package:fidl_fuchsia_examples_hello/fidl_async.dart';
import 'package:fidl_fuchsia_io/fidl_async.dart';
import 'package:fidl_fuchsia_sys/fidl_async.dart';
import 'package:fuchsia_services/services.dart';
import 'package:test/test.dart';
void main(List<String> args) {
final StartupContext context = StartupContext.fromStartupInfo();
LauncherProxy launcher;
setUp(() {
launcher = LauncherProxy();
context.incoming.connectToService(launcher);
});
tearDown(() {
launcher.ctrl.close();
launcher = null;
});
// TODO(rosswang): nested environments and determinism
test('schedule delayed futures',
() => Future<Null>.delayed(const Duration(seconds: 1)));
test('start hello_dart', () async {
const LaunchInfo info = LaunchInfo(
url:
'fuchsia-pkg://fuchsia.com/hello_dart_jit#meta/hello_dart_jit.cmx');
await launcher.createComponent(
info, ComponentControllerProxy().ctrl.request());
});
test('communicate with a fidl service (hello_app_dart)', () async {
final HelloProxy service = HelloProxy();
final dirProxy = DirectoryProxy();
final ComponentControllerProxy actl = ComponentControllerProxy();
final LaunchInfo info = LaunchInfo(
url:
'fuchsia-pkg://fuchsia.com/hello_app_dart_jit#meta/hello_app_dart_jit.cmx',
directoryRequest: dirProxy.ctrl.request().passChannel());
await launcher.createComponent(info, actl.ctrl.request());
Incoming(dirProxy).connectToService(service);
expect(await service.say('hello'), equals('hola from Dart!'));
actl.ctrl.close();
});
test('dart:io exit() throws UnsupportedError', () {
expect(() => io.exit(-1), throwsUnsupportedError);
});
}
{
"program": {
"data": "data/dart_aot_runner_test"
},
"sandbox": {
"services": [
"fuchsia.cobalt.LoggerFactory",
"fuchsia.fonts.Provider",
"fuchsia.logger.LogSink",
"fuchsia.modular.Clipboard",
"fuchsia.modular.ContextWriter",
"fuchsia.modular.ModuleContext",
"fuchsia.netstack.Netstack",
"fuchsia.sys.Environment",
"fuchsia.sys.Launcher",
"fuchsia.ui.input.ImeService",
"fuchsia.ui.policy.Presenter",
"fuchsia.ui.scenic.Scenic",
"fuchsia.wlan.service.Wlan"
]
}
}
{
"program": {
"data": "data/dart_jit_runner_test"
},
"sandbox": {
"services": [
"fuchsia.cobalt.LoggerFactory",
"fuchsia.fonts.Provider",
"fuchsia.logger.LogSink",
"fuchsia.modular.Clipboard",
"fuchsia.modular.ContextWriter",
"fuchsia.modular.ModuleContext",
"fuchsia.netstack.Netstack",
"fuchsia.sys.Environment",
"fuchsia.sys.Launcher",
"fuchsia.ui.input.ImeService",
"fuchsia.ui.policy.Presenter",
"fuchsia.ui.scenic.Scenic",
"fuchsia.wlan.service.Wlan"
]
}
}
# 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.
# 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.
import("//build/dart/dart_tool.gni")
import("//third_party/dart/utils/compile_platform.gni")
import("//topaz/runtime/dart/dart_component.gni")
compile_platform("kernel_platform_files") {
single_root_scheme = "org-dartlang-sdk"
single_root_base = rebase_path("../../../../")
libraries_specification_uri =
"org-dartlang-sdk:///topaz/runtime/dart_runner/kernel/libraries.json"
outputs = [
"$root_out_dir/dart_runner_patched_sdk/platform_strong.dill",
"$root_out_dir/dart_runner_patched_sdk/vm_outline_strong.dill",
]
args = [
# TODO(dartbug.com/36342): enable bytecode for core libraries when performance of bytecode
# pipeline is on par with default pipeline and continuously tracked.
# "--bytecode",
"--target=dart_runner",
"dart:core",
]
}
template("create_kernel_core_snapshot") {
assert(defined(invoker.product), "The parameter 'product' must be defined")
product_suffix = ""
if (invoker.product) {
product_suffix = "_product"
}
action(target_name) {
deps = gen_snapshot_deps + [ ":kernel_platform_files" ]
platform_dill = "$root_out_dir/dart_runner_patched_sdk/platform_strong.dill"
compilation_trace = "//topaz/runtime/flutter_runner/compilation_trace.txt"
inputs = [
platform_dill,
compilation_trace,
]
vm_snapshot_data = "$target_gen_dir/vm_data${product_suffix}.bin"
vm_snapshot_instructions =
"$target_gen_dir/vm_instructions${product_suffix}.bin"
isolate_snapshot_data = "$target_gen_dir/isolate_data${product_suffix}.bin"
isolate_snapshot_instructions =
"$target_gen_dir/isolate_instructions${product_suffix}.bin"
snapshot_profile = "$target_gen_dir/snapshot_profile${product_suffix}.json"
outputs = [
vm_snapshot_data,
vm_snapshot_instructions,
isolate_snapshot_data,
isolate_snapshot_instructions,
snapshot_profile,
]
if (invoker.product) {
script = gen_snapshot_product
} else {
script = gen_snapshot
}
args = [
# TODO(FL-117): Re-enable causal async stack traces when this issue is
# addressed.
"--no_causal_async_stacks",
"--use_bytecode_compiler",
"--enable_mirrors=false",
"--deterministic",
"--snapshot_kind=core-jit",
"--load_compilation_trace=" +
rebase_path(compilation_trace, root_build_dir),
"--vm_snapshot_data=" + rebase_path(vm_snapshot_data, root_build_dir),
"--vm_snapshot_instructions=" +
rebase_path(vm_snapshot_instructions, root_build_dir),
"--isolate_snapshot_data=" +
rebase_path(isolate_snapshot_data, root_build_dir),
"--isolate_snapshot_instructions=" +
rebase_path(isolate_snapshot_instructions, root_build_dir),
"--write_v8_snapshot_profile_to=" +
rebase_path(snapshot_profile, root_build_dir),
]
# No asserts in debug or release product.
# No asserts in release with flutter_profile=true (non-product)
# Yes asserts in non-product debug.
if (!invoker.product && (!flutter_profile || is_debug)) {
args += [ "--enable_asserts" ]
}
args += [ rebase_path(platform_dill) ]
}
}
create_kernel_core_snapshot("kernel_core_snapshot") {
product = false
}
create_kernel_core_snapshot("kernel_core_snapshot_product") {
product = true
}
{
"comment:0": "NOTE: THIS FILE IS GENERATED. DO NOT EDIT.",
"comment:1": "Instead modify 'topaz/runtime/dart_runner/kernel/libraries.yaml' and follow the instructions therein.",
"dart_runner": {
"libraries": {
"_builtin": {
"uri": "../../../../third_party/dart/runtime/bin/builtin.dart"
},
"core": {
"patches": [
"../../../../third_party/dart/runtime/lib/core_patch.dart",
"../../../../third_party/dart/runtime/lib/array.dart",
"../../../../third_party/dart/runtime/lib/array_patch.dart",
"../../../../third_party/dart/runtime/lib/bigint_patch.dart",
"../../../../third_party/dart/runtime/lib/bool_patch.dart",
"../../../../third_party/dart/runtime/lib/date_patch.dart",
"../../../../third_party/dart/runtime/lib/double.dart",
"../../../../third_party/dart/runtime/lib/double_patch.dart",
"../../../../third_party/dart/runtime/lib/errors_patch.dart",
"../../../../third_party/dart/runtime/lib/expando_patch.dart",
"../../../../third_party/dart/runtime/lib/function.dart",
"../../../../third_party/dart/runtime/lib/function_patch.dart",
"../../../../third_party/dart/runtime/lib/growable_array.dart",
"../../../../third_party/dart/runtime/lib/identical_patch.dart",
"../../../../third_party/dart/runtime/lib/immutable_map.dart",
"../../../../third_party/dart/runtime/lib/integers.dart",
"../../../../third_party/dart/runtime/lib/integers_patch.dart",
"../../../../third_party/dart/runtime/lib/invocation_mirror_patch.dart",
"../../../../third_party/dart/runtime/lib/lib_prefix.dart",
"../../../../third_party/dart/runtime/lib/map_patch.dart",
"../../../../third_party/dart/runtime/lib/null_patch.dart",
"../../../../third_party/dart/runtime/lib/object_patch.dart",
"../../../../third_party/dart/runtime/lib/regexp_patch.dart",
"../../../../third_party/dart/runtime/lib/stacktrace.dart",
"../../../../third_party/dart/runtime/lib/stopwatch_patch.dart",
"../../../../third_party/dart/runtime/lib/string_buffer_patch.dart",
"../../../../third_party/dart/runtime/lib/string_patch.dart",
"../../../../third_party/dart/runtime/lib/type_patch.dart",
"../../../../third_party/dart/runtime/lib/uri_patch.dart",
"../../../../third_party/dart/runtime/lib/weak_property.dart"
],
"uri": "../../../../third_party/dart/sdk/lib/core/core.dart"
},
"zircon": {
"uri": "../../../../topaz/public/dart-pkg/zircon/lib/zircon.dart"
},
"async": {
"patches": [
"../../../../third_party/dart/runtime/lib/async_patch.dart",
"../../../../third_party/dart/runtime/lib/deferred_load_patch.dart",
"../../../../third_party/dart/runtime/lib/schedule_microtask_patch.dart",
"../../../../third_party/dart/runtime/lib/timer_patch.dart"
],
"uri": "../../../../third_party/dart/sdk/lib/async/async.dart"
},
"collection": {
"patches": [
"../../../../third_party/dart/runtime/lib/collection_patch.dart",
"../../../../third_party/dart/runtime/lib/compact_hash.dart"
],
"uri": "../../../../third_party/dart/sdk/lib/collection/collection.dart"
},
"ffi": {
"patches": [
"../../../../third_party/dart/runtime/lib/ffi_dynamic_library_patch.dart",
"../../../../third_party/dart/runtime/lib/ffi_native_type_patch.dart",
"../../../../third_party/dart/runtime/lib/ffi_patch.dart"
],
"uri": "../../../../third_party/dart/sdk/lib/ffi/ffi.dart"
},
"typed_data": {
"patches": "../../../../third_party/dart/runtime/lib/typed_data_patch.dart",
"uri": "../../../../third_party/dart/sdk/lib/typed_data/typed_data.dart"
},
"nativewrappers": {
"uri": "../../../../third_party/dart/sdk/lib/html/dartium/nativewrappers.dart"
},
"developer": {
"patches": [
"../../../../third_party/dart/runtime/lib/developer.dart",
"../../../../third_party/dart/runtime/lib/profiler.dart",
"../../../../third_party/dart/runtime/lib/timeline.dart"
],
"uri": "../../../../third_party/dart/sdk/lib/developer/developer.dart"
},
"isolate": {
"patches": [
"../../../../third_party/dart/runtime/lib/isolate_patch.dart",
"../../../../third_party/dart/runtime/lib/timer_impl.dart"
],
"uri": "../../../../third_party/dart/sdk/lib/isolate/isolate.dart"
},
"mirrors": {
"patches": [
"../../../../third_party/dart/runtime/lib/mirrors_patch.dart",
"../../../../third_party/dart/runtime/lib/mirrors_impl.dart",
"../../../../third_party/dart/runtime/lib/mirror_reference.dart"
],
"uri": "../../../../third_party/dart/sdk/lib/mirrors/mirrors.dart"
},
"_vmservice": {
"uri": "../../../../third_party/dart/sdk/lib/vmservice/vmservice.dart"
},
"io": {
"patches": [
"../../../../third_party/dart/runtime/bin/common_patch.dart",
"../../../../third_party/dart/runtime/bin/directory_patch.dart",
"../../../../third_party/dart/runtime/bin/eventhandler_patch.dart",
"../../../../third_party/dart/runtime/bin/file_patch.dart",
"../../../../third_party/dart/runtime/bin/file_system_entity_patch.dart",
"../../../../third_party/dart/runtime/bin/filter_patch.dart",
"../../../../third_party/dart/runtime/bin/io_service_patch.dart",
"../../../../third_party/dart/runtime/bin/namespace_patch.dart",
"../../../../third_party/dart/runtime/bin/platform_patch.dart",
"../../../../third_party/dart/runtime/bin/process_patch.dart",
"../../../../third_party/dart/runtime/bin/socket_patch.dart",
"../../../../third_party/dart/runtime/bin/stdio_patch.dart",
"../../../../third_party/dart/runtime/bin/secure_socket_patch.dart",
"../../../../third_party/dart/runtime/bin/sync_socket_patch.dart"
],
"uri": "../../../../third_party/dart/sdk/lib/io/io.dart"
},
"_internal": {
"patches": [
"../../../../third_party/dart/runtime/lib/internal_patch.dart",
"../../../../third_party/dart/runtime/lib/class_id_fasta.dart",
"../../../../third_party/dart/runtime/lib/print_patch.dart",
"../../../../third_party/dart/runtime/lib/symbol_patch.dart",
"../../../../third_party/dart/sdk/lib/internal/patch.dart"
],
"uri": "../../../../third_party/dart/sdk/lib/internal/internal.dart"
},
"convert": {
"patches": "../../../../third_party/dart/runtime/lib/convert_patch.dart",
"uri": "../../../../third_party/dart/sdk/lib/convert/convert.dart"
},
"profiler": {
"uri": "../../../../third_party/dart/sdk/lib/profiler/profiler.dart"
},
"math": {
"patches": "../../../../third_party/dart/runtime/lib/math_patch.dart",
"uri": "../../../../third_party/dart/sdk/lib/math/math.dart"
},
"_http": {
"uri": "../../../../third_party/dart/sdk/lib/_http/http.dart"
},
"fuchsia": {
"uri": "../../../../topaz/public/dart-pkg/fuchsia/lib/fuchsia.dart"
},
"fuchsia.builtin": {
"uri": "../../../../topaz/runtime/dart_runner/embedder/builtin.dart"
},
"vmservice_io": {
"uri": "../../../../third_party/dart/runtime/bin/vmservice/vmservice_io.dart"
}
}
}
}
\ No newline at end of file
# Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
# Note: if you edit this file, you must also edit libraries.json in this
# directory:
#
# python third_party/dart/tools/yaml2json.py \
# topaz/runtime/dart_runner/kernel/libraries.yaml \
# topaz/runtime/dart_runner/kernel/libraries.json
#
# We currently have several different files that needs to be updated when
# changing libraries, sources, and patch files. See
# https://github.com/dart-lang/sdk/issues/28836.
dart_runner:
libraries:
_builtin:
uri: "../../../../third_party/dart/runtime/bin/builtin.dart"
_internal:
uri: "../../../../third_party/dart/sdk/lib/internal/internal.dart"
patches:
- "../../../../third_party/dart/runtime/lib/internal_patch.dart"
- "../../../../third_party/dart/runtime/lib/class_id_fasta.dart"
- "../../../../third_party/dart/runtime/lib/print_patch.dart"
- "../../../../third_party/dart/runtime/lib/symbol_patch.dart"
- "../../../../third_party/dart/sdk/lib/internal/patch.dart"
async:
uri: "../../../../third_party/dart/sdk/lib/async/async.dart"
patches:
- "../../../../third_party/dart/runtime/lib/async_patch.dart"
- "../../../../third_party/dart/runtime/lib/deferred_load_patch.dart"
- "../../../../third_party/dart/runtime/lib/schedule_microtask_patch.dart"
- "../../../../third_party/dart/runtime/lib/timer_patch.dart"
collection:
uri: "../../../../third_party/dart/sdk/lib/collection/collection.dart"
patches:
- "../../../../third_party/dart/runtime/lib/collection_patch.dart"
- "../../../../third_party/dart/runtime/lib/compact_hash.dart"
convert:
uri: "../../../../third_party/dart/sdk/lib/convert/convert.dart"
patches: "../../../../third_party/dart/runtime/lib/convert_patch.dart"
core:
uri: "../../../../third_party/dart/sdk/lib/core/core.dart"
patches:
- "../../../../third_party/dart/runtime/lib/core_patch.dart"
- "../../../../third_party/dart/runtime/lib/array.dart"
- "../../../../third_party/dart/runtime/lib/array_patch.dart"
- "../../../../third_party/dart/runtime/lib/bigint_patch.dart"
- "../../../../third_party/dart/runtime/lib/bool_patch.dart"
- "../../../../third_party/dart/runtime/lib/date_patch.dart"
- "../../../../third_party/dart/runtime/lib/double.dart"
- "../../../../third_party/dart/runtime/lib/double_patch.dart"
- "../../../../third_party/dart/runtime/lib/errors_patch.dart"
- "../../../../third_party/dart/runtime/lib/expando_patch.dart"
- "../../../../third_party/dart/runtime/lib/function.dart"
- "../../../../third_party/dart/runtime/lib/function_patch.dart"
- "../../../../third_party/dart/runtime/lib/growable_array.dart"
- "../../../../third_party/dart/runtime/lib/identical_patch.dart"
- "../../../../third_party/dart/runtime/lib/immutable_map.dart"
- "../../../../third_party/dart/runtime/lib/integers.dart"
- "../../../../third_party/dart/runtime/lib/integers_patch.dart"
- "../../../../third_party/dart/runtime/lib/invocation_mirror_patch.dart"
- "../../../../third_party/dart/runtime/lib/lib_prefix.dart"
- "../../../../third_party/dart/runtime/lib/map_patch.dart"
- "../../../../third_party/dart/runtime/lib/null_patch.dart"
- "../../../../third_party/dart/runtime/lib/object_patch.dart"
- "../../../../third_party/dart/runtime/lib/regexp_patch.dart"
- "../../../../third_party/dart/runtime/lib/stacktrace.dart"
- "../../../../third_party/dart/runtime/lib/stopwatch_patch.dart"
- "../../../../third_party/dart/runtime/lib/string_buffer_patch.dart"
- "../../../../third_party/dart/runtime/lib/string_patch.dart"
- "../../../../third_party/dart/runtime/lib/type_patch.dart"
- "../../../../third_party/dart/runtime/lib/uri_patch.dart"
- "../../../../third_party/dart/runtime/lib/weak_property.dart"
developer:
uri: "../../../../third_party/dart/sdk/lib/developer/developer.dart"
patches:
- "../../../../third_party/dart/runtime/lib/developer.dart"
- "../../../../third_party/dart/runtime/lib/profiler.dart"
- "../../../../third_party/dart/runtime/lib/timeline.dart"
ffi:
uri: "../../../../third_party/dart/sdk/lib/ffi/ffi.dart"
patches:
- "../../../../third_party/dart/runtime/lib/ffi_dynamic_library_patch.dart"
- "../../../../third_party/dart/runtime/lib/ffi_native_type_patch.dart"
- "../../../../third_party/dart/runtime/lib/ffi_patch.dart"
_http:
uri: "../../../../third_party/dart/sdk/lib/_http/http.dart"
io:
uri: "../../../../third_party/dart/sdk/lib/io/io.dart"
patches:
- "../../../../third_party/dart/runtime/bin/common_patch.dart"
- "../../../../third_party/dart/runtime/bin/directory_patch.dart"
- "../../../../third_party/dart/runtime/bin/eventhandler_patch.dart"
- "../../../../third_party/dart/runtime/bin/file_patch.dart"
- "../../../../third_party/dart/runtime/bin/file_system_entity_patch.dart"
- "../../../../third_party/dart/runtime/bin/filter_patch.dart"
- "../../../../third_party/dart/runtime/bin/io_service_patch.dart"
- "../../../../third_party/dart/runtime/bin/namespace_patch.dart"
- "../../../../third_party/dart/runtime/bin/platform_patch.dart"
- "../../../../third_party/dart/runtime/bin/process_patch.dart"
- "../../../../third_party/dart/runtime/bin/socket_patch.dart"
- "../../../../third_party/dart/runtime/bin/stdio_patch.dart"
- "../../../../third_party/dart/runtime/bin/secure_socket_patch.dart"
- "../../../../third_party/dart/runtime/bin/sync_socket_patch.dart"
isolate:
uri: "../../../../third_party/dart/sdk/lib/isolate/isolate.dart"
patches:
- "../../../../third_party/dart/runtime/lib/isolate_patch.dart"
- "../../../../third_party/dart/runtime/lib/timer_impl.dart"
math:
uri: "../../../../third_party/dart/sdk/lib/math/math.dart"
patches: "../../../../third_party/dart/runtime/lib/math_patch.dart"
mirrors:
uri: "../../../../third_party/dart/sdk/lib/mirrors/mirrors.dart"
patches:
- "../../../../third_party/dart/runtime/lib/mirrors_patch.dart"
- "../../../../third_party/dart/runtime/lib/mirrors_impl.dart"
- "../../../../third_party/dart/runtime/lib/mirror_reference.dart"
nativewrappers:
uri: "../../../../third_party/dart/sdk/lib/html/dartium/nativewrappers.dart"
profiler:
uri: "../../../../third_party/dart/sdk/lib/profiler/profiler.dart"
typed_data:
uri: "../../../../third_party/dart/sdk/lib/typed_data/typed_data.dart"
patches: "../../../../third_party/dart/runtime/lib/typed_data_patch.dart"
fuchsia.builtin:
uri: "../../../../topaz/runtime/dart_runner/embedder/builtin.dart"
zircon:
uri: "../../../../topaz/public/dart-pkg/zircon/lib/zircon.dart"
fuchsia:
uri: "../../../../topaz/public/dart-pkg/fuchsia/lib/fuchsia.dart"
_vmservice:
uri: "../../../../third_party/dart/sdk/lib/vmservice/vmservice.dart"
vmservice_io:
uri: "../../../../third_party/dart/runtime/bin/vmservice/vmservice_io.dart"
// 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.
#ifndef TOPAZ_RUNTIME_DART_RUNNER_LOGGING_H_
#define TOPAZ_RUNTIME_DART_RUNNER_LOGGING_H_
namespace dart_runner {
// Use to mark logs published via the syslog API.
#define LOG_TAG "dart-runner"
} // namespace dart_runner
#endif // TOPAZ_RUNTIME_DART_RUNNER_LOGGING_H_
// 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 <lib/async-loop/cpp/loop.h>
#include "dart_runner.h"
#include "flutter/fml/logging.h"
#include "flutter/fml/trace_event.h"
#include "logging.h"
#include "runtime/dart/utils/files.h"
#include "runtime/dart/utils/tempfs.h"
#include "third_party/dart/runtime/include/dart_api.h"
#if !defined(FUCHSIA_SDK)
#include <lib/syslog/cpp/logger.h>
#include <trace-provider/provider.h>
#include <trace/event.h>
#endif // !defined(FUCHSIA_SDK)
#if !defined(DART_PRODUCT)
// Register native symbol information for the Dart VM's profiler.
static void RegisterProfilerSymbols(const char* symbols_path,
const char* dso_name) {
std::string* symbols = new std::string();
if (dart_utils::ReadFileToString(symbols_path, symbols)) {
Dart_AddSymbols(dso_name, symbols->data(), symbols->size());
} else {
FML_LOG(ERROR) << "Failed to load " << symbols_path;
FML_CHECK(false);
}
}
#endif // !defined(DART_PRODUCT)
int main(int argc, const char** argv) {
async::Loop loop(&kAsyncLoopConfigAttachToThread);
#if !defined(FUCHSIA_SDK)
syslog::InitLogger();
fbl::unique_ptr<trace::TraceProvider> provider;
{
TRACE_EVENT0("dart", "CreateTraceProvider");
bool already_started;
// Use CreateSynchronously to prevent loss of early events.
trace::TraceProvider::CreateSynchronously(loop.dispatcher(), "dart_runner",
&provider, &already_started);
}
#endif // !defined(FUCHSIA_SDK)
#if !defined(DART_PRODUCT)
#if defined(AOT_RUNTIME)
RegisterProfilerSymbols(
"pkg/data/libdart_precompiled_runtime.dartprofilersymbols",
"libdart_precompiled_runtime.so");
RegisterProfilerSymbols("pkg/data/dart_aot_runner.dartprofilersymbols", "");
#else
RegisterProfilerSymbols("pkg/data/libdart_jit.dartprofilersymbols",
"libdart_jit.so");
RegisterProfilerSymbols("pkg/data/dart_jit_runner.dartprofilersymbols", "");
#endif // defined(AOT_RUNTIME)
#endif // !defined(DART_PRODUCT)
dart_utils::SetupRunnerTemp();
dart_runner::DartRunner runner;
loop.Run();
return 0;
}
// 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 "mapped_resource.h"
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <zircon/status.h>
#if !defined(FUCHSIA_SDK)
#include <trace/event.h>
#endif // !defined(FUCHSIA_SDK)
#include "flutter/fml/logging.h"
#include "logging.h"
#include "runtime/dart/utils/inlines.h"
#include "runtime/dart/utils/vmo.h"
namespace dart_runner {
bool MappedResource::LoadFromNamespace(fdio_ns_t* namespc,
const std::string& path,
MappedResource& resource,
bool executable) {
#if !defined(FUCHSIA_SDK)
TRACE_DURATION("dart", "LoadFromNamespace", "path", path);
#endif // !defined(FUCHSIA_SDK)
// openat of a path with a leading '/' ignores the namespace fd.
dart_utils::Check(path[0] != '/', LOG_TAG);
fuchsia::mem::Buffer resource_vmo;
if (namespc == nullptr) {
if (!dart_utils::VmoFromFilename(path, &resource_vmo)) {
return false;
}
} else {
auto root_dir = fdio_ns_opendir(namespc);
if (root_dir < 0) {
FML_LOG(ERROR) << "Failed to open namespace directory";
return false;
}
bool result = dart_utils::VmoFromFilenameAt(root_dir, path, &resource_vmo);
close(root_dir);
if (!result) {
return result;
}
}
if (executable) {
// VmoFromFilenameAt will return VMOs without ZX_RIGHT_EXECUTE,
// so we need replace_as_executable to be able to map them as
// ZX_VM_PERM_EXECUTE.
// TODO(mdempsky): Update comment once SEC-42 is fixed.
zx_status_t status =
resource_vmo.vmo.replace_as_executable(zx::handle(), &resource_vmo.vmo);
if (status != ZX_OK) {
FML_LOG(ERROR) << "Failed to make VMO executable: "
<< zx_status_get_string(status);
return false;
}
}
return LoadFromVmo(path, std::move(resource_vmo), resource, executable);
}
bool MappedResource::LoadFromVmo(const std::string& path,
fuchsia::mem::Buffer resource_vmo,
MappedResource& resource,
bool executable) {
if (resource_vmo.size == 0) {
return true;
}
uint32_t flags = ZX_VM_PERM_READ;
if (executable) {
flags |= ZX_VM_PERM_EXECUTE;
}
uintptr_t addr;
zx_status_t status = zx::vmar::root_self()->map(
0, resource_vmo.vmo, 0, resource_vmo.size, flags, &addr);
if (status != ZX_OK) {
FML_LOG(ERROR) << "Failed to map " << path << ": "
<< zx_status_get_string(status);
return false;
}
resource.address_ = reinterpret_cast<void*>(addr);
resource.size_ = resource_vmo.size;
return true;
}
MappedResource::~MappedResource() {
if (address_ != nullptr) {
zx::vmar::root_self()->unmap(reinterpret_cast<uintptr_t>(address_), size_);
address_ = nullptr;
size_ = 0;
}
}
} // namespace dart_runner
// 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.
#ifndef APPS_DART_RUNNER_MAPPED_RESOURCE_H_
#define APPS_DART_RUNNER_MAPPED_RESOURCE_H_
#include <fuchsia/mem/cpp/fidl.h>
#include <lib/fdio/namespace.h>
namespace dart_runner {
class MappedResource {
public:
MappedResource() : address_(nullptr), size_(0) {}
MappedResource(MappedResource&& other)
: address_(other.address_), size_(other.size_) {
other.address_ = nullptr;
other.size_ = 0;
}
MappedResource& operator=(MappedResource&& other) {
address_ = other.address_;
size_ = other.size_;
other.address_ = nullptr;
other.size_ = 0;
return *this;
}
~MappedResource();
// Loads the content of a file from the given namespace and maps it into the
// current process's address space. If namespace is null, the fdio "global"
// namespace is used (in which case, ./pkg means the dart_runner's package).
// The content is unmapped when the MappedResource goes out of scope. Returns
// true on success.
static bool LoadFromNamespace(fdio_ns_t* namespc,
const std::string& path,
MappedResource& resource,
bool executable = false);
// Maps a VMO into the current process's address space. The content is
// unmapped when the MappedResource goes out of scope. Returns true on
// success. The path is used only for error messages.
static bool LoadFromVmo(const std::string& path,
fuchsia::mem::Buffer resource_vmo,
MappedResource& resource,
bool executable = false);
const uint8_t* address() const {
return reinterpret_cast<const uint8_t*>(address_);
}
size_t size() const { return size_; }
private:
void* address_;
size_t size_;
// Disallow copy and assignment.
MappedResource(const MappedResource&) = delete;
MappedResource& operator=(const MappedResource&) = delete;
};
} // namespace dart_runner
#endif // APPS_DART_RUNNER_MAPPED_RESOURCE_H_
{
"runner": "fuchsia-pkg://fuchsia.com/dart_aot_product_runner#meta/dart_aot_product_runner.cmx"
}
{
"runner": "fuchsia-pkg://fuchsia.com/dart_aot_runner#meta/dart_aot_runner.cmx"
}
{
"program": {
"data": "data"
},
"sandbox": {
"features": [
"root-ssl-certificates"
],
"services": [
"fuchsia.crash.Analyzer",
"fuchsia.logger.LogSink",
"fuchsia.net.SocketProvider",
"fuchsia.timezone.Timezone",
"fuchsia.tracelink.Registry"
]
}
}
{
"program": {
"data": "data"
},
"sandbox": {
"features": [
"root-ssl-certificates"
],
"services": [
"fuchsia.crash.Analyzer",
"fuchsia.logger.LogSink",
"fuchsia.net.SocketProvider",
"fuchsia.timezone.Timezone",
"fuchsia.tracelink.Registry"
]
}
}
{
"program": {
"data": "data"
},
"sandbox": {
"features": [
"root-ssl-certificates"
],
"services": [
"fuchsia.crash.Analyzer",
"fuchsia.logger.LogSink",
"fuchsia.net.SocketProvider",
"fuchsia.process.Launcher",
"fuchsia.process.Resolver",
"fuchsia.timezone.Timezone",
"fuchsia.tracelink.Registry"
]
}
}
{
"program": {
"data": "data"
},
"sandbox": {
"features": [
"root-ssl-certificates"
],
"services": [
"fuchsia.crash.Analyzer",
"fuchsia.logger.LogSink",
"fuchsia.net.SocketProvider",
"fuchsia.process.Launcher",
"fuchsia.process.Resolver",
"fuchsia.timezone.Timezone",
"fuchsia.tracelink.Registry"
]
}
}
{
"program": {
"data": "data/dart_zircon_test"
},
"sandbox": {
"features": [
"root-ssl-certificates"
],
"services": [
"fuchsia.sys.Environment"
]
}
}
{
"runner": "fuchsia-pkg://fuchsia.com/dart_jit_product_runner#meta/dart_jit_product_runner.cmx"
}
{
"runner": "fuchsia-pkg://fuchsia.com/dart_jit_runner#meta/dart_jit_runner.cmx"
}
// 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/uint8_list.h"
#include "builtin_libraries.h"
#include "dart_component_controller.h"
#include "logging.h"
namespace dart_runner {
namespace {
MappedResource mapped_isolate_snapshot_data;
MappedResource mapped_isolate_snapshot_instructions;
MappedResource mapped_shared_snapshot_data;
MappedResource mapped_shared_snapshot_instructions;
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);
#if defined(AOT_RUNTIME)
// 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 (!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 (!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;
}
#if defined(AOT_RUNTIME)
if (!MappedResource::LoadFromNamespace(
nullptr, "pkg/data/vmservice_shared_snapshot_data.bin",
mapped_shared_snapshot_data)) {
*error = strdup("Failed to load snapshot for service isolate");
FX_LOG(ERROR, LOG_TAG, *error);
return nullptr;
}
if (!MappedResource::LoadFromNamespace(
nullptr, "pkg/data/vmservice_shared_snapshot_instructions.bin",
mapped_shared_snapshot_instructions, true /* executable */)) {
*error = strdup("Failed to load snapshot for service isolate");
FX_LOG(ERROR, LOG_TAG, *error);
return nullptr;
}
#endif
auto state = new std::shared_ptr<tonic::DartState>(new tonic::DartState());
Dart_Isolate isolate = Dart_CreateIsolate(
uri, DART_VM_SERVICE_ISOLATE_NAME, mapped_isolate_snapshot_data.address(),
mapped_isolate_snapshot_instructions.address(),
mapped_shared_snapshot_data.address(),
mapped_shared_snapshot_instructions.address(), nullptr /* flags */, state,
error);
if (!isolate) {
FX_LOGF(ERROR, LOG_TAG, "Dart_CreateIsolate 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() {
MappedResource observatory_tar;
if (!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
// 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.
#ifndef APPS_DART_RUNNER_SERVICE_ISOLATE_H_
#define APPS_DART_RUNNER_SERVICE_ISOLATE_H_
#include "third_party/dart/runtime/include/dart_api.h"
namespace dart_runner {
Dart_Isolate CreateServiceIsolate(const char* uri,
Dart_IsolateFlags* flags,
char** error);
Dart_Handle GetVMServiceAssetsArchiveCallback();
} // namespace dart_runner
#endif // APPS_DART_RUNNER_SERVICE_ISOLATE_H_
# 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.
import("//topaz/runtime/dart_runner/dart_app.gni")
dart_aot_app("vmservice") {
main_dart = "empty.dart"
meta = [
{
path = rebase_path("meta/vmservice.cmx")
dest = "vmservice.cmx"
},
]
source_dir = "."
product = false
sources = []
deps = []
}
# 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: ../../../tools/analysis_options.yaml
// 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.
// This entry point is never invoked. Its purpose is to allow the vmservice's
// Dart code to built with dart_aot_app.
void main(List<String> args) {}
{
"program": {
"data": "data/vmservice"
},
"sandbox": {
"services": [
"fuchsia.cobalt.LoggerFactory",
"fuchsia.fonts.Provider",
"fuchsia.logger.LogSink",
"fuchsia.modular.Clipboard",
"fuchsia.modular.ContextWriter",
"fuchsia.modular.ModuleContext",
"fuchsia.netstack.Netstack",
"fuchsia.sys.Environment",
"fuchsia.ui.input.ImeService",
"fuchsia.ui.policy.Presenter",
"fuchsia.ui.scenic.Scenic",
"fuchsia.wlan.service.Wlan"
]
}
}
\ No newline at end of file
# 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.
......@@ -5,6 +5,8 @@
#ifndef FLUTTER_SHELL_PLATFORM_FUCHSIA_LOGGING_H_
#define FLUTTER_SHELL_PLATFORM_FUCHSIA_LOGGING_H_
#include "flutter/fml/logging.h"
namespace flutter_runner {
// Use to mark logs published via the syslog API.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册