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 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import web_idl
from . import name_style
from .code_node import CodeNode
from .code_node import SymbolDefinitionNode
from .code_node import SymbolNode
from .code_node import SymbolScopeNode
from .code_node import TextNode
from .code_node import UnlikelyExitNode
import web_idl
_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):
"""
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):
assert isinstance(idl_type, web_idl.IdlType)
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}"]
blink_value = _format(pattern, _1=_1, _2=", ".join(_2))
idl_type_tag = _1
pattern = "{_1}& ${{{_2}}} = {_3};"
_1 = "NativeValueTraits<{}>::ImplType".format(idl_type_tag)
_2 = blink_var_name
_3 = blink_value
text = _format(pattern, _1=_1, _2=_2, _3=_3)
pattern = "const auto& ${{{_1}}} = {_2};"
_1 = blink_var_name
_2 = blink_value
text = _format(pattern, _1=_1, _2=_2)
def create_definition(symbol_node):
return SymbolDefinitionNode(symbol_node, [
......
......@@ -4,7 +4,7 @@
import copy
from blinkbuild.name_style_converter import NameStyleConverter
from . import name_style
class CodeGenerationContext(object):
......@@ -196,9 +196,7 @@ class CodeGenerationContext(object):
def v8_class(self):
if not self.idl_definition:
return None
return "V8{}".format(
NameStyleConverter(
self.idl_definition.identifier).to_upper_camel_case())
return name_style.class_("v8", self.idl_definition.identifier)
CodeGenerationContext.init()
......@@ -5,6 +5,7 @@
import os.path
from . import name_style
from .blink_v8_bridge import blink_type_info
from .blink_v8_bridge import make_v8_to_blink_value
from .code_generation_context import CodeGenerationContext
from .code_node import CodeNode
......@@ -193,7 +194,9 @@ def bind_return_value(code_node, cg_context):
if cg_context.return_type.unwrap().is_void:
text = "${blink_api_call};"
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:
text = "const auto& ${return_value} = ${blink_api_call};"
node = SymbolDefinitionNode(symbol_node, [TextNode(text)])
......
......@@ -192,6 +192,15 @@ class IdlType(WithExtendedAttributes, WithDebugInfo):
"""
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):
"""
Applies |callback| to all instances of IdlType of which this IdlType
......@@ -515,6 +524,10 @@ class SimpleType(IdlType):
return self._format_type_name(
NameStyleConverter(name).to_upper_camel_case())
@property
def keyword_typename(self):
return self._name
@property
def is_numeric(self):
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