Skip to content

Commit

Permalink
GC-safe parser (#9) WIP
Browse files Browse the repository at this point in the history
move struct _GREG to greg.h, expose it in P as P->parser.
Idea by Peter Arthur
  • Loading branch information
rurban committed Feb 6, 2019
1 parent cc4cc14 commit a8f688f
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 121 deletions.
53 changes: 53 additions & 0 deletions core/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ by Basile Starynkevitch.
#include "gc.h"
#include "khash.h"
#include "table.h"
#include "../tools/greg.h"

#if defined(DEBUG)
//mingw32 has struct timeval in sys/time.h
Expand Down Expand Up @@ -133,6 +134,56 @@ static inline int NEW_BIRTH_REGION(struct PNMemory *M, void **wb, int sz) {
return sz;
}

void potion_gc_minor_parser(PN parser) {
if(parser == 0)
return;

struct _GREG *G = (struct _GREG *)parser;
struct PNMemory *M = ((Potion *)G->data)->mem;
Potion *P = G->data;

if(PN_IS_PTR(G->ss)) {
GC_MINOR_UPDATE(G->ss);
potion_mark_minor(G->data, (const struct PNObject *) G->ss);
}
if(PN_IS_PTR(G->val[0])) {
GC_MINOR_UPDATE(G->val[0]);
potion_mark_minor(G->data, (const struct PNObject *) G->val[0]);
}
int c = G->val - G->vals;
for(int i = 0; i < c; i++) {
if(PN_IS_PTR(G->vals[i])) {
GC_MINOR_UPDATE(G->vals[i]);
potion_mark_minor(G->data, (const struct PNObject *) G->vals[i]);
}
}
}

void potion_gc_major_parser(PN parser) {
if(parser == 0)
return;

struct _GREG *G = (struct _GREG *)parser;
struct PNMemory *M = ((Potion *)G->data)->mem;
Potion *P = G->data;

if(PN_IS_PTR(G->ss)) {
GC_MAJOR_UPDATE(G->ss);
potion_mark_major(P, (const struct PNObject *) G->ss);
}
if(PN_IS_PTR(G->val[0])) {
GC_MAJOR_UPDATE(G->val[0]);
potion_mark_major(P, (const struct PNObject *) G->val[0]);
}
int c = G->val - G->vals;
for(int i = 0; i < c; i++) {
if(G->vals[i] != NULL && PN_IS_PTR(G->vals[i])) {
GC_MAJOR_UPDATE(G->vals[i]);
potion_mark_major(P, (const struct PNObject *) G->vals[i]);
}
}
}

/** \par
Both this function and potion_gc_major embody a simple
Cheney loop (also called a "two-finger collector.")
Expand Down Expand Up @@ -161,6 +212,7 @@ static int potion_gc_minor(Potion *P, int sz) {
potion_mark_stack(P, 1);

GC_MINOR_STRINGS();
potion_gc_minor_parser(P->parser);

wb = (void **)M->birth_storeptr;
for (storead = wb; storead < (void **)M->birth_hi; storead++) {
Expand Down Expand Up @@ -239,6 +291,7 @@ static int potion_gc_major(Potion *P, int siz) {
scanptr = 0;

GC_MAJOR_STRINGS();
potion_gc_minor_parser(P->parser);

pngc_page_delete((void *)prevoldlo, (char *)prevoldhi - (char *)prevoldlo);
prevoldlo = 0;
Expand Down
2 changes: 1 addition & 1 deletion core/potion.h
Original file line number Diff line number Diff line change
Expand Up @@ -653,7 +653,7 @@ struct Potion_State {
int prec; ///< double precision

//parser-only:
PN input, source; ///< parser input and output (AST)
PN input, source, parser;///< parser input and output (AST)
int yypos; ///< parser buffer position
PNAsm * volatile pbuf; ///< parser buffer
PN line; ///< currently parsed line (for debug)
Expand Down
2 changes: 2 additions & 0 deletions core/syntax.y
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,7 @@ PN potion_parse(Potion *P, PN code, char *filename) {
P->yypos = 0;
P->input = code;
P->source = PN_NIL;
P->parser = (PN)G;
P->pbuf = potion_asm_new(P);
#ifdef YY_DEBUG
yydebug = P->flags;
Expand Down Expand Up @@ -449,6 +450,7 @@ PN potion_sig(Potion *P, char *fmt) {
P->yypos = 0;
P->input = potion_byte_str(P, fmt);
P->source = out = PN_TUP0();
P->parser = (PN)G;
P->pbuf = NULL;
#ifdef YY_DEBUG
yydebug = P->flags;
Expand Down
36 changes: 2 additions & 34 deletions tools/compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,6 @@ static char *header= "\
#include <stdio.h>\n\
#include <stdlib.h>\n\
#include <string.h>\n\
struct _GREG;\n\
";

static char *preamble= "\
Expand Down Expand Up @@ -564,12 +563,6 @@ static char *preamble= "\
# define yyprintfvokrule(rule)\n\
# define yyprintfvfailrule(rule)\n\
#endif\n\
#ifndef YYSTYPE\n\
#define YYSTYPE int\n\
#endif\n\
#ifndef YY_XTYPE\n\
#define YY_XTYPE void *\n\
#endif\n\
#ifndef YY_XVAR\n\
#define YY_XVAR yyxvar\n\
#endif\n\
Expand All @@ -586,35 +579,9 @@ static char *preamble= "\
#define yydata G->data\n\
#define yy G->ss\n\
\n\
struct _yythunk; // forward declaration\n\
typedef void (*yyaction)(struct _GREG *G, char *yytext, int yyleng, struct _yythunk *thunkpos, YY_XTYPE YY_XVAR);\n\
typedef struct _yythunk { int begin, end; yyaction action; const char *name; struct _yythunk *next; } yythunk;\n\
\n\
typedef struct _GREG {\n\
char *buf;\n\
int buflen;\n\
int offset;\n\
int pos;\n\
int limit;\n\
char *text;\n\
int textlen;\n\
int begin;\n\
int end;\n\
yythunk *thunks;\n\
int thunkslen;\n\
int thunkpos;\n\
int lineno;\n\
char *filename;\n\
FILE *input;\n\
YYSTYPE ss;\n\
YYSTYPE *val;\n\
YYSTYPE *vals;\n\
int valslen;\n\
YY_XTYPE data;\n\
#ifdef YY_DEBUG\n\
int debug;\n\
#endif\n\
} GREG;\n\
\n\
YY_LOCAL(int) yyrefill(GREG *G)\n\
{\n\
Expand Down Expand Up @@ -925,7 +892,8 @@ YY_PARSE(void) YY_NAME(parse_free)(GREG *G)\n\

void Rule_compile_c_header(void)
{
fprintf(output, "/* A recursive-descent parser generated by greg %d.%d.%d */\n", GREG_MAJOR, GREG_MINOR, GREG_LEVEL);
fprintf(output, "/* A recursive-descent parser generated by greg %d.%d.%d */\n",
GREG_MAJOR, GREG_MINOR, GREG_LEVEL);
fprintf(output, "\n");
fprintf(output, "%s", header);
fprintf(output, "#define YYRULECOUNT %d\n", ruleCount);
Expand Down
97 changes: 32 additions & 65 deletions tools/greg.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct _GREG;

#define YYRULECOUNT 38

# include "greg.h"
Expand Down Expand Up @@ -129,12 +129,6 @@ int main()\n\
# define yyprintfvokrule(rule)
# define yyprintfvfailrule(rule)
#endif
#ifndef YYSTYPE
#define YYSTYPE int
#endif
#ifndef YY_XTYPE
#define YY_XTYPE void *
#endif
#ifndef YY_XVAR
#define YY_XVAR yyxvar
#endif
Expand All @@ -151,36 +145,9 @@ int main()\n\
#define yydata G->data
#define yy G->ss

struct _yythunk; // forward declaration
typedef void (*yyaction)(struct _GREG *G, char *yytext, int yyleng, struct _yythunk *thunkpos, YY_XTYPE YY_XVAR);
typedef struct _yythunk { int begin, end; yyaction action; const char *name; struct _yythunk *next; } yythunk;

typedef struct _GREG {
char *buf;
int buflen;
int offset;
int pos;
int limit;
char *text;
int textlen;
int begin;
int end;
yythunk *thunks;
int thunkslen;
int thunkpos;
int lineno;
char *filename;
FILE *input;
YYSTYPE ss;
YYSTYPE *val;
YYSTYPE *vals;
int valslen;
YY_XTYPE data;
#ifdef YY_DEBUG
int debug;
#endif
} GREG;

YY_LOCAL(int) yyrefill(GREG *G)
{
int yyn;
Expand Down Expand Up @@ -284,7 +251,7 @@ YY_LOCAL(int) yymatchString(GREG *G, const char *s)
return 1;
}

YY_LOCAL(int) yymatchClass(GREG *G, const unsigned char *bits, char *cclass)
YY_LOCAL(int) yymatchClass(GREG *G, unsigned char *bits, char *cclass)
{
int c;
if (G->pos >= G->limit && !yyrefill(G)) return 0;
Expand Down Expand Up @@ -799,35 +766,35 @@ YY_RULE(int) yy_char(GREG *G)
{
int yypos23= G->pos, yythunkpos23= G->thunkpos;
if (!yymatchChar(G, '\\')) goto l24;
if (!yymatchClass(G, (const unsigned char *)"\000\000\000\000\204\040\000\000\000\000\000\070\146\100\124\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", "-abefnrtv'\"\\[\\]\\\\")) goto l24;
if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\204\040\000\000\000\000\000\070\146\100\124\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", "-abefnrtv'\"\\[\\]\\\\")) goto l24;
goto l23;
l24:
G->pos= yypos23; G->thunkpos= yythunkpos23;
if (!yymatchChar(G, '\\')) goto l25;
if (!yymatchChar(G, 'x')) goto l25;
if (!yymatchClass(G, (const unsigned char *)"\000\000\000\000\000\000\377\003\176\000\000\000\176\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", "0-9A-Fa-f")) goto l25;
if (!yymatchClass(G, (const unsigned char *)"\000\000\000\000\000\000\377\003\176\000\000\000\176\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", "0-9A-Fa-f")) goto l25;
if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\000\377\003\176\000\000\000\176\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", "0-9A-Fa-f")) goto l25;
if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\000\377\003\176\000\000\000\176\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", "0-9A-Fa-f")) goto l25;
goto l23;
l25:
G->pos= yypos23; G->thunkpos= yythunkpos23;
if (!yymatchChar(G, '\\')) goto l26;
if (!yymatchChar(G, 'x')) goto l26;
if (!yymatchClass(G, (const unsigned char *)"\000\000\000\000\000\000\377\003\176\000\000\000\176\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", "0-9A-Fa-f")) goto l26;
if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\000\377\003\176\000\000\000\176\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", "0-9A-Fa-f")) goto l26;
goto l23;
l26:
G->pos= yypos23; G->thunkpos= yythunkpos23;
if (!yymatchChar(G, '\\')) goto l27;
if (!yymatchClass(G, (const unsigned char *)"\000\000\000\000\000\000\017\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", "0-3")) goto l27;
if (!yymatchClass(G, (const unsigned char *)"\000\000\000\000\000\000\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", "0-7")) goto l27;
if (!yymatchClass(G, (const unsigned char *)"\000\000\000\000\000\000\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", "0-7")) goto l27;
if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\000\017\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", "0-3")) goto l27;
if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\000\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", "0-7")) goto l27;
if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\000\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", "0-7")) goto l27;
goto l23;
l27:
G->pos= yypos23; G->thunkpos= yythunkpos23;
if (!yymatchChar(G, '\\')) goto l28;
if (!yymatchClass(G, (const unsigned char *)"\000\000\000\000\000\000\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", "0-7")) goto l28;
if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\000\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", "0-7")) goto l28;
{
int yypos30= G->pos, yythunkpos30= G->thunkpos;
if (!yymatchClass(G, (const unsigned char *)"\000\000\000\000\000\000\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", "0-7")) goto l30;
if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\000\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", "0-7")) goto l30;
goto l29;
l30:
G->pos= yypos30; G->thunkpos= yythunkpos30;
Expand Down Expand Up @@ -950,7 +917,7 @@ YY_RULE(int) yy_literal(GREG *G)
yyprintfv((stderr, "%s\n", "literal"));
{
int yypos40= G->pos, yythunkpos40= G->thunkpos;
if (!yymatchClass(G, (const unsigned char *)"\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", "'")) goto l41;
if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", "'")) goto l41;
yyText(G, G->begin, G->end);
{
#define yytext G->text
Expand All @@ -966,7 +933,7 @@ YY_RULE(int) yy_literal(GREG *G)
int yypos43= G->pos, yythunkpos43= G->thunkpos;
{
int yypos44= G->pos, yythunkpos44= G->thunkpos;
if (!yymatchClass(G, (const unsigned char *)"\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", "'")) goto l44;
if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", "'")) goto l44;
goto l43;
l44:
G->pos= yypos44; G->thunkpos= yythunkpos44;
Expand All @@ -985,12 +952,12 @@ YY_RULE(int) yy_literal(GREG *G)
#undef yyleng
}

if (!yymatchClass(G, (const unsigned char *)"\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", "'")) goto l41;
if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", "'")) goto l41;
if (!yy__(G)) goto l41;
goto l40;
l41:
G->pos= yypos40; G->thunkpos= yythunkpos40;
if (!yymatchClass(G, (const unsigned char *)"\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", "\"")) goto l39;
if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", "\"")) goto l39;
yyText(G, G->begin, G->end);
{
#define yytext G->text
Expand All @@ -1006,7 +973,7 @@ YY_RULE(int) yy_literal(GREG *G)
int yypos46= G->pos, yythunkpos46= G->thunkpos;
{
int yypos47= G->pos, yythunkpos47= G->thunkpos;
if (!yymatchClass(G, (const unsigned char *)"\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", "\"")) goto l47;
if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", "\"")) goto l47;
goto l46;
l47:
G->pos= yypos47; G->thunkpos= yythunkpos47;
Expand All @@ -1025,7 +992,7 @@ YY_RULE(int) yy_literal(GREG *G)
#undef yyleng
}

if (!yymatchClass(G, (const unsigned char *)"\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", "\"")) goto l39;
if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", "\"")) goto l39;
if (!yy__(G)) goto l39;
}

Expand Down Expand Up @@ -1469,12 +1436,12 @@ YY_RULE(int) yy_identifier(GREG *G)
#undef yyleng
}

if (!yymatchClass(G, (const unsigned char *)"\000\000\000\000\000\040\000\000\376\377\377\207\376\377\377\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", "-a-zA-Z_")) goto l95;
if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\040\000\000\376\377\377\207\376\377\377\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", "-a-zA-Z_")) goto l95;

l96:
{
int yypos97= G->pos, yythunkpos97= G->thunkpos;
if (!yymatchClass(G, (const unsigned char *)"\000\000\000\000\000\040\377\003\376\377\377\207\376\377\377\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", "-a-zA-Z_0-9")) goto l97;
if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\040\377\003\376\377\377\207\376\377\377\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", "-a-zA-Z_0-9")) goto l97;
goto l96;
l97:
G->pos= yypos97; G->thunkpos= yythunkpos97;
Expand Down Expand Up @@ -1729,26 +1696,26 @@ typedef int (*yyrule)(GREG *G);
YY_PARSE(int) YY_NAME(parse_from)(GREG *G, yyrule yystart)
{
int yyok;
if (!G->buflen) {
G->buflen= YY_BUFFER_START_SIZE;
G->buf= (char*)YY_ALLOC(G->buflen, G->data);
G->textlen= YY_BUFFER_START_SIZE;
G->text= (char*)YY_ALLOC(G->textlen, G->data);
G->thunkslen= YY_STACK_SIZE;
G->thunks= (yythunk*)YY_ALLOC(sizeof(yythunk) * G->thunkslen, G->data);
G->valslen= YY_STACK_SIZE;
G->vals= (YYSTYPE*)YY_ALLOC(sizeof(YYSTYPE) * G->valslen, G->data);
G->begin= G->end= G->pos= G->limit= G->thunkpos= 0;
}
G->pos= 0;
if (!G->buflen)
{
G->buflen= YY_BUFFER_START_SIZE;
G->buf= (char*)YY_ALLOC(G->buflen, G->data);
G->textlen= YY_BUFFER_START_SIZE;
G->text= (char*)YY_ALLOC(G->textlen, G->data);
G->thunkslen= YY_STACK_SIZE;
G->thunks= (yythunk*)YY_ALLOC(sizeof(yythunk) * G->thunkslen, G->data);
G->valslen= YY_STACK_SIZE;
G->vals= (YYSTYPE*)YY_ALLOC(sizeof(YYSTYPE) * G->valslen, G->data);
G->begin= G->end= G->pos= G->limit= G->thunkpos= 0;
}
G->pos = 0;
G->begin= G->end= G->pos;
G->thunkpos= 0;
G->val= G->vals;
yyok= yystart(G);
if (yyok) yyDone(G);
yyCommit(G);
return yyok;

(void)yyrefill;
(void)yymatchDot;
(void)yymatchChar;
Expand Down
Loading

0 comments on commit a8f688f

Please sign in to comment.