Revision: 21342
Author:   [email protected]
Date:     Fri May 16 13:23:32 2014 UTC
Log:      Add builtin detector to generate-runtime-tests.py

[email protected]

Review URL: https://codereview.chromium.org/283403002
http://code.google.com/p/v8/source/detail?r=21342

Modified:
 /branches/bleeding_edge/src/v8natives.js
 /branches/bleeding_edge/tools/generate-runtime-tests.py

=======================================
--- /branches/bleeding_edge/src/v8natives.js    Wed May 14 08:51:10 2014 UTC
+++ /branches/bleeding_edge/src/v8natives.js    Fri May 16 13:23:32 2014 UTC
@@ -1886,6 +1886,9 @@
 }

 function EnqueueMicrotask(fn) {
+  if (!IS_FUNCTION(fn)) {
+    throw new $TypeError('Can only enqueue functions');
+  }
   var microtaskState = %GetMicrotaskState();
if (IS_UNDEFINED(microtaskState.queue) || IS_NULL(microtaskState.queue)) {
     microtaskState.queue = new InternalArray;
=======================================
--- /branches/bleeding_edge/tools/generate-runtime-tests.py Fri May 16 13:16:08 2014 UTC +++ /branches/bleeding_edge/tools/generate-runtime-tests.py Fri May 16 13:23:32 2014 UTC
@@ -4,6 +4,7 @@
 # found in the LICENSE file.

 import itertools
+import js2c
 import multiprocessing
 import optparse
 import os
@@ -50,6 +51,7 @@
 EXPECTED_FUZZABLE_COUNT = 329
 EXPECTED_CCTEST_COUNT = 6
 EXPECTED_UNKNOWN_COUNT = 5
+EXPECTED_BUILTINS_COUNT = 827


 # Don't call these at all.
@@ -298,10 +300,6 @@
     return self._Variable(name,
         "\"%s\" + (function() { return \"%s\";})()" % (s1, s2))

-  def _ExternalString(self, name):
-    # Needs --expose-externalize-string.
-    return None
-
   def _InternalizedString(self, name):
     return self._Variable(name, "\"%s\"" % self._RawRandomString(0, 20))

@@ -918,6 +916,60 @@
         function = None
   return functions

+
+# Hack: This must have the same fields as class Function above, because the
+# two are used polymorphically in RunFuzzer(). We could use inheritance...
+class Builtin(object):
+  def __init__(self, match):
+    self.name = match.group(1)
+    args = match.group(2)
+    self.argslength = 0 if args == "" else args.count(",") + 1
+    self.inline = ""
+    self.args = {}
+    if self.argslength > 0:
+      args = args.split(",")
+      for i in range(len(args)):
+        # a = args[i].strip()  # TODO: filter out /* comments */ first.
+        a = ""
+        self.args[i] = Arg("Object", a, i)
+
+  def __str__(self):
+    return "%s(%d)" % (self.name, self.argslength)
+
+
+def FindJSBuiltins():
+  PATH = "src"
+  fileslist = []
+  for (root, dirs, files) in os.walk(PATH):
+    for f in files:
+      if f.endswith(".js"):
+        fileslist.append(os.path.join(root, f))
+  builtins = []
+  regexp = re.compile("^function (\w+)\s*\((.*?)\) {")
+  matches = 0
+  for filename in fileslist:
+    with open(filename, "r") as f:
+      file_contents = f.read()
+    file_contents = js2c.ExpandInlineMacros(file_contents)
+    lines = file_contents.split("\n")
+    partial_line = ""
+    for line in lines:
+      if line.startswith("function") and not '{' in line:
+        partial_line += line.rstrip()
+        continue
+      if partial_line:
+        partial_line += " " + line.strip()
+        if '{' in line:
+          line = partial_line
+          partial_line = ""
+        else:
+          continue
+      match = regexp.match(line)
+      if match:
+        builtins.append(Builtin(match))
+  return builtins
+
+
 # Classifies runtime functions.
 def ClassifyFunctions(functions):
   # Can be fuzzed with a JavaScript testcase.
@@ -1018,7 +1070,23 @@
   return "%s/fuzz_%d_%d.js" % (save_path, process_id, save_file_index)


+def _GetFuzzableRuntimeFunctions():
+  functions = FindRuntimeFunctions()
+  (js_fuzzable_functions, cctest_fuzzable_functions, unknown_functions) = \
+      ClassifyFunctions(functions)
+  return js_fuzzable_functions
+
+
+FUZZ_TARGET_LISTS = {
+  "runtime": _GetFuzzableRuntimeFunctions,
+  "builtins": FindJSBuiltins,
+}
+
+
 def RunFuzzer(process_id, options, stop_running):
+  MAX_SLEEP_TIME = 0.1
+  INITIAL_SLEEP_TIME = 0.001
+  SLEEP_TIME_FACTOR = 1.25
   base_file_name = "/dev/shm/runtime_fuzz_%d" % process_id
   test_file_name = "%s.js" % base_file_name
   stderr_file_name = "%s.out" % base_file_name
@@ -1026,19 +1094,14 @@
   while os.path.exists(_SaveFileName(options.save_path, process_id,
                                      save_file_index)):
     save_file_index += 1
-  MAX_SLEEP_TIME = 0.1
-  INITIAL_SLEEP_TIME = 0.001
-  SLEEP_TIME_FACTOR = 1.5

-  functions = FindRuntimeFunctions()
-  (js_fuzzable_functions, cctest_fuzzable_functions, unknown_functions) = \
-      ClassifyFunctions(functions)
-
+  targets = FUZZ_TARGET_LISTS[options.fuzz_target]()
   try:
     for i in range(options.num_tests):
       if stop_running.is_set(): break
-      function = random.choice(js_fuzzable_functions)  # TODO: others too
-      if function.argslength == 0: continue
+      function = None
+      while function is None or function.argslength == 0:
+        function = random.choice(targets)
       args = []
       definitions = []
       gen = Generator()
@@ -1086,11 +1149,11 @@
         save_file_index += 1
   except KeyboardInterrupt:
     stop_running.set()
-  except Exception, e:
-    print e
   finally:
-    os.remove(test_file_name)
-    os.remove(stderr_file_name)
+    if os.path.exists(test_file_name):
+      os.remove(test_file_name)
+    if os.path.exists(stderr_file_name):
+      os.remove(stderr_file_name)


 def BuildOptionParser():
@@ -1110,6 +1173,9 @@
   o = optparse.OptionParser(usage=usage)
   o.add_option("--binary", default="out/x64.debug/d8",
help="d8 binary used for running fuzz tests (default: %default)")
+  o.add_option("--fuzz-target", default="runtime",
+ help="Set of functions targeted by fuzzing. Allowed values: " + "%s (default: %%default)" % ", ".join(FUZZ_TARGET_LISTS))
   o.add_option("-n", "--num-tests", default=1000, type="int",
                help="Number of fuzz tests to generate per worker process"
                     " (default: %default)")
@@ -1122,12 +1188,21 @@
   return o


+def ProcessOptions(options, args):
+  options.save_path = os.path.expanduser(options.save_path)
+  if options.fuzz_target not in FUZZ_TARGET_LISTS:
+    print("Invalid fuzz target: %s" % options.fuzz_target)
+    return False
+  if len(args) != 1 or args[0] == "help":
+    return False
+  return True
+
+
 def Main():
   parser = BuildOptionParser()
   (options, args) = parser.parse_args()
-  options.save_path = os.path.expanduser(options.save_path)

-  if len(args) != 1 or args[0] == "help":
+  if not ProcessOptions(options, args):
     parser.print_help()
     return 1
   action = args[0]
@@ -1135,14 +1210,10 @@
   functions = FindRuntimeFunctions()
   (js_fuzzable_functions, cctest_fuzzable_functions, unknown_functions) = \
       ClassifyFunctions(functions)
+  builtins = FindJSBuiltins()

   if action == "test":
-    gen = Generator()
-    vartype = "JSTypedArray"
-    print("simple: %s" % gen.RandomVariable("x", vartype, True))
-    for i in range(10):
-      print("----")
-      print("%s" % "\n".join(gen.RandomVariable("x", vartype, False)))
+    print("put your temporary debugging code here")
     return 0

   if action == "info":
@@ -1150,6 +1221,7 @@
           "cctest_fuzzable_functions: %d, unknown_functions: %d"
           % (len(functions), len(js_fuzzable_functions),
              len(cctest_fuzzable_functions), len(unknown_functions)))
+    print("%d JavaScript builtins" % len(builtins))
     print("unknown functions:")
     for f in unknown_functions:
       print(f)
@@ -1175,6 +1247,8 @@
                          "cctest-fuzzable functions")
     errors += CheckCount(unknown_functions, EXPECTED_UNKNOWN_COUNT,
                          "functions with incomplete type information")
+    errors += CheckCount(builtins, EXPECTED_BUILTINS_COUNT,
+                         "JavaScript builtins")

     def CheckTestcasesExisting(functions):
       errors = 0
@@ -1196,6 +1270,19 @@

     errors += CheckTestcasesExisting(js_fuzzable_functions)

+    def CheckNameClashes(runtime_functions, builtins):
+      errors = 0
+      runtime_map = {}
+      for f in runtime_functions:
+        runtime_map[f.name] = 1
+      for b in builtins:
+        if b.name in runtime_map:
+          print("Builtin/Runtime_Function name clash: %s" % b.name)
+          errors += 1
+      return errors
+
+    errors += CheckNameClashes(functions, builtins)
+
     if errors > 0:
       return 1
     print("Generated runtime tests: all good.")

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to