Expand C++ macros in tools/generate-runtime-tests.py to increase coverage

R=dslomov@chromium.org

Review URL: https://codereview.chromium.org/290513002

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@21340 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 75a7a315
......@@ -1404,11 +1404,11 @@ static bool DataViewSetValue(
#define DATA_VIEW_GETTER(TypeName, Type, Converter) \
RUNTIME_FUNCTION(Runtime_DataViewGet##TypeName) { \
RUNTIME_FUNCTION(Runtime_DataViewGet##TypeName) { \
HandleScope scope(isolate); \
ASSERT(args.length() == 3); \
CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0); \
CONVERT_ARG_HANDLE_CHECKED(Object, offset, 1); \
CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset, 1); \
CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 2); \
Type result; \
if (DataViewGetValue( \
......@@ -1486,12 +1486,12 @@ double DataViewConvertValue<double>(double value) {
#define DATA_VIEW_SETTER(TypeName, Type) \
RUNTIME_FUNCTION(Runtime_DataViewSet##TypeName) { \
RUNTIME_FUNCTION(Runtime_DataViewSet##TypeName) { \
HandleScope scope(isolate); \
ASSERT(args.length() == 4); \
CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0); \
CONVERT_ARG_HANDLE_CHECKED(Object, offset, 1); \
CONVERT_ARG_HANDLE_CHECKED(Object, value, 2); \
CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset, 1); \
CONVERT_NUMBER_ARG_HANDLE_CHECKED(value, 2); \
CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 3); \
Type v = DataViewConvertValue<Type>(value->Number()); \
if (DataViewSetValue( \
......
// Copyright 2014 the V8 project authors. All rights reserved.
// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
// Flags: --allow-natives-syntax --harmony
var _holder = new Int32Array(2);
%_ArrayBufferViewGetByteLength(_holder);
// Copyright 2014 the V8 project authors. All rights reserved.
// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
// Flags: --allow-natives-syntax --harmony
var _holder = new Int32Array(2);
%_ArrayBufferViewGetByteOffset(_holder);
// Copyright 2014 the V8 project authors. All rights reserved.
// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
// Flags: --allow-natives-syntax --harmony
var _holder = new DataView(new ArrayBuffer(24));
%DataViewGetBuffer(_holder);
// Copyright 2014 the V8 project authors. All rights reserved.
// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
// Flags: --allow-natives-syntax --harmony
var _holder = new DataView(new ArrayBuffer(24));
var _offset = 1.5;
var _is_little_endian = true;
%DataViewGetFloat32(_holder, _offset, _is_little_endian);
// Copyright 2014 the V8 project authors. All rights reserved.
// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
// Flags: --allow-natives-syntax --harmony
var _holder = new DataView(new ArrayBuffer(24));
var _offset = 1.5;
var _is_little_endian = true;
%DataViewGetFloat64(_holder, _offset, _is_little_endian);
// Copyright 2014 the V8 project authors. All rights reserved.
// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
// Flags: --allow-natives-syntax --harmony
var _holder = new DataView(new ArrayBuffer(24));
var _offset = 1.5;
var _is_little_endian = true;
%DataViewGetInt16(_holder, _offset, _is_little_endian);
// Copyright 2014 the V8 project authors. All rights reserved.
// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
// Flags: --allow-natives-syntax --harmony
var _holder = new DataView(new ArrayBuffer(24));
var _offset = 1.5;
var _is_little_endian = true;
%DataViewGetInt32(_holder, _offset, _is_little_endian);
// Copyright 2014 the V8 project authors. All rights reserved.
// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
// Flags: --allow-natives-syntax --harmony
var _holder = new DataView(new ArrayBuffer(24));
var _offset = 1.5;
var _is_little_endian = true;
%DataViewGetInt8(_holder, _offset, _is_little_endian);
// Copyright 2014 the V8 project authors. All rights reserved.
// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
// Flags: --allow-natives-syntax --harmony
var _holder = new DataView(new ArrayBuffer(24));
var _offset = 1.5;
var _is_little_endian = true;
%DataViewGetUint16(_holder, _offset, _is_little_endian);
// Copyright 2014 the V8 project authors. All rights reserved.
// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
// Flags: --allow-natives-syntax --harmony
var _holder = new DataView(new ArrayBuffer(24));
var _offset = 1.5;
var _is_little_endian = true;
%DataViewGetUint32(_holder, _offset, _is_little_endian);
// Copyright 2014 the V8 project authors. All rights reserved.
// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
// Flags: --allow-natives-syntax --harmony
var _holder = new DataView(new ArrayBuffer(24));
var _offset = 1.5;
var _is_little_endian = true;
%DataViewGetUint8(_holder, _offset, _is_little_endian);
// Copyright 2014 the V8 project authors. All rights reserved.
// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
// Flags: --allow-natives-syntax --harmony
var _holder = new DataView(new ArrayBuffer(8));
var _holder = new DataView(new ArrayBuffer(24));
var _buffer = new ArrayBuffer(8);
var _byte_offset = 1.5;
var _byte_length = 1.5;
......
// Copyright 2014 the V8 project authors. All rights reserved.
// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
// Flags: --allow-natives-syntax --harmony
var _holder = new DataView(new ArrayBuffer(24));
var _offset = 1.5;
var _value = 1.5;
var _is_little_endian = true;
%DataViewSetFloat32(_holder, _offset, _value, _is_little_endian);
// Copyright 2014 the V8 project authors. All rights reserved.
// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
// Flags: --allow-natives-syntax --harmony
var _holder = new DataView(new ArrayBuffer(24));
var _offset = 1.5;
var _value = 1.5;
var _is_little_endian = true;
%DataViewSetFloat64(_holder, _offset, _value, _is_little_endian);
// Copyright 2014 the V8 project authors. All rights reserved.
// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
// Flags: --allow-natives-syntax --harmony
var _holder = new DataView(new ArrayBuffer(24));
var _offset = 1.5;
var _value = 1.5;
var _is_little_endian = true;
%DataViewSetInt16(_holder, _offset, _value, _is_little_endian);
// Copyright 2014 the V8 project authors. All rights reserved.
// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
// Flags: --allow-natives-syntax --harmony
var _holder = new DataView(new ArrayBuffer(24));
var _offset = 1.5;
var _value = 1.5;
var _is_little_endian = true;
%DataViewSetInt32(_holder, _offset, _value, _is_little_endian);
// Copyright 2014 the V8 project authors. All rights reserved.
// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
// Flags: --allow-natives-syntax --harmony
var _holder = new DataView(new ArrayBuffer(24));
var _offset = 1.5;
var _value = 1.5;
var _is_little_endian = true;
%DataViewSetInt8(_holder, _offset, _value, _is_little_endian);
// Copyright 2014 the V8 project authors. All rights reserved.
// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
// Flags: --allow-natives-syntax --harmony
var _holder = new DataView(new ArrayBuffer(24));
var _offset = 1.5;
var _value = 1.5;
var _is_little_endian = true;
%DataViewSetUint16(_holder, _offset, _value, _is_little_endian);
// Copyright 2014 the V8 project authors. All rights reserved.
// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
// Flags: --allow-natives-syntax --harmony
var _holder = new DataView(new ArrayBuffer(24));
var _offset = 1.5;
var _value = 1.5;
var _is_little_endian = true;
%DataViewSetUint32(_holder, _offset, _value, _is_little_endian);
// Copyright 2014 the V8 project authors. All rights reserved.
// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
// Flags: --allow-natives-syntax --harmony
var _holder = new DataView(new ArrayBuffer(24));
var _offset = 1.5;
var _value = 1.5;
var _is_little_endian = true;
%DataViewSetUint8(_holder, _offset, _value, _is_little_endian);
// Copyright 2014 the V8 project authors. All rights reserved.
// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
// Flags: --allow-natives-syntax --harmony
var _x = 1.5;
%MathAcos(_x);
// Copyright 2014 the V8 project authors. All rights reserved.
// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
// Flags: --allow-natives-syntax --harmony
var _x = 1.5;
%MathAsin(_x);
// Copyright 2014 the V8 project authors. All rights reserved.
// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
// Flags: --allow-natives-syntax --harmony
var _x = 1.5;
%MathAtan(_x);
// Copyright 2014 the V8 project authors. All rights reserved.
// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
// Flags: --allow-natives-syntax --harmony
var _x = 1.5;
%_MathLogRT(_x);
// Copyright 2014 the V8 project authors. All rights reserved.
// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
// Flags: --allow-natives-syntax --harmony
var _holder = new Int32Array(2);
%_TypedArrayGetLength(_holder);
......@@ -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.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment