From: jkummerow@chromium.org Date: Fri, 16 May 2014 13:16:08 +0000 (+0000) Subject: Expand C++ macros in tools/generate-runtime-tests.py to increase coverage X-Git-Tag: upstream/4.7.83~9103 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=48c39e57b23079a5d481efb337de88d1d73bab57;p=platform%2Fupstream%2Fv8.git 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 --- diff --git a/src/runtime.cc b/src/runtime.cc index 98fe997..8148cc8 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -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 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(value->Number()); \ if (DataViewSetValue( \ diff --git a/test/mjsunit/runtime-gen/arraybufferviewgetbytelength.js b/test/mjsunit/runtime-gen/arraybufferviewgetbytelength.js new file mode 100644 index 0000000..d150ce9 --- /dev/null +++ b/test/mjsunit/runtime-gen/arraybufferviewgetbytelength.js @@ -0,0 +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 Int32Array(2); +%_ArrayBufferViewGetByteLength(_holder); diff --git a/test/mjsunit/runtime-gen/arraybufferviewgetbyteoffset.js b/test/mjsunit/runtime-gen/arraybufferviewgetbyteoffset.js new file mode 100644 index 0000000..502795a --- /dev/null +++ b/test/mjsunit/runtime-gen/arraybufferviewgetbyteoffset.js @@ -0,0 +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 Int32Array(2); +%_ArrayBufferViewGetByteOffset(_holder); diff --git a/test/mjsunit/runtime-gen/dataviewgetbuffer.js b/test/mjsunit/runtime-gen/dataviewgetbuffer.js new file mode 100644 index 0000000..b4dc225 --- /dev/null +++ b/test/mjsunit/runtime-gen/dataviewgetbuffer.js @@ -0,0 +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)); +%DataViewGetBuffer(_holder); diff --git a/test/mjsunit/runtime-gen/dataviewgetfloat32.js b/test/mjsunit/runtime-gen/dataviewgetfloat32.js new file mode 100644 index 0000000..3d377a2 --- /dev/null +++ b/test/mjsunit/runtime-gen/dataviewgetfloat32.js @@ -0,0 +1,7 @@ +// 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); diff --git a/test/mjsunit/runtime-gen/dataviewgetfloat64.js b/test/mjsunit/runtime-gen/dataviewgetfloat64.js new file mode 100644 index 0000000..82fc220 --- /dev/null +++ b/test/mjsunit/runtime-gen/dataviewgetfloat64.js @@ -0,0 +1,7 @@ +// 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); diff --git a/test/mjsunit/runtime-gen/dataviewgetint16.js b/test/mjsunit/runtime-gen/dataviewgetint16.js new file mode 100644 index 0000000..e418ed2 --- /dev/null +++ b/test/mjsunit/runtime-gen/dataviewgetint16.js @@ -0,0 +1,7 @@ +// 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); diff --git a/test/mjsunit/runtime-gen/dataviewgetint32.js b/test/mjsunit/runtime-gen/dataviewgetint32.js new file mode 100644 index 0000000..787101d --- /dev/null +++ b/test/mjsunit/runtime-gen/dataviewgetint32.js @@ -0,0 +1,7 @@ +// 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); diff --git a/test/mjsunit/runtime-gen/dataviewgetint8.js b/test/mjsunit/runtime-gen/dataviewgetint8.js new file mode 100644 index 0000000..d3a3864 --- /dev/null +++ b/test/mjsunit/runtime-gen/dataviewgetint8.js @@ -0,0 +1,7 @@ +// 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); diff --git a/test/mjsunit/runtime-gen/dataviewgetuint16.js b/test/mjsunit/runtime-gen/dataviewgetuint16.js new file mode 100644 index 0000000..0437811 --- /dev/null +++ b/test/mjsunit/runtime-gen/dataviewgetuint16.js @@ -0,0 +1,7 @@ +// 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); diff --git a/test/mjsunit/runtime-gen/dataviewgetuint32.js b/test/mjsunit/runtime-gen/dataviewgetuint32.js new file mode 100644 index 0000000..af5122d --- /dev/null +++ b/test/mjsunit/runtime-gen/dataviewgetuint32.js @@ -0,0 +1,7 @@ +// 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); diff --git a/test/mjsunit/runtime-gen/dataviewgetuint8.js b/test/mjsunit/runtime-gen/dataviewgetuint8.js new file mode 100644 index 0000000..77e2c2d --- /dev/null +++ b/test/mjsunit/runtime-gen/dataviewgetuint8.js @@ -0,0 +1,7 @@ +// 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); diff --git a/test/mjsunit/runtime-gen/dataviewinitialize.js b/test/mjsunit/runtime-gen/dataviewinitialize.js index 901a1a5..7702f4e 100644 --- a/test/mjsunit/runtime-gen/dataviewinitialize.js +++ b/test/mjsunit/runtime-gen/dataviewinitialize.js @@ -1,7 +1,7 @@ // 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; diff --git a/test/mjsunit/runtime-gen/dataviewsetfloat32.js b/test/mjsunit/runtime-gen/dataviewsetfloat32.js new file mode 100644 index 0000000..009bbcc --- /dev/null +++ b/test/mjsunit/runtime-gen/dataviewsetfloat32.js @@ -0,0 +1,8 @@ +// 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); diff --git a/test/mjsunit/runtime-gen/dataviewsetfloat64.js b/test/mjsunit/runtime-gen/dataviewsetfloat64.js new file mode 100644 index 0000000..97c5d3e --- /dev/null +++ b/test/mjsunit/runtime-gen/dataviewsetfloat64.js @@ -0,0 +1,8 @@ +// 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); diff --git a/test/mjsunit/runtime-gen/dataviewsetint16.js b/test/mjsunit/runtime-gen/dataviewsetint16.js new file mode 100644 index 0000000..27b608b --- /dev/null +++ b/test/mjsunit/runtime-gen/dataviewsetint16.js @@ -0,0 +1,8 @@ +// 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); diff --git a/test/mjsunit/runtime-gen/dataviewsetint32.js b/test/mjsunit/runtime-gen/dataviewsetint32.js new file mode 100644 index 0000000..2a4164c --- /dev/null +++ b/test/mjsunit/runtime-gen/dataviewsetint32.js @@ -0,0 +1,8 @@ +// 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); diff --git a/test/mjsunit/runtime-gen/dataviewsetint8.js b/test/mjsunit/runtime-gen/dataviewsetint8.js new file mode 100644 index 0000000..9990c4b --- /dev/null +++ b/test/mjsunit/runtime-gen/dataviewsetint8.js @@ -0,0 +1,8 @@ +// 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); diff --git a/test/mjsunit/runtime-gen/dataviewsetuint16.js b/test/mjsunit/runtime-gen/dataviewsetuint16.js new file mode 100644 index 0000000..fc2800c --- /dev/null +++ b/test/mjsunit/runtime-gen/dataviewsetuint16.js @@ -0,0 +1,8 @@ +// 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); diff --git a/test/mjsunit/runtime-gen/dataviewsetuint32.js b/test/mjsunit/runtime-gen/dataviewsetuint32.js new file mode 100644 index 0000000..837623f --- /dev/null +++ b/test/mjsunit/runtime-gen/dataviewsetuint32.js @@ -0,0 +1,8 @@ +// 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); diff --git a/test/mjsunit/runtime-gen/dataviewsetuint8.js b/test/mjsunit/runtime-gen/dataviewsetuint8.js new file mode 100644 index 0000000..d1e7bc1 --- /dev/null +++ b/test/mjsunit/runtime-gen/dataviewsetuint8.js @@ -0,0 +1,8 @@ +// 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); diff --git a/test/mjsunit/runtime-gen/mathacos.js b/test/mjsunit/runtime-gen/mathacos.js new file mode 100644 index 0000000..e09b216 --- /dev/null +++ b/test/mjsunit/runtime-gen/mathacos.js @@ -0,0 +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 _x = 1.5; +%MathAcos(_x); diff --git a/test/mjsunit/runtime-gen/mathasin.js b/test/mjsunit/runtime-gen/mathasin.js new file mode 100644 index 0000000..6f268a6 --- /dev/null +++ b/test/mjsunit/runtime-gen/mathasin.js @@ -0,0 +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 _x = 1.5; +%MathAsin(_x); diff --git a/test/mjsunit/runtime-gen/mathatan.js b/test/mjsunit/runtime-gen/mathatan.js new file mode 100644 index 0000000..2de6785 --- /dev/null +++ b/test/mjsunit/runtime-gen/mathatan.js @@ -0,0 +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 _x = 1.5; +%MathAtan(_x); diff --git a/test/mjsunit/runtime-gen/mathlogrt.js b/test/mjsunit/runtime-gen/mathlogrt.js new file mode 100644 index 0000000..fd69bc5 --- /dev/null +++ b/test/mjsunit/runtime-gen/mathlogrt.js @@ -0,0 +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 _x = 1.5; +%_MathLogRT(_x); diff --git a/test/mjsunit/runtime-gen/typedarraygetlength.js b/test/mjsunit/runtime-gen/typedarraygetlength.js new file mode 100644 index 0000000..422b24f --- /dev/null +++ b/test/mjsunit/runtime-gen/typedarraygetlength.js @@ -0,0 +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 Int32Array(2); +%_TypedArrayGetLength(_holder); diff --git a/tools/generate-runtime-tests.py b/tools/generate-runtime-tests.py index 5ce4c9e..8770aa2 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.