Patch in a different way that hopefully won't fail

This commit is contained in:
Michael Droettboom 2018-07-10 16:24:48 -04:00
parent 4cec2073e5
commit c3a228e6ca
6 changed files with 9348 additions and 669 deletions

View File

@ -11,6 +11,7 @@ emsdk/emsdk:
./emsdk install --build=Release sdk-tag-1.38.4-64bit binaryen-tag-1.38.4-64bit ; \
cd .. ; \
(cat patches/*.patch | patch -p1) ; \
cp files/* emsdk/emscripten/tag-1.38.4/src/ ; \
cd emsdk/binaryen/tag-1.38.4_64bit_binaryen/ ; \
make ; \
cd ../.. ; \

4799
emsdk/files/library.js Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

2510
emsdk/files/preamble.js Normal file

File diff suppressed because it is too large Load Diff

519
emsdk/files/support.js Normal file
View File

@ -0,0 +1,519 @@
// {{PREAMBLE_ADDITIONS}}
var STACK_ALIGN = {{{ STACK_ALIGN }}};
#if ASSERTIONS
// stack management, and other functionality that is provided by the compiled code,
// should not be used before it is ready
stackSave = stackRestore = stackAlloc = setTempRet0 = getTempRet0 = function() {
abort('cannot use the stack before compiled code is ready to run, and has provided stack access');
};
#endif
function staticAlloc(size) {
assert(!staticSealed);
var ret = STATICTOP;
STATICTOP = (STATICTOP + size + 15) & -16;
return ret;
}
function dynamicAlloc(size) {
assert(DYNAMICTOP_PTR);
var ret = HEAP32[DYNAMICTOP_PTR>>2];
var end = (ret + size + 15) & -16;
HEAP32[DYNAMICTOP_PTR>>2] = end;
if (end >= TOTAL_MEMORY) {
var success = enlargeMemory();
if (!success) {
HEAP32[DYNAMICTOP_PTR>>2] = ret;
return 0;
}
}
return ret;
}
{{{ alignMemory }}}
{{{ getNativeTypeSize }}}
function warnOnce(text) {
if (!warnOnce.shown) warnOnce.shown = {};
if (!warnOnce.shown[text]) {
warnOnce.shown[text] = 1;
Module.printErr(text);
}
}
#if RELOCATABLE
var loadedDynamicLibraries = [];
function loadDynamicLibrary(lib) {
var libModule;
#if WASM
var bin;
if (lib.buffer) {
// we were provided the binary, in a typed array
bin = lib;
} else {
// load the binary synchronously
bin = Module['readBinary'](lib);
}
libModule = loadWebAssemblyModule(bin);
#else
var src = Module['read'](lib);
libModule = eval(src)(
alignFunctionTables(),
Module
);
#endif
// add symbols into global namespace TODO: weak linking etc.
for (var sym in libModule) {
if (!Module.hasOwnProperty(sym)) {
Module[sym] = libModule[sym];
}
#if ASSERTIONS == 2
else if (sym[0] === '_') {
var curr = Module[sym], next = libModule[sym];
// don't warn on functions - might be odr, linkonce_odr, etc.
if (!(typeof curr === 'function' && typeof next === 'function')) {
Module.printErr("warning: trying to dynamically load symbol '" + sym + "' (from '" + lib + "') that already exists (duplicate symbol? or weak linking, which isn't supported yet?)"); // + [curr, ' vs ', next]);
}
}
#endif
}
loadedDynamicLibraries.push(libModule);
}
#if WASM
// Loads a side module from binary data
function loadWebAssemblyModule(binary, loadAsync) {
var int32View = new Uint32Array(new Uint8Array(binary.subarray(0, 24)).buffer);
assert(int32View[0] == 0x6d736100, 'need to see wasm magic number'); // \0wasm
// we should see the dylink section right after the magic number and wasm version
assert(binary[8] === 0, 'need the dylink section to be first')
var next = 9;
function getLEB() {
var ret = 0;
var mul = 1;
while (1) {
var byte = binary[next++];
ret += ((byte & 0x7f) * mul);
mul *= 0x80;
if (!(byte & 0x80)) break;
}
return ret;
}
var sectionSize = getLEB();
assert(binary[next] === 6); next++; // size of "dylink" string
assert(binary[next] === 'd'.charCodeAt(0)); next++;
assert(binary[next] === 'y'.charCodeAt(0)); next++;
assert(binary[next] === 'l'.charCodeAt(0)); next++;
assert(binary[next] === 'i'.charCodeAt(0)); next++;
assert(binary[next] === 'n'.charCodeAt(0)); next++;
assert(binary[next] === 'k'.charCodeAt(0)); next++;
var memorySize = getLEB();
var memoryAlign = getLEB();
var tableSize = getLEB();
var tableAlign = getLEB();
// alignments are powers of 2
memoryAlign = Math.pow(2, memoryAlign);
tableAlign = Math.pow(2, tableAlign);
// finalize alignments and verify them
memoryAlign = Math.max(memoryAlign, STACK_ALIGN); // we at least need stack alignment
assert(tableAlign === 1);
// prepare memory
var memoryStart = alignMemory(getMemory(memorySize + memoryAlign), memoryAlign); // TODO: add to cleanups
// The static area consists of explicitly initialized data, followed by zero-initialized data.
// The latter may need zeroing out if the MAIN_MODULE has already used this memory area before
// dlopen'ing the SIDE_MODULE. Since we don't know the size of the explicitly initialized data
// here, we just zero the whole thing, which is suboptimal, but should at least resolve bugs
// from uninitialized memory.
for (var i = memoryStart; i < memoryStart + memorySize; ++i) HEAP8[i] = 0;
// prepare env imports
var env = Module['asmLibraryArg'];
// TODO: use only memoryBase and tableBase, need to update asm.js backend
var table = Module['wasmTable'];
var oldTableSize = table.length;
env['memoryBase'] = env['gb'] = memoryStart;
env['tableBase'] = env['fb'] = oldTableSize;
var originalTable = table;
table.grow(tableSize);
assert(table === originalTable);
// zero-initialize memory and table TODO: in some cases we can tell it is already zero initialized
for (var i = env['memoryBase']; i < env['memoryBase'] + memorySize; i++) {
HEAP8[i] = 0;
}
for (var i = env['tableBase']; i < env['tableBase'] + tableSize; i++) {
table.set(i, null);
}
// copy currently exported symbols so the new module can import them
for (var x in Module) {
if (!(x in env)) {
env[x] = Module[x];
}
}
var info = {
global: {
'NaN': NaN,
'Infinity': Infinity,
},
'global.Math': Math,
env: env
};
#if ASSERTIONS
var oldTable = [];
for (var i = 0; i < oldTableSize; i++) {
oldTable.push(table.get(i));
}
#endif
function postInstantiation(instance) {
var exports = {};
#if ASSERTIONS
// the table should be unchanged
assert(table === originalTable);
assert(table === Module['wasmTable']);
if (instance.exports['table']) {
assert(table === instance.exports['table']);
}
// the old part of the table should be unchanged
for (var i = 0; i < oldTableSize; i++) {
assert(table.get(i) === oldTable[i], 'old table entries must remain the same');
}
// verify that the new table region was filled in
for (var i = 0; i < tableSize; i++) {
assert(table.get(oldTableSize + i) !== undefined, 'table entry was not filled in');
}
#endif
for (var e in instance.exports) {
var value = instance.exports[e];
if (typeof value === 'object') {
// a breaking change in the wasm spec, globals are now objects
// https://github.com/WebAssembly/mutable-global/issues/1
value = value.value;
}
if (typeof value === 'number') {
// relocate it - modules export the absolute value, they can't relocate before they export
#if EMULATED_FUNCTION_POINTERS
// it may be a function pointer
if (e.substr(0, 3) == 'fp$' && typeof instance.exports[e.substr(3)] === 'function') {
value = value + env['tableBase'];
} else {
#endif
value = value + env['memoryBase'];
#if EMULATED_FUNCTION_POINTERS
}
#endif
}
exports[e] = value;
}
// initialize the module
var init = exports['__post_instantiate'];
if (init) {
if (runtimeInitialized) {
init();
} else {
// we aren't ready to run compiled code yet
__ATINIT__.push(init);
}
}
return exports;
}
if (loadAsync) {
return WebAssembly.instantiate(binary, info).then(function(result) {
return postInstantiation(result.instance);
});
} else {
var instance = new WebAssembly.Instance(new WebAssembly.Module(binary), info);
return postInstantiation(instance);
}
}
Module['loadWebAssemblyModule'] = loadWebAssemblyModule;
#endif // WASM
#endif // RELOCATABLE
#if EMULATED_FUNCTION_POINTERS
function getFunctionTables(module) {
if (!module) module = Module;
var tables = {};
for (var t in module) {
if (/^FUNCTION_TABLE_.*/.test(t)) {
var table = module[t];
if (typeof table === 'object') tables[t.substr('FUNCTION_TABLE_'.length)] = table;
}
}
return tables;
}
function alignFunctionTables(module) {
var tables = getFunctionTables(module);
var maxx = 0;
for (var sig in tables) {
maxx = Math.max(maxx, tables[sig].length);
}
assert(maxx >= 0);
for (var sig in tables) {
var table = tables[sig];
while (table.length < maxx) table.push(0);
}
return maxx;
}
#if RELOCATABLE
// register functions from a new module being loaded
function registerFunctions(sigs, newModule) {
sigs.forEach(function(sig) {
if (!Module['FUNCTION_TABLE_' + sig]) {
Module['FUNCTION_TABLE_' + sig] = [];
}
});
var oldMaxx = alignFunctionTables(); // align the new tables we may have just added
var newMaxx = alignFunctionTables(newModule);
var maxx = oldMaxx + newMaxx;
sigs.forEach(function(sig) {
var newTable = newModule['FUNCTION_TABLE_' + sig];
var oldTable = Module['FUNCTION_TABLE_' + sig];
assert(newTable !== oldTable);
assert(oldTable.length === oldMaxx);
for (var i = 0; i < newTable.length; i++) {
oldTable.push(newTable[i]);
}
assert(oldTable.length === maxx);
});
assert(maxx === alignFunctionTables()); // align the ones we didn't touch
}
// export this so side modules can use it
Module['registerFunctions'] = registerFunctions;
#endif // RELOCATABLE
#endif // EMULATED_FUNCTION_POINTERS
#if WASM_BACKEND_WITH_RESERVED_FUNCTION_POINTERS
var jsCallStartIndex = {{{ JSCALL_START_INDEX }}};
var jsCallSigOrder = {{{ JSON.stringify(JSCALL_SIG_ORDER) }}};
var jsCallNumSigs = Object.keys(jsCallSigOrder).length;
var functionPointers = new Array(jsCallNumSigs * {{{ RESERVED_FUNCTION_POINTERS }}});
#else // WASM_BACKEND_WITH_RESERVED_FUNCTION_POINTERS == 0
var jsCallStartIndex = 1;
var functionPointers = new Array({{{ RESERVED_FUNCTION_POINTERS }}});
#endif // WASM_BACKEND_WITH_RESERVED_FUNCTION_POINTERS
// 'sig' parameter is only used on LLVM wasm backend
function addFunction(func, sig) {
#if WASM_BACKEND
assert(typeof sig !== 'undefined',
'Second argument of addFunction should be a wasm function signature ' +
'string');
#endif // WASM_BACKEND
#if ASSERTIONS
if (typeof sig === 'undefined') {
Module.printErr('warning: addFunction(): You should provide a wasm function signature string as a second argument. This is not necessary for asm.js and asm2wasm, but is required for the LLVM wasm backend, so it is recommended for full portability.');
}
#endif // ASSERTIONS
#if EMULATED_FUNCTION_POINTERS == 0
#if WASM_BACKEND_WITH_RESERVED_FUNCTION_POINTERS
var base = jsCallSigOrder[sig] * {{{ RESERVED_FUNCTION_POINTERS }}};
#else // WASM_BACKEND_WITH_RESERVED_FUNCTION_POINTERS == 0
var base = 0;
#endif // WASM_BACKEND_WITH_RESERVED_FUNCTION_POINTERS
for (var i = base; i < base + {{{ RESERVED_FUNCTION_POINTERS }}}; i++) {
if (!functionPointers[i]) {
functionPointers[i] = func;
return jsCallStartIndex + i;
}
}
throw 'Finished up all reserved function pointers. Use a higher value for RESERVED_FUNCTION_POINTERS.';
#else
#if WASM
// we can simply append to the wasm table
var table = Module['wasmTable'];
var ret = table.length;
table.grow(1);
table.set(ret, func);
return ret;
#else
alignFunctionTables(); // XXX we should rely on this being an invariant
var tables = getFunctionTables();
var ret = -1;
for (var sig in tables) {
var table = tables[sig];
if (ret < 0) ret = table.length;
else assert(ret === table.length);
table.push(func);
}
return ret;
#endif
#endif
}
function removeFunction(index) {
#if EMULATED_FUNCTION_POINTERS == 0
functionPointers[index-jsCallStartIndex] = null;
#else
alignFunctionTables(); // XXX we should rely on this being an invariant
var tables = getFunctionTables();
for (var sig in tables) {
tables[sig][index] = null;
}
#endif
}
var funcWrappers = {};
function getFuncWrapper(func, sig) {
if (!func) return; // on null pointer, return undefined
assert(sig);
if (!funcWrappers[sig]) {
funcWrappers[sig] = {};
}
var sigCache = funcWrappers[sig];
if (!sigCache[func]) {
// optimize away arguments usage in common cases
if (sig.length === 1) {
sigCache[func] = function dynCall_wrapper() {
return dynCall(sig, func);
};
} else if (sig.length === 2) {
sigCache[func] = function dynCall_wrapper(arg) {
return dynCall(sig, func, [arg]);
};
} else {
// general case
sigCache[func] = function dynCall_wrapper() {
return dynCall(sig, func, Array.prototype.slice.call(arguments));
};
}
}
return sigCache[func];
}
#if RUNTIME_DEBUG
var runtimeDebug = true; // Switch to false at runtime to disable logging at the right times
var printObjectList = [];
function prettyPrint(arg) {
if (typeof arg == 'undefined') return '!UNDEFINED!';
if (typeof arg == 'boolean') arg = arg + 0;
if (!arg) return arg;
var index = printObjectList.indexOf(arg);
if (index >= 0) return '<' + arg + '|' + index + '>';
if (arg.toString() == '[object HTMLImageElement]') {
return arg + '\n\n';
}
if (arg.byteLength) {
return '{' + Array.prototype.slice.call(arg, 0, Math.min(arg.length, 400)) + '}'; // Useful for correct arrays, less so for compiled arrays, see the code below for that
var buf = new ArrayBuffer(32);
var i8buf = new Int8Array(buf);
var i16buf = new Int16Array(buf);
var f32buf = new Float32Array(buf);
switch(arg.toString()) {
case '[object Uint8Array]':
i8buf.set(arg.subarray(0, 32));
break;
case '[object Float32Array]':
f32buf.set(arg.subarray(0, 5));
break;
case '[object Uint16Array]':
i16buf.set(arg.subarray(0, 16));
break;
default:
alert('unknown array for debugging: ' + arg);
throw 'see alert';
}
var ret = '{' + arg.byteLength + ':\n';
var arr = Array.prototype.slice.call(i8buf);
ret += 'i8:' + arr.toString().replace(/,/g, ',') + '\n';
arr = Array.prototype.slice.call(f32buf, 0, 8);
ret += 'f32:' + arr.toString().replace(/,/g, ',') + '}';
return ret;
}
if (typeof arg == 'object') {
printObjectList.push(arg);
return '<' + arg + '|' + (printObjectList.length-1) + '>';
}
if (typeof arg == 'number') {
if (arg > 0) return '0x' + arg.toString(16) + ' (' + arg + ')';
}
return arg;
}
#endif
function makeBigInt(low, high, unsigned) {
return unsigned ? ((+((low>>>0)))+((+((high>>>0)))*4294967296.0)) : ((+((low>>>0)))+((+((high|0)))*4294967296.0));
}
function dynCall(sig, ptr, args) {
if (args && args.length) {
#if ASSERTIONS
assert(args.length == sig.length-1);
#endif
#if ASSERTIONS
assert(('dynCall_' + sig) in Module, 'bad function pointer type - no table for sig \'' + sig + '\'');
#endif
return Module['dynCall_' + sig].apply(null, [ptr].concat(args));
} else {
#if ASSERTIONS
assert(sig.length == 1);
#endif
#if ASSERTIONS
assert(('dynCall_' + sig) in Module, 'bad function pointer type - no table for sig \'' + sig + '\'');
#endif
return Module['dynCall_' + sig].call(null, ptr);
}
}
#if RELOCATABLE
// tempRet0 is normally handled in the module. but in relocatable code,
// we need to share a single one among all the modules, so they all call
// out.
var tempRet0 = 0;
var setTempRet0 = function(value) {
tempRet0 = value;
}
var getTempRet0 = function() {
return tempRet0;
}
#endif // RELOCATABLE
#if RETAIN_COMPILER_SETTINGS
var compilerSettings = {{{ JSON.stringify(makeRetainedCompilerSettings()) }}} ;
function getCompilerSetting(name) {
if (!(name in compilerSettings)) return 'invalid compiler setting: ' + name;
return compilerSettings[name];
}
#else // RETAIN_COMPILER_SETTINGS
#if ASSERTIONS
function getCompilerSetting(name) {
throw 'You must build with -s RETAIN_COMPILER_SETTINGS=1 for getCompilerSetting or emscripten_get_compiler_setting to work';
}
#endif // ASSERTIONS
#endif // RETAIN_COMPILER_SETTINGS
var Runtime = {
// FIXME backwards compatibility layer for ports. Support some Runtime.*
// for now, fix it there, then remove it from here. That way we
// can minimize any period of breakage.
dynCall: dynCall, // for SDL2 port
#if ASSERTIONS
// helpful errors
getTempRet0: function() { abort('getTempRet0() is now a top-level function, after removing the Runtime object. Remove "Runtime."') },
staticAlloc: function() { abort('staticAlloc() is now a top-level function, after removing the Runtime object. Remove "Runtime."') },
stackAlloc: function() { abort('stackAlloc() is now a top-level function, after removing the Runtime object. Remove "Runtime."') },
#endif
};
// The address globals begin at. Very low in memory, for code size and optimization opportunities.
// Above 0 is static memory, starting with globals.
// Then the stack.
// Then 'dynamic' memory for sbrk.
var GLOBAL_BASE = {{{ GLOBAL_BASE }}};
#if RELOCATABLE
GLOBAL_BASE = alignMemory(GLOBAL_BASE, {{{ MAX_GLOBAL_ALIGN || 1 }}});
#endif

View File

@ -1,669 +0,0 @@
diff --git a/emsdk/emscripten/tag-1.38.4/src/library.js b/emsdk/emscripten/tag-1.38.4/src/library.js
index 5fc87ab16..82ebcfd61 100644
--- a/emsdk/emscripten/tag-1.38.4/src/library.js
+++ b/emsdk/emscripten/tag-1.38.4/src/library.js
@@ -1012,7 +1012,7 @@ LibraryManager.library = {
llvm_va_copy: function(ppdest, ppsrc) {
// copy the list start
{{{ makeCopyValues('ppdest', 'ppsrc', Runtime.QUANTUM_SIZE, 'null', null, 1) }}};
-
+
// copy the list's current offset (will be advanced with each call to va_arg)
{{{ makeCopyValues('(ppdest+'+Runtime.QUANTUM_SIZE+')', '(ppsrc+'+Runtime.QUANTUM_SIZE+')', Runtime.QUANTUM_SIZE, 'null', null, 1) }}};
},
@@ -1755,39 +1755,44 @@ LibraryManager.library = {
return handle;
}
+ var lib_module;
if (filename === '__self__') {
var handle = -1;
- var lib_module = Module;
+ lib_module = Module;
} else {
- var target = FS.findObject(filename);
- if (!target || target.isFolder || target.isDevice) {
- DLFCN.errorMsg = 'Could not find dynamic lib: ' + filename;
- return 0;
- }
- FS.forceLoadFile(target);
+ if (Module['preloadedWasm'] !== undefined &&
+ Module['preloadedWasm'][filename] !== undefined) {
+ lib_module = Module['preloadedWasm'][filename];
+ } else {
+ var target = FS.findObject(filename);
+ if (!target || target.isFolder || target.isDevice) {
+ DLFCN.errorMsg = 'Could not find dynamic lib: ' + filename;
+ return 0;
+ }
+ FS.forceLoadFile(target);
- var lib_module;
- try {
+ try {
#if WASM
- // the shared library is a shared wasm library (see tools/shared.py WebAssembly.make_shared_library)
- var lib_data = FS.readFile(filename, { encoding: 'binary' });
- if (!(lib_data instanceof Uint8Array)) lib_data = new Uint8Array(lib_data);
- //Module.printErr('libfile ' + filename + ' size: ' + lib_data.length);
- lib_module = loadWebAssemblyModule(lib_data);
+ // the shared library is a shared wasm library (see tools/shared.py WebAssembly.make_shared_library)
+ var lib_data = FS.readFile(filename, { encoding: 'binary' });
+ if (!(lib_data instanceof Uint8Array)) lib_data = new Uint8Array(lib_data);
+ //Module.printErr('libfile ' + filename + ' size: ' + lib_data.length);
+ lib_module = loadWebAssemblyModule(lib_data);
#else
- // the shared library is a JS file, which we eval
- var lib_data = FS.readFile(filename, { encoding: 'utf8' });
- lib_module = eval(lib_data)(
- alignFunctionTables(),
- Module
- );
+ // the shared library is a JS file, which we eval
+ var lib_data = FS.readFile(filename, { encoding: 'utf8' });
+ lib_module = eval(lib_data)(
+ alignFunctionTables(),
+ Module
+ );
#endif
- } catch (e) {
+ } catch (e) {
#if ASSERTIONS
- Module.printErr('Error in loading dynamic library: ' + e);
+ Module.printErr('Error in loading dynamic library: ' + e);
#endif
- DLFCN.errorMsg = 'Could not evaluate dynamic lib: ' + filename + '\n' + e;
- return 0;
+ DLFCN.errorMsg = 'Could not evaluate dynamic lib: ' + filename + '\n' + e;
+ return 0;
+ }
}
// Not all browsers support Object.keys().
@@ -2224,7 +2229,7 @@ LibraryManager.library = {
newDate.setFullYear(newDate.getFullYear()+1);
}
} else {
- // we stay in current month
+ // we stay in current month
newDate.setDate(newDate.getDate()+days);
return newDate;
}
@@ -2336,7 +2341,7 @@ LibraryManager.library = {
} else {
return thisDate.getFullYear();
}
- } else {
+ } else {
return thisDate.getFullYear()-1;
}
};
@@ -2365,16 +2370,16 @@ LibraryManager.library = {
return leadingSomething(date.tm_mday, 2, ' ');
},
'%g': function(date) {
- // %g, %G, and %V give values according to the ISO 8601:2000 standard week-based year.
- // In this system, weeks begin on a Monday and week 1 of the year is the week that includes
- // January 4th, which is also the week that includes the first Thursday of the year, and
- // is also the first week that contains at least four days in the year.
- // If the first Monday of January is the 2nd, 3rd, or 4th, the preceding days are part of
- // the last week of the preceding year; thus, for Saturday 2nd January 1999,
- // %G is replaced by 1998 and %V is replaced by 53. If December 29th, 30th,
- // or 31st is a Monday, it and any following days are part of week 1 of the following year.
+ // %g, %G, and %V give values according to the ISO 8601:2000 standard week-based year.
+ // In this system, weeks begin on a Monday and week 1 of the year is the week that includes
+ // January 4th, which is also the week that includes the first Thursday of the year, and
+ // is also the first week that contains at least four days in the year.
+ // If the first Monday of January is the 2nd, 3rd, or 4th, the preceding days are part of
+ // the last week of the preceding year; thus, for Saturday 2nd January 1999,
+ // %G is replaced by 1998 and %V is replaced by 53. If December 29th, 30th,
+ // or 31st is a Monday, it and any following days are part of week 1 of the following year.
// Thus, for Tuesday 30th December 1997, %G is replaced by 1998 and %V is replaced by 01.
-
+
return getWeekBasedYear(date).toString().substring(2);
},
'%G': function(date) {
@@ -2420,13 +2425,13 @@ LibraryManager.library = {
return day.getDay() || 7;
},
'%U': function(date) {
- // Replaced by the week number of the year as a decimal number [00,53].
- // The first Sunday of January is the first day of week 1;
+ // Replaced by the week number of the year as a decimal number [00,53].
+ // The first Sunday of January is the first day of week 1;
// days in the new year before this are in week 0. [ tm_year, tm_wday, tm_yday]
var janFirst = new Date(date.tm_year+1900, 0, 1);
var firstSunday = janFirst.getDay() === 0 ? janFirst : __addDays(janFirst, 7-janFirst.getDay());
var endDate = new Date(date.tm_year+1900, date.tm_mon, date.tm_mday);
-
+
// is target date after the first Sunday?
if (compareByDay(firstSunday, endDate) < 0) {
// calculate difference in days between first Sunday and endDate
@@ -2439,10 +2444,10 @@ LibraryManager.library = {
return compareByDay(firstSunday, janFirst) === 0 ? '01': '00';
},
'%V': function(date) {
- // Replaced by the week number of the year (Monday as the first day of the week)
- // as a decimal number [01,53]. If the week containing 1 January has four
- // or more days in the new year, then it is considered week 1.
- // Otherwise, it is the last week of the previous year, and the next week is week 1.
+ // Replaced by the week number of the year (Monday as the first day of the week)
+ // as a decimal number [01,53]. If the week containing 1 January has four
+ // or more days in the new year, then it is considered week 1.
+ // Otherwise, it is the last week of the previous year, and the next week is week 1.
// Both January 4th and the first Thursday of January are always in week 1. [ tm_year, tm_wday, tm_yday]
var janFourthThisYear = new Date(date.tm_year+1900, 0, 4);
var janFourthNextYear = new Date(date.tm_year+1901, 0, 4);
@@ -2455,7 +2460,7 @@ LibraryManager.library = {
if (compareByDay(endDate, firstWeekStartThisYear) < 0) {
// if given date is before this years first week, then it belongs to the 53rd week of last year
return '53';
- }
+ }
if (compareByDay(firstWeekStartNextYear, endDate) <= 0) {
// if given date is after next years first week, then it belongs to the 01th week of next year
@@ -2478,8 +2483,8 @@ LibraryManager.library = {
return day.getDay();
},
'%W': function(date) {
- // Replaced by the week number of the year as a decimal number [00,53].
- // The first Monday of January is the first day of week 1;
+ // Replaced by the week number of the year as a decimal number [00,53].
+ // The first Monday of January is the first day of week 1;
// days in the new year before this are in week 0. [ tm_year, tm_wday, tm_yday]
var janFirst = new Date(date.tm_year, 0, 1);
var firstMonday = janFirst.getDay() === 1 ? janFirst : __addDays(janFirst, janFirst.getDay() === 0 ? 1 : 7-janFirst.getDay()+1);
@@ -2528,7 +2533,7 @@ LibraryManager.library = {
var bytes = intArrayFromString(pattern, false);
if (bytes.length > maxsize) {
return 0;
- }
+ }
writeArrayToMemory(bytes, s);
return bytes.length-1;
@@ -2569,7 +2574,7 @@ LibraryManager.library = {
for (var matcher in EQUIVALENT_MATCHERS) {
pattern = pattern.replace(matcher, EQUIVALENT_MATCHERS[matcher]);
}
-
+
// TODO: take care of locale
var DATE_PATTERNS = {
@@ -2599,7 +2604,7 @@ LibraryManager.library = {
var DAY_NUMBERS_MON_FIRST = {MON: 0, TUE: 1, WED: 2, THU: 3, FRI: 4, SAT: 5, SUN: 6};
for (var datePattern in DATE_PATTERNS) {
- pattern = pattern.replace(datePattern, '('+datePattern+DATE_PATTERNS[datePattern]+')');
+ pattern = pattern.replace(datePattern, '('+datePattern+DATE_PATTERNS[datePattern]+')');
}
// take care of capturing groups
@@ -2687,7 +2692,7 @@ LibraryManager.library = {
} else if ((value=getMatch('b'))) {
// parse from month name
date.month = MONTH_NUMBERS[value.substring(0,3).toUpperCase()] || 0;
- // TODO: derive month from day in year+year, week number+day of week+year
+ // TODO: derive month from day in year+year, week number+day of week+year
}
// day
@@ -2709,12 +2714,12 @@ LibraryManager.library = {
var weekDay = value.substring(0,3).toUpperCase();
if ((value=getMatch('U'))) {
// ... and week number (Sunday being first day of week)
- // Week number of the year (Sunday as the first day of the week) as a decimal number [00,53].
+ // Week number of the year (Sunday as the first day of the week) as a decimal number [00,53].
// All days in a new year preceding the first Sunday are considered to be in week 0.
var weekDayNumber = DAY_NUMBERS_SUN_FIRST[weekDay];
var weekNumber = parseInt(value);
- // January 1st
+ // January 1st
var janFirst = new Date(date.year, 0, 1);
var endDate;
if (janFirst.getDay() === 0) {
@@ -2728,12 +2733,12 @@ LibraryManager.library = {
date.month = endDate.getMonth();
} else if ((value=getMatch('W'))) {
// ... and week number (Monday being first day of week)
- // Week number of the year (Monday as the first day of the week) as a decimal number [00,53].
+ // Week number of the year (Monday as the first day of the week) as a decimal number [00,53].
// All days in a new year preceding the first Monday are considered to be in week 0.
var weekDayNumber = DAY_NUMBERS_MON_FIRST[weekDay];
var weekNumber = parseInt(value);
- // January 1st
+ // January 1st
var janFirst = new Date(date.year, 0, 1);
var endDate;
if (janFirst.getDay()===1) {
@@ -2755,10 +2760,10 @@ LibraryManager.library = {
tm_hour int hours since midnight 0-23
tm_mday int day of the month 1-31
tm_mon int months since January 0-11
- tm_year int years since 1900
+ tm_year int years since 1900
tm_wday int days since Sunday 0-6
tm_yday int days since January 1 0-365
- tm_isdst int Daylight Saving Time flag
+ tm_isdst int Daylight Saving Time flag
*/
var fullDate = new Date(date.year, date.month, date.day, date.hour, date.min, date.sec, 0);
@@ -2775,7 +2780,7 @@ LibraryManager.library = {
// we need to convert the matched sequence into an integer array to take care of UTF-8 characters > 0x7F
// TODO: not sure that intArrayFromString handles all unicode characters correctly
return buf+intArrayFromString(matches[0]).length-1;
- }
+ }
return 0;
},
@@ -2854,7 +2859,7 @@ LibraryManager.library = {
// ==========================================================================
// sys/timeb.h
// ==========================================================================
-
+
ftime: function(p) {
var millis = Date.now();
{{{ makeSetValue('p', C_STRUCTS.timeb.time, '(millis/1000)|0', 'i32') }}};
@@ -3884,7 +3889,7 @@ LibraryManager.library = {
if (val in GAI_ERRNO_MESSAGES) {
if (GAI_ERRNO_MESSAGES[val].length > buflen - 1) {
- msg = 'Message too long'; // EMSGSIZE message. This should never occur given the GAI_ERRNO_MESSAGES above.
+ msg = 'Message too long'; // EMSGSIZE message. This should never occur given the GAI_ERRNO_MESSAGES above.
} else {
msg = GAI_ERRNO_MESSAGES[val];
}
@@ -3958,7 +3963,7 @@ LibraryManager.library = {
// struct protoent *getprotoent(void);
// reads the next entry from the protocols 'database' or return NULL if 'eof'
if (_setprotoent.index === Protocols.list.length) {
- return 0;
+ return 0;
} else {
var result = Protocols.list[_setprotoent.index++];
return result;
@@ -4140,14 +4145,14 @@ LibraryManager.library = {
while (stack_args[1].indexOf('_emscripten_') >= 0)
stack_args = __emscripten_traverse_stack(stack_args[0]);
}
-
+
// Process all lines:
var lines = callstack.split('\n');
callstack = '';
var newFirefoxRe = new RegExp('\\s*(.*?)@(.*?):([0-9]+):([0-9]+)'); // New FF30 with column info: extract components of form ' Object._main@http://server.com:4324:12'
var firefoxRe = new RegExp('\\s*(.*?)@(.*):(.*)(:(.*))?'); // Old FF without column info: extract components of form ' Object._main@http://server.com:4324'
var chromeRe = new RegExp('\\s*at (.*?) \\\((.*):(.*):(.*)\\\)'); // Extract components of form ' at Object._main (http://server.com/file.html:4324:12)'
-
+
for (var l in lines) {
var line = lines[l];
@@ -4201,7 +4206,7 @@ LibraryManager.library = {
}
callstack += (haveSourceMap ? (' = '+jsSymbolName) : (' at '+cSymbolName)) + ' (' + file + ':' + lineno + ':' + column + ')\n';
}
-
+
// If we are still keeping track with the callstack by traversing via 'arguments.callee', print the function parameters as well.
if (flags & 128 /*EM_LOG_FUNC_PARAMS*/ && stack_args[0]) {
if (stack_args[1] == jsSymbolName && stack_args[2].length > 0) {
@@ -4792,4 +4797,3 @@ function autoAddDeps(object, name) {
}
}
}
-
diff --git a/emsdk/emscripten/tag-1.38.4/src/library_browser.js b/emsdk/emscripten/tag-1.38.4/src/library_browser.js
index 36738391e..e2ac2763e 100644
--- a/emsdk/emscripten/tag-1.38.4/src/library_browser.js
+++ b/emsdk/emscripten/tag-1.38.4/src/library_browser.js
@@ -225,6 +225,35 @@ var LibraryBrowser = {
};
Module['preloadPlugins'].push(audioPlugin);
+#if WASM
+#if MAIN_MODULE
+ var wasmPlugin = {};
+ wasmPlugin['asyncWasmLoadPromise'] = new Promise(
+ function(resolve, reject) { return resolve(); });
+ wasmPlugin['canHandle'] = function(name) {
+ return !Module.noWasmDecoding && (name.endsWith('.so') || name.endsWith('.wasm'));
+ };
+ wasmPlugin['handle'] = function(byteArray, name, onload, onerror) {
+ // loadWebAssemblyModule can not load modules out-of-order, so rather
+ // than just running the promises in parallel, this makes a chain of
+ // promises to run in series.
+ this['asyncWasmLoadPromise'] = this['asyncWasmLoadPromise'].then(
+ function() {
+ return loadWebAssemblyModule(byteArray, true);
+ }).then(
+ function(module) {
+ Module['preloadedWasm'][name] = module;
+ onload();
+ },
+ function(err) {
+ console.warn("Couldn't instantiate wasm: " + name + " '" + err + "'");
+ onerror();
+ });
+ };
+ Module['preloadPlugins'].push(wasmPlugin);
+#endif // MAIN_MODULE
+#endif // WASM
+
// Canvas event setup
function pointerLockChange() {
@@ -237,7 +266,7 @@ var LibraryBrowser = {
if (canvas) {
// forced aspect ratio can be enabled by defining 'forcedAspectRatio' on Module
// Module['forcedAspectRatio'] = 4 / 3;
-
+
canvas.requestPointerLock = canvas['requestPointerLock'] ||
canvas['mozRequestPointerLock'] ||
canvas['webkitRequestPointerLock'] ||
@@ -490,7 +519,7 @@ var LibraryBrowser = {
'mp3': 'audio/mpeg'
}[name.substr(name.lastIndexOf('.')+1)];
},
-
+
getUserMedia: function(func) {
if(!window.getUserMedia) {
window.getUserMedia = navigator['getUserMedia'] ||
@@ -524,13 +553,13 @@ var LibraryBrowser = {
getMouseWheelDelta: function(event) {
var delta = 0;
switch (event.type) {
- case 'DOMMouseScroll':
+ case 'DOMMouseScroll':
delta = event.detail;
break;
- case 'mousewheel':
+ case 'mousewheel':
delta = event.wheelDelta;
break;
- case 'wheel':
+ case 'wheel':
delta = event['deltaY'];
break;
default:
@@ -558,7 +587,7 @@ var LibraryBrowser = {
Browser.mouseMovementX = Browser.getMovementX(event);
Browser.mouseMovementY = Browser.getMovementY(event);
}
-
+
// check if SDL is available
if (typeof SDL != "undefined") {
Browser.mouseX = SDL.mouseX + Browser.mouseMovementX;
@@ -568,7 +597,7 @@ var LibraryBrowser = {
// FIXME: ideally this should be clamped against the canvas size and zero
Browser.mouseX += Browser.mouseMovementX;
Browser.mouseY += Browser.mouseMovementY;
- }
+ }
} else {
// Otherwise, calculate the movement based on the changes
// in the coordinates.
@@ -600,7 +629,7 @@ var LibraryBrowser = {
adjustedY = adjustedY * (ch / rect.height);
var coords = { x: adjustedX, y: adjustedY };
-
+
if (event.type === 'touchstart') {
Browser.lastTouches[touch.identifier] = coords;
Browser.touches[touch.identifier] = coords;
@@ -609,7 +638,7 @@ var LibraryBrowser = {
if (!last) last = coords;
Browser.lastTouches[touch.identifier] = last;
Browser.touches[touch.identifier] = coords;
- }
+ }
return;
}
@@ -1127,10 +1156,10 @@ var LibraryBrowser = {
}
console.log('main loop blocker "' + blocker.name + '" took ' + (Date.now() - start) + ' ms'); //, left: ' + Browser.mainLoop.remainingBlockers);
Browser.mainLoop.updateStatus();
-
+
// catches pause/resume main loop from blocker execution
if (thisMainLoopId < Browser.mainLoop.currentlyRunningMainloop) return;
-
+
setTimeout(Browser.mainLoop.runner, 0);
return;
}
@@ -1300,7 +1329,7 @@ var LibraryBrowser = {
emscripten_set_canvas_size: function(width, height) {
Browser.setCanvasSize(width, height);
},
-
+
emscripten_get_canvas_size__proxy: 'sync',
emscripten_get_canvas_size__sig: 'viii',
emscripten_get_canvas_size: function(width, height, isFullscreen) {
@@ -1488,4 +1517,3 @@ function slowLog(label, text) {
}
*/
-
diff --git a/emsdk/emscripten/tag-1.38.4/src/preamble.js b/emsdk/emscripten/tag-1.38.4/src/preamble.js
index a757e8300..c7b1f596f 100644
--- a/emsdk/emscripten/tag-1.38.4/src/preamble.js
+++ b/emsdk/emscripten/tag-1.38.4/src/preamble.js
@@ -1822,6 +1822,11 @@ function removeRunDependency(id) {
Module["preloadedImages"] = {}; // maps url to image data
Module["preloadedAudios"] = {}; // maps url to audio data
+#if WASM
+#if MAIN_MODULE
+Module["preloadedWasm"] = {}; // maps url to wasm instance exports
+#endif // MAIN_MODULE
+#endif // WASM
#if PGO
var PGOMonitor = {
diff --git a/emsdk/emscripten/tag-1.38.4/src/support.js b/emsdk/emscripten/tag-1.38.4/src/support.js
index f6c9842ff..99367db70 100644
--- a/emsdk/emscripten/tag-1.38.4/src/support.js
+++ b/emsdk/emscripten/tag-1.38.4/src/support.js
@@ -86,7 +86,7 @@ function loadDynamicLibrary(lib) {
#if WASM
// Loads a side module from binary data
-function loadWebAssemblyModule(binary) {
+function loadWebAssemblyModule(binary, loadAsync) {
var int32View = new Uint32Array(new Uint8Array(binary.subarray(0, 24)).buffer);
assert(int32View[0] == 0x6d736100, 'need to see wasm magic number'); // \0wasm
// we should see the dylink section right after the magic number and wasm version
@@ -166,59 +166,71 @@ function loadWebAssemblyModule(binary) {
oldTable.push(table.get(i));
}
#endif
- // create a module from the instance
- var instance = new WebAssembly.Instance(new WebAssembly.Module(binary), info);
+
+ function postInstantiation(instance) {
+ var exports = {};
#if ASSERTIONS
- // the table should be unchanged
- assert(table === originalTable);
- assert(table === Module['wasmTable']);
- if (instance.exports['table']) {
- assert(table === instance.exports['table']);
- }
- // the old part of the table should be unchanged
- for (var i = 0; i < oldTableSize; i++) {
- assert(table.get(i) === oldTable[i], 'old table entries must remain the same');
- }
- // verify that the new table region was filled in
- for (var i = 0; i < tableSize; i++) {
- assert(table.get(oldTableSize + i) !== undefined, 'table entry was not filled in');
- }
-#endif
- var exports = {};
- for (var e in instance.exports) {
- var value = instance.exports[e];
- if (typeof value === 'object') {
- // a breaking change in the wasm spec, globals are now objects
- // https://github.com/WebAssembly/mutable-global/issues/1
- value = value.value;
+ // the table should be unchanged
+ assert(table === originalTable);
+ assert(table === Module['wasmTable']);
+ if (instance.exports['table']) {
+ assert(table === instance.exports['table']);
+ }
+ // the old part of the table should be unchanged
+ for (var i = 0; i < oldTableSize; i++) {
+ assert(table.get(i) === oldTable[i], 'old table entries must remain the same');
+ }
+ // verify that the new table region was filled in
+ for (var i = 0; i < tableSize; i++) {
+ assert(table.get(oldTableSize + i) !== undefined, 'table entry was not filled in');
}
- if (typeof value === 'number') {
- // relocate it - modules export the absolute value, they can't relocate before they export
+#endif
+ for (var e in instance.exports) {
+ var value = instance.exports[e];
+ if (typeof value === 'object') {
+ // a breaking change in the wasm spec, globals are now objects
+ // https://github.com/WebAssembly/mutable-global/issues/1
+ value = value.value;
+ }
+ if (typeof value === 'number') {
+ // relocate it - modules export the absolute value, they can't relocate before they export
#if EMULATED_FUNCTION_POINTERS
- // it may be a function pointer
- if (e.substr(0, 3) == 'fp$' && typeof instance.exports[e.substr(3)] === 'function') {
- value = value + env['tableBase'];
- } else {
+ // it may be a function pointer
+ if (e.substr(0, 3) == 'fp$' && typeof instance.exports[e.substr(3)] === 'function') {
+ value = value + env['tableBase'];
+ } else {
#endif
- value = value + env['memoryBase'];
+ value = value + env['memoryBase'];
#if EMULATED_FUNCTION_POINTERS
- }
+ }
#endif
+ }
+ exports[e] = value;
}
- exports[e] = value;
- }
- // initialize the module
- var init = exports['__post_instantiate'];
- if (init) {
- if (runtimeInitialized) {
- init();
- } else {
- // we aren't ready to run compiled code yet
- __ATINIT__.push(init);
+ // initialize the module
+ var init = exports['__post_instantiate'];
+ if (init) {
+ if (runtimeInitialized) {
+ init();
+ } else {
+ // we aren't ready to run compiled code yet
+ __ATINIT__.push(init);
+ }
}
+ return exports;
+ }
+
+ if (loadAsync) {
+ return WebAssembly.instantiate(binary, info).then(function(result) {
+ return postInstantiation(result.instance);
+ });
+ } else {
+ var instance = new WebAssembly.Instance(new WebAssembly.Module(binary), info);
+ return postInstantiation(instance);
}
- return exports;
}
+Module['loadWebAssemblyModule'] = loadWebAssemblyModule;
+
#endif // WASM
#endif // RELOCATABLE
diff --git a/emsdk/emscripten/tag-1.38.4/tests/test_browser.py b/emsdk/emscripten/tag-1.38.4/tests/test_browser.py
index d5f49d04e..c85367f72 100644
--- a/emsdk/emscripten/tag-1.38.4/tests/test_browser.py
+++ b/emsdk/emscripten/tag-1.38.4/tests/test_browser.py
@@ -241,12 +241,12 @@ If manually bisecting:
printf("|%%s|\n", buf);
int result = !strcmp("load me right before", buf);
-
+
f = fopen("%s", "r");
if (f == NULL)
result = 0;
fclose(f);
-
+
f = fopen("%s", "r");
if (f != NULL)
result = 0;
@@ -2273,6 +2273,43 @@ void *getBindBuffer() {
Popen([PYTHON, EMCC, path_from_root('tests', 'browser_module.cpp'), '-o', 'module.js', '-O2', '-s', 'SIDE_MODULE=1', '-s', 'DLOPEN_SUPPORT=1', '-s', 'EXPORTED_FUNCTIONS=["_one", "_two"]']).communicate()
self.btest('browser_main.cpp', args=['-O2', '-s', 'MAIN_MODULE=1', '-s', 'DLOPEN_SUPPORT=1'], expected='8')
+ def test_preload_module(self):
+ expected = 'hello from main\nhello from library'
+ open('library.c', 'w').write(r'''
+ #include <stdio.h>
+ int library_func() {
+ return 42;
+ }
+ ''')
+ run_process([PYTHON, EMCC, 'library.c', '-s', 'SIDE_MODULE=1', '-O2', '-o', 'library.wasm', '-s', 'WASM=1'])
+ main = r'''
+ #include <dlfcn.h>
+ #include <stdio.h>
+ #include <emscripten.h>
+ int main() {
+ EM_ASM(
+ console.log(Object.keys(Module['preloadedWasm']));
+ if (Module['preloadedWasm']['/library.wasm'] === undefined) {
+ throw Error("Side module not preloaded");
+ }
+ );
+ void *lib_handle = dlopen("/library.wasm", 0);
+ if (!lib_handle) {
+ return 1;
+ }
+ typedef int (*voidfunc)();
+ voidfunc x = (voidfunc)dlsym(lib_handle, "library_func");
+ if (!x) return 1;
+ if (x() != 42) return 1;
+ REPORT_RESULT(0);
+ return 0;
+ }
+ '''
+ self.btest(
+ main,
+ args=['-s', 'MAIN_MODULE=1', '--preload-file', '.@/', '-O2', '-s', 'WASM=1', '--use-preload-plugins'],
+ expected='0')
+
def test_mmap_file(self):
open(self.in_dir('data.dat'), 'w').write('data from the file ' + ('.' * 9000))
for extra_args in [[], ['--no-heap-copy']]: