summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xemscripten.py7
-rw-r--r--src/compiler.js2
-rw-r--r--src/jsifier.js9
-rw-r--r--src/library.js8
-rw-r--r--src/library_browser.js1
-rw-r--r--src/library_egl.js5
-rw-r--r--src/library_fs.js27
-rw-r--r--src/library_gl.js281
-rw-r--r--src/library_sdl.js4
-rw-r--r--src/modules.js18
-rw-r--r--src/parseTools.js2
-rw-r--r--src/postamble.js1
-rw-r--r--src/settings.js5
-rw-r--r--system/include/compat/math.h14
-rw-r--r--system/include/compat/stdlib.h16
-rw-r--r--system/include/compat/string.h17
-rw-r--r--system/include/compat/sys/stat.h20
-rw-r--r--system/include/compat/sys/timeb.h (renamed from system/include/libc/sys/timeb.h)0
-rw-r--r--system/include/compat/unistd.h16
-rw-r--r--system/include/compat/xlocale.h21
-rw-r--r--system/include/emscripten/emscripten.h13
-rw-r--r--system/include/libc/stdlib.h2
-rw-r--r--system/include/libc/string.h2
-rw-r--r--system/include/libc/sys/unistd.h1
-rw-r--r--system/include/xlocale.h7
-rw-r--r--tests/aniso.c10
-rwxr-xr-xtests/runner.py24
-rw-r--r--tests/sdl_ogl_proc_alias.c180
-rw-r--r--tests/sockets/test_sockets_echo_server.c8
-rw-r--r--tests/sockets/test_sockets_partial_server.c24
-rw-r--r--tests/sockets/webrtc_host.c89
-rw-r--r--tests/sockets/webrtc_peer.c81
-rw-r--r--tests/test_browser.py117
-rw-r--r--tests/test_core.py8
-rw-r--r--tests/test_sockets.py68
-rw-r--r--tools/find_bigfuncs.py4
-rw-r--r--tools/response_file.py4
-rw-r--r--tools/shared.py1
-rwxr-xr-xtools/source-maps/sourcemapper.js43
39 files changed, 833 insertions, 327 deletions
diff --git a/emscripten.py b/emscripten.py
index 1b1284c7..a156ca73 100755
--- a/emscripten.py
+++ b/emscripten.py
@@ -190,6 +190,11 @@ def emscript(infile, settings, outfile, libraries=[], compiler_engine=None,
open(forwarded_file, 'w').write(forwarded_data)
if DEBUG: print >> sys.stderr, ' emscript: phase 1 took %s seconds' % (time.time() - t)
+ indexed_functions = set()
+ forwarded_json = json.loads(forwarded_data)
+ for key in forwarded_json['Functions']['indexedFunctions'].iterkeys():
+ indexed_functions.add(key)
+
# Phase 2 - func
cores = int(os.environ.get('EMCC_CORES') or multiprocessing.cpu_count())
@@ -203,8 +208,6 @@ def emscript(infile, settings, outfile, libraries=[], compiler_engine=None,
chunk_size = MAX_CHUNK_SIZE # if 1 core, just use the max chunk size
if DEBUG: t = time.time()
- forwarded_json = json.loads(forwarded_data)
- indexed_functions = set()
if settings.get('ASM_JS'):
settings['EXPORTED_FUNCTIONS'] = forwarded_json['EXPORTED_FUNCTIONS']
save_settings()
diff --git a/src/compiler.js b/src/compiler.js
index 365ff32f..2390f4c9 100644
--- a/src/compiler.js
+++ b/src/compiler.js
@@ -203,6 +203,8 @@ if (phase == 'pre') {
}
}
+if (VERBOSE) printErr('VERBOSE is on, this generates a lot of output and can slow down compilation');
+
// Load compiler code
load('framework.js');
diff --git a/src/jsifier.js b/src/jsifier.js
index c92526d2..8ed19194 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -16,6 +16,8 @@ var SETJMP_LABEL = -1;
var INDENTATION = ' ';
+var functionStubSigs = {};
+
// JSifier
function JSify(data, functionsOnly, givenFunctions) {
var mainPass = !functionsOnly;
@@ -407,6 +409,11 @@ function JSify(data, functionsOnly, givenFunctions) {
// functionStub
substrate.addActor('FunctionStub', {
processItem: function(item) {
+ // note the signature
+ if (item.returnType && item.params) {
+ functionStubSigs[item.ident] = Functions.getSignature(item.returnType.text, item.params.map(function(arg) { return arg.type }), false);
+ }
+
function addFromLibrary(ident) {
if (ident in addedLibraryItems) return '';
addedLibraryItems[ident] = true;
@@ -1537,7 +1544,7 @@ function JSify(data, functionsOnly, givenFunctions) {
// This is a call through an invoke_*, either a forced one, or a setjmp-required one
// note: no need to update argsTypes at this point
if (byPointerForced) Functions.unimplementedFunctions[callIdent] = sig;
- args.unshift(byPointerForced ? Functions.getIndex(callIdent, undefined, sig) : asmCoercion(callIdent, 'i32'));
+ args.unshift(byPointerForced ? Functions.getIndex(callIdent, sig) : asmCoercion(callIdent, 'i32'));
callIdent = 'invoke_' + sig;
}
} else if (SAFE_DYNCALLS) {
diff --git a/src/library.js b/src/library.js
index ee49ae1f..9e78db13 100644
--- a/src/library.js
+++ b/src/library.js
@@ -7235,7 +7235,7 @@ LibraryManager.library = {
socket__deps: ['$FS', '$Sockets'],
socket: function(family, type, protocol) {
var INCOMING_QUEUE_LENGTH = 64;
- var stream = FS.createStream({
+ var info = FS.createStream({
addr: null,
port: null,
inQueue: new CircularBuffer(INCOMING_QUEUE_LENGTH),
@@ -7244,7 +7244,7 @@ LibraryManager.library = {
socket: true,
stream_ops: {}
});
- assert(stream.fd < 64); // select() assumes socket fd values are in 0..63
+ assert(info.fd < 64); // select() assumes socket fd values are in 0..63
var stream = type == {{{ cDefine('SOCK_STREAM') }}};
if (protocol) {
assert(stream == (protocol == {{{ cDefine('IPPROTO_TCP') }}})); // if stream, must be tcp
@@ -7357,8 +7357,7 @@ LibraryManager.library = {
}
};
};
-
- return stream.fd;
+ return info.fd;
},
mkport__deps: ['$Sockets'],
@@ -7452,6 +7451,7 @@ LibraryManager.library = {
buffer.set(data, info.header.byteLength);
connection.send('unreliable', buffer.buffer);
+ return ret;
},
recvmsg__deps: ['$FS', '$Sockets', 'bind', '__setErrNo', '$ERRNO_CODES', 'htons'],
diff --git a/src/library_browser.js b/src/library_browser.js
index f65791e4..511e158e 100644
--- a/src/library_browser.js
+++ b/src/library_browser.js
@@ -6,6 +6,7 @@ mergeInto(LibraryManager.library, {
$Browser__deps: ['$PATH'],
$Browser__postset: 'Module["requestFullScreen"] = function(lockPointer, resizeCanvas) { Browser.requestFullScreen(lockPointer, resizeCanvas) };\n' + // exports
'Module["requestAnimationFrame"] = function(func) { Browser.requestAnimationFrame(func) };\n' +
+ 'Module["setCanvasSize"] = function(width, height, noUpdates) { Browser.setCanvasSize(width, height, noUpdates) };\n' +
'Module["pauseMainLoop"] = function() { Browser.mainLoop.pause() };\n' +
'Module["resumeMainLoop"] = function() { Browser.mainLoop.resume() };\n' +
'Module["getUserMedia"] = function() { Browser.getUserMedia() }',
diff --git a/src/library_egl.js b/src/library_egl.js
index 0e96e92f..ff912ed2 100644
--- a/src/library_egl.js
+++ b/src/library_egl.js
@@ -489,6 +489,11 @@ var LibraryEGL = {
eglSwapBuffers: function() {
EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
},
+
+ eglGetProcAddress__deps: ['emscripten_GetProcAddress'],
+ eglGetProcAddress: function(name_) {
+ return _emscripten_GetProcAddress(Pointer_stringify(name_));
+ },
};
autoAddDeps(LibraryEGL, '$EGL');
diff --git a/src/library_fs.js b/src/library_fs.js
index 8ea6b06f..9d1f0cfd 100644
--- a/src/library_fs.js
+++ b/src/library_fs.js
@@ -18,7 +18,7 @@ mergeInto(LibraryManager.library, {
devices: [null],
streams: [null],
nextInode: 1,
- name_table: new Array(4096),
+ name_table: null,
currentPath: '/',
initialized: false,
// Whether we are currently ignoring permissions. Useful when preparing the
@@ -27,16 +27,21 @@ mergeInto(LibraryManager.library, {
// to modify the filesystem freely before run() is called.
ignorePermissions: true,
- ErrnoError: function(errno) {
- this.errno = errno;
- for (var key in ERRNO_CODES) {
- if (ERRNO_CODES[key] === errno) {
- this.code = key;
- break;
+ ErrnoError: (function() {
+ function ErrnoError(errno) {
+ this.errno = errno;
+ for (var key in ERRNO_CODES) {
+ if (ERRNO_CODES[key] === errno) {
+ this.code = key;
+ break;
+ }
}
- }
- this.message = ERRNO_MESSAGES[errno] + ' : ' + new Error().stack;
- },
+ this.message = ERRNO_MESSAGES[errno];
+ };
+ ErrnoError.prototype = new Error();
+ ErrnoError.prototype.constructor = ErrnoError;
+ return ErrnoError;
+ }()),
handleFSError: function(e) {
if (!(e instanceof FS.ErrnoError)) throw e + ' : ' + new Error().stack;
@@ -863,6 +868,8 @@ mergeInto(LibraryManager.library, {
assert(stderr.fd === 3, 'invalid handle for stderr (' + stderr.fd + ')');
},
staticInit: function() {
+ FS.name_table = new Array(4096);
+
FS.root = FS.createNode(null, '/', {{{ cDefine('S_IFDIR') }}} | 0777, 0);
FS.mount(MEMFS, {}, '/');
diff --git a/src/library_gl.js b/src/library_gl.js
index 8c724245..c134ad97 100644
--- a/src/library_gl.js
+++ b/src/library_gl.js
@@ -1285,10 +1285,11 @@ var LibraryGL = {
return Module.ctx.isFramebuffer(fb);
},
-#if DISABLE_GL_EMULATION == 0
+#if LEGACY_GL_EMULATION
// GL emulation: provides misc. functionality not present in OpenGL ES 2.0 or WebGL
+ $GLEmulation__deps: ['$GLImmediateSetup', 'glEnable', 'glDisable', 'glIsEnabled', 'glGetBooleanv', 'glGetIntegerv', 'glGetString', 'glCreateShader', 'glShaderSource', 'glCompileShader', 'glAttachShader', 'glDetachShader', 'glUseProgram', 'glDeleteProgram', 'glBindAttribLocation', 'glLinkProgram', 'glBindBuffer', 'glGetFloatv', 'glHint', 'glEnableVertexAttribArray', 'glDisableVertexAttribArray', 'glVertexAttribPointer', 'glActiveTexture'],
$GLEmulation__postset: 'GLEmulation.init();',
$GLEmulation: {
// Fog support. Partial, we assume shaders are used that implement fog. We just pass them uniforms
@@ -1323,7 +1324,7 @@ var LibraryGL = {
GLEmulation.fogColor = new Float32Array(4);
// Add some emulation workarounds
- Module.printErr('WARNING: using emscripten GL emulation. This is a collection of limited workarounds, do not expect it to work. (If you do not want this, build with -s DISABLE_GL_EMULATION=1)');
+ Module.printErr('WARNING: using emscripten GL emulation. This is a collection of limited workarounds, do not expect it to work.');
#if GL_UNSAFE_OPTS == 0
Module.printErr('WARNING: using emscripten GL emulation unsafe opts. If weirdness happens, try -s GL_UNSAFE_OPTS=0');
#endif
@@ -1618,17 +1619,15 @@ var LibraryGL = {
var glCompileShader = _glCompileShader;
_glCompileShader = function(shader) {
Module.ctx.compileShader(GL.shaders[shader]);
+#if GL_DEBUG
if (!Module.ctx.getShaderParameter(GL.shaders[shader], Module.ctx.COMPILE_STATUS)) {
Module.printErr('Failed to compile shader: ' + Module.ctx.getShaderInfoLog(GL.shaders[shader]));
Module.printErr('Info: ' + JSON.stringify(GL.shaderInfos[shader]));
-#if GL_DEBUG
Module.printErr('Original source: ' + GL.shaderOriginalSources[shader]);
Module.printErr('Source: ' + GL.shaderSources[shader]);
throw 'Shader compilation halt';
-#else
- Module.printErr('Enable GL_DEBUG to see shader source');
-#endif
}
+#endif
};
GL.programShaders = {};
@@ -1775,170 +1774,6 @@ var LibraryGL = {
}
return attrib;
},
-
- getProcAddress: function(name) {
- name = name.replace('EXT', '').replace('ARB', '');
- // Do the translation carefully because of closure
- var ret = 0;
- switch (name) {
- case 'glCreateShaderObject': case 'glCreateShader': ret = {{{ Functions.getIndex('_glCreateShader', true) }}}; break;
- case 'glCreateProgramObject': case 'glCreateProgram': ret = {{{ Functions.getIndex('_glCreateProgram', true) }}}; break;
- case 'glAttachObject': case 'glAttachShader': ret = {{{ Functions.getIndex('_glAttachShader', true) }}}; break;
- case 'glUseProgramObject': case 'glUseProgram': ret = {{{ Functions.getIndex('_glUseProgram', true) }}}; break;
- case 'glDetachObject': case 'glDetachShader': ret = {{{ Functions.getIndex('_glDetachShader', true) }}}; break;
- case 'glDeleteObject': ret = {{{ Functions.getIndex('_glDeleteObject', true) }}}; break;
- case 'glGetObjectParameteriv': ret = {{{ Functions.getIndex('_glGetObjectParameteriv', true) }}}; break;
- case 'glGetInfoLog': ret = {{{ Functions.getIndex('_glGetInfoLog', true) }}}; break;
- case 'glBindProgram': ret = {{{ Functions.getIndex('_glBindProgram', true) }}}; break;
- case 'glDrawRangeElements': ret = {{{ Functions.getIndex('_glDrawRangeElements', true) }}}; break;
- case 'glShaderSource': ret = {{{ Functions.getIndex('_glShaderSource', true) }}}; break;
- case 'glCompileShader': ret = {{{ Functions.getIndex('_glCompileShader', true) }}}; break;
- case 'glLinkProgram': ret = {{{ Functions.getIndex('_glLinkProgram', true) }}}; break;
- case 'glGetUniformLocation': ret = {{{ Functions.getIndex('_glGetUniformLocation', true) }}}; break;
- case 'glUniform1f': ret = {{{ Functions.getIndex('_glUniform1f', true) }}}; break;
- case 'glUniform2f': ret = {{{ Functions.getIndex('_glUniform2f', true) }}}; break;
- case 'glUniform3f': ret = {{{ Functions.getIndex('_glUniform3f', true) }}}; break;
- case 'glUniform4f': ret = {{{ Functions.getIndex('_glUniform4f', true) }}}; break;
- case 'glUniform1fv': ret = {{{ Functions.getIndex('_glUniform1fv', true) }}}; break;
- case 'glUniform2fv': ret = {{{ Functions.getIndex('_glUniform2fv', true) }}}; break;
- case 'glUniform3fv': ret = {{{ Functions.getIndex('_glUniform3fv', true) }}}; break;
- case 'glUniform4fv': ret = {{{ Functions.getIndex('_glUniform4fv', true) }}}; break;
- case 'glUniform1i': ret = {{{ Functions.getIndex('_glUniform1i', true) }}}; break;
- case 'glUniform2i': ret = {{{ Functions.getIndex('_glUniform2i', true) }}}; break;
- case 'glUniform3i': ret = {{{ Functions.getIndex('_glUniform3i', true) }}}; break;
- case 'glUniform4i': ret = {{{ Functions.getIndex('_glUniform4i', true) }}}; break;
- case 'glUniform1iv': ret = {{{ Functions.getIndex('_glUniform1iv', true) }}}; break;
- case 'glUniform2iv': ret = {{{ Functions.getIndex('_glUniform2iv', true) }}}; break;
- case 'glUniform3iv': ret = {{{ Functions.getIndex('_glUniform3iv', true) }}}; break;
- case 'glUniform4iv': ret = {{{ Functions.getIndex('_glUniform4iv', true) }}}; break;
- case 'glBindAttribLocation': ret = {{{ Functions.getIndex('_glBindAttribLocation', true) }}}; break;
- case 'glGetActiveUniform': ret = {{{ Functions.getIndex('_glGetActiveUniform', true) }}}; break;
- case 'glGenBuffers': ret = {{{ Functions.getIndex('_glGenBuffers', true) }}}; break;
- case 'glBindBuffer': ret = {{{ Functions.getIndex('_glBindBuffer', true) }}}; break;
- case 'glBufferData': ret = {{{ Functions.getIndex('_glBufferData', true) }}}; break;
- case 'glBufferSubData': ret = {{{ Functions.getIndex('_glBufferSubData', true) }}}; break;
- case 'glDeleteBuffers': ret = {{{ Functions.getIndex('_glDeleteBuffers', true) }}}; break;
- case 'glActiveTexture': ret = {{{ Functions.getIndex('_glActiveTexture', true) }}}; break;
- case 'glClientActiveTexture': ret = {{{ Functions.getIndex('_glClientActiveTexture', true) }}}; break;
- case 'glGetProgramiv': ret = {{{ Functions.getIndex('_glGetProgramiv', true) }}}; break;
- case 'glEnableVertexAttribArray': ret = {{{ Functions.getIndex('_glEnableVertexAttribArray', true) }}}; break;
- case 'glDisableVertexAttribArray': ret = {{{ Functions.getIndex('_glDisableVertexAttribArray', true) }}}; break;
- case 'glVertexAttribPointer': ret = {{{ Functions.getIndex('_glVertexAttribPointer', true) }}}; break;
- case 'glVertexAttrib1f': ret = {{{ Functions.getIndex('_glVertexAttrib1f', true) }}}; break;
- case 'glVertexAttrib2f': ret = {{{ Functions.getIndex('_glVertexAttrib2f', true) }}}; break;
- case 'glVertexAttrib3f': ret = {{{ Functions.getIndex('_glVertexAttrib3f', true) }}}; break;
- case 'glVertexAttrib4f': ret = {{{ Functions.getIndex('_glVertexAttrib4f', true) }}}; break;
- case 'glVertexAttrib1fv': ret = {{{ Functions.getIndex('_glVertexAttrib1fv', true) }}}; break;
- case 'glVertexAttrib2fv': ret = {{{ Functions.getIndex('_glVertexAttrib2fv', true) }}}; break;
- case 'glVertexAttrib3fv': ret = {{{ Functions.getIndex('_glVertexAttrib3fv', true) }}}; break;
- case 'glVertexAttrib4fv': ret = {{{ Functions.getIndex('_glVertexAttrib4fv', true) }}}; break;
- case 'glGetVertexAttribfv': ret = {{{ Functions.getIndex('_glGetVertexAttribfv', true) }}}; break;
- case 'glGetVertexAttribiv': ret = {{{ Functions.getIndex('_glGetVertexAttribiv', true) }}}; break;
- case 'glGetVertexAttribPointerv': ret = {{{ Functions.getIndex('_glGetVertexAttribPointerv', true) }}}; break;
- case 'glGetAttribLocation': ret = {{{ Functions.getIndex('_glGetAttribLocation', true) }}}; break;
- case 'glGetActiveAttrib': ret = {{{ Functions.getIndex('_glGetActiveAttrib', true) }}}; break;
- case 'glBindRenderbuffer': ret = {{{ Functions.getIndex('_glBindRenderbuffer', true) }}}; break;
- case 'glDeleteRenderbuffers': ret = {{{ Functions.getIndex('_glDeleteRenderbuffers', true) }}}; break;
- case 'glGenRenderbuffers': ret = {{{ Functions.getIndex('_glGenRenderbuffers', true) }}}; break;
- case 'glCompressedTexImage2D': ret = {{{ Functions.getIndex('_glCompressedTexImage2D', true) }}}; break;
- case 'glCompressedTexSubImage2D': ret = {{{ Functions.getIndex('_glCompressedTexSubImage2D', true) }}}; break;
- case 'glBindFramebuffer': ret = {{{ Functions.getIndex('_glBindFramebuffer', true) }}}; break;
- case 'glGenFramebuffers': ret = {{{ Functions.getIndex('_glGenFramebuffers', true) }}}; break;
- case 'glDeleteFramebuffers': ret = {{{ Functions.getIndex('_glDeleteFramebuffers', true) }}}; break;
- case 'glFramebufferRenderbuffer': ret = {{{ Functions.getIndex('_glFramebufferRenderbuffer', true) }}}; break;
- case 'glFramebufferTexture2D': ret = {{{ Functions.getIndex('_glFramebufferTexture2D', true) }}}; break;
- case 'glGetFramebufferAttachmentParameteriv': ret = {{{ Functions.getIndex('_glGetFramebufferAttachmentParameteriv', true) }}}; break;
- case 'glIsFramebuffer': ret = {{{ Functions.getIndex('_glIsFramebuffer', true) }}}; break;
- case 'glCheckFramebufferStatus': ret = {{{ Functions.getIndex('_glCheckFramebufferStatus', true) }}}; break;
- case 'glRenderbufferStorage': ret = {{{ Functions.getIndex('_glRenderbufferStorage', true) }}}; break;
- case 'glGenVertexArrays': ret = {{{ Functions.getIndex('_glGenVertexArrays', true) }}}; break;
- case 'glDeleteVertexArrays': ret = {{{ Functions.getIndex('_glDeleteVertexArrays', true) }}}; break;
- case 'glBindVertexArray': ret = {{{ Functions.getIndex('_glBindVertexArray', true) }}}; break;
- case 'glGetString': ret = {{{ Functions.getIndex('_glGetString', true) }}}; break;
- case 'glBindTexture': ret = {{{ Functions.getIndex('_glBindTexture', true) }}}; break;
- case 'glGetBufferParameteriv': ret = {{{ Functions.getIndex('_glGetBufferParameteriv', true) }}}; break;
- case 'glIsBuffer': ret = {{{ Functions.getIndex('_glIsBuffer', true) }}}; break;
- case 'glDeleteShader': ret = {{{ Functions.getIndex('_glDeleteShader', true) }}}; break;
- case 'glUniformMatrix2fv': ret = {{{ Functions.getIndex('_glUniformMatrix2fv', true) }}}; break;
- case 'glUniformMatrix3fv': ret = {{{ Functions.getIndex('_glUniformMatrix3fv', true) }}}; break;
- case 'glUniformMatrix4fv': ret = {{{ Functions.getIndex('_glUniformMatrix4fv', true) }}}; break;
- case 'glIsRenderbuffer': ret = {{{ Functions.getIndex('_glIsRenderbuffer', true) }}}; break;
- case 'glBlendEquation': ret = {{{ Functions.getIndex('_glBlendEquation', true) }}}; break;
- case 'glBlendFunc': ret = {{{ Functions.getIndex('_glBlendFunc', true) }}}; break;
- case 'glBlendFuncSeparate': ret = {{{ Functions.getIndex('_glBlendFuncSeparate', true) }}}; break;
- case 'glBlendEquationSeparate': ret = {{{ Functions.getIndex('_glBlendEquationSeparate', true) }}}; break;
- case 'glDepthRangef': ret = {{{ Functions.getIndex('_glDepthRangef', true) }}}; break;
- case 'glClear': ret = {{{ Functions.getIndex('_glClear', true) }}}; break;
- case 'glGenerateMipmap': ret = {{{ Functions.getIndex('_glGenerateMipmap', true) }}}; break;
- case 'glBlendColor': ret = {{{ Functions.getIndex('_glBlendColor', true) }}}; break;
- case 'glClearDepthf': ret = {{{ Functions.getIndex('_glClearDepthf', true) }}}; break;
- case 'glDeleteProgram': ret = {{{ Functions.getIndex('_glDeleteProgram', true) }}}; break;
- case 'glUniformMatrix3fv': ret = {{{ Functions.getIndex('_glUniformMatrix3fv', true) }}}; break;
- case 'glClearColor': ret = {{{ Functions.getIndex('_glClearColor', true) }}}; break;
- case 'glGetRenderbufferParameteriv': ret = {{{ Functions.getIndex('_glGetRenderbufferParameteriv', true) }}}; break;
- case 'glGetShaderInfoLog': ret = {{{ Functions.getIndex('_glGetShaderInfoLog', true) }}}; break;
- case 'glUniformMatrix4fv': ret = {{{ Functions.getIndex('_glUniformMatrix4fv', true) }}}; break;
- case 'glClearStencil': ret = {{{ Functions.getIndex('_glClearStencil', true) }}}; break;
- case 'glGetProgramInfoLog': ret = {{{ Functions.getIndex('_glGetProgramInfoLog', true) }}}; break;
- case 'glGetUniformfv': ret = {{{ Functions.getIndex('_glGetUniformfv', true) }}}; break;
- case 'glStencilFuncSeparate': ret = {{{ Functions.getIndex('_glStencilFuncSeparate', true) }}}; break;
- case 'glSampleCoverage': ret = {{{ Functions.getIndex('_glSampleCoverage', true) }}}; break;
- case 'glColorMask': ret = {{{ Functions.getIndex('_glColorMask', true) }}}; break;
- case 'glGetShaderiv': ret = {{{ Functions.getIndex('_glGetShaderiv', true) }}}; break;
- case 'glGetUniformiv': ret = {{{ Functions.getIndex('_glGetUniformiv', true) }}}; break;
- case 'glCopyTexSubImage2D': ret = {{{ Functions.getIndex('_glCopyTexSubImage2D', true) }}}; break;
- case 'glDetachShader': ret = {{{ Functions.getIndex('_glDetachShader', true) }}}; break;
- case 'glGetShaderSource': ret = {{{ Functions.getIndex('_glGetShaderSource', true) }}}; break;
- case 'glDeleteTextures': ret = {{{ Functions.getIndex('_glDeleteTextures', true) }}}; break;
- case 'glGetAttachedShaders': ret = {{{ Functions.getIndex('_glGetAttachedShaders', true) }}}; break;
- case 'glValidateProgram': ret = {{{ Functions.getIndex('_glValidateProgram', true) }}}; break;
- case 'glDepthFunc': ret = {{{ Functions.getIndex('_glDepthFunc', true) }}}; break;
- case 'glIsShader': ret = {{{ Functions.getIndex('_glIsShader', true) }}}; break;
- case 'glDepthMask': ret = {{{ Functions.getIndex('_glDepthMask', true) }}}; break;
- case 'glStencilMaskSeparate': ret = {{{ Functions.getIndex('_glStencilMaskSeparate', true) }}}; break;
- case 'glIsProgram': ret = {{{ Functions.getIndex('_glIsProgram', true) }}}; break;
- case 'glDisable': ret = {{{ Functions.getIndex('_glDisable', true) }}}; break;
- case 'glStencilOpSeparate': ret = {{{ Functions.getIndex('_glStencilOpSeparate', true) }}}; break;
- case 'glDrawArrays': ret = {{{ Functions.getIndex('_glDrawArrays', true) }}}; break;
- case 'glDrawElements': ret = {{{ Functions.getIndex('_glDrawElements', true) }}}; break;
- case 'glEnable': ret = {{{ Functions.getIndex('_glEnable', true) }}}; break;
- case 'glFinish': ret = {{{ Functions.getIndex('_glFinish', true) }}}; break;
- case 'glFlush': ret = {{{ Functions.getIndex('_glFlush', true) }}}; break;
- case 'glFrontFace': ret = {{{ Functions.getIndex('_glFrontFace', true) }}}; break;
- case 'glCullFace': ret = {{{ Functions.getIndex('_glCullFace', true) }}}; break;
- case 'glGenTextures': ret = {{{ Functions.getIndex('_glGenTextures', true) }}}; break;
- case 'glGetError': ret = {{{ Functions.getIndex('_glGetError', true) }}}; break;
- case 'glGetIntegerv': ret = {{{ Functions.getIndex('_glGetIntegerv', true) }}}; break;
- case 'glGetBooleanv': ret = {{{ Functions.getIndex('_glGetBooleanv', true) }}}; break;
- case 'glGetFloatv': ret = {{{ Functions.getIndex('_glGetFloatv', true) }}}; break;
- case 'glHint': ret = {{{ Functions.getIndex('_glHint', true) }}}; break;
- case 'glIsTexture': ret = {{{ Functions.getIndex('_glIsTexture', true) }}}; break;
- case 'glPixelStorei': ret = {{{ Functions.getIndex('_glPixelStorei', true) }}}; break;
- case 'glReadPixels': ret = {{{ Functions.getIndex('_glReadPixels', true) }}}; break;
- case 'glScissor': ret = {{{ Functions.getIndex('_glScissor', true) }}}; break;
- case 'glStencilFunc': ret = {{{ Functions.getIndex('_glStencilFunc', true) }}}; break;
- case 'glStencilMask': ret = {{{ Functions.getIndex('_glStencilMask', true) }}}; break;
- case 'glStencilOp': ret = {{{ Functions.getIndex('_glStencilOp', true) }}}; break;
- case 'glTexImage2D': ret = {{{ Functions.getIndex('_glTexImage2D', true) }}}; break;
- case 'glTexParameterf': ret = {{{ Functions.getIndex('_glTexParameterf', true) }}}; break;
- case 'glTexParameterfv': ret = {{{ Functions.getIndex('_glTexParameterfv', true) }}}; break;
- case 'glTexParameteri': ret = {{{ Functions.getIndex('_glTexParameteri', true) }}}; break;
- case 'glTexParameteriv': ret = {{{ Functions.getIndex('_glTexParameteriv', true) }}}; break;
- case 'glGetTexParameterfv': ret = {{{ Functions.getIndex('_glGetTexParameterfv', true) }}}; break;
- case 'glGetTexParameteriv': ret = {{{ Functions.getIndex('_glGetTexParameteriv', true) }}}; break;
- case 'glTexSubImage2D': ret = {{{ Functions.getIndex('_glTexSubImage2D', true) }}}; break;
- case 'glCopyTexImage2D': ret = {{{ Functions.getIndex('_glCopyTexImage2D', true) }}}; break;
- case 'glViewport': ret = {{{ Functions.getIndex('_glViewport', true) }}}; break;
- case 'glIsEnabled': ret = {{{ Functions.getIndex('_glIsEnabled', true) }}}; break;
- case 'glLineWidth': ret = {{{ Functions.getIndex('_glLineWidth', true) }}}; break;
- case 'glPolygonOffset': ret = {{{ Functions.getIndex('_glPolygonOffset', true) }}}; break;
- case 'glReleaseShaderCompiler': ret = {{{ Functions.getIndex('_glReleaseShaderCompiler', true) }}}; break;
- case 'glGetShaderPrecisionFormat': ret = {{{ Functions.getIndex('_glGetShaderPrecisionFormat', true) }}}; break;
- case 'glShaderBinary': ret = {{{ Functions.getIndex('_glShaderBinary', true) }}}; break;
- }
- if (!ret) Module.printErr('WARNING: getProcAddress failed for ' + name);
- return ret;
- }
},
glGetShaderPrecisionFormat__sig: 'v',
@@ -4202,7 +4037,43 @@ var LibraryGL = {
glBindVertexArrayOES: 'glBindVertexArray',
glFramebufferTexture2DOES: 'glFramebufferTexture2D',
-#endif // DISABLE_GL_EMULATION == 0
+#else // LEGACY_GL_EMULATION
+
+ // Warn if code tries to use various emulation stuff, when emulation is disabled
+ // (do not warn if INCLUDE_FULL_LIBRARY is one, because then likely the gl code will
+ // not be called anyhow, leave only the runtime aborts)
+ glVertexPointer__deps: [function() {
+#if INCLUDE_FULL_LIBRARY == 0
+ warn('Legacy GL function (glVertexPointer) called. You need to compile with -s LEGACY_GL_EMULATION=1 to enable legacy GL emulation.');
+#endif
+ }],
+ glVertexPointer: function(){ throw 'Legacy GL function (glVertexPointer) called. You need to compile with -s LEGACY_GL_EMULATION=1 to enable legacy GL emulation.'; },
+ glGenVertexArrays__deps: [function() {
+#if INCLUDE_FULL_LIBRARY == 0
+ warn('Legacy GL function (glGenVertexArrays) called. You need to compile with -s LEGACY_GL_EMULATION=1 to enable legacy GL emulation.');
+#endif
+ }],
+ glGenVertexArrays: function(){ throw 'Legacy GL function (glGenVertexArrays) called. You need to compile with -s LEGACY_GL_EMULATION=1 to enable legacy GL emulation.'; },
+ glMatrixMode__deps: [function() {
+#if INCLUDE_FULL_LIBRARY == 0
+ warn('Legacy GL function (glMatrixMode) called. You need to compile with -s LEGACY_GL_EMULATION=1 to enable legacy GL emulation.');
+#endif
+ }],
+ glMatrixMode: function(){ throw 'Legacy GL function (glMatrixMode) called. You need to compile with -s LEGACY_GL_EMULATION=1 to enable legacy GL emulation.'; },
+ glBegin__deps: [function() {
+#if INCLUDE_FULL_LIBRARY == 0
+ warn('Legacy GL function (glBegin) called. You need to compile with -s LEGACY_GL_EMULATION=1 to enable legacy GL emulation.');
+#endif
+ }],
+ glBegin: function(){ throw 'Legacy GL function (glBegin) called. You need to compile with -s LEGACY_GL_EMULATION=1 to enable legacy GL emulation.'; },
+ glLoadIdentity__deps: [function() {
+#if INCLUDE_FULL_LIBRARY == 0
+ warn('Legacy GL function (glLoadIdentity) called. You need to compile with -s LEGACY_GL_EMULATION=1 to enable legacy GL emulation.');
+#endif
+ }],
+ glLoadIdentity: function(){ throw 'Legacy GL function (glLoadIdentity) called. You need to compile with -s LEGACY_GL_EMULATION=1 to enable legacy GL emulation.'; },
+
+#endif // LEGACY_GL_EMULATION
// GLU
@@ -4438,28 +4309,60 @@ var LibraryGL = {
autoAddDeps(LibraryGL, '$GL');
-if (!DISABLE_GL_EMULATION) {
- // Emulation requires everything else, potentially
- LibraryGL.$GLEmulation__deps = LibraryGL.$GLEmulation__deps.slice(0); // the __deps object is shared
- var glFuncs = [];
- for (var item in LibraryGL) {
- if (item != '$GLEmulation' && item.substr(-6) != '__deps' && item.substr(-9) != '__postset' && item.substr(-5) != '__sig' && item.substr(0, 2) == 'gl') {
- glFuncs.push(item);
+// Legacy GL emulation
+if (LEGACY_GL_EMULATION) {
+ DEFAULT_LIBRARY_FUNCS_TO_INCLUDE.push('$GLEmulation');
+}
+
+// GL proc address retrieval
+LibraryGL.emscripten_GetProcAddress__deps = [function() {
+ // ProcAddress is used, so include everything in GL. This runs before we go to the $ProcAddressTable object,
+ // and we fill its deps just in time, and create the lookup table
+ var table = {};
+ LibraryManager.library.emscripten_procAddressTable__deps = keys(LibraryGL).map(function(x) {
+ if (x.substr(-6) == '__deps' || x.substr(-9) == '__postset' || x.substr(-5) == '__sig' || x.substr(-5) == '__asm' || x.substr(0, 2) != 'gl') return null;
+ var original = x;
+ if (('_' + x) in Functions.implementedFunctions) {
+ // a user-implemented function aliases this one, but we still want it to be accessible by name, so rename it
+ var y = x + '__procTable';
+ LibraryManager.library[y] = LibraryManager.library[x];
+ LibraryManager.library[y + '__deps'] = LibraryManager.library[x + '__deps'];
+ LibraryManager.library[y + '__postset'] = LibraryManager.library[x + '__postset'];
+ LibraryManager.library[y + '__sig'] = LibraryManager.library[x + '__sig'];//|| Functions.implementedFunctions['_' + x];
+ LibraryManager.library[y + '__asm'] = LibraryManager.library[x + '__asm'];
+ x = y;
+ assert(!(y in Functions.implementedFunctions) && !Functions.unimplementedFunctions['_' + y]);
}
- }
- LibraryGL.$GLEmulation__deps = LibraryGL.$GLEmulation__deps.concat(glFuncs);
- LibraryGL.$GLEmulation__deps.push(function() {
- for (var func in Functions.getIndex.tentative) {
- Functions.getIndex(func);
- Functions.unimplementedFunctions[func] = LibraryGL[func.substr(1) + '__sig'];
+ var longX = '_' + x;
+ var sig = LibraryManager.library[x + '__sig'] || functionStubSigs[longX];
+ if (sig) {
+ table[original] = Functions.getIndex(longX, sig);
+ if (!(longX in Functions.implementedFunctions)) Functions.unimplementedFunctions[longX] = sig;
}
- });
-
- if (FORCE_GL_EMULATION) {
- LibraryGL.glDrawElements__deps = LibraryGL.glDrawElements__deps.concat('$GLEmulation');
- LibraryGL.glDrawArrays__deps = LibraryGL.glDrawArrays__deps.concat('$GLEmulation');
+ return x;
+ }).filter(function(x) { return x !== null });
+ // convert table into function with switch, to not confuse closure compiler
+ var tableImpl = 'switch(name) {\n';
+ for (var x in table) tableImpl += 'case "' + x + '": return ' + table[x] + '; break;\n';
+ tableImpl += '}\nreturn 0;';
+ LibraryManager.library.emscripten_procAddressTable = new Function('name', tableImpl);
+}, 'emscripten_procAddressTable'];
+LibraryGL.emscripten_GetProcAddress = function(name) {
+ name = name.replace('EXT', '').replace('ARB', '');
+ switch(name) { // misc renamings
+ case 'glCreateProgramObject': name = 'glCreateProgram'; break;
+ case 'glUseProgramObject': name = 'glUseProgram'; break;
+ case 'glCreateShaderObject': name = 'glCreateShader'; break;
+ case 'glAttachObject': name = 'glAttachShader'; break;
+ case 'glDetachObject': name = 'glDetachShader'; break;
}
+ var ret = _emscripten_procAddressTable(name);
+ if (!ret) Module.printErr('WARNING: getProcAddress failed for ' + name);
+ return ret;
}
+// Final merge
mergeInto(LibraryManager.library, LibraryGL);
+assert(!(FULL_ES2 && LEGACY_GL_EMULATION), 'cannot emulate both ES2 and legacy GL');
+
diff --git a/src/library_sdl.js b/src/library_sdl.js
index 6cc337e8..236ab1bf 100644
--- a/src/library_sdl.js
+++ b/src/library_sdl.js
@@ -2067,9 +2067,9 @@ var LibrarySDL = {
console.log('TODO: SDL_GL_SetAttribute');
},
- SDL_GL_GetProcAddress__deps: ['$GLEmulation'],
+ SDL_GL_GetProcAddress__deps: ['emscripten_GetProcAddress'],
SDL_GL_GetProcAddress: function(name_) {
- return GLEmulation.getProcAddress(Pointer_stringify(name_));
+ return _emscripten_GetProcAddress(Pointer_stringify(name_));
},
SDL_GL_SwapBuffers: function() {},
diff --git a/src/modules.js b/src/modules.js
index 13561777..fa6c0983 100644
--- a/src/modules.js
+++ b/src/modules.js
@@ -275,20 +275,15 @@ var Functions = {
},
// Mark a function as needing indexing. Python will coordinate them all
- getIndex: function(ident, doNotCreate, sig) {
- if (doNotCreate && !(ident in this.indexedFunctions)) {
- if (!Functions.getIndex.tentative) Functions.getIndex.tentative = {}; // only used by GL emulation; TODO: generalize when needed
- Functions.getIndex.tentative[ident] = 0;
- }
+ getIndex: function(ident, sig) {
var ret;
if (phase != 'post' && singlePhase) {
- if (!doNotCreate) this.indexedFunctions[ident] = 0; // tell python we need this indexized
ret = "'{{ FI_" + toNiceIdent(ident) + " }}'"; // something python will replace later
+ this.indexedFunctions[ident] = 0;
} else {
if (!singlePhase) return 'NO_INDEX'; // Should not index functions in post
ret = this.indexedFunctions[ident];
if (!ret) {
- if (doNotCreate) return '0';
ret = this.nextIndex;
this.nextIndex += 2; // Need to have indexes be even numbers, see |polymorph| test
this.indexedFunctions[ident] = ret;
@@ -326,7 +321,7 @@ var Functions = {
tables[sig][index] = ident;
}
var generated = false;
- var wrapped = {};
+ var wrapped = {}; // whether we wrapped a lib func
var maxTable = 0;
for (var t in tables) {
if (t == 'pre') continue;
@@ -349,10 +344,11 @@ var Functions = {
if (ASM_JS) {
var curr = table[i];
if (curr && curr != '0' && !Functions.implementedFunctions[curr]) {
- curr = toNiceIdent(curr); // fix Math.* to Math_*
+ var short = toNiceIdent(curr); // fix Math.* to Math_*
+ curr = t + '_' + short; // libfuncs can alias with different sigs, wrap each separately
// This is a library function, we can't just put it in the function table, need a wrapper
if (!wrapped[curr]) {
- var args = '', arg_coercions = '', call = curr + '(', retPre = '', retPost = '';
+ var args = '', arg_coercions = '', call = short + '(', retPre = '', retPost = '';
if (t[0] != 'v') {
if (t[0] == 'i') {
retPre = 'return ';
@@ -367,7 +363,7 @@ var Functions = {
call += (j > 1 ? ',' : '') + asmCoercion('a' + j, t[j] != 'i' ? 'float' : 'i32');
}
call += ')';
- if (curr == '_setjmp') printErr('WARNING: setjmp used via a function pointer. If this is for libc setjmp (not something of your own with the same name), it will break things');
+ if (short == '_setjmp') printErr('WARNING: setjmp used via a function pointer. If this is for libc setjmp (not something of your own with the same name), it will break things');
tables.pre += 'function ' + curr + '__wrapper(' + args + ') { ' + arg_coercions + ' ; ' + retPre + call + retPost + ' }\n';
wrapped[curr] = 1;
}
diff --git a/src/parseTools.js b/src/parseTools.js
index f11c867a..65e96264 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -1244,7 +1244,7 @@ function indexizeFunctions(value, type) {
if (!sig) {
sig = Functions.unimplementedFunctions[value] = Functions.getSignature(out.returnType, out.segments ? out.segments.map(function(segment) { return segment[0].text }) : [], isVarArgsFunctionType(type));
}
- return Functions.getIndex(value, undefined, sig);
+ return Functions.getIndex(value, sig);
}
return value;
}
diff --git a/src/postamble.js b/src/postamble.js
index c4ca3aae..08c3a9d8 100644
--- a/src/postamble.js
+++ b/src/postamble.js
@@ -127,6 +127,7 @@ Module['exit'] = Module.exit = exit;
function abort(text) {
if (text) {
Module.print(text);
+ Module.printErr(text);
}
ABORT = true;
diff --git a/src/settings.js b/src/settings.js
index 3ecac040..8757f7b9 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -191,9 +191,8 @@ var GL_TESTING = 0; // When enabled, sets preserveDrawingBuffer in the context,
var GL_MAX_TEMP_BUFFER_SIZE = 2097152; // How large GL emulation temp buffers are
var GL_UNSAFE_OPTS = 1; // Enables some potentially-unsafe optimizations in GL emulation code
var FULL_ES2 = 0; // Forces support for all GLES2 features, not just the WebGL-friendly subset.
-var FORCE_GL_EMULATION = 0; // Forces inclusion of full GL emulation code.
-var DISABLE_GL_EMULATION = 0; // Disable inclusion of full GL emulation code. Useful when you don't want emulation
- // but do need INCLUDE_FULL_LIBRARY or MAIN_MODULE.
+var LEGACY_GL_EMULATION = 0; // Includes code to emulate various desktop GL features. Incomplete but useful
+ // in some cases, see https://github.com/kripken/emscripten/wiki/OpenGL-support
var STB_IMAGE = 0; // Enables building of stb-image, a tiny public-domain library for decoding images, allowing
// decoding of images without using the browser's built-in decoders. The benefit is that this
diff --git a/system/include/compat/math.h b/system/include/compat/math.h
new file mode 100644
index 00000000..089cf66b
--- /dev/null
+++ b/system/include/compat/math.h
@@ -0,0 +1,14 @@
+#ifndef _COMPAT_MATH_H_
+#define _COMPAT_MATH_H_
+
+#ifndef isinff
+ #define isinff isinf
+#endif
+
+#ifndef isnanf
+ #define isnanf isnan
+#endif
+
+#include_next <math.h>
+
+#endif /* _COMPAT_MATH_H_ */
diff --git a/system/include/compat/stdlib.h b/system/include/compat/stdlib.h
new file mode 100644
index 00000000..dc01947d
--- /dev/null
+++ b/system/include/compat/stdlib.h
@@ -0,0 +1,16 @@
+#ifndef _COMPAT_STDLIB_H
+#define _COMPAT_STDLIB_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int getloadavg(double loadavg[], int nelem);
+
+#ifdef __cplusplus
+}
+#endif
+
+#include_next <stdlib.h>
+
+#endif
diff --git a/system/include/compat/string.h b/system/include/compat/string.h
new file mode 100644
index 00000000..880089cc
--- /dev/null
+++ b/system/include/compat/string.h
@@ -0,0 +1,17 @@
+#ifndef _COMPAT_STRING_H
+#define _COMPAT_STRING_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern char* strlwr(char *);
+extern char* strupr(char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#include_next <string.h>
+
+#endif
diff --git a/system/include/compat/sys/stat.h b/system/include/compat/sys/stat.h
new file mode 100644
index 00000000..731502ea
--- /dev/null
+++ b/system/include/compat/sys/stat.h
@@ -0,0 +1,20 @@
+#ifndef _COMPAT_STAT_H
+#define _COMPAT_STAT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include_next <sys/stat.h>
+
+#define S_IRWXUGO (S_IRWXU|S_IRWXG|S_IRWXO)
+#define S_IALLUGO (S_ISUID|S_ISGID|S_ISVTX|S_IRWXUGO)
+#define S_IRUGO (S_IRUSR|S_IRGRP|S_IROTH)
+#define S_IWUGO (S_IWUSR|S_IWGRP|S_IWOTH)
+#define S_IXUGO (S_IXUSR|S_IXGRP|S_IXOTH)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/system/include/libc/sys/timeb.h b/system/include/compat/sys/timeb.h
index 0a2c3de8..0a2c3de8 100644
--- a/system/include/libc/sys/timeb.h
+++ b/system/include/compat/sys/timeb.h
diff --git a/system/include/compat/unistd.h b/system/include/compat/unistd.h
new file mode 100644
index 00000000..07c3afde
--- /dev/null
+++ b/system/include/compat/unistd.h
@@ -0,0 +1,16 @@
+#ifndef _COMPAT_UNISTD_H
+#define _COMPAT_UNISTD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+char * getwd(char *__buf );
+
+#ifdef __cplusplus
+}
+#endif
+
+#include_next <unistd.h>
+
+#endif
diff --git a/system/include/compat/xlocale.h b/system/include/compat/xlocale.h
new file mode 100644
index 00000000..4bafa27d
--- /dev/null
+++ b/system/include/compat/xlocale.h
@@ -0,0 +1,21 @@
+#ifndef _COMPAT_XLOCALE_H_
+#define _COMPAT_XLOCALE_H_
+
+#include <locale.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+long long strtoll_l(const char *start, char **end, int base, locale_t loc);
+unsigned long long strtoull_l(const char *start, char **end, int base, locale_t loc);
+double strtold_l(const char *start, char **end, locale_t loc);
+
+#ifdef __cplusplus
+}
+#endif
+
+#include_next <xlocale.h>
+
+#endif /* _COMPAT_XLOCALE_H_ */
+
diff --git a/system/include/emscripten/emscripten.h b/system/include/emscripten/emscripten.h
index 28e6063c..f0df8dca 100644
--- a/system/include/emscripten/emscripten.h
+++ b/system/include/emscripten/emscripten.h
@@ -20,14 +20,13 @@ extern "C" {
/*
* Forces LLVM to not dead-code-eliminate a function. Note that
- * closure may still eliminate it at the JS level, for which you
- * should use EXPORTED_FUNCTIONS (see settings.js).
- *
- * **DEPRECATED**: Use EXPORTED_FUNCTIONS instead, which will work
- * with closure, asm.js, etc. For example
- * -s EXPORTED_FUNCTIONS=["_main", "myfunc"]
+ * you still need to use EXPORTED_FUNCTIONS so it stays alive
+ * in JS, e.g.
+ * emcc -s EXPORTED_FUNCTIONS=["_main", "_myfunc"]
+ * and in the source file
+ * void EMSCRIPTEN_KEEPALIVE myfunc() {..}
*/
-/* #define EMSCRIPTEN_KEEPALIVE __attribute__((used)) */
+#define EMSCRIPTEN_KEEPALIVE __attribute__((used))
/*
* Interface to the underlying JS engine. This function will
diff --git a/system/include/libc/stdlib.h b/system/include/libc/stdlib.h
index 888b6041..6fdef40b 100644
--- a/system/include/libc/stdlib.h
+++ b/system/include/libc/stdlib.h
@@ -223,8 +223,6 @@ extern long double strtold (const char *, char **);
extern long double wcstold (const wchar_t *, wchar_t **);
#endif /* _LDBL_EQ_DBL */
-int getloadavg(double loadavg[], int nelem); /* XXX Emscripten */
-
_END_STD_C
#endif /* _STDLIB_H_ */
diff --git a/system/include/libc/string.h b/system/include/libc/string.h
index 515c71a7..8fd9ea43 100644
--- a/system/include/libc/string.h
+++ b/system/include/libc/string.h
@@ -72,8 +72,6 @@ size_t _EXFUN(strlcpy,(char *, const char *, size_t));
int _EXFUN(strncasecmp,(const char *, const char *, size_t));
size_t _EXFUN(strnlen,(const char *, size_t));
char *_EXFUN(strsep,(char **, const char *));
-char *_EXFUN(strlwr,(char *));
-char *_EXFUN(strupr,(char *));
#if defined(__CYGWIN__) || defined(EMSCRIPTEN)
#ifndef DEFS_H /* Kludge to work around problem compiling in gdb */
char *_EXFUN(strsignal, (int __signo));
diff --git a/system/include/libc/sys/unistd.h b/system/include/libc/sys/unistd.h
index 1a414b3c..a4219d4d 100644
--- a/system/include/libc/sys/unistd.h
+++ b/system/include/libc/sys/unistd.h
@@ -102,7 +102,6 @@ uid_t _EXFUN(getuid, (void ));
#endif
#if defined(EMSCRIPTEN) || defined(__CYGWIN__)
char * _EXFUN(getusershell, (void));
-char * _EXFUN(getwd, (char *__buf ));
int _EXFUN(iruserok, (unsigned long raddr, int superuser, const char *ruser, const char *luser));
#endif
int _EXFUN(isatty, (int __fildes ));
diff --git a/system/include/xlocale.h b/system/include/xlocale.h
index bb3b50e5..6867d25f 100644
--- a/system/include/xlocale.h
+++ b/system/include/xlocale.h
@@ -1,4 +1,3 @@
-
#ifndef _XLOCALE_H_
#define _XLOCALE_H_
@@ -9,10 +8,6 @@
extern "C" {
#endif
-long long strtoll_l(const char *start, char **end, int base, locale_t loc);
-unsigned long long strtoull_l(const char *start, char **end, int base, locale_t loc);
-double strtold_l(const char *start, char **end, locale_t loc);
-
int strcoll_l(const char *s1, const char *s2, locale_t locale);
int wcscoll_l(const wchar_t *ws1, const wchar_t *ws2, locale_t locale);
@@ -43,5 +38,5 @@ size_t strftime_l(char *s, size_t maxsize, const char *format, const struct tm *
}
#endif
-#endif /* _LOCALE_H_ */
+#endif /* _XLOCALE_H_ */
diff --git a/tests/aniso.c b/tests/aniso.c
index 1126265e..f210e5a5 100644
--- a/tests/aniso.c
+++ b/tests/aniso.c
@@ -161,7 +161,7 @@ int main(int argc, char *argv[])
for (int x = 0; x < n; x++) {
int start = x*w*2;
glBegin( GL_TRIANGLES );
- glTexCoord2i( 1, 0 ); glVertex3f( start , 0, 0 );
+ glTexCoord2i( 1, 0 ); glVertex2i( start , 0 );
glTexCoord2i( 0, 0 ); glVertex3f( start+w, 300, 0 );
glTexCoord2i( 1, 1 ); glVertex3f( start-w, 300, 0 );
glEnd();
@@ -209,5 +209,11 @@ int main(int argc, char *argv[])
SDL_Quit();
- return 0;
+ // check for asm compilation bug with aliased functions with different sigs
+ void (*f)(int, int) = glVertex2i;
+ if ((int)f % 16 == 4) f(5, 7);
+ void (*g)(int, int) = glVertex3f;
+ if ((int)g % 16 == 4) g(5, 7);
+ return (int)f + (int)g;
}
+
diff --git a/tests/runner.py b/tests/runner.py
index 2f508dfc..318946e6 100755
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -275,6 +275,18 @@ process(sys.argv[1])
print "Output: " + output[0]
return output[0]
+ # Tests that the given two paths are identical, modulo path delimiters. E.g. "C:/foo" is equal to "C:\foo".
+ def assertPathsIdentical(self, path1, path2):
+ path1 = path1.replace('\\', '/')
+ path2 = path2.replace('\\', '/')
+ return self.assertIdentical(path1, path2)
+
+ # Tests that the given two multiline text content are identical, modulo line ending differences (\r\n on Windows, \n on Unix).
+ def assertTextDataIdentical(self, text1, text2):
+ text1 = text1.replace('\r\n', '\n')
+ text2 = text2.replace('\r\n', '\n')
+ return self.assertIdentical(text1, text2)
+
def assertIdentical(self, values, y):
if type(values) not in [list, tuple]: values = [values]
for x in values:
@@ -480,7 +492,7 @@ def server_func(dir, q):
if 'report_' in s.path:
q.put(s.path)
else:
- filename = s.path[1:]
+ filename = s.path.split('?')[0][1:]
if os.path.exists(filename):
s.send_response(200)
s.send_header("Content-type", "text/html")
@@ -649,6 +661,7 @@ class BrowserCore(RunnerCore):
self.reftest(path_from_root('tests', reference))
args = args + ['--pre-js', 'reftest.js', '-s', 'GL_TESTING=1']
Popen([PYTHON, EMCC, temp_filepath, '-o', outfile] + args).communicate()
+ assert os.path.exists(outfile)
if type(expected) is str: expected = [expected]
self.run_browser(outfile, message, ['/report_result?' + e for e in expected])
@@ -765,10 +778,17 @@ an individual test with
except:
pass
+ numFailures = 0 # Keep count of the total number of failing tests.
+
# Run the discovered tests
if not len(suites):
print >> sys.stderr, 'No tests found for %s' % str(sys.argv[1:])
+ numFailures = 1
else:
testRunner = unittest.TextTestRunner(verbosity=2)
for suite in suites:
- testRunner.run(suite)
+ results = testRunner.run(suite)
+ numFailures += len(results.errors) + len(results.failures)
+
+ # Return the number of failures as the process exit code for automating success/failure reporting.
+ exit(numFailures)
diff --git a/tests/sdl_ogl_proc_alias.c b/tests/sdl_ogl_proc_alias.c
new file mode 100644
index 00000000..c96da81b
--- /dev/null
+++ b/tests/sdl_ogl_proc_alias.c
@@ -0,0 +1,180 @@
+/*******************************************************************
+ * *
+ * 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>
+
+void (*true_glGenTextures)(GLsizei, GLuint*) = NULL;
+
+void glGenTextures(GLsizei n, GLuint *textures) {
+ printf("num? %d\n", n);
+ true_glGenTextures(n + 1, textures); // correct the error, ensures we are gone through
+}
+
+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 );
+
+ 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");
+ }
+
+ true_glGenTextures = SDL_GL_GetProcAddress("glGenTextures");
+
+ // Have OpenGL generate a texture object handle for us
+ glGenTextures( 0, &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/sockets/test_sockets_echo_server.c b/tests/sockets/test_sockets_echo_server.c
index 8a48b878..38e27cac 100644
--- a/tests/sockets/test_sockets_echo_server.c
+++ b/tests/sockets/test_sockets_echo_server.c
@@ -37,6 +37,11 @@ typedef struct {
server_t server;
client_t client;
+void cleanup() {
+ if (server.fd) close(server.fd);
+ if (client.fd) close(client.fd);
+}
+
void main_loop(void *arg) {
int res;
fd_set fdr;
@@ -105,6 +110,9 @@ int main() {
struct sockaddr_in addr;
int res;
+ atexit(cleanup);
+ signal(SIGTERM, cleanup);
+
memset(&server, 0, sizeof(server_t));
memset(&client, 0, sizeof(client_t));
diff --git a/tests/sockets/test_sockets_partial_server.c b/tests/sockets/test_sockets_partial_server.c
index 57fae84b..dfe0e249 100644
--- a/tests/sockets/test_sockets_partial_server.c
+++ b/tests/sockets/test_sockets_partial_server.c
@@ -14,18 +14,13 @@
#include <emscripten.h>
#endif
-int serverfd = -1;
-int clientfd = -1;
-
-// csock.send("\x09\x01\x02\x03\x04\x05\x06\x07\x08\x09")
-// csock.send("\x08\x01\x02\x03\x04\x05\x06\x07\x08")
-// csock.send("\x07\x01\x02\x03\x04\x05\x06\x07")
-// csock.send("\x06\x01\x02\x03\x04\x05\x06")
-// csock.send("\x05\x01\x02\x03\x04\x05")
-// csock.send("\x04\x01\x02\x03\x04")
-// csock.send("\x03\x01\x02\x03")
-// csock.send("\x02\x01\x02")
-// csock.send("\x01\x01")
+int serverfd = 0;
+int clientfd = 0;
+
+void cleanup() {
+ if (serverfd) close(serverfd);
+ if (clientfd) close(clientfd);
+}
void do_send(int sockfd) {
static char* buffers[] = {
@@ -69,7 +64,7 @@ void iter(void *arg) {
FD_ZERO(&fdr);
FD_ZERO(&fdw);
FD_SET(serverfd, &fdr);
- if (clientfd != -1) FD_SET(clientfd, &fdw);
+ if (clientfd) FD_SET(clientfd, &fdw);
res = select(64, &fdr, &fdw, NULL, NULL);
if (res == -1) {
perror("select failed");
@@ -91,6 +86,9 @@ int main() {
struct sockaddr_in addr;
int res;
+ atexit(cleanup);
+ signal(SIGTERM, cleanup);
+
// create the socket
serverfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (serverfd == -1) {
diff --git a/tests/sockets/webrtc_host.c b/tests/sockets/webrtc_host.c
new file mode 100644
index 00000000..770e59e0
--- /dev/null
+++ b/tests/sockets/webrtc_host.c
@@ -0,0 +1,89 @@
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <assert.h>
+#if EMSCRIPTEN
+#include <emscripten.h>
+#endif
+
+#define EXPECTED_BYTES 5
+#define BUFLEN 16
+
+int result = 0;
+int sock;
+char buf[BUFLEN];
+char expected[] = "emscripten";
+struct sockaddr_in si_host,
+ si_peer;
+struct iovec iov[1];
+struct msghdr hdr;
+int done = 0;
+
+void iter(void* arg) {
+ int n;
+ n = recvmsg(sock, &hdr, 0);
+
+ if(0 < n) {
+ done = 1;
+ fprintf(stderr, "received %d bytes: %s", n, (char*)hdr.msg_iov[0].iov_base);
+
+ shutdown(sock, SHUT_RDWR);
+ close(sock);
+
+#if EMSCRIPTEN
+ int result = 1;
+ REPORT_RESULT();
+ exit(EXIT_SUCCESS);
+ emscripten_cancel_main_loop();
+#endif
+ } else if(EWOULDBLOCK != errno) {
+ perror("recvmsg failed");
+ exit(EXIT_FAILURE);
+ emscripten_cancel_main_loop();
+ }
+}
+
+int main(void)
+{
+ memset(&si_host, 0, sizeof(struct sockaddr_in));
+ memset(&si_peer, 0, sizeof(struct sockaddr_in));
+
+ si_host.sin_family = AF_INET;
+ si_host.sin_port = htons(8991);
+ si_host.sin_addr.s_addr = htonl(INADDR_ANY);
+
+ if(-1 == (sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP))) {
+ perror("cannot create host socket");
+ exit(EXIT_FAILURE);
+ }
+
+ if(-1 == bind(sock, (struct sockaddr*)&si_host, sizeof(struct sockaddr))) {
+ perror("cannot bind host socket");
+ exit(EXIT_FAILURE);
+ }
+
+ iov[0].iov_base = buf;
+ iov[0].iov_len = sizeof(buf);
+
+ memset (&hdr, 0, sizeof (struct msghdr));
+
+ hdr.msg_name = &si_peer;
+ hdr.msg_namelen = sizeof(struct sockaddr_in);
+ hdr.msg_iov = iov;
+ hdr.msg_iovlen = 1;
+
+#if EMSCRIPTEN
+ emscripten_set_main_loop(iter, 0, 0);
+#else
+ while (!done) iter(NULL);
+#endif
+
+ return EXIT_SUCCESS;
+} \ No newline at end of file
diff --git a/tests/sockets/webrtc_peer.c b/tests/sockets/webrtc_peer.c
new file mode 100644
index 00000000..d24979e7
--- /dev/null
+++ b/tests/sockets/webrtc_peer.c
@@ -0,0 +1,81 @@
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <assert.h>
+#if EMSCRIPTEN
+#include <emscripten.h>
+#endif
+
+#define EXPECTED_BYTES 5
+#define BUFLEN 16
+#define HOST_ADDR "10.0.0.1"
+
+int result = 0;
+int sock;
+char buf[16] = "emscripten";
+struct sockaddr_in si_host;
+struct iovec iov[1];
+struct msghdr hdr;
+int done = 0;
+
+void iter(void* arg) {
+ int n;
+ n = sendmsg(sock, &hdr, 0);
+
+ if(0 < n) {
+ done = 1;
+ fprintf(stderr, "sent %d bytes: %s", n, (char*)hdr.msg_iov[0].iov_base);
+
+ shutdown(sock, SHUT_RDWR);
+ close(sock);
+
+ exit(EXIT_SUCCESS);
+ emscripten_cancel_main_loop();
+ } else if(EWOULDBLOCK != errno) {
+ perror("sendmsg failed");
+ exit(EXIT_FAILURE);
+ emscripten_cancel_main_loop();
+ }
+}
+
+int main(void)
+{
+ memset(&si_host, 0, sizeof(struct sockaddr_in));
+
+ si_host.sin_family = AF_INET;
+ si_host.sin_port = htons(8991);
+ if(0 == inet_pton(AF_INET, HOST_ADDR, &si_host.sin_addr)) {
+ perror("inet_aton failed");
+ exit(EXIT_FAILURE);
+ }
+
+ if(-1 == (sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP))) {
+ perror("cannot create socket");
+ exit(EXIT_FAILURE);
+ }
+
+ iov[0].iov_base = buf;
+ iov[0].iov_len = sizeof(buf);
+
+ memset (&hdr, 0, sizeof (struct msghdr));
+
+ hdr.msg_name = &si_host;
+ hdr.msg_namelen = sizeof(struct sockaddr_in);
+ hdr.msg_iov = iov;
+ hdr.msg_iovlen = 1;
+
+#if EMSCRIPTEN
+ emscripten_set_main_loop(iter, 0, 0);
+#else
+ while (!done) iter(NULL);
+#endif
+
+ return EXIT_SUCCESS;
+} \ No newline at end of file
diff --git a/tests/test_browser.py b/tests/test_browser.py
index be2c388b..69fb6f7e 100644
--- a/tests/test_browser.py
+++ b/tests/test_browser.py
@@ -620,7 +620,7 @@ Press any key to continue.'''
def test_sdl_canvas(self):
open(os.path.join(self.get_dir(), 'sdl_canvas.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl_canvas.c')).read()))
- Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'sdl_canvas.c'), '-o', 'page.html']).communicate()
+ Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'sdl_canvas.c'), '-o', 'page.html', '-s', 'LEGACY_GL_EMULATION=1']).communicate()
self.run_browser('page.html', '', '/report_result?1')
def test_sdl_key(self):
@@ -843,50 +843,55 @@ Press any key to continue.'''
def test_sdl_ogl(self):
shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png'))
self.btest('sdl_ogl.c', reference='screenshot-gray-purple.png', reference_slack=1,
- args=['-O2', '--minify', '0', '--preload-file', 'screenshot.png'],
+ args=['-O2', '--minify', '0', '--preload-file', 'screenshot.png', '-s', 'LEGACY_GL_EMULATION=1'],
message='You should see an image with gray at the top.')
def test_sdl_ogl_defaultmatrixmode(self):
shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png'))
self.btest('sdl_ogl_defaultMatrixMode.c', reference='screenshot-gray-purple.png', reference_slack=1,
- args=['--minify', '0', '--preload-file', 'screenshot.png'],
+ args=['--minify', '0', '--preload-file', 'screenshot.png', '-s', 'LEGACY_GL_EMULATION=1'],
message='You should see an image with gray at the top.')
def test_sdl_ogl_p(self):
# Immediate mode with pointers
shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png'))
self.btest('sdl_ogl_p.c', reference='screenshot-gray.png', reference_slack=1,
- args=['--preload-file', 'screenshot.png'],
+ args=['--preload-file', 'screenshot.png', '-s', 'LEGACY_GL_EMULATION=1'],
message='You should see an image with gray at the top.')
+ def test_sdl_ogl_proc_alias(self):
+ shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png'))
+ self.btest('sdl_ogl_proc_alias.c', reference='screenshot-gray-purple.png', reference_slack=1,
+ args=['-O2', '-g2', '-s', 'INLINING_LIMIT=1', '--preload-file', 'screenshot.png', '-s', 'LEGACY_GL_EMULATION=1', '-s', 'VERBOSE=1'])
+
def test_sdl_fog_simple(self):
shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png'))
self.btest('sdl_fog_simple.c', reference='screenshot-fog-simple.png',
- args=['-O2', '--minify', '0', '--preload-file', 'screenshot.png'],
+ args=['-O2', '--minify', '0', '--preload-file', 'screenshot.png', '-s', 'LEGACY_GL_EMULATION=1'],
message='You should see an image with fog.')
def test_sdl_fog_negative(self):
shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png'))
self.btest('sdl_fog_negative.c', reference='screenshot-fog-negative.png',
- args=['--preload-file', 'screenshot.png'],
+ args=['--preload-file', 'screenshot.png', '-s', 'LEGACY_GL_EMULATION=1'],
message='You should see an image with fog.')
def test_sdl_fog_density(self):
shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png'))
self.btest('sdl_fog_density.c', reference='screenshot-fog-density.png',
- args=['--preload-file', 'screenshot.png'],
+ args=['--preload-file', 'screenshot.png', '-s', 'LEGACY_GL_EMULATION=1'],
message='You should see an image with fog.')
def test_sdl_fog_exp2(self):
shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png'))
self.btest('sdl_fog_exp2.c', reference='screenshot-fog-exp2.png',
- args=['--preload-file', 'screenshot.png'],
+ args=['--preload-file', 'screenshot.png', '-s', 'LEGACY_GL_EMULATION=1'],
message='You should see an image with fog.')
def test_sdl_fog_linear(self):
shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png'))
self.btest('sdl_fog_linear.c', reference='screenshot-fog-linear.png', reference_slack=1,
- args=['--preload-file', 'screenshot.png'],
+ args=['--preload-file', 'screenshot.png', '-s', 'LEGACY_GL_EMULATION=1'],
message='You should see an image with fog.')
def test_openal_playback(self):
@@ -903,7 +908,7 @@ Press any key to continue.'''
def test_glfw(self):
open(os.path.join(self.get_dir(), 'glfw.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'glfw.c')).read()))
- Popen([PYTHON, EMCC, '-O2', os.path.join(self.get_dir(), 'glfw.c'), '-o', 'page.html']).communicate()
+ Popen([PYTHON, EMCC, '-O2', os.path.join(self.get_dir(), 'glfw.c'), '-o', 'page.html', '-s', 'LEGACY_GL_EMULATION=1']).communicate()
self.run_browser('page.html', '', '/report_result?1')
def test_egl_width_height(self):
@@ -1063,17 +1068,13 @@ Press any key to continue.'''
def test_glgears_animation(self):
es2_suffix = ['', '_full', '_full_944']
for full_es2 in [0, 1, 2]:
- for emulation in [0, 1]:
- if full_es2 and emulation: continue
- print full_es2, emulation
- Popen([PYTHON, EMCC, path_from_root('tests', 'hello_world_gles%s.c' % es2_suffix[full_es2]), '-o', 'something.html',
- '-DHAVE_BUILTIN_SINCOS', '-s', 'GL_TESTING=1',
- '--shell-file', path_from_root('tests', 'hello_world_gles_shell.html')] +
- (['-s', 'FORCE_GL_EMULATION=1'] if emulation else []) +
- (['-s', 'FULL_ES2=1'] if full_es2 else []),
- ).communicate()
- self.run_browser('something.html', 'You should see animating gears.', '/report_gl_result?true')
- assert ('var GLEmulation' in open(self.in_dir('something.html')).read()) == emulation, "emulation code should be added when asked for"
+ print full_es2
+ Popen([PYTHON, EMCC, path_from_root('tests', 'hello_world_gles%s.c' % es2_suffix[full_es2]), '-o', 'something.html',
+ '-DHAVE_BUILTIN_SINCOS', '-s', 'GL_TESTING=1',
+ '--shell-file', path_from_root('tests', 'hello_world_gles_shell.html')] +
+ (['-s', 'FULL_ES2=1'] if full_es2 else []),
+ ).communicate()
+ self.run_browser('something.html', 'You should see animating gears.', '/report_gl_result?true')
def test_fulles2_sdlproc(self):
self.btest('full_es2_sdlproc.c', '1', args=['-s', 'GL_TESTING=1', '-DHAVE_BUILTIN_SINCOS', '-s', 'FULL_ES2=1'])
@@ -1163,90 +1164,90 @@ Press any key to continue.'''
self.btest('glgetattachedshaders.c', '1')
def test_sdlglshader(self):
- self.btest('sdlglshader.c', reference='sdlglshader.png', args=['-O2', '--closure', '1'])
+ self.btest('sdlglshader.c', reference='sdlglshader.png', args=['-O2', '--closure', '1', '-s', 'LEGACY_GL_EMULATION=1'])
def test_gl_ps(self):
# pointers and a shader
shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png'))
- self.btest('gl_ps.c', reference='gl_ps.png', args=['--preload-file', 'screenshot.png'], reference_slack=1)
+ self.btest('gl_ps.c', reference='gl_ps.png', args=['--preload-file', 'screenshot.png', '-s', 'LEGACY_GL_EMULATION=1'], reference_slack=1)
def test_gl_ps_packed(self):
# packed data that needs to be strided
shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png'))
- self.btest('gl_ps_packed.c', reference='gl_ps.png', args=['--preload-file', 'screenshot.png'], reference_slack=1)
+ self.btest('gl_ps_packed.c', reference='gl_ps.png', args=['--preload-file', 'screenshot.png', '-s', 'LEGACY_GL_EMULATION=1'], reference_slack=1)
def test_gl_ps_strides(self):
shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png'))
- self.btest('gl_ps_strides.c', reference='gl_ps_strides.png', args=['--preload-file', 'screenshot.png'])
+ self.btest('gl_ps_strides.c', reference='gl_ps_strides.png', args=['--preload-file', 'screenshot.png', '-s', 'LEGACY_GL_EMULATION=1'])
def test_gl_renderers(self):
- self.btest('gl_renderers.c', reference='gl_renderers.png', args=['-s', 'GL_UNSAFE_OPTS=0'])
+ self.btest('gl_renderers.c', reference='gl_renderers.png', args=['-s', 'GL_UNSAFE_OPTS=0', '-s', 'LEGACY_GL_EMULATION=1'])
def test_gl_stride(self):
- self.btest('gl_stride.c', reference='gl_stride.png', args=['-s', 'GL_UNSAFE_OPTS=0'])
+ self.btest('gl_stride.c', reference='gl_stride.png', args=['-s', 'GL_UNSAFE_OPTS=0', '-s', 'LEGACY_GL_EMULATION=1'])
def test_matrix_identity(self):
- self.btest('gl_matrix_identity.c', expected=['-1882984448', '460451840'])
+ self.btest('gl_matrix_identity.c', expected=['-1882984448', '460451840'], args=['-s', 'LEGACY_GL_EMULATION=1'])
def test_cubegeom_pre(self):
- self.btest('cubegeom_pre.c', reference='cubegeom_pre.png')
+ self.btest('cubegeom_pre.c', reference='cubegeom_pre.png', args=['-s', 'LEGACY_GL_EMULATION=1'])
def test_cubegeom_pre2(self):
- self.btest('cubegeom_pre2.c', reference='cubegeom_pre2.png', args=['-s', 'GL_DEBUG=1']) # some coverage for GL_DEBUG not breaking the build
+ self.btest('cubegeom_pre2.c', reference='cubegeom_pre2.png', args=['-s', 'GL_DEBUG=1', '-s', 'LEGACY_GL_EMULATION=1']) # some coverage for GL_DEBUG not breaking the build
def test_cubegeom_pre3(self):
- self.btest('cubegeom_pre3.c', reference='cubegeom_pre2.png')
+ self.btest('cubegeom_pre3.c', reference='cubegeom_pre2.png', args=['-s', 'LEGACY_GL_EMULATION=1'])
def test_cubegeom(self):
- self.btest('cubegeom.c', args=['-O2', '-g'], reference='cubegeom.png')
+ self.btest('cubegeom.c', reference='cubegeom.png', args=['-O2', '-g', '-s', 'LEGACY_GL_EMULATION=1'])
def test_cubegeom_glew(self):
- self.btest('cubegeom_glew.c', args=['-O2', '--closure', '1'], reference='cubegeom.png')
+ self.btest('cubegeom_glew.c', reference='cubegeom.png', args=['-O2', '--closure', '1', '-s', 'LEGACY_GL_EMULATION=1'])
def test_cubegeom_color(self):
- self.btest('cubegeom_color.c', reference='cubegeom_color.png')
+ self.btest('cubegeom_color.c', reference='cubegeom_color.png', args=['-s', 'LEGACY_GL_EMULATION=1'])
def test_cubegeom_normal(self):
- self.btest('cubegeom_normal.c', reference='cubegeom_normal.png')
+ self.btest('cubegeom_normal.c', reference='cubegeom_normal.png', args=['-s', 'LEGACY_GL_EMULATION=1'])
def test_cubegeom_normal_dap(self): # draw is given a direct pointer to clientside memory, no element array buffer
- self.btest('cubegeom_normal_dap.c', reference='cubegeom_normal.png')
+ self.btest('cubegeom_normal_dap.c', reference='cubegeom_normal.png', args=['-s', 'LEGACY_GL_EMULATION=1'])
def test_cubegeom_normal_dap_far(self): # indices do nto start from 0
- self.btest('cubegeom_normal_dap_far.c', reference='cubegeom_normal.png')
+ self.btest('cubegeom_normal_dap_far.c', reference='cubegeom_normal.png', args=['-s', 'LEGACY_GL_EMULATION=1'])
def test_cubegeom_normal_dap_far_range(self): # glDrawRangeElements
- self.btest('cubegeom_normal_dap_far_range.c', reference='cubegeom_normal.png')
+ self.btest('cubegeom_normal_dap_far_range.c', reference='cubegeom_normal.png', args=['-s', 'LEGACY_GL_EMULATION=1'])
def test_cubegeom_normal_dap_far_glda(self): # use glDrawArrays
- self.btest('cubegeom_normal_dap_far_glda.c', reference='cubegeom_normal_dap_far_glda.png')
+ self.btest('cubegeom_normal_dap_far_glda.c', reference='cubegeom_normal_dap_far_glda.png', args=['-s', 'LEGACY_GL_EMULATION=1'])
def test_cubegeom_normal_dap_far_glda_quad(self): # with quad
- self.btest('cubegeom_normal_dap_far_glda_quad.c', reference='cubegeom_normal_dap_far_glda_quad.png')
+ self.btest('cubegeom_normal_dap_far_glda_quad.c', reference='cubegeom_normal_dap_far_glda_quad.png', args=['-s', 'LEGACY_GL_EMULATION=1'])
def test_cubegeom_mt(self):
- self.btest('cubegeom_mt.c', reference='cubegeom_mt.png') # multitexture
+ self.btest('cubegeom_mt.c', reference='cubegeom_mt.png', args=['-s', 'LEGACY_GL_EMULATION=1']) # multitexture
def test_cubegeom_color2(self):
- self.btest('cubegeom_color2.c', reference='cubegeom_color2.png')
+ self.btest('cubegeom_color2.c', reference='cubegeom_color2.png', args=['-s', 'LEGACY_GL_EMULATION=1'])
def test_cubegeom_texturematrix(self):
- self.btest('cubegeom_texturematrix.c', reference='cubegeom_texturematrix.png')
+ self.btest('cubegeom_texturematrix.c', reference='cubegeom_texturematrix.png', args=['-s', 'LEGACY_GL_EMULATION=1'])
def test_cubegeom_fog(self):
- self.btest('cubegeom_fog.c', reference='cubegeom_fog.png')
+ self.btest('cubegeom_fog.c', reference='cubegeom_fog.png', args=['-s', 'LEGACY_GL_EMULATION=1'])
def test_cubegeom_pre_vao(self):
- self.btest('cubegeom_pre_vao.c', reference='cubegeom_pre_vao.png')
+ self.btest('cubegeom_pre_vao.c', reference='cubegeom_pre_vao.png', args=['-s', 'LEGACY_GL_EMULATION=1'])
def test_cubegeom_pre2_vao(self):
- self.btest('cubegeom_pre2_vao.c', reference='cubegeom_pre_vao.png')
+ self.btest('cubegeom_pre2_vao.c', reference='cubegeom_pre_vao.png', args=['-s', 'LEGACY_GL_EMULATION=1'])
def test_cubegeom_pre2_vao2(self):
- self.btest('cubegeom_pre2_vao2.c', reference='cubegeom_pre2_vao2.png')
+ self.btest('cubegeom_pre2_vao2.c', reference='cubegeom_pre2_vao2.png', args=['-s', 'LEGACY_GL_EMULATION=1'])
def test_cube_explosion(self):
- self.btest('cube_explosion.c', reference='cube_explosion.png')
+ self.btest('cube_explosion.c', reference='cube_explosion.png', args=['-s', 'LEGACY_GL_EMULATION=1'])
def test_sdl_canvas_blank(self):
self.btest('sdl_canvas_blank.c', reference='sdl_canvas_blank.png')
@@ -1298,11 +1299,11 @@ Press any key to continue.'''
def test_glbegin_points(self):
shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png'))
- self.btest('glbegin_points.c', reference='glbegin_points.png', args=['--preload-file', 'screenshot.png'])
+ self.btest('glbegin_points.c', reference='glbegin_points.png', args=['--preload-file', 'screenshot.png', '-s', 'LEGACY_GL_EMULATION=1'])
def test_s3tc(self):
shutil.copyfile(path_from_root('tests', 'screenshot.dds'), os.path.join(self.get_dir(), 'screenshot.dds'))
- self.btest('s3tc.c', reference='s3tc.png', args=['--preload-file', 'screenshot.dds'])
+ self.btest('s3tc.c', reference='s3tc.png', args=['--preload-file', 'screenshot.dds', '-s', 'LEGACY_GL_EMULATION=1'])
def test_s3tc_crunch(self):
shutil.copyfile(path_from_root('tests', 'ship.dds'), 'ship.dds')
@@ -1313,7 +1314,7 @@ Press any key to continue.'''
shutil.move('ship.dds', 'ship.donotfindme.dds') # make sure we load from the compressed
shutil.move('bloom.dds', 'bloom.donotfindme.dds') # make sure we load from the compressed
shutil.move('water.dds', 'water.donotfindme.dds') # make sure we load from the compressed
- self.btest('s3tc_crunch.c', reference='s3tc_crunch.png', reference_slack=11, args=['--pre-js', 'pre.js'])
+ self.btest('s3tc_crunch.c', reference='s3tc_crunch.png', reference_slack=11, args=['--pre-js', 'pre.js', '-s', 'LEGACY_GL_EMULATION=1'])
def test_s3tc_crunch_split(self): # load several datafiles/outputs of file packager
shutil.copyfile(path_from_root('tests', 'ship.dds'), 'ship.dds')
@@ -1324,14 +1325,20 @@ Press any key to continue.'''
shutil.move('ship.dds', 'ship.donotfindme.dds') # make sure we load from the compressed
shutil.move('bloom.dds', 'bloom.donotfindme.dds') # make sure we load from the compressed
shutil.move('water.dds', 'water.donotfindme.dds') # make sure we load from the compressed
- self.btest('s3tc_crunch.c', reference='s3tc_crunch.png', reference_slack=11, args=['--pre-js', 'asset_a.js', '--pre-js', 'asset_b.js'])
+ self.btest('s3tc_crunch.c', reference='s3tc_crunch.png', reference_slack=11, args=['--pre-js', 'asset_a.js', '--pre-js', 'asset_b.js', '-s', 'LEGACY_GL_EMULATION=1'])
def test_aniso(self):
+ if SPIDERMONKEY_ENGINE in JS_ENGINES:
+ # asm.js-ification check
+ Popen([PYTHON, EMCC, path_from_root('tests', 'aniso.c'), '-O2', '-g2', '-s', 'LEGACY_GL_EMULATION=1']).communicate()
+ Settings.ASM_JS = 1
+ self.run_generated_code(SPIDERMONKEY_ENGINE, 'a.out.js')
+
shutil.copyfile(path_from_root('tests', 'water.dds'), 'water.dds')
- self.btest('aniso.c', reference='aniso.png', reference_slack=2, args=['--preload-file', 'water.dds'])
+ self.btest('aniso.c', reference='aniso.png', reference_slack=2, args=['--preload-file', 'water.dds', '-s', 'LEGACY_GL_EMULATION=1'])
def test_tex_nonbyte(self):
- self.btest('tex_nonbyte.c', reference='tex_nonbyte.png')
+ self.btest('tex_nonbyte.c', reference='tex_nonbyte.png', args=['-s', 'LEGACY_GL_EMULATION=1'])
def test_float_tex(self):
self.btest('float_tex.cpp', reference='float_tex.png')
@@ -1340,7 +1347,7 @@ Press any key to continue.'''
self.btest('gl_subdata.cpp', reference='float_tex.png')
def test_perspective(self):
- self.btest('perspective.c', reference='perspective.png')
+ self.btest('perspective.c', reference='perspective.png', args=['-s', 'LEGACY_GL_EMULATION=1'])
def test_runtimelink(self):
return self.skip('shared libs are deprecated')
diff --git a/tests/test_core.py b/tests/test_core.py
index 31db6ca5..88f6674a 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -9582,15 +9582,15 @@ def process(filename):
self.assertIdentical(clean(no_maps_file), clean(out_file))
map_filename = out_filename + '.map'
data = json.load(open(map_filename, 'r'))
- self.assertIdentical(out_filename, data['file'])
- self.assertIdentical(src_filename, data['sources'][0])
- self.assertIdentical(src, data['sourcesContent'][0])
+ self.assertPathsIdentical(out_filename, data['file'])
+ self.assertPathsIdentical(src_filename, data['sources'][0])
+ self.assertTextDataIdentical(src, data['sourcesContent'][0])
mappings = json.loads(jsrun.run_js(
path_from_root('tools', 'source-maps', 'sourcemap2json.js'),
tools.shared.NODE_JS, [map_filename]))
seen_lines = set()
for m in mappings:
- self.assertIdentical(src_filename, m['source'])
+ self.assertPathsIdentical(src_filename, m['source'])
seen_lines.add(m['originalLine'])
# ensure that all the 'meaningful' lines in the original code get mapped
assert seen_lines.issuperset([6, 7, 11, 12])
diff --git a/tests/test_sockets.py b/tests/test_sockets.py
index 03593674..4f6ee2a9 100644
--- a/tests/test_sockets.py
+++ b/tests/test_sockets.py
@@ -198,3 +198,71 @@ class sockets(BrowserCore):
# ]:
# with harness:
# self.btest(os.path.join('sockets', 'test_enet_client.c'), expected='0', args=['-DSOCKK=9011'] + enet)
+
+ def test_webrtc(self):
+ host_src = 'webrtc_host.c'
+ peer_src = 'webrtc_peer.c'
+
+ host_outfile = 'host.html'
+ peer_outfile = 'peer.html'
+
+ host_filepath = path_from_root('tests', 'sockets', host_src)
+ temp_host_filepath = os.path.join(self.get_dir(), os.path.basename(host_src))
+ with open(host_filepath) as f: host_src = f.read()
+ with open(temp_host_filepath, 'w') as f: f.write(self.with_report_result(host_src))
+
+ peer_filepath = path_from_root('tests', 'sockets', peer_src)
+ temp_peer_filepath = os.path.join(self.get_dir(), os.path.basename(peer_src))
+ with open(peer_filepath) as f: peer_src = f.read()
+ with open(temp_peer_filepath, 'w') as f: f.write(self.with_report_result(peer_src))
+
+ open(os.path.join(self.get_dir(), 'host_pre.js'), 'w').write('''
+ var Module = {
+ webrtc: {
+ broker: 'https://mdsw.ch:8080',
+ session: undefined,
+ onpeer: function(peer, route) {
+ window.open('http://localhost:8888/peer.html?' + route);
+ // iframe = document.createElement("IFRAME");
+ // iframe.setAttribute("src", "http://localhost:8888/peer.html?" + route);
+ // iframe.style.display = "none";
+ // document.body.appendChild(iframe);
+ peer.listen();
+ },
+ onconnect: function(peer) {
+ },
+ ondisconnect: function(peer) {
+ },
+ onerror: function(error) {
+ console.error(error);
+ }
+ },
+ };
+ ''')
+
+ open(os.path.join(self.get_dir(), 'peer_pre.js'), 'w').write('''
+ var Module = {
+ webrtc: {
+ broker: 'https://mdsw.ch:8080',
+ session: window.location.toString().split('?')[1],
+ onpeer: function(peer, route) {
+ peer.connect(Module['webrtc']['session']);
+ },
+ onconnect: function(peer) {
+ },
+ ondisconnect: function(peer) {
+ // Calling window.close() from this handler hangs my browser, so run it in the next turn
+ setTimeout(window.close, 0);
+ },
+ onerror: function(error) {
+ console.error(error);
+ }
+ }
+ };
+ ''')
+
+ Popen([PYTHON, EMCC, temp_host_filepath, '-o', host_outfile] + ['-s', 'GL_TESTING=1', '--pre-js', 'host_pre.js', '-s', 'SOCKET_WEBRTC=1', '-s', 'SOCKET_DEBUG=1']).communicate()
+ Popen([PYTHON, EMCC, temp_peer_filepath, '-o', peer_outfile] + ['-s', 'GL_TESTING=1', '--pre-js', 'peer_pre.js', '-s', 'SOCKET_WEBRTC=1', '-s', 'SOCKET_DEBUG=1']).communicate()
+
+ expected = '1'
+ self.run_browser(host_outfile, '.', ['/report_result?' + e for e in expected]) \ No newline at end of file
diff --git a/tools/find_bigfuncs.py b/tools/find_bigfuncs.py
index 6fdec3a9..79136343 100644
--- a/tools/find_bigfuncs.py
+++ b/tools/find_bigfuncs.py
@@ -1,5 +1,5 @@
'''
-Simple tool to find big functions in an .ll file.
+Simple tool to find big functions in a js or ll file
'''
import os, sys, re
@@ -11,7 +11,7 @@ curr = None
data = []
for line in open(filename):
i += 1
- if line.startswith('function '):
+ if line.startswith(('function ', 'define ')):
start = i
curr = line
elif line.startswith('}') and curr:
diff --git a/tools/response_file.py b/tools/response_file.py
index 312cda73..f19cf8af 100644
--- a/tools/response_file.py
+++ b/tools/response_file.py
@@ -6,8 +6,8 @@ def create_response_file(args, directory):
(response_fd, response_filename) = tempfile.mkstemp(prefix='emscripten_', suffix='.rsp', dir=directory, text=True)
response_fd = os.fdopen(response_fd, "w")
#print >> sys.stderr, "Creating response file '%s'" % response_filename
- args = map(lambda p: p.replace(' ', '').replace('\\', '\\\\').replace('"', '\\"'), args)
- response_fd.write(' '.join(args))
+ args = map(lambda p: p.replace('\\', '\\\\').replace('"', '\\"'), args)
+ response_fd.write('"' + '" "'.join(args) + '"')
response_fd.close()
return response_filename
diff --git a/tools/shared.py b/tools/shared.py
index 917f548e..0d0f20d4 100644
--- a/tools/shared.py
+++ b/tools/shared.py
@@ -550,6 +550,7 @@ if USE_EMSDK:
# allows projects to override them)
EMSDK_OPTS = ['-nostdinc', '-Xclang', '-nobuiltininc', '-Xclang', '-nostdsysteminc',
'-Xclang', '-isystem' + path_from_root('system', 'local', 'include'),
+ '-Xclang', '-isystem' + path_from_root('system', 'include', 'compat'),
'-Xclang', '-isystem' + path_from_root('system', 'include', 'libcxx'),
'-Xclang', '-isystem' + path_from_root('system', 'include'),
'-Xclang', '-isystem' + path_from_root('system', 'include', 'emscripten'),
diff --git a/tools/source-maps/sourcemapper.js b/tools/source-maps/sourcemapper.js
index fa908900..06c9a227 100755
--- a/tools/source-maps/sourcemapper.js
+++ b/tools/source-maps/sourcemapper.js
@@ -16,6 +16,38 @@ function countLines(s) {
return count;
}
+// For a minor optimization, only do win32->unix normalization if we are actually on Windows,
+// which avoids redundantly scanning files if not needed.
+var isWindows = (process.platform === 'win32');
+
+var unixPathRe = new RegExp('\\\\', 'g');
+// Returns the given (possibly Windows) path p normalized to unix path separators '/'.
+function toUnixPath(p) {
+ if (isWindows) {
+ return p.replace(unixPathRe, '/');
+ } else {
+ return p;
+ }
+}
+
+var unixLineEndRe = new RegExp('\r\n', 'g');
+// Returns the given (possibly Windows) text data t normalized to unix line endings '\n'.
+function toUnixLineEnding(t) {
+ if (isWindows) {
+ return t.replace(unixLineEndRe, '\n');
+ } else {
+ return t;
+ }
+}
+
+// If path "p2" is a relative path, joins paths p1 and p2 to form "p1/p2". If p2 is an absolute path, "p2" is returned.
+function joinPath(p1, p2) {
+ if (p2[0] == '/' || (p2.length >= 3 && p2[1] == ':' && (p2[2] == '/' || p2[2] == '\\'))) // Is p2 an absolute path?
+ return p2;
+ else
+ return toUnixPath(path.join(p1, p2));
+}
+
/*
* Extracts the line (not block) comments from the generated function code and
* invokes commentHandler with (comment content, line number of comment). This
@@ -105,8 +137,7 @@ function generateMap(mappings, sourceRoot, mapFileBaseName, generatedLineOffset)
// avoid doing it unnecessarily
if (!(originalFileName in seenFiles)) {
seenFiles[originalFileName] = true;
- var rootedPath = originalFileName[0] === path.sep ?
- originalFileName : path.join(sourceRoot, originalFileName);
+ var rootedPath = joinPath(sourceRoot, originalFileName);
try {
generator.setSourceContent(originalFileName, fs.readFileSync(rootedPath, 'utf-8'));
} catch (e) {
@@ -144,15 +175,15 @@ if (require.main === module) {
} else {
var opts = parseArgs(process.argv.slice(2));
var fileName = opts._[0];
- var sourceRoot = opts.sourceRoot ? opts.sourceRoot : ".";
- var mapFileBaseName = opts.mapFileBaseName ? opts.mapFileBaseName : fileName;
+ var sourceRoot = opts.sourceRoot ? toUnixPath(opts.sourceRoot) : ".";
+ var mapFileBaseName = toUnixPath(opts.mapFileBaseName ? opts.mapFileBaseName : fileName);
var generatedLineOffset = opts.offset ? parseInt(opts.offset, 10) : 0;
- var generatedSource = fs.readFileSync(fileName, 'utf-8');
+ var generatedSource = toUnixLineEnding(fs.readFileSync(fileName, 'utf-8'));
var source = generatedSource;
var mappings = getMappings(generatedSource);
for (var i = 1, l = opts._.length; i < l; i ++) {
- var optimizedSource = fs.readFileSync(opts._[i], 'utf-8')
+ var optimizedSource = toUnixLineEnding(fs.readFileSync(opts._[i], 'utf-8'))
var optimizedMappings = getMappings(optimizedSource);
var newMappings = {};
// uglify processes the code between EMSCRIPTEN_START_FUNCS and