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 27 matching lines...) Expand all Loading... | |
38 def ToCArray(lines): | 38 def ToCArray(lines): |
39 result = [] | 39 result = [] |
40 for chr in lines: | 40 for chr in lines: |
41 value = ord(chr) | 41 value = ord(chr) |
42 assert value < 128 | 42 assert value < 128 |
43 result.append(str(value)) | 43 result.append(str(value)) |
44 result.append("0") | 44 result.append("0") |
45 return ", ".join(result) | 45 return ", ".join(result) |
46 | 46 |
47 | 47 |
48 def RemoveCommentsAndTrailingWhitespace(lines): | |
49 lines = re.sub(r'//.*\n', '\n', lines) # end-of-line comments | |
50 lines = re.sub(re.compile(r'/\*.*?\*/', re.DOTALL), '', lines) # comments. | |
51 lines = re.sub(r'\s+\n+', '\n', lines) # trailing whitespace | |
52 return lines | |
53 | |
54 | |
48 def CompressScript(lines, do_jsmin): | 55 def CompressScript(lines, do_jsmin): |
49 # If we're not expecting this code to be user visible, we can run it through | 56 # If we're not expecting this code to be user visible, we can run it through |
50 # a more aggressive minifier. | 57 # a more aggressive minifier. |
51 if do_jsmin: | 58 if do_jsmin: |
52 return jsmin.jsmin(lines) | 59 return jsmin.jsmin(lines) |
53 | 60 |
54 # Remove stuff from the source that we don't want to appear when | 61 # Remove stuff from the source that we don't want to appear when |
55 # people print the source code using Function.prototype.toString(). | 62 # people print the source code using Function.prototype.toString(). |
56 # Note that we could easily compress the scripts mode but don't | 63 # Note that we could easily compress the scripts mode but don't |
57 # since we want it to remain readable. | 64 # since we want it to remain readable. |
58 lines = re.sub('//.*\n', '\n', lines) # end-of-line comments | 65 lines = RemoveCommentsAndTrailingWhitespace(lines) |
59 lines = re.sub(re.compile(r'/\*.*?\*/', re.DOTALL), '', lines) # comments. | |
60 lines = re.sub('\s+\n+', '\n', lines) # trailing whitespace | |
61 return lines | 66 return lines |
62 | 67 |
63 | 68 |
64 def ReadFile(filename): | 69 def ReadFile(filename): |
65 file = open(filename, "rt") | 70 file = open(filename, "rt") |
66 try: | 71 try: |
67 lines = file.read() | 72 lines = file.read() |
68 finally: | 73 finally: |
69 file.close() | 74 file.close() |
70 return lines | 75 return lines |
(...skipping 18 matching lines...) Expand all Loading... | |
89 | 94 |
90 | 95 |
91 def ParseValue(string): | 96 def ParseValue(string): |
92 string = string.strip() | 97 string = string.strip() |
93 if string.startswith('[') and string.endswith(']'): | 98 if string.startswith('[') and string.endswith(']'): |
94 return string.lstrip('[').rstrip(']').split() | 99 return string.lstrip('[').rstrip(']').split() |
95 else: | 100 else: |
96 return string | 101 return string |
97 | 102 |
98 | 103 |
104 EVAL_PATTERN = re.compile(r'\beval\s*\('); | |
105 WITH_PATTERN = re.compile(r'\bwith\s*\('); | |
106 | |
107 | |
108 def Validate(lines, file): | |
109 lines = RemoveCommentsAndTrailingWhitespace(lines) | |
110 # Because of simplified context setup, eval and with is not | |
111 # allowed in the natives files. | |
112 eval_match = EVAL_PATTERN.search(lines) | |
113 if eval_match: | |
114 raise ("Eval disallowed in natives: " + file) | |
Christian Plesner Hansen
2009/08/31 12:42:45
The formatting operator % should be used for strin
| |
115 with_match = WITH_PATTERN.search(lines) | |
116 if with_match: | |
117 raise ("With statements disallowed in natives: " + file) | |
118 | |
119 | |
99 def ExpandConstants(lines, constants): | 120 def ExpandConstants(lines, constants): |
100 for key, value in constants.items(): | 121 for key, value in constants.items(): |
101 lines = lines.replace(key, str(value)) | 122 lines = lines.replace(key, str(value)) |
102 return lines | 123 return lines |
103 | 124 |
104 | 125 |
105 def ExpandMacros(lines, macros): | 126 def ExpandMacros(lines, macros): |
106 for name, macro in macros.items(): | 127 for name, macro in macros.items(): |
107 start = lines.find(name + '(', 0) | 128 start = lines.find(name + '(', 0) |
108 while start != -1: | 129 while start != -1: |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
148 class PythonMacro: | 169 class PythonMacro: |
149 def __init__(self, args, fun): | 170 def __init__(self, args, fun): |
150 self.args = args | 171 self.args = args |
151 self.fun = fun | 172 self.fun = fun |
152 def expand(self, mapping): | 173 def expand(self, mapping): |
153 args = [] | 174 args = [] |
154 for arg in self.args: | 175 for arg in self.args: |
155 args.append(mapping[arg]) | 176 args.append(mapping[arg]) |
156 return str(self.fun(*args)) | 177 return str(self.fun(*args)) |
157 | 178 |
158 CONST_PATTERN = re.compile('^const\s+([a-zA-Z0-9_]+)\s*=\s*([^;]*);$') | 179 CONST_PATTERN = re.compile(r'^const\s+([a-zA-Z0-9_]+)\s*=\s*([^;]*);$') |
159 MACRO_PATTERN = re.compile('^macro\s+([a-zA-Z0-9_]+)\s*\(([^)]*)\)\s*=\s*([^;]*) ;$') | 180 MACRO_PATTERN = re.compile(r'^macro\s+([a-zA-Z0-9_]+)\s*\(([^)]*)\)\s*=\s*([^;]* );$') |
160 PYTHON_MACRO_PATTERN = re.compile('^python\s+macro\s+([a-zA-Z0-9_]+)\s*\(([^)]*) \)\s*=\s*([^;]*);$') | 181 PYTHON_MACRO_PATTERN = re.compile(r'^python\s+macro\s+([a-zA-Z0-9_]+)\s*\(([^)]* )\)\s*=\s*([^;]*);$') |
161 | 182 |
162 def ReadMacros(lines): | 183 def ReadMacros(lines): |
163 constants = { } | 184 constants = { } |
164 macros = { } | 185 macros = { } |
165 for line in lines: | 186 for line in lines: |
166 hash = line.find('#') | 187 hash = line.find('#') |
167 if hash != -1: line = line[:hash] | 188 if hash != -1: line = line[:hash] |
168 line = line.strip() | 189 line = line.strip() |
169 if len(line) is 0: continue | 190 if len(line) is 0: continue |
170 const_match = CONST_PATTERN.match(line) | 191 const_match = CONST_PATTERN.match(line) |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
269 for s in source: | 290 for s in source: |
270 if 'macros.py' == (os.path.split(str(s))[1]): | 291 if 'macros.py' == (os.path.split(str(s))[1]): |
271 (consts, macros) = ReadMacros(ReadLines(str(s))) | 292 (consts, macros) = ReadMacros(ReadLines(str(s))) |
272 else: | 293 else: |
273 modules.append(s) | 294 modules.append(s) |
274 | 295 |
275 # Build source code lines | 296 # Build source code lines |
276 source_lines = [ ] | 297 source_lines = [ ] |
277 source_lines_empty = [] | 298 source_lines_empty = [] |
278 for s in modules: | 299 for s in modules: |
279 delay = str(s).endswith('-delay.js') | 300 delay = str(s).endswith('-delay.js') |
Christian Plesner Hansen
2009/08/31 12:42:45
We use str(s) so many places here -- maybe do some
| |
280 lines = ReadFile(str(s)) | 301 lines = ReadFile(str(s)) |
281 do_jsmin = lines.find('// jsminify this file, js2c: jsmin') != -1 | 302 do_jsmin = lines.find('// jsminify this file, js2c: jsmin') != -1 |
282 lines = ExpandConstants(lines, consts) | 303 lines = ExpandConstants(lines, consts) |
283 lines = ExpandMacros(lines, macros) | 304 lines = ExpandMacros(lines, macros) |
305 Validate(lines, str(s)) | |
284 lines = CompressScript(lines, do_jsmin) | 306 lines = CompressScript(lines, do_jsmin) |
285 data = ToCArray(lines) | 307 data = ToCArray(lines) |
286 id = (os.path.split(str(s))[1])[:-3] | 308 id = (os.path.split(str(s))[1])[:-3] |
287 if delay: id = id[:-6] | 309 if delay: id = id[:-6] |
288 if delay: | 310 if delay: |
289 delay_ids.append((id, len(lines))) | 311 delay_ids.append((id, len(lines))) |
290 else: | 312 else: |
291 ids.append((id, len(lines))) | 313 ids.append((id, len(lines))) |
292 source_lines.append(SOURCE_DECLARATION % { 'id': id, 'data': data }) | 314 source_lines.append(SOURCE_DECLARATION % { 'id': id, 'data': data }) |
293 source_lines_empty.append(SOURCE_DECLARATION % { 'id': id, 'data': 0 }) | 315 source_lines_empty.append(SOURCE_DECLARATION % { 'id': id, 'data': 0 }) |
294 | 316 |
295 # Build delay support functions | 317 # Build delay support functions |
296 get_index_cases = [ ] | 318 get_index_cases = [ ] |
297 get_script_source_cases = [ ] | 319 get_script_source_cases = [ ] |
298 get_script_name_cases = [ ] | 320 get_script_name_cases = [ ] |
299 | 321 |
300 i = 0 | 322 i = 0 |
301 for (id, length) in delay_ids: | 323 for (id, length) in delay_ids: |
302 native_name = "native %s.js" % id | 324 native_name = "native %s.js" % id |
303 get_index_cases.append(GET_DELAY_INDEX_CASE % { 'id': id, 'i': i }) | 325 get_index_cases.append(GET_DELAY_INDEX_CASE % { 'id': id, 'i': i }) |
304 get_script_source_cases.append(GET_DELAY_SCRIPT_SOURCE_CASE % { | 326 get_script_source_cases.append(GET_DELAY_SCRIPT_SOURCE_CASE % { |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
356 | 378 |
357 def main(): | 379 def main(): |
358 natives = sys.argv[1] | 380 natives = sys.argv[1] |
359 natives_empty = sys.argv[2] | 381 natives_empty = sys.argv[2] |
360 type = sys.argv[3] | 382 type = sys.argv[3] |
361 source_files = sys.argv[4:] | 383 source_files = sys.argv[4:] |
362 JS2C(source_files, [natives, natives_empty], { 'TYPE': type }) | 384 JS2C(source_files, [natives, natives_empty], { 'TYPE': type }) |
363 | 385 |
364 if __name__ == "__main__": | 386 if __name__ == "__main__": |
365 main() | 387 main() |
OLD | NEW |