| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # | 2 # |
| 3 # Copyright 2012 the V8 project authors. All rights reserved. | 3 # Copyright 2012 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 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 109 if with_match: | 109 if with_match: |
| 110 raise ("With statements disallowed in natives: %s" % file) | 110 raise ("With statements disallowed in natives: %s" % file) |
| 111 | 111 |
| 112 | 112 |
| 113 def ExpandConstants(lines, constants): | 113 def ExpandConstants(lines, constants): |
| 114 for key, value in constants: | 114 for key, value in constants: |
| 115 lines = key.sub(str(value), lines) | 115 lines = key.sub(str(value), lines) |
| 116 return lines | 116 return lines |
| 117 | 117 |
| 118 | 118 |
| 119 def ExpandMacroDefinition(lines, pos, name_pattern, macro, expander): |
| 120 pattern_match = name_pattern.search(lines, pos) |
| 121 while pattern_match is not None: |
| 122 # Scan over the arguments |
| 123 height = 1 |
| 124 start = pattern_match.start() |
| 125 end = pattern_match.end() |
| 126 assert lines[end - 1] == '(' |
| 127 last_match = end |
| 128 arg_index = [0] # Wrap state into array, to work around Python "scoping" |
| 129 mapping = { } |
| 130 def add_arg(str): |
| 131 # Remember to expand recursively in the arguments |
| 132 replacement = expander(str.strip()) |
| 133 mapping[macro.args[arg_index[0]]] = replacement |
| 134 arg_index[0] += 1 |
| 135 while end < len(lines) and height > 0: |
| 136 # We don't count commas at higher nesting levels. |
| 137 if lines[end] == ',' and height == 1: |
| 138 add_arg(lines[last_match:end]) |
| 139 last_match = end + 1 |
| 140 elif lines[end] in ['(', '{', '[']: |
| 141 height = height + 1 |
| 142 elif lines[end] in [')', '}', ']']: |
| 143 height = height - 1 |
| 144 end = end + 1 |
| 145 # Remember to add the last match. |
| 146 add_arg(lines[last_match:end-1]) |
| 147 result = macro.expand(mapping) |
| 148 # Replace the occurrence of the macro with the expansion |
| 149 lines = lines[:start] + result + lines[end:] |
| 150 pattern_match = name_pattern.search(lines, start + len(result)) |
| 151 return lines |
| 152 |
| 119 def ExpandMacros(lines, macros): | 153 def ExpandMacros(lines, macros): |
| 120 # We allow macros to depend on the previously declared macros, but | 154 # We allow macros to depend on the previously declared macros, but |
| 121 # we don't allow self-dependecies or recursion. | 155 # we don't allow self-dependecies or recursion. |
| 122 for name_pattern, macro in reversed(macros): | 156 for name_pattern, macro in reversed(macros): |
| 123 pattern_match = name_pattern.search(lines, 0) | 157 def expander(s): |
| 124 while pattern_match is not None: | 158 return ExpandMacros(s, macros) |
| 125 # Scan over the arguments | 159 lines = ExpandMacroDefinition(lines, 0, name_pattern, macro, expander) |
| 126 height = 1 | |
| 127 start = pattern_match.start() | |
| 128 end = pattern_match.end() | |
| 129 assert lines[end - 1] == '(' | |
| 130 last_match = end | |
| 131 arg_index = [0] # Wrap state into array, to work around Python "scoping" | |
| 132 mapping = { } | |
| 133 def add_arg(str): | |
| 134 # Remember to expand recursively in the arguments | |
| 135 replacement = ExpandMacros(str.strip(), macros) | |
| 136 mapping[macro.args[arg_index[0]]] = replacement | |
| 137 arg_index[0] += 1 | |
| 138 while end < len(lines) and height > 0: | |
| 139 # We don't count commas at higher nesting levels. | |
| 140 if lines[end] == ',' and height == 1: | |
| 141 add_arg(lines[last_match:end]) | |
| 142 last_match = end + 1 | |
| 143 elif lines[end] in ['(', '{', '[']: | |
| 144 height = height + 1 | |
| 145 elif lines[end] in [')', '}', ']']: | |
| 146 height = height - 1 | |
| 147 end = end + 1 | |
| 148 # Remember to add the last match. | |
| 149 add_arg(lines[last_match:end-1]) | |
| 150 result = macro.expand(mapping) | |
| 151 # Replace the occurrence of the macro with the expansion | |
| 152 lines = lines[:start] + result + lines[end:] | |
| 153 pattern_match = name_pattern.search(lines, start + len(result)) | |
| 154 return lines | 160 return lines |
| 155 | 161 |
| 156 class TextMacro: | 162 class TextMacro: |
| 157 def __init__(self, args, body): | 163 def __init__(self, args, body): |
| 158 self.args = args | 164 self.args = args |
| 159 self.body = body | 165 self.body = body |
| 160 def expand(self, mapping): | 166 def expand(self, mapping): |
| 161 result = self.body | 167 result = self.body |
| 162 for key, value in mapping.items(): | 168 for key, value in mapping.items(): |
| 163 result = result.replace(key, value) | 169 result = result.replace(key, value) |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 if python_match: | 209 if python_match: |
| 204 name = python_match.group(1) | 210 name = python_match.group(1) |
| 205 args = [match.strip() for match in python_match.group(2).split(',')] | 211 args = [match.strip() for match in python_match.group(2).split(',')] |
| 206 body = python_match.group(3).strip() | 212 body = python_match.group(3).strip() |
| 207 fun = eval("lambda " + ",".join(args) + ': ' + body) | 213 fun = eval("lambda " + ",".join(args) + ': ' + body) |
| 208 macros.append((re.compile("\\b%s\\(" % name), PythonMacro(args, fun))) | 214 macros.append((re.compile("\\b%s\\(" % name), PythonMacro(args, fun))) |
| 209 else: | 215 else: |
| 210 raise ("Illegal line: " + line) | 216 raise ("Illegal line: " + line) |
| 211 return (constants, macros) | 217 return (constants, macros) |
| 212 | 218 |
| 219 INLINE_MACRO_PATTERN = re.compile(r'macro\s+([a-zA-Z0-9_]+)\s*\(([^)]*)\)\s*\n') |
| 220 INLINE_MACRO_END_PATTERN = re.compile(r'endmacro\s*\n') |
| 221 |
| 222 def ExpandInlineMacros(lines, filename): |
| 223 pos = 0 |
| 224 while True: |
| 225 macro_match = INLINE_MACRO_PATTERN.search(lines, pos) |
| 226 if macro_match is None: |
| 227 # no more macros |
| 228 return lines |
| 229 name = macro_match.group(1) |
| 230 args = [match.strip() for match in macro_match.group(2).split(',')] |
| 231 end_macro_match = INLINE_MACRO_END_PATTERN.search(lines, macro_match.end()); |
| 232 if end_macro_match is None: |
| 233 raise ("Macro %s unclosed in %s" % (name, filename)) |
| 234 body = lines[macro_match.end():end_macro_match.start()] |
| 235 |
| 236 # remove macro definition |
| 237 lines = lines[:macro_match.start()] + lines[end_macro_match.end():] |
| 238 name_pattern = re.compile("\\b%s\\(" % name) |
| 239 macro = TextMacro(args, body) |
| 240 |
| 241 # advance position to where the macro defintion was |
| 242 pos = macro_match.start() |
| 243 |
| 244 def non_expander(s): |
| 245 return s |
| 246 lines = ExpandMacroDefinition(lines, pos, name_pattern, macro, non_expander) |
| 213 | 247 |
| 214 HEADER_TEMPLATE = """\ | 248 HEADER_TEMPLATE = """\ |
| 215 // Copyright 2011 Google Inc. All Rights Reserved. | 249 // Copyright 2011 Google Inc. All Rights Reserved. |
| 216 | 250 |
| 217 // This file was generated from .js source files by GYP. If you | 251 // This file was generated from .js source files by GYP. If you |
| 218 // want to make changes to this file you should either change the | 252 // want to make changes to this file you should either change the |
| 219 // javascript source files or the GYP script. | 253 // javascript source files or the GYP script. |
| 220 | 254 |
| 221 #include "v8.h" | 255 #include "v8.h" |
| 222 #include "natives.h" | 256 #include "natives.h" |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 318 minifier = jsmin.JavaScriptMinifier() | 352 minifier = jsmin.JavaScriptMinifier() |
| 319 | 353 |
| 320 module_offset = 0 | 354 module_offset = 0 |
| 321 all_sources = [] | 355 all_sources = [] |
| 322 for module in modules: | 356 for module in modules: |
| 323 filename = str(module) | 357 filename = str(module) |
| 324 debugger = filename.endswith('-debugger.js') | 358 debugger = filename.endswith('-debugger.js') |
| 325 lines = ReadFile(filename) | 359 lines = ReadFile(filename) |
| 326 lines = ExpandConstants(lines, consts) | 360 lines = ExpandConstants(lines, consts) |
| 327 lines = ExpandMacros(lines, macros) | 361 lines = ExpandMacros(lines, macros) |
| 362 lines = RemoveCommentsAndTrailingWhitespace(lines) |
| 363 lines = ExpandInlineMacros(lines, filename) |
| 328 Validate(lines, filename) | 364 Validate(lines, filename) |
| 329 lines = minifier.JSMinify(lines) | 365 lines = minifier.JSMinify(lines) |
| 330 id = (os.path.split(filename)[1])[:-3] | 366 id = (os.path.split(filename)[1])[:-3] |
| 331 if debugger: id = id[:-9] | 367 if debugger: id = id[:-9] |
| 332 raw_length = len(lines) | 368 raw_length = len(lines) |
| 333 if debugger: | 369 if debugger: |
| 334 debugger_ids.append((id, raw_length, module_offset)) | 370 debugger_ids.append((id, raw_length, module_offset)) |
| 335 else: | 371 else: |
| 336 ids.append((id, raw_length, module_offset)) | 372 ids.append((id, raw_length, module_offset)) |
| 337 all_sources.append(lines) | 373 all_sources.append(lines) |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 387 | 423 |
| 388 def main(): | 424 def main(): |
| 389 natives = sys.argv[1] | 425 natives = sys.argv[1] |
| 390 type = sys.argv[2] | 426 type = sys.argv[2] |
| 391 compression = sys.argv[3] | 427 compression = sys.argv[3] |
| 392 source_files = sys.argv[4:] | 428 source_files = sys.argv[4:] |
| 393 JS2C(source_files, [natives], { 'TYPE': type, 'COMPRESSION': compression }) | 429 JS2C(source_files, [natives], { 'TYPE': type, 'COMPRESSION': compression }) |
| 394 | 430 |
| 395 if __name__ == "__main__": | 431 if __name__ == "__main__": |
| 396 main() | 432 main() |
| OLD | NEW |