From a2f95d50985660324812286771dbfdcf7da638a4 Mon Sep 17 00:00:00 2001 From: Jukka Jylänki Date: Thu, 6 Feb 2014 17:07:04 -0500 Subject: Add optimized versions of musl libc string and memory comparison functions. --- emcc | 7 +++ src/library.js | 66 --------------------------- system/lib/libc.symbols | 5 ++ system/lib/libc/musl/src/string/memcmp.c | 8 ++++ system/lib/libc/musl/src/string/strcasecmp.c | 9 ++++ system/lib/libc/musl/src/string/strcmp.c | 7 +++ system/lib/libc/musl/src/string/strncasecmp.c | 10 ++++ system/lib/libc/musl/src/string/strncmp.c | 9 ++++ tools/shared.py | 2 +- 9 files changed, 56 insertions(+), 67 deletions(-) create mode 100644 system/lib/libc/musl/src/string/memcmp.c create mode 100644 system/lib/libc/musl/src/string/strcasecmp.c create mode 100644 system/lib/libc/musl/src/string/strcmp.c create mode 100644 system/lib/libc/musl/src/string/strncasecmp.c create mode 100644 system/lib/libc/musl/src/string/strncmp.c diff --git a/emcc b/emcc index 6bf74707..a5432397 100755 --- a/emcc +++ b/emcc @@ -1476,6 +1476,13 @@ try: ['stdlib', [ 'atof.c', 'strtod.c', + ]], + ['string', [ + 'memcmp.c', + 'strcasecmp.c', + 'strcmp.c', + 'strncasecmp.c', + 'strncmp.c', ]] ] for directory, sources in musl_files: diff --git a/src/library.js b/src/library.js index 26ce8457..98d996ab 100644 --- a/src/library.js +++ b/src/library.js @@ -3754,10 +3754,6 @@ LibraryManager.library = { return pdest; }, - strcmp__deps: ['strncmp'], - strcmp: function(px, py) { - return _strncmp(px, py, TOTAL_MEMORY); - }, // We always assume ASCII locale. strcoll: 'strcmp', strcoll_l__deps: ['strcoll'], @@ -3765,68 +3761,6 @@ LibraryManager.library = { return _strcoll(px, py); // no locale support yet }, - strcasecmp__asm: true, - strcasecmp__sig: 'iii', - strcasecmp__deps: ['strncasecmp'], - strcasecmp: function(px, py) { - px = px|0; py = py|0; - return _strncasecmp(px, py, -1)|0; - }, - - strncmp: function(px, py, n) { - var i = 0; - while (i < n) { - var x = {{{ makeGetValue('px', 'i', 'i8', 0, 1) }}}; - var y = {{{ makeGetValue('py', 'i', 'i8', 0, 1) }}}; - if (x == y && x == 0) return 0; - if (x == 0) return -1; - if (y == 0) return 1; - if (x == y) { - i ++; - continue; - } else { - return x > y ? 1 : -1; - } - } - return 0; - }, - - strncasecmp__asm: true, - strncasecmp__sig: 'iiii', - strncasecmp__deps: ['tolower'], - strncasecmp: function(px, py, n) { - px = px|0; py = py|0; n = n|0; - var i = 0, x = 0, y = 0; - while ((i>>>0) < (n>>>0)) { - x = _tolower({{{ makeGetValueAsm('px', 'i', 'i8', 0, 1) }}})|0; - y = _tolower({{{ makeGetValueAsm('py', 'i', 'i8', 0, 1) }}})|0; - if (((x|0) == (y|0)) & ((x|0) == 0)) return 0; - if ((x|0) == 0) return -1; - if ((y|0) == 0) return 1; - if ((x|0) == (y|0)) { - i = (i + 1)|0; - continue; - } else { - return ((x>>>0) > (y>>>0) ? 1 : -1)|0; - } - } - return 0; - }, - - memcmp__asm: true, - memcmp__sig: 'iiii', - memcmp: function(p1, p2, num) { - p1 = p1|0; p2 = p2|0; num = num|0; - var i = 0, v1 = 0, v2 = 0; - while ((i|0) < (num|0)) { - v1 = {{{ makeGetValueAsm('p1', 'i', 'i8', true) }}}; - v2 = {{{ makeGetValueAsm('p2', 'i', 'i8', true) }}}; - if ((v1|0) != (v2|0)) return ((v1|0) > (v2|0) ? 1 : -1)|0; - i = (i+1)|0; - } - return 0; - }, - memchr: function(ptr, chr, num) { chr = unSign(chr); for (var i = 0; i < num; i++) { diff --git a/system/lib/libc.symbols b/system/lib/libc.symbols index 6f80ef90..705b2c88 100644 --- a/system/lib/libc.symbols +++ b/system/lib/libc.symbols @@ -72,7 +72,12 @@ W realloc_in_place T scalbn T scalbnl + T memcpy T strtod + T strcmp + T strncmp + T strcasecmp + T strncasecmp T strtod_l T strtof T strtof_l diff --git a/system/lib/libc/musl/src/string/memcmp.c b/system/lib/libc/musl/src/string/memcmp.c new file mode 100644 index 00000000..bdbce9f0 --- /dev/null +++ b/system/lib/libc/musl/src/string/memcmp.c @@ -0,0 +1,8 @@ +#include + +int memcmp(const void *vl, const void *vr, size_t n) +{ + const unsigned char *l=vl, *r=vr; + for (; n && *l == *r; n--, l++, r++); + return n ? *l-*r : 0; +} diff --git a/system/lib/libc/musl/src/string/strcasecmp.c b/system/lib/libc/musl/src/string/strcasecmp.c new file mode 100644 index 00000000..02fd5f8c --- /dev/null +++ b/system/lib/libc/musl/src/string/strcasecmp.c @@ -0,0 +1,9 @@ +#include +#include + +int strcasecmp(const char *_l, const char *_r) +{ + const unsigned char *l=(void *)_l, *r=(void *)_r; + for (; *l && *r && (*l == *r || tolower(*l) == tolower(*r)); l++, r++); + return tolower(*l) - tolower(*r); +} diff --git a/system/lib/libc/musl/src/string/strcmp.c b/system/lib/libc/musl/src/string/strcmp.c new file mode 100644 index 00000000..808bd837 --- /dev/null +++ b/system/lib/libc/musl/src/string/strcmp.c @@ -0,0 +1,7 @@ +#include + +int strcmp(const char *l, const char *r) +{ + for (; *l==*r && *l; l++, r++); + return *(unsigned char *)l - *(unsigned char *)r; +} diff --git a/system/lib/libc/musl/src/string/strncasecmp.c b/system/lib/libc/musl/src/string/strncasecmp.c new file mode 100644 index 00000000..24659721 --- /dev/null +++ b/system/lib/libc/musl/src/string/strncasecmp.c @@ -0,0 +1,10 @@ +#include +#include + +int strncasecmp(const char *_l, const char *_r, size_t n) +{ + const unsigned char *l=(void *)_l, *r=(void *)_r; + if (!n--) return 0; + for (; *l && *r && n && (*l == *r || tolower(*l) == tolower(*r)); l++, r++, n--); + return tolower(*l) - tolower(*r); +} diff --git a/system/lib/libc/musl/src/string/strncmp.c b/system/lib/libc/musl/src/string/strncmp.c new file mode 100644 index 00000000..e228843f --- /dev/null +++ b/system/lib/libc/musl/src/string/strncmp.c @@ -0,0 +1,9 @@ +#include + +int strncmp(const char *_l, const char *_r, size_t n) +{ + const unsigned char *l=(void *)_l, *r=(void *)_r; + if (!n--) return 0; + for (; *l && *r && n && *l == *r ; l++, r++, n--); + return *l - *r; +} diff --git a/tools/shared.py b/tools/shared.py index 3b0b92a3..dbf1e3ef 100644 --- a/tools/shared.py +++ b/tools/shared.py @@ -345,7 +345,7 @@ def find_temp_directory(): # we re-check sanity when the settings are changed) # We also re-check sanity and clear the cache when the version changes -EMSCRIPTEN_VERSION = '1.10.1' +EMSCRIPTEN_VERSION = '1.10.2' def generate_sanity(): return EMSCRIPTEN_VERSION + '|' + get_llvm_target() + '|' + LLVM_ROOT + '|' + get_clang_version() -- cgit v1.2.3-18-g5258 From 95b77f9e4abac6cb41a5269d087f296ebfac4f66 Mon Sep 17 00:00:00 2001 From: Jukka Jylänki Date: Thu, 6 Feb 2014 17:26:38 -0500 Subject: Add strcoll as well so that library.js does not need to depend on musl libc code. --- emcc | 1 + src/library.js | 7 ------- system/lib/libc.symbols | 3 +++ system/lib/libc/musl/src/locale/strcoll.c | 15 +++++++++++++++ 4 files changed, 19 insertions(+), 7 deletions(-) create mode 100644 system/lib/libc/musl/src/locale/strcoll.c diff --git a/emcc b/emcc index a5432397..dd329006 100755 --- a/emcc +++ b/emcc @@ -1545,6 +1545,7 @@ try: 'iswspace_l.c', 'iswupper_l.c', 'iswxdigit_l.c', + 'strcoll.c', 'strcasecmp_l.c', 'strfmon.c', 'strncasecmp_l.c', diff --git a/src/library.js b/src/library.js index 98d996ab..22fffb88 100644 --- a/src/library.js +++ b/src/library.js @@ -3754,13 +3754,6 @@ LibraryManager.library = { return pdest; }, - // We always assume ASCII locale. - strcoll: 'strcmp', - strcoll_l__deps: ['strcoll'], - strcoll_l: function(px, py) { - return _strcoll(px, py); // no locale support yet - }, - memchr: function(ptr, chr, num) { chr = unSign(chr); for (var i = 0; i < num; i++) { diff --git a/system/lib/libc.symbols b/system/lib/libc.symbols index 705b2c88..c427cf6f 100644 --- a/system/lib/libc.symbols +++ b/system/lib/libc.symbols @@ -74,6 +74,9 @@ T scalbnl T memcpy T strtod + T strcoll + T __strcoll_l + W strcoll_l T strcmp T strncmp T strcasecmp diff --git a/system/lib/libc/musl/src/locale/strcoll.c b/system/lib/libc/musl/src/locale/strcoll.c new file mode 100644 index 00000000..39ea1123 --- /dev/null +++ b/system/lib/libc/musl/src/locale/strcoll.c @@ -0,0 +1,15 @@ +#include +#include +#include "libc.h" + +int __strcoll_l(const char *l, const char *r, locale_t loc) +{ + return strcmp(l, r); +} + +int strcoll(const char *l, const char *r) +{ + return __strcoll_l(l, r, 0); +} + +weak_alias(__strcoll_l, strcoll_l); -- cgit v1.2.3-18-g5258 From 1df678f09958e9f8f8fcd386ed200540b9702cc4 Mon Sep 17 00:00:00 2001 From: Jukka Jylänki Date: Thu, 6 Feb 2014 17:43:56 -0500 Subject: Add missing memcmp symbol declaration from previous commit. --- system/lib/libc.symbols | 1 + 1 file changed, 1 insertion(+) diff --git a/system/lib/libc.symbols b/system/lib/libc.symbols index c427cf6f..53a27082 100644 --- a/system/lib/libc.symbols +++ b/system/lib/libc.symbols @@ -72,6 +72,7 @@ W realloc_in_place T scalbn T scalbnl + T memcmp T memcpy T strtod T strcoll -- cgit v1.2.3-18-g5258 From 25fcd51cd5c5f06fbfba6c07b00904e32c440b87 Mon Sep 17 00:00:00 2001 From: Jukka Jylänki Date: Thu, 6 Feb 2014 18:05:30 -0500 Subject: Revert strcmp.c to musl v0.9.13 so that the versions in this pull request match the ones that waywardmonkeys has pushed in earlier. --- system/lib/libc/musl/src/string/strcmp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/lib/libc/musl/src/string/strcmp.c b/system/lib/libc/musl/src/string/strcmp.c index 808bd837..91eb7404 100644 --- a/system/lib/libc/musl/src/string/strcmp.c +++ b/system/lib/libc/musl/src/string/strcmp.c @@ -2,6 +2,6 @@ int strcmp(const char *l, const char *r) { - for (; *l==*r && *l; l++, r++); + for (; *l==*r && *l && *r; l++, r++); return *(unsigned char *)l - *(unsigned char *)r; } -- cgit v1.2.3-18-g5258 From 831bb584a91f5409af5df3c44f1bc8dc354ff0d8 Mon Sep 17 00:00:00 2001 From: Jukka Jylänki Date: Thu, 6 Feb 2014 22:02:40 -0500 Subject: Fix test_strcmp_uni and test_dlfcn_stacks after previous commit. --- tests/core/test_strcmp_uni.out | 6 +++--- tests/test_core.py | 7 ++++++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/tests/core/test_strcmp_uni.out b/tests/core/test_strcmp_uni.out index 58e237d7..ebfe2c8e 100644 --- a/tests/core/test_strcmp_uni.out +++ b/tests/core/test_strcmp_uni.out @@ -1,3 +1,3 @@ -Compare value strncmp is -1 -Compare value strncasecmp is -1 -Compare value memcmp is -1 +Compare value strncmp is -108 +Compare value strncasecmp is -76 +Compare value memcmp is -108 diff --git a/tests/test_core.py b/tests/test_core.py index 55aeb697..eda5c8ff 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -3258,6 +3258,7 @@ def process(filename): #include #include #include + #include typedef int (*FUNCTYPE)(const char *); @@ -3268,6 +3269,10 @@ def process(filename): snprintf(str, sizeof(str), "foobar"); + // HACK: Use strcmp in the main executable so that it doesn't get optimized out and the dynamic library + // is able to use it. + assert(!strcmp(str, "foobar")); + lib_handle = dlopen("liblib.so", RTLD_NOW); assert(lib_handle != NULL); @@ -3280,7 +3285,7 @@ def process(filename): return 0; } ''' - Settings.EXPORTED_FUNCTIONS = ['_main', '_malloc'] + Settings.EXPORTED_FUNCTIONS = ['_main', '_malloc', '_strcmp'] self.do_run(src, 'success', force_c=True, post_build=self.dlfcn_post_build) def test_dlfcn_funcs(self): -- cgit v1.2.3-18-g5258