Skip to content

Commit d857b26

Browse files
committed
Fix hardcoded preprocessing of Fetch worker, and add preprocessing to pthread-main.js. Add writeStackCookie(); directive to pthread-main when STACK_OVERFLOW_CHECK is defined.
1 parent 7c1a2ab commit d857b26

File tree

3 files changed

+48
-24
lines changed

3 files changed

+48
-24
lines changed

emcc.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1647,8 +1647,8 @@ def repl(m):
16471647

16481648
if shared.Settings.USE_PTHREADS:
16491649
target_dir = os.path.dirname(os.path.abspath(target))
1650-
shutil.copyfile(shared.path_from_root('src', 'pthread-main.js'),
1651-
os.path.join(target_dir, 'pthread-main.js'))
1650+
shared.run_c_preprocessor_on_file(shared.path_from_root('src', 'pthread-main.js'),
1651+
os.path.join(target_dir, 'pthread-main.js'))
16521652

16531653
# Generate the fetch-worker.js script for multithreaded emscripten_fetch() support if targeting pthreads.
16541654
if shared.Settings.FETCH and shared.Settings.USE_PTHREADS:

src/pthread-main.js

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,12 @@ this.onmessage = function(e) {
7676
assert(STACK_BASE != 0);
7777
assert(STACK_MAX > STACK_BASE);
7878
Runtime.establishStackSpace(e.data.stackBase, e.data.stackBase + e.data.stackSize);
79+
80+
#if STACK_OVERFLOW_CHECK
81+
writeStackCookie();
82+
#endif
83+
7984
var result = 0;
80-
//#if STACK_OVERFLOW_CHECK
81-
if (typeof writeStackCookie === 'function') writeStackCookie();
82-
//#endif
8385

8486
PThread.receiveObjectTransfer(e.data);
8587

@@ -93,10 +95,9 @@ this.onmessage = function(e) {
9395
} else {
9496
result = Module['asm'].dynCall_i(e.data.start_routine); // as a hack, try signature 'i' as fallback.
9597
}
96-
//#if STACK_OVERFLOW_CHECK
97-
if (typeof checkStackCookie === 'function') checkStackCookie();
98-
//#endif
99-
98+
#if STACK_OVERFLOW_CHECK
99+
checkStackCookie();
100+
#endif
100101
} catch(e) {
101102
if (e === 'Canceled!') {
102103
PThread.threadCancel();

tools/shared.py

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2652,21 +2652,44 @@ def safe_copy(src, dst):
26522652
if dst == '/dev/null': return
26532653
shutil.copyfile(src, dst)
26542654

2655-
def clang_preprocess(filename):
2656-
# TODO: REMOVE HACK AND PASS PREPROCESSOR FLAGS TO CLANG.
2657-
return subprocess.check_output([CLANG_CC, '-DFETCH_DEBUG=1', '-E', '-P', '-C', '-x', 'c', filename])
2658-
2659-
def read_and_preprocess(filename):
2660-
f = open(filename, 'r').read()
2661-
pos = 0
2662-
include_pattern = re.compile('^#include\s*["<](.*)[">]\s?$', re.MULTILINE)
2663-
while(1):
2664-
m = include_pattern.search(f, pos)
2665-
if not m:
2666-
return f
2667-
included_file = open(os.path.join(os.path.dirname(filename), m.groups(0)[0]), 'r').read()
2655+
def find_lines_with_preprocessor_directives(file):
2656+
return filter(lambda x: '#if' in x or '#elif' in x, open(file, 'r').readlines())
2657+
2658+
def run_c_preprocessor_on_file(src, dst):
2659+
# Run LLVM's C preprocessor on the given file, expanding #includes and variables found in src/setting.js.
2660+
# Historically, .js file preprocessing only expands variables found in #if etc. statements, and .js
2661+
# code uses some setting names as variables as well. For example, pthread-main.js has a variable
2662+
# TOTAL_MEMORY, which is also a Setting name. Therefore detect to only expand those Setting names that
2663+
# are referred to if and #elif defines - but that expansion is done globally in the file, so it will
2664+
# preclude one from doing things like
2665+
#
2666+
# var TOTAL_MEMORY = {{{ TOTAL_MEMORY }}};
2667+
# if TOTAL_MEMORY > 65536
2668+
#
2669+
# Still, this should give a good balance to be compatible with existing behavior.
2670+
2671+
# Find the #if lines that we'll allow expanding.
2672+
whitelisted_defines = find_lines_with_preprocessor_directives(src)
2673+
2674+
def any_string_contains(string_list, substr):
2675+
for s in string_list:
2676+
if substr in s:
2677+
return True
2678+
return False
2679+
2680+
defines = []
2681+
for s in Settings.attrs:
2682+
if any_string_contains(whitelisted_defines, s):
2683+
d = '-D' + s + '=' + str(Settings.attrs[s])
2684+
logging.debug('Expanding #define ' + d + ' when preprocessing file ' + src)
2685+
defines += [d]
2686+
2687+
response_filename = response_file.create_response_file(defines, TEMP_DIR)
2688+
preprocessed = subprocess.check_output([CLANG_CC, '-E', '-P', '-C', '-x', 'c', '@' + response_filename, src])
2689+
try_delete(response_filename)
26682690

2669-
f = f[:m.start(0)] + included_file + f[m.end(0):]
2691+
if dst: open(dst, 'w').write(preprocessed)
2692+
return preprocessed
26702693

26712694
# Generates a suitable fetch-worker.js script from the given input source JS file (which is an asm.js build output),
26722695
# and writes it out to location output_file. fetch-worker.js is the root entry point for a dedicated filesystem web
@@ -2696,7 +2719,7 @@ def make_fetch_worker(source_file, output_file):
26962719
func_code = src[loc:end_loc]
26972720
function_prologue = function_prologue + '\n' + func_code
26982721

2699-
fetch_worker_src = function_prologue + '\n' + clang_preprocess(path_from_root('src', 'fetch-worker.js'))
2722+
fetch_worker_src = function_prologue + '\n' + run_c_preprocessor_on_file(path_from_root('src', 'fetch-worker.js'), dst=None)
27002723
open(output_file, 'w').write(fetch_worker_src)
27012724

27022725

0 commit comments

Comments
 (0)