diff options
author | Alon Zakai <alonzakai@gmail.com> | 2011-07-15 19:35:27 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2011-07-15 19:35:40 -0700 |
commit | 414f1dc84930595fa804023435267762e4f66be2 (patch) | |
tree | 2b8f6c3040bb5be129489353f4c4e94872639995 | |
parent | 51505880de541576c79ece8b93e73690290c6c5e (diff) |
option to provide type info at run time
-rw-r--r-- | src/jsifier.js | 4 | ||||
-rw-r--r-- | src/modules.js | 19 | ||||
-rw-r--r-- | src/settings.js | 5 | ||||
-rw-r--r-- | tests/runner.py | 45 |
4 files changed, 70 insertions, 3 deletions
diff --git a/src/jsifier.js b/src/jsifier.js index 2babaa05..dfd1f08d 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -826,6 +826,10 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) { var preFile = BUILD_AS_SHARED_LIB ? 'preamble_sharedlib.js' : 'preamble.js'; var pre = processMacros(preprocess(read(preFile).replace('{{RUNTIME}}', getRuntime()), CONSTANTS)); print(pre); + if (RUNTIME_TYPE_INFO) { + Types.cleanForRuntime(); + print('Runtime.typeInfo = ' + JSON.stringify(Types.types)); + } generated.forEach(function(item) { print(indentify(item.JS || '', 2)); }); print(Functions.generateIndexing()); diff --git a/src/modules.js b/src/modules.js index 0b00107c..f1f5f487 100644 --- a/src/modules.js +++ b/src/modules.js @@ -119,6 +119,25 @@ var Types = { this.types = temp; }, + // Remove all data not needed during runtime (like line numbers, JS, etc.) + cleanForRuntime: function() { + values(this.types).forEach(function(type) { + delete type.intertype; + delete type.name_; + delete type.lineNum; + delete type.lines; + delete type.needsFlattening; + delete type.JS; + }); + keys(this.types).forEach(function(longer) { + var shorter = longer.replace('%struct.', '').replace('%class.'); + if (shorter === longer) return; + if (shorter in this.types) return; + this.types[shorter] = this.types[longer]; + delete this.types[longer]; + }, this); + }, + needAnalysis: {} // Types noticed during parsing, that need analysis }; diff --git a/src/settings.js b/src/settings.js index 544cc7c2..226c30b2 100644 --- a/src/settings.js +++ b/src/settings.js @@ -116,6 +116,11 @@ SHOW_LABELS = 0; // Show labels in the generated code BUILD_AS_SHARED_LIB = 0; // Whether to build the code as a shared library, which // must be loaded dynamically using dlopen(). +RUNTIME_TYPE_INFO = 0; // Whether to expose type info to the script at run time. This + // increases the size of the generated script, but allows you + // to more easily perform operations from handwritten JS on + // objects with structures etc. + // Compiler debugging options DEBUG_TAGS_SHOWING = []; // Some useful items: diff --git a/tests/runner.py b/tests/runner.py index 1e8828a0..d3573d2c 100644 --- a/tests/runner.py +++ b/tests/runner.py @@ -173,7 +173,7 @@ class RunnerCore(unittest.TestCase): def do_emscripten(self, filename, output_processor=None, append_ext=True, extra_args=[]): # Run Emscripten exported_settings = {} - for setting in ['QUANTUM_SIZE', 'RELOOP', 'OPTIMIZE', 'ASSERTIONS', 'USE_TYPED_ARRAYS', 'SAFE_HEAP', 'CHECK_OVERFLOWS', 'CORRECT_OVERFLOWS', 'CORRECT_SIGNS', 'CHECK_SIGNS', 'CORRECT_OVERFLOWS_LINES', 'CORRECT_SIGNS_LINES', 'CORRECT_ROUNDINGS', 'CORRECT_ROUNDINGS_LINES', 'INVOKE_RUN', 'SAFE_HEAP_LINES', 'INIT_STACK', 'AUTO_OPTIMIZE', 'EXPORTED_FUNCTIONS', 'EXPORTED_GLOBALS', 'BUILD_AS_SHARED_LIB', 'INCLUDE_FULL_LIBRARY']: + for setting in ['QUANTUM_SIZE', 'RELOOP', 'OPTIMIZE', 'ASSERTIONS', 'USE_TYPED_ARRAYS', 'SAFE_HEAP', 'CHECK_OVERFLOWS', 'CORRECT_OVERFLOWS', 'CORRECT_SIGNS', 'CHECK_SIGNS', 'CORRECT_OVERFLOWS_LINES', 'CORRECT_SIGNS_LINES', 'CORRECT_ROUNDINGS', 'CORRECT_ROUNDINGS_LINES', 'INVOKE_RUN', 'SAFE_HEAP_LINES', 'INIT_STACK', 'AUTO_OPTIMIZE', 'EXPORTED_FUNCTIONS', 'EXPORTED_GLOBALS', 'BUILD_AS_SHARED_LIB', 'INCLUDE_FULL_LIBRARY', 'RUNTIME_TYPE_INFO']: try: value = eval(setting) exported_settings[setting] = value @@ -2722,6 +2722,44 @@ Child2:9 *ok* ''', post_build=post2) + def test_typeinfo(self): + global RUNTIME_TYPE_INFO; RUNTIME_TYPE_INFO = 1 + global QUANTUM_SIZE + if QUANTUM_SIZE != 4: return self.skip() + + src = ''' + #include<stdio.h> + struct UserStruct { + int x; + char y; + void *z; + }; + int main() { + UserStruct u; + u.y = 5; + printf("*ok:%d*\\n", u.y); + return 0; + } + ''' + + def post(filename): + src = open(filename, 'r').read().replace( + '// {{POST_RUN_ADDITIONS}}', + ''' + if (Runtime.typeInfo) { + print('|' + Runtime.typeInfo.UserStruct.fields + '|' + Runtime.typeInfo.UserStruct.flatIndexes + '|'); + } else { + print('No type info.'); + } + ''' + ) + open(filename, 'w').write(src) + self.do_test(src, '*ok:5*\n|i32,i8,i8*|0,4,8|', post_build=post) + + # Make sure that without the setting, we don't spam the .js with the type info + RUNTIME_TYPE_INFO = 0 + self.do_test(src, 'No type info.', post_build=post) + ### Tests for tools def test_safe_heap(self): @@ -3028,7 +3066,7 @@ Child2:9 exec(''' class %s(T): def setUp(self): - global COMPILER, QUANTUM_SIZE, RELOOP, OPTIMIZE, ASSERTIONS, USE_TYPED_ARRAYS, LLVM_OPTS, SAFE_HEAP, CHECK_OVERFLOWS, CORRECT_OVERFLOWS, CORRECT_OVERFLOWS_LINES, CORRECT_SIGNS, CORRECT_SIGNS_LINES, CHECK_SIGNS, COMPILER_TEST_OPTS, CORRECT_ROUNDINGS, CORRECT_ROUNDINGS_LINES, INVOKE_RUN, SAFE_HEAP_LINES, INIT_STACK, AUTO_OPTIMIZE + global COMPILER, QUANTUM_SIZE, RELOOP, OPTIMIZE, ASSERTIONS, USE_TYPED_ARRAYS, LLVM_OPTS, SAFE_HEAP, CHECK_OVERFLOWS, CORRECT_OVERFLOWS, CORRECT_OVERFLOWS_LINES, CORRECT_SIGNS, CORRECT_SIGNS_LINES, CHECK_SIGNS, COMPILER_TEST_OPTS, CORRECT_ROUNDINGS, CORRECT_ROUNDINGS_LINES, INVOKE_RUN, SAFE_HEAP_LINES, INIT_STACK, AUTO_OPTIMIZE, RUNTIME_TYPE_INFO COMPILER = '%s' llvm_opts = %d @@ -3050,6 +3088,7 @@ class %s(T): CORRECT_OVERFLOWS_LINES = CORRECT_SIGNS_LINES = CORRECT_ROUNDINGS_LINES = SAFE_HEAP_LINES = [] CHECK_SIGNS = 0 #1-(embetter or llvm_opts) INIT_STACK = 0 + RUNTIME_TYPE_INFO = 0 if LLVM_OPTS: self.pick_llvm_opts(3, True) COMPILER_TEST_OPTS = [] @@ -3100,7 +3139,7 @@ else: QUANTUM_SIZE = 1 RELOOP = OPTIMIZE = 1 USE_TYPED_ARRAYS = 0 - ASSERTIONS = SAFE_HEAP = CHECK_OVERFLOWS = CORRECT_OVERFLOWS = CHECK_SIGNS = INIT_STACK = AUTO_OPTIMIZE = 0 + ASSERTIONS = SAFE_HEAP = CHECK_OVERFLOWS = CORRECT_OVERFLOWS = CHECK_SIGNS = INIT_STACK = AUTO_OPTIMIZE = RUNTIME_TYPE_INFO = 0 INVOKE_RUN = 1 CORRECT_SIGNS = 0 CORRECT_ROUNDINGS = 0 |