1
0
mirror of https://github.com/Interlisp/maiko.git synced 2026-04-26 12:27:32 +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 #ifndef GCSCANDEFS_H
#define GCSCANDEFS_H 1 #define GCSCANDEFS_H 1
#include "lispemul.h" /* for DLword */ int gcscan1(int probe);
DLword gcscan1(int probe); int gcscan2(int probe);
DLword gcscan2(int probe);
#endif #endif

View File

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

View File

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

View File

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

View File

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