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 17 matching lines...) Expand all Loading... |
28 | 28 |
29 """Functions shared by various parts of the code generator. | 29 """Functions shared by various parts of the code generator. |
30 | 30 |
31 Design doc: http://www.chromium.org/developers/design-documents/idl-compiler | 31 Design doc: http://www.chromium.org/developers/design-documents/idl-compiler |
32 """ | 32 """ |
33 | 33 |
34 import re | 34 import re |
35 | 35 |
36 from idl_types import IdlTypeBase | 36 from idl_types import IdlTypeBase |
37 import idl_types | 37 import idl_types |
38 from idl_definitions import Exposure, IdlInterface | 38 from idl_definitions import Exposure, IdlInterface, IdlAttribute |
39 from v8_globals import includes | 39 from v8_globals import includes |
40 | 40 |
41 ACRONYMS = [ | 41 ACRONYMS = [ |
42 'CSSOM', # must come *before* CSS to match full acronym | 42 'CSSOM', # must come *before* CSS to match full acronym |
43 'CSS', | 43 'CSS', |
44 'HTML', | 44 'HTML', |
45 'IME', | 45 'IME', |
46 'JS', | 46 'JS', |
47 'SVG', | 47 'SVG', |
48 'URL', | 48 'URL', |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 | 118 |
119 def scoped_name(interface, definition, base_name): | 119 def scoped_name(interface, definition, base_name): |
120 if 'ImplementedInPrivateScript' in definition.extended_attributes: | 120 if 'ImplementedInPrivateScript' in definition.extended_attributes: |
121 return '%s::PrivateScript::%s' % (v8_class_name(interface), base_name) | 121 return '%s::PrivateScript::%s' % (v8_class_name(interface), base_name) |
122 # partial interfaces are implemented as separate classes, with their members | 122 # partial interfaces are implemented as separate classes, with their members |
123 # implemented as static member functions | 123 # implemented as static member functions |
124 partial_interface_implemented_as = definition.extended_attributes.get('Parti
alInterfaceImplementedAs') | 124 partial_interface_implemented_as = definition.extended_attributes.get('Parti
alInterfaceImplementedAs') |
125 if partial_interface_implemented_as: | 125 if partial_interface_implemented_as: |
126 return '%s::%s' % (partial_interface_implemented_as, base_name) | 126 return '%s::%s' % (partial_interface_implemented_as, base_name) |
127 if (definition.is_static or | 127 if (definition.is_static or |
128 definition.name in ('Constructor', 'NamedConstructor')): | 128 definition.name in ('Constructor', 'NamedConstructor')): |
129 return '%s::%s' % (cpp_name(interface), base_name) | 129 return '%s::%s' % (cpp_name(interface), base_name) |
130 return 'impl->%s' % base_name | 130 return 'impl->%s' % base_name |
131 | 131 |
132 | 132 |
133 def v8_class_name(interface): | 133 def v8_class_name(interface): |
134 return 'V8' + interface.name | 134 return 'V8' + interface.name |
135 | 135 |
136 | 136 |
137 def v8_class_name_or_partial(interface): | 137 def v8_class_name_or_partial(interface): |
138 class_name = v8_class_name(interface) | 138 class_name = v8_class_name(interface) |
(...skipping 30 matching lines...) Expand all Loading... |
169 """Returns if an isolated world check is required when generating activity | 169 """Returns if an isolated world check is required when generating activity |
170 logging code. | 170 logging code. |
171 | 171 |
172 The check is required when there is no per-world binding code and logging is | 172 The check is required when there is no per-world binding code and logging is |
173 required only for isolated world. | 173 required only for isolated world. |
174 """ | 174 """ |
175 extended_attributes = member.extended_attributes | 175 extended_attributes = member.extended_attributes |
176 if 'LogActivity' not in extended_attributes: | 176 if 'LogActivity' not in extended_attributes: |
177 return False | 177 return False |
178 if ('PerWorldBindings' not in extended_attributes and | 178 if ('PerWorldBindings' not in extended_attributes and |
179 'LogAllWorlds' not in extended_attributes): | 179 'LogAllWorlds' not in extended_attributes): |
180 return True | 180 return True |
181 return False | 181 return False |
182 | 182 |
183 | 183 |
184 # [CallWith] | 184 # [CallWith] |
185 CALL_WITH_ARGUMENTS = { | 185 CALL_WITH_ARGUMENTS = { |
186 'ScriptState': 'scriptState', | 186 'ScriptState': 'scriptState', |
187 'ExecutionContext': 'executionContext', | 187 'ExecutionContext': 'executionContext', |
188 'ScriptArguments': 'scriptArguments.release()', | 188 'ScriptArguments': 'scriptArguments.release()', |
189 'ActiveWindow': 'callingDOMWindow(info.GetIsolate())', | 189 'ActiveWindow': 'currentDOMWindow(info.GetIsolate())', |
190 'FirstWindow': 'enteredDOMWindow(info.GetIsolate())', | 190 'FirstWindow': 'enteredDOMWindow(info.GetIsolate())', |
191 'Document': 'document', | 191 'Document': 'document', |
192 'ThisValue': 'ScriptValue(scriptState, info.This())', | 192 'ThisValue': 'ScriptValue(scriptState, info.This())', |
193 } | 193 } |
194 # List because key order matters, as we want arguments in deterministic order | 194 # List because key order matters, as we want arguments in deterministic order |
195 CALL_WITH_VALUES = [ | 195 CALL_WITH_VALUES = [ |
196 'ScriptState', | 196 'ScriptState', |
197 'ExecutionContext', | 197 'ExecutionContext', |
198 'ScriptArguments', | 198 'ScriptArguments', |
199 'ActiveWindow', | 199 'ActiveWindow', |
200 'FirstWindow', | 200 'FirstWindow', |
201 'Document', | 201 'Document', |
202 'ThisValue', | 202 'ThisValue', |
203 ] | 203 ] |
204 | 204 |
205 | 205 |
206 def call_with_arguments(call_with_values): | 206 def call_with_arguments(call_with_values): |
207 if not call_with_values: | 207 if not call_with_values: |
208 return [] | 208 return [] |
209 return [CALL_WITH_ARGUMENTS[value] | 209 return [CALL_WITH_ARGUMENTS[value] |
210 for value in CALL_WITH_VALUES | 210 for value in CALL_WITH_VALUES |
211 if extended_attribute_value_contains(call_with_values, value)] | 211 if extended_attribute_value_contains(call_with_values, value)] |
212 | 212 |
213 | 213 |
214 # [Conditional] | |
215 DELIMITER_TO_OPERATOR = { | |
216 '|': '||', | |
217 ',': '&&', | |
218 } | |
219 | |
220 | |
221 def conditional_string(definition_or_member): | |
222 extended_attributes = definition_or_member.extended_attributes | |
223 if 'Conditional' not in extended_attributes: | |
224 return None | |
225 return 'ENABLE(%s)' % extended_attributes['Conditional'] | |
226 | |
227 | |
228 # [Constructor], [NamedConstructor] | 214 # [Constructor], [NamedConstructor] |
229 def is_constructor_attribute(member): | 215 def is_constructor_attribute(member): |
230 # TODO(yukishiino): replace this with [Constructor] and [NamedConstructor] e
xtended attribute | 216 # TODO(yukishiino): replace this with [Constructor] and [NamedConstructor] e
xtended attribute |
231 return member.idl_type.name.endswith('Constructor') | 217 return (type(member) == IdlAttribute and |
| 218 member.idl_type.name.endswith('Constructor')) |
232 | 219 |
233 | 220 |
234 # [DeprecateAs] | 221 # [DeprecateAs] |
235 def deprecate_as(member): | 222 def deprecate_as(member): |
236 extended_attributes = member.extended_attributes | 223 extended_attributes = member.extended_attributes |
237 if 'DeprecateAs' not in extended_attributes: | 224 if 'DeprecateAs' not in extended_attributes: |
238 return None | 225 return None |
239 includes.add('core/frame/UseCounter.h') | 226 includes.add('core/frame/Deprecation.h') |
240 return extended_attributes['DeprecateAs'] | 227 return extended_attributes['DeprecateAs'] |
241 | 228 |
242 | 229 |
243 # [Exposed] | 230 # [Exposed] |
244 EXPOSED_EXECUTION_CONTEXT_METHOD = { | 231 EXPOSED_EXECUTION_CONTEXT_METHOD = { |
245 'CompositorWorker': 'isCompositorWorkerGlobalScope', | 232 'CompositorWorker': 'isCompositorWorkerGlobalScope', |
246 'DedicatedWorker': 'isDedicatedWorkerGlobalScope', | 233 'DedicatedWorker': 'isDedicatedWorkerGlobalScope', |
247 'ServiceWorker': 'isServiceWorkerGlobalScope', | 234 'ServiceWorker': 'isServiceWorkerGlobalScope', |
248 'SharedWorker': 'isSharedWorkerGlobalScope', | 235 'SharedWorker': 'isSharedWorkerGlobalScope', |
249 'Window': 'isDocument', | 236 'Window': 'isDocument', |
250 'Worker': 'isWorkerGlobalScope', | 237 'Worker': 'isWorkerGlobalScope', |
| 238 'Worklet': 'isWorkletGlobalScope', |
251 } | 239 } |
252 | 240 |
253 | 241 |
254 EXPOSED_WORKERS = set([ | 242 EXPOSED_WORKERS = set([ |
255 'CompositorWorker', | 243 'CompositorWorker', |
256 'DedicatedWorker', | 244 'DedicatedWorker', |
257 'SharedWorker', | 245 'SharedWorker', |
258 'ServiceWorker', | 246 'ServiceWorker', |
259 ]) | 247 ]) |
260 | 248 |
(...skipping 23 matching lines...) Expand all Loading... |
284 self.exposures.add(exposure) | 272 self.exposures.add(exposure) |
285 | 273 |
286 def __len__(self): | 274 def __len__(self): |
287 return len(self.exposures) | 275 return len(self.exposures) |
288 | 276 |
289 def __iter__(self): | 277 def __iter__(self): |
290 return self.exposures.__iter__() | 278 return self.exposures.__iter__() |
291 | 279 |
292 @staticmethod | 280 @staticmethod |
293 def _code(exposure): | 281 def _code(exposure): |
294 exposed = ('context->%s()' % | 282 exposed = ('executionContext->%s()' % |
295 EXPOSED_EXECUTION_CONTEXT_METHOD[exposure.exposed]) | 283 EXPOSED_EXECUTION_CONTEXT_METHOD[exposure.exposed]) |
296 if exposure.runtime_enabled is not None: | 284 if exposure.runtime_enabled is not None: |
297 runtime_enabled = ('RuntimeEnabledFeatures::%sEnabled()' % | 285 runtime_enabled = ('RuntimeEnabledFeatures::%sEnabled()' % |
298 uncapitalize(exposure.runtime_enabled)) | 286 uncapitalize(exposure.runtime_enabled)) |
299 return '({0} && {1})'.format(exposed, runtime_enabled) | 287 return '({0} && {1})'.format(exposed, runtime_enabled) |
300 return exposed | 288 return exposed |
301 | 289 |
302 def code(self): | 290 def code(self): |
303 if len(self.exposures) == 0: | 291 if len(self.exposures) == 0: |
304 return None | 292 return None |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 return lambda suffix: extended_attributes['MeasureAs'] | 360 return lambda suffix: extended_attributes['MeasureAs'] |
373 if 'Measure' in extended_attributes: | 361 if 'Measure' in extended_attributes: |
374 includes.add('core/frame/UseCounter.h') | 362 includes.add('core/frame/UseCounter.h') |
375 measure_as_name = capitalize(definition_or_member.name) | 363 measure_as_name = capitalize(definition_or_member.name) |
376 if interface is not None: | 364 if interface is not None: |
377 measure_as_name = '%s_%s' % (capitalize(interface.name), measure_as_
name) | 365 measure_as_name = '%s_%s' % (capitalize(interface.name), measure_as_
name) |
378 return lambda suffix: 'V8%s_%s' % (measure_as_name, suffix) | 366 return lambda suffix: 'V8%s_%s' % (measure_as_name, suffix) |
379 return None | 367 return None |
380 | 368 |
381 | 369 |
| 370 def runtime_feature_name(definition_or_member): |
| 371 extended_attributes = definition_or_member.extended_attributes |
| 372 if 'RuntimeEnabled' not in extended_attributes: |
| 373 return None |
| 374 return extended_attributes['RuntimeEnabled'] |
| 375 |
| 376 |
| 377 def is_origin_trial_enabled(definition_or_member): |
| 378 return 'OriginTrialEnabled' in definition_or_member.extended_attributes |
| 379 |
| 380 |
| 381 def origin_trial_name(definition_or_member): |
| 382 return definition_or_member.extended_attributes['OriginTrialEnabled'] if is_
origin_trial_enabled(definition_or_member) else None |
| 383 |
| 384 |
| 385 def origin_trial_enabled_function(definition_or_member): |
| 386 trial_name = origin_trial_name(definition_or_member) |
| 387 feature_name = runtime_feature_name(definition_or_member) |
| 388 if not feature_name or not trial_name: |
| 389 return |
| 390 return 'OriginTrials::%sEnabled' % uncapitalize(feature_name) |
| 391 |
| 392 |
382 # [RuntimeEnabled] | 393 # [RuntimeEnabled] |
383 def runtime_enabled_function_name(definition_or_member): | 394 def runtime_enabled_function_name(definition_or_member): |
384 """Returns the name of the RuntimeEnabledFeatures function. | 395 """Returns the name of the RuntimeEnabledFeatures function. |
385 | 396 |
386 The returned function checks if a method/attribute is enabled. | 397 The returned function checks if a method/attribute is enabled. |
387 Given extended attribute RuntimeEnabled=FeatureName, return: | 398 Given extended attribute RuntimeEnabled=FeatureName, return: |
388 RuntimeEnabledFeatures::{featureName}Enabled | 399 RuntimeEnabledFeatures::{featureName}Enabled |
389 """ | 400 """ |
390 extended_attributes = definition_or_member.extended_attributes | 401 feature_name = runtime_feature_name(definition_or_member) |
391 if 'RuntimeEnabled' not in extended_attributes: | 402 |
392 return None | 403 # If an origin trial is on the method/attribute, it overrides the runtime |
393 feature_name = extended_attributes['RuntimeEnabled'] | 404 # enabled status. For now, we are unconditionally installing these |
| 405 # attributes/methods, so we are acting as though the runtime enabled |
| 406 # function doesn't exist. (It is checked in the generated OriginTrials |
| 407 # function, instead) |
| 408 trial_name = origin_trial_name(definition_or_member) |
| 409 if not feature_name or trial_name: |
| 410 return |
394 return 'RuntimeEnabledFeatures::%sEnabled' % uncapitalize(feature_name) | 411 return 'RuntimeEnabledFeatures::%sEnabled' % uncapitalize(feature_name) |
395 | 412 |
396 | 413 |
397 # [Unforgeable] | 414 # [Unforgeable] |
398 def is_unforgeable(interface, member): | 415 def is_unforgeable(interface, member): |
399 return (('Unforgeable' in interface.extended_attributes or | 416 return (('Unforgeable' in interface.extended_attributes or |
400 'Unforgeable' in member.extended_attributes) and | 417 'Unforgeable' in member.extended_attributes) and |
401 not member.is_static) | 418 not member.is_static) |
402 | 419 |
403 | 420 |
404 # [TypeChecking=Interface] / [LegacyInterfaceTypeChecking] | 421 # [LegacyInterfaceTypeChecking] |
405 def is_legacy_interface_type_checking(interface, member): | 422 def is_legacy_interface_type_checking(interface, member): |
406 if not ('TypeChecking' in interface.extended_attributes or | 423 return ('LegacyInterfaceTypeChecking' in interface.extended_attributes or |
407 'TypeChecking' in member.extended_attributes): | 424 'LegacyInterfaceTypeChecking' in member.extended_attributes) |
408 return True | |
409 if 'LegacyInterfaceTypeChecking' in member.extended_attributes: | |
410 return True | |
411 return False | |
412 | 425 |
413 | 426 |
414 # [Unforgeable], [Global], [PrimaryGlobal] and [DoNotExposeJSAccessors] | 427 # [Unforgeable], [Global], [PrimaryGlobal] |
415 def on_instance(interface, member): | 428 def on_instance(interface, member): |
416 """Returns True if the interface's member needs to be defined on every | 429 """Returns True if the interface's member needs to be defined on every |
417 instance object. | 430 instance object. |
418 | 431 |
419 The following members must be defiend on an instance object. | 432 The following members must be defiend on an instance object. |
420 - [Unforgeable] members | 433 - [Unforgeable] members |
421 - regular members of [Global] or [PrimaryGlobal] interfaces | 434 - regular members of [Global] or [PrimaryGlobal] interfaces |
422 - members on which [DoNotExposeJSAccessors] is specified | |
423 """ | 435 """ |
424 # TODO(yukishiino): Implement this function following the spec. | 436 if member.is_static: |
425 return not on_prototype(interface, member) | 437 return False |
| 438 |
| 439 # TODO(yukishiino): Remove a hack for toString once we support |
| 440 # Symbol.toStringTag. |
| 441 if (interface.name == 'Window' and member.name == 'toString'): |
| 442 return False |
| 443 |
| 444 # TODO(yukishiino): Implement "interface object" and its [[Call]] method |
| 445 # in a better way. Then we can get rid of this hack. |
| 446 if is_constructor_attribute(member): |
| 447 return True |
| 448 |
| 449 if ('PrimaryGlobal' in interface.extended_attributes or |
| 450 'Global' in interface.extended_attributes or |
| 451 'Unforgeable' in member.extended_attributes or |
| 452 'Unforgeable' in interface.extended_attributes): |
| 453 return True |
| 454 return False |
426 | 455 |
427 | 456 |
428 # [ExposeJSAccessors] | |
429 def on_prototype(interface, member): | 457 def on_prototype(interface, member): |
430 """Returns True if the interface's member needs to be defined on the | 458 """Returns True if the interface's member needs to be defined on the |
431 prototype object. | 459 prototype object. |
432 | 460 |
433 Most members are defined on the prototype object. Exceptions are as | 461 Most members are defined on the prototype object. Exceptions are as |
434 follows. | 462 follows. |
435 - constant members | |
436 - static members (optional) | 463 - static members (optional) |
437 - [Unforgeable] members | 464 - [Unforgeable] members |
438 - members of [Global] or [PrimaryGlobal] interfaces | 465 - members of [Global] or [PrimaryGlobal] interfaces |
439 - named properties of [Global] or [PrimaryGlobal] interfaces | 466 - named properties of [Global] or [PrimaryGlobal] interfaces |
440 However, if [ExposeJSAccessors] is specified, the member is defined on the | |
441 prototype object. | |
442 """ | 467 """ |
443 # TODO(yukishiino): Implement this function following the spec. | 468 if member.is_static: |
444 | |
445 if ('ExposeJSAccessors' in interface.extended_attributes and | |
446 'DoNotExposeJSAccessors' in interface.extended_attributes): | |
447 raise Exception('Both of ExposeJSAccessors and DoNotExposeJSAccessors ar
e specified at a time in an interface: ' + interface.name) | |
448 if ('ExposeJSAccessors' in member.extended_attributes and | |
449 'DoNotExposeJSAccessors' in member.extended_attributes): | |
450 raise Exception('Both of ExposeJSAccessors and DoNotExposeJSAccessors ar
e specified at a time on a member: ' + member.name + ' in an interface: ' + inte
rface.name) | |
451 | |
452 # Note that ExposeJSAccessors and DoNotExposeJSAccessors are more powerful | |
453 # than 'static', [Unforgeable] and [OverrideBuiltins]. | |
454 if 'ExposeJSAccessors' in member.extended_attributes: | |
455 return True | |
456 if 'DoNotExposeJSAccessors' in member.extended_attributes: | |
457 return False | 469 return False |
458 | 470 |
459 # These members must not be placed on prototype chains. | 471 # TODO(yukishiino): Remove a hack for toString once we support |
460 if (is_constructor_attribute(member) or | 472 # Symbol.toStringTag. |
461 member.is_static or | 473 if (interface.name == 'Window' and member.name == 'toString'): |
462 is_unforgeable(interface, member) or | 474 return True |
463 'OverrideBuiltins' in interface.extended_attributes): | 475 |
| 476 # TODO(yukishiino): Implement "interface object" and its [[Call]] method |
| 477 # in a better way. Then we can get rid of this hack. |
| 478 if is_constructor_attribute(member): |
464 return False | 479 return False |
465 | 480 |
466 # TODO(yukishiino): We should handle [Global] and [PrimaryGlobal] instead of | 481 if ('PrimaryGlobal' in interface.extended_attributes or |
467 # Window. | 482 'Global' in interface.extended_attributes or |
468 if (interface.name == 'Window'): | 483 'Unforgeable' in member.extended_attributes or |
469 return member.idl_type.name == 'EventHandler' | 484 'Unforgeable' in interface.extended_attributes): |
470 | |
471 if 'ExposeJSAccessors' in interface.extended_attributes: | |
472 return True | |
473 if 'DoNotExposeJSAccessors' in interface.extended_attributes: | |
474 return False | 485 return False |
475 | |
476 return True | 486 return True |
477 | 487 |
478 | 488 |
479 # static, const | 489 # static, const |
480 def on_interface(interface, member): | 490 def on_interface(interface, member): |
481 """Returns True if the interface's member needs to be defined on the | 491 """Returns True if the interface's member needs to be defined on the |
482 interface object. | 492 interface object. |
483 | 493 |
484 The following members must be defiend on an interface object. | 494 The following members must be defiend on an interface object. |
485 - constant members | |
486 - static members | 495 - static members |
487 """ | 496 """ |
488 # TODO(yukishiino): Implement this function following the spec. | 497 if member.is_static: |
| 498 return True |
489 return False | 499 return False |
490 | 500 |
491 | 501 |
492 ################################################################################ | 502 ################################################################################ |
493 # Indexed properties | 503 # Indexed properties |
494 # http://heycam.github.io/webidl/#idl-indexed-properties | 504 # http://heycam.github.io/webidl/#idl-indexed-properties |
495 ################################################################################ | 505 ################################################################################ |
496 | 506 |
497 def indexed_property_getter(interface): | 507 def indexed_property_getter(interface): |
498 try: | 508 try: |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
584 except StopIteration: | 594 except StopIteration: |
585 return None | 595 return None |
586 | 596 |
587 | 597 |
588 IdlInterface.indexed_property_getter = property(indexed_property_getter) | 598 IdlInterface.indexed_property_getter = property(indexed_property_getter) |
589 IdlInterface.indexed_property_setter = property(indexed_property_setter) | 599 IdlInterface.indexed_property_setter = property(indexed_property_setter) |
590 IdlInterface.indexed_property_deleter = property(indexed_property_deleter) | 600 IdlInterface.indexed_property_deleter = property(indexed_property_deleter) |
591 IdlInterface.named_property_getter = property(named_property_getter) | 601 IdlInterface.named_property_getter = property(named_property_getter) |
592 IdlInterface.named_property_setter = property(named_property_setter) | 602 IdlInterface.named_property_setter = property(named_property_setter) |
593 IdlInterface.named_property_deleter = property(named_property_deleter) | 603 IdlInterface.named_property_deleter = property(named_property_deleter) |
OLD | NEW |