OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright 2014 the V8 project authors. All rights reserved. | 2 # Copyright 2014 the V8 project authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 import js2c | 6 import js2c |
7 import os | 7 import os |
8 import re | 8 import re |
9 import sys | 9 import sys |
10 | 10 |
11 FILENAME = "src/runtime.cc" | 11 FILENAME = "src/runtime.h" |
12 FUNCTION = re.compile("^RUNTIME_FUNCTION\(Runtime_(\w+)") | 12 LISTHEAD = re.compile(r"#define\s+(\w+LIST\w*)\((\w+)\)") |
13 FUNCTIONEND = "}\n" | 13 LISTBODY = re.compile(r".*\\$") |
14 MACRO = re.compile(r"^#define ([^ ]+)\(([^)]*)\) *([^\\]*)\\?\n$") | 14 BLACKLIST = ['INLINE_FUNCTION_LIST'] |
15 FIRST_WORD = re.compile("^\s*(.*?)[\s({\[]") | |
16 | |
17 # Expand these macros, they define further runtime functions. | |
18 EXPAND_MACROS = [ | |
19 "BUFFER_VIEW_GETTER", | |
20 "DATA_VIEW_GETTER", | |
21 "DATA_VIEW_SETTER", | |
22 "ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION", | |
23 "FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION", | |
24 "RUNTIME_UNARY_MATH", | |
25 "TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION", | |
26 ] | |
27 | 15 |
28 | 16 |
29 class Function(object): | 17 class Function(object): |
30 def __init__(self, match): | 18 def __init__(self, match): |
31 self.name = match.group(1) | 19 self.name = match.group(1).strip() |
| 20 |
| 21 def ListMacroRe(list): |
| 22 macro = LISTHEAD.match(list[0]).group(2) |
| 23 re_string = "\s*%s\((\w+)" % macro |
| 24 return re.compile(re_string) |
32 | 25 |
33 | 26 |
34 class Macro(object): | 27 def FindLists(filename): |
35 def __init__(self, match): | 28 lists = [] |
36 self.name = match.group(1) | 29 current_list = [] |
37 self.args = [s.strip() for s in match.group(2).split(",")] | 30 mode = "SEARCHING" |
38 self.lines = [] | |
39 self.indentation = 0 | |
40 self.AddLine(match.group(3)) | |
41 | |
42 def AddLine(self, line): | |
43 if not line: return | |
44 if not self.lines: | |
45 # This is the first line, detect indentation. | |
46 self.indentation = len(line) - len(line.lstrip()) | |
47 line = line.rstrip("\\\n ") | |
48 if not line: return | |
49 assert len(line[:self.indentation].strip()) == 0, \ | |
50 ("expected whitespace: '%s', full line: '%s'" % | |
51 (line[:self.indentation], line)) | |
52 line = line[self.indentation:] | |
53 if not line: return | |
54 self.lines.append(line + "\n") | |
55 | |
56 def Finalize(self): | |
57 for arg in self.args: | |
58 pattern = re.compile(r"(##|\b)%s(##|\b)" % arg) | |
59 for i in range(len(self.lines)): | |
60 self.lines[i] = re.sub(pattern, "%%(%s)s" % arg, self.lines[i]) | |
61 | |
62 def FillIn(self, arg_values): | |
63 filler = {} | |
64 assert len(arg_values) == len(self.args) | |
65 for i in range(len(self.args)): | |
66 filler[self.args[i]] = arg_values[i] | |
67 result = [] | |
68 for line in self.lines: | |
69 result.append(line % filler) | |
70 return result | |
71 | |
72 | |
73 def ReadFileAndExpandMacros(filename): | |
74 found_macros = {} | |
75 expanded_lines = [] | |
76 with open(filename, "r") as f: | 31 with open(filename, "r") as f: |
77 found_macro = None | |
78 for line in f: | 32 for line in f: |
79 if found_macro is not None: | 33 if mode == "SEARCHING": |
80 found_macro.AddLine(line) | 34 match = LISTHEAD.match(line) |
81 if not line.endswith("\\\n"): | 35 if match and match.group(1) not in BLACKLIST: |
82 found_macro.Finalize() | 36 mode = "APPENDING" |
83 found_macro = None | 37 current_list.append(line) |
84 continue | 38 else: |
85 | 39 current_list.append(line) |
86 match = MACRO.match(line) | 40 match = LISTBODY.match(line) |
87 if match: | 41 if not match: |
88 found_macro = Macro(match) | 42 mode = "SEARCHING" |
89 if found_macro.name in EXPAND_MACROS: | 43 lists.append(current_list) |
90 found_macros[found_macro.name] = found_macro | 44 current_list = [] |
91 else: | 45 return lists |
92 found_macro = None | |
93 continue | |
94 | |
95 match = FIRST_WORD.match(line) | |
96 if match: | |
97 first_word = match.group(1) | |
98 if first_word in found_macros: | |
99 MACRO_CALL = re.compile("%s\(([^)]*)\)" % first_word) | |
100 match = MACRO_CALL.match(line) | |
101 assert match | |
102 args = [s.strip() for s in match.group(1).split(",")] | |
103 expanded_lines += found_macros[first_word].FillIn(args) | |
104 continue | |
105 | |
106 expanded_lines.append(line) | |
107 return expanded_lines | |
108 | 46 |
109 | 47 |
110 # Detects runtime functions by parsing FILENAME. | 48 # Detects runtime functions by parsing FILENAME. |
111 def FindRuntimeFunctions(): | 49 def FindRuntimeFunctions(): |
112 functions = [] | 50 functions = [] |
113 expanded_lines = ReadFileAndExpandMacros(FILENAME) | 51 lists = FindLists(FILENAME) |
114 function = None | 52 for list in lists: |
115 partial_line = "" | 53 function_re = ListMacroRe(list) |
116 for line in expanded_lines: | 54 for line in list: |
117 # Multi-line definition support, ignoring macros. | 55 match = function_re.match(line) |
118 if line.startswith("RUNTIME_FUNCTION") and not line.endswith("{\n"): | 56 if match: |
119 if line.endswith("\\\n"): continue | 57 functions.append(Function(match)) |
120 partial_line = line.rstrip() | |
121 continue | |
122 if partial_line: | |
123 partial_line += " " + line.strip() | |
124 if partial_line.endswith("{"): | |
125 line = partial_line | |
126 partial_line = "" | |
127 else: | |
128 continue | |
129 | |
130 match = FUNCTION.match(line) | |
131 if match: | |
132 function = Function(match) | |
133 continue | |
134 if function is None: continue | |
135 | |
136 if line == FUNCTIONEND: | |
137 if function is not None: | |
138 functions.append(function) | |
139 function = None | |
140 return functions | 58 return functions |
141 | 59 |
142 | 60 |
143 class Builtin(object): | 61 class Builtin(object): |
144 def __init__(self, match): | 62 def __init__(self, match): |
145 self.name = match.group(1) | 63 self.name = match.group(1) |
146 | 64 |
147 | 65 |
148 def FindJSNatives(): | 66 def FindJSNatives(): |
149 PATH = "src" | 67 PATH = "src" |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
192 | 110 |
193 if errors > 0: | 111 if errors > 0: |
194 return 1 | 112 return 1 |
195 print("Runtime/Natives name clashes: checked %d/%d functions, all good." % | 113 print("Runtime/Natives name clashes: checked %d/%d functions, all good." % |
196 (len(functions), len(natives))) | 114 (len(functions), len(natives))) |
197 return 0 | 115 return 0 |
198 | 116 |
199 | 117 |
200 if __name__ == "__main__": | 118 if __name__ == "__main__": |
201 sys.exit(Main()) | 119 sys.exit(Main()) |
OLD | NEW |