@@ -2370,110 +2370,6 @@ addToLibrary({
23702370 }
23712371 } ,
23722372
2373- $getCallstack__deps : [ '$jsStackTrace' , '$warnOnce' ] ,
2374- $getCallstack__docs : '/** @param {number=} flags */' ,
2375- $getCallstack : function ( flags ) {
2376- var callstack = jsStackTrace ( ) ;
2377-
2378- // Find the symbols in the callstack that corresponds to the functions that
2379- // report callstack information, and remove everything up to these from the
2380- // output.
2381- var iThisFunc = callstack . lastIndexOf ( '_emscripten_log' ) ;
2382- var iThisFunc2 = callstack . lastIndexOf ( '_emscripten_get_callstack' ) ;
2383- var iNextLine = callstack . indexOf ( '\n' , Math . max ( iThisFunc , iThisFunc2 ) ) + 1 ;
2384- callstack = callstack . slice ( iNextLine ) ;
2385-
2386- // If user requested to see the original source stack, but no source map
2387- // information is available, just fall back to showing the JS stack.
2388- if ( flags & { { { cDefs . EM_LOG_C_STACK } } } && typeof emscripten_source_map == 'undefined' ) {
2389- warnOnce ( 'Source map information is not available, emscripten_log with EM_LOG_C_STACK will be ignored. Build with "--pre-js $EMSCRIPTEN/src/emscripten-source-map.min.js" linker flag to add source map loading to code.' ) ;
2390- flags ^= { { { cDefs . EM_LOG_C_STACK } } } ;
2391- flags |= { { { cDefs . EM_LOG_JS_STACK } } } ;
2392- }
2393-
2394- // Process all lines:
2395- var lines = callstack . split ( '\n' ) ;
2396- callstack = '' ;
2397- // New FF30 with column info: extract components of form:
2398- // ' Object._main@http://server.com:4324:12'
2399- var newFirefoxRe = new RegExp ( '\\s*(.*?)@(.*?):([0-9]+):([0-9]+)' ) ;
2400- // Old FF without column info: extract components of form:
2401- // ' Object._main@http://server.com:4324'
2402- var firefoxRe = new RegExp ( '\\s*(.*?)@(.*):(.*)(:(.*))?' ) ;
2403- // Extract components of form:
2404- // ' at Object._main (http://server.com/file.html:4324:12)'
2405- var chromeRe = new RegExp ( '\\s*at (.*?) \\\((.*):(.*):(.*)\\\)' ) ;
2406-
2407- for ( var l in lines ) {
2408- var line = lines [ l ] ;
2409-
2410- var symbolName = '' ;
2411- var file = '' ;
2412- var lineno = 0 ;
2413- var column = 0 ;
2414-
2415- var parts = chromeRe . exec ( line ) ;
2416- if ( parts && parts . length == 5 ) {
2417- symbolName = parts [ 1 ] ;
2418- file = parts [ 2 ] ;
2419- lineno = parts [ 3 ] ;
2420- column = parts [ 4 ] ;
2421- } else {
2422- parts = newFirefoxRe . exec ( line ) ;
2423- if ( ! parts ) parts = firefoxRe . exec ( line ) ;
2424- if ( parts && parts . length >= 4 ) {
2425- symbolName = parts [ 1 ] ;
2426- file = parts [ 2 ] ;
2427- lineno = parts [ 3 ] ;
2428- // Old Firefox doesn't carry column information, but in new FF30, it
2429- // is present. See https://bugzilla.mozilla.org/show_bug.cgi?id=762556
2430- column = parts [ 4 ] | 0 ;
2431- } else {
2432- // Was not able to extract this line for demangling/sourcemapping
2433- // purposes. Output it as-is.
2434- callstack + = line + '\n' ;
2435- continue ;
2436- }
2437- }
2438-
2439- var haveSourceMap = false ;
2440-
2441- if ( flags & { { { cDefs . EM_LOG_C_STACK } } } ) {
2442- var orig = emscripten_source_map . originalPositionFor ( { line : lineno , column : column } ) ;
2443- haveSourceMap = orig ?. source ;
2444- if ( haveSourceMap ) {
2445- if ( flags & { { { cDefs . EM_LOG_NO_PATHS } } } ) {
2446- orig . source = orig . source . substring ( orig . source . replace ( / \\ / g, "/" ) . lastIndexOf ( '/' ) + 1 ) ;
2447- }
2448- callstack += ` at ${ symbolName } (${ orig . source } :${ orig . line } :${ orig . column } )\n` ;
2449- }
2450- }
2451- if ( ( flags & { { { cDefs . EM_LOG_JS_STACK } } } ) || ! haveSourceMap ) {
2452- if ( flags & { { { cDefs . EM_LOG_NO_PATHS } } } ) {
2453- file = file . substring ( file . replace ( / \\ / g, "/" ) . lastIndexOf ( '/' ) + 1 ) ;
2454- }
2455- callstack += ( haveSourceMap ? ( ` = ${symbolName} `) : (` at ${symbolName } `) ) + ` (${ file } :${ lineno } :${ column } )\n` ;
2456- }
2457- }
2458- // Trim extra whitespace at the end of the output.
2459- callstack = callstack . replace ( / \s + $ / , '' ) ;
2460- return callstack ;
2461- } ,
2462-
2463- emscripten_get_callstack__deps : [ '$getCallstack' , '$lengthBytesUTF8' , '$stringToUTF8' ] ,
2464- emscripten_get_callstack : function ( flags , str , maxbytes ) {
2465- var callstack = getCallstack ( flags ) ;
2466- // User can query the required amount of bytes to hold the callstack.
2467- if ( ! str || maxbytes <= 0 ) {
2468- return lengthBytesUTF8 ( callstack ) + 1 ;
2469- }
2470- // Output callstack string as C string to HEAP.
2471- var bytesWrittenExcludingNull = stringToUTF8 ( callstack , str , maxbytes ) ;
2472-
2473- // Return number of bytes written, including null.
2474- return bytesWrittenExcludingNull + 1 ;
2475- } ,
2476-
24772373 $emscriptenLog__deps : [ '$getCallstack' ] ,
24782374 $emscriptenLog : ( flags , str ) => {
24792375 if ( flags & { { { cDefs . EM_LOG_C_STACK | cDefs . EM_LOG_JS_STACK } } } ) {
@@ -2541,241 +2437,6 @@ addToLibrary({
25412437 else return lengthBytesUTF8 ( str ) ;
25422438 } ,
25432439
2544- // Generates a representation of the program counter from a line of stack trace.
2545- // The exact return value depends in whether we are running WASM or JS, and whether
2546- // the engine supports offsets into WASM. See the function body for details.
2547- $convertFrameToPC__docs : '/** @returns {number} */' ,
2548- $convertFrameToPC__internal : true ,
2549- $convertFrameToPC : ( frame ) => {
2550- #if ! USE_OFFSET_CONVERTER
2551- abort ( 'Cannot use convertFrameToPC (needed by __builtin_return_address) without -sUSE_OFFSET_CONVERTER' ) ;
2552- #else
2553- #if ASSERTIONS
2554- assert ( wasmOffsetConverter ) ;
2555- #endif
2556- var match ;
2557-
2558- if ( match = / \b w a s m - f u n c t i o n \[ \d + \] : ( 0 x [ 0 - 9 a - f ] + ) / . exec ( frame ) ) {
2559- // some engines give the binary offset directly, so we use that as return address
2560- return + match [ 1 ] ;
2561- } else if ( match = / \b w a s m - f u n c t i o n \[ ( \d + ) \] : ( \d + ) / . exec ( frame ) ) {
2562- // other engines only give function index and offset in the function,
2563- // so we try using the offset converter. If that doesn't work,
2564- // we pack index and offset into a "return address"
2565- return wasmOffsetConverter . convert ( + match [ 1 ] , + match [ 2 ] ) ;
2566- } else if ( match = / : ( \d + ) : \d + (?: \) | $ ) / . exec ( frame ) ) {
2567- // If we are in js, we can use the js line number as the "return address".
2568- // This should work for wasm2js. We tag the high bit to distinguish this
2569- // from wasm addresses.
2570- return 0x80000000 | + match [ 1 ] ;
2571- }
2572- #endif
2573- // return 0 if we can't find any
2574- return 0 ;
2575- } ,
2576-
2577- // Returns a representation of a call site of the caller of this function, in a manner
2578- // similar to __builtin_return_address. If level is 0, we return the call site of the
2579- // caller of this function.
2580- emscripten_return_address__deps : [ '$convertFrameToPC' , '$jsStackTrace' ] ,
2581- emscripten_return_address : ( level ) => {
2582- var callstack = jsStackTrace ( ) . split ( '\n' ) ;
2583- if ( callstack [ 0 ] == 'Error' ) {
2584- callstack . shift ( ) ;
2585- }
2586- // skip this function and the caller to get caller's return address
2587- #if MEMORY64
2588- // MEMORY64 injects and extra wrapper within emscripten_return_address
2589- // to handle BigInt conversions.
2590- var caller = callstack [ level + 4 ] ;
2591- #else
2592- var caller = callstack [ level + 3 ] ;
2593- #endif
2594- return convertFrameToPC ( caller ) ;
2595- } ,
2596-
2597- $UNWIND_CACHE : { } ,
2598-
2599- // This function pulls the JavaScript stack trace and updates UNWIND_CACHE so
2600- // that our representation of the program counter is mapped to the line of the
2601- // stack trace for every line in the stack trace. This allows
2602- // emscripten_pc_get_* to lookup the line of the stack trace from the PC and
2603- // return meaningful information.
2604- //
2605- // Additionally, it saves a copy of the entire stack trace and the return
2606- // address of the caller. This is because there are two common forms of a
2607- // stack trace. The first form starts the stack trace at the caller of the
2608- // function requesting a stack trace. In this case, the function can simply
2609- // walk down the stack from the return address using emscripten_return_address
2610- // with increasing values for level. The second form starts the stack trace
2611- // at the current function. This requires a helper function to get the program
2612- // counter. This helper function will return the return address. This is the
2613- // program counter at the call site. But there is a problem: when calling into
2614- // code that performs stack unwinding, the program counter has changed since
2615- // execution continued from calling the helper function. So we can't just walk
2616- // down the stack and expect to see the PC value we got. By caching the call
2617- // stack, we can call emscripten_stack_unwind with the PC value and use that
2618- // to unwind the cached stack. Naturally, the PC helper function will have to
2619- // call emscripten_stack_snapshot to cache the stack. We also return the
2620- // return address of the caller so the PC helper function does not need to
2621- // call emscripten_return_address, saving a lot of time.
2622- //
2623- // One might expect that a sensible solution is to call the stack unwinder and
2624- // explicitly tell it how many functions to skip from the stack. However,
2625- // existing libraries do not work this way. For example, compiler-rt's
2626- // sanitizer_common library has macros GET_CALLER_PC_BP_SP and
2627- // GET_CURRENT_PC_BP_SP, which obtains the PC value for the two common cases
2628- // stated above, respectively. Then, it passes the PC, BP, SP values along
2629- // until some other function uses them to unwind. On standard machines, the
2630- // stack can be unwound by treating BP as a linked list. This makes PC
2631- // unnecessary to walk the stack, since walking is done with BP, which remains
2632- // valid until the function returns. But on Emscripten, BP does not exist, at
2633- // least in JavaScript frames, so we have to rely on PC values. Therefore, we
2634- // must be able to unwind from a PC value that may no longer be on the
2635- // execution stack, and so we are forced to cache the entire call stack.
2636- emscripten_stack_snapshot__deps : [ '$convertFrameToPC' , '$UNWIND_CACHE' , '$saveInUnwindCache' , '$jsStackTrace' ] ,
2637- emscripten_stack_snapshot : function ( ) {
2638- var callstack = jsStackTrace ( ) . split ( '\n' ) ;
2639- if ( callstack [ 0 ] == 'Error' ) {
2640- callstack . shift ( ) ;
2641- }
2642- saveInUnwindCache ( callstack ) ;
2643-
2644- // Caches the stack snapshot so that emscripten_stack_unwind_buffer() can
2645- // unwind from this spot.
2646- UNWIND_CACHE . last_addr = convertFrameToPC ( callstack [ 3 ] ) ;
2647- UNWIND_CACHE . last_stack = callstack ;
2648- return UNWIND_CACHE . last_addr ;
2649- } ,
2650-
2651- $saveInUnwindCache__deps : [ '$UNWIND_CACHE' , '$convertFrameToPC' ] ,
2652- $saveInUnwindCache__internal : true ,
2653- $saveInUnwindCache : ( callstack ) => {
2654- callstack . forEach ( ( frame ) => {
2655- var pc = convertFrameToPC ( frame ) ;
2656- if ( pc ) {
2657- UNWIND_CACHE [ pc ] = frame ;
2658- }
2659- } ) ;
2660- } ,
2661-
2662- // Unwinds the stack from a cached PC value. See emscripten_stack_snapshot for
2663- // how this is used. addr must be the return address of the last call to
2664- // emscripten_stack_snapshot, or this function will instead use the current
2665- // call stack.
2666- emscripten_stack_unwind_buffer__deps : [ '$UNWIND_CACHE' , '$saveInUnwindCache' , '$convertFrameToPC' , '$jsStackTrace' ] ,
2667- emscripten_stack_unwind_buffer : ( addr , buffer , count ) => {
2668- var stack ;
2669- if ( UNWIND_CACHE . last_addr == addr ) {
2670- stack = UNWIND_CACHE . last_stack ;
2671- } else {
2672- stack = jsStackTrace ( ) . split ( '\n' ) ;
2673- if ( stack [ 0 ] == 'Error' ) {
2674- stack . shift ( ) ;
2675- }
2676- saveInUnwindCache ( stack ) ;
2677- }
2678-
2679- var offset = 3 ;
2680- while ( stack [ offset ] && convertFrameToPC ( stack [ offset ] ) != addr ) {
2681- ++ offset ;
2682- }
2683-
2684- for ( var i = 0 ; i < count && stack [ i + offset ] ; ++ i ) {
2685- { { { makeSetValue ( 'buffer' , 'i*4' , 'convertFrameToPC(stack[i + offset])' , 'i32' ) } } } ;
2686- }
2687- return i ;
2688- } ,
2689-
2690- // Look up the function name from our stack frame cache with our PC representation.
2691- #if USE_OFFSET_CONVERTER
2692- emscripten_pc_get_function__deps : [ '$UNWIND_CACHE' , 'free' , '$stringToNewUTF8' ] ,
2693- // Don't treat allocation of _emscripten_pc_get_function.ret as a leak
2694- emscripten_pc_get_function__noleakcheck : true ,
2695- #endif
2696- emscripten_pc_get_function : ( pc ) => {
2697- #if ! USE_OFFSET_CONVERTER
2698- abort ( 'Cannot use emscripten_pc_get_function without -sUSE_OFFSET_CONVERTER' ) ;
2699- return 0 ;
2700- #else
2701- var name ;
2702- if ( pc & 0x80000000 ) {
2703- // If this is a JavaScript function, try looking it up in the unwind cache.
2704- var frame = UNWIND_CACHE [ pc ] ;
2705- if ( ! frame ) return 0 ;
2706-
2707- var match ;
2708- if ( match = / ^ \s + a t ( .* ) \( .* \) $ / . exec ( frame ) ) {
2709- name = match [ 1 ] ;
2710- } else if ( match = / ^ ( .+ ?) @ / . exec ( frame ) ) {
2711- name = match [ 1 ] ;
2712- } else {
2713- return 0 ;
2714- }
2715- } else {
2716- name = wasmOffsetConverter . getName ( pc ) ;
2717- }
2718- if ( _emscripten_pc_get_function . ret ) _free ( _emscripten_pc_get_function . ret ) ;
2719- _emscripten_pc_get_function . ret = stringToNewUTF8 ( name ) ;
2720- return _emscripten_pc_get_function . ret ;
2721- #endif
2722- } ,
2723-
2724- $convertPCtoSourceLocation__deps: [ '$UNWIND_CACHE' , '$convertFrameToPC' ] ,
2725- $convertPCtoSourceLocation : ( pc ) => {
2726- if ( UNWIND_CACHE . last_get_source_pc == pc ) return UNWIND_CACHE . last_source ;
2727-
2728- var match ;
2729- var source ;
2730- #if LOAD_SOURCE_MAP
2731- if ( wasmSourceMap ) {
2732- source = wasmSourceMap . lookup ( pc ) ;
2733- }
2734- #endif
2735-
2736- if ( ! source ) {
2737- var frame = UNWIND_CACHE [ pc ] ;
2738- if ( ! frame ) return null ;
2739- // Example: at callMain (a.out.js:6335:22)
2740- if ( match = / \( ( .* ) : ( \d + ) : ( \d + ) \) $ / . exec ( frame ) ) {
2741- source = { file : match [ 1 ] , line : match [ 2 ] , column : match [ 3 ] } ;
2742- // Example: main@a .out.js:1337:42
2743- } else if ( match = / @ ( .* ) : ( \d + ) : ( \d + ) / . exec ( frame ) ) {
2744- source = { file : match [ 1 ] , line : match [ 2 ] , column : match [ 3 ] } ;
2745- }
2746- }
2747- UNWIND_CACHE . last_get_source_pc = pc ;
2748- UNWIND_CACHE . last_source = source ;
2749- return source ;
2750- } ,
2751-
2752- // Look up the file name from our stack frame cache with our PC representation.
2753- emscripten_pc_get_file__deps : [ '$convertPCtoSourceLocation' , 'free' , '$stringToNewUTF8' ] ,
2754- // Don't treat allocation of _emscripten_pc_get_file.ret as a leak
2755- emscripten_pc_get_file__noleakcheck : true ,
2756- emscripten_pc_get_file : ( pc ) = > {
2757- var result = convertPCtoSourceLocation ( pc ) ;
2758- if ( ! result ) return 0 ;
2759-
2760- if ( _emscripten_pc_get_file . ret ) _free ( _emscripten_pc_get_file . ret ) ;
2761- _emscripten_pc_get_file . ret = stringToNewUTF8 ( result . file ) ;
2762- return _emscripten_pc_get_file . ret ;
2763- } ,
2764-
2765- // Look up the line number from our stack frame cache with our PC representation.
2766- emscripten_pc_get_line__deps : [ '$convertPCtoSourceLocation' ] ,
2767- emscripten_pc_get_line : ( pc ) => {
2768- var result = convertPCtoSourceLocation ( pc ) ;
2769- return result ? result . line : 0 ;
2770- } ,
2771-
2772- // Look up the column number from our stack frame cache with our PC representation.
2773- emscripten_pc_get_column__deps : [ '$convertPCtoSourceLocation' ] ,
2774- emscripten_pc_get_column : ( pc ) => {
2775- var result = convertPCtoSourceLocation ( pc ) ;
2776- return result ? result . column || 0 : 0 ;
2777- } ,
2778-
27792440 emscripten_get_module_name__deps : [ '$stringToUTF8' ] ,
27802441 emscripten_get_module_name : ( buf , length ) => {
27812442#if MINIMAL_RUNTIME
0 commit comments