aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xemscripten.py36
-rw-r--r--src/library.js28
-rw-r--r--src/parseTools.js4
-rw-r--r--src/settings.js3
-rw-r--r--tests/runner.py6
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):