summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xemcc3
-rw-r--r--src/jsifier.js3
-rw-r--r--src/library.js4
-rw-r--r--src/library_gl.js15
-rw-r--r--tests/gl_vertex_buffer.c195
-rw-r--r--tests/gl_vertex_buffer.pngbin0 -> 47668 bytes
-rw-r--r--tests/gl_vertex_buffer_pre.c177
-rw-r--r--tests/gl_vertex_buffer_pre.pngbin0 -> 83534 bytes
-rw-r--r--tests/test_browser.py6
-rw-r--r--tests/test_core.py137
10 files changed, 533 insertions, 7 deletions
diff --git a/emcc b/emcc
index 93621a83..958ed7cd 100755
--- a/emcc
+++ b/emcc
@@ -1125,6 +1125,9 @@ try:
else:
logging.debug('using response file for EXPORTED_FUNCTIONS, make sure it includes _malloc and _free')
+ if shared.Settings.ASM_JS and shared.Settings.DLOPEN_SUPPORT:
+ assert shared.Settings.DISABLE_EXCEPTION_CATCHING, 'no exceptions support with dlopen in asm yet'
+
## Compile source code to bitcode
logging.debug('compiling to bitcode')
diff --git a/src/jsifier.js b/src/jsifier.js
index 8592364d..f5682a1b 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -338,6 +338,7 @@ function JSify(data, functionsOnly, givenFunctions) {
// External variables in shared libraries should not be declared as
// they would shadow similarly-named globals in the parent, so do nothing here.
if (BUILD_AS_SHARED_LIB) return ret;
+ if (SIDE_MODULE) return [];
// Library items need us to emit something, but everything else requires nothing.
if (!LibraryManager.library[item.ident.slice(1)]) return ret;
}
@@ -1408,7 +1409,7 @@ function JSify(data, functionsOnly, givenFunctions) {
var extCall = false;
if (ASM_JS && funcData.setjmpTable) forceByPointer = true; // in asm.js mode, we must do an invoke for each call
- if (ASM_JS && DLOPEN_SUPPORT && !invoke) extCall = true; // go out, to be able to access other modules TODO: optimize
+ if (ASM_JS && DLOPEN_SUPPORT && !invoke && !funcData.setjmpTable) extCall = true; // go out, to be able to access other modules TODO: optimize
ident = Variables.resolveAliasToIdent(ident);
var shortident = ident.slice(1);
diff --git a/src/library.js b/src/library.js
index 632d8291..25d880a0 100644
--- a/src/library.js
+++ b/src/library.js
@@ -4273,10 +4273,6 @@ LibraryManager.library = {
__cxa_guard_release: function() {},
__cxa_guard_abort: function() {},
- _ZTVN10__cxxabiv119__pointer_type_infoE: [0], // is a pointer
- _ZTVN10__cxxabiv117__class_type_infoE: [1], // no inherited classes
- _ZTVN10__cxxabiv120__si_class_type_infoE: [2], // yes inherited classes
-
// Exceptions
__cxa_allocate_exception: function(size) {
return _malloc(size);
diff --git a/src/library_gl.js b/src/library_gl.js
index c134ad97..16ea5531 100644
--- a/src/library_gl.js
+++ b/src/library_gl.js
@@ -657,6 +657,20 @@ var LibraryGL = {
glBufferData__sig: 'viiii',
glBufferData: function(target, size, data, usage) {
+ switch (usage) { // fix usages, WebGL only has *_DRAW
+ case 0x88E1: // GL_STREAM_READ
+ case 0x88E2: // GL_STREAM_COPY
+ usage = 0x88E0; // GL_STREAM_DRAW
+ break;
+ case 0x88E5: // GL_STATIC_READ
+ case 0x88E6: // GL_STATIC_COPY
+ usage = 0x88E4; // GL_STATIC_DRAW
+ break;
+ case 0x88E9: // GL_DYNAMIC_READ
+ case 0x88EA: // GL_DYNAMIC_COPY
+ usage = 0x88E8; // GL_DYNAMIC_DRAW
+ break;
+ }
Module.ctx.bufferData(target, HEAPU8.subarray(data, data+size), usage);
},
@@ -3398,6 +3412,7 @@ var LibraryGL = {
// does not work for glBegin/End, where we generate renderer components dynamically and then
// disable them ourselves, but it does help with glDrawElements/Arrays.
if (!this.modifiedClientAttributes) {
+ GL.immediate.vertexCounter = (GL.immediate.stride * count) / 4; // XXX assuming float
return;
}
this.modifiedClientAttributes = false;
diff --git a/tests/gl_vertex_buffer.c b/tests/gl_vertex_buffer.c
new file mode 100644
index 00000000..6b695462
--- /dev/null
+++ b/tests/gl_vertex_buffer.c
@@ -0,0 +1,195 @@
+/*******************************************************************
+ * *
+ * 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.
+ */
+
+#if !EMSCRIPTEN
+#define USE_GLEW 0
+#endif
+
+#if USE_GLEW
+#include "GL/glew.h"
+#endif
+
+#include <SDL/SDL.h>
+
+#if !USE_GLEW
+#include "SDL/SDL_opengl.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+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*
+
+ screen = SDL_SetVideoMode( 640, 480, 16, SDL_OPENGL ); // *changed*
+ if ( !screen ) {
+ printf("Unable to set video mode: %s\n", SDL_GetError());
+ return 1;
+ }
+
+ // Set the OpenGL state after creating the context with SDL_SetVideoMode
+
+ glClearColor( 0, 0, 0, 0 );
+
+#if !EMSCRIPTEN
+ glEnable( GL_TEXTURE_2D ); // Need this to display a texture XXX unnecessary in OpenGL ES 2.0/WebGL
+#endif
+
+ glViewport( 0, 0, 640, 480 );
+
+ glMatrixMode( GL_MODELVIEW );
+ glLoadIdentity();
+
+ // Clear the screen before drawing
+ glClear( GL_COLOR_BUFFER_BIT );
+
+ typedef struct Color {
+ GLubyte r;
+ GLubyte g;
+ GLubyte b;
+ GLubyte a;
+ } Color;
+
+ typedef struct Vertex {
+ GLfloat x;
+ GLfloat y;
+ Color color;
+ } Vertex;
+
+ Vertex vertices[18] = {
+ {-1.00, 0.0, {0xFF, 0x00, 0xFF, 0xFF}},
+ {-1.00, 1.0, {0xFF, 0xFF, 0x00, 0xFF}},
+ {-0.75, 0.0, {0xFF, 0x00, 0x00, 0xFF}},
+ {-0.75, 1.0, {0xFF, 0xFF, 0xFF, 0xFF}},
+ {-0.50, 0.0, {0xFF, 0x00, 0x00, 0xFF}},
+ {-0.50, 1.0, {0xFF, 0xFF, 0x00, 0xFF}},
+ {-0.25, 0.0, {0xFF, 0x00, 0xFF, 0xFF}},
+ {-0.25, 1.0, {0xFF, 0xFF, 0x00, 0xFF}},
+ {-0.00, 0.0, {0xFF, 0x00, 0x00, 0xFF}},
+ {-0.00, 1.0, {0xFF, 0xFF, 0xFF, 0xFF}},
+ { 0.25, 0.0, {0xFF, 0x00, 0x00, 0xFF}},
+ { 0.25, 1.0, {0xFF, 0xFF, 0x00, 0xFF}},
+ { 0.50, 0.0, {0xFF, 0x00, 0xFF, 0xFF}},
+ { 0.50, 1.0, {0xFF, 0xFF, 0x00, 0xFF}},
+ { 0.75, 0.0, {0xFF, 0x00, 0x00, 0xFF}},
+ { 0.75, 1.0, {0xFF, 0xFF, 0xFF, 0xFF}},
+ { 1.00, 0.0, {0xFF, 0x00, 0x00, 0xFF}},
+ { 1.00, 1.0, {0xFF, 0xFF, 0x00, 0xFF}}
+ };
+
+ Vertex vertices2[18] = {
+ {-1.00, -1.0, {0xFF, 0x00, 0xFF, 0xFF}},
+ {-1.00, 0.0, {0xFF, 0xFF, 0x00, 0xFF}},
+ {-0.75, -1.0, {0xFF, 0x00, 0x00, 0xFF}},
+ {-0.75, 0.0, {0xFF, 0xFF, 0xFF, 0xFF}},
+ {-0.50, -1.0, {0xFF, 0x00, 0x00, 0xFF}},
+ {-0.50, 0.0, {0xFF, 0xFF, 0x00, 0xFF}},
+ {-0.25, -1.0, {0xFF, 0x00, 0xFF, 0xFF}},
+ {-0.25, 0.0, {0xFF, 0xFF, 0x00, 0xFF}},
+ {-0.00, -1.0, {0xFF, 0x00, 0x00, 0xFF}},
+ {-0.00, 0.0, {0xFF, 0xFF, 0xFF, 0xFF}},
+ { 0.25, -1.0, {0xFF, 0x00, 0x00, 0xFF}},
+ { 0.25, 0.0, {0xFF, 0xFF, 0x00, 0xFF}},
+ { 0.50, -1.0, {0xFF, 0x00, 0xFF, 0xFF}},
+ { 0.50, 0.0, {0xFF, 0xFF, 0x00, 0xFF}},
+ { 0.75, -1.0, {0xFF, 0x00, 0x00, 0xFF}},
+ { 0.75, 0.0, {0xFF, 0xFF, 0xFF, 0xFF}},
+ { 1.00, -1.0, {0xFF, 0x00, 0x00, 0xFF}},
+ { 1.00, 0.0, {0xFF, 0xFF, 0x00, 0xFF}}
+ };
+
+ // make a vertex buffer for the second set of vertices
+ GLuint vbo = 0;
+ glGenBuffers(1, &vbo);
+
+
+ // bind to it
+ glBindBuffer(GL_ARRAY_BUFFER, vbo);
+ // send it to gl
+ glBufferData(GL_ARRAY_BUFFER, sizeof(vertices2), vertices2, GL_STATIC_READ); // GL_STATIC_READ is not in WebGL!
+
+ // unbind from it
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+
+ // DRAW
+
+ // Clear the screen before drawing
+ glClear( GL_COLOR_BUFFER_BIT );
+
+ // This test ensures that we can use two separate arrays in memory for different
+ // attributes, and that they each can have different stride.
+ // The first test shows implicit striding (the zero indicates tightly packed)
+ // The second test shows explicit striding where the stride is passed in
+ // even though it also is tightly packed
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_COLOR_ARRAY);
+
+ // TEST 1 - clientside data
+
+ glVertexPointer(2, GL_FLOAT, sizeof(Vertex), vertices);
+ glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex), &vertices[0].color);
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 6);
+ glDrawArrays(GL_TRIANGLE_STRIP, 10, 3);
+
+
+
+ // TEST 2 - bind to array buffer, gl*Pointer calls are offsets into the buffer, which was previously uploaded to
+
+ glBindBuffer(GL_ARRAY_BUFFER, vbo);
+
+ glVertexPointer(2, GL_FLOAT, sizeof(Vertex), 0);
+ glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex), (GLvoid*)((GLvoid*)&vertices2[0].color - (GLvoid*)&vertices2[0]));
+
+// gldrawarrays first with a low number of vertices, then with a high number
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 6);
+ glDrawArrays(GL_TRIANGLE_STRIP, 10, 3);
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ glDisableClientState(GL_COLOR_ARRAY);
+ glDisableClientState(GL_VERTEX_ARRAY);
+
+ SDL_GL_SwapBuffers();
+
+#if !EMSCRIPTEN
+ // Wait for 3 seconds to give us a chance to see the image
+ SDL_Delay(3000);
+#endif
+
+ SDL_Quit();
+
+ return 0;
+}
diff --git a/tests/gl_vertex_buffer.png b/tests/gl_vertex_buffer.png
new file mode 100644
index 00000000..3e1f2230
--- /dev/null
+++ b/tests/gl_vertex_buffer.png
Binary files differ
diff --git a/tests/gl_vertex_buffer_pre.c b/tests/gl_vertex_buffer_pre.c
new file mode 100644
index 00000000..84b76569
--- /dev/null
+++ b/tests/gl_vertex_buffer_pre.c
@@ -0,0 +1,177 @@
+/*******************************************************************
+ * *
+ * 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.
+ */
+
+#if !EMSCRIPTEN
+#define USE_GLEW 0
+#endif
+
+#if USE_GLEW
+#include "GL/glew.h"
+#endif
+
+#include <SDL/SDL.h>
+
+#if !USE_GLEW
+#include "SDL/SDL_opengl.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+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*
+
+ screen = SDL_SetVideoMode( 640, 480, 16, SDL_OPENGL ); // *changed*
+ if ( !screen ) {
+ printf("Unable to set video mode: %s\n", SDL_GetError());
+ return 1;
+ }
+
+ // Set the OpenGL state after creating the context with SDL_SetVideoMode
+
+ glClearColor( 0, 0, 0, 0 );
+
+#if !EMSCRIPTEN
+ glEnable( GL_TEXTURE_2D ); // Need this to display a texture XXX unnecessary in OpenGL ES 2.0/WebGL
+#endif
+
+ glViewport( 0, 0, 640, 480 );
+
+ glMatrixMode( GL_MODELVIEW );
+ glLoadIdentity();
+
+ // Clear the screen before drawing
+ glClear( GL_COLOR_BUFFER_BIT );
+
+ typedef struct Color {
+ GLubyte r;
+ GLubyte g;
+ GLubyte b;
+ GLubyte a;
+ } Color;
+
+ typedef struct Vertex {
+ GLfloat x;
+ GLfloat y;
+ Color color;
+ } Vertex;
+
+ Vertex vertices[18] = {
+ {-1.00, 0.0, {0xFF, 0x00, 0xFF, 0xFF}},
+ {-1.00, 1.0, {0xFF, 0xFF, 0x00, 0xFF}},
+ {-0.75, 0.0, {0xFF, 0x00, 0x00, 0xFF}},
+ {-0.75, 1.0, {0xFF, 0xFF, 0xFF, 0xFF}},
+ {-0.50, 0.0, {0xFF, 0x00, 0x00, 0xFF}},
+ {-0.50, 1.0, {0xFF, 0xFF, 0x00, 0xFF}},
+ {-0.25, 0.0, {0xFF, 0x00, 0xFF, 0xFF}},
+ {-0.25, 1.0, {0xFF, 0xFF, 0x00, 0xFF}},
+ {-0.00, 0.0, {0xFF, 0x00, 0x00, 0xFF}},
+ {-0.00, 1.0, {0xFF, 0xFF, 0xFF, 0xFF}},
+ { 0.25, 0.0, {0xFF, 0x00, 0x00, 0xFF}},
+ { 0.25, 1.0, {0xFF, 0xFF, 0x00, 0xFF}},
+ { 0.50, 0.0, {0xFF, 0x00, 0xFF, 0xFF}},
+ { 0.50, 1.0, {0xFF, 0xFF, 0x00, 0xFF}},
+ { 0.75, 0.0, {0xFF, 0x00, 0x00, 0xFF}},
+ { 0.75, 1.0, {0xFF, 0xFF, 0xFF, 0xFF}},
+ { 1.00, 0.0, {0xFF, 0x00, 0x00, 0xFF}},
+ { 1.00, 1.0, {0xFF, 0xFF, 0x00, 0xFF}}
+ };
+
+ Vertex vertices2[18] = {
+ {-1.00, -1.0, {0xFF, 0x00, 0xFF, 0xFF}},
+ {-1.00, 0.0, {0xFF, 0xFF, 0x00, 0xFF}},
+ {-0.75, -1.0, {0xFF, 0x00, 0x00, 0xFF}},
+ {-0.75, 0.0, {0xFF, 0xFF, 0xFF, 0xFF}},
+ {-0.50, -1.0, {0xFF, 0x00, 0x00, 0xFF}},
+ {-0.50, 0.0, {0xFF, 0xFF, 0x00, 0xFF}},
+ {-0.25, -1.0, {0xFF, 0x00, 0xFF, 0xFF}},
+ {-0.25, 0.0, {0xFF, 0xFF, 0x00, 0xFF}},
+ {-0.00, -1.0, {0xFF, 0x00, 0x00, 0xFF}},
+ {-0.00, 0.0, {0xFF, 0xFF, 0xFF, 0xFF}},
+ { 0.25, -1.0, {0xFF, 0x00, 0x00, 0xFF}},
+ { 0.25, 0.0, {0xFF, 0xFF, 0x00, 0xFF}},
+ { 0.50, -1.0, {0xFF, 0x00, 0xFF, 0xFF}},
+ { 0.50, 0.0, {0xFF, 0xFF, 0x00, 0xFF}},
+ { 0.75, -1.0, {0xFF, 0x00, 0x00, 0xFF}},
+ { 0.75, 0.0, {0xFF, 0xFF, 0xFF, 0xFF}},
+ { 1.00, -1.0, {0xFF, 0x00, 0x00, 0xFF}},
+ { 1.00, 0.0, {0xFF, 0xFF, 0x00, 0xFF}}
+ };
+
+ // make a vertex buffer for the second set of vertices
+ GLuint vbo = 0;
+ glGenBuffers(1, &vbo);
+
+
+ // bind to it
+ glBindBuffer(GL_ARRAY_BUFFER, vbo);
+ // send it to gl
+ glBufferData(GL_ARRAY_BUFFER, sizeof(vertices2), vertices2, GL_STATIC_DRAW);
+
+ // unbind from it
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+
+ // DRAW
+
+ // Clear the screen before drawing
+ glClear( GL_COLOR_BUFFER_BIT );
+
+ // This test ensures that we can use two separate arrays in memory for different
+ // attributes, and that they each can have different stride.
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_COLOR_ARRAY);
+
+ glVertexPointer(2, GL_FLOAT, sizeof(Vertex), vertices);
+ glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex), &vertices[0].color);
+ glDrawArrays(GL_TRIANGLE_STRIP, 10, 3);
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 6);
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ glDisableClientState(GL_COLOR_ARRAY);
+ glDisableClientState(GL_VERTEX_ARRAY);
+
+ SDL_GL_SwapBuffers();
+
+#if !EMSCRIPTEN
+ // Wait for 3 seconds to give us a chance to see the image
+ SDL_Delay(3000);
+#endif
+
+ SDL_Quit();
+
+ return 0;
+}
diff --git a/tests/gl_vertex_buffer_pre.png b/tests/gl_vertex_buffer_pre.png
new file mode 100644
index 00000000..5677a868
--- /dev/null
+++ b/tests/gl_vertex_buffer_pre.png
Binary files differ
diff --git a/tests/test_browser.py b/tests/test_browser.py
index b014b4f6..3ac640f1 100644
--- a/tests/test_browser.py
+++ b/tests/test_browser.py
@@ -1207,6 +1207,12 @@ If manually bisecting:
def test_gl_stride(self):
self.btest('gl_stride.c', reference='gl_stride.png', args=['-s', 'GL_UNSAFE_OPTS=0', '-s', 'LEGACY_GL_EMULATION=1'])
+ def test_gl_vertex_buffer_pre(self):
+ self.btest('gl_vertex_buffer_pre.c', reference='gl_vertex_buffer_pre.png', args=['-s', 'GL_UNSAFE_OPTS=0', '-s', 'LEGACY_GL_EMULATION=1'])
+
+ 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)
+
def test_matrix_identity(self):
self.btest('gl_matrix_identity.c', expected=['-1882984448', '460451840'], args=['-s', 'LEGACY_GL_EMULATION=1'])
diff --git a/tests/test_core.py b/tests/test_core.py
index 6bb5ccb6..ff768b5c 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -5751,8 +5751,8 @@ def process(filename):
if Settings.ASM_JS and os.path.exists(SPIDERMONKEY_ENGINE[0]):
out = run_js('liblib.so', engine=SPIDERMONKEY_ENGINE, full_output=True, stderr=STDOUT)
- assert 'asm' in out
- self.validate_asmjs(out)
+ if 'asm' in out:
+ self.validate_asmjs(out)
def test_dlfcn_data_and_fptr(self):
if Settings.ASM_JS: return self.skip('this is not a valid case - libraries should not be able to access their parents globals willy nilly')
@@ -6226,6 +6226,139 @@ ok
Settings.EXPORTED_FUNCTIONS = ['_main', '_malloc', '_free']
self.do_run(src, '''*294,153*''', force_c=True, post_build=self.dlfcn_post_build)
+ def test_dlfcn_longjmp(self):
+ if not self.can_dlfcn(): return
+
+ self.prep_dlfcn_lib()
+ lib_src = r'''
+ #include <setjmp.h>
+
+ void jumpy(jmp_buf buf) {
+ static int i = 0;
+ i++;
+ if (i == 10) longjmp(buf, i);
+ printf("pre %d\n", i);
+ }
+ '''
+ Settings.EXPORTED_FUNCTIONS = ['_jumpy']
+ dirname = self.get_dir()
+ filename = os.path.join(dirname, 'liblib.c')
+ self.build(lib_src, dirname, filename)
+ shutil.move(filename + '.o.js', os.path.join(dirname, 'liblib.so'))
+
+ self.prep_dlfcn_main()
+ src = r'''
+ #include <assert.h>
+ #include <stdio.h>
+ #include <dlfcn.h>
+ #include <setjmp.h>
+
+ typedef void (*jumpfunc)(jmp_buf);
+
+ int main() {
+ printf("go!\n");
+
+ void *lib_handle;
+ lib_handle = dlopen("liblib.so", RTLD_NOW);
+ assert(lib_handle != NULL);
+
+ jumpfunc jumpy = (jumpfunc)dlsym(lib_handle, "jumpy");
+ assert(jumpy);
+
+ jmp_buf buf;
+ int jmpval = setjmp(buf);
+ if (jmpval == 0) {
+ while (1) jumpy(buf);
+ } else {
+ printf("out!\n");
+ }
+
+ return 0;
+ }
+ '''
+ Settings.EXPORTED_FUNCTIONS = ['_main', '_malloc', '_free']
+ self.do_run(src, '''go!
+pre 1
+pre 2
+pre 3
+pre 4
+pre 5
+pre 6
+pre 7
+pre 8
+pre 9
+out!
+''', post_build=self.dlfcn_post_build, force_c=True)
+
+ def zzztest_dlfcn_exceptions(self): # TODO: make this work. need to forward tempRet0 across modules
+ if not self.can_dlfcn(): return
+
+ Settings.DISABLE_EXCEPTION_CATCHING = 0
+
+ self.prep_dlfcn_lib()
+ lib_src = r'''
+ extern "C" {
+ int ok() {
+ return 65;
+ }
+ int fail() {
+ throw 123;
+ }
+ }
+ '''
+ Settings.EXPORTED_FUNCTIONS = ['_ok', '_fail']
+ dirname = self.get_dir()
+ filename = os.path.join(dirname, 'liblib.cpp')
+ self.build(lib_src, dirname, filename)
+ shutil.move(filename + '.o.js', os.path.join(dirname, 'liblib.so'))
+
+ self.prep_dlfcn_main()
+ src = r'''
+ #include <assert.h>
+ #include <stdio.h>
+ #include <dlfcn.h>
+
+ typedef int (*intfunc)();
+
+ int main() {
+ printf("go!\n");
+
+ void *lib_handle;
+ lib_handle = dlopen("liblib.so", RTLD_NOW);
+ assert(lib_handle != NULL);
+
+ intfunc okk = (intfunc)dlsym(lib_handle, "ok");
+ intfunc faill = (intfunc)dlsym(lib_handle, "fail");
+ assert(okk && faill);
+
+ try {
+ printf("ok: %d\n", okk());
+ } catch(...) {
+ printf("wha\n");
+ }
+
+ try {
+ printf("fail: %d\n", faill());
+ } catch(int x) {
+ printf("int %d\n", x);
+ }
+
+ try {
+ printf("fail: %d\n", faill());
+ } catch(double x) {
+ printf("caught %f\n", x);
+ }
+
+ return 0;
+ }
+ '''
+ Settings.EXPORTED_FUNCTIONS = ['_main', '_malloc', '_free']
+ self.do_run(src, '''go!
+ok: 65
+int 123
+ok
+''', post_build=self.dlfcn_post_build)
+
def test_rand(self):
return self.skip('rand() is now random') # FIXME