aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOphir LOJKINE <pere.jobs@gmail.com>2014-05-19 23:21:21 +0200
committerOphir LOJKINE <pere.jobs@gmail.com>2014-05-19 23:21:21 +0200
commitea01df8b734fb59c8dd435b3c3a7c0aa77a9b08f (patch)
treebbb0594d17fa7e6d9fd435dff33608465164923d
parentba00e71ac68819df214fdfc57dda71c5bb58e887 (diff)
parentf681994208ed73f7642e5658ba9482c1743f0f35 (diff)
Merge remote-tracking branch 'upstream/incoming' into fast-cwrap
-rw-r--r--AUTHORS1
-rwxr-xr-xemcc2
-rw-r--r--emscripten-version.txt2
-rwxr-xr-xemscripten.py7
-rw-r--r--src/embind/emval.js5
-rw-r--r--src/library_browser.js42
-rw-r--r--src/library_html5.js6
-rw-r--r--src/library_sdl.js100
-rw-r--r--src/shell.html11
-rw-r--r--src/shell_minimal.html11
-rw-r--r--src/struct_info.json18
-rw-r--r--system/include/emscripten/html5.h6
-rw-r--r--system/include/emscripten/val.h6
-rw-r--r--tests/cases/i1tof_ta2.ll71
-rw-r--r--tests/cases/i1tof_ta2.txt3
-rw-r--r--tests/core/test_double_varargs.c34
-rw-r--r--tests/core/test_double_varargs.out2
-rw-r--r--tests/embind/embind.test.js10
-rw-r--r--tests/embind/embind_test.cpp8
-rw-r--r--tests/emscripten_fs_api_browser.cpp5
-rw-r--r--tests/test_benchmark.py37
-rw-r--r--tests/test_core.py5
-rw-r--r--tests/test_other.py11
-rw-r--r--tests/webidl/output.txt2
-rw-r--r--tests/webidl/post.js3
-rw-r--r--tests/webidl/test.h3
-rw-r--r--tests/webidl/test.idl3
-rw-r--r--third_party/WebIDL.py13
-rw-r--r--tools/bisect_pair_lines.py63
-rw-r--r--tools/eliminator/asm-eliminator-test-output.js79
-rw-r--r--tools/eliminator/asm-eliminator-test.js73
-rw-r--r--tools/js-optimizer.js169
-rw-r--r--tools/test-js-optimizer-asm-pre-output.js64
-rw-r--r--tools/test-js-optimizer-asm-pre.js66
-rw-r--r--tools/webidl_binder.py3
35 files changed, 882 insertions, 62 deletions
diff --git a/AUTHORS b/AUTHORS
index 7994f80e..137efb00 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -138,3 +138,4 @@ a license to everyone to use it as detailed in LICENSE.)
* Guillaume Blanc <guillaumeblanc.sc@gmail.com>
* Usagi Ito <usagi@WonderRabbitProject.net>
* Camilo Polymeris <cpolymeris@gmail.com>
+* Markus Henschel <markus.henschel@yager.de>
diff --git a/emcc b/emcc
index 1629f5c7..2dc525af 100755
--- a/emcc
+++ b/emcc
@@ -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..1992f2ad 100644
--- a/emscripten-version.txt
+++ b/emscripten-version.txt
@@ -1,2 +1,2 @@
-1.18.0
+1.18.2
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/embind/emval.js b/src/embind/emval.js
index 4007701a..ebec3881 100644
--- a/src/embind/emval.js
+++ b/src/embind/emval.js
@@ -286,3 +286,8 @@ function __emval_has_function(handle, name) {
name = getStringOrSymbol(name);
return handle[name] instanceof Function;
}
+
+function __emval_typeof(handle) {
+ handle = requireHandle(handle);
+ return __emval_register(typeof handle);
+}
diff --git a/src/library_browser.js b/src/library_browser.js
index 44e8c473..4ef7c577 100644
--- a/src/library_browser.js
+++ b/src/library_browser.js
@@ -322,11 +322,6 @@ mergeInto(LibraryManager.library, {
#endif
// Set the background of the WebGL canvas to black
canvas.style.backgroundColor = "black";
-
- // Warn on context loss
- canvas.addEventListener('webglcontextlost', function(event) {
- alert('WebGL context lost. You will need to reload the page.');
- }, false);
}
if (setInModule) {
GLctx = Module.ctx = ctx;
@@ -478,7 +473,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 +697,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 +743,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]);
}
@@ -740,8 +760,8 @@ mergeInto(LibraryManager.library, {
// PROGRESS
http.onprogress = function http_onprogress(e) {
- if (e.lengthComputable || (e.lengthComputable === undefined && e.totalSize != 0)) {
- var percentComplete = (e.position / e.totalSize)*100;
+ if (e.lengthComputable || (e.lengthComputable === undefined && e.total != 0)) {
+ var percentComplete = (e.loaded / e.total)*100;
if (onprogress) Runtime.dynCall('vii', onprogress, [arg, percentComplete]);
}
};
diff --git a/src/library_html5.js b/src/library_html5.js
index d9376c2a..d5d0cd66 100644
--- a/src/library_html5.js
+++ b/src/library_html5.js
@@ -1307,6 +1307,12 @@ var LibraryJSEvents = {
JSEvents.registerWebGlEventCallback(target, userData, useCapture, callbackfunc, {{{ cDefine('EMSCRIPTEN_EVENT_WEBGLCONTEXTRESTORED') }}}, "webglcontextrestored");
return {{{ cDefine('EMSCRIPTEN_RESULT_SUCCESS') }}};
},
+
+ emscripten_is_webgl_context_lost: function(target) {
+ // TODO: In the future if multiple GL contexts are supported, use the 'target' parameter to find the canvas to query.
+ if (!Module['ctx']) return true; // No context ~> lost context.
+ return Module['ctx'].isContextLost();
+ }
};
autoAddDeps(LibraryJSEvents, '$JSEvents');
diff --git a/src/library_sdl.js b/src/library_sdl.js
index d5b2b354..eabfe3e5 100644
--- a/src/library_sdl.js
+++ b/src/library_sdl.js
@@ -430,6 +430,15 @@ var LibrarySDL = {
savedKeydown: null,
receiveEvent: function(event) {
+ function unpressAllPressedKeys() {
+ // Un-press all pressed keys: TODO
+ for (var code in SDL.keyboardMap) {
+ SDL.events.push({
+ type: 'keyup',
+ keyCode: SDL.keyboardMap[code]
+ });
+ }
+ };
switch(event.type) {
case 'touchstart': case 'touchmove': {
event.preventDefault();
@@ -532,7 +541,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 +550,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({
@@ -635,18 +663,23 @@ var LibrarySDL = {
}
event.preventDefault();
break;
+ case 'focus':
+ SDL.events.push(event);
+ event.preventDefault();
+ break;
case 'blur':
- case 'visibilitychange': {
- // Un-press all pressed keys: TODO
- for (var code in SDL.keyboardMap) {
- SDL.events.push({
- type: 'keyup',
- keyCode: SDL.keyboardMap[code]
- });
- }
+ SDL.events.push(event);
+ unpressAllPressedKeys();
+ event.preventDefault();
+ break;
+ case 'visibilitychange':
+ SDL.events.push({
+ type: 'visibilitychange',
+ visible: !document.hidden
+ });
+ unpressAllPressedKeys();
event.preventDefault();
break;
- }
case 'unload':
if (Browser.mainLoop.runner) {
SDL.events.push(event);
@@ -787,6 +820,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;
@@ -840,6 +879,29 @@ var LibrarySDL = {
{{{ makeSetValue('ptr', C_STRUCTS.SDL_JoyAxisEvent.value, 'SDL.joystickAxisValueConversion(event.value)', 'i32') }}};
break;
}
+ case 'focus': {
+ var SDL_WINDOWEVENT_FOCUS_GAINED = 12 /* SDL_WINDOWEVENT_FOCUS_GAINED */;
+ {{{ makeSetValue('ptr', C_STRUCTS.SDL_WindowEvent.type, 'SDL.DOMEventToSDLEvent[event.type]', 'i32') }}};
+ {{{ makeSetValue('ptr', C_STRUCTS.SDL_WindowEvent.windowID, '0', 'i32') }}};
+ {{{ makeSetValue('ptr', C_STRUCTS.SDL_WindowEvent.event, 'SDL_WINDOWEVENT_FOCUS_GAINED', 'i8') }}};
+ break;
+ }
+ case 'blur': {
+ var SDL_WINDOWEVENT_FOCUS_LOST = 13 /* SDL_WINDOWEVENT_FOCUS_LOST */;
+ {{{ makeSetValue('ptr', C_STRUCTS.SDL_WindowEvent.type, 'SDL.DOMEventToSDLEvent[event.type]', 'i32') }}};
+ {{{ makeSetValue('ptr', C_STRUCTS.SDL_WindowEvent.windowID, '0', 'i32') }}};
+ {{{ makeSetValue('ptr', C_STRUCTS.SDL_WindowEvent.event, 'SDL_WINDOWEVENT_FOCUS_LOST', 'i8') }}};
+ break;
+ }
+ case 'visibilitychange': {
+ var SDL_WINDOWEVENT_SHOWN = 1 /* SDL_WINDOWEVENT_SHOWN */;
+ var SDL_WINDOWEVENT_HIDDEN = 2 /* SDL_WINDOWEVENT_HIDDEN */;
+ var visibilityEventID = event.visible ? SDL_WINDOWEVENT_SHOWN : SDL_WINDOWEVENT_HIDDEN;
+ {{{ makeSetValue('ptr', C_STRUCTS.SDL_WindowEvent.type, 'SDL.DOMEventToSDLEvent[event.type]', 'i32') }}};
+ {{{ makeSetValue('ptr', C_STRUCTS.SDL_WindowEvent.windowID, 0, 'i32') }}};
+ {{{ makeSetValue('ptr', C_STRUCTS.SDL_WindowEvent.event, 'visibilityEventID' , 'i8') }}};
+ break;
+ }
default: throw 'Unhandled SDL event: ' + event.type;
}
},
@@ -1043,6 +1105,7 @@ var LibrarySDL = {
document.addEventListener("keydown", SDL.receiveEvent);
document.addEventListener("keyup", SDL.receiveEvent);
document.addEventListener("keypress", SDL.receiveEvent);
+ window.addEventListener("focus", SDL.receiveEvent);
window.addEventListener("blur", SDL.receiveEvent);
document.addEventListener("visibilitychange", SDL.receiveEvent);
}
@@ -1065,11 +1128,16 @@ 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 */;
SDL.DOMEventToSDLEvent['unload'] = 0x100 /* SDL_QUIT */;
SDL.DOMEventToSDLEvent['resize'] = 0x7001 /* SDL_VIDEORESIZE/SDL_EVENT_COMPAT2 */;
+ SDL.DOMEventToSDLEvent['visibilitychange'] = 0x200 /* SDL_WINDOWEVENT */;
+ SDL.DOMEventToSDLEvent['focus'] = 0x200 /* SDL_WINDOWEVENT */;
+ SDL.DOMEventToSDLEvent['blur'] = 0x200 /* SDL_WINDOWEVENT */;
+
// These are not technically DOM events; the HTML gamepad API is poll-based.
// However, we define them here, as the rest of the SDL code assumes that
// all SDL events originate as DOM events.
@@ -1139,7 +1207,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);
});
@@ -2205,6 +2273,7 @@ var LibrarySDL = {
var url = URL.createObjectURL(blob);
audio = new Audio();
audio.src = url;
+ audio.mozAudioChannelType = 'content'; // bugzilla 910340
}
var id = SDL.audios.length;
@@ -2218,6 +2287,7 @@ var LibrarySDL = {
Mix_QuickLoad_RAW: function(mem, len) {
var audio = new Audio();
+ audio.mozAudioChannelType = 'content'; // bugzilla 910340
// Record the number of channels and frequency for later usage
audio.numChannels = SDL.mixerNumChannels;
audio.frequency = SDL.mixerFrequency;
diff --git a/src/shell.html b/src/shell.html
index 1e213024..d204bfa6 100644
--- a/src/shell.html
+++ b/src/shell.html
@@ -1245,7 +1245,16 @@
console.error(text);
}
},
- canvas: document.getElementById('canvas'),
+ canvas: (function() {
+ var canvas = document.getElementById('canvas');
+
+ // As a default initial behavior, pop up an alert when webgl context is lost. To make your
+ // application robust, you may want to override this behavior before shipping!
+ // See http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15.2
+ canvas.addEventListener("webglcontextlost", function(e) { alert('WebGL context lost. You will need to reload the page.'); e.preventDefault(); }, false);
+
+ return canvas;
+ })(),
setStatus: function(text) {
if (!Module.setStatus.last) Module.setStatus.last = { time: Date.now(), text: '' };
if (text === Module.setStatus.text) return;
diff --git a/src/shell_minimal.html b/src/shell_minimal.html
index 7dd67929..b67c6fdd 100644
--- a/src/shell_minimal.html
+++ b/src/shell_minimal.html
@@ -101,7 +101,16 @@
console.error(text);
}
},
- canvas: document.getElementById('canvas'),
+ canvas: (function() {
+ var canvas = document.getElementById('canvas');
+
+ // As a default initial behavior, pop up an alert when webgl context is lost. To make your
+ // application robust, you may want to override this behavior before shipping!
+ // See http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15.2
+ canvas.addEventListener("webglcontextlost", function(e) { alert('WebGL context lost. You will need to reload the page.'); e.preventDefault(); }, false);
+
+ return canvas;
+ })(),
setStatus: function(text) {
if (!Module.setStatus.last) Module.setStatus.last = { time: Date.now(), text: '' };
if (text === Module.setStatus.text) return;
diff --git a/src/struct_info.json b/src/struct_info.json
index f762bf2b..54c89fd7 100644
--- a/src/struct_info.json
+++ b/src/struct_info.json
@@ -932,6 +932,16 @@
"file": "SDL/SDL_events.h",
"defines": [],
"structs": {
+ "SDL_WindowEvent": [
+ "type",
+ "windowID",
+ "event",
+ "padding1",
+ "padding2",
+ "padding3",
+ "data1",
+ "data2"
+ ],
"SDL_KeyboardEvent": [
"type",
"windowID",
@@ -969,6 +979,14 @@
"x",
"y"
],
+ "SDL_MouseWheelEvent": [
+ "type",
+ "timestamp",
+ "windowID",
+ "which",
+ "x",
+ "y"
+ ],
"SDL_JoyAxisEvent": [
"type",
"which",
diff --git a/system/include/emscripten/html5.h b/system/include/emscripten/html5.h
index db81725a..74c32a99 100644
--- a/system/include/emscripten/html5.h
+++ b/system/include/emscripten/html5.h
@@ -636,6 +636,12 @@ extern EMSCRIPTEN_RESULT emscripten_set_beforeunload_callback(void *userData, co
extern EMSCRIPTEN_RESULT emscripten_set_webglcontextlost_callback(const char *target, void *userData, int useCapture, EM_BOOL (*func)(int eventType, const void *reserved, void *userData));
extern EMSCRIPTEN_RESULT emscripten_set_webglcontextrestored_callback(const char *target, void *userData, int useCapture, EM_BOOL (*func)(int eventType, const void *reserved, void *userData));
+/*
+ * Queries the given canvas element for whether its WebGL context is in a lost state.
+ * target: Reserved for future use, pass in 0.
+ */
+extern EM_BOOL emscripten_is_webgl_context_lost(const char *target);
+
#ifdef __cplusplus
} // ~extern "C"
#endif
diff --git a/system/include/emscripten/val.h b/system/include/emscripten/val.h
index e217c959..bfd8610a 100644
--- a/system/include/emscripten/val.h
+++ b/system/include/emscripten/val.h
@@ -62,6 +62,7 @@ namespace emscripten {
bool _emval_has_function(
EM_VAL value,
const char* methodName);
+ EM_VAL _emval_typeof(EM_VAL value);
}
template<const char* address>
@@ -254,7 +255,6 @@ namespace emscripten {
// * delete
// * in
// * instanceof
- // * typeof
// * ! ~ - + ++ --
// * * / %
// * + -
@@ -411,6 +411,10 @@ namespace emscripten {
return fromGenericWireType<T>(result);
}
+ val typeof() const {
+ return val(_emval_typeof(handle));
+ }
+
private:
// takes ownership, assumes handle already incref'd
explicit val(internal::EM_VAL handle)
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/core/test_double_varargs.c b/tests/core/test_double_varargs.c
new file mode 100644
index 00000000..d3eb3eed
--- /dev/null
+++ b/tests/core/test_double_varargs.c
@@ -0,0 +1,34 @@
+#include <stdio.h>
+#include <stdarg.h>
+
+double func_int_double_1(int unused1, ...)
+{
+ int i;
+ double d;
+ va_list vl;
+ va_start(vl, unused1);
+ i = va_arg(vl, int);
+ d = va_arg(vl, double);
+ va_end(vl);
+ return i+d;
+}
+
+double func_int_double_2(int unused1, int unused2, ...)
+{
+ int i;
+ double d;
+ va_list vl;
+ va_start(vl, unused2);
+ i = va_arg(vl, int);
+ d = va_arg(vl, double);
+ va_end(vl);
+ return i+d;
+}
+
+int main() {
+ double ret = func_int_double_1(0, 5, 10.0);
+ printf("%f\n", ret); // Expects to print 15
+ ret = func_int_double_2(0, 0, 5, 10.0);
+ printf("%f\n", ret); // Expects to print 15
+}
+
diff --git a/tests/core/test_double_varargs.out b/tests/core/test_double_varargs.out
new file mode 100644
index 00000000..c907dece
--- /dev/null
+++ b/tests/core/test_double_varargs.out
@@ -0,0 +1,2 @@
+15.000000
+15.000000
diff --git a/tests/embind/embind.test.js b/tests/embind/embind.test.js
index 3ded811a..53d3988a 100644
--- a/tests/embind/embind.test.js
+++ b/tests/embind/embind.test.js
@@ -2030,6 +2030,16 @@ module({
assert.equal(65538, instance.c);
});
});
+
+ BaseFixture.extend("typeof", function() {
+ test("typeof", function() {
+ assert.equal("object", cm.getTypeOfVal(null));
+ assert.equal("object", cm.getTypeOfVal({}));
+ assert.equal("function", cm.getTypeOfVal(function(){}));
+ assert.equal("number", cm.getTypeOfVal(1));
+ assert.equal("string", cm.getTypeOfVal("hi"));
+ });
+ });
});
/* global run_all_tests */
diff --git a/tests/embind/embind_test.cpp b/tests/embind/embind_test.cpp
index 5a83903a..52103bbb 100644
--- a/tests/embind/embind_test.cpp
+++ b/tests/embind/embind_test.cpp
@@ -2368,3 +2368,11 @@ EMSCRIPTEN_BINDINGS(val_new_) {
function("construct_with_memory_view", &construct_with_memory_view);
function("construct_with_ints_and_float", &construct_with_ints_and_float);
}
+
+std::string getTypeOfVal(const val& v) {
+ return v.typeof().as<std::string>();
+}
+
+EMSCRIPTEN_BINDINGS(typeof) {