webruby 0.2.4 → 0.2.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/webruby/environment.rb +4 -0
- data/lib/webruby/rake/files.rake +2 -1
- data/lib/webruby/rake/mruby.rake +4 -2
- data/modules/emscripten/AUTHORS +1 -0
- data/modules/emscripten/cmake/Platform/Emscripten.cmake +2 -0
- data/modules/emscripten/emcc +96 -40
- data/modules/emscripten/emrun +301 -136
- data/modules/emscripten/emscripten.py +5 -45
- data/modules/emscripten/src/analyzer.js +11 -1
- data/modules/emscripten/src/compiler.js +1 -1
- data/modules/emscripten/src/emrun_postjs.js +2 -2
- data/modules/emscripten/src/emrun_prejs.js +5 -0
- data/modules/emscripten/src/emscripten-source-map.min.js +31 -0
- data/modules/emscripten/src/library.js +187 -0
- data/modules/emscripten/src/library_egl.js +20 -0
- data/modules/emscripten/src/library_sdl.js +1 -0
- data/modules/emscripten/src/preamble.js +4 -0
- data/modules/emscripten/src/relooper/Relooper.cpp +33 -15
- data/modules/emscripten/src/relooper/Relooper.h +20 -14
- data/modules/emscripten/src/relooper/fuzzer.py +6 -0
- data/modules/emscripten/src/relooper/test.cpp +28 -0
- data/modules/emscripten/src/relooper/test.txt +211 -166
- data/modules/emscripten/src/relooper/test2.txt +20 -20
- data/modules/emscripten/src/relooper/test3.txt +41 -41
- data/modules/emscripten/src/relooper/test4.txt +26 -26
- data/modules/emscripten/src/relooper/test5.txt +52 -52
- data/modules/emscripten/src/relooper/test6.txt +19 -19
- data/modules/emscripten/src/relooper/test_dead.txt +1 -1
- data/modules/emscripten/src/relooper/test_debug.txt +31 -31
- data/modules/emscripten/src/relooper/test_fuzz1.txt +50 -50
- data/modules/emscripten/src/relooper/test_fuzz2.txt +21 -21
- data/modules/emscripten/src/relooper/test_fuzz3.txt +18 -18
- data/modules/emscripten/src/relooper/test_fuzz4.txt +28 -28
- data/modules/emscripten/src/relooper/test_fuzz5.txt +61 -61
- data/modules/emscripten/src/relooper/test_fuzz6.txt +179 -179
- data/modules/emscripten/src/relooper/test_inf.txt +846 -846
- data/modules/emscripten/src/relooper/testit.sh +15 -15
- data/modules/emscripten/system/include/emscripten/emscripten.h +64 -0
- data/modules/emscripten/tools/eliminator/asm-eliminator-test-output.js +8 -2
- data/modules/emscripten/tools/eliminator/asm-eliminator-test.js +9 -1
- data/modules/emscripten/tools/eliminator/eliminator-test-output.js +11 -0
- data/modules/emscripten/tools/eliminator/eliminator-test.js +16 -1
- data/modules/emscripten/tools/file_packager.py +59 -49
- data/modules/emscripten/tools/js-optimizer.js +47 -8
- data/modules/emscripten/tools/shared.py +3 -3
- data/modules/emscripten/tools/test-js-optimizer-asm-pre-output.js +5 -3
- data/modules/emscripten/tools/test-js-optimizer-asm-pre.js +4 -0
- data/modules/mruby/INSTALL +11 -6
- data/modules/mruby/include/mrbconf.h +0 -3
- data/modules/mruby/include/mruby/khash.h +34 -36
- data/modules/mruby/include/mruby/string.h +3 -0
- data/modules/mruby/include/mruby.h +3 -3
- data/modules/mruby/mrblib/string.rb +3 -0
- data/modules/mruby/src/class.c +12 -12
- data/modules/mruby/src/codegen.c +18 -11
- data/modules/mruby/src/hash.c +12 -12
- data/modules/mruby/src/kernel.c +3 -3
- data/modules/mruby/src/load.c +29 -14
- data/modules/mruby/src/numeric.c +1 -1
- data/modules/mruby/src/object.c +14 -2
- data/modules/mruby/src/state.c +13 -10
- data/modules/mruby/src/string.c +1 -3
- data/modules/mruby/src/symbol.c +44 -18
- data/modules/mruby/src/variable.c +6 -6
- data/modules/mruby/test/t/class.rb +34 -0
- data/modules/mruby/test/t/module.rb +1 -1
- data/modules/mruby/test/t/syntax.rb +28 -0
- metadata +5 -13
- data/modules/emscripten/src/relooper.js +0 -11516
- data/modules/emscripten/src/relooper.js.raw.js +0 -11511
- data/modules/emscripten/tools/__init__.pyc +0 -0
- data/modules/emscripten/tools/cache.pyc +0 -0
- data/modules/emscripten/tools/gen_struct_info.pyc +0 -0
- data/modules/emscripten/tools/js_optimizer.pyc +0 -0
- data/modules/emscripten/tools/jsrun.pyc +0 -0
- data/modules/emscripten/tools/response_file.pyc +0 -0
- data/modules/emscripten/tools/shared.pyc +0 -0
- data/modules/emscripten/tools/tempfiles.pyc +0 -0
@@ -733,60 +733,20 @@ def emscript_fast(infile, settings, outfile, libraries=[], compiler_engine=None,
|
|
733
733
|
# * Run compiler.js on the metadata to emit the shell js code, pre/post-ambles,
|
734
734
|
# JS library dependencies, etc.
|
735
735
|
|
736
|
-
if DEBUG: logging.debug('emscript: llvm backend')
|
737
|
-
|
738
|
-
# TODO: proper temp files
|
739
|
-
# TODO: use a single LLVM toolchain instead of normal for source, pnacl for simplification, custom for js backend
|
740
|
-
|
741
|
-
if DEBUG: shutil.copyfile(infile, os.path.join(shared.CANONICAL_TEMP_DIR, 'temp0.ll'))
|
742
|
-
|
743
|
-
extra_opt_args = []
|
744
|
-
#if DEBUG: extra_opt_args.append('-time-passes')
|
745
|
-
|
746
|
-
if DEBUG: t = time.time()
|
747
|
-
|
748
|
-
if DEBUG: logging.debug(' ..1..')
|
749
|
-
temp1 = temp_files.get('.1.bc').name
|
750
|
-
shared.jsrun.timeout_run(subprocess.Popen([os.path.join(shared.LLVM_ROOT, 'opt'), infile, '-pnacl-abi-simplify-preopt', '-o', temp1] + extra_opt_args))
|
751
|
-
assert os.path.exists(temp1)
|
752
|
-
if DEBUG:
|
753
|
-
shutil.copyfile(temp1, os.path.join(shared.CANONICAL_TEMP_DIR, 'temp1.bc'))
|
754
|
-
shared.jsrun.timeout_run(subprocess.Popen([os.path.join(shared.LLVM_ROOT, 'llvm-dis'), 'temp1.bc', '-o', 'temp1.ll']))
|
755
|
-
|
756
|
-
#if DEBUG: logging.debug(' ..2..')
|
757
|
-
#temp2 = temp_files.get('.2.bc').name
|
758
|
-
#shared.jsrun.timeout_run(subprocess.Popen([os.path.join(shared.LLVM_ROOT, 'opt'), temp1, '-O3', '-o', temp2]))
|
759
|
-
#assert os.path.exists(temp2)
|
760
|
-
#if DEBUG:
|
761
|
-
# shutil.copyfile(temp2, os.path.join(shared.CANONICAL_TEMP_DIR, 'temp2.bc'))
|
762
|
-
# shared.jsrun.timeout_run(subprocess.Popen([os.path.join(shared.LLVM_ROOT, 'llvm-dis'), 'temp2.bc', '-o', 'temp2.ll']))
|
763
|
-
temp2 = temp1 # XXX if we optimize the bc, we remove some pnacl clutter, but it also makes varargs stores be 8-byte aligned
|
764
|
-
|
765
|
-
if DEBUG: logging.debug(' ..3..')
|
766
|
-
temp3 = temp_files.get('.3.bc').name
|
767
|
-
shared.jsrun.timeout_run(subprocess.Popen([os.path.join(shared.LLVM_ROOT, 'opt'), temp2, '-pnacl-abi-simplify-postopt', '-o', temp3] + extra_opt_args))
|
768
|
-
#'-print-after-all'
|
769
|
-
assert os.path.exists(temp3)
|
770
|
-
if DEBUG:
|
771
|
-
shutil.copyfile(temp3, os.path.join(shared.CANONICAL_TEMP_DIR, 'temp3.bc'))
|
772
|
-
shared.jsrun.timeout_run(subprocess.Popen([os.path.join(shared.LLVM_ROOT, 'llvm-dis'), 'temp3.bc', '-o', 'temp3.ll']))
|
773
|
-
|
774
736
|
if DEBUG:
|
775
|
-
logging.debug('
|
737
|
+
logging.debug('emscript: llvm backend')
|
776
738
|
t = time.time()
|
777
739
|
|
778
|
-
|
779
|
-
temp4 = temp_files.get('.4.js').name
|
740
|
+
temp_js = temp_files.get('.4.js').name
|
780
741
|
backend_compiler = os.path.join(shared.LLVM_ROOT, 'llc')
|
781
|
-
shared.jsrun.timeout_run(subprocess.Popen([backend_compiler,
|
782
|
-
if DEBUG: shutil.copyfile(temp4, os.path.join(shared.CANONICAL_TEMP_DIR, 'temp4.js'))
|
742
|
+
shared.jsrun.timeout_run(subprocess.Popen([backend_compiler, infile, '-march=js', '-filetype=asm', '-o', temp_js], stdout=subprocess.PIPE))
|
783
743
|
|
784
744
|
if DEBUG:
|
785
745
|
logging.debug(' emscript: llvm backend took %s seconds' % (time.time() - t))
|
786
746
|
t = time.time()
|
787
747
|
|
788
748
|
# Split up output
|
789
|
-
backend_output = open(
|
749
|
+
backend_output = open(temp_js).read()
|
790
750
|
#if DEBUG: print >> sys.stderr, backend_output
|
791
751
|
|
792
752
|
start_funcs_marker = '// EMSCRIPTEN_START_FUNCTIONS'
|
@@ -825,7 +785,7 @@ def emscript_fast(infile, settings, outfile, libraries=[], compiler_engine=None,
|
|
825
785
|
else:
|
826
786
|
num = num[:e] + '.0' + num[e:]
|
827
787
|
return m.group(1) + m.group(2) + num
|
828
|
-
funcs = re.sub(r'([(
|
788
|
+
funcs = re.sub(r'([(=,+\-*/%<>:?] *)\+(-?)((0x)?[0-9a-f]*\.?[0-9]+([eE][-+]?[0-9]+)?)', lambda m: fix_dot_zero(m), funcs)
|
829
789
|
|
830
790
|
# js compiler
|
831
791
|
|
@@ -1570,7 +1570,17 @@ function analyzer(data, sidePass) {
|
|
1570
1570
|
for (var j = 0; j < label.lines.length; j++) {
|
1571
1571
|
var line = label.lines[j];
|
1572
1572
|
if ((line.intertype == 'call' || line.intertype == 'invoke') && line.ident == setjmp) {
|
1573
|
-
|
1573
|
+
if (line.intertype == 'invoke') {
|
1574
|
+
// setjmp cannot trigger unwinding, so just reduce the invoke to a call + branch
|
1575
|
+
line.intertype = 'call';
|
1576
|
+
label.lines.push({
|
1577
|
+
intertype: 'branch',
|
1578
|
+
label: line.toLabel,
|
1579
|
+
lineNum: line.lineNum + 0.01, // XXX legalizing might confuse this
|
1580
|
+
});
|
1581
|
+
line.toLabel = line.unwindLabel = -2;
|
1582
|
+
}
|
1583
|
+
// split this label into up to the setjmp (including), then a new label for the rest. longjmp will reach the rest
|
1574
1584
|
var oldLabel = label.ident;
|
1575
1585
|
var newLabel = func.labelIdCounter++;
|
1576
1586
|
if (!func.setjmpTable) func.setjmpTable = [];
|
@@ -134,7 +134,7 @@ load('settings.js');
|
|
134
134
|
var settings_file = arguments_[0];
|
135
135
|
var ll_file = arguments_[1];
|
136
136
|
phase = arguments_[2];
|
137
|
-
if (phase == 'pre') {
|
137
|
+
if (phase == 'pre' || phase == 'glue') {
|
138
138
|
additionalLibraries = Array.prototype.slice.call(arguments_, 3);
|
139
139
|
} else {
|
140
140
|
var forwardedDataFile = arguments_[3];
|
@@ -4,8 +4,8 @@ function emrun_register_handlers() {
|
|
4
4
|
http.open("POST", "stdio.html", true);
|
5
5
|
http.send(msg);
|
6
6
|
}
|
7
|
-
// If the address contains localhost, we can assume we're running the test runner and should post stdout logs.
|
8
|
-
if (document.URL.search("localhost") != -1) {
|
7
|
+
// If the address contains localhost, or we are running the page from port 6931, we can assume we're running the test runner and should post stdout logs.
|
8
|
+
if (document.URL.search("localhost") != -1 || document.URL.search(":6931/") != -1) {
|
9
9
|
var emrun_http_sequence_number = 1;
|
10
10
|
var prevExit = Module['exit'];
|
11
11
|
var prevPrint = Module['print'];
|
@@ -0,0 +1,31 @@
|
|
1
|
+
function define(e,t,n){if(typeof e!="string")throw new TypeError("Expected string, got: "+e);arguments.length==2&&(n=t);if(e in define.modules)throw new Error("Module already defined: "+e);define.modules[e]=n}function Domain(){this.modules={},this._currentModule=null}define.modules={},function(){function e(e){var t=e.split("/"),n=1;while(n<t.length)t[n]===".."?t.splice(n-1,1):t[n]==="."?t.splice(n,1):n++;return t.join("/")}function t(e,t){return e=e.trim(),t=t.trim(),/^\//.test(t)?t:e.replace(/\/*$/,"/")+t}function n(e){var t=e.split("/");return t.pop(),t.join("/")}Domain.prototype.require=function(e,t){if(Array.isArray(e)){var n=e.map(function(e){return this.lookup(e)},this);return t&&t.apply(null,n),undefined}return this.lookup(e)},Domain.prototype.lookup=function(r){/^\./.test(r)&&(r=e(t(n(this._currentModule),r)));if(r in this.modules){var i=this.modules[r];return i}if(r in define.modules){var i=define.modules[r];if(typeof i=="function"){var s={},o=this._currentModule;this._currentModule=r,i(this.require.bind(this),s,{id:r,uri:""}),this._currentModule=o,i=s}return this.modules[r]=i,i}throw new Error("Module not defined: "+r)}}(),define.Domain=Domain,define.globalDomain=new Domain;var require=define.globalDomain.require.bind(define.globalDomain);define("source-map/source-map-generator",["require","exports","module","source-map/base64-vlq","source-map/util","source-map/array-set"],function(e,t,n){function o(e){this._file=i.getArg(e,"file"),this._sourceRoot=i.getArg(e,"sourceRoot",null),this._sources=new s,this._names=new s,this._mappings=[],this._sourcesContents=null}function u(e,t){var n=(e&&e.line)-(t&&t.line);return n?n:(e&&e.column)-(t&&t.column)}function a(e,t){return e=e||"",t=t||"",(e>t)-(e<t)}function f(e,t){return u(e.generated,t.generated)||u(e.original,t.original)||a(e.source,t.source)||a(e.name,t.name)}var r=e("./base64-vlq"),i=e("./util"),s=e("./array-set").ArraySet;o.prototype._version=3,o.fromSourceMap=function(t){var n=t.sourceRoot,r=new o({file:t.file,sourceRoot:n});return t.eachMapping(function(e){var t={generated:{line:e.generatedLine,column:e.generatedColumn}};e.source&&(t.source=e.source,n&&(t.source=i.relative(n,t.source)),t.original={line:e.originalLine,column:e.originalColumn},e.name&&(t.name=e.name)),r.addMapping(t)}),t.sources.forEach(function(e){var n=t.sourceContentFor(e);n&&r.setSourceContent(e,n)}),r},o.prototype.addMapping=function(t){var n=i.getArg(t,"generated"),r=i.getArg(t,"original",null),s=i.getArg(t,"source",null),o=i.getArg(t,"name",null);this._validateMapping(n,r,s,o),s&&!this._sources.has(s)&&this._sources.add(s),o&&!this._names.has(o)&&this._names.add(o),this._mappings.push({generated:n,original:r,source:s,name:o})},o.prototype.setSourceContent=function(t,n){var r=t;this._sourceRoot&&(r=i.relative(this._sourceRoot,r)),n!==null?(this._sourcesContents||(this._sourcesContents={}),this._sourcesContents[i.toSetString(r)]=n):(delete this._sourcesContents[i.toSetString(r)],Object.keys(this._sourcesContents).length===0&&(this._sourcesContents=null))},o.prototype.applySourceMap=function(t,n){n||(n=t.file);var r=this._sourceRoot;r&&(n=i.relative(r,n));var o=new s,u=new s;this._mappings.forEach(function(e){if(e.source===n&&e.original){var s=t.originalPositionFor({line:e.original.line,column:e.original.column});s.source!==null&&(r?e.source=i.relative(r,s.source):e.source=s.source,e.original.line=s.line,e.original.column=s.column,s.name!==null&&e.name!==null&&(e.name=s.name))}var a=e.source;a&&!o.has(a)&&o.add(a);var f=e.name;f&&!u.has(f)&&u.add(f)},this),this._sources=o,this._names=u,t.sources.forEach(function(e){var n=t.sourceContentFor(e);n&&(r&&(e=i.relative(r,e)),this.setSourceContent(e,n))},this)},o.prototype._validateMapping=function(t,n,r,i){if(t&&"line"in t&&"column"in t&&t.line>0&&t.column>=0&&!n&&!r&&!i)return;if(t&&"line"in t&&"column"in t&&n&&"line"in n&&"column"in n&&t.line>0&&t.column>=0&&n.line>0&&n.column>=0&&r)return;throw new Error("Invalid mapping.")},o.prototype._serializeMappings=function(){var t=0,n=1,i=0,s=0,o=0,u=0,a="",l;this._mappings.sort(f);for(var c=0,h=this._mappings.length;c<h;c++){l=this._mappings[c];if(l.generated.line!==n){t=0;while(l.generated.line!==n)a+=";",n++}else if(c>0){if(!f(l,this._mappings[c-1]))continue;a+=","}a+=r.encode(l.generated.column-t),t=l.generated.column,l.source&&l.original&&(a+=r.encode(this._sources.indexOf(l.source)-u),u=this._sources.indexOf(l.source),a+=r.encode(l.original.line-1-s),s=l.original.line-1,a+=r.encode(l.original.column-i),i=l.original.column,l.name&&(a+=r.encode(this._names.indexOf(l.name)-o),o=this._names.indexOf(l.name)))}return a},o.prototype.toJSON=function(){var t={version:this._version,file:this._file,sources:this._sources.toArray(),names:this._names.toArray(),mappings:this._serializeMappings()};return this._sourceRoot&&(t.sourceRoot=this._sourceRoot),this._sourcesContents&&(t.sourcesContent=t.sources.map(function(e){return t.sourceRoot&&(e=i.relative(t.sourceRoot,e)),Object.prototype.hasOwnProperty.call(this._sourcesContents,i.toSetString(e))?this._sourcesContents[i.toSetString(e)]:null},this)),t},o.prototype.toString=function(){return JSON.stringify(this)},t.SourceMapGenerator=o}),define("source-map/base64-vlq",["require","exports","module","source-map/base64"],function(e,t,n){function a(e){return e<0?(-e<<1)+1:(e<<1)+0}function f(e){var t=(e&1)===1,n=e>>1;return t?-n:n}var r=e("./base64"),i=5,s=1<<i,o=s-1,u=s;t.encode=function(t){var n="",s,f=a(t);do s=f&o,f>>>=i,f>0&&(s|=u),n+=r.encode(s);while(f>0);return n},t.decode=function(t){var n=0,s=t.length,a=0,l=0,c,h;do{if(n>=s)throw new Error("Expected more digits in base 64 VLQ value.");h=r.decode(t.charAt(n++)),c=!!(h&u),h&=o,a+=h<<l,l+=i}while(c);return{value:f(a),rest:t.slice(n)}}}),define("source-map/base64",["require","exports","module"],function(e,t,n){var r={},i={};"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("").forEach(function(e,t){r[e]=t,i[t]=e}),t.encode=function(t){if(t in i)return i[t];throw new TypeError("Must be between 0 and 63: "+t)},t.decode=function(t){if(t in r)return r[t];throw new TypeError("Not a valid base 64 digit: "+t)}}),define("source-map/util",["require","exports","module"],function(e,t,n){function r(e,t,n){if(t in e)return e[t];if(arguments.length===3)return n;throw new Error('"'+t+'" is a required argument.')}function s(e){var t=e.match(i);return t?{scheme:t[1],auth:t[3],host:t[4],port:t[6],path:t[7]}:null}function o(e){var t=e.scheme+"://";return e.auth&&(t+=e.auth+"@"),e.host&&(t+=e.host),e.port&&(t+=":"+e.port),e.path&&(t+=e.path),t}function u(e,t){var n;return t.match(i)?t:t.charAt(0)==="/"&&(n=s(e))?(n.path=t,o(n)):e.replace(/\/$/,"")+"/"+t}function a(e){return"$"+e}function f(e){return e.substr(1)}function l(e,t){e=e.replace(/\/$/,"");var n=s(e);return t.charAt(0)=="/"&&n&&n.path=="/"?t.slice(1):t.indexOf(e+"/")===0?t.substr(e.length+1):t}t.getArg=r;var i=/([\w+\-.]+):\/\/((\w+:\w+)@)?([\w.]+)?(:(\d+))?(\S+)?/;t.urlParse=s,t.urlGenerate=o,t.join=u,t.toSetString=a,t.fromSetString=f,t.relative=l}),define("source-map/array-set",["require","exports","module","source-map/util"],function(e,t,n){function i(){this._array=[],this._set={}}var r=e("./util");i.fromArray=function(t,n){var r=new i;for(var s=0,o=t.length;s<o;s++)r.add(t[s],n);return r},i.prototype.add=function(t,n){var i=this.has(t),s=this._array.length;(!i||n)&&this._array.push(t),i||(this._set[r.toSetString(t)]=s)},i.prototype.has=function(t){return Object.prototype.hasOwnProperty.call(this._set,r.toSetString(t))},i.prototype.indexOf=function(t){if(this.has(t))return this._set[r.toSetString(t)];throw new Error('"'+t+'" is not in the set.')},i.prototype.at=function(t){if(t>=0&&t<this._array.length)return this._array[t];throw new Error("No element indexed by "+t)},i.prototype.toArray=function(){return this._array.slice()},t.ArraySet=i}),define("source-map/source-map-consumer",["require","exports","module","source-map/util","source-map/binary-search","source-map/array-set","source-map/base64-vlq"],function(e,t,n){function u(e){var t=e;typeof e=="string"&&(t=JSON.parse(e.replace(/^\)\]\}'/,"")));var n=r.getArg(t,"version"),i=r.getArg(t,"sources"),o=r.getArg(t,"names"),u=r.getArg(t,"sourceRoot",null),a=r.getArg(t,"sourcesContent",null),f=r.getArg(t,"mappings"),l=r.getArg(t,"file",null);if(n!==this._version)throw new Error("Unsupported version: "+n);this._names=s.fromArray(o,!0),this._sources=s.fromArray(i,!0),this.sourceRoot=u,this.sourcesContent=a,this.file=l,this._generatedMappings=[],this._originalMappings=[],this._parseMappings(f,u)}var r=e("./util"),i=e("./binary-search"),s=e("./array-set").ArraySet,o=e("./base64-vlq");u.prototype._version=3,Object.defineProperty(u.prototype,"sources",{get:function(){return this._sources.toArray().map(function(e){return this.sourceRoot?r.join(this.sourceRoot,e):e},this)}}),u.prototype._parseMappings=function(t,n){var r=1,i=0,s=0,u=0,a=0,f=0,l=/^[,;]/,c=t,h,p;while(c.length>0)if(c.charAt(0)===";")r++,c=c.slice(1),i=0;else if(c.charAt(0)===",")c=c.slice(1);else{h={},h.generatedLine=r,p=o.decode(c),h.generatedColumn=i+p.value,i=h.generatedColumn,c=p.rest;if(c.length>0&&!l.test(c.charAt(0))){p=o.decode(c),h.source=this._sources.at(a+p.value),a+=p.value,c=p.rest;if(c.length===0||l.test(c.charAt(0)))throw new Error("Found a source, but no line and column");p=o.decode(c),h.originalLine=s+p.value,s=h.originalLine,h.originalLine+=1,c=p.rest;if(c.length===0||l.test(c.charAt(0)))throw new Error("Found a source and line, but no column");p=o.decode(c),h.originalColumn=u+p.value,u=h.originalColumn,c=p.rest,c.length>0&&!l.test(c.charAt(0))&&(p=o.decode(c),h.name=this._names.at(f+p.value),f+=p.value,c=p.rest)}this._generatedMappings.push(h),typeof h.originalLine=="number"&&this._originalMappings.push(h)}this._originalMappings.sort(this._compareOriginalPositions)},u.prototype._compareOriginalPositions=function(t,n){if(t.source>n.source)return 1;if(t.source<n.source)return-1;var r=t.originalLine-n.originalLine;return r===0?t.originalColumn-n.originalColumn:r},u.prototype._compareGeneratedPositions=function(t,n){var r=t.generatedLine-n.generatedLine;return r===0?t.generatedColumn-n.generatedColumn:r},u.prototype._findMapping=function(t,n,r,s,o){if(t[r]<=0)throw new TypeError("Line must be greater than or equal to 1, got "+t[r]);if(t[s]<0)throw new TypeError("Column must be greater than or equal to 0, got "+t[s]);return i.search(t,n,o)},u.prototype.originalPositionFor=function(t){var n={generatedLine:r.getArg(t,"line"),generatedColumn:r.getArg(t,"column")},i=this._findMapping(n,this._generatedMappings,"generatedLine","generatedColumn",this._compareGeneratedPositions);if(i){var s=r.getArg(i,"source",null);return s&&this.sourceRoot&&(s=r.join(this.sourceRoot,s)),{source:s,line:r.getArg(i,"originalLine",null),column:r.getArg(i,"originalColumn",null),name:r.getArg(i,"name",null)}}return{source:null,line:null,column:null,name:null}},u.prototype.sourceContentFor=function(t){if(!this.sourcesContent)return null;this.sourceRoot&&(t=r.relative(this.sourceRoot,t));if(this._sources.has(t))return this.sourcesContent[this._sources.indexOf(t)];var n;if(this.sourceRoot&&(n=r.urlParse(this.sourceRoot))){var i=t.replace(/^file:\/\//,"");if(n.scheme=="file"&&this._sources.has(i))return this.sourcesContent[this._sources.indexOf(i)];if((!n.path||n.path=="/")&&this._sources.has("/"+t))return this.sourcesContent[this._sources.indexOf("/"+t)]}throw new Error('"'+t+'" is not in the SourceMap.')},u.prototype.generatedPositionFor=function(t){var n={source:r.getArg(t,"source"),originalLine:r.getArg(t,"line"),originalColumn:r.getArg(t,"column")};this.sourceRoot&&(n.source=r.relative(this.sourceRoot,n.source));var i=this._findMapping(n,this._originalMappings,"originalLine","originalColumn",this._compareOriginalPositions);return i?{line:r.getArg(i,"generatedLine",null),column:r.getArg(i,"generatedColumn",null)}:{line:null,column:null}},u.GENERATED_ORDER=1,u.ORIGINAL_ORDER=2,u.prototype.eachMapping=function(t,n,i){var s=n||null,o=i||u.GENERATED_ORDER,a;switch(o){case u.GENERATED_ORDER:a=this._generatedMappings;break;case u.ORIGINAL_ORDER:a=this._originalMappings;break;default:throw new Error("Unknown order of iteration.")}var f=this.sourceRoot;a.map(function(e){var t=e.source;return t&&f&&(t=r.join(f,t)),{source:t,generatedLine:e.generatedLine,generatedColumn:e.generatedColumn,originalLine:e.originalLine,originalColumn:e.originalColumn,name:e.name}}).forEach(t,s)},t.SourceMapConsumer=u}),define("source-map/binary-search",["require","exports","module"],function(e,t,n){function r(e,t,n,i,s){var o=Math.floor((t-e)/2)+e,u=s(n,i[o]);return u===0?i[o]:u>0?t-o>1?r(o,t,n,i,s):i[o]:o-e>1?r(e,o,n,i,s):e<0?null:i[e]}t.search=function(t,n,i){return n.length>0?r(-1,n.length,t,n,i):null}}),define("source-map/source-node",["require","exports","module","source-map/source-map-generator","source-map/util"],function(e,t,n){function s(e,t,n,r,i){this.children=[],this.sourceContents={},this.line=e===undefined?null:e,this.column=t===undefined?null:t,this.source=n===undefined?null:n,this.name=i===undefined?null:i,r!=null&&this.add(r)}var r=e("./source-map-generator").SourceMapGenerator,i=e("./util");s.fromStringWithSourceMap=function(t,n){function f(e,t){e===null||e.source===undefined?r.add(t):r.add(new s(e.originalLine,e.originalColumn,e.source,t,e.name))}var r=new s,i=t.split("\n"),o=1,u=0,a=null;return n.eachMapping(function(e){if(a===null){while(o<e.generatedLine)r.add(i.shift()+"\n"),o++;if(u<e.generatedColumn){var t=i[0];r.add(t.substr(0,e.generatedColumn)),i[0]=t.substr(e.generatedColumn),u=e.generatedColumn}}else if(o<e.generatedLine){var n="";do n+=i.shift()+"\n",o++,u=0;while(o<e.generatedLine);if(u<e.generatedColumn){var t=i[0];n+=t.substr(0,e.generatedColumn),i[0]=t.substr(e.generatedColumn),u=e.generatedColumn}f(a,n)}else{var t=i[0],n=t.substr(0,e.generatedColumn-u);i[0]=t.substr(e.generatedColumn-u),u=e.generatedColumn,f(a,n)}a=e},this),f(a,i.join("\n")),n.sources.forEach(function(e){var t=n.sourceContentFor(e);t&&r.setSourceContent(e,t)}),r},s.prototype.add=function(t){if(Array.isArray(t))t.forEach(function(e){this.add(e)},this);else{if(!(t instanceof s||typeof t=="string"))throw new TypeError("Expected a SourceNode, string, or an array of SourceNodes and strings. Got "+t);t&&this.children.push(t)}return this},s.prototype.prepend=function(t){if(Array.isArray(t))for(var n=t.length-1;n>=0;n--)this.prepend(t[n]);else{if(!(t instanceof s||typeof t=="string"))throw new TypeError("Expected a SourceNode, string, or an array of SourceNodes and strings. Got "+t);this.children.unshift(t)}return this},s.prototype.walk=function(t){this.children.forEach(function(e){e instanceof s?e.walk(t):e!==""&&t(e,{source:this.source,line:this.line,column:this.column,name:this.name})},this)},s.prototype.join=function(t){var n,r,i=this.children.length;if(i>0){n=[];for(r=0;r<i-1;r++)n.push(this.children[r]),n.push(t);n.push(this.children[r]),this.children=n}return this},s.prototype.replaceRight=function(t,n){var r=this.children[this.children.length-1];return r instanceof s?r.replaceRight(t,n):typeof r=="string"?this.children[this.children.length-1]=r.replace(t,n):this.children.push("".replace(t,n)),this},s.prototype.setSourceContent=function(t,n){this.sourceContents[i.toSetString(t)]=n},s.prototype.walkSourceContents=function(t){this.children.forEach(function(e){e instanceof s&&e.walkSourceContents(t)},this),Object.keys(this.sourceContents).forEach(function(e){t(i.fromSetString(e),this.sourceContents[e])},this)},s.prototype.toString=function(){var t="";return this.walk(function(e){t+=e}),t},s.prototype.toStringWithSourceMap=function(t){var n={code:"",line:1,column:0},i=new r(t),s=!1,o=null,u=null,a=null,f=null;return this.walk(function(e,t){n.code+=e,t.source!==null&&t.line!==null&&t.column!==null?((o!==t.source||u!==t.line||a!==t.column||f!==t.name)&&i.addMapping({source:t.source,original:{line:t.line,column:t.column},generated:{line:n.line,column:n.column},name:t.name}),o=t.source,u=t.line,a=t.column,f=t.name,s=!0):s&&(i.addMapping({generated:{line:n.line,column:n.column}}),o=null,s=!1),e.split("").forEach(function(e){e==="\n"?(n.line++,n.column=0):n.column++})}),this.walkSourceContents(function(e,t){i.setSourceContent(e,t)}),{code:n.code,map:i}},t.SourceNode=s}),window.sourceMap={SourceMapConsumer:require("source-map/source-map-consumer").SourceMapConsumer,SourceMapGenerator:require("source-map/source-map-generator").SourceMapGenerator,SourceNode:require("source-map/source-node").SourceNode}
|
2
|
+
|
3
|
+
var emscripten_sourcemap_xmlHttp = undefined;
|
4
|
+
function emscripten_sourceMapLoaded() {
|
5
|
+
if (emscripten_sourcemap_xmlHttp.readyState === 4) {
|
6
|
+
Module['removeRunDependency']('sourcemap');
|
7
|
+
if (emscripten_sourcemap_xmlHttp.status === 200) {
|
8
|
+
emscripten_source_map = new window.sourceMap.SourceMapConsumer(emscripten_sourcemap_xmlHttp.responseText);
|
9
|
+
console.log('Source map data loaded.');
|
10
|
+
} else {
|
11
|
+
console.warn('Source map data loading failed with status code ' + emscripten_sourcemap_xmlHttp.status + '.');
|
12
|
+
}
|
13
|
+
emscripten_sourcemap_xmlHttp = undefined;
|
14
|
+
}
|
15
|
+
}
|
16
|
+
function emscripten_loadSourceMap() {
|
17
|
+
var url = window.location.href+'.map';
|
18
|
+
console.log('Loading source map data from ' + url + '..');
|
19
|
+
Module['addRunDependency']('sourcemap');
|
20
|
+
emscripten_sourcemap_xmlHttp = new XMLHttpRequest();
|
21
|
+
emscripten_sourcemap_xmlHttp.onreadystatechange = emscripten_sourceMapLoaded;
|
22
|
+
emscripten_sourcemap_xmlHttp.open("GET", url, true);
|
23
|
+
emscripten_sourcemap_xmlHttp.send(null);
|
24
|
+
}
|
25
|
+
|
26
|
+
var Module;
|
27
|
+
if (Module['preRun'] instanceof Array) {
|
28
|
+
Module['preRun'].push(emscripten_loadSourceMap);
|
29
|
+
} else {
|
30
|
+
Module['preRun'] = [emscripten_loadSourceMap];
|
31
|
+
}
|
@@ -8835,6 +8835,193 @@ LibraryManager.library = {
|
|
8835
8835
|
}
|
8836
8836
|
},
|
8837
8837
|
|
8838
|
+
// Returns [parentFuncArguments, functionName, paramListName]
|
8839
|
+
_emscripten_traverse_stack: function(args) {
|
8840
|
+
if (!args || !args.callee || !args.callee.name) {
|
8841
|
+
return [null, '', ''];
|
8842
|
+
}
|
8843
|
+
|
8844
|
+
var funstr = args.callee.toString();
|
8845
|
+
var funcname = args.callee.name;
|
8846
|
+
var str = '(';
|
8847
|
+
var first = true;
|
8848
|
+
for(i in args) {
|
8849
|
+
var a = args[i];
|
8850
|
+
if (!first) {
|
8851
|
+
str += ", ";
|
8852
|
+
}
|
8853
|
+
first = false;
|
8854
|
+
if (typeof a === 'number' || typeof a === 'string') {
|
8855
|
+
str += a;
|
8856
|
+
} else {
|
8857
|
+
str += '(' + typeof a + ')';
|
8858
|
+
}
|
8859
|
+
}
|
8860
|
+
str += ')';
|
8861
|
+
args = args.callee.caller.arguments;
|
8862
|
+
if (first)
|
8863
|
+
str = '';
|
8864
|
+
return [args, funcname, str];
|
8865
|
+
},
|
8866
|
+
|
8867
|
+
emscripten_get_callstack_js__deps: ['_emscripten_traverse_stack'],
|
8868
|
+
emscripten_get_callstack_js: function(flags) {
|
8869
|
+
var err = new Error();
|
8870
|
+
if (!err.stack) {
|
8871
|
+
Runtime.warnOnce('emscripten_get_callstack_js is not supported on this browser!');
|
8872
|
+
return '';
|
8873
|
+
}
|
8874
|
+
var callstack = new Error().stack.toString();
|
8875
|
+
|
8876
|
+
// Find the symbols in the callstack that corresponds to the functions that report callstack information, and remove everyhing up to these from the output.
|
8877
|
+
var iThisFunc = callstack.lastIndexOf('_emscripten_log');
|
8878
|
+
var iThisFunc2 = callstack.lastIndexOf('_emscripten_get_callstack');
|
8879
|
+
var iNextLine = callstack.indexOf('\n', Math.max(iThisFunc, iThisFunc2))+1;
|
8880
|
+
callstack = callstack.slice(iNextLine);
|
8881
|
+
|
8882
|
+
// If user requested to see the original source stack, but no source map information is available, just fall back to showing the JS stack.
|
8883
|
+
if (flags & 8/*EM_LOG_C_STACK*/ && typeof emscripten_source_map === 'undefined') {
|
8884
|
+
Runtime.warnOnce('Source map information is not available, emscripten_log with EM_LOG_C_STACK will be ignored. Build with "--pre-js $EMSCRIPTEN/src/emscripten-source-map.min.js" linker flag to add source map loading to code.');
|
8885
|
+
flags ^= 8/*EM_LOG_C_STACK*/;
|
8886
|
+
flags |= 16/*EM_LOG_JS_STACK*/;
|
8887
|
+
}
|
8888
|
+
|
8889
|
+
var stack_args = null;
|
8890
|
+
if (flags & 128 /*EM_LOG_FUNC_PARAMS*/) {
|
8891
|
+
// To get the actual parameters to the functions, traverse the stack via the unfortunately deprecated 'arguments.callee' method, if it works:
|
8892
|
+
var stack_args = __emscripten_traverse_stack(arguments);
|
8893
|
+
while (stack_args[1].indexOf('_emscripten_') >= 0)
|
8894
|
+
stack_args = __emscripten_traverse_stack(stack_args[0]);
|
8895
|
+
}
|
8896
|
+
|
8897
|
+
// Process all lines:
|
8898
|
+
lines = callstack.split('\n');
|
8899
|
+
callstack = '';
|
8900
|
+
var firefoxRe = new RegExp('\\s*(.*?)@(.*):(.*)'); // Extract components of form ' Object._main@http://server.com:4324'
|
8901
|
+
var chromeRe = new RegExp('\\s*at (.*?) \\\((.*):(.*):(.*)\\\)'); // Extract components of form ' at Object._main (http://server.com/file.html:4324:12)'
|
8902
|
+
|
8903
|
+
for(l in lines) {
|
8904
|
+
var line = lines[l];
|
8905
|
+
|
8906
|
+
var jsSymbolName = '';
|
8907
|
+
var file = '';
|
8908
|
+
var lineno = 0;
|
8909
|
+
var column = 0;
|
8910
|
+
|
8911
|
+
var parts = chromeRe.exec(line);
|
8912
|
+
if (parts && parts.length == 5) {
|
8913
|
+
jsSymbolName = parts[1];
|
8914
|
+
file = parts[2];
|
8915
|
+
lineno = parts[3];
|
8916
|
+
column = parts[4];
|
8917
|
+
} else {
|
8918
|
+
parts = firefoxRe.exec(line);
|
8919
|
+
if (parts && parts.length == 4) {
|
8920
|
+
jsSymbolName = parts[1];
|
8921
|
+
file = parts[2];
|
8922
|
+
lineno = parts[3];
|
8923
|
+
column = 0; // Firefox doesn't carry column information. See https://bugzilla.mozilla.org/show_bug.cgi?id=762556
|
8924
|
+
} else {
|
8925
|
+
// Was not able to extract this line for demangling/sourcemapping purposes. Output it as-is.
|
8926
|
+
callstack += line + '\n';
|
8927
|
+
continue;
|
8928
|
+
}
|
8929
|
+
}
|
8930
|
+
|
8931
|
+
// Try to demangle the symbol, but fall back to showing the original JS symbol name if not available.
|
8932
|
+
var cSymbolName = (flags & 32/*EM_LOG_DEMANGLE*/) ? demangle(jsSymbolName) : jsSymbolName;
|
8933
|
+
if (!cSymbolName) {
|
8934
|
+
cSymbolName = jsSymbolName;
|
8935
|
+
}
|
8936
|
+
|
8937
|
+
var haveSourceMap = false;
|
8938
|
+
|
8939
|
+
if (flags & 8/*EM_LOG_C_STACK*/) {
|
8940
|
+
var orig = emscripten_source_map.originalPositionFor({line: lineno, column: column});
|
8941
|
+
haveSourceMap = (orig && orig.source);
|
8942
|
+
if (haveSourceMap) {
|
8943
|
+
if (flags & 64/*EM_LOG_NO_PATHS*/) {
|
8944
|
+
orig.source = orig.source.substring(orig.source.replace(/\\/g, "/").lastIndexOf('/')+1);
|
8945
|
+
}
|
8946
|
+
callstack += ' at ' + cSymbolName + ' (' + orig.source + ':' + orig.line + ':' + orig.column + ')\n';
|
8947
|
+
}
|
8948
|
+
}
|
8949
|
+
if ((flags & 16/*EM_LOG_JS_STACK*/) || !haveSourceMap) {
|
8950
|
+
if (flags & 64/*EM_LOG_NO_PATHS*/) {
|
8951
|
+
file = file.substring(file.replace(/\\/g, "/").lastIndexOf('/')+1);
|
8952
|
+
}
|
8953
|
+
callstack += (haveSourceMap ? (' = '+jsSymbolName) : (' at '+cSymbolName)) + ' (' + file + ':' + lineno + ':' + column + ')\n';
|
8954
|
+
}
|
8955
|
+
|
8956
|
+
// If we are still keeping track with the callstack by traversing via 'arguments.callee', print the function parameters as well.
|
8957
|
+
if (flags & 128 /*EM_LOG_FUNC_PARAMS*/ && stack_args[0]) {
|
8958
|
+
if (stack_args[1] == jsSymbolName && stack_args[2].length > 0) {
|
8959
|
+
callstack = callstack.replace(/\s+$/, '');
|
8960
|
+
callstack += ' with values: ' + stack_args[1] + stack_args[2] + '\n';
|
8961
|
+
}
|
8962
|
+
stack_args = __emscripten_traverse_stack(stack_args[0]);
|
8963
|
+
}
|
8964
|
+
}
|
8965
|
+
// Trim extra whitespace at the end of the output.
|
8966
|
+
callstack = callstack.replace(/\s+$/, '');
|
8967
|
+
return callstack;
|
8968
|
+
},
|
8969
|
+
|
8970
|
+
emscripten_get_callstack__deps: ['emscripten_get_callstack_js'],
|
8971
|
+
emscripten_get_callstack: function(flags, str, maxbytes) {
|
8972
|
+
var callstack = _emscripten_get_callstack_js(flags);
|
8973
|
+
// User can query the required amount of bytes to hold the callstack.
|
8974
|
+
if (!str || maxbytes <= 0) {
|
8975
|
+
return callstack.length+1;
|
8976
|
+
}
|
8977
|
+
// Truncate output to avoid writing past bounds.
|
8978
|
+
if (callstack.length > maxbytes-1) {
|
8979
|
+
callstack.slice(0, maxbytes-1);
|
8980
|
+
}
|
8981
|
+
// Output callstack string as C string to HEAP.
|
8982
|
+
writeStringToMemory(callstack, str, false);
|
8983
|
+
|
8984
|
+
// Return number of bytes written.
|
8985
|
+
return callstack.length+1;
|
8986
|
+
},
|
8987
|
+
|
8988
|
+
emscripten_log_js__deps: ['emscripten_get_callstack_js'],
|
8989
|
+
emscripten_log_js: function(flags, str) {
|
8990
|
+
if (flags & 24/*EM_LOG_C_STACK | EM_LOG_JS_STACK*/) {
|
8991
|
+
str = str.replace(/\s+$/, ''); // Ensure the message and the callstack are joined cleanly with exactly one newline.
|
8992
|
+
str += (str.length > 0 ? '\n' : '') + _emscripten_get_callstack_js(flags);
|
8993
|
+
}
|
8994
|
+
|
8995
|
+
if (flags & 1 /*EM_LOG_CONSOLE*/) {
|
8996
|
+
if (flags & 4 /*EM_LOG_ERROR*/) {
|
8997
|
+
console.error(str);
|
8998
|
+
} else if (flags & 2 /*EM_LOG_WARN*/) {
|
8999
|
+
console.warn(str);
|
9000
|
+
} else {
|
9001
|
+
console.log(str);
|
9002
|
+
}
|
9003
|
+
} else if (flags & 6 /*EM_LOG_ERROR|EM_LOG_WARN*/) {
|
9004
|
+
Module.printErr(str);
|
9005
|
+
} else {
|
9006
|
+
Module.print(str);
|
9007
|
+
}
|
9008
|
+
},
|
9009
|
+
|
9010
|
+
emscripten_log__deps: ['_formatString', 'emscripten_log_js'],
|
9011
|
+
emscripten_log: function(flags, varargs) {
|
9012
|
+
// Extract the (optionally-existing) printf format specifier field from varargs.
|
9013
|
+
var format = {{{ makeGetValue('varargs', '0', 'i32', undefined, undefined, true) }}};
|
9014
|
+
varargs += Math.max(Runtime.getNativeFieldSize('i32'), Runtime.getAlignSize('i32', null, true));
|
9015
|
+
var str = '';
|
9016
|
+
if (format) {
|
9017
|
+
var result = __formatString(format, varargs);
|
9018
|
+
for(var i = 0 ; i < result.length; ++i) {
|
9019
|
+
str += String.fromCharCode(result[i]);
|
9020
|
+
}
|
9021
|
+
}
|
9022
|
+
_emscripten_log_js(flags, str);
|
9023
|
+
},
|
9024
|
+
|
8838
9025
|
//============================
|
8839
9026
|
// emscripten vector ops
|
8840
9027
|
//============================
|
@@ -264,6 +264,26 @@ var LibraryEGL = {
|
|
264
264
|
return 0;
|
265
265
|
}
|
266
266
|
|
267
|
+
// EGL 1.4 spec says default EGL_CONTEXT_CLIENT_VERSION is GLES1, but this is not supported by Emscripten.
|
268
|
+
// So user must pass EGL_CONTEXT_CLIENT_VERSION == 2 to initialize EGL.
|
269
|
+
var glesContextVersion = 1;
|
270
|
+
for(;;) {
|
271
|
+
var param = {{{ makeGetValue('contextAttribs', '0', 'i32') }}};
|
272
|
+
if (!param) break;
|
273
|
+
var value = {{{ makeGetValue('contextAttribs', '4', 'i32') }}};
|
274
|
+
if (param == 0x3098 /*EGL_CONTEXT_CLIENT_VERSION*/) {
|
275
|
+
glesContextVersion = value;
|
276
|
+
}
|
277
|
+
contextAttribs += 8;
|
278
|
+
}
|
279
|
+
if (glesContextVersion != 2) {
|
280
|
+
#if GL_ASSERTIONS
|
281
|
+
Module.printErr('When initializing GLES2/WebGL1 via EGL, one must pass EGL_CONTEXT_CLIENT_VERSION = 2 to GL context attributes! GLES version ' + glesContextVersion + ' is not supported!');
|
282
|
+
#endif
|
283
|
+
EGL.setErrorCode(0x3005 /* EGL_BAD_CONFIG */);
|
284
|
+
return 0; /* EGL_NO_CONTEXT */
|
285
|
+
}
|
286
|
+
|
267
287
|
_glutInitDisplayMode(0x92 /* GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE */);
|
268
288
|
EGL.windowID = _glutCreateWindow();
|
269
289
|
if (EGL.windowID != 0) {
|
@@ -1220,6 +1220,7 @@ var LibrarySDL = {
|
|
1220
1220
|
if (surf) SDL.freeSurface(surf);
|
1221
1221
|
},
|
1222
1222
|
|
1223
|
+
SDL_UpperBlit__deps: ['SDL_LockSurface'],
|
1223
1224
|
SDL_UpperBlit: function(src, srcrect, dst, dstrect) {
|
1224
1225
|
var srcData = SDL.surfaces[src];
|
1225
1226
|
var dstData = SDL.surfaces[dst];
|
@@ -642,6 +642,10 @@ Module['stringToUTF32'] = stringToUTF32;
|
|
642
642
|
|
643
643
|
function demangle(func) {
|
644
644
|
try {
|
645
|
+
// Special-case the entry point, since its name differs from other name mangling.
|
646
|
+
if (func == 'Object._main' || func == '_main') {
|
647
|
+
return 'main()';
|
648
|
+
}
|
645
649
|
if (typeof func === 'number') func = Pointer_stringify(func);
|
646
650
|
if (func[0] !== '_') return func;
|
647
651
|
if (func[1] !== '_') return func; // C function
|
@@ -101,9 +101,7 @@ void Branch::Render(Block *Target, bool SetLabel) {
|
|
101
101
|
|
102
102
|
// Block
|
103
103
|
|
104
|
-
|
105
|
-
|
106
|
-
Block::Block(const char *CodeInit, const char *BranchVarInit) : Parent(NULL), Id(Block::IdCounter++), IsCheckedMultipleEntry(false) {
|
104
|
+
Block::Block(const char *CodeInit, const char *BranchVarInit) : Parent(NULL), Id(-1), IsCheckedMultipleEntry(false) {
|
107
105
|
Code = strdup(CodeInit);
|
108
106
|
BranchVar = BranchVarInit ? strdup(BranchVarInit) : NULL;
|
109
107
|
}
|
@@ -142,6 +140,7 @@ void Block::Render(bool InLoop) {
|
|
142
140
|
if (!ProcessedBranchesOut.size()) return;
|
143
141
|
|
144
142
|
bool SetLabel = true; // in some cases it is clear we can avoid setting label, see later
|
143
|
+
bool ForceSetLabel = Shape::IsEmulated(Parent);
|
145
144
|
|
146
145
|
// A setting of the label variable (label = x) is necessary if it can
|
147
146
|
// cause an impact. The main case is where we set label to x, then elsewhere
|
@@ -210,7 +209,7 @@ void Block::Render(bool InLoop) {
|
|
210
209
|
Target = DefaultTarget;
|
211
210
|
Details = ProcessedBranchesOut[DefaultTarget];
|
212
211
|
}
|
213
|
-
bool SetCurrLabel = SetLabel && Target->IsCheckedMultipleEntry;
|
212
|
+
bool SetCurrLabel = (SetLabel && Target->IsCheckedMultipleEntry) || ForceSetLabel;
|
214
213
|
bool HasFusedContent = Fused && contains(Fused->InnerMap, Target);
|
215
214
|
bool HasContent = SetCurrLabel || Details->Type != Branch::Direct || HasFusedContent || Details->Code;
|
216
215
|
if (iter != ProcessedBranchesOut.end()) {
|
@@ -272,10 +271,6 @@ void Block::Render(bool InLoop) {
|
|
272
271
|
}
|
273
272
|
}
|
274
273
|
|
275
|
-
// Shape
|
276
|
-
|
277
|
-
int Shape::IdCounter = 0;
|
278
|
-
|
279
274
|
// MultipleShape
|
280
275
|
|
281
276
|
void MultipleShape::RenderLoopPrefix() {
|
@@ -330,16 +325,19 @@ void LoopShape::Render(bool InLoop) {
|
|
330
325
|
if (Next) Next->Render(InLoop);
|
331
326
|
};
|
332
327
|
|
333
|
-
/*
|
334
328
|
// EmulatedShape
|
335
329
|
|
336
330
|
void EmulatedShape::Render(bool InLoop) {
|
331
|
+
PrintIndented("label = %d;\n", Entry->Id);
|
332
|
+
if (Labeled) {
|
333
|
+
PrintIndented("L%d: ", Id);
|
334
|
+
}
|
337
335
|
PrintIndented("while(1) {\n");
|
338
336
|
Indenter::Indent();
|
339
|
-
PrintIndented("switch(label) {\n");
|
337
|
+
PrintIndented("switch(label|0) {\n");
|
340
338
|
Indenter::Indent();
|
341
|
-
for (
|
342
|
-
Block *Curr =
|
339
|
+
for (BlockSet::iterator iter = Blocks.begin(); iter != Blocks.end(); iter++) {
|
340
|
+
Block *Curr = *iter;
|
343
341
|
PrintIndented("case %d: {\n", Curr->Id);
|
344
342
|
Indenter::Indent();
|
345
343
|
Curr->Render(InLoop);
|
@@ -353,11 +351,10 @@ void EmulatedShape::Render(bool InLoop) {
|
|
353
351
|
PrintIndented("}\n");
|
354
352
|
if (Next) Next->Render(InLoop);
|
355
353
|
};
|
356
|
-
*/
|
357
354
|
|
358
355
|
// Relooper
|
359
356
|
|
360
|
-
Relooper::Relooper() : Root(NULL) {
|
357
|
+
Relooper::Relooper() : Root(NULL), Emulate(false), BlockIdCounter(1), ShapeIdCounter(0) { // block ID 0 is reserved for clearings
|
361
358
|
}
|
362
359
|
|
363
360
|
Relooper::~Relooper() {
|
@@ -366,6 +363,7 @@ Relooper::~Relooper() {
|
|
366
363
|
}
|
367
364
|
|
368
365
|
void Relooper::AddBlock(Block *New) {
|
366
|
+
New->Id = BlockIdCounter++;
|
369
367
|
Blocks.push_back(New);
|
370
368
|
}
|
371
369
|
|
@@ -461,7 +459,7 @@ void Relooper::Calculate(Block *Entry) {
|
|
461
459
|
}
|
462
460
|
}
|
463
461
|
|
464
|
-
Pre.SplitDeadEnds();
|
462
|
+
if (!Emulate) Pre.SplitDeadEnds();
|
465
463
|
|
466
464
|
// Recursively process the graph
|
467
465
|
|
@@ -470,6 +468,7 @@ void Relooper::Calculate(Block *Entry) {
|
|
470
468
|
|
471
469
|
// Add a shape to the list of shapes in this Relooper calculation
|
472
470
|
void Notice(Shape *New) {
|
471
|
+
New->Id = Parent->ShapeIdCounter++;
|
473
472
|
Parent->Shapes.push_back(New);
|
474
473
|
}
|
475
474
|
|
@@ -526,6 +525,21 @@ void Relooper::Calculate(Block *Entry) {
|
|
526
525
|
return Simple;
|
527
526
|
}
|
528
527
|
|
528
|
+
Shape *MakeEmulated(BlockSet &Blocks, Block *Entry, BlockSet &NextEntries) {
|
529
|
+
PrintDebug("creating emulated block with entry #%d and everything it can reach, %d blocks\n", Entry->Id, Blocks.size());
|
530
|
+
EmulatedShape *Emulated = new EmulatedShape;
|
531
|
+
Notice(Emulated);
|
532
|
+
Emulated->Entry = Entry;
|
533
|
+
for (BlockSet::iterator iter = Blocks.begin(); iter != Blocks.end(); iter++) {
|
534
|
+
Block *Curr = *iter;
|
535
|
+
Emulated->Blocks.insert(Curr);
|
536
|
+
Curr->Parent = Emulated;
|
537
|
+
Solipsize(Curr, Branch::Continue, Emulated, Blocks);
|
538
|
+
}
|
539
|
+
Blocks.clear();
|
540
|
+
return Emulated;
|
541
|
+
}
|
542
|
+
|
529
543
|
Shape *MakeLoop(BlockSet &Blocks, BlockSet& Entries, BlockSet &NextEntries) {
|
530
544
|
// Find the inner blocks in this loop. Proceed backwards from the entries until
|
531
545
|
// you reach a seen block, collecting as you go.
|
@@ -837,6 +851,9 @@ void Relooper::Calculate(Block *Entry) {
|
|
837
851
|
if (Entries->size() == 0) return Ret;
|
838
852
|
if (Entries->size() == 1) {
|
839
853
|
Block *Curr = *(Entries->begin());
|
854
|
+
if (Parent->Emulate) {
|
855
|
+
Make(MakeEmulated(Blocks, Curr, *NextEntries));
|
856
|
+
}
|
840
857
|
if (Curr->BranchesIn.size() == 0) {
|
841
858
|
// One entry, no looping ==> Simple
|
842
859
|
Make(MakeSimple(Blocks, Curr, *NextEntries));
|
@@ -844,6 +861,7 @@ void Relooper::Calculate(Block *Entry) {
|
|
844
861
|
// One entry, looping ==> Loop
|
845
862
|
Make(MakeLoop(Blocks, *Entries, *NextEntries));
|
846
863
|
}
|
864
|
+
|
847
865
|
// More than one entry, try to eliminate through a Multiple groups of
|
848
866
|
// independent blocks from an entry/ies. It is important to remove through
|
849
867
|
// multiples as opposed to looping since the former is more performant.
|