diff options
-rwxr-xr-x | emscripten.py | 36 | ||||
-rw-r--r-- | src/library.js | 28 | ||||
-rw-r--r-- | src/parseTools.js | 4 | ||||
-rw-r--r-- | src/settings.js | 3 | ||||
-rw-r--r-- | tests/runner.py | 6 |
5 files changed, 58 insertions, 19 deletions
diff --git a/emscripten.py b/emscripten.py index ecfb04fc..a26e1346 100755 --- a/emscripten.py +++ b/emscripten.py @@ -4,6 +4,7 @@ import json import optparse import os import subprocess +import re import sys import tempfile from tools import shared @@ -164,13 +165,42 @@ def main(args): settings['CORRECT_SIGNS'] = 2 settings['CORRECT_SIGNS_LINES'] = lines + # Add header defines to settings + defines = {} + include_root = path_from_root('system', 'include') + headers = args.headers[0].split(',') + while len(headers) > 0: + header = headers.pop(0) + if not os.path.isabs(header): + header = os.path.join(include_root, header) + for line in open(header, 'r'): + line = line.replace('\t', ' ') + m = re.match('^ *#define +(?P<name>[\w_]+) +(?P<value>\d+).*', line) + if m: + defines[m.group('name')] = m.group('value') + m = re.match('^ *#include *["<](?P<name>[\w_.-/]+)[">].*', line) + if m: + # Find this file + found = False + for w in [w for w in os.walk(include_root)]: + for f in w[2]: + curr = os.path.join(w[0], f) + if curr.endswith(m.group('name')): + headers.append(curr) + found = True + break + if found: break + #assert found, 'Could not find header: ' + m.group('name') + if len(defines) > 0: + settings['C_DEFINES'] = defines + # Compile the assembly to Javascript. emscript(args.infile, json.dumps(settings), args.outfile) if __name__ == '__main__': parser = optparse.OptionParser( - usage='usage: %prog [-h] [-O] [-m] [-o OUTFILE] [-s FOO=BAR]* infile', + usage='usage: %prog [-h] [-O] [-m] [-H HEADERS] [-o OUTFILE] [-s FOO=BAR]* infile', description=('Compile an LLVM assembly file to Javascript. Accepts both ' 'human-readable (*.ll) and bitcode (*.bc) formats.'), epilog='You should have an ~/.emscripten file set up; see settings.py.') @@ -182,6 +212,10 @@ if __name__ == '__main__': default=False, action='store_true', help='Use dlmalloc. Without, uses a dummy allocator.') + parser.add_option('-H', '--headers', + default=[], + action='append', + help='System headers (comma separated) whose #defines should be exposed to the compiled code.') parser.add_option('-o', '--outfile', default=sys.stdout, help='Where to write the output; defaults to stdout.') diff --git a/src/library.js b/src/library.js index a0f41a35..d9ca93cf 100644 --- a/src/library.js +++ b/src/library.js @@ -971,7 +971,7 @@ LibraryManager.library = { } var stream = FS.streams[fildes]; switch (cmd) { - case 0: // F_DUPFD. + case {{{ C_DEFINES['F_DUPFD'] }}}: var arg = {{{ makeGetValue('varargs', 0, 'i32') }}}; if (arg < 0) { ___setErrNo(ERRNO_CODES.EINVAL); @@ -984,10 +984,10 @@ LibraryManager.library = { if (arg in FS.streams) arg = FS.streams.length; FS.streams[arg] = newStream; return arg; - case 1: // F_GETFD. - case 2: // F_SETFD. + case {{{ C_DEFINES['F_GETFD'] }}}: + case {{{ C_DEFINES['F_SETFD'] }}}: return 0; // FD_CLOEXEC makes no sense for a single process. - case 3: // F_GETFL. + case {{{ C_DEFINES['F_GETFL'] }}}: var flags = 0; if (stream.isRead && stream.isWrite) flags = 0x2; // O_RDWR. else if (!stream.isRead && stream.isWrite) flags = 0x1; // O_WRONLY. @@ -995,26 +995,26 @@ LibraryManager.library = { if (stream.isAppend) flags |= 0x400; // O_APPEND. // Synchronization and blocking flags are irrelevant to us. return flags; - case 4: // F_SETFL. + case {{{ C_DEFINES['F_SETFL'] }}}: var arg = {{{ makeGetValue('varargs', 0, 'i32') }}}; stream.isAppend = Boolean(arg | 0x400); // O_APPEND. // Synchronization and blocking flags are irrelevant to us. return 0; - case 5: // F_GETLK. - case 12: // F_GETLK64. + case {{{ C_DEFINES['F_GETLK'] }}}: + case {{{ C_DEFINES['F_GETLK64'] }}}: var arg = {{{ makeGetValue('varargs', 0, 'i32') }}}; var offset = ___flock_struct_layout.l_type; // We're always unlocked. - {{{ makeSetValue('arg', 'offset', '2', 'i16') }}} // F_UNLCK. + {{{ makeSetValue('arg', 'offset', C_DEFINES['F_UNLCK'], 'i16') }}} return 0; - case 6: // F_SETLK. - case 7: // F_SETLKW. - case 13: // F_SETLK64. - case 14: // F_SETLKW64. + case {{{ C_DEFINES['F_SETLK'] }}}: + case {{{ C_DEFINES['F_SETLKW'] }}}: + case {{{ C_DEFINES['F_SETLK64'] }}}: + case {{{ C_DEFINES['F_SETLKW64'] }}}: // Pretend that the locking is successful. return 0; - case 8: // F_SETOWN. - case 9: // F_GETOWN. + case {{{ C_DEFINES['F_SETOWN'] }}}: + case {{{ C_DEFINES['F_GETOWN'] }}}: // These are for sockets. We don't have them implemented (yet?). ___setErrNo(ERRNO_CODES.EINVAL); return -1; diff --git a/src/parseTools.js b/src/parseTools.js index ab67cbf7..7d62b34d 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -6,7 +6,9 @@ function processMacros(text) { return text.replace(/{{{[^}]+}}}/g, function(str) { str = str.substr(3, str.length-6); - return eval(str).toString(); + var ret = eval(str); + if (ret !== undefined) ret = ret.toString(); + return ret; }); } diff --git a/src/settings.js b/src/settings.js index ed4fcd05..392263df 100644 --- a/src/settings.js +++ b/src/settings.js @@ -123,6 +123,9 @@ INCLUDE_FULL_LIBRARY = 0; // Whether to include the whole library rather than ju // dynamically loading modules that make use of runtime // library functions that are not used in the main module. +C_DEFINES = {}; // A set of defines, for example generated from your header files. + // This lets the emscripten libc see the right values + SHOW_LABELS = 0; // Show labels in the generated code BUILD_AS_SHARED_LIB = 0; // Whether to build the code as a shared library, which diff --git a/tests/runner.py b/tests/runner.py index 9afedecf..5bd321da 100644 --- a/tests/runner.py +++ b/tests/runner.py @@ -2513,7 +2513,7 @@ if 'benchmark' not in str(sys.argv): open(filename, 'w').write(src) src = open(path_from_root('tests', 'fcntl', 'src.c'), 'r').read() expected = open(path_from_root('tests', 'fcntl', 'output.txt'), 'r').read() - self.do_test(src, expected, post_build=add_pre_run) + self.do_test(src, expected, post_build=add_pre_run, extra_emscripten_args=['-H', 'libc/fcntl.h']) def test_fcntl_open(self): def add_pre_run(filename): @@ -2528,7 +2528,7 @@ if 'benchmark' not in str(sys.argv): open(filename, 'w').write(src) src = open(path_from_root('tests', 'fcntl-open', 'src.c'), 'r').read() expected = open(path_from_root('tests', 'fcntl-open', 'output.txt'), 'r').read() - self.do_test(src, expected, post_build=add_pre_run) + self.do_test(src, expected, post_build=add_pre_run, extra_emscripten_args=['-H', 'libc/fcntl.h']) def test_fcntl_misc(self): def add_pre_run(filename): @@ -2539,7 +2539,7 @@ if 'benchmark' not in str(sys.argv): open(filename, 'w').write(src) src = open(path_from_root('tests', 'fcntl-misc', 'src.c'), 'r').read() expected = open(path_from_root('tests', 'fcntl-misc', 'output.txt'), 'r').read() - self.do_test(src, expected, post_build=add_pre_run) + self.do_test(src, expected, post_build=add_pre_run, extra_emscripten_args=['-H', 'libc/fcntl.h']) def test_poll(self): def add_pre_run(filename): |