Commit 2ce65f04 authored by Yuki Shiino's avatar Yuki Shiino Committed by Commit Bot

bind-gen: Reimplement V8DOMConfiguration as IDLMemberInstaller

Implements the same features of V8DOMConfiguration as a new
class IDLMemberInstaller with refactoring and clean-up.

V8DOMConfiguration remains unchanged in order to make the old
bindings generator workable as much as possible.

IDLMemberInstaller gets rid of old and unnecessary burden, and
the APK size will be reduced by 30 KBytes.

IDL constants of origin trial features are removed because
1) It's not used in production, it's used only in testing.
2) IDL constants themselves are (a sort of) obsolete.
Overall, it's unlikely that we'll need IDL constants of origin
trial features.

Bug: 839389
Change-Id: I7bd876c779542c4889edbec6d9f6d4150e0bfec3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2448570
Commit-Queue: Yuki Shiino <yukishiino@chromium.org>
Reviewed-by: default avatarHitoshi Yoshida <peria@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Reviewed-by: default avatarIan Clelland <iclelland@chromium.org>
Cr-Commit-Position: refs/heads/master@{#816470}
parent 874bd97e
...@@ -202,7 +202,8 @@ def generate_callback_interface(callback_interface_identifier): ...@@ -202,7 +202,8 @@ def generate_callback_interface(callback_interface_identifier):
]) ])
installer_function_defs.accumulate( installer_function_defs.accumulate(
CodeGenAccumulator.require_include_headers([ CodeGenAccumulator.require_include_headers([
"third_party/blink/renderer/bindings/core/v8/v8_dom_configuration.h" "third_party/blink/renderer/bindings/core/v8/v8_dom_configuration.h",
"third_party/blink/renderer/platform/bindings/idl_member_installer.h",
])) ]))
# WrapperTypeInfo # WrapperTypeInfo
......
...@@ -4266,18 +4266,16 @@ ${npo_prototype_template}->SetInternalFieldCount( ...@@ -4266,18 +4266,16 @@ ${npo_prototype_template}->SetInternalFieldCount(
code_node.register_code_symbol(symbol_node) code_node.register_code_symbol(symbol_node)
def _make_property_entry_cached_accessor(property_): def _make_property_entry_cross_origin_check(property_,
value = property_.extended_attributes.value_of("CachedAccessor") is_get=False,
return "V8PrivateProperty::CachedAccessor::{}".format(value or "kNone") is_set=False):
def _make_property_entry_check_cross_origin_access(property_,
is_get=False,
is_set=False):
constants = { constants = {
True: "V8DOMConfiguration::kDoNotCheckAccess", False: "unsigned(IDLMemberInstaller::FlagCrossOriginCheck::kCheck)",
False: "V8DOMConfiguration::kCheckAccess", True:
"unsigned(IDLMemberInstaller::FlagCrossOriginCheck::kDoNotCheck)",
} }
if property_.is_static:
return constants[True]
if "CrossOrigin" not in property_.extended_attributes: if "CrossOrigin" not in property_.extended_attributes:
return constants[False] return constants[False]
values = property_.extended_attributes.values_of("CrossOrigin") values = property_.extended_attributes.values_of("CrossOrigin")
...@@ -4289,54 +4287,26 @@ def _make_property_entry_check_cross_origin_access(property_, ...@@ -4289,54 +4287,26 @@ def _make_property_entry_check_cross_origin_access(property_,
return constants[True] return constants[True]
def _make_property_entry_check_receiver(property_): def _make_property_entry_location(property_):
if hasattr(property_, "is_static") and property_.is_static:
return "unsigned(IDLMemberInstaller::FlagLocation::kInterface)"
if "Global" in property_.owner.extended_attributes:
return "unsigned(IDLMemberInstaller::FlagLocation::kInstance)"
if "LegacyUnforgeable" in property_.extended_attributes:
return "unsigned(IDLMemberInstaller::FlagLocation::kInstance)"
return "unsigned(IDLMemberInstaller::FlagLocation::kPrototype)"
def _make_property_entry_receiver_check(property_):
if ("LegacyLenientThis" in property_.extended_attributes if ("LegacyLenientThis" in property_.extended_attributes
or property_.is_static
or (isinstance(property_, web_idl.Attribute) or (isinstance(property_, web_idl.Attribute)
and property_.idl_type.unwrap().is_promise) and property_.idl_type.unwrap().is_promise)
or (isinstance(property_, web_idl.OverloadGroup) or (isinstance(property_, web_idl.OverloadGroup)
and property_[0].return_type.unwrap().is_promise)): and property_[0].return_type.unwrap().is_promise)):
return "V8DOMConfiguration::kDoNotCheckHolder" return "unsigned(IDLMemberInstaller::FlagReceiverCheck::kDoNotCheck)"
else: else:
return "V8DOMConfiguration::kCheckHolder" return "unsigned(IDLMemberInstaller::FlagReceiverCheck::kCheck)"
def _make_property_entry_constant_type_and_value_format(property_):
idl_type = property_.idl_type.unwrap()
if (idl_type.keyword_typename == "long long"
or idl_type.keyword_typename == "unsigned long long"):
assert False, "64-bit constants are not yet supported."
if idl_type.keyword_typename == "unsigned long":
return ("V8DOMConfiguration::kConstantTypeUnsignedLong",
"static_cast<int>({value})")
if idl_type.is_integer:
return ("V8DOMConfiguration::kConstantTypeLong",
"static_cast<int>({value})")
if idl_type.is_floating_point_numeric:
return ("V8DOMConfiguration::kConstantTypeDouble",
"static_cast<double>({value})")
assert False, "Unsupported type: {}".format(idl_type.syntactic_form)
def _make_property_entry_has_side_effect(property_):
if property_.extended_attributes.value_of("Affects") == "Nothing":
return "V8DOMConfiguration::kHasNoSideEffect"
else:
return "V8DOMConfiguration::kHasSideEffect"
def _make_property_entry_on_which_object(property_):
ON_INSTANCE = "V8DOMConfiguration::kOnInstance"
ON_PROTOTYPE = "V8DOMConfiguration::kOnPrototype"
ON_INTERFACE = "V8DOMConfiguration::kOnInterface"
if isinstance(property_, web_idl.Constant):
return ON_INTERFACE
if hasattr(property_, "is_static") and property_.is_static:
return ON_INTERFACE
if "Global" in property_.owner.extended_attributes:
return ON_INSTANCE
if "LegacyUnforgeable" in property_.extended_attributes:
return ON_INSTANCE
return ON_PROTOTYPE
def _make_property_entry_v8_c_function(entry): def _make_property_entry_v8_c_function(entry):
...@@ -4346,6 +4316,11 @@ def _make_property_entry_v8_c_function(entry): ...@@ -4346,6 +4316,11 @@ def _make_property_entry_v8_c_function(entry):
entry.no_alloc_direct_callback_name) entry.no_alloc_direct_callback_name)
def _make_property_entry_v8_cached_accessor(property_):
return "unsigned(V8PrivateProperty::CachedAccessor::{})".format(
property_.extended_attributes.value_of("CachedAccessor") or "kNone")
def _make_property_entry_v8_property_attribute(property_): def _make_property_entry_v8_property_attribute(property_):
values = [] values = []
if "NotEnumerable" in property_.extended_attributes: if "NotEnumerable" in property_.extended_attributes:
...@@ -4357,19 +4332,25 @@ def _make_property_entry_v8_property_attribute(property_): ...@@ -4357,19 +4332,25 @@ def _make_property_entry_v8_property_attribute(property_):
if not values: if not values:
values.append("v8::None") values.append("v8::None")
if len(values) == 1: if len(values) == 1:
return values[0] return "unsigned({})".format(values[0])
else:
return "unsigned({})".format(" | ".join(values))
def _make_property_entry_v8_side_effect(property_):
if property_.extended_attributes.value_of("Affects") == "Nothing":
return "unsigned(v8::SideEffectType::kHasNoSideEffect)"
else: else:
return "static_cast<v8::PropertyAttribute>({})".format( return "unsigned(v8::SideEffectType::kHasSideEffect)"
" | ".join(values))
def _make_property_entry_world(world): def _make_property_entry_world(world):
if world == CodeGenContext.MAIN_WORLD: if world == CodeGenContext.MAIN_WORLD:
return "V8DOMConfiguration::kMainWorld" return "unsigned(IDLMemberInstaller::FlagWorld::kMainWorld)"
if world == CodeGenContext.NON_MAIN_WORLDS: if world == CodeGenContext.NON_MAIN_WORLDS:
return "V8DOMConfiguration::kNonMainWorlds" return "unsigned(IDLMemberInstaller::FlagWorld::kNonMainWorlds)"
if world == CodeGenContext.ALL_WORLDS: if world == CodeGenContext.ALL_WORLDS:
return "V8DOMConfiguration::kAllWorlds" return "unsigned(IDLMemberInstaller::FlagWorld::kAllWorlds)"
assert False assert False
...@@ -4387,42 +4368,41 @@ def _make_attribute_registration_table(table_name, attribute_entries): ...@@ -4387,42 +4368,41 @@ def _make_attribute_registration_table(table_name, attribute_entries):
"\"{property_name}\", " "\"{property_name}\", "
"{attribute_get_callback}, " "{attribute_get_callback}, "
"{attribute_set_callback}, " "{attribute_set_callback}, "
"static_cast<unsigned>({cached_accessor}), "
"{v8_property_attribute}, " "{v8_property_attribute}, "
"{on_which_object}, " "{location}, "
"{check_receiver}, " "{world}, "
"{check_cross_origin_get_access}, " "{receiver_check}, "
"{check_cross_origin_set_access}, " "{cross_origin_check_for_get}, "
"{has_side_effect}, " "{cross_origin_check_for_set}, "
"{world}" "{v8_side_effect}, "
"{v8_cached_accessor}"
"}},") "}},")
text = _format( text = _format(
pattern, pattern,
property_name=entry.property_.identifier, property_name=entry.property_.identifier,
attribute_get_callback=entry.attr_get_callback_name, attribute_get_callback=entry.attr_get_callback_name,
attribute_set_callback=(entry.attr_set_callback_name or "nullptr"), attribute_set_callback=(entry.attr_set_callback_name or "nullptr"),
cached_accessor=_make_property_entry_cached_accessor(
entry.property_),
v8_property_attribute=_make_property_entry_v8_property_attribute( v8_property_attribute=_make_property_entry_v8_property_attribute(
entry.property_), entry.property_),
on_which_object=_make_property_entry_on_which_object( location=_make_property_entry_location(entry.property_),
entry.property_), world=_make_property_entry_world(entry.world),
check_receiver=_make_property_entry_check_receiver( receiver_check=_make_property_entry_receiver_check(
entry.property_), entry.property_),
check_cross_origin_get_access=( cross_origin_check_for_get=(
_make_property_entry_check_cross_origin_access(entry.property_, _make_property_entry_cross_origin_check(entry.property_,
is_get=True)), is_get=True)),
check_cross_origin_set_access=( cross_origin_check_for_set=(
_make_property_entry_check_cross_origin_access(entry.property_, _make_property_entry_cross_origin_check(entry.property_,
is_set=True)), is_set=True)),
has_side_effect=_make_property_entry_has_side_effect( v8_side_effect=_make_property_entry_v8_side_effect(
entry.property_), entry.property_),
world=_make_property_entry_world(entry.world)) v8_cached_accessor=_make_property_entry_v8_cached_accessor(
entry.property_))
entry_nodes.append(T(text)) entry_nodes.append(T(text))
return ListNode([ return ListNode([
T("static constexpr const V8DOMConfiguration::AccessorConfiguration " + T("static const IDLMemberInstaller::AttributeConfig " + table_name +
table_name + "[] = {"), "[] = {"),
ListNode(entry_nodes), ListNode(entry_nodes),
T("};"), T("};"),
]) ])
...@@ -4448,9 +4428,8 @@ def _make_constant_callback_registration_table(table_name, constant_entries): ...@@ -4448,9 +4428,8 @@ def _make_constant_callback_registration_table(table_name, constant_entries):
entry_nodes.append(T(text)) entry_nodes.append(T(text))
return ListNode([ return ListNode([
T("static constexpr const " T("static const IDLMemberInstaller::ConstantCallbackConfig " +
"V8DOMConfiguration::ConstantCallbackConfiguration " + table_name + table_name + "[] = {"),
"[] = {"),
ListNode(entry_nodes), ListNode(entry_nodes),
T("};"), T("};"),
]) ])
...@@ -4469,23 +4448,15 @@ def _make_constant_value_registration_table(table_name, constant_entries): ...@@ -4469,23 +4448,15 @@ def _make_constant_value_registration_table(table_name, constant_entries):
for entry in constant_entries: for entry in constant_entries:
pattern = ("{{" pattern = ("{{"
"\"{property_name}\", " "\"{property_name}\", "
"{constant_type}, "
"{constant_value}" "{constant_value}"
"}},") "}},")
constant_type, constant_value_fmt = ( text = _format(pattern,
_make_property_entry_constant_type_and_value_format( property_name=entry.property_.identifier,
entry.property_)) constant_value=entry.const_constant_name)
constant_value = _format(
constant_value_fmt, value=entry.const_constant_name)
text = _format(
pattern,
property_name=entry.property_.identifier,
constant_type=constant_type,
constant_value=constant_value)
entry_nodes.append(T(text)) entry_nodes.append(T(text))
return ListNode([ return ListNode([
T("static constexpr const V8DOMConfiguration::ConstantConfiguration " + T("static const IDLMemberInstaller::ConstantValueConfig " +
table_name + "[] = {"), table_name + "[] = {"),
ListNode(entry_nodes), ListNode(entry_nodes),
T("};"), T("};"),
...@@ -4506,25 +4477,16 @@ def _make_exposed_construct_registration_table(table_name, ...@@ -4506,25 +4477,16 @@ def _make_exposed_construct_registration_table(table_name,
for entry in exposed_construct_entries: for entry in exposed_construct_entries:
pattern = ("{{" pattern = ("{{"
"\"{property_name}\", " "\"{property_name}\", "
"{exposed_construct_callback}, " "{exposed_construct_callback}"
"nullptr, "
"static_cast<v8::PropertyAttribute>(v8::DontEnum), "
"V8DOMConfiguration::kOnInstance, "
"V8DOMConfiguration::kDoNotCheckHolder, "
"V8DOMConfiguration::kHasNoSideEffect, "
"V8DOMConfiguration::kReplaceWithDataProperty, "
"{world}"
"}}, ") "}}, ")
text = _format( text = _format(pattern,
pattern, property_name=entry.property_.identifier,
property_name=entry.property_.identifier, exposed_construct_callback=entry.prop_callback_name)
exposed_construct_callback=entry.prop_callback_name,
world=_make_property_entry_world(entry.world))
entry_nodes.append(T(text)) entry_nodes.append(T(text))
return ListNode([ return ListNode([
T("static constexpr const V8DOMConfiguration::AttributeConfiguration " T("static const IDLMemberInstaller::ExposedConstructConfig " +
+ table_name + "[] = {"), table_name + "[] = {"),
ListNode(entry_nodes), ListNode(entry_nodes),
T("};"), T("};"),
]) ])
...@@ -4554,11 +4516,11 @@ def _make_operation_registration_table(table_name, operation_entries): ...@@ -4554,11 +4516,11 @@ def _make_operation_registration_table(table_name, operation_entries):
"{operation_callback}, " "{operation_callback}, "
"{function_length}, " "{function_length}, "
"{v8_property_attribute}, " "{v8_property_attribute}, "
"{on_which_object}, " "{location}, "
"{check_receiver}, " "{world}, "
"{check_cross_origin_access}, " "{receiver_check}, "
"{has_side_effect}, " "{cross_origin_check}, "
"{world}" "{v8_side_effect}"
"}}, ") "}}, ")
if no_alloc_direct_call_enabled: if no_alloc_direct_call_enabled:
pattern = "{{" + pattern + "{v8_c_function}}}, " pattern = "{{" + pattern + "{v8_c_function}}}, "
...@@ -4569,24 +4531,23 @@ def _make_operation_registration_table(table_name, operation_entries): ...@@ -4569,24 +4531,23 @@ def _make_operation_registration_table(table_name, operation_entries):
function_length=entry.op_func_length, function_length=entry.op_func_length,
v8_property_attribute=_make_property_entry_v8_property_attribute( v8_property_attribute=_make_property_entry_v8_property_attribute(
entry.property_), entry.property_),
on_which_object=_make_property_entry_on_which_object( location=_make_property_entry_location(entry.property_),
world=_make_property_entry_world(entry.world),
receiver_check=_make_property_entry_receiver_check(
entry.property_), entry.property_),
check_receiver=_make_property_entry_check_receiver( cross_origin_check=_make_property_entry_cross_origin_check(
entry.property_), entry.property_),
check_cross_origin_access=( v8_side_effect=_make_property_entry_v8_side_effect(
_make_property_entry_check_cross_origin_access(
entry.property_)),
has_side_effect=_make_property_entry_has_side_effect(
entry.property_), entry.property_),
world=_make_property_entry_world(entry.world),
v8_c_function=_make_property_entry_v8_c_function(entry)) v8_c_function=_make_property_entry_v8_c_function(entry))
entry_nodes.append(T(text)) entry_nodes.append(T(text))
table_decl_before_name = ( table_decl_before_name = (
"static constexpr const V8DOMConfiguration::MethodConfiguration") "static const IDLMemberInstaller::OperationConfig")
if no_alloc_direct_call_enabled: if no_alloc_direct_call_enabled:
table_decl_before_name = ("static const V8DOMConfiguration::" table_decl_before_name = (
"NoAllocDirectCallMethodConfiguration") "static const "
"IDLMemberInstaller::NoAllocDirectCallOperationConfig")
return ListNode([ return ListNode([
T(table_decl_before_name + " " + table_name + "[] = {"), T(table_decl_before_name + " " + table_name + "[] = {"),
ListNode(entry_nodes), ListNode(entry_nodes),
...@@ -5480,6 +5441,11 @@ def make_install_properties(cg_context, function_name, class_name, ...@@ -5480,6 +5441,11 @@ def make_install_properties(cg_context, function_name, class_name,
body.add_template_var(arg_name, arg_name) body.add_template_var(arg_name, arg_name)
bind_installer_local_vars(body, cg_context) bind_installer_local_vars(body, cg_context)
body.extend([
TextNode("using bindings::IDLMemberInstaller;"),
EmptyNode(),
])
if (is_per_context_install if (is_per_context_install
and "Global" in cg_context.interface.extended_attributes): and "Global" in cg_context.interface.extended_attributes):
body.extend([ body.extend([
...@@ -5531,32 +5497,34 @@ ${instance_object} = ${v8_context}->Global()->GetPrototype().As<v8::Object>();\ ...@@ -5531,32 +5497,34 @@ ${instance_object} = ${v8_context}->Global()->GetPrototype().As<v8::Object>();\
])) ]))
body.append(EmptyNode()) body.append(EmptyNode())
table_name = "kAttributeTable"
if is_per_context_install: if is_per_context_install:
installer_call_text = ( pattern = ("{install_func}("
"V8DOMConfiguration::InstallAccessors(${isolate}, ${world}, " "${isolate}, ${world}, "
"${instance_object}, ${prototype_object}, ${interface_object}, " "v8::Local<v8::Object>(${instance_object}), "
"${signature}, kAttributeTable, base::size(kAttributeTable));") "v8::Local<v8::Object>(${prototype_object}), "
"v8::Local<v8::Object>(${interface_object}), "
"${signature}, {table_name});")
else: else:
installer_call_text = ( pattern = ("{install_func}("
"V8DOMConfiguration::InstallAccessors(${isolate}, ${world}, " "${isolate}, ${world}, "
"${instance_template}, ${prototype_template}, " "v8::Local<v8::Template>(${instance_template}), "
"${interface_template}, ${signature}, " "v8::Local<v8::Template>(${prototype_template}), "
"kAttributeTable, base::size(kAttributeTable));") "v8::Local<v8::Template>(${interface_template}), "
"${signature}, {table_name});")
table_name = "kAttributeTable"
installer_call_text = _format(
pattern,
install_func="IDLMemberInstaller::InstallAttributes",
table_name=table_name)
install_properties(table_name, attribute_entries, install_properties(table_name, attribute_entries,
_make_attribute_registration_table, installer_call_text) _make_attribute_registration_table, installer_call_text)
table_name = "kConstantCallbackTable" table_name = "kConstantCallbackTable"
if is_per_context_install: installer_call_text = _format(
installer_call_text = ( pattern,
"V8DOMConfiguration::InstallConstants(${isolate}, " install_func="IDLMemberInstaller::InstallConstants",
"${interface_object}, ${prototype_object}, " table_name=table_name)
"kConstantCallbackTable, base::size(kConstantCallbackTable));")
else:
installer_call_text = (
"V8DOMConfiguration::InstallConstants(${isolate}, "
"${interface_template}, ${prototype_template}, "
"kConstantCallbackTable, base::size(kConstantCallbackTable));")
constant_callback_entries = filter(lambda entry: entry.const_callback_name, constant_callback_entries = filter(lambda entry: entry.const_callback_name,
constant_entries) constant_entries)
install_properties(table_name, constant_callback_entries, install_properties(table_name, constant_callback_entries,
...@@ -5564,16 +5532,10 @@ ${instance_object} = ${v8_context}->Global()->GetPrototype().As<v8::Object>();\ ...@@ -5564,16 +5532,10 @@ ${instance_object} = ${v8_context}->Global()->GetPrototype().As<v8::Object>();\
installer_call_text) installer_call_text)
table_name = "kConstantValueTable" table_name = "kConstantValueTable"
if is_per_context_install: installer_call_text = _format(
installer_call_text = ( pattern,
"V8DOMConfiguration::InstallConstants(${isolate}, " install_func="IDLMemberInstaller::InstallConstants",
"${interface_object}, ${prototype_object}, " table_name=table_name)
"kConstantValueTable, base::size(kConstantValueTable));")
else:
installer_call_text = (
"V8DOMConfiguration::InstallConstants(${isolate}, "
"${interface_template}, ${prototype_template}, "
"kConstantValueTable, base::size(kConstantValueTable));")
constant_value_entries = filter( constant_value_entries = filter(
lambda entry: not entry.const_callback_name, constant_entries) lambda entry: not entry.const_callback_name, constant_entries)
install_properties(table_name, constant_value_entries, install_properties(table_name, constant_value_entries,
...@@ -5581,32 +5543,19 @@ ${instance_object} = ${v8_context}->Global()->GetPrototype().As<v8::Object>();\ ...@@ -5581,32 +5543,19 @@ ${instance_object} = ${v8_context}->Global()->GetPrototype().As<v8::Object>();\
installer_call_text) installer_call_text)
table_name = "kExposedConstructTable" table_name = "kExposedConstructTable"
if is_per_context_install: installer_call_text = _format(
installer_call_text = ( pattern,
"V8DOMConfiguration::InstallAttributes(${isolate}, ${world}, " install_func="IDLMemberInstaller::InstallExposedConstructs",
"${instance_object}, ${prototype_object}, " table_name=table_name)
"kExposedConstructTable, base::size(kExposedConstructTable));")
else:
installer_call_text = (
"V8DOMConfiguration::InstallAttributes(${isolate}, ${world}, "
"${instance_template}, ${prototype_template}, "
"kExposedConstructTable, base::size(kExposedConstructTable));")
install_properties(table_name, exposed_construct_entries, install_properties(table_name, exposed_construct_entries,
_make_exposed_construct_registration_table, _make_exposed_construct_registration_table,
installer_call_text) installer_call_text)
table_name = "kOperationTable" table_name = "kOperationTable"
if is_per_context_install: installer_call_text = _format(
installer_call_text = ( pattern,
"V8DOMConfiguration::InstallMethods(${isolate}, ${world}, " install_func="IDLMemberInstaller::InstallOperations",
"${instance_object}, ${prototype_object}, ${interface_object}, " table_name=table_name)
"${signature}, kOperationTable, base::size(kOperationTable));")
else:
installer_call_text = (
"V8DOMConfiguration::InstallMethods(${isolate}, ${world}, "
"${instance_template}, ${prototype_template}, "
"${interface_template}, ${signature}, "
"kOperationTable, base::size(kOperationTable));")
entries = filter(lambda entry: not entry.no_alloc_direct_callback_name, entries = filter(lambda entry: not entry.no_alloc_direct_callback_name,
operation_entries) operation_entries)
install_properties(table_name, entries, _make_operation_registration_table, install_properties(table_name, entries, _make_operation_registration_table,
...@@ -6956,6 +6905,7 @@ def generate_interface(interface_identifier): ...@@ -6956,6 +6905,7 @@ def generate_interface(interface_identifier):
"third_party/blink/renderer/bindings/core/v8/v8_dom_configuration.h", "third_party/blink/renderer/bindings/core/v8/v8_dom_configuration.h",
"third_party/blink/renderer/bindings/core/v8/v8_set_return_value_for_core.h", "third_party/blink/renderer/bindings/core/v8/v8_set_return_value_for_core.h",
"third_party/blink/renderer/platform/bindings/exception_messages.h", "third_party/blink/renderer/platform/bindings/exception_messages.h",
"third_party/blink/renderer/platform/bindings/idl_member_installer.h",
"third_party/blink/renderer/platform/bindings/runtime_call_stats.h", "third_party/blink/renderer/platform/bindings/runtime_call_stats.h",
"third_party/blink/renderer/platform/bindings/v8_binding.h", "third_party/blink/renderer/platform/bindings/v8_binding.h",
]) ])
......
...@@ -7,7 +7,6 @@ interface OriginTrialsTest { ...@@ -7,7 +7,6 @@ interface OriginTrialsTest {
[RuntimeEnabled=OriginTrialsSampleAPI] static readonly attribute boolean staticAttribute; [RuntimeEnabled=OriginTrialsSampleAPI] static readonly attribute boolean staticAttribute;
[RuntimeEnabled=OriginTrialsSampleAPI] boolean normalMethod(); [RuntimeEnabled=OriginTrialsSampleAPI] boolean normalMethod();
[RuntimeEnabled=OriginTrialsSampleAPI] static boolean staticMethod(); [RuntimeEnabled=OriginTrialsSampleAPI] static boolean staticMethod();
[RuntimeEnabled=OriginTrialsSampleAPI] const unsigned short CONSTANT = 1;
// This attribute uses native code to test whether the trial is enabled, // This attribute uses native code to test whether the trial is enabled,
// and throws an exception in JavaScript if it is not. // and throws an exception in JavaScript if it is not.
...@@ -27,7 +26,6 @@ interface OriginTrialsTest { ...@@ -27,7 +26,6 @@ interface OriginTrialsTest {
boolean unconditionalMethod(); boolean unconditionalMethod();
void unconditionalDictionaryMethod(OriginTrialsTestDictionary dict); void unconditionalDictionaryMethod(OriginTrialsTestDictionary dict);
static boolean staticUnconditionalMethod(); static boolean staticUnconditionalMethod();
const unsigned short UNCONDITIONAL_CONSTANT = 99;
// These are available whether or not the trial is enabled, but only in a // These are available whether or not the trial is enabled, but only in a
// secure context. // secure context.
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
ImplementedAs=OriginTrialsTestPartial, ImplementedAs=OriginTrialsTestPartial,
RuntimeEnabled=OriginTrialsSampleAPI RuntimeEnabled=OriginTrialsSampleAPI
] partial interface OriginTrialsTest { ] partial interface OriginTrialsTest {
const unsigned short CONSTANT_PARTIAL = 2;
readonly attribute boolean normalAttributePartial; readonly attribute boolean normalAttributePartial;
static readonly attribute boolean staticAttributePartial; static readonly attribute boolean staticAttributePartial;
boolean normalMethodPartial(); boolean normalMethodPartial();
......
...@@ -418,6 +418,8 @@ component("platform") { ...@@ -418,6 +418,8 @@ component("platform") {
"bindings/exception_messages.h", "bindings/exception_messages.h",
"bindings/exception_state.cc", "bindings/exception_state.cc",
"bindings/exception_state.h", "bindings/exception_state.h",
"bindings/idl_member_installer.cc",
"bindings/idl_member_installer.h",
"bindings/microtask.cc", "bindings/microtask.cc",
"bindings/microtask.h", "bindings/microtask.h",
"bindings/name_client.h", "bindings/name_client.h",
......
// Copyright 2020 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 "third_party/blink/renderer/platform/bindings/idl_member_installer.h"
#include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h"
#include "third_party/blink/renderer/platform/bindings/v8_binding.h"
#include "third_party/blink/renderer/platform/bindings/v8_private_property.h"
namespace blink {
namespace bindings {
namespace {
template <typename Config>
bool DoesWorldMatch(const Config& config, const DOMWrapperWorld& world) {
const unsigned world_bit = static_cast<unsigned>(
world.IsMainWorld() ? IDLMemberInstaller::FlagWorld::kMainWorld
: IDLMemberInstaller::FlagWorld::kNonMainWorlds);
return config.world & world_bit;
}
enum class FunctionKind {
kAttributeGet,
kAttributeSet,
kOperation,
};
template <FunctionKind kind, typename Config>
v8::FunctionCallback GetConfigCallback(const Config& config);
template <>
v8::FunctionCallback GetConfigCallback<FunctionKind::kAttributeGet>(
const IDLMemberInstaller::AttributeConfig& config) {
return config.callback_for_get;
}
template <>
v8::FunctionCallback GetConfigCallback<FunctionKind::kAttributeSet>(
const IDLMemberInstaller::AttributeConfig& config) {
return config.callback_for_set;
}
template <>
v8::FunctionCallback GetConfigCallback<FunctionKind::kOperation>(
const IDLMemberInstaller::OperationConfig& config) {
return config.callback;
}
template <FunctionKind kind, typename Config>
int GetConfigLength(const Config& config);
template <>
int GetConfigLength<FunctionKind::kAttributeGet>(
const IDLMemberInstaller::AttributeConfig& config) {
return 0;
}
template <>
int GetConfigLength<FunctionKind::kAttributeSet>(
const IDLMemberInstaller::AttributeConfig& config) {
return 1;
}
template <>
int GetConfigLength<FunctionKind::kOperation>(
const IDLMemberInstaller::OperationConfig& config) {
return config.length;
}
template <FunctionKind kind, typename Config>
IDLMemberInstaller::FlagCrossOriginCheck GetConfigCrossOriginCheck(
const Config& config);
template <>
IDLMemberInstaller::FlagCrossOriginCheck
GetConfigCrossOriginCheck<FunctionKind::kAttributeGet>(
const IDLMemberInstaller::AttributeConfig& config) {
return static_cast<IDLMemberInstaller::FlagCrossOriginCheck>(
config.cross_origin_check_for_get);
}
template <>
IDLMemberInstaller::FlagCrossOriginCheck
GetConfigCrossOriginCheck<FunctionKind::kAttributeSet>(
const IDLMemberInstaller::AttributeConfig& config) {
return static_cast<IDLMemberInstaller::FlagCrossOriginCheck>(
config.cross_origin_check_for_set);
}
template <>
IDLMemberInstaller::FlagCrossOriginCheck
GetConfigCrossOriginCheck<FunctionKind::kOperation>(
const IDLMemberInstaller::OperationConfig& config) {
return static_cast<IDLMemberInstaller::FlagCrossOriginCheck>(
config.cross_origin_check);
}
template <FunctionKind kind, typename Config>
v8::SideEffectType GetConfigSideEffect(const Config& config);
template <>
v8::SideEffectType GetConfigSideEffect<FunctionKind::kAttributeGet>(
const IDLMemberInstaller::AttributeConfig& config) {
return static_cast<v8::SideEffectType>(config.v8_side_effect);
}
template <>
v8::SideEffectType GetConfigSideEffect<FunctionKind::kAttributeSet>(
const IDLMemberInstaller::AttributeConfig& config) {
return v8::SideEffectType::kHasSideEffect;
}
template <>
v8::SideEffectType GetConfigSideEffect<FunctionKind::kOperation>(
const IDLMemberInstaller::OperationConfig& config) {
return static_cast<v8::SideEffectType>(config.v8_side_effect);
}
template <FunctionKind kind, typename Config>
V8PrivateProperty::CachedAccessor GetConfigV8CachedAccessor(
const Config& config);
template <>
V8PrivateProperty::CachedAccessor
GetConfigV8CachedAccessor<FunctionKind::kAttributeGet>(
const IDLMemberInstaller::AttributeConfig& config) {
return static_cast<V8PrivateProperty::CachedAccessor>(
config.v8_cached_accessor);
}
template <>
V8PrivateProperty::CachedAccessor
GetConfigV8CachedAccessor<FunctionKind::kAttributeSet>(
const IDLMemberInstaller::AttributeConfig& config) {
return V8PrivateProperty::CachedAccessor::kNone;
}
template <>
V8PrivateProperty::CachedAccessor
GetConfigV8CachedAccessor<FunctionKind::kOperation>(
const IDLMemberInstaller::OperationConfig& config) {
return V8PrivateProperty::CachedAccessor::kNone;
}
template <FunctionKind kind, typename Config>
v8::Local<v8::FunctionTemplate> CreateFunctionTemplate(
v8::Isolate* isolate,
const DOMWrapperWorld& world,
v8::Local<v8::Signature> signature,
v8::Local<v8::String> name,
const Config& config,
const v8::CFunction* v8_c_function = nullptr) {
v8::FunctionCallback callback = GetConfigCallback<kind>(config);
if (!callback)
return v8::Local<v8::FunctionTemplate>();
int length = GetConfigLength<kind>(config);
v8::SideEffectType v8_side_effect = GetConfigSideEffect<kind>(config);
V8PrivateProperty::CachedAccessor v8_cached_accessor =
GetConfigV8CachedAccessor<kind>(config);
v8::Local<v8::FunctionTemplate> function_template;
if (v8_cached_accessor == V8PrivateProperty::CachedAccessor::kNone ||
(v8_cached_accessor ==
V8PrivateProperty::CachedAccessor::kWindowDocument &&
!world.IsMainWorld())) {
function_template = v8::FunctionTemplate::New(
isolate, callback, v8::Local<v8::Value>(), signature, length,
v8::ConstructorBehavior::kThrow, v8_side_effect, v8_c_function);
} else {
function_template = v8::FunctionTemplate::NewWithCache(
isolate, callback,
V8PrivateProperty::GetCachedAccessor(isolate, v8_cached_accessor)
.GetPrivate(),
v8::Local<v8::Value>(), signature, length, v8_side_effect);
}
function_template->SetClassName(name);
function_template->RemovePrototype();
function_template->SetAcceptAnyReceiver(
GetConfigCrossOriginCheck<kind>(config) ==
IDLMemberInstaller::FlagCrossOriginCheck::kDoNotCheck);
return function_template;
}
template <FunctionKind kind, typename Config>
v8::Local<v8::Function> CreateFunction(v8::Isolate* isolate,
v8::Local<v8::Context> context,
const DOMWrapperWorld& world,
v8::Local<v8::Signature> signature,
v8::Local<v8::String> name,
const Config& config) {
if (!GetConfigCallback<kind>(config))
return v8::Local<v8::Function>();
return CreateFunctionTemplate<kind>(isolate, world, signature, name, config)
->GetFunction(context)
.ToLocalChecked();
}
void InstallAttribute(v8::Isolate* isolate,
const DOMWrapperWorld& world,
v8::Local<v8::Template> instance_template,
v8::Local<v8::Template> prototype_template,
v8::Local<v8::Template> interface_template,
v8::Local<v8::Signature> signature,
const IDLMemberInstaller::AttributeConfig& config) {
if (!DoesWorldMatch(config, world))
return;
IDLMemberInstaller::FlagLocation location =
static_cast<IDLMemberInstaller::FlagLocation>(config.location);
if (static_cast<IDLMemberInstaller::FlagReceiverCheck>(
config.receiver_check) ==
IDLMemberInstaller::FlagReceiverCheck::kDoNotCheck ||
location == IDLMemberInstaller::FlagLocation::kInterface)
signature = v8::Local<v8::Signature>();
StringView name_as_view(config.name);
v8::Local<v8::String> name = V8AtomicString(isolate, name_as_view);
v8::Local<v8::String> get_name = V8AtomicString(
isolate, static_cast<String>(StringView("get ", 4) + name_as_view));
v8::Local<v8::String> set_name = V8AtomicString(
isolate, static_cast<String>(StringView("set ", 4) + name_as_view));
v8::Local<v8::FunctionTemplate> get_func =
CreateFunctionTemplate<FunctionKind::kAttributeGet>(
isolate, world, signature, get_name, config);
v8::Local<v8::FunctionTemplate> set_func =
CreateFunctionTemplate<FunctionKind::kAttributeSet>(
isolate, world, signature, set_name, config);
v8::Local<v8::Template> target_template;
switch (location) {
case IDLMemberInstaller::FlagLocation::kInstance:
target_template = instance_template;
break;
case IDLMemberInstaller::FlagLocation::kPrototype:
target_template = prototype_template;
break;
case IDLMemberInstaller::FlagLocation::kInterface:
target_template = interface_template;
break;
default:
NOTREACHED();
}
target_template->SetAccessorProperty(
name, get_func, set_func,
static_cast<v8::PropertyAttribute>(config.v8_property_attribute));
}
void InstallAttribute(v8::Isolate* isolate,
v8::Local<v8::Context> context,
const DOMWrapperWorld& world,
v8::Local<v8::Object> instance_object,
v8::Local<v8::Object> prototype_object,
v8::Local<v8::Object> interface_object,
v8::Local<v8::Signature> signature,
const IDLMemberInstaller::AttributeConfig& config) {
if (!DoesWorldMatch(config, world))
return;
IDLMemberInstaller::FlagLocation location =
static_cast<IDLMemberInstaller::FlagLocation>(config.location);
if (static_cast<IDLMemberInstaller::FlagReceiverCheck>(
config.receiver_check) ==
IDLMemberInstaller::FlagReceiverCheck::kDoNotCheck ||
location == IDLMemberInstaller::FlagLocation::kInterface)
signature = v8::Local<v8::Signature>();
StringView name_as_view(config.name);
v8::Local<v8::String> name = V8AtomicString(isolate, name_as_view);
v8::Local<v8::String> get_name = V8AtomicString(
isolate, static_cast<String>(StringView("get ", 4) + name_as_view));
v8::Local<v8::String> set_name = V8AtomicString(
isolate, static_cast<String>(StringView("set ", 4) + name_as_view));
v8::Local<v8::Function> get_func =
CreateFunction<FunctionKind::kAttributeGet>(isolate, context, world,
signature, get_name, config);
v8::Local<v8::Function> set_func =
CreateFunction<FunctionKind::kAttributeSet>(isolate, context, world,
signature, set_name, config);
v8::Local<v8::Object> target_object;
switch (location) {
case IDLMemberInstaller::FlagLocation::kInstance:
target_object = instance_object;
break;
case IDLMemberInstaller::FlagLocation::kPrototype:
target_object = prototype_object;
break;
case IDLMemberInstaller::FlagLocation::kInterface:
target_object = interface_object;
break;
default:
NOTREACHED();
}
target_object->SetAccessorProperty(
name, get_func, set_func,
static_cast<v8::PropertyAttribute>(config.v8_property_attribute));
}
void InstallOperation(v8::Isolate* isolate,
const DOMWrapperWorld& world,
v8::Local<v8::Template> instance_template,
v8::Local<v8::Template> prototype_template,
v8::Local<v8::Template> interface_template,
v8::Local<v8::Signature> signature,
const IDLMemberInstaller::OperationConfig& config,
const v8::CFunction* v8_c_function = nullptr) {
if (!DoesWorldMatch(config, world))
return;
IDLMemberInstaller::FlagLocation location =
static_cast<IDLMemberInstaller::FlagLocation>(config.location);
if (static_cast<IDLMemberInstaller::FlagReceiverCheck>(
config.receiver_check) ==
IDLMemberInstaller::FlagReceiverCheck::kDoNotCheck ||
location == IDLMemberInstaller::FlagLocation::kInterface)
signature = v8::Local<v8::Signature>();
v8::Local<v8::String> name = V8AtomicString(isolate, config.name);
v8::Local<v8::FunctionTemplate> func =
CreateFunctionTemplate<FunctionKind::kOperation>(
isolate, world, signature, name, config, v8_c_function);
v8::Local<v8::Template> target_template;
switch (location) {
case IDLMemberInstaller::FlagLocation::kInstance:
target_template = instance_template;
break;
case IDLMemberInstaller::FlagLocation::kPrototype:
target_template = prototype_template;
break;
case IDLMemberInstaller::FlagLocation::kInterface:
target_template = interface_template;
break;
default:
NOTREACHED();
}
target_template->Set(
name, func,
static_cast<v8::PropertyAttribute>(config.v8_property_attribute));
}
void InstallOperation(v8::Isolate* isolate,
v8::Local<v8::Context> context,
const DOMWrapperWorld& world,
v8::Local<v8::Object> instance_object,
v8::Local<v8::Object> prototype_object,
v8::Local<v8::Object> interface_object,
v8::Local<v8::Signature> signature,
const IDLMemberInstaller::OperationConfig& config) {
if (!DoesWorldMatch(config, world))
return;
IDLMemberInstaller::FlagLocation location =
static_cast<IDLMemberInstaller::FlagLocation>(config.location);
if (static_cast<IDLMemberInstaller::FlagReceiverCheck>(
config.receiver_check) ==
IDLMemberInstaller::FlagReceiverCheck::kDoNotCheck ||
location == IDLMemberInstaller::FlagLocation::kInterface)
signature = v8::Local<v8::Signature>();
v8::Local<v8::String> name = V8AtomicString(isolate, config.name);
v8::Local<v8::Function> func = CreateFunction<FunctionKind::kOperation>(
isolate, context, world, signature, name, config);
v8::Local<v8::Object> target_object;
switch (location) {
case IDLMemberInstaller::FlagLocation::kInstance:
target_object = instance_object;
break;
case IDLMemberInstaller::FlagLocation::kPrototype:
target_object = prototype_object;
break;
case IDLMemberInstaller::FlagLocation::kInterface:
target_object = interface_object;
break;
default:
NOTREACHED();
}
target_object
->DefineOwnProperty(
context, name, func,
static_cast<v8::PropertyAttribute>(config.v8_property_attribute))
.ToChecked();
}
} // namespace
// static
void IDLMemberInstaller::InstallAttributes(
v8::Isolate* isolate,
const DOMWrapperWorld& world,
v8::Local<v8::Template> instance_template,
v8::Local<v8::Template> prototype_template,
v8::Local<v8::Template> interface_template,
v8::Local<v8::Signature> signature,
base::span<const AttributeConfig> configs) {
for (const auto& config : configs) {
InstallAttribute(isolate, world, instance_template, prototype_template,
interface_template, signature, config);
}
}
// static
void IDLMemberInstaller::InstallAttributes(
v8::Isolate* isolate,
const DOMWrapperWorld& world,
v8::Local<v8::Object> instance_object,
v8::Local<v8::Object> prototype_object,
v8::Local<v8::Object> interface_object,
v8::Local<v8::Signature> signature,
base::span<const AttributeConfig> configs) {
v8::Local<v8::Context> context = isolate->GetCurrentContext();
for (const auto& config : configs) {
InstallAttribute(isolate, context, world, instance_object, prototype_object,
interface_object, signature, config);
}
}
// static
void IDLMemberInstaller::InstallConstants(
v8::Isolate* isolate,
const DOMWrapperWorld& world,
v8::Local<v8::Template> instance_template,
v8::Local<v8::Template> prototype_template,
v8::Local<v8::Template> interface_template,
v8::Local<v8::Signature> signature,
base::span<const ConstantCallbackConfig> configs) {
const bool has_prototype_template = !prototype_template.IsEmpty();
const v8::PropertyAttribute v8_property_attribute =
static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete);
for (const auto& config : configs) {
v8::Local<v8::String> name = V8AtomicString(isolate, config.name);
if (has_prototype_template) {
prototype_template->SetLazyDataProperty(
name, config.callback, v8::Local<v8::Value>(), v8_property_attribute,
v8::SideEffectType::kHasNoSideEffect);
}
interface_template->SetLazyDataProperty(
name, config.callback, v8::Local<v8::Value>(), v8_property_attribute,
v8::SideEffectType::kHasNoSideEffect);
}
}
// static
void IDLMemberInstaller::InstallConstants(
v8::Isolate* isolate,
const DOMWrapperWorld& world,
v8::Local<v8::Template> instance_template,
v8::Local<v8::Template> prototype_template,
v8::Local<v8::Template> interface_template,
v8::Local<v8::Signature> signature,
base::span<const ConstantValueConfig> configs) {
const bool has_prototype_template = !prototype_template.IsEmpty();
const v8::PropertyAttribute v8_property_attribute =
static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete);
for (const auto& config : configs) {
v8::Local<v8::String> name = V8AtomicString(isolate, config.name);
v8::Local<v8::Integer> value;
if (config.value < 0) {
int32_t i32_value = static_cast<int32_t>(config.value);
DCHECK_EQ(static_cast<int64_t>(i32_value), config.value);
value = v8::Integer::New(isolate, i32_value);
} else {
uint32_t u32_value = static_cast<uint32_t>(config.value);
DCHECK_EQ(static_cast<int64_t>(u32_value), config.value);
value = v8::Integer::NewFromUnsigned(isolate, u32_value);
}
if (has_prototype_template) {
prototype_template->Set(name, value, v8_property_attribute);
}
interface_template->Set(name, value, v8_property_attribute);
}
}
// static
void IDLMemberInstaller::InstallOperations(
v8::Isolate* isolate,
const DOMWrapperWorld& world,
v8::Local<v8::Template> instance_template,
v8::Local<v8::Template> prototype_template,
v8::Local<v8::Template> interface_template,
v8::Local<v8::Signature> signature,
base::span<const OperationConfig> configs) {
for (const auto& config : configs) {
InstallOperation(isolate, world, instance_template, prototype_template,
interface_template, signature, config);
}
}
// static
void IDLMemberInstaller::InstallOperations(
v8::Isolate* isolate,
const DOMWrapperWorld& world,
v8::Local<v8::Object> instance_object,
v8::Local<v8::Object> prototype_object,
v8::Local<v8::Object> interface_object,
v8::Local<v8::Signature> signature,
base::span<const OperationConfig> configs) {
v8::Local<v8::Context> context = isolate->GetCurrentContext();
for (const auto& config : configs) {
InstallOperation(isolate, context, world, instance_object, prototype_object,
interface_object, signature, config);
}
}
// static
void IDLMemberInstaller::InstallOperations(
v8::Isolate* isolate,
const DOMWrapperWorld& world,
v8::Local<v8::Template> instance_template,
v8::Local<v8::Template> prototype_template,
v8::Local<v8::Template> interface_template,
v8::Local<v8::Signature> signature,
base::span<const NoAllocDirectCallOperationConfig> configs) {
for (const auto& config : configs) {
InstallOperation(isolate, world, instance_template, prototype_template,
interface_template, signature, config.operation_config,
&config.v8_c_function);
}
}
// static
void IDLMemberInstaller::InstallExposedConstructs(
v8::Isolate* isolate,
const DOMWrapperWorld& world,
v8::Local<v8::Template> instance_template,
v8::Local<v8::Template> prototype_template,
v8::Local<v8::Template> interface_template,
v8::Local<v8::Signature> signature,
base::span<const ExposedConstructConfig> configs) {
for (const auto& config : configs) {
v8::Local<v8::String> name = V8AtomicString(isolate, config.name);
instance_template->SetLazyDataProperty(
name, config.callback, v8::Local<v8::Value>(), v8::DontEnum,
v8::SideEffectType::kHasNoSideEffect);
}
}
// static
void IDLMemberInstaller::InstallExposedConstructs(
v8::Isolate* isolate,
const DOMWrapperWorld& world,
v8::Local<v8::Object> instance_object,
v8::Local<v8::Object> prototype_object,
v8::Local<v8::Object> interface_object,
v8::Local<v8::Signature> signature,
base::span<const ExposedConstructConfig> configs) {
v8::Local<v8::Context> context = isolate->GetCurrentContext();
for (const auto& config : configs) {
instance_object
->SetLazyDataProperty(context, V8AtomicString(isolate, config.name),
config.callback, v8::Local<v8::Value>(),
v8::DontEnum,
v8::SideEffectType::kHasNoSideEffect)
.ToChecked();
}
}
} // namespace bindings
} // namespace blink
// Copyright 2020 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_IDL_MEMBER_INSTALLER_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_IDL_MEMBER_INSTALLER_H_
#include "base/containers/span.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "v8/include/v8-fast-api-calls.h"
#include "v8/include/v8.h"
namespace blink {
class DOMWrapperWorld;
namespace bindings {
// IDLMemberInstaller is a set of utility functions to define IDL members as
// ES properties.
class PLATFORM_EXPORT IDLMemberInstaller final {
STATIC_ONLY(IDLMemberInstaller);
public:
// On which object the property is defined
enum class FlagLocation {
kInstance,
kPrototype,
kInterface,
};
// In which world the property is defined
enum class FlagWorld {
kMainWorld = 1 << 0,
kNonMainWorlds = 1 << 1,
kAllWorlds = kMainWorld | kNonMainWorlds,
};
// v8::Signature check against the receiver object
enum class FlagReceiverCheck {
kCheck,
kDoNotCheck,
};
// Cross origin access check
enum class FlagCrossOriginCheck {
kCheck,
kDoNotCheck,
};
// Web IDL attribute
struct AttributeConfig {
AttributeConfig& operator=(const AttributeConfig&) = delete;
const char* name;
v8::FunctionCallback callback_for_get;
v8::FunctionCallback callback_for_set;
unsigned v8_property_attribute : 3; // v8::PropertyAttribute
unsigned location : 2; // FlagLocation
unsigned world : 2; // FlagWorld
unsigned receiver_check : 1; // FlagReceiverCheck
unsigned cross_origin_check_for_get : 1; // FlagCrossOriginCheck
unsigned cross_origin_check_for_set : 1; // FlagCrossOriginCheck
unsigned v8_side_effect : 2; // v8::SideEffectType
unsigned v8_cached_accessor : 2; // V8PrivateProperty::CachedAccessor
};
static void InstallAttributes(v8::Isolate* isolate,
const DOMWrapperWorld& world,
v8::Local<v8::Template> instance_template,
v8::Local<v8::Template> prototype_template,
v8::Local<v8::Template> interface_template,
v8::Local<v8::Signature> signature,
base::span<const AttributeConfig> configs);
static void InstallAttributes(v8::Isolate* isolate,
const DOMWrapperWorld& world,
v8::Local<v8::Object> instance_object,
v8::Local<v8::Object> prototype_object,
v8::Local<v8::Object> interface_object,
v8::Local<v8::Signature> signature,
base::span<const AttributeConfig> configs);
// Web IDL constant
struct ConstantCallbackConfig {
ConstantCallbackConfig& operator=(const ConstantCallbackConfig&) = delete;
const char* name;
v8::AccessorNameGetterCallback callback;
};
static void InstallConstants(
v8::Isolate* isolate,
const DOMWrapperWorld& world,
v8::Local<v8::Template> instance_template,
v8::Local<v8::Template> prototype_template,
v8::Local<v8::Template> interface_template,
v8::Local<v8::Signature> signature,
base::span<const ConstantCallbackConfig> configs);
struct ConstantValueConfig {
ConstantValueConfig& operator=(const ConstantValueConfig&) = delete;
const char* name;
int64_t value;
};
static void InstallConstants(v8::Isolate* isolate,
const DOMWrapperWorld& world,
v8::Local<v8::Template> instance_template,
v8::Local<v8::Template> prototype_template,
v8::Local<v8::Template> interface_template,
v8::Local<v8::Signature> signature,
base::span<const ConstantValueConfig> configs);
// Web IDL operation
struct OperationConfig {
OperationConfig& operator=(const OperationConfig&) = delete;
const char* name;
v8::FunctionCallback callback;
unsigned length : 8;
unsigned v8_property_attribute : 3; // v8::PropertyAttribute
unsigned location : 2; // FlagLocation
unsigned world : 2; // FlagWorld
unsigned receiver_check : 1; // FlagReceiverCheck
unsigned cross_origin_check : 1; // FlagCrossOriginCheck
unsigned v8_side_effect : 2; // v8::SideEffectType
};
static void InstallOperations(v8::Isolate* isolate,
const DOMWrapperWorld& world,
v8::Local<v8::Template> instance_template,
v8::Local<v8::Template> prototype_template,
v8::Local<v8::Template> interface_template,
v8::Local<v8::Signature> signature,
base::span<const OperationConfig> configs);
static void InstallOperations(v8::Isolate* isolate,
const DOMWrapperWorld& world,
v8::Local<v8::Object> instance_object,
v8::Local<v8::Object> prototype_object,
v8::Local<v8::Object> interface_object,
v8::Local<v8::Signature> signature,
base::span<const OperationConfig> configs);
struct NoAllocDirectCallOperationConfig {
OperationConfig operation_config;
v8::CFunction v8_c_function;
};
static void InstallOperations(
v8::Isolate* isolate,
const DOMWrapperWorld& world,
v8::Local<v8::Template> instance_template,
v8::Local<v8::Template> prototype_template,
v8::Local<v8::Template> interface_template,
v8::Local<v8::Signature> signature,
base::span<const NoAllocDirectCallOperationConfig> configs);
// Global property reference
// https://heycam.github.io/webidl/#define-the-global-property-references
// [LegacyNamespace]
// https://heycam.github.io/webidl/#LegacyNamespace
struct ExposedConstructConfig {
ExposedConstructConfig& operator=(const ExposedConstructConfig&) = delete;
const char* name;
v8::AccessorNameGetterCallback callback;
};
static void InstallExposedConstructs(
v8::Isolate* isolate,
const DOMWrapperWorld& world,
v8::Local<v8::Template> instance_template,
v8::Local<v8::Template> prototype_template,
v8::Local<v8::Template> interface_template,
v8::Local<v8::Signature> signature,
base::span<const ExposedConstructConfig> configs);
static void InstallExposedConstructs(
v8::Isolate* isolate,
const DOMWrapperWorld& world,
v8::Local<v8::Object> instance_object,
v8::Local<v8::Object> prototype_object,
v8::Local<v8::Object> interface_object,
v8::Local<v8::Signature> signature,
base::span<const ExposedConstructConfig> configs);
};
} // namespace bindings
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_IDL_MEMBER_INSTALLER_H_
...@@ -37,11 +37,6 @@ expect_failure_worker = () => { ...@@ -37,11 +37,6 @@ expect_failure_worker = () => {
assert_false('normalAttribute' in testObject); assert_false('normalAttribute' in testObject);
assert_equals(testObject.normalAttribute, undefined); assert_equals(testObject.normalAttribute, undefined);
}, 'Attribute should not exist in ' + worker_type + ' worker'); }, 'Attribute should not exist in ' + worker_type + ' worker');
test(() => {
var testObject = self.internals.originTrialsTest();
assert_false('CONSTANT' in testObject);
assert_equals(testObject.CONSTANT, undefined);
}, 'Constant should not exist in ' + worker_type + ' worker');
done(); done();
} }
...@@ -119,17 +114,6 @@ expect_success_worker = () => { ...@@ -119,17 +114,6 @@ expect_success_worker = () => {
assert_idl_attribute(testObject, 'normalAttribute'); assert_idl_attribute(testObject, 'normalAttribute');
assert_true(testObject.normalAttribute, 'Attribute should return boolean value'); assert_true(testObject.normalAttribute, 'Attribute should return boolean value');
}, 'Attribute should exist and return value in ' + worker_type + ' worker'); }, 'Attribute should exist and return value in ' + worker_type + ' worker');
test(() => {
var testObject = self.internals.originTrialsTest();
assert_idl_attribute(testObject, 'CONSTANT');
assert_equals(testObject.CONSTANT, 1, 'Constant should return integer value');
}, 'Constant should exist and return value in ' + worker_type + ' worker');
test(() => {
var testObject = self.internals.originTrialsTest();
assert_idl_attribute(testObject, 'CONSTANT');
testObject.CONSTANT = 10;
assert_equals(testObject.CONSTANT, 1, 'Constant should not be modifiable');
}, 'Constant should exist and not be modifiable in ' + worker_type + ' worker');
done(); done();
} }
......
...@@ -83,19 +83,6 @@ expect_css_media = (feature_name) => { ...@@ -83,19 +83,6 @@ expect_css_media = (feature_name) => {
assert_true(media_list.mediaText.indexOf("not all") === -1); assert_true(media_list.mediaText.indexOf("not all") === -1);
} }
// Verify that the given constant exists, and returns the expected value, and
// is not modifiable.
expect_constant = (constant_name, constant_value, get_value_func) => {
var testObject = internals.originTrialsTest();
var testInterface = testObject.constructor;
assert_own_property(testInterface, constant_name);
assert_equals(get_value_func(testInterface), constant_value,
'Constant should return expected value');
testInterface[constant_name] = constant_value + 1;
assert_equals(get_value_func(testInterface), constant_value,
'Constant should not be modifiable');
}
// Verify that given member does not exist, and does not provide a value // Verify that given member does not exist, and does not provide a value
// (i.e. is undefined). // (i.e. is undefined).
expect_member_fails = (member_name) => { expect_member_fails = (member_name) => {
...@@ -186,10 +173,6 @@ expect_failure = (skip_worker) => { ...@@ -186,10 +173,6 @@ expect_failure = (skip_worker) => {
expect_member_fails('normalAttribute'); expect_member_fails('normalAttribute');
}, 'Attribute should not exist, with trial disabled'); }, 'Attribute should not exist, with trial disabled');
test(() => {
expect_static_member_fails('CONSTANT');
}, 'Constant should not exist, with trial disabled');
if (!skip_worker) { if (!skip_worker) {
fetch_tests_from_worker(new Worker('resources/disabled-worker.js')); fetch_tests_from_worker(new Worker('resources/disabled-worker.js'));
} }
...@@ -278,12 +261,6 @@ expect_success = () => { ...@@ -278,12 +261,6 @@ expect_success = () => {
}); });
}, 'Attribute should exist on object and return value'); }, 'Attribute should exist on object and return value');
test(() => {
expect_constant('CONSTANT', 1, (testObject) => {
return testObject.CONSTANT;
});
}, 'Constant should exist on interface and return value');
fetch_tests_from_worker(new Worker('resources/enabled-worker.js')); fetch_tests_from_worker(new Worker('resources/enabled-worker.js'));
}; };
...@@ -384,12 +361,6 @@ expect_always_bindings = (insecure_context, opt_description_suffix) => { ...@@ -384,12 +361,6 @@ expect_always_bindings = (insecure_context, opt_description_suffix) => {
}); });
}, 'Static method should exist and return value, regardless of trial' + description_suffix); }, 'Static method should exist and return value, regardless of trial' + description_suffix);
test(() => {
expect_constant('UNCONDITIONAL_CONSTANT', 99, (testObject) => {
return testObject.UNCONDITIONAL_CONSTANT;
});
}, 'Constant should exist on interface and return value, regardless of trial' + description_suffix);
test(() => { test(() => {
expect_dictionary_member('unconditionalBool'); expect_dictionary_member('unconditionalBool');
}, 'Dictionary output from method should return member value, regardless of trial' + description_suffix); }, 'Dictionary output from method should return member value, regardless of trial' + description_suffix);
...@@ -539,12 +510,6 @@ expect_success_bindings = (insecure_context) => { ...@@ -539,12 +510,6 @@ expect_success_bindings = (insecure_context) => {
}); });
}, 'Static method should exist on partial interface and return value'); }, 'Static method should exist on partial interface and return value');
test(() => {
expect_constant('CONSTANT_PARTIAL', 2, (testObject) => {
return testObject.CONSTANT_PARTIAL;
});
}, 'Constant should exist on partial interface and return value');
// Tests for combination of [RuntimeEnabled] and [SecureContext] // Tests for combination of [RuntimeEnabled] and [SecureContext]
test(() => { test(() => {
expect_member('secureAttribute', (testObject) => { expect_member('secureAttribute', (testObject) => {
...@@ -645,9 +610,6 @@ expect_failure_bindings_impl = (insecure_context, description_suffix) => { ...@@ -645,9 +610,6 @@ expect_failure_bindings_impl = (insecure_context, description_suffix) => {
test(() => { test(() => {
expect_static_member_fails('staticMethodPartial'); expect_static_member_fails('staticMethodPartial');
}, 'Static method should not exist on partial interface, with trial disabled'); }, 'Static method should not exist on partial interface, with trial disabled');
test(() => {
expect_static_member_fails('CONSTANT_PARTIAL');
}, 'Constant should not exist on partial interface, with trial disabled');
// Tests for combination of [RuntimeEnabled] and [SecureContext] // Tests for combination of [RuntimeEnabled] and [SecureContext]
test(() => { test(() => {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment