OLD | NEW |
1 # Copyright (C) 2013 Google Inc. All rights reserved. | 1 # Copyright (C) 2013 Google Inc. All rights reserved. |
2 # | 2 # |
3 # Redistribution and use in source and binary forms, with or without | 3 # Redistribution and use in source and binary forms, with or without |
4 # modification, are permitted provided that the following conditions are | 4 # modification, are permitted provided that the following conditions are |
5 # met: | 5 # met: |
6 # | 6 # |
7 # * Redistributions of source code must retain the above copyright | 7 # * Redistributions of source code must retain the above copyright |
8 # notice, this list of conditions and the following disclaimer. | 8 # notice, this list of conditions and the following disclaimer. |
9 # * Redistributions in binary form must reproduce the above | 9 # * Redistributions in binary form must reproduce the above |
10 # copyright notice, this list of conditions and the following disclaimer | 10 # copyright notice, this list of conditions and the following disclaimer |
(...skipping 21 matching lines...) Expand all Loading... |
32 class methods. | 32 class methods. |
33 | 33 |
34 Spec: | 34 Spec: |
35 http://www.w3.org/TR/WebIDL/#es-type-mapping | 35 http://www.w3.org/TR/WebIDL/#es-type-mapping |
36 | 36 |
37 Design doc: http://www.chromium.org/developers/design-documents/idl-compiler | 37 Design doc: http://www.chromium.org/developers/design-documents/idl-compiler |
38 """ | 38 """ |
39 | 39 |
40 import posixpath | 40 import posixpath |
41 | 41 |
42 from idl_types import IdlTypeBase, IdlType, IdlUnionType, IdlArrayOrSequenceType | 42 from idl_types import IdlTypeBase, IdlType, IdlUnionType, IdlArrayOrSequenceType
, IdlNullableType |
43 import v8_attributes # for IdlType.constructor_type_name | 43 import v8_attributes # for IdlType.constructor_type_name |
44 from v8_globals import includes | 44 from v8_globals import includes |
45 | 45 |
46 | 46 |
47 ################################################################################ | 47 ################################################################################ |
48 # V8-specific handling of IDL types | 48 # V8-specific handling of IDL types |
49 ################################################################################ | 49 ################################################################################ |
50 | 50 |
51 NON_WRAPPER_TYPES = frozenset([ | 51 NON_WRAPPER_TYPES = frozenset([ |
52 'CompareHow', | |
53 'Dictionary', | 52 'Dictionary', |
54 'EventHandler', | 53 'EventHandler', |
55 'EventListener', | 54 'EventListener', |
56 'MediaQueryListListener', | |
57 'NodeFilter', | 55 'NodeFilter', |
58 'SerializedScriptValue', | 56 'SerializedScriptValue', |
59 ]) | 57 ]) |
60 TYPED_ARRAYS = { | 58 TYPED_ARRAYS = { |
61 # (cpp_type, v8_type), used by constructor templates | 59 # (cpp_type, v8_type), used by constructor templates |
62 'ArrayBuffer': None, | 60 'ArrayBuffer': None, |
63 'ArrayBufferView': None, | 61 'ArrayBufferView': None, |
64 'Float32Array': ('float', 'v8::kExternalFloatArray'), | 62 'Float32Array': ('float', 'v8::kExternalFloatArray'), |
65 'Float64Array': ('double', 'v8::kExternalDoubleArray'), | 63 'Float64Array': ('double', 'v8::kExternalDoubleArray'), |
66 'Int8Array': ('signed char', 'v8::kExternalByteArray'), | 64 'Int8Array': ('signed char', 'v8::kExternalByteArray'), |
67 'Int16Array': ('short', 'v8::kExternalShortArray'), | 65 'Int16Array': ('short', 'v8::kExternalShortArray'), |
68 'Int32Array': ('int', 'v8::kExternalIntArray'), | 66 'Int32Array': ('int', 'v8::kExternalIntArray'), |
69 'Uint8Array': ('unsigned char', 'v8::kExternalUnsignedByteArray'), | 67 'Uint8Array': ('unsigned char', 'v8::kExternalUnsignedByteArray'), |
70 'Uint8ClampedArray': ('unsigned char', 'v8::kExternalPixelArray'), | 68 'Uint8ClampedArray': ('unsigned char', 'v8::kExternalPixelArray'), |
71 'Uint16Array': ('unsigned short', 'v8::kExternalUnsignedShortArray'), | 69 'Uint16Array': ('unsigned short', 'v8::kExternalUnsignedShortArray'), |
72 'Uint32Array': ('unsigned int', 'v8::kExternalUnsignedIntArray'), | 70 'Uint32Array': ('unsigned int', 'v8::kExternalUnsignedIntArray'), |
73 } | 71 } |
74 | 72 |
75 IdlTypeBase.is_typed_array_element_type = False | |
76 IdlType.is_typed_array_element_type = property( | 73 IdlType.is_typed_array_element_type = property( |
77 lambda self: self.base_type in TYPED_ARRAYS) | 74 lambda self: self.base_type in TYPED_ARRAYS) |
78 | 75 |
79 | |
80 IdlTypeBase.is_wrapper_type = False | |
81 IdlType.is_wrapper_type = property( | 76 IdlType.is_wrapper_type = property( |
82 lambda self: (self.is_interface_type and | 77 lambda self: (self.is_interface_type and |
83 self.base_type not in NON_WRAPPER_TYPES)) | 78 self.base_type not in NON_WRAPPER_TYPES)) |
84 | 79 |
85 | 80 |
86 ################################################################################ | 81 ################################################################################ |
87 # C++ types | 82 # C++ types |
88 ################################################################################ | 83 ################################################################################ |
89 | 84 |
90 CPP_TYPE_SAME_AS_IDL_TYPE = set([ | 85 CPP_TYPE_SAME_AS_IDL_TYPE = set([ |
91 'double', | 86 'double', |
92 'float', | 87 'float', |
93 'long long', | 88 'long long', |
94 'unsigned long long', | 89 'unsigned long long', |
95 ]) | 90 ]) |
96 CPP_INT_TYPES = set([ | 91 CPP_INT_TYPES = set([ |
97 'byte', | 92 'byte', |
98 'long', | 93 'long', |
99 'short', | 94 'short', |
100 ]) | 95 ]) |
101 CPP_UNSIGNED_TYPES = set([ | 96 CPP_UNSIGNED_TYPES = set([ |
102 'octet', | 97 'octet', |
103 'unsigned int', | 98 'unsigned int', |
104 'unsigned long', | 99 'unsigned long', |
105 'unsigned short', | 100 'unsigned short', |
106 ]) | 101 ]) |
107 CPP_SPECIAL_CONVERSION_RULES = { | 102 CPP_SPECIAL_CONVERSION_RULES = { |
108 'CompareHow': 'Range::CompareHow', | |
109 'Date': 'double', | 103 'Date': 'double', |
110 'Dictionary': 'Dictionary', | 104 'Dictionary': 'Dictionary', |
111 'EventHandler': 'EventListener*', | 105 'EventHandler': 'EventListener*', |
112 'MediaQueryListListener': 'RefPtrWillBeRawPtr<MediaQueryListListener>', | |
113 'NodeFilter': 'RefPtrWillBeRawPtr<NodeFilter>', | 106 'NodeFilter': 'RefPtrWillBeRawPtr<NodeFilter>', |
114 'Promise': 'ScriptPromise', | 107 'Promise': 'ScriptPromise', |
115 'ScriptValue': 'ScriptValue', | 108 'ScriptValue': 'ScriptValue', |
116 # FIXME: Eliminate custom bindings for XPathNSResolver http://crbug.com/345
529 | 109 # FIXME: Eliminate custom bindings for XPathNSResolver http://crbug.com/345
529 |
117 'XPathNSResolver': 'RefPtrWillBeRawPtr<XPathNSResolver>', | 110 'XPathNSResolver': 'RefPtrWillBeRawPtr<XPathNSResolver>', |
118 'boolean': 'bool', | 111 'boolean': 'bool', |
119 'unrestricted double': 'double', | 112 'unrestricted double': 'double', |
120 'unrestricted float': 'float', | 113 'unrestricted float': 'float', |
121 } | 114 } |
122 | 115 |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
196 return base_idl_type + '*' | 189 return base_idl_type + '*' |
197 | 190 |
198 | 191 |
199 def cpp_type_initializer(idl_type): | 192 def cpp_type_initializer(idl_type): |
200 """Returns a string containing a C++ initialization statement for the | 193 """Returns a string containing a C++ initialization statement for the |
201 corresponding type. | 194 corresponding type. |
202 | 195 |
203 |idl_type| argument is of type IdlType. | 196 |idl_type| argument is of type IdlType. |
204 """ | 197 """ |
205 | 198 |
206 if (idl_type.is_numeric_type): | 199 base_idl_type = idl_type.base_type |
| 200 |
| 201 if idl_type.native_array_element_type: |
| 202 return '' |
| 203 if idl_type.is_numeric_type: |
207 return ' = 0' | 204 return ' = 0' |
208 if idl_type.base_type == 'boolean': | 205 if base_idl_type == 'boolean': |
209 return ' = false' | 206 return ' = false' |
210 if idl_type.base_type == 'Promise': | 207 if idl_type.base_type == 'Promise': |
211 return '(nullptr)' | 208 return '(nullptr)' |
212 return '' | 209 |
| 210 if (base_idl_type in NON_WRAPPER_TYPES or |
| 211 base_idl_type in CPP_SPECIAL_CONVERSION_RULES or |
| 212 base_idl_type == 'any' or |
| 213 idl_type.is_string_type or |
| 214 idl_type.is_enum): |
| 215 return '' |
| 216 return ' = nullptr' |
213 | 217 |
214 | 218 |
215 def cpp_type_union(idl_type, extended_attributes=None, raw_type=False): | 219 def cpp_type_union(idl_type, extended_attributes=None, raw_type=False): |
216 # FIXME: Need to revisit the design of union support. | 220 # FIXME: Need to revisit the design of union support. |
217 # http://crbug.com/240176 | 221 # http://crbug.com/240176 |
218 return None | 222 return None |
219 | 223 |
220 | 224 |
221 def cpp_type_initializer_union(idl_type): | 225 def cpp_type_initializer_union(idl_type): |
222 return (member_type.cpp_type_initializer for member_type in idl_type.member_
types) | 226 return (member_type.cpp_type_initializer for member_type in idl_type.member_
types) |
223 | 227 |
224 | 228 |
225 # Allow access as idl_type.cpp_type if no arguments | 229 # Allow access as idl_type.cpp_type if no arguments |
226 IdlTypeBase.cpp_type = property(cpp_type) | 230 IdlTypeBase.cpp_type = property(cpp_type) |
227 IdlTypeBase.cpp_type_initializer = property(cpp_type_initializer) | 231 IdlTypeBase.cpp_type_initializer = property(cpp_type_initializer) |
228 IdlTypeBase.cpp_type_args = cpp_type | 232 IdlTypeBase.cpp_type_args = cpp_type |
229 IdlUnionType.cpp_type = property(cpp_type_union) | 233 IdlUnionType.cpp_type = property(cpp_type_union) |
230 IdlUnionType.cpp_type_initializer = property(cpp_type_initializer_union) | 234 IdlUnionType.cpp_type_initializer = property(cpp_type_initializer_union) |
231 IdlUnionType.cpp_type_args = cpp_type_union | 235 IdlUnionType.cpp_type_args = cpp_type_union |
232 | 236 |
233 | 237 |
234 IdlTypeBase.native_array_element_type = None | |
235 IdlArrayOrSequenceType.native_array_element_type = property( | 238 IdlArrayOrSequenceType.native_array_element_type = property( |
236 lambda self: self.element_type) | 239 lambda self: self.element_type) |
237 | 240 |
238 | 241 |
239 def cpp_template_type(template, inner_type): | 242 def cpp_template_type(template, inner_type): |
240 """Returns C++ template specialized to type, with space added if needed.""" | 243 """Returns C++ template specialized to type, with space added if needed.""" |
241 if inner_type.endswith('>'): | 244 if inner_type.endswith('>'): |
242 format_string = '{template}<{inner_type} >' | 245 format_string = '{template}<{inner_type} >' |
243 else: | 246 else: |
244 format_string = '{template}<{inner_type}>' | 247 format_string = '{template}<{inner_type}>' |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
280 IdlType.implemented_as = property(implemented_as) | 283 IdlType.implemented_as = property(implemented_as) |
281 | 284 |
282 IdlType.set_implemented_as_interfaces = classmethod( | 285 IdlType.set_implemented_as_interfaces = classmethod( |
283 lambda cls, new_implemented_as_interfaces: | 286 lambda cls, new_implemented_as_interfaces: |
284 cls.implemented_as_interfaces.update(new_implemented_as_interfaces)) | 287 cls.implemented_as_interfaces.update(new_implemented_as_interfaces)) |
285 | 288 |
286 | 289 |
287 # [GarbageCollected] | 290 # [GarbageCollected] |
288 IdlType.garbage_collected_types = set() | 291 IdlType.garbage_collected_types = set() |
289 | 292 |
290 IdlTypeBase.is_garbage_collected = False | |
291 IdlType.is_garbage_collected = property( | 293 IdlType.is_garbage_collected = property( |
292 lambda self: self.base_type in IdlType.garbage_collected_types) | 294 lambda self: self.base_type in IdlType.garbage_collected_types) |
293 | 295 |
294 IdlType.set_garbage_collected_types = classmethod( | 296 IdlType.set_garbage_collected_types = classmethod( |
295 lambda cls, new_garbage_collected_types: | 297 lambda cls, new_garbage_collected_types: |
296 cls.garbage_collected_types.update(new_garbage_collected_types)) | 298 cls.garbage_collected_types.update(new_garbage_collected_types)) |
297 | 299 |
298 | 300 |
299 # [WillBeGarbageCollected] | 301 # [WillBeGarbageCollected] |
300 IdlType.will_be_garbage_collected_types = set() | 302 IdlType.will_be_garbage_collected_types = set() |
301 | 303 |
302 IdlTypeBase.is_will_be_garbage_collected = False | |
303 IdlType.is_will_be_garbage_collected = property( | 304 IdlType.is_will_be_garbage_collected = property( |
304 lambda self: self.base_type in IdlType.will_be_garbage_collected_types) | 305 lambda self: self.base_type in IdlType.will_be_garbage_collected_types) |
305 | 306 |
306 IdlType.set_will_be_garbage_collected_types = classmethod( | 307 IdlType.set_will_be_garbage_collected_types = classmethod( |
307 lambda cls, new_will_be_garbage_collected_types: | 308 lambda cls, new_will_be_garbage_collected_types: |
308 cls.will_be_garbage_collected_types.update(new_will_be_garbage_collected
_types)) | 309 cls.will_be_garbage_collected_types.update(new_will_be_garbage_collected
_types)) |
309 | 310 |
310 | 311 |
311 def gc_type(idl_type): | 312 def gc_type(idl_type): |
312 if idl_type.is_garbage_collected: | 313 if idl_type.is_garbage_collected: |
313 return 'GarbageCollectedObject' | 314 return 'GarbageCollectedObject' |
314 if idl_type.is_will_be_garbage_collected: | 315 if idl_type.is_will_be_garbage_collected: |
315 return 'WillBeGarbageCollectedObject' | 316 return 'WillBeGarbageCollectedObject' |
316 return 'RefCountedObject' | 317 return 'RefCountedObject' |
317 | 318 |
318 IdlTypeBase.gc_type = property(gc_type) | 319 IdlTypeBase.gc_type = property(gc_type) |
319 | 320 |
320 | 321 |
321 ################################################################################ | 322 ################################################################################ |
322 # Includes | 323 # Includes |
323 ################################################################################ | 324 ################################################################################ |
324 | 325 |
325 def includes_for_cpp_class(class_name, relative_dir_posix): | 326 def includes_for_cpp_class(class_name, relative_dir_posix): |
326 return set([posixpath.join('bindings', relative_dir_posix, class_name + '.h'
)]) | 327 return set([posixpath.join('bindings', relative_dir_posix, class_name + '.h'
)]) |
327 | 328 |
328 | 329 |
329 INCLUDES_FOR_TYPE = { | 330 INCLUDES_FOR_TYPE = { |
330 'object': set(), | 331 'object': set(), |
331 'CompareHow': set(), | |
332 'Dictionary': set(['bindings/core/v8/Dictionary.h']), | 332 'Dictionary': set(['bindings/core/v8/Dictionary.h']), |
333 'EventHandler': set(['bindings/core/v8/V8AbstractEventListener.h', | 333 'EventHandler': set(['bindings/core/v8/V8AbstractEventListener.h', |
334 'bindings/core/v8/V8EventListenerList.h']), | 334 'bindings/core/v8/V8EventListenerList.h']), |
335 'EventListener': set(['bindings/common/BindingSecurity.h', | 335 'EventListener': set(['bindings/common/BindingSecurity.h', |
336 'bindings/core/v8/V8EventListenerList.h', | 336 'bindings/core/v8/V8EventListenerList.h', |
337 'core/frame/LocalDOMWindow.h']), | 337 'core/frame/LocalDOMWindow.h']), |
338 'HTMLCollection': set(['bindings/core/v8/V8HTMLCollection.h', | 338 'HTMLCollection': set(['bindings/core/v8/V8HTMLCollection.h', |
339 'core/dom/ClassCollection.h', | 339 'core/dom/ClassCollection.h', |
340 'core/dom/TagCollection.h', | 340 'core/dom/TagCollection.h', |
341 'core/html/HTMLCollection.h', | 341 'core/html/HTMLCollection.h', |
| 342 'core/html/HTMLDataListOptionsCollection.h', |
342 'core/html/HTMLFormControlsCollection.h', | 343 'core/html/HTMLFormControlsCollection.h', |
343 'core/html/HTMLTableRowsCollection.h']), | 344 'core/html/HTMLTableRowsCollection.h']), |
344 'MediaQueryListListener': set(['core/css/MediaQueryListListener.h']), | |
345 'NodeList': set(['bindings/core/v8/V8NodeList.h', | 345 'NodeList': set(['bindings/core/v8/V8NodeList.h', |
346 'core/dom/NameNodeList.h', | 346 'core/dom/NameNodeList.h', |
347 'core/dom/NodeList.h', | 347 'core/dom/NodeList.h', |
348 'core/dom/StaticNodeList.h', | 348 'core/dom/StaticNodeList.h', |
349 'core/html/LabelsNodeList.h']), | 349 'core/html/LabelsNodeList.h']), |
350 'Promise': set(['bindings/core/v8/V8ScriptPromise.h']), | 350 'Promise': set(['bindings/core/v8/V8ScriptPromise.h']), |
351 'SerializedScriptValue': set(['bindings/core/v8/SerializedScriptValue.h']), | 351 'SerializedScriptValue': set(['bindings/core/v8/SerializedScriptValue.h']), |
352 'ScriptValue': set(['bindings/common/ScriptValue.h']), | 352 'ScriptValue': set(['bindings/common/ScriptValue.h']), |
353 } | 353 } |
354 | 354 |
(...skipping 19 matching lines...) Expand all Loading... |
374 if base_idl_type.endswith('Constructor'): | 374 if base_idl_type.endswith('Constructor'): |
375 # FIXME: replace with a [ConstructorAttribute] extended attribute | 375 # FIXME: replace with a [ConstructorAttribute] extended attribute |
376 base_idl_type = idl_type.constructor_type_name | 376 base_idl_type = idl_type.constructor_type_name |
377 if base_idl_type not in component_dir: | 377 if base_idl_type not in component_dir: |
378 return set() | 378 return set() |
379 return set(['bindings/%s/v8/V8%s.h' % (component_dir[base_idl_type], | 379 return set(['bindings/%s/v8/V8%s.h' % (component_dir[base_idl_type], |
380 base_idl_type)]) | 380 base_idl_type)]) |
381 | 381 |
382 IdlType.includes_for_type = property(includes_for_type) | 382 IdlType.includes_for_type = property(includes_for_type) |
383 IdlUnionType.includes_for_type = property( | 383 IdlUnionType.includes_for_type = property( |
384 lambda self: set.union(*[includes_for_type(member_type) | 384 lambda self: set.union(*[member_type.includes_for_type |
385 for member_type in self.member_types])) | 385 for member_type in self.member_types])) |
386 IdlArrayOrSequenceType.includes_for_type = property( | 386 IdlArrayOrSequenceType.includes_for_type = property( |
387 lambda self: self.element_type.includes_for_type) | 387 lambda self: self.element_type.includes_for_type) |
388 | 388 |
389 | 389 |
390 def add_includes_for_type(idl_type): | 390 def add_includes_for_type(idl_type): |
391 includes.update(idl_type.includes_for_type) | 391 includes.update(idl_type.includes_for_type) |
392 | 392 |
393 IdlTypeBase.add_includes_for_type = add_includes_for_type | 393 IdlTypeBase.add_includes_for_type = add_includes_for_type |
394 | 394 |
(...skipping 18 matching lines...) Expand all Loading... |
413 if idl_type.impl_should_use_nullable_container: | 413 if idl_type.impl_should_use_nullable_container: |
414 includes_for_type.add('bindings/common/Nullable.h') | 414 includes_for_type.add('bindings/common/Nullable.h') |
415 | 415 |
416 idl_type = idl_type.preprocessed_type | 416 idl_type = idl_type.preprocessed_type |
417 native_array_element_type = idl_type.native_array_element_type | 417 native_array_element_type = idl_type.native_array_element_type |
418 if native_array_element_type: | 418 if native_array_element_type: |
419 includes_for_type.update(impl_includes_for_type( | 419 includes_for_type.update(impl_includes_for_type( |
420 native_array_element_type, interfaces_info)) | 420 native_array_element_type, interfaces_info)) |
421 includes_for_type.add('wtf/Vector.h') | 421 includes_for_type.add('wtf/Vector.h') |
422 | 422 |
| 423 base_idl_type = idl_type.base_type |
423 if idl_type.is_string_type: | 424 if idl_type.is_string_type: |
424 includes_for_type.add('wtf/text/WTFString.h') | 425 includes_for_type.add('wtf/text/WTFString.h') |
425 if idl_type.name in interfaces_info: | 426 if base_idl_type in interfaces_info: |
426 interface_info = interfaces_info[idl_type.name] | 427 interface_info = interfaces_info[idl_type.base_type] |
427 includes_for_type.add(interface_info['include_path']) | 428 includes_for_type.add(interface_info['include_path']) |
| 429 if base_idl_type in INCLUDES_FOR_TYPE: |
| 430 includes_for_type.update(INCLUDES_FOR_TYPE[base_idl_type]) |
428 return includes_for_type | 431 return includes_for_type |
429 | 432 |
430 IdlTypeBase.impl_includes_for_type = impl_includes_for_type | 433 IdlTypeBase.impl_includes_for_type = impl_includes_for_type |
431 | 434 |
432 | 435 |
433 component_dir = {} | 436 component_dir = {} |
434 | 437 |
435 | 438 |
436 def set_component_dirs(new_component_dirs): | 439 def set_component_dirs(new_component_dirs): |
437 component_dir.update(new_component_dirs) | 440 component_dir.update(new_component_dirs) |
438 | 441 |
439 | 442 |
440 ################################################################################ | 443 ################################################################################ |
441 # V8 -> C++ | 444 # V8 -> C++ |
442 ################################################################################ | 445 ################################################################################ |
443 | 446 |
444 V8_VALUE_TO_CPP_VALUE = { | 447 V8_VALUE_TO_CPP_VALUE = { |
445 # Basic | 448 # Basic |
446 'Date': 'toCoreDate({v8_value})', | 449 'Date': 'toCoreDate({v8_value})', |
447 'DOMString': '{v8_value}', | 450 'DOMString': '{v8_value}', |
448 'ByteString': 'toByteString({arguments})', | 451 'ByteString': 'toByteString({arguments})', |
449 'ScalarValueString': 'toScalarValueString({arguments})', | 452 'ScalarValueString': 'toScalarValueString({arguments})', |
450 'boolean': '{v8_value}->BooleanValue()', | 453 'boolean': '{v8_value}->BooleanValue()', |
451 'float': 'static_cast<float>({v8_value}->NumberValue())', | 454 'float': 'toFloat({arguments})', |
452 'unrestricted float': 'static_cast<float>({v8_value}->NumberValue())', | 455 'unrestricted float': 'toFloat({arguments})', |
453 'double': 'static_cast<double>({v8_value}->NumberValue())', | 456 'double': 'toDouble({arguments})', |
454 'unrestricted double': 'static_cast<double>({v8_value}->NumberValue())', | 457 'unrestricted double': 'toDouble({arguments})', |
455 'byte': 'toInt8({arguments})', | 458 'byte': 'toInt8({arguments})', |
456 'octet': 'toUInt8({arguments})', | 459 'octet': 'toUInt8({arguments})', |
457 'short': 'toInt16({arguments})', | 460 'short': 'toInt16({arguments})', |
458 'unsigned short': 'toUInt16({arguments})', | 461 'unsigned short': 'toUInt16({arguments})', |
459 'long': 'toInt32({arguments})', | 462 'long': 'toInt32({arguments})', |
460 'unsigned long': 'toUInt32({arguments})', | 463 'unsigned long': 'toUInt32({arguments})', |
461 'long long': 'toInt64({arguments})', | 464 'long long': 'toInt64({arguments})', |
462 'unsigned long long': 'toUInt64({arguments})', | 465 'unsigned long long': 'toUInt64({arguments})', |
463 # Interface types | 466 # Interface types |
464 'CompareHow': 'static_cast<Range::CompareHow>({v8_value}->Int32Value())', | |
465 'Dictionary': 'Dictionary({v8_value}, {isolate})', | 467 'Dictionary': 'Dictionary({v8_value}, {isolate})', |
466 'EventTarget': 'V8DOMWrapper::isDOMWrapper({v8_value}) ? toWrapperTypeInfo(v
8::Handle<v8::Object>::Cast({v8_value}))->toEventTarget(v8::Handle<v8::Object>::
Cast({v8_value})) : 0', | 468 'EventTarget': 'V8DOMWrapper::isDOMWrapper({v8_value}) ? toWrapperTypeInfo(v
8::Handle<v8::Object>::Cast({v8_value}))->toEventTarget(v8::Handle<v8::Object>::
Cast({v8_value})) : 0', |
467 'MediaQueryListListener': 'MediaQueryListListener::create(V8ScriptState::cur
rent({isolate}), ScriptValue(V8ScriptState::current({isolate}), {v8_value}))', | |
468 'NodeFilter': 'toNodeFilter({v8_value}, info.Holder(), V8ScriptState::curren
t({isolate}))', | 469 'NodeFilter': 'toNodeFilter({v8_value}, info.Holder(), V8ScriptState::curren
t({isolate}))', |
469 'Promise': 'V8ScriptPromise::cast(V8ScriptState::current({isolate}), {v8_val
ue})', | 470 'Promise': 'V8ScriptPromise::cast(V8ScriptState::current({isolate}), {v8_val
ue})', |
470 'SerializedScriptValue': 'SerializedScriptValue::create({v8_value}, {isolate
})', | 471 'SerializedScriptValue': 'SerializedScriptValue::create({v8_value}, 0, 0, ex
ceptionState, {isolate})', |
471 'ScriptValue': 'ScriptValue(V8ScriptState::current({isolate}), {v8_value})', | 472 'ScriptValue': 'ScriptValue(V8ScriptState::current({isolate}), {v8_value})', |
472 'Window': 'toDOMWindow({v8_value}, {isolate})', | 473 'Window': 'toDOMWindow({v8_value}, {isolate})', |
473 'XPathNSResolver': 'toXPathNSResolver({v8_value}, {isolate})', | 474 'XPathNSResolver': 'toXPathNSResolver({v8_value}, {isolate})', |
474 } | 475 } |
475 | 476 |
476 | 477 |
| 478 def v8_conversion_needs_exception_state(idl_type): |
| 479 return (idl_type.is_numeric_type or |
| 480 idl_type.is_dictionary or |
| 481 idl_type.name in ('ByteString', 'ScalarValueString', 'SerializedScri
ptValue')) |
| 482 |
| 483 IdlType.v8_conversion_needs_exception_state = property(v8_conversion_needs_excep
tion_state) |
| 484 IdlArrayOrSequenceType.v8_conversion_needs_exception_state = True |
| 485 |
| 486 |
| 487 TRIVIAL_CONVERSIONS = frozenset([ |
| 488 'any', |
| 489 'boolean', |
| 490 'Date', |
| 491 'Dictionary', |
| 492 'NodeFilter', |
| 493 'XPathNSResolver', |
| 494 'Promise' |
| 495 ]) |
| 496 |
| 497 |
| 498 def v8_conversion_is_trivial(idl_type): |
| 499 # The conversion is a simple expression that returns the converted value and |
| 500 # cannot raise an exception. |
| 501 return (idl_type.base_type in TRIVIAL_CONVERSIONS or |
| 502 idl_type.is_wrapper_type) |
| 503 |
| 504 IdlType.v8_conversion_is_trivial = property(v8_conversion_is_trivial) |
| 505 |
| 506 |
477 def v8_value_to_cpp_value(idl_type, extended_attributes, v8_value, index, isolat
e): | 507 def v8_value_to_cpp_value(idl_type, extended_attributes, v8_value, index, isolat
e): |
478 if idl_type.name == 'void': | 508 if idl_type.name == 'void': |
479 return '' | 509 return '' |
480 | 510 |
481 # Array or sequence types | 511 # Array or sequence types |
482 native_array_element_type = idl_type.native_array_element_type | 512 native_array_element_type = idl_type.native_array_element_type |
483 if native_array_element_type: | 513 if native_array_element_type: |
484 return v8_value_to_cpp_value_array_or_sequence(native_array_element_type
, v8_value, index) | 514 return v8_value_to_cpp_value_array_or_sequence(native_array_element_type
, v8_value, index) |
485 | 515 |
486 # Simple types | 516 # Simple types |
487 idl_type = idl_type.preprocessed_type | 517 idl_type = idl_type.preprocessed_type |
488 add_includes_for_type(idl_type) | 518 add_includes_for_type(idl_type) |
489 base_idl_type = idl_type.base_type | 519 base_idl_type = idl_type.base_type |
490 | 520 |
491 if 'EnforceRange' in extended_attributes: | 521 if 'EnforceRange' in extended_attributes: |
492 arguments = ', '.join([v8_value, 'EnforceRange', 'exceptionState']) | 522 arguments = ', '.join([v8_value, 'EnforceRange', 'exceptionState']) |
493 elif idl_type.may_raise_exception_on_conversion: | 523 elif 'Clamp' in extended_attributes: |
| 524 arguments = ', '.join([v8_value, 'Clamp', 'exceptionState']) |
| 525 elif idl_type.v8_conversion_needs_exception_state: |
494 arguments = ', '.join([v8_value, 'exceptionState']) | 526 arguments = ', '.join([v8_value, 'exceptionState']) |
495 else: | 527 else: |
496 arguments = v8_value | 528 arguments = v8_value |
497 | 529 |
498 if base_idl_type in V8_VALUE_TO_CPP_VALUE: | 530 if base_idl_type in V8_VALUE_TO_CPP_VALUE: |
499 cpp_expression_format = V8_VALUE_TO_CPP_VALUE[base_idl_type] | 531 cpp_expression_format = V8_VALUE_TO_CPP_VALUE[base_idl_type] |
500 elif idl_type.is_typed_array_element_type: | 532 elif idl_type.is_typed_array_element_type: |
501 cpp_expression_format = ( | 533 cpp_expression_format = ( |
502 '{v8_value}->Is{idl_type}() ? ' | 534 '{v8_value}->Is{idl_type}() ? ' |
503 'V8{idl_type}::toNative(v8::Handle<v8::{idl_type}>::Cast({v8_value})
) : 0') | 535 'V8{idl_type}::toImpl(v8::Handle<v8::{idl_type}>::Cast({v8_value}))
: 0') |
504 elif idl_type.is_dictionary: | 536 elif idl_type.is_dictionary: |
505 cpp_expression_format = 'V8{idl_type}::toNative({isolate}, {v8_value})' | 537 cpp_expression_format = 'V8{idl_type}::toImpl({isolate}, {v8_value}, exc
eptionState)' |
506 else: | 538 else: |
507 cpp_expression_format = ( | 539 cpp_expression_format = ( |
508 'V8{idl_type}::toNativeWithTypeCheck({isolate}, {v8_value})') | 540 'V8{idl_type}::toImplWithTypeCheck({isolate}, {v8_value})') |
509 | 541 |
510 return cpp_expression_format.format(arguments=arguments, idl_type=base_idl_t
ype, v8_value=v8_value, isolate=isolate) | 542 return cpp_expression_format.format(arguments=arguments, idl_type=base_idl_t
ype, v8_value=v8_value, isolate=isolate) |
511 | 543 |
512 | 544 |
513 def v8_value_to_cpp_value_array_or_sequence(native_array_element_type, v8_value,
index, isolate='info.GetIsolate()'): | 545 def v8_value_to_cpp_value_array_or_sequence(native_array_element_type, v8_value,
index, isolate='info.GetIsolate()'): |
514 # Index is None for setters, index (starting at 0) for method arguments, | 546 # Index is None for setters, index (starting at 0) for method arguments, |
515 # and is used to provide a human-readable exception message | 547 # and is used to provide a human-readable exception message |
516 if index is None: | 548 if index is None: |
517 index = 0 # special case, meaning "setter" | 549 index = 0 # special case, meaning "setter" |
518 else: | 550 else: |
519 index += 1 # human-readable index | 551 index += 1 # human-readable index |
520 if (native_array_element_type.is_interface_type and | 552 if (native_array_element_type.is_interface_type and |
521 native_array_element_type.name != 'Dictionary'): | 553 native_array_element_type.name != 'Dictionary'): |
522 this_cpp_type = None | 554 this_cpp_type = None |
523 ref_ptr_type = cpp_ptr_type('RefPtr', 'Member', native_array_element_typ
e.gc_type) | 555 ref_ptr_type = cpp_ptr_type('RefPtr', 'Member', native_array_element_typ
e.gc_type) |
524 expression_format = '(to{ref_ptr_type}NativeArray<{native_array_element_
type}, V8{native_array_element_type}>({v8_value}, {index}, {isolate}))' | 556 expression_format = '(to{ref_ptr_type}NativeArray<{native_array_element_
type}, V8{native_array_element_type}>({v8_value}, {index}, {isolate}, exceptionS
tate))' |
525 add_includes_for_type(native_array_element_type) | 557 add_includes_for_type(native_array_element_type) |
526 else: | 558 else: |
527 ref_ptr_type = None | 559 ref_ptr_type = None |
528 this_cpp_type = native_array_element_type.cpp_type | 560 this_cpp_type = native_array_element_type.cpp_type |
529 expression_format = 'toNativeArray<{cpp_type}>({v8_value}, {index}, {iso
late})' | 561 expression_format = 'toImplArray<{cpp_type}>({v8_value}, {index}, {isola
te}, exceptionState)' |
530 expression = expression_format.format(native_array_element_type=native_array
_element_type.name, cpp_type=this_cpp_type, index=index, ref_ptr_type=ref_ptr_ty
pe, v8_value=v8_value, isolate=isolate) | 562 expression = expression_format.format(native_array_element_type=native_array
_element_type.name, cpp_type=this_cpp_type, index=index, ref_ptr_type=ref_ptr_ty
pe, v8_value=v8_value, isolate=isolate) |
531 return expression | 563 return expression |
532 | 564 |
533 | 565 |
534 def v8_value_to_local_cpp_value(idl_type, extended_attributes, v8_value, variabl
e_name, index=None, declare_variable=True, isolate='info.GetIsolate()', used_in_
private_script=False, return_promise=False): | 566 def v8_value_to_local_cpp_value(idl_type, extended_attributes, v8_value, variabl
e_name, index=None, declare_variable=True, isolate='info.GetIsolate()', used_in_
private_script=False, return_promise=False): |
535 """Returns an expression that converts a V8 value to a C++ value and stores
it as a local value.""" | 567 """Returns an expression that converts a V8 value to a C++ value and stores
it as a local value.""" |
536 | 568 |
537 # FIXME: Support union type. | 569 # FIXME: Support union type. |
538 if idl_type.is_union_type: | 570 if idl_type.is_union_type: |
539 return '' | 571 return '/* no V8 -> C++ conversion for IDL union type: %s */' % idl_type
.name |
540 | 572 |
541 this_cpp_type = idl_type.cpp_type_args(extended_attributes=extended_attribut
es, raw_type=True) | 573 this_cpp_type = idl_type.cpp_type_args(extended_attributes=extended_attribut
es, raw_type=True) |
| 574 idl_type = idl_type.preprocessed_type |
542 | 575 |
543 idl_type = idl_type.preprocessed_type | 576 if idl_type.base_type in ('void', 'object', 'EventHandler', 'EventListener')
: |
| 577 return '/* no V8 -> C++ conversion for IDL type: %s */' % idl_type.name |
| 578 |
544 cpp_value = v8_value_to_cpp_value(idl_type, extended_attributes, v8_value, i
ndex, isolate) | 579 cpp_value = v8_value_to_cpp_value(idl_type, extended_attributes, v8_value, i
ndex, isolate) |
545 args = [variable_name, cpp_value] | 580 if idl_type.is_string_type or idl_type.v8_conversion_needs_exception_state: |
546 if idl_type.base_type == 'DOMString': | 581 # Types that need error handling and use one of a group of (C++) macros |
547 macro = 'TOSTRING_DEFAULT' if used_in_private_script else 'TOSTRING_VOID
' | 582 # to take care of this. |
548 elif idl_type.may_raise_exception_on_conversion: | |
549 macro = 'TONATIVE_DEFAULT_EXCEPTIONSTATE' if used_in_private_script else
'TONATIVE_VOID_EXCEPTIONSTATE' | |
550 args.append('exceptionState') | |
551 else: | |
552 macro = 'TONATIVE_DEFAULT' if used_in_private_script else 'TONATIVE_VOID
' | |
553 | 583 |
554 if used_in_private_script: | 584 args = [variable_name, cpp_value] |
555 args.append('false') | |
556 | 585 |
557 # Macros come in several variants, to minimize expensive creation of | 586 if idl_type.v8_conversion_needs_exception_state: |
558 # v8::TryCatch. | 587 macro = 'TONATIVE_DEFAULT_EXCEPTIONSTATE' if used_in_private_script
else 'TONATIVE_VOID_EXCEPTIONSTATE' |
559 suffix = '' | 588 elif return_promise: |
| 589 macro = 'TOSTRING_VOID_EXCEPTIONSTATE' |
| 590 else: |
| 591 macro = 'TOSTRING_DEFAULT' if used_in_private_script else 'TOSTRING_
VOID' |
560 | 592 |
561 if return_promise: | 593 if macro.endswith('_EXCEPTIONSTATE'): |
562 suffix += '_PROMISE' | 594 args.append('exceptionState') |
563 args.append('info') | |
564 if macro == 'TONATIVE_VOID_EXCEPTIONSTATE': | |
565 args.append('V8ScriptState::current(%s)' % isolate) | |
566 | 595 |
| 596 if used_in_private_script: |
| 597 args.append('false') |
| 598 |
| 599 suffix = '' |
| 600 |
| 601 if return_promise: |
| 602 suffix += '_PROMISE' |
| 603 args.append('info') |
| 604 if macro.endswith('_EXCEPTIONSTATE'): |
| 605 args.append('V8ScriptState::current(%s)' % isolate) |
| 606 |
| 607 if declare_variable: |
| 608 args.insert(0, this_cpp_type) |
| 609 else: |
| 610 suffix += '_INTERNAL' |
| 611 |
| 612 return '%s(%s)' % (macro + suffix, ', '.join(args)) |
| 613 |
| 614 # Types that don't need error handling, and simply assign a value to the |
| 615 # local variable. |
| 616 |
| 617 if not idl_type.v8_conversion_is_trivial: |
| 618 raise Exception('unclassified V8 -> C++ conversion for IDL type: %s' % i
dl_type.name) |
| 619 |
| 620 assignment = '%s = %s' % (variable_name, cpp_value) |
567 if declare_variable: | 621 if declare_variable: |
568 args.insert(0, this_cpp_type) | 622 return '%s %s' % (this_cpp_type, assignment) |
569 else: | 623 return assignment |
570 suffix += '_INTERNAL' | |
571 | 624 |
572 return '%s(%s)' % (macro + suffix, ', '.join(args)) | |
573 | 625 |
574 IdlTypeBase.v8_value_to_local_cpp_value = v8_value_to_local_cpp_value | 626 IdlTypeBase.v8_value_to_local_cpp_value = v8_value_to_local_cpp_value |
575 | 627 |
576 | 628 |
577 ################################################################################ | 629 ################################################################################ |
578 # C++ -> V8 | 630 # C++ -> V8 |
579 ################################################################################ | 631 ################################################################################ |
580 | 632 |
581 def preprocess_idl_type(idl_type): | 633 def preprocess_idl_type(idl_type): |
582 if idl_type.is_enum: | 634 if idl_type.is_enum: |
583 # Enumerations are internally DOMStrings | 635 # Enumerations are internally DOMStrings |
584 return IdlType('DOMString') | 636 return IdlType('DOMString') |
585 if (idl_type.name == 'Any' or idl_type.is_callback_function): | 637 if (idl_type.name in ['Any', 'Object'] or idl_type.is_callback_function): |
586 return IdlType('ScriptValue') | 638 return IdlType('ScriptValue') |
587 return idl_type | 639 return idl_type |
588 | 640 |
589 IdlTypeBase.preprocessed_type = property(preprocess_idl_type) | 641 IdlTypeBase.preprocessed_type = property(preprocess_idl_type) |
590 | 642 |
591 | 643 |
592 def preprocess_idl_type_and_value(idl_type, cpp_value, extended_attributes): | 644 def preprocess_idl_type_and_value(idl_type, cpp_value, extended_attributes): |
593 """Returns IDL type and value, with preliminary type conversions applied.""" | 645 """Returns IDL type and value, with preliminary type conversions applied.""" |
594 idl_type = idl_type.preprocessed_type | 646 idl_type = idl_type.preprocessed_type |
595 if idl_type.name == 'Promise': | 647 if idl_type.name == 'Promise': |
596 idl_type = IdlType('ScriptValue') | 648 idl_type = IdlType('ScriptValue') |
597 if idl_type.base_type in ['long long', 'unsigned long long']: | 649 if idl_type.base_type in ['long long', 'unsigned long long']: |
598 # long long and unsigned long long are not representable in ECMAScript; | 650 # long long and unsigned long long are not representable in ECMAScript; |
599 # we represent them as doubles. | 651 # we represent them as doubles. |
600 idl_type = IdlType('double', is_nullable=idl_type.is_nullable) | 652 is_nullable = idl_type.is_nullable |
| 653 idl_type = IdlType('double') |
| 654 if is_nullable: |
| 655 idl_type = IdlNullableType(idl_type) |
601 cpp_value = 'static_cast<double>(%s)' % cpp_value | 656 cpp_value = 'static_cast<double>(%s)' % cpp_value |
602 # HTML5 says that unsigned reflected attributes should be in the range | 657 # HTML5 says that unsigned reflected attributes should be in the range |
603 # [0, 2^31). When a value isn't in this range, a default value (or 0) | 658 # [0, 2^31). When a value isn't in this range, a default value (or 0) |
604 # should be returned instead. | 659 # should be returned instead. |
605 extended_attributes = extended_attributes or {} | 660 extended_attributes = extended_attributes or {} |
606 if ('Reflect' in extended_attributes and | 661 if ('Reflect' in extended_attributes and |
607 idl_type.base_type in ['unsigned long', 'unsigned short']): | 662 idl_type.base_type in ['unsigned long', 'unsigned short']): |
608 cpp_value = cpp_value.replace('getUnsignedIntegralAttribute', | 663 cpp_value = cpp_value.replace('getUnsignedIntegralAttribute', |
609 'getIntegralAttribute') | 664 'getIntegralAttribute') |
610 cpp_value = 'std::max(0, static_cast<int>(%s))' % cpp_value | 665 cpp_value = 'std::max(0, static_cast<int>(%s))' % cpp_value |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
727 return None | 782 return None |
728 | 783 |
729 | 784 |
730 IdlTypeBase.v8_set_return_value = v8_set_return_value | 785 IdlTypeBase.v8_set_return_value = v8_set_return_value |
731 IdlUnionType.v8_set_return_value = v8_set_return_value_union | 786 IdlUnionType.v8_set_return_value = v8_set_return_value_union |
732 | 787 |
733 IdlType.release = property(lambda self: self.is_interface_type) | 788 IdlType.release = property(lambda self: self.is_interface_type) |
734 IdlUnionType.release = property( | 789 IdlUnionType.release = property( |
735 lambda self: [member_type.is_interface_type | 790 lambda self: [member_type.is_interface_type |
736 for member_type in self.member_types]) | 791 for member_type in self.member_types]) |
737 IdlArrayOrSequenceType.release = False | |
738 | 792 |
739 | 793 |
740 CPP_VALUE_TO_V8_VALUE = { | 794 CPP_VALUE_TO_V8_VALUE = { |
741 # Built-in types | 795 # Built-in types |
742 'Date': 'v8DateOrNaN({cpp_value}, {isolate})', | 796 'Date': 'v8DateOrNaN({cpp_value}, {isolate})', |
743 'DOMString': 'v8String({isolate}, {cpp_value})', | 797 'DOMString': 'v8String({isolate}, {cpp_value})', |
744 'ByteString': 'v8String({isolate}, {cpp_value})', | 798 'ByteString': 'v8String({isolate}, {cpp_value})', |
745 'ScalarValueString': 'v8String({isolate}, {cpp_value})', | 799 'ScalarValueString': 'v8String({isolate}, {cpp_value})', |
746 'boolean': 'v8Boolean({cpp_value}, {isolate})', | 800 'boolean': 'v8Boolean({cpp_value}, {isolate})', |
747 'int': 'v8::Integer::New({isolate}, {cpp_value})', | 801 'int': 'v8::Integer::New({isolate}, {cpp_value})', |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
788 | 842 |
789 | 843 |
790 ################################################################################ | 844 ################################################################################ |
791 # Utility properties for nullable types | 845 # Utility properties for nullable types |
792 ################################################################################ | 846 ################################################################################ |
793 | 847 |
794 | 848 |
795 def cpp_type_has_null_value(idl_type): | 849 def cpp_type_has_null_value(idl_type): |
796 # - String types (String/AtomicString) represent null as a null string, | 850 # - String types (String/AtomicString) represent null as a null string, |
797 # i.e. one for which String::isNull() returns true. | 851 # i.e. one for which String::isNull() returns true. |
| 852 # - Enum types, as they are implemented as Strings. |
798 # - Wrapper types (raw pointer or RefPtr/PassRefPtr) represent null as | 853 # - Wrapper types (raw pointer or RefPtr/PassRefPtr) represent null as |
799 # a null pointer. | 854 # a null pointer. |
800 return idl_type.is_string_type or idl_type.is_wrapper_type | 855 # - Dictionary types represent null as a null pointer. They are garbage |
| 856 # collected so their type is raw pointer. |
| 857 # - 'Object' type. We use ScriptValue for object type. |
| 858 return (idl_type.is_string_type or idl_type.is_wrapper_type or |
| 859 idl_type.is_enum or idl_type.is_dictionary or idl_type.base_type ==
'object') |
801 | 860 |
802 IdlTypeBase.cpp_type_has_null_value = property(cpp_type_has_null_value) | 861 IdlTypeBase.cpp_type_has_null_value = property(cpp_type_has_null_value) |
803 | 862 |
804 | 863 |
805 def is_implicit_nullable(idl_type): | 864 def is_implicit_nullable(idl_type): |
806 # Nullable type where the corresponding C++ type supports a null value. | 865 # Nullable type where the corresponding C++ type supports a null value. |
807 return idl_type.is_nullable and idl_type.cpp_type_has_null_value | 866 return idl_type.is_nullable and idl_type.cpp_type_has_null_value |
808 | 867 |
809 | 868 |
810 def is_explicit_nullable(idl_type): | 869 def is_explicit_nullable(idl_type): |
811 # Nullable type that isn't implicit nullable (see above.) For such types, | 870 # Nullable type that isn't implicit nullable (see above.) For such types, |
812 # we use Nullable<T> or similar explicit ways to represent a null value. | 871 # we use Nullable<T> or similar explicit ways to represent a null value. |
813 return idl_type.is_nullable and not idl_type.is_implicit_nullable | 872 return idl_type.is_nullable and not idl_type.is_implicit_nullable |
814 | 873 |
815 IdlTypeBase.is_implicit_nullable = property(is_implicit_nullable) | 874 IdlTypeBase.is_implicit_nullable = property(is_implicit_nullable) |
816 IdlUnionType.is_implicit_nullable = False | 875 IdlUnionType.is_implicit_nullable = False |
817 IdlTypeBase.is_explicit_nullable = property(is_explicit_nullable) | 876 IdlTypeBase.is_explicit_nullable = property(is_explicit_nullable) |
OLD | NEW |