diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/analyzer.js | 4 | ||||
-rw-r--r-- | src/library_browser.js | 10 | ||||
-rw-r--r-- | src/library_sdl.js | 1 | ||||
-rw-r--r-- | src/parseTools.js | 51 |
4 files changed, 45 insertions, 21 deletions
diff --git a/src/analyzer.js b/src/analyzer.js index 8ded86f1..1453b22c 100644 --- a/src/analyzer.js +++ b/src/analyzer.js @@ -544,6 +544,10 @@ function analyzer(data, sidePass) { params: [(signed && j + whole > sourceElements.length) ? signedKeepAlive : null], type: 'i32', }; + if (j == 0 && isUnsignedOp(value.op) && sourceBits < 32) { + // zext sign correction + result.ident = makeSignOp(result.ident, 'i' + sourceBits, 'un', 1, 1); + } if (fraction != 0) { var other = { intertype: 'value', diff --git a/src/library_browser.js b/src/library_browser.js index 66aeeaf8..a37ef612 100644 --- a/src/library_browser.js +++ b/src/library_browser.js @@ -3,6 +3,16 @@ // Utilities for browser environments mergeInto(LibraryManager.library, { + emscripten_async_run_script__deps: ['emscripten_run_script'], + emscripten_async_run_script: function(script, millis) { + Module['noExitRuntime'] = true; + + // TODO: cache these to avoid generating garbage + setTimeout(function() { + _emscripten_run_script(script); + }, millis); + }, + emscripten_set_main_loop: function(func, fps) { Module['noExitRuntime'] = true; diff --git a/src/library_sdl.js b/src/library_sdl.js index e76a2a28..809ff658 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -611,6 +611,7 @@ 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 SDL.events.push({ type: 'mousemove', pageX: x + Module['canvas'].offsetLeft, diff --git a/src/parseTools.js b/src/parseTools.js index 92fb038a..21852c5d 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -1314,27 +1314,36 @@ function finalizeLLVMFunctionCall(item, noIndexizeFunctions) { // Warn about some types of casts, then fall through to the handling code below var oldType = item.params[0].type; var newType = item.type; - if (isPossiblyFunctionType(oldType) && isPossiblyFunctionType(newType) && - countNormalArgs(oldType) != countNormalArgs(newType)) { - warnOnce('Casting a function pointer type to another with a different number of arguments. See more info in the source'); - // This may be dangerous as clang generates different code for C and C++ calling conventions. The only problem - // case appears to be passing a structure by value, C will have (field1, field2) as function args, and the - // function will internally create a structure with that data, while C++ will have (struct* byVal) and it - // will create a copy before calling the function, then call it with a pointer to the copy. Mixing the two - // first of all leads to two copies being made, so this is a bad idea even regardless of Emscripten. But, - // what is a problem for Emscr ipten is that mixing these two calling conventions (say, calling a C one from - // C++) will then assume that (struct* byVal) is actually the same as (field1, field2). In native code, this - // is easily possible, you place the two fields on the stack and call the function (you know to place the - // values since there is 'byVal'). In Emscripten, though, this means we would need to always do one or the - // other of the two possibilities, for example, always passing by-value structs as (field1, field2). This - // would slow down everything, just to handle this corner case. (Which, just to point out how much of a - // corner case it is, does not appear to happen with nested structures!) - // - // The recommended solution for this problem is not to mix C and C++ calling conventions when passing structs - // by value. Either always pass structs by value within C code or C++ code, but not mixing the two by - // defining a function in one and calling it from the other (so, just changing .c to .cpp, or moving code - // from one file to another, would be enough to fix this), or, do not pass structs by value (which in general - // is inefficient, and worth avoiding if you can). + if (isPossiblyFunctionType(oldType) && isPossiblyFunctionType(newType)) { + var oldCount = countNormalArgs(oldType); + var newCount = countNormalArgs(newType); + if (oldCount != newCount && oldCount && newCount) { + if (!ASSERTIONS) { + warnOnce('Casting a function pointer type to another with a different number of arguments. See more info in the compiler source'); + } else { + warn('Casting a function pointer type to another with a different number of arguments: ' + oldType + ' vs. ' + newType + ', on ' + item.params[0].ident); + } + // This may be dangerous as clang generates different code for C and C++ calling conventions. The only problem + // case appears to be passing a structure by value, C will have (field1, field2) as function args, and the + // function will internally create a structure with that data, while C++ will have (struct* byVal) and it + // will create a copy before calling the function, then call it with a pointer to the copy. Mixing the two + // first of all leads to two copies being made, so this is a bad idea even regardless of Emscripten. But, + // what is a problem for Emscr ipten is that mixing these two calling conventions (say, calling a C one from + // C++) will then assume that (struct* byVal) is actually the same as (field1, field2). In native code, this + // is easily possible, you place the two fields on the stack and call the function (you know to place the + // values since there is 'byVal'). In Emscripten, though, this means we would need to always do one or the + // other of the two possibilities, for example, always passing by-value structs as (field1, field2). This + // would slow down everything, just to handle this corner case. (Which, just to point out how much of a + // corner case it is, does not appear to happen with nested structures!) + // + // The recommended solution for this problem is not to mix C and C++ calling conventions when passing structs + // by value. Either always pass structs by value within C code or C++ code, but not mixing the two by + // defining a function in one and calling it from the other (so, just changing .c to .cpp, or moving code + // from one file to another, would be enough to fix this), or, do not pass structs by value (which in general + // is inefficient, and worth avoiding if you can). + // + // Note that removing all arguments is acceptable, as a vast to void ()*. + } } } var temp = { |