aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS2
-rwxr-xr-xemcc8
-rw-r--r--src/embind/embind.js11
-rw-r--r--src/library.js23
-rw-r--r--src/library_browser.js2
-rw-r--r--src/library_sdl.js6
-rw-r--r--src/preamble.js12
-rw-r--r--src/relooper/Relooper.cpp11
-rw-r--r--system/include/emscripten/bind.h2
-rw-r--r--system/lib/embind/bind.cpp1
-rw-r--r--tests/cases/redundantswitch_fastcomp.ll28
-rw-r--r--tests/cases/redundantswitch_fastcomp.txt2
-rw-r--r--tests/core/test_sscanf_hex.in24
-rw-r--r--tests/core/test_sscanf_hex.out3
-rw-r--r--tests/embind/embind.test.js15
-rw-r--r--tests/embind/embind_test.cpp5
-rw-r--r--tests/test_core.py3
-rw-r--r--tests/test_other.py5
18 files changed, 127 insertions, 36 deletions
diff --git a/AUTHORS b/AUTHORS
index c162103a..7994f80e 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -137,4 +137,4 @@ a license to everyone to use it as detailed in LICENSE.)
* Ori Avtalion <ori@avtalion.name>
* Guillaume Blanc <guillaumeblanc.sc@gmail.com>
* Usagi Ito <usagi@WonderRabbitProject.net>
-
+* Camilo Polymeris <cpolymeris@gmail.com>
diff --git a/emcc b/emcc
index 47dbc60d..b9d74713 100755
--- a/emcc
+++ b/emcc
@@ -1366,9 +1366,11 @@ try:
for header in input_files:
assert header.endswith(HEADER_ENDINGS), 'if you have one header input, we assume you want to precompile headers, and cannot have source files or other inputs as well: ' + str(input_files) + ' : ' + header
args = newargs + shared.EMSDK_CXX_OPTS + input_files
- logging.debug("running (for precompiled headers: " + call + ' ' + ' '.join(args))
+ if specified_target:
+ args += ['-o', specified_target]
+ logging.debug("running (for precompiled headers): " + call + ' ' + ' '.join(args))
execute([call] + args) # let compiler frontend print directly, so colors are saved (PIPE kills that)
- sys.exit(1)
+ sys.exit(0)
def get_bitcode_file(input_file):
if final_suffix not in JS_CONTAINING_SUFFIXES:
@@ -1744,7 +1746,7 @@ try:
js_optimizer_extra_info['sizeToOutline'] = shared.Settings.OUTLINING_LIMIT
if opt_level >= 2 and (not closure or shared.Settings.ASM_JS) and shared.Settings.RELOOP and debug_level < 3:
- if shared.Settings.ASM_JS and opt_level >= 3 and shared.Settings.OUTLINING_LIMIT == 0:
+ if shared.Settings.ASM_JS and opt_level >= 3:
js_optimizer_queue += ['registerizeHarder']
else:
js_optimizer_queue += ['registerize']
diff --git a/src/embind/embind.js b/src/embind/embind.js
index bb979365..3eadb85f 100644
--- a/src/embind/embind.js
+++ b/src/embind/embind.js
@@ -723,9 +723,16 @@ function requireFunction(signature, rawFunction) {
// possibly allocate.
var dc = asm['dynCall_' + signature];
if (dc === undefined) {
- throwBindingError("No dynCall invoker for signature: " + signature);
+ // We will always enter this branch if the signature
+ // contains 'f' and PRECISE_F32 is not enabled.
+ //
+ // Try again, replacing 'f' with 'd'.
+ dc = asm['dynCall_' + signature.replace(/f/g, 'd')];
+ if (dc === undefined) {
+ throwBindingError("No dynCall invoker for signature: " + signature);
+ }
}
- fp = asm['dynCall_' + signature].bind(undefined, rawFunction);
+ fp = dc.bind(undefined, rawFunction);
} else {
fp = FUNCTION_TABLE[rawFunction];
}
diff --git a/src/library.js b/src/library.js
index c2830397..c8c5a0ff 100644
--- a/src/library.js
+++ b/src/library.js
@@ -1584,7 +1584,6 @@ LibraryManager.library = {
return /^[+-]?[0-9]*\.?[0-9]+([eE][+-]?[0-9]+)?/.exec(text);
},
- // TODO: Document.
_scanString__deps: ['_getFloat'],
_scanString: function(format, get, unget, varargs) {
if (!__scanString.whiteSpace) {
@@ -1726,6 +1725,7 @@ LibraryManager.library = {
}
var long_ = false;
var half = false;
+ var quarter = false;
var longLong = false;
if (format[formatIndex] == 'l') {
long_ = true;
@@ -1737,6 +1737,10 @@ LibraryManager.library = {
} else if (format[formatIndex] == 'h') {
half = true;
formatIndex++;
+ if (format[formatIndex] == 'h') {
+ quarter = true;
+ formatIndex++;
+ }
}
var type = format[formatIndex];
formatIndex++;
@@ -1795,20 +1799,21 @@ LibraryManager.library = {
var text = buffer.join('');
var argPtr = {{{ makeGetValue('varargs', 'argIndex', 'void*') }}};
argIndex += Runtime.getAlignSize('void*', null, true);
+ var base = 10;
switch (type) {
+ case 'X': case 'x':
+ base = 16;
case 'd': case 'u': case 'i':
- if (half) {
- {{{ makeSetValue('argPtr', 0, 'parseInt(text, 10)', 'i16') }}};
+ if (quarter) {
+ {{{ makeSetValue('argPtr', 0, 'parseInt(text, base)', 'i8') }}};
+ } else if (half) {
+ {{{ makeSetValue('argPtr', 0, 'parseInt(text, base)', 'i16') }}};
} else if (longLong) {
- {{{ makeSetValue('argPtr', 0, 'parseInt(text, 10)', 'i64') }}};
+ {{{ makeSetValue('argPtr', 0, 'parseInt(text, base)', 'i64') }}};
} else {
- {{{ makeSetValue('argPtr', 0, 'parseInt(text, 10)', 'i32') }}};
+ {{{ makeSetValue('argPtr', 0, 'parseInt(text, base)', 'i32') }}};
}
break;
- case 'X':
- case 'x':
- {{{ makeSetValue('argPtr', 0, 'parseInt(text, 16)', 'i32') }}};
- break;
case 'F':
case 'f':
case 'E':
diff --git a/src/library_browser.js b/src/library_browser.js
index 4cd8b392..5cc7e122 100644
--- a/src/library_browser.js
+++ b/src/library_browser.js
@@ -430,11 +430,13 @@ mergeInto(LibraryManager.library, {
});
},
safeSetTimeout: function(func, timeout) {
+ Module['noExitRuntime'] = true;
return setTimeout(function() {
if (!ABORT) func();
}, timeout);
},
safeSetInterval: function(func, timeout) {
+ Module['noExitRuntime'] = true;
return setInterval(function() {
if (!ABORT) func();
}, timeout);
diff --git a/src/library_sdl.js b/src/library_sdl.js
index 6e235e90..077f72eb 100644
--- a/src/library_sdl.js
+++ b/src/library_sdl.js
@@ -686,11 +686,7 @@ var LibrarySDL = {
} else {
code = SDL.keyCodes[event.keyCode] || event.keyCode;
}
-
- var scan = code & ~(1 << 10);
- scan = SDL.scanCodes[scan] || scan;
-
- {{{ makeSetValue('SDL.keyboardState', 'scan', 'down', 'i8') }}};
+ {{{ makeSetValue('SDL.keyboardState', 'code', 'down', 'i8') }}};
// TODO: lmeta, rmeta, numlock, capslock, KMOD_MODE, KMOD_RESERVED
SDL.modState = ({{{ makeGetValue('SDL.keyboardState', '1248', 'i8') }}} ? 0x0040 | 0x0080 : 0) | // KMOD_LCTRL & KMOD_RCTRL
({{{ makeGetValue('SDL.keyboardState', '1249', 'i8') }}} ? 0x0001 | 0x0002 : 0) | // KMOD_LSHIFT & KMOD_RSHIFT
diff --git a/src/preamble.js b/src/preamble.js
index 5dd8ada1..2aec94c6 100644
--- a/src/preamble.js
+++ b/src/preamble.js
@@ -186,17 +186,17 @@ function SAFE_HEAP_STORE(dest, value, bytes, isFloat) {
#if SAFE_HEAP_LOG
Module.print('SAFE_HEAP store: ' + [dest, value, bytes, isFloat]);
#endif
- assert(dest > 0, 'segmentation fault');
- assert(dest % bytes === 0, 'alignment error');
- assert(dest < Math.max(DYNAMICTOP, STATICTOP), 'segmentation fault (high)');
+ if (dest <= 0) abort('segmentation fault storing ' + bytes + ' bytes to address ' + dest);
+ if (dest % bytes !== 0) abort('alignment error storing to address ' + dest + ', which was expected to be aligned to a multiple of ' + bytes);
+ if (dest + bytes > Math.max(DYNAMICTOP, STATICTOP)) abort('segmentation fault, exceeded the top of the available heap when storing ' + bytes + ' bytes to address ' + dest + '. STATICTOP=' + STATICTOP + ', DYNAMICTOP=' + DYNAMICTOP);
assert(DYNAMICTOP <= TOTAL_MEMORY);
setValue(dest, value, getSafeHeapType(bytes, isFloat), 1);
}
function SAFE_HEAP_LOAD(dest, bytes, isFloat, unsigned) {
- assert(dest > 0, 'segmentation fault');
- assert(dest % bytes === 0, 'alignment error');
- assert(dest < Math.max(DYNAMICTOP, STATICTOP), 'segmentation fault (high)');
+ if (dest <= 0) abort('segmentation fault loading ' + bytes + ' bytes from address ' + dest);
+ if (dest % bytes !== 0) abort('alignment error loading from address ' + dest + ', which was expected to be aligned to a multiple of ' + bytes);
+ if (dest + bytes > Math.max(DYNAMICTOP, STATICTOP)) abort('segmentation fault, exceeded the top of the available heap when loading ' + bytes + ' bytes from address ' + dest + '. STATICTOP=' + STATICTOP + ', DYNAMICTOP=' + DYNAMICTOP);
assert(DYNAMICTOP <= TOTAL_MEMORY);
var type = getSafeHeapType(bytes, isFloat);
var ret = getValue(dest, type, 1);
diff --git a/src/relooper/Relooper.cpp b/src/relooper/Relooper.cpp
index ce9232d9..568dd381 100644
--- a/src/relooper/Relooper.cpp
+++ b/src/relooper/Relooper.cpp
@@ -17,6 +17,10 @@
typedef std::string ministring;
#endif
+// uncomment these out to get LLVM errs() debugging support
+//#include <llvm/Support/raw_ostream.h>
+//using namespace llvm;
+
template <class T, class U> static bool contains(const T& container, const U& contained) {
return container.count(contained);
}
@@ -202,6 +206,7 @@ void Block::Render(bool InLoop) {
if (Fused) {
PrintDebug("Fusing Multiple to Simple\n");
Parent->Next = Parent->Next->Next;
+ Fused->UseSwitch = false; // TODO: emit switches here
Fused->RenderLoopPrefix();
// When the Multiple has the same number of groups as we have branches,
@@ -319,11 +324,7 @@ void MultipleShape::RenderLoopPrefix() {
}
} else {
if (Labeled) {
- if (UseSwitch) {
- PrintIndented("L%d: ", Id);
- } else {
- PrintIndented("L%d: do {\n", Id);
- }
+ PrintIndented("L%d: do {\n", Id);
} else {
PrintIndented("do {\n");
}
diff --git a/system/include/emscripten/bind.h b/system/include/emscripten/bind.h
index 699e834b..eede0755 100644
--- a/system/include/emscripten/bind.h
+++ b/system/include/emscripten/bind.h
@@ -330,7 +330,7 @@ namespace emscripten {
template<>
struct SignatureCode<float> {
static constexpr char get() {
- return 'd';
+ return 'f';
}
};
diff --git a/system/lib/embind/bind.cpp b/system/lib/embind/bind.cpp
index 37918050..16c24a91 100644
--- a/system/lib/embind/bind.cpp
+++ b/system/lib/embind/bind.cpp
@@ -78,6 +78,7 @@ EMSCRIPTEN_BINDINGS(native_and_builtin_types) {
register_float<double>("double");
_embind_register_std_string(TypeID<std::string>::get(), "std::string");
+ _embind_register_std_string(TypeID<std::basic_string<unsigned char> >::get(), "std::basic_string<unsigned char>");
_embind_register_std_wstring(TypeID<std::wstring>::get(), sizeof(wchar_t), "std::wstring");
_embind_register_emval(TypeID<val>::get(), "emscripten::val");
_embind_register_memory_view(TypeID<memory_view>::get(), "emscripten::memory_view");
diff --git a/tests/cases/redundantswitch_fastcomp.ll b/tests/cases/redundantswitch_fastcomp.ll
new file mode 100644
index 00000000..5b797ac8
--- /dev/null
+++ b/tests/cases/redundantswitch_fastcomp.ll
@@ -0,0 +1,28 @@
+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 constant [18 x i8] c"hello, world: %d\0A\00", align 1
+
+declare i32 @printf(i8*, ...)
+
+define linkonce_odr i32 @main() align 2 {
+entry:
+ %temp32 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([18 x i8]* @.str, i32 0, i32 0), i32 5)
+ switch i32 %temp32, label %mid1 [
+ i32 1000, label %mid1
+ i32 1001, label %mid2
+ i32 2000, label %finish
+ ]
+
+mid1:
+ br label %finish
+
+mid2:
+ br label %finish
+
+finish: ; preds = %555
+ %last = phi i32 [0, %entry], [1, %mid1], [2, %mid2]
+ %a333c = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([18 x i8]* @.str, i32 0, i32 0), i32 %last)
+ ret i32 0
+}
+
diff --git a/tests/cases/redundantswitch_fastcomp.txt b/tests/cases/redundantswitch_fastcomp.txt
new file mode 100644
index 00000000..72084b0c
--- /dev/null
+++ b/tests/cases/redundantswitch_fastcomp.txt
@@ -0,0 +1,2 @@
+hello, world: 5
+hello, world: 1
diff --git a/tests/core/test_sscanf_hex.in b/tests/core/test_sscanf_hex.in
index d8175e82..a05eb890 100644
--- a/tests/core/test_sscanf_hex.in
+++ b/tests/core/test_sscanf_hex.in
@@ -1,7 +1,27 @@
-#include "stdio.h"
+#include <stdio.h>
+#include <string>
+#include <cstdlib>
-int main() {
+int main()
+{
unsigned int a, b;
sscanf("0x12AB 12AB", "%x %x", &a, &b);
printf("%d %d\n", a, b);
+
+ std::string hexstr("0102037F00FF");
+ const char * cstr = hexstr.c_str();
+ int len = hexstr.length() / 2;
+ char * tmp_data = new char[len];
+ for(int i = 0; i < len; i++)
+ {
+ sscanf(cstr, "%2hhx", &tmp_data[i]);
+ cstr += 2 * sizeof(char);
+ }
+
+ for (int j = 0; j < len; j++)
+ printf("%i, ", tmp_data[j]);
+ printf("\n");
+ delete[] tmp_data;
}
+
+
diff --git a/tests/core/test_sscanf_hex.out b/tests/core/test_sscanf_hex.out
index ac855044..6e7f66aa 100644
--- a/tests/core/test_sscanf_hex.out
+++ b/tests/core/test_sscanf_hex.out
@@ -1 +1,2 @@
-4779 4779 \ No newline at end of file
+4779 4779
+1, 2, 3, 127, 0, -1,
diff --git a/tests/embind/embind.test.js b/tests/embind/embind.test.js
index 6bba4de0..3ded811a 100644
--- a/tests/embind/embind.test.js
+++ b/tests/embind/embind.test.js
@@ -442,6 +442,21 @@ module({
var e = cm.emval_test_take_and_return_std_string((new Int8Array([65, 66, 67, 68])).buffer);
assert.equal('ABCD', e);
});
+
+ test("can pass Uint8Array to std::basic_string<unsigned char>", function() {
+ var e = cm.emval_test_take_and_return_std_basic_string_unsigned_char(new Uint8Array([65, 66, 67, 68]));
+ assert.equal('ABCD', e);
+ });
+
+ test("can pass Int8Array to std::basic_string<unsigned char>", function() {
+ var e = cm.emval_test_take_and_return_std_basic_string_unsigned_char(new Int8Array([65, 66, 67, 68]));
+ assert.equal('ABCD', e);
+ });
+
+ test("can pass ArrayBuffer to std::basic_string<unsigned char>", function() {
+ var e = cm.emval_test_take_and_return_std_basic_string_unsigned_char((new Int8Array([65, 66, 67, 68])).buffer);
+ assert.equal('ABCD', e);
+ });
test("non-ascii wstrings", function() {
var expected = String.fromCharCode(10) +
diff --git a/tests/embind/embind_test.cpp b/tests/embind/embind_test.cpp
index 1b835751..5a83903a 100644
--- a/tests/embind/embind_test.cpp
+++ b/tests/embind/embind_test.cpp
@@ -109,6 +109,10 @@ std::string emval_test_take_and_return_std_string_const_ref(const std::string& s
return str;
}
+std::basic_string<unsigned char> emval_test_take_and_return_std_basic_string_unsigned_char(std::basic_string<unsigned char> str) {
+ return str;
+}
+
std::wstring take_and_return_std_wstring(std::wstring str) {
return str;
}
@@ -1446,6 +1450,7 @@ EMSCRIPTEN_BINDINGS(tests) {
//function("emval_test_take_and_return_const_char_star", &emval_test_take_and_return_const_char_star);
function("emval_test_take_and_return_std_string", &emval_test_take_and_return_std_string);
function("emval_test_take_and_return_std_string_const_ref", &emval_test_take_and_return_std_string_const_ref);
+ function("emval_test_take_and_return_std_basic_string_unsigned_char", &emval_test_take_and_return_std_basic_string_unsigned_char);
function("take_and_return_std_wstring", &take_and_return_std_wstring);
//function("emval_test_take_and_return_CustomStruct", &emval_test_take_and_return_CustomStruct);
diff --git a/tests/test_core.py b/tests/test_core.py
index c9784ec9..cf2730d0 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -3905,6 +3905,8 @@ Pass: 0.000012 0.000012''')
self.do_run_from_file(src, output)
def test_sscanf_hex(self):
+ if Settings.USE_TYPED_ARRAYS != 2: return self.skip('requires ta2')
+
test_path = path_from_root('tests', 'core', 'test_sscanf_hex')
src, output = (test_path + s for s in ('.in', '.out'))
@@ -5662,7 +5664,6 @@ def process(filename):
def test_embind_2(self):
if self.emcc_args is None: return self.skip('requires emcc')
- if self.run_name == 'asm2f': return self.skip('embind/asm.js not compatible with PRECISE_F32 because it changes signature strings')
if self.run_name == 'slow2asm': return self.skip('embind/asm.js requires fastcomp')
Building.COMPILER_TEST_OPTS += ['--bind', '--post-js', 'post.js']
open('post.js', 'w').write('''
diff --git a/tests/test_other.py b/tests/test_other.py
index 0721bb35..4560ac6e 100644
--- a/tests/test_other.py
+++ b/tests/test_other.py
@@ -2380,6 +2380,11 @@ int main() {
err = Popen([PYTHON, EMCC, 'src.cpp', '-include', 'header.h', '-Xclang', '-print-stats'], stderr=PIPE).communicate()
assert '*** PCH/Modules Loaded:\nModule: header.h.gch' not in err[1], err[1]
+ # with specified target via -o
+ try_delete('header.h.gch')
+ Popen([PYTHON, EMCC, '-xc++-header', 'header.h', '-o', 'my.gch']).communicate()
+ assert os.path.exists('my.gch')
+
def test_warn_unaligned(self):
if os.environ.get('EMCC_FAST_COMPILER') == '0': return self.skip('need fastcomp')
open('src.cpp', 'w').write(r'''