summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/union.py
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/blink/renderer/bindings/scripts/bind_gen/union.py')
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/bind_gen/union.py160
1 files changed, 117 insertions, 43 deletions
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/union.py b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/union.py
index 8b3e236c7c7..4973cc52f3e 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/union.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/union.py
@@ -11,6 +11,7 @@ from .blink_v8_bridge import make_v8_to_blink_value
from .blink_v8_bridge import native_value_tag
from .blink_v8_bridge import v8_bridge_class_name
from .code_node import EmptyNode
+from .code_node import FormatNode
from .code_node import ListNode
from .code_node import SequenceNode
from .code_node import SymbolDefinitionNode
@@ -42,6 +43,14 @@ from .task_queue import TaskQueue
class _UnionMember(object):
+ """
+ _UnionMember represents the properties that the code generator directly
+ needs while web_idl.Union represents properties of IDL union independent
+ from ECMAScript binding. _UnionMember is specific to not only ECMAScript
+ binding but also Blink implementation of IDL union and its flattened member
+ types.
+ """
+
def __init__(self, base_name):
assert isinstance(base_name, str)
@@ -98,8 +107,16 @@ class _UnionMember(object):
class _UnionMemberImpl(_UnionMember):
+ """
+ Represents a flattened member type of an union type or the special null
+ type, which represents that the union type includes a nullable type.
+
+ For example, either of (A? or B) or (A or B?) is represented as a list of
+ [_UnionMemberImpl(A), _UnionMemberImpl(B), _UnionMemberImpl(null)].
+ """
+
def __init__(self, union, idl_type):
- assert isinstance(union, web_idl.NewUnion)
+ assert isinstance(union, web_idl.Union)
assert idl_type is None or isinstance(idl_type, web_idl.IdlType)
if idl_type is None:
@@ -120,13 +137,24 @@ class _UnionMemberImpl(_UnionMember):
class _UnionMemberSubunion(_UnionMember):
+ """
+ Represents a subset of flattened member types in an union type as
+ 'subunion'.
+
+ For example, given an union type X = (A or B or C) with the following use
+ cases,
+ ((A or B) or C)
+ (A or (B or C))
+ subunions of the union type X are represented as
+ [_UnionMemberSubunion(A or B), _UnionMemberSubunion(B or C)].
+ """
+
def __init__(self, union, subunion):
- assert isinstance(union, web_idl.NewUnion)
- assert isinstance(subunion, web_idl.NewUnion)
+ assert isinstance(union, web_idl.Union)
+ assert isinstance(subunion, web_idl.Union)
_UnionMember.__init__(self, base_name=blink_class_name(subunion))
- self._type_info = blink_type_info(subunion.idl_types[0],
- use_new_union=True)
+ self._type_info = blink_type_info(subunion.idl_types[0])
self._typedef_aliases = tuple(
map(lambda typedef: _UnionMemberAlias(impl=self, typedef=typedef),
subunion.aliasing_typedefs))
@@ -138,17 +166,29 @@ class _UnionMemberSubunion(_UnionMember):
class _UnionMemberAlias(_UnionMember):
+ """
+ Represents a typedef'ed aliases to a flattened member type or subunion of
+ an union type.
+
+ For example, given the following Web IDL fragments,
+ typedef (A or B) T1;
+ typedef B T2;
+ (T1 or C)
+ _UnionMemberAlias(T1) represents an alias to _UnionMemberSubunion(A or B)
+ and _UnionMemberAlias(T2) represents an alias to _UnionMemberImpl(B).
+ """
+
def __init__(self, impl, typedef):
assert isinstance(impl, (_UnionMemberImpl, _UnionMemberSubunion))
assert isinstance(typedef, web_idl.Typedef)
- _UnionMember.__init__(self, base_name=typedef.identifier)
+ _UnionMember.__init__(self, base_name=blink_class_name(typedef))
self._var_name = impl.var_name
self._type_info = impl.type_info
def create_union_members(union):
- assert isinstance(union, web_idl.NewUnion)
+ assert isinstance(union, web_idl.Union)
union_members = list(map(
lambda member_type: _UnionMemberImpl(union, member_type),
@@ -195,7 +235,7 @@ def make_factory_methods(cg_context):
S = SymbolNode
T = TextNode
- F = lambda *args, **kwargs: T(_format(*args, **kwargs))
+ F = FormatNode
func_decl = CxxFuncDeclNode(name="Create",
arg_decls=[
@@ -336,8 +376,9 @@ def make_factory_methods(cg_context):
# then:
# 8.1. If types includes a typed array type whose name is the value of V's
# [[TypedArrayName]] internal slot, ...
- typed_array_types = ("Int8Array", "Int16Array", "Int32Array", "Uint8Array",
- "Uint16Array", "Uint32Array", "Uint8ClampedArray",
+ typed_array_types = ("Int8Array", "Int16Array", "Int32Array",
+ "BigInt64Array", "Uint8Array", "Uint16Array",
+ "Uint32Array", "BigUint64Array", "Uint8ClampedArray",
"Float32Array", "Float64Array")
for typed_array_type in typed_array_types:
member = find_by_type(lambda t: t.keyword_typename == typed_array_type)
@@ -372,8 +413,9 @@ def make_factory_methods(cg_context):
T("ScriptIterator script_iterator = ScriptIterator::FromIterable("
"${isolate}, ${v8_value}.As<v8::Object>(), "
"${exception_state});"),
- CxxUnlikelyIfNode(cond="${exception_state}.HadException()",
- body=T("return nullptr;")),
+ CxxUnlikelyIfNode(
+ cond="UNLIKELY(${exception_state}.HadException())",
+ body=T("return nullptr;")),
])
def blink_value_from_iterator(union_member):
@@ -386,8 +428,9 @@ def make_factory_methods(cg_context):
"${exception_state});"),
native_value_tag(
union_member.idl_type.unwrap().element_type)),
- CxxUnlikelyIfNode(cond="${exception_state}.HadException()",
- body=T("return nullptr;")),
+ CxxUnlikelyIfNode(
+ cond="UNLIKELY(${exception_state}.HadException())",
+ body=T("return nullptr;")),
])
return node
@@ -543,16 +586,11 @@ def make_accessor_functions(cg_context):
assert isinstance(cg_context, CodeGenContext)
T = TextNode
- F = lambda *args, **kwargs: T(_format(*args, **kwargs))
+ F = FormatNode
decls = ListNode()
defs = ListNode()
- def add(func_decl, func_def):
- decls.append(func_decl)
- defs.append(func_def)
- defs.append(EmptyNode())
-
func_def = CxxFuncDefNode(name="GetContentType",
arg_decls=[],
return_type="ContentType",
@@ -651,23 +689,6 @@ def make_accessor_functions(cg_context):
])
return func_def, None
- for member in cg_context.union_members:
- if member.is_null:
- add(*make_api_pred(member))
- add(*make_api_set_null(member))
- else:
- add(*make_api_pred(member))
- for alias in member.typedef_aliases:
- add(*make_api_pred(alias))
- add(*make_api_get(member))
- for alias in member.typedef_aliases:
- add(*make_api_get(alias))
- if member.type_info.is_move_effective:
- add(*make_api_set_copy_and_move(member))
- else:
- add(*make_api_set(member))
- decls.append(EmptyNode())
-
def make_api_subunion_pred(subunion, subunion_members):
func_def = CxxFuncDefNode(name=subunion.api_pred,
arg_decls=[],
@@ -724,12 +745,56 @@ def make_accessor_functions(cg_context):
func_def.body.append(node)
return func_decl, func_def
+ def make_api_subunion_alias_pred(subunion, alias):
+ func_def = CxxFuncDefNode(name=alias.api_pred,
+ arg_decls=[],
+ return_type="bool",
+ const=True)
+ func_def.set_base_template_vars(cg_context.template_bindings())
+ func_def.body.append(F("return {}();", subunion.api_pred))
+ return func_def, None
+
+ def make_api_subunion_alias_get(subunion, alias):
+ func_def = CxxFuncDefNode(name=alias.api_get,
+ arg_decls=[],
+ return_type=alias.type_info.value_t,
+ const=True)
+ func_def.set_base_template_vars(cg_context.template_bindings())
+ func_def.body.append(F("return {}();", subunion.api_get))
+ return func_def, None
+
+ def add(func_decl, func_def):
+ decls.append(func_decl)
+ defs.append(func_def)
+ defs.append(EmptyNode())
+
+ # Accessors to member types of the union type
+ for member in cg_context.union_members:
+ if member.is_null:
+ add(*make_api_pred(member))
+ add(*make_api_set_null(member))
+ else:
+ add(*make_api_pred(member))
+ add(*make_api_get(member))
+ if member.type_info.is_move_effective:
+ add(*make_api_set_copy_and_move(member))
+ else:
+ add(*make_api_set(member))
+ for alias in member.typedef_aliases:
+ add(*make_api_pred(alias))
+ add(*make_api_get(alias))
+ decls.append(EmptyNode())
+
+ # Accessors to subunions in the union type
for subunion in cg_context.union.union_members:
subunion_members = create_union_members(subunion)
subunion = _UnionMemberSubunion(cg_context.union, subunion)
add(*make_api_subunion_pred(subunion, subunion_members))
add(*make_api_subunion_get(subunion, subunion_members))
add(*make_api_subunion_set(subunion, subunion_members))
+ for alias in subunion.typedef_aliases:
+ add(*make_api_subunion_alias_pred(subunion, alias))
+ add(*make_api_subunion_alias_get(subunion, alias))
decls.append(EmptyNode())
return decls, defs
@@ -855,11 +920,20 @@ def make_member_vars_def(cg_context):
EmptyNode(),
])
- entries = [
- "{} {};".format(member.type_info.member_t, member.var_name)
- for member in cg_context.union_members if not member.is_null
- ]
- member_vars_def.extend(map(TextNode, entries))
+ for member in cg_context.union_members:
+ if member.is_null:
+ continue
+ if member.idl_type.is_enumeration:
+ # Since the IDL enumeration class is not default constructible,
+ # construct the IDL enumeration with 0th enum value. Note that
+ # this is necessary only for compilation, and the value must never
+ # be used due to the guard by `content_type_`.
+ pattern = "{} {}{{static_cast<{}::Enum>(0)}};"
+ else:
+ pattern = "{} {};"
+ node = FormatNode(pattern, member.type_info.member_t, member.var_name,
+ member.type_info.value_t)
+ member_vars_def.append(node)
return member_vars_def
@@ -1033,5 +1107,5 @@ def generate_unions(task_queue):
web_idl_database = package_initializer().web_idl_database()
- for union in web_idl_database.new_union_types:
+ for union in web_idl_database.union_types:
task_queue.post_task(generate_union, union.identifier)