aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/jsifier.js5
-rw-r--r--src/library.js6
-rw-r--r--src/library_gl.js107
-rw-r--r--src/library_sdl.js27
-rw-r--r--src/preamble.js19
-rw-r--r--src/settings.js21
6 files changed, 139 insertions, 46 deletions
diff --git a/src/jsifier.js b/src/jsifier.js
index 4263618a..bc89b0c4 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -513,7 +513,9 @@ function JSify(data, functionsOnly, givenFunctions) {
item.JS = addFromLibrary(shortident);
} else if (!LibraryManager.library.hasOwnProperty(shortident + '__inline')) {
item.JS = 'var ' + item.ident + '; // stub for ' + item.ident;
- if (WARN_ON_UNDEFINED_SYMBOLS || ASM_JS) { // always warn on undefs in asm, since it breaks validation
+ if (ASM_JS) {
+ throw 'Unresolved symbol: ' + item.ident + ', this must be corrected for asm.js validation to succeed. Consider adding it to DEAD_FUNCTIONS.';
+ } else if (WARN_ON_UNDEFINED_SYMBOLS) {
warn('Unresolved symbol: ' + item.ident);
}
}
@@ -722,6 +724,7 @@ function JSify(data, functionsOnly, givenFunctions) {
ret += indent + 'label = ' + getLabelId(block.entries[0]) + '; ' + (SHOW_LABELS ? '/* ' + getOriginalLabelId(block.entries[0]) + ' */' : '') + '\n';
} // otherwise, should have been set before!
if (func.setjmpTable) {
+ assert(!ASM_JS, 'asm.js mode does not support setjmp yet');
var setjmpTable = {};
ret += indent + 'var mySetjmpIds = {};\n';
ret += indent + 'var setjmpTable = {';
diff --git a/src/library.js b/src/library.js
index 45187d8d..51921541 100644
--- a/src/library.js
+++ b/src/library.js
@@ -2638,7 +2638,7 @@ LibraryManager.library = {
}
return fields;
},
- // Performs prtinf-style formatting.
+ // Performs printf-style formatting.
// format: A pointer to the format string.
// varargs: A pointer to the start of the arguments list.
// Returns the resulting string string as a character array.
@@ -2821,7 +2821,9 @@ LibraryManager.library = {
} else if (next == {{{ charCode('x') }}} || next == {{{ charCode('X') }}}) {
prefix = flagAlternative ? '0x' : '';
#if PRECISE_I64_MATH
- if (argSize == 8 && i64Math) argText = (origArg[1]>>>0).toString(16) + (origArg[0]>>>0).toString(16); else
+ if (argSize == 8 && i64Math) {
+ argText = (origArg[1] ? (origArg[1]>>>0).toString(16) : '') + (origArg[0]>>>0).toString(16);
+ } else
#endif
if (currArg < 0) {
// Represent negative numbers in hex as 2's complement.
diff --git a/src/library_gl.js b/src/library_gl.js
index 9e12e4ee..031f4560 100644
--- a/src/library_gl.js
+++ b/src/library_gl.js
@@ -58,7 +58,12 @@ var LibraryGL = {
return ret;
},
- // Temporary buffers
+ // Mini temp buffer
+ MINI_TEMP_BUFFER_SIZE: 16,
+ miniTempBuffer: null,
+ miniTempBufferViews: [0], // index i has the view of size i+1
+
+ // Large temporary buffers
MAX_TEMP_BUFFER_SIZE: {{{ GL_MAX_TEMP_BUFFER_SIZE }}},
tempBufferIndexLookup: null,
tempVertexBuffers: null,
@@ -311,6 +316,11 @@ var LibraryGL = {
if (!Module.useWebGL) return; // an app might link both gl and 2d backends
+ GL.miniTempBuffer = new Float32Array(GL.MINI_TEMP_BUFFER_SIZE);
+ for (var i = 0; i < GL.MINI_TEMP_BUFFER_SIZE; i++) {
+ GL.miniTempBufferViews[i] = GL.miniTempBuffer.subarray(0, i+1);
+ }
+
GL.maxVertexAttribs = Module.ctx.getParameter(Module.ctx.MAX_VERTEX_ATTRIBS);
#if FULL_ES2
for (var i = 0; i < GL.maxVertexAttribs; i++) {
@@ -832,53 +842,108 @@ var LibraryGL = {
glUniform1fv__sig: 'viii',
glUniform1fv: function(location, count, value) {
location = GL.uniforms[location];
- value = {{{ makeHEAPView('F32', 'value', 'value+count*4') }}};
- Module.ctx.uniform1fv(location, value);
+ var view;
+ if (count == 1) {
+ // avoid allocation for the common case of uploading one uniform
+ view = GL.miniTempBufferViews[0];
+ view[0] = {{{ makeGetValue('value', '0', 'float') }}};
+ } else {
+ view = {{{ makeHEAPView('F32', 'value', 'value+count*4') }}};
+ }
+ Module.ctx.uniform1fv(location, view);
},
glUniform2fv__sig: 'viii',
glUniform2fv: function(location, count, value) {
location = GL.uniforms[location];
- count *= 2;
- value = {{{ makeHEAPView('F32', 'value', 'value+count*4') }}};
- Module.ctx.uniform2fv(location, value);
+ var view;
+ if (count == 1) {
+ // avoid allocation for the common case of uploading one uniform
+ view = GL.miniTempBufferViews[1];
+ view[0] = {{{ makeGetValue('value', '0', 'float') }}};
+ view[1] = {{{ makeGetValue('value', '4', 'float') }}};
+ } else {
+ view = {{{ makeHEAPView('F32', 'value', 'value+count*8') }}};
+ }
+ Module.ctx.uniform2fv(location, view);
},
glUniform3fv__sig: 'viii',
glUniform3fv: function(location, count, value) {
location = GL.uniforms[location];
- count *= 3;
- value = {{{ makeHEAPView('F32', 'value', 'value+count*4') }}};
- Module.ctx.uniform3fv(location, value);
+ var view;
+ if (count == 1) {
+ // avoid allocation for the common case of uploading one uniform
+ view = GL.miniTempBufferViews[2];
+ view[0] = {{{ makeGetValue('value', '0', 'float') }}};
+ view[1] = {{{ makeGetValue('value', '4', 'float') }}};
+ view[2] = {{{ makeGetValue('value', '8', 'float') }}};
+ } else {
+ view = {{{ makeHEAPView('F32', 'value', 'value+count*12') }}};
+ }
+ Module.ctx.uniform3fv(location, view);
},
glUniform4fv__sig: 'viii',
glUniform4fv: function(location, count, value) {
location = GL.uniforms[location];
- count *= 4;
- value = {{{ makeHEAPView('F32', 'value', 'value+count*4') }}};
- Module.ctx.uniform4fv(location, value);
+ var view;
+ if (count == 1) {
+ // avoid allocation for the common case of uploading one uniform
+ view = GL.miniTempBufferViews[3];
+ view[0] = {{{ makeGetValue('value', '0', 'float') }}};
+ view[1] = {{{ makeGetValue('value', '4', 'float') }}};
+ view[2] = {{{ makeGetValue('value', '8', 'float') }}};
+ view[3] = {{{ makeGetValue('value', '12', 'float') }}};
+ } else {
+ view = {{{ makeHEAPView('F32', 'value', 'value+count*16') }}};
+ }
+ Module.ctx.uniform4fv(location, view);
},
glUniformMatrix2fv: function(location, count, transpose, value) {
location = GL.uniforms[location];
- count *= 4;
- value = {{{ makeHEAPView('F32', 'value', 'value+count*4') }}};
- Module.ctx.uniformMatrix2fv(location, transpose, value);
+ var view;
+ if (count == 1) {
+ // avoid allocation for the common case of uploading one uniform matrix
+ view = GL.miniTempBufferViews[3];
+ for (var i = 0; i < 4; i++) {
+ view[i] = {{{ makeGetValue('value', 'i*4', 'float') }}};
+ }
+ } else {
+ view = {{{ makeHEAPView('F32', 'value', 'value+count*16') }}};
+ }
+ Module.ctx.uniformMatrix2fv(location, transpose, view);
},
glUniformMatrix3fv: function(location, count, transpose, value) {
location = GL.uniforms[location];
- count *= 9;
- value = {{{ makeHEAPView('F32', 'value', 'value+count*4') }}};
- Module.ctx.uniformMatrix3fv(location, transpose, value);
+ var view;
+ if (count == 1) {
+ // avoid allocation for the common case of uploading one uniform matrix
+ view = GL.miniTempBufferViews[8];
+ for (var i = 0; i < 9; i++) {
+ view[i] = {{{ makeGetValue('value', 'i*4', 'float') }}};
+ }
+ } else {
+ view = {{{ makeHEAPView('F32', 'value', 'value+count*36') }}};
+ }
+ Module.ctx.uniformMatrix3fv(location, transpose, view);
},
glUniformMatrix4fv: function(location, count, transpose, value) {
location = GL.uniforms[location];
- count *= 16;
- value = {{{ makeHEAPView('F32', 'value', 'value+count*4') }}};
- Module.ctx.uniformMatrix4fv(location, transpose, value);
+ var view;
+ if (count == 1) {
+ // avoid allocation for the common case of uploading one uniform matrix
+ view = GL.miniTempBufferViews[15];
+ for (var i = 0; i < 16; i++) {
+ view[i] = {{{ makeGetValue('value', 'i*4', 'float') }}};
+ }
+ } else {
+ view = {{{ makeHEAPView('F32', 'value', 'value+count*64') }}};
+ }
+ Module.ctx.uniformMatrix4fv(location, transpose, view);
},
glBindBuffer__sig: 'vii',
diff --git a/src/library_sdl.js b/src/library_sdl.js
index 9fc979d2..77305609 100644
--- a/src/library_sdl.js
+++ b/src/library_sdl.js
@@ -443,6 +443,23 @@ var LibrarySDL = {
return false;
},
+ offsetsTemp: { left: 0, top: 0 }, // temporary object to avoid generating garbage in offsets(). assumes the object is not captured
+
+ offsets: function(element) {
+ var left = 0;
+ var top = 0;
+
+ do {
+ left += element.offsetLeft;
+ top += element.offsetTop;
+ } while (element = element.offsetParent)
+
+ var ret = SDL.offsetsTemp;
+ ret.left = left;
+ ret.top = top;
+ return ret;
+ },
+
makeCEvent: function(event, ptr) {
if (typeof event === 'number') {
// This is a pointer to a native C event that was SDL_PushEvent'ed
@@ -524,8 +541,9 @@ var LibrarySDL = {
} else {
// Otherwise, calculate the movement based on the changes
// in the coordinates.
- var x = event.pageX - Module["canvas"].offsetLeft;
- var y = event.pageY - Module["canvas"].offsetTop;
+ var offsets = SDL.offsets(Module["canvas"]);
+ var x = event.pageX - offsets.left;
+ var y = event.pageY - offsets.top;
var movementX = x - SDL.mouseX;
var movementY = y - SDL.mouseY;
}
@@ -912,10 +930,11 @@ var LibrarySDL = {
SDL_WarpMouse: function(x, y) {
return; // TODO: implement this in a non-buggy way. Need to keep relative mouse movements correct after calling this
+ var offsets = SDL.offsets(Module["canvas"]);
SDL.events.push({
type: 'mousemove',
- pageX: x + Module['canvas'].offsetLeft,
- pageY: y + Module['canvas'].offsetTop
+ pageX: x + offsets.left,
+ pageY: y + offsets.top
});
},
diff --git a/src/preamble.js b/src/preamble.js
index 7538b19c..a1755798 100644
--- a/src/preamble.js
+++ b/src/preamble.js
@@ -503,6 +503,7 @@ function allocate(slab, types, allocator, ptr) {
Module['allocate'] = allocate;
function Pointer_stringify(ptr, /* optional */ length) {
+#if UTF_STRING_SUPPORT
var utf8 = new Runtime.UTF8Processor();
var nullTerminated = typeof(length) == "undefined";
var ret = "";
@@ -519,18 +520,16 @@ function Pointer_stringify(ptr, /* optional */ length) {
if (!nullTerminated && i == length) break;
}
return ret;
+#else
+#if USE_TYPED_ARRAYS == 2
+ return String.fromCharCode.apply(String, HEAPU8.subarray(ptr, ptr + (length || _strlen(ptr))));
+#else
+ throw 'unsupported combination';
+#endif
+#endif
}
Module['Pointer_stringify'] = Pointer_stringify;
-function Array_stringify(array) {
- var ret = "";
- for (var i = 0; i < array.length; i++) {
- ret += String.fromCharCode(array[i]);
- }
- return ret;
-}
-Module['Array_stringify'] = Array_stringify;
-
// Memory management
var PAGE_SIZE = 4096;
@@ -557,7 +556,7 @@ function enlargeMemory() {
#if ASM_JS == 0
abort('Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value, (2) compile with ALLOW_MEMORY_GROWTH which adjusts the size at runtime but prevents some optimizations, or (3) set Module.TOTAL_MEMORY before the program runs.');
#else
- abort('Cannot enlarge memory arrays in asm.js. Compile with -s TOTAL_MEMORY=X with X higher than the current value.');
+ abort('Cannot enlarge memory arrays in asm.js. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value, or (2) set Module.TOTAL_MEMORY before the program runs.');
#endif
#else
// TOTAL_MEMORY is the current size of the actual array, and STATICTOP is the new top.
diff --git a/src/settings.js b/src/settings.js
index 101c403c..37c594ac 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -171,6 +171,8 @@ var GL_UNSAFE_OPTS = 1; // Enables some potentially-unsafe optimizations in GL e
var FULL_ES2 = 0; // Forces support for all GLES2 features, not just the WebGL-friendly subset.
var FORCE_GL_EMULATION = 0; // Forces inclusion of full GL emulation code.
+var UTF_STRING_SUPPORT = 1; // Perform utf-8 conversion between C and JS strings (adds overhead in such conversions)
+
var DISABLE_EXCEPTION_CATCHING = 0; // Disables generating code to actually catch exceptions. If the code you
// are compiling does not actually rely on catching exceptions (but the
// compiler generates code for it, maybe because of stdlibc++ stuff),
@@ -224,19 +226,22 @@ var NAMED_GLOBALS = 0; // If 1, we use global variables for globals. Otherwise
// they are referred to by a base plus an offset (called an indexed global),
// saving global variables but adding runtime overhead.
-var EXPORT_ALL = 0; // If true, we export all the symbols
var EXPORTED_FUNCTIONS = ['_main']; // Functions that are explicitly exported. These functions are kept alive
// through LLVM dead code elimination, and also made accessible outside of
// the generated code even after running closure compiler (on "Module").
// Note the necessary prefix of "_".
+var EXPORT_ALL = 0; // If true, we export all the symbols
+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 DEFAULT_LIBRARY_FUNCS_TO_INCLUDE = ['memcpy', 'memset', 'malloc', 'free', '$Browser']; // JS library functions (C functions implemented in JS)
- // that we include by default. If you want to make sure
- // something is included by the JS compiler, add it here.
- // For example, if you do not use some emscripten_*
- // C API call from C, but you want to call it from JS,
- // add it here (and in EXPORTED FUNCTIONS with prefix
- // "_", for closure).
+// JS library functions (C functions implemented in JS)
+// that we include by default. If you want to make sure
+// something is included by the JS compiler, add it here.
+// For example, if you do not use some emscripten_*
+// C API call from C, but you want to call it from JS,
+// add it here (and in EXPORTED FUNCTIONS with prefix
+// "_", for closure).
+var DEFAULT_LIBRARY_FUNCS_TO_INCLUDE = ['memcpy', 'memset', 'malloc', 'free', 'strlen', '$Browser'];
var LIBRARY_DEPS_TO_AUTOEXPORT = ['memcpy']; // This list is also used to determine
// auto-exporting of library dependencies (i.e., functions that