OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # | 2 # |
3 # Copyright 2006-2008 the V8 project authors. All rights reserved. | 3 # Copyright 2006-2008 the V8 project authors. All rights reserved. |
4 # Redistribution and use in source and binary forms, with or without | 4 # Redistribution and use in source and binary forms, with or without |
5 # modification, are permitted provided that the following conditions are | 5 # modification, are permitted provided that the following conditions are |
6 # met: | 6 # met: |
7 # | 7 # |
8 # * Redistributions of source code must retain the above copyright | 8 # * Redistributions of source code must retain the above copyright |
9 # notice, this list of conditions and the following disclaimer. | 9 # notice, this list of conditions and the following disclaimer. |
10 # * Redistributions in binary form must reproduce the above | 10 # * Redistributions in binary form must reproduce the above |
(...skipping 15 matching lines...) Expand all Loading... |
26 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
28 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 | 29 |
30 # This is a utility for converting JavaScript source code into C-style | 30 # This is a utility for converting JavaScript source code into C-style |
31 # char arrays. It is used for embedded JavaScript code in the V8 | 31 # char arrays. It is used for embedded JavaScript code in the V8 |
32 # library. | 32 # library. |
33 | 33 |
34 import os, re, sys, string | 34 import os, re, sys, string |
35 import jsmin | 35 import jsmin |
| 36 import bz2 |
| 37 |
| 38 |
| 39 def ToCAsciiArray(lines): |
| 40 result = [] |
| 41 for chr in lines: |
| 42 value = ord(chr) |
| 43 assert value < 128 |
| 44 result.append(str(value)) |
| 45 return ", ".join(result) |
36 | 46 |
37 | 47 |
38 def ToCArray(lines): | 48 def ToCArray(lines): |
39 result = [] | 49 result = [] |
40 for chr in lines: | 50 for chr in lines: |
41 value = ord(chr) | 51 result.append(str(ord(chr))) |
42 assert value < 128 | |
43 result.append(str(value)) | |
44 result.append("0") | |
45 return ", ".join(result) | 52 return ", ".join(result) |
46 | 53 |
47 | 54 |
48 def RemoveCommentsAndTrailingWhitespace(lines): | 55 def RemoveCommentsAndTrailingWhitespace(lines): |
49 lines = re.sub(r'//.*\n', '\n', lines) # end-of-line comments | 56 lines = re.sub(r'//.*\n', '\n', lines) # end-of-line comments |
50 lines = re.sub(re.compile(r'/\*.*?\*/', re.DOTALL), '', lines) # comments. | 57 lines = re.sub(re.compile(r'/\*.*?\*/', re.DOTALL), '', lines) # comments. |
51 lines = re.sub(r'\s+\n+', '\n', lines) # trailing whitespace | 58 lines = re.sub(r'\s+\n+', '\n', lines) # trailing whitespace |
52 return lines | 59 return lines |
53 | 60 |
54 | 61 |
(...skipping 25 matching lines...) Expand all Loading... |
80 | 87 |
81 | 88 |
82 def ParseValue(string): | 89 def ParseValue(string): |
83 string = string.strip() | 90 string = string.strip() |
84 if string.startswith('[') and string.endswith(']'): | 91 if string.startswith('[') and string.endswith(']'): |
85 return string.lstrip('[').rstrip(']').split() | 92 return string.lstrip('[').rstrip(']').split() |
86 else: | 93 else: |
87 return string | 94 return string |
88 | 95 |
89 | 96 |
90 EVAL_PATTERN = re.compile(r'\beval\s*\('); | 97 EVAL_PATTERN = re.compile(r'\beval\s*\(') |
91 WITH_PATTERN = re.compile(r'\bwith\s*\('); | 98 WITH_PATTERN = re.compile(r'\bwith\s*\(') |
92 | 99 |
93 | 100 |
94 def Validate(lines, file): | 101 def Validate(lines, file): |
95 lines = RemoveCommentsAndTrailingWhitespace(lines) | 102 lines = RemoveCommentsAndTrailingWhitespace(lines) |
96 # Because of simplified context setup, eval and with is not | 103 # Because of simplified context setup, eval and with is not |
97 # allowed in the natives files. | 104 # allowed in the natives files. |
98 eval_match = EVAL_PATTERN.search(lines) | 105 eval_match = EVAL_PATTERN.search(lines) |
99 if eval_match: | 106 if eval_match: |
100 raise ("Eval disallowed in natives: %s" % file) | 107 raise ("Eval disallowed in natives: %s" % file) |
101 with_match = WITH_PATTERN.search(lines) | 108 with_match = WITH_PATTERN.search(lines) |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 | 212 |
206 HEADER_TEMPLATE = """\ | 213 HEADER_TEMPLATE = """\ |
207 // Copyright 2011 Google Inc. All Rights Reserved. | 214 // Copyright 2011 Google Inc. All Rights Reserved. |
208 | 215 |
209 // This file was generated from .js source files by SCons. If you | 216 // This file was generated from .js source files by SCons. If you |
210 // want to make changes to this file you should either change the | 217 // want to make changes to this file you should either change the |
211 // javascript source files or the SConstruct script. | 218 // javascript source files or the SConstruct script. |
212 | 219 |
213 #include "v8.h" | 220 #include "v8.h" |
214 #include "natives.h" | 221 #include "natives.h" |
| 222 #include "utils.h" |
215 | 223 |
216 namespace v8 { | 224 namespace v8 { |
217 namespace internal { | 225 namespace internal { |
218 | 226 |
219 %(source_lines)s\ | 227 static const byte sources[] = { %(sources_data)s }; |
| 228 |
| 229 %(raw_sources_declaration)s\ |
220 | 230 |
221 template <> | 231 template <> |
222 int NativesCollection<%(type)s>::GetBuiltinsCount() { | 232 int NativesCollection<%(type)s>::GetBuiltinsCount() { |
223 return %(builtin_count)i; | 233 return %(builtin_count)i; |
224 } | 234 } |
225 | 235 |
226 template <> | 236 template <> |
227 int NativesCollection<%(type)s>::GetDebuggerCount() { | 237 int NativesCollection<%(type)s>::GetDebuggerCount() { |
228 return %(debugger_count)i; | 238 return %(debugger_count)i; |
229 } | 239 } |
230 | 240 |
231 template <> | 241 template <> |
232 int NativesCollection<%(type)s>::GetIndex(const char* name) { | 242 int NativesCollection<%(type)s>::GetIndex(const char* name) { |
233 %(get_index_cases)s\ | 243 %(get_index_cases)s\ |
234 return -1; | 244 return -1; |
235 } | 245 } |
236 | 246 |
237 template <> | 247 template <> |
238 Vector<const char> NativesCollection<%(type)s>::GetScriptSource(int index) { | 248 int NativesCollection<%(type)s>::GetRawScriptsSize() { |
239 %(get_script_source_cases)s\ | 249 return %(raw_total_length)i; |
| 250 } |
| 251 |
| 252 template <> |
| 253 Vector<const char> NativesCollection<%(type)s>::GetRawScriptSource(int index)
{ |
| 254 %(get_raw_script_source_cases)s\ |
240 return Vector<const char>("", 0); | 255 return Vector<const char>("", 0); |
241 } | 256 } |
242 | 257 |
243 template <> | 258 template <> |
244 Vector<const char> NativesCollection<%(type)s>::GetScriptName(int index) { | 259 Vector<const char> NativesCollection<%(type)s>::GetScriptName(int index) { |
245 %(get_script_name_cases)s\ | 260 %(get_script_name_cases)s\ |
246 return Vector<const char>("", 0); | 261 return Vector<const char>("", 0); |
247 } | 262 } |
248 | 263 |
| 264 template <> |
| 265 Vector<const byte> NativesCollection<%(type)s>::GetScriptsSource() { |
| 266 return Vector<const byte>(sources, %(total_length)i); |
| 267 } |
| 268 |
| 269 template <> |
| 270 void NativesCollection<%(type)s>::SetRawScriptsSource(Vector<const char> raw_s
ource) { |
| 271 ASSERT(%(raw_total_length)i == raw_source.length()); |
| 272 raw_sources = raw_source.start(); |
| 273 } |
| 274 |
249 } // internal | 275 } // internal |
250 } // v8 | 276 } // v8 |
251 """ | 277 """ |
252 | 278 |
253 | 279 |
254 SOURCE_DECLARATION = """\ | 280 RAW_SOURCES_COMPRESSION_DECLARATION = """\ |
255 static const char %(id)s[] = { %(data)s }; | 281 static const char* raw_sources = NULL; |
256 """ | 282 """ |
257 | 283 |
258 | 284 |
259 GET_DEBUGGER_INDEX_CASE = """\ | 285 RAW_SOURCES_DECLARATION = """\ |
| 286 static const char* raw_sources = reinterpret_cast<const char*>(sources); |
| 287 """ |
| 288 |
| 289 |
| 290 GET_INDEX_CASE = """\ |
260 if (strcmp(name, "%(id)s") == 0) return %(i)i; | 291 if (strcmp(name, "%(id)s") == 0) return %(i)i; |
261 """ | 292 """ |
262 | 293 |
263 | 294 |
264 GET_DEBUGGER_SCRIPT_SOURCE_CASE = """\ | 295 GET_RAW_SCRIPT_SOURCE_CASE = """\ |
265 if (index == %(i)i) return Vector<const char>(%(id)s, %(length)i); | 296 if (index == %(i)i) return Vector<const char>(raw_sources + %(offset)i, %(ra
w_length)i); |
266 """ | 297 """ |
267 | 298 |
268 | 299 |
269 GET_DEBUGGER_SCRIPT_NAME_CASE = """\ | 300 GET_SCRIPT_NAME_CASE = """\ |
270 if (index == %(i)i) return Vector<const char>("%(name)s", %(length)i); | 301 if (index == %(i)i) return Vector<const char>("%(name)s", %(length)i); |
271 """ | 302 """ |
272 | 303 |
273 def JS2C(source, target, env): | 304 def JS2C(source, target, env): |
274 ids = [] | 305 ids = [] |
275 debugger_ids = [] | 306 debugger_ids = [] |
276 modules = [] | 307 modules = [] |
277 # Locate the macros file name. | 308 # Locate the macros file name. |
278 consts = [] | 309 consts = [] |
279 macros = [] | 310 macros = [] |
280 for s in source: | 311 for s in source: |
281 if 'macros.py' == (os.path.split(str(s))[1]): | 312 if 'macros.py' == (os.path.split(str(s))[1]): |
282 (consts, macros) = ReadMacros(ReadLines(str(s))) | 313 (consts, macros) = ReadMacros(ReadLines(str(s))) |
283 else: | 314 else: |
284 modules.append(s) | 315 modules.append(s) |
285 | 316 |
286 # Build source code lines | |
287 source_lines = [ ] | |
288 | |
289 minifier = jsmin.JavaScriptMinifier() | 317 minifier = jsmin.JavaScriptMinifier() |
290 | 318 |
| 319 module_offset = 0 |
| 320 all_sources = [] |
291 for module in modules: | 321 for module in modules: |
292 filename = str(module) | 322 filename = str(module) |
293 debugger = filename.endswith('-debugger.js') | 323 debugger = filename.endswith('-debugger.js') |
294 lines = ReadFile(filename) | 324 lines = ReadFile(filename) |
295 lines = ExpandConstants(lines, consts) | 325 lines = ExpandConstants(lines, consts) |
296 lines = ExpandMacros(lines, macros) | 326 lines = ExpandMacros(lines, macros) |
297 Validate(lines, filename) | 327 Validate(lines, filename) |
298 lines = minifier.JSMinify(lines) | 328 lines = minifier.JSMinify(lines) |
299 data = ToCArray(lines) | |
300 id = (os.path.split(filename)[1])[:-3] | 329 id = (os.path.split(filename)[1])[:-3] |
301 if debugger: id = id[:-9] | 330 if debugger: id = id[:-9] |
| 331 raw_length = len(lines) |
302 if debugger: | 332 if debugger: |
303 debugger_ids.append((id, len(lines))) | 333 debugger_ids.append((id, raw_length, module_offset)) |
304 else: | 334 else: |
305 ids.append((id, len(lines))) | 335 ids.append((id, raw_length, module_offset)) |
306 source_lines.append(SOURCE_DECLARATION % { 'id': id, 'data': data }) | 336 all_sources.append(lines) |
| 337 module_offset += raw_length |
| 338 total_length = raw_total_length = module_offset |
| 339 |
| 340 if env['COMPRESSION'] == 'off': |
| 341 raw_sources_declaration = RAW_SOURCES_DECLARATION |
| 342 sources_data = ToCAsciiArray("".join(all_sources)) |
| 343 else: |
| 344 raw_sources_declaration = RAW_SOURCES_COMPRESSION_DECLARATION |
| 345 if env['COMPRESSION'] == 'bz2': |
| 346 all_sources = bz2.compress("".join(all_sources)) |
| 347 total_length = len(all_sources) |
| 348 sources_data = ToCArray(all_sources) |
307 | 349 |
308 # Build debugger support functions | 350 # Build debugger support functions |
309 get_index_cases = [ ] | 351 get_index_cases = [ ] |
310 get_script_source_cases = [ ] | 352 get_raw_script_source_cases = [ ] |
311 get_script_name_cases = [ ] | 353 get_script_name_cases = [ ] |
312 | 354 |
313 i = 0 | 355 i = 0 |
314 for (id, length) in debugger_ids: | 356 for (id, raw_length, module_offset) in debugger_ids + ids: |
315 native_name = "native %s.js" % id | 357 native_name = "native %s.js" % id |
316 get_index_cases.append(GET_DEBUGGER_INDEX_CASE % { 'id': id, 'i': i }) | 358 get_index_cases.append(GET_INDEX_CASE % { 'id': id, 'i': i }) |
317 get_script_source_cases.append(GET_DEBUGGER_SCRIPT_SOURCE_CASE % { | 359 get_raw_script_source_cases.append(GET_RAW_SCRIPT_SOURCE_CASE % { |
318 'id': id, | 360 'offset': module_offset, |
319 'length': length, | 361 'raw_length': raw_length, |
320 'i': i | 362 'i': i |
321 }) | 363 }) |
322 get_script_name_cases.append(GET_DEBUGGER_SCRIPT_NAME_CASE % { | 364 get_script_name_cases.append(GET_SCRIPT_NAME_CASE % { |
323 'name': native_name, | 365 'name': native_name, |
324 'length': len(native_name), | 366 'length': len(native_name), |
325 'i': i | 367 'i': i |
326 }); | 368 }) |
327 i = i + 1 | |
328 | |
329 for (id, length) in ids: | |
330 native_name = "native %s.js" % id | |
331 get_index_cases.append(GET_DEBUGGER_INDEX_CASE % { 'id': id, 'i': i }) | |
332 get_script_source_cases.append(GET_DEBUGGER_SCRIPT_SOURCE_CASE % { | |
333 'id': id, | |
334 'length': length, | |
335 'i': i | |
336 }) | |
337 get_script_name_cases.append(GET_DEBUGGER_SCRIPT_NAME_CASE % { | |
338 'name': native_name, | |
339 'length': len(native_name), | |
340 'i': i | |
341 }); | |
342 i = i + 1 | 369 i = i + 1 |
343 | 370 |
344 # Emit result | 371 # Emit result |
345 output = open(str(target[0]), "w") | 372 output = open(str(target[0]), "w") |
346 output.write(HEADER_TEMPLATE % { | 373 output.write(HEADER_TEMPLATE % { |
347 'builtin_count': len(ids) + len(debugger_ids), | 374 'builtin_count': len(ids) + len(debugger_ids), |
348 'debugger_count': len(debugger_ids), | 375 'debugger_count': len(debugger_ids), |
349 'source_lines': "\n".join(source_lines), | 376 'sources_data': sources_data, |
| 377 'raw_sources_declaration': raw_sources_declaration, |
| 378 'raw_total_length': raw_total_length, |
| 379 'total_length': total_length, |
350 'get_index_cases': "".join(get_index_cases), | 380 'get_index_cases': "".join(get_index_cases), |
351 'get_script_source_cases': "".join(get_script_source_cases), | 381 'get_raw_script_source_cases': "".join(get_raw_script_source_cases), |
352 'get_script_name_cases': "".join(get_script_name_cases), | 382 'get_script_name_cases': "".join(get_script_name_cases), |
353 'type': env['TYPE'] | 383 'type': env['TYPE'] |
354 }) | 384 }) |
355 output.close() | 385 output.close() |
356 | 386 |
357 def main(): | 387 def main(): |
358 natives = sys.argv[1] | 388 natives = sys.argv[1] |
359 type = sys.argv[2] | 389 type = sys.argv[2] |
360 source_files = sys.argv[3:] | 390 compression = sys.argv[3] |
361 JS2C(source_files, [natives], { 'TYPE': type }) | 391 source_files = sys.argv[4:] |
| 392 JS2C(source_files, [natives], { 'TYPE': type, 'COMPRESSION': compression }) |
362 | 393 |
363 if __name__ == "__main__": | 394 if __name__ == "__main__": |
364 main() | 395 main() |
OLD | NEW |