aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/analyzer.js33
-rw-r--r--src/library.js44
-rw-r--r--src/library_browser.js4
-rw-r--r--src/library_sdl.js18
-rw-r--r--src/preamble.js43
-rw-r--r--src/runtime.js45
-rw-r--r--src/settings.js2
7 files changed, 124 insertions, 65 deletions
diff --git a/src/analyzer.js b/src/analyzer.js
index 4bf2255e..163ff4a8 100644
--- a/src/analyzer.js
+++ b/src/analyzer.js
@@ -253,6 +253,7 @@ function analyzer(data, sidePass) {
}
// This is an illegal-containing line, and it is unfolded. Legalize it now
dprint('legalizer', 'Legalizing ' + item.intertype + ' at line ' + item.lineNum);
+ var finalizer = null;
switch (item.intertype) {
case 'store': {
var toAdd = [];
@@ -486,12 +487,13 @@ function analyzer(data, sidePass) {
};
break;
}
- case 'or': case 'and': case 'xor': {
+ case 'or': case 'and': case 'xor': case 'icmp': {
var otherElements = getLegalVars(value.params[1].ident, sourceBits);
processor = function(result, j) {
return {
intertype: 'mathop',
op: value.op,
+ variant: value.variant,
type: 'i' + otherElements[j].bits,
params: [
result,
@@ -499,10 +501,35 @@ function analyzer(data, sidePass) {
]
};
};
+ if (value.op == 'icmp') {
+ if (sourceBits == 64) { // handle the i64 case in processMathOp, where we handle full i64 math
+ i++;
+ continue;
+ }
+ finalizer = function() {
+ var ident = '';
+ for (var i = 0; i < targetElements.length; i++) {
+ if (i > 0) {
+ switch(value.variant) {
+ case 'eq': ident += '&&'; break;
+ case 'ne': ident += '||'; break;
+ default: throw 'unhandleable illegal icmp: ' + value.variant;
+ }
+ }
+ ident += targetElements[i].ident;
+ }
+ return {
+ intertype: 'value',
+ ident: ident,
+ type: 'rawJS',
+ assignTo: item.assignTo
+ };
+ }
+ }
break;
}
case 'add': case 'sub': case 'sdiv': case 'udiv': case 'mul': case 'urem': case 'srem':
- case 'icmp':case 'uitofp': case 'sitofp': {
+ case 'uitofp': case 'sitofp': {
// We cannot do these in parallel chunks of 32-bit operations. We will handle these in processMathop
i++;
continue;
@@ -611,6 +638,8 @@ function analyzer(data, sidePass) {
};
legalValue.assignTo = item.assignTo;
toAdd.push(legalValue);
+ } else if (finalizer) {
+ toAdd.push(finalizer());
}
i += removeAndAdd(label.lines, i, toAdd);
continue;
diff --git a/src/library.js b/src/library.js
index bb73c48a..d1ede6bc 100644
--- a/src/library.js
+++ b/src/library.js
@@ -367,12 +367,13 @@ LibraryManager.library = {
return input.cache.shift();
};
}
+ var utf8 = new Runtime.UTF8Processor();
function simpleOutput(val) {
if (val === null || val === '\n'.charCodeAt(0)) {
output.printer(output.buffer.join(''));
output.buffer = [];
} else {
- output.buffer.push(String.fromCharCode(val));
+ output.buffer.push(utf8.processCChar(val));
}
}
if (!output) {
@@ -2281,6 +2282,14 @@ LibraryManager.library = {
var fields = 0;
var argIndex = 0;
var next;
+ // remove initial whitespace
+ while (1) {
+ next = get();
+ if (next == 0) return 0;
+ if (!(next in __scanString.whiteSpace)) break;
+ }
+ unget(next);
+ next = 1;
for (var formatIndex = 0; formatIndex < format.length; formatIndex++) {
if (next <= 0) return fields;
var next = get();
@@ -2319,11 +2328,10 @@ LibraryManager.library = {
}
next = get();
}
+ unget(next);
while (buffer.length > last) {
- buffer.pop();
- unget();
+ unget(buffer.pop().charCodeAt(0));
}
- unget();
next = get();
} else {
var first = true;
@@ -2380,7 +2388,7 @@ LibraryManager.library = {
next = get();
if (next <= 0) return fields; // End of input.
}
- unget();
+ unget(next);
} else {
// Not a specifier.
if (format[formatIndex].charCodeAt(0) !== next) {
@@ -4519,33 +4527,11 @@ LibraryManager.library = {
},
llvm_bswap_i16: function(x) {
- x = unSign(x, 32);
- var bytes = [];
- bytes[0] = x & 255;
- x >>= 8;
- bytes[1] = x & 255;
- x >>= 8;
- var ret = 0;
- ret <<= 8;
- ret += bytes[0];
- ret <<= 8;
- ret += bytes[1];
- return ret;
+ return ((x&0xff)<<8) | ((x>>8)&0xff);
},
llvm_bswap_i32: function(x) {
- x = unSign(x, 32);
- var bytes = [];
- for (var i = 0; i < 4; i++) {
- bytes[i] = x & 255;
- x >>= 8;
- }
- var ret = 0;
- for (i = 0; i < 4; i++) {
- ret <<= 8;
- ret += bytes[i];
- }
- return ret;
+ return ((x&0xff)<<24) | (((x>>8)&0xff)<<16) | (((x>>16)&0xff)<<8) | (x>>>24);
},
llvm_ctlz_i32: function(x) {
diff --git a/src/library_browser.js b/src/library_browser.js
index 4c26037e..ce59dbdd 100644
--- a/src/library_browser.js
+++ b/src/library_browser.js
@@ -223,7 +223,8 @@ mergeInto(LibraryManager.library, {
var wrapper = function() {
if (Browser.mainLoop.queue.length > 0) {
Browser.mainLoop.queue.shift()();
- Browser.mainLoop.scheduler();
+ if (Browser.mainLoop.queue.length == 0 && Module['setStatus']) Module['setStatus']('');
+ setTimeout(wrapper, 0);
return;
}
if (Browser.mainLoop.shouldPause) {
@@ -267,6 +268,7 @@ mergeInto(LibraryManager.library, {
},
emscripten_push_main_loop_blocker: function(func) {
+ if (Module['setStatus']) Module['setStatus']('Please wait..');
Browser.mainLoop.queue.push(FUNCTION_TABLE[func]);
},
diff --git a/src/library_sdl.js b/src/library_sdl.js
index 48e45f27..662620d6 100644
--- a/src/library_sdl.js
+++ b/src/library_sdl.js
@@ -28,6 +28,9 @@ var LibrarySDL = {
mixerNumChannels: 2,
mixerChunkSize: 1024,
+ GL: false, // Set to true if we call SDL_SetVideoMode with SDL_OPENGL, and if so, we do not create 2D canvases&contexts for blitting
+ // Note that images loaded before SDL_SetVideoMode will not get this optimization
+
keyboardState: null,
shiftKey: false,
ctrlKey: false,
@@ -263,6 +266,7 @@ var LibrarySDL = {
// Decide if we want to use WebGL or not
var useWebGL = (flags & 0x04000000) != 0; // SDL_OPENGL
+ SDL.GL = SDL.GL || useWebGL;
var canvas;
if (!usePageCanvas) {
canvas = document.createElement('canvas');
@@ -695,6 +699,8 @@ var LibrarySDL = {
// Copy data from the C++-accessible storage to the canvas backing
SDL_UnlockSurface: function(surf) {
+ assert(!SDL.GL); // in GL mode we do not keep around 2D canvases and contexts
+
var surfData = SDL.surfaces[surf];
surfData.locked--;
@@ -977,9 +983,13 @@ var LibrarySDL = {
}
var raw = Module["preloadedImages"][filename];
if (!raw) {
+ if (raw === null) Module.printErr('Trying to reuse preloaded image, but freePreloadedMediaOnUse is set!');
Runtime.warnOnce('Cannot find preloaded image ' + filename);
return 0;
}
+ if (Module['freePreloadedMediaOnUse']) {
+ Module["preloadedImages"][filename] = null;
+ }
var surf = SDL.makeSurface(raw.width, raw.height, 0, false, 'load:' + filename);
var surfData = SDL.surfaces[surf];
surfData.ctx.drawImage(raw, 0, 0, raw.width, raw.height, 0, 0, raw.width, raw.height);
@@ -989,6 +999,10 @@ var LibrarySDL = {
// are in fact available, so we retrieve it here. This does add overhead though.
_SDL_LockSurface(surf);
surfData.locked--; // The surface is not actually locked in this hack
+ if (SDL.GL) {
+ // After getting the pixel data, we can free the canvas and context if we do not need to do 2D canvas blitting
+ surfData.canvas = surfData.ctx = null;
+ }
return surf;
},
SDL_LoadBMP: 'IMG_Load',
@@ -1110,9 +1124,13 @@ var LibrarySDL = {
filename = FS.standardizePath(Pointer_stringify(filename));
var raw = Module["preloadedAudios"][filename];
if (!raw) {
+ if (raw === null) Module.printErr('Trying to reuse preloaded audio, but freePreloadedMediaOnUse is set!');
Runtime.warnOnce('Cannot find preloaded audio ' + filename);
return 0;
}
+ if (Module['freePreloadedMediaOnUse']) {
+ Module["preloadedAudios"][filename] = null;
+ }
var id = SDL.audios.length;
SDL.audios.push({
source: filename,
diff --git a/src/preamble.js b/src/preamble.js
index ae00b796..5c5e64fc 100644
--- a/src/preamble.js
+++ b/src/preamble.js
@@ -513,17 +513,17 @@ function allocate(slab, types, allocator) {
Module['allocate'] = allocate;
function Pointer_stringify(ptr, /* optional */ length) {
+ var utf8 = new Runtime.UTF8Processor();
var nullTerminated = typeof(length) == "undefined";
var ret = "";
var i = 0;
var t;
- var nullByte = String.fromCharCode(0);
while (1) {
- t = String.fromCharCode({{{ makeGetValue('ptr', 'i', 'i8', 0, 1) }}});
- if (nullTerminated && t == nullByte) { break; } else {}
- ret += t;
+ t = {{{ makeGetValue('ptr', 'i', 'i8', 0, 1) }}};
+ if (nullTerminated && t == 0) break;
+ ret += utf8.processCChar(t);
i += 1;
- if (!nullTerminated && i == length) { break; }
+ if (!nullTerminated && i == length) break;
}
return ret;
}
@@ -734,22 +734,9 @@ Module['String_len'] = String_len;
// This processes a JS string into a C-line array of numbers, 0-terminated.
// For LLVM-originating strings, see parser.js:parseLLVMString function
function intArrayFromString(stringy, dontAddNull, length /* optional */) {
- var ret = [];
- var t;
- var i = 0;
- if (length === undefined) {
- length = stringy.length;
- }
- while (i < length) {
- var chr = stringy.charCodeAt(i);
- if (chr > 0xFF) {
-#if ASSERTIONS
- assert(false, 'Character code ' + chr + ' (' + stringy[i] + ') at offset ' + i + ' not in 0x00-0xFF.');
-#endif
- chr &= 0xFF;
- }
- ret.push(chr);
- i = i + 1;
+ var ret = (new Runtime.UTF8Processor()).processJSString(stringy);
+ if (length) {
+ ret.length = length;
}
if (!dontAddNull) {
ret.push(0);
@@ -776,21 +763,13 @@ Module['intArrayToString'] = intArrayToString;
// Write a Javascript array to somewhere in the heap
function writeStringToMemory(string, buffer, dontAddNull) {
+ var array = intArrayFromString(string, dontAddNull);
var i = 0;
- while (i < string.length) {
- var chr = string.charCodeAt(i);
- if (chr > 0xFF) {
-#if ASSERTIONS
- assert(false, 'Character code ' + chr + ' (' + string[i] + ') at offset ' + i + ' not in 0x00-0xFF.');
-#endif
- chr &= 0xFF;
- }
+ while (i < array.length) {
+ var chr = array[i];
{{{ makeSetValue('buffer', 'i', 'chr', 'i8') }}}
i = i + 1;
}
- if (!dontAddNull) {
- {{{ makeSetValue('buffer', 'i', '0', 'i8') }}}
- }
}
Module['writeStringToMemory'] = writeStringToMemory;
diff --git a/src/runtime.js b/src/runtime.js
index 1f8a618f..6defbb35 100644
--- a/src/runtime.js
+++ b/src/runtime.js
@@ -334,6 +334,51 @@ var Runtime = {
return Runtime.funcWrappers[func];
},
+ // Returns a processor of UTF.
+ // processCChar() receives characters from a C-like UTF representation and returns JS string fragments.
+ // processJSString() receives a JS string and returns a C-like UTF representation in an array
+ UTF8Processor: function() {
+ var buffer = [];
+ var needed = 0;
+ this.processCChar = function (code) {
+ code = code & 0xff;
+ if (needed) {
+ buffer.push(code);
+ needed--;
+ }
+ if (buffer.length == 0) {
+ if (code < 128) return String.fromCharCode(code);
+ buffer.push(code);
+ if (code > 191 && code < 224) {
+ needed = 1;
+ } else {
+ needed = 2;
+ }
+ return '';
+ }
+ if (needed > 0) return '';
+ var c1 = buffer[0];
+ var c2 = buffer[1];
+ var c3 = buffer[2];
+ var ret;
+ if (c1 > 191 && c1 < 224) {
+ ret = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));
+ } else {
+ ret = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
+ }
+ buffer.length = 0;
+ return ret;
+ }
+ this.processJSString = function(string) {
+ string = unescape(encodeURIComponent(string));
+ var ret = [];
+ for (var i = 0; i < string.length; i++) {
+ ret.push(string.charCodeAt(i));
+ }
+ return ret;
+ }
+ },
+
#if RUNTIME_DEBUG
debug: true, // Switch to false at runtime to disable logging at the right times
diff --git a/src/settings.js b/src/settings.js
index 2526081b..16c28529 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -639,7 +639,7 @@ var C_DEFINES = {'SI_MESGQ': '5',
'SING': '2',
'M_INVLN2': '1.44269504089',
'SDL_TIMERS_DISABLED': '1',
- 'M_TWOPI': '3.14159265359',
+ 'M_TWOPI': '6.28318530718',
'_PC_REC_XFER_ALIGN': '19',
'_NL_TIME_DATE_FMT': '84',
'_SC_REALTIME_SIGNALS': '29',