Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(43)

Unified Diff: tools/generate-runtime-tests.py

Issue 290513002: Expand C++ macros in tools/generate-runtime-tests.py to increase coverage (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: formatting Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « test/mjsunit/runtime-gen/typedarraygetlength.js ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/generate-runtime-tests.py
diff --git a/tools/generate-runtime-tests.py b/tools/generate-runtime-tests.py
index 5ce4c9efddc2485dc8b60a2abd61e37834e7d45d..8770aa2916b51c76e49ec2e241fe782dac4714bf 100755
--- a/tools/generate-runtime-tests.py
+++ b/tools/generate-runtime-tests.py
@@ -16,24 +16,38 @@ import subprocess
import sys
import time
-# TODO(jkummerow): Support DATA_VIEW_{G,S}ETTER in runtime.cc
-
FILENAME = "src/runtime.cc"
HEADERFILENAME = "src/runtime.h"
FUNCTION = re.compile("^RUNTIME_FUNCTION\(Runtime_(\w+)")
ARGSLENGTH = re.compile(".*ASSERT\(.*args\.length\(\) == (\d+)\);")
FUNCTIONEND = "}\n"
+MACRO = re.compile(r"^#define ([^ ]+)\(([^)]*)\) *([^\\]*)\\?\n$")
+FIRST_WORD = re.compile("^\s*(.*?)[\s({\[]")
WORKSPACE = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), ".."))
BASEPATH = os.path.join(WORKSPACE, "test", "mjsunit", "runtime-gen")
THIS_SCRIPT = os.path.relpath(sys.argv[0])
+# Expand these macros, they define further runtime functions.
+EXPAND_MACROS = [
+ "BUFFER_VIEW_GETTER",
+ "DATA_VIEW_GETTER",
+ "DATA_VIEW_SETTER",
+ "RUNTIME_UNARY_MATH",
+]
+# TODO(jkummerow): We could also whitelist the following macros, but the
+# functions they define are so trivial that it's unclear how much benefit
+# that would provide:
+# ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION
+# FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION
+# TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION
+
# Counts of functions in each detection state. These are used to assert
# that the parser doesn't bit-rot. Change the values as needed when you add,
# remove or change runtime functions, but make sure we don't lose our ability
# to parse them!
-EXPECTED_FUNCTION_COUNT = 338
-EXPECTED_FUZZABLE_COUNT = 305
+EXPECTED_FUNCTION_COUNT = 362
+EXPECTED_FUZZABLE_COUNT = 329
EXPECTED_CCTEST_COUNT = 6
EXPECTED_UNKNOWN_COUNT = 5
@@ -580,6 +594,12 @@ class Generator(object):
"new %sArray(%s)" % (arraytype, ", ".join(args)),
fallback="new %sArray(8)" % arraytype))
+ def _JSArrayBufferView(self, name, recursion_budget):
+ if random.random() < 0.4:
+ return self._JSDataView(name, recursion_budget)
+ else:
+ return self._JSTypedArray(name, recursion_budget)
+
def _JSWeakCollection(self, name, recursion_budget):
ctor = random.choice([self._JSMap, self._JSSet])
return ctor(name, recursion_budget, weak="Weak")
@@ -634,7 +654,8 @@ class Generator(object):
"Int32": ["32", _Int32],
"JSArray": ["new Array()", _JSArray],
"JSArrayBuffer": ["new ArrayBuffer(8)", _JSArrayBuffer],
- "JSDataView": ["new DataView(new ArrayBuffer(8))", _JSDataView],
+ "JSArrayBufferView": ["new Int32Array(2)", _JSArrayBufferView],
+ "JSDataView": ["new DataView(new ArrayBuffer(24))", _JSDataView],
"JSDate": ["new Date()", _JSDate],
"JSFunction": ["function() {}", _JSFunction],
"JSFunctionProxy": ["Proxy.createFunction({}, function() {})",
@@ -757,6 +778,45 @@ class Function(object):
return "".join(s)
+class Macro(object):
+ def __init__(self, match):
+ self.name = match.group(1)
+ self.args = [s.strip() for s in match.group(2).split(",")]
+ self.lines = []
+ self.indentation = 0
+ self.AddLine(match.group(3))
+
+ def AddLine(self, line):
+ if not line: return
+ if not self.lines:
+ # This is the first line, detect indentation.
+ self.indentation = len(line) - len(line.lstrip())
+ line = line.rstrip("\\\n ")
+ if not line: return
+ assert len(line[:self.indentation].strip()) == 0, \
+ ("expected whitespace: '%s', full line: '%s'" %
+ (line[:self.indentation], line))
+ line = line[self.indentation:]
+ if not line: return
+ self.lines.append(line + "\n")
+
+ def Finalize(self):
+ for arg in self.args:
+ pattern = re.compile(r"(##|\b)%s(##|\b)" % arg)
+ for i in range(len(self.lines)):
+ self.lines[i] = re.sub(pattern, "%%(%s)s" % arg, self.lines[i])
+
+ def FillIn(self, arg_values):
+ filler = {}
+ assert len(arg_values) == len(self.args)
+ for i in range(len(self.args)):
+ filler[self.args[i]] = arg_values[i]
+ result = []
+ for line in self.lines:
+ result.append(line % filler)
+ return result
+
+
# Parses HEADERFILENAME to find out which runtime functions are "inline".
def FindInlineRuntimeFunctions():
inline_functions = []
@@ -778,47 +838,84 @@ def FindInlineRuntimeFunctions():
return inline_functions
-# Detects runtime functions by parsing FILENAME.
-def FindRuntimeFunctions():
- inline_functions = FindInlineRuntimeFunctions()
- functions = []
- with open(FILENAME, "r") as f:
- function = None
- partial_line = ""
+def ReadFileAndExpandMacros(filename):
+ found_macros = {}
+ expanded_lines = []
+ with open(filename, "r") as f:
+ found_macro = None
for line in f:
- # Multi-line definition support, ignoring macros.
- if line.startswith("RUNTIME_FUNCTION") and not line.endswith("{\n"):
- if line.endswith("\\\n"): continue
- partial_line = line.rstrip()
+ if found_macro is not None:
+ found_macro.AddLine(line)
+ if not line.endswith("\\\n"):
+ found_macro.Finalize()
+ found_macro = None
continue
- if partial_line:
- partial_line += " " + line.strip()
- if partial_line.endswith("{"):
- line = partial_line
- partial_line = ""
- else:
- continue
- match = FUNCTION.match(line)
+ match = MACRO.match(line)
if match:
- function = Function(match)
- if function.name in inline_functions:
- function.inline = "_"
+ found_macro = Macro(match)
+ if found_macro.name in EXPAND_MACROS:
+ found_macros[found_macro.name] = found_macro
+ else:
+ found_macro = None
continue
- if function is None: continue
- match = ARGSLENGTH.match(line)
+ match = FIRST_WORD.match(line)
if match:
- function.SetArgsLength(match)
- continue
+ first_word = match.group(1)
+ if first_word in found_macros:
+ MACRO_CALL = re.compile("%s\(([^)]*)\)" % first_word)
+ match = MACRO_CALL.match(line)
+ assert match
+ args = [s.strip() for s in match.group(1).split(",")]
+ expanded_lines += found_macros[first_word].FillIn(args)
+ continue
+
+ expanded_lines.append(line)
+ return expanded_lines
+
- if function.TryParseArg(line):
+# Detects runtime functions by parsing FILENAME.
+def FindRuntimeFunctions():
+ inline_functions = FindInlineRuntimeFunctions()
+ functions = []
+ expanded_lines = ReadFileAndExpandMacros(FILENAME)
+ function = None
+ partial_line = ""
+ for line in expanded_lines:
+ # Multi-line definition support, ignoring macros.
+ if line.startswith("RUNTIME_FUNCTION") and not line.endswith("{\n"):
+ if line.endswith("\\\n"): continue
+ partial_line = line.rstrip()
+ continue
+ if partial_line:
+ partial_line += " " + line.strip()
+ if partial_line.endswith("{"):
+ line = partial_line
+ partial_line = ""
+ else:
continue
- if line == FUNCTIONEND:
- if function is not None:
- functions.append(function)
- function = None
+ match = FUNCTION.match(line)
+ if match:
+ function = Function(match)
+ if function.name in inline_functions:
+ function.inline = "_"
+ continue
+ if function is None: continue
+
+ match = ARGSLENGTH.match(line)
+ if match:
+ function.SetArgsLength(match)
+ continue
+
+ if function.TryParseArg(line):
+ continue
+
+ if line == FUNCTIONEND:
+ if function is not None:
+ functions.append(function)
+ function = None
return functions
# Classifies runtime functions.
« no previous file with comments | « test/mjsunit/runtime-gen/typedarraygetlength.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698