aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiler.js31
-rw-r--r--src/jsifier.js19
-rw-r--r--src/library.js119
-rw-r--r--src/library_browser.js9
-rw-r--r--src/library_glut.js10
-rw-r--r--src/library_sdl.js3
-rw-r--r--src/library_xlib.js3
-rw-r--r--src/modules.js5
-rw-r--r--src/settings.js10
9 files changed, 186 insertions, 23 deletions
diff --git a/src/compiler.js b/src/compiler.js
index 89da32d5..2863afda 100644
--- a/src/compiler.js
+++ b/src/compiler.js
@@ -31,15 +31,30 @@ if (ENVIRONMENT_IS_NODE) {
var nodeFS = require('fs');
var nodePath = require('path');
- read = function(filename) {
- filename = nodePath['normalize'](filename);
- var ret = nodeFS['readFileSync'](filename).toString();
- // The path is absolute if the normalized version is the same as the resolved.
- if (!ret && filename != nodePath['resolve'](filename)) {
- filename = path.join(__dirname, '..', 'src', filename);
- ret = nodeFS['readFileSync'](filename).toString();
+ if (!nodeFS.existsSync) {
+ nodeFS.existsSync = function(path) {
+ try {
+ return !!nodeFS.readFileSync(path);
+ } catch(e) {
+ return false;
+ }
+ }
+ }
+
+ function find(filename) {
+ var prefixes = [__dirname, process.cwd()];
+ for (var i = 0; i < prefixes.length; ++i) {
+ var combined = nodePath.join(prefixes[i], filename);
+ if (nodeFS.existsSync(combined)) {
+ return combined;
+ }
}
- return ret;
+ return filename;
+ }
+
+ read = function(filename) {
+ var absolute = find(filename);
+ return nodeFS['readFileSync'](absolute).toString();
};
load = function(f) {
diff --git a/src/jsifier.js b/src/jsifier.js
index 01ecd7d3..8021f8a1 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -32,7 +32,7 @@ function JSify(data, functionsOnly, givenFunctions) {
// else. This lets us not hold any strings in memory, we simply print
// things out as they are ready.
- var shellFile = BUILD_AS_SHARED_LIB ? 'shell_sharedlib.js' : 'shell.js';
+ var shellFile = SHELL_FILE ? SHELL_FILE : (BUILD_AS_SHARED_LIB ? 'shell_sharedlib.js' : 'shell.js');
var shellParts = read(shellFile).split('{{BODY}}');
print(shellParts[0]);
var preFile = BUILD_AS_SHARED_LIB ? 'preamble_sharedlib.js' : 'preamble.js';
@@ -522,6 +522,11 @@ function JSify(data, functionsOnly, givenFunctions) {
func.JS += ' */\n';
}
+ if (PRINT_SPLIT_FILE_MARKER) {
+ func.JS += '\n//FUNCTION_BEGIN_MARKER\n'
+ var associatedSourceFile = "NO_SOURCE";
+ }
+
func.JS += 'function ' + func.ident + '(' + paramIdents.join(', ') + ') {\n';
if (PROFILE) {
@@ -572,6 +577,13 @@ function JSify(data, functionsOnly, givenFunctions) {
if (EXECUTION_TIMEOUT > 0) {
ret += indent + 'if (Date.now() - START_TIME >= ' + (EXECUTION_TIMEOUT*1000) + ') throw "Timed out!" + (new Error().stack);\n';
}
+
+ if (PRINT_SPLIT_FILE_MARKER && Debugging.on && Debugging.getAssociatedSourceFile(line.lineNum)) {
+ // Overwrite the associated source file for every line. The last line should contain the source file associated to
+ // the return value/address of outer most block (the marked function).
+ associatedSourceFile = Debugging.getAssociatedSourceFile(line.lineNum);
+ }
+
// for special labels we care about (for phi), mark that we visited them
return ret + label.lines.map(function(line) { return line.JS + (Debugging.on ? Debugging.getComment(line.lineNum) : '') })
.join('\n')
@@ -653,6 +665,11 @@ function JSify(data, functionsOnly, givenFunctions) {
func.JS += ' return' + (func.returnType !== 'void' ? ' null' : '') + ';\n';
}
func.JS += '}\n';
+
+ if (PRINT_SPLIT_FILE_MARKER) {
+ func.JS += '\n//FUNCTION_END_MARKER_OF_SOURCE_FILE_' + associatedSourceFile + '\n';
+ }
+
if (func.ident in EXPORTED_FUNCTIONS) {
func.JS += 'Module["' + func.ident + '"] = ' + func.ident + ';';
}
diff --git a/src/library.js b/src/library.js
index 1c150bc9..938a3c92 100644
--- a/src/library.js
+++ b/src/library.js
@@ -4850,6 +4850,7 @@ LibraryManager.library = {
// RTTI hacks for exception handling, defining type_infos for common types.
// The values are dummies. We simply use the addresses of these statically
// allocated variables as unique identifiers.
+ _ZTIb: [0], // bool
_ZTIi: [0], // int
_ZTIj: [0], // unsigned int
_ZTIl: [0], // long
@@ -4863,7 +4864,7 @@ LibraryManager.library = {
_ZTIa: [0], // signed char
_ZTIh: [0], // unsigned char
_ZTIs: [0], // short
- _ZTIt: [0], // signed short
+ _ZTIt: [0], // unsigned short
_ZTIv: [0], // void
_ZTIPv: [0], // void*
@@ -6314,6 +6315,122 @@ LibraryManager.library = {
ntohl: 'htonl',
ntohs: 'htons',
+ inet_pton__deps: ['__setErrNo', '$ERRNO_CODES'],
+ inet_pton: function(af, src, dst) {
+ // int af, const char *src, void *dst
+ if ((af ^ {{{ cDefine("AF_INET") }}}) !== 0) { ___setErrNo(ERRNO_CODES.EAFNOSUPPORT); return -1; }
+ var b = Pointer_stringify(src).split(".");
+ if (b.length !== 4) return 0;
+ var ret = Number(b[0]) | (Number(b[1]) << 8) | (Number(b[2]) << 16) | (Number(b[3]) << 24);
+ if (isNaN(ret)) return 0;
+ setValue(dst, ret, 'i32');
+ return 1;
+ },
+
+ _inet_ntop_raw: function(addr) {
+ return (addr & 0xff) + '.' + ((addr >> 8) & 0xff) + '.' + ((addr >> 16) & 0xff) + '.' + ((addr >> 24) & 0xff)
+ },
+
+ inet_ntop__deps: ['_inet_ntop_raw'],
+ inet_ntop: function(af, src, dst, size) {
+ var addr = getValue(src, 'i32');
+ var str = __inet_ntop_raw(addr);
+ writeStringToMemory(str.substr(0, size), dst, true);
+ return dst;
+ },
+
+ // ==========================================================================
+ // sockets
+ // ==========================================================================
+
+ $Sockets__deps: ['__setErrNo', '$ERRNO_CODES'],
+ $Sockets: {
+ BUFFER_SIZE: 10*1024,
+ nextFd: 1,
+ fds: {},
+ sockaddr_in_layout: Runtime.generateStructInfo([
+ ['i16', 'sin_family'],
+ ['i16', 'sin_port'],
+ ['i32', 'sin_addr'],
+ ['i64', 'sin_zero'],
+ ]),
+ },
+
+ socket__deps: ['$Sockets'],
+ socket: function(family, type, protocol) {
+ var fd = Sockets.nextFd++;
+ Sockets.fds[fd] = {
+ connected: false
+ };
+ return fd;
+ },
+
+ connect__deps: ['$Sockets', '_inet_ntop_raw', 'ntohs'],
+ connect: function(fd, addr, addrlen) {
+ var info = Sockets.fds[fd];
+ if (!info) return -1;
+ info.connected = true;
+ info.addr = getValue(addr + Sockets.sockaddr_in_layout.sin_addr, 'i32');
+ info.port = _ntohs(getValue(addr + Sockets.sockaddr_in_layout.sin_port, 'i16'));
+ info.host = __inet_ntop_raw(info.addr);
+ info.socket = new WebSocket('ws://' + info.host + ':' + info.port, ['arraybuffer']);
+ info.socket.binaryType = 'arraybuffer';
+ info.buffer = new Uint8Array(Sockets.BUFFER_SIZE);
+ info.bufferWrite = info.bufferRead = 0;
+ info.socket.onmessage = function (event) {
+ var data = event.data;
+ if (typeof data == 'string') {
+ var binaryString = window.atob(data);
+ var len = binaryString.length;
+ for (var i = 0; i < len; i++) {
+ info.buffer[info.bufferWrite++] = binaryString.charCodeAt(i);
+ if (info.bufferWrite == Sockets.BUFFER_SIZE) info.bufferWrite = 0;
+ if (info.bufferWrite == info.bufferRead) throw 'socket buffer overflow';
+ }
+ } else {
+ console.log('binary!');
+ }
+ }
+ return 0;
+ },
+
+ recv__deps: ['$Sockets'],
+ recv: function(fd, buf, len, flags) {
+ var info = Sockets.fds[fd];
+ if (!info) return -1;
+ if (info.bufferWrite == info.bufferRead) {
+ ___setErrNo(ERRNO_CODES.EAGAIN); // no data, and all sockets are nonblocking, so this is the right behavior
+ return 0; // should this be -1 like the spec says?
+ }
+ var ret = 0;
+ while (info.bufferWrite != info.bufferRead && len > 0) {
+ // write out a byte
+ {{{ makeSetValue('buf++', '0', 'info.buffer[info.bufferRead++]', 'i8') }}};
+ if (info.bufferRead == Sockets.BUFFER_SIZE) info.bufferRead = 0;
+ len--;
+ ret++;
+ }
+ return ret;
+ },
+
+ shutdown: function(fd, how) {
+ var info = Sockets.fds[fd];
+ if (!info) return -1;
+ info.socket.close();
+ Sockets.fds[fd] = null;
+ },
+
+ ioctl: function(fd, request, varargs) {
+ var info = Sockets.fds[fd];
+ if (!info) return -1;
+ var start = info.bufferRead;
+ var end = info.bufferWrite;
+ if (end < start) end += Sockets.BUFFER_SIZE;
+ var dest = {{{ makeGetValue('varargs', '0', 'i32') }}};
+ {{{ makeSetValue('dest', '0', 'end - start', 'i32') }}};
+ return 0;
+ },
+
// ==========================================================================
// emscripten.h
// ==========================================================================
diff --git a/src/library_browser.js b/src/library_browser.js
index 5291dcee..27bf4a0c 100644
--- a/src/library_browser.js
+++ b/src/library_browser.js
@@ -347,6 +347,12 @@ mergeInto(LibraryManager.library, {
});
addRunDependency('al ' + url);
},
+
+ setCanvasSize: function(width, height) {
+ var canvas = Module['canvas'];
+ canvas.width = width;
+ canvas.height = height;
+ }
},
emscripten_async_wget: function(url, file, onload, onerror) {
@@ -494,8 +500,7 @@ mergeInto(LibraryManager.library, {
},
emscripten_set_canvas_size: function(width, height) {
- Module['canvas'].width = width;
- Module['canvas'].height = height;
+ Browser.setCanvasSize(width, height);
},
emscripten_get_now: function() {
diff --git a/src/library_glut.js b/src/library_glut.js
index d33f8436..b146cf47 100644
--- a/src/library_glut.js
+++ b/src/library_glut.js
@@ -237,8 +237,7 @@ var LibraryGLUT = {
document.removeEventListener('mozfullscreenchange', GLUT.onFullScreenEventChange, true);
document.removeEventListener('webkitfullscreenchange', GLUT.onFullScreenEventChange, true);
}
- Module['canvas'].width = width;
- Module['canvas'].height = height;
+ Browser.setCanvasSize(width, height);
/* Can't call _glutReshapeWindow as that requests cancelling fullscreen. */
if (GLUT.reshapeFunc) {
// console.log("GLUT.reshapeFunc (from FS): " + width + ", " + height);
@@ -274,8 +273,8 @@ var LibraryGLUT = {
},
glutInitWindowSize: function(width, height) {
- Module['canvas'].width = GLUT.initWindowWidth = width;
- Module['canvas'].height = GLUT.initWindowHeight = height;
+ Browser.setCanvasSize( GLUT.initWindowWidth = width,
+ GLUT.initWindowHeight = height );
},
glutInitWindowPosition: function(x, y) {
@@ -371,8 +370,7 @@ var LibraryGLUT = {
glutReshapeWindow: function(width, height) {
GLUT.cancelFullScreen();
// console.log("glutReshapeWindow: " + width + ", " + height);
- Module['canvas'].width = width;
- Module['canvas'].height = height;
+ Browser.setCanvasSize(width, height);
if (GLUT.reshapeFunc) {
// console.log("GLUT.reshapeFunc: " + width + ", " + height);
FUNCTION_TABLE[GLUT.reshapeFunc](width, height);
diff --git a/src/library_sdl.js b/src/library_sdl.js
index da1e88af..c056c3f1 100644
--- a/src/library_sdl.js
+++ b/src/library_sdl.js
@@ -659,8 +659,7 @@ var LibrarySDL = {
['mousedown', 'mouseup', 'mousemove', 'DOMMouseScroll', 'mousewheel', 'mouseout'].forEach(function(event) {
Module['canvas'].addEventListener(event, SDL.receiveEvent, true);
});
- Module['canvas'].width = width;
- Module['canvas'].height = height;
+ Browser.setCanvasSize(width, height);
return SDL.screen = SDL.makeSurface(width, height, flags, true, 'screen');
},
diff --git a/src/library_xlib.js b/src/library_xlib.js
index a110c786..7e420400 100644
--- a/src/library_xlib.js
+++ b/src/library_xlib.js
@@ -6,8 +6,7 @@ var LibraryXlib = {
XCreateWindow: function(display, parent, x, y, width, height, border_width, depth, class_, visual, valuemask, attributes) {
// All we can do is set the width and height
- Module['canvas'].width = width;
- Module['canvas'].height = height;
+ Browser.setCanvasSize(width, height);
return 2;
},
diff --git a/src/modules.js b/src/modules.js
index 0f3b483b..cf1b072e 100644
--- a/src/modules.js
+++ b/src/modules.js
@@ -127,6 +127,11 @@ var Debugging = {
this.llvmLineToSourceFile[lineNum] + '"' : '';
},
+ getAssociatedSourceFile: function(lineNum) {
+ if (!this.on) return null;
+ return lineNum in this.llvmLineToSourceLine ? this.llvmLineToSourceFile[lineNum] : null;
+ },
+
getIdentifier: function(lineNum) {
if (!this.on) return null;
if (lineNum === undefined) {
diff --git a/src/settings.js b/src/settings.js
index 76dc25a1..5970737c 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -198,8 +198,12 @@ var INCLUDE_FULL_LIBRARY = 0; // Whether to include the whole library rather tha
// dynamically loading modules that make use of runtime
// library functions that are not used in the main module.
+var SHELL_FILE = 0; // set this to a string to override the shell file used
+
var SHOW_LABELS = 0; // Show labels in the generated code
+var PRINT_SPLIT_FILE_MARKER = 0; // Prints markers in Javascript generation to split the file later on. See emcc --split option.
+
var BUILD_AS_SHARED_LIB = 0; // Whether to build the code as a shared library, which
// must be loaded dynamically using dlopen().
// 0 here means this is not a shared lib: It is a main file.
@@ -1122,5 +1126,9 @@ var C_DEFINES = {'SI_MESGQ': '5',
'AT_FDCWD': '-2',
'SIGTTOU': '22',
'_CS_POSIX_V7_LP64_OFF64_LDFLAGS': '10',
- '_SC_TTY_NAME_MAX': '41'};
+ '_SC_TTY_NAME_MAX': '41',
+ 'AF_INET': '1',
+ 'AF_INET6': '6',
+ 'FIONREAD': '1'
+};