1# Copyright (C) 2013 Google Inc. All rights reserved. 2# 3# Redistribution and use in source and binary forms, with or without 4# modification, are permitted provided that the following conditions are 5# met: 6# 7# * Redistributions of source code must retain the above copyright 8# notice, this list of conditions and the following disclaimer. 9# * Redistributions in binary form must reproduce the above 10# copyright notice, this list of conditions and the following disclaimer 11# in the documentation and/or other materials provided with the 12# distribution. 13# * Neither the name of Google Inc. nor the names of its 14# contributors may be used to endorse or promote products derived from 15# this software without specific prior written permission. 16# 17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29"""Functions for type handling and type conversion (Blink/C++ <-> V8/JS). 30 31Spec: 32http://www.w3.org/TR/WebIDL/#es-type-mapping 33 34FIXME: Not currently used in build. 35This is a rewrite of the Perl IDL compiler in Python, but is not complete. 36Once it is complete, we will switch all IDL files over to Python at once. 37Until then, please work on the Perl IDL compiler. 38For details, see bug http://crbug.com/239771 39""" 40 41import posixpath 42import re 43 44from v8_globals import includes 45import idl_definitions # for UnionType 46from v8_utilities import strip_suffix 47 48################################################################################ 49# IDL types 50################################################################################ 51 52BASIC_TYPES = set([ 53 # Built-in, non-composite, non-object data types 54 # http://www.w3.org/TR/WebIDL/#dfn-primitive-type 55 'boolean', 56 'float', 57 # unrestricted float is not supported 58 'double', 59 # unrestricted double is not supported 60 # integer types 61 # http://www.w3.org/TR/WebIDL/#dfn-integer-type 62 'byte', 63 'octet', 64 'short', 65 'unsigned short', 66 # int and unsigned are not IDL types 67 'long', 68 'unsigned long', 69 'long long', 70 'unsigned long long', 71 # http://www.w3.org/TR/WebIDL/#idl-types 72 'DOMString', 73 'Date', 74 # http://www.w3.org/TR/WebIDL/#es-type-mapping 75 'void', 76]) 77 78enum_types = {} # name -> values 79callback_function_types = set() 80 81 82def array_or_sequence_type(idl_type): 83 return array_type(idl_type) or sequence_type(idl_type) 84 85 86def array_type(idl_type): 87 matched = re.match(r'([\w\s]+)\[\]', idl_type) 88 return matched and matched.group(1) 89 90 91def is_basic_type(idl_type): 92 return idl_type in BASIC_TYPES 93 94 95def is_callback_function_type(idl_type): 96 return idl_type in callback_function_types 97 98 99def set_callback_function_types(callback_functions): 100 callback_function_types.update(callback_functions.keys()) 101 102 103def is_composite_type(idl_type): 104 return (idl_type == 'any' or 105 array_type(idl_type) or 106 sequence_type(idl_type) or 107 is_union_type(idl_type)) 108 109 110def is_enum_type(idl_type): 111 return idl_type in enum_types 112 113 114def enum_values(idl_type): 115 return enum_types.get(idl_type) 116 117 118def set_enum_types(enumerations): 119 enum_types.update([[enum.name, enum.values] 120 for enum in enumerations.values()]) 121 122 123def is_interface_type(idl_type): 124 # Anything that is not another type is an interface type. 125 # http://www.w3.org/TR/WebIDL/#idl-types 126 # http://www.w3.org/TR/WebIDL/#idl-interface 127 # In C++ these are RefPtr or PassRefPtr types. 128 return not(is_basic_type(idl_type) or 129 is_composite_type(idl_type) or 130 is_callback_function_type(idl_type) or 131 is_enum_type(idl_type) or 132 idl_type == 'object' or 133 idl_type == 'Promise') # Promise will be basic in future 134 135 136def sequence_type(idl_type): 137 matched = re.match(r'sequence<([\w\s]+)>', idl_type) 138 return matched and matched.group(1) 139 140 141def is_union_type(idl_type): 142 return isinstance(idl_type, idl_definitions.IdlUnionType) 143 144 145################################################################################ 146# V8-specific type handling 147################################################################################ 148 149DOM_NODE_TYPES = set([ 150 'Attr', 151 'CDATASection', 152 'CharacterData', 153 'Comment', 154 'Document', 155 'DocumentFragment', 156 'DocumentType', 157 'Element', 158 'Entity', 159 'HTMLDocument', 160 'Node', 161 'Notation', 162 'ProcessingInstruction', 163 'ShadowRoot', 164 'SVGDocument', 165 'Text', 166 'TestNode', 167]) 168NON_WRAPPER_TYPES = set([ 169 'CompareHow', 170 'Dictionary', 171 'MediaQueryListListener', 172 'NodeFilter', 173 'SerializedScriptValue', 174]) 175TYPED_ARRAYS = { 176 # (cpp_type, v8_type), used by constructor templates 177 'ArrayBuffer': None, 178 'ArrayBufferView': None, 179 'Float32Array': ('float', 'v8::kExternalFloatArray'), 180 'Float64Array': ('double', 'v8::kExternalDoubleArray'), 181 'Int8Array': ('signed char', 'v8::kExternalByteArray'), 182 'Int16Array': ('short', 'v8::kExternalShortArray'), 183 'Int32Array': ('int', 'v8::kExternalIntArray'), 184 'Uint8Array': ('unsigned char', 'v8::kExternalUnsignedByteArray'), 185 'Uint8ClampedArray': ('unsigned char', 'v8::kExternalPixelArray'), 186 'Uint16Array': ('unsigned short', 'v8::kExternalUnsignedShortArray'), 187 'Uint32Array': ('unsigned int', 'v8::kExternalUnsignedIntArray'), 188} 189 190 191def constructor_type(idl_type): 192 return strip_suffix(idl_type, 'Constructor') 193 194 195def is_dom_node_type(idl_type): 196 return (idl_type in DOM_NODE_TYPES or 197 (idl_type.startswith(('HTML', 'SVG')) and 198 idl_type.endswith('Element'))) 199 200 201def is_typed_array_type(idl_type): 202 return idl_type in TYPED_ARRAYS 203 204 205def is_wrapper_type(idl_type): 206 return (is_interface_type(idl_type) and 207 idl_type not in NON_WRAPPER_TYPES) 208 209 210################################################################################ 211# C++ types 212################################################################################ 213 214CPP_TYPE_SAME_AS_IDL_TYPE = set([ 215 'double', 216 'float', 217 'long long', 218 'unsigned long long', 219]) 220CPP_INT_TYPES = set([ 221 'byte', 222 'long', 223 'short', 224]) 225CPP_UNSIGNED_TYPES = set([ 226 'octet', 227 'unsigned int', 228 'unsigned long', 229 'unsigned short', 230]) 231CPP_SPECIAL_CONVERSION_RULES = { 232 'CompareHow': 'Range::CompareHow', 233 'Date': 'double', 234 'Dictionary': 'Dictionary', 235 'EventHandler': 'EventListener*', 236 'Promise': 'ScriptPromise', 237 'any': 'ScriptValue', 238 'boolean': 'bool', 239} 240 241def cpp_type(idl_type, extended_attributes=None, used_as_argument=False): 242 """Returns C++ type corresponding to IDL type.""" 243 def string_mode(): 244 # FIXME: the Web IDL spec requires 'EmptyString', not 'NullString', 245 # but we use NullString for performance. 246 if extended_attributes.get('TreatNullAs') != 'NullString': 247 return '' 248 if extended_attributes.get('TreatUndefinedAs') != 'NullString': 249 return 'WithNullCheck' 250 return 'WithUndefinedOrNullCheck' 251 252 extended_attributes = extended_attributes or {} 253 idl_type = preprocess_idl_type(idl_type) 254 255 if idl_type in CPP_TYPE_SAME_AS_IDL_TYPE: 256 return idl_type 257 if idl_type in CPP_INT_TYPES: 258 return 'int' 259 if idl_type in CPP_UNSIGNED_TYPES: 260 return 'unsigned' 261 if idl_type in CPP_SPECIAL_CONVERSION_RULES: 262 return CPP_SPECIAL_CONVERSION_RULES[idl_type] 263 if (idl_type in NON_WRAPPER_TYPES or 264 idl_type == 'XPathNSResolver'): # FIXME: eliminate this special case 265 return 'RefPtr<%s>' % idl_type 266 if idl_type == 'DOMString': 267 if not used_as_argument: 268 return 'String' 269 return 'V8StringResource<%s>' % string_mode() 270 if is_union_type(idl_type): 271 raise Exception('UnionType is not supported') 272 this_array_or_sequence_type = array_or_sequence_type(idl_type) 273 if this_array_or_sequence_type: 274 return cpp_template_type('Vector', cpp_type(this_array_or_sequence_type)) 275 276 if is_typed_array_type and used_as_argument: 277 return idl_type + '*' 278 if is_interface_type(idl_type) and not used_as_argument: 279 return cpp_template_type('RefPtr', idl_type) 280 # Default, assume native type is a pointer with same type name as idl type 281 return idl_type + '*' 282 283 284def cpp_template_type(template, inner_type): 285 """Returns C++ template specialized to type, with space added if needed.""" 286 if inner_type.endswith('>'): 287 format_string = '{template}<{inner_type} >' 288 else: 289 format_string = '{template}<{inner_type}>' 290 return format_string.format(template=template, inner_type=inner_type) 291 292 293def v8_type(interface_type): 294 return 'V8' + interface_type 295 296 297################################################################################ 298# Includes 299################################################################################ 300 301 302def includes_for_cpp_class(class_name, relative_dir_posix): 303 return set([posixpath.join('bindings', relative_dir_posix, class_name + '.h')]) 304 305 306INCLUDES_FOR_TYPE = { 307 'any': set(['bindings/v8/ScriptValue.h']), 308 'object': set(), 309 'Dictionary': set(['bindings/v8/Dictionary.h']), 310 'EventHandler': set(['bindings/v8/V8AbstractEventListener.h', 311 'bindings/v8/V8EventListenerList.h']), 312 'EventListener': set(['bindings/v8/BindingSecurity.h', 313 'bindings/v8/V8EventListenerList.h', 314 'core/frame/DOMWindow.h']), 315 'MediaQueryListListener': set(['core/css/MediaQueryListListener.h']), 316 'Promise': set(['bindings/v8/ScriptPromise.h']), 317 'SerializedScriptValue': set(['bindings/v8/SerializedScriptValue.h']), 318} 319 320def includes_for_type(idl_type): 321 if idl_type in INCLUDES_FOR_TYPE: 322 return INCLUDES_FOR_TYPE[idl_type] 323 if is_basic_type(idl_type) or is_enum_type(idl_type): 324 return set() 325 if is_typed_array_type(idl_type): 326 return set(['bindings/v8/custom/V8%sCustom.h' % idl_type]) 327 this_array_or_sequence_type = array_or_sequence_type(idl_type) 328 if this_array_or_sequence_type: 329 return includes_for_type(this_array_or_sequence_type) 330 if idl_type.endswith('Constructor'): 331 idl_type = constructor_type(idl_type) 332 return set(['V8%s.h' % idl_type]) 333 334 335def add_includes_for_type(idl_type): 336 includes.update(includes_for_type(idl_type)) 337 338 339################################################################################ 340# V8 -> C++ 341################################################################################ 342 343V8_VALUE_TO_CPP_VALUE = { 344 # Basic 345 'Date': 'toWebCoreDate({v8_value})', 346 'DOMString': '{v8_value}', 347 'boolean': '{v8_value}->BooleanValue()', 348 'float': 'static_cast<float>({v8_value}->NumberValue())', 349 'double': 'static_cast<double>({v8_value}->NumberValue())', 350 'byte': 'toInt8({arguments})', 351 'octet': 'toUInt8({arguments})', 352 'short': 'toInt16({arguments})', 353 'unsigned short': 'toUInt16({arguments})', 354 'long': 'toInt32({arguments})', 355 'unsigned long': 'toUInt32({arguments})', 356 'long long': 'toInt64({arguments})', 357 'unsigned long long': 'toUInt64({arguments})', 358 # Interface types 359 'any': 'ScriptValue({v8_value}, info.GetIsolate())', 360 'CompareHow': 'static_cast<Range::CompareHow>({v8_value}->Int32Value())', 361 'Dictionary': 'Dictionary({v8_value}, info.GetIsolate())', 362 'MediaQueryListListener': 'MediaQueryListListener::create(ScriptValue({v8_value}, info.GetIsolate()))', 363 'NodeFilter': 'toNodeFilter({v8_value}, info.GetIsolate())', 364 'Promise': 'ScriptPromise({v8_value})', 365 'SerializedScriptValue': 'SerializedScriptValue::create({v8_value}, info.GetIsolate())', 366 'XPathNSResolver': 'toXPathNSResolver({v8_value}, info.GetIsolate())', 367} 368 369 370def v8_value_to_cpp_value(idl_type, extended_attributes, v8_value, index): 371 this_array_or_sequence_type = array_or_sequence_type(idl_type) 372 if this_array_or_sequence_type: 373 return v8_value_to_cpp_value_array_or_sequence(this_array_or_sequence_type, v8_value, index) 374 375 idl_type = preprocess_idl_type(idl_type) 376 add_includes_for_type(idl_type) 377 378 if 'EnforceRange' in extended_attributes: 379 arguments = ', '.join([v8_value, 'EnforceRange', 'ok']) 380 else: # NormalConversion 381 arguments = v8_value 382 383 if idl_type in V8_VALUE_TO_CPP_VALUE: 384 cpp_expression_format = V8_VALUE_TO_CPP_VALUE[idl_type] 385 elif is_typed_array_type(idl_type): 386 cpp_expression_format = ( 387 '{v8_value}->Is{idl_type}() ? ' 388 'V8{idl_type}::toNative(v8::Handle<v8::{idl_type}>::Cast({v8_value})) : 0') 389 else: 390 cpp_expression_format = ( 391 'V8{idl_type}::hasInstance({v8_value}, info.GetIsolate(), worldType(info.GetIsolate())) ? ' 392 'V8{idl_type}::toNative(v8::Handle<v8::Object>::Cast({v8_value})) : 0') 393 394 return cpp_expression_format.format(arguments=arguments, idl_type=idl_type, v8_value=v8_value) 395 396 397def v8_value_to_cpp_value_array_or_sequence(this_array_or_sequence_type, v8_value, index): 398 # Index is None for setters, index (starting at 0) for method arguments, 399 # and is used to provide a human-readable exception message 400 if index is None: 401 index = 0 # special case, meaning "setter" 402 else: 403 index += 1 # human-readable index 404 if (is_interface_type(this_array_or_sequence_type) and 405 this_array_or_sequence_type != 'Dictionary'): 406 this_cpp_type = None 407 expression_format = '(toRefPtrNativeArray<{array_or_sequence_type}, V8{array_or_sequence_type}>({v8_value}, {index}, info.GetIsolate()))' 408 add_includes_for_type(this_array_or_sequence_type) 409 else: 410 this_cpp_type = cpp_type(this_array_or_sequence_type) 411 expression_format = 'toNativeArray<{cpp_type}>({v8_value}, {index}, info.GetIsolate())' 412 expression = expression_format.format(array_or_sequence_type=this_array_or_sequence_type, cpp_type=this_cpp_type, index=index, v8_value=v8_value) 413 return expression 414 415 416def v8_value_to_local_cpp_value(idl_type, extended_attributes, v8_value, variable_name, index=None): 417 """Returns an expression that converts a V8 value to a C++ value and stores it as a local value.""" 418 this_cpp_type = cpp_type(idl_type, extended_attributes=extended_attributes, used_as_argument=True) 419 420 idl_type = preprocess_idl_type(idl_type) 421 if idl_type == 'DOMString': 422 format_string = 'V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID({cpp_type}, {variable_name}, {cpp_value})' 423 elif 'EnforceRange' in extended_attributes: 424 format_string = 'V8TRYCATCH_WITH_TYPECHECK_VOID({cpp_type}, {variable_name}, {cpp_value}, info.GetIsolate())' 425 else: 426 format_string = 'V8TRYCATCH_VOID({cpp_type}, {variable_name}, {cpp_value})' 427 428 cpp_value = v8_value_to_cpp_value(idl_type, extended_attributes, v8_value, index) 429 return format_string.format(cpp_type=this_cpp_type, cpp_value=cpp_value, variable_name=variable_name) 430 431 432################################################################################ 433# C++ -> V8 434################################################################################ 435 436 437def preprocess_idl_type(idl_type): 438 if is_enum_type(idl_type): 439 # Enumerations are internally DOMStrings 440 return 'DOMString' 441 if is_callback_function_type(idl_type): 442 return 'ScriptValue' 443 return idl_type 444 445 446def preprocess_idl_type_and_value(idl_type, cpp_value, extended_attributes): 447 """Returns IDL type and value, with preliminary type conversions applied.""" 448 idl_type = preprocess_idl_type(idl_type) 449 if idl_type in ['Promise', 'any']: 450 idl_type = 'ScriptValue' 451 if idl_type in ['long long', 'unsigned long long']: 452 # long long and unsigned long long are not representable in ECMAScript; 453 # we represent them as doubles. 454 idl_type = 'double' 455 cpp_value = 'static_cast<double>(%s)' % cpp_value 456 # HTML5 says that unsigned reflected attributes should be in the range 457 # [0, 2^31). When a value isn't in this range, a default value (or 0) 458 # should be returned instead. 459 extended_attributes = extended_attributes or {} 460 if ('Reflect' in extended_attributes and 461 idl_type in ['unsigned long', 'unsigned short']): 462 cpp_value = cpp_value.replace('getUnsignedIntegralAttribute', 463 'getIntegralAttribute') 464 cpp_value = 'std::max(0, %s)' % cpp_value 465 return idl_type, cpp_value 466 467 468def v8_conversion_type(idl_type, extended_attributes): 469 """Returns V8 conversion type, adding any additional includes. 470 471 The V8 conversion type is used to select the C++ -> V8 conversion function 472 or v8SetReturnValue* function; it can be an idl_type, a cpp_type, or a 473 separate name for the type of conversion (e.g., 'DOMWrapper'). 474 """ 475 extended_attributes = extended_attributes or {} 476 # Basic types, without additional includes 477 if idl_type in CPP_INT_TYPES: 478 return 'int' 479 if idl_type in CPP_UNSIGNED_TYPES: 480 return 'unsigned' 481 if idl_type == 'DOMString': 482 if 'TreatReturnedNullStringAs' not in extended_attributes: 483 return 'DOMString' 484 treat_returned_null_string_as = extended_attributes['TreatReturnedNullStringAs'] 485 if treat_returned_null_string_as == 'Null': 486 return 'StringOrNull' 487 if treat_returned_null_string_as == 'Undefined': 488 return 'StringOrUndefined' 489 raise 'Unrecognized TreatReturnNullStringAs value: "%s"' % treat_returned_null_string_as 490 if is_basic_type(idl_type) or idl_type == 'ScriptValue': 491 return idl_type 492 493 # Data type with potential additional includes 494 this_array_or_sequence_type = array_or_sequence_type(idl_type) 495 if this_array_or_sequence_type: 496 if is_interface_type(this_array_or_sequence_type): 497 add_includes_for_type(this_array_or_sequence_type) 498 return 'array' 499 500 add_includes_for_type(idl_type) 501 if idl_type in V8_SET_RETURN_VALUE: # Special v8SetReturnValue treatment 502 return idl_type 503 504 # Pointer type 505 includes.add('wtf/GetPtr.h') # FIXME: remove if can eliminate WTF::getPtr 506 includes.add('wtf/RefPtr.h') 507 return 'DOMWrapper' 508 509 510V8_SET_RETURN_VALUE = { 511 'boolean': 'v8SetReturnValueBool(info, {cpp_value})', 512 'int': 'v8SetReturnValueInt(info, {cpp_value})', 513 'unsigned': 'v8SetReturnValueUnsigned(info, {cpp_value})', 514 'DOMString': 'v8SetReturnValueString(info, {cpp_value}, info.GetIsolate())', 515 # [TreatNullReturnValueAs] 516 'StringOrNull': 'v8SetReturnValueStringOrNull(info, {cpp_value}, info.GetIsolate())', 517 'StringOrUndefined': 'v8SetReturnValueStringOrUndefined(info, {cpp_value}, info.GetIsolate())', 518 'void': '', 519 # No special v8SetReturnValue* function (set value directly) 520 'float': 'v8SetReturnValue(info, {cpp_value})', 521 'double': 'v8SetReturnValue(info, {cpp_value})', 522 # No special v8SetReturnValue* function, but instead convert value to V8 523 # and then use general v8SetReturnValue. 524 'array': 'v8SetReturnValue(info, {cpp_value})', 525 'Date': 'v8SetReturnValue(info, {cpp_value})', 526 'EventHandler': 'v8SetReturnValue(info, {cpp_value})', 527 'ScriptValue': 'v8SetReturnValue(info, {cpp_value})', 528 'SerializedScriptValue': 'v8SetReturnValue(info, {cpp_value})', 529 # DOMWrapper 530 'DOMWrapperFast': 'v8SetReturnValueFast(info, {cpp_value}, {script_wrappable})', 531 'DOMWrapperDefault': 'v8SetReturnValue(info, {cpp_value})', 532} 533 534 535def v8_set_return_value(idl_type, cpp_value, extended_attributes=None, script_wrappable=''): 536 """Returns a statement that converts a C++ value to a V8 value and sets it as a return value.""" 537 def dom_wrapper_conversion_type(): 538 if not script_wrappable: 539 return 'DOMWrapperDefault' 540 return 'DOMWrapperFast' 541 542 idl_type, cpp_value = preprocess_idl_type_and_value(idl_type, cpp_value, extended_attributes) 543 this_v8_conversion_type = v8_conversion_type(idl_type, extended_attributes) 544 # SetReturn-specific overrides 545 if this_v8_conversion_type in ['Date', 'EventHandler', 'ScriptValue', 'SerializedScriptValue', 'array']: 546 # Convert value to V8 and then use general v8SetReturnValue 547 cpp_value = cpp_value_to_v8_value(idl_type, cpp_value, extended_attributes=extended_attributes) 548 if this_v8_conversion_type == 'DOMWrapper': 549 this_v8_conversion_type = dom_wrapper_conversion_type() 550 551 format_string = V8_SET_RETURN_VALUE[this_v8_conversion_type] 552 statement = format_string.format(cpp_value=cpp_value, script_wrappable=script_wrappable) 553 return statement 554 555 556CPP_VALUE_TO_V8_VALUE = { 557 # Built-in types 558 'Date': 'v8DateOrNull({cpp_value}, {isolate})', 559 'DOMString': 'v8String({isolate}, {cpp_value})', 560 'boolean': 'v8Boolean({cpp_value}, {isolate})', 561 'int': 'v8::Integer::New({isolate}, {cpp_value})', 562 'unsigned': 'v8::Integer::NewFromUnsigned({isolate}, {cpp_value})', 563 'float': 'v8::Number::New({isolate}, {cpp_value})', 564 'double': 'v8::Number::New({isolate}, {cpp_value})', 565 'void': 'v8Undefined()', 566 # Special cases 567 'EventHandler': '{cpp_value} ? v8::Handle<v8::Value>(V8AbstractEventListener::cast({cpp_value})->getListenerObject(imp->executionContext())) : v8::Handle<v8::Value>(v8::Null({isolate}))', 568 'ScriptValue': '{cpp_value}.v8Value()', 569 'SerializedScriptValue': '{cpp_value} ? {cpp_value}->deserialize() : v8::Handle<v8::Value>(v8::Null({isolate}))', 570 # General 571 'array': 'v8Array({cpp_value}, {isolate})', 572 'DOMWrapper': 'toV8({cpp_value}, {creation_context}, {isolate})', 573} 574 575 576def cpp_value_to_v8_value(idl_type, cpp_value, isolate='info.GetIsolate()', creation_context='', extended_attributes=None): 577 """Returns an expression that converts a C++ value to a V8 value.""" 578 # the isolate parameter is needed for callback interfaces 579 idl_type, cpp_value = preprocess_idl_type_and_value(idl_type, cpp_value, extended_attributes) 580 this_v8_conversion_type = v8_conversion_type(idl_type, extended_attributes) 581 format_string = CPP_VALUE_TO_V8_VALUE[this_v8_conversion_type] 582 statement = format_string.format(cpp_value=cpp_value, isolate=isolate, creation_context=creation_context) 583 return statement 584