ref: 6002304890fefb27aa0f75bf2389a56083e57ddd
parent: 4db170e4e9764d8f82a206f826823bf4e17dfbe9
author: Lennart Augustsson <lennart.augustsson@epicgames.com>
date: Tue Sep 26 11:22:07 EDT 2023
Refactor code reading from file.
--- a/Tools/Addcombs.hs
+++ b/Tools/Addcombs.hs
@@ -19,7 +19,8 @@
file <- readFile fn
let size = length file
chunks = chunkify 20 file
- putStrLn $ "struct { size_t b_size; size_t b_pos; uint8_t b_buffer[]; } combs = { " ++ showInt size ++ ", 0, {"+ putStrLn $ "struct { BFILE mets; size_t b_size; size_t b_pos; uint8_t b_buffer[]; } combs =\n { { getb_buf, ungetb_buf, closeb_buf }, "+ ++ showInt size ++ ", 0, {"mapM_ (putStrLn . showChunk) chunks
putStrLn "}};"
putStrLn "BFILE *comb_internal = (BFILE*)&combs;"
--- a/src/runtime/eval.c
+++ b/src/runtime/eval.c
@@ -272,19 +272,7 @@
heapoffs_t free_map_nwords;
heapoffs_t next_scan_index;
-typedef struct {- size_t b_size;
- size_t b_pos;
- uint8_t b_buffer[1];
-} BFILE;
-
-struct handler {- jmp_buf hdl_buf; /* env storage */
- struct handler *hdl_old; /* old handler */
- stackptr_t hdl_stack; /* old stack pointer */
- NODEPTR hdl_exn; /* used temporarily to pass the exception value */
-} *cur_handler = 0;
-
+__attribute__ ((noreturn)) // [[noreturn]]
void
memerr(void)
{@@ -292,21 +280,27 @@
exit(1);
}
-BFILE *
-alloc_buffer(size_t size)
-{- BFILE *p;
- p = malloc(sizeof(BFILE) + size);
- if (!p)
- memerr();
- p->b_size = size;
- p->b_pos = 0;
- return p;
-}
+/***************** BFILE *******************/
+/* BFILE will have different implementations, they all have these methods */
+typedef struct BFILE {+ int (*getb)(struct BFILE*);
+ void (*ungetb)(int c, struct BFILE*);
+ void (*closeb)(struct BFILE*);
+} BFILE;
+
+/*** BFILE from static buffer ***/
+struct BFILE_buffer {+ BFILE mets;
+ size_t b_size;
+ size_t b_pos;
+ uint8_t b_buffer[1];
+};
+
int
-getb(BFILE *p)
+getb_buf(BFILE *bp)
{+ struct BFILE_buffer *p = (struct BFILE_buffer *)bp;
if (p->b_pos >= p->b_size)
return -1;
return p->b_buffer[p->b_pos++];
@@ -313,13 +307,71 @@
}
void
-ungetb(int c, BFILE *p)
+ungetb_buf(int c, BFILE *bp)
{+ struct BFILE_buffer *p = (struct BFILE_buffer *)bp;
if (p->b_pos == 0)
ERR("ungetb");p->b_buffer[--p->b_pos] = (uint8_t)c;
}
+void
+closeb_buf(BFILE *)
+{+}
+
+/*** BFILE via FILE ***/
+struct BFILE_file {+ BFILE mets;
+ FILE *file;
+};
+
+int
+getb_file(BFILE *bp)
+{+ struct BFILE_file *p = (struct BFILE_file *)bp;
+ return fgetc(p->file);
+}
+
+void
+ungetb_file(int c, BFILE *bp)
+{+ struct BFILE_file *p = (struct BFILE_file *)bp;
+ ungetc(c, p->file);
+}
+
+void
+closeb_file(BFILE *bp)
+{+ struct BFILE_file *p = (struct BFILE_file *)bp;
+ free(p);
+}
+
+BFILE *
+openb_FILE(FILE *f)
+{+ struct BFILE_file *p = malloc(sizeof (struct BFILE_file));
+ if (!p)
+ memerr();
+ p->mets.getb = getb_file;
+ p->mets.ungetb = ungetb_file;
+ p->mets.closeb = closeb_file;
+ p->file = f;
+ return (BFILE*)p;
+}
+
+/*** Coming soon: BFILE via decompression ***/
+
+
+/*****************************************************************************/
+
+struct handler {+ jmp_buf hdl_buf; /* env storage */
+ struct handler *hdl_old; /* old handler */
+ stackptr_t hdl_stack; /* old stack pointer */
+ NODEPTR hdl_exn; /* used temporarily to pass the exception value */
+} *cur_handler = 0;
+
/* Set FREE bit to 0 */
static inline void mark_used(NODEPTR n)
{@@ -760,11 +812,11 @@
int
gobble(BFILE *f, int c)
{- int d = getb(f);
+ int d = f->getb(f);
if (c == d) {return 1;
} else {- ungetb(d, f);
+ f->ungetb(d, f);
return 0;
}
}
@@ -775,9 +827,9 @@
{int c;
- c = getb(f);
+ c = f->getb(f);
if (c == ' ' || c == ')') {- ungetb(c, f);
+ f->ungetb(c, f);
return 0;
} else {return c;
@@ -788,12 +840,12 @@
parse_int(BFILE *f)
{value_t i = 0;
- int c = getb(f);
+ int c = f->getb(f);
for(;;) {i = i * 10 + c - '0';
- c = getb(f);
+ c = f->getb(f);
if (c < '0' || c > '9') {- ungetb(c, f);
+ f->ungetb(c, f);
break;
}
}
@@ -864,7 +916,7 @@
int c;
char buf[80]; /* store names of primitives. */
- c = getb(f);
+ c = f->getb(f);
if (c < 0) ERR("parse EOF"); switch (c) { case '(' :@@ -876,7 +928,7 @@
if (!gobble(f, ')')) ERR("parse ')'");return r;
case '-':
- c = getb(f);
+ c = f->getb(f);
neg = -1;
if ('0' <= c && c <= '9') {goto number;
@@ -891,7 +943,7 @@
/* integer [0-9]+*/
neg = 1;
number:
- ungetb(c, f);
+ f->ungetb(c, f);
i = neg * parse_int(f);
r = mkInt(i);
return r;
@@ -943,7 +995,7 @@
char *buffer = malloc(10000);
char *p = buffer;
for(;;) {- c = getb(f);
+ c = f->getb(f);
if (c == '"')
break;
if (c == '\\') {@@ -978,7 +1030,7 @@
int c;
while ((c = *p++)) {- if (c != getb(f))
+ if (c != f->getb(f))
ERR("version mismatch");}
gobble(f, '\r'); /* allow extra CR */
@@ -1007,24 +1059,10 @@
NODEPTR
parse_FILE(FILE *f)
{- size_t size;
- off_t pos;
-
- /* Determine how much is left of the file */
- pos = ftell(f);
- (void)fseek(f, 0, SEEK_END);
- size = (size_t)(ftell(f) - pos);
- (void)fseek(f, pos, SEEK_SET);
-
- /* Read entire file */
- BFILE *b = alloc_buffer(size);
- if (fread(b->b_buffer, 1, size, f) != size)
- ERR("fread");-
+ BFILE *p = openb_FILE(f);
/* And parse it */
- NODEPTR n = parse_top(b);
-
- free(b);
+ NODEPTR n = parse_top(p);
+ p->closeb(p);
return n;
}
@@ -1034,9 +1072,10 @@
FILE *f = fopen(fn, "r");
if (!f)
ERR("file not found");+
+ /* And parse it */
NODEPTR n = parse_FILE(f);
*psize = ftell(f);
- fclose(f);
return n;
}
--
⑨