LCOV - code coverage report
Current view: top level - src - rtutils.c (source / functions) Hit Total Coverage
Test: [test only] commit 0f242327d2cc9bd130497f44b6350c924185606a Lines: 598 852 70.2 %
Date: 2022-07-16 23:42:53 Functions: 45 59 76.3 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 372 592 62.8 %

           Branch data     Line data    Source code
       1                 :            : // This file is a part of Julia. License is MIT: https://julialang.org/license
       2                 :            : 
       3                 :            : /*
       4                 :            :   utility functions used by the runtime system, generated code, and Base library
       5                 :            : */
       6                 :            : #include "platform.h"
       7                 :            : 
       8                 :            : #include <stdlib.h>
       9                 :            : #include <stdio.h>
      10                 :            : #include <string.h>
      11                 :            : #include <stdarg.h>
      12                 :            : #include <setjmp.h>
      13                 :            : #include <sys/types.h>
      14                 :            : #include <errno.h>
      15                 :            : #include <fcntl.h>
      16                 :            : #include <inttypes.h>
      17                 :            : #if defined(_OS_WINDOWS_)
      18                 :            : #include <malloc.h>
      19                 :            : #else
      20                 :            : #include <unistd.h>
      21                 :            : #endif
      22                 :            : #include <ctype.h>
      23                 :            : #include "julia.h"
      24                 :            : #include "julia_internal.h"
      25                 :            : #include "julia_assert.h"
      26                 :            : 
      27                 :            : #ifdef __cplusplus
      28                 :            : extern "C" {
      29                 :            : #endif
      30                 :            : 
      31                 :            : // exceptions -----------------------------------------------------------------
      32                 :            : 
      33                 :      11265 : JL_DLLEXPORT void JL_NORETURN jl_error(const char *str)
      34                 :            : {
      35         [ +  + ]:      11265 :     if (jl_errorexception_type == NULL) {
      36                 :          4 :         jl_printf(JL_STDERR, "ERROR: %s\n", str);
      37                 :          4 :         jl_exit(1);
      38                 :            :     }
      39                 :      11261 :     jl_value_t *msg = jl_pchar_to_string((char*)str, strlen(str));
      40                 :      11261 :     JL_GC_PUSH1(&msg);
      41                 :      11261 :     jl_throw(jl_new_struct(jl_errorexception_type, msg));
      42                 :            : }
      43                 :            : 
      44                 :            : extern int vasprintf(char **str, const char *fmt, va_list ap);
      45                 :            : 
      46                 :      21466 : jl_value_t *jl_vexceptionf(jl_datatype_t *exception_type,
      47                 :            :                            const char *fmt, va_list args)
      48                 :            : {
      49         [ +  + ]:      21466 :     if (exception_type == NULL) {
      50                 :         26 :         jl_printf(JL_STDERR, "ERROR: ");
      51                 :         26 :         jl_vprintf(JL_STDERR, fmt, args);
      52                 :         26 :         jl_printf(JL_STDERR, "\n");
      53                 :         26 :         jl_exit(1);
      54                 :            :     }
      55                 :      21440 :     char *str = NULL;
      56                 :      21440 :     int ok = vasprintf(&str, fmt, args);
      57                 :            :     jl_value_t *msg;
      58         [ -  + ]:      21440 :     if (ok < 0) {  // vasprintf failed
      59                 :          0 :         msg = jl_cstr_to_string("internal error: could not display error message");
      60                 :            :     }
      61                 :            :     else {
      62                 :      21440 :         msg = jl_pchar_to_string(str, strlen(str));
      63                 :      21440 :         free(str);
      64                 :            :     }
      65                 :      21440 :     JL_GC_PUSH1(&msg);
      66                 :      21440 :     jl_value_t *e = jl_new_struct(exception_type, msg);
      67                 :      21440 :     JL_GC_POP();
      68                 :      21440 :     return e;
      69                 :            : }
      70                 :            : 
      71                 :      21408 : JL_DLLEXPORT void JL_NORETURN jl_errorf(const char *fmt, ...)
      72                 :            : {
      73                 :            :     va_list args;
      74                 :      21408 :     va_start(args, fmt);
      75                 :      21408 :     jl_value_t *e = jl_vexceptionf(jl_errorexception_type, fmt, args);
      76                 :      21382 :     va_end(args);
      77                 :      21382 :     jl_throw(e);
      78                 :            : }
      79                 :            : 
      80                 :         22 : JL_DLLEXPORT void JL_NORETURN jl_exceptionf(jl_datatype_t *exception_type,
      81                 :            :                                             const char *fmt, ...)
      82                 :            : {
      83                 :            :     va_list args;
      84                 :         22 :     va_start(args, fmt);
      85                 :         22 :     jl_value_t *e = jl_vexceptionf(exception_type, fmt, args);
      86                 :         22 :     va_end(args);
      87                 :         22 :     jl_throw(e);
      88                 :            : }
      89                 :            : 
      90                 :          0 : jl_value_t *jl_get_exceptionf(jl_datatype_t *exception_type,
      91                 :            :                               const char *fmt, ...)
      92                 :            : {
      93                 :            :     va_list args;
      94                 :          0 :     va_start(args, fmt);
      95                 :          0 :     jl_value_t *e = jl_vexceptionf(exception_type, fmt, args);
      96                 :          0 :     va_end(args);
      97                 :          0 :     return e;
      98                 :            : }
      99                 :            : 
     100                 :          5 : JL_DLLEXPORT void JL_NORETURN jl_too_few_args(const char *fname, int min)
     101                 :            : {
     102                 :          5 :     jl_exceptionf(jl_argumenterror_type, "%s: too few arguments (expected %d)", fname, min);
     103                 :            : }
     104                 :            : 
     105                 :          0 : JL_DLLEXPORT void JL_NORETURN jl_too_many_args(const char *fname, int max)
     106                 :            : {
     107                 :          0 :     jl_exceptionf(jl_argumenterror_type, "%s: too many arguments (expected %d)", fname, max);
     108                 :            : }
     109                 :            : 
     110                 :            : // with function name / location description, plus extra context
     111                 :       2192 : JL_DLLEXPORT void JL_NORETURN jl_type_error_rt(const char *fname, const char *context,
     112                 :            :                                                jl_value_t *expected JL_MAYBE_UNROOTED,
     113                 :            :                                                jl_value_t *got JL_MAYBE_UNROOTED)
     114                 :            : {
     115                 :       2192 :     jl_value_t *ctxt=NULL;
     116                 :       2192 :     JL_GC_PUSH3(&ctxt, &expected, &got);
     117                 :       2192 :     ctxt = jl_pchar_to_string((char*)context, strlen(context));
     118                 :       2192 :     jl_value_t *ex = jl_new_struct(jl_typeerror_type, jl_symbol(fname), ctxt, expected, got);
     119                 :       2192 :     jl_throw(ex);
     120                 :            : }
     121                 :            : 
     122                 :            : // with function name or description only
     123                 :        163 : JL_DLLEXPORT void JL_NORETURN jl_type_error(const char *fname,
     124                 :            :                                             jl_value_t *expected JL_MAYBE_UNROOTED,
     125                 :            :                                             jl_value_t *got JL_MAYBE_UNROOTED)
     126                 :            : {
     127                 :        163 :     jl_type_error_rt(fname, "", expected, got);
     128                 :            : }
     129                 :            : 
     130                 :         91 : JL_DLLEXPORT void JL_NORETURN jl_undefined_var_error(jl_sym_t *var)
     131                 :            : {
     132                 :         91 :     jl_throw(jl_new_struct(jl_undefvarerror_type, var));
     133                 :            : }
     134                 :            : 
     135                 :       2080 : JL_DLLEXPORT void JL_NORETURN jl_atomic_error(char *str) // == jl_exceptionf(jl_atomicerror_type, "%s", str)
     136                 :            : {
     137                 :       2080 :     jl_value_t *msg = jl_pchar_to_string((char*)str, strlen(str));
     138                 :       2080 :     JL_GC_PUSH1(&msg);
     139                 :       2080 :     jl_throw(jl_new_struct(jl_atomicerror_type, msg));
     140                 :            : }
     141                 :            : 
     142                 :            : 
     143                 :         73 : JL_DLLEXPORT void JL_NORETURN jl_bounds_error(jl_value_t *v, jl_value_t *t)
     144                 :            : {
     145                 :         73 :     JL_GC_PUSH2(&v, &t); // root arguments so the caller doesn't need to
     146                 :         73 :     jl_throw(jl_new_struct((jl_datatype_t*)jl_boundserror_type, v, t));
     147                 :            : }
     148                 :            : 
     149                 :          0 : JL_DLLEXPORT void JL_NORETURN jl_bounds_error_v(jl_value_t *v, jl_value_t **idxs, size_t nidxs)
     150                 :            : {
     151                 :          0 :     jl_value_t *t = NULL;
     152                 :            :     // items in idxs are assumed to already be rooted
     153                 :          0 :     JL_GC_PUSH2(&v, &t); // root v so the caller doesn't need to
     154                 :          0 :     t = jl_f_tuple(NULL, idxs, nidxs);
     155                 :          0 :     jl_throw(jl_new_struct((jl_datatype_t*)jl_boundserror_type, v, t));
     156                 :            : }
     157                 :            : 
     158                 :          1 : JL_DLLEXPORT void JL_NORETURN jl_bounds_error_tuple_int(jl_value_t **v, size_t nv, size_t i)
     159                 :            : {
     160                 :            :     // values in v are expected to already be gc-rooted
     161                 :          1 :     jl_bounds_error_int(jl_f_tuple(NULL, v, nv), i);
     162                 :            : }
     163                 :            : 
     164                 :         52 : JL_DLLEXPORT void JL_NORETURN jl_bounds_error_unboxed_int(void *data, jl_value_t *vt, size_t i)
     165                 :            : {
     166                 :         52 :     jl_value_t *t = NULL, *v = NULL;
     167                 :            :     // data is expected to be gc-safe (either gc-rooted, or alloca)
     168                 :            :     // vt is expected to be gc-rooted (in a linfo-root probably)
     169                 :         52 :     JL_GC_PUSH2(&v, &t);
     170                 :         52 :     v = jl_new_bits(vt, data);
     171                 :         52 :     t = jl_box_long(i);
     172                 :         52 :     jl_throw(jl_new_struct((jl_datatype_t*)jl_boundserror_type, v, t));
     173                 :            : }
     174                 :            : 
     175                 :       8282 : JL_DLLEXPORT void JL_NORETURN jl_bounds_error_int(jl_value_t *v JL_MAYBE_UNROOTED, size_t i)
     176                 :            : {
     177                 :       8282 :     jl_value_t *t = NULL;
     178                 :       8282 :     JL_GC_PUSH2(&v, &t); // root arguments so the caller doesn't need to
     179                 :       8282 :     t = jl_box_long(i);
     180                 :       8282 :     jl_throw(jl_new_struct((jl_datatype_t*)jl_boundserror_type, v, t));
     181                 :            : }
     182                 :            : 
     183                 :         71 : JL_DLLEXPORT void JL_NORETURN jl_bounds_error_ints(jl_value_t *v JL_MAYBE_UNROOTED,
     184                 :            :                                                    size_t *idxs, size_t nidxs)
     185                 :            : {
     186                 :            :     size_t i;
     187                 :         71 :     jl_value_t *t = NULL;
     188                 :         71 :     JL_GC_PUSH2(&v, &t); // root arguments so the caller doesn't need to
     189                 :         71 :     t = (jl_value_t*)jl_alloc_svec(nidxs);
     190         [ +  + ]:        160 :     for (i = 0; i < nidxs; i++) {
     191                 :         89 :         jl_svecset(t, i, jl_box_long(idxs[i]));
     192                 :            :     }
     193                 :         71 :     t = jl_f_tuple(NULL, jl_svec_data(t), nidxs);
     194                 :         71 :     jl_throw(jl_new_struct((jl_datatype_t*)jl_boundserror_type, v, t));
     195                 :            : }
     196                 :            : 
     197                 :          2 : JL_DLLEXPORT void JL_NORETURN jl_eof_error(void)
     198                 :            : {
     199                 :            :     jl_datatype_t *eof_error =
     200                 :          2 :         (jl_datatype_t*)jl_get_global(jl_base_module, jl_symbol("EOFError"));
     201         [ -  + ]:          2 :     assert(eof_error != NULL);
     202                 :          2 :     jl_throw(jl_new_struct(eof_error));
     203                 :            : }
     204                 :            : 
     205                 :            : // get kwsorter field, with appropriate error check and message
     206                 :     194902 : JL_DLLEXPORT jl_value_t *jl_get_keyword_sorter(jl_value_t *f)
     207                 :            : {
     208                 :     194902 :     return jl_get_kwsorter(jl_typeof(f));
     209                 :            : }
     210                 :            : 
     211                 :   38016100 : JL_DLLEXPORT void jl_typeassert(jl_value_t *x, jl_value_t *t)
     212                 :            : {
     213         [ +  + ]:   38016100 :     if (!jl_isa(x,t))
     214                 :          6 :         jl_type_error("typeassert", t, x);
     215                 :   38016100 : }
     216                 :            : 
     217                 :            : #ifndef HAVE_SSP
     218                 :            : JL_DLLEXPORT uintptr_t __stack_chk_guard = (uintptr_t)0xBAD57ACCBAD67ACC; // 0xBADSTACKBADSTACK
     219                 :            : 
     220                 :          0 : JL_DLLEXPORT void __stack_chk_fail(void)
     221                 :            : {
     222                 :            :     /* put your panic function or similar in here */
     223                 :          0 :     fprintf(stderr, "fatal error: stack corruption detected\n");
     224                 :          0 :     jl_gc_debug_critical_error();
     225                 :          0 :     abort(); // end with abort, since the compiler destroyed the stack upon entry to this function, there's no going back now
     226                 :            : }
     227                 :            : #endif
     228                 :            : 
     229                 :            : // exceptions -----------------------------------------------------------------
     230                 :            : 
     231                 :   96273900 : JL_DLLEXPORT void jl_enter_handler(jl_handler_t *eh)
     232                 :            : {
     233                 :   96273900 :     jl_task_t *ct = jl_current_task;
     234                 :            :     // Must have no safepoint
     235                 :   96273900 :     eh->prev = ct->eh;
     236                 :   96273900 :     eh->gcstack = ct->gcstack;
     237                 :   96273900 :     eh->gc_state = jl_atomic_load_relaxed(&ct->ptls->gc_state);
     238                 :   96273900 :     eh->locks_len = ct->ptls->locks.len;
     239                 :   96273900 :     eh->defer_signal = ct->ptls->defer_signal;
     240                 :   96273900 :     eh->world_age = ct->world_age;
     241                 :   96273900 :     ct->eh = eh;
     242                 :            : #ifdef ENABLE_TIMINGS
     243                 :            :     eh->timing_stack = ct->ptls->timing_stack;
     244                 :            : #endif
     245                 :   96273900 : }
     246                 :            : 
     247                 :            : // Restore thread local state to saved state in error handler `eh`.
     248                 :            : // This is executed in two circumstances:
     249                 :            : // * We leave a try block through normal control flow
     250                 :            : // * An exception causes a nonlocal jump to the catch block. In this case
     251                 :            : //   there's additional cleanup required, eg pushing the exception stack.
     252                 :   91420300 : JL_DLLEXPORT void jl_eh_restore_state(jl_handler_t *eh)
     253                 :            : {
     254                 :   91420300 :     jl_task_t *ct = jl_current_task;
     255                 :            : #ifdef _OS_WINDOWS_
     256                 :            :     if (ct->ptls->needs_resetstkoflw) {
     257                 :            :         _resetstkoflw();
     258                 :            :         ct->ptls->needs_resetstkoflw = 0;
     259                 :            :     }
     260                 :            : #endif
     261                 :            :     // `eh` may be not equal to `ct->eh`. See `jl_pop_handler`
     262                 :            :     // This function should **NOT** have any safepoint before the ones at the
     263                 :            :     // end.
     264                 :   91420300 :     sig_atomic_t old_defer_signal = ct->ptls->defer_signal;
     265                 :   91420300 :     int8_t old_gc_state = jl_atomic_load_relaxed(&ct->ptls->gc_state);
     266                 :   91420300 :     ct->eh = eh->prev;
     267                 :   91420300 :     ct->gcstack = eh->gcstack;
     268                 :   91420300 :     small_arraylist_t *locks = &ct->ptls->locks;
     269                 :   91420300 :     int unlocks = locks->len > eh->locks_len;
     270         [ +  + ]:   91420300 :     if (unlocks) {
     271         [ +  + ]:      62637 :         for (size_t i = locks->len; i > eh->locks_len; i--)
     272                 :      31319 :             jl_mutex_unlock_nogc((jl_mutex_t*)locks->items[i - 1]);
     273                 :      31318 :         locks->len = eh->locks_len;
     274                 :            :     }
     275                 :   91420300 :     ct->world_age = eh->world_age;
     276                 :   91420300 :     ct->ptls->defer_signal = eh->defer_signal;
     277         [ -  + ]:   91420300 :     if (old_gc_state != eh->gc_state) {
     278                 :          0 :         jl_atomic_store_release(&ct->ptls->gc_state, eh->gc_state);
     279         [ #  # ]:          0 :         if (old_gc_state) {
     280                 :          0 :             jl_gc_safepoint_(ct->ptls);
     281                 :            :         }
     282                 :            :     }
     283   [ +  +  +  + ]:   91420300 :     if (old_defer_signal && !eh->defer_signal) {
     284                 :      21898 :         jl_sigint_safepoint(ct->ptls);
     285                 :            :     }
     286   [ +  +  +  + ]:   91420300 :     if (jl_atomic_load_relaxed(&jl_gc_have_pending_finalizers) &&
     287         [ +  + ]:       1313 :             unlocks && eh->locks_len == 0) {
     288                 :          5 :         jl_gc_run_pending_finalizers(ct);
     289                 :            :     }
     290                 :   91420300 : }
     291                 :            : 
     292                 :   63305700 : JL_DLLEXPORT void jl_pop_handler(int n)
     293                 :            : {
     294                 :   63305700 :     jl_task_t *ct = jl_current_task;
     295         [ -  + ]:   63305700 :     if (__unlikely(n <= 0))
     296                 :          0 :         return;
     297                 :   63305700 :     jl_handler_t *eh = ct->eh;
     298         [ +  + ]:   64484700 :     while (--n > 0)
     299                 :    1178960 :         eh = eh->prev;
     300                 :   63305700 :     jl_eh_restore_state(eh);
     301                 :            : }
     302                 :            : 
     303                 :   96346500 : JL_DLLEXPORT size_t jl_excstack_state(void) JL_NOTSAFEPOINT
     304                 :            : {
     305                 :   96346500 :     jl_task_t *ct = jl_current_task;
     306                 :   96346500 :     jl_excstack_t *s = ct->excstack;
     307         [ +  + ]:   96346500 :     return s ? s->top : 0;
     308                 :            : }
     309                 :            : 
     310                 :     253298 : JL_DLLEXPORT void jl_restore_excstack(size_t state) JL_NOTSAFEPOINT
     311                 :            : {
     312                 :     253298 :     jl_task_t *ct = jl_current_task;
     313                 :     253298 :     jl_excstack_t *s = ct->excstack;
     314         [ +  - ]:     253298 :     if (s) {
     315         [ -  + ]:     253298 :         assert(s->top >= state);
     316                 :     253298 :         s->top = state;
     317                 :            :     }
     318                 :     253298 : }
     319                 :            : 
     320                 :       1454 : static void jl_copy_excstack(jl_excstack_t *dest, jl_excstack_t *src) JL_NOTSAFEPOINT
     321                 :            : {
     322         [ -  + ]:       1454 :     assert(dest->reserved_size >= src->top);
     323                 :       1454 :     memcpy(jl_excstack_raw(dest), jl_excstack_raw(src), sizeof(jl_bt_element_t)*src->top);
     324                 :       1454 :     dest->top = src->top;
     325                 :       1454 : }
     326                 :            : 
     327                 :     253874 : static void jl_reserve_excstack(jl_excstack_t **stack JL_REQUIRE_ROOTED_SLOT,
     328                 :            :                                 size_t reserved_size)
     329                 :            : {
     330                 :     253874 :     jl_excstack_t *s = *stack;
     331   [ +  +  +  + ]:     253874 :     if (s && s->reserved_size >= reserved_size)
     332                 :     248300 :         return;
     333                 :       5574 :     size_t bufsz = sizeof(jl_excstack_t) + sizeof(uintptr_t)*reserved_size;
     334                 :       5574 :     jl_task_t *ct = jl_current_task;
     335                 :       5574 :     jl_excstack_t *new_s = (jl_excstack_t*)jl_gc_alloc_buf(ct->ptls, bufsz);
     336                 :       5574 :     new_s->top = 0;
     337                 :       5574 :     new_s->reserved_size = reserved_size;
     338         [ +  + ]:       5574 :     if (s)
     339                 :       1454 :         jl_copy_excstack(new_s, s);
     340                 :       5574 :     *stack = new_s;
     341                 :            : }
     342                 :            : 
     343                 :     253874 : void jl_push_excstack(jl_excstack_t **stack JL_REQUIRE_ROOTED_SLOT JL_ROOTING_ARGUMENT,
     344                 :            :                       jl_value_t *exception JL_ROOTED_ARGUMENT,
     345                 :            :                       jl_bt_element_t *bt_data, size_t bt_size)
     346                 :            : {
     347         [ +  + ]:     253874 :     jl_reserve_excstack(stack, (*stack ? (*stack)->top : 0) + bt_size + 2);
     348                 :     253874 :     jl_excstack_t *s = *stack;
     349                 :     253874 :     jl_bt_element_t *rawstack = jl_excstack_raw(s);
     350                 :     253874 :     memcpy(rawstack + s->top, bt_data, sizeof(jl_bt_element_t)*bt_size);
     351                 :     253874 :     s->top += bt_size + 2;
     352                 :     253874 :     rawstack[s->top-2].uintptr = bt_size;
     353                 :     253874 :     rawstack[s->top-1].jlvalue = exception;
     354                 :     253874 : }
     355                 :            : 
     356                 :            : // conversion -----------------------------------------------------------------
     357                 :            : 
     358                 :          0 : JL_DLLEXPORT void *(jl_symbol_name)(jl_sym_t *s)
     359                 :            : {
     360                 :          0 :     return jl_symbol_name(s);
     361                 :            : }
     362                 :            : 
     363                 :            : // WARNING: THIS FUNCTION IS NEVER CALLED BUT INLINE BY CCALL
     364                 :          0 : JL_DLLEXPORT void *jl_array_ptr(jl_array_t *a)
     365                 :            : {
     366                 :          0 :     return a->data;
     367                 :            : }
     368                 :          0 : JL_DLLEXPORT jl_value_t *jl_value_ptr(jl_value_t *a)
     369                 :            : {
     370                 :          0 :     return a;
     371                 :            : }
     372                 :            : 
     373                 :            : // optimization of setfield which bypasses boxing of the idx (and checking field type validity)
     374                 :       6247 : JL_DLLEXPORT void jl_set_nth_field(jl_value_t *v, size_t idx0, jl_value_t *rhs)
     375                 :            : {
     376                 :       6247 :     jl_datatype_t *st = (jl_datatype_t*)jl_typeof(v);
     377         [ +  + ]:       6247 :     if (!st->name->mutabl)
     378                 :          1 :         jl_errorf("setfield!: immutable struct of type %s cannot be changed", jl_symbol_name(st->name->name));
     379         [ +  + ]:       6246 :     if (idx0 >= jl_datatype_nfields(st))
     380                 :          1 :         jl_bounds_error_int(v, idx0 + 1);
     381                 :            :     //jl_value_t *ft = jl_field_type(st, idx0);
     382                 :            :     //if (!jl_isa(rhs, ft)) {
     383                 :            :     //    jl_type_error("setfield!", ft, rhs);
     384                 :            :     //}
     385                 :            :     //int isatomic = jl_field_isatomic(st, idx0);
     386                 :            :     //if (isatomic) ...
     387                 :       6245 :     set_nth_field(st, v, idx0, rhs, 0);
     388                 :       6245 : }
     389                 :            : 
     390                 :            : 
     391                 :            : // parsing --------------------------------------------------------------------
     392                 :            : 
     393                 :      45368 : static int substr_isspace(char *p, char *pend)
     394                 :            : {
     395         [ +  + ]:      49093 :     while (p != pend) {
     396         [ +  + ]:       3741 :         if (!isspace((unsigned char)*p)) {
     397                 :         16 :             return 0;
     398                 :            :         }
     399                 :       3725 :         p++;
     400                 :            :     }
     401                 :      45352 :     return 1;
     402                 :            : }
     403                 :            : 
     404                 :      15345 : JL_DLLEXPORT jl_nullable_float64_t jl_try_substrtod(char *str, size_t offset, size_t len)
     405                 :            : {
     406                 :            :     char *p;
     407                 :      15345 :     char *bstr = str+offset;
     408                 :      15345 :     char *pend = bstr+len;
     409                 :      15345 :     char *tofree = NULL;
     410                 :      15345 :     int hasvalue = 0;
     411                 :            : 
     412                 :      15345 :     errno = 0;
     413   [ +  +  +  +  :      15345 :     if (!(*pend == '\0' || isspace((unsigned char)*pend) || *pend == ',')) {
                   +  + ]
     414                 :            :         // confusing data outside substring. must copy.
     415                 :            :         char *newstr;
     416         [ +  - ]:      11165 :         if (len + 1 < jl_page_size) {
     417                 :      11165 :             newstr = (char*)alloca(len + 1);
     418                 :            :         }
     419                 :            :         else {
     420                 :          0 :             newstr = tofree = (char*)malloc_s(len + 1);
     421                 :            :         }
     422                 :      11165 :         memcpy(newstr, bstr, len);
     423                 :      11165 :         newstr[len] = 0;
     424                 :      11165 :         bstr = newstr;
     425                 :      11165 :         pend = bstr+len;
     426                 :            :     }
     427                 :      15345 :     double out = jl_strtod_c(bstr, &p);
     428                 :            : 
     429   [ -  +  -  -  :      15345 :     if (errno==ERANGE && (out==0 || out==HUGE_VAL || out==-HUGE_VAL)) {
             -  -  -  - ]
     430                 :          0 :         hasvalue = 0;
     431                 :            :     }
     432         [ +  + ]:      15345 :     else if (p == bstr) {
     433                 :        709 :         hasvalue = 0;
     434                 :            :     }
     435                 :            :     else {
     436                 :            :         // Deal with case where the substring might be something like "1 ",
     437                 :            :         // which is OK, and "1 X", which we don't allow.
     438                 :      14636 :         hasvalue = substr_isspace(p, pend) ? 1 : 0;
     439                 :            :     }
     440                 :            : 
     441         [ -  + ]:      15345 :     if (__unlikely(tofree))
     442                 :          0 :         free(tofree);
     443                 :            : 
     444                 :      15345 :     jl_nullable_float64_t ret = {(uint8_t)hasvalue, out};
     445                 :      15345 :     return ret;
     446                 :            : }
     447                 :            : 
     448                 :          0 : JL_DLLEXPORT int jl_substrtod(char *str, size_t offset, size_t len, double *out)
     449                 :            : {
     450                 :          0 :     jl_nullable_float64_t nd = jl_try_substrtod(str, offset, len);
     451         [ #  # ]:          0 :     if (0 != nd.hasvalue) {
     452                 :          0 :         *out = nd.value;
     453                 :          0 :         return 0;
     454                 :            :     }
     455                 :          0 :     return 1;
     456                 :            : }
     457                 :            : 
     458                 :            : // MSVC pre-2013 did not define HUGE_VALF
     459                 :            : #ifndef HUGE_VALF
     460                 :            : #define HUGE_VALF (1e25f * 1e25f)
     461                 :            : #endif
     462                 :            : 
     463                 :      30732 : JL_DLLEXPORT jl_nullable_float32_t jl_try_substrtof(char *str, size_t offset, size_t len)
     464                 :            : {
     465                 :            :     char *p;
     466                 :      30732 :     char *bstr = str+offset;
     467                 :      30732 :     char *pend = bstr+len;
     468                 :      30732 :     char *tofree = NULL;
     469                 :      30732 :     int hasvalue = 0;
     470                 :            : 
     471                 :      30732 :     errno = 0;
     472   [ +  +  +  -  :      30732 :     if (!(*pend == '\0' || isspace((unsigned char)*pend) || *pend == ',')) {
                   +  + ]
     473                 :            :         // confusing data outside substring. must copy.
     474                 :            :         char *newstr;
     475         [ +  - ]:          3 :         if (len + 1 < jl_page_size) {
     476                 :          3 :             newstr = (char*)alloca(len + 1);
     477                 :            :         }
     478                 :            :         else {
     479                 :          0 :             newstr = tofree = (char*)malloc_s(len + 1);
     480                 :            :         }
     481                 :          3 :         memcpy(newstr, bstr, len);
     482                 :          3 :         newstr[len] = 0;
     483                 :          3 :         bstr = newstr;
     484                 :          3 :         pend = bstr+len;
     485                 :            :     }
     486                 :            : #if defined(_OS_WINDOWS_) && !defined(_COMPILER_GCC_)
     487                 :            :     float out = (float)jl_strtod_c(bstr, &p);
     488                 :            : #else
     489                 :      30732 :     float out = jl_strtof_c(bstr, &p);
     490                 :            : #endif
     491                 :            : 
     492   [ -  +  -  -  :      30732 :     if (errno==ERANGE && (out==0 || out==HUGE_VALF || out==-HUGE_VALF)) {
             -  -  -  - ]
     493                 :          0 :         hasvalue = 0;
     494                 :            :     }
     495         [ -  + ]:      30732 :     else if (p == bstr) {
     496                 :          0 :         hasvalue = 0;
     497                 :            :     }
     498                 :            :     else {
     499                 :            :         // Deal with case where the substring might be something like "1 ",
     500                 :            :         // which is OK, and "1 X", which we don't allow.
     501                 :      30732 :         hasvalue = substr_isspace(p, pend) ? 1 : 0;
     502                 :            :     }
     503                 :            : 
     504         [ -  + ]:      30732 :     if (__unlikely(tofree))
     505                 :          0 :         free(tofree);
     506                 :            : 
     507                 :      30732 :     jl_nullable_float32_t ret = {(uint8_t)hasvalue, out};
     508                 :      30732 :     return ret;
     509                 :            : }
     510                 :            : 
     511                 :          0 : JL_DLLEXPORT int jl_substrtof(char *str, int offset, size_t len, float *out)
     512                 :            : {
     513                 :          0 :     jl_nullable_float32_t nf = jl_try_substrtof(str, offset, len);
     514         [ #  # ]:          0 :     if (0 != nf.hasvalue) {
     515                 :          0 :         *out = nf.value;
     516                 :          0 :         return 0;
     517                 :            :     }
     518                 :          0 :     return 1;
     519                 :            : }
     520                 :            : 
     521                 :            : // showing --------------------------------------------------------------------
     522                 :            : 
     523                 :        574 : JL_DLLEXPORT void jl_flush_cstdio(void) JL_NOTSAFEPOINT
     524                 :            : {
     525                 :        574 :     fflush(stdout);
     526                 :        574 :     fflush(stderr);
     527                 :        574 : }
     528                 :            : 
     529                 :          0 : JL_DLLEXPORT jl_value_t *jl_stdout_obj(void) JL_NOTSAFEPOINT
     530                 :            : {
     531         [ #  # ]:          0 :     if (jl_base_module == NULL)
     532                 :          0 :         return NULL;
     533                 :          0 :     jl_binding_t *stdout_obj = jl_get_module_binding(jl_base_module, jl_symbol("stdout"));
     534         [ #  # ]:          0 :     return stdout_obj ? jl_atomic_load_relaxed(&stdout_obj->value) : NULL;
     535                 :            : }
     536                 :            : 
     537                 :          0 : JL_DLLEXPORT jl_value_t *jl_stderr_obj(void) JL_NOTSAFEPOINT
     538                 :            : {
     539         [ #  # ]:          0 :     if (jl_base_module == NULL)
     540                 :          0 :         return NULL;
     541                 :          0 :     jl_binding_t *stderr_obj = jl_get_module_binding(jl_base_module, jl_symbol("stderr"));
     542         [ #  # ]:          0 :     return stderr_obj ? jl_atomic_load_relaxed(&stderr_obj->value) : NULL;
     543                 :            : }
     544                 :            : 
     545                 :            : // toys for debugging ---------------------------------------------------------
     546                 :            : 
     547                 :          0 : static size_t jl_show_svec(JL_STREAM *out, jl_svec_t *t, const char *head, const char *opn, const char *cls) JL_NOTSAFEPOINT
     548                 :            : {
     549                 :          0 :     size_t i, n=0, len = jl_svec_len(t);
     550                 :          0 :     n += jl_printf(out, "%s", head);
     551                 :          0 :     n += jl_printf(out, "%s", opn);
     552         [ #  # ]:          0 :     for (i = 0; i < len; i++) {
     553                 :          0 :         jl_value_t *v = jl_svecref(t,i);
     554                 :          0 :         n += jl_static_show(out, v);
     555         [ #  # ]:          0 :         if (i != len-1)
     556                 :          0 :             n += jl_printf(out, ", ");
     557                 :            :     }
     558                 :          0 :     n += jl_printf(out, "%s", cls);
     559                 :          0 :     return n;
     560                 :            : }
     561                 :            : 
     562                 :            : struct recur_list {
     563                 :            :     struct recur_list *prev;
     564                 :            :     jl_value_t *v;
     565                 :            : };
     566                 :            : 
     567                 :            : static size_t jl_static_show_x(JL_STREAM *out, jl_value_t *v, struct recur_list *depth) JL_NOTSAFEPOINT;
     568                 :            : static size_t jl_static_show_next_(JL_STREAM *out, jl_value_t *v, jl_value_t *prev, struct recur_list *depth) JL_NOTSAFEPOINT;
     569                 :            : 
     570                 :            : JL_DLLEXPORT int jl_id_start_char(uint32_t wc) JL_NOTSAFEPOINT;
     571                 :            : JL_DLLEXPORT int jl_id_char(uint32_t wc) JL_NOTSAFEPOINT;
     572                 :            : 
     573                 :      11750 : JL_DLLEXPORT int jl_is_identifier(char *str) JL_NOTSAFEPOINT
     574                 :            : {
     575                 :      11750 :     size_t i = 0;
     576                 :      11750 :     uint32_t wc = u8_nextchar(str, &i);
     577         [ +  + ]:      11750 :     if (!jl_id_start_char(wc))
     578                 :        593 :         return 0;
     579         [ +  + ]:      72068 :     while ((wc = u8_nextchar(str, &i)) != 0) {
     580         [ +  + ]:      60921 :         if (!jl_id_char(wc))
     581                 :         10 :             return 0;
     582                 :            :     }
     583                 :      11147 :     return 1;
     584                 :            : }
     585                 :            : 
     586                 :      26614 : static jl_datatype_t *first_arg_datatype(jl_value_t *a JL_PROPAGATES_ROOT, int got_tuple1) JL_NOTSAFEPOINT
     587                 :            : {
     588         [ +  + ]:      26614 :     if (jl_is_datatype(a)) {
     589         [ +  + ]:      19693 :         if (got_tuple1)
     590                 :      13294 :             return (jl_datatype_t*)a;
     591         [ +  - ]:       6399 :         if (jl_is_tuple_type(a)) {
     592         [ -  + ]:       6399 :             if (jl_nparams(a) < 1)
     593                 :          0 :                 return NULL;
     594                 :       6399 :             return first_arg_datatype(jl_tparam0(a), 1);
     595                 :            :         }
     596                 :          0 :         return NULL;
     597                 :            :     }
     598         [ +  + ]:       6921 :     else if (jl_is_typevar(a)) {
     599                 :         50 :         return first_arg_datatype(((jl_tvar_t*)a)->ub, got_tuple1);
     600                 :            :     }
     601         [ +  + ]:       6871 :     else if (jl_is_unionall(a)) {
     602                 :       6840 :         return first_arg_datatype(((jl_unionall_t*)a)->body, got_tuple1);
     603                 :            :     }
     604         [ +  + ]:         31 :     else if (jl_is_uniontype(a)) {
     605                 :         25 :         jl_uniontype_t *u = (jl_uniontype_t*)a;
     606                 :         25 :         jl_datatype_t *d1 = first_arg_datatype(u->a, got_tuple1);
     607         [ -  + ]:         25 :         if (d1 == NULL) return NULL;
     608                 :         25 :         jl_datatype_t *d2 = first_arg_datatype(u->b, got_tuple1);
     609   [ +  +  +  + ]:         25 :         if (d2 == NULL || d1->name != d2->name)
     610                 :         21 :             return NULL;
     611                 :          4 :         return d1;
     612                 :            :     }
     613                 :          6 :     return NULL;
     614                 :            : }
     615                 :            : 
     616                 :            : // get DataType of first tuple element (if present), or NULL if cannot be determined
     617                 :       6399 : JL_DLLEXPORT jl_datatype_t *jl_first_argument_datatype(jl_value_t *argtypes JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT
     618                 :            : {
     619                 :       6399 :     return first_arg_datatype(argtypes, 0);
     620                 :            : }
     621                 :            : 
     622                 :            : // get DataType implied by a single given type, or `nothing`
     623                 :       6876 : JL_DLLEXPORT jl_value_t *jl_argument_datatype(jl_value_t *argt JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT
     624                 :            : {
     625                 :       6876 :     jl_datatype_t *dt = first_arg_datatype(argt, 1);
     626         [ +  + ]:       6876 :     if (dt == NULL)
     627                 :         11 :         return jl_nothing;
     628                 :       6865 :     return (jl_value_t*)dt;
     629                 :            : }
     630                 :            : 
     631                 :      13641 : static int is_globname_binding(jl_value_t *v, jl_datatype_t *dv) JL_NOTSAFEPOINT
     632                 :            : {
     633         [ +  + ]:      13641 :     jl_sym_t *globname = dv->name->mt != NULL ? dv->name->mt->name : NULL;
     634   [ +  +  +  -  :      13641 :     if (globname && dv->name->module && jl_binding_resolved_p(dv->name->module, globname)) {
                   +  + ]
     635                 :      13113 :         jl_binding_t *b = jl_get_module_binding(dv->name->module, globname);
     636   [ +  -  +  + ]:      13113 :         if (b && b->constp) {
     637                 :      10850 :             jl_value_t *bv = jl_atomic_load_relaxed(&b->value);
     638                 :            :             // The `||` makes this function work for both function instances and function types.
     639   [ +  +  +  + ]:      10850 :             if (bv == v || jl_typeof(bv) == v)
     640                 :       2116 :                 return 1;
     641                 :            :         }
     642                 :            :     }
     643                 :      11525 :     return 0;
     644                 :            : }
     645                 :            : 
     646                 :       2116 : static int is_globfunction(jl_value_t *v, jl_datatype_t *dv, jl_sym_t **globname_out) JL_NOTSAFEPOINT
     647                 :            : {
     648         [ +  - ]:       2116 :     jl_sym_t *globname = dv->name->mt != NULL ? dv->name->mt->name : NULL;
     649                 :       2116 :     *globname_out = globname;
     650   [ +  -  +  +  :       2116 :     if (globname && !strchr(jl_symbol_name(globname), '#') && !strchr(jl_symbol_name(globname), '@')) {
                   +  - ]
     651                 :       2075 :         return 1;
     652                 :            :     }
     653                 :         41 :     return 0;
     654                 :            : }
     655                 :            : 
     656                 :      10994 : static size_t jl_static_show_x_sym_escaped(JL_STREAM *out, jl_sym_t *name) JL_NOTSAFEPOINT
     657                 :            : {
     658                 :      10994 :     size_t n = 0;
     659                 :            : 
     660                 :      10994 :     char *sn = jl_symbol_name(name);
     661                 :      10994 :     int hidden = 0;
     662   [ +  +  +  + ]:      10994 :     if (!(jl_is_identifier(sn) || jl_is_operator(sn))) {
     663                 :        431 :         hidden = 1;
     664                 :            :     }
     665                 :            : 
     666         [ +  + ]:      10994 :     if (hidden) {
     667                 :        431 :         n += jl_printf(out, "var\"");
     668                 :            :     }
     669                 :      10994 :     n += jl_printf(out, "%s", sn);
     670         [ +  + ]:      10994 :     if (hidden) {
     671                 :        431 :         n += jl_printf(out, "\"");
     672                 :            :     }
     673                 :      10994 :     return n;
     674                 :            : }
     675                 :            : 
     676                 :            : // `jl_static_show()` cannot call `jl_subtype()`, for the GC reasons
     677                 :            : // explained in the comment on `jl_static_show_x_()`, below.
     678                 :            : // This function checks if `vt <: Function` without triggering GC.
     679                 :        364 : static int jl_static_is_function_(jl_datatype_t *vt) JL_NOTSAFEPOINT {
     680         [ -  + ]:        364 :     if (!jl_function_type) {  // Make sure there's a Function type defined.
     681                 :          0 :         return 0;
     682                 :            :     }
     683                 :        364 :     int _iter_count = 0;  // To prevent infinite loops from corrupt type objects.
     684         [ +  + ]:        740 :     while (vt != jl_any_type) {
     685         [ -  + ]:        381 :         if (vt == NULL) {
     686                 :          0 :             return 0;
     687         [ -  + ]:        381 :         } else if (_iter_count > 10000) {
     688                 :            :             // We are very likely stuck in a cyclic datastructure, so we assume this is
     689                 :            :             // _not_ a Function.
     690                 :          0 :             return 0;
     691         [ +  + ]:        381 :         } else if (vt == jl_function_type) {
     692                 :          5 :             return 1;
     693                 :            :         }
     694                 :        376 :         vt = vt->super;
     695                 :        376 :         _iter_count += 1;
     696                 :            :     }
     697                 :        359 :     return 0;
     698                 :            : }
     699                 :            : 
     700                 :            : // `v` might be pointing to a field inlined in a structure therefore
     701                 :            : // `jl_typeof(v)` may not be the same with `vt` and only `vt` should be
     702                 :            : // used to determine the type of the value.
     703                 :            : // This is necessary to make sure that this function doesn't allocate any
     704                 :            : // memory through the Julia GC
     705                 :      24049 : static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt,
     706                 :            :                                 struct recur_list *depth) JL_NOTSAFEPOINT
     707                 :            : {
     708                 :      24049 :     size_t n = 0;
     709         [ -  + ]:      24049 :     if ((uintptr_t)vt < 4096U) {
     710                 :          0 :         n += jl_printf(out, "<?#%p::%p>", (void*)v, (void*)vt);
     711                 :            :     }
     712         [ -  + ]:      24049 :     else if ((uintptr_t)v < 4096U) {
     713                 :          0 :         n += jl_printf(out, "<?#%p::", (void*)v);
     714                 :          0 :         n += jl_static_show_x(out, (jl_value_t*)vt, depth);
     715                 :          0 :         n += jl_printf(out, ">");
     716                 :            :     }
     717                 :            :     // These need to be special cased because they
     718                 :            :     // exist only by pointer identity in early startup
     719         [ +  + ]:      24049 :     else if (v == (jl_value_t*)jl_simplevector_type) {
     720                 :         17 :         n += jl_printf(out, "Core.SimpleVector");
     721                 :            :     }
     722         [ +  + ]:      24032 :     else if (v == (jl_value_t*)jl_typename_type) {
     723                 :          2 :         n += jl_printf(out, "Core.TypeName");
     724                 :            :     }
     725         [ +  + ]:      24030 :     else if (v == (jl_value_t*)jl_symbol_type) {
     726                 :        323 :         n += jl_printf(out, "Symbol");
     727                 :            :     }
     728         [ +  + ]:      23707 :     else if (v == (jl_value_t*)jl_methtable_type) {
     729                 :          1 :         n += jl_printf(out, "Core.MethodTable");
     730                 :            :     }
     731         [ +  + ]:      23706 :     else if (v == (jl_value_t*)jl_any_type) {
     732                 :        629 :         n += jl_printf(out, "Any");
     733                 :            :     }
     734         [ +  + ]:      23077 :     else if (v == (jl_value_t*)jl_type_type) {
     735                 :         90 :         n += jl_printf(out, "Type");
     736                 :            :     }
     737         [ +  + ]:      22987 :     else if (vt == jl_method_type) {
     738                 :         11 :         jl_method_t *m = (jl_method_t*)v;
     739                 :         11 :         n += jl_static_show_func_sig(out, m->sig);
     740                 :            :     }
     741         [ -  + ]:      22976 :     else if (vt == jl_method_instance_type) {
     742                 :          0 :         jl_method_instance_t *li = (jl_method_instance_t*)v;
     743         [ #  # ]:          0 :         if (jl_is_method(li->def.method)) {
     744                 :          0 :             n += jl_static_show_func_sig(out, li->specTypes);
     745                 :          0 :             n += jl_printf(out, " from ");
     746                 :          0 :             n += jl_static_show_func_sig(out, li->def.method->sig);
     747                 :            :         }
     748                 :            :         else {
     749                 :          0 :             n += jl_static_show_x(out, (jl_value_t*)li->def.module, depth);
     750                 :          0 :             n += jl_printf(out, ".<toplevel thunk> -> ");
     751                 :          0 :             n += jl_static_show_x(out, li->uninferred, depth);
     752                 :            :         }
     753                 :            :     }
     754         [ -  + ]:      22976 :     else if (vt == jl_typename_type) {
     755                 :          0 :         n += jl_static_show_x(out, jl_unwrap_unionall(((jl_typename_t*)v)->wrapper), depth);
     756                 :          0 :         n += jl_printf(out, ".name");
     757                 :            :     }
     758         [ -  + ]:      22976 :     else if (vt == jl_simplevector_type) {
     759                 :          0 :         n += jl_show_svec(out, (jl_svec_t*)v, "svec", "(", ")");
     760                 :            :     }
     761         [ +  + ]:      22976 :     else if (v == (jl_value_t*)jl_unionall_type) {
     762                 :            :         // avoid printing `typeof(Type)` for `UnionAll`.
     763                 :          8 :         n += jl_printf(out, "UnionAll");
     764                 :            :     }
     765         [ +  + ]:      22968 :     else if (vt == jl_vararg_type) {
     766                 :         95 :         jl_vararg_t *vm = (jl_vararg_t*)v;
     767                 :         95 :         n += jl_printf(out, "Vararg");
     768         [ +  - ]:         95 :         if (vm->T) {
     769                 :         95 :             n += jl_printf(out, "{");
     770                 :         95 :             n += jl_static_show_x(out, vm->T, depth);
     771         [ +  + ]:         95 :             if (vm->N) {
     772                 :          7 :                 n += jl_printf(out, ", ");
     773                 :          7 :                 n += jl_static_show_x(out, vm->N, depth);
     774                 :            :             }
     775                 :         95 :             n += jl_printf(out, "}");
     776                 :            :         }
     777                 :            :     }
     778         [ +  + ]:      22873 :     else if (vt == jl_datatype_type) {
     779                 :            :         // typeof(v) == DataType, so v is a Type object.
     780                 :            :         // Types are printed as a fully qualified name, with parameters, e.g.
     781                 :            :         // `Base.Set{Int}`, and function types are printed as e.g. `typeof(Main.f)`
     782                 :      13636 :         jl_datatype_t *dv = (jl_datatype_t*)v;
     783                 :            :         jl_sym_t *globname;
     784   [ +  +  +  + ]:      13636 :         int globfunc = is_globname_binding(v, dv) && is_globfunction(v, dv, &globname);
     785         [ +  + ]:      13636 :         jl_sym_t *sym = globfunc ? globname : dv->name->name;
     786                 :      13636 :         char *sn = jl_symbol_name(sym);
     787                 :      13636 :         size_t quote = 0;
     788         [ +  + ]:      13636 :         if (dv->name == jl_tuple_typename) {
     789         [ +  + ]:       3410 :             if (dv == jl_tuple_type)
     790                 :       3410 :                 return jl_printf(out, "Tuple");
     791                 :       3206 :             int taillen = 1, tlen = jl_nparams(dv), i;
     792         [ +  + ]:       3879 :             for (i = tlen-2; i >= 0; i--) {
     793         [ +  + ]:       3298 :                 if (jl_tparam(dv, i) == jl_tparam(dv, tlen-1))
     794                 :        673 :                     taillen++;
     795                 :            :                 else
     796                 :       2625 :                     break;
     797                 :            :             }
     798   [ +  +  +  + ]:       3206 :             if (taillen == tlen && taillen > 3) {
     799                 :         22 :                 n += jl_printf(out, "NTuple{%d, ", tlen);
     800                 :         22 :                 n += jl_static_show_x(out, jl_tparam0(dv), depth);
     801                 :         22 :                 n += jl_printf(out, "}");
     802                 :            :             }
     803                 :            :             else {
     804                 :       3184 :                 n += jl_printf(out, "Tuple{");
     805   [ +  +  +  + ]:      11650 :                 for (i = 0; i < (taillen > 3 ? tlen-taillen : tlen); i++) {
     806         [ +  + ]:       8466 :                     if (i > 0)
     807                 :       5319 :                         n += jl_printf(out, ", ");
     808                 :       8466 :                     n += jl_static_show_x(out, jl_tparam(dv, i), depth);
     809                 :            :                 }
     810         [ +  + ]:       3184 :                 if (taillen > 3) {
     811                 :         28 :                     n += jl_printf(out, ", Vararg{");
     812                 :         28 :                     n += jl_static_show_x(out, jl_tparam(dv, tlen-1), depth);
     813                 :         28 :                     n += jl_printf(out, ", %d}", taillen);
     814                 :            :                 }
     815                 :       3184 :                 n += jl_printf(out, "}");
     816                 :            :             }
     817                 :       3206 :             return n;
     818                 :            :         }
     819         [ +  + ]:      10226 :         if (globfunc) {
     820                 :       2072 :             n += jl_printf(out, "typeof(");
     821                 :            :         }
     822   [ +  -  +  +  :      10226 :         if (jl_core_module && (dv->name->module != jl_core_module || !jl_module_exports_p(jl_core_module, sym))) {
                   +  + ]
     823                 :       4866 :             n += jl_static_show_x(out, (jl_value_t*)dv->name->module, depth);
     824                 :       4866 :             n += jl_printf(out, ".");
     825                 :       4866 :             size_t i = 0;
     826   [ +  +  +  + ]:       4866 :             if (globfunc && !jl_id_start_char(u8_nextchar(sn, &i))) {
     827                 :        156 :                 n += jl_printf(out, ":(");
     828                 :        156 :                 quote = 1;
     829                 :            :             }
     830                 :            :         }
     831                 :      10226 :         n += jl_static_show_x_sym_escaped(out, sym);
     832         [ +  + ]:      10226 :         if (globfunc) {
     833                 :       2072 :             n += jl_printf(out, ")");
     834         [ +  + ]:       2072 :             if (quote) {
     835                 :        156 :                 n += jl_printf(out, ")");
     836                 :            :             }
     837                 :            :         }
     838   [ +  -  +  + ]:      10226 :         if (dv->parameters && (jl_value_t*)dv != dv->name->wrapper) {
     839                 :       2973 :             size_t j, tlen = jl_nparams(dv);
     840         [ +  - ]:       2973 :             if (tlen > 0) {
     841                 :       2973 :                 n += jl_printf(out, "{");
     842         [ +  + ]:       7589 :                 for (j = 0; j < tlen; j++) {
     843                 :       4616 :                     jl_value_t *p = jl_tparam(dv,j);
     844                 :       4616 :                     n += jl_static_show_x(out, p, depth);
     845         [ +  + ]:       4616 :                     if (j != tlen-1)
     846                 :       1643 :                         n += jl_printf(out, ", ");
     847                 :            :                 }
     848                 :       2973 :                 n += jl_printf(out, "}");
     849                 :            :             }
     850                 :            :         }
     851                 :            :     }
     852         [ -  + ]:       9237 :     else if (vt == jl_intrinsic_type) {
     853                 :          0 :         int f = *(uint32_t*)jl_data_ptr(v);
     854                 :          0 :         n += jl_printf(out, "#<intrinsic #%d %s>", f, jl_intrinsic_name(f));
     855                 :            :     }
     856         [ +  + ]:       9237 :     else if (vt == jl_int64_type) {
     857                 :        530 :         n += jl_printf(out, "%" PRId64, *(int64_t*)v);
     858                 :            :     }
     859         [ -  + ]:       8707 :     else if (vt == jl_int32_type) {
     860                 :          0 :         n += jl_printf(out, "%" PRId32, *(int32_t*)v);
     861                 :            :     }
     862         [ -  + ]:       8707 :     else if (vt == jl_int16_type) {
     863                 :          0 :         n += jl_printf(out, "%" PRId16, *(int16_t*)v);
     864                 :            :     }
     865         [ -  + ]:       8707 :     else if (vt == jl_int8_type) {
     866                 :          0 :         n += jl_printf(out, "%" PRId8, *(int8_t*)v);
     867                 :            :     }
     868         [ -  + ]:       8707 :     else if (vt == jl_uint64_type) {
     869                 :          0 :         n += jl_printf(out, "0x%016" PRIx64, *(uint64_t*)v);
     870                 :            :     }
     871         [ -  + ]:       8707 :     else if (vt == jl_uint32_type) {
     872                 :          0 :         n += jl_printf(out, "0x%08" PRIx32, *(uint32_t*)v);
     873                 :            :     }
     874         [ -  + ]:       8707 :     else if (vt == jl_uint16_type) {
     875                 :          0 :         n += jl_printf(out, "0x%04" PRIx16, *(uint16_t*)v);
     876                 :            :     }
     877         [ -  + ]:       8707 :     else if (vt == jl_uint8_type) {
     878                 :          0 :         n += jl_printf(out, "0x%02" PRIx8, *(uint8_t*)v);
     879                 :            :     }
     880   [ +  -  -  + ]:       8707 :     else if (jl_pointer_type && jl_is_cpointer_type((jl_value_t*)vt)) {
     881                 :            : #ifdef _P64
     882                 :          0 :         n += jl_printf(out, "0x%016" PRIx64, *(uint64_t*)v);
     883                 :            : #else
     884                 :            :         n += jl_printf(out, "0x%08" PRIx32, *(uint32_t*)v);
     885                 :            : #endif
     886                 :            :     }
     887         [ -  + ]:       8707 :     else if (vt == jl_float32_type) {
     888                 :          0 :         n += jl_printf(out, "%gf", *(float*)v);
     889                 :            :     }
     890         [ +  + ]:       8707 :     else if (vt == jl_float64_type) {
     891                 :          2 :         n += jl_printf(out, "%g", *(double*)v);
     892                 :            :     }
     893         [ +  + ]:       8705 :     else if (vt == jl_bool_type) {
     894         [ +  - ]:          2 :         n += jl_printf(out, "%s", *(uint8_t*)v ? "true" : "false");
     895                 :            :     }
     896   [ +  -  +  -  :       8703 :     else if (v == jl_nothing || (jl_nothing && (jl_value_t*)vt == jl_typeof(jl_nothing))) {
                   -  + ]
     897                 :          0 :         n += jl_printf(out, "nothing");
     898                 :            :     }
     899         [ +  + ]:       8703 :     else if (vt == jl_string_type) {
     900                 :         19 :         n += jl_printf(out, "\"");
     901                 :         19 :         jl_uv_puts(out, jl_string_data(v), jl_string_len(v)); n += jl_string_len(v);
     902                 :         19 :         n += jl_printf(out, "\"");
     903                 :            :     }
     904         [ +  + ]:       8684 :     else if (v == jl_bottom_type) {
     905                 :         10 :         n += jl_printf(out, "Union{}");
     906                 :            :     }
     907         [ +  + ]:       8674 :     else if (vt == jl_uniontype_type) {
     908                 :         30 :         n += jl_printf(out, "Union{");
     909         [ +  + ]:         64 :         while (jl_is_uniontype(v)) {
     910                 :            :             // tail-recurse on b to flatten the printing of the Union structure in the common case
     911                 :         34 :             n += jl_static_show_x(out, ((jl_uniontype_t*)v)->a, depth);
     912                 :         34 :             n += jl_printf(out, ", ");
     913                 :         34 :             v = ((jl_uniontype_t*)v)->b;
     914                 :            :         }
     915                 :         30 :         n += jl_static_show_x(out, v, depth);
     916                 :         30 :         n += jl_printf(out, "}");
     917                 :            :     }
     918         [ +  + ]:       8644 :     else if (vt == jl_unionall_type) {
     919                 :        378 :         jl_unionall_t *ua = (jl_unionall_t*)v;
     920                 :        378 :         n += jl_static_show_x(out, ua->body, depth);
     921                 :        378 :         n += jl_printf(out, " where ");
     922                 :        378 :         n += jl_static_show_x(out, (jl_value_t*)ua->var, depth->prev);
     923                 :            :     }
     924         [ -  + ]:       8266 :     else if (vt == jl_typename_type) {
     925                 :          0 :         n += jl_printf(out, "typename(");
     926                 :          0 :         n += jl_static_show_x(out, jl_unwrap_unionall(((jl_typename_t*)v)->wrapper), depth);
     927                 :          0 :         n += jl_printf(out, ")");
     928                 :            :     }
     929         [ +  + ]:       8266 :     else if (vt == jl_tvar_type) {
     930                 :            :         // show type-var bounds only if they aren't going to be printed by UnionAll later
     931                 :        764 :         jl_tvar_t *var = (jl_tvar_t*)v;
     932                 :            :         struct recur_list *p;
     933                 :        764 :         int showbounds = 1;
     934         [ +  + ]:       2952 :         for (p = depth; p != NULL; p = p->prev) {
     935   [ +  +  +  + ]:       2572 :             if (jl_is_unionall(p->v) && ((jl_unionall_t*)p->v)->var == var) {
     936                 :        384 :                 showbounds = 0;
     937                 :        384 :                 break;
     938                 :            :             }
     939                 :            :         }
     940                 :        764 :         jl_value_t *lb = var->lb, *ub = var->ub;
     941   [ +  +  -  + ]:        764 :         if (showbounds && lb != jl_bottom_type) {
     942                 :            :             // show type-var lower bound if it is defined
     943                 :          0 :             int ua = jl_is_unionall(lb);
     944         [ #  # ]:          0 :             if (ua)
     945                 :          0 :                 n += jl_printf(out, "(");
     946                 :          0 :             n += jl_static_show_x(out, lb, depth);
     947         [ #  # ]:          0 :             if (ua)
     948                 :          0 :                 n += jl_printf(out, ")");
     949                 :          0 :             n += jl_printf(out, "<:");
     950                 :            :         }
     951                 :        764 :         n += jl_static_show_x_sym_escaped(out, var->name);
     952   [ +  +  +  +  :        764 :         if (showbounds && (ub != (jl_value_t*)jl_any_type || lb != jl_bottom_type)) {
                   -  + ]
     953                 :            :             // show type-var upper bound if it is defined, or if we showed the lower bound
     954                 :        195 :             int ua = jl_is_unionall(ub);
     955                 :        195 :             n += jl_printf(out, "<:");
     956         [ +  + ]:        195 :             if (ua)
     957                 :          1 :                 n += jl_printf(out, "(");
     958                 :        195 :             n += jl_static_show_x(out, ub, depth);
     959         [ +  + ]:        195 :             if (ua)
     960                 :          1 :                 n += jl_printf(out, ")");
     961                 :            :         }
     962                 :            :     }
     963         [ +  + ]:       7502 :     else if (vt == jl_module_type) {
     964                 :       6356 :         jl_module_t *m = (jl_module_t*)v;
     965   [ +  +  +  + ]:       6356 :         if (m->parent != m && m->parent != jl_main_module) {
     966                 :       1472 :             n += jl_static_show_x(out, (jl_value_t*)m->parent, depth);
     967                 :       1472 :             n += jl_printf(out, ".");
     968                 :            :         }
     969                 :       6356 :         n += jl_printf(out, "%s", jl_symbol_name(m->name));
     970                 :            :     }
     971         [ +  + ]:       1146 :     else if (vt == jl_symbol_type) {
     972                 :        751 :         char *sn = jl_symbol_name((jl_sym_t*)v);
     973   [ +  +  +  + ]:        751 :         int quoted = !jl_is_identifier(sn) && jl_operator_precedence(sn) == 0;
     974         [ +  + ]:        751 :         if (quoted)
     975                 :         11 :             n += jl_printf(out, "Symbol(\"");
     976                 :            :         else
     977                 :        740 :             n += jl_printf(out, ":");
     978                 :        751 :         n += jl_printf(out, "%s", sn);
     979         [ +  + ]:        751 :         if (quoted)
     980                 :         11 :             n += jl_printf(out, "\")");
     981                 :            :     }
     982         [ +  + ]:        395 :     else if (vt == jl_ssavalue_type) {
     983                 :         10 :         n += jl_printf(out, "SSAValue(%" PRIuPTR ")",
     984                 :         10 :                        (uintptr_t)((jl_ssavalue_t*)v)->id);
     985                 :            :     }
     986         [ +  + ]:        385 :     else if (vt == jl_globalref_type) {
     987                 :          5 :         n += jl_static_show_x(out, (jl_value_t*)jl_globalref_mod(v), depth);
     988                 :          5 :         char *name = jl_symbol_name(jl_globalref_name(v));
     989         [ +  - ]:          5 :         n += jl_printf(out, jl_is_identifier(name) ? ".%s" : ".:(%s)", name);
     990                 :            :     }
     991         [ -  + ]:        380 :     else if (vt == jl_gotonode_type) {
     992                 :          0 :         n += jl_printf(out, "goto %" PRIuPTR, jl_gotonode_label(v));
     993                 :            :     }
     994         [ +  + ]:        380 :     else if (vt == jl_quotenode_type) {
     995                 :          1 :         jl_value_t *qv = *(jl_value_t**)v;
     996         [ -  + ]:          1 :         if (!jl_is_symbol(qv)) {
     997                 :          0 :             n += jl_printf(out, "quote ");
     998                 :            :         }
     999                 :            :         else {
    1000                 :          1 :             n += jl_printf(out, ":(");
    1001                 :            :         }
    1002                 :          1 :         n += jl_static_show_x(out, qv, depth);
    1003         [ -  + ]:          1 :         if (!jl_is_symbol(qv)) {
    1004                 :          0 :             n += jl_printf(out, " end");
    1005                 :            :         }
    1006                 :            :         else {
    1007                 :          1 :             n += jl_printf(out, ")");
    1008                 :            :         }
    1009                 :            :     }
    1010         [ -  + ]:        379 :     else if (vt == jl_newvarnode_type) {
    1011                 :          0 :         n += jl_printf(out, "<newvar ");
    1012                 :          0 :         n += jl_static_show_x(out, *(jl_value_t**)v, depth);
    1013                 :          0 :         n += jl_printf(out, ">");
    1014                 :            :     }
    1015         [ -  + ]:        379 :     else if (vt == jl_linenumbernode_type) {
    1016                 :          0 :         n += jl_printf(out, "#= ");
    1017                 :          0 :         n += jl_static_show_x(out, jl_linenode_file(v), depth);
    1018                 :          0 :         n += jl_printf(out, ":%" PRIuPTR " =#", jl_linenode_line(v));
    1019                 :            :     }
    1020         [ +  + ]:        379 :     else if (vt == jl_expr_type) {
    1021                 :          7 :         jl_expr_t *e = (jl_expr_t*)v;
    1022   [ -  +  -  - ]:          7 :         if (e->head == jl_assign_sym && jl_array_len(e->args) == 2) {
    1023                 :          0 :             n += jl_static_show_x(out, jl_exprarg(e,0), depth);
    1024                 :          0 :             n += jl_printf(out, " = ");
    1025                 :          0 :             n += jl_static_show_x(out, jl_exprarg(e,1), depth);
    1026                 :            :         }
    1027                 :            :         else {
    1028                 :          7 :             char sep = ' ';
    1029                 :          7 :             n += jl_printf(out, "Expr(:%s", jl_symbol_name(e->head));
    1030                 :          7 :             size_t i, len = jl_array_len(e->args);
    1031         [ +  + ]:         28 :             for (i = 0; i < len; i++) {
    1032                 :         21 :                 n += jl_printf(out, ",%c", sep);
    1033                 :         21 :                 n += jl_static_show_x(out, jl_exprarg(e,i), depth);
    1034                 :            :             }
    1035                 :          7 :             n += jl_printf(out, ")");
    1036                 :            :         }
    1037                 :            :     }
    1038   [ +  -  -  + ]:        372 :     else if (jl_array_type && jl_is_array_type(vt)) {
    1039                 :          0 :         n += jl_printf(out, "Array{");
    1040                 :          0 :         n += jl_static_show_x(out, (jl_value_t*)jl_tparam0(vt), depth);
    1041                 :          0 :         n += jl_printf(out, ", (");
    1042                 :          0 :         size_t i, ndims = jl_array_ndims(v);
    1043         [ #  # ]:          0 :         if (ndims == 1)
    1044                 :          0 :             n += jl_printf(out, "%" PRIdPTR ",", jl_array_dim0(v));
    1045                 :            :         else
    1046         [ #  # ]:          0 :             for (i = 0; i < ndims; i++)
    1047         [ #  # ]:          0 :                 n += jl_printf(out, (i > 0 ? ", %" PRIdPTR : "%" PRIdPTR), jl_array_dim(v, i));
    1048                 :          0 :         n += jl_printf(out, ")}[");
    1049                 :          0 :         size_t j, tlen = jl_array_len(v);
    1050                 :          0 :         jl_array_t *av = (jl_array_t*)v;
    1051                 :          0 :         jl_value_t *el_type = jl_tparam0(vt);
    1052   [ #  #  #  # ]:          0 :         char *typetagdata = (!av->flags.ptrarray && jl_is_uniontype(el_type)) ? jl_array_typetagdata(av) : NULL;
    1053                 :          0 :         int nlsep = 0;
    1054         [ #  # ]:          0 :         if (av->flags.ptrarray) {
    1055                 :            :             // print arrays with newlines, unless the elements are probably small
    1056         [ #  # ]:          0 :             for (j = 0; j < tlen; j++) {
    1057                 :          0 :                 jl_value_t **ptr = ((jl_value_t**)av->data) + j;
    1058                 :          0 :                 jl_value_t *p = *ptr;
    1059   [ #  #  #  # ]:          0 :                 if (p != NULL && (uintptr_t)p >= 4096U) {
    1060                 :          0 :                     jl_value_t *p_ty = jl_typeof(p);
    1061         [ #  # ]:          0 :                     if ((uintptr_t)p_ty >= 4096U) {
    1062         [ #  # ]:          0 :                         if (!jl_isbits(p_ty)) {
    1063                 :          0 :                             nlsep = 1;
    1064                 :          0 :                             break;
    1065                 :            :                         }
    1066                 :            :                     }
    1067                 :            :                 }
    1068                 :            :             }
    1069                 :            :         }
    1070   [ #  #  #  # ]:          0 :         if (nlsep && tlen > 1)
    1071                 :          0 :             n += jl_printf(out, "\n  ");
    1072         [ #  # ]:          0 :         for (j = 0; j < tlen; j++) {
    1073         [ #  # ]:          0 :             if (av->flags.ptrarray) {
    1074                 :          0 :                 jl_value_t **ptr = ((jl_value_t**)av->data) + j;
    1075                 :          0 :                 n += jl_static_show_x(out, *ptr, depth);
    1076                 :            :             }
    1077                 :            :             else {
    1078                 :          0 :                 char *ptr = ((char*)av->data) + j * av->elsize;
    1079         [ #  # ]:          0 :                 n += jl_static_show_x_(out, (jl_value_t*)ptr,
    1080                 :          0 :                         typetagdata ? (jl_datatype_t*)jl_nth_union_component(el_type, typetagdata[j]) : (jl_datatype_t*)el_type,
    1081                 :            :                         depth);
    1082                 :            :             }
    1083         [ #  # ]:          0 :             if (j != tlen - 1)
    1084         [ #  # ]:          0 :                 n += jl_printf(out, nlsep ? ",\n  " : ", ");
    1085                 :            :         }
    1086                 :          0 :         n += jl_printf(out, "]");
    1087                 :            :     }
    1088         [ -  + ]:        372 :     else if (vt == jl_loaderror_type) {
    1089                 :          0 :         n += jl_printf(out, "LoadError(at ");
    1090                 :          0 :         n += jl_static_show_x(out, *(jl_value_t**)v, depth);
    1091                 :            :         // Access the field directly to avoid allocation
    1092                 :          0 :         n += jl_printf(out, " line %" PRIdPTR, ((intptr_t*)v)[1]);
    1093                 :          0 :         n += jl_printf(out, ": ");
    1094                 :          0 :         n += jl_static_show_x(out, ((jl_value_t**)v)[2], depth);
    1095                 :          0 :         n += jl_printf(out, ")");
    1096                 :            :     }
    1097         [ +  + ]:        372 :     else if (vt == jl_errorexception_type) {
    1098                 :          8 :         n += jl_printf(out, "ErrorException(");
    1099                 :          8 :         n += jl_static_show_x(out, *(jl_value_t**)v, depth);
    1100                 :          8 :         n += jl_printf(out, ")");
    1101                 :            :     }
    1102   [ +  +  +  + ]:        368 :     else if (jl_static_is_function_(vt) && is_globname_binding(v, (jl_datatype_t*)vt)) {
    1103                 :            :         // v is function instance (an instance of a Function type).
    1104                 :          4 :         jl_datatype_t *dv = (jl_datatype_t*)vt;
    1105                 :            :         jl_sym_t *sym;
    1106                 :          4 :         int globfunc = is_globfunction(v, dv, &sym);
    1107                 :          4 :         int quote = 0;
    1108   [ +  -  -  +  :          4 :         if (jl_core_module && (dv->name->module != jl_core_module || !jl_module_exports_p(jl_core_module, sym))) {
                   -  - ]
    1109                 :          4 :             n += jl_static_show_x(out, (jl_value_t*)dv->name->module, depth);
    1110                 :          4 :             n += jl_printf(out, ".");
    1111                 :            : 
    1112                 :          4 :             size_t i = 0;
    1113                 :          4 :             char *sn = jl_symbol_name(sym);
    1114   [ +  +  +  + ]:          4 :             if (globfunc && !jl_id_start_char(u8_nextchar(sn, &i))) {
    1115                 :          2 :                 n += jl_printf(out, ":(");
    1116                 :          2 :                 quote = 1;
    1117                 :            :             }
    1118                 :            :         }
    1119                 :            : 
    1120                 :          4 :         n += jl_static_show_x_sym_escaped(out, sym);
    1121                 :            : 
    1122         [ +  + ]:          4 :         if (globfunc) {
    1123         [ +  + ]:          3 :             if (quote) {
    1124                 :          2 :                 n += jl_printf(out, ")");
    1125                 :            :             }
    1126                 :            :         }
    1127                 :            :     }
    1128   [ +  -  +  - ]:        360 :     else if (jl_datatype_type && jl_is_datatype(vt)) {
    1129                 :            :         // typeof(v) isa DataType, so v is an *instance of* a type that is a Datatype,
    1130                 :            :         // meaning v is e.g. an instance of a struct. These are printed as a call to a
    1131                 :            :         // type constructor, such as e.g. `Base.UnitRange{Int64}(start=1, stop=2)`
    1132                 :        360 :         int istuple = jl_is_tuple_type(vt), isnamedtuple = jl_is_namedtuple_type(vt);
    1133                 :        360 :         size_t tlen = jl_datatype_nfields(vt);
    1134         [ -  + ]:        360 :         if (isnamedtuple) {
    1135         [ #  # ]:          0 :             if (tlen == 0)
    1136                 :          0 :                 n += jl_printf(out, "NamedTuple");
    1137                 :            :         }
    1138         [ +  + ]:        360 :         else if (!istuple) {
    1139                 :         13 :             n += jl_static_show_x(out, (jl_value_t*)vt, depth);
    1140                 :            :         }
    1141                 :        360 :         n += jl_printf(out, "(");
    1142                 :        360 :         size_t nb = jl_datatype_size(vt);
    1143   [ +  +  +  + ]:        361 :         if (nb > 0 && tlen == 0) {
    1144                 :          1 :             uint8_t *data = (uint8_t*)v;
    1145                 :          1 :             n += jl_printf(out, "0x");
    1146         [ +  + ]:         17 :             for(int i = nb - 1; i >= 0; --i)
    1147                 :         16 :                 n += jl_printf(out, "%02" PRIx8, data[i]);
    1148                 :            :         }
    1149                 :            :         else {
    1150                 :        359 :             size_t i = 0;
    1151         [ -  + ]:        359 :             if (vt == jl_typemap_entry_type)
    1152                 :          0 :                 i = 1;
    1153         [ -  + ]:        359 :             jl_value_t *names = isnamedtuple ? jl_tparam0(vt) : (jl_value_t*)jl_field_names(vt);
    1154         [ +  + ]:       1111 :             for (; i < tlen; i++) {
    1155         [ +  + ]:        752 :                 if (!istuple) {
    1156         [ -  + ]:         17 :                     jl_value_t *fname = isnamedtuple ? jl_fieldref_noalloc(names, i) : jl_svecref(names, i);
    1157                 :         17 :                     n += jl_printf(out, "%s=", jl_symbol_name((jl_sym_t*)fname));
    1158                 :            :                 }
    1159                 :        752 :                 size_t offs = jl_field_offset(vt, i);
    1160                 :        752 :                 char *fld_ptr = (char*)v + offs;
    1161         [ +  + ]:        752 :                 if (jl_field_isptr(vt, i)) {
    1162                 :        751 :                     n += jl_static_show_x(out, *(jl_value_t**)fld_ptr, depth);
    1163                 :            :                 }
    1164                 :            :                 else {
    1165                 :          1 :                     jl_datatype_t *ft = (jl_datatype_t*)jl_field_type_concrete(vt, i);
    1166         [ -  + ]:          1 :                     if (jl_is_uniontype(ft)) {
    1167                 :          0 :                         uint8_t sel = ((uint8_t*)fld_ptr)[jl_field_size(vt, i) - 1];
    1168                 :          0 :                         ft = (jl_datatype_t*)jl_nth_union_component((jl_value_t*)ft, sel);
    1169                 :            :                     }
    1170                 :          1 :                     n += jl_static_show_x_(out, (jl_value_t*)fld_ptr, ft, depth);
    1171                 :            :                 }
    1172   [ +  +  -  +  :        752 :                 if ((istuple || isnamedtuple) && tlen == 1)
                   +  + ]
    1173                 :        153 :                     n += jl_printf(out, ",");
    1174         [ +  + ]:        599 :                 else if (i != tlen - 1)
    1175                 :        414 :                     n += jl_printf(out, ", ");
    1176                 :            :             }
    1177         [ -  + ]:        359 :             if (vt == jl_typemap_entry_type) {
    1178                 :          0 :                 n += jl_printf(out, ", next=↩︎\n  ");
    1179                 :          0 :                 jl_value_t *next = (jl_value_t*)jl_atomic_load_relaxed(&((jl_typemap_entry_t*)v)->next);
    1180                 :          0 :                 n += jl_static_show_next_(out, next, v, depth);
    1181                 :            :             }
    1182                 :            :         }
    1183                 :        360 :         n += jl_printf(out, ")");
    1184                 :            :     }
    1185                 :            :     else {
    1186                 :          0 :         n += jl_printf(out, "<?#%p::", (void*)v);
    1187                 :          0 :         n += jl_static_show_x(out, (jl_value_t*)vt, depth);
    1188                 :          0 :         n += jl_printf(out, ">");
    1189                 :            :     }
    1190                 :      20639 :     return n;
    1191                 :            : }
    1192                 :            : 
    1193                 :      24048 : static size_t jl_static_show_x(JL_STREAM *out, jl_value_t *v, struct recur_list *depth) JL_NOTSAFEPOINT
    1194                 :            : {
    1195                 :            :     // show values without calling a julia method or allocating through the GC
    1196                 :      24048 :     return jl_static_show_next_(out, v, NULL, depth);
    1197                 :            : }
    1198                 :            : 
    1199                 :      24048 : static size_t jl_static_show_next_(JL_STREAM *out, jl_value_t *v, jl_value_t *prev, struct recur_list *depth) JL_NOTSAFEPOINT
    1200                 :            : {
    1201                 :            :     // helper for showing a typemap list by following the next pointers
    1202                 :            :     // while being careful about avoiding any recursion due to malformed (circular) references
    1203         [ -  + ]:      24048 :     if (v == NULL) {
    1204                 :          0 :         return jl_printf(out, "#<null>");
    1205                 :            :     }
    1206         [ -  + ]:      24048 :     else if ((uintptr_t)v < 4096U) {
    1207                 :          0 :         return jl_printf(out, "#<%d>", (int)(uintptr_t)v);
    1208                 :            :     }
    1209                 :      24048 :     unsigned int dist = 1;
    1210                 :      24048 :     struct recur_list this_item = {depth, v},
    1211                 :      24048 :                       *newdepth = &this_item,
    1212                 :      24048 :                       *p = depth;
    1213         [ +  + ]:      70041 :     while (p) {
    1214   [ -  +  -  - ]:      45993 :         if (jl_typeis(v, jl_typemap_entry_type) && newdepth == &this_item) {
    1215                 :          0 :             jl_value_t *m = p->v;
    1216                 :          0 :             unsigned nid = 1;
    1217   [ #  #  #  # ]:          0 :             while (m && jl_typeis(m, jl_typemap_entry_type)) {
    1218         [ #  # ]:          0 :                 if (m == v) {
    1219                 :          0 :                     return jl_printf(out, "<typemap reference #%u @-%u ", nid, dist) +
    1220                 :          0 :                            jl_static_show_x(out, (jl_value_t*)((jl_typemap_entry_t*)m)->sig, depth) +
    1221                 :          0 :                            jl_printf(out, ">");
    1222                 :            :                 }
    1223         [ #  # ]:          0 :                 if (m == prev) {
    1224                 :          0 :                     newdepth = depth;
    1225                 :          0 :                     break;
    1226                 :            :                 }
    1227                 :            :                 // verify that we aren't trying to follow a circular list
    1228                 :            :                 // by following the list again, and ensuring this is the only link to next
    1229                 :          0 :                 jl_value_t *mnext = (jl_value_t*)jl_atomic_load_relaxed(&((jl_typemap_entry_t*)m)->next);
    1230                 :          0 :                 jl_value_t *m2 = p->v;
    1231         [ #  # ]:          0 :                 if (m2 == mnext)
    1232                 :          0 :                     break;
    1233   [ #  #  #  # ]:          0 :                 while (m2 && jl_typeis(m2, jl_typemap_entry_type)) {
    1234                 :          0 :                     jl_value_t *mnext2 = (jl_value_t*)jl_atomic_load_relaxed(&((jl_typemap_entry_t*)m2)->next);
    1235         [ #  # ]:          0 :                     if (mnext2 == mnext) {
    1236         [ #  # ]:          0 :                         if (m2 != m)
    1237                 :          0 :                             mnext = NULL;
    1238                 :          0 :                         break;
    1239                 :            :                     }
    1240                 :          0 :                     m2 = mnext2;
    1241                 :            :                 }
    1242                 :          0 :                 m = mnext;
    1243                 :          0 :                 nid++;
    1244                 :            :             }
    1245                 :            :         }
    1246         [ -  + ]:      45993 :         if (p->v == v)
    1247                 :          0 :             return jl_printf(out, "<circular reference @-%u>", dist);
    1248                 :      45993 :         dist++;
    1249                 :      45993 :         p = p->prev;
    1250                 :            :     }
    1251                 :      24048 :     return jl_static_show_x_(out, v, (jl_datatype_t*)jl_typeof(v), newdepth);
    1252                 :            : }
    1253                 :            : 
    1254                 :       2649 : JL_DLLEXPORT size_t jl_static_show(JL_STREAM *out, jl_value_t *v) JL_NOTSAFEPOINT
    1255                 :            : {
    1256                 :       2649 :     return jl_static_show_x(out, v, 0);
    1257                 :            : }
    1258                 :            : 
    1259                 :         19 : JL_DLLEXPORT size_t jl_static_show_func_sig(JL_STREAM *s, jl_value_t *type) JL_NOTSAFEPOINT
    1260                 :            : {
    1261                 :         19 :     size_t n = 0;
    1262                 :            :     size_t i;
    1263                 :         19 :     jl_value_t *ftype = (jl_value_t*)jl_first_argument_datatype(type);
    1264         [ +  + ]:         19 :     if (ftype == NULL)
    1265                 :          5 :         return jl_static_show(s, type);
    1266                 :         14 :     jl_unionall_t *tvars = (jl_unionall_t*)type;
    1267                 :         14 :     int nvars = jl_subtype_env_size(type);
    1268                 :         14 :     struct recur_list *depth = NULL;
    1269         [ +  + ]:         14 :     if (nvars > 0)  {
    1270                 :          1 :         depth = (struct recur_list*)alloca(sizeof(struct recur_list) * nvars);
    1271         [ +  + ]:          3 :         for (i = 0; i < nvars; i++) {
    1272         [ +  + ]:          2 :             depth[i].prev = i == 0 ? NULL : &depth[i - 1];
    1273                 :          2 :             depth[i].v = type;
    1274                 :          2 :             type = ((jl_unionall_t*)type)->body;
    1275                 :            :         }
    1276                 :          1 :         depth += nvars - 1;
    1277                 :            :     }
    1278         [ -  + ]:         14 :     if (!jl_is_datatype(type)) {
    1279                 :          0 :         n += jl_static_show(s, type);
    1280                 :          0 :         return n;
    1281                 :            :     }
    1282   [ -  +  -  - ]:         14 :     if (jl_nparams(ftype) == 0 || ftype == ((jl_datatype_t*)ftype)->name->wrapper) {
    1283                 :         14 :         n += jl_printf(s, "%s", jl_symbol_name(((jl_datatype_t*)ftype)->name->mt->name));
    1284                 :            :     }
    1285                 :            :     else {
    1286                 :          0 :         n += jl_printf(s, "(::");
    1287                 :          0 :         n += jl_static_show_x(s, ftype, depth);
    1288                 :          0 :         n += jl_printf(s, ")");
    1289                 :            :     }
    1290                 :         14 :     size_t tl = jl_nparams(type);
    1291                 :         14 :     n += jl_printf(s, "(");
    1292         [ +  + ]:         21 :     for (i = 1; i < tl; i++) {
    1293                 :          7 :         jl_value_t *tp = jl_tparam(type, i);
    1294         [ +  + ]:          7 :         if (i != tl - 1) {
    1295                 :          1 :             n += jl_static_show_x(s, tp, depth);
    1296                 :          1 :             n += jl_printf(s, ", ");
    1297                 :            :         }
    1298                 :            :         else {
    1299         [ +  + ]:          6 :             if (jl_vararg_kind(tp) == JL_VARARG_UNBOUND) {
    1300                 :          1 :                 tp = jl_unwrap_vararg(tp);
    1301         [ -  + ]:          1 :                 if (jl_is_unionall(tp))
    1302                 :          0 :                     n += jl_printf(s, "(");
    1303                 :          1 :                 n += jl_static_show_x(s, tp, depth);
    1304         [ -  + ]:          1 :                 if (jl_is_unionall(tp))
    1305                 :          0 :                     n += jl_printf(s, ")");
    1306                 :          1 :                 n += jl_printf(s, "...");
    1307                 :            :             }
    1308                 :            :             else {
    1309                 :          5 :                 n += jl_static_show_x(s, tp, depth);
    1310                 :            :             }
    1311                 :            :         }
    1312                 :            :     }
    1313                 :         14 :     n += jl_printf(s, ")");
    1314         [ +  + ]:         14 :     if (jl_is_unionall(tvars)) {
    1315                 :          1 :         depth -= nvars - 1;
    1316                 :          1 :         int first = 1;
    1317                 :          1 :         n += jl_printf(s, " where {");
    1318         [ +  + ]:          3 :         while (jl_is_unionall(tvars)) {
    1319         [ +  + ]:          2 :             if (!first)
    1320                 :          1 :                 n += jl_printf(s, ", ");
    1321         [ +  + ]:          2 :             n += jl_static_show_x(s, (jl_value_t*)tvars->var, first ? NULL : depth);
    1322                 :          2 :             tvars = (jl_unionall_t*)tvars->body;
    1323         [ +  + ]:          2 :             if (!first)
    1324                 :          1 :                 depth += 1;
    1325                 :          2 :             first = 0;
    1326                 :            :         }
    1327                 :          1 :         n += jl_printf(s, "}");
    1328                 :            :     }
    1329                 :         14 :     return n;
    1330                 :            : }
    1331                 :            : 
    1332                 :          0 : JL_DLLEXPORT void jl_(void *jl_value) JL_NOTSAFEPOINT
    1333                 :            : {
    1334                 :          0 :     jl_jmp_buf *old_buf = jl_get_safe_restore();
    1335                 :            :     jl_jmp_buf buf;
    1336                 :          0 :     jl_set_safe_restore(&buf);
    1337         [ #  # ]:          0 :     if (!jl_setjmp(buf, 0)) {
    1338                 :          0 :         jl_static_show((JL_STREAM*)STDERR_FILENO, (jl_value_t*)jl_value);
    1339                 :          0 :         jl_printf((JL_STREAM*)STDERR_FILENO,"\n");
    1340                 :            :     }
    1341                 :            :     else {
    1342                 :          0 :         jl_printf((JL_STREAM*)STDERR_FILENO, "\n!!! ERROR in jl_ -- ABORTING !!!\n");
    1343                 :            :     }
    1344                 :          0 :     jl_set_safe_restore(old_buf);
    1345                 :          0 : }
    1346                 :            : 
    1347                 :          5 : JL_DLLEXPORT void jl_breakpoint(jl_value_t *v)
    1348                 :            : {
    1349                 :            :     // put a breakpoint in your debugger here
    1350                 :          5 : }
    1351                 :            : 
    1352                 :        103 : JL_DLLEXPORT void jl_test_failure_breakpoint(jl_value_t *v)
    1353                 :            : {
    1354                 :            :     // put a breakpoint in your debugger here
    1355                 :        103 : }
    1356                 :            : 
    1357                 :            : // logging tools --------------------------------------------------------------
    1358                 :            : 
    1359                 :          0 : void jl_log(int level, jl_value_t *module, jl_value_t *group, jl_value_t *id,
    1360                 :            :             jl_value_t *file, jl_value_t *line, jl_value_t *kwargs,
    1361                 :            :             jl_value_t *msg)
    1362                 :            : {
    1363                 :            :     static jl_value_t *logmsg_func = NULL;
    1364   [ #  #  #  # ]:          0 :     if (!logmsg_func && jl_base_module) {
    1365                 :          0 :         jl_value_t *corelogging = jl_get_global(jl_base_module, jl_symbol("CoreLogging"));
    1366   [ #  #  #  # ]:          0 :         if (corelogging && jl_is_module(corelogging)) {
    1367                 :          0 :             logmsg_func = jl_get_global((jl_module_t*)corelogging, jl_symbol("logmsg_shim"));
    1368                 :            :         }
    1369                 :            :     }
    1370         [ #  # ]:          0 :     if (!logmsg_func) {
    1371                 :            :         ios_t str_;
    1372                 :          0 :         ios_mem(&str_, 300);
    1373                 :          0 :         JL_STREAM* str = (JL_STREAM*)&str_;
    1374         [ #  # ]:          0 :         if (jl_is_string(msg)) {
    1375                 :          0 :             jl_uv_puts(str, jl_string_data(msg), jl_string_len(msg));
    1376                 :            :         }
    1377         [ #  # ]:          0 :         else if (jl_is_symbol(msg)) {
    1378                 :          0 :             jl_printf(str, "%s", jl_symbol_name((jl_sym_t*)msg));
    1379                 :            :         }
    1380                 :          0 :         jl_printf(str, "\n@ ");
    1381         [ #  # ]:          0 :         if (jl_is_string(file)) {
    1382                 :          0 :             jl_uv_puts(str, jl_string_data(file), jl_string_len(file));
    1383                 :            :         }
    1384         [ #  # ]:          0 :         else if (jl_is_symbol(file)) {
    1385                 :          0 :             jl_printf(str, "%s", jl_symbol_name((jl_sym_t*)file));
    1386                 :            :         }
    1387                 :          0 :         jl_printf(str, ":");
    1388                 :          0 :         jl_static_show(str, line);
    1389                 :          0 :         jl_safe_printf("%s [Fallback logging]: %.*s\n",
    1390                 :            :                        level < JL_LOGLEVEL_INFO ? "Debug" :
    1391         [ #  # ]:          0 :                        level < JL_LOGLEVEL_WARN ? "Info" :
    1392         [ #  # ]:          0 :                        level < JL_LOGLEVEL_ERROR ? "Warning" : "Error",
    1393         [ #  # ]:          0 :                        (int)str_.size, str_.buf);
    1394                 :          0 :         ios_close(&str_);
    1395                 :          0 :         return;
    1396                 :            :     }
    1397                 :            :     jl_value_t **args;
    1398                 :          0 :     const int nargs = 9;
    1399                 :          0 :     JL_GC_PUSHARGS(args, nargs);
    1400                 :          0 :     args[0] = logmsg_func;
    1401                 :          0 :     args[1] = jl_box_long(level);
    1402                 :          0 :     args[2] = msg;
    1403                 :            :     // Would some of the jl_nothing here be better as `missing` instead?
    1404         [ #  # ]:          0 :     args[3] = module ? module  : jl_nothing;
    1405         [ #  # ]:          0 :     args[4] = group  ? group   : jl_nothing;
    1406         [ #  # ]:          0 :     args[5] = id     ? id      : jl_nothing;
    1407         [ #  # ]:          0 :     args[6] = file   ? file    : jl_nothing;
    1408         [ #  # ]:          0 :     args[7] = line   ? line    : jl_nothing;
    1409         [ #  # ]:          0 :     args[8] = kwargs ? kwargs  : (jl_value_t*)jl_alloc_vec_any(0);
    1410                 :          0 :     jl_apply(args, nargs);
    1411                 :          0 :     JL_GC_POP();
    1412                 :            : }
    1413                 :            : 
    1414                 :            : #ifdef __cplusplus
    1415                 :            : }
    1416                 :            : #endif

Generated by: LCOV version 1.14