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

Side by Side Diff: Source/bindings/scripts/v8_values.py

Issue 17572008: WIP IDL compiler rewrite (Closed) Base URL: https://chromium.googlesource.com/chromium/blink@master
Patch Set: Branch: const + primitive type readonly attributes Created 7 years, 4 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
« no previous file with comments | « Source/bindings/scripts/v8_utilities.py ('k') | Source/bindings/templates/attributes.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
30 import v8_types
31 from v8_types import get_array_or_sequence_type, primitive_type
32
33 # WIP
34 from v8_includes import get_includes_for_type, includes_for_type
35 from v8_types import get_native_type, is_callback_function_type, is_enum_type, i s_primitive_type, is_ref_ptr_type, is_union_type
36
37
38 CPP_VALUE_TO_JS_VALUE_DICT = {
39 'boolean': 'v8Boolean({cpp_value}, {isolate})',
40 # long long and unsigned long long are not representable in ECMAScript.
41 'long long': 'v8::Number::New(static_cast<double>({cpp_value}))',
42 'unsigned long long': 'v8::Number::New(static_cast<double>({cpp_value}))',
43 'float': 'v8::Number::New({cpp_value})',
44 'double': 'v8::Number::New({cpp_value})',
45 'DOMTimeStamp': 'v8::Number::New(static_cast<double>({cpp_value}))',
46 'DOMString': 'v8String({cpp_value}, {isolate})',
47 }
48 CPP_VALUE_TO_JS_VALUE_ARRAY_OR_SEQUENCE_TYPE = 'v8Array({cpp_value}, {isolate})'
49 CPP_VALUE_TO_JS_VALUE_DEFAULT = 'toV8({cpp_value}, {creation_context}, {isolate} )'
50
51 CPP_VALUE_TO_JS_VALUE_RETURN_DICT = {
52 'unsigned': 'v8SetReturnValueUnsigned({callback_info}, {cpp_value});',
53 }
54
55
56 def cpp_value_to_js_value(data_type, cpp_value, isolate, creation_context=''):
57 """Return an expression converting a C++ value to a JS value."""
58 if data_type in CPP_VALUE_TO_JS_VALUE_DICT:
59 expression_format_string = CPP_VALUE_TO_JS_VALUE_DICT[data_type]
60 elif primitive_type(data_type): # primitive but not in dict
61 raise Exception('unexpected data_type %s' % data_type)
62 elif get_array_or_sequence_type(data_type):
63 expression_format_string = CPP_VALUE_TO_JS_VALUE_ARRAY_OR_SEQUENCE_TYPE
64 else:
65 expression_format_string = CPP_VALUE_TO_JS_VALUE_DEFAULT
66 return expression_format_string.format(cpp_value=cpp_value, creation_context =creation_context, isolate=isolate)
67
68
69 def cpp_value_to_js_value_return(data_type, cpp_value, callback_info=''):
70 """Return an expression converting a C++ value to a JS value, as a return va lue."""
71 cpp_type = v8_types.cpp_type(data_type)
72 if cpp_type in CPP_VALUE_TO_JS_VALUE_RETURN_DICT:
73 expression_format_string = CPP_VALUE_TO_JS_VALUE_RETURN_DICT[cpp_type]
74 else:
75 raise Exception('unexpected data_type %s' % data_type)
76 return expression_format_string.format(callback_info=callback_info, cpp_valu e=cpp_value)
77
78
79 ################################################################################
80 # WIP
81 ################################################################################
82
83 JS_VALUE_TO_NATIVE_DICT = {
84 # js_type -> (native_expression_format, additional_includes)
85 'boolean': ('{js_value}->BooleanValue()', []),
86 'float': ('static_cast<{idl_type}>({js_value}->NumberValue())', []),
87 'double': ('static_cast<{idl_type}>({js_value}->NumberValue())', []),
88 'byte': ('toInt8({arguments})', []),
89 'octet': ('toUInt8({arguments})', []),
90 'long': ('toInt32({arguments})', []),
91 'short': ('toInt32({arguments})', []),
92 'unsigned long': ('toUInt32({arguments})', []),
93 'unsigned short': ('toUInt32({arguments})', []),
94 'long long': ('toInt64({arguments})', []),
95 'unsigned long long': ('toUInt64({arguments})', []),
96 'CompareHow': ('static_cast<Range::CompareHow>({js_value}->Int32Value())', [ ]),
97 'Date': ('toWebCoreDate({js_value})', []),
98 'DOMStringList': ('toDOMStringList({js_value}, {isolate})', []),
99 'DOMString': ('{js_value}', []),
100 'SerializedScriptValue': ('SerializedScriptValue::create({js_value}, {isolat e})', ['bindings/v8/SerializedScriptValue.h']),
101 'Dictionary': ('Dictionary({js_value}, {isolate})', ['bindings/v8/Dictionary .h']),
102 'any': ('ScriptValue({js_value})', ['bindings/v8/ScriptValue.h']),
103 'NodeFilter': ('toNodeFilter({js_value})', []),
104 'MediaQueryListListener': ('MediaQueryListListener::create({js_value})', ['c ore/css/MediaQueryListListener.h']),
105 'EventTarget': ('V8DOMWrapper::isDOMWrapper({js_value}) ? toWrapperTypeInfo( v8::Handle<v8::Object>::Cast({js_value}))->toEventTarget(v8::Handle<v8::Object>: :Cast({js_value})) : 0', []),
106 'XPathNSResolver': ('toXPathNSResolver({js_value}, {isolate})', []),
107 }
108
109
110 def array_or_sequence_type_to_native(array_or_sequence_type, js_value, isolate):
111 if is_ref_ptr_type(array_or_sequence_type):
112 native_expression_format = '(toRefPtrNativeArray<{array_or_sequence_type }, V8{array_or_sequence_type}>({js_value}, {isolate}))'
113 native_expression = native_expression_format.format(array_or_sequence_ty pe=array_or_sequence_type, js_value=js_value, isolate=isolate)
114 additional_includes = ['V8%s.h' % array_or_sequence_type]
115 return native_expression, additional_includes
116
117 native_type = get_native_type(array_or_sequence_type)
118 native_expression_format = 'toNativeArray<{native_type}>({js_value})'
119 native_expression = native_expression_format.format(native_type=native_type, js_value=js_value)
120 return native_expression, []
121
122
123 def get_js_value_to_native(idl_type, extended_attributes, js_value, isolate):
124 if 'EnforceRange' in extended_attributes:
125 arguments_list = [js_value, 'EnforceRange', 'ok']
126 arguments = ', '.join(arguments_list)
127 else: # NormalConversion
128 arguments = js_value
129
130 array_or_sequence_type = get_array_or_sequence_type(idl_type)
131 if array_or_sequence_type:
132 return array_or_sequence_type_to_native(array_or_sequence_type, js_value , isolate)
133
134 if is_enum_type(idl_type):
135 idl_type = 'DOMString'
136 if is_callback_function_type(idl_type):
137 idl_type = 'any'
138
139 if idl_type in JS_VALUE_TO_NATIVE_DICT:
140 native_expression_format, additional_includes = JS_VALUE_TO_NATIVE_DICT[ idl_type]
141 elif idl_type == 'ArrayBuffer':
142 native_expression_format = '$value->IsArrayBuffer() ? V8ArrayBuffer::toN ative(v8::Handle<v8::ArrayBuffer>::Cast({js_value})) : 0'
143 additional_includes = get_includes_for_type(idl_type)
144 else:
145 native_expression_format = 'V8{idl_type}::HasInstance({js_value}, {isola te}, worldType({isolate})) ? V8{idl_type}::toNative(v8::Handle<v8::Object>::Cast ({js_value})) : 0'
146 additional_includes = get_includes_for_type(idl_type) + ['V8%s.h' % idl_ type]
147
148 native_expression = native_expression_format.format(arguments=arguments, idl _type=idl_type, isolate=isolate, js_value=js_value)
149 return native_expression, additional_includes
150
151
152 def get_js_value_to_native_statement(data_type, extended_attributes, js_value, v ariable_name, isolate):
153 native_type = get_native_type(data_type, extended_attributes=extended_attrib utes, used_to_assign_js_value=True)
154 if data_type == 'unsigned long' and 'IsIndex' in extended_attributes:
155 # Special-case index arguments because we need to check that they aren't < 0.
156 native_type = 'int'
157 native_value, includes = get_js_value_to_native(data_type, extended_attribut es, js_value, isolate)
158 # print '[get_js_value_to_native_statement]', native_value
159 if data_type == 'DOMString' or is_enum_type(data_type):
160 if not native_type.startswith('V8StringResource'):
161 raise Exception('Wrong native type passed: ' + native_type)
162 code = 'V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(%s, %s, %s);' % (native_typ e, variable_name, native_value)
163 elif 'EnforceRange' in extended_attributes:
164 code = 'V8TRYCATCH_WITH_TYPECHECK_VOID(%s, %s, %s, %s);' % (native_type, variable_name, native_value, isolate)
165 else:
166 code = 'V8TRYCATCH_VOID(%s, %s, %s);' % (native_type, variable_name, nat ive_value)
167 return code, includes
168
169
170 def get_pass_owner_expression(data_type, expression):
171 if is_ref_ptr_type(data_type):
172 return expression + '.release()'
173 return expression
174
175
176 def get_native_to_js_value_statement(idl_type, extended_attributes, native_value , receiver='', creation_context='', isolate='', callback_info='', script_wrappab le='', for_main_world_suffix='', indent='', used_as_return_value=False):
177 """
178 Create statement which convert native(C++) value into JS value.
179 FIXME: merge with cpp_value_to_js_value and cpp_value_to_js_value_return
180
181 @param[in] idl_type IDL type
182 @param[in] extended_attributes
183 @param[in] native_value e.g. 'imp->getImte(index)'
184
185 @param[in] indent
186 @param[in] receiver '%s' will be replaced with JS value. to ret urn something, use used_as_return_value=True
187 @param[in] creation_context
188 @param[in] isolate
189 @param[in] callback_info
190 @param[in] script_wrappable
191 @param[in] for_main_world_suffix
192 @param[in] used_as_return_value
193 """
194 # print '[get_native_to_js_value_statement]', idl_type, native_value
195 def create_arguments(arguments):
196 return ', '.join([argument for argument in arguments if argument])
197
198 def create_statement(receiver, js_value):
199 # print 'create_statement', receiver, js_value, '\n\n\n'
200 if '%s' in receiver:
201 return receiver % js_value
202 return receiver
203
204 def create_statements(receiver, js_value):
205 if isinstance(receiver, str):
206 return create_statement(receiver, js_value)
207 if isinstance(receiver, list):
208 return '\n'.join([create_statement(each_receiver, js_value) for each _receiver in receiver])
209 raise Exception('receiver should be string or list')
210
211 if not isolate:
212 raise Exception('An Isolate is mandatory for native value => JS value co nversion.')
213
214 includes = []
215
216 if is_union_type(idl_type):
217 codes = []
218 for i, union_member_type in enumerate(idl_type.union_member_types):
219 union_member_number = i
220 union_member_variable = '%s%d' % (native_value, union_member_number)
221 union_member_enabled_variable = '%s%dEnabled' % (native_value, union _member_number)
222 union_member_native_value = get_pass_owner_expression(union_member_t ype, union_member_variable)
223 return_js_value_code, union_member_includes = get_native_to_js_value _statement(union_member_type, extended_attributes, union_member_native_value, re ceiver=receiver, creation_context=creation_context, isolate=isolate, callback_in fo=callback_info, script_wrappable=script_wrappable, for_main_world_suffix=for_m ain_world_suffix, indent=indent + indent, used_as_return_value=used_as_return_va lue)
224 includes += union_member_includes
225 code = ''
226 if used_as_return_value:
227 code += indent + 'if (%s) {\n' % union_member_enabled_variable
228 code += indent + indent + return_js_value_code + '\n'
229 code += indent + indent + 'return;\n'
230 code += indent + '}\n'
231 else:
232 code += indent + 'if (%s) {\n' % union_member_enabled_variable
233 code += return_js_value_code + '\n'
234 codes.append(code)
235 # print '[]', codes
236 return '\n'.join(codes), includes
237
238 native_type = get_native_type(idl_type)
239
240 if idl_type == 'boolean':
241 if used_as_return_value:
242 # receiver = ['%s;', 'return;']
243 receiver = ['%s;']
244 return create_statements(receiver, 'v8SetReturnValueBool(%s, %s)' % (callback_info, native_value)), includes
245 return create_statements(receiver, 'v8Boolean(%s, %s)' % (native_value, isolate)), includes
246
247 if idl_type == 'void':
248 if used_as_return_value:
249 # return 'return;', includes
250 return '', includes
251 return create_statements(receiver, 'v8Undefined()'), includes
252
253 # HTML5 says that unsigned reflected attributes should be in the range
254 # [0, 2^31). When a value isn't in this range, a default value (or 0)
255 # should be returned instead.
256 if 'Reflect' in extended_attributes and (idl_type in ['unsigned long', 'unsi gned short']):
257 native_value = native_value.replace('getUnsignedIntegralAttribute', 'get IntegralAttribute')
258 if used_as_return_value:
259 receiver = ['%s;']
260 return create_statements(receiver, 'v8SetReturnValueUnsigned(%s, std ::max(0, %s))' % (callback_info, native_value)), includes
261 return create_statements(receiver, 'v8::Integer::NewFromUnsigned(std::ma x(0, %s), %s);' % (native_value, isolate)), includes
262
263 if native_type == 'int':
264 if used_as_return_value:
265 # receiver = ['%s;', 'return;']
266 receiver = ['%s;']
267 return create_statements(receiver, 'v8SetReturnValueInt(%s, %s)' % ( callback_info, native_value)), includes
268 return create_statements(receiver, 'v8::Integer::New(%s, %s)' % (native_ value, isolate)), includes
269
270 if native_type == 'unsigned':
271 if used_as_return_value:
272 # receiver = ['%s;', 'return;']
273 receiver = ['%s;']
274 return create_statements(receiver, 'v8SetReturnValueUnsigned(%s, %s) ' % (callback_info, native_value)), includes
275 return create_statements(receiver, 'v8::Integer::NewFromUnsigned(%s, %s) ' % (native_value, isolate)), includes
276
277 if idl_type == 'Date':
278 if used_as_return_value:
279 # receiver = ['%s;', 'return;']
280 # receiver = ['v8SetReturnValue(%s, %%s);' % callback_info, 'ret urn;']
281 receiver = ['v8SetReturnValue(%s, %%s);' % callback_info]
282 # return create_statements(receiver, 'v8SetReturnValue(%s, v8Dat eOrNull(%s, %s))' % (callback_info, native_value, isolate)), includes
283 return create_statements(receiver, 'v8DateOrNull(%s, %s)' % (native_valu e, isolate)), includes
284
285 # long long and unsigned long long are not representable in ECMAScript.
286 if idl_type in ['long long', 'unsigned long long', 'DOMTimeStamp']:
287 if used_as_return_value:
288 # receiver = ['%s;', 'return;']
289 receiver = ['%s;']
290 return create_statements(receiver, 'v8SetReturnValue(%s, static_cast <double>(%s))' % (callback_info, native_value)), includes
291 return create_statements(receiver, 'v8::Number::New(static_cast<double>( %s))' % native_value), includes
292
293 if is_primitive_type(idl_type):
294 if idl_type not in ['float', 'double']:
295 raise Exception('unexpected type %s' % idl_type)
296 if used_as_return_value:
297 # receiver = ['%s;', 'return;']
298 receiver = ['%s;']
299 return create_statements(receiver, 'v8SetReturnValue(%s, %s)' % (cal lback_info, native_value)), includes
300 return create_statements(receiver, 'v8::Number::New(%s)' % native_value) , includes
301
302 if native_type == 'ScriptValue':
303 if used_as_return_value:
304 receiver = ['v8SetReturnValue(%s, %%s);' % callback_info]
305 js_value = '%s.v8Value()' % native_value
306 return create_statements(receiver, js_value), includes
307
308 if idl_type == 'DOMString' or is_enum_type(idl_type):
309 conversion = extended_attributes.get('TreatReturnedNullStringAs')
310 js_value = ''
311 null_as = ''
312 function_suffix = ''
313 arguments = create_arguments([native_value, isolate])
314 if conversion is None:
315 null_as = 'NullStringAsEmpty'
316 js_value = 'v8String(%s)' % arguments
317 elif conversion == 'Null':
318 null_as = 'NullStringAsNull'
319 js_value = 'v8StringOrNull(%s)' % arguments
320 function_suffix = 'OrNull'
321 elif conversion == 'Undefined':
322 null_as = 'NullStringAsUndefined'
323 js_value = 'v8StringOrUndefined(%s)' % arguments
324 function_suffix = 'OrUndefined'
325 else:
326 raise Exception('Unknown value for TreatReturnedNullStringAs extende d attribute')
327
328 if used_as_return_value:
329 receiver = ['v8SetReturnValueString%s(%s, %%s, %s);' % (function_suf fix, callback_info, isolate)]
330 return create_statements(receiver, native_value), includes
331 return create_statements(receiver, js_value), includes
332
333 array_or_sequence_type = get_array_or_sequence_type(idl_type)
334 if array_or_sequence_type:
335 if is_ref_ptr_type(array_or_sequence_type):
336 includes += get_includes_for_type(array_or_sequence_type)
337 if used_as_return_value:
338 # receiver = ['v8SetReturnValue(%s, %%s);' % callback_info, 'ret urn;']
339 receiver = ['v8SetReturnValue(%s, %%s);' % callback_info]
340 # return create_statements(receiver, 'v8SetReturnValue(%s, v8Arr ay(%s, %s))' % (callback_info, native_value, isolate)), includes
341 return create_statements(receiver, 'v8Array(%s, %s)' % (native_value, is olate)), includes
342
343 includes += get_includes_for_type(idl_type)
344
345 if idl_type == 'SerializedScriptValue':
346 includes.append('%s.h' % idl_type)
347 if used_as_return_value:
348 receiver = ['v8SetReturnValue(%s, %%s);' % callback_info]
349 js_value = '%s ? %s->deserialize() : v8::Handle<v8::Value>(v8::Null(%s)) ' % (native_value, native_value, isolate)
350 return create_statements(receiver, js_value), includes
351
352 includes.append('wtf/RefPtr.h')
353 includes.append('wtf/GetPtr.h')
354
355 if used_as_return_value:
356 # receiver = ['v8SetReturnValue(%s, %%s);' % callback_info, 'return; ']
357 receiver = ['v8SetReturnValue(%s, %%s);' % callback_info]
358
359 if script_wrappable:
360 # FIXME: Use safe handles
361 if for_main_world_suffix == 'ForMainWorld':
362 return create_statements(receiver, 'toV8ForMainWorld(%s, %s.Holder() , %s.GetIsolate())' % (native_value, callback_info, callback_info)), includes
363 return create_statements(receiver, 'toV8Fast(%s, %s, %s)' % (native_valu e, callback_info, script_wrappable)), includes
364
365 # FIXME: Use safe handles
366 return create_statements(receiver, 'toV8(%s, %s, %s)' % (native_value, creat ion_context, isolate)), includes
OLDNEW
« no previous file with comments | « Source/bindings/scripts/v8_utilities.py ('k') | Source/bindings/templates/attributes.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698