Chromium Code Reviews| 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 %(source_lines)s\ |
| 220 | 228 |
| 229 %(raw_source_lines)s\ | |
| 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>::GetRawScriptSize(int index) { |
| 239 %(get_script_source_cases)s\ | 249 %(get_raw_script_size_cases)s\ |
| 250 return -1; | |
| 251 } | |
| 252 | |
| 253 template <> | |
| 254 Vector<const char> NativesCollection<%(type)s>::GetRawScriptSource(int index) { | |
| 255 %(get_raw_script_source_cases)s\ | |
| 240 return Vector<const char>("", 0); | 256 return Vector<const char>("", 0); |
| 241 } | 257 } |
| 242 | 258 |
| 243 template <> | 259 template <> |
| 244 Vector<const char> NativesCollection<%(type)s>::GetScriptName(int index) { | 260 Vector<const char> NativesCollection<%(type)s>::GetScriptName(int index) { |
| 245 %(get_script_name_cases)s\ | 261 %(get_script_name_cases)s\ |
| 246 return Vector<const char>("", 0); | 262 return Vector<const char>("", 0); |
| 247 } | 263 } |
| 248 | 264 |
| 265 template <> | |
| 266 Vector<const byte> NativesCollection<%(type)s>::GetScriptSource(int index) { | |
| 267 %(get_script_source_cases)s\ | |
| 268 static const byte empty[] = { 0 }; | |
| 269 return Vector<const byte>(empty, 0); | |
| 270 } | |
| 271 | |
| 272 template <> | |
| 273 void NativesCollection<%(type)s>::SetRawScriptSource(int index, Vector<const c har> raw_source) { | |
| 274 %(set_raw_script_source_cases)s\ | |
| 275 } | |
| 276 | |
| 249 } // internal | 277 } // internal |
| 250 } // v8 | 278 } // v8 |
| 251 """ | 279 """ |
| 252 | 280 |
| 253 | 281 |
| 254 SOURCE_DECLARATION = """\ | 282 SOURCE_DECLARATION = """\ |
| 255 static const char %(id)s[] = { %(data)s }; | 283 static const byte %(id)s[] = { %(data)s }; |
| 256 """ | 284 """ |
| 257 | 285 |
| 258 | 286 |
| 259 GET_DEBUGGER_INDEX_CASE = """\ | 287 RAW_SOURCE_COMPRESSION_DECLARATION = """\ |
| 288 static const char* %(raw_id)s = NULL; | |
| 289 """ | |
| 290 | |
| 291 | |
| 292 RAW_SOURCE_DECLARATION = """\ | |
| 293 static const char* %(raw_id)s = reinterpret_cast<const char*>(%(id)s); | |
| 294 """ | |
| 295 | |
| 296 | |
| 297 GET_INDEX_CASE = """\ | |
| 260 if (strcmp(name, "%(id)s") == 0) return %(i)i; | 298 if (strcmp(name, "%(id)s") == 0) return %(i)i; |
| 261 """ | 299 """ |
| 262 | 300 |
| 263 | 301 |
| 264 GET_DEBUGGER_SCRIPT_SOURCE_CASE = """\ | 302 GET_RAW_SCRIPT_SIZE_CASE = """\ |
| 265 if (index == %(i)i) return Vector<const char>(%(id)s, %(length)i); | 303 if (index == %(i)i) return %(raw_length)i; |
| 266 """ | 304 """ |
| 267 | 305 |
| 268 | 306 |
| 269 GET_DEBUGGER_SCRIPT_NAME_CASE = """\ | 307 GET_RAW_SCRIPT_SOURCE_CASE = """\ |
| 308 if (index == %(i)i) return Vector<const char>(%(raw_id)s, %(raw_length)i); | |
| 309 """ | |
| 310 | |
| 311 | |
| 312 GET_SCRIPT_NAME_CASE = """\ | |
| 270 if (index == %(i)i) return Vector<const char>("%(name)s", %(length)i); | 313 if (index == %(i)i) return Vector<const char>("%(name)s", %(length)i); |
| 271 """ | 314 """ |
| 272 | 315 |
| 316 | |
| 317 GET_SCRIPT_SOURCE_CASE = """\ | |
| 318 if (index == %(i)i) return Vector<const byte>(%(id)s, %(length)i); | |
| 319 """ | |
| 320 | |
| 321 | |
| 322 SET_RAW_SOURCE_CASE = """\ | |
| 323 if (index == %(i)i) { ASSERT(%(raw_length)i == raw_source.length()); %(raw_i d)s = raw_source.start(); } | |
| 324 """ | |
| 325 | |
| 273 def JS2C(source, target, env): | 326 def JS2C(source, target, env): |
| 274 ids = [] | 327 ids = [] |
| 275 debugger_ids = [] | 328 debugger_ids = [] |
| 276 modules = [] | 329 modules = [] |
| 277 # Locate the macros file name. | 330 # Locate the macros file name. |
| 278 consts = [] | 331 consts = [] |
| 279 macros = [] | 332 macros = [] |
| 280 for s in source: | 333 for s in source: |
| 281 if 'macros.py' == (os.path.split(str(s))[1]): | 334 if 'macros.py' == (os.path.split(str(s))[1]): |
| 282 (consts, macros) = ReadMacros(ReadLines(str(s))) | 335 (consts, macros) = ReadMacros(ReadLines(str(s))) |
| 283 else: | 336 else: |
| 284 modules.append(s) | 337 modules.append(s) |
| 285 | 338 |
| 286 # Build source code lines | 339 # Build source code lines |
| 287 source_lines = [ ] | 340 source_lines = [ ] |
| 341 raw_source_lines = [ ] | |
| 288 | 342 |
| 289 minifier = jsmin.JavaScriptMinifier() | 343 minifier = jsmin.JavaScriptMinifier() |
| 290 | 344 |
| 291 for module in modules: | 345 for module in modules: |
| 292 filename = str(module) | 346 filename = str(module) |
| 293 debugger = filename.endswith('-debugger.js') | 347 debugger = filename.endswith('-debugger.js') |
| 294 lines = ReadFile(filename) | 348 lines = ReadFile(filename) |
| 295 lines = ExpandConstants(lines, consts) | 349 lines = ExpandConstants(lines, consts) |
| 296 lines = ExpandMacros(lines, macros) | 350 lines = ExpandMacros(lines, macros) |
| 297 Validate(lines, filename) | 351 Validate(lines, filename) |
| 298 lines = minifier.JSMinify(lines) | 352 lines = minifier.JSMinify(lines) |
| 299 data = ToCArray(lines) | 353 raw_length = len(lines) |
| 354 if env['COMPRESSION'] == 'bz2': | |
|
Vitaly Repeshko
2011/06/06 10:08:23
I think we can get better compression by gluing to
mnaganov (inactive)
2011/06/06 13:40:18
Good idea! This also simplifies code.
| |
| 355 lines = bz2.compress(lines, 9) | |
|
Vitaly Repeshko
2011/06/06 10:08:23
9 seems to be the default compression level so we
mnaganov (inactive)
2011/06/06 13:40:18
Done.
| |
| 356 length = len(lines) | |
| 357 if env['COMPRESSION'] == 'off': | |
| 358 data = ToCAsciiArray(lines) | |
| 359 else: | |
| 360 data = ToCArray(lines) | |
| 300 id = (os.path.split(filename)[1])[:-3] | 361 id = (os.path.split(filename)[1])[:-3] |
| 301 if debugger: id = id[:-9] | 362 if debugger: id = id[:-9] |
| 302 if debugger: | 363 if debugger: |
| 303 debugger_ids.append((id, len(lines))) | 364 debugger_ids.append((id, raw_length, length)) |
| 304 else: | 365 else: |
| 305 ids.append((id, len(lines))) | 366 ids.append((id, raw_length, length)) |
| 367 raw_id = 'raw_' + id | |
| 306 source_lines.append(SOURCE_DECLARATION % { 'id': id, 'data': data }) | 368 source_lines.append(SOURCE_DECLARATION % { 'id': id, 'data': data }) |
| 369 if env['COMPRESSION'] == 'off': | |
| 370 raw_source_lines.append(RAW_SOURCE_DECLARATION % { 'raw_id': raw_id, 'id': id }) | |
|
Vitaly Repeshko
2011/06/06 10:08:23
Let's at least fit the code lines in 80 cols.
mnaganov (inactive)
2011/06/06 13:40:18
Done.
| |
| 371 else: | |
| 372 raw_source_lines.append(RAW_SOURCE_COMPRESSION_DECLARATION % { 'raw_id': r aw_id, 'id': id }) | |
| 307 | 373 |
| 308 # Build debugger support functions | 374 # Build debugger support functions |
| 309 get_index_cases = [ ] | 375 get_index_cases = [ ] |
| 376 get_raw_script_size_cases = [ ] | |
| 377 get_raw_script_source_cases = [ ] | |
| 378 get_script_name_cases = [ ] | |
| 310 get_script_source_cases = [ ] | 379 get_script_source_cases = [ ] |
| 311 get_script_name_cases = [ ] | 380 set_raw_script_source_cases = [ ] |
| 312 | 381 |
| 313 i = 0 | 382 i = 0 |
| 314 for (id, length) in debugger_ids: | 383 for (id, raw_length, length) in debugger_ids: |
| 315 native_name = "native %s.js" % id | 384 native_name = "native %s.js" % id |
| 316 get_index_cases.append(GET_DEBUGGER_INDEX_CASE % { 'id': id, 'i': i }) | 385 raw_id = 'raw_' + id |
| 317 get_script_source_cases.append(GET_DEBUGGER_SCRIPT_SOURCE_CASE % { | 386 get_index_cases.append(GET_INDEX_CASE % { 'id': id, 'i': i }) |
| 318 'id': id, | 387 get_raw_script_size_cases.append(GET_RAW_SCRIPT_SIZE_CASE % { |
| 319 'length': length, | 388 'raw_length': raw_length, |
| 320 'i': i | 389 'i': i |
| 321 }) | 390 }) |
| 322 get_script_name_cases.append(GET_DEBUGGER_SCRIPT_NAME_CASE % { | 391 get_raw_script_source_cases.append(GET_RAW_SCRIPT_SOURCE_CASE % { |
| 323 'name': native_name, | 392 'raw_id': raw_id, |
| 324 'length': len(native_name), | 393 'raw_length': raw_length, |
| 325 'i': i | 394 'i': i |
| 326 }); | 395 }) |
| 396 get_script_name_cases.append(GET_SCRIPT_NAME_CASE % { | |
| 397 'name': native_name, | |
| 398 'length': len(native_name), | |
| 399 'i': i | |
| 400 }) | |
| 401 get_script_source_cases.append(GET_SCRIPT_SOURCE_CASE % { | |
| 402 'id': id, | |
| 403 'length': length, | |
| 404 'i': i | |
| 405 }) | |
| 406 set_raw_script_source_cases.append(SET_RAW_SOURCE_CASE % { | |
| 407 'raw_id': raw_id, | |
| 408 'raw_length': raw_length, | |
| 409 'i': i | |
| 410 }) | |
| 327 i = i + 1 | 411 i = i + 1 |
| 328 | 412 |
| 329 for (id, length) in ids: | 413 for (id, raw_length, length) in ids: |
| 330 native_name = "native %s.js" % id | 414 native_name = "native %s.js" % id |
| 331 get_index_cases.append(GET_DEBUGGER_INDEX_CASE % { 'id': id, 'i': i }) | 415 raw_id = 'raw_' + id |
| 332 get_script_source_cases.append(GET_DEBUGGER_SCRIPT_SOURCE_CASE % { | 416 get_index_cases.append(GET_INDEX_CASE % { 'id': id, 'i': i }) |
| 333 'id': id, | 417 get_raw_script_size_cases.append(GET_RAW_SCRIPT_SIZE_CASE % { |
| 334 'length': length, | 418 'raw_length': raw_length, |
| 335 'i': i | 419 'i': i |
| 336 }) | 420 }) |
| 337 get_script_name_cases.append(GET_DEBUGGER_SCRIPT_NAME_CASE % { | 421 get_raw_script_source_cases.append(GET_RAW_SCRIPT_SOURCE_CASE % { |
| 338 'name': native_name, | 422 'raw_id': raw_id, |
| 339 'length': len(native_name), | 423 'raw_length': raw_length, |
| 340 'i': i | 424 'i': i |
| 341 }); | 425 }) |
| 426 get_script_name_cases.append(GET_SCRIPT_NAME_CASE % { | |
| 427 'name': native_name, | |
| 428 'length': len(native_name), | |
| 429 'i': i | |
| 430 }) | |
| 431 get_script_source_cases.append(GET_SCRIPT_SOURCE_CASE % { | |
| 432 'id': id, | |
| 433 'length': length, | |
| 434 'i': i | |
| 435 }) | |
| 436 set_raw_script_source_cases.append(SET_RAW_SOURCE_CASE % { | |
| 437 'raw_id': raw_id, | |
| 438 'raw_length': raw_length, | |
| 439 'i': i | |
| 440 }) | |
| 342 i = i + 1 | 441 i = i + 1 |
| 343 | 442 |
| 344 # Emit result | 443 # Emit result |
| 345 output = open(str(target[0]), "w") | 444 output = open(str(target[0]), "w") |
| 346 output.write(HEADER_TEMPLATE % { | 445 output.write(HEADER_TEMPLATE % { |
| 347 'builtin_count': len(ids) + len(debugger_ids), | 446 'builtin_count': len(ids) + len(debugger_ids), |
| 348 'debugger_count': len(debugger_ids), | 447 'debugger_count': len(debugger_ids), |
| 349 'source_lines': "\n".join(source_lines), | 448 'source_lines': "\n".join(source_lines), |
| 449 'raw_source_lines': "\n".join(raw_source_lines), | |
| 350 'get_index_cases': "".join(get_index_cases), | 450 'get_index_cases': "".join(get_index_cases), |
| 451 'get_raw_script_size_cases': "".join(get_raw_script_size_cases), | |
| 452 'get_raw_script_source_cases': "".join(get_raw_script_source_cases), | |
| 453 'get_script_name_cases': "".join(get_script_name_cases), | |
| 351 'get_script_source_cases': "".join(get_script_source_cases), | 454 'get_script_source_cases': "".join(get_script_source_cases), |
| 352 'get_script_name_cases': "".join(get_script_name_cases), | 455 'set_raw_script_source_cases': "".join(set_raw_script_source_cases), |
| 353 'type': env['TYPE'] | 456 'type': env['TYPE'] |
| 354 }) | 457 }) |
| 355 output.close() | 458 output.close() |
| 356 | 459 |
| 357 def main(): | 460 def main(): |
| 358 natives = sys.argv[1] | 461 natives = sys.argv[1] |
| 359 type = sys.argv[2] | 462 type = sys.argv[2] |
| 360 source_files = sys.argv[3:] | 463 compression = sys.argv[3] |
| 361 JS2C(source_files, [natives], { 'TYPE': type }) | 464 source_files = sys.argv[4:] |
| 465 JS2C(source_files, [natives], { 'TYPE': type, 'COMPRESSION': compression }) | |
| 362 | 466 |
| 363 if __name__ == "__main__": | 467 if __name__ == "__main__": |
| 364 main() | 468 main() |
| OLD | NEW |