diff options
-rwxr-xr-x | emcc | 2 | ||||
-rw-r--r-- | emscripten-version.txt | 2 | ||||
-rwxr-xr-x | emscripten.py | 7 | ||||
-rw-r--r-- | src/library_browser.js | 33 | ||||
-rw-r--r-- | src/library_sdl.js | 38 | ||||
-rw-r--r-- | src/struct_info.json | 8 | ||||
-rw-r--r-- | tests/cases/i1tof_ta2.ll | 71 | ||||
-rw-r--r-- | tests/cases/i1tof_ta2.txt | 3 | ||||
-rw-r--r-- | tests/emscripten_fs_api_browser.cpp | 5 | ||||
-rw-r--r-- | tests/test_benchmark.py | 1 | ||||
-rw-r--r-- | tests/test_other.py | 11 |
11 files changed, 168 insertions, 13 deletions
@@ -1223,6 +1223,8 @@ try: value = '"@' + os.path.abspath(value[1:]) + '"' value = value.replace('\\\\', '/').replace('\\', '/') # Convert backslash paths to forward slashes on Windows as well, since the JS compiler otherwise needs the backslashes escaped (alternative is to escape all input paths passing to JS, which feels clumsier to read) exec('shared.Settings.' + key + ' = ' + value) + if key == 'EXPORTED_FUNCTIONS': + shared.Settings.ORIGINAL_EXPORTED_FUNCTIONS = shared.Settings.EXPORTED_FUNCTIONS[:] # used for warnings in emscripten.py fastcomp = os.environ.get('EMCC_FAST_COMPILER') != '0' diff --git a/emscripten-version.txt b/emscripten-version.txt index a36c9a1e..6cee04e0 100644 --- a/emscripten-version.txt +++ b/emscripten-version.txt @@ -1,2 +1,2 @@ -1.18.0 +1.18.1 diff --git a/emscripten.py b/emscripten.py index e2aef648..d75214d5 100755 --- a/emscripten.py +++ b/emscripten.py @@ -895,10 +895,15 @@ def emscript_fast(infile, settings, outfile, libraries=[], compiler_engine=None, exported_implemented_functions = set(metadata['exports']) export_bindings = settings['EXPORT_BINDINGS'] export_all = settings['EXPORT_ALL'] - for key in metadata['implementedFunctions'] + forwarded_json['Functions']['implementedFunctions'].keys(): # XXX perf + all_implemented = metadata['implementedFunctions'] + forwarded_json['Functions']['implementedFunctions'].keys() # XXX perf? + for key in all_implemented: if key in all_exported_functions or export_all or (export_bindings and key.startswith('_emscripten_bind')): exported_implemented_functions.add(key) implemented_functions = set(metadata['implementedFunctions']) + if settings['ASSERTIONS'] and settings.get('ORIGINAL_EXPORTED_FUNCTIONS'): + for requested in settings['ORIGINAL_EXPORTED_FUNCTIONS']: + if requested not in all_implemented: + logging.warning('function requested to be exported, but not implemented: "%s"', requested) # Add named globals named_globals = '\n'.join(['var %s = %s;' % (k, v) for k, v in metadata['namedGlobals'].iteritems()]) diff --git a/src/library_browser.js b/src/library_browser.js index c164d4b7..07d33b32 100644 --- a/src/library_browser.js +++ b/src/library_browser.js @@ -478,7 +478,21 @@ mergeInto(LibraryManager.library, { }, getMouseWheelDelta: function(event) { - return Math.max(-1, Math.min(1, event.type === 'DOMMouseScroll' ? event.detail : -event.wheelDelta)); + var delta = 0; + switch (event.type) { + case 'DOMMouseScroll': + delta = event.detail; + break; + case 'mousewheel': + delta = -event.wheelDelta; + break; + case 'wheel': + delta = event.deltaY; + break; + default: + throw 'unrecognized mouse wheel event: ' + event.type; + } + return Math.max(-1, Math.min(1, delta)); }, mouseX: 0, @@ -688,15 +702,22 @@ mergeInto(LibraryManager.library, { emscripten_async_wget: function(url, file, onload, onerror) { var _url = Pointer_stringify(url); var _file = Pointer_stringify(file); + function doCallback(callback) { + if (callback) { + var stack = Runtime.stackSave(); + Runtime.dynCall('vi', callback, [allocate(intArrayFromString(_file), 'i8', ALLOC_STACK)]); + Runtime.stackRestore(stack); + } + } FS.createPreloadedFile( PATH.dirname(_file), PATH.basename(_file), _url, true, true, function() { - if (onload) Runtime.dynCall('vi', onload, [file]); + doCallback(onload); }, function() { - if (onerror) Runtime.dynCall('vi', onerror, [file]); + doCallback(onerror); } ); }, @@ -727,7 +748,11 @@ mergeInto(LibraryManager.library, { http.onload = function http_onload(e) { if (http.status == 200) { FS.createDataFile( _file.substr(0, index), _file.substr(index + 1), new Uint8Array(http.response), true, true); - if (onload) Runtime.dynCall('vii', onload, [arg, file]); + if (onload) { + var stack = Runtime.stackSave(); + Runtime.dynCall('vii', onload, [arg, allocate(intArrayFromString(_file), 'i8', ALLOC_STACK)]); + Runtime.stackRestore(stack); + } } else { if (onerror) Runtime.dynCall('vii', onerror, [arg, http.status]); } diff --git a/src/library_sdl.js b/src/library_sdl.js index d5b2b354..ae384d22 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -532,7 +532,7 @@ var LibrarySDL = { } } // fall through - case 'keydown': case 'keyup': case 'keypress': case 'mousedown': case 'mouseup': case 'DOMMouseScroll': case 'mousewheel': + case 'keydown': case 'keyup': case 'keypress': case 'mousedown': case 'mouseup': case 'DOMMouseScroll': case 'mousewheel': case 'wheel': // If we preventDefault on keydown events, the subsequent keypress events // won't fire. However, it's fine (and in some cases necessary) to // preventDefault for keys that don't generate a character. Otherwise, @@ -541,21 +541,40 @@ var LibrarySDL = { event.preventDefault(); } - if (event.type == 'DOMMouseScroll' || event.type == 'mousewheel') { + if (event.type == 'DOMMouseScroll' || event.type == 'mousewheel' || event.type == 'wheel') { + // Simulate old-style SDL events representing mouse wheel input as buttons var button = Browser.getMouseWheelDelta(event) > 0 ? 4 : 3; - var event2 = { + var event1 = { type: 'mousedown', button: button, pageX: event.pageX, pageY: event.pageY }; - SDL.events.push(event2); - event = { + SDL.events.push(event1); + var event2 = { type: 'mouseup', button: button, pageX: event.pageX, pageY: event.pageY }; + SDL.events.push(event2); + + // Convert DOMMouseScroll events to wheel events for new style SDL events. + if (event.type == 'DOMMouseScroll') { + SDL.events.push({ + type: 'wheel', + deltaX: 0, + deltaY: -event.detail, + }); + break; + } else if (event.type == 'mousewheel') { + SDL.events.push({ + type: 'wheel', + deltaX: 0, + deltaY: event.wheelDelta, + }); + break; + } } else if (event.type == 'mousedown') { SDL.DOMButtons[event.button] = 1; SDL.events.push({ @@ -787,6 +806,12 @@ var LibrarySDL = { } break; } + case 'wheel': { + {{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseWheelEvent.type, 'SDL.DOMEventToSDLEvent[event.type]', 'i32') }}}; + {{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseWheelEvent.x, 'event.deltaX', 'i32') }}}; + {{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseWheelEvent.y, 'event.deltaY', 'i32') }}}; + break; + } case 'touchstart': case 'touchend': case 'touchmove': { var touch = event.touch; if (!Browser.touches[touch.identifier]) break; @@ -1065,6 +1090,7 @@ var LibrarySDL = { SDL.DOMEventToSDLEvent['mousedown'] = 0x401 /* SDL_MOUSEBUTTONDOWN */; SDL.DOMEventToSDLEvent['mouseup'] = 0x402 /* SDL_MOUSEBUTTONUP */; SDL.DOMEventToSDLEvent['mousemove'] = 0x400 /* SDL_MOUSEMOTION */; + SDL.DOMEventToSDLEvent['wheel'] = 0x403 /* SDL_MOUSEWHEEL */; SDL.DOMEventToSDLEvent['touchstart'] = 0x700 /* SDL_FINGERDOWN */; SDL.DOMEventToSDLEvent['touchend'] = 0x701 /* SDL_FINGERUP */; SDL.DOMEventToSDLEvent['touchmove'] = 0x702 /* SDL_FINGERMOTION */; @@ -1139,7 +1165,7 @@ var LibrarySDL = { }, SDL_SetVideoMode: function(width, height, depth, flags) { - ['touchstart', 'touchend', 'touchmove', 'mousedown', 'mouseup', 'mousemove', 'DOMMouseScroll', 'mousewheel', 'mouseout'].forEach(function(event) { + ['touchstart', 'touchend', 'touchmove', 'mousedown', 'mouseup', 'mousemove', 'DOMMouseScroll', 'mousewheel', 'wheel', 'mouseout'].forEach(function(event) { Module['canvas'].addEventListener(event, SDL.receiveEvent, true); }); diff --git a/src/struct_info.json b/src/struct_info.json index f762bf2b..9aeeb283 100644 --- a/src/struct_info.json +++ b/src/struct_info.json @@ -969,6 +969,14 @@ "x", "y" ], + "SDL_MouseWheelEvent": [ + "type", + "timestamp", + "windowID", + "which", + "x", + "y" + ], "SDL_JoyAxisEvent": [ "type", "which", diff --git a/tests/cases/i1tof_ta2.ll b/tests/cases/i1tof_ta2.ll new file mode 100644 index 00000000..12940907 --- /dev/null +++ b/tests/cases/i1tof_ta2.ll @@ -0,0 +1,71 @@ +; ModuleID = 'bad/emcc-0-basebc.bc' +target datalayout = "e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-p:32:32:32-v128:32:128-n32-S128" +target triple = "asmjs-unknown-emscripten" + +@.str = private unnamed_addr constant [7 x i8] c"%0.1f\0A\00", align 1 +@.str2 = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1 + +; Function Attrs: noinline +define float @_Z2v1v() #0 { +entry: + %call = tail call double @emscripten_get_now() + %cmp = fcmp oge double %call, 0.000000e+00 + %cond = select i1 %cmp, float 0x3FECCCCCC0000000, float 0.000000e+00 + ret float %cond +} + +define double @emscripten_get_now() #0 { + ret double 1.0 +} + +; Function Attrs: noinline +define float @_Z2v2v() #0 { +entry: + %call = tail call double @emscripten_get_now() + %cmp = fcmp oge double %call, 0.000000e+00 + %cond = select i1 %cmp, float 0x3FD99999A0000000, float 0.000000e+00 + ret float %cond +} + +; Function Attrs: noinline +define float @_Z2v3v() #0 { +entry: + %call = tail call double @emscripten_get_now() + %cmp = fcmp oge double %call, 0.000000e+00 + %cond = select i1 %cmp, float 0x3FB99999A0000000, float 0.000000e+00 + ret float %cond +} + +define i32 @main() #1 { +entry: + %call = tail call float @_Z2v1v() + %call1 = tail call float @_Z2v2v() + %call2 = tail call float @_Z2v3v() + %sub = fsub float %call1, %call + %cmp.i = fcmp ogt float %sub, 0.000000e+00 + br i1 %cmp.i, label %_ZL5signff.exit, label %cond.false.i + +cond.false.i: ; preds = %entry + %cmp1.i = fcmp olt float %sub, 0.000000e+00 + %phitmp = sitofp i1 %cmp1.i to float + %phitmpd = fpext float %phitmp to double + %call1115a = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([7 x i8]* @.str, i32 0, i32 0), double %phitmpd) + %phitmpi = sext i1 %cmp1.i to i32 + %call1115b = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str2, i32 0, i32 0), i32 %phitmpi) + br label %_ZL5signff.exit + +_ZL5signff.exit: ; preds = %cond.false.i, %entry + %cond2.i = phi float [ %phitmp, %cond.false.i ], [ 1.000000e+00, %entry ] + %mul = fmul float %call2, %cond2.i + %add = fadd float %call, %mul + %conv4 = fpext float %add to double + %call5 = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([7 x i8]* @.str, i32 0, i32 0), double %conv4) + ret i32 0 +} + +; Function Attrs: nounwind +declare i32 @printf(i8* nocapture, ...) #2 + +attributes #0 = { noinline "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } diff --git a/tests/cases/i1tof_ta2.txt b/tests/cases/i1tof_ta2.txt new file mode 100644 index 00000000..5d3943cd --- /dev/null +++ b/tests/cases/i1tof_ta2.txt @@ -0,0 +1,3 @@ +-1.0 +-1 +0.8 diff --git a/tests/emscripten_fs_api_browser.cpp b/tests/emscripten_fs_api_browser.cpp index 0355287a..1410ba3c 100644 --- a/tests/emscripten_fs_api_browser.cpp +++ b/tests/emscripten_fs_api_browser.cpp @@ -107,11 +107,14 @@ int main() { onLoaded, onError); + char name[40]; + strcpy(name, "/tmp/screen_shot.png"); // test for issue #2349, name being free'd emscripten_async_wget( "http://localhost:8888/screenshot.png", - "/tmp/screen_shot.png", + name, onLoaded, onError); + memset(name, 0, 30); emscripten_set_main_loop(wait_wgets, 0, 0); diff --git a/tests/test_benchmark.py b/tests/test_benchmark.py index 735f0feb..821caa6b 100644 --- a/tests/test_benchmark.py +++ b/tests/test_benchmark.py @@ -112,6 +112,7 @@ process(sys.argv[1]) '--memory-init-file', '0', '--js-transform', 'python hardcode.py', '-s', 'TOTAL_MEMORY=128*1024*1024', #'-profiling', + #'--closure', '1', '-o', final] + shared_args + emcc_args + self.extra_args, stdout=PIPE, stderr=PIPE, env=self.env).communicate() assert os.path.exists(final), 'Failed to compile file: ' + output[0] self.filename = final diff --git a/tests/test_other.py b/tests/test_other.py index 349a16b4..4a6296e0 100644 --- a/tests/test_other.py +++ b/tests/test_other.py @@ -2791,3 +2791,14 @@ int main(int argc, char **argv) { assert sizes[0] == 7 # no aliasing, all unique, fat tables assert sizes[1] == 3 # aliased once more + def test_bad_export(self): + for m in ['', ' ']: + self.clear() + cmd = [PYTHON, EMCC, path_from_root('tests', 'hello_world.c'), '-s', 'EXPORTED_FUNCTIONS=["' + m + '_main"]'] + print cmd + stdout, stderr = Popen(cmd, stderr=PIPE).communicate() + if m: + assert 'function requested to be exported, but not implemented: " _main"' in stderr, stderr + else: + self.assertContained('hello, world!', run_js('a.out.js')) + |