Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(320)

Side by Side Diff: Source/bindings/scripts/unstable/v8_attributes.py

Issue 181513006: IDL compiler: delete Perl compiler, remove unstable/ directory (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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 """Generate template values for attributes.
30
31 FIXME: Not currently used in build.
32 This is a rewrite of the Perl IDL compiler in Python, but is not complete.
33 Once it is complete, we will switch all IDL files over to Python at once.
34 Until then, please work on the Perl IDL compiler.
35 For details, see bug http://crbug.com/239771
36 """
37
38 from v8_globals import includes, interfaces
39 import v8_types
40 import v8_utilities
41 from v8_utilities import capitalize, cpp_name, has_extended_attribute, uncapital ize
42
43
44 def generate_attribute(interface, attribute):
45 idl_type = attribute.idl_type
46 extended_attributes = attribute.extended_attributes
47
48 v8_types.add_includes_for_type(idl_type)
49
50 # [CheckSecurity]
51 is_check_security_for_node = 'CheckSecurity' in extended_attributes
52 if is_check_security_for_node:
53 includes.add('bindings/v8/BindingSecurity.h')
54 # [Custom]
55 has_custom_getter = ('Custom' in extended_attributes and
56 extended_attributes['Custom'] in [None, 'Getter'])
57 has_custom_setter = (not attribute.is_read_only and
58 'Custom' in extended_attributes and
59 extended_attributes['Custom'] in [None, 'Setter'])
60 # [CustomElementCallbacks], [Reflect]
61 is_custom_element_callbacks = 'CustomElementCallbacks' in extended_attribute s
62 is_reflect = 'Reflect' in extended_attributes
63 if is_custom_element_callbacks or is_reflect:
64 includes.add('core/dom/custom/CustomElementCallbackDispatcher.h')
65 # [RaisesException], [RaisesException=Setter]
66 is_setter_raises_exception = (
67 'RaisesException' in extended_attributes and
68 extended_attributes['RaisesException'] in [None, 'Setter'])
69 # [StrictTypeChecking]
70 has_strict_type_checking = (
71 ('StrictTypeChecking' in extended_attributes or
72 'StrictTypeChecking' in interface.extended_attributes) and
73 v8_types.is_wrapper_type(idl_type))
74
75 if (idl_type == 'EventHandler' and
76 interface.name in ['Window', 'WorkerGlobalScope'] and
77 attribute.name == 'onerror'):
78 includes.add('bindings/v8/V8ErrorHandler.h')
79
80 contents = {
81 'access_control_list': access_control_list(attribute),
82 'activity_logging_world_list_for_getter': v8_utilities.activity_logging_ world_list(attribute, 'Getter'), # [ActivityLogging]
83 'activity_logging_world_list_for_setter': v8_utilities.activity_logging_ world_list(attribute, 'Setter'), # [ActivityLogging]
84 'cached_attribute_validation_method': extended_attributes.get('CachedAtt ribute'),
85 'conditional_string': v8_utilities.conditional_string(attribute),
86 'constructor_type': v8_types.constructor_type(idl_type)
87 if is_constructor_attribute(attribute) else None,
88 'cpp_name': cpp_name(attribute),
89 'cpp_type': v8_types.cpp_type(idl_type),
90 'deprecate_as': v8_utilities.deprecate_as(attribute), # [DeprecateAs]
91 'enum_validation_expression':
92 v8_utilities.enum_validation_expression(idl_type),
93 'has_custom_getter': has_custom_getter,
94 'has_custom_setter': has_custom_setter,
95 'has_strict_type_checking': has_strict_type_checking,
96 'idl_type': idl_type,
97 'is_call_with_execution_context': v8_utilities.has_extended_attribute_va lue(attribute, 'CallWith', 'ExecutionContext'),
98 'is_check_security_for_node': is_check_security_for_node,
99 'is_custom_element_callbacks': is_custom_element_callbacks,
100 'is_expose_js_accessors': 'ExposeJSAccessors' in extended_attributes,
101 'is_getter_raises_exception': ( # [RaisesException]
102 'RaisesException' in extended_attributes and
103 extended_attributes['RaisesException'] in [None, 'Getter']),
104 'is_implemented_by': 'ImplementedBy' in extended_attributes,
105 'is_initialized_by_event_constructor':
106 'InitializedByEventConstructor' in extended_attributes,
107 'is_keep_alive_for_gc': is_keep_alive_for_gc(interface, attribute),
108 'is_nullable': attribute.is_nullable,
109 'is_per_world_bindings': 'PerWorldBindings' in extended_attributes,
110 'is_read_only': attribute.is_read_only,
111 'is_reflect': is_reflect,
112 'is_replaceable': 'Replaceable' in attribute.extended_attributes,
113 'is_setter_call_with_execution_context': v8_utilities.has_extended_attri bute_value(attribute, 'SetterCallWith', 'ExecutionContext'),
114 'is_setter_raises_exception': is_setter_raises_exception,
115 'has_setter_exception_state': (
116 is_setter_raises_exception or has_strict_type_checking or
117 v8_types.is_integer_type(idl_type)),
118 'is_static': attribute.is_static,
119 'is_url': 'URL' in extended_attributes,
120 'is_unforgeable': 'Unforgeable' in extended_attributes,
121 'measure_as': v8_utilities.measure_as(attribute), # [MeasureAs]
122 'name': attribute.name,
123 'per_context_enabled_function': v8_utilities.per_context_enabled_functio n_name(attribute), # [PerContextEnabled]
124 'property_attributes': property_attributes(attribute),
125 'put_forwards': 'PutForwards' in extended_attributes,
126 'reflect_empty': extended_attributes.get('ReflectEmpty'),
127 'reflect_invalid': extended_attributes.get('ReflectInvalid', ''),
128 'reflect_missing': extended_attributes.get('ReflectMissing'),
129 'reflect_only': extended_attributes['ReflectOnly'].split('|')
130 if 'ReflectOnly' in extended_attributes else None,
131 'setter_callback': setter_callback_name(interface, attribute),
132 'v8_type': v8_types.v8_type(idl_type),
133 'runtime_enabled_function': v8_utilities.runtime_enabled_function_name(a ttribute), # [RuntimeEnabled]
134 'world_suffixes': ['', 'ForMainWorld']
135 if 'PerWorldBindings' in extended_attributes
136 else [''], # [PerWorldBindings]
137 }
138
139 if is_constructor_attribute(attribute):
140 return contents
141 if not has_custom_getter:
142 generate_getter(interface, attribute, contents)
143 if (not has_custom_setter and
144 (not attribute.is_read_only or 'PutForwards' in extended_attributes)):
145 generate_setter(interface, attribute, contents)
146
147 return contents
148
149
150 ################################################################################
151 # Getter
152 ################################################################################
153
154 def generate_getter(interface, attribute, contents):
155 idl_type = attribute.idl_type
156 extended_attributes = attribute.extended_attributes
157
158 cpp_value = getter_expression(interface, attribute, contents)
159 # Normally we can inline the function call into the return statement to
160 # avoid the overhead of using a Ref<> temporary, but for some cases
161 # (nullable types, EventHandler, [CachedAttribute], or if there are
162 # exceptions), we need to use a local variable.
163 # FIXME: check if compilers are smart enough to inline this, and if so,
164 # always use a local variable (for readability and CG simplicity).
165 release = False
166 if (attribute.is_nullable or
167 idl_type == 'EventHandler' or
168 'CachedAttribute' in extended_attributes or
169 contents['is_getter_raises_exception']):
170 contents['cpp_value_original'] = cpp_value
171 cpp_value = 'jsValue'
172 # EventHandler has special handling
173 if idl_type != 'EventHandler' and v8_types.is_interface_type(idl_type):
174 release = True
175
176 if 'ReflectOnly' in extended_attributes:
177 contents['cpp_value_original'] = cpp_value
178 # FIXME: rename to jsValue
179 cpp_value = 'resultValue'
180
181 def v8_set_return_value_statement(for_main_world=False):
182 if contents['is_keep_alive_for_gc']:
183 return 'v8SetReturnValue(info, wrapper)'
184 return v8_types.v8_set_return_value(idl_type, cpp_value, extended_attrib utes=extended_attributes, script_wrappable='imp', release=release, for_main_worl d=for_main_world)
185
186 contents.update({
187 'cpp_value': cpp_value,
188 'v8_set_return_value_for_main_world': v8_set_return_value_statement(for_ main_world=True),
189 'v8_set_return_value': v8_set_return_value_statement(),
190 })
191
192
193 def getter_expression(interface, attribute, contents):
194 arguments = []
195 this_getter_base_name = getter_base_name(interface, attribute, arguments)
196 getter_name = v8_utilities.scoped_name(interface, attribute, this_getter_bas e_name)
197
198 arguments.extend(v8_utilities.call_with_arguments(attribute))
199 if ('ImplementedBy' in attribute.extended_attributes and
200 not attribute.is_static):
201 arguments.append('*imp')
202 if attribute.is_nullable:
203 arguments.append('isNull')
204 if contents['is_getter_raises_exception']:
205 arguments.append('exceptionState')
206 return '%s(%s)' % (getter_name, ', '.join(arguments))
207
208
209 CONTENT_ATTRIBUTE_GETTER_NAMES = {
210 'boolean': 'fastHasAttribute',
211 'long': 'getIntegralAttribute',
212 'unsigned long': 'getUnsignedIntegralAttribute',
213 }
214
215
216 def getter_base_name(interface, attribute, arguments):
217 extended_attributes = attribute.extended_attributes
218 if 'Reflect' not in extended_attributes:
219 return uncapitalize(cpp_name(attribute))
220
221 content_attribute_name = extended_attributes['Reflect'] or attribute.name.lo wer()
222 if content_attribute_name in ['class', 'id', 'name']:
223 # Special-case for performance optimization.
224 return 'get%sAttribute' % content_attribute_name.capitalize()
225
226 arguments.append(scoped_content_attribute_name(interface, attribute))
227
228 idl_type = attribute.idl_type
229 if idl_type in CONTENT_ATTRIBUTE_GETTER_NAMES:
230 return CONTENT_ATTRIBUTE_GETTER_NAMES[idl_type]
231 if 'URL' in attribute.extended_attributes:
232 return 'getURLAttribute'
233 return 'fastGetAttribute'
234
235
236 def is_keep_alive_for_gc(interface, attribute):
237 idl_type = attribute.idl_type
238 extended_attributes = attribute.extended_attributes
239 return (
240 # For readonly attributes, for performance reasons we keep the attribute
241 # wrapper alive while the owner wrapper is alive, because the attribute
242 # never changes.
243 (attribute.is_read_only and
244 v8_types.is_wrapper_type(idl_type) and
245 # There are some exceptions, however:
246 not(
247 # Node lifetime is managed by object grouping.
248 v8_types.inherits_interface(interface.name, 'Node') or
249 v8_types.inherits_interface(idl_type, 'Node') or
250 # A self-reference is unnecessary.
251 attribute.name == 'self' or
252 # FIXME: Remove these hard-coded hacks.
253 idl_type in ['EventTarget', 'Window'] or
254 idl_type.startswith(('HTML', 'SVG')))))
255
256
257 ################################################################################
258 # Setter
259 ################################################################################
260
261 def generate_setter(interface, attribute, contents):
262 def target_attribute():
263 target_interface_name = attribute.idl_type
264 target_attribute_name = extended_attributes['PutForwards']
265 target_interface = interfaces[target_interface_name]
266 try:
267 return next(attribute
268 for attribute in target_interface.attributes
269 if attribute.name == target_attribute_name)
270 except StopIteration:
271 raise Exception('[PutForward] target not found:\n'
272 'Attribute "%s" is not present in interface "%s"' %
273 (target_attribute_name, target_interface_name))
274
275 extended_attributes = attribute.extended_attributes
276
277 if 'PutForwards' in extended_attributes:
278 # Use target attribute in place of original attribute
279 attribute = target_attribute()
280
281 contents.update({
282 'cpp_setter': setter_expression(interface, attribute, contents),
283 'v8_value_to_local_cpp_value': v8_types.v8_value_to_local_cpp_value(
284 attribute.idl_type, extended_attributes, 'jsValue', 'cppValue'),
285 })
286
287
288 def setter_expression(interface, attribute, contents):
289 extended_attributes = attribute.extended_attributes
290 arguments = v8_utilities.call_with_arguments(attribute, extended_attributes. get('SetterCallWith'))
291
292 this_setter_base_name = setter_base_name(interface, attribute, arguments)
293 setter_name = v8_utilities.scoped_name(interface, attribute, this_setter_bas e_name)
294
295 if ('ImplementedBy' in extended_attributes and
296 not attribute.is_static):
297 arguments.append('*imp')
298 idl_type = attribute.idl_type
299 if idl_type == 'EventHandler':
300 getter_name = v8_utilities.scoped_name(interface, attribute, cpp_name(at tribute))
301 contents['event_handler_getter_expression'] = '%s(%s)' % (
302 getter_name, ', '.join(arguments))
303 if (interface.name in ['Window', 'WorkerGlobalScope'] and
304 attribute.name == 'onerror'):
305 includes.add('bindings/v8/V8ErrorHandler.h')
306 arguments.append('V8EventListenerList::findOrCreateWrapper<V8ErrorHa ndler>(jsValue, true, info.GetIsolate())')
307 else:
308 arguments.append('V8EventListenerList::getEventListener(jsValue, tru e, ListenerFindOrCreate)')
309 elif v8_types.is_interface_type(idl_type) and not v8_types.array_type(idl_ty pe):
310 # FIXME: should be able to eliminate WTF::getPtr in most or all cases
311 arguments.append('WTF::getPtr(cppValue)')
312 else:
313 arguments.append('cppValue')
314 if contents['is_setter_raises_exception']:
315 arguments.append('exceptionState')
316
317 return '%s(%s)' % (setter_name, ', '.join(arguments))
318
319
320 CONTENT_ATTRIBUTE_SETTER_NAMES = {
321 'boolean': 'setBooleanAttribute',
322 'long': 'setIntegralAttribute',
323 'unsigned long': 'setUnsignedIntegralAttribute',
324 }
325
326
327 def setter_base_name(interface, attribute, arguments):
328 if 'Reflect' not in attribute.extended_attributes:
329 return 'set%s' % capitalize(cpp_name(attribute))
330 arguments.append(scoped_content_attribute_name(interface, attribute))
331
332 idl_type = attribute.idl_type
333 if idl_type in CONTENT_ATTRIBUTE_SETTER_NAMES:
334 return CONTENT_ATTRIBUTE_SETTER_NAMES[idl_type]
335 return 'setAttribute'
336
337
338 def scoped_content_attribute_name(interface, attribute):
339 content_attribute_name = attribute.extended_attributes['Reflect'] or attribu te.name.lower()
340 namespace = 'SVGNames' if interface.name.startswith('SVG') else 'HTMLNames'
341 includes.add('%s.h' % namespace)
342 return '%s::%sAttr' % (namespace, content_attribute_name)
343
344
345 ################################################################################
346 # Attribute configuration
347 ################################################################################
348
349 # [Replaceable]
350 def setter_callback_name(interface, attribute):
351 cpp_class_name = cpp_name(interface)
352 extended_attributes = attribute.extended_attributes
353 if (('Replaceable' in extended_attributes and
354 'PutForwards' not in extended_attributes) or
355 is_constructor_attribute(attribute)):
356 # FIXME: rename to ForceSetAttributeOnThisCallback, since also used for Constructors
357 return '{0}V8Internal::{0}ReplaceableAttributeSetterCallback'.format(cpp _class_name)
358 if attribute.is_read_only and 'PutForwards' not in extended_attributes:
359 return '0'
360 return '%sV8Internal::%sAttributeSetterCallback' % (cpp_class_name, attribut e.name)
361
362
363 # [DoNotCheckSecurity], [Unforgeable]
364 def access_control_list(attribute):
365 extended_attributes = attribute.extended_attributes
366 access_control = []
367 if 'DoNotCheckSecurity' in extended_attributes:
368 do_not_check_security = extended_attributes['DoNotCheckSecurity']
369 if do_not_check_security == 'Setter':
370 access_control.append('v8::ALL_CAN_WRITE')
371 else:
372 access_control.append('v8::ALL_CAN_READ')
373 if (not attribute.is_read_only or
374 'Replaceable' in extended_attributes):
375 access_control.append('v8::ALL_CAN_WRITE')
376 if 'Unforgeable' in extended_attributes:
377 access_control.append('v8::PROHIBITS_OVERWRITING')
378 return access_control or ['v8::DEFAULT']
379
380
381 # [NotEnumerable], [Unforgeable]
382 def property_attributes(attribute):
383 extended_attributes = attribute.extended_attributes
384 property_attributes_list = []
385 if ('NotEnumerable' in extended_attributes or
386 is_constructor_attribute(attribute)):
387 property_attributes_list.append('v8::DontEnum')
388 if 'Unforgeable' in extended_attributes:
389 property_attributes_list.append('v8::DontDelete')
390 return property_attributes_list or ['v8::None']
391
392
393 ################################################################################
394 # Constructors
395 ################################################################################
396
397 def is_constructor_attribute(attribute):
398 return attribute.idl_type.endswith('Constructor')
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698