1
0
mirror of https://github.com/Interlisp/maiko.git synced 2026-02-27 00:59:46 +00:00

Fix gcscan1, gcscan2 can miss finding 0th entry in gc hashtable #1038

The Lisp implementation distinguishes between 0 and NIL as the result of
    the gcscan1/gcscan2 opcodes, however the C implementation did not, since
    NIL and 0 are indistinguishable.
This commit is contained in:
Nick Briggs
2023-02-15 12:50:58 -08:00
parent 937a003bfb
commit 900c9557ab
5 changed files with 26 additions and 21 deletions

View File

@@ -1,6 +1,5 @@
#ifndef GCSCANDEFS_H
#define GCSCANDEFS_H 1
#include "lispemul.h" /* for DLword */
DLword gcscan1(int probe);
DLword gcscan2(int probe);
int gcscan1(int probe);
int gcscan2(int probe);
#endif

View File

@@ -449,15 +449,15 @@
#define GCSCAN1 \
do { \
TOPOFSTACK = gcscan1(TOPOFSTACK & 0xffff); \
if (TOPOFSTACK) { TOPOFSTACK |= S_POSITIVE; }; \
int scan = gcscan1(TOPOFSTACK & 0xffff); \
TOPOFSTACK = (scan == -1) ? NIL : (S_POSITIVE | scan); \
nextop1; \
} while (0)
#define GCSCAN2 \
do { \
TOPOFSTACK = gcscan2(TOPOFSTACK & 0xffff); \
if (TOPOFSTACK) { TOPOFSTACK |= S_POSITIVE; }; \
int scan = gcscan2(TOPOFSTACK & 0xffff); \
TOPOFSTACK = (scan == -1) ? NIL : (S_POSITIVE | scan); \
nextop1; \
} while (0)

View File

@@ -40,13 +40,17 @@
/**********************************************************************/
void OP_gcscan1(void) {
int scan;
#ifdef TRACE
printPC();
printf("TRACE: OP_gcscan1()\n");
#endif
if ((TopOfStack & SEGMASK) == S_POSITIVE) { TopOfStack = gcscan1(LOLOC(TopOfStack)); }
if (TopOfStack != NIL) TopOfStack |= S_POSITIVE;
if ((TopOfStack & SEGMASK) == S_POSITIVE) {
scan = gcscan1(LOLOC(TopOfStack));
TopOfStack = (scan == -1) ? NIL : scan | S_POSITIVE;
} else {
printf("OP_gcscan1: not a number\n");
}
PC++;
} /* OP_gcscan1 end */
@@ -57,12 +61,14 @@ void OP_gcscan1(void) {
/**********************************************************************/
void OP_gcscan2(void) {
int scan;
#ifdef TRACE
printPC();
printf("TRACE: OP_gcscan2()\n");
#endif
if ((TopOfStack & SEGMASK) == S_POSITIVE) { TopOfStack = gcscan2(LOLOC(TopOfStack)); }
if (TopOfStack != NIL) TopOfStack |= S_POSITIVE;
if ((TopOfStack & SEGMASK) == S_POSITIVE) {
scan = gcscan2(LOLOC(TopOfStack));
TopOfStack = (scan == -1) ? NIL : scan | S_POSITIVE;
}
PC++;
} /* OP_gcscan2 end */

View File

@@ -89,14 +89,14 @@
LispPTR gcmapscan(void) {
GCENTRY probe;
int probe;
GCENTRY *entry;
GCENTRY offset, dbgcontents;
LispPTR ptr;
probe = HTMAIN_ENTRY_COUNT;
nextentry:
while ((probe = gcscan1(probe)) != NIL) {
while ((probe = gcscan1(probe)) != -1) {
entry = (GCENTRY *)HTmain + probe;
retry:
if (HENTRY->collision) {
@@ -135,12 +135,12 @@ nextentry:
}
LispPTR gcmapunscan(void) {
GCENTRY probe;
int probe;
GCENTRY *entry;
GCENTRY offset;
probe = HTMAIN_ENTRY_COUNT;
while ((probe = gcscan2(probe)) != NIL) {
while ((probe = gcscan2(probe)) != -1) {
entry = (GCENTRY *)HTmain + probe;
retry:
if (HENTRY->collision) {

View File

@@ -63,7 +63,7 @@
#define GetStkCnt(entry1) (entry1 >> 9)
#endif /* BIGVM */
DLword gcscan1(int probe)
int gcscan1(int probe)
/* probe is offset */
{
struct htlinkptr *htlptr; /* overlay access method */
@@ -76,10 +76,10 @@ DLword gcscan1(int probe)
if (contents && (((struct hashentry *)GCPTR(HTENDS))->collision || (GetStkCnt(contents) == 0)))
return (probe);
}
return (NIL);
return (-1);
}
DLword gcscan2(int probe)
int gcscan2(int probe)
/* probe is offset */
{
struct htlinkptr *htlptr; /* overlay access method */
@@ -90,5 +90,5 @@ DLword gcscan2(int probe)
if (((HTSTKBIT | 1) & ((struct htlinkptr *)GCPTR(htlptr))->contents) != 0)
return (probe); /* stackref or collision ON */
}
return (NIL);
return (-1);
}