Commit 244d65f3 authored by Yuki Shiino's avatar Yuki Shiino Committed by Commit Bot

bind-gen: Implement blink_type_info and native_value_tag

Implements two type conversion functions in blink_v8_bridge.py.

Bug: 839389
Change-Id: I31dfbf882e8abd3a71719b54d8226313dd4bba92
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1899632Reviewed-by: default avatarHitoshi Yoshida <peria@chromium.org>
Commit-Queue: Yuki Shiino <yukishiino@chromium.org>
Cr-Commit-Position: refs/heads/master@{#712656}
parent ec4308ae
...@@ -2,17 +2,156 @@ ...@@ -2,17 +2,156 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
import web_idl
from . import name_style
from .code_node import CodeNode from .code_node import CodeNode
from .code_node import SymbolDefinitionNode from .code_node import SymbolDefinitionNode
from .code_node import SymbolNode from .code_node import SymbolNode
from .code_node import SymbolScopeNode from .code_node import SymbolScopeNode
from .code_node import TextNode from .code_node import TextNode
from .code_node import UnlikelyExitNode from .code_node import UnlikelyExitNode
import web_idl
_format = CodeNode.format_template _format = CodeNode.format_template
def blink_type_info(idl_type):
"""
Returns the types of Blink implementation corresponding to the given IDL
type. The returned object has the following attributes.
member_t: The type of a member variable. E.g. T => Member<T>
ref_t: The type of a local variable that references to an already-existing
value. E.g. String => String&
value_t: The type of a variable that behaves as a value. E.g. String =>
String
is_nullable: True if the Blink implementation type can represent IDL null
value by itself.
"""
assert isinstance(idl_type, web_idl.IdlType)
class TypeInfo(object):
def __init__(self,
typename,
member_fmt="{}",
ref_fmt="{}",
value_fmt="{}",
is_nullable=False):
self.member_t = member_fmt.format(typename)
self.ref_t = ref_fmt.format(typename)
self.value_t = value_fmt.format(typename)
# Whether Blink impl type can represent IDL null or not.
self.is_nullable = is_nullable
real_type = idl_type.unwrap(typedef=True)
if real_type.is_boolean or real_type.is_numeric:
cxx_type = {
"boolean": "bool",
"byte": "int8_t",
"octet": "uint8_t",
"short": "int16_t",
"unsigned short": "uint16_t",
"long": "int32_t",
"unsigned long": "uint32_t",
"long long": "int64_t",
"unsigned long long": "uint64_t",
"float": "float",
"unrestricted float": "float",
"double": "double",
"unrestricted double": "double",
}
return TypeInfo(cxx_type[real_type.keyword_typename])
if real_type.is_string:
return TypeInfo("String", ref_fmt="{}&", is_nullable=True)
if real_type.is_symbol:
assert False, "Blink does not support/accept IDL symbol type."
if real_type.is_any or real_type.is_object:
return TypeInfo("ScriptValue", ref_fmt="{}&", is_nullable=True)
if real_type.is_void:
assert False, "Blink does not support/accept IDL void type."
if real_type.type_definition_object is not None:
type_def_obj = real_type.type_definition_object
blink_impl_type = (
type_def_obj.code_generator_info.receiver_implemented_as
or name_style.class_(type_def_obj.identifier))
return TypeInfo(
blink_impl_type,
member_fmt="Member<{}>",
ref_fmt="{}*",
is_nullable=True)
if (real_type.is_sequence or real_type.is_frozen_array
or real_type.is_variadic):
element_type = blink_type_info(real_type.element_type)
return TypeInfo(
"VectorOf<{}>".format(element_type.value_t), ref_fmt="{}&")
if real_type.is_record:
key_type = blink_type_info(real_type.key_type)
value_type = blink_type_info(real_type.value_type)
return TypeInfo(
"VectorOfPairs<{}, {}>".format(key_type.value_t,
value_type.value_t),
ref_fmt="{}&")
if real_type.is_promise:
return TypeInfo("ScriptPromise", ref_fmt="{}&")
if real_type.is_union:
return TypeInfo("ToBeImplementedUnion")
if real_type.is_nullable:
inner_type = blink_type_info(real_type.inner_type)
if inner_type.is_nullable:
return inner_type
return TypeInfo(
"base::Optional<{}>".format(inner_type.value_t), ref_fmt="{}&")
def native_value_tag(idl_type):
"""Returns the tag type of NativeValueTraits."""
assert isinstance(idl_type, web_idl.IdlType)
real_type = idl_type.unwrap(typedef=True)
if (real_type.is_boolean or real_type.is_numeric or real_type.is_string
or real_type.is_any or real_type.is_object):
return "IDL{}".format(real_type.type_name)
if real_type.is_symbol:
assert False, "Blink does not support/accept IDL symbol type."
if real_type.is_void:
assert False, "Blink does not support/accept IDL void type."
if real_type.type_definition_object is not None:
return blink_type_info(real_type).value_t
if real_type.is_sequence:
return "IDLSequence<{}>".format(
native_value_tag(real_type.element_type))
if real_type.is_record:
return "IDLRecord<{}, {}>".format(
native_value_tag(real_type.key_type),
native_value_tag(real_type.value_type))
if real_type.is_promise:
return "IDLPromise"
if real_type.is_union:
return blink_type_info(real_type).value_t
if real_type.is_nullable:
return "IDLNullable<{}>".format(native_value_tag(real_type.inner_type))
def make_v8_to_blink_value(blink_var_name, v8_value_expr, idl_type): def make_v8_to_blink_value(blink_var_name, v8_value_expr, idl_type):
""" """
Returns a SymbolNode whose definition converts a v8::Value to a Blink value. Returns a SymbolNode whose definition converts a v8::Value to a Blink value.
...@@ -22,17 +161,14 @@ def make_v8_to_blink_value(blink_var_name, v8_value_expr, idl_type): ...@@ -22,17 +161,14 @@ def make_v8_to_blink_value(blink_var_name, v8_value_expr, idl_type):
assert isinstance(idl_type, web_idl.IdlType) assert isinstance(idl_type, web_idl.IdlType)
pattern = "NativeValueTraits<{_1}>::NativeValue({_2})" pattern = "NativeValueTraits<{_1}>::NativeValue({_2})"
_1 = "IDL{}".format(idl_type.type_name) _1 = native_value_tag(idl_type)
_2 = ["${isolate}", v8_value_expr, "${exception_state}"] _2 = ["${isolate}", v8_value_expr, "${exception_state}"]
blink_value = _format(pattern, _1=_1, _2=", ".join(_2)) blink_value = _format(pattern, _1=_1, _2=", ".join(_2))
idl_type_tag = _1
pattern = "{_1}& ${{{_2}}} = {_3};" pattern = "const auto& ${{{_1}}} = {_2};"
_1 = "NativeValueTraits<{}>::ImplType".format(idl_type_tag) _1 = blink_var_name
_2 = blink_var_name _2 = blink_value
_3 = blink_value text = _format(pattern, _1=_1, _2=_2)
text = _format(pattern, _1=_1, _2=_2, _3=_3)
def create_definition(symbol_node): def create_definition(symbol_node):
return SymbolDefinitionNode(symbol_node, [ return SymbolDefinitionNode(symbol_node, [
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
import copy import copy
from blinkbuild.name_style_converter import NameStyleConverter from . import name_style
class CodeGenerationContext(object): class CodeGenerationContext(object):
...@@ -196,9 +196,7 @@ class CodeGenerationContext(object): ...@@ -196,9 +196,7 @@ class CodeGenerationContext(object):
def v8_class(self): def v8_class(self):
if not self.idl_definition: if not self.idl_definition:
return None return None
return "V8{}".format( return name_style.class_("v8", self.idl_definition.identifier)
NameStyleConverter(
self.idl_definition.identifier).to_upper_camel_case())
CodeGenerationContext.init() CodeGenerationContext.init()
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
import os.path import os.path
from . import name_style from . import name_style
from .blink_v8_bridge import blink_type_info
from .blink_v8_bridge import make_v8_to_blink_value from .blink_v8_bridge import make_v8_to_blink_value
from .code_generation_context import CodeGenerationContext from .code_generation_context import CodeGenerationContext
from .code_node import CodeNode from .code_node import CodeNode
...@@ -193,7 +194,9 @@ def bind_return_value(code_node, cg_context): ...@@ -193,7 +194,9 @@ def bind_return_value(code_node, cg_context):
if cg_context.return_type.unwrap().is_void: if cg_context.return_type.unwrap().is_void:
text = "${blink_api_call};" text = "${blink_api_call};"
elif cg_context.is_return_by_argument: elif cg_context.is_return_by_argument:
text = "${blink_return_type} ${return_value};\n${blink_api_call};" pattern = "{_1} ${return_value};\n${blink_api_call};"
_1 = blink_type_info(cg_context.return_type).value_t
text = _format(pattern, _1=_1)
else: else:
text = "const auto& ${return_value} = ${blink_api_call};" text = "const auto& ${return_value} = ${blink_api_call};"
node = SymbolDefinitionNode(symbol_node, [TextNode(text)]) node = SymbolDefinitionNode(symbol_node, [TextNode(text)])
......
...@@ -192,6 +192,15 @@ class IdlType(WithExtendedAttributes, WithDebugInfo): ...@@ -192,6 +192,15 @@ class IdlType(WithExtendedAttributes, WithDebugInfo):
""" """
raise exceptions.NotImplementedError() raise exceptions.NotImplementedError()
@property
def keyword_typename(self):
"""
Returns the keyword name of the type if this is a simple built-in type,
e.g. "any", "boolean", "unsigned long long", "void", etc. Otherwise,
returns None.
"""
return None
def apply_to_all_composing_elements(self, callback): def apply_to_all_composing_elements(self, callback):
""" """
Applies |callback| to all instances of IdlType of which this IdlType Applies |callback| to all instances of IdlType of which this IdlType
...@@ -515,6 +524,10 @@ class SimpleType(IdlType): ...@@ -515,6 +524,10 @@ class SimpleType(IdlType):
return self._format_type_name( return self._format_type_name(
NameStyleConverter(name).to_upper_camel_case()) NameStyleConverter(name).to_upper_camel_case())
@property
def keyword_typename(self):
return self._name
@property @property
def is_numeric(self): def is_numeric(self):
return self._name in SimpleType._NUMERIC_TYPES return self._name in SimpleType._NUMERIC_TYPES
......
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