From efce9428b0afd1dab67f62734cfd9da4260fbf63 Mon Sep 17 00:00:00 2001 From: HASUMI Hitoshi Date: Mon, 22 Jan 2024 21:59:01 +0900 Subject: [PATCH] WIP --- parse.y | 211 +++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 187 insertions(+), 24 deletions(-) diff --git a/parse.y b/parse.y index 7cb92b88e3385b..fba1095d870273 100644 --- a/parse.y +++ b/parse.y @@ -2130,6 +2130,168 @@ rb_str_to_parser_encoding_string(rb_parser_t *p, VALUE str) /* Type check */ return rb_parser_encoding_string_new(p, RSTRING_PTR(str), RSTRING_LEN(str), rb_enc_get(str)); } + +/* + * Array-like object for parser + */ + +#define rb_parser_ary_element VALUE +typedef struct rb_parser_ary { + VALUE flags; + rb_parser_ary_element *data; + long len; // current size + long capa; // capacity +} rb_parser_ary_t; + +#define PARRAY(obj) ((struct rb_parser_ary *)(obj)) + +static void +rb_parser_ary_extend(rb_parser_t *p, VALUE ary, long len) +{ + long i; + if (PARRAY(ary)->capa < len) { + PARRAY(ary)->capa = len; + PARRAY(ary)->data = realloc(PARRAY(ary)->data, sizeof(rb_parser_ary_element) * len); + for (i = PARRAY(ary)->len; i < len; i++) { + PARRAY(ary)->data[i] = Qnil; + } + } +} + +static VALUE +rb_parser_ary_new_capa(rb_parser_t *p, long len) +{ + VALUE ary = (VALUE)xmalloc(sizeof(struct rb_parser_ary)); + long i; + PARRAY(ary)->flags = T_ARRAY; + PARRAY(ary)->len = len; + PARRAY(ary)->capa = len; + PARRAY(ary)->data = xmalloc(sizeof(rb_parser_ary_element) * len); + for (i = 0; i < len; i++) { + PARRAY(ary)->data[i] = Qnil; + } + return ary; +} +#define rb_parser_ary_new2 rb_parser_ary_new_capa + +static void +rb_parser_ary_store(rb_parser_t *p, VALUE ary, long key, VALUE val) +{ + if (PARRAY(ary)->data[key]) { + //rb_gc_force_recycle(PARRAY(ary)->data[key]); + } + if (PARRAY(ary)->len <= key) { + rb_parser_ary_extend(p, ary, key + 1); + } + PARRAY(ary)->data[key] = val; +} + +static VALUE +rb_parser_ary_new_from_args(rb_parser_t *p, long len, ...) +{ + va_list ar; + VALUE ary; + long i; + ary = rb_parser_ary_new_capa(p, len); + va_start(ar, len); + if (len > 0) { + for (i = 0; i < len; i++) { + rb_parser_ary_store(p, ary, i, va_arg(ar, VALUE)); + } + } + va_end(ar); + return ary; +} + +inline static VALUE +rb_parser_ary_new(rb_parser_t *p) +{ + return rb_parser_ary_new_capa(p, 0); +} + +static VALUE +rb_parser_ary_unshift(rb_parser_t *p, VALUE ary, VALUE val) +{ + rb_parser_ary_extend(p, ary, PARRAY(ary)->len + 1); + memmove(PARRAY(ary)->data + 1, PARRAY(ary)->data, sizeof(rb_parser_ary_element) * PARRAY(ary)->len); + PARRAY(ary)->data[0] = val; + PARRAY(ary)->len++; + rb_gc_mark(val); + return ary; +} + +static VALUE +rb_parser_ary_push(rb_parser_t *p, VALUE ary, VALUE val) +{ + rb_parser_ary_extend(p, ary, PARRAY(ary)->len + 1); + PARRAY(ary)->data[PARRAY(ary)->len++] = val; + rb_gc_mark(val); + return ary; +} + +static VALUE +rb_parser_ary_reverse(rb_parser_t *p, VALUE ary) +{ + long i; + for (i = 0; i < PARRAY(ary)->len / 2; i++) { + VALUE tmp = PARRAY(ary)->data[i]; + PARRAY(ary)->data[i] = PARRAY(ary)->data[PARRAY(ary)->len - i - 1]; + PARRAY(ary)->data[PARRAY(ary)->len - i - 1] = tmp; + } + return ary; +} + +static VALUE +rb_parser_ary_clear(rb_parser_t *p, VALUE ary) +{ + long i; + for (i = 0; i < PARRAY(ary)->len; i++) { + //rb_gc_force_recycle(PARRAY(ary)->data[i]); + } + PARRAY(ary)->len = 0; + return ary; +} + +/* +static VALUE +rb_parser_ary_concat(rb_parser_t *p, VALUE ary1, VALUE ary2) +{ + long i; + rb_parser_ary_extend(p, ary1, PARRAY(ary1)->len + PARRAY(ary2)->len); + for (i = 0; i < PARRAY(ary2)->len; i++) { + PARRAY(ary1)->data[PARRAY(ary1)->len++] = PARRAY(ary2)->data[i]; + } + return ary1; +} +*/ + +static VALUE +rb_parser_ary_join(rb_parser_t *p, VALUE ary, VALUE sep) +{ + long i; + VALUE str = rb_str_new(0, 0); + for (i = 0; i < PARRAY(ary)->len; i++) { + if (i > 0) { + rb_str_concat(str, sep); + } + rb_str_concat(str, PARRAY(ary)->data[i]); + } + return str; +} + +static void +rb_parser_ary_modify(rb_parser_t *p, VALUE ary) +{ + /* what should i do? */ +} + +#undef RARRAY_LEN +#define RARRAY_LEN(ary) PARRAY(ary)->len +#undef RARRAY_CONST_PTR +#define RARRAY_CONST_PTR(ary) PARRAY(ary)->data +#undef RARRAY_AREF +#define RARRAY_AREF(ary, i) PARRAY(ary)->data[i] + #endif %} @@ -7082,7 +7244,7 @@ parser_has_token(struct parser_params *p) static VALUE code_loc_to_ary(struct parser_params *p, const rb_code_location_t *loc) { - VALUE ary = rb_ary_new_from_args(4, + VALUE ary = rb_parser_ary_new_from_args(p, 4, INT2NUM(loc->beg_pos.lineno), INT2NUM(loc->beg_pos.column), INT2NUM(loc->end_pos.lineno), INT2NUM(loc->end_pos.column)); rb_obj_freeze(ary); @@ -7096,14 +7258,14 @@ parser_append_tokens(struct parser_params *p, VALUE str, enum yytokentype t, int VALUE ary; int token_id; - ary = rb_ary_new2(4); + ary = rb_parser_ary_new2(p, 4); token_id = p->token_id; - rb_ary_push(ary, INT2FIX(token_id)); - rb_ary_push(ary, ID2SYM(parser_token2id(p, t))); - rb_ary_push(ary, str); - rb_ary_push(ary, code_loc_to_ary(p, p->yylloc)); + rb_parser_ary_push(p, ary, INT2FIX(token_id)); + rb_parser_ary_push(p, ary, ID2SYM(parser_token2id(p, t))); + rb_parser_ary_push(p, ary, str); + rb_parser_ary_push(p, ary, code_loc_to_ary(p, p->yylloc)); rb_obj_freeze(ary); - rb_ary_push(p->tokens, ary); + rb_parser_ary_push(p, p->tokens, ary); p->token_id++; if (p->debug) { @@ -7614,7 +7776,7 @@ yycompile0(VALUE arg) VALUE str = rb_default_rs; n = p->ruby_sourceline; do { - rb_ary_push(p->debug_lines, str); + rb_parser_ary_push(p, p->debug_lines, str); } while (--n); } @@ -7927,7 +8089,7 @@ nextline(struct parser_params *p, int set_encoding) #ifndef RIPPER if (p->debug_lines) { if (set_encoding) rb_enc_associate(v, p->enc); - rb_ary_push(p->debug_lines, v); + rb_parser_ary_push(p, p->debug_lines, v); } #endif p->cr_seen = FALSE; @@ -13893,23 +14055,23 @@ const_decl_path(struct parser_params *p, NODE **dest) } else { n = RNODE_CDECL(n)->nd_else; - path = rb_ary_new(); + path = rb_parser_ary_new(p); for (; n && nd_type_p(n, NODE_COLON2); n = RNODE_COLON2(n)->nd_head) { - rb_ary_push(path, rb_id2str(RNODE_COLON2(n)->nd_mid)); + rb_parser_ary_push(p, path, rb_id2str(RNODE_COLON2(n)->nd_mid)); } if (n && nd_type_p(n, NODE_CONST)) { // Const::Name - rb_ary_push(path, rb_id2str(RNODE_CONST(n)->nd_vid)); + rb_parser_ary_push(p, path, rb_id2str(RNODE_CONST(n)->nd_vid)); } else if (n && nd_type_p(n, NODE_COLON3)) { // ::Const::Name - rb_ary_push(path, rb_str_new(0, 0)); + rb_parser_ary_push(p, path, rb_str_new(0, 0)); } else { // expression::Name - rb_ary_push(path, rb_str_new_cstr("...")); + rb_parser_ary_push(p, path, rb_str_new_cstr("...")); } - path = rb_ary_join(rb_ary_reverse(path), rb_str_new_cstr("::")); + path = rb_parser_ary_join(p, rb_parser_ary_reverse(p, path), rb_str_new_cstr("::")); path = rb_fstring(path); } *dest = n = NEW_LIT(path, loc); @@ -14021,14 +14183,14 @@ shareable_literal_constant(struct parser_params *p, enum shareability shareable, return value; case NODE_ZLIST: - lit = rb_ary_new(); + lit = rb_parser_ary_new(p); OBJ_FREEZE_RAW(lit); NODE *n = NEW_LIT(lit, loc); RB_OBJ_WRITTEN(p->ast, Qnil, RNODE_LIT(n)->nd_lit); return n; case NODE_LIST: - lit = rb_ary_new(); + lit = rb_parser_ary_new(p); for (NODE *n = value; n; n = RNODE_LIST(n)->nd_next) { NODE *elt = RNODE_LIST(n)->nd_head; if (elt) { @@ -14037,17 +14199,17 @@ shareable_literal_constant(struct parser_params *p, enum shareability shareable, RNODE_LIST(n)->nd_head = elt; } else if (RTEST(lit)) { - rb_ary_clear(lit); + rb_parser_ary_clear(p, lit); lit = Qfalse; } } if (RTEST(lit)) { VALUE e = shareable_literal_value(p, elt); if (!UNDEF_P(e)) { - rb_ary_push(lit, e); + rb_parser_ary_push(p, lit, e); } else { - rb_ary_clear(lit); + rb_parser_ary_clear(p, lit); lit = Qnil; /* make shareable at runtime */ } } @@ -14110,7 +14272,8 @@ shareable_literal_constant(struct parser_params *p, enum shareability shareable, value = make_shareable_node(p, value, false, loc); } else { - value = NEW_LIT(rb_ractor_make_shareable(lit), loc); + //value = NEW_LIT(rb_ractor_make_shareable(lit), loc); + value = NEW_LIT(lit, loc); RB_OBJ_WRITTEN(p->ast, Qnil, RNODE_LIT(value)->nd_lit); } @@ -16022,11 +16185,11 @@ rb_ruby_parser_set_script_lines(rb_parser_t *p, VALUE lines) lines = Qfalse; } else if (lines == Qtrue) { - lines = rb_ary_new(); + lines = rb_parser_ary_new(p); } else { Check_Type(lines, T_ARRAY); - rb_ary_modify(lines); + rb_parser_ary_modify(p, lines); } p->debug_lines = lines; } @@ -16042,7 +16205,7 @@ rb_ruby_parser_keep_tokens(rb_parser_t *p) { p->keep_tokens = 1; // TODO - p->tokens = rb_ary_new(); + p->tokens = rb_parser_ary_new(p); } #ifndef UNIVERSAL_PARSER