12c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org#!/usr/bin/env python 22c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org# Copyright 2014 the V8 project authors. All rights reserved. 32c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org# Use of this source code is governed by a BSD-style license that can be 42c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org# found in the LICENSE file. 52c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org 62c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.orgimport js2c 72c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.orgimport os 82c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.orgimport re 92c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.orgimport sys 102c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org 112c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.orgFILENAME = "src/runtime.cc" 122c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.orgFUNCTION = re.compile("^RUNTIME_FUNCTION\(Runtime_(\w+)") 132c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.orgFUNCTIONEND = "}\n" 142c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.orgMACRO = re.compile(r"^#define ([^ ]+)\(([^)]*)\) *([^\\]*)\\?\n$") 152c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.orgFIRST_WORD = re.compile("^\s*(.*?)[\s({\[]") 162c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org 172c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org# Expand these macros, they define further runtime functions. 182c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.orgEXPAND_MACROS = [ 192c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org "BUFFER_VIEW_GETTER", 202c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org "DATA_VIEW_GETTER", 212c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org "DATA_VIEW_SETTER", 222c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org "ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION", 232c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org "FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION", 242c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org "RUNTIME_UNARY_MATH", 252c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org "TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION", 262c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org] 272c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org 282c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org 292c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.orgclass Function(object): 302c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org def __init__(self, match): 312c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org self.name = match.group(1) 322c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org 332c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org 342c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.orgclass Macro(object): 352c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org def __init__(self, match): 362c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org self.name = match.group(1) 372c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org self.args = [s.strip() for s in match.group(2).split(",")] 382c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org self.lines = [] 392c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org self.indentation = 0 402c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org self.AddLine(match.group(3)) 412c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org 422c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org def AddLine(self, line): 432c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if not line: return 442c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if not self.lines: 452c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org # This is the first line, detect indentation. 462c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org self.indentation = len(line) - len(line.lstrip()) 472c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org line = line.rstrip("\\\n ") 482c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if not line: return 492c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org assert len(line[:self.indentation].strip()) == 0, \ 502c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org ("expected whitespace: '%s', full line: '%s'" % 512c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org (line[:self.indentation], line)) 522c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org line = line[self.indentation:] 532c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if not line: return 542c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org self.lines.append(line + "\n") 552c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org 562c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org def Finalize(self): 572c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org for arg in self.args: 582c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org pattern = re.compile(r"(##|\b)%s(##|\b)" % arg) 592c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org for i in range(len(self.lines)): 602c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org self.lines[i] = re.sub(pattern, "%%(%s)s" % arg, self.lines[i]) 612c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org 622c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org def FillIn(self, arg_values): 632c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org filler = {} 642c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org assert len(arg_values) == len(self.args) 652c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org for i in range(len(self.args)): 662c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org filler[self.args[i]] = arg_values[i] 672c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org result = [] 682c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org for line in self.lines: 692c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org result.append(line % filler) 702c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org return result 712c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org 722c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org 732c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.orgdef ReadFileAndExpandMacros(filename): 742c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org found_macros = {} 752c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org expanded_lines = [] 762c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org with open(filename, "r") as f: 772c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org found_macro = None 782c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org for line in f: 792c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if found_macro is not None: 802c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org found_macro.AddLine(line) 812c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if not line.endswith("\\\n"): 822c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org found_macro.Finalize() 832c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org found_macro = None 842c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org continue 852c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org 862c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org match = MACRO.match(line) 872c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if match: 882c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org found_macro = Macro(match) 892c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if found_macro.name in EXPAND_MACROS: 902c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org found_macros[found_macro.name] = found_macro 912c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org else: 922c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org found_macro = None 932c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org continue 942c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org 952c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org match = FIRST_WORD.match(line) 962c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if match: 972c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org first_word = match.group(1) 982c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if first_word in found_macros: 992c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org MACRO_CALL = re.compile("%s\(([^)]*)\)" % first_word) 1002c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org match = MACRO_CALL.match(line) 1012c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org assert match 1022c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org args = [s.strip() for s in match.group(1).split(",")] 1032c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org expanded_lines += found_macros[first_word].FillIn(args) 1042c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org continue 1052c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org 1062c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org expanded_lines.append(line) 1072c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org return expanded_lines 1082c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org 1092c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org 1102c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org# Detects runtime functions by parsing FILENAME. 1112c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.orgdef FindRuntimeFunctions(): 1122c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org functions = [] 1132c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org expanded_lines = ReadFileAndExpandMacros(FILENAME) 1142c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org function = None 1152c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org partial_line = "" 1162c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org for line in expanded_lines: 1172c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org # Multi-line definition support, ignoring macros. 1182c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if line.startswith("RUNTIME_FUNCTION") and not line.endswith("{\n"): 1192c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if line.endswith("\\\n"): continue 1202c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org partial_line = line.rstrip() 1212c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org continue 1222c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if partial_line: 1232c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org partial_line += " " + line.strip() 1242c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if partial_line.endswith("{"): 1252c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org line = partial_line 1262c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org partial_line = "" 1272c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org else: 1282c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org continue 1292c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org 1302c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org match = FUNCTION.match(line) 1312c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if match: 1322c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org function = Function(match) 1332c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org continue 1342c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if function is None: continue 1352c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org 1362c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if line == FUNCTIONEND: 1372c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if function is not None: 1382c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org functions.append(function) 1392c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org function = None 1402c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org return functions 1412c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org 1422c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org 1432c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.orgclass Builtin(object): 1442c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org def __init__(self, match): 1452c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org self.name = match.group(1) 1462c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org 1472c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org 1482c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.orgdef FindJSNatives(): 1492c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org PATH = "src" 1502c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org fileslist = [] 1512c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org for (root, dirs, files) in os.walk(PATH): 1522c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org for f in files: 1532c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if f.endswith(".js"): 1542c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org fileslist.append(os.path.join(root, f)) 1552c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org natives = [] 1562c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org regexp = re.compile("^function (\w+)\s*\((.*?)\) {") 1572c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org matches = 0 1582c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org for filename in fileslist: 1592c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org with open(filename, "r") as f: 1602c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org file_contents = f.read() 1612c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org file_contents = js2c.ExpandInlineMacros(file_contents) 1622c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org lines = file_contents.split("\n") 1632c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org partial_line = "" 1642c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org for line in lines: 1652c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if line.startswith("function") and not '{' in line: 1662c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org partial_line += line.rstrip() 1672c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org continue 1682c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if partial_line: 1692c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org partial_line += " " + line.strip() 1702c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if '{' in line: 1712c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org line = partial_line 1722c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org partial_line = "" 1732c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org else: 1742c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org continue 1752c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org match = regexp.match(line) 1762c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if match: 1772c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org natives.append(Builtin(match)) 1782c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org return natives 1792c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org 1802c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org 1812c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.orgdef Main(): 1822c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org functions = FindRuntimeFunctions() 1832c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org natives = FindJSNatives() 1842c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org errors = 0 1852c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org runtime_map = {} 1862c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org for f in functions: 1872c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org runtime_map[f.name] = 1 1882c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org for b in natives: 1892c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if b.name in runtime_map: 1902c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org print("JS_Native/Runtime_Function name clash: %s" % b.name) 1912c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org errors += 1 1922c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org 1932c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if errors > 0: 1942c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org return 1 1952c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org print("Runtime/Natives name clashes: checked %d/%d functions, all good." % 1962c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org (len(functions), len(natives))) 1972c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org return 0 1982c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org 1992c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org 2002c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.orgif __name__ == "__main__": 2012c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org sys.exit(Main()) 202