diff --git a/configure b/configure index d999cfc47d87fd..8770c915761700 100755 --- a/configure +++ b/configure @@ -439,6 +439,11 @@ intl_optgroup.add_option('--download-path', parser.add_option_group(intl_optgroup) +parser.add_option('--debug-lib', + action='store_true', + dest='node_debug_lib', + help='build lib with DCHECK macros') + http2_optgroup.add_option('--debug-http2', action='store_true', dest='debug_http2', @@ -949,6 +954,8 @@ def configure_node(o): if options.enable_static: o['variables']['node_target_type'] = 'static_library' + o['variables']['node_debug_lib'] = b(options.node_debug_lib) + if options.debug_http2: o['variables']['debug_http2'] = 1 else: diff --git a/lib/.eslintrc.yaml b/lib/.eslintrc.yaml index e87596d4d5c21b..4eebdb6617c101 100644 --- a/lib/.eslintrc.yaml +++ b/lib/.eslintrc.yaml @@ -5,3 +5,18 @@ rules: no-let-in-for-declaration: error lowercase-name-for-primitive: error non-ascii-character: error +globals: + CHECK: false + CHECK_EQ: false + CHECK_GE: false + CHECK_GT: false + CHECK_LE: false + CHECK_LT: false + CHECK_NE: false + DCHECK: false + DCHECK_EQ: false + DCHECK_GE: false + DCHECK_GT: false + DCHECK_LE: false + DCHECK_LT: false + DCHECK_NE: false diff --git a/node.gyp b/node.gyp index 1ab7b207e21339..349f9a0b6fb755 100644 --- a/node.gyp +++ b/node.gyp @@ -702,6 +702,7 @@ 'inputs': [ '<@(library_files)', './config.gypi', + 'tools/check_macros.py' ], 'outputs': [ '<(SHARED_INTERMEDIATE_DIR)/node_javascript.cc', @@ -715,6 +716,12 @@ }], [ 'node_use_perfctr=="false"', { 'inputs': [ 'src/noperfctr_macros.py' ] + }], + [ 'node_debug_lib=="false"', { + 'inputs': [ 'tools/nodcheck_macros.py' ] + }], + [ 'node_debug_lib=="true"', { + 'inputs': [ 'tools/dcheck_macros.py' ] }] ], 'action': [ diff --git a/tools/check_macros.py b/tools/check_macros.py new file mode 100644 index 00000000000000..2baf0d7f419573 --- /dev/null +++ b/tools/check_macros.py @@ -0,0 +1,7 @@ +macro CHECK(x) = do { if (!(x)) (process._rawDebug("CHECK: x == true"), process.abort()) } while (0); +macro CHECK_EQ(a, b) = CHECK((a) === (b)); +macro CHECK_GE(a, b) = CHECK((a) >= (b)); +macro CHECK_GT(a, b) = CHECK((a) > (b)); +macro CHECK_LE(a, b) = CHECK((a) <= (b)); +macro CHECK_LT(a, b) = CHECK((a) < (b)); +macro CHECK_NE(a, b) = CHECK((a) !== (b)); diff --git a/tools/dcheck_macros.py b/tools/dcheck_macros.py new file mode 100644 index 00000000000000..acc68fadb01abe --- /dev/null +++ b/tools/dcheck_macros.py @@ -0,0 +1,7 @@ +macro DCHECK(x) = do { if (!(x)) (process._rawDebug("DCHECK: x == true"), process.abort()) } while (0); +macro DCHECK_EQ(a, b) = DCHECK((a) === (b)); +macro DCHECK_GE(a, b) = DCHECK((a) >= (b)); +macro DCHECK_GT(a, b) = DCHECK((a) > (b)); +macro DCHECK_LE(a, b) = DCHECK((a) <= (b)); +macro DCHECK_LT(a, b) = DCHECK((a) < (b)); +macro DCHECK_NE(a, b) = DCHECK((a) !== (b)); diff --git a/tools/js2c.py b/tools/js2c.py index d2d63ad571205d..fa22b0b9722ce4 100755 --- a/tools/js2c.py +++ b/tools/js2c.py @@ -74,20 +74,27 @@ def ExpandConstants(lines, constants): def ExpandMacros(lines, macros): + def expander(s): + return ExpandMacros(s, macros) for name, macro in macros.items(): - start = lines.find(name + '(', 0) - while start != -1: + name_pattern = re.compile("\\b%s\\(" % name) + pattern_match = name_pattern.search(lines, 0) + while pattern_match is not None: # Scan over the arguments - assert lines[start + len(name)] == '(' height = 1 - end = start + len(name) + 1 + start = pattern_match.start() + end = pattern_match.end() + assert lines[end - 1] == '(' last_match = end - arg_index = 0 - mapping = { } + arg_index = [0] # Wrap state into array, to work around Python "scoping" + mapping = {} def add_arg(str): # Remember to expand recursively in the arguments - replacement = ExpandMacros(str.strip(), macros) - mapping[macro.args[arg_index]] = replacement + if arg_index[0] >= len(macro.args): + return + replacement = expander(str.strip()) + mapping[macro.args[arg_index[0]]] = replacement + arg_index[0] += 1 while end < len(lines) and height > 0: # We don't count commas at higher nesting levels. if lines[end] == ',' and height == 1: @@ -100,10 +107,13 @@ def add_arg(str): end = end + 1 # Remember to add the last match. add_arg(lines[last_match:end-1]) + if arg_index[0] < len(macro.args) -1: + lineno = lines.count(os.linesep, 0, start) + 1 + raise Exception('line %s: Too few arguments for macro "%s"' % (lineno, name)) result = macro.expand(mapping) # Replace the occurrence of the macro with the expansion lines = lines[:start] + result + lines[end:] - start = lines.find(name + '(', start) + pattern_match = name_pattern.search(lines, start + len(result)) return lines diff --git a/tools/nodcheck_macros.py b/tools/nodcheck_macros.py new file mode 100644 index 00000000000000..7bd2f209f511fc --- /dev/null +++ b/tools/nodcheck_macros.py @@ -0,0 +1,7 @@ +macro DCHECK(x) = void(x); +macro DCHECK_EQ(a, b) = void(a, b); +macro DCHECK_GE(a, b) = void(a, b); +macro DCHECK_GT(a, b) = void(a, b); +macro DCHECK_LE(a, b) = void(a, b); +macro DCHECK_LT(a, b) = void(a, b); +macro DCHECK_NE(a, b) = void(a, b);