mirror of
https://github.com/janet-lang/janet
synced 2025-02-10 13:50:02 +00:00
Allocate parser with GC.
This fixes janet_dobytes, which manually allocated a parser on the stack, and then possibly ran garbage collection before it was deallocated.
This commit is contained in:
parent
06d581dde3
commit
49f151e265
@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
/* Run a string */
|
/* Run a string */
|
||||||
int janet_dobytes(JanetTable *env, const uint8_t *bytes, int32_t len, const char *sourcePath, Janet *out) {
|
int janet_dobytes(JanetTable *env, const uint8_t *bytes, int32_t len, const char *sourcePath, Janet *out) {
|
||||||
JanetParser parser;
|
JanetParser *parser;
|
||||||
int errflags = 0, done = 0;
|
int errflags = 0, done = 0;
|
||||||
int32_t index = 0;
|
int32_t index = 0;
|
||||||
Janet ret = janet_wrap_nil();
|
Janet ret = janet_wrap_nil();
|
||||||
@ -37,14 +37,16 @@ int janet_dobytes(JanetTable *env, const uint8_t *bytes, int32_t len, const char
|
|||||||
|
|
||||||
if (where) janet_gcroot(janet_wrap_string(where));
|
if (where) janet_gcroot(janet_wrap_string(where));
|
||||||
if (NULL == sourcePath) sourcePath = "<unknown>";
|
if (NULL == sourcePath) sourcePath = "<unknown>";
|
||||||
janet_parser_init(&parser);
|
parser = janet_abstract(&janet_parser_type, sizeof(JanetParser));
|
||||||
|
janet_parser_init(parser);
|
||||||
|
janet_gcroot(janet_wrap_abstract(parser));
|
||||||
|
|
||||||
/* While we haven't seen an error */
|
/* While we haven't seen an error */
|
||||||
while (!done) {
|
while (!done) {
|
||||||
|
|
||||||
/* Evaluate parsed values */
|
/* Evaluate parsed values */
|
||||||
while (janet_parser_has_more(&parser)) {
|
while (janet_parser_has_more(parser)) {
|
||||||
Janet form = janet_parser_produce(&parser);
|
Janet form = janet_parser_produce(parser);
|
||||||
JanetCompileResult cres = janet_compile(form, env, where);
|
JanetCompileResult cres = janet_compile(form, env, where);
|
||||||
if (cres.status == JANET_COMPILE_OK) {
|
if (cres.status == JANET_COMPILE_OK) {
|
||||||
JanetFunction *f = janet_thunk(cres.funcdef);
|
JanetFunction *f = janet_thunk(cres.funcdef);
|
||||||
@ -58,8 +60,8 @@ int janet_dobytes(JanetTable *env, const uint8_t *bytes, int32_t len, const char
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ret = janet_wrap_string(cres.error);
|
ret = janet_wrap_string(cres.error);
|
||||||
int32_t line = (int32_t) parser.line;
|
int32_t line = (int32_t) parser->line;
|
||||||
int32_t col = (int32_t) parser.column;
|
int32_t col = (int32_t) parser->column;
|
||||||
if ((cres.error_mapping.line > 0) &&
|
if ((cres.error_mapping.line > 0) &&
|
||||||
(cres.error_mapping.column > 0)) {
|
(cres.error_mapping.column > 0)) {
|
||||||
line = cres.error_mapping.line;
|
line = cres.error_mapping.line;
|
||||||
@ -81,16 +83,16 @@ int janet_dobytes(JanetTable *env, const uint8_t *bytes, int32_t len, const char
|
|||||||
if (done) break;
|
if (done) break;
|
||||||
|
|
||||||
/* Dispatch based on parse state */
|
/* Dispatch based on parse state */
|
||||||
switch (janet_parser_status(&parser)) {
|
switch (janet_parser_status(parser)) {
|
||||||
case JANET_PARSE_DEAD:
|
case JANET_PARSE_DEAD:
|
||||||
done = 1;
|
done = 1;
|
||||||
break;
|
break;
|
||||||
case JANET_PARSE_ERROR: {
|
case JANET_PARSE_ERROR: {
|
||||||
const char *e = janet_parser_error(&parser);
|
const char *e = janet_parser_error(parser);
|
||||||
errflags |= 0x04;
|
errflags |= 0x04;
|
||||||
ret = janet_cstringv(e);
|
ret = janet_cstringv(e);
|
||||||
int32_t line = (int32_t) parser.line;
|
int32_t line = (int32_t) parser->line;
|
||||||
int32_t col = (int32_t) parser.column;
|
int32_t col = (int32_t) parser->column;
|
||||||
janet_eprintf("%s:%d:%d: parse error: %s\n", sourcePath, line, col, e);
|
janet_eprintf("%s:%d:%d: parse error: %s\n", sourcePath, line, col, e);
|
||||||
done = 1;
|
done = 1;
|
||||||
break;
|
break;
|
||||||
@ -98,9 +100,9 @@ int janet_dobytes(JanetTable *env, const uint8_t *bytes, int32_t len, const char
|
|||||||
case JANET_PARSE_ROOT:
|
case JANET_PARSE_ROOT:
|
||||||
case JANET_PARSE_PENDING:
|
case JANET_PARSE_PENDING:
|
||||||
if (index >= len) {
|
if (index >= len) {
|
||||||
janet_parser_eof(&parser);
|
janet_parser_eof(parser);
|
||||||
} else {
|
} else {
|
||||||
janet_parser_consume(&parser, bytes[index++]);
|
janet_parser_consume(parser, bytes[index++]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -108,7 +110,7 @@ int janet_dobytes(JanetTable *env, const uint8_t *bytes, int32_t len, const char
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Clean up and return errors */
|
/* Clean up and return errors */
|
||||||
janet_parser_deinit(&parser);
|
janet_gcunroot(janet_wrap_abstract(parser));
|
||||||
if (where) janet_gcunroot(janet_wrap_string(where));
|
if (where) janet_gcunroot(janet_wrap_string(where));
|
||||||
#ifdef JANET_EV
|
#ifdef JANET_EV
|
||||||
/* Enter the event loop if we are not already in it */
|
/* Enter the event loop if we are not already in it */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user