aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/deps_info.json7
-rw-r--r--src/embind/emval.js36
-rw-r--r--src/headlessCanvas.js1
-rw-r--r--src/jsifier.js72
-rw-r--r--src/library.js320
-rw-r--r--src/library_browser.js22
-rw-r--r--src/library_egl.js2
-rw-r--r--src/library_fs.js213
-rw-r--r--src/library_gl.js198
-rw-r--r--src/library_glfw.js8
-rw-r--r--src/library_glut.js2
-rw-r--r--src/library_html5.js19
-rw-r--r--src/library_idbfs.js324
-rw-r--r--src/library_openal.js195
-rw-r--r--src/library_sdl.js160
-rw-r--r--src/parseTools.js4
-rw-r--r--src/postamble.js4
-rw-r--r--src/preamble.js9
-rw-r--r--src/runtime.js4
-rw-r--r--src/settings.js16
-rw-r--r--src/struct_info.json4
21 files changed, 1028 insertions, 592 deletions
diff --git a/src/deps_info.json b/src/deps_info.json
new file mode 100644
index 00000000..b38ffd00
--- /dev/null
+++ b/src/deps_info.json
@@ -0,0 +1,7 @@
+{
+ "uuid_compare": ["memcmp"],
+ "SDL_Init": ["malloc", "free"],
+ "SDL_GL_GetProcAddress": ["emscripten_GetProcAddress"],
+ "eglGetProcAddress": ["emscripten_GetProcAddress"]
+}
+
diff --git a/src/embind/emval.js b/src/embind/emval.js
index 0d075188..039f1d61 100644
--- a/src/embind/emval.js
+++ b/src/embind/emval.js
@@ -3,7 +3,7 @@
/*global new_*/
/*global createNamedFunction*/
/*global readLatin1String, writeStringToMemory*/
-/*global requireRegisteredType, throwBindingError*/
+/*global requireRegisteredType, throwBindingError, runDestructors*/
/*jslint sub:true*/ /* The symbols 'fromWireType' and 'toWireType' must be accessed via array notation to be closure-safe since craftInvokerFunction crafts functions as strings that can't be closured. */
var Module = Module || {};
@@ -79,6 +79,12 @@ function __emval_decref(handle) {
}
}
+function __emval_run_destructors(handle) {
+ var destructors = _emval_handle_array[handle].value;
+ runDestructors(destructors);
+ __emval_decref(handle);
+}
+
function __emval_new_array() {
return __emval_register([]);
}
@@ -199,11 +205,12 @@ function __emval_set_property(handle, key, value) {
_emval_handle_array[handle].value[_emval_handle_array[key].value] = _emval_handle_array[value].value;
}
-function __emval_as(handle, returnType) {
+function __emval_as(handle, returnType, destructorsRef) {
requireHandle(handle);
returnType = requireRegisteredType(returnType, 'emval::as');
var destructors = [];
- // caller owns destructing
+ var rd = __emval_register(destructors);
+ HEAP32[destructorsRef >> 2] = rd;
return returnType['toWireType'](destructors, _emval_handle_array[handle].value);
}
@@ -242,14 +249,20 @@ function lookupTypes(argCount, argTypes, argWireTypes) {
return a;
}
+function allocateDestructors(destructorsRef) {
+ var destructors = [];
+ HEAP32[destructorsRef >> 2] = __emval_register(destructors);
+ return destructors;
+}
+
function __emval_get_method_caller(argCount, argTypes) {
var types = lookupTypes(argCount, argTypes);
var retType = types[0];
var signatureName = retType.name + "_$" + types.slice(1).map(function (t) { return t.name; }).join("_") + "$";
- var args1 = ["addFunction", "createNamedFunction", "requireHandle", "getStringOrSymbol", "_emval_handle_array", "retType"];
- var args2 = [Runtime.addFunction, createNamedFunction, requireHandle, getStringOrSymbol, _emval_handle_array, retType];
+ var args1 = ["addFunction", "createNamedFunction", "requireHandle", "getStringOrSymbol", "_emval_handle_array", "retType", "allocateDestructors"];
+ var args2 = [Runtime.addFunction, createNamedFunction, requireHandle, getStringOrSymbol, _emval_handle_array, retType, allocateDestructors];
var argsList = ""; // 'arg0, arg1, arg2, ... , argN'
var argsListWired = ""; // 'arg0Wired, ..., argNWired'
@@ -261,16 +274,17 @@ function __emval_get_method_caller(argCount, argTypes) {
}
var invokerFnBody =
- "return addFunction(createNamedFunction('" + signatureName + "', function (handle, name" + argsListWired + ") {\n" +
- "requireHandle(handle);\n" +
- "name = getStringOrSymbol(name);\n";
+ "return addFunction(createNamedFunction('" + signatureName + "', function (handle, name, destructorsRef" + argsListWired + ") {\n" +
+ " requireHandle(handle);\n" +
+ " name = getStringOrSymbol(name);\n";
for (var i = 0; i < argCount - 1; ++i) {
- invokerFnBody += "var arg" + i + " = argType" + i + ".fromWireType(arg" + i + "Wired);\n";
+ invokerFnBody += " var arg" + i + " = argType" + i + ".fromWireType(arg" + i + "Wired);\n";
}
invokerFnBody +=
- "var obj = _emval_handle_array[handle].value;\n" +
- "return retType.toWireType(null, obj[name](" + argsList + "));\n" +
+ " var obj = _emval_handle_array[handle].value;\n" +
+ " var rv = obj[name](" + argsList + ");\n" +
+ " return retType.toWireType(allocateDestructors(destructorsRef), rv);\n" +
"}));\n";
args1.push(invokerFnBody);
diff --git a/src/headlessCanvas.js b/src/headlessCanvas.js
index 6b0f9d47..4bd17a7b 100644
--- a/src/headlessCanvas.js
+++ b/src/headlessCanvas.js
@@ -446,6 +446,7 @@ function headlessCanvas() {
case /* GL_MAX_FRAGMENT_UNIFORM_VECTORS */ 0x8DFD: return 4096;
case /* GL_MAX_VARYING_VECTORS */ 0x8DFC: return 32;
case /* GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS */ 0x8B4D: return 32;
+ case /* GL_ARRAY_BUFFER_BINDING */ 0x8894: return 0;
default: console.log('getParameter ' + pname + '?'); return 0;
}
},
diff --git a/src/jsifier.js b/src/jsifier.js
index f4819584..35846d39 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -224,6 +224,7 @@ function JSify(data, functionsOnly) {
// globalVariable
function globalVariableHandler(item) {
+
function needsPostSet(value) {
if (typeof value !== 'string') return false;
// (' is ok, as it is something we can indexize later into a concrete int: ('{{ FI_ ...
@@ -274,7 +275,9 @@ function JSify(data, functionsOnly) {
constant = Runtime.alignMemory(calcAllocatedSize(item.type));
} else {
if (item.external) {
- if (Runtime.isNumberType(item.type) || isPointerType(item.type)) {
+ if (LibraryManager.library[item.ident.slice(1)]) {
+ constant = LibraryManager.library[item.ident.slice(1)];
+ } else if (Runtime.isNumberType(item.type) || isPointerType(item.type)) {
constant = zeros(Runtime.getNativeFieldSize(item.type));
} else {
constant = makeEmptyStruct(item.type);
@@ -282,22 +285,23 @@ function JSify(data, functionsOnly) {
} else {
constant = parseConst(item.value, item.type, item.ident);
}
- assert(typeof constant === 'object');//, [typeof constant, JSON.stringify(constant), item.external]);
// This is a flattened object. We need to find its idents, so they can be assigned to later
- var structTypes = null;
- constant.forEach(function(value, i) {
- if (needsPostSet(value)) { // ident, or expression containing an ident
- if (!structTypes) structTypes = generateStructTypes(item.type);
- itemsDict.GlobalVariablePostSet.push({
- intertype: 'GlobalVariablePostSet',
- JS: makeSetValue(makeGlobalUse(item.ident), i, value, structTypes[i], false, true) + ';' // ignore=true, since e.g. rtti and statics cause lots of safe_heap errors
- });
- constant[i] = '0';
- } else {
- if (typeof value === 'string') constant[i] = deParenCarefully(value);
- }
- });
+ if (typeof constant === 'object') {
+ var structTypes = null;
+ constant.forEach(function(value, i) {
+ if (needsPostSet(value)) { // ident, or expression containing an ident
+ if (!structTypes) structTypes = generateStructTypes(item.type);
+ itemsDict.GlobalVariablePostSet.push({
+ intertype: 'GlobalVariablePostSet',
+ JS: makeSetValue(makeGlobalUse(item.ident), i, value, structTypes[i], false, true) + ';' // ignore=true, since e.g. rtti and statics cause lots of safe_heap errors
+ });
+ constant[i] = '0';
+ } else {
+ if (typeof value === 'string') constant[i] = deParenCarefully(value);
+ }
+ });
+ }
if (item.external) {
// External variables in shared libraries should not be declared as
@@ -312,14 +316,18 @@ function JSify(data, functionsOnly) {
}
// ensure alignment
- var extra = Runtime.alignMemory(constant.length) - constant.length;
- if (item.ident.substr(0, 5) == '__ZTV') extra += Runtime.alignMemory(QUANTUM_SIZE);
- while (extra-- > 0) constant.push(0);
+ if (typeof constant === 'object') {
+ var extra = Runtime.alignMemory(constant.length) - constant.length;
+ if (item.ident.substr(0, 5) == '__ZTV') extra += Runtime.alignMemory(QUANTUM_SIZE);
+ while (extra-- > 0) constant.push(0);
+ }
}
// NOTE: This is the only place that could potentially create static
// allocations in a shared library.
- constant = makePointer(constant, null, allocator, item.type, index);
+ if (typeof constant !== 'string') {
+ constant = makePointer(constant, null, allocator, item.type, index);
+ }
var js = (index !== null ? '' : item.ident + '=') + constant;
if (js) js += ';';
@@ -387,6 +395,13 @@ function JSify(data, functionsOnly) {
// Note: We don't return the dependencies here. Be careful not to end up where this matters
if (('_' + ident) in Functions.implementedFunctions) return '';
+ if (!LibraryManager.library.hasOwnProperty(ident) && !LibraryManager.library.hasOwnProperty(ident + '__inline')) {
+ if (ERROR_ON_UNDEFINED_SYMBOLS) error('unresolved symbol: ' + ident);
+ else if (VERBOSE || (WARN_ON_UNDEFINED_SYMBOLS && !LINKABLE)) warn('unresolved symbol: ' + ident);
+ // emit a stub that will fail at runtime
+ LibraryManager.library[shortident] = new Function("Module['printErr']('missing function: " + shortident + "'); abort(-1);");
+ }
+
var snippet = LibraryManager.library[ident];
var redirectedIdent = null;
var deps = LibraryManager.library[ident + '__deps'] || [];
@@ -448,7 +463,7 @@ function JSify(data, functionsOnly) {
} else {
ident = '_' + ident;
}
- if (VERBOSE) printErr('adding ' + ident + ' and deps ' + deps);
+ if (VERBOSE) printErr('adding ' + ident + ' and deps ' + deps + ' : ' + (snippet + '').substr(0, 40));
var depsText = (deps ? '\n' + deps.map(addFromLibrary).filter(function(x) { return x != '' }).join('\n') : '');
var contentText = isFunction ? snippet : ('var ' + ident + '=' + snippet + ';');
if (ASM_JS) {
@@ -478,7 +493,6 @@ function JSify(data, functionsOnly) {
item.JS = '';
} else {
// If this is not linkable, anything not in the library is definitely missing
- var cancel = false;
if (item.ident in DEAD_FUNCTIONS) {
if (LibraryManager.library[shortident + '__asm']) {
warn('cannot kill asm library function ' + item.ident);
@@ -488,17 +502,7 @@ function JSify(data, functionsOnly) {
delete LibraryManager.library[shortident + '__deps'];
}
}
- if (!LINKABLE && !LibraryManager.library.hasOwnProperty(shortident) && !LibraryManager.library.hasOwnProperty(shortident + '__inline')) {
- if (ERROR_ON_UNDEFINED_SYMBOLS) error('unresolved symbol: ' + shortident);
- else if (VERBOSE || WARN_ON_UNDEFINED_SYMBOLS) warn('unresolved symbol: ' + shortident);
- if (ASM_JS) {
- // emit a stub that will fail during runtime. this allows asm validation to succeed.
- LibraryManager.library[shortident] = new Function("Module['printErr']('missing function: " + shortident + "'); abort(-1);");
- } else {
- cancel = true; // emit nothing, not even var X = undefined;
- }
- }
- item.JS = cancel ? ';' : addFromLibrary(shortident);
+ item.JS = addFromLibrary(shortident);
}
}
@@ -1223,7 +1227,7 @@ function JSify(data, functionsOnly) {
// in an assignment
var disabled = DISABLE_EXCEPTION_CATCHING == 2 && !(item.funcData.ident in EXCEPTION_CATCHING_WHITELIST);
var phiSets = calcPhiSets(item);
- var call_ = makeFunctionCall(item, item.params, item.funcData, item.type, ASM_JS && !disabled, !!item.assignTo || !item.standalone, true);
+ var call_ = makeFunctionCall(item, item.params, item.funcData, item.type, ASM_JS && !disabled, !!item.assignTo || !item.standalone, !disabled);
var ret;
@@ -1844,7 +1848,7 @@ function JSify(data, functionsOnly) {
// rest of the output that we started to print out earlier (see comment on the
// "Final shape that will be created").
if (PRECISE_I64_MATH && Types.preciseI64MathUsed) {
- if (!INCLUDE_FULL_LIBRARY && !SIDE_MODULE) {
+ if (!INCLUDE_FULL_LIBRARY && !SIDE_MODULE && !BUILD_AS_SHARED_LIB) {
// first row are utilities called from generated code, second are needed from fastLong
['i64Add', 'i64Subtract', 'bitshift64Shl', 'bitshift64Lshr', 'bitshift64Ashr',
'llvm_ctlz_i32', 'llvm_cttz_i32'].forEach(function(func) {
diff --git a/src/library.js b/src/library.js
index bca47944..f69b52e5 100644
--- a/src/library.js
+++ b/src/library.js
@@ -52,32 +52,33 @@ LibraryManager.library = {
___setErrNo(ERRNO_CODES.ENOTDIR);
return 0;
}
- var err = _open(dirname, {{{ cDefine('O_RDONLY') }}}, allocate([0, 0, 0, 0], 'i32', ALLOC_STACK));
- // open returns 0 on failure, not -1
- return err === -1 ? 0 : err;
+ var fd = _open(dirname, {{{ cDefine('O_RDONLY') }}}, allocate([0, 0, 0, 0], 'i32', ALLOC_STACK));
+ return fd === -1 ? 0 : FS.getPtrForStream(FS.getStream(fd));
},
- closedir__deps: ['$FS', '__setErrNo', '$ERRNO_CODES', 'close'],
+ closedir__deps: ['$FS', '__setErrNo', '$ERRNO_CODES', 'close', 'fileno'],
closedir: function(dirp) {
// int closedir(DIR *dirp);
// http://pubs.opengroup.org/onlinepubs/007908799/xsh/closedir.html
- return _close(dirp);
+ var fd = _fileno(dirp);
+ return _close(fd);
},
telldir__deps: ['$FS', '__setErrNo', '$ERRNO_CODES'],
telldir: function(dirp) {
// long int telldir(DIR *dirp);
// http://pubs.opengroup.org/onlinepubs/007908799/xsh/telldir.html
- var stream = FS.getStream(dirp);
+ var stream = FS.getStreamFromPtr(dirp);
if (!stream || !FS.isDir(stream.node.mode)) {
___setErrNo(ERRNO_CODES.EBADF);
return -1;
}
return stream.position;
},
- seekdir__deps: ['$FS', '__setErrNo', '$ERRNO_CODES', 'lseek'],
+ seekdir__deps: ['$FS', '__setErrNo', '$ERRNO_CODES', 'lseek', 'fileno'],
seekdir: function(dirp, loc) {
// void seekdir(DIR *dirp, long int loc);
// http://pubs.opengroup.org/onlinepubs/007908799/xsh/seekdir.html
- _lseek(dirp, loc, {{{ cDefine('SEEK_SET') }}});
+ var fd = _fileno(dirp);
+ _lseek(fd, loc, {{{ cDefine('SEEK_SET') }}});
},
rewinddir__deps: ['seekdir'],
rewinddir: function(dirp) {
@@ -89,7 +90,7 @@ LibraryManager.library = {
readdir_r: function(dirp, entry, result) {
// int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);
// http://pubs.opengroup.org/onlinepubs/007908799/xsh/readdir_r.html
- var stream = FS.getStream(dirp);
+ var stream = FS.getStreamFromPtr(dirp);
if (!stream) {
return ___setErrNo(ERRNO_CODES.EBADF);
}
@@ -134,7 +135,7 @@ LibraryManager.library = {
readdir: function(dirp) {
// struct dirent *readdir(DIR *dirp);
// http://pubs.opengroup.org/onlinepubs/007908799/xsh/readdir_r.html
- var stream = FS.getStream(dirp);
+ var stream = FS.getStreamFromPtr(dirp);
if (!stream) {
___setErrNo(ERRNO_CODES.EBADF);
return 0;
@@ -1641,6 +1642,7 @@ LibraryManager.library = {
for (var i = 0; i < maxx; i++) {
next = get();
{{{ makeSetValue('argPtr++', 0, 'next', 'i8') }}};
+ if (next === 0) return i > 0 ? fields : fields-1; // we failed to read the full length of this field
}
formatIndex += nextC - formatIndex + 1;
continue;
@@ -2289,19 +2291,20 @@ LibraryManager.library = {
clearerr: function(stream) {
// void clearerr(FILE *stream);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/clearerr.html
- stream = FS.getStream(stream);
+ stream = FS.getStreamFromPtr(stream);
if (!stream) {
return;
}
stream.eof = false;
stream.error = false;
},
- fclose__deps: ['close', 'fsync'],
+ fclose__deps: ['close', 'fsync', 'fileno'],
fclose: function(stream) {
// int fclose(FILE *stream);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/fclose.html
- _fsync(stream);
- return _close(stream);
+ var fd = _fileno(stream);
+ _fsync(fd);
+ return _close(fd);
},
fdopen__deps: ['$FS', '__setErrNo', '$ERRNO_CODES'],
fdopen: function(fildes, mode) {
@@ -2322,21 +2325,21 @@ LibraryManager.library = {
} else {
stream.error = false;
stream.eof = false;
- return fildes;
+ return FS.getPtrForStream(stream);
}
},
feof__deps: ['$FS'],
feof: function(stream) {
// int feof(FILE *stream);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/feof.html
- stream = FS.getStream(stream);
+ stream = FS.getStreamFromPtr(stream);
return Number(stream && stream.eof);
},
ferror__deps: ['$FS'],
ferror: function(stream) {
// int ferror(FILE *stream);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/ferror.html
- stream = FS.getStream(stream);
+ stream = FS.getStreamFromPtr(stream);
return Number(stream && stream.error);
},
fflush__deps: ['$FS', '__setErrNo', '$ERRNO_CODES'],
@@ -2350,7 +2353,7 @@ LibraryManager.library = {
fgetc: function(stream) {
// int fgetc(FILE *stream);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/fgetc.html
- var streamObj = FS.getStream(stream);
+ var streamObj = FS.getStreamFromPtr(stream);
if (!streamObj) return -1;
if (streamObj.eof || streamObj.error) return -1;
var ret = _fread(_fgetc.ret, 1, 1, stream);
@@ -2375,7 +2378,7 @@ LibraryManager.library = {
fgetpos: function(stream, pos) {
// int fgetpos(FILE *restrict stream, fpos_t *restrict pos);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/fgetpos.html
- stream = FS.getStream(stream);
+ stream = FS.getStreamFromPtr(stream);
if (!stream) {
___setErrNo(ERRNO_CODES.EBADF);
return -1;
@@ -2393,7 +2396,7 @@ LibraryManager.library = {
fgets: function(s, n, stream) {
// char *fgets(char *restrict s, int n, FILE *restrict stream);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/fgets.html
- var streamObj = FS.getStream(stream);
+ var streamObj = FS.getStreamFromPtr(stream);
if (!streamObj) return 0;
if (streamObj.error || streamObj.eof) return 0;
var byte_;
@@ -2417,8 +2420,7 @@ LibraryManager.library = {
fileno: function(stream) {
// int fileno(FILE *stream);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/fileno.html
- // We use file descriptor numbers and FILE* streams interchangeably.
- return stream;
+ return FS.getStreamFromPtr(stream).fd;
},
ftrylockfile: function() {
// int ftrylockfile(FILE *file);
@@ -2460,19 +2462,20 @@ LibraryManager.library = {
___setErrNo(ERRNO_CODES.EINVAL);
return 0;
}
- var ret = _open(filename, flags, allocate([0x1FF, 0, 0, 0], 'i32', ALLOC_STACK)); // All creation permissions.
- return (ret == -1) ? 0 : ret;
+ var fd = _open(filename, flags, allocate([0x1FF, 0, 0, 0], 'i32', ALLOC_STACK)); // All creation permissions.
+ return fd === -1 ? 0 : FS.getPtrForStream(FS.getStream(fd));
},
- fputc__deps: ['$FS', 'write'],
+ fputc__deps: ['$FS', 'write', 'fileno'],
fputc__postset: '_fputc.ret = allocate([0], "i8", ALLOC_STATIC);',
fputc: function(c, stream) {
// int fputc(int c, FILE *stream);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/fputc.html
var chr = unSign(c & 0xFF);
{{{ makeSetValue('_fputc.ret', '0', 'chr', 'i8') }}};
- var ret = _write(stream, _fputc.ret, 1);
+ var fd = _fileno(stream);
+ var ret = _write(fd, _fputc.ret, 1);
if (ret == -1) {
- var streamObj = FS.getStream(stream);
+ var streamObj = FS.getStreamFromPtr(stream);
if (streamObj) streamObj.error = true;
return -1;
} else {
@@ -2488,11 +2491,12 @@ LibraryManager.library = {
return _fputc(c, {{{ makeGetValue(makeGlobalUse('_stdout'), '0', 'void*') }}});
},
putchar_unlocked: 'putchar',
- fputs__deps: ['write', 'strlen'],
+ fputs__deps: ['write', 'strlen', 'fileno'],
fputs: function(s, stream) {
// int fputs(const char *restrict s, FILE *restrict stream);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/fputs.html
- return _write(stream, s, _strlen(s));
+ var fd = _fileno(stream);
+ return _write(fd, s, _strlen(s));
},
puts__deps: ['fputs', 'fputc', 'stdout'],
puts: function(s) {
@@ -2517,7 +2521,7 @@ LibraryManager.library = {
return 0;
}
var bytesRead = 0;
- var streamObj = FS.getStream(stream);
+ var streamObj = FS.getStreamFromPtr(stream);
if (!streamObj) {
___setErrNo(ERRNO_CODES.EBADF);
return 0;
@@ -2527,7 +2531,7 @@ LibraryManager.library = {
bytesToRead--;
bytesRead++;
}
- var err = _read(stream, ptr, bytesToRead);
+ var err = _read(streamObj.fd, ptr, bytesToRead);
if (err == -1) {
if (streamObj) streamObj.error = true;
return 0;
@@ -2541,7 +2545,7 @@ LibraryManager.library = {
// FILE *freopen(const char *restrict filename, const char *restrict mode, FILE *restrict stream);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/freopen.html
if (!filename) {
- var streamObj = FS.getStream(stream);
+ var streamObj = FS.getStreamFromPtr(stream);
if (!streamObj) {
___setErrNo(ERRNO_CODES.EBADF);
return 0;
@@ -2553,15 +2557,16 @@ LibraryManager.library = {
_fclose(stream);
return _fopen(filename, mode);
},
- fseek__deps: ['$FS', 'lseek'],
+ fseek__deps: ['$FS', 'lseek', 'fileno'],
fseek: function(stream, offset, whence) {
// int fseek(FILE *stream, long offset, int whence);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/fseek.html
- var ret = _lseek(stream, offset, whence);
+ var fd = _fileno(stream);
+ var ret = _lseek(fd, offset, whence);
if (ret == -1) {
return -1;
}
- stream = FS.getStream(stream);
+ stream = FS.getStreamFromPtr(stream);
stream.eof = false;
return 0;
},
@@ -2570,7 +2575,7 @@ LibraryManager.library = {
fsetpos: function(stream, pos) {
// int fsetpos(FILE *stream, const fpos_t *pos);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/fsetpos.html
- stream = FS.getStream(stream);
+ stream = FS.getStreamFromPtr(stream);
if (!stream) {
___setErrNo(ERRNO_CODES.EBADF);
return -1;
@@ -2589,7 +2594,7 @@ LibraryManager.library = {
ftell: function(stream) {
// long ftell(FILE *stream);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/ftell.html
- stream = FS.getStream(stream);
+ stream = FS.getStreamFromPtr(stream);
if (!stream) {
___setErrNo(ERRNO_CODES.EBADF);
return -1;
@@ -2602,15 +2607,16 @@ LibraryManager.library = {
}
},
ftello: 'ftell',
- fwrite__deps: ['$FS', 'write'],
+ fwrite__deps: ['$FS', 'write', 'fileno'],
fwrite: function(ptr, size, nitems, stream) {
// size_t fwrite(const void *restrict ptr, size_t size, size_t nitems, FILE *restrict stream);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/fwrite.html
var bytesToWrite = nitems * size;
if (bytesToWrite == 0) return 0;
- var bytesWritten = _write(stream, ptr, bytesToWrite);
+ var fd = _fileno(stream);
+ var bytesWritten = _write(fd, ptr, bytesToWrite);
if (bytesWritten == -1) {
- var streamObj = FS.getStream(stream);
+ var streamObj = FS.getStreamFromPtr(stream);
if (streamObj) streamObj.error = true;
return 0;
} else {
@@ -2673,7 +2679,7 @@ LibraryManager.library = {
// void rewind(FILE *stream);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/rewind.html
_fseek(stream, 0, 0); // SEEK_SET.
- var streamObj = FS.getStream(stream);
+ var streamObj = FS.getStreamFromPtr(stream);
if (streamObj) streamObj.error = false;
},
setvbuf: function(stream, buf, type, size) {
@@ -2730,7 +2736,7 @@ LibraryManager.library = {
ungetc: function(c, stream) {
// int ungetc(int c, FILE *stream);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/ungetc.html
- stream = FS.getStream(stream);
+ stream = FS.getStreamFromPtr(stream);
if (!stream) {
return -1;
}
@@ -2755,7 +2761,7 @@ LibraryManager.library = {
fscanf: function(stream, format, varargs) {
// int fscanf(FILE *restrict stream, const char *restrict format, ... );
// http://pubs.opengroup.org/onlinepubs/000095399/functions/scanf.html
- var streamObj = FS.getStream(stream);
+ var streamObj = FS.getStreamFromPtr(stream);
if (!streamObj) {
return -1;
}
@@ -2898,7 +2904,7 @@ LibraryManager.library = {
// ==========================================================================
mmap__deps: ['$FS'],
- mmap: function(start, num, prot, flags, stream, offset) {
+ mmap: function(start, num, prot, flags, fd, offset) {
/* FIXME: Since mmap is normally implemented at the kernel level,
* this implementation simply uses malloc underneath the call to
* mmap.
@@ -2909,13 +2915,13 @@ LibraryManager.library = {
if (!_mmap.mappings) _mmap.mappings = {};
- if (stream == -1) {
+ if (fd == -1) {
ptr = _malloc(num);
if (!ptr) return -1;
_memset(ptr, 0, num);
allocated = true;
} else {
- var info = FS.getStream(stream);
+ var info = FS.getStream(fd);
if (!info) return -1;
try {
var res = FS.mmap(info, HEAPU8, start, num, offset, prot, flags);
@@ -3229,22 +3235,34 @@ LibraryManager.library = {
strtoll: function(str, endptr, base) {
return __parseInt64(str, endptr, base, '-9223372036854775808', '9223372036854775807'); // LLONG_MIN, LLONG_MAX.
},
- strtoll_l: 'strtoll', // no locale support yet
+ strtoll_l__deps: ['strtoll'],
+ strtoll_l: function(str, endptr, base) {
+ return _strtoll(str, endptr, base); // no locale support yet
+ },
strtol__deps: ['_parseInt'],
strtol: function(str, endptr, base) {
return __parseInt(str, endptr, base, -2147483648, 2147483647, 32); // LONG_MIN, LONG_MAX.
},
- strtol_l: 'strtol', // no locale support yet
+ strtol_l__deps: ['strtol'],
+ strtol_l: function(str, endptr, base) {
+ return _strtol(str, endptr, base); // no locale support yet
+ },
strtoul__deps: ['_parseInt'],
strtoul: function(str, endptr, base) {
return __parseInt(str, endptr, base, 0, 4294967295, 32, true); // ULONG_MAX.
},
- strtoul_l: 'strtoul', // no locale support yet
+ strtoul_l__deps: ['strtoul'],
+ strtoul_l: function(str, endptr, base) {
+ return _strtoul(str, endptr, base); // no locale support yet
+ },
strtoull__deps: ['_parseInt64'],
strtoull: function(str, endptr, base) {
return __parseInt64(str, endptr, base, 0, '18446744073709551615', true); // ULONG_MAX.
},
- strtoull_l: 'strtoull', // no locale support yet
+ strtoull_l__deps: ['strtoull'],
+ strtoull_l: function(str, endptr, base) {
+ return _strtoull(str, endptr, base); // no locale support yet
+ },
atoi__deps: ['strtol'],
atoi: function(ptr) {
@@ -3435,13 +3453,25 @@ LibraryManager.library = {
return limit;
},
- // Use browser's Math.random(). We can't set a seed, though.
- srand: function(seed) {}, // XXX ignored
- rand: function() {
- return Math.floor(Math.random()*0x80000000);
+ __rand_seed: 'allocate([0x0273459b, 0, 0, 0], "i32", ALLOC_STATIC)',
+ srand__deps: ['__rand_seed'],
+ srand: function(seed) {
+ {{{ makeSetValue('___rand_seed', 0, 'seed', 'i32') }}}
+ },
+ rand_r__sig: 'ii',
+ rand_r__asm: true,
+ rand_r: function(seedp) {
+ seedp = seedp|0;
+ var val = 0;
+ val = ((Math_imul({{{ makeGetValueAsm('seedp', 0, 'i32') }}}, 31010991)|0) + 0x676e6177 ) & {{{ cDefine('RAND_MAX') }}}; // assumes RAND_MAX is in bit mask form (power of 2 minus 1)
+ {{{ makeSetValueAsm('seedp', 0, 'val', 'i32') }}};
+ return val|0;
},
- rand_r: function(seed) { // XXX ignores the seed
- return Math.floor(Math.random()*0x80000000);
+ rand__sig: 'i',
+ rand__asm: true,
+ rand__deps: ['rand_r', '__rand_seed'],
+ rand: function() {
+ return _rand_r(___rand_seed)|0;
},
drand48: function() {
@@ -3485,11 +3515,18 @@ LibraryManager.library = {
return ret;
},
+ emscripten_memcpy_big: function(dest, src, num) {
+ HEAPU8.set(HEAPU8.subarray(src, src+num), dest);
+ return dest;
+ },
+
memcpy__asm: true,
memcpy__sig: 'iiii',
+ memcpy__deps: ['emscripten_memcpy_big'],
memcpy: function(dest, src, num) {
dest = dest|0; src = src|0; num = num|0;
var ret = 0;
+ if ((num|0) >= 4096) return _emscripten_memcpy_big(dest|0, src|0, num|0)|0;
ret = dest|0;
if ((dest&3) == (src&3)) {
while (dest & 3) {
@@ -3729,76 +3766,6 @@ LibraryManager.library = {
return pdest;
},
- strcmp__deps: ['strncmp'],
- strcmp: function(px, py) {
- return _strncmp(px, py, TOTAL_MEMORY);
- },
- // We always assume ASCII locale.
- strcoll: 'strcmp',
- strcoll_l: 'strcmp',
-
- strcasecmp__asm: true,
- strcasecmp__sig: 'iii',
- strcasecmp__deps: ['strncasecmp'],
- strcasecmp: function(px, py) {
- px = px|0; py = py|0;
- return _strncasecmp(px, py, -1)|0;
- },
-
- strncmp: function(px, py, n) {
- var i = 0;
- while (i < n) {
- var x = {{{ makeGetValue('px', 'i', 'i8', 0, 1) }}};
- var y = {{{ makeGetValue('py', 'i', 'i8', 0, 1) }}};
- if (x == y && x == 0) return 0;
- if (x == 0) return -1;
- if (y == 0) return 1;
- if (x == y) {
- i ++;
- continue;
- } else {
- return x > y ? 1 : -1;
- }
- }
- return 0;
- },
-
- strncasecmp__asm: true,
- strncasecmp__sig: 'iiii',
- strncasecmp__deps: ['tolower'],
- strncasecmp: function(px, py, n) {
- px = px|0; py = py|0; n = n|0;
- var i = 0, x = 0, y = 0;
- while ((i>>>0) < (n>>>0)) {
- x = _tolower({{{ makeGetValueAsm('px', 'i', 'i8', 0, 1) }}})|0;
- y = _tolower({{{ makeGetValueAsm('py', 'i', 'i8', 0, 1) }}})|0;
- if (((x|0) == (y|0)) & ((x|0) == 0)) return 0;
- if ((x|0) == 0) return -1;
- if ((y|0) == 0) return 1;
- if ((x|0) == (y|0)) {
- i = (i + 1)|0;
- continue;
- } else {
- return ((x>>>0) > (y>>>0) ? 1 : -1)|0;
- }
- }
- return 0;
- },
-
- memcmp__asm: true,
- memcmp__sig: 'iiii',
- memcmp: function(p1, p2, num) {
- p1 = p1|0; p2 = p2|0; num = num|0;
- var i = 0, v1 = 0, v2 = 0;
- while ((i|0) < (num|0)) {
- v1 = {{{ makeGetValueAsm('p1', 'i', 'i8', true) }}};
- v2 = {{{ makeGetValueAsm('p2', 'i', 'i8', true) }}};
- if ((v1|0) != (v2|0)) return ((v1|0) > (v2|0) ? 1 : -1)|0;
- i = (i+1)|0;
- }
- return 0;
- },
-
memchr: function(ptr, chr, num) {
chr = unSign(chr);
for (var i = 0; i < num; i++) {
@@ -4000,7 +3967,10 @@ LibraryManager.library = {
}
},
_toupper: 'toupper',
- toupper_l: 'toupper',
+ toupper_l__deps: ['toupper'],
+ toupper_l: function(str, endptr, base) {
+ return _toupper(str, endptr, base); // no locale support yet
+ },
tolower__asm: true,
tolower__sig: 'ii',
@@ -4011,65 +3981,104 @@ LibraryManager.library = {
return (chr - {{{ charCode('A') }}} + {{{ charCode('a') }}})|0;
},
_tolower: 'tolower',
- tolower_l: 'tolower',
+ tolower_l__deps: ['tolower'],
+ tolower_l: function(chr) {
+ return _tolower(chr); // no locale support yet
+ },
// The following functions are defined as macros in glibc.
islower: function(chr) {
return chr >= {{{ charCode('a') }}} &&