diff options
author | Alon Zakai <alonzakai@gmail.com> | 2014-02-16 12:30:22 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2014-02-16 12:30:22 -0800 |
commit | 153f2d93520f37525f30a3808b969c5533387a3c (patch) | |
tree | 93d691925a910406f0eb5cd0edfa48da4401b43b | |
parent | 6334c3dd9814ef4174baadd0a4ecfed572596b72 (diff) |
RETAIN_COMPILER_SETTINGS, Runtime.getCompilerSetting and emscripten_get_compiler_setting - an optional way to look up compiler flags at runtime
-rwxr-xr-x | emcc | 4 | ||||
-rw-r--r-- | src/library.js | 14 | ||||
-rw-r--r-- | src/runtime.js | 22 | ||||
-rw-r--r-- | src/settings.js | 11 | ||||
-rw-r--r-- | src/utility.js | 6 | ||||
-rw-r--r-- | system/include/emscripten/emscripten.h | 21 | ||||
-rw-r--r-- | tests/core/emscripten_get_compiler_setting.c | 11 | ||||
-rw-r--r-- | tests/core/emscripten_get_compiler_setting.out | 2 | ||||
-rw-r--r-- | tests/test_core.py | 7 |
9 files changed, 95 insertions, 3 deletions
@@ -1308,6 +1308,10 @@ try: if js_opts: shared.Settings.RUNNING_JS_OPTS = 1 + shared.Settings.EMSCRIPTEN_VERSION = shared.EMSCRIPTEN_VERSION + shared.Settings.OPT_LEVEL = opt_level + shared.Settings.DEBUG_LEVEL = debug_level + ## Compile source code to bitcode logging.debug('compiling to bitcode') diff --git a/src/library.js b/src/library.js index f69b52e5..1b5e8b20 100644 --- a/src/library.js +++ b/src/library.js @@ -9051,6 +9051,20 @@ LibraryManager.library = { _emscripten_log_js(flags, str); }, + emscripten_get_compiler_setting: function(name) { + name = Pointer_stringify(name); + + var ret = Runtime.getCompilerSetting(name); + if (typeof ret === 'number') return ret; + + if (!_emscripten_get_compiler_setting.cache) _emscripten_get_compiler_setting.cache = {}; + var cache = _emscripten_get_compiler_setting.cache; + var fullname = name + '__str'; + var fullret = cache[fullname]; + if (fullret) return fullret; + return cache[fullname] = allocate(intArrayFromString(ret + ''), 'i8', ALLOC_NORMAL); + }, + //============================ // emscripten vector ops //============================ diff --git a/src/runtime.js b/src/runtime.js index a9265e70..0c724e50 100644 --- a/src/runtime.js +++ b/src/runtime.js @@ -487,6 +487,19 @@ var Runtime = { } }, +#if RETAIN_COMPILER_SETTINGS + compilerSettings: {}, +#endif + + getCompilerSetting: function(name) { +#if RETAIN_COMPILER_SETTINGS == 0 + throw 'You must build with -s RETAIN_COMPILER_SETTINGS=1 for Runtime.getCompilerSetting or emscripten_get_compiler_setting to work'; +#else + if (!(name in Runtime.compilerSettings)) return 'invalid compiler setting: ' + name; + return Runtime.compilerSettings[name]; +#endif + }, + #if RUNTIME_DEBUG debug: true, // Switch to false at runtime to disable logging at the right times @@ -612,3 +625,12 @@ function reSign(value, bits, ignore) { // Then 'dynamic' memory for sbrk. Runtime.GLOBAL_BASE = Runtime.alignMemory(1); +if (RETAIN_COMPILER_SETTINGS) { + var blacklist = set('RELOOPER', 'STRUCT_INFO'); + for (var x in this) { + try { + if (x[0] !== '_' && !(x in blacklist) && x == x.toUpperCase() && (typeof this[x] === 'number' || typeof this[x] === 'string' || this.isArray())) Runtime.compilerSettings[x] = this[x]; + } catch(e){} + } +} + diff --git a/src/settings.js b/src/settings.js index 1db91dca..c8114059 100644 --- a/src/settings.js +++ b/src/settings.js @@ -315,6 +315,17 @@ var EXPORT_ALL = 0; // If true, we export all the symbols. Note that this does * // still eliminate functions as dead. This just exports them on the Module object. var EXPORT_BINDINGS = 0; // Export all bindings generator functions (prefixed with emscripten_bind_). This // is necessary to use the bindings generator with asm.js +var RETAIN_COMPILER_SETTINGS = 0; // Remembers the values of these settings, and makes them accessible + // through Runtime.getCompilerSetting and emscripten_get_compiler_setting. + // To see what is retained, look for compilerSettings in the generated code. + + +var EMSCRIPTEN_VERSION = ''; // this will contain the emscripten version. you should not modify it. This + // and the following few settings are useful in combination with + // RETAIN_COMPILER_SETTINGS +var OPT_LEVEL = 0; // this will contain the optimization level (-Ox). you should not modify it. +var DEBUG_LEVEL = 0; // this will contain the debug level (-gx). you should not modify it. + // JS library functions (C functions implemented in JS) // that we include by default. If you want to make sure diff --git a/src/utility.js b/src/utility.js index 178c596b..54cc2d69 100644 --- a/src/utility.js +++ b/src/utility.js @@ -200,11 +200,11 @@ function dprint() { printErr(text); } -var PROF_ORIGIN = Date.now(); -var PROF_TIME = PROF_ORIGIN; +var _PROF_ORIGIN = Date.now(); +var _PROF_TIME = _PROF_ORIGIN; function PROF(pass) { if (!pass) { - dprint("Profiling: " + ((Date.now() - PROF_TIME)/1000) + ' seconds, total: ' + ((Date.now() - PROF_ORIGIN)/1000)); + dprint("Profiling: " + ((Date.now() - _PROF_TIME)/1000) + ' seconds, total: ' + ((Date.now() - _PROF_ORIGIN)/1000)); } PROF_TIME = Date.now(); } diff --git a/system/include/emscripten/emscripten.h b/system/include/emscripten/emscripten.h index eb5ded91..426206c4 100644 --- a/system/include/emscripten/emscripten.h +++ b/system/include/emscripten/emscripten.h @@ -420,6 +420,27 @@ int emscripten_get_worker_queue_size(worker_handle worker); #define EMSCRIPTEN_NETWORK_WEBRTC 1 void emscripten_set_network_backend(int backend); +/* + * Returns the value of a compiler setting. For example + * + * emscripten_get_compiler_setting("PRECISE_F32") + * + * will return an integer representing the value of + * PRECISE_F32 during compilation. For values containing + * anything other than an integer, a string is returned + * (you will need to cast the int return value to a char*). + * + * Some useful things this can do is provide the + * version of emscripten ("EMSCRIPTEN_VERSION"), the optimization + * level ("OPT_LEVEL"), debug level ("DEBUG_LEVEL"), etc. + * + * For this command to work, you must build with + * -s RETAIN_COMPILER_SETTINGS=1 + * as otherwise we do not want to increase the build size + * with this metadata. + */ +int emscripten_get_compiler_setting(const char *name); + /* Internal APIs. Be careful with these. */ /* diff --git a/tests/core/emscripten_get_compiler_setting.c b/tests/core/emscripten_get_compiler_setting.c new file mode 100644 index 00000000..41eb8e38 --- /dev/null +++ b/tests/core/emscripten_get_compiler_setting.c @@ -0,0 +1,11 @@ +#include <stdio.h> +#include <assert.h> +#include <emscripten.h> + +int main() { + printf("QS: %d\n", emscripten_get_compiler_setting("QUANTUM_SIZE")); + assert((unsigned)emscripten_get_compiler_setting("OPT_LEVEL") <= 3); + assert((unsigned)emscripten_get_compiler_setting("DEBUG_LEVEL") <= 4); + printf("EV: %s\n", (char*)emscripten_get_compiler_setting("EMSCRIPTEN_VERSION")); +} + diff --git a/tests/core/emscripten_get_compiler_setting.out b/tests/core/emscripten_get_compiler_setting.out new file mode 100644 index 00000000..cd520064 --- /dev/null +++ b/tests/core/emscripten_get_compiler_setting.out @@ -0,0 +1,2 @@ +QS: 4 +EV: waka diff --git a/tests/test_core.py b/tests/test_core.py index 6a9ef979..045b43c1 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -1925,6 +1925,13 @@ def process(filename): self.emcc_args += ['--closure', '1'] # Use closure here for some additional coverage self.do_run(open(path_from_root('tests', 'emscripten_get_now.cpp')).read(), 'Timer resolution is good.') + def test_emscripten_get_compiler_setting(self): + test_path = path_from_root('tests', 'core', 'emscripten_get_compiler_setting') + src, output = (test_path + s for s in ('.c', '.out')) + self.do_run(open(src).read(), 'You must build with -s RETAIN_COMPILER_SETTINGS=1') + Settings.RETAIN_COMPILER_SETTINGS = 1 + self.do_run(open(src).read(), open(output).read().replace('waka', EMSCRIPTEN_VERSION)) + def test_inlinejs(self): if not self.is_le32(): return self.skip('le32 needed for inline js') if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('fastcomp only supports EM_ASM') |