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