mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Add the c++ code part of bindings2/
This is all the bindings-level dart code we had to write to enable Dart in Sky. We wrote this over the last 2 weeks in: https://github.com/eseidel/skydart R=abarth@chromium.org, jamesr@chromium.org BUG=454613 Review URL: https://codereview.chromium.org/918333002
This commit is contained in:
parent
aa99c2f67b
commit
c7d2352897
399
engine/bindings2/BUILD.gn
Normal file
399
engine/bindings2/BUILD.gn
Normal file
@ -0,0 +1,399 @@
|
||||
# Copyright 2015 The Chromium 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("//sky/engine/bindings2/bindings.gni")
|
||||
import("//sky/engine/core/core.gni")
|
||||
|
||||
source_set("bindings2") {
|
||||
sources = [
|
||||
"builtin.cc",
|
||||
"builtin.h",
|
||||
"builtin_natives.cc",
|
||||
"builtin_natives.h",
|
||||
"builtin_sky.cc",
|
||||
"builtin_sky.h",
|
||||
"dart_callback.cc",
|
||||
"dart_callback.h",
|
||||
"dart_event_listener.cc",
|
||||
"dart_event_listener.h",
|
||||
"exception_messages.cc",
|
||||
"exception_messages.h",
|
||||
"exception_state.cc",
|
||||
"exception_state.h",
|
||||
"exception_state_placeholder.cc",
|
||||
"exception_state_placeholder.h",
|
||||
"mojo_natives.cc",
|
||||
"mojo_natives.h",
|
||||
"nullable.h",
|
||||
"scheduled_action.cc",
|
||||
"scheduled_action.h",
|
||||
]
|
||||
deps = [
|
||||
"//base",
|
||||
"//dart/runtime/bin:libdart_withcore",
|
||||
"//mojo/public/c/system",
|
||||
"//mojo/public/cpp/system",
|
||||
"//sky/engine/platform:platform",
|
||||
"//sky/engine/tonic",
|
||||
"//sky/engine/wtf",
|
||||
":generated_bindings",
|
||||
":snapshot_cc",
|
||||
]
|
||||
include_dirs = [
|
||||
"..",
|
||||
"$root_build_dir",
|
||||
]
|
||||
}
|
||||
|
||||
action("generate_snapshot_bin") {
|
||||
deps = [
|
||||
"//dart/runtime/bin:gen_snapshot($host_toolchain)",
|
||||
":generate_sky_core_dart",
|
||||
]
|
||||
inputs = [
|
||||
"//dart/runtime/tools/create_snapshot_bin.py",
|
||||
"//sky/engine/bindings2/builtin.dart",
|
||||
"//mojo/public/dart/bindings.dart",
|
||||
"//mojo/public/dart/core.dart",
|
||||
"//mojo/public/dart/src/application.dart",
|
||||
"//mojo/public/dart/src/buffer.dart",
|
||||
"//mojo/public/dart/src/codec.dart",
|
||||
"//mojo/public/dart/src/data_pipe.dart",
|
||||
"//mojo/public/dart/src/drain_data.dart",
|
||||
"//mojo/public/dart/src/event_stream.dart",
|
||||
"//mojo/public/dart/src/handle.dart",
|
||||
"//mojo/public/dart/src/handle_watcher.dart",
|
||||
"//mojo/public/dart/src/message.dart",
|
||||
"//mojo/public/dart/src/message_pipe.dart",
|
||||
"//mojo/public/dart/src/proxy.dart",
|
||||
"//mojo/public/dart/src/service_provider.dart",
|
||||
"//mojo/public/dart/src/struct.dart",
|
||||
"//mojo/public/dart/src/stub.dart",
|
||||
"//mojo/public/dart/src/timer_queue.dart",
|
||||
"//mojo/public/dart/src/types.dart",
|
||||
"snapshot.dart",
|
||||
]
|
||||
output = "$target_gen_dir/snapshot_gen.bin"
|
||||
outputs = [
|
||||
output,
|
||||
]
|
||||
|
||||
builtin_path = rebase_path("//sky/engine/bindings2/builtin.dart")
|
||||
sky_core_path = rebase_path("$bindings_output_dir/sky_core.dart")
|
||||
mojo_bindings_path = rebase_path("//mojo/public/dart/bindings.dart")
|
||||
mojo_core_path = rebase_path("//mojo/public/dart/core.dart")
|
||||
|
||||
gen_snapshot_dir =
|
||||
get_label_info("//dart/runtime/bin:gen_snapshot($host_toolchain)",
|
||||
"root_out_dir")
|
||||
script = "//dart/runtime/tools/create_snapshot_bin.py"
|
||||
|
||||
args = [
|
||||
"--executable",
|
||||
rebase_path("$gen_snapshot_dir/gen_snapshot"),
|
||||
"--package_root",
|
||||
rebase_path("$root_gen_dir"),
|
||||
"--script",
|
||||
rebase_path("snapshot.dart"),
|
||||
"--output_bin",
|
||||
rebase_path(output, root_build_dir),
|
||||
"--target_os",
|
||||
os,
|
||||
"--url_mapping=dart:sky,$sky_core_path",
|
||||
"--url_mapping=dart:mojo_bindings,$mojo_bindings_path",
|
||||
"--url_mapping=dart:mojo_core,$mojo_core_path",
|
||||
"--url_mapping=dart:sky_builtin,$builtin_path",
|
||||
]
|
||||
}
|
||||
|
||||
action("generate_snapshot_file") {
|
||||
deps = [
|
||||
":generate_snapshot_bin",
|
||||
]
|
||||
inputs = [
|
||||
"//dart/runtime/tools/create_snapshot_file.py",
|
||||
"snapshot.cc.tmpl",
|
||||
"$target_gen_dir/snapshot_gen.bin",
|
||||
]
|
||||
output = "$target_gen_dir/snapshot.cc"
|
||||
outputs = [
|
||||
output,
|
||||
]
|
||||
|
||||
script = "//dart/runtime/tools/create_snapshot_file.py"
|
||||
args = [
|
||||
"--input_bin",
|
||||
rebase_path("$target_gen_dir/snapshot_gen.bin"),
|
||||
"--input_cc",
|
||||
rebase_path("snapshot.cc.tmpl"),
|
||||
"--output",
|
||||
rebase_path(output),
|
||||
]
|
||||
}
|
||||
|
||||
source_set("snapshot_cc") {
|
||||
sources = [
|
||||
"$target_gen_dir/snapshot.cc",
|
||||
]
|
||||
|
||||
deps = [
|
||||
":generate_snapshot_file",
|
||||
]
|
||||
}
|
||||
|
||||
action("compute_interfaces_info_individual") {
|
||||
sources = core_idl_files + core_dependency_idl_files
|
||||
script = "$bindings_scripts_dir/compute_interfaces_info_individual.py"
|
||||
output_file = "$bindings_output_dir/InterfacesInfoIndividual.pickle"
|
||||
|
||||
# TODO(eseidel): This is no longer needed, could pass these as args.
|
||||
file_list = "$target_gen_dir/${target_name}_file_list.txt"
|
||||
write_file(file_list, rebase_path(sources, root_build_dir))
|
||||
|
||||
# TODO(eseidel): Use depfile instead of this manual list.
|
||||
inputs = [ "$bindings_scripts_dir/utilities.py" ] + sources
|
||||
|
||||
outputs = [
|
||||
file_list,
|
||||
output_file,
|
||||
]
|
||||
|
||||
args = [
|
||||
# TODO(eseidel): Remove component-dir, it is meaningless in sky.
|
||||
"--component-dir",
|
||||
"ignored",
|
||||
"--idl-files-list",
|
||||
rebase_path(file_list, root_build_dir),
|
||||
"--interfaces-info-file",
|
||||
rebase_path(output_file, root_build_dir),
|
||||
|
||||
# TODO(eseidel): only-if-changed is always true, remove
|
||||
"--write-file-only-if-changed=1",
|
||||
]
|
||||
}
|
||||
|
||||
interfaces_info_individual_path =
|
||||
"$bindings_output_dir/InterfacesInfoIndividual.pickle"
|
||||
|
||||
interfaces_info_overall_path =
|
||||
"$bindings_output_dir/InterfacesInfoOverall.pickle"
|
||||
|
||||
action("compute_interfaces_info_overall") {
|
||||
script = "$bindings_scripts_dir/compute_interfaces_info_overall.py"
|
||||
|
||||
inputs = [
|
||||
interfaces_info_individual_path,
|
||||
]
|
||||
outputs = [
|
||||
interfaces_info_overall_path,
|
||||
]
|
||||
|
||||
args = [
|
||||
# TODO(eseidel): only-if-changed is always true, remove
|
||||
"--write-file-only-if-changed=1",
|
||||
"--",
|
||||
]
|
||||
args += rebase_path(inputs, root_build_dir)
|
||||
args += rebase_path(outputs, root_build_dir)
|
||||
|
||||
deps = [
|
||||
":compute_interfaces_info_individual",
|
||||
]
|
||||
}
|
||||
|
||||
# This separate pre-caching step is required to use lex/parse table
|
||||
# caching in PLY, since PLY itself does not check if the cache is
|
||||
# valid, and thus may end up using a stale cache if this step hasn"t
|
||||
# been run to update it.
|
||||
#
|
||||
# This action"s dependencies *is* the cache validation.
|
||||
#
|
||||
# GYP version: scripts.gyp:cached_lex_yacc_tables
|
||||
action("cached_lex_yacc_tables") {
|
||||
script = "scripts/blink_idl_parser.py"
|
||||
|
||||
inputs = idl_lexer_parser_files
|
||||
outputs = [
|
||||
"$bindings_output_dir/lextab.py",
|
||||
"$bindings_output_dir/parsetab.pickle",
|
||||
]
|
||||
|
||||
args = [ rebase_path(bindings_output_dir, root_build_dir) ]
|
||||
}
|
||||
|
||||
# Runs the idl_compiler script over a list of sources.
|
||||
#
|
||||
# Parameters:
|
||||
# sources = list of IDL files to compile
|
||||
# output_dir = string containing the directory to put the output files.
|
||||
template("idl_compiler") {
|
||||
output_dir = invoker.output_dir
|
||||
|
||||
action_foreach(target_name) {
|
||||
# TODO(brettw) GYP adds a "-S before the script name to skip "import site" to
|
||||
# speed up startup. Figure out if we need this and do something similar (not
|
||||
# really expressible in GN now).
|
||||
script = "$bindings_scripts_dir/compiler.py"
|
||||
|
||||
inputs = idl_lexer_parser_files + idl_compiler_files
|
||||
inputs += [
|
||||
"scripts/templates/attributes_cpp.template",
|
||||
"scripts/templates/callback_interface_cpp.template",
|
||||
"scripts/templates/callback_interface_dart.template",
|
||||
"scripts/templates/callback_interface_h.template",
|
||||
"scripts/templates/interface_base_cpp.template",
|
||||
"scripts/templates/interface_cpp.template",
|
||||
"scripts/templates/interface_dart.template",
|
||||
"scripts/templates/interface_h.template",
|
||||
"scripts/templates/methods_cpp.template",
|
||||
]
|
||||
inputs += [
|
||||
"$bindings_output_dir/lextab.py",
|
||||
"$bindings_output_dir/parsetab.pickle",
|
||||
|
||||
# "$bindings_output_dir/cached_jinja_templates.stamp",
|
||||
"//sky/engine/bindings2/IDLExtendedAttributes.txt",
|
||||
|
||||
# If the dependency structure or public interface info (e.g.,
|
||||
# [ImplementedAs]) changes, we rebuild all files, since we"re not
|
||||
# computing dependencies file-by-file in the build.
|
||||
# This data is generally stable.
|
||||
interfaces_info_overall_path,
|
||||
]
|
||||
|
||||
# Further, if any dependency (partial interface or implemented
|
||||
# interface) changes, rebuild everything, since every IDL potentially
|
||||
# depends on them, because we"re not computing dependencies
|
||||
# file-by-file.
|
||||
# FIXME: This is too conservative, and causes excess rebuilds:
|
||||
# compute this file-by-file. http://crbug.com/341748
|
||||
# This should theoretically just be the IDL files passed in.
|
||||
inputs += core_dependency_idl_files
|
||||
|
||||
sources = invoker.sources
|
||||
outputs = [
|
||||
"$output_dir/Dart{{source_name_part}}.cpp",
|
||||
"$output_dir/Dart{{source_name_part}}.h",
|
||||
"$output_dir/{{source_name_part}}.dart",
|
||||
]
|
||||
|
||||
args = [
|
||||
"--output-dir",
|
||||
rebase_path(output_dir, root_build_dir),
|
||||
"--interfaces-info",
|
||||
rebase_path(interfaces_info_overall_path, root_build_dir),
|
||||
"--write-file-only-if-changed=1", # Always true for Ninja.
|
||||
"{{source}}",
|
||||
]
|
||||
|
||||
deps = [
|
||||
":compute_interfaces_info_overall",
|
||||
":cached_lex_yacc_tables",
|
||||
|
||||
# ":cached_jinja_templates",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
idl_compiler("compile_idls") {
|
||||
sources = core_idl_files
|
||||
output_dir = bindings_output_dir
|
||||
}
|
||||
|
||||
action("generate_dart_globals") {
|
||||
sources = core_idl_files
|
||||
script = "$bindings_scripts_dir/compiler.py"
|
||||
|
||||
file_list = "$target_gen_dir/${target_name}_file_list.txt"
|
||||
write_file(file_list, rebase_path(sources, root_build_dir))
|
||||
|
||||
inputs = sources + idl_compiler_files
|
||||
inputs += [
|
||||
"scripts/templates/global_cpp.template",
|
||||
"scripts/templates/global_h.template",
|
||||
]
|
||||
|
||||
outputs = [
|
||||
file_list,
|
||||
"$bindings_output_dir/DartGlobal.h",
|
||||
"$bindings_output_dir/DartGlobal.cpp",
|
||||
]
|
||||
|
||||
args = [
|
||||
"--output-directory",
|
||||
rebase_path(bindings_output_dir, root_build_dir),
|
||||
"--generate-globals",
|
||||
rebase_path(bindings_output_dir, root_build_dir),
|
||||
rebase_path(file_list, root_build_dir),
|
||||
]
|
||||
|
||||
deps = [
|
||||
":compile_idls",
|
||||
]
|
||||
}
|
||||
|
||||
action("generate_sky_core_dart") {
|
||||
sources = core_idl_files
|
||||
script = "$bindings_scripts_dir/compiler.py"
|
||||
|
||||
file_list = "$target_gen_dir/${target_name}_file_list.txt"
|
||||
write_file(file_list, rebase_path(sources, root_build_dir))
|
||||
|
||||
inputs =
|
||||
sources + idl_compiler_files + [ "scripts/templates/dart_blink.template" ]
|
||||
|
||||
outputs = [
|
||||
file_list,
|
||||
"$bindings_output_dir/sky_core.dart",
|
||||
]
|
||||
|
||||
args = [
|
||||
"--output-directory",
|
||||
rebase_path(bindings_output_dir, root_build_dir),
|
||||
"--generate-dart-blink",
|
||||
rebase_path(bindings_output_dir, root_build_dir),
|
||||
rebase_path(file_list, root_build_dir),
|
||||
]
|
||||
|
||||
deps = [
|
||||
":compile_idls",
|
||||
]
|
||||
}
|
||||
|
||||
source_set("generated_bindings") {
|
||||
deps = [
|
||||
"//base",
|
||||
"//dart/runtime/bin:libdart_withcore",
|
||||
"//gpu/command_buffer/client:gles2_c_lib",
|
||||
"//mojo/application",
|
||||
"//mojo/common",
|
||||
"//mojo/edk/js",
|
||||
"//mojo/public/c/system",
|
||||
"//mojo/public/cpp/bindings",
|
||||
"//mojo/public/cpp/system",
|
||||
"//mojo/public/cpp/utility",
|
||||
"//mojo/public/interfaces/application",
|
||||
"//mojo/services/keyboard/public/interfaces",
|
||||
"//mojo/services/navigation/public/interfaces",
|
||||
"//mojo/services/view_manager/public/cpp",
|
||||
"//skia",
|
||||
"//sky/engine/wtf",
|
||||
"//third_party/angle:translator",
|
||||
"//third_party/iccjpeg",
|
||||
"//third_party/libpng",
|
||||
"//third_party/ots",
|
||||
"//third_party/qcms",
|
||||
"//third_party/zlib",
|
||||
"//url",
|
||||
":generate_dart_globals",
|
||||
]
|
||||
|
||||
include_dirs = [
|
||||
"..",
|
||||
"$root_build_dir",
|
||||
]
|
||||
|
||||
sources = get_target_outputs(":compile_idls")
|
||||
sources += get_target_outputs(":generate_dart_globals")
|
||||
}
|
||||
81
engine/bindings2/IDLExtendedAttributes.txt
Normal file
81
engine/bindings2/IDLExtendedAttributes.txt
Normal file
@ -0,0 +1,81 @@
|
||||
#
|
||||
# This file describes all Blink IDL extended attributes and allowed values.
|
||||
# If any IDL file uses an extended attribute or values not listed below, the
|
||||
# build will fail.
|
||||
# If you would like to add a new extended attribute or value, please:
|
||||
# (1) add the extended attribute or value to this file
|
||||
# (2) add an explanation to the Blink IDL extended attributes document:
|
||||
# http://www.chromium.org/blink/webidl/blink-idl-extended-attributes
|
||||
# (3) add appropriate test cases to run-bindings-tests
|
||||
#
|
||||
# The syntax of this file is as follows:
|
||||
# - One extended attribute per one line: Name and (optionally) Values.
|
||||
# - "Attr" means that the Attr does not take a value, i.e. [Attr].
|
||||
# - "Attr=X" means that Attr takes a required value, which must be X;
|
||||
# i.e. [Attr=X].
|
||||
# - "Attr=X|Y|Z" means that Attr takes a required value, and the valid
|
||||
# values are X, Y, and Z, and combinations thereof;
|
||||
# e.g. [Attr=X], [Attr=Y], [Attr=X|Z].
|
||||
# The separator must be | or &, so [Attr=X&Z] is also valid; the
|
||||
# separator makes a difference for Conditional, but otherwise is simply
|
||||
# a style convention.
|
||||
# - "Attr=|X|Y|Z" means that Attr takes an optional value, whose valid
|
||||
# values (if present) are X, Y, and Z, and combinations thereof; e.g.
|
||||
# [Attr], [Attr=X], [Attr=Y], [Attr=X|Z], [Attr=X|Y|Z], [Attr=X&Z].
|
||||
# Note that including an empty value in the list, as in [Attr=X||Y],
|
||||
# is NOT valid: the value is optional, but empty values are not allowed.
|
||||
# - "Attr=*" means that Attr takes a required value, which can be
|
||||
# arbitrary, and combinations thereof, e.g. [Attr=IndexedDB],
|
||||
# [Attr=DeleteFunction], [Attr=X|Y].
|
||||
# - "Attr=|*" means that Attr takes an optional value, which can be
|
||||
# arbitrary, e.g. [Attr], [Attr=X].
|
||||
# - "Attr=X|*" means that Attr takes an required value, which can be
|
||||
# arbitrary, but that "X" is standard, e.g. [Attr=X], [Attr=Foo].
|
||||
#
|
||||
|
||||
ActiveDOMObject
|
||||
CachedAttribute=*
|
||||
CallWith=ExecutionContext|ScriptState|ScriptArguments|ActiveWindow|FirstWindow|ThisValue
|
||||
Constructor
|
||||
# FIXME: remove [ConstructorCallWith=Document], as can instead use
|
||||
# [ConstructorCallWith=ExecutionContext] + toDocument(executionContext)
|
||||
ConstructorCallWith=ExecutionContext|Document
|
||||
Custom=|Getter|Setter|VisitDOMWrapper|Wrap|PropertyGetter|PropertyEnumerator|PropertyQuery
|
||||
CustomConstructor
|
||||
CustomElementCallbacks
|
||||
Default=Undefined
|
||||
DependentLifetime
|
||||
DoNotCheckConstants
|
||||
EnforceRange
|
||||
EventConstructor
|
||||
Exposed=*
|
||||
Global=|*
|
||||
Immutable
|
||||
ImplementedAs=*
|
||||
InitializedByEventConstructor
|
||||
Iterable
|
||||
LegacyTreatAsPartialInterface
|
||||
NamedConstructor=*
|
||||
NoImplHeader
|
||||
NoInterfaceObject
|
||||
NotEnumerable
|
||||
NotScriptWrappable
|
||||
OverrideBuiltins
|
||||
PartialInterfaceImplementedAs=*
|
||||
PutForwards=*
|
||||
RaisesException=|Getter|Setter|Constructor
|
||||
Reflect=|*
|
||||
ReflectEmpty=*
|
||||
ReflectInvalid=*
|
||||
ReflectMissing=*
|
||||
ReflectOnly=*
|
||||
Replaceable
|
||||
SetWrapperReferenceFrom=*
|
||||
SetWrapperReferenceTo=*
|
||||
SetterCallWith=ExecutionContext|ScriptArguments|ActiveWindow|FirstWindow
|
||||
SpecialWrapFor=*
|
||||
TreatNullAs=NullString|EmptyString
|
||||
TreatReturnedNullStringAs=Null|Undefined
|
||||
TreatUndefinedAs=NullString
|
||||
TypeChecking=Interface|Unrestricted
|
||||
URL
|
||||
50
engine/bindings2/bindings.gni
Normal file
50
engine/bindings2/bindings.gni
Normal file
@ -0,0 +1,50 @@
|
||||
# Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
bindings_scripts_dir = "//sky/engine/bindings2/scripts"
|
||||
bindings_output_dir = "$root_gen_dir/sky/bindings"
|
||||
|
||||
idl_lexer_parser_files = [
|
||||
# PLY (Python Lex-Yacc)
|
||||
"//third_party/ply/lex.py",
|
||||
"//third_party/ply/yacc.py",
|
||||
|
||||
# Web IDL lexer/parser (base parser)
|
||||
"//tools/idl_parser/idl_lexer.py",
|
||||
"//tools/idl_parser/idl_node.py",
|
||||
"//tools/idl_parser/idl_parser.py",
|
||||
|
||||
# Blink IDL lexer/parser/constructor
|
||||
"scripts/blink_idl_lexer.py",
|
||||
"scripts/blink_idl_parser.py",
|
||||
]
|
||||
|
||||
idl_compiler_files = [
|
||||
"scripts/compiler.py",
|
||||
|
||||
# Blink IDL front end (ex-lexer/parser)
|
||||
"scripts/idl_definitions.py",
|
||||
"scripts/idl_reader.py",
|
||||
"scripts/idl_types.py",
|
||||
"scripts/idl_validator.py",
|
||||
"scripts/interface_dependency_resolver.py",
|
||||
|
||||
# Dart Code gen goes here.
|
||||
"scripts/dart_attributes.py",
|
||||
"scripts/dart_callback_interface.py",
|
||||
"scripts/dart_compiler.py",
|
||||
"scripts/dart_interface.py",
|
||||
"scripts/dart_methods.py",
|
||||
"scripts/dart_types.py",
|
||||
"scripts/dart_utilities.py",
|
||||
"scripts/code_generator_dart.py",
|
||||
|
||||
# The dart files depend on the v8 files. :(
|
||||
"scripts/v8_attributes.py",
|
||||
"scripts/v8_globals.py",
|
||||
"scripts/v8_interface.py",
|
||||
"scripts/v8_methods.py",
|
||||
"scripts/v8_types.py",
|
||||
"scripts/v8_utilities.py",
|
||||
]
|
||||
60
engine/bindings2/builtin.cc
Normal file
60
engine/bindings2/builtin.cc
Normal file
@ -0,0 +1,60 @@
|
||||
// Copyright 2015 The Chromium 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 "sky/engine/config.h"
|
||||
#include "sky/engine/bindings2/builtin.h"
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "dart/runtime/include/dart_api.h"
|
||||
#include "gen/sky/bindings/DartGlobal.h"
|
||||
#include "sky/engine/bindings2/builtin_natives.h"
|
||||
#include "sky/engine/bindings2/builtin_sky.h"
|
||||
#include "sky/engine/bindings2/mojo_natives.h"
|
||||
|
||||
namespace blink {
|
||||
namespace {
|
||||
|
||||
struct LibraryDescriptor {
|
||||
const char* url;
|
||||
bool has_natives;
|
||||
Dart_NativeEntrySymbol native_symbol;
|
||||
Dart_NativeEntryResolver native_resolver;
|
||||
};
|
||||
|
||||
const LibraryDescriptor kBuiltinLibraries[] = {
|
||||
/* { url_, has_natives_, native_symbol_, native_resolver_ } */
|
||||
{"dart:sky_builtin", true, BuiltinNatives::NativeSymbol, BuiltinNatives::NativeLookup},
|
||||
{"dart:sky", true, skySnapshotSymbolizer, skySnapshotResolver},
|
||||
{"dart:mojo_bindings", false, nullptr, nullptr},
|
||||
{"dart:mojo_core", true, MojoNativeSymbol, MojoNativeLookup},
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
void Builtin::SetNativeResolver(BuiltinLibraryId id) {
|
||||
static_assert(arraysize(kBuiltinLibraries) == kInvalidLibrary,
|
||||
"Unexpected number of builtin libraries");
|
||||
DCHECK_GE(id, kBuiltinLibrary);
|
||||
DCHECK_LT(id, kInvalidLibrary);
|
||||
if (kBuiltinLibraries[id].has_natives) {
|
||||
Dart_Handle library = DartBuiltin::LookupLibrary(kBuiltinLibraries[id].url);
|
||||
// Setup the native resolver for built in library functions.
|
||||
DART_CHECK_VALID(
|
||||
Dart_SetNativeResolver(library,
|
||||
kBuiltinLibraries[id].native_resolver,
|
||||
kBuiltinLibraries[id].native_symbol));
|
||||
}
|
||||
}
|
||||
|
||||
Dart_Handle Builtin::LoadAndCheckLibrary(BuiltinLibraryId id) {
|
||||
static_assert(arraysize(kBuiltinLibraries) == kInvalidLibrary,
|
||||
"Unexpected number of builtin libraries");
|
||||
DCHECK_GE(id, kBuiltinLibrary);
|
||||
DCHECK_LT(id, kInvalidLibrary);
|
||||
Dart_Handle library = DartBuiltin::LookupLibrary(kBuiltinLibraries[id].url);
|
||||
DART_CHECK_VALID(library);
|
||||
return library;
|
||||
}
|
||||
|
||||
} // namespace blink
|
||||
53
engine/bindings2/builtin.dart
Normal file
53
engine/bindings2/builtin.dart
Normal file
@ -0,0 +1,53 @@
|
||||
// Copyright 2014 The Chromium 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 sky_builtin;
|
||||
|
||||
import "dart:async";
|
||||
|
||||
// Corelib 'print' implementation.
|
||||
void _print(arg) {
|
||||
_Logger._printString(arg.toString());
|
||||
}
|
||||
|
||||
class _Logger {
|
||||
static void _printString(String s) native "Logger_PrintString";
|
||||
}
|
||||
|
||||
class _Timer implements Timer {
|
||||
_Timer(int milliseconds,
|
||||
void callback(Timer timer),
|
||||
bool repeating) {
|
||||
_id = _create(milliseconds, () {
|
||||
if (!repeating)
|
||||
_id = 0;
|
||||
callback(this);
|
||||
}, repeating);
|
||||
}
|
||||
|
||||
void cancel() {
|
||||
_cancel(_id);
|
||||
_id = 0;
|
||||
}
|
||||
|
||||
bool get isActive => _id != 0;
|
||||
|
||||
static int _create(int milliseconds,
|
||||
void callback(),
|
||||
bool repeating) native "Timer_create";
|
||||
static void _cancel(int id) native "Timer_cancel";
|
||||
|
||||
int _id;
|
||||
}
|
||||
|
||||
void _scheduleMicrotask(void callback()) native "ScheduleMicrotask";
|
||||
Timer _createTimer(int milliseconds,
|
||||
void callback(Timer timer),
|
||||
bool repeating) {
|
||||
return new _Timer(milliseconds, callback, repeating);
|
||||
}
|
||||
|
||||
_getPrintClosure() => _print;
|
||||
_getScheduleMicrotaskClosure() => _scheduleMicrotask;
|
||||
_getCreateTimerClosure() => _createTimer;
|
||||
34
engine/bindings2/builtin.h
Normal file
34
engine/bindings2/builtin.h
Normal file
@ -0,0 +1,34 @@
|
||||
// Copyright 2015 The Chromium 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 SKY_ENGINE_BINDINGS2_BUILTIN_H_
|
||||
#define SKY_ENGINE_BINDINGS2_BUILTIN_H_
|
||||
|
||||
#include "base/macros.h"
|
||||
#include "dart/runtime/include/dart_api.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
class Builtin {
|
||||
public:
|
||||
// Note: Changes to this enum should be accompanied with changes to
|
||||
// the builtin_libraries_ array in builtin.cc.
|
||||
enum BuiltinLibraryId {
|
||||
kBuiltinLibrary,
|
||||
kSkyLibrary,
|
||||
kMojoBindingsLibrary,
|
||||
kMojoCoreLibrary,
|
||||
kInvalidLibrary,
|
||||
};
|
||||
|
||||
static void SetNativeResolver(BuiltinLibraryId id);
|
||||
static Dart_Handle LoadAndCheckLibrary(BuiltinLibraryId id);
|
||||
|
||||
private:
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(Builtin);
|
||||
};
|
||||
|
||||
} // namespace blink
|
||||
|
||||
#endif // SKY_ENGINE_BINDINGS2_BUILTIN_H_
|
||||
184
engine/bindings2/builtin_natives.cc
Normal file
184
engine/bindings2/builtin_natives.cc
Normal file
@ -0,0 +1,184 @@
|
||||
// Copyright 2014 The Chromium 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 "sky/engine/config.h"
|
||||
#include "sky/engine/bindings2/builtin_natives.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/macros.h"
|
||||
#include "dart/runtime/include/dart_api.h"
|
||||
#include "sky/engine/bindings2/builtin.h"
|
||||
#include "sky/engine/core/dom/Microtask.h"
|
||||
#include "sky/engine/core/script/dom_dart_state.h"
|
||||
#include "sky/engine/tonic/dart_api_scope.h"
|
||||
#include "sky/engine/tonic/dart_error.h"
|
||||
#include "sky/engine/tonic/dart_isolate_scope.h"
|
||||
#include "sky/engine/tonic/dart_state.h"
|
||||
#include "sky/engine/tonic/dart_value.h"
|
||||
#include "sky/engine/wtf/text/WTFString.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
#define REGISTER_FUNCTION(name, count) \
|
||||
{ "" #name, name, count },
|
||||
#define DECLARE_FUNCTION(name, count) \
|
||||
extern void name(Dart_NativeArguments args);
|
||||
|
||||
// Lists the native functions implementing basic functionality in
|
||||
// the Mojo embedder dart, such as printing, and file I/O.
|
||||
#define BUILTIN_NATIVE_LIST(V) \
|
||||
V(Logger_PrintString, 1) \
|
||||
V(ScheduleMicrotask, 1) \
|
||||
V(Timer_create, 3) \
|
||||
V(Timer_cancel, 1)
|
||||
|
||||
BUILTIN_NATIVE_LIST(DECLARE_FUNCTION);
|
||||
|
||||
static struct NativeEntries {
|
||||
const char* name;
|
||||
Dart_NativeFunction function;
|
||||
int argument_count;
|
||||
} BuiltinEntries[] = {BUILTIN_NATIVE_LIST(REGISTER_FUNCTION)};
|
||||
|
||||
Dart_NativeFunction BuiltinNatives::NativeLookup(Dart_Handle name,
|
||||
int argument_count,
|
||||
bool* auto_setup_scope) {
|
||||
const char* function_name = nullptr;
|
||||
Dart_Handle result = Dart_StringToCString(name, &function_name);
|
||||
DART_CHECK_VALID(result);
|
||||
DCHECK(function_name != nullptr);
|
||||
DCHECK(auto_setup_scope != nullptr);
|
||||
*auto_setup_scope = true;
|
||||
size_t num_entries = arraysize(BuiltinEntries);
|
||||
for (size_t i = 0; i < num_entries; i++) {
|
||||
const struct NativeEntries& entry = BuiltinEntries[i];
|
||||
if (!strcmp(function_name, entry.name) &&
|
||||
(entry.argument_count == argument_count)) {
|
||||
return entry.function;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const uint8_t* BuiltinNatives::NativeSymbol(Dart_NativeFunction native_function) {
|
||||
size_t num_entries = arraysize(BuiltinEntries);
|
||||
for (size_t i = 0; i < num_entries; i++) {
|
||||
const struct NativeEntries& entry = BuiltinEntries[i];
|
||||
if (entry.function == native_function) {
|
||||
return reinterpret_cast<const uint8_t*>(entry.name);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static Dart_Handle GetClosure(Dart_Handle builtin_library, const char* name) {
|
||||
Dart_Handle getter_name = ToDart(name);
|
||||
Dart_Handle closure = Dart_Invoke(builtin_library, getter_name, 0, nullptr);
|
||||
DART_CHECK_VALID(closure);
|
||||
return closure;
|
||||
}
|
||||
|
||||
static void InitDartInternal(Dart_Handle builtin_library) {
|
||||
Dart_Handle print = GetClosure(builtin_library, "_getPrintClosure");
|
||||
Dart_Handle timer = GetClosure(builtin_library, "_getCreateTimerClosure");
|
||||
|
||||
Dart_Handle internal_library = DartBuiltin::LookupLibrary("dart:_internal")
|
||||
|
||||
DART_CHECK_VALID(Dart_SetField(
|
||||
internal_library, ToDart("_printClosure"), print));
|
||||
|
||||
Dart_Handle vm_hooks_name = ToDart("VMLibraryHooks");
|
||||
Dart_Handle vm_hooks = Dart_GetClass(internal_library, vm_hooks_name);
|
||||
DART_CHECK_VALID(vm_hooks);
|
||||
Dart_Handle timer_name = ToDart("timerFactory");
|
||||
DART_CHECK_VALID(Dart_SetField(vm_hooks, timer_name, timer));
|
||||
}
|
||||
|
||||
static void InitAsync(Dart_Handle builtin_library) {
|
||||
Dart_Handle schedule_microtask =
|
||||
GetClosure(builtin_library, "_getScheduleMicrotaskClosure");
|
||||
Dart_Handle internal_library = DartBuiltin::LookupLibrary("dart:async")
|
||||
Dart_Handle set_schedule_microtask = ToDart("_setScheduleImmediateClosure");
|
||||
DART_CHECK_VALID(Dart_Invoke(async_library, set_schedule_microtask, 1,
|
||||
&schedule_microtask));
|
||||
}
|
||||
|
||||
void BuiltinNatives::Init() {
|
||||
Dart_Handle builtin = Builtin::LoadAndCheckLibrary(Builtin::kBuiltinLibrary);
|
||||
DART_CHECK_VALID(builtin);
|
||||
InitDartInternal(builtin);
|
||||
InitAsync(builtin);
|
||||
}
|
||||
|
||||
// Implementation of native functions which are used for some
|
||||
// test/debug functionality in standalone dart mode.
|
||||
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 {
|
||||
|
||||
String message(chars, length);
|
||||
// TODO(dart): Hook up to developer console (if/when that's a thing).
|
||||
#if OS(ANDROID)
|
||||
LOG(INFO) << "CONSOLE: " << message.utf8().data();
|
||||
#else
|
||||
printf("CONSOLE: %s\n", message.utf8().data());
|
||||
fflush(stdout);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static void ExecuteMicrotask(base::WeakPtr<DartState> dart_state,
|
||||
RefPtr<DartValue> callback) {
|
||||
if (!dart_state)
|
||||
return;
|
||||
DartIsolateScope scope(dart_state->isolate());
|
||||
DartApiScope api_scope;
|
||||
LogIfError(Dart_InvokeClosure(callback->dart_value(), 0, nullptr));
|
||||
}
|
||||
|
||||
void ScheduleMicrotask(Dart_NativeArguments args) {
|
||||
Dart_Handle closure = Dart_GetNativeArgument(args, 0);
|
||||
if (LogIfError(closure) || !Dart_IsClosure(closure))
|
||||
return;
|
||||
DartState* dart_state = DartState::Current();
|
||||
Microtask::enqueueMicrotask(base::Bind(&ExecuteMicrotask,
|
||||
dart_state->GetWeakPtr(), DartValue::Create(dart_state, closure)));
|
||||
}
|
||||
|
||||
void Timer_create(Dart_NativeArguments args) {
|
||||
int64_t milliseconds = 0;
|
||||
DART_CHECK_VALID(Dart_GetNativeIntegerArgument(args, 0, &milliseconds));
|
||||
Dart_Handle closure = Dart_GetNativeArgument(args, 1);
|
||||
DART_CHECK_VALID(closure);
|
||||
CHECK(Dart_IsClosure(closure));
|
||||
bool repeating = false;
|
||||
DART_CHECK_VALID(Dart_GetNativeBooleanArgument(args, 2, &repeating));
|
||||
|
||||
DOMDartState* state = DOMDartState::Current();
|
||||
int timer_id = DOMTimer::install(state->document(),
|
||||
ScheduledAction::Create(state, closure),
|
||||
milliseconds,
|
||||
!repeating);
|
||||
Dart_SetIntegerReturnValue(args, timer_id);
|
||||
}
|
||||
|
||||
void Timer_cancel(Dart_NativeArguments args) {
|
||||
int64_t timer_id = 0;
|
||||
DART_CHECK_VALID(Dart_GetNativeIntegerArgument(args, 0, &timer_id));
|
||||
|
||||
DOMDartState* state = DOMDartState::Current();
|
||||
DOMTimer::removeByID(state->document(), timer_id);
|
||||
}
|
||||
|
||||
} // namespace blink
|
||||
28
engine/bindings2/builtin_natives.h
Normal file
28
engine/bindings2/builtin_natives.h
Normal file
@ -0,0 +1,28 @@
|
||||
// Copyright 2014 The Chromium 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 SKY_ENGINE_BINDINGS2_BUILTIN_NATIVES_H_
|
||||
#define SKY_ENGINE_BINDINGS2_BUILTIN_NATIVES_H_
|
||||
|
||||
#include "base/macros.h"
|
||||
#include "dart/runtime/include/dart_api.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
class BuiltinNatives {
|
||||
public:
|
||||
static Dart_NativeFunction NativeLookup(Dart_Handle name,
|
||||
int argument_count,
|
||||
bool* auto_setup_scope);
|
||||
static const uint8_t* NativeSymbol(Dart_NativeFunction native_function);
|
||||
|
||||
static void Init();
|
||||
|
||||
private:
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(BuiltinNatives);
|
||||
};
|
||||
|
||||
} // namespace blink
|
||||
|
||||
#endif // SKY_ENGINE_BINDINGS2_BUILTIN_NATIVES_H_
|
||||
37
engine/bindings2/builtin_sky.cc
Normal file
37
engine/bindings2/builtin_sky.cc
Normal file
@ -0,0 +1,37 @@
|
||||
// Copyright 2014 The Chromium 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 "sky/engine/config.h"
|
||||
#include "sky/engine/bindings2/builtin_sky.h"
|
||||
|
||||
#include "sky/engine/bindings2/builtin.h"
|
||||
#include "sky/engine/core/frame/LocalDOMWindow.h"
|
||||
#include "sky/engine/core/script/dom_dart_state.h"
|
||||
#include "sky/engine/tonic/dart_error.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
BuiltinSky::BuiltinSky(DOMDartState* dart_state) {
|
||||
Builtin::SetNativeResolver(Builtin::kSkyLibrary);
|
||||
library_.Set(dart_state, Builtin::LoadAndCheckLibrary(Builtin::kSkyLibrary));
|
||||
}
|
||||
|
||||
BuiltinSky::~BuiltinSky() {
|
||||
}
|
||||
|
||||
void BuiltinSky::InstallWindow(DOMDartState* dart_state) {
|
||||
CHECK(!LogIfError(Dart_SetField(library_.value(),
|
||||
ToDart("window"),
|
||||
ToDart(dart_state->CurrentWindow()))));
|
||||
// TODO(abarth): Retain the document wrapper.
|
||||
}
|
||||
|
||||
Dart_Handle BuiltinSky::GetClassByName(const char* class_name) {
|
||||
Dart_Handle name_handle = ToDart(class_name);
|
||||
Dart_Handle class_handle = Dart_GetType(library_.value(), name_handle, 0, nullptr);
|
||||
DCHECK(!Dart_IsError(class_handle)) << class_name;
|
||||
return class_handle;
|
||||
}
|
||||
|
||||
} // namespace blink
|
||||
34
engine/bindings2/builtin_sky.h
Normal file
34
engine/bindings2/builtin_sky.h
Normal file
@ -0,0 +1,34 @@
|
||||
// Copyright 2014 The Chromium 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 SKY_ENGINE_BINDINGS2_BUILTIN_SKY_H_
|
||||
#define SKY_ENGINE_BINDINGS2_BUILTIN_SKY_H_
|
||||
|
||||
#include "base/macros.h"
|
||||
#include "dart/runtime/include/dart_api.h"
|
||||
#include "sky/engine/tonic/dart_class_provider.h"
|
||||
#include "sky/engine/tonic/dart_persistent_value.h"
|
||||
|
||||
namespace blink {
|
||||
class DOMDartState;
|
||||
|
||||
class BuiltinSky : public DartClassProvider {
|
||||
public:
|
||||
explicit BuiltinSky(DOMDartState* dart_state);
|
||||
~BuiltinSky();
|
||||
|
||||
void InstallWindow(DOMDartState* dart_state);
|
||||
|
||||
// DartClassProvider:
|
||||
Dart_Handle GetClassByName(const char* class_name) override;
|
||||
|
||||
private:
|
||||
DartPersistentValue library_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(BuiltinSky);
|
||||
};
|
||||
|
||||
} // namespace blink
|
||||
|
||||
#endif // SKY_ENGINE_BINDINGS2_BUILTIN_SKY_H_
|
||||
39
engine/bindings2/dart_callback.cc
Normal file
39
engine/bindings2/dart_callback.cc
Normal file
@ -0,0 +1,39 @@
|
||||
// Copyright 2015 The Chromium 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 "sky/engine/config.h"
|
||||
#include "sky/engine/bindings2/dart_callback.h"
|
||||
|
||||
#include "sky/engine/tonic/dart_error.h"
|
||||
#include "sky/engine/tonic/dart_state.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
DartCallback::DartCallback(DartState* dart_state,
|
||||
Dart_Handle callback,
|
||||
Dart_Handle& exception)
|
||||
: callback_(dart_state, callback) {
|
||||
if (!Dart_IsClosure(callback)) {
|
||||
exception = ToDart("Callback must be a function");
|
||||
callback_.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
DartCallback::~DartCallback() {
|
||||
}
|
||||
|
||||
bool DartCallback::IsIsolateAlive() const {
|
||||
return !!callback_.dart_state();
|
||||
}
|
||||
|
||||
Dart_Isolate DartCallback::GetIsolate() const {
|
||||
return callback_.dart_state()->isolate();
|
||||
}
|
||||
|
||||
bool DartCallback::handleEvent(int argc, Dart_Handle* argv) {
|
||||
LogIfError(Dart_InvokeClosure(callback_.value(), argc, argv));
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace blink
|
||||
30
engine/bindings2/dart_callback.h
Normal file
30
engine/bindings2/dart_callback.h
Normal file
@ -0,0 +1,30 @@
|
||||
// Copyright 2015 The Chromium 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 SKY_ENGINE_BINDINGS2_DART_CALLBACK_H_
|
||||
#define SKY_ENGINE_BINDINGS2_DART_CALLBACK_H_
|
||||
|
||||
#include "dart/runtime/include/dart_api.h"
|
||||
#include "sky/engine/tonic/dart_persistent_value.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
class DartCallback {
|
||||
public:
|
||||
DartCallback(DartState* dart_state,
|
||||
Dart_Handle callback,
|
||||
Dart_Handle& exception);
|
||||
~DartCallback();
|
||||
|
||||
bool handleEvent(int argc, Dart_Handle* argv);
|
||||
|
||||
bool IsIsolateAlive() const;
|
||||
Dart_Isolate GetIsolate() const;
|
||||
|
||||
private:
|
||||
DartPersistentValue callback_;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // SKY_ENGINE_BINDINGS2_DART_CALLBACK_H_
|
||||
69
engine/bindings2/dart_event_listener.cc
Normal file
69
engine/bindings2/dart_event_listener.cc
Normal file
@ -0,0 +1,69 @@
|
||||
// Copyright 2015 The Chromium 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 "sky/engine/config.h"
|
||||
#include "sky/engine/bindings2/dart_event_listener.h"
|
||||
|
||||
#include "sky/engine/core/events/Event.h"
|
||||
#include "sky/engine/tonic/dart_api_scope.h"
|
||||
#include "sky/engine/tonic/dart_error.h"
|
||||
#include "sky/engine/tonic/dart_gc_visitor.h"
|
||||
#include "sky/engine/tonic/dart_isolate_scope.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
PassRefPtr<DartEventListener> DartEventListener::FromDart(Dart_Handle handle) {
|
||||
if (!Dart_IsClosure(handle))
|
||||
return nullptr;
|
||||
void* peer = nullptr;
|
||||
CHECK(!Dart_IsError(Dart_GetPeer(handle, &peer)));
|
||||
if (DartEventListener* listener = static_cast<DartEventListener*>(peer))
|
||||
return listener;
|
||||
RefPtr<DartEventListener> listener = adoptRef(new DartEventListener(handle));
|
||||
listener->data_state_ = DartState::Current()->GetWeakPtr();
|
||||
DCHECK(Dart_IsClosure(handle));
|
||||
listener->ref(); // Balanced in Finalize
|
||||
listener->closure_ = Dart_NewPrologueWeakPersistentHandle(
|
||||
handle, listener.get(), sizeof(*listener), &DartEventListener::Finalize);
|
||||
CHECK(!Dart_IsError(Dart_SetPeer(handle, listener.get())));
|
||||
return listener.release();
|
||||
}
|
||||
|
||||
DartEventListener::DartEventListener(Dart_Handle handle) : closure_(nullptr) {
|
||||
}
|
||||
|
||||
DartEventListener::~DartEventListener() {
|
||||
}
|
||||
|
||||
void DartEventListener::handleEvent(ExecutionContext* context, Event* event) {
|
||||
if (!closure_ || !data_state_)
|
||||
return;
|
||||
|
||||
DartIsolateScope scope(data_state_->isolate());
|
||||
DartApiScope api_scope;
|
||||
|
||||
// Notice that we protect ourselves as well as the closure object in the VM.
|
||||
RefPtr<DartEventListener> protect(this);
|
||||
Dart_Handle closure_handle = Dart_HandleFromWeakPersistent(closure_);
|
||||
Dart_Handle event_handle = ToDart(event);
|
||||
DCHECK(event_handle);
|
||||
|
||||
Dart_Handle params[] = {event_handle};
|
||||
LogIfError(Dart_InvokeClosure(closure_handle, arraysize(params), params));
|
||||
}
|
||||
|
||||
void DartEventListener::AcceptDartGCVisitor(DartGCVisitor& visitor) const {
|
||||
CHECK(!Dart_IsError(Dart_AppendValueToWeakReferenceSet(
|
||||
visitor.current_set(), closure_)));
|
||||
}
|
||||
|
||||
void DartEventListener::Finalize(void* isolate_callback_data,
|
||||
Dart_WeakPersistentHandle handle,
|
||||
void* peer) {
|
||||
DartEventListener* listener = static_cast<DartEventListener*>(peer);
|
||||
listener->closure_ = nullptr;
|
||||
listener->deref(); // Balances ref in DartEventListener::DartEventListener
|
||||
}
|
||||
|
||||
} // namespace blink
|
||||
64
engine/bindings2/dart_event_listener.h
Normal file
64
engine/bindings2/dart_event_listener.h
Normal file
@ -0,0 +1,64 @@
|
||||
// Copyright 2015 The Chromium 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 SKY_ENGINE_BINDINGS2_DART_EVENT_LISTENER_H_
|
||||
#define SKY_ENGINE_BINDINGS2_DART_EVENT_LISTENER_H_
|
||||
|
||||
#include "dart/runtime/include/dart_api.h"
|
||||
#include "sky/engine/core/events/EventListener.h"
|
||||
#include "sky/engine/wtf/PassRefPtr.h"
|
||||
#include "sky/engine/tonic/dart_converter.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
class DartEventListener : public EventListener {
|
||||
public:
|
||||
static PassRefPtr<DartEventListener> FromDart(Dart_Handle handle);
|
||||
|
||||
~DartEventListener() override;
|
||||
|
||||
bool operator==(const EventListener& other) override {
|
||||
return this == &other;
|
||||
}
|
||||
void handleEvent(ExecutionContext*, Event*) override;
|
||||
|
||||
void AcceptDartGCVisitor(DartGCVisitor& visitor) const override;
|
||||
|
||||
private:
|
||||
explicit DartEventListener(Dart_Handle handle);
|
||||
|
||||
static void Finalize(void* isolate_callback_data,
|
||||
Dart_WeakPersistentHandle handle,
|
||||
void* peer);
|
||||
|
||||
base::WeakPtr<DartState> data_state_;
|
||||
Dart_WeakPersistentHandle closure_;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct DartConverter<EventListener*> {
|
||||
static PassRefPtr<EventListener> FromDart(Dart_Handle handle) {
|
||||
return DartEventListener::FromDart(handle);
|
||||
}
|
||||
|
||||
static PassRefPtr<EventListener> FromArguments(Dart_NativeArguments args,
|
||||
int index,
|
||||
Dart_Handle& exception) {
|
||||
return FromDart(Dart_GetNativeArgument(args, index));
|
||||
}
|
||||
|
||||
static PassRefPtr<EventListener> FromArgumentsWithNullCheck(
|
||||
Dart_NativeArguments args,
|
||||
int index,
|
||||
Dart_Handle& exception) {
|
||||
Dart_Handle handle = Dart_GetNativeArgument(args, index);
|
||||
if (Dart_IsNull(handle))
|
||||
return nullptr;
|
||||
return FromDart(handle);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace blink
|
||||
|
||||
#endif // SKY_ENGINE_BINDINGS2_DART_EVENT_LISTENER_H_
|
||||
166
engine/bindings2/exception_messages.cc
Normal file
166
engine/bindings2/exception_messages.cc
Normal file
@ -0,0 +1,166 @@
|
||||
// Copyright 2015 The Chromium 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 "sky/engine/config.h"
|
||||
#include "sky/engine/bindings2/exception_messages.h"
|
||||
|
||||
#include "sky/engine/platform/Decimal.h"
|
||||
#include "sky/engine/wtf/MathExtras.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
String ExceptionMessages::failedToConstruct(const char* type,
|
||||
const String& detail) {
|
||||
return "Failed to construct '" + String(type) +
|
||||
(!detail.isEmpty() ? String("': " + detail) : String("'"));
|
||||
}
|
||||
|
||||
String ExceptionMessages::failedToEnumerate(const char* type,
|
||||
const String& detail) {
|
||||
return "Failed to enumerate the properties of '" + String(type) +
|
||||
(!detail.isEmpty() ? String("': " + detail) : String("'"));
|
||||
}
|
||||
|
||||
String ExceptionMessages::failedToExecute(const char* method,
|
||||
const char* type,
|
||||
const String& detail) {
|
||||
return "Failed to execute '" + String(method) + "' on '" + String(type) +
|
||||
(!detail.isEmpty() ? String("': " + detail) : String("'"));
|
||||
}
|
||||
|
||||
String ExceptionMessages::failedToGet(const char* property,
|
||||
const char* type,
|
||||
const String& detail) {
|
||||
return "Failed to read the '" + String(property) + "' property from '" +
|
||||
String(type) + "': " + detail;
|
||||
}
|
||||
|
||||
String ExceptionMessages::failedToSet(const char* property,
|
||||
const char* type,
|
||||
const String& detail) {
|
||||
return "Failed to set the '" + String(property) + "' property on '" +
|
||||
String(type) + "': " + detail;
|
||||
}
|
||||
|
||||
String ExceptionMessages::failedToDelete(const char* property,
|
||||
const char* type,
|
||||
const String& detail) {
|
||||
return "Failed to delete the '" + String(property) + "' property from '" +
|
||||
String(type) + "': " + detail;
|
||||
}
|
||||
|
||||
String ExceptionMessages::failedToGetIndexed(const char* type,
|
||||
const String& detail) {
|
||||
return "Failed to read an indexed property from '" + String(type) + "': " +
|
||||
detail;
|
||||
}
|
||||
|
||||
String ExceptionMessages::failedToSetIndexed(const char* type,
|
||||
const String& detail) {
|
||||
return "Failed to set an indexed property on '" + String(type) + "': " +
|
||||
detail;
|
||||
}
|
||||
|
||||
String ExceptionMessages::failedToDeleteIndexed(const char* type,
|
||||
const String& detail) {
|
||||
return "Failed to delete an indexed property from '" + String(type) + "': " +
|
||||
detail;
|
||||
}
|
||||
|
||||
String ExceptionMessages::constructorNotCallableAsFunction(const char* type) {
|
||||
return failedToConstruct(type,
|
||||
"Please use the 'new' operator, this DOM object "
|
||||
"constructor cannot be called as a function.");
|
||||
}
|
||||
|
||||
String ExceptionMessages::incorrectPropertyType(const String& property,
|
||||
const String& detail) {
|
||||
return "The '" + property + "' property " + detail;
|
||||
}
|
||||
|
||||
String ExceptionMessages::invalidArity(const char* expected,
|
||||
unsigned provided) {
|
||||
return "Valid arities are: " + String(expected) + ", but " +
|
||||
String::number(provided) + " arguments provided.";
|
||||
}
|
||||
|
||||
String ExceptionMessages::argumentNullOrIncorrectType(
|
||||
int argumentIndex,
|
||||
const String& expectedType) {
|
||||
return "The " + ordinalNumber(argumentIndex) +
|
||||
" argument provided is either null, or an invalid " + expectedType +
|
||||
" object.";
|
||||
}
|
||||
|
||||
String ExceptionMessages::notAnArrayTypeArgumentOrValue(int argumentIndex) {
|
||||
String kind;
|
||||
if (argumentIndex) // method argument
|
||||
kind = ordinalNumber(argumentIndex) + " argument";
|
||||
else // value, e.g. attribute setter
|
||||
kind = "value provided";
|
||||
return "The " + kind +
|
||||
" is neither an array, nor does it have indexed properties.";
|
||||
}
|
||||
|
||||
String ExceptionMessages::notASequenceTypeProperty(const String& propertyName) {
|
||||
return "'" + propertyName +
|
||||
"' property is neither an array, nor does it have indexed properties.";
|
||||
}
|
||||
|
||||
String ExceptionMessages::notEnoughArguments(unsigned expected,
|
||||
unsigned provided) {
|
||||
return String::number(expected) + " argument" + (expected > 1 ? "s" : "") +
|
||||
" required, but only " + String::number(provided) + " present.";
|
||||
}
|
||||
|
||||
String ExceptionMessages::notAFiniteNumber(double value, const char* name) {
|
||||
ASSERT(!std::isfinite(value));
|
||||
return String::format("The %s is %s.", name,
|
||||
std::isinf(value) ? "infinite" : "not a number");
|
||||
}
|
||||
|
||||
String ExceptionMessages::notAFiniteNumber(const Decimal& value,
|
||||
const char* name) {
|
||||
ASSERT(!value.isFinite());
|
||||
return String::format("The %s is %s.", name,
|
||||
value.isInfinity() ? "infinite" : "not a number");
|
||||
}
|
||||
|
||||
String ExceptionMessages::ordinalNumber(int number) {
|
||||
String suffix("th");
|
||||
switch (number % 10) {
|
||||
case 1:
|
||||
if (number % 100 != 11)
|
||||
suffix = "st";
|
||||
break;
|
||||
case 2:
|
||||
if (number % 100 != 12)
|
||||
suffix = "nd";
|
||||
break;
|
||||
case 3:
|
||||
if (number % 100 != 13)
|
||||
suffix = "rd";
|
||||
break;
|
||||
}
|
||||
return String::number(number) + suffix;
|
||||
}
|
||||
|
||||
String ExceptionMessages::readOnly(const char* detail) {
|
||||
DEFINE_STATIC_LOCAL(String, readOnly, ("This object is read-only."));
|
||||
return detail
|
||||
? String::format("This object is read-only, because %s.", detail)
|
||||
: readOnly;
|
||||
}
|
||||
|
||||
template <>
|
||||
String ExceptionMessages::formatNumber<float>(float number) {
|
||||
return formatPotentiallyNonFiniteNumber(number);
|
||||
}
|
||||
|
||||
template <>
|
||||
String ExceptionMessages::formatNumber<double>(double number) {
|
||||
return formatPotentiallyNonFiniteNumber(number);
|
||||
}
|
||||
|
||||
} // namespace blink
|
||||
155
engine/bindings2/exception_messages.h
Normal file
155
engine/bindings2/exception_messages.h
Normal file
@ -0,0 +1,155 @@
|
||||
// Copyright 2015 The Chromium 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 SKY_ENGINE_BINDINGS2_EXCEPTIONMESSAGES_H_
|
||||
#define SKY_ENGINE_BINDINGS2_EXCEPTIONMESSAGES_H_
|
||||
|
||||
#include "sky/engine/wtf/MathExtras.h"
|
||||
#include "sky/engine/wtf/text/StringBuilder.h"
|
||||
#include "sky/engine/wtf/text/WTFString.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
class Decimal;
|
||||
|
||||
class ExceptionMessages {
|
||||
public:
|
||||
enum BoundType {
|
||||
InclusiveBound,
|
||||
ExclusiveBound,
|
||||
};
|
||||
|
||||
static String argumentNullOrIncorrectType(int argumentIndex,
|
||||
const String& expectedType);
|
||||
static String constructorNotCallableAsFunction(const char* type);
|
||||
|
||||
static String failedToConstruct(const char* type, const String& detail);
|
||||
static String failedToEnumerate(const char* type, const String& detail);
|
||||
static String failedToExecute(const char* method,
|
||||
const char* type,
|
||||
const String& detail);
|
||||
static String failedToGet(const char* property,
|
||||
const char* type,
|
||||
const String& detail);
|
||||
static String failedToSet(const char* property,
|
||||
const char* type,
|
||||
const String& detail);
|
||||
static String failedToDelete(const char* property,
|
||||
const char* type,
|
||||
const String& detail);
|
||||
static String failedToGetIndexed(const char* type, const String& detail);
|
||||
static String failedToSetIndexed(const char* type, const String& detail);
|
||||
static String failedToDeleteIndexed(const char* type, const String& detail);
|
||||
|
||||
template <typename NumType>
|
||||
static String formatNumber(NumType number) {
|
||||
return formatFiniteNumber(number);
|
||||
}
|
||||
|
||||
static String incorrectPropertyType(const String& property,
|
||||
const String& detail);
|
||||
|
||||
template <typename NumberType>
|
||||
static String indexExceedsMaximumBound(const char* name,
|
||||
NumberType given,
|
||||
NumberType bound) {
|
||||
bool eq = given == bound;
|
||||
StringBuilder result;
|
||||
result.appendLiteral("The ");
|
||||
result.append(name);
|
||||
result.appendLiteral(" provided (");
|
||||
result.append(formatNumber(given));
|
||||
result.appendLiteral(") is greater than ");
|
||||
result.append(eq ? "or equal to " : "");
|
||||
result.appendLiteral("the maximum bound (");
|
||||
result.append(formatNumber(bound));
|
||||
result.appendLiteral(").");
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
template <typename NumberType>
|
||||
static String indexExceedsMinimumBound(const char* name,
|
||||
NumberType given,
|
||||
NumberType bound) {
|
||||
bool eq = given == bound;
|
||||
StringBuilder result;
|
||||
result.appendLiteral("The ");
|
||||
result.append(name);
|
||||
result.appendLiteral(" provided (");
|
||||
result.append(formatNumber(given));
|
||||
result.appendLiteral(") is less than ");
|
||||
result.append(eq ? "or equal to " : "");
|
||||
result.appendLiteral("the minimum bound (");
|
||||
result.append(formatNumber(bound));
|
||||
result.appendLiteral(").");
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
template <typename NumberType>
|
||||
static String indexOutsideRange(const char* name,
|
||||
NumberType given,
|
||||
NumberType lowerBound,
|
||||
BoundType lowerType,
|
||||
NumberType upperBound,
|
||||
BoundType upperType) {
|
||||
StringBuilder result;
|
||||
result.appendLiteral("The ");
|
||||
result.append(name);
|
||||
result.appendLiteral(" provided (");
|
||||
result.append(formatNumber(given));
|
||||
result.appendLiteral(") is outside the range ");
|
||||
result.append(lowerType == ExclusiveBound ? '(' : '[');
|
||||
result.append(formatNumber(lowerBound));
|
||||
result.appendLiteral(", ");
|
||||
result.append(formatNumber(upperBound));
|
||||
result.append(upperType == ExclusiveBound ? ')' : ']');
|
||||
result.append('.');
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
static String invalidArity(const char* expected, unsigned provided);
|
||||
|
||||
// If > 0, the argument index that failed type check (1-indexed.)
|
||||
// If == 0, a (non-argument) value (e.g., a setter) failed the same check.
|
||||
static String notAnArrayTypeArgumentOrValue(int argumentIndex);
|
||||
static String notASequenceTypeProperty(const String& propertyName);
|
||||
static String notAFiniteNumber(double value,
|
||||
const char* name = "value provided");
|
||||
static String notAFiniteNumber(const Decimal& value,
|
||||
const char* name = "value provided");
|
||||
|
||||
static String notEnoughArguments(unsigned expected, unsigned provided);
|
||||
|
||||
static String readOnly(const char* detail = 0);
|
||||
|
||||
private:
|
||||
template <typename NumType>
|
||||
static String formatFiniteNumber(NumType number) {
|
||||
if (number > 1e20 || number < -1e20)
|
||||
return String::format("%e", 1.0 * number);
|
||||
return String::number(number);
|
||||
}
|
||||
|
||||
template <typename NumType>
|
||||
static String formatPotentiallyNonFiniteNumber(NumType number) {
|
||||
if (std::isnan(number))
|
||||
return "NaN";
|
||||
if (std::isinf(number))
|
||||
return number > 0 ? "Infinity" : "-Infinity";
|
||||
if (number > 1e20 || number < -1e20)
|
||||
return String::format("%e", number);
|
||||
return String::number(number);
|
||||
}
|
||||
|
||||
static String ordinalNumber(int number);
|
||||
};
|
||||
|
||||
template <>
|
||||
String ExceptionMessages::formatNumber<float>(float number);
|
||||
template <>
|
||||
String ExceptionMessages::formatNumber<double>(double number);
|
||||
|
||||
} // namespace blink
|
||||
|
||||
#endif // SKY_ENGINE_BINDINGS2_EXCEPTIONMESSAGES_H_
|
||||
48
engine/bindings2/exception_state.cc
Normal file
48
engine/bindings2/exception_state.cc
Normal file
@ -0,0 +1,48 @@
|
||||
// Copyright 2014 The Chromium 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 "sky/engine/config.h"
|
||||
#include "sky/engine/bindings2/exception_state.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
ExceptionState::ExceptionState() : code_(0), had_exception_(false) {
|
||||
}
|
||||
|
||||
ExceptionState::ExceptionState(Context context,
|
||||
const char* propertyName,
|
||||
const char* interfaceName) {
|
||||
}
|
||||
|
||||
ExceptionState::ExceptionState(Context context, const char* interfaceName) {
|
||||
}
|
||||
|
||||
ExceptionState::~ExceptionState() {
|
||||
}
|
||||
|
||||
void ExceptionState::ThrowDOMException(const ExceptionCode&,
|
||||
const String& message) {
|
||||
}
|
||||
|
||||
void ExceptionState::ThrowTypeError(const String& message) {
|
||||
}
|
||||
|
||||
void ExceptionState::ThrowRangeError(const String& message) {
|
||||
}
|
||||
|
||||
bool ExceptionState::ThrowIfNeeded() {
|
||||
return had_exception_;
|
||||
}
|
||||
|
||||
void ExceptionState::ClearException() {
|
||||
}
|
||||
|
||||
Dart_Handle ExceptionState::GetDartException(Dart_NativeArguments args,
|
||||
bool auto_scope) {
|
||||
// TODO(abarth): Still don't understand autoscope.
|
||||
DCHECK(auto_scope);
|
||||
return exception_.Release();
|
||||
}
|
||||
|
||||
} // namespace blink
|
||||
68
engine/bindings2/exception_state.h
Normal file
68
engine/bindings2/exception_state.h
Normal file
@ -0,0 +1,68 @@
|
||||
// Copyright 2014 The Chromium 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 SKY_ENGINE_BINDINGS2_EXCEPTION_STATE_H_
|
||||
#define SKY_ENGINE_BINDINGS2_EXCEPTION_STATE_H_
|
||||
|
||||
#include "sky/engine/tonic/dart_persistent_value.h"
|
||||
#include "sky/engine/wtf/Noncopyable.h"
|
||||
#include "sky/engine/wtf/text/WTFString.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
typedef int ExceptionCode;
|
||||
|
||||
class ExceptionState {
|
||||
WTF_MAKE_NONCOPYABLE(ExceptionState);
|
||||
|
||||
public:
|
||||
enum Context {
|
||||
ConstructionContext,
|
||||
ExecutionContext,
|
||||
DeletionContext,
|
||||
GetterContext,
|
||||
SetterContext,
|
||||
EnumerationContext,
|
||||
QueryContext,
|
||||
IndexedGetterContext,
|
||||
IndexedSetterContext,
|
||||
IndexedDeletionContext,
|
||||
UnknownContext, // FIXME: Remove this once we've flipped over to the new
|
||||
// API.
|
||||
};
|
||||
|
||||
ExceptionState();
|
||||
ExceptionState(Context context, const char* interfaceName);
|
||||
ExceptionState(Context context,
|
||||
const char* propertyName,
|
||||
const char* interfaceName);
|
||||
~ExceptionState();
|
||||
|
||||
void ThrowDOMException(const ExceptionCode& code, const String& message);
|
||||
void ThrowTypeError(const String& message);
|
||||
void ThrowRangeError(const String& message);
|
||||
|
||||
bool ThrowIfNeeded();
|
||||
void ClearException();
|
||||
|
||||
ExceptionCode code() const { return code_; }
|
||||
const String& message() const { return message_; }
|
||||
bool had_exception() const { return had_exception_ || code_; }
|
||||
|
||||
Dart_Handle GetDartException(Dart_NativeArguments args, bool auto_scope);
|
||||
|
||||
private:
|
||||
ExceptionCode code_;
|
||||
String message_;
|
||||
bool had_exception_;
|
||||
DartPersistentValue exception_;
|
||||
};
|
||||
|
||||
class NonThrowableExceptionState final : public ExceptionState {};
|
||||
|
||||
class TrackExceptionState final : public ExceptionState {};
|
||||
|
||||
} // namespace blink
|
||||
|
||||
#endif // SKY_ENGINE_BINDINGS2_EXCEPTION_STATE_H_
|
||||
19
engine/bindings2/exception_state_placeholder.cc
Normal file
19
engine/bindings2/exception_state_placeholder.cc
Normal file
@ -0,0 +1,19 @@
|
||||
// Copyright 2014 The Chromium 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 "sky/engine/config.h"
|
||||
#include "sky/engine/bindings2/exception_state_placeholder.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
#if ENABLE(ASSERT)
|
||||
|
||||
NoExceptionStateAssertionChecker::NoExceptionStateAssertionChecker(
|
||||
const char* file,
|
||||
int line) {
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace blink
|
||||
39
engine/bindings2/exception_state_placeholder.h
Normal file
39
engine/bindings2/exception_state_placeholder.h
Normal file
@ -0,0 +1,39 @@
|
||||
// Copyright 2014 The Chromium 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 SKY_ENGINE_BINDINGS2_EXCEPTION_STATE_PLACEHOLDER_H_
|
||||
#define SKY_ENGINE_BINDINGS2_EXCEPTION_STATE_PLACEHOLDER_H_
|
||||
|
||||
#include "sky/engine/bindings2/exception_state.h"
|
||||
#include "sky/engine/wtf/Assertions.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
class IgnorableExceptionState final : public ExceptionState {
|
||||
public:
|
||||
ExceptionState& ReturnThis() { return *this; }
|
||||
};
|
||||
|
||||
#define IGNORE_EXCEPTION (::blink::IgnorableExceptionState().ReturnThis())
|
||||
|
||||
#if ENABLE(ASSERT)
|
||||
|
||||
class NoExceptionStateAssertionChecker final : public ExceptionState {
|
||||
public:
|
||||
NoExceptionStateAssertionChecker(const char* file, int line);
|
||||
ExceptionState& ReturnThis() { return *this; }
|
||||
};
|
||||
|
||||
#define ASSERT_NO_EXCEPTION \
|
||||
(::blink::NoExceptionStateAssertionChecker(__FILE__, __LINE__).ReturnThis())
|
||||
|
||||
#else
|
||||
|
||||
#define ASSERT_NO_EXCEPTION (::blink::IgnorableExceptionState().ReturnThis())
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace blink
|
||||
|
||||
#endif // SKY_ENGINE_BINDINGS2_EXCEPTION_STATE_PLACEHOLDER_H_
|
||||
804
engine/bindings2/mojo_natives.cc
Normal file
804
engine/bindings2/mojo_natives.cc
Normal file
@ -0,0 +1,804 @@
|
||||
// Copyright 2014 The Chromium 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 <stdio.h>
|
||||
#include <string.h>
|
||||
#include <vector>
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/macros.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "builtin.h"
|
||||
#include "dart/runtime/include/dart_api.h"
|
||||
#include "mojo/public/c/system/core.h"
|
||||
#include "mojo/public/cpp/system/core.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
#define REGISTER_FUNCTION(name, count) \
|
||||
{ "" #name, name, count },
|
||||
#define DECLARE_FUNCTION(name, count) \
|
||||
extern void name(Dart_NativeArguments args);
|
||||
|
||||
#define MOJO_NATIVE_LIST(V) \
|
||||
V(MojoSharedBuffer_Create, 2) \
|
||||
V(MojoSharedBuffer_Duplicate, 2) \
|
||||
V(MojoSharedBuffer_Map, 5) \
|
||||
V(MojoSharedBuffer_Unmap, 1) \
|
||||
V(MojoDataPipe_Create, 3) \
|
||||
V(MojoDataPipe_WriteData, 4) \
|
||||
V(MojoDataPipe_BeginWriteData, 3) \
|
||||
V(MojoDataPipe_EndWriteData, 2) \
|
||||
V(MojoDataPipe_ReadData, 4) \
|
||||
V(MojoDataPipe_BeginReadData, 3) \
|
||||
V(MojoDataPipe_EndReadData, 2) \
|
||||
V(MojoMessagePipe_Create, 1) \
|
||||
V(MojoMessagePipe_Write, 5) \
|
||||
V(MojoMessagePipe_Read, 5) \
|
||||
V(MojoHandle_Close, 1) \
|
||||
V(MojoHandle_Wait, 3) \
|
||||
V(MojoHandle_Register, 1) \
|
||||
V(MojoHandle_WaitMany, 3) \
|
||||
V(MojoHandleWatcher_SendControlData, 4) \
|
||||
V(MojoHandleWatcher_RecvControlData, 1) \
|
||||
V(MojoHandleWatcher_SetControlHandle, 1) \
|
||||
V(MojoHandleWatcher_GetControlHandle, 0)
|
||||
|
||||
MOJO_NATIVE_LIST(DECLARE_FUNCTION);
|
||||
|
||||
static struct NativeEntries {
|
||||
const char* name;
|
||||
Dart_NativeFunction function;
|
||||
int argument_count;
|
||||
} MojoEntries[] = {MOJO_NATIVE_LIST(REGISTER_FUNCTION)};
|
||||
|
||||
Dart_NativeFunction MojoNativeLookup(Dart_Handle name,
|
||||
int argument_count,
|
||||
bool* auto_setup_scope) {
|
||||
const char* function_name = nullptr;
|
||||
Dart_Handle result = Dart_StringToCString(name, &function_name);
|
||||
DART_CHECK_VALID(result);
|
||||
DCHECK(function_name != nullptr);
|
||||
DCHECK(auto_setup_scope != nullptr);
|
||||
*auto_setup_scope = true;
|
||||
size_t num_entries = arraysize(MojoEntries);
|
||||
for (size_t i = 0; i < num_entries; ++i) {
|
||||
const struct NativeEntries& entry = MojoEntries[i];
|
||||
if (!strcmp(function_name, entry.name) &&
|
||||
(entry.argument_count == argument_count)) {
|
||||
return entry.function;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const uint8_t* MojoNativeSymbol(Dart_NativeFunction nf) {
|
||||
size_t num_entries = arraysize(MojoEntries);
|
||||
for (size_t i = 0; i < num_entries; ++i) {
|
||||
const struct NativeEntries& entry = MojoEntries[i];
|
||||
if (entry.function == nf) {
|
||||
return reinterpret_cast<const uint8_t*>(entry.name);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static void SetNullReturn(Dart_NativeArguments arguments) {
|
||||
Dart_SetReturnValue(arguments, Dart_Null());
|
||||
}
|
||||
|
||||
static void SetInvalidArgumentReturn(Dart_NativeArguments arguments) {
|
||||
Dart_SetIntegerReturnValue(
|
||||
arguments, static_cast<int64_t>(MOJO_RESULT_INVALID_ARGUMENT));
|
||||
}
|
||||
|
||||
static Dart_Handle MojoLib() {
|
||||
return DartBuiltins::LookupLibrary("dart:mojo_core");
|
||||
}
|
||||
|
||||
static Dart_Handle SignalsStateToDart(Dart_Handle klass,
|
||||
const MojoHandleSignalsState& state) {
|
||||
Dart_Handle arg1 = Dart_NewInteger(state.satisfied_signals);
|
||||
Dart_Handle arg2 = Dart_NewInteger(state.satisfiable_signals);
|
||||
Dart_Handle args[] = {arg1, arg2};
|
||||
return Dart_New(klass, Dart_Null(), 2, args);
|
||||
}
|
||||
|
||||
#define CHECK_INTEGER_ARGUMENT(args, num, result, failure) \
|
||||
{ \
|
||||
Dart_Handle __status; \
|
||||
__status = Dart_GetNativeIntegerArgument(args, num, result); \
|
||||
if (Dart_IsError(__status)) { \
|
||||
Set##failure##Return(arguments); \
|
||||
return; \
|
||||
} \
|
||||
} \
|
||||
|
||||
struct CloserCallbackPeer {
|
||||
MojoHandle handle;
|
||||
};
|
||||
|
||||
static void MojoHandleCloserCallback(void* isolate_data,
|
||||
Dart_WeakPersistentHandle handle,
|
||||
void* peer) {
|
||||
CloserCallbackPeer* callback_peer =
|
||||
reinterpret_cast<CloserCallbackPeer*>(peer);
|
||||
if (callback_peer->handle != MOJO_HANDLE_INVALID) {
|
||||
MojoClose(callback_peer->handle);
|
||||
}
|
||||
delete callback_peer;
|
||||
}
|
||||
|
||||
// Setup a weak persistent handle for a Dart MojoHandle that calls MojoClose
|
||||
// on the handle when the MojoHandle is GC'd or the VM is going down.
|
||||
void MojoHandle_Register(Dart_NativeArguments arguments) {
|
||||
// An instance of Dart class MojoHandle.
|
||||
Dart_Handle mojo_handle_instance = Dart_GetNativeArgument(arguments, 0);
|
||||
if (!Dart_IsInstance(mojo_handle_instance)) {
|
||||
SetInvalidArgumentReturn(arguments);
|
||||
return;
|
||||
}
|
||||
// TODO(zra): Here, we could check that mojo_handle_instance is really a
|
||||
// MojoHandle instance, but with the Dart API it's not too easy to get a Type
|
||||
// object from the class name outside of the root library. For now, we'll rely
|
||||
// on the existence of the right fields to be sufficient.
|
||||
|
||||
Dart_Handle raw_mojo_handle_instance = Dart_GetField(
|
||||
mojo_handle_instance, ToDart("_handle"));
|
||||
if (Dart_IsError(raw_mojo_handle_instance)) {
|
||||
SetInvalidArgumentReturn(arguments);
|
||||
return;
|
||||
}
|
||||
|
||||
Dart_Handle mojo_handle = Dart_GetField(
|
||||
raw_mojo_handle_instance, ToDart("h"));
|
||||
if (Dart_IsError(mojo_handle)) {
|
||||
SetInvalidArgumentReturn(arguments);
|
||||
return;
|
||||
}
|
||||
|
||||
int64_t raw_handle = static_cast<int64_t>(MOJO_HANDLE_INVALID);
|
||||
Dart_Handle result = Dart_IntegerToInt64(mojo_handle, &raw_handle);
|
||||
if (Dart_IsError(result)) {
|
||||
SetInvalidArgumentReturn(arguments);
|
||||
return;
|
||||
}
|
||||
|
||||
if (raw_handle == static_cast<int64_t>(MOJO_HANDLE_INVALID)) {
|
||||
SetInvalidArgumentReturn(arguments);
|
||||
return;
|
||||
}
|
||||
|
||||
CloserCallbackPeer* callback_peer = new CloserCallbackPeer();
|
||||
callback_peer->handle = static_cast<MojoHandle>(raw_handle);
|
||||
Dart_NewWeakPersistentHandle(mojo_handle_instance,
|
||||
reinterpret_cast<void*>(callback_peer),
|
||||
sizeof(CloserCallbackPeer),
|
||||
MojoHandleCloserCallback);
|
||||
Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(MOJO_RESULT_OK));
|
||||
}
|
||||
|
||||
void MojoHandle_Close(Dart_NativeArguments arguments) {
|
||||
int64_t handle;
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, InvalidArgument);
|
||||
|
||||
MojoResult res = MojoClose(static_cast<MojoHandle>(handle));
|
||||
|
||||
Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(res));
|
||||
}
|
||||
|
||||
void MojoHandle_Wait(Dart_NativeArguments arguments) {
|
||||
int64_t handle = 0;
|
||||
int64_t signals = 0;
|
||||
int64_t deadline = 0;
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, InvalidArgument);
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 1, &signals, InvalidArgument);
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 2, &deadline, InvalidArgument);
|
||||
|
||||
MojoHandleSignalsState state;
|
||||
MojoResult r = mojo::Wait(mojo::Handle(static_cast<MojoHandle>(handle)),
|
||||
static_cast<MojoHandleSignals>(signals),
|
||||
static_cast<MojoDeadline>(deadline), &state);
|
||||
|
||||
Dart_Handle klass = Dart_GetClass(
|
||||
MojoLib(), ToDart("MojoHandleSignalsState"));
|
||||
DART_CHECK_VALID(klass);
|
||||
|
||||
// The return value is structured as a list of length 2:
|
||||
// [0] MojoResult
|
||||
// [1] MojoHandleSignalsState. (may be null)
|
||||
Dart_Handle list = Dart_NewList(2);
|
||||
Dart_ListSetAt(list, 0, Dart_NewInteger(r));
|
||||
if (mojo::WaitManyResult(r).AreSignalsStatesValid()) {
|
||||
Dart_ListSetAt(list, 1, SignalsStateToDart(klass, state));
|
||||
} else {
|
||||
Dart_ListSetAt(list, 1, Dart_Null());
|
||||
}
|
||||
Dart_SetReturnValue(arguments, list);
|
||||
}
|
||||
|
||||
void MojoHandle_WaitMany(Dart_NativeArguments arguments) {
|
||||
int64_t deadline = 0;
|
||||
Dart_Handle handles = Dart_GetNativeArgument(arguments, 0);
|
||||
Dart_Handle signals = Dart_GetNativeArgument(arguments, 1);
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 2, &deadline, InvalidArgument);
|
||||
|
||||
if (!Dart_IsList(handles) || !Dart_IsList(signals)) {
|
||||
SetInvalidArgumentReturn(arguments);
|
||||
return;
|
||||
}
|
||||
|
||||
intptr_t handles_len = 0;
|
||||
intptr_t signals_len = 0;
|
||||
Dart_ListLength(handles, &handles_len);
|
||||
Dart_ListLength(signals, &signals_len);
|
||||
if (handles_len != signals_len) {
|
||||
SetInvalidArgumentReturn(arguments);
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<mojo::Handle> mojo_handles(handles_len);
|
||||
std::vector<MojoHandleSignals> mojo_signals(handles_len);
|
||||
|
||||
for (int i = 0; i < handles_len; i++) {
|
||||
Dart_Handle dart_handle = Dart_ListGetAt(handles, i);
|
||||
Dart_Handle dart_signal = Dart_ListGetAt(signals, i);
|
||||
if (!Dart_IsInteger(dart_handle) || !Dart_IsInteger(dart_signal)) {
|
||||
SetInvalidArgumentReturn(arguments);
|
||||
return;
|
||||
}
|
||||
int64_t mojo_handle = 0;
|
||||
int64_t mojo_signal = 0;
|
||||
Dart_IntegerToInt64(dart_handle, &mojo_handle);
|
||||
Dart_IntegerToInt64(dart_signal, &mojo_signal);
|
||||
mojo_handles[i] = mojo::Handle(mojo_handle);
|
||||
mojo_signals[i] = static_cast<MojoHandleSignals>(mojo_signal);
|
||||
}
|
||||
|
||||
std::vector<MojoHandleSignalsState> states(handles_len);
|
||||
mojo::WaitManyResult wmr = mojo::WaitMany(
|
||||
mojo_handles, mojo_signals, static_cast<MojoDeadline>(deadline), &states);
|
||||
|
||||
Dart_Handle klass = Dart_GetClass(
|
||||
MojoLib(), ToDart("MojoHandleSignalsState"));
|
||||
DART_CHECK_VALID(klass);
|
||||
|
||||
// The return value is structured as a list of length 3:
|
||||
// [0] MojoResult
|
||||
// [1] index of handle that caused a return (may be null)
|
||||
// [2] list of MojoHandleSignalsState. (may be null)
|
||||
Dart_Handle list = Dart_NewList(3);
|
||||
Dart_ListSetAt(list, 0, Dart_NewInteger(wmr.result));
|
||||
if (wmr.IsIndexValid())
|
||||
Dart_ListSetAt(list, 1, Dart_NewInteger(wmr.index));
|
||||
else
|
||||
Dart_ListSetAt(list, 1, Dart_Null());
|
||||
if (wmr.AreSignalsStatesValid()) {
|
||||
Dart_Handle stateList = Dart_NewList(handles_len);
|
||||
for (int i = 0; i < handles_len; i++) {
|
||||
Dart_ListSetAt(stateList, i, SignalsStateToDart(klass, states[i]));
|
||||
}
|
||||
Dart_ListSetAt(list, 2, stateList);
|
||||
} else {
|
||||
Dart_ListSetAt(list, 2, Dart_Null());
|
||||
}
|
||||
Dart_SetReturnValue(arguments, list);
|
||||
}
|
||||
|
||||
void MojoSharedBuffer_Create(Dart_NativeArguments arguments) {
|
||||
int64_t num_bytes = 0;
|
||||
int64_t flags = 0;
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 0, &num_bytes, Null);
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 1, &flags, Null);
|
||||
|
||||
MojoCreateSharedBufferOptions options;
|
||||
options.struct_size = sizeof(MojoCreateSharedBufferOptions);
|
||||
options.flags = static_cast<MojoCreateSharedBufferOptionsFlags>(flags);
|
||||
|
||||
MojoHandle out = MOJO_HANDLE_INVALID;;
|
||||
MojoResult res = MojoCreateSharedBuffer(
|
||||
&options, static_cast<int32_t>(num_bytes), &out);
|
||||
|
||||
Dart_Handle list = Dart_NewList(2);
|
||||
Dart_ListSetAt(list, 0, Dart_NewInteger(res));
|
||||
Dart_ListSetAt(list, 1, Dart_NewInteger(out));
|
||||
Dart_SetReturnValue(arguments, list);
|
||||
}
|
||||
|
||||
void MojoSharedBuffer_Duplicate(Dart_NativeArguments arguments) {
|
||||
int64_t handle = 0;
|
||||
int64_t flags = 0;
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, Null);
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 1, &flags, Null);
|
||||
|
||||
MojoDuplicateBufferHandleOptions options;
|
||||
options.struct_size = sizeof(MojoDuplicateBufferHandleOptions);
|
||||
options.flags = static_cast<MojoDuplicateBufferHandleOptionsFlags>(flags);
|
||||
|
||||
MojoHandle out = MOJO_HANDLE_INVALID;;
|
||||
MojoResult res = MojoDuplicateBufferHandle(
|
||||
static_cast<MojoHandle>(handle), &options, &out);
|
||||
|
||||
Dart_Handle list = Dart_NewList(2);
|
||||
Dart_ListSetAt(list, 0, Dart_NewInteger(res));
|
||||
Dart_ListSetAt(list, 1, Dart_NewInteger(out));
|
||||
Dart_SetReturnValue(arguments, list);
|
||||
}
|
||||
|
||||
static void MojoBufferUnmapCallback(void* isolate_data,
|
||||
Dart_WeakPersistentHandle handle,
|
||||
void* peer) {
|
||||
MojoUnmapBuffer(peer);
|
||||
}
|
||||
|
||||
void MojoSharedBuffer_Map(Dart_NativeArguments arguments) {
|
||||
int64_t handle = 0;
|
||||
int64_t offset = 0;
|
||||
int64_t num_bytes = 0;
|
||||
int64_t flags = 0;
|
||||
Dart_Handle mojo_buffer = Dart_GetNativeArgument(arguments, 0);
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 1, &handle, Null);
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 2, &offset, Null);
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 3, &num_bytes, Null);
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 4, &flags, Null);
|
||||
|
||||
void* out;
|
||||
MojoResult res = MojoMapBuffer(static_cast<MojoHandle>(handle),
|
||||
offset,
|
||||
num_bytes,
|
||||
&out,
|
||||
static_cast<MojoMapBufferFlags>(flags));
|
||||
|
||||
Dart_Handle list = Dart_NewList(2);
|
||||
Dart_Handle typed_data;
|
||||
if (res == MOJO_RESULT_OK) {
|
||||
typed_data = Dart_NewExternalTypedData(
|
||||
Dart_TypedData_kByteData, out, num_bytes);
|
||||
Dart_NewWeakPersistentHandle(
|
||||
mojo_buffer, out, num_bytes, MojoBufferUnmapCallback);
|
||||
} else {
|
||||
typed_data = Dart_Null();
|
||||
}
|
||||
Dart_ListSetAt(list, 0, Dart_NewInteger(res));
|
||||
Dart_ListSetAt(list, 1, typed_data);
|
||||
Dart_SetReturnValue(arguments, list);
|
||||
}
|
||||
|
||||
void MojoSharedBuffer_Unmap(Dart_NativeArguments arguments) {
|
||||
Dart_Handle typed_data = Dart_GetNativeArgument(arguments, 0);
|
||||
if (Dart_GetTypeOfExternalTypedData(typed_data) == Dart_TypedData_kInvalid) {
|
||||
SetInvalidArgumentReturn(arguments);
|
||||
return;
|
||||
}
|
||||
|
||||
Dart_TypedData_Type typ;
|
||||
void *data;
|
||||
intptr_t len;
|
||||
Dart_TypedDataAcquireData(typed_data, &typ, &data, &len);
|
||||
MojoResult res = MojoUnmapBuffer(data);
|
||||
Dart_TypedDataReleaseData(typed_data);
|
||||
|
||||
Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(res));
|
||||
}
|
||||
|
||||
void MojoDataPipe_Create(Dart_NativeArguments arguments) {
|
||||
int64_t element_bytes = 0;
|
||||
int64_t capacity_bytes = 0;
|
||||
int64_t flags = 0;
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 0, &element_bytes, Null);
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 1, &capacity_bytes, Null);
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 2, &flags, Null);
|
||||
|
||||
MojoCreateDataPipeOptions options;
|
||||
options.struct_size = sizeof(MojoCreateDataPipeOptions);
|
||||
options.flags = static_cast<MojoCreateDataPipeOptionsFlags>(flags);
|
||||
options.element_num_bytes = static_cast<uint32_t>(element_bytes);
|
||||
options.capacity_num_bytes = static_cast<uint32_t>(capacity_bytes);
|
||||
|
||||
MojoHandle producer = MOJO_HANDLE_INVALID;
|
||||
MojoHandle consumer = MOJO_HANDLE_INVALID;
|
||||
MojoResult res = MojoCreateDataPipe(&options, &producer, &consumer);
|
||||
|
||||
Dart_Handle list = Dart_NewList(3);
|
||||
Dart_ListSetAt(list, 0, Dart_NewInteger(res));
|
||||
Dart_ListSetAt(list, 1, Dart_NewInteger(producer));
|
||||
Dart_ListSetAt(list, 2, Dart_NewInteger(consumer));
|
||||
Dart_SetReturnValue(arguments, list);
|
||||
}
|
||||
|
||||
void MojoDataPipe_WriteData(Dart_NativeArguments arguments) {
|
||||
int64_t handle = 0;
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, Null);
|
||||
|
||||
Dart_Handle typed_data = Dart_GetNativeArgument(arguments, 1);
|
||||
if (!Dart_IsTypedData(typed_data)) {
|
||||
SetNullReturn(arguments);
|
||||
return;
|
||||
}
|
||||
|
||||
int64_t num_bytes = 0;
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 2, &num_bytes, Null);
|
||||
if (num_bytes <= 0) {
|
||||
SetNullReturn(arguments);
|
||||
return;
|
||||
}
|
||||
|
||||
int64_t flags = 0;
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 3, &flags, Null);
|
||||
|
||||
Dart_TypedData_Type type;
|
||||
void* data;
|
||||
intptr_t data_length;
|
||||
Dart_TypedDataAcquireData(typed_data, &type, &data, &data_length);
|
||||
uint32_t length = static_cast<uint32_t>(num_bytes);
|
||||
MojoResult res = MojoWriteData(
|
||||
static_cast<MojoHandle>(handle),
|
||||
data,
|
||||
&length,
|
||||
static_cast<MojoWriteDataFlags>(flags));
|
||||
Dart_TypedDataReleaseData(typed_data);
|
||||
|
||||
Dart_Handle list = Dart_NewList(2);
|
||||
Dart_ListSetAt(list, 0, Dart_NewInteger(res));
|
||||
Dart_ListSetAt(list, 1, Dart_NewInteger(length));
|
||||
Dart_SetReturnValue(arguments, list);
|
||||
}
|
||||
|
||||
void MojoDataPipe_BeginWriteData(Dart_NativeArguments arguments) {
|
||||
int64_t handle = 0;
|
||||
int64_t buffer_bytes = 0;
|
||||
int64_t flags = 0;
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, Null);
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 1, &buffer_bytes, Null);
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 2, &flags, Null);
|
||||
|
||||
void* buffer;
|
||||
uint32_t size = static_cast<uint32_t>(buffer_bytes);
|
||||
MojoResult res = MojoBeginWriteData(
|
||||
static_cast<MojoHandle>(handle),
|
||||
&buffer,
|
||||
&size,
|
||||
static_cast<MojoWriteDataFlags>(flags));
|
||||
|
||||
Dart_Handle list = Dart_NewList(2);
|
||||
Dart_Handle typed_data;
|
||||
if (res == MOJO_RESULT_OK) {
|
||||
typed_data = Dart_NewExternalTypedData(
|
||||
Dart_TypedData_kByteData, buffer, size);
|
||||
} else {
|
||||
typed_data = Dart_Null();
|
||||
}
|
||||
Dart_ListSetAt(list, 0, Dart_NewInteger(res));
|
||||
Dart_ListSetAt(list, 1, typed_data);
|
||||
Dart_SetReturnValue(arguments, list);
|
||||
}
|
||||
|
||||
void MojoDataPipe_EndWriteData(Dart_NativeArguments arguments) {
|
||||
int64_t handle = 0;
|
||||
int64_t num_bytes_written = 0;
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, InvalidArgument);
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 1, &num_bytes_written, InvalidArgument);
|
||||
|
||||
MojoResult res = MojoEndWriteData(
|
||||
static_cast<MojoHandle>(handle),
|
||||
static_cast<uint32_t>(num_bytes_written));
|
||||
|
||||
Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(res));
|
||||
}
|
||||
|
||||
void MojoDataPipe_ReadData(Dart_NativeArguments arguments) {
|
||||
int64_t handle = 0;
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, Null);
|
||||
|
||||
Dart_Handle typed_data = Dart_GetNativeArgument(arguments, 1);
|
||||
if (!Dart_IsTypedData(typed_data) && !Dart_IsNull(typed_data)) {
|
||||
SetNullReturn(arguments);
|
||||
return;
|
||||
}
|
||||
// When querying the amount of data available to read from the pipe,
|
||||
// null is passed in for typed_data.
|
||||
|
||||
int64_t num_bytes = 0;
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 2, &num_bytes, Null);
|
||||
|
||||
int64_t flags = 0;
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 3, &flags, Null);
|
||||
|
||||
Dart_TypedData_Type typ;
|
||||
void* data = nullptr;
|
||||
intptr_t bdlen = 0;
|
||||
if (!Dart_IsNull(typed_data)) {
|
||||
Dart_TypedDataAcquireData(typed_data, &typ, &data, &bdlen);
|
||||
}
|
||||
uint32_t len = static_cast<uint32_t>(num_bytes);
|
||||
MojoResult res = MojoReadData(
|
||||
static_cast<MojoHandle>(handle),
|
||||
data,
|
||||
&len,
|
||||
static_cast<MojoReadDataFlags>(flags));
|
||||
if (!Dart_IsNull(typed_data)) {
|
||||
Dart_TypedDataReleaseData(typed_data);
|
||||
}
|
||||
|
||||
Dart_Handle list = Dart_NewList(2);
|
||||
Dart_ListSetAt(list, 0, Dart_NewInteger(res));
|
||||
Dart_ListSetAt(list, 1, Dart_NewInteger(len));
|
||||
Dart_SetReturnValue(arguments, list);
|
||||
}
|
||||
|
||||
void MojoDataPipe_BeginReadData(Dart_NativeArguments arguments) {
|
||||
int64_t handle = 0;
|
||||
int64_t buffer_bytes = 0;
|
||||
int64_t flags = 0;
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, Null);
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 1, &buffer_bytes, Null);
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 2, &flags, Null);
|
||||
|
||||
void* buffer;
|
||||
uint32_t size = static_cast<uint32_t>(buffer_bytes);
|
||||
MojoResult res = MojoBeginReadData(
|
||||
static_cast<MojoHandle>(handle),
|
||||
const_cast<const void**>(&buffer),
|
||||
&size,
|
||||
static_cast<MojoWriteDataFlags>(flags));
|
||||
|
||||
Dart_Handle list = Dart_NewList(2);
|
||||
Dart_Handle typed_data;
|
||||
if (res == MOJO_RESULT_OK) {
|
||||
typed_data = Dart_NewExternalTypedData(
|
||||
Dart_TypedData_kByteData, buffer, size);
|
||||
} else {
|
||||
typed_data = Dart_Null();
|
||||
}
|
||||
Dart_ListSetAt(list, 0, Dart_NewInteger(res));
|
||||
Dart_ListSetAt(list, 1, typed_data);
|
||||
Dart_SetReturnValue(arguments, list);
|
||||
}
|
||||
|
||||
void MojoDataPipe_EndReadData(Dart_NativeArguments arguments) {
|
||||
int64_t handle = 0;
|
||||
int64_t num_bytes_read = 0;
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, InvalidArgument);
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 1, &num_bytes_read, InvalidArgument);
|
||||
|
||||
MojoResult res = MojoEndReadData(
|
||||
static_cast<MojoHandle>(handle),
|
||||
static_cast<uint32_t>(num_bytes_read));
|
||||
|
||||
Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(res));
|
||||
}
|
||||
|
||||
void MojoMessagePipe_Create(Dart_NativeArguments arguments) {
|
||||
int64_t flags = 0;
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 0, &flags, Null);
|
||||
|
||||
MojoCreateMessagePipeOptions options;
|
||||
options.struct_size = sizeof(MojoCreateMessagePipeOptions);
|
||||
options.flags = static_cast<MojoCreateMessagePipeOptionsFlags>(flags);
|
||||
|
||||
MojoHandle end1 = MOJO_HANDLE_INVALID;
|
||||
MojoHandle end2 = MOJO_HANDLE_INVALID;
|
||||
MojoResult res = MojoCreateMessagePipe(&options, &end1, &end2);
|
||||
|
||||
Dart_Handle list = Dart_NewList(3);
|
||||
Dart_ListSetAt(list, 0, Dart_NewInteger(res));
|
||||
Dart_ListSetAt(list, 1, Dart_NewInteger(end1));
|
||||
Dart_ListSetAt(list, 2, Dart_NewInteger(end2));
|
||||
Dart_SetReturnValue(arguments, list);
|
||||
}
|
||||
|
||||
void MojoMessagePipe_Write(Dart_NativeArguments arguments) {
|
||||
int64_t handle = 0;
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, InvalidArgument);
|
||||
|
||||
Dart_Handle typed_data = Dart_GetNativeArgument(arguments, 1);
|
||||
if (!Dart_IsTypedData(typed_data) && !Dart_IsNull(typed_data)) {
|
||||
SetInvalidArgumentReturn(arguments);
|
||||
return;
|
||||
}
|
||||
|
||||
int64_t num_bytes = 0;
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 2, &num_bytes, InvalidArgument);
|
||||
if ((Dart_IsNull(typed_data) && (num_bytes != 0)) ||
|
||||
(!Dart_IsNull(typed_data) && (num_bytes <= 0))) {
|
||||
SetInvalidArgumentReturn(arguments);
|
||||
return;
|
||||
}
|
||||
|
||||
Dart_Handle handles = Dart_GetNativeArgument(arguments, 3);
|
||||
if (!Dart_IsList(handles) && !Dart_IsNull(handles)) {
|
||||
SetInvalidArgumentReturn(arguments);
|
||||
return;
|
||||
}
|
||||
|
||||
int64_t flags = 0;
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 4, &flags, InvalidArgument);
|
||||
|
||||
// Grab the data if there is any.
|
||||
Dart_TypedData_Type typ;
|
||||
void* bytes = nullptr;
|
||||
intptr_t bdlen = 0;
|
||||
if (!Dart_IsNull(typed_data)) {
|
||||
Dart_TypedDataAcquireData(typed_data, &typ, &bytes, &bdlen);
|
||||
}
|
||||
|
||||
// Grab the handles if there are any.
|
||||
scoped_ptr<MojoHandle[]> mojo_handles;
|
||||
intptr_t handles_len = 0;
|
||||
if (!Dart_IsNull(handles)) {
|
||||
Dart_ListLength(handles, &handles_len);
|
||||
if (handles_len > 0) {
|
||||
mojo_handles.reset(new MojoHandle[handles_len]);
|
||||
}
|
||||
for (int i = 0; i < handles_len; i++) {
|
||||
Dart_Handle dart_handle = Dart_ListGetAt(handles, i);
|
||||
if (!Dart_IsInteger(dart_handle)) {
|
||||
SetInvalidArgumentReturn(arguments);
|
||||
return;
|
||||
}
|
||||
int64_t mojo_handle = 0;
|
||||
Dart_IntegerToInt64(dart_handle, &mojo_handle);
|
||||
mojo_handles[i] = static_cast<MojoHandle>(mojo_handle);
|
||||
}
|
||||
}
|
||||
|
||||
MojoResult res = MojoWriteMessage(
|
||||
static_cast<MojoHandle>(handle),
|
||||
const_cast<const void*>(bytes),
|
||||
static_cast<uint32_t>(num_bytes),
|
||||
mojo_handles.get(),
|
||||
static_cast<uint32_t>(handles_len),
|
||||
static_cast<MojoWriteMessageFlags>(flags));
|
||||
|
||||
// Release the data.
|
||||
if (!Dart_IsNull(typed_data)) {
|
||||
Dart_TypedDataReleaseData(typed_data);
|
||||
}
|
||||
|
||||
Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(res));
|
||||
}
|
||||
|
||||
void MojoMessagePipe_Read(Dart_NativeArguments arguments) {
|
||||
int64_t handle = 0;
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, Null);
|
||||
|
||||
Dart_Handle typed_data = Dart_GetNativeArgument(arguments, 1);
|
||||
if (!Dart_IsTypedData(typed_data) && !Dart_IsNull(typed_data)) {
|
||||
SetNullReturn(arguments);
|
||||
return;
|
||||
}
|
||||
// When querying the amount of data available to read from the pipe,
|
||||
// null is passed in for typed_data.
|
||||
|
||||
int64_t num_bytes = 0;
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 2, &num_bytes, Null);
|
||||
if ((Dart_IsNull(typed_data) && (num_bytes != 0)) ||
|
||||
(!Dart_IsNull(typed_data) && (num_bytes <= 0))) {
|
||||
SetNullReturn(arguments);
|
||||
return;
|
||||
}
|
||||
|
||||
Dart_Handle handles = Dart_GetNativeArgument(arguments, 3);
|
||||
if (!Dart_IsList(handles) && !Dart_IsNull(handles)) {
|
||||
SetNullReturn(arguments);
|
||||
return;
|
||||
}
|
||||
|
||||
int64_t flags = 0;
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 4, &flags, Null);
|
||||
|
||||
// Grab the data if there is any.
|
||||
Dart_TypedData_Type typ;
|
||||
void* bytes = nullptr;
|
||||
intptr_t byte_data_len = 0;
|
||||
if (!Dart_IsNull(typed_data)) {
|
||||
Dart_TypedDataAcquireData(typed_data, &typ, &bytes, &byte_data_len);
|
||||
}
|
||||
uint32_t blen = static_cast<uint32_t>(num_bytes);
|
||||
|
||||
// Grab the handles if there are any.
|
||||
scoped_ptr<MojoHandle[]> mojo_handles;
|
||||
intptr_t handles_len = 0;
|
||||
if (!Dart_IsNull(handles)) {
|
||||
Dart_ListLength(handles, &handles_len);
|
||||
mojo_handles.reset(new MojoHandle[handles_len]);
|
||||
}
|
||||
uint32_t hlen = static_cast<uint32_t>(handles_len);
|
||||
|
||||
MojoResult res = MojoReadMessage(
|
||||
static_cast<MojoHandle>(handle),
|
||||
bytes,
|
||||
&blen,
|
||||
mojo_handles.get(),
|
||||
&hlen,
|
||||
static_cast<MojoReadMessageFlags>(flags));
|
||||
|
||||
// Release the data.
|
||||
if (!Dart_IsNull(typed_data)) {
|
||||
Dart_TypedDataReleaseData(typed_data);
|
||||
}
|
||||
|
||||
if (!Dart_IsNull(handles)) {
|
||||
for (int i = 0; i < handles_len; i++) {
|
||||
Dart_ListSetAt(handles, i, Dart_NewInteger(mojo_handles[i]));
|
||||
}
|
||||
}
|
||||
|
||||
Dart_Handle list = Dart_NewList(3);
|
||||
Dart_ListSetAt(list, 0, Dart_NewInteger(res));
|
||||
Dart_ListSetAt(list, 1, Dart_NewInteger(blen));
|
||||
Dart_ListSetAt(list, 2, Dart_NewInteger(hlen));
|
||||
Dart_SetReturnValue(arguments, list);
|
||||
}
|
||||
|
||||
struct ControlData {
|
||||
int64_t handle;
|
||||
Dart_Port port;
|
||||
int64_t data;
|
||||
};
|
||||
|
||||
void MojoHandleWatcher_SendControlData(Dart_NativeArguments arguments) {
|
||||
int64_t control_handle = 0;
|
||||
int64_t client_handle = 0;
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 0, &control_handle, InvalidArgument);
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 1, &client_handle, InvalidArgument);
|
||||
|
||||
Dart_Handle send_port_handle = Dart_GetNativeArgument(arguments, 2);
|
||||
Dart_Port send_port_id = 0;
|
||||
if (!Dart_IsNull(send_port_handle)) {
|
||||
Dart_Handle result = Dart_SendPortGetId(send_port_handle, &send_port_id);
|
||||
if (Dart_IsError(result)) {
|
||||
SetInvalidArgumentReturn(arguments);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int64_t data = 0;
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 3, &data, InvalidArgument);
|
||||
|
||||
ControlData cd;
|
||||
cd.handle = client_handle;
|
||||
cd.port = send_port_id;
|
||||
cd.data = data;
|
||||
const void* bytes = reinterpret_cast<const void*>(&cd);
|
||||
MojoResult res = MojoWriteMessage(
|
||||
control_handle, bytes, sizeof(cd), nullptr, 0, 0);
|
||||
Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(res));
|
||||
}
|
||||
|
||||
void MojoHandleWatcher_RecvControlData(Dart_NativeArguments arguments) {
|
||||
int64_t control_handle = 0;
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 0, &control_handle, Null);
|
||||
|
||||
ControlData cd;
|
||||
void* bytes = reinterpret_cast<void*>(&cd);
|
||||
uint32_t num_bytes = sizeof(cd);
|
||||
uint32_t num_handles = 0;
|
||||
MojoResult res = MojoReadMessage(
|
||||
control_handle, bytes, &num_bytes, nullptr, &num_handles, 0);
|
||||
if (res != MOJO_RESULT_OK) {
|
||||
SetNullReturn(arguments);
|
||||
return;
|
||||
}
|
||||
|
||||
Dart_Handle list = Dart_NewList(3);
|
||||
Dart_ListSetAt(list, 0, Dart_NewInteger(cd.handle));
|
||||
Dart_ListSetAt(list, 1, Dart_NewSendPort(cd.port));
|
||||
Dart_ListSetAt(list, 2, Dart_NewInteger(cd.data));
|
||||
Dart_SetReturnValue(arguments, list);
|
||||
}
|
||||
|
||||
static int64_t mojo_control_handle = MOJO_HANDLE_INVALID;
|
||||
void MojoHandleWatcher_SetControlHandle(Dart_NativeArguments arguments) {
|
||||
int64_t control_handle;
|
||||
CHECK_INTEGER_ARGUMENT(arguments, 0, &control_handle, InvalidArgument);
|
||||
mojo_control_handle = control_handle;
|
||||
Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(MOJO_RESULT_OK));
|
||||
}
|
||||
|
||||
void MojoHandleWatcher_GetControlHandle(Dart_NativeArguments arguments) {
|
||||
Dart_SetIntegerReturnValue(arguments, mojo_control_handle);
|
||||
}
|
||||
|
||||
} // namespace blink
|
||||
20
engine/bindings2/mojo_natives.h
Normal file
20
engine/bindings2/mojo_natives.h
Normal file
@ -0,0 +1,20 @@
|
||||
// Copyright 2014 The Chromium 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 SKY_ENGINE_BINDINGS2_MOJO_NATIVES_H_
|
||||
#define SKY_ENGINE_BINDINGS2_MOJO_NATIVES_H_
|
||||
|
||||
#include "dart/runtime/include/dart_api.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
Dart_NativeFunction MojoNativeLookup(Dart_Handle name,
|
||||
int argument_count,
|
||||
bool* auto_setup_scope);
|
||||
|
||||
const uint8_t* MojoNativeSymbol(Dart_NativeFunction nf);
|
||||
|
||||
} // namespace blink
|
||||
|
||||
#endif // SKY_ENGINE_BINDINGS2_MOJO_NATIVES_H_
|
||||
54
engine/bindings2/nullable.h
Normal file
54
engine/bindings2/nullable.h
Normal file
@ -0,0 +1,54 @@
|
||||
// Copyright 2014 The Chromium 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 SKY_ENGINE_BINDINGS2_NULLABLE_H_
|
||||
#define SKY_ENGINE_BINDINGS2_NULLABLE_H_
|
||||
|
||||
#include "base/logging.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
template <typename T>
|
||||
class Nullable {
|
||||
public:
|
||||
Nullable() : value_(), is_null_(true) {}
|
||||
Nullable(const T& value) : value_(value), is_null_(false) {}
|
||||
Nullable(const Nullable& other)
|
||||
: value_(other.value_), is_null_(other.is_null_) {}
|
||||
|
||||
Nullable& operator=(const Nullable& other) = default;
|
||||
|
||||
void set(const T& value) {
|
||||
value_ = value;
|
||||
is_null_ = false;
|
||||
}
|
||||
|
||||
const T& get() const {
|
||||
DCHECK(!is_null_);
|
||||
return value_;
|
||||
}
|
||||
T& get() {
|
||||
DCHECK(!is_null_);
|
||||
return value_;
|
||||
}
|
||||
|
||||
bool is_null() const { return is_null_; }
|
||||
|
||||
// See comment in RefPtr.h about what UnspecifiedBoolType is.
|
||||
typedef const T* UnspecifiedBoolType;
|
||||
operator UnspecifiedBoolType() const { return is_null_ ? 0 : &value_; }
|
||||
|
||||
bool operator==(const Nullable& other) const {
|
||||
return (is_null_ && other.is_null_) ||
|
||||
(!is_null_ && !other.is_null_ && value_ == other.value_);
|
||||
}
|
||||
|
||||
private:
|
||||
T value_;
|
||||
bool is_null_;
|
||||
};
|
||||
|
||||
} // namespace blink
|
||||
|
||||
#endif // SKY_ENGINE_BINDINGS2_NULLABLE_H_
|
||||
30
engine/bindings2/scheduled_action.cc
Normal file
30
engine/bindings2/scheduled_action.cc
Normal file
@ -0,0 +1,30 @@
|
||||
// Copyright 2014 The Chromium 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 "sky/engine/config.h"
|
||||
#include "sky/engine/bindings2/scheduled_action.h"
|
||||
|
||||
#include "sky/engine/tonic/dart_api_scope.h"
|
||||
#include "sky/engine/tonic/dart_error.h"
|
||||
#include "sky/engine/tonic/dart_isolate_scope.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
ScheduledAction::ScheduledAction(DartState* dart_state, Dart_Handle closure)
|
||||
: closure_(dart_state, closure) {
|
||||
DCHECK(Dart_IsClosure(closure));
|
||||
}
|
||||
|
||||
ScheduledAction::~ScheduledAction() {
|
||||
}
|
||||
|
||||
void ScheduledAction::Execute(ExecutionContext*) {
|
||||
if (!closure_.dart_state())
|
||||
return;
|
||||
DartIsolateScope scope(closure_.dart_state()->isolate());
|
||||
DartApiScope api_scope;
|
||||
LogIfError(Dart_InvokeClosure(closure_.value(), 0, nullptr));
|
||||
}
|
||||
|
||||
} // namespace blink
|
||||
37
engine/bindings2/scheduled_action.h
Normal file
37
engine/bindings2/scheduled_action.h
Normal file
@ -0,0 +1,37 @@
|
||||
// Copyright 2014 The Chromium 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 SKY_ENGINE_BINDINGS2_SCHEDULED_ACTION_H_
|
||||
#define SKY_ENGINE_BINDINGS2_SCHEDULED_ACTION_H_
|
||||
|
||||
#include "dart/runtime/include/dart_api.h"
|
||||
#include "sky/engine/tonic/dart_persistent_value.h"
|
||||
#include "sky/engine/tonic/dart_state.h"
|
||||
#include "sky/engine/wtf/RefPtr.h"
|
||||
#include "sky/engine/wtf/PassOwnPtr.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
class ExecutionContext;
|
||||
|
||||
class ScheduledAction {
|
||||
public:
|
||||
static PassOwnPtr<ScheduledAction> Create(DartState* dart_state,
|
||||
Dart_Handle closure) {
|
||||
return adoptPtr(new ScheduledAction(dart_state, closure));
|
||||
}
|
||||
|
||||
~ScheduledAction();
|
||||
|
||||
void Execute(ExecutionContext*);
|
||||
|
||||
private:
|
||||
ScheduledAction(DartState* dart_state, Dart_Handle closure);
|
||||
|
||||
DartPersistentValue closure_;
|
||||
};
|
||||
|
||||
} // namespace blink
|
||||
|
||||
#endif // SKY_ENGINE_BINDINGS2_SCHEDULED_ACTION_H_
|
||||
@ -8,7 +8,7 @@ static void {{static_attribute_name(attribute, 'Getter')}}(Dart_NativeArguments
|
||||
{% if attribute.is_call_with_execution_context %}
|
||||
ExecutionContext* context = DOMDartState::CurrentDocument();
|
||||
if (!context) {
|
||||
exception = Dart_NewStringFromCString("Failed to retrieve a context");
|
||||
exception = ToDart("Failed to retrieve a context");
|
||||
goto fail;
|
||||
}
|
||||
{% endif %}
|
||||
@ -95,7 +95,7 @@ static void {{static_attribute_name(attribute, 'Setter')}}(Dart_NativeArguments
|
||||
|
||||
ExecutionContext* context = DOMDartState::CurrentDocument();
|
||||
if (!context) {
|
||||
exception = Dart_NewStringFromCString("Failed to retrieve a context");
|
||||
exception = ToDart("Failed to retrieve a context");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -104,7 +104,7 @@ static void {{static_attribute_name(attribute, 'Setter')}}(Dart_NativeArguments
|
||||
{% if attribute.is_call_with_script_state %}
|
||||
ScriptState* state = DartUtilities::currentScriptState();
|
||||
if (!state) {
|
||||
exception = Dart_NewStringFromCString("Failed to retrieve a script state");
|
||||
exception = ToDart("Failed to retrieve a script state");
|
||||
goto fail;
|
||||
}
|
||||
{% endif %}
|
||||
|
||||
@ -94,14 +94,14 @@ static void {{static_method_name(method.name, overload_index)}}(Dart_NativeArgum
|
||||
{% if method.is_call_with_script_state %}
|
||||
ScriptState* state = DartUtilities::currentScriptState();
|
||||
if (!state) {
|
||||
exception = Dart_NewStringFromCString("Failed to retrieve a script state");
|
||||
exception = ToDart("Failed to retrieve a script state");
|
||||
goto fail;
|
||||
}
|
||||
{% endif %}
|
||||
{% if method.is_call_with_execution_context %}
|
||||
ExecutionContext* context = DOMDartState::CurrentDocument();
|
||||
if (!context) {
|
||||
exception = Dart_NewStringFromCString("Failed to retrieve a context");
|
||||
exception = ToDart("Failed to retrieve a context");
|
||||
goto fail;
|
||||
}
|
||||
{% endif %}
|
||||
@ -318,14 +318,14 @@ static void {{static_method_name(constructor.name, overload_index)}}(Dart_Native
|
||||
{% if is_constructor_call_with_execution_context %}
|
||||
ExecutionContext* context = DOMDartState::CurrentDocument();
|
||||
if (!context) {
|
||||
exception = Dart_NewStringFromCString("Failed to retrieve a context");
|
||||
exception = ToDart("Failed to retrieve a context");
|
||||
goto fail;
|
||||
}
|
||||
{% endif %}
|
||||
{% if is_constructor_call_with_document or (constructor == named_constructor) %}
|
||||
LocalDOMWindow* domWindow = DOMDartState::CurrentWindow();
|
||||
if (!domWindow) {
|
||||
exception = Dart_NewStringFromCString("Failed to fetch domWindow");
|
||||
exception = ToDart("Failed to fetch domWindow");
|
||||
goto fail;
|
||||
}
|
||||
Document& document = *domWindow->document();
|
||||
|
||||
18
engine/bindings2/snapshot.cc.tmpl
Normal file
18
engine/bindings2/snapshot.cc.tmpl
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright 2015 The Chromium 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 <inttypes.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
namespace blink {
|
||||
|
||||
// The string on the next line will be filled in with the contents of the
|
||||
// generated snapshot binary file.
|
||||
// This string forms the content of a snapshot which is loaded in by dart.
|
||||
static const uint8_t snapshot_buffer_[] = { % s};
|
||||
|
||||
const uint8_t* kDartSnapshotBuffer = snapshot_buffer_;
|
||||
|
||||
} // namespace blink
|
||||
16
engine/bindings2/snapshot.dart
Normal file
16
engine/bindings2/snapshot.dart
Normal file
@ -0,0 +1,16 @@
|
||||
// Copyright 2015 The Chromium 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:collection';
|
||||
import 'dart:convert';
|
||||
import 'dart:core';
|
||||
import 'dart:isolate';
|
||||
import 'dart:math';
|
||||
import 'dart:mirrors';
|
||||
import 'dart:mojo_bindings';
|
||||
import 'dart:mojo_core';
|
||||
import 'dart:sky';
|
||||
import 'dart:sky_builtin';
|
||||
import 'dart:typed_data';
|
||||
@ -9,6 +9,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "sky/engine/tonic/dart_converter.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
@ -47,4 +48,10 @@ const uint8_t* DartBuiltin::Symbolizer(Dart_NativeFunction native_function) cons
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Dart_Handle DartBuiltin::LookupLibrary(const char* name) {
|
||||
Dart_Handle library = Dart_LookupLibrary(ToDart(name));
|
||||
DCHECK(!Dart_IsError(library));
|
||||
return library;
|
||||
}
|
||||
|
||||
} // namespace blink
|
||||
|
||||
@ -27,6 +27,9 @@ class DartBuiltin {
|
||||
|
||||
const uint8_t* Symbolizer(Dart_NativeFunction native_function) const;
|
||||
|
||||
// Helper around Dart_LookupLibrary.
|
||||
static Dart_Handle LookupLibrary(const char* name);
|
||||
|
||||
private:
|
||||
const Natives* natives_;
|
||||
size_t count_;
|
||||
|
||||
@ -320,6 +320,12 @@ inline std::string StdStringFromDart(Dart_Handle handle) {
|
||||
return std::string(utf8.data(), utf8.length());
|
||||
}
|
||||
|
||||
|
||||
// Alias Dart_NewStringFromCString for less typing.
|
||||
inline Dart_Handle ToDart(const char* val) {
|
||||
return Dart_NewStringFromCString(val);
|
||||
}
|
||||
|
||||
} // namespace blink
|
||||
|
||||
#endif // SKY_ENGINE_TONIC_DART_CONVERTER_H_
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user