aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/aniso.c3
-rw-r--r--tests/cases/2xi40.ll42
-rw-r--r--tests/cases/2xi40.txt1
-rw-r--r--tests/cases/caall.ll2
-rw-r--r--tests/cases/emptyasm_le32.ll16
-rw-r--r--tests/embind/shell.html2
-rw-r--r--tests/hello_world_gles_shell.html2
-rw-r--r--tests/sdl_canvas_size.c191
-rw-r--r--tests/sdl_canvas_size.html93
-rw-r--r--tests/test_browser.py47
-rw-r--r--tests/test_core.py148
-rw-r--r--tests/test_other.py44
-rw-r--r--tests/test_webgl_context_attributes_common.c262
-rw-r--r--tests/test_webgl_context_attributes_glfw.c47
-rw-r--r--tests/test_webgl_context_attributes_glut.c42
-rw-r--r--tests/test_webgl_context_attributes_sdl.c50
16 files changed, 945 insertions, 47 deletions
diff --git a/tests/aniso.c b/tests/aniso.c
index e8d7bd3f..f1674cad 100644
--- a/tests/aniso.c
+++ b/tests/aniso.c
@@ -66,6 +66,9 @@ int main(int argc, char *argv[])
const char *exts = (const char *)glGetString(GL_EXTENSIONS);
assert(hasext(exts, "GL_EXT_texture_filter_anisotropic"));
+ const char *vendor = (const char *)glGetString(GL_VENDOR);
+ printf("vendor: %s\n", vendor);
+
GLint aniso;
glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &aniso);
printf("Max anisotropy: %d (using that)\n", aniso);
diff --git a/tests/cases/2xi40.ll b/tests/cases/2xi40.ll
new file mode 100644
index 00000000..592f1ba4
--- /dev/null
+++ b/tests/cases/2xi40.ll
@@ -0,0 +1,42 @@
+; ModuleID = '/tmp/tmpe4Pk1F/a.out.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:32"
+target triple = "le32-unknown-nacl"
+
+%struct.pair = type { [5 x i8], [5 x i8] }
+
+@.str = private unnamed_addr constant [6 x i8] c"|%d|\0A\00", align 1
+@.str1 = private unnamed_addr constant [7 x i8] c"%s,%s\0A\00", align 1
+
+define i32 @main() {
+ %1 = alloca i32, align 4
+ %pp = alloca [2 x i40], align 8
+ %p = bitcast [2 x i40]* %pp to %struct.pair*
+ store i32 0, i32* %1
+ %2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([6 x i8]* @.str, i32 0, i32 0), i32 10)
+ %3 = bitcast %struct.pair* %p to i8*
+ call void @llvm.memset.p0i8.i32(i8* %3, i8 120, i32 10, i32 1, i1 false)
+ %4 = getelementptr inbounds [2 x i40]* %pp, i32 0, i32 0
+ %b4 = bitcast i40* %4 to [5 x i8]*
+ %5 = getelementptr inbounds [5 x i8]* %b4, i32 0, i32 2
+ store i8 97, i8* %5, align 1
+ %6 = getelementptr inbounds %struct.pair* %p, i32 0, i32 0
+ %7 = getelementptr inbounds [5 x i8]* %6, i32 0, i32 4
+ store i8 0, i8* %7, align 1
+ %8 = getelementptr inbounds %struct.pair* %p, i32 0, i32 1
+ %9 = getelementptr inbounds [5 x i8]* %8, i32 0, i32 3
+ store i8 98, i8* %9, align 1
+ %10 = getelementptr inbounds [2 x i40]* %pp, i32 0, i32 1
+ %b10 = bitcast i40* %10 to [5 x i8]*
+ %11 = getelementptr inbounds [5 x i8]* %b10, i32 0, i32 4
+ store i8 0, i8* %11, align 1
+ %12 = getelementptr inbounds %struct.pair* %p, i32 0, i32 0
+ %13 = getelementptr inbounds [5 x i8]* %12, i32 0, i32 0
+ %14 = getelementptr inbounds %struct.pair* %p, i32 0, i32 1
+ %15 = getelementptr inbounds [5 x i8]* %14, i32 0, i32 0
+ %16 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([7 x i8]* @.str1, i32 0, i32 0), i8* %13, i8* %15)
+ ret i32 0
+}
+
+declare i32 @printf(i8*, ...)
+
+declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) nounwind
diff --git a/tests/cases/2xi40.txt b/tests/cases/2xi40.txt
new file mode 100644
index 00000000..59a1104e
--- /dev/null
+++ b/tests/cases/2xi40.txt
@@ -0,0 +1 @@
+xxax,xxxb
diff --git a/tests/cases/caall.ll b/tests/cases/caall.ll
index 313116e6..5b8f7f29 100644
--- a/tests/cases/caall.ll
+++ b/tests/cases/caall.ll
@@ -18,7 +18,7 @@ entry:
define (i32*)** @_ZNSt3__13mapINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEPFvP6ObjectENS_4lessIS6_EENS4_INS_4pairIKS6_SA_EEEEEixERSE_(i32 %x) {
entry:
%ret = inttoptr i32 0 to (i32*)**
- ret %ret
+ ret (i32*)** %ret
}
; [#uses=1]
diff --git a/tests/cases/emptyasm_le32.ll b/tests/cases/emptyasm_le32.ll
new file mode 100644
index 00000000..e123d3d5
--- /dev/null
+++ b/tests/cases/emptyasm_le32.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*]
+ store i32 0, i32* %retval
+ call void asm sideeffect "", "~{memory}"() nounwind, !srcloc !0
+ %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/embind/shell.html b/tests/embind/shell.html
index c3655e03..f0ee10f8 100644
--- a/tests/embind/shell.html
+++ b/tests/embind/shell.html
@@ -85,6 +85,6 @@
};
Module.setStatus('Downloading...');
</script>
- <script type='text/javascript'>{{{ SCRIPT_CODE }}}</script>
+ {{{ SCRIPT }}}
</body>
</html>
diff --git a/tests/hello_world_gles_shell.html b/tests/hello_world_gles_shell.html
index 2459d755..22ecee7b 100644
--- a/tests/hello_world_gles_shell.html
+++ b/tests/hello_world_gles_shell.html
@@ -49,7 +49,7 @@
Module.postRun = doTest;
</script>
- <script>{{{ SCRIPT_CODE }}}</script>
+ {{{ SCRIPT }}}
</body>
</html>
diff --git a/tests/sdl_canvas_size.c b/tests/sdl_canvas_size.c
new file mode 100644
index 00000000..923a9014
--- /dev/null
+++ b/tests/sdl_canvas_size.c
@@ -0,0 +1,191 @@
+/*******************************************************************
+ * *
+ * Using SDL With OpenGL *
+ * *
+ * Tutorial by Kyle Foley (sdw) *
+ * *
+ * http://gpwiki.org/index.php/SDL:Tutorials:Using_SDL_with_OpenGL *
+ * *
+ *******************************************************************/
+
+/*
+THIS WORK, INCLUDING THE SOURCE CODE, DOCUMENTATION
+AND RELATED MEDIA AND DATA, IS PLACED INTO THE PUBLIC DOMAIN.
+
+THE ORIGINAL AUTHOR IS KYLE FOLEY.
+
+THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY
+OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF
+MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE,
+ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE
+RESULTING FROM THE USE, MODIFICATION, OR
+REDISTRIBUTION OF THIS SOFTWARE.
+*/
+
+#include "SDL/SDL.h"
+#include "SDL/SDL_image.h"
+#include "SDL/SDL_opengl.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#ifdef EMSCRIPTEN
+#include <emscripten.h>
+#endif
+
+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;
+ }
+
+ SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); // *new*
+
+#ifdef EMSCRIPTEN
+ // Test 1: Check that initializing video mode with size (0,0) will use the size from the <canvas> element.
+ screen = SDL_SetVideoMode( 0, 0, 16, SDL_OPENGL ); // *changed*
+
+ // Test 2: Check that getting current canvas size works.
+ int w, h, fs;
+ emscripten_get_canvas_size(&w, &h, &fs);
+ printf("w:%d,h:%d\n", w,h);
+ assert(w == 700);
+ assert(h == 200);
+
+ // Test 3: Check that resizing the canvas works as well.
+ emscripten_set_canvas_size(640, 480);
+ // Set the OpenGL state after creating the context with SDL_SetVideoMode
+#else
+ screen = SDL_SetVideoMode( 640, 480, 16, SDL_OPENGL ); // *changed*
+#endif
+
+ if ( !screen ) {
+ printf("Unable to set video mode: %s\n", SDL_GetError());
+ return 1;
+ }
+
+ glClearColor( 0, 0, 0, 0 );
+
+ glEnable( GL_TEXTURE_2D ); // Needed when we're using the fixed-function pipeline.
+
+ glViewport( 0, 0, 640, 480 );
+
+ glMatrixMode( GL_PROJECTION );
+ glPushMatrix(); // just for testing
+ glLoadIdentity();
+
+ glOrtho( 0, 640, 480, 0, -1, 1 );
+
+ glMatrixMode( GL_MODELVIEW );
+ glLoadIdentity();
+
+ // Load the OpenGL texture
+
+ GLuint texture; // Texture object handle
+ SDL_Surface *surface; // Gives us the information to make the texture
+
+ if ( (surface = IMG_Load("screenshot.png")) ) {
+
+ // Check that the image's width is a power of 2
+ if ( (surface->w & (surface->w - 1)) != 0 ) {
+ printf("warning: image.bmp's width is not a power of 2\n");
+ }
+
+ // Also check if the height is a power of 2
+ if ( (surface->h & (surface->h - 1)) != 0 ) {
+ printf("warning: image.bmp's height is not a power of 2\n");
+ }
+
+ // Have OpenGL generate a texture object handle for us
+ glGenTextures( 1, &texture );
+
+ // Bind the texture object
+ glBindTexture( GL_TEXTURE_2D, texture );
+
+ // Set the texture's stretching properties
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+
+ //SDL_LockSurface(surface);
+
+ // Add some greyness
+ memset(surface->pixels, 0x66, surface->w*surface->h);
+
+ // Edit the texture object's image data using the information SDL_Surface gives us
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface->w, surface->h, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels );
+
+ //SDL_UnlockSurface(surface);
+ }
+ else {
+ printf("SDL could not load image.bmp: %s\n", SDL_GetError());
+ SDL_Quit();
+ return 1;
+ }
+
+ // Free the SDL_Surface only if it was successfully created
+ if ( surface ) {
+ SDL_FreeSurface( surface );
+ }
+
+ // Clear the screen before drawing
+ glClear( GL_COLOR_BUFFER_BIT );
+
+ // Bind the texture to which subsequent calls refer to
+ glBindTexture( GL_TEXTURE_2D, texture );
+
+ glBegin( GL_QUADS );
+ glTexCoord2i( 0, 0 ); glVertex3f( 10, 10, 0 );
+ glTexCoord2i( 1, 0 ); glVertex3f( 300, 10, 0 );
+ glTexCoord2i( 1, 1 ); glVertex3f( 300, 128, 0 );
+ glTexCoord2i( 0, 1 ); glVertex3f( 10, 128, 0 );
+
+ glTexCoord2f( 0, 0.5 ); glVertex3f( 410, 10, 0 );
+ glTexCoord2f( 1, 0.5 ); glVertex3f( 600, 10, 0 );
+ glTexCoord2f( 1, 1 ); glVertex3f( 630, 200, 0 );
+ glTexCoord2f( 0.5, 1 ); glVertex3f( 310, 250, 0 );
+ glEnd();
+
+ glBegin( GL_TRIANGLE_STRIP );
+ glTexCoord2i( 0, 0 ); glVertex3f( 100, 300, 0 );
+ glTexCoord2i( 1, 0 ); glVertex3f( 300, 300, 0 );
+ glTexCoord2i( 1, 1 ); glVertex3f( 300, 400, 0 );
+ glTexCoord2i( 0, 1 ); glVertex3f( 500, 410, 0 );
+ glEnd();
+
+ glDisable(GL_TEXTURE_2D);
+
+ glColor3ub(90, 255, 255);
+ glBegin( GL_QUADS );
+ glVertex3f( 10, 410, 0 );
+ glVertex3f( 300, 410, 0 );
+ glVertex3f( 300, 480, 0 );
+ glVertex3f( 10, 470, 0 );
+ glEnd();
+
+ glBegin( GL_QUADS );
+ glColor3f(1.0, 0, 1.0); glVertex3f( 410, 410, 0 );
+ glColor3f(0, 1.0, 0); glVertex3f( 600, 410, 0 );
+ glColor3f(0, 0, 1.0); glVertex3f( 600, 480, 0 );
+ glColor3f(1.0, 1.0, 1.0); glVertex3f( 410, 470, 0 );
+ glEnd();
+
+ SDL_GL_SwapBuffers();
+
+#if !EMSCRIPTEN
+ // Wait for 3 seconds to give us a chance to see the image
+ SDL_Delay(3000);
+#endif
+
+ // Now we can delete the OpenGL texture and close down SDL
+ glDeleteTextures( 1, &texture );
+
+ SDL_Quit();
+
+ return 0;
+}
diff --git a/tests/sdl_canvas_size.html b/tests/sdl_canvas_size.html
new file mode 100644
index 00000000..50495049
--- /dev/null
+++ b/tests/sdl_canvas_size.html
@@ -0,0 +1,93 @@
+<!doctype html>
+<html lang="en-us">
+ <head>
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <title>Emscripten-Generated Code</title>
+ <style>
+ .emscripten { padding-right: 0; margin-left: auto; margin-right: auto; display: block; }
+ textarea.emscripten { font-family: monospace; width: 80%; }
+ div.emscripten { text-align: center; }
+ div.emscripten_border { border: 1px solid black; }
+ /* the canvas *must not* have any border or padding, or mouse coords will be wrong */
+ canvas.emscripten { border: 0px none; }
+ </style>
+ </head>
+ <body>
+ <hr/>
+ <div class="emscripten" id="status">Downloading...</div>
+ <div class="emscripten">
+ <progress value="0" max="100" id="progress" hidden=1></progress>
+ </div>
+ <div class="emscripten_border">
+ <!-- Pass custom width/height to test that SDL_SetVideoMode(0,0, ...) will use these. -->
+ <canvas class="emscripten" id="canvas" width="700" height="200" oncontextmenu="event.preventDefault()"></canvas>
+ </div>
+ <hr/>
+ <div class="emscripten">
+ <input type="checkbox" id="resize">Resize canvas
+ <input type="checkbox" id="pointerLock" checked>Lock/hide mouse pointer
+ &nbsp;&nbsp;&nbsp;
+ <input type="button" value="Fullscreen" onclick="Module.requestFullScreen(document.getElementById('pointerLock').checked,
+ document.getElementById('resize').checked)">
+ </div>
+
+ <hr/>
+ <textarea class="emscripten" id="output" rows="8"></textarea>
+ <hr>
+ <script type='text/javascript'>
+ // connect to canvas
+ var Module = {
+ preRun: [],
+ postRun: [],
+ print: (function() {
+ var element = document.getElementById('output');
+ element.value = ''; // clear browser cache
+ return function(text) {
+ text = Array.prototype.slice.call(arguments).join(' ');
+ // These replacements are necessary if you render to raw HTML
+ //text = text.replace(/&/g, "&amp;");
+ //text = text.replace(/</g, "&lt;");
+ //text = text.replace(/>/g, "&gt;");
+ //text = text.replace('\n', '<br>', 'g');
+ element.value += text + "\n";
+ element.scrollTop = 99999; // focus on bottom
+ };
+ })(),
+ printErr: function(text) {
+ text = Array.prototype.slice.call(arguments).join(' ');
+ if (0) { // XXX disabled for safety typeof dump == 'function') {
+ dump(text + '\n'); // fast, straight to the real console
+ } else {
+ console.log(text);
+ }
+ },
+ canvas: document.getElementById('canvas'),
+ setStatus: function(text) {
+ if (Module.setStatus.interval) clearInterval(Module.setStatus.interval);
+ var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/);
+ var statusElement = document.getElementById('status');
+ var progressElement = document.getElementById('progress');
+ if (m) {
+ text = m[1];
+ progressElement.value = parseInt(m[2])*100;
+ progressElement.max = parseInt(m[4])*100;
+ progressElement.hidden = false;
+ } else {
+ progressElement.value = null;
+ progressElement.max = null;
+ progressElement.hidden = true;
+ }
+ statusElement.innerHTML = text;
+ },
+ totalDependencies: 0,
+ monitorRunDependencies: function(left) {
+ this.totalDependencies = Math.max(this.totalDependencies, left);
+ Module.setStatus(left ? 'Preparing... (' + (this.totalDependencies-left) + '/' + this.totalDependencies + ')' : 'All downloads complete.');
+ }
+ };
+ Module.setStatus('Downloading...');
+ </script>
+ {{{ SCRIPT }}}
+ </body>
+</html>
diff --git a/tests/test_browser.py b/tests/test_browser.py
index ecd331fd..2ff9106b 100644
--- a/tests/test_browser.py
+++ b/tests/test_browser.py
@@ -869,6 +869,48 @@ keydown(100);keyup(100); // trigger the end
def test_glut_wheelevents(self):
self.btest('glut_wheelevents.c', '1')
+ def test_webgl_context_attributes(self):
+ # Javascript code to check the attributes support we want to test in the WebGL implementation
+ # (request the attribute, create a context and check its value afterwards in the context attributes).
+ # Tests will succeed when an attribute is not supported.
+ open(os.path.join(self.get_dir(), 'check_webgl_attributes_support.js'), 'w').write('''
+ mergeInto(LibraryManager.library, {
+ webglAntialiasSupported: function() {
+ canvas = document.createElement('canvas');
+ context = canvas.getContext('experimental-webgl', {antialias: true});
+ attributes = context.getContextAttributes();
+ return attributes.antialias;
+ },
+ webglDepthSupported: function() {
+ canvas = document.createElement('canvas');
+ context = canvas.getContext('experimental-webgl', {depth: true});
+ attributes = context.getContextAttributes();
+ return attributes.depth;
+ },
+ webglStencilSupported: function() {
+ canvas = document.createElement('canvas');
+ context = canvas.getContext('experimental-webgl', {stencil: true});
+ attributes = context.getContextAttributes();
+ return attributes.stencil;
+ }
+ });
+ ''')
+
+ # Copy common code file to temporary directory
+ filepath = path_from_root('tests/test_webgl_context_attributes_common.c')
+ temp_filepath = os.path.join(self.get_dir(), os.path.basename(filepath))
+ shutil.copyfile(filepath, temp_filepath)
+
+ # perform tests with attributes activated
+ self.btest('test_webgl_context_attributes_glut.c', '1', args=['--js-library', 'check_webgl_attributes_support.js', '-DAA_ACTIVATED', '-DDEPTH_ACTIVATED', '-DSTENCIL_ACTIVATED'])
+ self.btest('test_webgl_context_attributes_sdl.c', '1', args=['--js-library', 'check_webgl_attributes_support.js', '-DAA_ACTIVATED', '-DDEPTH_ACTIVATED', '-DSTENCIL_ACTIVATED'])
+ self.btest('test_webgl_context_attributes_glfw.c', '1', args=['--js-library', 'check_webgl_attributes_support.js', '-DAA_ACTIVATED', '-DDEPTH_ACTIVATED', '-DSTENCIL_ACTIVATED'])
+
+ # perform tests with attributes desactivated
+ self.btest('test_webgl_context_attributes_glut.c', '1', args=['--js-library', 'check_webgl_attributes_support.js'])
+ self.btest('test_webgl_context_attributes_sdl.c', '1', args=['--js-library', 'check_webgl_attributes_support.js'])
+ self.btest('test_webgl_context_attributes_glfw.c', '1', args=['--js-library', 'check_webgl_attributes_support.js'])
+
def test_emscripten_get_now(self):
self.btest('emscripten_get_now.cpp', '1')
@@ -942,6 +984,11 @@ keydown(100);keyup(100); // trigger the end
Popen([PYTHON, EMCC, '-O2', '--closure', '1', '--minify', '0', os.path.join(self.get_dir(), 'sdl_audio_beep.cpp'), '-s', 'DISABLE_EXCEPTION_CATCHING=0', '-o', 'page.html']).communicate()
self.run_browser('page.html', '', '/report_result?1')
+ def test_sdl_canvas_size(self):
+ self.btest('sdl_canvas_size.c', reference='screenshot-gray-purple.png', reference_slack=1,
+ args=['-O2', '--minify', '0', '--shell-file', path_from_root('tests', 'sdl_canvas_size.html'), '--preload-file', path_from_root('tests', 'screenshot.png') + '@/', '-s', 'LEGACY_GL_EMULATION=1'],
+ message='You should see an image with gray at the top.')
+
def test_sdl_gl_read(self):
# SDL, OpenGL, readPixels
open(os.path.join(self.get_dir(), 'sdl_gl_read.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl_gl_read.c')).read()))
diff --git a/tests/test_core.py b/tests/test_core.py
index 69fb31f3..c196adf3 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -2949,6 +2949,23 @@ Exiting setjmp function, level: 0, prev_jmp: -1
'''
self.do_run(src, '3.14159')
+ def test_iswdigit(self):
+ if self.emcc_args is None: return self.skip('no libcxx inclusion without emcc')
+
+ src = '''
+ #include <stdio.h>
+ #include <cctype>
+ #include <cwctype>
+
+ int main() {
+ using namespace std;
+ printf("%d ", isdigit('0'));
+ printf("%d ", iswdigit(L'0'));
+ return 0;
+ }
+ '''
+ self.do_run(src, '1 1')
+
def test_polymorph(self):
if self.emcc_args is None: return self.skip('requires emcc')
src = '''
@@ -7268,6 +7285,18 @@ date: 18.07.2013w; day 18, month 7, year 2013, extra: 201, 3
'''
self.do_run(src, '4779 4779')
+ def test_sscanf_float(self):
+ src = r'''
+ #include "stdio.h"
+
+ int main(){
+ float f1, f2, f3, f4, f5, f6, f7, f8, f9;
+ sscanf("0.512 0.250x5.129_-9.98 1.12*+54.32E3 +54.32E3^87.5E-3 87.5E-3$", "%f %fx%f_%f %f*%f %f^%f %f$", &f1, &f2, &f3, &f4, &f5, &f6, &f7, &f8, &f9);
+ printf("\n%f, %f, %f, %f, %f, %f, %f, %f, %f\n", f1, f2, f3, f4, f5, f6, f7, f8, f9);
+ }
+ '''
+ self.do_run(src, '\n0.512000, 0.250000, 5.129000, -9.980000, 1.120000, 54320.000000, 54320.000000, 0.087500, 0.087500\n')
+
def test_langinfo(self):
src = open(path_from_root('tests', 'langinfo', 'test.c'), 'r').read()
expected = open(path_from_root('tests', 'langinfo', 'output.txt'), 'r').read()
@@ -8631,6 +8660,122 @@ void*:16
main = main[:main.find('\n}')]
assert main.count('\n') == 7, 'must not emit too many postSets: %d' % main.count('\n')
+ def test_simd(self):
+ if Settings.USE_TYPED_ARRAYS != 2: return self.skip('needs ta2')
+ if Settings.ASM_JS: Settings.ASM_JS = 2 # does not validate
+ src = r'''
+#include <stdio.h>
+
+#include <emscripten/vector.h>
+
+static inline float32x4 __attribute__((always_inline))
+_mm_set_ps(const float __Z, const float __Y, const float __X, const float __W)
+{
+ return (float32x4){ __W, __X, __Y, __Z };
+}
+
+static __inline__ float32x4 __attribute__((__always_inline__))
+_mm_setzero_ps(void)
+{
+ return (float32x4){ 0.0, 0.0, 0.0, 0.0 };
+}
+
+int main(int argc, char **argv) {
+ float data[8];
+ for (int i = 0; i < 32; i++) data[i] = (1+i+argc)*(2+i+argc*argc);
+ {
+ float32x4 *a = (float32x4*)&data[0];
+ float32x4 *b = (float32x4*)&data[4];
+ float32x4 c, d;
+ c = *a;
+ d = *b;
+ printf("1floats! %d, %d, %d, %d %d, %d, %d, %d\n", (int)c[0], (int)c[1], (int)c[2], (int)c[3], (int)d[0], (int)d[1], (int)d[2], (int)d[3]);
+ c = c+d;
+ printf("2floats! %d, %d, %d, %d %d, %d, %d, %d\n", (int)c[0], (int)c[1], (int)c[2], (int)c[3], (int)d[0], (int)d[1], (int)d[2], (int)d[3]);
+ d = c*d;
+ printf("3floats! %d, %d, %d, %d %d, %d, %d, %d\n", (int)c[0], (int)c[1], (int)c[2], (int)c[3], (int)d[0], (int)d[1], (int)d[2], (int)d[3]);
+ c = _mm_setzero_ps();
+ printf("zeros %d, %d, %d, %d\n", (int)c[0], (int)c[1], (int)c[2], (int)c[3]);
+ }
+ {
+ uint32x4 *a = (uint32x4*)&data[0];
+ uint32x4 *b = (uint32x4*)&data[4];
+ uint32x4 c, d, e, f;
+ c = *a;
+ d = *b;
+ printf("4uints! %d, %d, %d, %d %d, %d, %d, %d\n", c[0], c[1], c[2], c[3], d[0], d[1], d[2], d[3]);
+ e = c+d;
+ f = c-d;
+ printf("5uints! %d, %d, %d, %d %d, %d, %d, %d\n", e[0], e[1], e[2], e[3], f[0], f[1], f[2], f[3]);
+ }
+ {
+ float32x4 c, d, e, f;
+ c = _mm_set_ps(9.0, 4.0, 0, -9.0);
+ d = _mm_set_ps(10.0, 14.0, -12, -2.0);
+ printf("6floats! %d, %d, %d, %d %d, %d, %d, %d\n", (int)c[0], (int)c[1], (int)c[2], (int)c[3], (int)d[0], (int)d[1], (int)d[2], (int)d[3]);
+ printf("7calcs: %d\n", emscripten_float32x4_signmask(c)); // TODO: just not just compilation but output as well
+ }
+
+ return 0;
+}
+ '''
+
+ self.do_run(src, '''1floats! 6, 12, 20, 30 42, 56, 72, 90
+2floats! 48, 68, 92, 120 42, 56, 72, 90
+3floats! 48, 68, 92, 120 2016, 3808, 6624, 10800
+zeros 0, 0, 0, 0
+4uints! 1086324736, 1094713344, 1101004800, 1106247680 1109917696, 1113587712, 1116733440, 1119092736
+5uints! -2098724864, -2086666240, -2077229056, -2069626880 -23592960, -18874368, -15728640, -12845056
+6floats! -9, 0, 4, 9 -2, -12, 14, 10
+''')
+
+ def test_simd2(self):
+ if Settings.ASM_JS: Settings.ASM_JS = 2 # does not validate
+
+ self.do_run(r'''
+ #include <stdio.h>
+
+ typedef float __m128 __attribute__ ((__vector_size__ (16)));
+
+ static inline __m128 __attribute__((always_inline))
+ _mm_set_ps(const float __Z, const float __Y, const float __X, const float __W)
+ {
+ return (__m128){ __W, __X, __Y, __Z };
+ }
+
+ static inline void __attribute__((always_inline))
+ _mm_store_ps(float *__P, __m128 __A)
+ {
+ *(__m128 *)__P = __A;
+ }
+
+ static inline __m128 __attribute__((always_inline))
+ _mm_add_ps(__m128 __A, __m128 __B)
+ {
+ return __A + __B;
+ }
+
+ using namespace std;
+
+ int main(int argc, char ** argv) {
+ float __attribute__((__aligned__(16))) ar[4];
+ __m128 v1 = _mm_set_ps(9.0, 4.0, 0, -9.0);
+ __m128 v2 = _mm_set_ps(7.0, 3.0, 2.5, 1.0);
+ __m128 v3 = _mm_add_ps(v1, v2);
+ _mm_store_ps(ar, v3);
+
+ for (int i = 0; i < 4; i++) {
+ printf("%f\n", ar[i]);
+ }
+
+ return 0;
+ }
+ ''', '''-8.000000
+2.500000
+7.000000
+16.000000
+''')
+
def test_gcc_unmangler(self):
Settings.NAMED_GLOBALS = 1 # test coverage for this
@@ -9044,6 +9189,9 @@ def process(filename):
if '_noasm' in shortname and Settings.ASM_JS:
print self.skip('case "%s" not relevant for asm.js' % shortname)
continue
+ if '_le32' in shortname and not self.is_le32():
+ print self.skip('case "%s" not relevant for non-le32 target' % shortname)
+ continue
self.emcc_args = emcc_args
if os.path.exists(shortname + '.emcc'):
if not self.emcc_args: continue
diff --git a/tests/test_other.py b/tests/test_other.py
index e251da5d..86e0eadf 100644
--- a/tests/test_other.py
+++ b/tests/test_other.py
@@ -2015,47 +2015,3 @@ a(int [32], char [5]*)
Popen([PYTHON, EMCC, path_from_root('tests', 'linpack.c'), '-O2', '-DSP', '--llvm-opts', '''['-O3', '-vectorize', '-vectorize-loops', '-bb-vectorize-vector-bits=128', '-force-vector-width=4']''']).communicate()
self.assertContained('Unrolled Single Precision', run_js('a.out.js'))
- def test_simd2(self):
- self.clear()
- open('src.cpp', 'w').write(r'''
-#include <stdio.h>
-
-#include <emscripten/vector.h>
-
-int main(int argc, char **argv) {
- float data[8];
- for (int i = 0; i < 32; i++) data[i] = (1+i+argc)*(2+i+argc*argc);
- {
- float32x4 *a = (float32x4*)&data[0];
- float32x4 *b = (float32x4*)&data[4];
- float32x4 c, d;
- c = *a;
- d = *b;
- printf("floats! %d, %d, %d, %d %d, %d, %d, %d\n", (int)c[0], (int)c[1], (int)c[2], (int)c[3], (int)d[0], (int)d[1], (int)d[2], (int)d[3]);
- c = c+d;
- printf("floats! %d, %d, %d, %d %d, %d, %d, %d\n", (int)c[0], (int)c[1], (int)c[2], (int)c[3], (int)d[0], (int)d[1], (int)d[2], (int)d[3]);
- d = c*d;
- printf("floats! %d, %d, %d, %d %d, %d, %d, %d\n", (int)c[0], (int)c[1], (int)c[2], (int)c[3], (int)d[0], (int)d[1], (int)d[2], (int)d[3]);
- }
- {
- uint32x4 *a = (uint32x4*)&data[0];
- uint32x4 *b = (uint32x4*)&data[4];
- uint32x4 c, d, e, f;
- c = *a;
- d = *b;
- printf("uints! %d, %d, %d, %d %d, %d, %d, %d\n", c[0], c[1], c[2], c[3], d[0], d[1], d[2], d[3]);
- e = c+d;
- f = c-d;
- printf("uints! %d, %d, %d, %d %d, %d, %d, %d\n", e[0], e[1], e[2], e[3], f[0], f[1], f[2], f[3]);
- }
- return 0;
-}
- ''')
- Popen([PYTHON, EMCC, 'src.cpp', '-O2']).communicate()
- self.assertContained('''floats! 6, 12, 20, 30 42, 56, 72, 90
-floats! 48, 68, 92, 120 42, 56, 72, 90
-floats! 48, 68, 92, 120 2016, 3808, 6624, 10800
-uints! 1086324736, 1094713344, 1101004800, 1106247680 1109917696, 1113587712, 1116733440, 1119092736
-uints! -2098724864, -2086666240, -2077229056, -2069626880 -23592960, -18874368, -15728640, -12845056
-''', run_js('a.out.js'))
-
diff --git a/tests/test_webgl_context_attributes_common.c b/tests/test_webgl_context_attributes_common.c
new file mode 100644
index 00000000..7131203b
--- /dev/null
+++ b/tests/test_webgl_context_attributes_common.c
@@ -0,0 +1,262 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+
+#include <emscripten.h>
+
+#define BUFFER_OFFSET(i) ((char *)NULL + (i))
+
+static const int WINDOWS_SIZE = 500;
+
+static GLfloat vertices[] = { 0.0f, 250.f, 0.0f,
+ -250.f, -250.f, 0.0f,
+ 250.f, -250.f, 0.0f };
+
+static GLfloat vertices2[] = { 0.0f, 250.f, -1.0f,
+ -250.f, -250.f, -1.0f,
+ 250.f, -250.f, -1.0f };
+
+static GLuint shaderProgram = 0;
+static GLuint verticesVBO = 0;
+static GLuint verticesVBO2 = 0;
+
+static unsigned char backgroundColor[4] = {255, 255, 255, 255};
+static unsigned char triangleColor[4] = {255, 0, 0, 255};
+static unsigned char triangleColor2[4] = {0, 255, 0, 255};
+
+static char vertexShaderSrc[] =
+ "precision highp float;"
+ "precision highp int;"
+
+ "uniform mat4 u_mvpMatrix;"
+ "uniform vec4 u_color;"
+
+ "attribute vec3 a_position;"
+
+ "varying vec4 v_color;"
+
+ "void main() {"
+ " gl_Position = u_mvpMatrix * vec4(a_position, 1.0);"
+ " v_color = u_color;"
+ "}"
+ ;
+
+static char fragmentShaderSrc[] =
+ "precision highp float;"
+ "precision highp int;"
+
+ "varying vec4 v_color;"
+
+ "void main() {"
+ " gl_FragColor = v_color;"
+ "}"
+ ;
+
+static GLuint createShader(const char *source, int type) {
+ GLuint shader = glCreateShader(type);
+ glShaderSource(shader, 1, (const GLchar**)(&source), NULL);
+ glCompileShader(shader);
+ return shader;
+}
+
+static GLuint createShaderProgram(const char *vertexShaderSrc, const char *fragmentShaderSrc) {
+ GLuint program = glCreateProgram();
+ glAttachShader(program, createShader(vertexShaderSrc, GL_VERTEX_SHADER));
+ glAttachShader(program, createShader(fragmentShaderSrc, GL_FRAGMENT_SHADER));
+ glLinkProgram(program);
+ return program;
+}
+
+void ortho(float left, float right, float bottom, float top, float nearVal, float farVal, GLfloat *projMatrix) {
+ float tx = -(right+left)/(right-left);
+ float ty = -(top+bottom)/(top-bottom);
+ float tz = -(farVal+nearVal)/(farVal-nearVal);
+ memset(projMatrix, 0, 16 * sizeof(GLfloat));
+ projMatrix[0] = 2.0f / (right-left);
+ projMatrix[3] = tx;
+ projMatrix[1*4+1] = 2.0f / (top-bottom);
+ projMatrix[1*4+3] = ty;
+ projMatrix[2*4+2] = -2.0f / (farVal-nearVal);
+ projMatrix[2*4+3] = tz;
+ projMatrix[3*4+3] = 1.0f;
+}
+
+static void initGlObjects() {
+ glGenBuffers(1, &verticesVBO);
+ glBindBuffer(GL_ARRAY_BUFFER, verticesVBO);
+ glBufferData(GL_ARRAY_BUFFER, 9*sizeof(float), vertices, GL_STATIC_DRAW);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ glGenBuffers(1, &verticesVBO2);
+ glBindBuffer(GL_ARRAY_BUFFER, verticesVBO2);
+ glBufferData(GL_ARRAY_BUFFER, 9*sizeof(float), vertices2, GL_STATIC_DRAW);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ shaderProgram = createShaderProgram(vertexShaderSrc, fragmentShaderSrc);
+}
+
+static void drawTriangle(GLuint verticesVBO, unsigned char r, unsigned char g, unsigned char b, unsigned char a) {
+ glUseProgram(shaderProgram);
+ GLuint posLoc = glGetAttribLocation(shaderProgram, "a_position");
+ GLuint mvpLoc = glGetUniformLocation(shaderProgram, "u_mvpMatrix");
+ GLuint colorLoc = glGetUniformLocation(shaderProgram, "u_color");
+
+ GLfloat mvpMat[16];
+ ortho(-WINDOWS_SIZE/2, WINDOWS_SIZE/2, -WINDOWS_SIZE/2, WINDOWS_SIZE/2, -100, 100, mvpMat);
+
+ glUniformMatrix4fv(mvpLoc, 1, GL_FALSE, mvpMat);
+ glUniform4f(colorLoc, r/255.f, g/255.f, b/255.f, a/255.f);
+
+ glBindBuffer(GL_ARRAY_BUFFER, verticesVBO);
+ glEnableVertexAttribArray(posLoc);
+ glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), BUFFER_OFFSET(0));
+
+ glDrawArrays(GL_TRIANGLES, 0, 3);
+
+ glBindBuffer(GL_ARRAY_B