| 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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 | 61 |
| 62 def ReadFile(filename): | 62 def ReadFile(filename): |
| 63 file = open(filename, "rt") | 63 file = open(filename, "rt") |
| 64 try: | 64 try: |
| 65 lines = file.read() | 65 lines = file.read() |
| 66 finally: | 66 finally: |
| 67 file.close() | 67 file.close() |
| 68 return lines | 68 return lines |
| 69 | 69 |
| 70 | 70 |
| 71 def ReadLines(filename): | |
| 72 result = [] | |
| 73 for line in open(filename, "rt"): | |
| 74 if '#' in line: | |
| 75 line = line[:line.index('#')] | |
| 76 line = line.strip() | |
| 77 if len(line) > 0: | |
| 78 result.append(line) | |
| 79 return result | |
| 80 | |
| 81 | |
| 82 def LoadConfigFrom(name): | 71 def LoadConfigFrom(name): |
| 83 import ConfigParser | 72 import ConfigParser |
| 84 config = ConfigParser.ConfigParser() | 73 config = ConfigParser.ConfigParser() |
| 85 config.read(name) | 74 config.read(name) |
| 86 return config | 75 return config |
| 87 | 76 |
| 88 | 77 |
| 89 def ParseValue(string): | 78 def ParseValue(string): |
| 90 string = string.strip() | 79 string = string.strip() |
| 91 if string.startswith('[') and string.endswith(']'): | 80 if string.startswith('[') and string.endswith(']'): |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 172 class PythonMacro: | 161 class PythonMacro: |
| 173 def __init__(self, args, fun): | 162 def __init__(self, args, fun): |
| 174 self.args = args | 163 self.args = args |
| 175 self.fun = fun | 164 self.fun = fun |
| 176 def expand(self, mapping): | 165 def expand(self, mapping): |
| 177 args = [] | 166 args = [] |
| 178 for arg in self.args: | 167 for arg in self.args: |
| 179 args.append(mapping[arg]) | 168 args.append(mapping[arg]) |
| 180 return str(self.fun(*args)) | 169 return str(self.fun(*args)) |
| 181 | 170 |
| 171 |
| 182 CONST_PATTERN = re.compile(r'^const\s+([a-zA-Z0-9_]+)\s*=\s*([^;]*);$') | 172 CONST_PATTERN = re.compile(r'^const\s+([a-zA-Z0-9_]+)\s*=\s*([^;]*);$') |
| 183 MACRO_PATTERN = re.compile(r'^macro\s+([a-zA-Z0-9_]+)\s*\(([^)]*)\)\s*=\s*([^;]*
);$') | 173 MACRO_PATTERN = re.compile(r'^macro\s+([a-zA-Z0-9_]+)\s*\(([^)]*)\)\s*=\s*([^;]*
);$') |
| 174 MACRO_START_PATTERN = re.compile(r'macro\s+([a-zA-Z0-9_]+)\s*\(([^)]*)\)\s*\n') |
| 175 MACRO_END_PATTERN = re.compile(r'endmacro\s*\n') |
| 184 PYTHON_MACRO_PATTERN = re.compile(r'^python\s+macro\s+([a-zA-Z0-9_]+)\s*\(([^)]*
)\)\s*=\s*([^;]*);$') | 176 PYTHON_MACRO_PATTERN = re.compile(r'^python\s+macro\s+([a-zA-Z0-9_]+)\s*\(([^)]*
)\)\s*=\s*([^;]*);$') |
| 185 | 177 |
| 186 | 178 |
| 187 def ReadMacros(lines): | 179 def ReadMacros(contents): |
| 188 constants = [] | 180 constants = [] |
| 189 macros = [] | 181 macros = [] |
| 182 |
| 183 multiple_line_macros = [] |
| 184 pos = 0 |
| 185 while True: |
| 186 macro_start_match = MACRO_START_PATTERN.search(contents, pos) |
| 187 if macro_start_match is None: |
| 188 # no more multiple line macros |
| 189 break |
| 190 name = macro_start_match.group(1) |
| 191 args = [match.strip() for match in macro_start_match.group(2).split(',')] |
| 192 macro_end_match = MACRO_END_PATTERN.search(contents, macro_start_match.end()
); |
| 193 if macro_end_match is None: |
| 194 raise ("Macro %s unclosed in %s" % (name, 'macros.py')) |
| 195 body = contents[macro_start_match.end():macro_end_match.start()] |
| 196 |
| 197 # remove multiple line macro definition |
| 198 contents = contents[:macro_start_match.start()] + contents[macro_end_match.e
nd():] |
| 199 # record multiple line macro definition |
| 200 multiple_line_macros.append((re.compile("\\b%s\\(" % name), TextMacro(args,
body))) |
| 201 # advance position to where the multiple line macro defintion was |
| 202 pos = macro_start_match.start() |
| 203 |
| 204 lines = contents.split('\n') |
| 190 for line in lines: | 205 for line in lines: |
| 191 hash = line.find('#') | 206 hash = line.find('#') |
| 192 if hash != -1: line = line[:hash] | 207 if hash != -1: line = line[:hash] |
| 193 line = line.strip() | 208 line = line.strip() |
| 194 if len(line) is 0: continue | 209 if len(line) is 0: continue |
| 195 const_match = CONST_PATTERN.match(line) | 210 const_match = CONST_PATTERN.match(line) |
| 196 if const_match: | 211 if const_match: |
| 197 name = const_match.group(1) | 212 name = const_match.group(1) |
| 198 value = const_match.group(2).strip() | 213 value = const_match.group(2).strip() |
| 199 constants.append((re.compile("\\b%s\\b" % name), value)) | 214 constants.append((re.compile("\\b%s\\b" % name), value)) |
| 200 else: | 215 else: |
| 201 macro_match = MACRO_PATTERN.match(line) | 216 macro_match = MACRO_PATTERN.match(line) |
| 202 if macro_match: | 217 if macro_match: |
| 203 name = macro_match.group(1) | 218 name = macro_match.group(1) |
| 204 args = [match.strip() for match in macro_match.group(2).split(',')] | 219 args = [match.strip() for match in macro_match.group(2).split(',')] |
| 205 body = macro_match.group(3).strip() | 220 body = macro_match.group(3).strip() |
| 206 macros.append((re.compile("\\b%s\\(" % name), TextMacro(args, body))) | 221 macros.append((re.compile("\\b%s\\(" % name), TextMacro(args, body))) |
| 207 else: | 222 else: |
| 208 python_match = PYTHON_MACRO_PATTERN.match(line) | 223 python_match = PYTHON_MACRO_PATTERN.match(line) |
| 209 if python_match: | 224 if python_match: |
| 210 name = python_match.group(1) | 225 name = python_match.group(1) |
| 211 args = [match.strip() for match in python_match.group(2).split(',')] | 226 args = [match.strip() for match in python_match.group(2).split(',')] |
| 212 body = python_match.group(3).strip() | 227 body = python_match.group(3).strip() |
| 213 fun = eval("lambda " + ",".join(args) + ': ' + body) | 228 fun = eval("lambda " + ",".join(args) + ': ' + body) |
| 214 macros.append((re.compile("\\b%s\\(" % name), PythonMacro(args, fun))) | 229 macros.append((re.compile("\\b%s\\(" % name), PythonMacro(args, fun))) |
| 215 else: | 230 else: |
| 216 raise ("Illegal line: " + line) | 231 raise ("Illegal line: " + line) |
| 232 |
| 233 # append multiple line macros to macros so that they will be expanded first |
| 234 for m in multiple_line_macros: |
| 235 macros.append(m) |
| 236 |
| 217 return (constants, macros) | 237 return (constants, macros) |
| 218 | 238 |
| 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) | |
| 247 | 239 |
| 248 HEADER_TEMPLATE = """\ | 240 HEADER_TEMPLATE = """\ |
| 249 // Copyright 2011 Google Inc. All Rights Reserved. | 241 // Copyright 2011 Google Inc. All Rights Reserved. |
| 250 | 242 |
| 251 // This file was generated from .js source files by GYP. If you | 243 // This file was generated from .js source files by GYP. If you |
| 252 // want to make changes to this file you should either change the | 244 // want to make changes to this file you should either change the |
| 253 // javascript source files or the GYP script. | 245 // javascript source files or the GYP script. |
| 254 | 246 |
| 255 #include "v8.h" | 247 #include "v8.h" |
| 256 #include "natives.h" | 248 #include "natives.h" |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 338 | 330 |
| 339 def JS2C(source, target, env): | 331 def JS2C(source, target, env): |
| 340 ids = [] | 332 ids = [] |
| 341 debugger_ids = [] | 333 debugger_ids = [] |
| 342 modules = [] | 334 modules = [] |
| 343 # Locate the macros file name. | 335 # Locate the macros file name. |
| 344 consts = [] | 336 consts = [] |
| 345 macros = [] | 337 macros = [] |
| 346 for s in source: | 338 for s in source: |
| 347 if 'macros.py' == (os.path.split(str(s))[1]): | 339 if 'macros.py' == (os.path.split(str(s))[1]): |
| 348 (consts, macros) = ReadMacros(ReadLines(str(s))) | 340 (consts, macros) = ReadMacros(ReadFile(str(s))) |
| 349 else: | 341 else: |
| 350 modules.append(s) | 342 modules.append(s) |
| 351 | 343 |
| 352 minifier = jsmin.JavaScriptMinifier() | 344 minifier = jsmin.JavaScriptMinifier() |
| 353 | 345 |
| 354 module_offset = 0 | 346 module_offset = 0 |
| 355 all_sources = [] | 347 all_sources = [] |
| 356 for module in modules: | 348 for module in modules: |
| 357 filename = str(module) | 349 filename = str(module) |
| 358 debugger = filename.endswith('-debugger.js') | 350 debugger = filename.endswith('-debugger.js') |
| 359 lines = ReadFile(filename) | 351 lines = ReadFile(filename) |
| 352 lines = ExpandMacros(lines, macros) |
| 360 lines = ExpandConstants(lines, consts) | 353 lines = ExpandConstants(lines, consts) |
| 361 lines = ExpandMacros(lines, macros) | |
| 362 lines = RemoveCommentsAndTrailingWhitespace(lines) | 354 lines = RemoveCommentsAndTrailingWhitespace(lines) |
| 363 lines = ExpandInlineMacros(lines, filename) | |
| 364 Validate(lines, filename) | 355 Validate(lines, filename) |
| 365 lines = minifier.JSMinify(lines) | 356 lines = minifier.JSMinify(lines) |
| 366 id = (os.path.split(filename)[1])[:-3] | 357 id = (os.path.split(filename)[1])[:-3] |
| 367 if debugger: id = id[:-9] | 358 if debugger: id = id[:-9] |
| 368 raw_length = len(lines) | 359 raw_length = len(lines) |
| 369 if debugger: | 360 if debugger: |
| 370 debugger_ids.append((id, raw_length, module_offset)) | 361 debugger_ids.append((id, raw_length, module_offset)) |
| 371 else: | 362 else: |
| 372 ids.append((id, raw_length, module_offset)) | 363 ids.append((id, raw_length, module_offset)) |
| 373 all_sources.append(lines) | 364 all_sources.append(lines) |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 423 | 414 |
| 424 def main(): | 415 def main(): |
| 425 natives = sys.argv[1] | 416 natives = sys.argv[1] |
| 426 type = sys.argv[2] | 417 type = sys.argv[2] |
| 427 compression = sys.argv[3] | 418 compression = sys.argv[3] |
| 428 source_files = sys.argv[4:] | 419 source_files = sys.argv[4:] |
| 429 JS2C(source_files, [natives], { 'TYPE': type, 'COMPRESSION': compression }) | 420 JS2C(source_files, [natives], { 'TYPE': type, 'COMPRESSION': compression }) |
| 430 | 421 |
| 431 if __name__ == "__main__": | 422 if __name__ == "__main__": |
| 432 main() | 423 main() |
| OLD | NEW |