aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/cases/fp80_ta2.ll21
-rw-r--r--tests/cases/phiptrtoint.ll138
-rw-r--r--tests/cases/phiptrtoint.txt0
-rw-r--r--tests/cases/sub_11_0.ll16
-rw-r--r--tests/gles2_uniform_arrays.cpp121
-rwxr-xr-xtests/runner.py9
-rw-r--r--tests/sdl_rotozoom.c2
-rw-r--r--tests/sdl_rotozoom.pngbin431168 -> 711242 bytes
-rw-r--r--tests/stdio/test_rename.c10
-rw-r--r--tests/test_browser.py6
-rw-r--r--tests/test_core.py106
-rw-r--r--tests/test_other.py80
-rw-r--r--tests/test_sanity.py9
13 files changed, 442 insertions, 76 deletions
diff --git a/tests/cases/fp80_ta2.ll b/tests/cases/fp80_ta2.ll
deleted file mode 100644
index 7fc0db4a..00000000
--- a/tests/cases/fp80_ta2.ll
+++ /dev/null
@@ -1,21 +0,0 @@
-; ModuleID = 'src.cpp.o'
-target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"
-target triple = "i386-pc-linux-gnu"
-
-@.str = private unnamed_addr constant [15 x i8] c"hello, world!\0A\00" ; [#uses=1]
-
-; [#uses=0]
-define i32 @main() {
-entry:
- %x = zext i32 0 to x86_fp80
- %1 = bitcast x86_fp80 %x to i80
- %2 = trunc i80 %1 to i32
- %retval = alloca i32, align 4 ; [#uses=1]
- store i32 0, i32* %retval
- %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([15 x i8]* @.str, i32 0, i32 0)) ; [#uses=0]
- ret i32 0
-}
-
-; [#uses=1]
-declare i32 @printf(i8*, ...)
-
diff --git a/tests/cases/phiptrtoint.ll b/tests/cases/phiptrtoint.ll
new file mode 100644
index 00000000..d682dc06
--- /dev/null
+++ b/tests/cases/phiptrtoint.ll
@@ -0,0 +1,138 @@
+; ModuleID = '/tmp/tmpJctwj0/bug.bc'
+; just an asm validation check, no output
+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:32"
+target triple = "le32-unknown-nacl"
+
+%"class.test::Processor" = type { i32, %"class.test::StateMachine" }
+%"class.test::StateMachine" = type { { i32, i32 } }
+
+@_ZN4test9ProcessorC1Ev = alias internal void (%"class.test::Processor"*)* @_ZN4test9ProcessorC2Ev
+@_ZN4test9ProcessorD1Ev = alias internal void (%"class.test::Processor"*)* @_ZN4test9ProcessorD2Ev
+
+define internal void @_ZN4test9ProcessorC2Ev(%"class.test::Processor"* nocapture %this) unnamed_addr nounwind align 2 {
+ %1 = getelementptr inbounds %"class.test::Processor"* %this, i32 0, i32 0
+ store i32 0, i32* %1, align 4
+ %2 = getelementptr inbounds %"class.test::Processor"* %this, i32 0, i32 1, i32 0
+ store { i32, i32 } zeroinitializer, { i32, i32 }* %2, align 4
+ ret void
+}
+
+define internal void @_ZN4test9ProcessorD2Ev(%"class.test::Processor"* nocapture %this) unnamed_addr nounwind readnone align 2 {
+ ret void
+}
+
+define internal zeroext i1 @_ZN4test9Processor16handleFirstStateEv(%"class.test::Processor"* nocapture %this) align 2 {
+ %1 = tail call i32 @rand()
+ %2 = getelementptr inbounds %"class.test::Processor"* %this, i32 0, i32 0
+ %3 = load i32* %2, align 4
+ %4 = add nsw i32 %3, %1
+ store i32 %4, i32* %2, align 4
+ %5 = and i32 %4, 1
+ %6 = icmp eq i32 %5, 0
+ ret i1 %6
+}
+
+declare i32 @rand()
+
+define internal zeroext i1 @_ZN4test9Processor15handleLastStateEv(%"class.test::Processor"* nocapture %this) align 2 {
+ %1 = tail call i32 @rand()
+ %2 = getelementptr inbounds %"class.test::Processor"* %this, i32 0, i32 0
+ %3 = load i32* %2, align 4
+ %4 = add nsw i32 %3, %1
+ store i32 %4, i32* %2, align 4
+ ret i1 true
+}
+
+define internal zeroext i1 @_ZN4test9Processor3runEv(%"class.test::Processor"* %this) align 2 {
+ %1 = getelementptr inbounds %"class.test::Processor"* %this, i32 0, i32 1, i32 0
+ store { i32, i32 } { i32 ptrtoint (i1 (%"class.test::Processor"*)* @_ZN4test9Processor16handleFirstStateEv to i32), i32 0 }, { i32, i32 }* %1, align 4
+ %2 = bitcast %"class.test::Processor"* %this to i8*
+ br label %.backedge
+
+.backedge: ; preds = %25, %..backedge_crit_edge, %0
+ %3 = phi { i32, i32 } [ { i32 ptrtoint (i1 (%"class.test::Processor"*)* @_ZN4test9Processor16handleFirstStateEv to i32), i32 0 }, %0 ], [ %.pre.pre, %..backedge_crit_edge ], [ { i32 ptrtoint (i1 (%"class.test::Processor"*)* @_ZN4test9Processor15handleLastStateEv to i32), i32 0 }, %25 ]
+ %.fca.0.extract = extractvalue { i32, i32 } %3, 0
+ %.fca.1.extract = extractvalue { i32, i32 } %3, 1
+ %4 = icmp ne i32 %.fca.0.extract, ptrtoint (i1 (%"class.test::Processor"*)* @_ZN4test9Processor15handleLastStateEv to i32)
+ %5 = icmp ne i32 %.fca.0.extract, 0
+ %6 = icmp ne i32 %.fca.1.extract, 0
+ %7 = and i1 %5, %6
+ %8 = or i1 %4, %7
+ %9 = getelementptr inbounds i8* %2, i32 %.fca.1.extract
+ %10 = bitcast i8* %9 to %"class.test::Processor"*
+ %11 = and i32 %.fca.0.extract, 1
+ %12 = icmp eq i32 %11, 0
+ br i1 %12, label %20, label %13
+
+; <label>:13 ; preds = %.backedge
+ %14 = bitcast i8* %9 to i8**
+ %15 = load i8** %14, align 4
+ %16 = add i32 %.fca.0.extract, -1
+ %17 = getelementptr i8* %15, i32 %16
+ %18 = bitcast i8* %17 to i1 (%"class.test::Processor"*)**
+ %19 = load i1 (%"class.test::Processor"*)** %18, align 4
+ br label %_ZN4test12StateMachineINS_9ProcessorEE11handleStateEPS1_.exit
+
+; <label>:20 ; preds = %.backedge
+ %21 = inttoptr i32 %.fca.0.extract to i1 (%"class.test::Processor"*)*
+ br label %_ZN4test12StateMachineINS_9ProcessorEE11handleStateEPS1_.exit
+
+_ZN4test12StateMachineINS_9ProcessorEE11handleStateEPS1_.exit: ; preds = %20, %13
+ %22 = phi i1 (%"class.test::Processor"*)* [ %19, %13 ], [ %21, %20 ]
+ %23 = tail call zeroext i1 %22(%"class.test::Processor"* %10)
+ br i1 %8, label %24, label %26
+
+; <label>:24 ; preds = %_ZN4test12StateMachineINS_9ProcessorEE11handleStateEPS1_.exit
+ br i1 %23, label %25, label %..backedge_crit_edge
+
+..backedge_crit_edge: ; preds = %24
+ %.pre.pre = load { i32, i32 }* %1, align 4
+ br label %.backedge
+
+; <label>:25 ; preds = %24
+ store { i32, i32 } { i32 ptrtoint (i1 (%"class.test::Processor"*)* @_ZN4test9Processor15handleLastStateEv to i32), i32 0 }, { i32, i32 }* %1, align 4
+ br label %.backedge
+
+; <label>:26 ; preds = %_ZN4test12StateMachineINS_9ProcessorEE11handleStateEPS1_.exit
+ ret i1 %23
+}
+
+define internal i32 @_ZNK4test9Processor6resultEv(%"class.test::Processor"* nocapture %this) nounwind readonly align 2 {
+ %1 = getelementptr inbounds %"class.test::Processor"* %this, i32 0, i32 0
+ %2 = load i32* %1, align 4
+ ret i32 %2
+}
+
+define i32 @runProcess() {
+ %processor = alloca %"class.test::Processor", align 4
+ call void @_ZN4test9ProcessorC1Ev(%"class.test::Processor"* %processor)
+ %1 = invoke zeroext i1 @_ZN4test9Processor3runEv(%"class.test::Processor"* %processor)
+ to label %2 unwind label %5
+
+; <label>:2 ; preds = %0
+ %3 = invoke i32 @_ZNK4test9Processor6resultEv(%"class.test::Processor"* %processor)
+ to label %4 unwind label %5
+
+; <label>:4 ; preds = %2
+ call void @_ZN4test9ProcessorD1Ev(%"class.test::Processor"* %processor)
+ ret i32 %3
+
+; <label>:5 ; preds = %2, %0
+ %6 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ cleanup
+ invoke void @_ZN4test9ProcessorD1Ev(%"class.test::Processor"* %processor)
+ to label %7 unwind label %8
+
+; <label>:7 ; preds = %5
+ resume { i8*, i32 } %6
+
+; <label>:8 ; preds = %5
+ %9 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ catch i8* null
+ call void @_ZSt9terminatev() noreturn nounwind
+ unreachable
+}
+
+declare i32 @__gxx_personality_v0(...)
+
+declare void @_ZSt9terminatev()
diff --git a/tests/cases/phiptrtoint.txt b/tests/cases/phiptrtoint.txt
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/tests/cases/phiptrtoint.txt
diff --git a/tests/cases/sub_11_0.ll b/tests/cases/sub_11_0.ll
new file mode 100644
index 00000000..7f0bb285
--- /dev/null
+++ b/tests/cases/sub_11_0.ll
@@ -0,0 +1,16 @@
+; ModuleID = 'tests/hello_world.bc'
+
+@.str = private unnamed_addr constant [15 x i8] c"hello, world!\0A\00", align 1 ; [#uses=1 type=[15 x i8]*]
+
+; [#uses=0]
+define i32 @main() {
+entry:
+ %retval = alloca i32, align 4 ; [#uses=1 type=i32*]
+ %0 = sub nsw i32 1, 1
+ 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]
+ ret i32 1
+}
+
+; [#uses=1]
+declare i32 @printf(i8*, ...)
diff --git a/tests/gles2_uniform_arrays.cpp b/tests/gles2_uniform_arrays.cpp
new file mode 100644
index 00000000..84e394dc
--- /dev/null
+++ b/tests/gles2_uniform_arrays.cpp
@@ -0,0 +1,121 @@
+#include "SDL/SDL_opengl.h"
+#include "SDL/SDL.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+void RunTest(int testVariant)
+{
+ GLuint vs = 0;
+
+ const char *vsCode = "#version 100\n"
+ "attribute vec4 pos; void main() { gl_Position = pos; }";
+
+ vs = glCreateShader(GL_VERTEX_SHADER);
+ glShaderSource(vs, 1, &vsCode, NULL);
+ glCompileShader(vs);
+
+ GLuint ps = 0;
+
+ const char *psCode = "#version 100\n"
+ "precision lowp float;\n"
+ "uniform vec3 color;\n"
+ "uniform vec3 colors[3];\n"
+ "void main() { gl_FragColor = vec4(color,1) + vec4(colors[0].r, colors[1].g, colors[2].b, 1); }";
+
+ ps = glCreateShader(GL_FRAGMENT_SHADER);
+ glShaderSource(ps, 1, &psCode, NULL);
+ glCompileShader(ps);
+
+ GLuint program = 0;
+ program = glCreateProgram();
+ glAttachShader(program, vs);
+ glAttachShader(program, ps);
+ glBindAttribLocation(program, 0, "pos");
+ glLinkProgram(program);
+
+ int color_loc = glGetUniformLocation(program, "color");
+ assert(color_loc != -1);
+
+ glUseProgram(program);
+ float col[3] = { 0.2f, 0.2f, 0.2f };
+ glUniform3fv(color_loc, 1, col);
+
+ int loc = glGetUniformLocation(program, "colors");
+ assert(loc != -1);
+ // In previous Emscripten GL layer code, calling glGetUniformLocation would do extra caching operations that interacts how glUniform** after that will work,
+ // so to exhibit extra issues in old code (and to keep new code from regressing), must test both with and without excess glGetUniformLocation calls.
+ if ((testVariant&1) != 0)
+ {
+ // Deliberately check in odd order to make sure any kind of lazy operations won't affect the indices we get.
+ assert(glGetUniformLocation(program, "colors[2]") == loc+2);
+ assert(glGetUniformLocation(program, "colors[0]") == loc);
+ assert(glGetUniformLocation(program, "colors[3]") == -1);
+ assert(glGetUniformLocation(program, "colors[1]") == loc+1);
+ assert(glGetUniformLocation(program, "colors[]") == loc);
+ assert(glGetUniformLocation(program, "colors[-100]") == -1);
+ assert(glGetUniformLocation(program, "colors[bleh]") == -1);
+ }
+
+ float colors[4*3] = { 1,0,0, 0,0.5,0, 0,0,0.2, 1,1,1 };
+
+ if ((testVariant&2)!=0)
+ {
+ glUniform3fv(loc+1, 3, colors+3); // Pass the actual colors (testing a nonzero location offset), but do a mistake by setting one index too many. Spec says this should be gracefully handled, and that excess elements are ignored.
+ assert(glGetError() == GL_NO_ERROR);
+ glUniform3fv(loc, 1, colors); // Set the first index as well.
+ assert(glGetError() == GL_NO_ERROR);
+ }
+ else
+ {
+ glUniform3fv(loc, 4, colors); // Just directly set the full array.
+ assert(glGetError() == GL_NO_ERROR);
+ }
+
+ assert(glGetError() == GL_NO_ERROR);
+
+ GLuint vbo = 0;
+ const GLfloat v[] = { -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1 };
+ glGenBuffers(1, &vbo);
+ glBindBuffer(GL_ARRAY_BUFFER, vbo);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(v), v, GL_STATIC_DRAW);
+
+ glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2*sizeof(GLfloat), 0);
+ glEnableVertexAttribArray(0);
+
+ glDrawArrays(GL_TRIANGLES, 0, 6);
+
+ unsigned char pixel[4];
+ glReadPixels(1,1,1,1,GL_RGBA,GL_UNSIGNED_BYTE, pixel);
+ //printf("%d,%d,%d,%d\n", pixel[0], pixel[1], pixel[2], pixel[3]);
+ assert(pixel[0] == 255);
+ assert(pixel[1] == 178);
+ assert(pixel[2] == 102);
+ assert(pixel[3] == 255);
+
+ printf("OK: Case %d passed.\n", testVariant);
+ // Lazy, don't clean up afterwards.
+}
+
+int main(int argc, char *argv[])
+{
+ SDL_Surface *screen;
+
+ // Slightly different SDL initialization
+ if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) {
+ printf("Unable to initialize SDL: %s\n", SDL_GetError());
+ return 1;
+ }
+
+ screen = SDL_SetVideoMode( 640, 480, 16, SDL_OPENGL ); // *changed*
+ if ( !screen ) {
+ printf("Unable to set video mode: %s\n", SDL_GetError());
+ return 1;
+ }
+
+ for(int i = 0; i < 4; ++i)
+ RunTest(i);
+
+ return 0;
+}
diff --git a/tests/runner.py b/tests/runner.py
index ddc97ea4..867f7113 100755
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -737,13 +737,15 @@ if __name__ == '__main__':
print '''
==============================================================================
Running the main part of the test suite. Don't forget to run the other parts!
+A recommended order is:
- other - tests separate from the main suite
sanity - tests for first run, etc., modifies ~/.emscripten
- benchmark - run before and after each set of changes before pushing to
- master, verify no regressions
+ (the main test suite)
+ other - tests separate from the main suite
browser - runs pages in a web browser
sockets - runs websocket networking tests
+ benchmark - run before and after each set of changes before pushing to
+ master, verify no regressions
There are also commands to run specific subsets of the test suite:
@@ -799,3 +801,4 @@ an individual test with
# Return the number of failures as the process exit code for automating success/failure reporting.
exit(numFailures)
+
diff --git a/tests/sdl_rotozoom.c b/tests/sdl_rotozoom.c
index cdbdcc6f..2c0d35df 100644
--- a/tests/sdl_rotozoom.c
+++ b/tests/sdl_rotozoom.c
@@ -38,7 +38,7 @@ int main(int argc, char **argv) {
sprite[2] = zoomSurface(sprite[0], 0.5, 0.5, SMOOTHING_ON);
sprite[3] = zoomSurface(sprite[1], 0.5, 0.5, SMOOTHING_ON);
sprite[4] = rotozoomSurface(sprite[0], -20, 0.3, SMOOTHING_ON);
- sprite[5] = rotozoomSurface(sprite[1], 45, 0.5, SMOOTHING_ON);
+ sprite[5] = rotozoomSurface(sprite[1], 20, 1, SMOOTHING_ON);
sprite[6] = zoomSurface(sprite[0], -0.5, 0.5, SMOOTHING_ON);
sprite[7] = zoomSurface(sprite[0], -0.5, -0.5, SMOOTHING_ON);
sprite[8] = rotozoomSurface(sprite[1], 0, 0.5, SMOOTHING_ON);
diff --git a/tests/sdl_rotozoom.png b/tests/sdl_rotozoom.png
index 5933754f..ebde79f2 100644
--- a/tests/sdl_rotozoom.png
+++ b/tests/sdl_rotozoom.png
Binary files differ
diff --git a/tests/stdio/test_rename.c b/tests/stdio/test_rename.c
index f15c8140..1a5017c1 100644
--- a/tests/stdio/test_rename.c
+++ b/tests/stdio/test_rename.c
@@ -25,6 +25,8 @@ void setup() {
mkdir("dir/subdir", 0777);
mkdir("dir-readonly", 0555);
mkdir("dir-nonempty", 0777);
+ mkdir("dir/subdir3", 0777);
+ mkdir("dir/subdir3/subdir3_1", 0777);
create_file("dir-nonempty/file", "abcdef", 0777);
}
@@ -38,6 +40,9 @@ void cleanup() {
rmdir("dir/subdir");
rmdir("dir/subdir1");
rmdir("dir/subdir2");
+ rmdir("dir/subdir3/subdir3_1/subdir1 renamed");
+ rmdir("dir/subdir3/subdir3_1");
+ rmdir("dir/subdir3");
rmdir("dir");
rmdir("dir-readonly");
unlink("dir-nonempty/file");
@@ -96,6 +101,11 @@ void test() {
err = access("dir/subdir2", F_OK);
assert(!err);
+ err = rename("dir/subdir2", "dir/subdir3/subdir3_1/subdir1 renamed");
+ assert(!err);
+ err = access("dir/subdir3/subdir3_1/subdir1 renamed", F_OK);
+ assert(!err);
+
puts("success");
}
diff --git a/tests/test_browser.py b/tests/test_browser.py
index f4e4b89a..ecd331fd 100644
--- a/tests/test_browser.py
+++ b/tests/test_browser.py
@@ -1311,6 +1311,10 @@ keydown(100);keyup(100); // trigger the end
def test_gl_vertex_buffer(self):
self.btest('gl_vertex_buffer.c', reference='gl_vertex_buffer.png', args=['-s', 'GL_UNSAFE_OPTS=0', '-s', 'LEGACY_GL_EMULATION=1'], reference_slack=1)
+ # Does not pass due to https://bugzilla.mozilla.org/show_bug.cgi?id=924264 so disabled for now.
+ # def test_gles2_uniform_arrays(self):
+ # self.btest('gles2_uniform_arrays.cpp', args=['-s', 'GL_ASSERTIONS=1'], expected=['1'])
+
def test_matrix_identity(self):
self.btest('gl_matrix_identity.c', expected=['-1882984448', '460451840'], args=['-s', 'LEGACY_GL_EMULATION=1'])
@@ -1388,7 +1392,7 @@ keydown(100);keyup(100); // trigger the end
def test_sdl_rotozoom(self):
shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png'))
- self.btest('sdl_rotozoom.c', reference='sdl_rotozoom.png', args=['--preload-file', 'screenshot.png'], reference_slack=5)
+ self.btest('sdl_rotozoom.c', reference='sdl_rotozoom.png', args=['--preload-file', 'screenshot.png'])
def test_sdl_gfx_primitives(self):
self.btest('sdl_gfx_primitives.c', reference='sdl_gfx_primitives.png', reference_slack=1)
diff --git a/tests/test_core.py b/tests/test_core.py
index f51c1691..87925082 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -1073,7 +1073,6 @@ Succeeded!
self.do_run(open(path_from_root('tests', 'cube2md5.cpp')).read(), open(path_from_root('tests', 'cube2md5.ok')).read())
def test_cube2hash(self):
-
try:
old_chunk_size = os.environ.get('EMSCRIPT_MAX_CHUNK_SIZE') or ''
os.environ['EMSCRIPT_MAX_CHUNK_SIZE'] = '1' # test splitting out each function to a chunk in emscripten.py (21 functions here)
@@ -1091,6 +1090,17 @@ Succeeded!
finally:
os.environ['EMSCRIPT_MAX_CHUNK_SIZE'] = old_chunk_size
+ assert 'asm1' in test_modes
+ if self.run_name == 'asm1':
+ assert Settings.RELOOP
+ generated = open('src.cpp.o.js').read()
+ main = generated[generated.find('function _main'):]
+ main = main[:main.find('\n}')]
+ num_vars = 0
+ for v in re.findall('var [^;]+;', main):
+ num_vars += v.count(',') + 1
+ assert num_vars == 10, 'no variable elimination should have been run, but seeing %d' % num_vars
+
def test_unaligned(self):
if Settings.QUANTUM_SIZE == 1: return self.skip('No meaning to unaligned addresses in q1')
@@ -3841,25 +3851,26 @@ def process(filename):
self.do_run(src, '4\n200\ndone\n')
def test_inlinejs3(self):
- if Settings.ASM_JS: return self.skip('asm does not support random code, TODO: something that works in asm')
- src = r'''
- #include <stdio.h>
- #include <emscripten.h>
+ src = r'''
+ #include <stdio.h>
+ #include <emscripten.h>
- int main() {
- EM_ASM(Module.print('hello dere1'));
- EM_ASM(
- Module.print('hello dere2');
- );
+ int main() {
+ EM_ASM(Module.print('hello dere1'));
+ EM_ASM(
+ Module.print('hello dere2');
+ );
+ for (int i = 0; i < 3; i++) {
EM_ASM(
Module.print('hello dere3');
Module.print('hello dere' + 4);
);
- return 0;
}
- '''
+ return 0;
+ }
+ '''
- self.do_run(src, 'hello dere1\nhello dere2\nhello dere3\nhello dere4\n')
+ self.do_run(src, 'hello dere1\nhello dere2\nhello dere3\nhello dere4\nhello dere3\nhello dere4\nhello dere3\nhello dere4\n')
def test_memorygrowth(self):
if Settings.USE_TYPED_ARRAYS == 0: return self.skip('memory growth is only supported with typed arrays')
@@ -7266,6 +7277,7 @@ date: 18.07.2013w; day 18, month 7, year 2013, extra: 201, 3
if self.emcc_args is not None and '-O2' in self.emcc_args:
self.emcc_args += ['--closure', '1'] # Use closure here, to test we don't break FS stuff
self.emcc_args = filter(lambda x: x != '-g', self.emcc_args) # ensure we test --closure 1 --memory-init-file 1 (-g would disable closure)
+ self.emcc_args += ["-s", "CHECK_HEAP_ALIGN=0"] # disable heap align check here, it mixes poorly with closure
Settings.CORRECT_SIGNS = 1 # Just so our output is what we expect. Can flip them both.
post = '''
@@ -7743,20 +7755,20 @@ def process(filename):
Settings.INCLUDE_FULL_LIBRARY = 0
def test_fs_nodefs_rw(self):
+ if self.emcc_args is None: return self.skip('requires emcc')
+ if not self.is_le32(): return self.skip('le32 needed for inline js')
src = open(path_from_root('tests', 'fs', 'test_nodefs_rw.c'), 'r').read()
- self.do_run(src, 'success', force_c=True)
+ self.do_run(src, 'success', force_c=True, js_engines=[NODE_JS])
def test_unistd_access(self):
- if Settings.ASM_JS: Settings.ASM_JS = 2 # skip validation, asm does not support random code
if not self.is_le32(): return self.skip('le32 needed for inline js')
for fs in ['MEMFS', 'NODEFS']:
src = open(path_from_root('tests', 'unistd', 'access.c'), 'r').read()
expected = open(path_from_root('tests', 'unistd', 'access.out'), 'r').read()
Building.COMPILER_TEST_OPTS += ['-D' + fs]
- self.do_run(src, expected)
+ self.do_run(src, expected, js_engines=[NODE_JS])
def test_unistd_curdir(self):
- if Settings.ASM_JS: Settings.ASM_JS = 2 # skip validation, asm does not support random code
if not self.is_le32(): return self.skip('le32 needed for inline js')
src = open(path_from_root('tests', 'unistd', 'curdir.c'), 'r').read()
expected = open(path_from_root('tests', 'unistd', 'curdir.out'), 'r').read()
@@ -7787,13 +7799,12 @@ def process(filename):
self.do_run(src, expected)
def test_unistd_truncate(self):
- if Settings.ASM_JS: Settings.ASM_JS = 2 # skip validation, asm does not support random code
if not self.is_le32(): return self.skip('le32 needed for inline js')
for fs in ['MEMFS', 'NODEFS']:
src = open(path_from_root('tests', 'unistd', 'truncate.c'), 'r').read()
expected = open(path_from_root('tests', 'unistd', 'truncate.out'), 'r').read()
Building.COMPILER_TEST_OPTS += ['-D' + fs]
- self.do_run(src, expected)
+ self.do_run(src, expected, js_engines=[NODE_JS])
def test_unistd_swab(self):
src = open(path_from_root('tests', 'unistd', 'swab.c'), 'r').read()
@@ -7815,19 +7826,20 @@ def process(filename):
self.do_run(src, expected)
def test_unistd_unlink(self):
+ if self.emcc_args is None: return self.skip('requires emcc')
+ if not self.is_le32(): return self.skip('le32 needed for inline js')
for fs in ['MEMFS', 'NODEFS']:
src = open(path_from_root('tests', 'unistd', 'unlink.c'), 'r').read()
Building.COMPILER_TEST_OPTS += ['-D' + fs]
- self.do_run(src, 'success', force_c=True)
+ self.do_run(src, 'success', force_c=True, js_engines=[NODE_JS])
def test_unistd_links(self):
- if Settings.ASM_JS: Settings.ASM_JS = 2 # skip validation, asm does not support random code
if not self.is_le32(): return self.skip('le32 needed for inline js')
for fs in ['MEMFS', 'NODEFS']:
src = open(path_from_root('tests', 'unistd', 'links.c'), 'r').read()
expected = open(path_from_root('tests', 'unistd', 'links.out'), 'r').read()
Building.COMPILER_TEST_OPTS += ['-D' + fs]
- self.do_run(src, expected)
+ self.do_run(src, expected, js_engines=[NODE_JS])
def test_unistd_sleep(self):
src = open(path_from_root('tests', 'unistd', 'sleep.c'), 'r').read()
@@ -7835,21 +7847,23 @@ def process(filename):
self.do_run(src, expected)
def test_unistd_io(self):
- if Settings.ASM_JS: Settings.ASM_JS = 2 # skip validation, asm does not support random code
if not self.is_le32(): return self.skip('le32 needed for inline js')
if self.run_name == 'o2': return self.skip('non-asm optimized builds can fail with inline js')
+ if self.emcc_args is None: return self.skip('requires emcc')
for fs in ['MEMFS', 'NODEFS']:
src = open(path_from_root('tests', 'unistd', 'io.c'), 'r').read()
expected = open(path_from_root('tests', 'unistd', 'io.out'), 'r').read()
Building.COMPILER_TEST_OPTS += ['-D' + fs]
- self.do_run(src, expected)
+ self.do_run(src, expected, js_engines=[NODE_JS])
def test_unistd_misc(self):
+ if self.emcc_args is None: return self.skip('requires emcc')
+ if not self.is_le32(): return self.skip('le32 needed for inline js')
for fs in ['MEMFS', 'NODEFS']:
src = open(path_from_root('tests', 'unistd', 'misc.c'), 'r').read()
expected = open(path_from_root('tests', 'unistd', 'misc.out'), 'r').read()
Building.COMPILER_TEST_OPTS += ['-D' + fs]
- self.do_run(src, expected)
+ self.do_run(src, expected, js_engines=[NODE_JS])
def test_uname(self):
src = r'''
@@ -8602,6 +8616,13 @@ void*:16
assert ' & 255]()' not in original, 'big function table does not exist'
assert ' & 255]()' in final, 'big function table exists'
+ assert 'asm1' in test_modes
+ if self.run_name == 'asm1':
+ generated = open('src.cpp.o.js').read()
+ main = generated[generated.find('function runPostSets'):]
+ main = main[:main.find('\n}')]
+ assert main.count('\n') == 7, 'must not emit too many postSets: %d' % main.count('\n')
+
def test_gcc_unmangler(self):
Settings.NAMED_GLOBALS = 1 # test coverage for this
@@ -8639,7 +8660,10 @@ void*:16
def test_freetype(self):
if self.emcc_args is None: return self.skip('requires emcc')
if Settings.QUANTUM_SIZE == 1: return self.skip('TODO: Figure out and try to fix')
- if Settings.ASM_JS and '-O2' not in self.emcc_args: return self.skip('mozilla bug 863867')
+
+ assert 'asm2g' in test_modes
+ if self.run_name == 'asm2g':
+ Settings.ALIASING_FUNCTION_POINTERS = 1 - Settings.ALIASING_FUNCTION_POINTERS # flip for some more coverage here
if Settings.CORRECT_SIGNS == 0: Settings.CORRECT_SIGNS = 1 # Not sure why, but needed
@@ -9452,6 +9476,32 @@ def process(filename):
Settings.ALIASING_FUNCTION_POINTERS = 1 - Settings.ALIASING_FUNCTION_POINTERS # flip the test
self.do_run(src, '''Hello 7 from JS!''')
+ def test_demangle_stacks(self):
+ if Settings.ASM_JS: return self.skip('spidermonkey has stack trace issues')
+
+ src = r'''
+ #include<stdio.h>
+ #include<stdlib.h>
+
+ namespace NameSpace {
+ class Class {
+ public:
+ int Aborter(double x, char y, int *z) {
+ int addr = x+y+(int)z;
+ void *p = (void*)addr;
+ for (int i = 0; i < 100; i++) free(p); // will abort, should show proper stack trace
+ }
+ };
+ }
+
+ int main(int argc, char **argv) {
+ NameSpace::Class c;
+ c.Aborter(1.234, 'a', NULL);
+ return 0;
+ }
+ '''
+ self.do_run(src, 'NameSpace::Class::Aborter(double, char, int*)');
+
def test_embind(self):
if self.emcc_args is None: return self.skip('requires emcc')
Building.COMPILER_TEST_OPTS += ['--bind']
@@ -10510,9 +10560,9 @@ o1 = make_run("o1", compiler=CLANG, emcc_args=["-O1", "-s", "ASM_JS=0", "-s", "S
o2 = make_run("o2", compiler=CLANG, emcc_args=["-O2", "-s", "ASM_JS=0", "-s", "JS_CHUNK_SIZE=1024"])
# asm.js
-asm1 = make_run("asm1", compiler=CLANG, emcc_args=["-O1", "-s", "CHECK_HEAP_ALIGN=1"])
+asm1 = make_run("asm1", compiler=CLANG, emcc_args=["-O1"])
asm2 = make_run("asm2", compiler=CLANG, emcc_args=["-O2"])
-asm2g = make_run("asm2g", compiler=CLANG, emcc_args=["-O2", "-g", "-s", "ASSERTIONS=1", "--memory-init-file", "1"])
+asm2g = make_run("asm2g", compiler=CLANG, emcc_args=["-O2", "-g", "-s", "ASSERTIONS=1", "--memory-init-file", "1", "-s", "CHECK_HEAP_ALIGN=1"])
asm2x86 = make_run("asm2x86", compiler=CLANG, emcc_args=["-O2", "-g", "-s", "CHECK_HEAP_ALIGN=1"], env={"EMCC_LLVM_TARGET": "i386-pc-linux-gnu"})
# Make custom runs with various options
diff --git a/tests/test_other.py b/tests/test_other.py
index 9f331439..185b4853 100644
--- a/tests/test_other.py
+++ b/tests/test_other.py
@@ -125,8 +125,6 @@ Options that are modified or new in %s include:
(['-o', 'something.js', '-O0'], 0, None, 0, 0),
(['-o', 'something.js', '-O1'], 1, None, 0, 0),
(['-o', 'something.js', '-O1', '-g'], 1, None, 0, 0), # no closure since debug
- (['-o', 'something.js', '-O1', '--closure', '1'], 1, None, 1, 0),
- (['-o', 'something.js', '-O1', '--closure', '1', '-s', 'ASM_JS=0'], 1, None, 1, 0),
(['-o', 'something.js', '-O2'], 2, None, 0, 1),
(['-o', 'something.js', '-O2', '-g'], 2, None, 0, 0),
(['-o', 'something.js', '-Os'], 2, None, 0, 1),
@@ -169,13 +167,13 @@ Options that are modified or new in %s include:
# closure has not been run, we can do some additional checks. TODO: figure out how to do these even with closure
assert '._main = ' not in generated, 'closure compiler should not have been run'
if keep_debug:
- assert ('(label)' in generated or '(label | 0)' in generated) == (opt_level <= 1), 'relooping should be in opt >= 2'
+ assert ('(label)' in generated or '(label | 0)' in generated) == (opt_level <= 0), 'relooping should be in opt >= 1'
assert ('assert(STACKTOP < STACK_MAX' in generated) == (opt_level == 0), 'assertions should be in opt == 0'
- assert 'var $i;' in generated or 'var $i_0' in generated or 'var $storemerge3;' in generated or 'var $storemerge4;' in generated or 'var $i_04;' in generated or 'var $original = 0' in generated, 'micro opts should always be on'
+ assert 'var $i;' in generated or 'var $i_0' in generated or 'var $storemerge3;' in generated or 'var $storemerge4;' in generated or '$i_04' in generated or '$i_05' in generated or 'var $original = 0' in generated, 'micro opts should always be on'
if opt_level >= 2 and '-g' in params:
assert re.search('HEAP8\[\$?\w+ ?\+ ?\(+\$?\w+ ?', generated) or re.search('HEAP8\[HEAP32\[', generated), 'eliminator should create compound expressions, and fewer one-time vars' # also in -O1, but easier to test in -O2
assert ('_puts(' in generated) == (opt_level >= 1), 'with opt >= 1, llvm opts are run and they should optimize printf to puts'
- if opt_level == 0 or '-g' in params: assert 'function _main() {' in generated, 'Should be unminified, including whitespace'
+ if opt_level == 0 or '-g' in params: assert 'function _main() {' in generated or 'function _main(){' in generated, 'Should be unminified'
elif opt_level >= 2: assert ('function _main(){' in generated or '"use asm";var a=' in generated), 'Should be whitespace-minified'
# emcc -s RELOOP=1 src.cpp ==> should pass -s to emscripten.py. --typed-arrays is a convenient alias for -s USE_TYPED_ARRAYS
@@ -807,10 +805,10 @@ f.close()
0: (1500, 5000)
}),
(['-O2'], {
- 100: (0, 1500),
- 250: (0, 1500),
- 500: (0, 1500),
- 1000: (0, 1500),
+ 100: (0, 1600),
+ 250: (0, 1600),
+ 500: (0, 1600),
+ 1000: (0, 1600),
2000: (0, 2000),
5000: (0, 5000),
0: (0, 5000)
@@ -1647,6 +1645,8 @@ f.close()
['asm', 'outline']),
(path_from_root('tools', 'test-js-optimizer-asm-outline3.js'), open(path_from_root('tools', 'test-js-optimizer-asm-outline3-output.js')).read(),
['asm', 'outline']),
+ (path_from_root('tools', 'test-js-optimizer-asm-minlast.js'), open(path_from_root('tools', 'test-js-optimizer-asm-minlast-output.js')).read(),
+ ['asm', 'minifyWhitespace', 'last']),
]:
print input
output = Popen(listify(NODE_JS) + [path_from_root('tools', 'js-optimizer.js'), input] + passes, stdin=PIPE, stdout=PIPE).communicate()[0]
@@ -1666,20 +1666,16 @@ f.close()
try:
os.environ['EMCC_DEBUG'] = '1'
os.environ['EMCC_CORES'] = '2' # standardize over machines
- for asm, linkable, chunks, js_chunks in [
- (0, 0, 2, 2), (0, 1, 2, 4),
- (1, 0, 2, 2), (1, 1, 2, 4)
+ for asm, linkable, chunks in [
+ (0, 0, 2), (0, 1, 2),
+ (1, 0, 2), (1, 1, 2)
]:
- print asm, linkable, chunks, js_chunks
+ print asm, linkable, chunks
output, err = Popen([PYTHON, EMCC, path_from_root('tests', 'hello_libcxx.cpp'), '-O1', '-s', 'LINKABLE=%d' % linkable, '-s', 'ASM_JS=%d' % asm] + (['-O2'] if asm else []), stdout=PIPE, stderr=PIPE).communicate()
ok = False
for c in range(chunks, chunks+2):
ok = ok or ('phase 2 working on %d chunks' % c in err)
assert ok, err
- ok = False
- for c in range(js_chunks, js_chunks+2):
- ok = ok or ('splitting up js optimization into %d chunks' % c in err)
- assert ok, err
finally:
del os.environ['EMCC_DEBUG']
del os.environ['EMCC_CORES']
@@ -1910,3 +1906,53 @@ done.
assert '''tests/hello_world.c"''' in out
assert '''printf("hello, world!''' in out
+ def test_demangle(self):
+ open('src.cpp', 'w').write('''
+ #include <stdio.h>
+ #include <emscripten.h>
+ void two(char c) {
+ EM_ASM(Module.print(stackTrace()));
+ }
+ void one(int x) {
+ two(x % 17);
+ }
+ int main() {
+ EM_ASM(Module.print(demangle('__Znwj'))); // check for no aborts
+ EM_ASM(Module.print(demangle('_main')));
+ EM_ASM(Module.print(demangle('__Z2f2v')));
+ EM_ASM(Module.print(demangle('__Z12abcdabcdabcdi')));
+ EM_ASM(Module.print(demangle('__Z4testcsifdPvPiPc')));
+ EM_ASM(Module.print(demangle('__ZN4test5moarrEcslfdPvPiPc')));
+ EM_ASM(Module.print(demangle('__ZN4Waka1f12a234123412345pointEv')));
+ EM_ASM(Module.print(demangle('__Z3FooIiEvv')));
+ EM_ASM(Module.print(demangle('__Z3FooIidEvi')));
+ EM_ASM(Module.print(demangle('__ZN3Foo3BarILi5EEEvv')));
+ EM_ASM(Module.print(demangle('__ZNK10__cxxabiv120__si_class_type_info16search_below_dstEPNS_19__dynamic_cast_infoEPKvib')));
+ EM_ASM(Module.print(demangle('__Z9parsewordRPKciRi')));
+ EM_ASM(Module.print(demangle('__Z5multiwahtjmxyz')));
+ EM_ASM(Module.print(demangle('__Z1aA32_iPA5_c')));
+ one(17);
+ return 0;
+ }
+ ''')
+
+ Popen([PYTHON, EMCC, 'src.cpp', '-s', 'LINKABLE=1']).communicate()
+ output = run_js('a.out.js')
+ self.assertContained('''main
+f2()
+abcdabcdabcd(int)
+test(char, short, int, float, double, void*, int*, char*)
+test::moarr(char, short, long, float, double, void*, int*, char*)
+Waka::f::a23412341234::point()
+void Foo<int>()
+void Foo<int, double>(int)
+void Foo::Bar<5>()
+__cxxabiv1::__si_class_type_info::search_below_dst(__cxxabiv1::__dynamic_cast_info*, void*, int, bool)
+parseword(char*&, int, int&)
+multi(wchar_t, signed char, unsigned char, unsigned short, unsigned int, unsigned long, long long, unsigned long long,