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 18 matching lines...) Expand all Loading... | |
29 """Generate Blink V8 bindings (.h and .cpp files). | 29 """Generate Blink V8 bindings (.h and .cpp files). |
30 | 30 |
31 Input: An object of class IdlDefinitions, containing an IDL interface X | 31 Input: An object of class IdlDefinitions, containing an IDL interface X |
32 Output: V8X.h and V8X.cpp | 32 Output: V8X.h and V8X.cpp |
33 """ | 33 """ |
34 | 34 |
35 import os | 35 import os |
36 import posixpath | 36 import posixpath |
37 import re | 37 import re |
38 import sys | 38 import sys |
39 import idl_definitions | |
39 | 40 |
40 # jinja2 is in chromium's third_party directory. | 41 # jinja2 is in chromium's third_party directory. |
41 module_path, module_name = os.path.split(__file__) | 42 module_path, module_name = os.path.split(__file__) |
42 third_party = os.path.join(module_path, os.pardir, os.pardir, os.pardir, os.pard ir) | 43 third_party = os.path.join(module_path, os.pardir, os.pardir, os.pardir, os.pard ir) |
43 sys.path.append(third_party) | 44 sys.path.append(third_party) |
44 import jinja2 | 45 import jinja2 |
45 | 46 |
46 | 47 |
47 CALLBACK_INTERFACE_CPP_INCLUDES = set([ | 48 CALLBACK_INTERFACE_CPP_INCLUDES = set([ |
48 'core/dom/ScriptExecutionContext.h', | 49 'core/dom/ScriptExecutionContext.h', |
49 'bindings/v8/V8Binding.h', | 50 'bindings/v8/V8Binding.h', |
50 'bindings/v8/V8Callback.h', | 51 'bindings/v8/V8Callback.h', |
51 'wtf/Assertions.h', | 52 'wtf/Assertions.h', |
52 ]) | 53 ]) |
53 | 54 |
54 | 55 |
55 CALLBACK_INTERFACE_H_INCLUDES = set([ | 56 CALLBACK_INTERFACE_H_INCLUDES = set([ |
56 'bindings/v8/ActiveDOMCallback.h', | 57 'bindings/v8/ActiveDOMCallback.h', |
57 'bindings/v8/DOMWrapperWorld.h', | 58 'bindings/v8/DOMWrapperWorld.h', |
58 'bindings/v8/ScopedPersistent.h', | 59 'bindings/v8/ScopedPersistent.h', |
59 ]) | 60 ]) |
60 | 61 |
61 | 62 |
62 CPP_TYPE_SPECIAL_CONVERSION_RULES = { | 63 CPP_TYPE_SPECIAL_CONVERSION_RULES = { |
64 'any': 'ScriptValue', | |
63 'float': 'float', | 65 'float': 'float', |
64 'double': 'double', | 66 'double': 'double', |
65 'long long': 'long long', | 67 'long long': 'long long', |
66 'unsigned long long': 'unsigned long long', | 68 'unsigned long long': 'unsigned long long', |
67 'long': 'int', | 69 'long': 'int', |
68 'short': 'int', | 70 'short': 'int', |
69 'byte': 'int', | 71 'byte': 'int', |
70 'boolean': 'bool', | 72 'boolean': 'bool', |
71 'DOMString': 'const String&', | 73 'DOMString': 'const String&', |
72 } | 74 } |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
110 return 'Vector<%s >' % cpp_type(sequence_type(data_type), 'RefPtr') | 112 return 'Vector<%s >' % cpp_type(sequence_type(data_type), 'RefPtr') |
111 if pointer_type == 'raw': | 113 if pointer_type == 'raw': |
112 return data_type + '*' | 114 return data_type + '*' |
113 if pointer_type == 'RefPtr': | 115 if pointer_type == 'RefPtr': |
114 return 'RefPtr<%s>' % data_type | 116 return 'RefPtr<%s>' % data_type |
115 return '' | 117 return '' |
116 | 118 |
117 | 119 |
118 def cpp_value_to_js_value(data_type, cpp_value, isolate, creation_context=''): | 120 def cpp_value_to_js_value(data_type, cpp_value, isolate, creation_context=''): |
119 """Returns a expression that represent JS value corresponding to a C++ value .""" | 121 """Returns a expression that represent JS value corresponding to a C++ value .""" |
122 if data_type == 'any': | |
123 return '%s.v8Value()' % cpp_value | |
120 if data_type == 'boolean': | 124 if data_type == 'boolean': |
121 return 'v8Boolean(%s, %s)' % (cpp_value, isolate) | 125 return 'v8Boolean(%s, %s)' % (cpp_value, isolate) |
122 if data_type in ['long long', 'unsigned long long', 'DOMTimeStamp']: | 126 if data_type in ['long long', 'unsigned long long', 'DOMTimeStamp']: |
123 # long long and unsigned long long are not representable in ECMAScript. | 127 # long long and unsigned long long are not representable in ECMAScript. |
124 return 'v8::Number::New(static_cast<double>(%s))' % cpp_value | 128 return 'v8::Number::New(static_cast<double>(%s))' % cpp_value |
125 if primitive_type(data_type): | 129 if primitive_type(data_type): |
126 if data_type not in ['float', 'double']: | 130 if data_type not in ['float', 'double']: |
127 raise Exception('unexpected data_type %s' % data_type) | 131 raise Exception('unexpected data_type %s' % data_type) |
128 return 'v8::Number::New(%s)' % cpp_value | 132 return 'v8::Number::New(%s)' % cpp_value |
129 if data_type == 'DOMString': | 133 if data_type == 'DOMString': |
(...skipping 11 matching lines...) Expand all Loading... | |
141 if operator in conditional: | 145 if operator in conditional: |
142 conditions = set(conditional.split(operator)) | 146 conditions = set(conditional.split(operator)) |
143 operator_separator = ' %s%s ' % (operator, operator) | 147 operator_separator = ' %s%s ' % (operator, operator) |
144 return operator_separator.join(['ENABLE(%s)' % expression for expres sion in sorted(conditions)]) | 148 return operator_separator.join(['ENABLE(%s)' % expression for expres sion in sorted(conditions)]) |
145 return 'ENABLE(%s)' % conditional | 149 return 'ENABLE(%s)' % conditional |
146 | 150 |
147 | 151 |
148 def includes_for_type(data_type): | 152 def includes_for_type(data_type): |
149 if primitive_type(data_type) or data_type == 'DOMString': | 153 if primitive_type(data_type) or data_type == 'DOMString': |
150 return set() | 154 return set() |
155 if data_type == 'any': | |
156 return set(['bindings/v8/ScriptValue.h']) | |
151 if sequence_type(data_type): | 157 if sequence_type(data_type): |
152 return includes_for_type(sequence_type(data_type)) | 158 return includes_for_type(sequence_type(data_type)) |
153 return set(['V8%s.h' % data_type]) | 159 return set(['V8%s.h' % data_type]) |
154 | 160 |
155 | 161 |
156 def includes_for_operation(operation): | 162 def includes_for_operation(operation): |
157 includes = includes_for_type(operation.data_type) | 163 includes = includes_for_type(operation.data_type) |
158 for parameter in operation.arguments: | 164 for parameter in operation.arguments: |
159 includes |= includes_for_type(parameter.data_type) | 165 includes |= includes_for_type(parameter.data_type) |
160 return includes | 166 return includes |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
223 self.write_cpp_code(cpp_basename, contents) | 229 self.write_cpp_code(cpp_basename, contents) |
224 | 230 |
225 def write_header_and_cpp(self): | 231 def write_header_and_cpp(self): |
226 header_basename = v8_class_name(self.interface) + '.h' | 232 header_basename = v8_class_name(self.interface) + '.h' |
227 cpp_basename = v8_class_name(self.interface) + '.cpp' | 233 cpp_basename = v8_class_name(self.interface) + '.cpp' |
228 template_contents = { | 234 template_contents = { |
229 'conditional_string': generate_conditional_string(self.interface), | 235 'conditional_string': generate_conditional_string(self.interface), |
230 } | 236 } |
231 if self.interface.is_callback: | 237 if self.interface.is_callback: |
232 template_contents.update(self.generate_callback_interface()) | 238 template_contents.update(self.generate_callback_interface()) |
233 header_file_text = apply_template('templates/callback.h', template_c ontents) | 239 header_file_text = apply_template('templates/callback.h.tmpl', templ ate_contents) |
234 cpp_file_text = apply_template('templates/callback.cpp', template_co ntents) | 240 cpp_file_text = apply_template('templates/callback.cpp.tmpl', templa te_contents) |
235 else: | 241 else: |
236 # FIXME: Implement. | 242 # FIXME: Implement. |
237 header_file_text = '' | 243 header_file_text = '' |
238 cpp_file_text = '' | 244 cpp_file_text = '' |
239 self.write_header_code(header_basename, header_file_text) | 245 self.write_header_code(header_basename, header_file_text) |
240 self.write_cpp_code(cpp_basename, cpp_file_text) | 246 self.write_cpp_code(cpp_basename, cpp_file_text) |
241 | 247 |
242 def write_header_code(self, header_basename, header_file_text): | 248 def write_header_code(self, header_basename, header_file_text): |
243 header_filename = os.path.join(self.output_directory, header_basename) | 249 header_filename = os.path.join(self.output_directory, header_basename) |
244 with open(header_filename, 'w') as header_file: | 250 with open(header_filename, 'w') as header_file: |
(...skipping 14 matching lines...) Expand all Loading... | |
259 cpp_to_js_conversion = self.generate_cpp_to_js_conversion(argument.d ata_type, argument.name, receiver, 'isolate', creation_context='v8::Handle<v8::O bject>()') | 265 cpp_to_js_conversion = self.generate_cpp_to_js_conversion(argument.d ata_type, argument.name, receiver, 'isolate', creation_context='v8::Handle<v8::O bject>()') |
260 return { | 266 return { |
261 'name': argument.name, | 267 'name': argument.name, |
262 'cpp_to_js_conversion': cpp_to_js_conversion, | 268 'cpp_to_js_conversion': cpp_to_js_conversion, |
263 } | 269 } |
264 | 270 |
265 def generate_method(operation): | 271 def generate_method(operation): |
266 def argument_declaration(argument): | 272 def argument_declaration(argument): |
267 return '%s %s' % (cpp_type(argument.data_type, 'raw'), argument. name) | 273 return '%s %s' % (cpp_type(argument.data_type, 'raw'), argument. name) |
268 | 274 |
275 # FIXME: The CallWith extended attribute should be parsed into a lis t of values | |
276 call_with_this_value = 'ThisValue' in operation.extended_attributes. get('CallWith', '').split('|') | |
haraken
2013/08/05 10:52:41
Could you implement a helper method so that we can
alancutter (OOO until 2018)
2013/08/06 04:47:13
Done.
| |
277 this_value_argument = generate_argument(idl_definitions.IdlArgument( 'thisValue', 'any')) | |
278 declaration_arguments = operation.arguments | |
279 if call_with_this_value: | |
280 declaration_arguments = [idl_definitions.IdlArgument('thisValue' , 'any')] + declaration_arguments | |
haraken
2013/08/05 10:52:41
Can't you write this as follows?
operation.argu
| |
281 | |
269 arguments = [] | 282 arguments = [] |
270 custom = 'Custom' in operation.extended_attributes | 283 custom = 'Custom' in operation.extended_attributes |
271 if not custom: | 284 if not custom: |
272 self.cpp_includes |= includes_for_operation(operation) | 285 self.cpp_includes |= includes_for_operation(operation) |
273 if operation.data_type != 'boolean': | 286 if operation.data_type != 'boolean': |
274 raise Exception("We don't yet support callbacks that return non-boolean values.") | 287 raise Exception("We don't yet support callbacks that return non-boolean values.") |
275 arguments = [generate_argument(argument) for argument in operati on.arguments] | 288 arguments = [generate_argument(argument) for argument in operati on.arguments] |
276 method = { | 289 method = { |
290 'call_with_this_value': call_with_this_value, | |
291 'this_value_argument': this_value_argument, | |
277 'return_type': cpp_type(operation.data_type, 'RefPtr'), | 292 'return_type': cpp_type(operation.data_type, 'RefPtr'), |
278 'name': operation.name, | 293 'name': operation.name, |
279 'arguments': arguments, | 294 'arguments': arguments, |
280 'argument_declaration': ', '.join([argument_declaration(argument ) for argument in operation.arguments]), | 295 'argument_declaration': ', '.join([argument_declaration(argument ) for argument in declaration_arguments]), |
281 'handles': ', '.join(['%sHandle' % argument.name for argument in operation.arguments]), | 296 'handles': ', '.join(['%sHandle' % argument.name for argument in operation.arguments]), |
282 'custom': custom, | 297 'custom': custom, |
283 } | 298 } |
284 return method | 299 return method |
285 | 300 |
286 methods = [generate_method(operation) for operation in self.interface.op erations] | 301 methods = [generate_method(operation) for operation in self.interface.op erations] |
287 template_contents = { | 302 template_contents = { |
288 'cpp_class_name': self.interface.name, | 303 'cpp_class_name': self.interface.name, |
289 'v8_class_name': v8_class_name(self.interface), | 304 'v8_class_name': v8_class_name(self.interface), |
290 'cpp_includes': sorted(list(self.cpp_includes)), | 305 'cpp_includes': sorted(list(self.cpp_includes)), |
291 'header_includes': sorted(list(self.header_includes)), | 306 'header_includes': sorted(list(self.header_includes)), |
292 'methods': methods, | 307 'methods': methods, |
293 } | 308 } |
294 return template_contents | 309 return template_contents |
OLD | NEW |