lib: add internal check macros

PR-URL: https://github.com/nodejs/node/pull/18852
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
This commit is contained in:
Gus Caplan 2018-03-01 21:04:59 -06:00
parent 0c25cdf39a
commit 3ed363cb36
No known key found for this signature in database
GPG Key ID: F00BD11880E82F0E
7 changed files with 69 additions and 9 deletions

7
configure vendored
View File

@ -434,6 +434,11 @@ intl_optgroup.add_option('--download-path',
parser.add_option_group(intl_optgroup) 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', http2_optgroup.add_option('--debug-http2',
action='store_true', action='store_true',
dest='debug_http2', dest='debug_http2',
@ -935,6 +940,8 @@ def configure_node(o):
if options.enable_static: if options.enable_static:
o['variables']['node_target_type'] = 'static_library' o['variables']['node_target_type'] = 'static_library'
o['variables']['node_debug_lib'] = b(options.node_debug_lib)
if options.debug_http2: if options.debug_http2:
o['variables']['debug_http2'] = 1 o['variables']['debug_http2'] = 1
else: else:

View File

@ -5,3 +5,18 @@ rules:
node-core/no-let-in-for-declaration: error node-core/no-let-in-for-declaration: error
node-core/lowercase-name-for-primitive: error node-core/lowercase-name-for-primitive: error
node-core/non-ascii-character: error node-core/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

View File

@ -714,6 +714,7 @@
'inputs': [ 'inputs': [
'<@(library_files)', '<@(library_files)',
'./config.gypi', './config.gypi',
'tools/check_macros.py'
], ],
'outputs': [ 'outputs': [
'<(SHARED_INTERMEDIATE_DIR)/node_javascript.cc', '<(SHARED_INTERMEDIATE_DIR)/node_javascript.cc',
@ -724,6 +725,12 @@
}], }],
[ 'node_use_perfctr=="false"', { [ 'node_use_perfctr=="false"', {
'inputs': [ 'src/noperfctr_macros.py' ] 'inputs': [ 'src/noperfctr_macros.py' ]
}],
[ 'node_debug_lib=="false"', {
'inputs': [ 'tools/nodcheck_macros.py' ]
}],
[ 'node_debug_lib=="true"', {
'inputs': [ 'tools/dcheck_macros.py' ]
}] }]
], ],
'action': [ 'action': [

7
tools/check_macros.py Normal file
View File

@ -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));

7
tools/dcheck_macros.py Normal file
View File

@ -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));

View File

@ -74,20 +74,27 @@ def ExpandConstants(lines, constants):
def ExpandMacros(lines, macros): def ExpandMacros(lines, macros):
def expander(s):
return ExpandMacros(s, macros)
for name, macro in macros.items(): for name, macro in macros.items():
start = lines.find(name + '(', 0) name_pattern = re.compile("\\b%s\\(" % name)
while start != -1: pattern_match = name_pattern.search(lines, 0)
while pattern_match is not None:
# Scan over the arguments # Scan over the arguments
assert lines[start + len(name)] == '('
height = 1 height = 1
end = start + len(name) + 1 start = pattern_match.start()
end = pattern_match.end()
assert lines[end - 1] == '('
last_match = end last_match = end
arg_index = 0 arg_index = [0] # Wrap state into array, to work around Python "scoping"
mapping = { } mapping = {}
def add_arg(str): def add_arg(str):
# Remember to expand recursively in the arguments # Remember to expand recursively in the arguments
replacement = ExpandMacros(str.strip(), macros) if arg_index[0] >= len(macro.args):
mapping[macro.args[arg_index]] = replacement return
replacement = expander(str.strip())
mapping[macro.args[arg_index[0]]] = replacement
arg_index[0] += 1
while end < len(lines) and height > 0: while end < len(lines) and height > 0:
# We don't count commas at higher nesting levels. # We don't count commas at higher nesting levels.
if lines[end] == ',' and height == 1: if lines[end] == ',' and height == 1:
@ -100,10 +107,13 @@ def ExpandMacros(lines, macros):
end = end + 1 end = end + 1
# Remember to add the last match. # Remember to add the last match.
add_arg(lines[last_match:end-1]) 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) result = macro.expand(mapping)
# Replace the occurrence of the macro with the expansion # Replace the occurrence of the macro with the expansion
lines = lines[:start] + result + lines[end:] lines = lines[:start] + result + lines[end:]
start = lines.find(name + '(', start) pattern_match = name_pattern.search(lines, start + len(result))
return lines return lines

7
tools/nodcheck_macros.py Normal file
View File

@ -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);