diff options
-rw-r--r-- | AUTHORS | 1 | ||||
-rw-r--r-- | src/jsifier.js | 10 | ||||
-rw-r--r-- | src/library.js | 4 | ||||
-rw-r--r-- | src/library_sdl.js | 17 | ||||
-rw-r--r-- | src/parseTools.js | 3 | ||||
-rw-r--r-- | src/settings.js | 3 | ||||
-rw-r--r-- | tests/glbook/CH08_SimpleVertexShader.png | bin | 0 -> 1600 bytes | |||
-rw-r--r-- | tests/glbook/Chapter_8/Simple_VertexShader/Simple_VertexShader.c | 21 | ||||
-rw-r--r-- | tests/glbook/Common/esShapes.c | 6 | ||||
-rw-r--r-- | tests/glbook/Common/esUtil.h | 2 | ||||
-rw-r--r-- | tests/glbook/Makefile | 2 | ||||
-rwxr-xr-x | tests/runner.py | 45 | ||||
-rw-r--r-- | tools/shared.py | 1 |
13 files changed, 91 insertions, 24 deletions
@@ -17,3 +17,4 @@ under the licensing terms detailed in LICENSE. * Richard Assar <richard.assar@gmail.com> * Nathan Hammond <emscripten@nathanhammond.com> * Behdad Esfahbod <behdad@behdad.org> +* David Benjamin <davidben@mit.edu> diff --git a/src/jsifier.js b/src/jsifier.js index dcc853f2..8e688d8d 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -38,7 +38,6 @@ function JSify(data, functionsOnly, givenFunctions) { var preFile = BUILD_AS_SHARED_LIB ? 'preamble_sharedlib.js' : 'preamble.js'; var pre = processMacros(preprocess(read(preFile).replace('{{RUNTIME}}', getRuntime()))); print(pre); - if (PRECISE_I64_MATH) print(read('long.js')); Functions.implementedFunctions = set(data.unparsedFunctions.map(function(func) { return func.ident })); } @@ -405,7 +404,8 @@ function JSify(data, functionsOnly, givenFunctions) { // name the function; overwrite if it's already named snippet = snippet.replace(/function(?:\s+([^(]+))?\s*\(/, 'function _' + ident + '('); if (LIBRARY_DEBUG) { - snippet = snippet.replace('{', '{ Module.printErr("[library call:' + ident + ': " + Array.prototype.slice.call(arguments) + "]"); '); + snippet = snippet.replace('{', '{ var ret = (function() {Module.printErr("[library call:' + ident + ': " + Array.prototype.slice.call(arguments) + "]"); '); + snippet = snippet.substr(0, snippet.length-1) + '}).apply(this, arguments); Module.printErr(" [ return:" + ret); return ret; }'; } } @@ -1200,6 +1200,12 @@ function JSify(data, functionsOnly, givenFunctions) { // This is the main pass. Print out the generated code that we have here, together with the // rest of the output that we started to print out earlier (see comment on the // "Final shape that will be created"). + if (PRECISE_I64_MATH && preciseI64MathUsed) { + print(read('long.js')); + } else { + print('// Warning: printing of i64 values may be slightly rounded! No deep i64 math used, so precise i64 code not included'); + print('var i64Math = null;'); + } var generated = itemsDict.functionStub.concat(itemsDict.GlobalVariablePostSet); generated.forEach(function(item) { print(indentify(item.JS || '', 2)); }); if (RUNTIME_TYPE_INFO) { diff --git a/src/library.js b/src/library.js index f49a8a58..be5e48d7 100644 --- a/src/library.js +++ b/src/library.js @@ -2507,12 +2507,12 @@ LibraryManager.library = { var prefix = ''; if (next == 'd'.charCodeAt(0) || next == 'i'.charCodeAt(0)) { #if PRECISE_I64_MATH == 1 - if (argSize == 8) argText = i64Math.stringify(origArg[0], origArg[1]); else + if (argSize == 8 && i64Math) argText = i64Math.stringify(origArg[0], origArg[1]); else #endif argText = reSign(currArg, 8 * argSize, 1).toString(10); } else if (next == 'u'.charCodeAt(0)) { #if PRECISE_I64_MATH == 1 - if (argSize == 8) argText = i64Math.stringify(origArg[0], origArg[1], true); else + if (argSize == 8 && i64Math) argText = i64Math.stringify(origArg[0], origArg[1], true); else #endif argText = unSign(currArg, 8 * argSize, 1).toString(10); currArg = Math.abs(currArg); diff --git a/src/library_sdl.js b/src/library_sdl.js index 631de481..a6c5c559 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -84,6 +84,8 @@ mergeInto(LibraryManager.library, { copyOnLock: true }, + version: null, + surfaces: {}, events: [], audios: [null], @@ -162,6 +164,11 @@ mergeInto(LibraryManager.library, { ['i32', 'size'], ['void*', 'callback'], ['void*', 'userdata'] + ]), + version: Runtime.generateStructInfo([ + ['i8', 'major'], + ['i8', 'minor'], + ['i8', 'patch'] ]) }, @@ -369,6 +376,16 @@ mergeInto(LibraryManager.library, { } }, + SDL_Linked_Version: function() { + if (SDL.version === null) { + SDL.version = _malloc(SDL.structs.version.__size__); + {{{ makeSetValue('SDL.version + SDL.structs.version.major', '0', '1', 'i8') }}} + {{{ makeSetValue('SDL.version + SDL.structs.version.minor', '0', '3', 'i8') }}} + {{{ makeSetValue('SDL.version + SDL.structs.version.patch', '0', '0', 'i8') }}} + } + return SDL.version; + }, + SDL_Init__deps: ['$SDL'], SDL_Init: function(what) { SDL.startTime = Date.now(); diff --git a/src/parseTools.js b/src/parseTools.js index 5ec3b4ed..22f38207 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -1560,6 +1560,8 @@ function isSignedOp(op, variant) { } var legalizedI64s = USE_TYPED_ARRAYS == 2; // We do not legalize globals, but do legalize function lines. This will be true in the latter case +var preciseI64MathUsed = false; // Set to true if we actually use precise i64 math: If PRECISE_I64_MATH is set, and also such math is actually + // needed (+,-,*,/,% - we do not need it for bitops) function processMathop(item) { var op = item.op; @@ -1617,6 +1619,7 @@ function processMathop(item) { } } function i64PreciseOp(type, lastArg) { + preciseI64MathUsed = true; return finish(['(i64Math.' + type + '(' + low1 + ',' + high1 + ',' + low2 + ',' + high2 + (lastArg ? ',' + lastArg : '') + '),i64Math.result[0])', 'i64Math.result[1]']); } diff --git a/src/settings.js b/src/settings.js index ede00dd5..15c92176 100644 --- a/src/settings.js +++ b/src/settings.js @@ -67,9 +67,8 @@ var DOUBLE_MODE = 1; // How to load and store 64-bit doubles. Without typed arra // then load it aligned, and that load-store will make JS engines alter it if it is being // stored to a typed array for security reasons. That will 'fix' the number from being a // NaN or an infinite number. -var PRECISE_I64_MATH = 0; // If enabled, i64 addition etc. is emulated - which is slow but precise. If disabled, +var PRECISE_I64_MATH = 1; // If enabled, i64 addition etc. is emulated - which is slow but precise. If disabled, // we use the 'double trick' which is fast but incurs rounding at high values. - // Note that precise math currently only handles *signed* values, not unsigned var CLOSURE_ANNOTATIONS = 0; // If set, the generated code will be annotated for the closure // compiler. This potentially lets closure optimize the code better. diff --git a/tests/glbook/CH08_SimpleVertexShader.png b/tests/glbook/CH08_SimpleVertexShader.png Binary files differnew file mode 100644 index 00000000..84b276fd --- /dev/null +++ b/tests/glbook/CH08_SimpleVertexShader.png diff --git a/tests/glbook/Chapter_8/Simple_VertexShader/Simple_VertexShader.c b/tests/glbook/Chapter_8/Simple_VertexShader/Simple_VertexShader.c index 6036bf0c..44380c18 100644 --- a/tests/glbook/Chapter_8/Simple_VertexShader/Simple_VertexShader.c +++ b/tests/glbook/Chapter_8/Simple_VertexShader/Simple_VertexShader.c @@ -29,7 +29,7 @@ typedef struct // Vertex daata GLfloat *vertices; - GLuint *indices; + GLushort *indices; int numIndices; // Rotation angle @@ -37,6 +37,8 @@ typedef struct // MVP matrix ESMatrix mvpMatrix; + + GLuint vertPosObject, indicesObject; } UserData; /// @@ -78,6 +80,14 @@ int Init ( ESContext *esContext ) // Starting rotation angle for the cube userData->angle = 45.0f; + glGenBuffers(1, &userData->vertPosObject); + glBindBuffer(GL_ARRAY_BUFFER, userData->vertPosObject); + glBufferData(GL_ARRAY_BUFFER, 24 * sizeof(GLfloat) * 3, userData->vertices, GL_STATIC_DRAW); + + glGenBuffers(1, &userData->indicesObject); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, userData->indicesObject); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, userData->numIndices * sizeof(GLushort), userData->indices, GL_STATIC_DRAW); + glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f ); return GL_TRUE; } @@ -137,17 +147,20 @@ void Draw ( ESContext *esContext ) glUseProgram ( userData->programObject ); // Load the vertex position + glBindBuffer(GL_ARRAY_BUFFER, userData->vertPosObject); glVertexAttribPointer ( userData->positionLoc, 3, GL_FLOAT, - GL_FALSE, 3 * sizeof(GLfloat), userData->vertices ); - + GL_FALSE, 0, 0 ); glEnableVertexAttribArray ( userData->positionLoc ); + // Load the index buffer + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, userData->indicesObject); + // Load the MVP matrix glUniformMatrix4fv( userData->mvpLoc, 1, GL_FALSE, (GLfloat*) &userData->mvpMatrix.m[0][0] ); // Draw the cube - glDrawElements ( GL_TRIANGLES, userData->numIndices, GL_UNSIGNED_INT, userData->indices ); + glDrawElements ( GL_TRIANGLES, userData->numIndices, GL_UNSIGNED_SHORT, 0 ); } /// diff --git a/tests/glbook/Common/esShapes.c b/tests/glbook/Common/esShapes.c index 0fa65057..aecd37ce 100644 --- a/tests/glbook/Common/esShapes.c +++ b/tests/glbook/Common/esShapes.c @@ -139,7 +139,7 @@ int ESUTIL_API esGenSphere ( int numSlices, float radius, GLfloat **vertices, GL /// if it is not NULL ) as a GL_TRIANGLE_STRIP // int ESUTIL_API esGenCube ( float scale, GLfloat **vertices, GLfloat **normals, - GLfloat **texCoords, GLuint **indices ) + GLfloat **texCoords, GLushort **indices ) { int i; int numVertices = 24; @@ -256,7 +256,7 @@ int ESUTIL_API esGenCube ( float scale, GLfloat **vertices, GLfloat **normals, // Generate the indices if ( indices != NULL ) { - GLuint cubeIndices[] = + GLushort cubeIndices[] = { 0, 2, 1, 0, 3, 2, @@ -272,7 +272,7 @@ int ESUTIL_API esGenCube ( float scale, GLfloat **vertices, GLfloat **normals, 20, 22, 21 }; - *indices = malloc ( sizeof(GLuint) * numIndices ); + *indices = malloc ( sizeof(GLushort) * numIndices ); memcpy( *indices, cubeIndices, sizeof( cubeIndices ) ); } diff --git a/tests/glbook/Common/esUtil.h b/tests/glbook/Common/esUtil.h index b675e367..1ff236de 100644 --- a/tests/glbook/Common/esUtil.h +++ b/tests/glbook/Common/esUtil.h @@ -199,7 +199,7 @@ int ESUTIL_API esGenSphere ( int numSlices, float radius, GLfloat **vertices, GL /// if it is not NULL ) as a GL_TRIANGLES
//
int ESUTIL_API esGenCube ( float scale, GLfloat **vertices, GLfloat **normals,
- GLfloat **texCoords, GLuint **indices );
+ GLfloat **texCoords, GLushort **indices );
//
/// \brief Loads a 24-bit TGA image from a file
diff --git a/tests/glbook/Makefile b/tests/glbook/Makefile index 299b594f..386d5717 100644 --- a/tests/glbook/Makefile +++ b/tests/glbook/Makefile @@ -23,7 +23,7 @@ CH13SRC2=./Chapter_13/ParticleSystem/ParticleSystem.c default: all all: ./Chapter_2/Hello_Triangle/CH02_HelloTriangle.bc \ -# ./Chapter_8/Simple_VertexShader/CH08_SimpleVertexShader.bc \ + ./Chapter_8/Simple_VertexShader/CH08_SimpleVertexShader.bc \ # ./Chapter_9/Simple_Texture2D/CH09_SimpleTexture2D.bc \ # ./Chapter_9/MipMap2D/CH09_MipMap2D.bc \ # ./Chapter_9/Simple_TextureCubemap/CH09_TextureCubemap.bc \ diff --git a/tests/runner.py b/tests/runner.py index 62d09ee9..431a1c6e 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -598,13 +598,13 @@ if 'benchmark' not in str(sys.argv) and 'sanity' not in str(sys.argv) and 'brows return 0; } ''' - self.do_run(src, '*1311918518731868200\n' + + self.do_run(src, '*1311918518731868041\n' + '0,0,0,1,1\n' + '1,0,1,0,1*\n' + '*245127260211081*\n' + '*245127260209443*\n' + - '*18446744073709552000*\n' + - '*576460752303423500*\n' + + '*18446744073709551615*\n' + + '*576460752303423487*\n' + 'm1: 127\n' + '*123*\n' + '*127*\n' + @@ -832,7 +832,6 @@ m_divisor is 1091269979 def test_i64_precise(self): if Settings.USE_TYPED_ARRAYS != 2: return self.skip('full i64 stuff only in ta2') - Settings.PRECISE_I64_MATH = 1 src = r''' #include <inttypes.h> @@ -860,14 +859,39 @@ m_divisor is 1091269979 ''' self.do_run(src, open(path_from_root('tests', 'i64_precise.txt')).read()) - print 'TODO: make precise the default, and imprecise in -O3. Remove precise setting in this test and cube2hash' - print 'TODO: only include this code when needed' - #1/0. + # Verify that without precision, we do not include the precision code + Settings.PRECISE_I64_MATH = 0 + self.do_run(src, 'unsigned') + code = open(os.path.join(self.get_dir(), 'src.cpp.o.js')).read() + assert 'goog.math.Long' not in code and 'jsbn' not in code, 'i64 precise math should not have been included if not asked for' + + # Verify that even if we ask for precision, if it is not needed it is not included + Settings.PRECISE_I64_MATH = 1 + src = ''' + #include <inttypes.h> + #include <stdio.h> + + int main(int argc, char **argv) { + uint64_t x = 2125299906845564, y = 1225891506842664; + if (argc == 12) { + x = x >> 1; + y = y >> 1; + } + x = x & 12ULL; + y = y | 12ULL; + x = x ^ y; + x <<= 2; + y >>= 3; + printf("*%llu, %llu*\\n", x, y); + } + ''' + self.do_run(src, '*4903566027370624, 153236438355333*') + code = open(os.path.join(self.get_dir(), 'src.cpp.o.js')).read() + assert 'goog.math.Long' not in code and 'jsbn' not in code, 'i64 precise math should not have been included if not actually used' def test_cube2hash(self): # A good test of i64 math if Settings.USE_TYPED_ARRAYS != 2: return self.skip('requires ta2 C-style memory aliasing') - Settings.PRECISE_I64_MATH = 1 self.do_run('', 'Usage: hashstring <seed>', libraries=self.get_library('cube2hash', ['cube2hash.bc'], configure=None), includes=[path_from_root('tests', 'cube2hash')]) @@ -6854,7 +6878,10 @@ elif 'browser' in str(sys.argv): self.run_browser('something.html', 'You should not see animating gears.', '/report_gl_result?false') def test_glbook(self): - programs = self.get_library('glbook', [os.path.join('Chapter_2/Hello_Triangle/CH02_HelloTriangle.bc')], configure=None) + programs = self.get_library('glbook', [ + os.path.join('Chapter_2/Hello_Triangle/CH02_HelloTriangle.bc'), + os.path.join('Chapter_8/Simple_VertexShader/CH08_SimpleVertexShader.bc') + ], configure=None) for program in programs: print program self.reftest(path_from_root('tests', 'glbook', os.path.basename(program).replace('.bc', '.png'))) diff --git a/tools/shared.py b/tools/shared.py index 4e5f3d6a..17887afe 100644 --- a/tools/shared.py +++ b/tools/shared.py @@ -344,6 +344,7 @@ class Settings: Settings.CORRECT_OVERFLOWS = 0 Settings.CORRECT_ROUNDINGS = 0 Settings.DOUBLE_MODE = 0 + Settings.PRECISE_I64_MATH = 0 if noisy: print >> sys.stderr, 'Warning: Applying some potentially unsafe optimizations! (Use -O2 if this fails.)' global Settings |