diff options
-rw-r--r-- | AUTHORS | 2 | ||||
-rwxr-xr-x | emcc | 8 | ||||
-rw-r--r-- | src/embind/embind.js | 11 | ||||
-rw-r--r-- | src/library.js | 23 | ||||
-rw-r--r-- | src/library_browser.js | 2 | ||||
-rw-r--r-- | src/library_sdl.js | 6 | ||||
-rw-r--r-- | src/preamble.js | 12 | ||||
-rw-r--r-- | src/relooper/Relooper.cpp | 11 | ||||
-rw-r--r-- | system/include/emscripten/bind.h | 2 | ||||
-rw-r--r-- | system/lib/embind/bind.cpp | 1 | ||||
-rw-r--r-- | tests/cases/redundantswitch_fastcomp.ll | 28 | ||||
-rw-r--r-- | tests/cases/redundantswitch_fastcomp.txt | 2 | ||||
-rw-r--r-- | tests/core/test_sscanf_hex.in | 24 | ||||
-rw-r--r-- | tests/core/test_sscanf_hex.out | 3 | ||||
-rw-r--r-- | tests/embind/embind.test.js | 15 | ||||
-rw-r--r-- | tests/embind/embind_test.cpp | 5 | ||||
-rw-r--r-- | tests/test_core.py | 3 | ||||
-rw-r--r-- | tests/test_other.py | 5 |
18 files changed, 127 insertions, 36 deletions
@@ -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> @@ -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''' |