mg.c: Perl_magic_get() dont call libc's getter func _errno() over and over #23370
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Ever since threads and SMP motherboards were invented, C's grammer token errno has been a function call returning an int * and not a extern "C" global data variable. Whether C grammer token is an inline asm intrinsic macro, or a traditional linker symbol in the C lang's symbol table, doesn't matter. On Windows errno is a macro to int * _errno(void) from ucrtbase.dll The UCRT dll from its day 1 upto atleast the UCRT dllfrom Win 10 ~2019, has a severe multi-eval bug in its C++/CPP getter method for its core TLS fetcher function. The multi-eval problem involves GetProcAddress(), and dynamic dispatching between TlsGetValue() and FlsGetValue(), and the rule that non-inlined function calls may never be de-duped for any reason. C++ operator overloading and CPP #define will never turn 10 method calls in a .i file or C++ template, into 1 method call and 1 POD size_t/void * variable. VC6, all msvcrt.dlls thru VC 2013, correctly only execute TlsGetValue() once and cache the result. UCRT does not.
A pathologic reading of the POSIX spec, guarentees sv_setnv() UBed the value inside errno, through some ISO C lexer token inside the sv.i file made from sv.c that defines the body of sv_setnv(). If libc.so is chmod to --x by root user, how can a user prove the machine code inside libc's memcpy() does not call libc's sqrt() function? All behavior is unspecified and valid until it is defined. A realistic, not pedantic, location where errno was UBed could be these 2 lines:
SV_CHECK_THINKFIRST_COW_DROP(sv);
sv_upgrade(sv, SVt_PVNV);
This patch was written for Win32 perf reasons, and not POSIX/C compliance. The later are an afterthought. To fix all of the above, cache the retval of errno. The ticket for this patch has a before/after.