aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2012-01-04 17:42:29 -0800
committerAlon Zakai <alonzakai@gmail.com>2012-01-04 17:42:29 -0800
commitcf1d3bfc8e393900b1177b155520b9dca19385ed (patch)
treec4f8fd019b75b0b1edba842cbfa42d87093e953c
parentc4ff5f2c3b51f52c226809a14a56a888f673efd1 (diff)
parente1375560afb1768b26725ffb86d6b03457411e28 (diff)
Merge branch 'incoming'
-rwxr-xr-xemcc33
-rw-r--r--src/modules.js2
-rw-r--r--tests/runner.py40
-rw-r--r--tools/shared.py22
4 files changed, 68 insertions, 29 deletions
diff --git a/emcc b/emcc
index e08de1cb..f60cc114 100755
--- a/emcc
+++ b/emcc
@@ -138,6 +138,20 @@ Options that are modified or new in %s include:
generated code!
--closure <on> 0: No closure compiler (default in -O0, -O1)
1: Run closure compiler (default in -O2, -O3)
+ --js-transform <cmd> <cmd> will be called on the generated code
+ before it is optimized. This lets you modify
+ the JavaScript, for example adding some code
+ or removing some code, in a way that those
+ modifications will be optimized together with
+ the generated code properly. <cmd> will be
+ called with the filename of the generated
+ code as a parameter; to modify the code, you
+ can read the original data and then append to
+ it or overwrite it with the modified data.
+ <cmd> is interpreted as a space-separated
+ list of arguments, for example, <cmd> of
+ "python processor.py" will cause a python
+ script to be run.
The target file, if specified (-o <target>), defines what will
be generated:
@@ -254,6 +268,7 @@ try:
opt_level = 0
llvm_opt_level = None
closure = None
+ js_transform = None
def check_bad_eq(arg):
assert '=' not in arg, 'Invalid parameter (do not use "=" with "--" options)'
@@ -277,6 +292,11 @@ try:
closure = int(newargs[i+1])
newargs[i] = ''
newargs[i+1] = ''
+ elif newargs[i].startswith('--js-transform'):
+ check_bad_eq(newargs[i])
+ js_transform = newargs[i+1]
+ newargs[i] = ''
+ newargs[i+1] = ''
elif newargs[i] == '-MF': # clang cannot handle this, so we fake it
f = open(newargs[i+1], 'w')
f.write('\n')
@@ -461,15 +481,15 @@ try:
print >> sys.stderr, 'emcc: saving intermediate processing steps to %s' % shared.EMSCRIPTEN_TEMP_DIR
intermediate_counter = 0
- def save_intermediate(name=None):
+ def save_intermediate(name=None, suffix='js'):
global intermediate_counter
- shutil.copyfile(final, os.path.join(shared.EMSCRIPTEN_TEMP_DIR, 'emcc-%d%s.js' % (intermediate_counter, '' if name is None else '-' + name)))
+ shutil.copyfile(final, os.path.join(shared.EMSCRIPTEN_TEMP_DIR, 'emcc-%d%s.%s' % (intermediate_counter, '' if name is None else '-' + name, suffix)))
intermediate_counter += 1
if not LEAVE_INPUTS_RAW:
final = in_temp(target_basename + '.bc')
final = shared.Building.llvm_dis(final, final + '.ll')
- if DEBUG: save_intermediate('ll')
+ if DEBUG: save_intermediate('ll', 'll')
else:
assert len(input_files) == 1
final = input_files[0]
@@ -478,12 +498,11 @@ try:
if DEBUG: save_intermediate('original')
# Apply a source code transformation, if requested
- source_transform = os.environ.get('EMCC_JS_PROCESSOR')
- if source_transform:
- exec source_transform in locals()
+ if js_transform:
shutil.copyfile(final, final + '.tr.js')
final += '.tr.js'
- process(final)
+ if DEBUG: print >> sys.stderr, 'emcc: applying transform: %s' % js_transform
+ Popen(js_transform.split(' ') + [os.path.abspath(final)]).communicate()
if DEBUG: save_intermediate('transformed')
if opt_level >= 1:
diff --git a/src/modules.js b/src/modules.js
index 0bc8894c..1e996fca 100644
--- a/src/modules.js
+++ b/src/modules.js
@@ -48,7 +48,7 @@ var Debugging = {
var form3 = new RegExp(/^!(\d+) = metadata !{i32 (\d+), (?:i32 \d+|null), metadata !(\d+), .*}$/);
var form3a = new RegExp(/^!(\d+) = metadata !{i32 \d+, (?:i32 \d+|metadata !\d+), (?:i32 \d+|null), (?:i32 \d+|null), metadata !(\d+), (?:i32 \d+|null)}.*/);
var form3ab = new RegExp(/^!(\d+) = metadata !{i32 \d+, (?:metadata !\d+|i32 \d+|null), metadata !(\d+).*$/);
- var form3ac = new RegExp(/^!(\d+) = metadata !{i32 \d+, (?:metadata !\d+|null), metadata !"[^"]+", metadata !(\d+)[^\[]*.*$/);
+ var form3ac = new RegExp(/^!(\d+) = metadata !{i32 \d+, (?:metadata !\d+|null), metadata !"[^"]*", metadata !(\d+)[^\[]*.*$/);
var form3ad = new RegExp(/^!(\d+) = metadata !{i32 \d+, (?:i32 \d+|null), (?:i32 \d+|null), metadata !"[^"]*", metadata !"[^"]*", metadata !"[^"]*", metadata !(\d+),.*$/);
var form3b = new RegExp(/^!(\d+) = metadata !{i32 \d+, metadata !"([^"]+)", metadata !"([^"]+)", (metadata !\d+|null)}.*$/);
var form3c = new RegExp(/^!(\d+) = metadata !{\w+\d* !?(\d+)[^\d].*$/);
diff --git a/tests/runner.py b/tests/runner.py
index de35fbe3..45077ca0 100644
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -105,14 +105,21 @@ class RunnerCore(unittest.TestCase):
shutil.copyfile(filename + '.o.js', filename + '.o.js.prepost.js')
process(filename + '.o.js')
else:
- if post_build is not None:
- os.environ['EMCC_JS_PROCESSOR'] = post_build
- else:
- try:
- del os.environ['EMCC_JS_PROCESSOR']
- except:
- pass
- Building.emcc(filename + '.o.ll', Settings.serialize() + self.emcc_args, filename + '.o.js')
+ transform_args = []
+ if post_build:
+ transform_filename = os.path.join(self.get_dir(), 'transform.py')
+ transform = open(transform_filename, 'w')
+ transform.write('''
+import sys
+sys.path += ['%s']
+''' % path_from_root(''))
+ transform.write(post_build)
+ transform.write('''
+process(sys.argv[1])
+''')
+ transform.close()
+ transform_args = ['--js-transform', "python %s" % transform_filename]
+ Building.emcc(filename + '.o.ll', Settings.serialize() + self.emcc_args + transform_args, filename + '.o.js')
# Build JavaScript code from source code
def build(self, src, dirname, filename, output_processor=None, main_file=None, additional_files=[], libraries=[], includes=[], build_ll_hook=None, extra_emscripten_args=[], post_build=None):
@@ -5275,8 +5282,21 @@ Options that are modified or new in %s include:
assert os.path.exists('combined.bc'), '\n'.join(output)
self.assertContained('side got: hello from main, over', self.run_llvm_interpreter(['combined.bc']))
- # TODO: Add an argument for EMCC_JS_PROCESSOR to make it simpler to use, other simplifications there (allow non-py, just run it if not .py)
- # Add in files test a clear example of using disablePermissions, and link to it from the wiki
+ # --js-transform <transform>
+ clear()
+ trans = os.path.join(self.get_dir(), 't.py')
+ trans_file = open(trans, 'w')
+ trans_file.write('''
+import sys
+f = open(sys.argv[1], 'w')
+f.write('transformed!')
+f.close()
+''')
+ trans_file.close()
+ output = Popen([compiler, path_from_root('tests', 'hello_world' + suffix), '--js-transform', 'python t.py'], stdout=PIPE, stderr=PIPE).communicate()
+ assert open('a.out.js').read() == 'transformed!', 'Transformed output must be as expected'
+
+ # TODO: Add in files test a clear example of using disablePermissions, and link to it from the wiki
# TODO: test normal project linking, static and dynamic: get_library should not need to be told what to link!
# TODO: deprecate llvm optimizations, dlmalloc, etc. in emscripten.py.
diff --git a/tools/shared.py b/tools/shared.py
index 294f15ee..88f00b5f 100644
--- a/tools/shared.py
+++ b/tools/shared.py
@@ -151,17 +151,17 @@ USE_EMSDK = not os.environ.get('EMMAKEN_NO_SDK')
if USE_EMSDK:
# Disable system C and C++ include directories, and add our own (using -idirafter so they are last, like system dirs, which
# allows projects to override them)
- EMSDK_OPTS = [ '-nostdinc', '-nostdinc++',
- '-idirafter' + path_from_root('system', 'include'),
- '-idirafter' + path_from_root('system', 'include', 'bsd'), # posix stuff
- '-idirafter' + path_from_root('system', 'include', 'libc'),
- '-idirafter' + path_from_root('system', 'include', 'libcxx'),
- '-idirafter' + path_from_root('system', 'include', 'gfx'),
- '-idirafter' + path_from_root('system', 'include', 'net'),
- '-idirafter' + path_from_root('system', 'include', 'SDL'),
-] + [
- '-U__APPLE__'
-]
+ EMSDK_OPTS = ['-nostdinc', '-nostdinc++', '-Xclang', '-nobuiltininc', '-Xclang', '-nostdinc++', '-Xclang', '-nostdsysteminc',
+ '-Xclang', '-isystem' + path_from_root('system', 'include'),
+ '-Xclang', '-isystem' + path_from_root('system', 'include', 'bsd'), # posix stuff
+ '-Xclang', '-isystem' + path_from_root('system', 'include', 'libc'),
+ '-Xclang', '-isystem' + path_from_root('system', 'include', 'libcxx'),
+ '-Xclang', '-isystem' + path_from_root('system', 'include', 'gfx'),
+ '-Xclang', '-isystem' + path_from_root('system', 'include', 'net'),
+ '-Xclang', '-isystem' + path_from_root('system', 'include', 'SDL'),
+ ] + [
+ '-U__APPLE__'
+ ]
COMPILER_OPTS += EMSDK_OPTS
else:
EMSDK_OPTS = []