Files
Iain Buclaw e8c9f4ab8f d: Merge upstream dmd, druntime b7e3b3b617
D front-end changes:

	- `delete' is no longer a keyword.
	- Initializing a field with itself has been deprecated.

D runtime changes:

	- Add Windows BCrypt bindings under `core.sys.windows.bcrypt'.

gcc/d/ChangeLog:

	* dmd/MERGE: Merge upstream b7e3b3b617.

libphobos/ChangeLog:

	* libdruntime/MERGE: Merge upstream b7e3b3b617.
	* libdruntime/Makefile.am (DRUNTIME_DSOURCES_WINDOWS): Add
	core/sys/windows/bcrypt.d.
	* libdruntime/Makefile.in: Regenerate.
	* libdruntime/gcc/sections/elf.d (sizeofTLS): Give function the same
	mangling as gcc.sections.sizeofTLS.
	* libdruntime/gcc/sections/package.d: Import core.internal.traits.
	(pinLoadedLibraries): Mangle as function from rt.sections_elf_shared.
	(unpinLoadedLibraries): Likewise.
	(inheritLoadedLibraries): Likewise.
	(cleanupLoadedLibraries): Likewise.
	(sizeOfTLS): Add forward declaration.
2025-03-15 16:33:00 +01:00

106 lines
3.0 KiB
D

/**
* Array utilities.
*
* Copyright: Denis Shelomovskij 2013
* License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).
* Authors: Denis Shelomovskij
* Source: $(DRUNTIMESRC core/internal/util/_array.d)
*/
module core.internal.util.array;
import core.internal.string;
import core.stdc.stdint : uintptr_t;
// TLS storage shared for all error messages.
private align(2 * size_t.sizeof) char[256] _store;
private char[] errorMessage(Args...)(scope const(char*) format,
const char[] action, Args args) @trusted
{
import core.stdc.stdio : snprintf;
snprintf(&_store[0], _store.sizeof, format, &action[0], args);
return _store;
}
@safe /* pure dmd @@@BUG11461@@@ */ nothrow:
void enforceRawArraysConformable(const char[] action, const size_t elementSize,
const void[] a1, const void[] a2, const bool allowOverlap = false)
{
_enforceSameLength(action, a1.length, a2.length);
if (!allowOverlap)
_enforceNoOverlap(action, arrayToPtr(a1), arrayToPtr(a2), elementSize * a1.length);
}
private void _enforceSameLength(const char[] action,
const size_t length1, const size_t length2)
{
if (length1 == length2)
return;
UnsignedStringBuf tmpBuff = void;
string msg = "Array lengths don't match for ";
msg ~= action;
msg ~= ": ";
msg ~= length1.unsignedToTempString(tmpBuff);
msg ~= " != ";
msg ~= length2.unsignedToTempString(tmpBuff);
assert(0, msg);
}
private void _enforceNoOverlap(const char[] action,
uintptr_t ptr1, uintptr_t ptr2, const size_t bytes)
{
const d = ptr1 > ptr2 ? ptr1 - ptr2 : ptr2 - ptr1;
if (d >= bytes)
return;
const overlappedBytes = bytes - d;
UnsignedStringBuf tmpBuff = void;
string msg = "Overlapping arrays in ";
msg ~= action;
msg ~= ": ";
msg ~= overlappedBytes.unsignedToTempString(tmpBuff);
msg ~= " byte(s) overlap of ";
msg ~= bytes.unsignedToTempString(tmpBuff);
assert(0, msg);
}
void enforceRawArraysConformableNogc(const char[] action, const size_t elementSize,
const void[] a1, const void[] a2, const bool allowOverlap = false)
{
_enforceSameLengthNogc(action, a1.length, a2.length);
if (!allowOverlap)
_enforceNoOverlapNogc(action, arrayToPtr(a1), arrayToPtr(a2), elementSize * a1.length);
}
private void _enforceNoOverlapNogc(const ref char[] action,
uintptr_t ptr1, uintptr_t ptr2, const size_t bytes)
{
const d = ptr1 > ptr2 ? ptr1 - ptr2 : ptr2 - ptr1;
if (d >= bytes)
return;
const overlappedBytes = bytes - d;
assert(0, errorMessage("Overlapping arrays in %s: %zu byte(s) overlap of %zu",
action, overlappedBytes, bytes));
}
private void _enforceSameLengthNogc(const ref char[] action,
const size_t length1, const size_t length2)
{
if (length1 == length2)
return;
assert(0, errorMessage("Array lengths don't match for %s: %zu != %zu",
action, length1, length2));
}
private uintptr_t arrayToPtr(const void[] array) @trusted
{
// Ok because the user will never dereference the pointer
return cast(uintptr_t)array.ptr;
}