Commit f017de27 authored by Yuki Shiino's avatar Yuki Shiino Committed by Commit Bot

bind-gen: Implement named properties object's interceptors

Bug: 839389
Change-Id: I2cfee5b72b46e9aa8e02e21cd38f104ed21d539e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2143066
Commit-Queue: Yuki Shiino <yukishiino@chromium.org>
Reviewed-by: default avatarHitoshi Yoshida <peria@chromium.org>
Cr-Commit-Position: refs/heads/master@{#758474}
parent 840dfccd
...@@ -1919,6 +1919,11 @@ def make_operation_callback_def(cg_context, function_name): ...@@ -1919,6 +1919,11 @@ def make_operation_callback_def(cg_context, function_name):
return node return node
# ----------------------------------------------------------------------------
# Callback functions of indexed and named interceptors
# ----------------------------------------------------------------------------
def make_indexed_property_getter_callback(cg_context, function_name): def make_indexed_property_getter_callback(cg_context, function_name):
assert isinstance(cg_context, CodeGenContext) assert isinstance(cg_context, CodeGenContext)
assert isinstance(function_name, str) assert isinstance(function_name, str)
...@@ -1956,7 +1961,7 @@ def make_indexed_property_getter_callback(cg_context, function_name): ...@@ -1956,7 +1961,7 @@ def make_indexed_property_getter_callback(cg_context, function_name):
TextNode("""\ TextNode("""\
v8::Local<v8::String> property_name = v8::Local<v8::String> property_name =
V8AtomicString(${isolate}, AtomicString::Number(${index})); V8AtomicString(${isolate}, AtomicString::Number(${index}));
${class_name}::NamedPropertyGetterCallback(property_name, ${info});\ ${class_name}::NamedPropertyGetterCallback(property_name, ${info});
""")) """))
return func_decl, func_def return func_decl, func_def
...@@ -1969,7 +1974,7 @@ ${class_name}::NamedPropertyGetterCallback(property_name, ${info});\ ...@@ -1969,7 +1974,7 @@ ${class_name}::NamedPropertyGetterCallback(property_name, ${info});\
// step 1.2. If index is a supported property index, then: // step 1.2. If index is a supported property index, then:
// step 3. Return OrdinaryGetOwnProperty(O, P). // step 3. Return OrdinaryGetOwnProperty(O, P).
if (${index} >= ${blink_receiver}->length()) if (${index} >= ${blink_receiver}->length())
return; // Do not intercept. Fallback to OrdinaryGetOwnProperty.\ return; // Do not intercept. Fallback to OrdinaryGetOwnProperty.
"""), """),
make_v8_set_return_value(cg_context), make_v8_set_return_value(cg_context),
]) ])
...@@ -2017,7 +2022,7 @@ def make_indexed_property_setter_callback(cg_context, function_name): ...@@ -2017,7 +2022,7 @@ def make_indexed_property_setter_callback(cg_context, function_name):
v8::Local<v8::String> property_name = v8::Local<v8::String> property_name =
V8AtomicString(${isolate}, AtomicString::Number(${index})); V8AtomicString(${isolate}, AtomicString::Number(${index}));
${class_name}::NamedPropertySetterCallback( ${class_name}::NamedPropertySetterCallback(
property_name, ${v8_property_value}, ${info});\ property_name, ${v8_property_value}, ${info});
""")) """))
return func_decl, func_def return func_decl, func_def
...@@ -2046,7 +2051,7 @@ if (${info}.Holder() == ${info}.This()) { ...@@ -2046,7 +2051,7 @@ if (${info}.Holder() == ${info}.This()) {
// step 3. Perform ? OrdinarySetWithOwnDescriptor(O, P, V, Receiver, // step 3. Perform ? OrdinarySetWithOwnDescriptor(O, P, V, Receiver,
// ownDesc). // ownDesc).
// //
// Do not intercept. Fallback to OrdinarySetWithOwnDescriptor.\ // Do not intercept. Fallback to OrdinarySetWithOwnDescriptor.
""")) """))
return func_decl, func_def return func_decl, func_def
...@@ -2082,7 +2087,7 @@ return;"""), ...@@ -2082,7 +2087,7 @@ return;"""),
]), ]),
EmptyNode(), EmptyNode(),
TextNode("""\ TextNode("""\
// Do not intercept. Fallback to OrdinarySetWithOwnDescriptor.\ // Do not intercept. Fallback to OrdinarySetWithOwnDescriptor.
"""), """),
]) ])
...@@ -2126,7 +2131,7 @@ def make_indexed_property_deleter_callback(cg_context, function_name): ...@@ -2126,7 +2131,7 @@ def make_indexed_property_deleter_callback(cg_context, function_name):
TextNode("""\ TextNode("""\
v8::Local<v8::String> property_name = v8::Local<v8::String> property_name =
V8AtomicString(${isolate}, AtomicString::Number(${index})); V8AtomicString(${isolate}, AtomicString::Number(${index}));
${class_name}::NamedPropertyDeleterCallback(property_name, ${info});\ ${class_name}::NamedPropertyDeleterCallback(property_name, ${info});
""")) """))
return func_decl, func_def return func_decl, func_def
...@@ -2188,7 +2193,7 @@ def make_indexed_property_definer_callback(cg_context, function_name): ...@@ -2188,7 +2193,7 @@ def make_indexed_property_definer_callback(cg_context, function_name):
v8::Local<v8::String> property_name = v8::Local<v8::String> property_name =
V8AtomicString(${isolate}, AtomicString::Number(${index})); V8AtomicString(${isolate}, AtomicString::Number(${index}));
${class_name}::NamedPropertyDefinerCallback( ${class_name}::NamedPropertyDefinerCallback(
property_name, ${v8_property_desc}, ${info});\ property_name, ${v8_property_desc}, ${info});
""")) """))
return func_decl, func_def return func_decl, func_def
...@@ -2227,7 +2232,7 @@ if (${info}.ShouldThrowOnError()) { ...@@ -2227,7 +2232,7 @@ if (${info}.ShouldThrowOnError()) {
TextNode("""\ TextNode("""\
// step 1.3. Invoke the indexed property setter with P and Desc.[[Value]]. // step 1.3. Invoke the indexed property setter with P and Desc.[[Value]].
${class_name}::IndexedPropertySetterCallback( ${class_name}::IndexedPropertySetterCallback(
${index}, ${v8_property_desc}.value(), ${info});\ ${index}, ${v8_property_desc}.value(), ${info});
""")) """))
return func_decl, func_def return func_decl, func_def
...@@ -2270,7 +2275,7 @@ def make_indexed_property_descriptor_callback(cg_context, function_name): ...@@ -2270,7 +2275,7 @@ def make_indexed_property_descriptor_callback(cg_context, function_name):
TextNode("""\ TextNode("""\
v8::Local<v8::String> property_name = v8::Local<v8::String> property_name =
V8AtomicString(${isolate}, AtomicString::Number(${index})); V8AtomicString(${isolate}, AtomicString::Number(${index}));
${class_name}::NamedPropertyDescriptorCallback(property_name, ${info});\ ${class_name}::NamedPropertyDescriptorCallback(property_name, ${info});
""")) """))
return func_decl, func_def return func_decl, func_def
...@@ -2349,7 +2354,7 @@ def make_indexed_property_enumerator_callback(cg_context, function_name): ...@@ -2349,7 +2354,7 @@ def make_indexed_property_enumerator_callback(cg_context, function_name):
uint32_t length = ${blink_receiver}->length(); uint32_t length = ${blink_receiver}->length();
v8::Local<v8::Array> array = v8::Local<v8::Array> array =
bindings::EnumerateIndexedProperties(${isolate}, length); bindings::EnumerateIndexedProperties(${isolate}, length);
bindings::V8SetReturnValue(${info}, array);\ bindings::V8SetReturnValue(${info}, array);
""")) """))
return func_decl, func_def return func_decl, func_def
...@@ -2505,7 +2510,7 @@ if (${info}.Holder() == ${info}.This()) { ...@@ -2505,7 +2510,7 @@ if (${info}.Holder() == ${info}.This()) {
// step 3. Perform ? OrdinarySetWithOwnDescriptor(O, P, V, Receiver, // step 3. Perform ? OrdinarySetWithOwnDescriptor(O, P, V, Receiver,
// ownDesc). // ownDesc).
// //
// Do not intercept. Fallback to OrdinarySetWithOwnDescriptor.\ // Do not intercept. Fallback to OrdinarySetWithOwnDescriptor.
""")) """))
return func_decl, func_def return func_decl, func_def
...@@ -2549,7 +2554,7 @@ return;"""), ...@@ -2549,7 +2554,7 @@ return;"""),
]), ]),
EmptyNode(), EmptyNode(),
TextNode("""\ TextNode("""\
// Do not intercept. Fallback to OrdinarySetWithOwnDescriptor.\ // Do not intercept. Fallback to OrdinarySetWithOwnDescriptor.
"""), """),
]) ])
...@@ -2601,7 +2606,7 @@ def make_named_property_deleter_callback(cg_context, function_name): ...@@ -2601,7 +2606,7 @@ def make_named_property_deleter_callback(cg_context, function_name):
// is true, then: // is true, then:
// //
// There is no easy way to determine whether the named property is visible // There is no easy way to determine whether the named property is visible
// or not. Just do not intercept and fallback to the default behavior.\ // or not. Just do not intercept and fallback to the default behavior.
""")) """))
return func_decl, func_def return func_decl, func_def
...@@ -2626,13 +2631,12 @@ if (exception_state.HadException()) ...@@ -2626,13 +2631,12 @@ if (exception_state.HadException())
if (does_exist) { if (does_exist) {
bindings::V8SetReturnValue(${info}, false); bindings::V8SetReturnValue(${info}, false);
if (${info}.ShouldThrowOnError()) { if (${info}.ShouldThrowOnError()) {
exception_state.ThrowTypeError( exception_state.ThrowTypeError("Named property deleter is not supported.");
"Named property deleter is not supported.");
} }
return; return;
} }
// Do not intercept.\ // Do not intercept.
""")) """))
return func_decl, func_def return func_decl, func_def
...@@ -2724,7 +2728,7 @@ if (!is_creating) { ...@@ -2724,7 +2728,7 @@ if (!is_creating) {
return; return;
} }
// Do not intercept. Fallback to OrdinaryDefineOwnProperty.\ // Do not intercept. Fallback to OrdinaryDefineOwnProperty.
""")) """))
else: else:
body.append( body.append(
...@@ -2748,7 +2752,7 @@ if (v8_property_desc.has_get() || v8_property_desc.has_set()) { ...@@ -2748,7 +2752,7 @@ if (v8_property_desc.has_get() || v8_property_desc.has_set()) {
// step 2.2.2.2. Invoke the named property setter with P and Desc.[[Value]]. // step 2.2.2.2. Invoke the named property setter with P and Desc.[[Value]].
${class_name}::NamedPropertySetterCallback( ${class_name}::NamedPropertySetterCallback(
${v8_property_name}, ${v8_property_desc}.value(), ${info}); ${v8_property_name}, ${v8_property_desc}.value(), ${info});
bindings::V8SetReturnValue(${info}, nullptr);\ bindings::V8SetReturnValue(${info}, nullptr);
""")) """))
return func_decl, func_def return func_decl, func_def
...@@ -2784,11 +2788,24 @@ def make_named_property_descriptor_callback(cg_context, function_name): ...@@ -2784,11 +2788,24 @@ def make_named_property_descriptor_callback(cg_context, function_name):
body.extend([ body.extend([
make_runtime_call_timer_scope(cg_context, "NamedPropertyDescriptor"), make_runtime_call_timer_scope(cg_context, "NamedPropertyDescriptor"),
EmptyNode(), EmptyNode(),
TextNode("""\
// LegacyPlatformObjectGetOwnProperty
// https://heycam.github.io/webidl/#LegacyPlatformObjectGetOwnProperty\
"""),
]) ])
if "OverrideBuiltins" not in cg_context.interface.extended_attributes:
body.append(
TextNode("""\
// step 2.1. If the result of running the named property visibility algorithm
// with property name P and object O is true, then:
if (${v8_receiver}->GetRealNamedPropertyAttributesInPrototypeChain(
${current_context}, ${v8_property_name}).IsJust()) {
return; // Do not intercept. Fallback to OrdinaryGetOwnProperty.
}
"""))
pattern = """\ pattern = """\
// LegacyPlatformObjectGetOwnProperty
// https://heycam.github.io/webidl/#LegacyPlatformObjectGetOwnProperty
// step 2.1.3. If operation was defined without an identifier, then set // step 2.1.3. If operation was defined without an identifier, then set
// value to the result of performing the steps listed in the interface // value to the result of performing the steps listed in the interface
// description to determine the value of a named property with P as the // description to determine the value of a named property with P as the
...@@ -2815,7 +2832,7 @@ if (v8_value->IsUndefined()) ...@@ -2815,7 +2832,7 @@ if (v8_value->IsUndefined())
v8::PropertyDescriptor desc(v8_value, /*writable=*/{cxx_writable}); v8::PropertyDescriptor desc(v8_value, /*writable=*/{cxx_writable});
desc.set_enumerable({cxx_enumerable}); desc.set_enumerable({cxx_enumerable});
desc.set_configurable(true); desc.set_configurable(true);
bindings::V8SetReturnValue(${info}, desc);\ bindings::V8SetReturnValue(${info}, desc);
""" """
props = cg_context.interface.indexed_and_named_properties props = cg_context.interface.indexed_and_named_properties
writable = bool(props.named_setter) writable = bool(props.named_setter)
...@@ -2894,77 +2911,458 @@ if (!does_exist) ...@@ -2894,77 +2911,458 @@ if (!does_exist)
property_attribute=property_attribute)), property_attribute=property_attribute)),
]) ])
return func_decl, func_def return func_decl, func_def
def make_named_property_enumerator_callback(cg_context, function_name):
assert isinstance(cg_context, CodeGenContext)
assert isinstance(function_name, str)
props = cg_context.interface.indexed_and_named_properties
if "NotEnumerable" in props.named_getter.extended_attributes:
return None, None
arg_decls = ["const v8::PropertyCallbackInfo<v8::Array>& info"]
return_type = "void"
func_decl = CxxFuncDeclNode(
name=function_name,
arg_decls=arg_decls,
return_type=return_type,
static=True)
func_def = CxxFuncDefNode(
name=function_name,
arg_decls=arg_decls,
return_type=return_type,
class_name=cg_context.class_name)
func_def.set_base_template_vars(cg_context.template_bindings())
body = func_def.body
body.add_template_var("info", "info")
bind_callback_local_vars(body, cg_context)
body.extend([
make_runtime_call_timer_scope(cg_context, "NamedPropertyEnumerator"),
EmptyNode(),
TextNode("""\
// 3.8.6. [[OwnPropertyKeys]]
// https://heycam.github.io/webidl/#legacy-platform-object-ownpropertykeys
// step 3. If O supports named properties, then for each P of O's supported
// property names that is visible according to the named property
// visibility algorithm, append P to keys.
Vector<String> blink_property_names;
${blink_receiver}->NamedPropertyEnumerator(
blink_property_names, ${exception_state});
if (${exception_state}.HadException())
return;
bindings::V8SetReturnValue(
${info},
ToV8(blink_property_names, ${creation_context_object}, ${isolate}));
"""),
])
return func_decl, func_def
def make_stringifier_callback_def(cg_context, function_name):
assert isinstance(cg_context, CodeGenContext)
assert isinstance(function_name, str)
if cg_context.stringifier.attribute:
return make_attribute_get_callback_def(
cg_context.make_copy(
attribute=cg_context.stringifier.attribute,
attribute_get=True), function_name)
elif cg_context.stringifier.operation:
return make_operation_function_def(
cg_context.make_copy(operation=cg_context.stringifier.operation),
function_name)
assert False
# ----------------------------------------------------------------------------
# Callback functions of interceptors on named properties object
# ----------------------------------------------------------------------------
def make_named_props_obj_indexed_getter_callback(cg_context, function_name):
assert isinstance(cg_context, CodeGenContext)
assert isinstance(function_name, str)
func_def = CxxFuncDefNode(
name=function_name,
arg_decls=[
"uint32_t index",
"const v8::PropertyCallbackInfo<v8::Value>& info",
],
return_type="void")
func_def.set_base_template_vars(cg_context.template_bindings())
body = func_def.body
body.add_template_var("index", "index")
body.add_template_var("info", "info")
bind_callback_local_vars(body, cg_context)
body.extend([
make_runtime_call_timer_scope(
cg_context, "NamedPropertiesObject_IndexedPropertyGetter"),
EmptyNode(),
TextNode("""\
v8::Local<v8::String> property_name =
V8AtomicString(${isolate}, AtomicString::Number(${index}));
NamedPropsObjNamedGetterCallback(property_name, ${info});
"""),
])
return func_def
def make_named_props_obj_indexed_setter_callback(cg_context, function_name):
assert isinstance(cg_context, CodeGenContext)
assert isinstance(function_name, str)
func_def = CxxFuncDefNode(
name=function_name,
arg_decls=[
"uint32_t index",
"v8::Local<v8::Value> v8_property_value",
"const v8::PropertyCallbackInfo<v8::Value>& info",
],
return_type="void")
func_def.set_base_template_vars(cg_context.template_bindings())
body = func_def.body
body.add_template_var("index", "index")
body.add_template_var("v8_property_value", "v8_property_value")
body.add_template_var("info", "info")
bind_callback_local_vars(body, cg_context)
body.extend([
make_runtime_call_timer_scope(
cg_context, "NamedPropertiesObject_IndexedPropertySetter"),
EmptyNode(),
TextNode("""\
v8::Local<v8::String> property_name =
V8AtomicString(${isolate}, AtomicString::Number(${index}));
NamedPropsObjNamedSetterCallback(property_name, ${v8_property_value}, ${info});
"""),
])
return func_def
def make_named_props_obj_indexed_deleter_callback(cg_context, function_name):
assert isinstance(cg_context, CodeGenContext)
assert isinstance(function_name, str)
func_def = CxxFuncDefNode(
name=function_name,
arg_decls=[
"uint32_t index",
"const v8::PropertyCallbackInfo<v8::Boolean>& info",
],
return_type="void")
func_def.set_base_template_vars(cg_context.template_bindings())
body = func_def.body
body.add_template_var("index", "index")
body.add_template_var("info", "info")
bind_callback_local_vars(body, cg_context)
body.extend([
make_runtime_call_timer_scope(
cg_context, "NamedPropertiesObject_IndexedPropertyDeleter"),
EmptyNode(),
TextNode("""\
bindings::V8SetReturnValue(${info}, false);
if (${info}.ShouldThrowOnError()) {
ExceptionState exception_state(${info}.GetIsolate(),
ExceptionState::kDeletionContext,
"${interface.identifier}");
exception_state.ThrowTypeError("Named property deleter is not supported.");
}
"""),
])
return func_def
def make_named_props_obj_indexed_definer_callback(cg_context, function_name):
assert isinstance(cg_context, CodeGenContext)
assert isinstance(function_name, str)
func_def = CxxFuncDefNode(
name=function_name,
arg_decls=[
"uint32_t index",
"const v8::PropertyDescriptor& v8_property_desc",
"const v8::PropertyCallbackInfo<v8::Value>& info",
],
return_type="void")
func_def.set_base_template_vars(cg_context.template_bindings())
body = func_def.body
body.add_template_var("index", "index")
body.add_template_var("v8_property_desc", "v8_property_desc")
body.add_template_var("info", "info")
bind_callback_local_vars(body, cg_context)
body.extend([
make_runtime_call_timer_scope(
cg_context, "NamedPropertiesObject_IndexedPropertyDefiner"),
EmptyNode(),
TextNode("""\
// 3.6.4.2. [[DefineOwnProperty]]
// https://heycam.github.io/webidl/#named-properties-object-defineownproperty
bindings::V8SetReturnValue(${info}, nullptr);
if (${info}.ShouldThrowOnError()) {
ExceptionState exception_state(${info}.GetIsolate(),
ExceptionState::kSetterContext,
"${interface.identifier}");
exception_state.ThrowTypeError("Named property deleter is not supported.");
}
"""),
])
return func_def
def make_named_props_obj_indexed_descriptor_callback(cg_context,
function_name):
assert isinstance(cg_context, CodeGenContext)
assert isinstance(function_name, str)
func_def = CxxFuncDefNode(
name=function_name,
arg_decls=[
"uint32_t index",
"const v8::PropertyCallbackInfo<v8::Value>& info",
],
return_type="void")
func_def.set_base_template_vars(cg_context.template_bindings())
body = func_def.body
body.add_template_var("index", "index")
body.add_template_var("info", "info")
bind_callback_local_vars(body, cg_context)
body.extend([
make_runtime_call_timer_scope(
cg_context, "NamedPropertiesObject_IndexedPropertyDescriptor"),
EmptyNode(),
TextNode("""\
v8::Local<v8::String> property_name =
V8AtomicString(${isolate}, AtomicString::Number(${index}));
NamedPropsObjNamedDescriptorCallback(property_name, ${info});
"""),
])
return func_def
def make_named_props_obj_named_getter_callback(cg_context, function_name):
assert isinstance(cg_context, CodeGenContext)
assert isinstance(function_name, str)
func_def = CxxFuncDefNode(
name=function_name,
arg_decls=[
"v8::Local<v8::Name> v8_property_name",
"const v8::PropertyCallbackInfo<v8::Value>& info",
],
return_type="void")
func_def.set_base_template_vars(cg_context.template_bindings())
body = func_def.body
body.add_template_var("v8_property_name", "v8_property_name")
body.add_template_var("info", "info")
bind_callback_local_vars(body, cg_context)
body.extend([
make_runtime_call_timer_scope(
cg_context, "NamedPropertiesObject_NamedPropertyGetter"),
EmptyNode(),
TextNode("""\
// 3.6.4.1. [[GetOwnProperty]]
// https://heycam.github.io/webidl/#named-properties-object-getownproperty
//
// TODO(yukishiino): Update the following hard-coded call to an appropriate
// one.
V8Window::NamedPropertyGetterCustom(${blink_property_name}, ${info});
"""),
])
return func_def
def make_named_props_obj_named_setter_callback(cg_context, function_name):
assert isinstance(cg_context, CodeGenContext)
assert isinstance(function_name, str)
func_def = CxxFuncDefNode(
name=function_name,
arg_decls=[
"v8::Local<v8::Name> v8_property_name",
"v8::Local<v8::Value> v8_property_value",
"const v8::PropertyCallbackInfo<v8::Value>& info",
],
return_type="void")
func_def.set_base_template_vars(cg_context.template_bindings())
body = func_def.body
body.add_template_var("v8_property_name", "v8_property_name")
body.add_template_var("v8_property_value", "v8_property_value")
body.add_template_var("info", "info")
bind_callback_local_vars(body, cg_context)
body.extend([
make_runtime_call_timer_scope(
cg_context, "NamedPropertiesObject_NamedPropertySetter"),
EmptyNode(),
TextNode("""\
if (${info}.Holder() == ${info}.This()) {
// 3.6.4.2. [[DefineOwnProperty]]
// https://heycam.github.io/webidl/#named-properties-object-defineownproperty
bindings::V8SetReturnValue(${info}, nullptr);
if (${info}.ShouldThrowOnError()) {
ExceptionState exception_state(${info}.GetIsolate(),
ExceptionState::kSetterContext,
"${interface.identifier}");
exception_state.ThrowTypeError(
"Named property setter is not supported.");
}
return;
}
"""),
])
return func_def
def make_named_props_obj_named_deleter_callback(cg_context, function_name):
assert isinstance(cg_context, CodeGenContext)
assert isinstance(function_name, str)
func_def = CxxFuncDefNode(
name=function_name,
arg_decls=[
"v8::Local<v8::Name> v8_property_name",
"const v8::PropertyCallbackInfo<v8::Boolean>& info",
],
return_type="void")
func_def.set_base_template_vars(cg_context.template_bindings())
body = func_def.body
body.add_template_var("v8_property_name", "v8_property_name")
body.add_template_var("info", "info")
bind_callback_local_vars(body, cg_context)
body.extend([
make_runtime_call_timer_scope(
cg_context, "NamedPropertiesObject_NamedPropertyDeleter"),
EmptyNode(),
TextNode("""\
// 3.6.4.3. [[Delete]]
// https://heycam.github.io/webidl/#named-properties-object-delete
bindings::V8SetReturnValue(${info}, false);
if (${info}.ShouldThrowOnError()) {
ExceptionState exception_state(${info}.GetIsolate(),
ExceptionState::kDeletionContext,
"${interface.identifier}");
exception_state.ThrowTypeError("Named property deleter is not supported.");
}
"""),
])
return func_def
def make_named_props_obj_named_definer_callback(cg_context, function_name):
assert isinstance(cg_context, CodeGenContext)
assert isinstance(function_name, str)
func_def = CxxFuncDefNode(
name=function_name,
arg_decls=[
"v8::Local<v8::Name> v8_property_name",
"const v8::PropertyDescriptor& v8_property_desc",
"const v8::PropertyCallbackInfo<v8::Value>& info",
],
return_type="void")
func_def.set_base_template_vars(cg_context.template_bindings())
body = func_def.body
body.add_template_var("v8_property_name", "v8_property_name")
body.add_template_var("v8_property_desc", "v8_property_desc")
body.add_template_var("info", "info")
bind_callback_local_vars(body, cg_context)
body.extend([
make_runtime_call_timer_scope(
cg_context, "NamedPropertiesObject_NamedPropertyDefiner"),
EmptyNode(),
TextNode("""\
// 3.6.4.2. [[DefineOwnProperty]]
// https://heycam.github.io/webidl/#named-properties-object-defineownproperty
bindings::V8SetReturnValue(${info}, nullptr);
if (${info}.ShouldThrowOnError()) {
ExceptionState exception_state(${info}.GetIsolate(),
ExceptionState::kSetterContext,
"${interface.identifier}");
exception_state.ThrowTypeError("Named property setter is not supported.");
}
"""),
])
return func_def
def make_named_property_enumerator_callback(cg_context, function_name): def make_named_props_obj_named_descriptor_callback(cg_context, function_name):
assert isinstance(cg_context, CodeGenContext) assert isinstance(cg_context, CodeGenContext)
assert isinstance(function_name, str) assert isinstance(function_name, str)
props = cg_context.interface.indexed_and_named_properties
if "NotEnumerable" in props.named_getter.extended_attributes:
return None, None
arg_decls = ["const v8::PropertyCallbackInfo<v8::Array>& info"]
return_type = "void"
func_decl = CxxFuncDeclNode(
name=function_name,
arg_decls=arg_decls,
return_type=return_type,
static=True)
func_def = CxxFuncDefNode( func_def = CxxFuncDefNode(
name=function_name, name=function_name,
arg_decls=arg_decls, arg_decls=[
return_type=return_type, "v8::Local<v8::Name> v8_property_name",
class_name=cg_context.class_name) "const v8::PropertyCallbackInfo<v8::Value>& info",
],
return_type="void")
func_def.set_base_template_vars(cg_context.template_bindings()) func_def.set_base_template_vars(cg_context.template_bindings())
body = func_def.body body = func_def.body
body.add_template_var("v8_property_name", "v8_property_name")
body.add_template_var("info", "info") body.add_template_var("info", "info")
bind_callback_local_vars(body, cg_context) bind_callback_local_vars(body, cg_context)
body.extend([ body.extend([
make_runtime_call_timer_scope(cg_context, "NamedPropertyEnumerator"), make_runtime_call_timer_scope(
cg_context, "NamedPropertiesObject_NamedPropertyDescriptor"),
EmptyNode(), EmptyNode(),
TextNode("""\ TextNode("""\
// 3.8.6. [[OwnPropertyKeys]] // 3.6.4.1. [[GetOwnProperty]]
// https://heycam.github.io/webidl/#legacy-platform-object-ownpropertykeys // https://heycam.github.io/webidl/#named-properties-object-getownproperty
// step 3. If O supports named properties, then for each P of O's supported // step 4. If the result of running the named property visibility algorithm
// property names that is visible according to the named property // with property name P and object object is true, then:
// visibility algorithm, append P to keys. if (${v8_receiver}->GetRealNamedPropertyAttributesInPrototypeChain(
Vector<String> blink_property_names; ${current_context}, ${v8_property_name}).IsJust()) {
${blink_receiver}->NamedPropertyEnumerator( return; // Do not intercept. Fallback to OrdinaryGetOwnProperty.
blink_property_names, ${exception_state}); }
if (${exception_state}.HadException())
return;
bindings::V8SetReturnValue(
${info},
ToV8(blink_property_names, ${creation_context_object}, ${isolate}));\
"""),
])
return func_decl, func_def
// TODO(yukishiino): Update the following hard-coded call to an appropriate
// one.
V8Window::NamedPropertyGetterCustom(${blink_property_name}, ${info});
v8::Local<v8::Value> v8_value = ${info}.GetReturnValue().Get();
if (v8_value->IsUndefined())
return; // Do not intercept. Fallback to OrdinaryGetOwnProperty.
def make_stringifier_callback_def(cg_context, function_name): // step 4.7. If A implements an interface with the
assert isinstance(cg_context, CodeGenContext) // [LegacyUnenumerableNamedProperties] extended attribute, then set
assert isinstance(function_name, str) // desc.[[Enumerable]] to false, otherwise set it to true.
// step 4.8. Set desc.[[Writable]] to true and desc.[[Configurable]] to
// true.
v8::PropertyDescriptor desc(v8_value, /*writable=*/true);
desc.set_enumerable(false);
desc.set_configurable(true);
bindings::V8SetReturnValue(${info}, desc);
"""),
])
if cg_context.stringifier.attribute: return func_def
return make_attribute_get_callback_def(
cg_context.make_copy(
attribute=cg_context.stringifier.attribute,
attribute_get=True), function_name)
elif cg_context.stringifier.operation:
return make_operation_function_def(
cg_context.make_copy(operation=cg_context.stringifier.operation),
function_name)
assert False
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# Callback functions of cross origin properties # Callback functions of cross origin interceptors
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
...@@ -3022,8 +3420,7 @@ def make_cross_origin_indexed_getter_callback(cg_context, function_name): ...@@ -3022,8 +3420,7 @@ def make_cross_origin_indexed_getter_callback(cg_context, function_name):
body.add_template_var("info", "info") body.add_template_var("info", "info")
bind_callback_local_vars(body, cg_context) bind_callback_local_vars(body, cg_context)
props = cg_context.interface.indexed_and_named_properties if cg_context.interface.identifier != "Window":
if not (props and props.indexed_getter):
body.append(TextNode("${throw_security_error}")) body.append(TextNode("${throw_security_error}"))
return func_def return func_def
...@@ -3034,7 +3431,7 @@ if (${index} >= ${blink_receiver}->length()) { ...@@ -3034,7 +3431,7 @@ if (${index} >= ${blink_receiver}->length()) {
return; return;
} }
${class_name}::IndexedPropertyGetterCallback(${index}, ${info});\ ${class_name}::IndexedPropertyGetterCallback(${index}, ${info});
""")) """))
return func_def return func_def
...@@ -3127,8 +3524,7 @@ def make_cross_origin_indexed_descriptor_callback(cg_context, function_name): ...@@ -3127,8 +3524,7 @@ def make_cross_origin_indexed_descriptor_callback(cg_context, function_name):
body.add_template_var("info", "info") body.add_template_var("info", "info")
bind_callback_local_vars(body, cg_context) bind_callback_local_vars(body, cg_context)
props = cg_context.interface.indexed_and_named_properties if cg_context.interface.identifier != "Window":
if not (props and props.indexed_getter):
body.append(TextNode("${throw_security_error}")) body.append(TextNode("${throw_security_error}"))
return func_def return func_def
...@@ -3144,7 +3540,7 @@ if (v8_value->IsUndefined()) { ...@@ -3144,7 +3540,7 @@ if (v8_value->IsUndefined()) {
v8::PropertyDescriptor desc(v8_value, /*writable=*/false); v8::PropertyDescriptor desc(v8_value, /*writable=*/false);
desc.set_enumerable(true); desc.set_enumerable(true);
desc.set_configurable(true); desc.set_configurable(true);
bindings::V8SetReturnValue(${info}, desc);\ bindings::V8SetReturnValue(${info}, desc);
""")) """))
return func_def return func_def
...@@ -3163,8 +3559,7 @@ def make_cross_origin_indexed_enumerator_callback(cg_context, function_name): ...@@ -3163,8 +3559,7 @@ def make_cross_origin_indexed_enumerator_callback(cg_context, function_name):
body.add_template_var("info", "info") body.add_template_var("info", "info")
bind_callback_local_vars(body, cg_context) bind_callback_local_vars(body, cg_context)
props = cg_context.interface.indexed_and_named_properties if cg_context.interface.identifier != "Window":
if not (props and props.indexed_getter):
return func_def return func_def
body.append( body.append(
...@@ -3172,7 +3567,7 @@ def make_cross_origin_indexed_enumerator_callback(cg_context, function_name): ...@@ -3172,7 +3567,7 @@ def make_cross_origin_indexed_enumerator_callback(cg_context, function_name):
uint32_t length = ${blink_receiver}->length(); uint32_t length = ${blink_receiver}->length();
v8::Local<v8::Array> array = v8::Local<v8::Array> array =
bindings::EnumerateIndexedProperties(${isolate}, length); bindings::EnumerateIndexedProperties(${isolate}, length);
bindings::V8SetReturnValue(${info}, array);\ bindings::V8SetReturnValue(${info}, array);
""")) """))
return func_def return func_def
...@@ -3220,8 +3615,10 @@ for (const auto& operation : kCrossOriginOperationTable) { ...@@ -3220,8 +3615,10 @@ for (const auto& operation : kCrossOriginOperationTable) {
} }
return; return;
} }
% if interface.identifier == "Window": """))
if cg_context.interface.identifier == "Window":
string_case_body.append(
TextNode("""\
// Window object's document-tree child browsing context name property set // Window object's document-tree child browsing context name property set
// //
// TODO(yukishiino): Update the following hard-coded call to an appropriate // TODO(yukishiino): Update the following hard-coded call to an appropriate
...@@ -3229,7 +3626,7 @@ for (const auto& operation : kCrossOriginOperationTable) { ...@@ -3229,7 +3626,7 @@ for (const auto& operation : kCrossOriginOperationTable) {
V8Window::NamedPropertyGetterCustom(${blink_property_name}, ${info}); V8Window::NamedPropertyGetterCustom(${blink_property_name}, ${info});
if (!${info}.GetReturnValue().Get()->IsUndefined()) if (!${info}.GetReturnValue().Get()->IsUndefined())
return; return;
% endif""")) """))
body.extend([ body.extend([
make_runtime_call_timer_scope(cg_context, "CrossOriginPropertyGetter"), make_runtime_call_timer_scope(cg_context, "CrossOriginPropertyGetter"),
...@@ -3244,7 +3641,7 @@ if (bindings::IsSupportedInCrossOriginPropertyFallback( ...@@ -3244,7 +3641,7 @@ if (bindings::IsSupportedInCrossOriginPropertyFallback(
${info}.GetIsolate(), ${v8_property_name})) { ${info}.GetIsolate(), ${v8_property_name})) {
return ${info}.GetReturnValue().SetUndefined(); return ${info}.GetReturnValue().SetUndefined();
} }
${throw_security_error}\ ${throw_security_error}
"""), """),
]) ])
...@@ -3278,7 +3675,8 @@ for (const auto& attribute : kCrossOriginAttributeTable) { ...@@ -3278,7 +3675,8 @@ for (const auto& attribute : kCrossOriginAttributeTable) {
attribute.set_value(${v8_property_name}, ${v8_property_value}, ${info}); attribute.set_value(${v8_property_name}, ${v8_property_value}, ${info});
return; return;
} }
}""")) }
"""))
body.extend([ body.extend([
make_runtime_call_timer_scope(cg_context, "CrossOriginPropertySetter"), make_runtime_call_timer_scope(cg_context, "CrossOriginPropertySetter"),
...@@ -3397,8 +3795,10 @@ for (const auto& operation : kCrossOriginOperationTable) { ...@@ -3397,8 +3795,10 @@ for (const auto& operation : kCrossOriginOperationTable) {
bindings::V8SetReturnValue(${info}, desc); bindings::V8SetReturnValue(${info}, desc);
return; return;
} }
% if interface.identifier == "Window": """))
if cg_context.interface.identifier == "Window":
string_case_body.append(
TextNode("""\
// Window object's document-tree child browsing context name property set // Window object's document-tree child browsing context name property set
// //
// TODO(yukishiino): Update the following hard-coded call to an appropriate // TODO(yukishiino): Update the following hard-coded call to an appropriate
...@@ -3412,7 +3812,7 @@ if (!${info}.GetReturnValue().Get()->IsUndefined()) { ...@@ -3412,7 +3812,7 @@ if (!${info}.GetReturnValue().Get()->IsUndefined()) {
bindings::V8SetReturnValue(${info}, desc); bindings::V8SetReturnValue(${info}, desc);
return; return;
} }
% endif""")) """))
body.extend([ body.extend([
CxxLikelyIfNode( CxxLikelyIfNode(
...@@ -3430,7 +3830,7 @@ if (bindings::IsSupportedInCrossOriginPropertyFallback( ...@@ -3430,7 +3830,7 @@ if (bindings::IsSupportedInCrossOriginPropertyFallback(
bindings::V8SetReturnValue(${info}, desc); bindings::V8SetReturnValue(${info}, desc);
return; return;
} }
${throw_security_error}\ ${throw_security_error}
"""), """),
]) ])
...@@ -3474,7 +3874,8 @@ for (const auto& operation : kCrossOriginOperationTable) { ...@@ -3474,7 +3874,8 @@ for (const auto& operation : kCrossOriginOperationTable) {
int32_t v8_property_attribute = v8::DontEnum | v8::ReadOnly; int32_t v8_property_attribute = v8::DontEnum | v8::ReadOnly;
bindings::V8SetReturnValue(${info}, v8_property_attribute); bindings::V8SetReturnValue(${info}, v8_property_attribute);
return; return;
}""")) }
"""))
body.extend([ body.extend([
CxxLikelyIfNode( CxxLikelyIfNode(
...@@ -3488,7 +3889,8 @@ if (bindings::IsSupportedInCrossOriginPropertyFallback( ...@@ -3488,7 +3889,8 @@ if (bindings::IsSupportedInCrossOriginPropertyFallback(
int32_t v8_property_attribute = v8::DontEnum | v8::ReadOnly; int32_t v8_property_attribute = v8::DontEnum | v8::ReadOnly;
bindings::V8SetReturnValue(${info}, v8_property_attribute); bindings::V8SetReturnValue(${info}, v8_property_attribute);
return; return;
}"""), }
"""),
]) ])
return func_def return func_def
...@@ -3514,7 +3916,7 @@ bindings::V8SetReturnValue( ...@@ -3514,7 +3916,7 @@ bindings::V8SetReturnValue(
bindings::EnumerateCrossOriginProperties( bindings::EnumerateCrossOriginProperties(
${isolate}, ${isolate},
kCrossOriginAttributeTable, kCrossOriginAttributeTable,
kCrossOriginOperationTable));\ kCrossOriginOperationTable));
""")) """))
return func_def return func_def
...@@ -4287,10 +4689,10 @@ ${prototype_object}->GetPrototype().As<v8::Object>()->Delete( ...@@ -4287,10 +4689,10 @@ ${prototype_object}->GetPrototype().As<v8::Object>()->Delete(
return SequenceNode(nodes) if nodes else None return SequenceNode(nodes) if nodes else None
def make_install_interface_template( def make_install_interface_template(cg_context, function_name, class_name,
cg_context, function_name, class_name, trampoline_var_name, trampoline_var_name, constructor_entries,
constructor_entries, indexed_and_named_property_install_nodes, supplemental_install_node,
cross_origin_property_install_nodes, install_unconditional_func_name, install_unconditional_func_name,
install_context_independent_func_name): install_context_independent_func_name):
""" """
Returns: Returns:
...@@ -4308,8 +4710,7 @@ def make_install_interface_template( ...@@ -4308,8 +4710,7 @@ def make_install_interface_template(
assert all( assert all(
isinstance(entry, _PropEntryConstructorGroup) isinstance(entry, _PropEntryConstructorGroup)
for entry in constructor_entries) for entry in constructor_entries)
assert isinstance(indexed_and_named_property_install_nodes, SequenceNode) assert isinstance(supplemental_install_node, SequenceNode)
assert isinstance(cross_origin_property_install_nodes, SequenceNode)
assert _is_none_or_str(install_unconditional_func_name) assert _is_none_or_str(install_unconditional_func_name)
assert _is_none_or_str(install_context_independent_func_name) assert _is_none_or_str(install_context_independent_func_name)
...@@ -4385,9 +4786,8 @@ def make_install_interface_template( ...@@ -4385,9 +4786,8 @@ def make_install_interface_template(
assert False assert False
body.append(EmptyNode()) body.append(EmptyNode())
if cross_origin_property_install_nodes:
body.extend([ body.extend([
cross_origin_property_install_nodes, supplemental_install_node,
EmptyNode(), EmptyNode(),
]) ])
...@@ -4463,12 +4863,6 @@ ${instance_template}->SetImmutableProto(); ...@@ -4463,12 +4863,6 @@ ${instance_template}->SetImmutableProto();
${prototype_template}->SetImmutableProto(); ${prototype_template}->SetImmutableProto();
""")) """))
if indexed_and_named_property_install_nodes:
body.extend([
indexed_and_named_property_install_nodes,
EmptyNode(),
])
if (cg_context.interface if (cg_context.interface
and cg_context.interface.indexed_and_named_properties and and cg_context.interface.indexed_and_named_properties and
cg_context.interface.indexed_and_named_properties.indexed_getter cg_context.interface.indexed_and_named_properties.indexed_getter
...@@ -4765,7 +5159,16 @@ def make_install_properties(cg_context, function_name, class_name, ...@@ -4765,7 +5159,16 @@ def make_install_properties(cg_context, function_name, class_name,
return func_decl, func_def, trampoline_def return func_decl, func_def, trampoline_def
def make_indexed_and_named_property_callbacks_and_install_nodes(cg_context): def make_indexed_and_named_property_callbacks_and_install_node(cg_context):
"""
Implements non-ordinary internal methods of legacy platform objects.
https://heycam.github.io/webidl/#es-legacy-platform-objects
Also implements the same origin case of indexed access to WindowProxy
objects just same as indexed properties of legacy platform objects.
https://html.spec.whatwg.org/C/#the-windowproxy-exotic-object
"""
assert isinstance(cg_context, CodeGenContext) assert isinstance(cg_context, CodeGenContext)
F = lambda *args, **kwargs: TextNode(_format(*args, **kwargs)) F = lambda *args, **kwargs: TextNode(_format(*args, **kwargs))
...@@ -4792,6 +5195,69 @@ def make_indexed_and_named_property_callbacks_and_install_nodes(cg_context): ...@@ -4792,6 +5195,69 @@ def make_indexed_and_named_property_callbacks_and_install_nodes(cg_context):
cg_context = cg_context.make_copy( cg_context = cg_context.make_copy(
v8_callback_type=CodeGenContext.V8_OTHER_CALLBACK) v8_callback_type=CodeGenContext.V8_OTHER_CALLBACK)
if (props.own_named_getter
and "Global" not in interface.extended_attributes):
add_callback(*make_named_property_getter_callback(
cg_context.make_copy(named_property_getter=props.named_getter),
"NamedPropertyGetterCallback"))
add_callback(*make_named_property_setter_callback(
cg_context.make_copy(named_property_setter=props.named_setter),
"NamedPropertySetterCallback"))
add_callback(*make_named_property_deleter_callback(
cg_context.make_copy(named_property_deleter=props.named_deleter),
"NamedPropertyDeleterCallback"))
add_callback(*make_named_property_definer_callback(
cg_context, "NamedPropertyDefinerCallback"))
add_callback(*make_named_property_descriptor_callback(
cg_context, "NamedPropertyDescriptorCallback"))
add_callback(*make_named_property_query_callback(
cg_context, "NamedPropertyQueryCallback"))
add_callback(*make_named_property_enumerator_callback(
cg_context, "NamedPropertyEnumeratorCallback"))
if props.named_getter and "Global" not in interface.extended_attributes:
impl_bridge = v8_bridge_class_name(
most_derived_interface(
props.named_getter.owner, props.named_setter
and props.named_setter.owner, props.named_deleter
and props.named_deleter.owner))
flags = ["v8::PropertyHandlerFlags::kOnlyInterceptStrings"]
if "OverrideBuiltins" not in interface.extended_attributes:
flags.append("v8::PropertyHandlerFlags::kNonMasking")
if (props.named_getter.extended_attributes.value_of("Affects") ==
"Nothing"):
flags.append("v8::PropertyHandlerFlags::kHasNoSideEffect")
property_handler_flags = (
"static_cast<v8::PropertyHandlerFlags>({})".format(" | ".join(
map(lambda flag: "int32_t({})".format(flag), flags))))
pattern = """\
// Named interceptors
${instance_template}->SetHandler(
v8::NamedPropertyHandlerConfiguration(
{impl_bridge}::NamedPropertyGetterCallback,
{impl_bridge}::NamedPropertySetterCallback,
% if "NotEnumerable" not in \
interface.indexed_and_named_properties.named_getter.extended_attributes:
{impl_bridge}::NamedPropertyQueryCallback,
% else:
nullptr, // query
% endif
{impl_bridge}::NamedPropertyDeleterCallback,
% if "NotEnumerable" not in \
interface.indexed_and_named_properties.named_getter.extended_attributes:
{impl_bridge}::NamedPropertyEnumeratorCallback,
% else:
nullptr, // enumerator
% endif
{impl_bridge}::NamedPropertyDefinerCallback,
{impl_bridge}::NamedPropertyDescriptorCallback,
v8::Local<v8::Value>(),
{property_handler_flags}));"""
install_nodes.append(
F(pattern,
impl_bridge=impl_bridge,
property_handler_flags=property_handler_flags))
if props.own_indexed_getter or props.own_named_getter: if props.own_indexed_getter or props.own_named_getter:
add_callback(*make_indexed_property_getter_callback( add_callback(*make_indexed_property_getter_callback(
cg_context.make_copy(indexed_property_getter=props.indexed_getter), cg_context.make_copy(indexed_property_getter=props.indexed_getter),
...@@ -4815,8 +5281,7 @@ def make_indexed_and_named_property_callbacks_and_install_nodes(cg_context): ...@@ -4815,8 +5281,7 @@ def make_indexed_and_named_property_callbacks_and_install_nodes(cg_context):
props.indexed_setter and props.indexed_setter.owner, props.indexed_setter and props.indexed_setter.owner,
props.named_getter and props.named_getter.owner, props.named_getter and props.named_getter.owner,
props.named_setter and props.named_setter.owner, props.named_setter and props.named_setter.owner,
props.named_deleter and props.named_deleter.owner, props.named_deleter and props.named_deleter.owner))
))
flags = [] flags = []
if (props.indexed_getter and props.indexed_getter.extended_attributes. if (props.indexed_getter and props.indexed_getter.extended_attributes.
value_of("Affects") == "Nothing"): value_of("Affects") == "Nothing"):
...@@ -4825,7 +5290,7 @@ def make_indexed_and_named_property_callbacks_and_install_nodes(cg_context): ...@@ -4825,7 +5290,7 @@ def make_indexed_and_named_property_callbacks_and_install_nodes(cg_context):
flags.append("v8::PropertyHandlerFlags::kNone") flags.append("v8::PropertyHandlerFlags::kNone")
property_handler_flags = flags[0] property_handler_flags = flags[0]
pattern = """\ pattern = """\
// Indexed properties // Indexed interceptors
${instance_template}->SetHandler( ${instance_template}->SetHandler(
v8::IndexedPropertyHandlerConfiguration( v8::IndexedPropertyHandlerConfiguration(
{impl_bridge}::IndexedPropertyGetterCallback, {impl_bridge}::IndexedPropertyGetterCallback,
...@@ -4846,79 +5311,97 @@ ${instance_template}->SetHandler( ...@@ -4846,79 +5311,97 @@ ${instance_template}->SetHandler(
impl_bridge=impl_bridge, impl_bridge=impl_bridge,
property_handler_flags=property_handler_flags)) property_handler_flags=property_handler_flags))
if props.own_named_getter: return func_decls, func_defs, install_nodes
add_callback(*make_named_property_getter_callback(
cg_context.make_copy(named_property_getter=props.named_getter),
"NamedPropertyGetterCallback"))
add_callback(*make_named_property_setter_callback(
cg_context.make_copy(named_property_setter=props.named_setter),
"NamedPropertySetterCallback"))
add_callback(*make_named_property_deleter_callback(
cg_context.make_copy(named_property_deleter=props.named_deleter),
"NamedPropertyDeleterCallback"))
add_callback(*make_named_property_definer_callback(
cg_context, "NamedPropertyDefinerCallback"))
add_callback(*make_named_property_descriptor_callback(
cg_context, "NamedPropertyDescriptorCallback"))
add_callback(*make_named_property_query_callback(
cg_context, "NamedPropertyQueryCallback"))
add_callback(*make_named_property_enumerator_callback(
cg_context, "NamedPropertyEnumeratorCallback"))
if props.named_getter:
impl_bridge = v8_bridge_class_name( def make_named_properties_object_callbacks_and_install_node(cg_context):
most_derived_interface( """
props.named_getter.owner, Implements non-ordinary internal methods of named properties objects.
props.named_setter and props.named_setter.owner, https://heycam.github.io/webidl/#named-properties-object
props.named_deleter and props.named_deleter.owner, """
))
flags = ["v8::PropertyHandlerFlags::kOnlyInterceptStrings"] assert isinstance(cg_context, CodeGenContext)
if "OverrideBuiltins" not in interface.extended_attributes:
flags.append("v8::PropertyHandlerFlags::kNonMasking") callback_defs = []
if (props.named_getter.extended_attributes.value_of("Affects") == install_nodes = SequenceNode()
"Nothing"):
flags.append("v8::PropertyHandlerFlags::kHasNoSideEffect") interface = cg_context.interface
property_handler_flags = ( if not (interface and interface.indexed_and_named_properties
"static_cast<v8::PropertyHandlerFlags>({})".format(" | ".join( and interface.indexed_and_named_properties.named_getter
map(lambda flag: "int32_t({})".format(flag), flags)))) and "Global" in interface.extended_attributes):
pattern = """\ return callback_defs, install_nodes
// Named properties
% if "Global" in interface.extended_attributes: cg_context = cg_context.make_copy(
${npo_prototype_template} v8_callback_type=CodeGenContext.V8_OTHER_CALLBACK)
% else:
${instance_template} func_defs = [
%endif make_named_props_obj_named_getter_callback(
->SetHandler( cg_context, "NamedPropsObjNamedGetterCallback"),
make_named_props_obj_named_setter_callback(
cg_context, "NamedPropsObjNamedSetterCallback"),
make_named_props_obj_named_deleter_callback(
cg_context, "NamedPropsObjNamedDeleterCallback"),
make_named_props_obj_named_definer_callback(
cg_context, "NamedPropsObjNamedDefinerCallback"),
make_named_props_obj_named_descriptor_callback(
cg_context, "NamedPropsObjNamedDescriptorCallback"),
make_named_props_obj_indexed_getter_callback(
cg_context, "NamedPropsObjIndexedGetterCallback"),
make_named_props_obj_indexed_setter_callback(
cg_context, "NamedPropsObjIndexedSetterCallback"),
make_named_props_obj_indexed_deleter_callback(
cg_context, "NamedPropsObjIndexedDeleterCallback"),
make_named_props_obj_indexed_definer_callback(
cg_context, "NamedPropsObjIndexedDefinerCallback"),
make_named_props_obj_indexed_descriptor_callback(
cg_context, "NamedPropsObjIndexedDescriptorCallback"),
]
for func_def in func_defs:
callback_defs.append(func_def)
callback_defs.append(EmptyNode())
text = """\
// Named interceptors
${npo_prototype_template}->SetHandler(
v8::NamedPropertyHandlerConfiguration( v8::NamedPropertyHandlerConfiguration(
{impl_bridge}::NamedPropertyGetterCallback, NamedPropsObjNamedGetterCallback,
{impl_bridge}::NamedPropertySetterCallback, NamedPropsObjNamedSetterCallback,
% if "NotEnumerable" not in \
interface.indexed_and_named_properties.named_getter.extended_attributes:
{impl_bridge}::NamedPropertyQueryCallback,
% else:
nullptr, // query nullptr, // query
% endif NamedPropsObjNamedDeleterCallback,
{impl_bridge}::NamedPropertyDeleterCallback,
% if "NotEnumerable" not in \
interface.indexed_and_named_properties.named_getter.extended_attributes:
{impl_bridge}::NamedPropertyEnumeratorCallback,
% else:
nullptr, // enumerator nullptr, // enumerator
% endif NamedPropsObjNamedDefinerCallback,
{impl_bridge}::NamedPropertyDefinerCallback, NamedPropsObjNamedDescriptorCallback,
{impl_bridge}::NamedPropertyDescriptorCallback,
v8::Local<v8::Value>(), v8::Local<v8::Value>(),
{property_handler_flags}));""" static_cast<v8::PropertyHandlerFlags>(
install_nodes.append( int32_t(v8::PropertyHandlerFlags::kNonMasking) |
F(pattern, int32_t(v8::PropertyHandlerFlags::kOnlyInterceptStrings))));
impl_bridge=impl_bridge, // Indexed interceptors
property_handler_flags=property_handler_flags)) ${npo_prototype_template}->SetHandler(
v8::IndexedPropertyHandlerConfiguration(
NamedPropsObjIndexedGetterCallback,
NamedPropsObjIndexedSetterCallback,
nullptr, // query
NamedPropsObjIndexedDeleterCallback,
nullptr, // enumerator
NamedPropsObjIndexedDefinerCallback,
NamedPropsObjIndexedDescriptorCallback,
v8::Local<v8::Value>(),
v8::PropertyHandlerFlags::kNone));"""
install_nodes.append(TextNode(text))
return func_decls, func_defs, install_nodes return callback_defs, install_nodes
def make_cross_origin_property_callbacks_and_install_nodes( def make_cross_origin_property_callbacks_and_install_node(
cg_context, attribute_entries, operation_entries): cg_context, attribute_entries, operation_entries):
"""
Implements non-ordinary internal methods of WindowProxy and Location
objects for the cross origin case. The same origin case is implemented
in |make_indexed_and_named_property_callbacks_and_install_nodes|.
https://html.spec.whatwg.org/C/#the-windowproxy-exotic-object
https://html.spec.whatwg.org/C/#the-location-interface
"""
assert isinstance(cg_context, CodeGenContext) assert isinstance(cg_context, CodeGenContext)
callback_defs = [] callback_defs = []
...@@ -5004,49 +5487,39 @@ def make_cross_origin_property_callbacks_and_install_nodes( ...@@ -5004,49 +5487,39 @@ def make_cross_origin_property_callbacks_and_install_nodes(
cg_context = cg_context.make_copy( cg_context = cg_context.make_copy(
v8_callback_type=CodeGenContext.V8_OTHER_CALLBACK) v8_callback_type=CodeGenContext.V8_OTHER_CALLBACK)
callback_defs.extend([ func_defs = [
make_cross_origin_access_check_callback( make_cross_origin_access_check_callback(
cg_context, "CrossOriginAccessCheckCallback"), cg_context, "CrossOriginAccessCheckCallback"),
EmptyNode(),
make_cross_origin_indexed_getter_callback( make_cross_origin_indexed_getter_callback(
cg_context, "CrossOriginIndexedGetterCallback"), cg_context, "CrossOriginIndexedGetterCallback"),
EmptyNode(),
make_cross_origin_indexed_setter_callback( make_cross_origin_indexed_setter_callback(
cg_context, "CrossOriginIndexedSetterCallback"), cg_context, "CrossOriginIndexedSetterCallback"),
EmptyNode(),
make_cross_origin_indexed_deleter_callback( make_cross_origin_indexed_deleter_callback(
cg_context, "CrossOriginIndexedDeleterCallback"), cg_context, "CrossOriginIndexedDeleterCallback"),
EmptyNode(),
make_cross_origin_indexed_definer_callback( make_cross_origin_indexed_definer_callback(
cg_context, "CrossOriginIndexedDefinerCallback"), cg_context, "CrossOriginIndexedDefinerCallback"),
EmptyNode(),
make_cross_origin_indexed_descriptor_callback( make_cross_origin_indexed_descriptor_callback(
cg_context, "CrossOriginIndexedDescriptorCallback"), cg_context, "CrossOriginIndexedDescriptorCallback"),
EmptyNode(),
make_cross_origin_indexed_enumerator_callback( make_cross_origin_indexed_enumerator_callback(
cg_context, "CrossOriginIndexedEnumeratorCallback"), cg_context, "CrossOriginIndexedEnumeratorCallback"),
EmptyNode(),
make_cross_origin_named_getter_callback( make_cross_origin_named_getter_callback(
cg_context, "CrossOriginNamedGetterCallback"), cg_context, "CrossOriginNamedGetterCallback"),
EmptyNode(),
make_cross_origin_named_setter_callback( make_cross_origin_named_setter_callback(
cg_context, "CrossOriginNamedSetterCallback"), cg_context, "CrossOriginNamedSetterCallback"),
EmptyNode(),
make_cross_origin_named_deleter_callback( make_cross_origin_named_deleter_callback(
cg_context, "CrossOriginNamedDeleterCallback"), cg_context, "CrossOriginNamedDeleterCallback"),
EmptyNode(),
make_cross_origin_named_definer_callback( make_cross_origin_named_definer_callback(
cg_context, "CrossOriginNamedDefinerCallback"), cg_context, "CrossOriginNamedDefinerCallback"),
EmptyNode(),
make_cross_origin_named_descriptor_callback( make_cross_origin_named_descriptor_callback(
cg_context, "CrossOriginNamedDescriptorCallback"), cg_context, "CrossOriginNamedDescriptorCallback"),
EmptyNode(),
make_cross_origin_named_query_callback( make_cross_origin_named_query_callback(
cg_context, "CrossOriginNamedQueryCallback"), cg_context, "CrossOriginNamedQueryCallback"),
EmptyNode(),
make_cross_origin_named_enumerator_callback( make_cross_origin_named_enumerator_callback(
cg_context, "CrossOriginNamedEnumeratorCallback"), cg_context, "CrossOriginNamedEnumeratorCallback"),
]) ]
for func_def in func_defs:
callback_defs.append(func_def)
callback_defs.append(EmptyNode())
text = """\ text = """\
// Cross origin properties // Cross origin properties
...@@ -5074,7 +5547,7 @@ ${instance_template}->SetAccessCheckCallbackAndHandler( ...@@ -5074,7 +5547,7 @@ ${instance_template}->SetAccessCheckCallbackAndHandler(
v8::PropertyHandlerFlags::kNone), v8::PropertyHandlerFlags::kNone),
v8::External::New( v8::External::New(
${isolate}, ${isolate},
const_cast<WrapperTypeInfo*>(${class_name}::GetWrapperTypeInfo())));\ const_cast<WrapperTypeInfo*>(${class_name}::GetWrapperTypeInfo())));
""" """
install_nodes.append(TextNode(text)) install_nodes.append(TextNode(text))
install_nodes.accumulate( install_nodes.accumulate(
...@@ -5543,19 +6016,32 @@ def generate_interface(interface): ...@@ -5543,19 +6016,32 @@ def generate_interface(interface):
constructor_entries=constructor_entries, constructor_entries=constructor_entries,
exposed_construct_entries=exposed_construct_entries, exposed_construct_entries=exposed_construct_entries,
operation_entries=operation_entries) operation_entries=operation_entries)
supplemental_install_node = SequenceNode()
# Indexed and named properties # Indexed and named properties
# Shorten a function name to mitigate a style check error.
f = make_indexed_and_named_property_callbacks_and_install_node
(indexed_and_named_property_decls, indexed_and_named_property_defs, (indexed_and_named_property_decls, indexed_and_named_property_defs,
indexed_and_named_property_install_nodes) = ( indexed_and_named_property_install_node) = f(cg_context)
make_indexed_and_named_property_callbacks_and_install_nodes( supplemental_install_node.append(indexed_and_named_property_install_node)
cg_context)) supplemental_install_node.append(EmptyNode())
# Named properties object
(named_properties_object_callback_defs,
named_properties_object_install_node) = (
make_named_properties_object_callbacks_and_install_node(cg_context))
callback_defs.extend(named_properties_object_callback_defs)
supplemental_install_node.append(named_properties_object_install_node)
supplemental_install_node.append(EmptyNode())
# Cross origin properties # Cross origin properties
(cross_origin_property_callback_defs, (cross_origin_property_callback_defs,
cross_origin_property_install_nodes) = ( cross_origin_property_install_node) = (
make_cross_origin_property_callbacks_and_install_nodes( make_cross_origin_property_callbacks_and_install_node(
cg_context, attribute_entries, operation_entries)) cg_context, attribute_entries, operation_entries))
callback_defs.extend(cross_origin_property_callback_defs) callback_defs.extend(cross_origin_property_callback_defs)
supplemental_install_node.append(cross_origin_property_install_node)
supplemental_install_node.append(EmptyNode())
# Installer functions # Installer functions
is_unconditional = lambda entry: entry.exposure_conditional.is_always_true is_unconditional = lambda entry: entry.exposure_conditional.is_always_true
...@@ -5606,10 +6092,7 @@ def generate_interface(interface): ...@@ -5606,10 +6092,7 @@ def generate_interface(interface):
class_name=impl_class_name, class_name=impl_class_name,
trampoline_var_name=tp_install_interface_template, trampoline_var_name=tp_install_interface_template,
constructor_entries=constructor_entries, constructor_entries=constructor_entries,
indexed_and_named_property_install_nodes=( supplemental_install_node=supplemental_install_node,
indexed_and_named_property_install_nodes),
cross_origin_property_install_nodes=(
cross_origin_property_install_nodes),
install_unconditional_func_name=(install_unconditional_props_def install_unconditional_func_name=(install_unconditional_props_def
and FN_INSTALL_UNCONDITIONAL_PROPS), and FN_INSTALL_UNCONDITIONAL_PROPS),
install_context_independent_func_name=( install_context_independent_func_name=(
......
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