1 # Copyright (C) 2013 Google Inc. All rights reserved.
3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions are
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
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.
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.
29 """Functions for type handling and type conversion (Blink/C++ <-> V8/JS).
32 http://www.w3.org/TR/WebIDL/#es-type-mapping
34 FIXME: Not currently used in build.
35 This is a rewrite of the Perl IDL compiler in Python, but is not complete.
36 Once it is complete, we will switch all IDL files over to Python at once.
37 Until then, please work on the Perl IDL compiler.
38 For details, see bug http://crbug.com/239771
44 from v8_globals import includes
45 import idl_definitions # for UnionType
46 from v8_utilities import strip_suffix
48 ################################################################################
50 ################################################################################
53 # Built-in, non-composite, non-object data types
54 # http://www.w3.org/TR/WebIDL/#dfn-primitive-type
57 # unrestricted float is not supported
59 # unrestricted double is not supported
60 # http://www.w3.org/TR/WebIDL/#idl-types
63 # http://www.w3.org/TR/WebIDL/#es-type-mapping
67 # http://www.w3.org/TR/WebIDL/#dfn-integer-type
72 # int and unsigned are not IDL types
78 BASIC_TYPES.update(INTEGER_TYPES)
80 ancestors = {} # interface_name -> ancestors
81 callback_functions = set()
82 callback_interfaces = set()
83 enums = {} # name -> values
86 def array_or_sequence_type(idl_type):
87 return array_type(idl_type) or sequence_type(idl_type)
90 def array_type(idl_type):
91 if is_union_type(idl_type):
92 # We do not support arrays of union types
94 matched = re.match(r'([\w\s]+)\[\]', idl_type)
95 return matched and matched.group(1)
98 def is_basic_type(idl_type):
99 return idl_type in BASIC_TYPES
102 def is_integer_type(idl_type):
103 return idl_type in INTEGER_TYPES
106 def is_callback_function(idl_type):
107 return idl_type in callback_functions
110 def set_callback_functions(new_callback_functions):
111 callback_functions.update(new_callback_functions)
114 def is_callback_interface(idl_type):
115 return idl_type in callback_interfaces
118 def set_callback_interfaces(new_callback_interfaces):
119 callback_interfaces.update(new_callback_interfaces)
122 def is_composite_type(idl_type):
123 return (idl_type == 'any' or
124 array_type(idl_type) or
125 sequence_type(idl_type) or
126 is_union_type(idl_type))
129 def is_enum(idl_type):
130 return idl_type in enums
133 def enum_values(idl_type):
134 return enums.get(idl_type)
137 def set_enums(new_enums):
138 enums.update(new_enums)
141 def inherits_interface(interface_name, ancestor_name):
142 return (interface_name == ancestor_name or
143 ancestor_name in ancestors.get(interface_name, []))
146 def set_ancestors(new_ancestors):
147 ancestors.update(new_ancestors)
150 def is_interface_type(idl_type):
151 # Anything that is not another type is an interface type.
152 # http://www.w3.org/TR/WebIDL/#idl-types
153 # http://www.w3.org/TR/WebIDL/#idl-interface
154 # In C++ these are RefPtr or PassRefPtr types.
155 return not(is_basic_type(idl_type) or
156 is_composite_type(idl_type) or
157 is_callback_function(idl_type) or
159 idl_type == 'object' or
160 idl_type == 'Promise') # Promise will be basic in future
163 def sequence_type(idl_type):
164 if is_union_type(idl_type):
165 # We do not support sequences of union types
167 matched = re.match(r'sequence<([\w\s]+)>', idl_type)
168 return matched and matched.group(1)
171 def is_union_type(idl_type):
172 return isinstance(idl_type, idl_definitions.IdlUnionType)
175 ################################################################################
176 # V8-specific type handling
177 ################################################################################
179 NON_WRAPPER_TYPES = set([
184 'MediaQueryListListener',
186 'SerializedScriptValue',
189 # (cpp_type, v8_type), used by constructor templates
191 'ArrayBufferView': None,
192 'Float32Array': ('float', 'v8::kExternalFloatArray'),
193 'Float64Array': ('double', 'v8::kExternalDoubleArray'),
194 'Int8Array': ('signed char', 'v8::kExternalByteArray'),
195 'Int16Array': ('short', 'v8::kExternalShortArray'),
196 'Int32Array': ('int', 'v8::kExternalIntArray'),
197 'Uint8Array': ('unsigned char', 'v8::kExternalUnsignedByteArray'),
198 'Uint8ClampedArray': ('unsigned char', 'v8::kExternalPixelArray'),
199 'Uint16Array': ('unsigned short', 'v8::kExternalUnsignedShortArray'),
200 'Uint32Array': ('unsigned int', 'v8::kExternalUnsignedIntArray'),
204 def constructor_type(idl_type):
205 return strip_suffix(idl_type, 'Constructor')
208 def is_typed_array_type(idl_type):
209 return idl_type in TYPED_ARRAYS
212 def is_wrapper_type(idl_type):
213 return (is_interface_type(idl_type) and
214 idl_type not in NON_WRAPPER_TYPES)
217 ################################################################################
219 ################################################################################
221 CPP_TYPE_SAME_AS_IDL_TYPE = set([
225 'unsigned long long',
227 CPP_INT_TYPES = set([
232 CPP_UNSIGNED_TYPES = set([
238 CPP_SPECIAL_CONVERSION_RULES = {
239 'CompareHow': 'Range::CompareHow',
241 'Dictionary': 'Dictionary',
242 'EventHandler': 'EventListener*',
243 'Promise': 'ScriptPromise',
244 'ScriptValue': 'ScriptValue',
248 def cpp_type(idl_type, extended_attributes=None, used_as_argument=False):
249 """Returns C++ type corresponding to IDL type."""
251 # FIXME: the Web IDL spec requires 'EmptyString', not 'NullString',
252 # but we use NullString for performance.
253 if extended_attributes.get('TreatNullAs') != 'NullString':
255 if extended_attributes.get('TreatUndefinedAs') != 'NullString':
256 return 'WithNullCheck'
257 return 'WithUndefinedOrNullCheck'
259 extended_attributes = extended_attributes or {}
260 idl_type = preprocess_idl_type(idl_type)
262 if idl_type in CPP_TYPE_SAME_AS_IDL_TYPE:
264 if idl_type in CPP_INT_TYPES:
266 if idl_type in CPP_UNSIGNED_TYPES:
268 if idl_type in CPP_SPECIAL_CONVERSION_RULES:
269 return CPP_SPECIAL_CONVERSION_RULES[idl_type]
270 if (idl_type in NON_WRAPPER_TYPES or
271 idl_type == 'XPathNSResolver'): # FIXME: eliminate this special case
272 return 'RefPtr<%s>' % idl_type
273 if idl_type == 'DOMString':
274 if not used_as_argument:
276 return 'V8StringResource<%s>' % string_mode()
277 if is_union_type(idl_type):
278 # Attribute 'union_member_types' use is ok, but pylint can't infer this
279 # pylint: disable=E1103
280 return (cpp_type(union_member_type)
281 for union_member_type in idl_type.union_member_types)
282 this_array_or_sequence_type = array_or_sequence_type(idl_type)
283 if this_array_or_sequence_type:
284 return cpp_template_type('Vector', cpp_type(this_array_or_sequence_type))
286 if is_typed_array_type(idl_type) and used_as_argument:
287 return idl_type + '*'
288 if is_interface_type(idl_type):
289 implemented_as_class = implemented_as(idl_type)
291 return implemented_as_class + '*'
292 if is_will_be_garbage_collected(idl_type):
293 return cpp_template_type('RefPtrWillBeRawPtr', implemented_as_class)
294 return cpp_template_type('RefPtr', implemented_as_class)
295 # Default, assume native type is a pointer with same type name as idl type
296 return idl_type + '*'
299 def cpp_template_type(template, inner_type):
300 """Returns C++ template specialized to type, with space added if needed."""
301 if inner_type.endswith('>'):
302 format_string = '{template}<{inner_type} >'
304 format_string = '{template}<{inner_type}>'
305 return format_string.format(template=template, inner_type=inner_type)
308 def v8_type(interface_type):
309 return 'V8' + interface_type
313 # This handles [ImplementedAs] on interface types, not [ImplementedAs] in the
314 # interface being generated. e.g., given:
315 # Foo.idl: interface Foo {attribute Bar bar};
316 # Bar.idl: [ImplementedAs=Zork] interface Bar {};
317 # when generating bindings for Foo, the [ImplementedAs] on Bar is needed.
318 # This data is external to Foo.idl, and hence computed as global information in
319 # compute_dependencies.py to avoid having to parse IDLs of all used interfaces.
320 implemented_as_interfaces = {}
323 def implemented_as(idl_type):
324 if idl_type in implemented_as_interfaces:
325 return implemented_as_interfaces[idl_type]
329 def set_implemented_as_interfaces(new_implemented_as_interfaces):
330 implemented_as_interfaces.update(new_implemented_as_interfaces)
333 # [WillBeGarbageCollected]
334 will_be_garbage_collected_types = set()
337 def is_will_be_garbage_collected(idl_type):
338 return idl_type in will_be_garbage_collected_types
341 def set_will_be_garbage_collected_types(new_will_be_garbage_collected_types):
342 will_be_garbage_collected_types.update(new_will_be_garbage_collected_types)
345 ################################################################################
347 ################################################################################
349 def includes_for_cpp_class(class_name, relative_dir_posix):
350 return set([posixpath.join('bindings', relative_dir_posix, class_name + '.h')])
353 INCLUDES_FOR_TYPE = {
356 'Dictionary': set(['bindings/v8/Dictionary.h']),
357 'EventHandler': set(['bindings/v8/V8AbstractEventListener.h',
358 'bindings/v8/V8EventListenerList.h']),
359 'EventListener': set(['bindings/v8/BindingSecurity.h',
360 'bindings/v8/V8EventListenerList.h',
361 'core/frame/DOMWindow.h']),
362 'MediaQueryListListener': set(['core/css/MediaQueryListListener.h']),
363 'Promise': set(['bindings/v8/ScriptPromise.h']),
364 'SerializedScriptValue': set(['bindings/v8/SerializedScriptValue.h']),
365 'ScriptValue': set(['bindings/v8/ScriptValue.h']),
368 def includes_for_type(idl_type):
369 idl_type = preprocess_idl_type(idl_type)
370 if idl_type in INCLUDES_FOR_TYPE:
371 return INCLUDES_FOR_TYPE[idl_type]
372 if is_basic_type(idl_type):
374 if is_typed_array_type(idl_type):
375 return set(['bindings/v8/custom/V8%sCustom.h' % idl_type])
376 this_array_or_sequence_type = array_or_sequence_type(idl_type)
377 if this_array_or_sequence_type:
378 return includes_for_type(this_array_or_sequence_type)
379 if is_union_type(idl_type):
380 # Attribute 'union_member_types' use is ok, but pylint can't infer this
381 # pylint: disable=E1103
383 includes_for_type(union_member_type)
384 for union_member_type in idl_type.union_member_types])
385 if idl_type.endswith('ConstructorConstructor'):
386 # FIXME: rename to NamedConstructor
387 # Ending with 'ConstructorConstructor' indicates a named constructor,
388 # and these do not have header files, as they are part of the generated
389 # bindings for the interface
391 if idl_type.endswith('Constructor'):
392 idl_type = constructor_type(idl_type)
393 return set(['V8%s.h' % idl_type])
396 def add_includes_for_type(idl_type):
397 includes.update(includes_for_type(idl_type))
400 ################################################################################
402 ################################################################################
404 V8_VALUE_TO_CPP_VALUE = {
406 'Date': 'toCoreDate({v8_value})',
407 'DOMString': '{v8_value}',
408 'boolean': '{v8_value}->BooleanValue()',
409 'float': 'static_cast<float>({v8_value}->NumberValue())',
410 'double': 'static_cast<double>({v8_value}->NumberValue())',
411 'byte': 'toInt8({arguments})',
412 'octet': 'toUInt8({arguments})',
413 'short': 'toInt16({arguments})',
414 'unsigned short': 'toUInt16({arguments})',
415 'long': 'toInt32({arguments})',
416 'unsigned long': 'toUInt32({arguments})',
417 'long long': 'toInt64({arguments})',
418 'unsigned long long': 'toUInt64({arguments})',
420 'CompareHow': 'static_cast<Range::CompareHow>({v8_value}->Int32Value())',
421 'Dictionary': 'Dictionary({v8_value}, info.GetIsolate())',
422 'EventTarget': 'V8DOMWrapper::isDOMWrapper({v8_value}) ? toWrapperTypeInfo(v8::Handle<v8::Object>::Cast({v8_value}))->toEventTarget(v8::Handle<v8::Object>::Cast({v8_value})) : 0',
423 'MediaQueryListListener': 'MediaQueryListListener::create(ScriptValue({v8_value}, info.GetIsolate()))',
424 'NodeFilter': 'toNodeFilter({v8_value}, info.GetIsolate())',
425 'Promise': 'ScriptPromise({v8_value}, info.GetIsolate())',
426 'SerializedScriptValue': 'SerializedScriptValue::create({v8_value}, info.GetIsolate())',
427 'ScriptValue': 'ScriptValue({v8_value}, info.GetIsolate())',
428 'Window': 'toDOMWindow({v8_value}, info.GetIsolate())',
429 'XPathNSResolver': 'toXPathNSResolver({v8_value}, info.GetIsolate())',
433 def v8_value_to_cpp_value(idl_type, extended_attributes, v8_value, index):
434 this_array_or_sequence_type = array_or_sequence_type(idl_type)
435 if this_array_or_sequence_type:
436 return v8_value_to_cpp_value_array_or_sequence(this_array_or_sequence_type, v8_value, index)
438 idl_type = preprocess_idl_type(idl_type)
439 add_includes_for_type(idl_type)
441 if 'EnforceRange' in extended_attributes:
442 arguments = ', '.join([v8_value, 'EnforceRange', 'exceptionState'])
443 elif is_integer_type(idl_type): # NormalConversion
444 arguments = ', '.join([v8_value, 'exceptionState'])
448 if idl_type in V8_VALUE_TO_CPP_VALUE:
449 cpp_expression_format = V8_VALUE_TO_CPP_VALUE[idl_type]
450 elif is_typed_array_type(idl_type):
451 cpp_expression_format = (
452 '{v8_value}->Is{idl_type}() ? '
453 'V8{idl_type}::toNative(v8::Handle<v8::{idl_type}>::Cast({v8_value})) : 0')
455 cpp_expression_format = (
456 'V8{idl_type}::hasInstance({v8_value}, info.GetIsolate()) ? '
457 'V8{idl_type}::toNative(v8::Handle<v8::Object>::Cast({v8_value})) : 0')
459 return cpp_expression_format.format(arguments=arguments, idl_type=idl_type, v8_value=v8_value)
462 def v8_value_to_cpp_value_array_or_sequence(this_array_or_sequence_type, v8_value, index):
463 # Index is None for setters, index (starting at 0) for method arguments,
464 # and is used to provide a human-readable exception message
466 index = 0 # special case, meaning "setter"
468 index += 1 # human-readable index
469 if (is_interface_type(this_array_or_sequence_type) and
470 this_array_or_sequence_type != 'Dictionary'):
472 expression_format = '(toRefPtrNativeArray<{array_or_sequence_type}, V8{array_or_sequence_type}>({v8_value}, {index}, info.GetIsolate()))'
473 add_includes_for_type(this_array_or_sequence_type)
475 this_cpp_type = cpp_type(this_array_or_sequence_type)
476 expression_format = 'toNativeArray<{cpp_type}>({v8_value}, {index}, info.GetIsolate())'
477 expression = expression_format.format(array_or_sequence_type=this_array_or_sequence_type, cpp_type=this_cpp_type, index=index, v8_value=v8_value)
481 def v8_value_to_local_cpp_value(idl_type, extended_attributes, v8_value, variable_name, index=None):
482 """Returns an expression that converts a V8 value to a C++ value and stores it as a local value."""
483 this_cpp_type = cpp_type(idl_type, extended_attributes=extended_attributes, used_as_argument=True)
485 idl_type = preprocess_idl_type(idl_type)
486 if idl_type == 'DOMString':
487 format_string = 'V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID({cpp_type}, {variable_name}, {cpp_value})'
488 elif is_integer_type(idl_type):
489 format_string = 'V8TRYCATCH_EXCEPTION_VOID({cpp_type}, {variable_name}, {cpp_value}, exceptionState)'
491 format_string = 'V8TRYCATCH_VOID({cpp_type}, {variable_name}, {cpp_value})'
493 cpp_value = v8_value_to_cpp_value(idl_type, extended_attributes, v8_value, index)
494 return format_string.format(cpp_type=this_cpp_type, cpp_value=cpp_value, variable_name=variable_name)
497 ################################################################################
499 ################################################################################
501 def preprocess_idl_type(idl_type):
502 if is_enum(idl_type):
503 # Enumerations are internally DOMStrings
505 if (idl_type == 'any' or is_callback_function(idl_type)):
510 def preprocess_idl_type_and_value(idl_type, cpp_value, extended_attributes):
511 """Returns IDL type and value, with preliminary type conversions applied."""
512 idl_type = preprocess_idl_type(idl_type)
513 if idl_type == 'Promise':
514 idl_type = 'ScriptValue'
515 if idl_type in ['long long', 'unsigned long long']:
516 # long long and unsigned long long are not representable in ECMAScript;
517 # we represent them as doubles.
519 cpp_value = 'static_cast<double>(%s)' % cpp_value
520 # HTML5 says that unsigned reflected attributes should be in the range
521 # [0, 2^31). When a value isn't in this range, a default value (or 0)
522 # should be returned instead.
523 extended_attributes = extended_attributes or {}
524 if ('Reflect' in extended_attributes and
525 idl_type in ['unsigned long', 'unsigned short']):
526 cpp_value = cpp_value.replace('getUnsignedIntegralAttribute',
527 'getIntegralAttribute')
528 cpp_value = 'std::max(0, %s)' % cpp_value
529 return idl_type, cpp_value
532 def v8_conversion_type(idl_type, extended_attributes):
533 """Returns V8 conversion type, adding any additional includes.
535 The V8 conversion type is used to select the C++ -> V8 conversion function
536 or v8SetReturnValue* function; it can be an idl_type, a cpp_type, or a
537 separate name for the type of conversion (e.g., 'DOMWrapper').
539 extended_attributes = extended_attributes or {}
540 # Basic types, without additional includes
541 if idl_type in CPP_INT_TYPES:
543 if idl_type in CPP_UNSIGNED_TYPES:
545 if idl_type == 'DOMString':
546 if 'TreatReturnedNullStringAs' not in extended_attributes:
548 treat_returned_null_string_as = extended_attributes['TreatReturnedNullStringAs']
549 if treat_returned_null_string_as == 'Null':
550 return 'StringOrNull'
551 if treat_returned_null_string_as == 'Undefined':
552 return 'StringOrUndefined'
553 raise 'Unrecognized TreatReturnNullStringAs value: "%s"' % treat_returned_null_string_as
554 if is_basic_type(idl_type) or idl_type == 'ScriptValue':
557 # Data type with potential additional includes
558 this_array_or_sequence_type = array_or_sequence_type(idl_type)
559 if this_array_or_sequence_type:
560 if is_interface_type(this_array_or_sequence_type):
561 add_includes_for_type(this_array_or_sequence_type)
564 add_includes_for_type(idl_type)
565 if idl_type in V8_SET_RETURN_VALUE: # Special v8SetReturnValue treatment
572 V8_SET_RETURN_VALUE = {
573 'boolean': 'v8SetReturnValueBool(info, {cpp_value})',
574 'int': 'v8SetReturnValueInt(info, {cpp_value})',
575 'unsigned': 'v8SetReturnValueUnsigned(info, {cpp_value})',
576 'DOMString': 'v8SetReturnValueString(info, {cpp_value}, info.GetIsolate())',
577 # [TreatNullReturnValueAs]
578 'StringOrNull': 'v8SetReturnValueStringOrNull(info, {cpp_value}, info.GetIsolate())',
579 'StringOrUndefined': 'v8SetReturnValueStringOrUndefined(info, {cpp_value}, info.GetIsolate())',
581 # No special v8SetReturnValue* function (set value directly)
582 'float': 'v8SetReturnValue(info, {cpp_value})',
583 'double': 'v8SetReturnValue(info, {cpp_value})',
584 # No special v8SetReturnValue* function, but instead convert value to V8
585 # and then use general v8SetReturnValue.
586 'array': 'v8SetReturnValue(info, {cpp_value})',
587 'Date': 'v8SetReturnValue(info, {cpp_value})',
588 'EventHandler': 'v8SetReturnValue(info, {cpp_value})',
589 'ScriptValue': 'v8SetReturnValue(info, {cpp_value})',
590 'SerializedScriptValue': 'v8SetReturnValue(info, {cpp_value})',
592 'DOMWrapperForMainWorld': 'v8SetReturnValueForMainWorld(info, {cpp_value})',
593 'DOMWrapperFast': 'v8SetReturnValueFast(info, {cpp_value}, {script_wrappable})',
594 'DOMWrapperDefault': 'v8SetReturnValue(info, {cpp_value})',
598 def v8_set_return_value(idl_type, cpp_value, extended_attributes=None, script_wrappable='', release=False, for_main_world=False):
599 """Returns a statement that converts a C++ value to a V8 value and sets it as a return value.
601 release: for union types, can be either False (False for all member types)
602 or a sequence (list or tuple) of booleans (if specified
605 def dom_wrapper_conversion_type():
606 if not script_wrappable:
607 return 'DOMWrapperDefault'
609 return 'DOMWrapperForMainWorld'
610 return 'DOMWrapperFast'
612 if is_union_type(idl_type):
614 v8_set_return_value(union_member_type,
618 release and release[i])
619 for i, union_member_type in
620 enumerate(idl_type.union_member_types)]
621 idl_type, cpp_value = preprocess_idl_type_and_value(idl_type, cpp_value, extended_attributes)
622 this_v8_conversion_type = v8_conversion_type(idl_type, extended_attributes)
623 # SetReturn-specific overrides
624 if this_v8_conversion_type in ['Date', 'EventHandler', 'ScriptValue', 'SerializedScriptValue', 'array']:
625 # Convert value to V8 and then use general v8SetReturnValue
626 cpp_value = cpp_value_to_v8_value(idl_type, cpp_value, extended_attributes=extended_attributes)
627 if this_v8_conversion_type == 'DOMWrapper':
628 this_v8_conversion_type = dom_wrapper_conversion_type()
630 format_string = V8_SET_RETURN_VALUE[this_v8_conversion_type]
632 cpp_value = '%s.release()' % cpp_value
633 statement = format_string.format(cpp_value=cpp_value, script_wrappable=script_wrappable)
637 CPP_VALUE_TO_V8_VALUE = {
639 'Date': 'v8DateOrNull({cpp_value}, {isolate})',
640 'DOMString': 'v8String({isolate}, {cpp_value})',
641 'boolean': 'v8Boolean({cpp_value}, {isolate})',
642 'int': 'v8::Integer::New({isolate}, {cpp_value})',
643 'unsigned': 'v8::Integer::NewFromUnsigned({isolate}, {cpp_value})',
644 'float': 'v8::Number::New({isolate}, {cpp_value})',
645 'double': 'v8::Number::New({isolate}, {cpp_value})',
646 'void': 'v8Undefined()',
648 'EventHandler': '{cpp_value} ? v8::Handle<v8::Value>(V8AbstractEventListener::cast({cpp_value})->getListenerObject(imp->executionContext())) : v8::Handle<v8::Value>(v8::Null({isolate}))',
649 'ScriptValue': '{cpp_value}.v8Value()',
650 'SerializedScriptValue': '{cpp_value} ? {cpp_value}->deserialize() : v8::Handle<v8::Value>(v8::Null({isolate}))',
652 'array': 'v8Array({cpp_value}, {isolate})',
653 'DOMWrapper': 'toV8({cpp_value}, {creation_context}, {isolate})',
657 def cpp_value_to_v8_value(idl_type, cpp_value, isolate='info.GetIsolate()', creation_context='', extended_attributes=None):
658 """Returns an expression that converts a C++ value to a V8 value."""
659 # the isolate parameter is needed for callback interfaces
660 idl_type, cpp_value = preprocess_idl_type_and_value(idl_type, cpp_value, extended_attributes)
661 this_v8_conversion_type = v8_conversion_type(idl_type, extended_attributes)
662 format_string = CPP_VALUE_TO_V8_VALUE[this_v8_conversion_type]
663 statement = format_string.format(cpp_value=cpp_value, isolate=isolate, creation_context=creation_context)