2018-07-10 20:24:48 +00:00
// === Preamble library stuff ===
// Documentation for the public APIs defined in this file must be updated in:
// site/source/docs/api_reference/preamble.js.rst
// A prebuilt local version of the documentation is available at:
// site/build/text/docs/api_reference/preamble.js.txt
// You can also build docs locally as HTML or other formats in site/
// An online HTML version (which may be of a different version of Emscripten)
// is up at http://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html
# if BENCHMARK
Module . realPrint = Module . print ;
Module . print = Module . printErr = function ( ) { } ;
# endif
# if SAFE _HEAP
function getSafeHeapType ( bytes , isFloat ) {
switch ( bytes ) {
case 1 : return 'i8' ;
case 2 : return 'i16' ;
case 4 : return isFloat ? 'float' : 'i32' ;
case 8 : return 'double' ;
default : assert ( 0 ) ;
}
}
# if SAFE _HEAP _LOG
var SAFE _HEAP _COUNTER = 0 ;
# endif
function SAFE _HEAP _STORE ( dest , value , bytes , isFloat ) {
# if SAFE _HEAP _LOG
Module . print ( 'SAFE_HEAP store: ' + [ dest , value , bytes , isFloat , SAFE _HEAP _COUNTER ++ ] ) ;
# endif
if ( dest <= 0 ) abort ( 'segmentation fault storing ' + bytes + ' bytes to address ' + dest ) ;
if ( dest % bytes !== 0 ) abort ( 'alignment error storing to address ' + dest + ', which was expected to be aligned to a multiple of ' + bytes ) ;
if ( staticSealed ) {
if ( dest + bytes > HEAP32 [ DYNAMICTOP _PTR >> 2 ] ) abort ( 'segmentation fault, exceeded the top of the available dynamic heap when storing ' + bytes + ' bytes to address ' + dest + '. STATICTOP=' + STATICTOP + ', DYNAMICTOP=' + HEAP32 [ DYNAMICTOP _PTR >> 2 ] ) ;
assert ( DYNAMICTOP _PTR ) ;
assert ( HEAP32 [ DYNAMICTOP _PTR >> 2 ] <= TOTAL _MEMORY ) ;
} else {
if ( dest + bytes > STATICTOP ) abort ( 'segmentation fault, exceeded the top of the available static heap when storing ' + bytes + ' bytes to address ' + dest + '. STATICTOP=' + STATICTOP ) ;
}
setValue ( dest , value , getSafeHeapType ( bytes , isFloat ) , 1 ) ;
}
function SAFE _HEAP _STORE _D ( dest , value , bytes ) {
SAFE _HEAP _STORE ( dest , value , bytes , true ) ;
}
function SAFE _HEAP _LOAD ( dest , bytes , unsigned , isFloat ) {
if ( dest <= 0 ) abort ( 'segmentation fault loading ' + bytes + ' bytes from address ' + dest ) ;
if ( dest % bytes !== 0 ) abort ( 'alignment error loading from address ' + dest + ', which was expected to be aligned to a multiple of ' + bytes ) ;
if ( staticSealed ) {
if ( dest + bytes > HEAP32 [ DYNAMICTOP _PTR >> 2 ] ) abort ( 'segmentation fault, exceeded the top of the available dynamic heap when loading ' + bytes + ' bytes from address ' + dest + '. STATICTOP=' + STATICTOP + ', DYNAMICTOP=' + HEAP32 [ DYNAMICTOP _PTR >> 2 ] ) ;
assert ( DYNAMICTOP _PTR ) ;
assert ( HEAP32 [ DYNAMICTOP _PTR >> 2 ] <= TOTAL _MEMORY ) ;
} else {
if ( dest + bytes > STATICTOP ) abort ( 'segmentation fault, exceeded the top of the available static heap when loading ' + bytes + ' bytes from address ' + dest + '. STATICTOP=' + STATICTOP ) ;
}
var type = getSafeHeapType ( bytes , isFloat ) ;
var ret = getValue ( dest , type , 1 ) ;
if ( unsigned ) ret = unSign ( ret , parseInt ( type . substr ( 1 ) ) , 1 ) ;
# if SAFE _HEAP _LOG
Module . print ( 'SAFE_HEAP load: ' + [ dest , ret , bytes , isFloat , unsigned , SAFE _HEAP _COUNTER ++ ] ) ;
# endif
return ret ;
}
function SAFE _HEAP _LOAD _D ( dest , bytes , unsigned ) {
return SAFE _HEAP _LOAD ( dest , bytes , unsigned , true ) ;
}
function SAFE _FT _MASK ( value , mask ) {
var ret = value & mask ;
if ( ret !== value ) {
abort ( 'Function table mask error: function pointer is ' + value + ' which is masked by ' + mask + ', the likely cause of this is that the function pointer is being called by the wrong type.' ) ;
}
return ret ;
}
function segfault ( ) {
abort ( 'segmentation fault' ) ;
}
function alignfault ( ) {
abort ( 'alignment fault' ) ;
}
function ftfault ( ) {
abort ( 'Function table mask error' ) ;
}
# endif
//========================================
// Runtime essentials
//========================================
var ABORT = 0 ; // whether we are quitting the application. no code should run after this. set in exit() and abort()
var EXITSTATUS = 0 ;
/** @type {function(*, string=)} */
function assert ( condition , text ) {
if ( ! condition ) {
abort ( 'Assertion failed: ' + text ) ;
}
}
var globalScope = this ;
// Returns the C function with a specified identifier (for C++, you need to do manual name mangling)
function getCFunc ( ident ) {
var func = Module [ '_' + ident ] ; // closure exported function
assert ( func , 'Cannot call unknown function ' + ident + ', make sure it is exported' ) ;
return func ;
}
var JSfuncs = {
// Helpers for cwrap -- it can't refer to Runtime directly because it might
// be renamed by closure, instead it calls JSfuncs['stackSave'].body to find
// out what the minified function name is.
'stackSave' : function ( ) {
stackSave ( )
} ,
'stackRestore' : function ( ) {
stackRestore ( )
} ,
// type conversion from js to c
'arrayToC' : function ( arr ) {
var ret = stackAlloc ( arr . length ) ;
writeArrayToMemory ( arr , ret ) ;
return ret ;
} ,
'stringToC' : function ( str ) {
var ret = 0 ;
if ( str !== null && str !== undefined && str !== 0 ) { // null string
// at most 4 bytes per UTF-8 code point, +1 for the trailing '\0'
var len = ( str . length << 2 ) + 1 ;
ret = stackAlloc ( len ) ;
stringToUTF8 ( str , ret , len ) ;
}
return ret ;
}
} ;
// For fast lookup of conversion functions
var toC = {
'string' : JSfuncs [ 'stringToC' ] , 'array' : JSfuncs [ 'arrayToC' ]
} ;
// C calling interface.
function ccall ( ident , returnType , argTypes , args , opts ) {
var func = getCFunc ( ident ) ;
var cArgs = [ ] ;
var stack = 0 ;
# if ASSERTIONS
assert ( returnType !== 'array' , 'Return type should not be "array".' ) ;
# endif
if ( args ) {
for ( var i = 0 ; i < args . length ; i ++ ) {
var converter = toC [ argTypes [ i ] ] ;
if ( converter ) {
if ( stack === 0 ) stack = stackSave ( ) ;
cArgs [ i ] = converter ( args [ i ] ) ;
} else {
cArgs [ i ] = args [ i ] ;
}
}
}
var ret = func . apply ( null , cArgs ) ;
# if ASSERTIONS
# if EMTERPRETIFY _ASYNC
if ( ( ! opts || ! opts . async ) && typeof EmterpreterAsync === 'object' ) {
assert ( ! EmterpreterAsync . state , 'cannot start async op with normal JS calling ccall' ) ;
}
if ( opts && opts . async ) assert ( ! returnType , 'async ccalls cannot return values' ) ;
# endif
# endif
if ( returnType === 'string' ) ret = Pointer _stringify ( ret ) ;
else if ( returnType === 'boolean' ) ret = Boolean ( ret ) ;
if ( stack !== 0 ) {
# if EMTERPRETIFY _ASYNC
if ( opts && opts . async ) {
EmterpreterAsync . asyncFinalizers . push ( function ( ) {
stackRestore ( stack ) ;
} ) ;
return ;
}
# endif
stackRestore ( stack ) ;
}
return ret ;
}
function cwrap ( ident , returnType , argTypes ) {
argTypes = argTypes || [ ] ;
var cfunc = getCFunc ( ident ) ;
// When the function takes numbers and returns a number, we can just return
// the original function
var numericArgs = argTypes . every ( function ( type ) { return type === 'number' } ) ;
var numericRet = returnType !== 'string' ;
if ( numericRet && numericArgs ) {
return cfunc ;
}
return function ( ) {
return ccall ( ident , returnType , argTypes , arguments ) ;
}
}
/** @type {function(number, number, string, boolean=)} */
function setValue ( ptr , value , type , noSafe ) {
type = type || 'i8' ;
if ( type . charAt ( type . length - 1 ) === '*' ) type = 'i32' ; // pointers are 32-bit
# if SAFE _HEAP
if ( noSafe ) {
switch ( type ) {
case 'i1' : { { { makeSetValue ( 'ptr' , '0' , 'value' , 'i1' , undefined , undefined , undefined , '1' ) } } } ; break ;
case 'i8' : { { { makeSetValue ( 'ptr' , '0' , 'value' , 'i8' , undefined , undefined , undefined , '1' ) } } } ; break ;
case 'i16' : { { { makeSetValue ( 'ptr' , '0' , 'value' , 'i16' , undefined , undefined , undefined , '1' ) } } } ; break ;
case 'i32' : { { { makeSetValue ( 'ptr' , '0' , 'value' , 'i32' , undefined , undefined , undefined , '1' ) } } } ; break ;
case 'i64' : { { { makeSetValue ( 'ptr' , '0' , 'value' , 'i64' , undefined , undefined , undefined , '1' ) } } } ; break ;
case 'float' : { { { makeSetValue ( 'ptr' , '0' , 'value' , 'float' , undefined , undefined , undefined , '1' ) } } } ; break ;
case 'double' : { { { makeSetValue ( 'ptr' , '0' , 'value' , 'double' , undefined , undefined , undefined , '1' ) } } } ; break ;
default : abort ( 'invalid type for setValue: ' + type ) ;
}
} else {
# endif
switch ( type ) {
case 'i1' : { { { makeSetValue ( 'ptr' , '0' , 'value' , 'i1' ) } } } ; break ;
case 'i8' : { { { makeSetValue ( 'ptr' , '0' , 'value' , 'i8' ) } } } ; break ;
case 'i16' : { { { makeSetValue ( 'ptr' , '0' , 'value' , 'i16' ) } } } ; break ;
case 'i32' : { { { makeSetValue ( 'ptr' , '0' , 'value' , 'i32' ) } } } ; break ;
case 'i64' : { { { makeSetValue ( 'ptr' , '0' , 'value' , 'i64' ) } } } ; break ;
case 'float' : { { { makeSetValue ( 'ptr' , '0' , 'value' , 'float' ) } } } ; break ;
case 'double' : { { { makeSetValue ( 'ptr' , '0' , 'value' , 'double' ) } } } ; break ;
default : abort ( 'invalid type for setValue: ' + type ) ;
}
# if SAFE _HEAP
}
# endif
}
/** @type {function(number, string, boolean=)} */
function getValue ( ptr , type , noSafe ) {
type = type || 'i8' ;
if ( type . charAt ( type . length - 1 ) === '*' ) type = 'i32' ; // pointers are 32-bit
# if SAFE _HEAP
if ( noSafe ) {
switch ( type ) {
case 'i1' : return { { { makeGetValue ( 'ptr' , '0' , 'i1' , undefined , undefined , undefined , undefined , '1' ) } } } ;
case 'i8' : return { { { makeGetValue ( 'ptr' , '0' , 'i8' , undefined , undefined , undefined , undefined , '1' ) } } } ;
case 'i16' : return { { { makeGetValue ( 'ptr' , '0' , 'i16' , undefined , undefined , undefined , undefined , '1' ) } } } ;
case 'i32' : return { { { makeGetValue ( 'ptr' , '0' , 'i32' , undefined , undefined , undefined , undefined , '1' ) } } } ;
case 'i64' : return { { { makeGetValue ( 'ptr' , '0' , 'i64' , undefined , undefined , undefined , undefined , '1' ) } } } ;
case 'float' : return { { { makeGetValue ( 'ptr' , '0' , 'float' , undefined , undefined , undefined , undefined , '1' ) } } } ;
case 'double' : return { { { makeGetValue ( 'ptr' , '0' , 'double' , undefined , undefined , undefined , undefined , '1' ) } } } ;
default : abort ( 'invalid type for getValue: ' + type ) ;
}
} else {
# endif
switch ( type ) {
case 'i1' : return { { { makeGetValue ( 'ptr' , '0' , 'i1' ) } } } ;
case 'i8' : return { { { makeGetValue ( 'ptr' , '0' , 'i8' ) } } } ;
case 'i16' : return { { { makeGetValue ( 'ptr' , '0' , 'i16' ) } } } ;
case 'i32' : return { { { makeGetValue ( 'ptr' , '0' , 'i32' ) } } } ;
case 'i64' : return { { { makeGetValue ( 'ptr' , '0' , 'i64' ) } } } ;
case 'float' : return { { { makeGetValue ( 'ptr' , '0' , 'float' ) } } } ;
case 'double' : return { { { makeGetValue ( 'ptr' , '0' , 'double' ) } } } ;
default : abort ( 'invalid type for getValue: ' + type ) ;
}
# if SAFE _HEAP
}
# endif
return null ;
}
var ALLOC _NORMAL = 0 ; // Tries to use _malloc()
var ALLOC _STACK = 1 ; // Lives for the duration of the current function call
var ALLOC _STATIC = 2 ; // Cannot be freed
var ALLOC _DYNAMIC = 3 ; // Cannot be freed except through sbrk
var ALLOC _NONE = 4 ; // Do not allocate
// allocate(): This is for internal use. You can use it yourself as well, but the interface
// is a little tricky (see docs right below). The reason is that it is optimized
// for multiple syntaxes to save space in generated code. So you should
// normally not use allocate(), and instead allocate memory using _malloc(),
// initialize it with setValue(), and so forth.
// @slab: An array of data, or a number. If a number, then the size of the block to allocate,
// in *bytes* (note that this is sometimes confusing: the next parameter does not
// affect this!)
// @types: Either an array of types, one for each byte (or 0 if no type at that position),
// or a single type which is used for the entire block. This only matters if there
// is initial data - if @slab is a number, then this does not matter at all and is
// ignored.
// @allocator: How to allocate memory, see ALLOC_*
/** @type {function((TypedArray|Array<number>|number), string, number, number=)} */
function allocate ( slab , types , allocator , ptr ) {
var zeroinit , size ;
if ( typeof slab === 'number' ) {
zeroinit = true ;
size = slab ;
} else {
zeroinit = false ;
size = slab . length ;
}
var singleType = typeof types === 'string' ? types : null ;
var ret ;
if ( allocator == ALLOC _NONE ) {
ret = ptr ;
} else {
ret = [ typeof _malloc === 'function' ? _malloc : staticAlloc , stackAlloc , staticAlloc , dynamicAlloc ] [ allocator === undefined ? ALLOC _STATIC : allocator ] ( Math . max ( size , singleType ? 1 : types . length ) ) ;
}
if ( zeroinit ) {
var stop ;
ptr = ret ;
assert ( ( ret & 3 ) == 0 ) ;
stop = ret + ( size & ~ 3 ) ;
for ( ; ptr < stop ; ptr += 4 ) {
{ { { makeSetValue ( 'ptr' , '0' , '0' , 'i32' , null , true ) } } } ;
}
stop = ret + size ;
while ( ptr < stop ) {
{ { { makeSetValue ( 'ptr++' , '0' , '0' , 'i8' , null , true ) } } } ;
}
return ret ;
}
if ( singleType === 'i8' ) {
if ( slab . subarray || slab . slice ) {
HEAPU8 . set ( /** @type {!Uint8Array} */ ( slab ) , ret ) ;
} else {
HEAPU8 . set ( new Uint8Array ( slab ) , ret ) ;
}
return ret ;
}
var i = 0 , type , typeSize , previousType ;
while ( i < size ) {
var curr = slab [ i ] ;
type = singleType || types [ i ] ;
if ( type === 0 ) {
i ++ ;
continue ;
}
# if ASSERTIONS
assert ( type , 'Must know what type to store in allocate!' ) ;
# endif
if ( type == 'i64' ) type = 'i32' ; // special case: we have one i32 here, and one i32 later
setValue ( ret + i , curr , type ) ;
// no need to look up size unless type changes, so cache it
if ( previousType !== type ) {
typeSize = getNativeTypeSize ( type ) ;
previousType = type ;
}
i += typeSize ;
}
return ret ;
}
// Allocate memory during any stage of startup - static memory early on, dynamic memory later, malloc when ready
function getMemory ( size ) {
if ( ! staticSealed ) return staticAlloc ( size ) ;
if ( ! runtimeInitialized ) return dynamicAlloc ( size ) ;
return _malloc ( size ) ;
}
/** @type {function(number, number=)} */
function Pointer _stringify ( ptr , length ) {
if ( length === 0 || ! ptr ) return '' ;
// Find the length, and check for UTF while doing so
var hasUtf = 0 ;
var t ;
var i = 0 ;
while ( 1 ) {
# if ASSERTIONS
assert ( ptr + i < TOTAL _MEMORY ) ;
# endif
t = { { { makeGetValue ( 'ptr' , 'i' , 'i8' , 0 , 1 ) } } } ;
hasUtf |= t ;
if ( t == 0 && ! length ) break ;
i ++ ;
if ( length && i == length ) break ;
}
if ( ! length ) length = i ;
var ret = '' ;
if ( hasUtf < 128 ) {
var MAX _CHUNK = 1024 ; // split up into chunks, because .apply on a huge string can overflow the stack
var curr ;
while ( length > 0 ) {
curr = String . fromCharCode . apply ( String , HEAPU8 . subarray ( ptr , ptr + Math . min ( length , MAX _CHUNK ) ) ) ;
ret = ret ? ret + curr : curr ;
ptr += MAX _CHUNK ;
length -= MAX _CHUNK ;
}
return ret ;
}
return UTF8ToString ( ptr ) ;
}
// Given a pointer 'ptr' to a null-terminated ASCII-encoded string in the emscripten HEAP, returns
// a copy of that string as a Javascript String object.
function AsciiToString ( ptr ) {
var str = '' ;
while ( 1 ) {
var ch = { { { makeGetValue ( 'ptr++' , 0 , 'i8' ) } } } ;
if ( ! ch ) return str ;
str += String . fromCharCode ( ch ) ;
}
}
// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
// null-terminated and encoded in ASCII form. The copy will require at most str.length+1 bytes of space in the HEAP.
function stringToAscii ( str , outPtr ) {
return writeAsciiToMemory ( str , outPtr , false ) ;
}
// Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the given array that contains uint8 values, returns
// a copy of that string as a Javascript String object.
# if TEXTDECODER
var UTF8Decoder = typeof TextDecoder !== 'undefined' ? new TextDecoder ( 'utf8' ) : undefined ;
# endif
function UTF8ArrayToString ( u8Array , idx ) {
# if TEXTDECODER
var endPtr = idx ;
// TextDecoder needs to know the byte length in advance, it doesn't stop on null terminator by itself.
// Also, use the length info to avoid running tiny strings through TextDecoder, since .subarray() allocates garbage.
while ( u8Array [ endPtr ] ) ++ endPtr ;
if ( endPtr - idx > 16 && u8Array . subarray && UTF8Decoder ) {
return UTF8Decoder . decode ( u8Array . subarray ( idx , endPtr ) ) ;
} else {
# endif
var u0 , u1 , u2 , u3 , u4 , u5 ;
var str = '' ;
while ( 1 ) {
// For UTF8 byte structure, see http://en.wikipedia.org/wiki/UTF-8#Description and https://www.ietf.org/rfc/rfc2279.txt and https://tools.ietf.org/html/rfc3629
u0 = u8Array [ idx ++ ] ;
if ( ! u0 ) return str ;
if ( ! ( u0 & 0x80 ) ) { str += String . fromCharCode ( u0 ) ; continue ; }
u1 = u8Array [ idx ++ ] & 63 ;
if ( ( u0 & 0xE0 ) == 0xC0 ) { str += String . fromCharCode ( ( ( u0 & 31 ) << 6 ) | u1 ) ; continue ; }
u2 = u8Array [ idx ++ ] & 63 ;
if ( ( u0 & 0xF0 ) == 0xE0 ) {
u0 = ( ( u0 & 15 ) << 12 ) | ( u1 << 6 ) | u2 ;
} else {
u3 = u8Array [ idx ++ ] & 63 ;
if ( ( u0 & 0xF8 ) == 0xF0 ) {
u0 = ( ( u0 & 7 ) << 18 ) | ( u1 << 12 ) | ( u2 << 6 ) | u3 ;
} else {
u4 = u8Array [ idx ++ ] & 63 ;
if ( ( u0 & 0xFC ) == 0xF8 ) {
u0 = ( ( u0 & 3 ) << 24 ) | ( u1 << 18 ) | ( u2 << 12 ) | ( u3 << 6 ) | u4 ;
} else {
u5 = u8Array [ idx ++ ] & 63 ;
u0 = ( ( u0 & 1 ) << 30 ) | ( u1 << 24 ) | ( u2 << 18 ) | ( u3 << 12 ) | ( u4 << 6 ) | u5 ;
}
}
}
if ( u0 < 0x10000 ) {
str += String . fromCharCode ( u0 ) ;
} else {
var ch = u0 - 0x10000 ;
str += String . fromCharCode ( 0xD800 | ( ch >> 10 ) , 0xDC00 | ( ch & 0x3FF ) ) ;
}
}
# if TEXTDECODER
}
# endif
}
// Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the emscripten HEAP, returns
// a copy of that string as a Javascript String object.
function UTF8ToString ( ptr ) {
return UTF8ArrayToString ( { { { heapAndOffset ( 'HEAPU8' , 'ptr' ) } } } ) ;
}
// Copies the given Javascript String object 'str' to the given byte array at address 'outIdx',
// encoded in UTF8 form and null-terminated. The copy will require at most str.length*4+1 bytes of space in the HEAP.
// Use the function lengthBytesUTF8 to compute the exact number of bytes (excluding null terminator) that this function will write.
// Parameters:
// str: the Javascript string to copy.
// outU8Array: the array to copy to. Each index in this array is assumed to be one 8-byte element.
// outIdx: The starting offset in the array to begin the copying.
// maxBytesToWrite: The maximum number of bytes this function can write to the array. This count should include the null
// terminator, i.e. if maxBytesToWrite=1, only the null terminator will be written and nothing else.
// maxBytesToWrite=0 does not write any bytes to the output, not even the null terminator.
// Returns the number of bytes written, EXCLUDING the null terminator.
function stringToUTF8Array ( str , outU8Array , outIdx , maxBytesToWrite ) {
if ( ! ( maxBytesToWrite > 0 ) ) // Parameter maxBytesToWrite is not optional. Negative values, 0, null, undefined and false each don't write out any bytes.
return 0 ;
var startIdx = outIdx ;
var endIdx = outIdx + maxBytesToWrite - 1 ; // -1 for string null terminator.
for ( var i = 0 ; i < str . length ; ++ i ) {
// Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! So decode UTF16->UTF32->UTF8.
// See http://unicode.org/faq/utf_bom.html#utf16-3
// For UTF8 byte structure, see http://en.wikipedia.org/wiki/UTF-8#Description and https://www.ietf.org/rfc/rfc2279.txt and https://tools.ietf.org/html/rfc3629
var u = str . charCodeAt ( i ) ; // possibly a lead surrogate
if ( u >= 0xD800 && u <= 0xDFFF ) u = 0x10000 + ( ( u & 0x3FF ) << 10 ) | ( str . charCodeAt ( ++ i ) & 0x3FF ) ;
if ( u <= 0x7F ) {
if ( outIdx >= endIdx ) break ;
outU8Array [ outIdx ++ ] = u ;
} else if ( u <= 0x7FF ) {
if ( outIdx + 1 >= endIdx ) break ;
outU8Array [ outIdx ++ ] = 0xC0 | ( u >> 6 ) ;
outU8Array [ outIdx ++ ] = 0x80 | ( u & 63 ) ;
} else if ( u <= 0xFFFF ) {
if ( outIdx + 2 >= endIdx ) break ;
outU8Array [ outIdx ++ ] = 0xE0 | ( u >> 12 ) ;
outU8Array [ outIdx ++ ] = 0x80 | ( ( u >> 6 ) & 63 ) ;
outU8Array [ outIdx ++ ] = 0x80 | ( u & 63 ) ;
} else if ( u <= 0x1FFFFF ) {
if ( outIdx + 3 >= endIdx ) break ;
outU8Array [ outIdx ++ ] = 0xF0 | ( u >> 18 ) ;
outU8Array [ outIdx ++ ] = 0x80 | ( ( u >> 12 ) & 63 ) ;
outU8Array [ outIdx ++ ] = 0x80 | ( ( u >> 6 ) & 63 ) ;
outU8Array [ outIdx ++ ] = 0x80 | ( u & 63 ) ;
} else if ( u <= 0x3FFFFFF ) {
if ( outIdx + 4 >= endIdx ) break ;
outU8Array [ outIdx ++ ] = 0xF8 | ( u >> 24 ) ;
outU8Array [ outIdx ++ ] = 0x80 | ( ( u >> 18 ) & 63 ) ;
outU8Array [ outIdx ++ ] = 0x80 | ( ( u >> 12 ) & 63 ) ;
outU8Array [ outIdx ++ ] = 0x80 | ( ( u >> 6 ) & 63 ) ;
outU8Array [ outIdx ++ ] = 0x80 | ( u & 63 ) ;
} else {
if ( outIdx + 5 >= endIdx ) break ;
outU8Array [ outIdx ++ ] = 0xFC | ( u >> 30 ) ;
outU8Array [ outIdx ++ ] = 0x80 | ( ( u >> 24 ) & 63 ) ;
outU8Array [ outIdx ++ ] = 0x80 | ( ( u >> 18 ) & 63 ) ;
outU8Array [ outIdx ++ ] = 0x80 | ( ( u >> 12 ) & 63 ) ;
outU8Array [ outIdx ++ ] = 0x80 | ( ( u >> 6 ) & 63 ) ;
outU8Array [ outIdx ++ ] = 0x80 | ( u & 63 ) ;
}
}
// Null-terminate the pointer to the buffer.
outU8Array [ outIdx ] = 0 ;
return outIdx - startIdx ;
}
// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
// null-terminated and encoded in UTF8 form. The copy will require at most str.length*4+1 bytes of space in the HEAP.
// Use the function lengthBytesUTF8 to compute the exact number of bytes (excluding null terminator) that this function will write.
// Returns the number of bytes written, EXCLUDING the null terminator.
function stringToUTF8 ( str , outPtr , maxBytesToWrite ) {
# if ASSERTIONS
assert ( typeof maxBytesToWrite == 'number' , 'stringToUTF8(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!' ) ;
# endif
return stringToUTF8Array ( str , { { { heapAndOffset ( 'HEAPU8' , 'outPtr' ) } } } , maxBytesToWrite ) ;
}
// Returns the number of bytes the given Javascript string takes if encoded as a UTF8 byte array, EXCLUDING the null terminator byte.
function lengthBytesUTF8 ( str ) {
var len = 0 ;
for ( var i = 0 ; i < str . length ; ++ i ) {
// Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! So decode UTF16->UTF32->UTF8.
// See http://unicode.org/faq/utf_bom.html#utf16-3
var u = str . charCodeAt ( i ) ; // possibly a lead surrogate
if ( u >= 0xD800 && u <= 0xDFFF ) u = 0x10000 + ( ( u & 0x3FF ) << 10 ) | ( str . charCodeAt ( ++ i ) & 0x3FF ) ;
if ( u <= 0x7F ) {
++ len ;
} else if ( u <= 0x7FF ) {
len += 2 ;
} else if ( u <= 0xFFFF ) {
len += 3 ;
} else if ( u <= 0x1FFFFF ) {
len += 4 ;
} else if ( u <= 0x3FFFFFF ) {
len += 5 ;
} else {
len += 6 ;
}
}
return len ;
}
// Given a pointer 'ptr' to a null-terminated UTF16LE-encoded string in the emscripten HEAP, returns
// a copy of that string as a Javascript String object.
var UTF16Decoder = typeof TextDecoder !== 'undefined' ? new TextDecoder ( 'utf-16le' ) : undefined ;
function UTF16ToString ( ptr ) {
# if ASSERTIONS
assert ( ptr % 2 == 0 , 'Pointer passed to UTF16ToString must be aligned to two bytes!' ) ;
# endif
# if TEXTDECODER
var endPtr = ptr ;
// TextDecoder needs to know the byte length in advance, it doesn't stop on null terminator by itself.
// Also, use the length info to avoid running tiny strings through TextDecoder, since .subarray() allocates garbage.
var idx = endPtr >> 1 ;
while ( HEAP16 [ idx ] ) ++ idx ;
endPtr = idx << 1 ;
if ( endPtr - ptr > 32 && UTF16Decoder ) {
return UTF16Decoder . decode ( HEAPU8 . subarray ( ptr , endPtr ) ) ;
} else {
# endif
var i = 0 ;
var str = '' ;
while ( 1 ) {
var codeUnit = { { { makeGetValue ( 'ptr' , 'i*2' , 'i16' ) } } } ;
if ( codeUnit == 0 ) return str ;
++ i ;
// fromCharCode constructs a character from a UTF-16 code unit, so we can pass the UTF16 string right through.
str += String . fromCharCode ( codeUnit ) ;
}
# if TEXTDECODER
}
# endif
}
// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
// null-terminated and encoded in UTF16 form. The copy will require at most str.length*4+2 bytes of space in the HEAP.
// Use the function lengthBytesUTF16() to compute the exact number of bytes (excluding null terminator) that this function will write.
// Parameters:
// str: the Javascript string to copy.
// outPtr: Byte address in Emscripten HEAP where to write the string to.
// maxBytesToWrite: The maximum number of bytes this function can write to the array. This count should include the null
// terminator, i.e. if maxBytesToWrite=2, only the null terminator will be written and nothing else.
// maxBytesToWrite<2 does not write any bytes to the output, not even the null terminator.
// Returns the number of bytes written, EXCLUDING the null terminator.
function stringToUTF16 ( str , outPtr , maxBytesToWrite ) {
# if ASSERTIONS
assert ( outPtr % 2 == 0 , 'Pointer passed to stringToUTF16 must be aligned to two bytes!' ) ;
# endif
# if ASSERTIONS
assert ( typeof maxBytesToWrite == 'number' , 'stringToUTF16(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!' ) ;
# endif
// Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed.
if ( maxBytesToWrite === undefined ) {
maxBytesToWrite = 0x7FFFFFFF ;
}
if ( maxBytesToWrite < 2 ) return 0 ;
maxBytesToWrite -= 2 ; // Null terminator.
var startPtr = outPtr ;
var numCharsToWrite = ( maxBytesToWrite < str . length * 2 ) ? ( maxBytesToWrite / 2 ) : str . length ;
for ( var i = 0 ; i < numCharsToWrite ; ++ i ) {
// charCodeAt returns a UTF-16 encoded code unit, so it can be directly written to the HEAP.
var codeUnit = str . charCodeAt ( i ) ; // possibly a lead surrogate
{ { { makeSetValue ( 'outPtr' , 0 , 'codeUnit' , 'i16' ) } } } ;
outPtr += 2 ;
}
// Null-terminate the pointer to the HEAP.
{ { { makeSetValue ( 'outPtr' , 0 , 0 , 'i16' ) } } } ;
return outPtr - startPtr ;
}
// Returns the number of bytes the given Javascript string takes if encoded as a UTF16 byte array, EXCLUDING the null terminator byte.
function lengthBytesUTF16 ( str ) {
return str . length * 2 ;
}
function UTF32ToString ( ptr ) {
# if ASSERTIONS
assert ( ptr % 4 == 0 , 'Pointer passed to UTF32ToString must be aligned to four bytes!' ) ;
# endif
var i = 0 ;
var str = '' ;
while ( 1 ) {
var utf32 = { { { makeGetValue ( 'ptr' , 'i*4' , 'i32' ) } } } ;
if ( utf32 == 0 )
return str ;
++ i ;
// Gotcha: fromCharCode constructs a character from a UTF-16 encoded code (pair), not from a Unicode code point! So encode the code point to UTF-16 for constructing.
// See http://unicode.org/faq/utf_bom.html#utf16-3
if ( utf32 >= 0x10000 ) {
var ch = utf32 - 0x10000 ;
str += String . fromCharCode ( 0xD800 | ( ch >> 10 ) , 0xDC00 | ( ch & 0x3FF ) ) ;
} else {
str += String . fromCharCode ( utf32 ) ;
}
}
}
// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
// null-terminated and encoded in UTF32 form. The copy will require at most str.length*4+4 bytes of space in the HEAP.
// Use the function lengthBytesUTF32() to compute the exact number of bytes (excluding null terminator) that this function will write.
// Parameters:
// str: the Javascript string to copy.
// outPtr: Byte address in Emscripten HEAP where to write the string to.
// maxBytesToWrite: The maximum number of bytes this function can write to the array. This count should include the null
// terminator, i.e. if maxBytesToWrite=4, only the null terminator will be written and nothing else.
// maxBytesToWrite<4 does not write any bytes to the output, not even the null terminator.
// Returns the number of bytes written, EXCLUDING the null terminator.
function stringToUTF32 ( str , outPtr , maxBytesToWrite ) {
# if ASSERTIONS
assert ( outPtr % 4 == 0 , 'Pointer passed to stringToUTF32 must be aligned to four bytes!' ) ;
# endif
# if ASSERTIONS
assert ( typeof maxBytesToWrite == 'number' , 'stringToUTF32(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!' ) ;
# endif
// Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed.
if ( maxBytesToWrite === undefined ) {
maxBytesToWrite = 0x7FFFFFFF ;
}
if ( maxBytesToWrite < 4 ) return 0 ;
var startPtr = outPtr ;
var endPtr = startPtr + maxBytesToWrite - 4 ;
for ( var i = 0 ; i < str . length ; ++ i ) {
// Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! We must decode the string to UTF-32 to the heap.
// See http://unicode.org/faq/utf_bom.html#utf16-3
var codeUnit = str . charCodeAt ( i ) ; // possibly a lead surrogate
if ( codeUnit >= 0xD800 && codeUnit <= 0xDFFF ) {
var trailSurrogate = str . charCodeAt ( ++ i ) ;
codeUnit = 0x10000 + ( ( codeUnit & 0x3FF ) << 10 ) | ( trailSurrogate & 0x3FF ) ;
}
{ { { makeSetValue ( 'outPtr' , 0 , 'codeUnit' , 'i32' ) } } } ;
outPtr += 4 ;
if ( outPtr + 4 > endPtr ) break ;
}
// Null-terminate the pointer to the HEAP.
{ { { makeSetValue ( 'outPtr' , 0 , 0 , 'i32' ) } } } ;
return outPtr - startPtr ;
}
// Returns the number of bytes the given Javascript string takes if encoded as a UTF16 byte array, EXCLUDING the null terminator byte.
function lengthBytesUTF32 ( str ) {
var len = 0 ;
for ( var i = 0 ; i < str . length ; ++ i ) {
// Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! We must decode the string to UTF-32 to the heap.
// See http://unicode.org/faq/utf_bom.html#utf16-3
var codeUnit = str . charCodeAt ( i ) ;
if ( codeUnit >= 0xD800 && codeUnit <= 0xDFFF ) ++ i ; // possibly a lead surrogate, so skip over the tail surrogate.
len += 4 ;
}
return len ;
}
// Allocate heap space for a JS string, and write it there.
// It is the responsibility of the caller to free() that memory.
function allocateUTF8 ( str ) {
var size = lengthBytesUTF8 ( str ) + 1 ;
var ret = _malloc ( size ) ;
if ( ret ) stringToUTF8Array ( str , HEAP8 , ret , size ) ;
return ret ;
}
// Allocate stack space for a JS string, and write it there.
function allocateUTF8OnStack ( str ) {
var size = lengthBytesUTF8 ( str ) + 1 ;
var ret = stackAlloc ( size ) ;
stringToUTF8Array ( str , HEAP8 , ret , size ) ;
return ret ;
}
function demangle ( func ) {
# if DEMANGLE _SUPPORT
var _ _cxa _demangle _func = Module [ '___cxa_demangle' ] || Module [ '__cxa_demangle' ] ;
assert ( _ _cxa _demangle _func ) ;
try {
var s =
# if WASM _BACKEND
func ;
# else
func . substr ( 1 ) ;
# endif
var len = lengthBytesUTF8 ( s ) + 1 ;
var buf = _malloc ( len ) ;
stringToUTF8 ( s , buf , len ) ;
var status = _malloc ( 4 ) ;
var ret = _ _cxa _demangle _func ( buf , 0 , 0 , status ) ;
if ( { { { makeGetValue ( 'status' , '0' , 'i32' ) } } } === 0 && ret ) {
return Pointer _stringify ( ret ) ;
}
// otherwise, libcxxabi failed
} catch ( e ) {
// ignore problems here
} finally {
if ( buf ) _free ( buf ) ;
if ( status ) _free ( status ) ;
if ( ret ) _free ( ret ) ;
}
// failure when using libcxxabi, don't demangle
return func ;
# else // DEMANGLE_SUPPORT
# if ASSERTIONS
warnOnce ( 'warning: build with -s DEMANGLE_SUPPORT=1 to link in libcxxabi demangling' ) ;
# endif // ASSERTIONS
return func ;
# endif // DEMANGLE_SUPPORT
}
function demangleAll ( text ) {
var regex =
# if WASM _BACKEND
/_Z[\w\d_]+/g ;
# else
/__Z[\w\d_]+/g ;
# endif
return text . replace ( regex ,
function ( x ) {
var y = demangle ( x ) ;
return x === y ? x : ( x + ' [' + y + ']' ) ;
} ) ;
}
function jsStackTrace ( ) {
var err = new Error ( ) ;
if ( ! err . stack ) {
// IE10+ special cases: It does have callstack info, but it is only populated if an Error object is thrown,
// so try that as a special-case.
try {
throw new Error ( 0 ) ;
} catch ( e ) {
err = e ;
}
if ( ! err . stack ) {
return '(no stack trace available)' ;
}
}
return err . stack . toString ( ) ;
}
function stackTrace ( ) {
var js = jsStackTrace ( ) ;
if ( Module [ 'extraStackTrace' ] ) js += '\n' + Module [ 'extraStackTrace' ] ( ) ;
return demangleAll ( js ) ;
}
// Memory management
var PAGE _SIZE = 16384 ;
var WASM _PAGE _SIZE = 65536 ;
var ASMJS _PAGE _SIZE = 16777216 ;
var MIN _TOTAL _MEMORY = 16777216 ;
function alignUp ( x , multiple ) {
if ( x % multiple > 0 ) {
x += multiple - ( x % multiple ) ;
}
return x ;
}
var HEAP ,
/** @type {ArrayBuffer} */
buffer ,
/** @type {Int8Array} */
HEAP8 ,
/** @type {Uint8Array} */
HEAPU8 ,
/** @type {Int16Array} */
HEAP16 ,
/** @type {Uint16Array} */
HEAPU16 ,
/** @type {Int32Array} */
HEAP32 ,
/** @type {Uint32Array} */
HEAPU32 ,
/** @type {Float32Array} */
HEAPF32 ,
/** @type {Float64Array} */
HEAPF64 ;
function updateGlobalBuffer ( buf ) {
Module [ 'buffer' ] = buffer = buf ;
}
function updateGlobalBufferViews ( ) {
Module [ 'HEAP8' ] = HEAP8 = new Int8Array ( buffer ) ;
Module [ 'HEAP16' ] = HEAP16 = new Int16Array ( buffer ) ;
Module [ 'HEAP32' ] = HEAP32 = new Int32Array ( buffer ) ;
Module [ 'HEAPU8' ] = HEAPU8 = new Uint8Array ( buffer ) ;
Module [ 'HEAPU16' ] = HEAPU16 = new Uint16Array ( buffer ) ;
Module [ 'HEAPU32' ] = HEAPU32 = new Uint32Array ( buffer ) ;
Module [ 'HEAPF32' ] = HEAPF32 = new Float32Array ( buffer ) ;
Module [ 'HEAPF64' ] = HEAPF64 = new Float64Array ( buffer ) ;
}
var STATIC _BASE , STATICTOP , staticSealed ; // static area
var STACK _BASE , STACKTOP , STACK _MAX ; // stack area
var DYNAMIC _BASE , DYNAMICTOP _PTR ; // dynamic area handled by sbrk
# if USE _PTHREADS
if ( ! ENVIRONMENT _IS _PTHREAD ) { // Pthreads have already initialized these variables in src/pthread-main.js, where they were passed to the thread worker at startup time
# endif
STATIC _BASE = STATICTOP = STACK _BASE = STACKTOP = STACK _MAX = DYNAMIC _BASE = DYNAMICTOP _PTR = 0 ;
staticSealed = false ;
# if USE _PTHREADS
}
# endif
# if USE _PTHREADS
if ( ENVIRONMENT _IS _PTHREAD ) {
staticSealed = true ; // The static memory area has been initialized already in the main thread, pthreads skip this.
# if SEPARATE _ASM != 0
importScripts ( '{{{ SEPARATE_ASM }}}' ) ; // load the separated-out asm.js
# endif
}
# endif
# if STACK _OVERFLOW _CHECK
// Initializes the stack cookie. Called at the startup of main and at the startup of each thread in pthreads mode.
function writeStackCookie ( ) {
assert ( ( STACK _MAX & 3 ) == 0 ) ;
HEAPU32 [ ( STACK _MAX >> 2 ) - 1 ] = 0x02135467 ;
HEAPU32 [ ( STACK _MAX >> 2 ) - 2 ] = 0x89BACDFE ;
}
function checkStackCookie ( ) {
if ( HEAPU32 [ ( STACK _MAX >> 2 ) - 1 ] != 0x02135467 || HEAPU32 [ ( STACK _MAX >> 2 ) - 2 ] != 0x89BACDFE ) {
abort ( 'Stack overflow! Stack cookie has been overwritten, expected hex dwords 0x89BACDFE and 0x02135467, but received 0x' + HEAPU32 [ ( STACK _MAX >> 2 ) - 2 ] . toString ( 16 ) + ' ' + HEAPU32 [ ( STACK _MAX >> 2 ) - 1 ] . toString ( 16 ) ) ;
}
# if ! SAFE _SPLIT _MEMORY
// Also test the global address 0 for integrity. This check is not compatible with SAFE_SPLIT_MEMORY though, since that mode already tests all address 0 accesses on its own.
if ( HEAP32 [ 0 ] !== 0x63736d65 /* 'emsc' */ ) throw 'Runtime error: The application has corrupted its heap memory area (address zero)!' ;
# endif
}
function abortStackOverflow ( allocSize ) {
abort ( 'Stack overflow! Attempted to allocate ' + allocSize + ' bytes on the stack, but stack has only ' + ( STACK _MAX - stackSave ( ) + allocSize ) + ' bytes available!' ) ;
}
# endif
# if ABORTING _MALLOC
function abortOnCannotGrowMemory ( ) {
# if WASM
abort ( 'Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value ' + TOTAL _MEMORY + ', (2) compile with -s ALLOW_MEMORY_GROWTH=1 which allows increasing the size at runtime, or (3) if you want malloc to return NULL (0) instead of this abort, compile with -s ABORTING_MALLOC=0 ' ) ;
# else
abort ( 'Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value ' + TOTAL _MEMORY + ', (2) compile with -s ALLOW_MEMORY_GROWTH=1 which allows increasing the size at runtime but prevents some optimizations, (3) set Module.TOTAL_MEMORY to a higher value before the program runs, or (4) if you want malloc to return NULL (0) instead of this abort, compile with -s ABORTING_MALLOC=0 ' ) ;
# endif
}
# endif
# if ALLOW _MEMORY _GROWTH
if ( ! Module [ 'reallocBuffer' ] ) Module [ 'reallocBuffer' ] = function ( size ) {
var ret ;
try {
if ( ArrayBuffer . transfer ) {
ret = ArrayBuffer . transfer ( buffer , size ) ;
} else {
var oldHEAP8 = HEAP8 ;
ret = new ArrayBuffer ( size ) ;
var temp = new Int8Array ( ret ) ;
temp . set ( oldHEAP8 ) ;
}
} catch ( e ) {
return false ;
}
var success = _emscripten _replace _memory ( ret ) ;
if ( ! success ) return false ;
return ret ;
} ;
# endif
function enlargeMemory ( ) {
# if USE _PTHREADS
abort ( 'Cannot enlarge memory arrays, since compiling with pthreads support enabled (-s USE_PTHREADS=1).' ) ;
# else
# if ALLOW _MEMORY _GROWTH == 0
# if ABORTING _MALLOC
abortOnCannotGrowMemory ( ) ;
# else
return false ; // malloc will report failure
# endif
# else
// TOTAL_MEMORY is the current size of the actual array, and DYNAMICTOP is the new top.
# if ASSERTIONS
assert ( HEAP32 [ DYNAMICTOP _PTR >> 2 ] > TOTAL _MEMORY ) ; // This function should only ever be called after the ceiling of the dynamic heap has already been bumped to exceed the current total size of the asm.js heap.
# endif
# if EMSCRIPTEN _TRACING
// Report old layout one last time
_emscripten _trace _report _memory _layout ( ) ;
# endif
var PAGE _MULTIPLE = Module [ "usingWasm" ] ? WASM _PAGE _SIZE : ASMJS _PAGE _SIZE ; // In wasm, heap size must be a multiple of 64KB. In asm.js, they need to be multiples of 16MB.
var LIMIT = 2147483648 - PAGE _MULTIPLE ; // We can do one page short of 2GB as theoretical maximum.
if ( HEAP32 [ DYNAMICTOP _PTR >> 2 ] > LIMIT ) {
# if ASSERTIONS
Module . printErr ( 'Cannot enlarge memory, asked to go up to ' + HEAP32 [ DYNAMICTOP _PTR >> 2 ] + ' bytes, but the limit is ' + LIMIT + ' bytes!' ) ;
# endif
return false ;
}
var OLD _TOTAL _MEMORY = TOTAL _MEMORY ;
TOTAL _MEMORY = Math . max ( TOTAL _MEMORY , MIN _TOTAL _MEMORY ) ; // So the loop below will not be infinite, and minimum asm.js memory size is 16MB.
while ( TOTAL _MEMORY < HEAP32 [ DYNAMICTOP _PTR >> 2 ] ) { // Keep incrementing the heap size as long as it's less than what is requested.
if ( TOTAL _MEMORY <= 536870912 ) {
TOTAL _MEMORY = alignUp ( 2 * TOTAL _MEMORY , PAGE _MULTIPLE ) ; // Simple heuristic: double until 1GB...
} else {
// ..., but after that, add smaller increments towards 2GB, which we cannot reach
TOTAL _MEMORY = Math . min ( alignUp ( ( 3 * TOTAL _MEMORY + 2147483648 ) / 4 , PAGE _MULTIPLE ) , LIMIT ) ;
# if ASSERTIONS
if ( TOTAL _MEMORY === OLD _TOTAL _MEMORY ) {
warnOnce ( 'Cannot ask for more memory since we reached the practical limit in browsers (which is just below 2GB), so the request would have failed. Requesting only ' + TOTAL _MEMORY ) ;
}
# endif
}
}
# if ASSERTIONS
var start = Date . now ( ) ;
# endif
var replacement = Module [ 'reallocBuffer' ] ( TOTAL _MEMORY ) ;
if ( ! replacement || replacement . byteLength != TOTAL _MEMORY ) {
# if ASSERTIONS
Module . printErr ( 'Failed to grow the heap from ' + OLD _TOTAL _MEMORY + ' bytes to ' + TOTAL _MEMORY + ' bytes, not enough memory!' ) ;
if ( replacement ) {
Module . printErr ( 'Expected to get back a buffer of size ' + TOTAL _MEMORY + ' bytes, but instead got back a buffer of size ' + replacement . byteLength ) ;
}
# endif
// restore the state to before this call, we failed
TOTAL _MEMORY = OLD _TOTAL _MEMORY ;
return false ;
}
// everything worked
updateGlobalBuffer ( replacement ) ;
updateGlobalBufferViews ( ) ;
# if ASSERTIONS
if ( ! Module [ "usingWasm" ] ) {
Module . printErr ( 'Warning: Enlarging memory arrays, this is not fast! ' + [ OLD _TOTAL _MEMORY , TOTAL _MEMORY ] ) ;
}
# endif
# if EMSCRIPTEN _TRACING
_emscripten _trace _js _log _message ( "Emscripten" , "Enlarging memory arrays from " + OLD _TOTAL _MEMORY + " to " + TOTAL _MEMORY ) ;
// And now report the new layout
_emscripten _trace _report _memory _layout ( ) ;
# endif
return true ;
# endif // ALLOW_MEMORY_GROWTH
# endif // USE_PTHREADS
}
# if ALLOW _MEMORY _GROWTH
var byteLength ;
try {
byteLength = Function . prototype . call . bind ( Object . getOwnPropertyDescriptor ( ArrayBuffer . prototype , 'byteLength' ) . get ) ;
byteLength ( new ArrayBuffer ( 4 ) ) ; // can fail on older ie
} catch ( e ) { // can fail on older node/v8
byteLength = function ( buffer ) { return buffer . byteLength ; } ;
}
# endif
var TOTAL _STACK = Module [ 'TOTAL_STACK' ] || { { { TOTAL _STACK } } } ;
var TOTAL _MEMORY = Module [ 'TOTAL_MEMORY' ] || { { { TOTAL _MEMORY } } } ;
if ( TOTAL _MEMORY < TOTAL _STACK ) Module . printErr ( 'TOTAL_MEMORY should be larger than TOTAL_STACK, was ' + TOTAL _MEMORY + '! (TOTAL_STACK=' + TOTAL _STACK + ')' ) ;
// Initialize the runtime's memory
# if ASSERTIONS
// check for full engine support (use string 'subarray' to avoid closure compiler confusion)
assert ( typeof Int32Array !== 'undefined' && typeof Float64Array !== 'undefined' && Int32Array . prototype . subarray !== undefined && Int32Array . prototype . set !== undefined ,
'JS engine does not provide full typed array support' ) ;
# endif
# if IN _TEST _HARNESS
// Test runs in browsers should always be free from uncaught exceptions. If an uncaught exception is thrown, we fail browser test execution in the REPORT_RESULT() macro to output an error value.
if ( ENVIRONMENT _IS _WEB ) {
window . addEventListener ( 'error' , function ( e ) {
if ( e . message . indexOf ( 'SimulateInfiniteLoop' ) != - 1 ) return ;
console . error ( 'Page threw an exception ' + e ) ;
Module [ 'pageThrewException' ] = true ;
} ) ;
}
# if USE _PTHREADS == 1
if ( typeof SharedArrayBuffer === 'undefined' || typeof Atomics === 'undefined' ) {
xhr = new XMLHttpRequest ( ) ;
xhr . open ( 'GET' , 'http://localhost:8888/report_result?skipped:%20SharedArrayBuffer%20is%20not%20supported!' ) ;
xhr . send ( ) ;
setTimeout ( function ( ) { window . close ( ) } , 2000 ) ;
}
# endif
# endif
# if USE _PTHREADS
# if ! WASM
if ( typeof SharedArrayBuffer !== 'undefined' ) {
if ( ! ENVIRONMENT _IS _PTHREAD ) buffer = new SharedArrayBuffer ( TOTAL _MEMORY ) ;
// Currently SharedArrayBuffer does not have a slice() operation, so polyfill it in.
// Adapted from https://github.com/ttaubert/node-arraybuffer-slice, (c) 2014 Tim Taubert <tim@timtaubert.de>
// arraybuffer-slice may be freely distributed under the MIT license.
( function ( undefined ) {
"use strict" ;
function clamp ( val , length ) {
val = ( val | 0 ) || 0 ;
if ( val < 0 ) return Math . max ( val + length , 0 ) ;
return Math . min ( val , length ) ;
}
if ( typeof SharedArrayBuffer !== 'undefined' && ! SharedArrayBuffer . prototype . slice ) {
SharedArrayBuffer . prototype . slice = function ( from , to ) {
var length = this . byteLength ;
var begin = clamp ( from , length ) ;
var end = length ;
if ( to !== undefined ) end = clamp ( to , length ) ;
if ( begin > end ) return new ArrayBuffer ( 0 ) ;
var num = end - begin ;
var target = new ArrayBuffer ( num ) ;
var targetArray = new Uint8Array ( target ) ;
var sourceArray = new Uint8Array ( this , begin , num ) ;
targetArray . set ( sourceArray ) ;
return target ;
} ;
}
} ) ( ) ;
} else {
if ( ! ENVIRONMENT _IS _PTHREAD ) buffer = new ArrayBuffer ( TOTAL _MEMORY ) ;
}
updateGlobalBufferViews ( ) ;
if ( typeof Atomics === 'undefined' ) {
// Polyfill singlethreaded atomics ops from http://lars-t-hansen.github.io/ecmascript_sharedmem/shmem.html#Atomics.add
// No thread-safety needed since we don't have multithreading support.
Atomics = { } ;
Atomics [ 'add' ] = function ( t , i , v ) { var w = t [ i ] ; t [ i ] += v ; return w ; }
Atomics [ 'and' ] = function ( t , i , v ) { var w = t [ i ] ; t [ i ] &= v ; return w ; }
Atomics [ 'compareExchange' ] = function ( t , i , e , r ) { var w = t [ i ] ; if ( w == e ) t [ i ] = r ; return w ; }
Atomics [ 'exchange' ] = function ( t , i , v ) { var w = t [ i ] ; t [ i ] = v ; return w ; }
Atomics [ 'wait' ] = function ( t , i , v , o ) { if ( t [ i ] != v ) return 'not-equal' ; else return 'timed-out' ; }
Atomics [ 'wake' ] = function ( t , i , c ) { return 0 ; }
Atomics [ 'wakeOrRequeue' ] = function ( t , i1 , c , i2 , v ) { return 0 ; }
Atomics [ 'isLockFree' ] = function ( s ) { return true ; }
Atomics [ 'load' ] = function ( t , i ) { return t [ i ] ; }
Atomics [ 'or' ] = function ( t , i , v ) { var w = t [ i ] ; t [ i ] |= v ; return w ; }
Atomics [ 'store' ] = function ( t , i , v ) { t [ i ] = v ; return v ; }
Atomics [ 'sub' ] = function ( t , i , v ) { var w = t [ i ] ; t [ i ] -= v ; return w ; }
Atomics [ 'xor' ] = function ( t , i , v ) { var w = t [ i ] ; t [ i ] ^= v ; return w ; }
}
# else
if ( ! ENVIRONMENT _IS _PTHREAD ) {
# if ALLOW _MEMORY _GROWTH
Module [ 'wasmMemory' ] = new WebAssembly . Memory ( { 'initial' : TOTAL _MEMORY / WASM _PAGE _SIZE , 'maximum' : { { { WASM _MEM _MAX } } } / WASM _PAGE _SIZE , 'shared' : true } ) ;
# else
Module [ 'wasmMemory' ] = new WebAssembly . Memory ( { 'initial' : TOTAL _MEMORY / WASM _PAGE _SIZE , 'maximum' : TOTAL _MEMORY / WASM _PAGE _SIZE , 'shared' : true } ) ;
# endif
buffer = Module [ 'wasmMemory' ] . buffer ;
}
updateGlobalBufferViews ( ) ;
# endif // !WASM
# else // USE_PTHREADS
# if SPLIT _MEMORY == 0
// Use a provided buffer, if there is one, or else allocate a new one
if ( Module [ 'buffer' ] ) {
buffer = Module [ 'buffer' ] ;
# if ASSERTIONS
assert ( buffer . byteLength === TOTAL _MEMORY , 'provided buffer should be ' + TOTAL _MEMORY + ' bytes, but it is ' + buffer . byteLength ) ;
# endif
} else {
// Use a WebAssembly memory where available
# if WASM
if ( typeof WebAssembly === 'object' && typeof WebAssembly . Memory === 'function' ) {
# if ASSERTIONS
assert ( TOTAL _MEMORY % WASM _PAGE _SIZE === 0 ) ;
# endif // ASSERTIONS
# if ALLOW _MEMORY _GROWTH
# if WASM _MEM _MAX
# if ASSERTIONS
assert ( { { { WASM _MEM _MAX } } } % WASM _PAGE _SIZE == 0 ) ;
# endif
Module [ 'wasmMemory' ] = new WebAssembly . Memory ( { 'initial' : TOTAL _MEMORY / WASM _PAGE _SIZE , 'maximum' : { { { WASM _MEM _MAX } } } / WASM _PAGE _SIZE } ) ;
# else
Module [ 'wasmMemory' ] = new WebAssembly . Memory ( { 'initial' : TOTAL _MEMORY / WASM _PAGE _SIZE } ) ;
# endif // BINARYEN_MEM_MAX
# else
Module [ 'wasmMemory' ] = new WebAssembly . Memory ( { 'initial' : TOTAL _MEMORY / WASM _PAGE _SIZE , 'maximum' : TOTAL _MEMORY / WASM _PAGE _SIZE } ) ;
# endif // ALLOW_MEMORY_GROWTH
buffer = Module [ 'wasmMemory' ] . buffer ;
} else
# endif // WASM
{
buffer = new ArrayBuffer ( TOTAL _MEMORY ) ;
}
# if ASSERTIONS
assert ( buffer . byteLength === TOTAL _MEMORY ) ;
# endif // ASSERTIONS
Module [ 'buffer' ] = buffer ;
}
updateGlobalBufferViews ( ) ;
# else // SPLIT_MEMORY
// make sure total memory is a multiple of the split memory size
var SPLIT _MEMORY = { { { SPLIT _MEMORY } } } ;
var SPLIT _MEMORY _MASK = SPLIT _MEMORY - 1 ;
var SPLIT _MEMORY _BITS = - 1 ;
var ALLOW _MEMORY _GROWTH = { { { ALLOW _MEMORY _GROWTH } } } ;
var ABORTING _MALLOC = { { { ABORTING _MALLOC } } } ;
Module [ 'SPLIT_MEMORY' ] = SPLIT _MEMORY ;
totalMemory = TOTAL _MEMORY ;
if ( totalMemory % SPLIT _MEMORY ) {
totalMemory += SPLIT _MEMORY - ( totalMemory % SPLIT _MEMORY ) ;
}
if ( totalMemory === SPLIT _MEMORY ) totalMemory *= 2 ;
if ( totalMemory !== TOTAL _MEMORY ) {
TOTAL _MEMORY = totalMemory ;
# if ASSERTIONS == 2
Module . printErr ( 'increasing TOTAL_MEMORY to ' + TOTAL _MEMORY + ' to be a multiple>1 of the split memory size ' + SPLIT _MEMORY + ')' ) ;
# endif
}
var buffers = [ ] , HEAP8s = [ ] , HEAP16s = [ ] , HEAP32s = [ ] , HEAPU8s = [ ] , HEAPU16s = [ ] , HEAPU32s = [ ] , HEAPF32s = [ ] , HEAPF64s = [ ] ;
// Allocates a split chunk, a range of memory of size SPLIT_MEMORY. Generally data is not provided, and a new
// buffer is allocated, this is what happens when malloc works. However, you can provide your own buffer,
// which then lets you access it at address [ i*SPLIT_MEMORY, (i+1)*SPLIT_MEMORY ).
// The function returns true if it succeeds. It can also throw an exception if no data is provided and
// the browser fails to allocate the buffer.
function allocateSplitChunk ( i , data ) {
if ( buffers [ i ] ) return false ; // already taken
// any of these allocations might fail; do them all before writing anything to global state
var currBuffer = data ? data : new ArrayBuffer ( SPLIT _MEMORY ) ;
# if ASSERTIONS
assert ( currBuffer instanceof ArrayBuffer ) ;
# endif
var currHEAP8s = new Int8Array ( currBuffer ) ;
var currHEAP16s = new Int16Array ( currBuffer ) ;
var currHEAP32s = new Int32Array ( currBuffer ) ;
var currHEAPU8s = new Uint8Array ( currBuffer ) ;
var currHEAPU16s = new Uint16Array ( currBuffer ) ;
var currHEAPU32s = new Uint32Array ( currBuffer ) ;
var currHEAPF32s = new Float32Array ( currBuffer ) ;
var currHEAPF64s = new Float64Array ( currBuffer ) ;
buffers [ i ] = currBuffer ;
HEAP8s [ i ] = currHEAP8s ;
HEAP16s [ i ] = currHEAP16s ;
HEAP32s [ i ] = currHEAP32s ;
HEAPU8s [ i ] = currHEAPU8s ;
HEAPU16s [ i ] = currHEAPU16s ;
HEAPU32s [ i ] = currHEAPU32s ;
HEAPF32s [ i ] = currHEAPF32s ;
HEAPF64s [ i ] = currHEAPF64s ;
return true ;
}
function freeSplitChunk ( i ) {
# if ASSERTIONS
assert ( buffers [ i ] && HEAP8s [ i ] ) ;
assert ( i > 0 ) ; // cannot free the first chunk
# endif
buffers [ i ] = HEAP8s [ i ] = HEAP16s [ i ] = HEAP32s [ i ] = HEAPU8s [ i ] = HEAPU16s [ i ] = HEAPU32s [ i ] = HEAPF32s [ i ] = HEAPF64s [ i ] = null ;
}
( function ( ) {
for ( var i = 0 ; i < TOTAL _MEMORY / SPLIT _MEMORY ; i ++ ) {
buffers [ i ] = HEAP8s [ i ] = HEAP16s [ i ] = HEAP32s [ i ] = HEAPU8s [ i ] = HEAPU16s [ i ] = HEAPU32s [ i ] = HEAPF32s [ i ] = HEAPF64s [ i ] = null ;
}
var temp = SPLIT _MEMORY ;
while ( temp ) {
temp >>= 1 ;
SPLIT _MEMORY _BITS ++ ;
}
allocateSplitChunk ( 0 ) ; // first chunk is for core runtime, static, stack, etc., always must be initialized
// support HEAP8.subarray etc.
var SHIFT _TABLE = [ 0 , 0 , 1 , 0 , 2 , 0 , 0 , 0 , 3 ] ;
function fake ( real ) {
var bytes = real [ 0 ] . BYTES _PER _ELEMENT ;
var shifts = SHIFT _TABLE [ bytes ] ;
# if ASSERTIONS
assert ( shifts > 0 || bytes == 1 ) ;
# endif
var that = {
BYTES _PER _ELEMENT : bytes ,
set : function ( array , offset ) {
if ( offset === undefined ) offset = 0 ;
// potentially split over multiple chunks
while ( array . length > 0 ) {
var chunk = offset >> SPLIT _MEMORY _BITS ;
var relative = offset & SPLIT _MEMORY _MASK ;
if ( relative + ( array . length << shifts ) < SPLIT _MEMORY ) {
real [ chunk ] . set ( array , relative ) ; // all fits in this chunk
break ;
} else {
var currSize = SPLIT _MEMORY - relative ;
# if ASSERTIONS
assert ( currSize % that . BYTES _PER _ELEMENT === 0 ) ;
# endif
var lastIndex = currSize >> shifts ;
real [ chunk ] . set ( array . subarray ( 0 , lastIndex ) , relative ) ;
// increments
array = array . subarray ( lastIndex ) ;
offset += currSize ;
}
}
} ,
subarray : function ( from , to ) {
from = from << shifts ;
var start = from >> SPLIT _MEMORY _BITS ;
if ( to === undefined ) {
to = ( start + 1 ) << SPLIT _MEMORY _BITS ;
} else {
to = to << shifts ;
}
to = Math . max ( from , to ) ; // if to is smaller, we'll get nothing anyway, same as to == from
if ( from < to ) {
var end = ( to - 1 ) >> SPLIT _MEMORY _BITS ; // -1, since we do not actually read the last address
# if ASSERTIONS
assert ( start === end , 'subarray cannot span split chunks' ) ;
# endif
}
if ( to > from && ( to & SPLIT _MEMORY _MASK ) == 0 ) {
// avoid the mask on the next line giving 0 for the end
return real [ start ] . subarray ( ( from & SPLIT _MEMORY _MASK ) >> shifts ) ; // just return to the end of the chunk
}
return real [ start ] . subarray ( ( from & SPLIT _MEMORY _MASK ) >> shifts , ( to & SPLIT _MEMORY _MASK ) >> shifts ) ;
} ,
buffer : {
slice : function ( from , to ) {
# if ASSERTIONS
assert ( to , 'TODO: this is an actual copy, so we could support a slice across multiple chunks' ) ;
# endif
return new Uint8Array ( HEAPU8 . subarray ( from , to ) ) . buffer ;
} ,
} ,
} ;
return that ;
}
HEAP8 = fake ( HEAP8s ) ;
HEAP16 = fake ( HEAP16s ) ;
HEAP32 = fake ( HEAP32s ) ;
HEAPU8 = fake ( HEAPU8s ) ;
HEAPU16 = fake ( HEAPU16s ) ;
HEAPU32 = fake ( HEAPU32s ) ;
HEAPF32 = fake ( HEAPF32s ) ;
HEAPF64 = fake ( HEAPF64s ) ;
} ) ( ) ;
# if SAFE _SPLIT _MEMORY
function checkPtr ( ptr , shifts ) {
if ( ptr <= 0 ) abort ( 'segmentation fault storing to address ' + ptr ) ;
if ( ptr !== ( ( ptr >> shifts ) << shifts ) ) abort ( 'alignment error storing to address ' + ptr + ', which was expected to be aligned to a shift of ' + shifts ) ;
if ( ( ptr >> SPLIT _MEMORY _BITS ) !== ( ptr + Math . pow ( 2 , shifts ) - 1 >> SPLIT _MEMORY _BITS ) ) abort ( 'segmentation fault, write spans split chunks ' + [ ptr , shifts ] ) ;
}
# endif
function get8 ( ptr ) {
ptr = ptr | 0 ;
# if SAFE _SPLIT _MEMORY
checkPtr ( ptr , 0 ) ;
# endif
return HEAP8s [ ptr >> SPLIT _MEMORY _BITS ] [ ( ptr & SPLIT _MEMORY _MASK ) >> 0 ] | 0 ;
}
function get16 ( ptr ) {
ptr = ptr | 0 ;
# if SAFE _SPLIT _MEMORY
checkPtr ( ptr , 1 ) ;
# endif
return HEAP16s [ ptr >> SPLIT _MEMORY _BITS ] [ ( ptr & SPLIT _MEMORY _MASK ) >> 1 ] | 0 ;
}
function get32 ( ptr ) {
ptr = ptr | 0 ;
# if SAFE _SPLIT _MEMORY
checkPtr ( ptr , 2 ) ;
# endif
return HEAP32s [ ptr >> SPLIT _MEMORY _BITS ] [ ( ptr & SPLIT _MEMORY _MASK ) >> 2 ] | 0 ;
}
function getU8 ( ptr ) {
ptr = ptr | 0 ;
# if SAFE _SPLIT _MEMORY
checkPtr ( ptr , 0 ) ;
# endif
return HEAPU8s [ ptr >> SPLIT _MEMORY _BITS ] [ ( ptr & SPLIT _MEMORY _MASK ) >> 0 ] | 0 ;
}
function getU16 ( ptr ) {
ptr = ptr | 0 ;
# if SAFE _SPLIT _MEMORY
checkPtr ( ptr , 1 ) ;
# endif
return HEAPU16s [ ptr >> SPLIT _MEMORY _BITS ] [ ( ptr & SPLIT _MEMORY _MASK ) >> 1 ] | 0 ;
}
function getU32 ( ptr ) {
ptr = ptr | 0 ;
# if SAFE _SPLIT _MEMORY
checkPtr ( ptr , 2 ) ;
# endif
return HEAPU32s [ ptr >> SPLIT _MEMORY _BITS ] [ ( ptr & SPLIT _MEMORY _MASK ) >> 2 ] >>> 0 ;
}
function getF32 ( ptr ) {
ptr = ptr | 0 ;
# if SAFE _SPLIT _MEMORY
checkPtr ( ptr , 2 ) ;
# endif
return + HEAPF32s [ ptr >> SPLIT _MEMORY _BITS ] [ ( ptr & SPLIT _MEMORY _MASK ) >> 2 ] ;
}
function getF64 ( ptr ) {
ptr = ptr | 0 ;
# if SAFE _SPLIT _MEMORY
checkPtr ( ptr , 3 ) ;
# endif
return + HEAPF64s [ ptr >> SPLIT _MEMORY _BITS ] [ ( ptr & SPLIT _MEMORY _MASK ) >> 3 ] ;
}
function set8 ( ptr , value ) {
ptr = ptr | 0 ;
value = value | 0 ;
# if SAFE _SPLIT _MEMORY
checkPtr ( ptr , 0 ) ;
# endif
HEAP8s [ ptr >> SPLIT _MEMORY _BITS ] [ ( ptr & SPLIT _MEMORY _MASK ) >> 0 ] = value ;
}
function set16 ( ptr , value ) {
ptr = ptr | 0 ;
value = value | 0 ;
# if SAFE _SPLIT _MEMORY
checkPtr ( ptr , 1 ) ;
# endif
HEAP16s [ ptr >> SPLIT _MEMORY _BITS ] [ ( ptr & SPLIT _MEMORY _MASK ) >> 1 ] = value ;
}
function set32 ( ptr , value ) {
ptr = ptr | 0 ;
value = value | 0 ;
# if SAFE _SPLIT _MEMORY
checkPtr ( ptr , 2 ) ;
# endif
HEAP32s [ ptr >> SPLIT _MEMORY _BITS ] [ ( ptr & SPLIT _MEMORY _MASK ) >> 2 ] = value ;
}
function setU8 ( ptr , value ) {
ptr = ptr | 0 ;
value = value | 0 ;
# if SAFE _SPLIT _MEMORY
checkPtr ( ptr , 0 ) ;
# endif
HEAPU8s [ ptr >> SPLIT _MEMORY _BITS ] [ ( ptr & SPLIT _MEMORY _MASK ) >> 0 ] = value ;
}
function setU16 ( ptr , value ) {
ptr = ptr | 0 ;
value = value | 0 ;
# if SAFE _SPLIT _MEMORY
checkPtr ( ptr , 1 ) ;
# endif
HEAPU16s [ ptr >> SPLIT _MEMORY _BITS ] [ ( ptr & SPLIT _MEMORY _MASK ) >> 1 ] = value ;
}
function setU32 ( ptr , value ) {
ptr = ptr | 0 ;
value = value | 0 ;
# if SAFE _SPLIT _MEMORY
checkPtr ( ptr , 2 ) ;
# endif
HEAPU32s [ ptr >> SPLIT _MEMORY _BITS ] [ ( ptr & SPLIT _MEMORY _MASK ) >> 2 ] = value ;
}
function setF32 ( ptr , value ) {
ptr = ptr | 0 ;
value = + value ;
# if SAFE _SPLIT _MEMORY
checkPtr ( ptr , 2 ) ;
# endif
HEAPF32s [ ptr >> SPLIT _MEMORY _BITS ] [ ( ptr & SPLIT _MEMORY _MASK ) >> 2 ] = value ;
}
function setF64 ( ptr , value ) {
ptr = ptr | 0 ;
value = + value ;
# if SAFE _SPLIT _MEMORY
checkPtr ( ptr , 3 ) ;
# endif
HEAPF64s [ ptr >> SPLIT _MEMORY _BITS ] [ ( ptr & SPLIT _MEMORY _MASK ) >> 3 ] = value ;
}
# endif // SPLIT_MEMORY
# endif // USE_PTHREADS
function getTotalMemory ( ) {
return TOTAL _MEMORY ;
}
// Endianness check (note: assumes compiler arch was little-endian)
# if SAFE _SPLIT _MEMORY == 0
# if USE _PTHREADS
if ( ! ENVIRONMENT _IS _PTHREAD ) {
# endif
HEAP32 [ 0 ] = 0x63736d65 ; /* 'emsc' */
# if USE _PTHREADS
} else {
if ( HEAP32 [ 0 ] !== 0x63736d65 ) throw 'Runtime error: The application has corrupted its heap memory area (address zero)!' ;
}
# endif
HEAP16 [ 1 ] = 0x6373 ;
if ( HEAPU8 [ 2 ] !== 0x73 || HEAPU8 [ 3 ] !== 0x63 ) throw 'Runtime error: expected the system to be little-endian!' ;
# endif
function callRuntimeCallbacks ( callbacks ) {
while ( callbacks . length > 0 ) {
var callback = callbacks . shift ( ) ;
if ( typeof callback == 'function' ) {
callback ( ) ;
continue ;
}
var func = callback . func ;
if ( typeof func === 'number' ) {
if ( callback . arg === undefined ) {
Module [ 'dynCall_v' ] ( func ) ;
} else {
Module [ 'dynCall_vi' ] ( func , callback . arg ) ;
}
} else {
func ( callback . arg === undefined ? null : callback . arg ) ;
}
}
}
var _ _ATPRERUN _ _ = [ ] ; // functions called before the runtime is initialized
var _ _ATINIT _ _ = [ ] ; // functions called during startup
var _ _ATMAIN _ _ = [ ] ; // functions called when main() is to be run
var _ _ATEXIT _ _ = [ ] ; // functions called during shutdown
2018-07-11 00:33:36 +00:00
var _ _ATPOSTRUN _ _ = [ ] ; // functions called after the main() is called
2018-07-10 20:24:48 +00:00
var runtimeInitialized = false ;
var runtimeExited = false ;
# if USE _PTHREADS
if ( ENVIRONMENT _IS _PTHREAD ) runtimeInitialized = true ; // The runtime is hosted in the main thread, and bits shared to pthreads via SharedArrayBuffer. No need to init again in pthread.
# endif
function preRun ( ) {
# if USE _PTHREADS
if ( ENVIRONMENT _IS _PTHREAD ) return ; // PThreads reuse the runtime from the main thread.
# endif
// compatibility - merge in anything from Module['preRun'] at this time
if ( Module [ 'preRun' ] ) {
if ( typeof Module [ 'preRun' ] == 'function' ) Module [ 'preRun' ] = [ Module [ 'preRun' ] ] ;
while ( Module [ 'preRun' ] . length ) {
addOnPreRun ( Module [ 'preRun' ] . shift ( ) ) ;
}
}
callRuntimeCallbacks ( _ _ATPRERUN _ _ ) ;
}
function ensureInitRuntime ( ) {
# if STACK _OVERFLOW _CHECK
checkStackCookie ( ) ;
# endif
# if USE _PTHREADS
if ( ENVIRONMENT _IS _PTHREAD ) return ; // PThreads reuse the runtime from the main thread.
# endif
if ( runtimeInitialized ) return ;
runtimeInitialized = true ;
# if USE _PTHREADS
// Pass the thread address inside the asm.js scope to store it for fast access that avoids the need for a FFI out.
_ _register _pthread _ptr ( PThread . mainThreadBlock , /*isMainBrowserThread=*/ ! ENVIRONMENT _IS _WORKER , /*isMainRuntimeThread=*/ 1 ) ;
# endif
callRuntimeCallbacks ( _ _ATINIT _ _ ) ;
}
function preMain ( ) {
# if STACK _OVERFLOW _CHECK
checkStackCookie ( ) ;
# endif
# if USE _PTHREADS
if ( ENVIRONMENT _IS _PTHREAD ) return ; // PThreads reuse the runtime from the main thread.
# endif
callRuntimeCallbacks ( _ _ATMAIN _ _ ) ;
}
function exitRuntime ( ) {
# if STACK _OVERFLOW _CHECK
checkStackCookie ( ) ;
# endif
# if USE _PTHREADS
if ( ENVIRONMENT _IS _PTHREAD ) return ; // PThreads reuse the runtime from the main thread.
# endif
callRuntimeCallbacks ( _ _ATEXIT _ _ ) ;
runtimeExited = true ;
}
function postRun ( ) {
# if STACK _OVERFLOW _CHECK
checkStackCookie ( ) ;
# endif
# if USE _PTHREADS
if ( ENVIRONMENT _IS _PTHREAD ) return ; // PThreads reuse the runtime from the main thread.
# endif
// compatibility - merge in anything from Module['postRun'] at this time
if ( Module [ 'postRun' ] ) {
if ( typeof Module [ 'postRun' ] == 'function' ) Module [ 'postRun' ] = [ Module [ 'postRun' ] ] ;
while ( Module [ 'postRun' ] . length ) {
addOnPostRun ( Module [ 'postRun' ] . shift ( ) ) ;
}
}
callRuntimeCallbacks ( _ _ATPOSTRUN _ _ ) ;
}
function addOnPreRun ( cb ) {
_ _ATPRERUN _ _ . unshift ( cb ) ;
}
function addOnInit ( cb ) {
_ _ATINIT _ _ . unshift ( cb ) ;
}
function addOnPreMain ( cb ) {
_ _ATMAIN _ _ . unshift ( cb ) ;
}
function addOnExit ( cb ) {
_ _ATEXIT _ _ . unshift ( cb ) ;
}
function addOnPostRun ( cb ) {
_ _ATPOSTRUN _ _ . unshift ( cb ) ;
}
// Deprecated: This function should not be called because it is unsafe and does not provide
// a maximum length limit of how many bytes it is allowed to write. Prefer calling the
// function stringToUTF8Array() instead, which takes in a maximum length that can be used
// to be secure from out of bounds writes.
/** @deprecated */
function writeStringToMemory ( string , buffer , dontAddNull ) {
warnOnce ( 'writeStringToMemory is deprecated and should not be called! Use stringToUTF8() instead!' ) ;
var /** @type {number} */ lastChar , /** @type {number} */ end ;
if ( dontAddNull ) {
// stringToUTF8Array always appends null. If we don't want to do that, remember the
// character that existed at the location where the null will be placed, and restore
// that after the write (below).
end = buffer + lengthBytesUTF8 ( string ) ;
lastChar = HEAP8 [ end ] ;
}
stringToUTF8 ( string , buffer , Infinity ) ;
if ( dontAddNull ) HEAP8 [ end ] = lastChar ; // Restore the value under the null character.
}
function writeArrayToMemory ( array , buffer ) {
# if ASSERTIONS
assert ( array . length >= 0 , 'writeArrayToMemory array must have a length (should be an array or typed array)' )
# endif
HEAP8 . set ( array , buffer ) ;
}
function writeAsciiToMemory ( str , buffer , dontAddNull ) {
for ( var i = 0 ; i < str . length ; ++ i ) {
# if ASSERTIONS
assert ( str . charCodeAt ( i ) === str . charCodeAt ( i ) & 0xff ) ;
# endif
{ { { makeSetValue ( 'buffer++' , 0 , 'str.charCodeAt(i)' , 'i8' ) } } } ;
}
// Null-terminate the pointer to the HEAP.
if ( ! dontAddNull ) { { { makeSetValue ( 'buffer' , 0 , 0 , 'i8' ) } } } ;
}
{ { { unSign } } }
{ { { reSign } } }
# if LEGACY _VM _SUPPORT
// check for imul support, and also for correctness ( https://bugs.webkit.org/show_bug.cgi?id=126345 )
if ( ! Math [ 'imul' ] || Math [ 'imul' ] ( 0xffffffff , 5 ) !== - 5 ) Math [ 'imul' ] = function imul ( a , b ) {
var ah = a >>> 16 ;
var al = a & 0xffff ;
var bh = b >>> 16 ;
var bl = b & 0xffff ;
return ( al * bl + ( ( ah * bl + al * bh ) << 16 ) ) | 0 ;
} ;
Math . imul = Math [ 'imul' ] ;
# if PRECISE _F32
# if PRECISE _F32 == 1
if ( ! Math [ 'fround' ] ) {
var froundBuffer = new Float32Array ( 1 ) ;
Math [ 'fround' ] = function ( x ) { froundBuffer [ 0 ] = x ; return froundBuffer [ 0 ] } ;
}
# else // 2
if ( ! Math [ 'fround' ] ) Math [ 'fround' ] = function ( x ) { return x } ;
# endif
Math . fround = Math [ 'fround' ] ;
# else
# if SIMD
if ( ! Math [ 'fround' ] ) Math [ 'fround' ] = function ( x ) { return x } ;
# endif
# endif
if ( ! Math [ 'clz32' ] ) Math [ 'clz32' ] = function ( x ) {
x = x >>> 0 ;
for ( var i = 0 ; i < 32 ; i ++ ) {
if ( x & ( 1 << ( 31 - i ) ) ) return i ;
}
return 32 ;
} ;
Math . clz32 = Math [ 'clz32' ]
if ( ! Math [ 'trunc' ] ) Math [ 'trunc' ] = function ( x ) {
return x < 0 ? Math . ceil ( x ) : Math . floor ( x ) ;
} ;
Math . trunc = Math [ 'trunc' ] ;
# else // LEGACY_VM_SUPPORT
# if ASSERTIONS
assert ( Math [ 'imul' ] && Math [ 'fround' ] && Math [ 'clz32' ] && Math [ 'trunc' ] , 'this is a legacy browser, build with LEGACY_VM_SUPPORT' ) ;
# endif
# endif // LEGACY_VM_SUPPORT
var Math _abs = Math . abs ;
var Math _cos = Math . cos ;
var Math _sin = Math . sin ;
var Math _tan = Math . tan ;
var Math _acos = Math . acos ;
var Math _asin = Math . asin ;
var Math _atan = Math . atan ;
var Math _atan2 = Math . atan2 ;
var Math _exp = Math . exp ;
var Math _log = Math . log ;
var Math _sqrt = Math . sqrt ;
var Math _ceil = Math . ceil ;
var Math _floor = Math . floor ;
var Math _pow = Math . pow ;
var Math _imul = Math . imul ;
var Math _fround = Math . fround ;
var Math _round = Math . round ;
var Math _min = Math . min ;
var Math _max = Math . max ;
var Math _clz32 = Math . clz32 ;
var Math _trunc = Math . trunc ;
// A counter of dependencies for calling run(). If we need to
// do asynchronous work before running, increment this and
// decrement it. Incrementing must happen in a place like
// PRE_RUN_ADDITIONS (used by emcc to add file preloading).
// Note that you can add dependencies in preRun, even though
// it happens right before run - run will be postponed until
// the dependencies are met.
var runDependencies = 0 ;
var runDependencyWatcher = null ;
var dependenciesFulfilled = null ; // overridden to take different actions when all run dependencies are fulfilled
# if ASSERTIONS
var runDependencyTracking = { } ;
# endif
function getUniqueRunDependency ( id ) {
# if ASSERTIONS
var orig = id ;
while ( 1 ) {
if ( ! runDependencyTracking [ id ] ) return id ;
id = orig + Math . random ( ) ;
}
# endif
return id ;
}
function addRunDependency ( id ) {
# if USE _PTHREADS
// We should never get here in pthreads (could no-op this out if called in pthreads, but that might indicate a bug in caller side,
// so good to be very explicit)
assert ( ! ENVIRONMENT _IS _PTHREAD ) ;
# endif
runDependencies ++ ;
if ( Module [ 'monitorRunDependencies' ] ) {
Module [ 'monitorRunDependencies' ] ( runDependencies ) ;
}
# if ASSERTIONS
if ( id ) {
assert ( ! runDependencyTracking [ id ] ) ;
runDependencyTracking [ id ] = 1 ;
if ( runDependencyWatcher === null && typeof setInterval !== 'undefined' ) {
// Check for missing dependencies every few seconds
runDependencyWatcher = setInterval ( function ( ) {
if ( ABORT ) {
clearInterval ( runDependencyWatcher ) ;
runDependencyWatcher = null ;
return ;
}
var shown = false ;
for ( var dep in runDependencyTracking ) {
if ( ! shown ) {
shown = true ;
Module . printErr ( 'still waiting on run dependencies:' ) ;
}
Module . printErr ( 'dependency: ' + dep ) ;
}
if ( shown ) {
Module . printErr ( '(end of list)' ) ;
}
} , 10000 ) ;
}
} else {
Module . printErr ( 'warning: run dependency added without ID' ) ;
}
# endif
}
function removeRunDependency ( id ) {
runDependencies -- ;
if ( Module [ 'monitorRunDependencies' ] ) {
Module [ 'monitorRunDependencies' ] ( runDependencies ) ;
}
# if ASSERTIONS
if ( id ) {
assert ( runDependencyTracking [ id ] ) ;
delete runDependencyTracking [ id ] ;
} else {
Module . printErr ( 'warning: run dependency removed without ID' ) ;
}
# endif
if ( runDependencies == 0 ) {
if ( runDependencyWatcher !== null ) {
clearInterval ( runDependencyWatcher ) ;
runDependencyWatcher = null ;
}
if ( dependenciesFulfilled ) {
var callback = dependenciesFulfilled ;
dependenciesFulfilled = null ;
callback ( ) ; // can add another dependenciesFulfilled
}
}
}
Module [ "preloadedImages" ] = { } ; // maps url to image data
Module [ "preloadedAudios" ] = { } ; // maps url to audio data
2018-07-11 00:33:36 +00:00
# if ( WASM != 0 ) && ( MAIN _MODULE != 0 )
2018-07-10 20:24:48 +00:00
Module [ "preloadedWasm" ] = { } ; // maps url to wasm instance exports
2018-07-11 00:33:36 +00:00
# endif
2018-07-10 20:24:48 +00:00
# if PGO
var PGOMonitor = {
called : { } ,
dump : function ( ) {
var dead = [ ] ;
for ( var i = 0 ; i < this . allGenerated . length ; i ++ ) {
var func = this . allGenerated [ i ] ;
if ( ! this . called [ func ] ) dead . push ( func ) ;
}
Module . print ( '-s DEAD_FUNCTIONS=\'' + JSON . stringify ( dead ) + '\'\n' ) ;
}
} ;
Module [ 'PGOMonitor' ] = PGOMonitor ;
_ _ATEXIT _ _ . push ( function ( ) { PGOMonitor . dump ( ) } ) ;
addOnPreRun ( function ( ) { addRunDependency ( 'pgo' ) } ) ;
# endif
# if RELOCATABLE
{ { {
( function ( ) {
// add in RUNTIME_LINKED_LIBS, if provided
if ( RUNTIME _LINKED _LIBS . length > 0 ) {
return "if (!Module['dynamicLibraries']) Module['dynamicLibraries'] = [];\n" +
"Module['dynamicLibraries'] = " + JSON . stringify ( RUNTIME _LINKED _LIBS ) + ".concat(Module['dynamicLibraries']);\n" ;
}
return '' ;
} ) ( )
} } }
addOnPreRun ( function ( ) {
function loadDynamicLibraries ( libs ) {
if ( libs ) {
libs . forEach ( function ( lib ) {
loadDynamicLibrary ( lib ) ;
} ) ;
}
if ( Module [ 'asm' ] [ 'runPostSets' ] ) {
Module [ 'asm' ] [ 'runPostSets' ] ( ) ;
}
}
// if we can load dynamic libraries synchronously, do so, otherwise, preload
# if WASM
if ( Module [ 'dynamicLibraries' ] && Module [ 'dynamicLibraries' ] . length > 0 && ! Module [ 'readBinary' ] ) {
// we can't read binary data synchronously, so preload
addRunDependency ( 'preload_dynamicLibraries' ) ;
var binaries = [ ] ;
Module [ 'dynamicLibraries' ] . forEach ( function ( lib ) {
fetch ( lib , { credentials : 'same-origin' } ) . then ( function ( response ) {
if ( ! response [ 'ok' ] ) {
throw "failed to load wasm binary file at '" + lib + "'" ;
}
return response [ 'arrayBuffer' ] ( ) ;
} ) . then ( function ( buffer ) {
var binary = new Uint8Array ( buffer ) ;
binaries . push ( binary ) ;
if ( binaries . length === Module [ 'dynamicLibraries' ] . length ) {
// we got them all, wonderful
loadDynamicLibraries ( binaries ) ;
removeRunDependency ( 'preload_dynamicLibraries' ) ;
}
} ) ;
} ) ;
return ;
}
# endif
loadDynamicLibraries ( Module [ 'dynamicLibraries' ] ) ;
} ) ;
# if ASSERTIONS
function lookupSymbol ( ptr ) { // for a pointer, print out all symbols that resolve to it
var ret = [ ] ;
for ( var i in Module ) {
if ( Module [ i ] === ptr ) ret . push ( i ) ;
}
print ( ptr + ' is ' + ret ) ;
}
# endif
# endif
var memoryInitializer = null ;
# if USE _PTHREADS
# if PTHREAD _HINT _NUM _CORES < 0
if ( ! ENVIRONMENT _IS _PTHREAD ) addOnPreRun ( function ( ) {
addRunDependency ( 'pthreads_querycores' ) ;
var bg = document . createElement ( 'div' ) ;
bg . style = "position: absolute; top: 0%; left: 0%; width: 100%; height: 100%; background-color: black; z-index:1001; -moz-opacity: 0.8; opacity:.80; filter: alpha(opacity=80);" ;
var div = document . createElement ( 'div' ) ;
var default _num _cores = navigator . hardwareConcurrency || 4 ;
var hwConcurrency = navigator . hardwareConcurrency ? ( "says " + navigator . hardwareConcurrency ) : "is not available" ;
var html = '<div style="width: 100%; text-align:center;"> Thread setup</div> <br /> Number of logical cores: <input type="number" style="width: 50px;" value="'
+ default _num _cores + '" min="1" max="32" id="thread_setup_num_logical_cores"></input> <br /><span style="font-size: 75%;">(<span style="font-family: monospace;">navigator.hardwareConcurrency</span> '
+ hwConcurrency + ')</span> <br />' ;
# if PTHREAD _POOL _SIZE < 0
html += 'PThread pool size: <input type="number" style="width: 50px;" value="'
+ default _num _cores + '" min="1" max="32" id="thread_setup_pthread_pool_size"></input> <br />' ;
# endif
html += ' <br /> <input type="button" id="thread_setup_button_go" value="Go"></input>' ;
div . innerHTML = html ;
div . style = 'position: absolute; top: 35%; left: 35%; width: 30%; height: 150px; padding: 16px; border: 16px solid gray; background-color: white; z-index:1002; overflow: auto;' ;
document . body . appendChild ( bg ) ;
document . body . appendChild ( div ) ;
var goButton = document . getElementById ( 'thread_setup_button_go' ) ;
goButton . onclick = function ( ) {
var num _logical _cores = parseInt ( document . getElementById ( 'thread_setup_num_logical_cores' ) . value ) ;
_emscripten _force _num _logical _cores ( num _logical _cores ) ;
# if PTHREAD _POOL _SIZE < 0
var pthread _pool _size = parseInt ( document . getElementById ( 'thread_setup_pthread_pool_size' ) . value ) ;
PThread . allocateUnusedWorkers ( pthread _pool _size , function ( ) { removeRunDependency ( 'pthreads_querycores' ) ; } ) ;
# else
removeRunDependency ( 'pthreads_querycores' ) ;
# endif
document . body . removeChild ( bg ) ;
document . body . removeChild ( div ) ;
}
} ) ;
# endif
# endif
# if PTHREAD _POOL _SIZE > 0
// To work around https://bugzilla.mozilla.org/show_bug.cgi?id=1049079, warm up a worker pool before starting up the application.
if ( ! ENVIRONMENT _IS _PTHREAD ) addOnPreRun ( function ( ) { if ( typeof SharedArrayBuffer !== 'undefined' ) { addRunDependency ( 'pthreads' ) ; PThread . allocateUnusedWorkers ( { { { PTHREAD _POOL _SIZE } } } , function ( ) { removeRunDependency ( 'pthreads' ) ; } ) ; } } ) ;
# endif
# if ASSERTIONS
# if NO _FILESYSTEM
var /* show errors on likely calls to FS when it was not included */ FS = {
error : function ( ) {
abort ( 'Filesystem support (FS) was not included. The problem is that you are using files from JS, but files were not used from C/C++, so filesystem support was not auto-included. You can force-include filesystem support with -s FORCE_FILESYSTEM=1' ) ;
} ,
init : function ( ) { FS . error ( ) } ,
createDataFile : function ( ) { FS . error ( ) } ,
createPreloadedFile : function ( ) { FS . error ( ) } ,
createLazyFile : function ( ) { FS . error ( ) } ,
open : function ( ) { FS . error ( ) } ,
mkdev : function ( ) { FS . error ( ) } ,
registerDevice : function ( ) { FS . error ( ) } ,
analyzePath : function ( ) { FS . error ( ) } ,
loadFilesFromDB : function ( ) { FS . error ( ) } ,
ErrnoError : function ErrnoError ( ) { FS . error ( ) } ,
} ;
Module [ 'FS_createDataFile' ] = FS . createDataFile ;
Module [ 'FS_createPreloadedFile' ] = FS . createPreloadedFile ;
# endif
# endif
# if CYBERDWARF
var cyberDWARFFile = '{{{ BUNDLED_CD_DEBUG_FILE }}}' ;
# endif
# include "URIUtils.js"
# if WASM
function integrateWasmJS ( ) {
// wasm.js has several methods for creating the compiled code module here:
// * 'native-wasm' : use native WebAssembly support in the browser
// * 'interpret-s-expr': load s-expression code from a .wast and interpret
// * 'interpret-binary': load binary wasm and interpret
// * 'interpret-asm2wasm': load asm.js code, translate to wasm, and interpret
// * 'asmjs': no wasm, just load the asm.js code and use that (good for testing)
// The method is set at compile time (BINARYEN_METHOD)
// The method can be a comma-separated list, in which case, we will try the
// options one by one. Some of them can fail gracefully, and then we can try
// the next.
// inputs
var method = '{{{ BINARYEN_METHOD }}}' ;
var wasmTextFile = '{{{ WASM_TEXT_FILE }}}' ;
var wasmBinaryFile = '{{{ WASM_BINARY_FILE }}}' ;
var asmjsCodeFile = '{{{ ASMJS_CODE_FILE }}}' ;
if ( typeof Module [ 'locateFile' ] === 'function' ) {
if ( ! isDataURI ( wasmTextFile ) ) {
wasmTextFile = Module [ 'locateFile' ] ( wasmTextFile ) ;
}
if ( ! isDataURI ( wasmBinaryFile ) ) {
wasmBinaryFile = Module [ 'locateFile' ] ( wasmBinaryFile ) ;
}
if ( ! isDataURI ( asmjsCodeFile ) ) {
asmjsCodeFile = Module [ 'locateFile' ] ( asmjsCodeFile ) ;
}
}
// utilities
var wasmPageSize = 64 * 1024 ;
var info = {
'global' : null ,
'env' : null ,
2018-07-11 00:33:36 +00:00
'asm2wasm' : asm2wasmImports ,
2018-07-10 20:24:48 +00:00
'parent' : Module // Module inside wasm-js.cpp refers to wasm-js.cpp; this allows access to the outside program.
} ;
var exports = null ;
# if BINARYEN _METHOD != 'native-wasm'
function lookupImport ( mod , base ) {
var lookup = info ;
if ( mod . indexOf ( '.' ) < 0 ) {
lookup = ( lookup || { } ) [ mod ] ;
} else {
var parts = mod . split ( '.' ) ;
lookup = ( lookup || { } ) [ parts [ 0 ] ] ;
lookup = ( lookup || { } ) [ parts [ 1 ] ] ;
}
if ( base ) {
lookup = ( lookup || { } ) [ base ] ;
}
if ( lookup === undefined ) {
abort ( 'bad lookupImport to (' + mod + ').' + base ) ;
}
return lookup ;
}
# endif // BINARYEN_METHOD != 'native-wasm'
function mergeMemory ( newBuffer ) {
// The wasm instance creates its memory. But static init code might have written to
// buffer already, including the mem init file, and we must copy it over in a proper merge.
// TODO: avoid this copy, by avoiding such static init writes
// TODO: in shorter term, just copy up to the last static init write
var oldBuffer = Module [ 'buffer' ] ;
if ( newBuffer . byteLength < oldBuffer . byteLength ) {
Module [ 'printErr' ] ( 'the new buffer in mergeMemory is smaller than the previous one. in native wasm, we should grow memory here' ) ;
}
var oldView = new Int8Array ( oldBuffer ) ;
var newView = new Int8Array ( newBuffer ) ;
# if MEM _INIT _IN _WASM == 0
// If we have a mem init file, do not trample it
if ( ! memoryInitializer ) {
oldView . set ( newView . subarray ( Module [ 'STATIC_BASE' ] , Module [ 'STATIC_BASE' ] + Module [ 'STATIC_BUMP' ] ) , Module [ 'STATIC_BASE' ] ) ;
}
# endif
newView . set ( oldView ) ;
updateGlobalBuffer ( newBuffer ) ;
updateGlobalBufferViews ( ) ;
}
function fixImports ( imports ) {
# if WASM _BACKEND
var ret = { } ;
for ( var i in imports ) {
var fixed = i ;
if ( fixed [ 0 ] == '_' ) fixed = fixed . substr ( 1 ) ;
ret [ fixed ] = imports [ i ] ;
}
return ret ;
# else
return imports ;
# endif // WASM_BACKEND
}
function getBinary ( ) {
try {
if ( Module [ 'wasmBinary' ] ) {
return new Uint8Array ( Module [ 'wasmBinary' ] ) ;
}
# if SUPPORT _BASE64 _EMBEDDING
var binary = tryParseAsDataURI ( wasmBinaryFile ) ;
if ( binary ) {
return binary ;
}
# endif
if ( Module [ 'readBinary' ] ) {
return Module [ 'readBinary' ] ( wasmBinaryFile ) ;
} else {
throw "on the web, we need the wasm binary to be preloaded and set on Module['wasmBinary']. emcc.py will do that for you when generating HTML (but not JS)" ;
}
}
catch ( err ) {
abort ( err ) ;
}
}
function getBinaryPromise ( ) {
// if we don't have the binary yet, and have the Fetch api, use that
// in some environments, like Electron's render process, Fetch api may be present, but have a different context than expected, let's only use it on the Web
if ( ! Module [ 'wasmBinary' ] && ( ENVIRONMENT _IS _WEB || ENVIRONMENT _IS _WORKER ) && typeof fetch === 'function' ) {
return fetch ( wasmBinaryFile , { credentials : 'same-origin' } ) . then ( function ( response ) {
if ( ! response [ 'ok' ] ) {
throw "failed to load wasm binary file at '" + wasmBinaryFile + "'" ;
}
return response [ 'arrayBuffer' ] ( ) ;
} ) . catch ( function ( ) {
return getBinary ( ) ;
} ) ;
}
// Otherwise, getBinary should be able to get it synchronously
return new Promise ( function ( resolve , reject ) {
resolve ( getBinary ( ) ) ;
} ) ;
}
// do-method functions
# if BINARYEN _METHOD != 'native-wasm'
function doJustAsm ( global , env , providedBuffer ) {
// if no Module.asm, or it's the method handler helper (see below), then apply
// the asmjs
if ( typeof Module [ 'asm' ] !== 'function' || Module [ 'asm' ] === methodHandler ) {
if ( ! Module [ 'asmPreload' ] ) {
// you can load the .asm.js file before this, to avoid this sync xhr and eval
{ { { makeEval ( "eval(Module['read'](asmjsCodeFile));" ) } } } // set Module.asm
} else {
Module [ 'asm' ] = Module [ 'asmPreload' ] ;
}
}
if ( typeof Module [ 'asm' ] !== 'function' ) {
Module [ 'printErr' ] ( 'asm evalling did not set the module properly' ) ;
return false ;
}
return Module [ 'asm' ] ( global , env , providedBuffer ) ;
}
# endif // BINARYEN_METHOD != 'native-wasm'
function doNativeWasm ( global , env , providedBuffer ) {
if ( typeof WebAssembly !== 'object' ) {
# if BINARYEN _METHOD == 'native-wasm'
# if ASSERTIONS
// when the method is just native-wasm, our error message can be very specific
abort ( 'No WebAssembly support found. Build with -s WASM=0 to target JavaScript instead.' ) ;
# endif
# endif
Module [ 'printErr' ] ( 'no native wasm support detected' ) ;
return false ;
}
// prepare memory import
if ( ! ( Module [ 'wasmMemory' ] instanceof WebAssembly . Memory ) ) {
Module [ 'printErr' ] ( 'no native wasm Memory in use' ) ;
return false ;
}
env [ 'memory' ] = Module [ 'wasmMemory' ] ;
// Load the wasm module and create an instance of using native support in the JS engine.
info [ 'global' ] = {
'NaN' : NaN ,
'Infinity' : Infinity
} ;
info [ 'global.Math' ] = Math ;
info [ 'env' ] = env ;
// handle a generated wasm instance, receiving its exports and
// performing other necessary setup
function receiveInstance ( instance , module ) {
exports = instance . exports ;
if ( exports . memory ) mergeMemory ( exports . memory ) ;
Module [ 'asm' ] = exports ;
Module [ "usingWasm" ] = true ;
# if WASM _BACKEND
// wasm backend stack goes down
STACKTOP = STACK _BASE + TOTAL _STACK ;
STACK _MAX = STACK _BASE ;
// can't call stackRestore() here since this function can be called
// synchronously before stackRestore() is declared.
Module [ "asm" ] [ "stackRestore" ] ( STACKTOP ) ;
# endif
# if USE _PTHREADS
// Keep a reference to the compiled module so we can post it to the workers.
Module [ 'wasmModule' ] = module ;
// Instantiation is synchronous in pthreads and we assert on run dependencies.
if ( ! ENVIRONMENT _IS _PTHREAD ) removeRunDependency ( 'wasm-instantiate' ) ;
# else
removeRunDependency ( 'wasm-instantiate' ) ;
# endif
}
# if USE _PTHREADS
if ( ! ENVIRONMENT _IS _PTHREAD ) {
addRunDependency ( 'wasm-instantiate' ) ; // we can't run yet (except in a pthread, where we have a custom sync instantiator)
}
# else
addRunDependency ( 'wasm-instantiate' ) ;
# endif
// User shell pages can write their own Module.instantiateWasm = function(imports, successCallback) callback
// to manually instantiate the Wasm module themselves. This allows pages to run the instantiation parallel
// to any other async startup actions they are performing.
if ( Module [ 'instantiateWasm' ] ) {
try {
return Module [ 'instantiateWasm' ] ( info , receiveInstance ) ;
} catch ( e ) {
Module [ 'printErr' ] ( 'Module.instantiateWasm callback failed with error: ' + e ) ;
return false ;
}
}
# if BINARYEN _ASYNC _COMPILATION
# if RUNTIME _LOGGING
Module [ 'printErr' ] ( 'asynchronously preparing wasm' ) ;
# endif
# if ASSERTIONS
// Async compilation can be confusing when an error on the page overwrites Module
// (for example, if the order of elements is wrong, and the one defining Module is
// later), so we save Module and check it later.
var trueModule = Module ;
# endif
function receiveInstantiatedSource ( output ) {
// 'output' is a WebAssemblyInstantiatedSource object which has both the module and instance.
// receiveInstance() will swap in the exports (to Module.asm) so they can be called
# if ASSERTIONS
assert ( Module === trueModule , 'the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?' ) ;
trueModule = null ;
# endif
receiveInstance ( output [ 'instance' ] , output [ 'module' ] ) ;
}
function instantiateArrayBuffer ( receiver ) {
getBinaryPromise ( ) . then ( function ( binary ) {
return WebAssembly . instantiate ( binary , info ) ;
} ) . then ( receiver ) . catch ( function ( reason ) {
Module [ 'printErr' ] ( 'failed to asynchronously prepare wasm: ' + reason ) ;
abort ( reason ) ;
} ) ;
}
// Prefer streaming instantiation if available.
if ( ! Module [ 'wasmBinary' ] &&
typeof WebAssembly . instantiateStreaming === 'function' &&
! isDataURI ( wasmBinaryFile ) &&
typeof fetch === 'function' ) {
WebAssembly . instantiateStreaming ( fetch ( wasmBinaryFile , { credentials : 'same-origin' } ) , info )
. then ( receiveInstantiatedSource )
. catch ( function ( reason ) {
// We expect the most common failure cause to be a bad MIME type for the binary,
// in which case falling back to ArrayBuffer instantiation should work.
Module [ 'printErr' ] ( 'wasm streaming compile failed: ' + reason ) ;
Module [ 'printErr' ] ( 'falling back to ArrayBuffer instantiation' ) ;
instantiateArrayBuffer ( receiveInstantiatedSource ) ;
} ) ;
} else {
instantiateArrayBuffer ( receiveInstantiatedSource ) ;
}
return { } ; // no exports yet; we'll fill them in later
# else
var instance ;
try {
instance = new WebAssembly . Instance ( new WebAssembly . Module ( getBinary ( ) ) , info )
} catch ( e ) {
Module [ 'printErr' ] ( 'failed to compile wasm module: ' + e ) ;
if ( e . toString ( ) . indexOf ( 'imported Memory with incompatible size' ) >= 0 ) {
Module [ 'printErr' ] ( 'Memory size incompatibility issues may be due to changing TOTAL_MEMORY at runtime to something too large. Use ALLOW_MEMORY_GROWTH to allow any size memory (and also make sure not to set TOTAL_MEMORY at runtime to something smaller than it was at compile time).' ) ;
}
return false ;
}
receiveInstance ( instance ) ;
return exports ;
# endif
}
# if BINARYEN _METHOD != 'native-wasm'
function doWasmPolyfill ( global , env , providedBuffer , method ) {
if ( typeof WasmJS !== 'function' ) {
Module [ 'printErr' ] ( 'WasmJS not detected - polyfill not bundled?' ) ;
return false ;
}
// Use wasm.js to polyfill and execute code in a wasm interpreter.
var wasmJS = WasmJS ( { } ) ;
// XXX don't be confused. Module here is in the outside program. wasmJS is the inner wasm-js.cpp.
wasmJS [ 'outside' ] = Module ; // Inside wasm-js.cpp, Module['outside'] reaches the outside module.
// Information for the instance of the module.
wasmJS [ 'info' ] = info ;
wasmJS [ 'lookupImport' ] = lookupImport ;
assert ( providedBuffer === Module [ 'buffer' ] ) ; // we should not even need to pass it as a 3rd arg for wasm, but that's the asm.js way.
info . global = global ;
info . env = env ;
// polyfill interpreter expects an ArrayBuffer
assert ( providedBuffer === Module [ 'buffer' ] ) ;
env [ 'memory' ] = providedBuffer ;
assert ( env [ 'memory' ] instanceof ArrayBuffer ) ;
wasmJS [ 'providedTotalMemory' ] = Module [ 'buffer' ] . byteLength ;
// Prepare to generate wasm, using either asm2wasm or s-exprs
var code ;
if ( method === 'interpret-binary' ) {
code = getBinary ( ) ;
} else {
code = Module [ 'read' ] ( method == 'interpret-asm2wasm' ? asmjsCodeFile : wasmTextFile ) ;
}
var temp ;
if ( method == 'interpret-asm2wasm' ) {
temp = wasmJS [ '_malloc' ] ( code . length + 1 ) ;
wasmJS [ 'writeAsciiToMemory' ] ( code , temp ) ;
wasmJS [ '_load_asm2wasm' ] ( temp ) ;
} else if ( method === 'interpret-s-expr' ) {
temp = wasmJS [ '_malloc' ] ( code . length + 1 ) ;
wasmJS [ 'writeAsciiToMemory' ] ( code , temp ) ;
wasmJS [ '_load_s_expr2wasm' ] ( temp ) ;
} else if ( method === 'interpret-binary' ) {
temp = wasmJS [ '_malloc' ] ( code . length ) ;
wasmJS [ 'HEAPU8' ] . set ( code , temp ) ;
wasmJS [ '_load_binary2wasm' ] ( temp , code . length ) ;
} else {
throw 'what? ' + method ;
}
wasmJS [ '_free' ] ( temp ) ;
wasmJS [ '_instantiate' ] ( temp ) ;
if ( Module [ 'newBuffer' ] ) {
mergeMemory ( Module [ 'newBuffer' ] ) ;
Module [ 'newBuffer' ] = null ;
}
exports = wasmJS [ 'asmExports' ] ;
return exports ;
}
# endif // BINARYEN_METHOD != 'native-wasm'
// We may have a preloaded value in Module.asm, save it
Module [ 'asmPreload' ] = Module [ 'asm' ] ;
// Memory growth integration code
var asmjsReallocBuffer = Module [ 'reallocBuffer' ] ;
var wasmReallocBuffer = function ( size ) {
var PAGE _MULTIPLE = Module [ "usingWasm" ] ? WASM _PAGE _SIZE : ASMJS _PAGE _SIZE ; // In wasm, heap size must be a multiple of 64KB. In asm.js, they need to be multiples of 16MB.
size = alignUp ( size , PAGE _MULTIPLE ) ; // round up to wasm page size
var old = Module [ 'buffer' ] ;
var oldSize = old . byteLength ;
if ( Module [ "usingWasm" ] ) {
// native wasm support
try {
var result = Module [ 'wasmMemory' ] . grow ( ( size - oldSize ) / wasmPageSize ) ; // .grow() takes a delta compared to the previous size
if ( result !== ( - 1 | 0 ) ) {
// success in native wasm memory growth, get the buffer from the memory
return Module [ 'buffer' ] = Module [ 'wasmMemory' ] . buffer ;
} else {
return null ;
}
} catch ( e ) {
# if ASSERTIONS
console . error ( 'Module.reallocBuffer: Attempted to grow from ' + oldSize + ' bytes to ' + size + ' bytes, but got error: ' + e ) ;
# endif
return null ;
}
}
# if BINARYEN _METHOD != 'native-wasm'
else {
// wasm interpreter support
exports [ '__growWasmMemory' ] ( ( size - oldSize ) / wasmPageSize ) ; // tiny wasm method that just does grow_memory
// in interpreter, we replace Module.buffer if we allocate
return Module [ 'buffer' ] !== old ? Module [ 'buffer' ] : null ; // if it was reallocated, it changed
}
# endif // BINARYEN_METHOD != 'native-wasm'
} ;
Module [ 'reallocBuffer' ] = function ( size ) {
if ( finalMethod === 'asmjs' ) {
return asmjsReallocBuffer ( size ) ;
} else {
return wasmReallocBuffer ( size ) ;
}
} ;
// we may try more than one; this is the final one, that worked and we are using
var finalMethod = '' ;
// Provide an "asm.js function" for the application, called to "link" the asm.js module. We instantiate
// the wasm module at that time, and it receives imports and provides exports and so forth, the app
// doesn't need to care that it is wasm or olyfilled wasm or asm.js.
Module [ 'asm' ] = function ( global , env , providedBuffer ) {
# if BINARYEN _METHOD != 'native-wasm'
global = fixImports ( global ) ;
# endif
env = fixImports ( env ) ;
// import table
if ( ! env [ 'table' ] ) {
var TABLE _SIZE = Module [ 'wasmTableSize' ] ;
if ( TABLE _SIZE === undefined ) TABLE _SIZE = 1024 ; // works in binaryen interpreter at least
var MAX _TABLE _SIZE = Module [ 'wasmMaxTableSize' ] ;
if ( typeof WebAssembly === 'object' && typeof WebAssembly . Table === 'function' ) {
if ( MAX _TABLE _SIZE !== undefined ) {
env [ 'table' ] = new WebAssembly . Table ( { 'initial' : TABLE _SIZE , 'maximum' : MAX _TABLE _SIZE , 'element' : 'anyfunc' } ) ;
} else {
env [ 'table' ] = new WebAssembly . Table ( { 'initial' : TABLE _SIZE , element : 'anyfunc' } ) ;
}
} else {
env [ 'table' ] = new Array ( TABLE _SIZE ) ; // works in binaryen interpreter at least
}
Module [ 'wasmTable' ] = env [ 'table' ] ;
}
if ( ! env [ 'memoryBase' ] ) {
env [ 'memoryBase' ] = Module [ 'STATIC_BASE' ] ; // tell the memory segments where to place themselves
}
if ( ! env [ 'tableBase' ] ) {
env [ 'tableBase' ] = 0 ; // table starts at 0 by default, in dynamic linking this will change
}
// try the methods. each should return the exports if it succeeded
var exports ;
# if BINARYEN _METHOD == 'native-wasm'
exports = doNativeWasm ( global , env , providedBuffer ) ;
# else // native-wasm
# if BINARYEN _METHOD == 'asmjs'
exports = doJustAsm ( global , env , providedBuffer ) ;
# else
var methods = method . split ( ',' ) ;
for ( var i = 0 ; i < methods . length ; i ++ ) {
var curr = methods [ i ] ;
# if RUNTIME _LOGGING
Module [ 'printErr' ] ( 'trying binaryen method: ' + curr ) ;
# endif
finalMethod = curr ;
if ( curr === 'native-wasm' ) {
if ( exports = doNativeWasm ( global , env , providedBuffer ) ) break ;
} else if ( curr === 'asmjs' ) {
if ( exports = doJustAsm ( global , env , providedBuffer ) ) break ;
} else if ( curr === 'interpret-asm2wasm' || curr === 'interpret-s-expr' || curr === 'interpret-binary' ) {
if ( exports = doWasmPolyfill ( global , env , providedBuffer , curr ) ) break ;
} else {
abort ( 'bad method: ' + curr ) ;
}
}
# endif // asmjs
# endif // native-wasm
# if ASSERTIONS
assert ( exports , 'no binaryen method succeeded. consider enabling more options, like interpreting, if you want that: https://github.com/kripken/emscripten/wiki/WebAssembly#binaryen-methods' ) ;
# else
assert ( exports , 'no binaryen method succeeded.' ) ;
# endif
# if RUNTIME _LOGGING
Module [ 'printErr' ] ( 'binaryen method succeeded.' ) ;
# endif
return exports ;
} ;
var methodHandler = Module [ 'asm' ] ; // note our method handler, as we may modify Module['asm'] later
}
integrateWasmJS ( ) ;
# endif
// === Body ===