summaryrefslogtreecommitdiff
path: root/rts/StablePtr.c
diff options
context:
space:
mode:
authorAdam Sandberg Ericsson <adam@sandbergericsson.se>2022-06-18 10:01:22 +0100
committerMarge Bot <ben+marge-bot@smart-cactus.org>2022-07-07 23:24:34 -0400
commit42c917df5be8d75f79a283a8ed59fbaf099bc973 (patch)
tree9efeae5f39cd9c8ff49ec68ceb3b9f5f5a6ee2cf /rts/StablePtr.c
parentfa59223b05e24d6e477e3ab0ab296e32b2b65a8b (diff)
downloadhaskell-42c917df5be8d75f79a283a8ed59fbaf099bc973.tar.gz
rts: allow NULL to be used as an invalid StgStablePtr
Diffstat (limited to 'rts/StablePtr.c')
-rw-r--r--rts/StablePtr.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/rts/StablePtr.c b/rts/StablePtr.c
index ffd1d0775a..c2e7cda2c3 100644
--- a/rts/StablePtr.c
+++ b/rts/StablePtr.c
@@ -88,6 +88,16 @@
https://gitlab.haskell.org/ghc/ghc/issues/7670 for details.
*/
+/*
+ * Note [NULL StgStablePtr]
+ * ~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * StablePtr index 0 is reserved to represent NULL. Consequently, we must
+ * subtract 1 to get the index into the array and add 1 to the index to get the
+ * StablePtr.
+ */
+
+
spEntry *stable_ptr_table = NULL;
static spEntry *stable_ptr_free = NULL;
static unsigned int SPT_size = 0;
@@ -255,8 +265,13 @@ freeSpEntry(spEntry *sp)
void
freeStablePtrUnsafe(StgStablePtr sp)
{
- ASSERT((StgWord)sp < SPT_size);
- freeSpEntry(&stable_ptr_table[(StgWord)sp]);
+ // see Note [NULL StgStablePtr]
+ if (sp == NULL) {
+ return;
+ }
+ StgWord spw = (StgWord)sp - 1;
+ ASSERT(spw < SPT_size);
+ freeSpEntry(&stable_ptr_table[spw]);
}
void
@@ -282,6 +297,8 @@ getStablePtr(StgPtr p)
stable_ptr_free = (spEntry*)(stable_ptr_free->addr);
RELAXED_STORE(&stable_ptr_table[sp].addr, p);
stablePtrUnlock();
+ // see Note [NULL StgStablePtr]
+ sp = sp + 1;
return (StgStablePtr)(sp);
}