Skip to content

Drop cxx-stl#263

Open
axd1x8a wants to merge 16 commits intomainfrom
feat/drop-cxx-stl
Open

Drop cxx-stl#263
axd1x8a wants to merge 16 commits intomainfrom
feat/drop-cxx-stl

Conversation

@axd1x8a
Copy link
Collaborator

@axd1x8a axd1x8a commented Mar 7, 2026

No description provided.

@axd1x8a
Copy link
Collaborator Author

axd1x8a commented Mar 7, 2026

Requires #259 to be merged first

@axd1x8a axd1x8a requested review from Dasaav-dsv, nex3 and vswarte March 7, 2026 09:54
@axd1x8a axd1x8a force-pushed the feat/drop-cxx-stl branch from ba694e4 to b845b1f Compare March 7, 2026 10:05
@axd1x8a axd1x8a mentioned this pull request Mar 7, 2026
@vswarte
Copy link
Owner

vswarte commented Mar 7, 2026

@nex3 can you confirm this works for DS3 too as far as you can?

@axd1x8a axd1x8a force-pushed the feat/drop-cxx-stl branch from b845b1f to ccf97cf Compare March 9, 2026 05:34
@axd1x8a axd1x8a force-pushed the feat/impl-stl-ourselves branch 2 times, most recently from dd3ce2b to cebdf96 Compare March 9, 2026 23:13
@axd1x8a axd1x8a force-pushed the feat/drop-cxx-stl branch from ccf97cf to 92d0d6c Compare March 9, 2026 23:41
@axd1x8a axd1x8a force-pushed the feat/impl-stl-ourselves branch from cebdf96 to 44a19b1 Compare March 10, 2026 02:26
@axd1x8a axd1x8a force-pushed the feat/drop-cxx-stl branch from 92d0d6c to 183066a Compare March 10, 2026 02:28
@axd1x8a axd1x8a force-pushed the feat/drop-cxx-stl branch 2 times, most recently from 2d2f960 to dfd9996 Compare March 10, 2026 05:07
@axd1x8a axd1x8a force-pushed the feat/drop-cxx-stl branch 2 times, most recently from 139cb21 to 19d7f8c Compare March 11, 2026 04:20
Base automatically changed from feat/impl-stl-ourselves to main March 15, 2026 05:09
@axd1x8a axd1x8a force-pushed the feat/drop-cxx-stl branch from a7688c1 to f643771 Compare March 15, 2026 06:02
@axd1x8a axd1x8a marked this pull request as ready for review March 15, 2026 06:02
Comment on lines +11 to +17
pub struct DLAllocatorForStl(NonNull<DLAllocatorBase>);

impl<T> DoublyLinkedList<T> {
pub fn iter(&self) -> impl Iterator<Item = &T> {
let mut count = self.count;
let mut current = unsafe { self.head.as_ref() };
impl From<NonNull<DLAllocatorBase>> for DLAllocatorForStl {
fn from(ptr: NonNull<DLAllocatorBase>) -> Self {
Self(ptr)
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is (and has always been) unsound. The From implementation especially allows you to convert from a pointer which provides no guarantees that the allocator is even initialized, let alone that it will live as long as as the reference. We should take this opportunity to fix it.

The most straightforward solution would be to just use &'static DLAllocatorBase instead for the vast majority of uses that do in fact refer to global allocators that last the entire process lifetime. That means we don't have to invent a bunch of our own custom infrastructure around creating and using it; we can just implement fromsoftware_shared_stl::Allocator for DLAllocatorBase directly.

If/when we need to model weirder situations like arena allocators that only exist for the lifetime of some parent object, we could use a newtype specifically for that like ShortLivedDLAllocator. This would also implement fromsoftware_shared_stl::Allocator to DLAllocatorBase, but it would have to strictly require (in the "Safety" block) that any ShortLivedDLAllocator members on FFI structs be private; otherwise, a caller with a mutable reference could potentially take ownership of it and use it beyond its stated lifetime without an unsafe {} block. This would have to include the STL types.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem here is: allocator type in collections is actually pointer to an allocator, so implementing it for DLAllocatorBase will not work, and we can't implement anything for NonNull or use OwnedPtr to get Deref.

}
})
impl fromsoftware_shared_stl::Allocator for DLAllocatorForStl {
unsafe fn allocate_raw(&mut self, size: usize, allign: usize) -> *mut c_void {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking about this more, I think we have to make this &self, not &mut self. Most allocators in these games are thread-safe, and for those it's expected that de/allocation calls be made concurrently across multiple threads. If this is &mut self that means that self can change while we hold a mutable reference, which violates soundness.

For arena allocators, we can treat them as having implicit UnsafeCells.

impl DLAllocatorForStl {
/// Returns the global instance of DLAllocator that uses the
/// standard MSVC malloc()/free() implementation for heap management
pub fn runtime_heap_allocator() -> Self {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should also return &'static DLAllocatorBase.

@nex3
Copy link
Collaborator

nex3 commented Mar 16, 2026

I don't think we should tie the allocator infrastructure so tightly to STL in particular. The same DLKR allocators are used all over the codebase, not just in STL types. Particularly with #269, we'll want to call the allocation and deallocation functions in contexts that are divorced from STL.

In practice, I think this means that we shouldn't rename DLAllocatorReference to DLAllocatorForStl. We can still use fromsoftware_shared_stl::Allocator to represent the user-friendly allocation interface, though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants