diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/cases/fixablebadcasts_fastcomp.ll | 27 | ||||
-rw-r--r-- | tests/cases/fixablebadcasts_fastcomp.txt | 1 | ||||
-rw-r--r-- | tests/cases/returnnan_fastcomp.ll | 34 | ||||
-rw-r--r-- | tests/cases/returnnan_fastcomp.txt | 3 | ||||
-rw-r--r-- | tests/core/test_inlinejs3.in | 1 | ||||
-rw-r--r-- | tests/core/test_inlinejs3.out | 1 | ||||
-rw-r--r-- | tests/dirent/test_readdir_empty.c | 47 | ||||
-rw-r--r-- | tests/embind/embind.test.js | 76 | ||||
-rw-r--r-- | tests/embind/embind_test.cpp | 59 | ||||
-rw-r--r-- | tests/fs/test_idbfs_sync.c | 26 | ||||
-rw-r--r-- | tests/hello_world.ll | 9 | ||||
-rw-r--r-- | tests/test_core.py | 4 | ||||
-rw-r--r-- | tests/test_other.py | 16 |
13 files changed, 284 insertions, 20 deletions
diff --git a/tests/cases/fixablebadcasts_fastcomp.ll b/tests/cases/fixablebadcasts_fastcomp.ll new file mode 100644 index 00000000..3870e0e0 --- /dev/null +++ b/tests/cases/fixablebadcasts_fastcomp.ll @@ -0,0 +1,27 @@ +; ModuleID = 'tests/hello_world.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 [18 x i8] c"hello, world %d!\0A\00", align 1 + +; [#uses=0] +define i32 @main() { +entry: + %retval = alloca i32, align 4 ; [#uses=1 type=i32*] + store i32 0, i32* %retval + %a = call i32 bitcast (i32 (i32)* @twoparam to i32 (i32, i32)*)(i32 5, i32 6) + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([18 x i8]* @.str, i32 0, i32 0), i32 %a) ; [#uses=0 type=i32] + call void bitcast (void (i32, i32*, i32*)* @_ZN7WebCore33signedPublicKeyAndChallengeStringEjRKN3WTF6StringERKNS_3URLE to void (i32*, i32, i32*, i32*)*)(i32* sret null, i32 0, i32* null, i32* null) + ret i32 1 +} + +define i32 @twoparam(i32 %x) { + ret i32 %x +} + +define void @_ZN7WebCore33signedPublicKeyAndChallengeStringEjRKN3WTF6StringERKNS_3URLE(i32, i32* nocapture, i32* nocapture) { + ret void +} + +; [#uses=1] +declare i32 @printf(i8*, ...) diff --git a/tests/cases/fixablebadcasts_fastcomp.txt b/tests/cases/fixablebadcasts_fastcomp.txt new file mode 100644 index 00000000..47abd748 --- /dev/null +++ b/tests/cases/fixablebadcasts_fastcomp.txt @@ -0,0 +1 @@ +hello, world 5! diff --git a/tests/cases/returnnan_fastcomp.ll b/tests/cases/returnnan_fastcomp.ll new file mode 100644 index 00000000..3a6a9f9e --- /dev/null +++ b/tests/cases/returnnan_fastcomp.ll @@ -0,0 +1,34 @@ +; ModuleID = 'tests/hello_world.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 [18 x i8] c"hello, world %f!\0A\00", align 1 + +define i32 @main() { +entry: + %retval = alloca i32, align 4 + store i32 0, i32* %retval + %f = call double @nand() + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([18 x i8]* @.str, i32 0, i32 0), double %f) + %g = call double @zerod() + %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([18 x i8]* @.str, i32 0, i32 0), double %g) + %h = call float @zerof() + %hd = fpext float %h to double + %call3 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([18 x i8]* @.str, i32 0, i32 0), double %hd) + ret i32 1 +} + +define double @nand() unnamed_addr align 2 { + ret double 0x7FF8000000000000 +} + +define double @zerod() unnamed_addr align 2 { + ret double 0x0000000000000000 +} + +define float @zerof() unnamed_addr align 2 { + ret float 0x0000000000000000 +} + +declare i32 @printf(i8*, ...) + diff --git a/tests/cases/returnnan_fastcomp.txt b/tests/cases/returnnan_fastcomp.txt new file mode 100644 index 00000000..f11733ba --- /dev/null +++ b/tests/cases/returnnan_fastcomp.txt @@ -0,0 +1,3 @@ +hello, world nan! +hello, world 0.000000! +hello, world 0.000000! diff --git a/tests/core/test_inlinejs3.in b/tests/core/test_inlinejs3.in index b45abe95..c3b9b769 100644 --- a/tests/core/test_inlinejs3.in +++ b/tests/core/test_inlinejs3.in @@ -13,6 +13,7 @@ int main(int argc, char **argv) { EM_ASM(Module.print('hello dere3'); Module.print('hello dere' + 4);); } EM_ASM_({ Module.print('hello input ' + $0) }, 123); + EM_ASM_ARGS({ Module.print('hello input ' + $0) }, 456); int sum = 0; for (int i = 0; i < argc * 3; i++) { sum += EM_ASM_INT({ diff --git a/tests/core/test_inlinejs3.out b/tests/core/test_inlinejs3.out index 5d185adc..c48cc3c8 100644 --- a/tests/core/test_inlinejs3.out +++ b/tests/core/test_inlinejs3.out @@ -7,6 +7,7 @@ hello dere4 hello dere3 hello dere4 hello input 123 +hello input 456 i: 0,0.00 i: 1,0.08 i: 2,0.17 diff --git a/tests/dirent/test_readdir_empty.c b/tests/dirent/test_readdir_empty.c new file mode 100644 index 00000000..00102733 --- /dev/null +++ b/tests/dirent/test_readdir_empty.c @@ -0,0 +1,47 @@ +#include <stdio.h> +#include <dirent.h> +#include <sys/stat.h> +#include <string.h> +#include <errno.h> + + +int main(int argc, char** argv) { + if (mkdir("/tmp", S_IRWXG) != 0 && errno != EEXIST) { + printf("Unable to create dir '/tmp'\n"); + return -1; + } + + if (mkdir("/tmp/1", S_IRWXG) != 0 && errno != EEXIST) { + printf("Unable to create dir '/tmp/1'\n"); + return -1; + } + + if (mkdir("/tmp/1/", S_IRWXG) != 0 && errno != EEXIST) { + printf("Unable to create dir '/tmp/1/'\n"); + return -1; + } + + DIR *dir = opendir("/tmp"); + + if (!dir) { + printf("Unable to open dir '/tmp'\n"); + return -2; + } + + struct dirent *dirent; + + while ((dirent = readdir(dir)) != 0) { + printf("Found '%s'\n", dirent->d_name); + + if (strlen(dirent->d_name) == 0) { + printf("Found empty path!\n"); + return -3; + } + } + + closedir(dir); + + printf("success\n"); + return 0; +} + diff --git a/tests/embind/embind.test.js b/tests/embind/embind.test.js index 5ca972be..e2160c33 100644 --- a/tests/embind/embind.test.js +++ b/tests/embind/embind.test.js @@ -1938,10 +1938,84 @@ module({ derived.delete(); // Let the memory leak test superfixture check that no leaks occurred. }); + + BaseFixture.extend("val::as", function() { + test("built-ins", function() { + assert.equal(true, cm.val_as_bool(true)); + assert.equal(false, cm.val_as_bool(false)); + assert.equal(127, cm.val_as_char(127)); + assert.equal(32767, cm.val_as_short(32767)); + assert.equal(65536, cm.val_as_int(65536)); + assert.equal(65536, cm.val_as_long(65536)); + assert.equal(10.5, cm.val_as_float(10.5)); + assert.equal(10.5, cm.val_as_double(10.5)); + + assert.equal("foo", cm.val_as_string("foo")); + assert.equal("foo", cm.val_as_wstring("foo")); + + var obj = {}; + assert.equal(obj, cm.val_as_val(obj)); + + // JS->C++ memory view not implemented + //var ab = cm.val_as_memory_view(new ArrayBuffer(13)); + //assert.equal(13, ab.byteLength); + }); + + test("value types", function() { + var tuple = [1, 2, 3, 4]; + assert.deepEqual(tuple, cm.val_as_value_array(tuple)); + + var struct = {x: 1, y: 2, z: 3, w: 4}; + assert.deepEqual(struct, cm.val_as_value_object(struct)); + }); + + test("enums", function() { + assert.equal(cm.Enum.ONE, cm.val_as_enum(cm.Enum.ONE)); + }); + }); + + BaseFixture.extend("val::new_", function() { + test("variety of types", function() { + function factory() { + this.arguments = Array.prototype.slice.call(arguments, 0); + } + var instance = cm.construct_with_6_arguments(factory); + assert.deepEqual( + [6, -12.5, "a3", {x: 1, y: 2, z: 3, w: 4}, cm.EnumClass.TWO, [-1, -2, -3, -4]], + instance.arguments); + }); + + test("memory view", function() { + function factory(before, view, after) { + this.before = before; + this.view = view; + this.after = after; + } + + var instance = cm.construct_with_memory_view(factory); + assert.equal("before", instance.before); + assert.equal(10, instance.view.byteLength); + assert.equal("after", instance.after); + }); + + test("ints_and_float", function() { + function factory(a, b, c) { + this.a = a; + this.b = b; + this.c = c; + } + + var instance = cm.construct_with_ints_and_float(factory); + assert.equal(65537, instance.a); + assert.equal(4.0, instance.b); + assert.equal(65538, instance.c); + }); + }); }); /* global run_all_tests */ // If running as part of the emscripten test runner suite, and not as part of the IMVU suite, // we launch the test execution from here. IMVU suite uses its own dedicated mechanism instead of this. -if (typeof run_all_tests !== "undefined") +if (typeof run_all_tests !== "undefined") { run_all_tests(); +} diff --git a/tests/embind/embind_test.cpp b/tests/embind/embind_test.cpp index 4efc4bd8..d299660a 100644 --- a/tests/embind/embind_test.cpp +++ b/tests/embind/embind_test.cpp @@ -842,7 +842,7 @@ Enum emval_test_take_and_return_Enum(Enum e) { return e; } -enum class EnumClass { ONE, TWO }; +enum class EnumClass : char { ONE, TWO }; EnumClass emval_test_take_and_return_EnumClass(EnumClass e) { return e; @@ -2304,3 +2304,60 @@ EMSCRIPTEN_BINDINGS(mixins) { .constructor<>() ); } + +template<typename T> +T val_as(const val& v) { + return v.as<T>(); +} + +EMSCRIPTEN_BINDINGS(val_as) { + function("val_as_bool", &val_as<bool>); + function("val_as_char", &val_as<char>); + function("val_as_short", &val_as<short>); + function("val_as_int", &val_as<int>); + function("val_as_long", &val_as<long>); + + function("val_as_float", &val_as<float>); + function("val_as_double", &val_as<double>); + + function("val_as_string", &val_as<std::string>); + function("val_as_wstring", &val_as<std::wstring>); + function("val_as_val", &val_as<val>); + + function("val_as_value_object", &val_as<StructVector>); + function("val_as_value_array", &val_as<TupleVector>); + + function("val_as_enum", &val_as<Enum>); + + // memory_view is always JS -> C++ + //function("val_as_memory_view", &val_as<memory_view>); +} + +val construct_with_6(val factory) { + unsigned char a1 = 6; + double a2 = -12.5; + std::string a3("a3"); + StructVector a4(1, 2, 3, 4); + EnumClass a5 = EnumClass::TWO; + TupleVector a6(-1, -2, -3, -4); + return factory.new_(a1, a2, a3, a4, a5, a6); +} + +val construct_with_memory_view(val factory) { + static const char data[11] = "0123456789"; + return factory.new_( + std::string("before"), + memory_view(10, data), + std::string("after")); +} + +val construct_with_ints_and_float(val factory) { + static const char data[11] = "0123456789"; + return factory.new_(65537, 4.0f, 65538); +} + +EMSCRIPTEN_BINDINGS(val_new_) { + function("construct_with_6_arguments", &construct_with_6); + function("construct_with_memory_view", &construct_with_memory_view); + function("construct_with_ints_and_float", &construct_with_ints_and_float); +} diff --git a/tests/fs/test_idbfs_sync.c b/tests/fs/test_idbfs_sync.c index ff356416..0d8f4d71 100644 --- a/tests/fs/test_idbfs_sync.c +++ b/tests/fs/test_idbfs_sync.c @@ -1,8 +1,6 @@ #include <stdio.h> #include <emscripten.h> -#define EM_ASM_REEXPAND(x) EM_ASM(x) - void success() { int result = 1; REPORT_RESULT(); @@ -15,31 +13,35 @@ int main() { ); #if FIRST - // store local files to backing IDB - EM_ASM_REEXPAND( + // store local files to backing IDB. Note that we use the JS FS API for everything here, but we + // could use normal libc fwrite etc. to do the writing. All we need the JS FS API for is to + // mount the filesystem and do syncfs. + EM_ASM_ARGS({ FS.writeFile('/working/waka.txt', 'az'); - FS.writeFile('/working/moar.txt', SECRET); + FS.writeFile('/working/moar.txt', $0); FS.syncfs(function (err) { assert(!err); - ccall('success', 'v', '', []); + ccall('success', 'v'); }); - ); + }, SECRET); #else // load files from backing IDB - EM_ASM_REEXPAND( + EM_ASM_ARGS({ FS.syncfs(true, function (err) { assert(!err); var contents = FS.readFile('/working/waka.txt', { encoding: 'utf8' }); - assert(contents === 'az'); + assert(contents === 'az', 'bad contents ' + contents); - var secret = FS.readFile('/working/moar.txt', { encoding: 'utf8' }); - assert(secret === SECRET); + // note we convert to a number here (using +), since we used writeFile, which writes a + // JS string. + var secret = +FS.readFile('/working/moar.txt', { encoding: 'utf8' }); + assert(secret === $0, 'bad secret ' + [secret, $0, typeof secret, typeof $0]); ccall('success', 'v', '', []); }); - ); + }, SECRET); #endif emscripten_exit_with_live_runtime(); diff --git a/tests/hello_world.ll b/tests/hello_world.ll index ab4b199f..7090b732 100644 --- a/tests/hello_world.ll +++ b/tests/hello_world.ll @@ -2,16 +2,15 @@ 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 [15 x i8] c"hello, world!\0A\00", align 1 ; [#uses=1 type=[15 x i8]*] +@.str = private unnamed_addr constant [15 x i8] c"hello, world!\0A\00", align 1 -; [#uses=0] define i32 @main() { entry: - %retval = alloca i32, align 4 ; [#uses=1 type=i32*] + %retval = alloca i32, align 4 store i32 0, i32* %retval - %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([15 x i8]* @.str, i32 0, i32 0)) ; [#uses=0 type=i32] + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([15 x i8]* @.str, i32 0, i32 0)) ret i32 1 } -; [#uses=1] declare i32 @printf(i8*, ...) + diff --git a/tests/test_core.py b/tests/test_core.py index 885a0c52..d5b855b9 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -4097,6 +4097,10 @@ def process(filename): src = open(path_from_root('tests', 'dirent', 'test_readdir.c'), 'r').read() self.do_run(src, 'success', force_c=True) + def test_readdir_empty(self): + src = open(path_from_root('tests', 'dirent', 'test_readdir_empty.c'), 'r').read() + self.do_run(src, 'success', force_c=True) + def test_stat(self): src = open(path_from_root('tests', 'stat', 'test_stat.c'), 'r').read() self.do_run(src, 'success', force_c=True) diff --git a/tests/test_other.py b/tests/test_other.py index 0f5a4191..aae399c8 100644 --- a/tests/test_other.py +++ b/tests/test_other.py @@ -2536,9 +2536,10 @@ int main() (['-Wno-error=implicit-function-declaration'], ['abort()', 'it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this'], [IMPLICIT_WARNING]), # turn error into warning (['-Wno-implicit-function-declaration'], ['abort()', 'it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this'], []), # turn error into nothing at all (['-Wno-error=implicit-function-declaration', '-s', 'ASSERTIONS=2'], ['abort()', 'This pointer might make sense in another type signature'], []), - (['-Wno-error=implicit-function-declaration', '-O1'], ['hello 2\nhello 5\n'], []), # invalid output - second arg is sent as varargs, but needs to be int. llvm optimizer avoided the crash silently, caused undefined behavior... at least people can debug this by running an -O0 build. + (['-Wno-error=implicit-function-declaration', '-O1'], ['hello 0\nhello 0\n'], []), # invalid output - second arg is sent as varargs, but needs to be int. llvm optimizer avoided the crash silently, caused undefined behavior... at least people can debug this by running an -O0 build. ]: print opts, expected + try_delete('a.out.js') stdout, stderr = Popen([PYTHON, EMCC, 'src.c'] + opts, stderr=PIPE).communicate() for ce in compile_expected + ['''warning: incompatible pointer types''']: self.assertContained(ce, stderr) @@ -2580,6 +2581,19 @@ int main() out, err = Popen([PYTHON, EMCC, 'a.bc'], stdout=PIPE, stderr=PIPE).communicate() assert 'warning' in err, err assert 'incorrect target triple' in err, err + + def test_valid_abspath(self): + # Test whether abspath warning appears + abs_include_path = path_from_root('tests') + process = Popen([PYTHON, EMCC, '-I%s' % abs_include_path, path_from_root('tests', 'hello_world.c')], stdout=PIPE, stderr=PIPE) + out, err = process.communicate() + warning = '-I or -L of an absolute path "-I%s" encountered. If this is to a local system header/library, it may cause problems (local system files make sense for compiling natively on your system, but not necessarily to JavaScript). Pass \'-Wno-warn-absolute-paths\' to emcc to hide this warning.' % abs_include_path + assert(warning in err) + + # Hide warning for this include path + process = Popen([PYTHON, EMCC, '--valid-abspath', abs_include_path,'-I%s' % abs_include_path, path_from_root('tests', 'hello_world.c')], stdout=PIPE, stderr=PIPE) + out, err = process.communicate() + assert(warning not in err) def test_simplify_ifs(self): def test(src, nums): |