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 |