aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/paper.tex8
-rwxr-xr-xemcc39
-rw-r--r--src/library.js39
-rw-r--r--src/library_egl.js31
-rw-r--r--src/library_gl.js8
-rw-r--r--src/preamble.js6
-rw-r--r--tests/cube_explosion.c7
-rw-r--r--tools/shared.py4
8 files changed, 85 insertions, 57 deletions
diff --git a/docs/paper.tex b/docs/paper.tex
index 4ad795b8..3b8da618 100644
--- a/docs/paper.tex
+++ b/docs/paper.tex
@@ -114,7 +114,7 @@ main ones of which are Clang and LLVM-GCC) into the
LLVM intermediary representation (which can be machine-readable
bitcode, or human-readable assembly), and then passes it
through a \emph{backend} which generates actual machine code for a particular
-architecure. Emscripten plays the role of a backend which targets JavaScript.
+architecture. Emscripten plays the role of a backend which targets JavaScript.
By using Emscripten, potentially many languages can be
run on the web, using one of the following methods:
@@ -138,7 +138,7 @@ run on the web, using one of the following methods:
From a technical standpoint, one challenge in designing and implementing
Emscripten is that it compiles a low-level language -- LLVM assembly -- into
-a high-level one -- JavaScript. This is somethat the reverse of the usual
+a high-level one -- JavaScript. This is somewhat the reverse of the usual
situation one is in when building a compiler, and leads to some unique
difficulties. For example, to get good performance in JavaScript one must
use natural JavaScript code flow structures, like loops and ifs, but
@@ -475,7 +475,7 @@ a compilation option, SAFE\_HEAP, which generates code that checks that LSC hold
doesn't. It also warns about other memory-related issues like
reading from memory before a value was written (somewhat similarly to tools
like Valgrind\footnote{\url{http://valgrind.org/}}). When such problems are detected, possible solutions are to ignore the issue (if it has no actual
-consqeuences), or alter the source code.
+consequences), or alter the source code.
Note that it is somewhat wasteful to allocate 4 memory locations for
a 32-bit integer, and use only one of them. It is possible to change
@@ -737,7 +737,7 @@ surprisingly easy to implement. For example, C++ exceptions are represented in
LLVM by \emph{invoke} and \emph{unwind}, where \emph{invoke} is a call to a function that will
potentially trigger an \emph{unwind}, and \emph{unwind} returns to the earliest invoke.
If one were to implement those
-in a typical compiler, doing so would require careful work. In Emscripen, however,
+in a typical compiler, doing so would require careful work. In Emscripten, however,
it is possible to do so using JavaScript exceptions in a straightforward manner:
\emph{invoke} becomes a function call wrapped in a \emph{try} block, and \emph{unwind}
becomes \emph{throw}. This is a case where compiling to a high-level language turns
diff --git a/emcc b/emcc
index 88f38bda..3ea0a964 100755
--- a/emcc
+++ b/emcc
@@ -248,6 +248,15 @@ Options that are modified or new in %s include:
are compiling to. To run your code, you
will need both the .html and the .data.
+ emcc runs tools/file_packager.py to do the
+ actual packaging of embedded and preloaded
+ files. You can run the file packager yourself
+ if you want, see docs inside that file. You
+ should then put the output of the file packager
+ in an emcc --pre-js, so that it executes before
+ your main compiled code (or run it before in
+ some other way).
+
--compression <codec> Compress both the compiled code and embedded/
preloaded files. <codec> should be a triple,
@@ -1089,36 +1098,6 @@ try:
shared.Building.llvm_opt(in_temp(target_basename + '.bc'), link_opts)
if DEBUG: save_intermediate('linktime', 'bc')
- # Optimization and lto can add new intrinsics like memcpy that were not present before. We
- # are now *after* linking in libc, so we missed our chance to get memcpy - check and add it now
- # if necessary
- final_symbols = shared.Building.llvm_nm(final)
- need_memcpy = False
- for symbol in final_symbols.undefs:
- if symbol in MEMCPY_ALIASES:
- need_memcpy = True
- break
- has_memcpy = False
- for symbol in final_symbols.defs:
- if symbol in MEMCPY_ALIASES:
- has_memcpy = True
- break
- if need_memcpy and not has_memcpy:
- if DEBUG: print >> sys.stderr, 'memcpy intrinsic added in optimizations, linking in optimized memcpy'
- memcpy = in_temp('memcpy.bc')
- force_cxx = os.environ.get('EMMAKEN_CXX')
- if force_cxx is not None: del os.environ['EMMAKEN_CXX'] # memcpy must be compiled as C
- execute([shared.PYTHON, shared.EMCC, shared.path_from_root('system', 'lib', 'libc', 'musl', 'memcpy.c'), '-o', memcpy], stdout=stdout, stderr=stderr)
- if force_cxx is not None: os.environ['EMMAKEN_CXX'] = force_cxx
- shared.Building.llvm_opt(memcpy, llvm_opts) # optimize it just like normal code; no point in lto though
- next = final + '.postrinsics.bc'
- shared.Building.link([final, memcpy], next)
- final = next
- if shared.Settings.ASM_JS: # export it so other library functions etc. can use it
- if '_memcpy' not in shared.Settings.EXPORTED_FUNCTIONS:
- shared.Settings.EXPORTED_FUNCTIONS.append('_memcpy')
- if DEBUG: save_intermediate('postrinsics', 'bc')
-
# Prepare .ll for Emscripten
if not LEAVE_INPUTS_RAW:
final = shared.Building.llvm_dis(final, final + '.ll')
diff --git a/src/library.js b/src/library.js
index 53fc8617..5071552a 100644
--- a/src/library.js
+++ b/src/library.js
@@ -4217,16 +4217,31 @@ LibraryManager.library = {
return ret;
},
+ memcpy__asm: 'true',
+ memcpy__sig: 'iiii',
memcpy: function (dest, src, num) {
- // simple version, in general it should not be used - we should pull it in from libc
- if (!_memcpy.shown) {
- _memcpy.shown = true;
- Module.printErr('warning: library.js memcpy should not be running, it is only for testing!');
+ dest = dest|0; src = src|0; num = num|0;
+ if ((dest&3) == (src&3)) {
+ while (dest & 3 & num) {
+ {{{ makeSetValueAsm('dest', 0, makeGetValueAsm('src', 0, 'i8'), 'i8') }}};
+ dest = (dest+1)|0;
+ src = (src+1)|0;
+ num = (num-1)|0;
+ }
+ while ((num|0) >= 4) {
+ {{{ makeSetValueAsm('dest', 0, makeGetValueAsm('src', 0, 'i32'), 'i32') }}};
+ dest = (dest+4)|0;
+ src = (src+4)|0;
+ num = (num-4)|0;
+ }
}
-#endif
- while (num--) {
- HEAP8[dest++] = HEAP8[src++];
+ while ((num|0) > 0) {
+ {{{ makeSetValueAsm('dest', 0, makeGetValueAsm('src', 0, 'i8'), 'i8') }}};
+ dest = (dest+1)|0;
+ src = (src+1)|0;
+ num = (num-1)|0;
}
+ return dest|0;
},
wmemcpy: function() { throw 'wmemcpy not implemented' },
@@ -5601,11 +5616,11 @@ LibraryManager.library = {
// ==========================================================================
__utsname_struct_layout: Runtime.generateStructInfo([
- 'sysname',
- 'nodename',
- 'release',
- 'version',
- 'machine'], '%struct.utsname'),
+ 'sysname',
+ 'nodename',
+ 'release',
+ 'version',
+ 'machine'], '%struct.utsname'),
uname__deps: ['__utsname_struct_layout'],
uname: function(name) {
// int uname(struct utsname *name);
diff --git a/src/library_egl.js b/src/library_egl.js
index 1c35ddf4..a9eb37dd 100644
--- a/src/library_egl.js
+++ b/src/library_egl.js
@@ -71,6 +71,17 @@ var LibraryEGL = {
return 0;
}
},
+
+ // EGLAPI EGLBoolean EGLAPIENTRY eglTerminate(EGLDisplay dpy);
+ eglTerminate: function(display) {
+ if (display != 62000 /* Magic ID for Emscripten 'default display' */) {
+ EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);
+ return 0;
+ }
+ // TODO: Tear down EGL here. Currently a no-op since we don't need to actually do anything here for the browser.
+ EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
+ return 1;
+ },
// EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
eglGetConfigs: function(display, configs, config_size, numConfigs) {
@@ -228,6 +239,22 @@ var LibraryEGL = {
return 62004; // Magic ID for Emscripten EGLContext
},
+ // EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay dpy, EGLContext ctx);
+ eglDestroyContext: function(display, context) {
+ if (display != 62000 /* Magic ID for Emscripten 'default display' */) {
+ EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);
+ return 0;
+ }
+
+ if (context != 62004 /* Magic ID for Emscripten EGLContext */) {
+ EGL.setErrorCode(0x3006 /* EGL_BAD_CONTEXT */);
+ return 0;
+ }
+
+ EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
+ return 1;
+ },
+
// EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value);
eglQuerySurface: function(display, surface, attribute, value) {
if (display != 62000 /* Magic ID for Emscripten 'default display' */) {
@@ -336,6 +363,7 @@ var LibraryEGL = {
return EGL.eglErrorCode;
},
+ // EGLAPI const char * EGLAPIENTRY eglQueryString(EGLDisplay dpy, EGLint name);
eglQueryString: function(display, name) {
if (display != 62000 /* Magic ID for Emscripten 'default display' */) {
EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);
@@ -412,7 +440,8 @@ var LibraryEGL = {
EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
return 1;
},
-
+
+ // EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surface);
eglSwapBuffers: function() {
EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
},
diff --git a/src/library_gl.js b/src/library_gl.js
index 0566b3a0..f7966dab 100644
--- a/src/library_gl.js
+++ b/src/library_gl.js
@@ -424,11 +424,9 @@ var LibraryGL = {
},
glIsTexture: function(texture) {
- var fb = GL.textures[texture];
- if (typeof(fb) == 'undefined') {
- return 0;
- }
- return Module.ctx.isTexture(fb);
+ var texture = GL.textures[texture];
+ if (!texture) return 0;
+ return Module.ctx.isTexture(texture);
},
glGenBuffers__sig: 'vii',
diff --git a/src/preamble.js b/src/preamble.js
index 8a68736e..aab50e9a 100644
--- a/src/preamble.js
+++ b/src/preamble.js
@@ -35,8 +35,8 @@ function SAFE_HEAP_ACCESS(dest, type, store, ignore) {
// When using typed arrays, reads over the top of TOTAL_MEMORY will fail silently, so we must
// correct that by growing TOTAL_MEMORY as needed. Without typed arrays, memory is a normal
// JS array so it will work (potentially slowly, depending on the engine).
- assert(dest < STATICTOP);
- assert(STATICTOP <= TOTAL_MEMORY);
+ assert(ignore || dest < STATICTOP);
+ assert(ignore || STATICTOP <= TOTAL_MEMORY);
#endif
#if USE_TYPED_ARRAYS == 2
@@ -482,7 +482,7 @@ Module['ALLOC_NONE'] = ALLOC_NONE;
var _memset = function(ptr, value, num) {
var stop = ptr + num;
while (ptr < stop) {
- {{{ makeSetValueAsm('ptr++', 0, 'value', 'i8', null, null, null, true) }}};
+ {{{ makeSetValue('ptr++', 0, 'value', 'i8', null, true) }}};
}
}
diff --git a/tests/cube_explosion.c b/tests/cube_explosion.c
index ee990a57..3f55b3c6 100644
--- a/tests/cube_explosion.c
+++ b/tests/cube_explosion.c
@@ -64,8 +64,11 @@ int main(int argc, char *argv[])
// Create a texture
GLuint texture;
+ assert(!glIsTexture(1)); // not a texture
glGenTextures( 1, &texture );
+ assert(!glIsTexture(texture)); // not a texture until glBindTexture
glBindTexture( GL_TEXTURE_2D, texture );
+ assert(glIsTexture(texture)); // NOW it is a texture
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
GLubyte textureData[16*16*4];
@@ -223,6 +226,10 @@ int main(int argc, char *argv[])
SDL_GL_SwapBuffers();
+ assert(glIsTexture(texture)); // still a texture
+ glDeleteTextures(1, &texture);
+ assert(!glIsTexture(texture)); // but not anymore
+
verify();
#if !EMSCRIPTEN
diff --git a/tools/shared.py b/tools/shared.py
index e41d7c5c..b55e60dc 100644
--- a/tools/shared.py
+++ b/tools/shared.py
@@ -1081,7 +1081,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e
Building._is_ar_cache[filename] = sigcheck
return sigcheck
except Exception, e:
- print >> sys.stderr, 'shared.Building.is_ar failed to test whether file \'%s\' is a llvm archive file! Failed on exception: %s' % (filename, e)
+ if DEBUG: print >> sys.stderr, 'shared.Building.is_ar failed to test whether file \'%s\' is a llvm archive file! Failed on exception: %s' % (filename, e)
return False
@staticmethod
@@ -1101,7 +1101,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e
assert os.path.exists(test_ll)
try_delete(test_ll)
except Exception, e:
- print >> sys.stderr, 'shared.Building.is_bitcode failed to test whether file \'%s\' is a llvm bitcode file! Failed on exception: %s' % (filename, e)
+ if DEBUG: print >> sys.stderr, 'shared.Building.is_bitcode failed to test whether file \'%s\' is a llvm bitcode file! Failed on exception: %s' % (filename, e)
return False
# look for magic signature