webruby 0.2.5 → 0.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/lib/webruby.rb +0 -4
  3. data/lib/webruby/app.rb +4 -0
  4. data/lib/webruby/rake/files.rake +2 -1
  5. data/lib/webruby/rake/mruby.rake +1 -1
  6. data/modules/emscripten/AUTHORS +1 -0
  7. data/modules/emscripten/ChangeLog +34 -1
  8. data/modules/emscripten/cmake/Platform/Emscripten.cmake +30 -9
  9. data/modules/emscripten/emcc +61 -28
  10. data/modules/emscripten/emrun +15 -11
  11. data/modules/emscripten/emscripten.py +3 -0
  12. data/modules/emscripten/src/closure-externs.js +110 -0
  13. data/modules/emscripten/src/intertyper.js +1 -1
  14. data/modules/emscripten/src/jsifier.js +7 -21
  15. data/modules/emscripten/src/library.js +2 -1
  16. data/modules/emscripten/src/library_browser.js +16 -5
  17. data/modules/emscripten/src/library_fs.js +3 -1
  18. data/modules/emscripten/src/library_gl.js +691 -591
  19. data/modules/emscripten/src/library_glut.js +2 -0
  20. data/modules/emscripten/src/library_sdl.js +29 -5
  21. data/modules/emscripten/src/library_uuid.js +140 -0
  22. data/modules/emscripten/src/modules.js +1 -1
  23. data/modules/emscripten/src/parseTools.js +29 -19
  24. data/modules/emscripten/src/postamble.js +3 -4
  25. data/modules/emscripten/src/preamble.js +17 -1
  26. data/modules/emscripten/src/relooper/Relooper.cpp +8 -8
  27. data/modules/emscripten/src/relooper/Relooper.h +5 -5
  28. data/modules/emscripten/src/relooper/test.txt +2 -2
  29. data/modules/emscripten/src/runtime.js +1 -1
  30. data/modules/emscripten/src/settings.js +3 -0
  31. data/modules/emscripten/src/struct_info.json +12 -0
  32. data/modules/emscripten/system/include/uuid/uuid.h +35 -0
  33. data/modules/emscripten/tools/js-optimizer.js +191 -142
  34. data/modules/emscripten/tools/js_optimizer.py +3 -29
  35. data/modules/emscripten/tools/shared.py +43 -6
  36. data/modules/mruby/include/mruby/value.h +3 -2
  37. data/modules/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c +5 -9
  38. data/modules/mruby/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c +3 -5
  39. data/modules/mruby/mrbgems/mruby-hash-ext/src/hash-ext.c +0 -3
  40. data/modules/mruby/mrbgems/mruby-numeric-ext/src/numeric_ext.c +0 -1
  41. data/modules/mruby/mrbgems/mruby-random/src/mt19937ar.c +0 -1
  42. data/modules/mruby/mrbgems/mruby-range-ext/src/range.c +2 -6
  43. data/modules/mruby/mrbgems/mruby-sprintf/src/sprintf.c +0 -4
  44. data/modules/mruby/mrbgems/mruby-string-ext/mrblib/string.rb +22 -0
  45. data/modules/mruby/mrbgems/mruby-string-ext/src/string.c +2 -2
  46. data/modules/mruby/mrbgems/mruby-string-ext/test/string.rb +21 -2
  47. data/modules/mruby/mrbgems/mruby-string-utf8/mrbgem.rake +4 -0
  48. data/modules/mruby/mrbgems/mruby-string-utf8/src/string.c +297 -0
  49. data/modules/mruby/mrbgems/mruby-string-utf8/test/string.rb +27 -0
  50. data/modules/mruby/mrbgems/mruby-struct/src/struct.c +0 -1
  51. data/modules/mruby/mrblib/init_mrblib.c +0 -3
  52. data/modules/mruby/src/array.c +22 -8
  53. data/modules/mruby/src/backtrace.c +12 -9
  54. data/modules/mruby/src/class.c +3 -3
  55. data/modules/mruby/src/codegen.c +17 -5
  56. data/modules/mruby/src/dump.c +5 -6
  57. data/modules/mruby/src/error.c +0 -2
  58. data/modules/mruby/src/etc.c +0 -2
  59. data/modules/mruby/src/gc.c +4 -8
  60. data/modules/mruby/src/load.c +1 -6
  61. data/modules/mruby/src/numeric.c +0 -6
  62. data/modules/mruby/src/object.c +3 -5
  63. data/modules/mruby/src/parse.y +37 -38
  64. data/modules/mruby/src/proc.c +8 -1
  65. data/modules/mruby/src/range.c +3 -7
  66. data/modules/mruby/src/state.c +0 -1
  67. data/modules/mruby/src/string.c +2 -17
  68. data/modules/mruby/src/symbol.c +0 -1
  69. data/modules/mruby/src/variable.c +3 -22
  70. data/modules/mruby/src/vm.c +9 -8
  71. data/modules/mruby/tasks/mrbgem_spec.rake +13 -5
  72. data/modules/mruby/tasks/mrbgems_test.rake +3 -3
  73. data/modules/mruby/tasks/mruby_build_commands.rake +2 -2
  74. data/modules/mruby/tasks/mruby_build_gem.rake +3 -3
  75. data/modules/mruby/test/init_mrbtest.c +0 -3
  76. data/modules/mruby/test/t/array.rb +12 -1
  77. data/modules/mruby/test/t/class.rb +67 -0
  78. data/modules/mruby/test/t/exception.rb +12 -0
  79. data/modules/mruby/test/t/kernel.rb +75 -1
  80. data/modules/mruby/test/t/syntax.rb +115 -0
  81. data/scripts/gen_require.rb +12 -1
  82. metadata +8 -2
@@ -250,7 +250,7 @@ var Runtime = {
250
250
  prev = curr;
251
251
  return curr;
252
252
  });
253
- if (type.name_[0] === '[') {
253
+ if (type.name_ && type.name_[0] === '[') {
254
254
  // arrays have 2 elements, so we get the proper difference. then we scale here. that way we avoid
255
255
  // allocating a potentially huge array for [999999 x i8] etc.
256
256
  type.flatSize = parseInt(type.name_.substr(1))*type.flatSize/2;
@@ -123,6 +123,7 @@ var PRECISE_F32 = 0; // 0: Use JS numbers for floating-point values. These are 6
123
123
  // 2: Model C++ floats precisely using Math.fround if available in the JS engine, otherwise
124
124
  // use an empty polyfill. This will have less of a speed penalty than using the full
125
125
  // polyfill in cases where engine support is not present.
126
+ var SIMD = 0; // Whether to emit SIMD code ( https://github.com/johnmccutchan/ecmascript_simd )
126
127
 
127
128
  var CLOSURE_ANNOTATIONS = 0; // If set, the generated code will be annotated for the closure
128
129
  // compiler. This potentially lets closure optimize the code better.
@@ -156,6 +157,8 @@ var OUTLINING_LIMIT = 0; // A function size above which we try to automatically
156
157
  // with, but something around 20,000 to 100,000 might make sense.
157
158
  // (The unit size is number of AST nodes.)
158
159
 
160
+ var AGGRESSIVE_VARIABLE_ELIMINATION = 0; // Run aggressiveVariableElimination in js-optimizer.js
161
+
159
162
  // Generated code debugging options
160
163
  var SAFE_HEAP = 0; // Check each write to the heap, for example, this will give a clear
161
164
  // error on what would be segfaults in a native build (like deferencing
@@ -1061,5 +1061,17 @@
1061
1061
  "patch"
1062
1062
  ]
1063
1063
  }
1064
+ },
1065
+ {
1066
+ "file": "uuid/uuid.h",
1067
+ "defines": [
1068
+ "UUID_VARIANT_NCS",
1069
+ "UUID_VARIANT_DCE",
1070
+ "UUID_VARIANT_MICROSOFT",
1071
+ "UUID_VARIANT_OTHER",
1072
+ "UUID_TYPE_DCE_TIME",
1073
+ "UUID_TYPE_DCE_RANDOM"
1074
+ ],
1075
+ "structs": {}
1064
1076
  }
1065
1077
  ]
@@ -0,0 +1,35 @@
1
+
2
+ #ifndef _UUID_H
3
+ #define _UUID_H
4
+
5
+ typedef unsigned char uuid_t[16];
6
+
7
+ #define UUID_VARIANT_NCS 0
8
+ #define UUID_VARIANT_DCE 1
9
+ #define UUID_VARIANT_MICROSOFT 2
10
+ #define UUID_VARIANT_OTHER 3
11
+
12
+ #define UUID_TYPE_DCE_TIME 1
13
+ #define UUID_TYPE_DCE_RANDOM 4
14
+
15
+ #ifdef __cplusplus
16
+ extern "C" {
17
+ #endif
18
+
19
+ void uuid_clear(uuid_t uu);
20
+ int uuid_compare(const uuid_t uu1, const uuid_t uu2);
21
+ void uuid_copy(uuid_t dst, const uuid_t src);
22
+ void uuid_generate(uuid_t out);
23
+ int uuid_is_null(const uuid_t uu);
24
+ int uuid_parse(const char *in, uuid_t uu);
25
+ void uuid_unparse(const uuid_t uu, char *out);
26
+ void uuid_unparse_lower(const uuid_t uu, char *out);
27
+ void uuid_unparse_upper(const uuid_t uu, char *out);
28
+ int uuid_type(const uuid_t uu);
29
+ int uuid_variant(const uuid_t uu);
30
+
31
+ #ifdef __cplusplus
32
+ }
33
+ #endif
34
+
35
+ #endif /* _UUID_H */
@@ -1743,6 +1743,36 @@ function getStackBumpSize(ast) {
1743
1743
  return node ? node[3][2][3][1] : 0;
1744
1744
  }
1745
1745
 
1746
+ // Name minification
1747
+
1748
+ var RESERVED = set('do', 'if', 'in', 'for', 'new', 'try', 'var', 'env', 'let');
1749
+ var VALID_MIN_INITS = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$';
1750
+ var VALID_MIN_LATERS = VALID_MIN_INITS + '0123456789';
1751
+
1752
+ var minifiedNames = [];
1753
+ var minifiedState = [0];
1754
+
1755
+ function ensureMinifiedNames(n) { // make sure the nth index in minifiedNames exists. done 100% deterministically
1756
+ while (minifiedNames.length < n+1) {
1757
+ // generate the current name
1758
+ var name = VALID_MIN_INITS[minifiedState[0]];
1759
+ for (var i = 1; i < minifiedState.length; i++) {
1760
+ name += VALID_MIN_LATERS[minifiedState[i]];
1761
+ }
1762
+ if (!(name in RESERVED)) minifiedNames.push(name);
1763
+ // increment the state
1764
+ var i = 0;
1765
+ while (1) {
1766
+ minifiedState[i]++;
1767
+ if (minifiedState[i] < (i === 0 ? VALID_MIN_INITS : VALID_MIN_LATERS).length) break;
1768
+ // overflow
1769
+ minifiedState[i] = 0;
1770
+ i++;
1771
+ if (i === minifiedState.length) minifiedState.push(-1); // will become 0 after increment in next loop head
1772
+ }
1773
+ }
1774
+ }
1775
+
1746
1776
  // Very simple 'registerization', coalescing of variables into a smaller number,
1747
1777
  // as part of minification. Globals-level minification began in a previous pass,
1748
1778
  // we receive extraInfo which tells us how to rename globals. (Only in asm.js.)
@@ -1853,14 +1883,14 @@ function registerize(ast) {
1853
1883
  return ret;
1854
1884
  }
1855
1885
  // find the next free minified name that is not used by a global that shows up in this function
1856
- while (nextRegName < extraInfo.names.length) {
1857
- var ret = extraInfo.names[nextRegName++];
1886
+ while (1) {
1887
+ ensureMinifiedNames(nextRegName);
1888
+ var ret = minifiedNames[nextRegName++];
1858
1889
  if (!usedGlobals[ret]) {
1859
1890
  regTypes[ret] = type;
1860
1891
  return ret;
1861
1892
  }
1862
1893
  }
1863
- assert('ran out of names');
1864
1894
  }
1865
1895
  // Find the # of uses of each variable.
1866
1896
  // While doing so, check if all a variable's uses are dominated in a simple
@@ -2847,16 +2877,16 @@ function minifyGlobals(ast) {
2847
2877
  var vars = node[1];
2848
2878
  for (var i = 0; i < vars.length; i++) {
2849
2879
  var name = vars[i][0];
2850
- assert(next < extraInfo.names.length);
2851
- vars[i][0] = minified[name] = extraInfo.names[next++];
2880
+ ensureMinifiedNames(next);
2881
+ vars[i][0] = minified[name] = minifiedNames[next++];
2852
2882
  }
2853
2883
  }
2854
2884
  });
2855
2885
  // add all globals in function chunks, i.e. not here but passed to us
2856
2886
  for (var i = 0; i < extraInfo.globals.length; i++) {
2857
2887
  name = extraInfo.globals[i];
2858
- assert(next < extraInfo.names.length);
2859
- minified[name] = extraInfo.names[next++];
2888
+ ensureMinifiedNames(next);
2889
+ minified[name] = minifiedNames[next++];
2860
2890
  }
2861
2891
  // apply minification
2862
2892
  traverse(ast, function(node, type) {
@@ -2930,162 +2960,180 @@ function relocate(ast) {
2930
2960
  var NODES_WITHOUT_ELIMINATION_SENSITIVITY = set('name', 'num', 'binary', 'unary-prefix');
2931
2961
  var FAST_ELIMINATION_BINARIES = setUnion(setUnion(USEFUL_BINARY_OPS, COMPARE_OPS), set('+'));
2932
2962
 
2933
- function outline(ast) {
2934
- function measureSize(ast) {
2935
- var size = 0;
2936
- traverse(ast, function() {
2937
- size++;
2938
- });
2939
- return size;
2940
- }
2941
-
2942
- function aggressiveVariableElimination(func, asmData) {
2943
- // This removes as many variables as possible. This is often not the best thing because it increases
2944
- // code size, but it is far preferable to the risk of split functions needing to do more spilling. Specifically,
2945
- // it finds 'trivial' variables: ones with 1 definition, and that definition is not sensitive to any changes: it
2946
- // only depends on constants and local variables that are themselves trivial. We can unquestionably eliminate
2947
- // such variables in a trivial manner.
2948
-
2949
- var assignments = {};
2950
- var appearances = {};
2951
- var defs = {};
2952
- var considered = {};
2963
+ function measureSize(ast) {
2964
+ var size = 0;
2965
+ traverse(ast, function() {
2966
+ size++;
2967
+ });
2968
+ return size;
2969
+ }
2953
2970
 
2954
- traverse(func, function(node, type) {
2955
- if (type == 'assign' && node[2][0] == 'name') {
2956
- var name = node[2][1];
2957
- if (name in asmData.vars) {
2958
- assignments[name] = (assignments[name] || 0) + 1;
2959
- appearances[name] = (appearances[name] || 0) - 1; // this appearance is a definition, offset the counting later
2960
- defs[name] = node;
2961
- } else {
2962
- if (name in asmData.params) {
2963
- assignments[name] = (assignments[name] || 1) + 1; // init to 1 for initial parameter assignment
2964
- considered[name] = true; // this parameter is not ssa, it must be in a hand-optimized function, so it is not trivial
2965
- }
2966
- }
2967
- } else if (type == 'name') {
2968
- var name = node[1];
2969
- if (name in asmData.vars) {
2970
- appearances[name] = (appearances[name] || 0) + 1;
2971
+ function aggressiveVariableEliminationInternal(func, asmData) {
2972
+ // This removes as many variables as possible. This is often not the best thing because it increases
2973
+ // code size, but it is far preferable to the risk of split functions needing to do more spilling, so
2974
+ // we use it when outlining.
2975
+ // Specifically, this finds 'trivial' variables: ones with 1 definition, and that definition is not sensitive to any changes: it
2976
+ // only depends on constants and local variables that are themselves trivial. We can unquestionably eliminate
2977
+ // such variables in a trivial manner.
2978
+
2979
+ var assignments = {};
2980
+ var appearances = {};
2981
+ var defs = {};
2982
+ var considered = {};
2983
+
2984
+ traverse(func, function(node, type) {
2985
+ if (type == 'assign' && node[2][0] == 'name') {
2986
+ var name = node[2][1];
2987
+ if (name in asmData.vars) {
2988
+ assignments[name] = (assignments[name] || 0) + 1;
2989
+ appearances[name] = (appearances[name] || 0) - 1; // this appearance is a definition, offset the counting later
2990
+ defs[name] = node;
2991
+ } else {
2992
+ if (name in asmData.params) {
2993
+ assignments[name] = (assignments[name] || 1) + 1; // init to 1 for initial parameter assignment
2994
+ considered[name] = true; // this parameter is not ssa, it must be in a hand-optimized function, so it is not trivial
2971
2995
  }
2972
2996
  }
2973
- });
2997
+ } else if (type == 'name') {
2998
+ var name = node[1];
2999
+ if (name in asmData.vars) {
3000
+ appearances[name] = (appearances[name] || 0) + 1;
3001
+ }
3002
+ }
3003
+ });
2974
3004
 
2975
- var allTrivials = {}; // key of a trivial var => size of its (expanded) value, at least 1
2976
-
2977
- // three levels of variables:
2978
- // 1. trivial: 1 def (or less), uses nothing sensitive, can be eliminated
2979
- // 2. safe: 1 def (or less), can be used in a trivial, but cannot itself be eliminated
2980
- // 3. sensitive: uses a global or memory or something else that prevents trivial elimination.
2981
-
2982
- function assessTriviality(name) {
2983
- // only care about vars with 0-1 assignments of (0 for parameters), and can ignore label (which is not explicitly initialized, but cannot be eliminated ever anyhow)
2984
- if (assignments[name] > 1 || (!(name in asmData.vars) && !(name in asmData.params)) || name == 'label') return false;
2985
- if (considered[name]) return allTrivials[name];
2986
- considered[name] = true;
2987
- var sensitive = false;
2988
- var size = 0, originalSize = 0;
2989
- var def = defs[name];
2990
- if (def) {
2991
- var value = def[3];
2992
- originalSize = measureSize(value);
2993
- if (value) {
2994
- traverse(value, function recurseValue(node, type) {
2995
- var one = node[1];
2996
- if (!(type in NODES_WITHOUT_ELIMINATION_SENSITIVITY)) { // || (type == 'binary' && !(one in FAST_ELIMINATION_BINARIES))) {
2997
- sensitive = true;
3005
+ var allTrivials = {}; // key of a trivial var => size of its (expanded) value, at least 1
3006
+
3007
+ // three levels of variables:
3008
+ // 1. trivial: 1 def (or less), uses nothing sensitive, can be eliminated
3009
+ // 2. safe: 1 def (or less), can be used in a trivial, but cannot itself be eliminated
3010
+ // 3. sensitive: uses a global or memory or something else that prevents trivial elimination.
3011
+
3012
+ function assessTriviality(name) {
3013
+ // only care about vars with 0-1 assignments of (0 for parameters), and can ignore label (which is not explicitly initialized, but cannot be eliminated ever anyhow)
3014
+ if (assignments[name] > 1 || (!(name in asmData.vars) && !(name in asmData.params)) || name == 'label') return false;
3015
+ if (considered[name]) return allTrivials[name];
3016
+ considered[name] = true;
3017
+ var sensitive = false;
3018
+ var size = 0, originalSize = 0;
3019
+ var def = defs[name];
3020
+ if (def) {
3021
+ var value = def[3];
3022
+ originalSize = measureSize(value);
3023
+ if (value) {
3024
+ traverse(value, function recurseValue(node, type) {
3025
+ var one = node[1];
3026
+ if (!(type in NODES_WITHOUT_ELIMINATION_SENSITIVITY)) { // || (type == 'binary' && !(one in FAST_ELIMINATION_BINARIES))) {
3027
+ sensitive = true;
3028
+ return true;
3029
+ }
3030
+ if (type == 'name' && !assessTriviality(one)) {
3031
+ if (assignments[one] > 1 || (!(one in asmData.vars) && !(one in asmData.params))) {
3032
+ sensitive = true; // directly using something sensitive
2998
3033
  return true;
2999
- }
3000
- if (type == 'name' && !assessTriviality(one)) {
3001
- if (assignments[one] > 1 || (!(one in asmData.vars) && !(one in asmData.params))) {
3002
- sensitive = true; // directly using something sensitive
3003
- return true;
3004
- } // otherwise, not trivial, but at least safe.
3005
- }
3006
- // if this is a name, it must be a trivial variable (or a safe one) and we know its size
3007
- size += ((type == 'name') ? allTrivials[one] : 1) || 1;
3008
- });
3009
- }
3010
- }
3011
- if (!sensitive) {
3012
- size = size || 1;
3013
- originalSize = originalSize || 1;
3014
- var factor = ((appearances[name] - 1) || 0) * (size - originalSize); // If no size change or just one appearance, always ok to trivially eliminate. otherwise, tradeoff
3015
- if (factor <= 12) {
3016
- allTrivials[name] = size; // trivial!
3017
- return true;
3018
- }
3034
+ } // otherwise, not trivial, but at least safe.
3035
+ }
3036
+ // if this is a name, it must be a trivial variable (or a safe one) and we know its size
3037
+ size += ((type == 'name') ? allTrivials[one] : 1) || 1;
3038
+ });
3019
3039
  }
3020
- return false;
3021
3040
  }
3022
- for (var name in asmData.vars) {
3023
- assessTriviality(name);
3041
+ if (!sensitive) {
3042
+ size = size || 1;
3043
+ originalSize = originalSize || 1;
3044
+ var factor = ((appearances[name] - 1) || 0) * (size - originalSize); // If no size change or just one appearance, always ok to trivially eliminate. otherwise, tradeoff
3045
+ if (factor <= 12) {
3046
+ allTrivials[name] = size; // trivial!
3047
+ return true;
3048
+ }
3024
3049
  }
3025
- var trivials = {};
3050
+ return false;
3051
+ }
3052
+ for (var name in asmData.vars) {
3053
+ assessTriviality(name);
3054
+ }
3055
+ var trivials = {};
3026
3056
 
3027
- for (var name in allTrivials) { // from now on, ignore parameters
3028
- if (name in asmData.vars) trivials[name] = true;
3029
- }
3057
+ for (var name in allTrivials) { // from now on, ignore parameters
3058
+ if (name in asmData.vars) trivials[name] = true;
3059
+ }
3030
3060
 
3031
- allTrivials = {};
3061
+ allTrivials = {};
3032
3062
 
3033
- var values = {};
3063
+ var values = {}, recursives = {};
3034
3064
 
3035
- function evaluate(name) {
3036
- var node = values[name];
3037
- if (node) return node;
3038
- values[node] = null; // prevent infinite recursion
3039
- var def = defs[name];
3040
- if (def) {
3041
- node = def[3];
3042
- if (node[0] == 'name') {
3043
- var name2 = node[1];
3044
- if (name2 in trivials) {
3045
- node = evaluate(name2);
3046
- }
3047
- } else {
3048
- traverse(node, function(node, type) {
3049
- if (type == 'name') {
3050
- var name2 = node[1];
3051
- if (name2 in trivials) {
3052
- return evaluate(name2);
3053
- }
3054
- }
3055
- });
3065
+ function evaluate(name) {
3066
+ var node = values[name];
3067
+ if (node) return node;
3068
+ values[name] = null; // prevent infinite recursion
3069
+ var def = defs[name];
3070
+ if (def) {
3071
+ node = def[3];
3072
+ if (node[0] == 'name') {
3073
+ var name2 = node[1];
3074
+ assert(name2 !== name);
3075
+ if (name2 in trivials) {
3076
+ node = evaluate(name2);
3056
3077
  }
3057
- values[name] = node;
3078
+ } else {
3079
+ traverse(node, function(node, type) {
3080
+ if (type == 'name') {
3081
+ var name2 = node[1];
3082
+ if (name2 === name) {
3083
+ recursives[name] = 1;
3084
+ return false;
3085
+ }
3086
+ if (name2 in trivials) {
3087
+ return evaluate(name2);
3088
+ }
3089
+ }
3090
+ });
3058
3091
  }
3059
- return node;
3092
+ values[name] = node;
3060
3093
  }
3094
+ return node;
3095
+ }
3096
+
3097
+ for (var name in trivials) {
3098
+ evaluate(name);
3099
+ }
3100
+ for (var name in recursives) {
3101
+ delete trivials[name];
3102
+ }
3061
3103
 
3062
- for (var name in trivials) {
3063
- evaluate(name);
3104
+ for (var name in trivials) {
3105
+ var def = defs[name];
3106
+ if (def) {
3107
+ def.length = 0;
3108
+ def[0] = 'toplevel';
3109
+ def[1] = [];
3064
3110
  }
3111
+ delete asmData.vars[name];
3112
+ }
3065
3113
 
3066
- for (var name in trivials) {
3067
- var def = defs[name];
3068
- if (def) {
3069
- def.length = 0;
3070
- def[0] = 'toplevel';
3071
- def[1] = [];
3114
+ // Perform replacements TODO: save list of uses objects before, replace directly, avoid extra traverse
3115
+ traverse(func, function(node, type) {
3116
+ if (type == 'name') {
3117
+ var name = node[1];
3118
+ if (name in trivials) {
3119
+ var value = values[name];
3120
+ if (!value) throw 'missing value: ' + [func[1], name, values[name]] + ' - faulty reliance on asm zero-init?';
3121
+ return copy(value); // must copy, or else the same object can be used multiple times
3072
3122
  }
3073
- delete asmData.vars[name];
3074
3123
  }
3124
+ });
3125
+ }
3075
3126
 
3076
- // Perform replacements TODO: save list of uses objects before, replace directly, avoid extra traverse
3077
- traverse(func, function(node, type) {
3078
- if (type == 'name') {
3079
- var name = node[1];
3080
- if (name in trivials) {
3081
- var value = values[name];
3082
- if (!value) throw 'missing value: ' + [func[1], name, values[name]] + ' - faulty reliance on asm zero-init?';
3083
- return copy(value); // must copy, or else the same object can be used multiple times
3084
- }
3085
- }
3086
- });
3087
- }
3127
+ function aggressiveVariableElimination(ast) {
3128
+ assert(asm, 'need ASM_JS for aggressive variable elimination');
3129
+ traverseGeneratedFunctions(ast, function(func, type) {
3130
+ var asmData = normalizeAsm(func);
3131
+ aggressiveVariableEliminationInternal(func, asmData);
3132
+ denormalizeAsm(func, asmData);
3133
+ });
3134
+ }
3088
3135
 
3136
+ function outline(ast) {
3089
3137
  // Try to flatten out code as much as possible, to make outlining more feasible.
3090
3138
  function flatten(func, asmData) {
3091
3139
  var minSize = extraInfo.sizeToOutline/4;
@@ -3740,7 +3788,7 @@ function outline(ast) {
3740
3788
  var size = measureSize(func);
3741
3789
  if (size >= extraInfo.sizeToOutline && maxTotalFunctions > 0) {
3742
3790
  maxTotalFunctions--;
3743
- aggressiveVariableElimination(func, asmData);
3791
+ aggressiveVariableEliminationInternal(func, asmData);
3744
3792
  flatten(func, asmData);
3745
3793
  analyzeFunction(func, asmData);
3746
3794
  calculateThreshold(func, asmData);
@@ -3921,6 +3969,7 @@ var passes = {
3921
3969
  registerize: registerize,
3922
3970
  eliminate: eliminate,
3923
3971
  eliminateMemSafe: eliminateMemSafe,
3972
+ aggressiveVariableElimination: aggressiveVariableElimination,
3924
3973
  minifyGlobals: minifyGlobals,
3925
3974
  relocate: relocate,
3926
3975
  outline: outline,