зеркало из https://github.com/github/ruby.git
[Universal parser] Decouple IMEMO from rb_ast_t
This patch removes the `VALUE flags` member from the `rb_ast_t` structure making `rb_ast_t` no longer an IMEMO object. ## Background We are trying to make the Ruby parser generated from parse.y a universal parser that can be used by other implementations such as mruby. To achieve this, it is necessary to exclude VALUE and IMEMO from parse.y, AST, and NODE. ## Summary (file by file) - `rubyparser.h` - Remove the `VALUE flags` member from `rb_ast_t` - `ruby_parser.c` and `internal/ruby_parser.h` - Use TypedData_Make_Struct VALUE which wraps `rb_ast_t` `in ast_alloc()` so that GC can manage it - You can retrieve `rb_ast_t` from the VALUE by `rb_ruby_ast_data_get()` - Change the return type of `rb_parser_compile_XXXX()` functions from `rb_ast_t *` to `VALUE` - rb_ruby_ast_new() which internally `calls ast_alloc()` is to create VALUE vast outside ruby_parser.c - `iseq.c` and `vm_core.h` - Amend the first parameter of `rb_iseq_new_XXXX()` functions from `rb_ast_body_t *` to `VALUE` - This keeps the VALUE of AST on the machine stack to prevent being removed by GC - `ast.c` - Almost all change is replacement `rb_ast_t *ast` with `VALUE vast` (sorry for the big diff) - Fix `node_memsize()` - Now it includes `rb_ast_local_table_link`, `tokens` and script_lines - `compile.c`, `load.c`, `node.c`, `parse.y`, `proc.c`, `ruby.c`, `template/prelude.c.tmpl`, `vm.c` and `vm_eval.c` - Follow-up due to the above changes - `imemo.{c|h}` - If an object with `imemo_ast` appears, considers it a bug Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org>
This commit is contained in:
Родитель
9b5bc8e6ea
Коммит
2244c58b00
294
ast.c
294
ast.c
|
@ -16,7 +16,7 @@ static VALUE rb_mAST;
|
|||
static VALUE rb_cNode;
|
||||
|
||||
struct ASTNodeData {
|
||||
rb_ast_t *ast;
|
||||
VALUE vast;
|
||||
const NODE *node;
|
||||
};
|
||||
|
||||
|
@ -24,14 +24,16 @@ static void
|
|||
node_gc_mark(void *ptr)
|
||||
{
|
||||
struct ASTNodeData *data = (struct ASTNodeData *)ptr;
|
||||
rb_gc_mark((VALUE)data->ast);
|
||||
rb_gc_mark(data->vast);
|
||||
}
|
||||
|
||||
static size_t
|
||||
node_memsize(const void *ptr)
|
||||
{
|
||||
struct ASTNodeData *data = (struct ASTNodeData *)ptr;
|
||||
return rb_ast_memsize(data->ast);
|
||||
rb_ast_t *ast = rb_ruby_ast_data_get(data->vast);
|
||||
|
||||
return sizeof(struct ASTNodeData) + rb_ast_memsize(ast);
|
||||
}
|
||||
|
||||
static const rb_data_type_t rb_node_type = {
|
||||
|
@ -44,22 +46,22 @@ static const rb_data_type_t rb_node_type = {
|
|||
static VALUE rb_ast_node_alloc(VALUE klass);
|
||||
|
||||
static void
|
||||
setup_node(VALUE obj, rb_ast_t *ast, const NODE *node)
|
||||
setup_node(VALUE obj, VALUE vast, const NODE *node)
|
||||
{
|
||||
struct ASTNodeData *data;
|
||||
|
||||
TypedData_Get_Struct(obj, struct ASTNodeData, &rb_node_type, data);
|
||||
data->ast = ast;
|
||||
data->vast = vast;
|
||||
data->node = node;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
ast_new_internal(rb_ast_t *ast, const NODE *node)
|
||||
ast_new_internal(VALUE vast, const NODE *node)
|
||||
{
|
||||
VALUE obj;
|
||||
|
||||
obj = rb_ast_node_alloc(rb_cNode);
|
||||
setup_node(obj, ast, node);
|
||||
setup_node(obj, vast, node);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
@ -74,14 +76,16 @@ ast_parse_new(void)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
ast_parse_done(rb_ast_t *ast)
|
||||
ast_parse_done(VALUE vast)
|
||||
{
|
||||
rb_ast_t *ast = rb_ruby_ast_data_get(vast);
|
||||
|
||||
if (!ast->body.root) {
|
||||
rb_ast_dispose(ast);
|
||||
rb_exc_raise(GET_EC()->errinfo);
|
||||
}
|
||||
|
||||
return ast_new_internal(ast, (NODE *)ast->body.root);
|
||||
return ast_new_internal(vast, (NODE *)ast->body.root);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
@ -93,15 +97,15 @@ ast_s_parse(rb_execution_context_t *ec, VALUE module, VALUE str, VALUE keep_scri
|
|||
static VALUE
|
||||
rb_ast_parse_str(VALUE str, VALUE keep_script_lines, VALUE error_tolerant, VALUE keep_tokens)
|
||||
{
|
||||
rb_ast_t *ast = 0;
|
||||
VALUE vast;
|
||||
|
||||
StringValue(str);
|
||||
VALUE vparser = ast_parse_new();
|
||||
if (RTEST(keep_script_lines)) rb_parser_set_script_lines(vparser);
|
||||
if (RTEST(error_tolerant)) rb_parser_error_tolerant(vparser);
|
||||
if (RTEST(keep_tokens)) rb_parser_keep_tokens(vparser);
|
||||
ast = rb_parser_compile_string_path(vparser, Qnil, str, 1);
|
||||
return ast_parse_done(ast);
|
||||
vast = rb_parser_compile_string_path(vparser, Qnil, str, 1);
|
||||
return ast_parse_done(vast);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
@ -114,7 +118,7 @@ static VALUE
|
|||
rb_ast_parse_file(VALUE path, VALUE keep_script_lines, VALUE error_tolerant, VALUE keep_tokens)
|
||||
{
|
||||
VALUE f;
|
||||
rb_ast_t *ast = 0;
|
||||
VALUE vast = Qnil;
|
||||
rb_encoding *enc = rb_utf8_encoding();
|
||||
|
||||
f = rb_file_open_str(path, "r");
|
||||
|
@ -123,26 +127,26 @@ rb_ast_parse_file(VALUE path, VALUE keep_script_lines, VALUE error_tolerant, VAL
|
|||
if (RTEST(keep_script_lines)) rb_parser_set_script_lines(vparser);
|
||||
if (RTEST(error_tolerant)) rb_parser_error_tolerant(vparser);
|
||||
if (RTEST(keep_tokens)) rb_parser_keep_tokens(vparser);
|
||||
ast = rb_parser_compile_file_path(vparser, Qnil, f, 1);
|
||||
vast = rb_parser_compile_file_path(vparser, Qnil, f, 1);
|
||||
rb_io_close(f);
|
||||
return ast_parse_done(ast);
|
||||
return ast_parse_done(vast);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_ast_parse_array(VALUE array, VALUE keep_script_lines, VALUE error_tolerant, VALUE keep_tokens)
|
||||
{
|
||||
rb_ast_t *ast = 0;
|
||||
VALUE vast = Qnil;
|
||||
|
||||
array = rb_check_array_type(array);
|
||||
VALUE vparser = ast_parse_new();
|
||||
if (RTEST(keep_script_lines)) rb_parser_set_script_lines(vparser);
|
||||
if (RTEST(error_tolerant)) rb_parser_error_tolerant(vparser);
|
||||
if (RTEST(keep_tokens)) rb_parser_keep_tokens(vparser);
|
||||
ast = rb_parser_compile_array(vparser, Qnil, array, 1);
|
||||
return ast_parse_done(ast);
|
||||
vast = rb_parser_compile_array(vparser, Qnil, array, 1);
|
||||
return ast_parse_done(vast);
|
||||
}
|
||||
|
||||
static VALUE node_children(rb_ast_t*, const NODE*);
|
||||
static VALUE node_children(VALUE, const NODE*);
|
||||
|
||||
static VALUE
|
||||
node_find(VALUE self, const int node_id)
|
||||
|
@ -154,7 +158,7 @@ node_find(VALUE self, const int node_id)
|
|||
|
||||
if (nd_node_id(data->node) == node_id) return self;
|
||||
|
||||
ary = node_children(data->ast, data->node);
|
||||
ary = node_children(data->vast, data->node);
|
||||
|
||||
for (i = 0; i < RARRAY_LEN(ary); i++) {
|
||||
VALUE child = RARRAY_AREF(ary, i);
|
||||
|
@ -277,10 +281,10 @@ ast_node_node_id(rb_execution_context_t *ec, VALUE self)
|
|||
return INT2FIX(nd_node_id(data->node));
|
||||
}
|
||||
|
||||
#define NEW_CHILD(ast, node) node ? ast_new_internal(ast, node) : Qnil
|
||||
#define NEW_CHILD(vast, node) (node ? ast_new_internal(vast, node) : Qnil)
|
||||
|
||||
static VALUE
|
||||
rb_ary_new_from_node_args(rb_ast_t *ast, long n, ...)
|
||||
rb_ary_new_from_node_args(VALUE vast, long n, ...)
|
||||
{
|
||||
va_list ar;
|
||||
VALUE ary;
|
||||
|
@ -292,39 +296,39 @@ rb_ary_new_from_node_args(rb_ast_t *ast, long n, ...)
|
|||
for (i=0; i<n; i++) {
|
||||
NODE *node;
|
||||
node = va_arg(ar, NODE *);
|
||||
rb_ary_push(ary, NEW_CHILD(ast, node));
|
||||
rb_ary_push(ary, NEW_CHILD(vast, node));
|
||||
}
|
||||
va_end(ar);
|
||||
return ary;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
dump_block(rb_ast_t *ast, const struct RNode_BLOCK *node)
|
||||
dump_block(VALUE vast, const struct RNode_BLOCK *node)
|
||||
{
|
||||
VALUE ary = rb_ary_new();
|
||||
do {
|
||||
rb_ary_push(ary, NEW_CHILD(ast, node->nd_head));
|
||||
rb_ary_push(ary, NEW_CHILD(vast, node->nd_head));
|
||||
} while (node->nd_next &&
|
||||
nd_type_p(node->nd_next, NODE_BLOCK) &&
|
||||
(node = RNODE_BLOCK(node->nd_next), 1));
|
||||
if (node->nd_next) {
|
||||
rb_ary_push(ary, NEW_CHILD(ast, node->nd_next));
|
||||
rb_ary_push(ary, NEW_CHILD(vast, node->nd_next));
|
||||
}
|
||||
|
||||
return ary;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
dump_array(rb_ast_t *ast, const struct RNode_LIST *node)
|
||||
dump_array(VALUE vast, const struct RNode_LIST *node)
|
||||
{
|
||||
VALUE ary = rb_ary_new();
|
||||
rb_ary_push(ary, NEW_CHILD(ast, node->nd_head));
|
||||
rb_ary_push(ary, NEW_CHILD(vast, node->nd_head));
|
||||
|
||||
while (node->nd_next && nd_type_p(node->nd_next, NODE_LIST)) {
|
||||
node = RNODE_LIST(node->nd_next);
|
||||
rb_ary_push(ary, NEW_CHILD(ast, node->nd_head));
|
||||
rb_ary_push(ary, NEW_CHILD(vast, node->nd_head));
|
||||
}
|
||||
rb_ary_push(ary, NEW_CHILD(ast, node->nd_next));
|
||||
rb_ary_push(ary, NEW_CHILD(vast, node->nd_next));
|
||||
|
||||
return ary;
|
||||
}
|
||||
|
@ -346,155 +350,155 @@ no_name_rest(void)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
rest_arg(rb_ast_t *ast, const NODE *rest_arg)
|
||||
rest_arg(VALUE vast, const NODE *rest_arg)
|
||||
{
|
||||
return NODE_NAMED_REST_P(rest_arg) ? NEW_CHILD(ast, rest_arg) : no_name_rest();
|
||||
return NODE_NAMED_REST_P(rest_arg) ? NEW_CHILD(vast, rest_arg) : no_name_rest();
|
||||
}
|
||||
|
||||
static VALUE
|
||||
node_children(rb_ast_t *ast, const NODE *node)
|
||||
node_children(VALUE vast, const NODE *node)
|
||||
{
|
||||
char name[sizeof("$") + DECIMAL_SIZE_OF(long)];
|
||||
|
||||
enum node_type type = nd_type(node);
|
||||
switch (type) {
|
||||
case NODE_BLOCK:
|
||||
return dump_block(ast, RNODE_BLOCK(node));
|
||||
return dump_block(vast, RNODE_BLOCK(node));
|
||||
case NODE_IF:
|
||||
return rb_ary_new_from_node_args(ast, 3, RNODE_IF(node)->nd_cond, RNODE_IF(node)->nd_body, RNODE_IF(node)->nd_else);
|
||||
return rb_ary_new_from_node_args(vast, 3, RNODE_IF(node)->nd_cond, RNODE_IF(node)->nd_body, RNODE_IF(node)->nd_else);
|
||||
case NODE_UNLESS:
|
||||
return rb_ary_new_from_node_args(ast, 3, RNODE_UNLESS(node)->nd_cond, RNODE_UNLESS(node)->nd_body, RNODE_UNLESS(node)->nd_else);
|
||||
return rb_ary_new_from_node_args(vast, 3, RNODE_UNLESS(node)->nd_cond, RNODE_UNLESS(node)->nd_body, RNODE_UNLESS(node)->nd_else);
|
||||
case NODE_CASE:
|
||||
return rb_ary_new_from_node_args(ast, 2, RNODE_CASE(node)->nd_head, RNODE_CASE(node)->nd_body);
|
||||
return rb_ary_new_from_node_args(vast, 2, RNODE_CASE(node)->nd_head, RNODE_CASE(node)->nd_body);
|
||||
case NODE_CASE2:
|
||||
return rb_ary_new_from_node_args(ast, 2, RNODE_CASE2(node)->nd_head, RNODE_CASE2(node)->nd_body);
|
||||
return rb_ary_new_from_node_args(vast, 2, RNODE_CASE2(node)->nd_head, RNODE_CASE2(node)->nd_body);
|
||||
case NODE_CASE3:
|
||||
return rb_ary_new_from_node_args(ast, 2, RNODE_CASE3(node)->nd_head, RNODE_CASE3(node)->nd_body);
|
||||
return rb_ary_new_from_node_args(vast, 2, RNODE_CASE3(node)->nd_head, RNODE_CASE3(node)->nd_body);
|
||||
case NODE_WHEN:
|
||||
return rb_ary_new_from_node_args(ast, 3, RNODE_WHEN(node)->nd_head, RNODE_WHEN(node)->nd_body, RNODE_WHEN(node)->nd_next);
|
||||
return rb_ary_new_from_node_args(vast, 3, RNODE_WHEN(node)->nd_head, RNODE_WHEN(node)->nd_body, RNODE_WHEN(node)->nd_next);
|
||||
case NODE_IN:
|
||||
return rb_ary_new_from_node_args(ast, 3, RNODE_IN(node)->nd_head, RNODE_IN(node)->nd_body, RNODE_IN(node)->nd_next);
|
||||
return rb_ary_new_from_node_args(vast, 3, RNODE_IN(node)->nd_head, RNODE_IN(node)->nd_body, RNODE_IN(node)->nd_next);
|
||||
case NODE_WHILE:
|
||||
case NODE_UNTIL:
|
||||
return rb_ary_push(rb_ary_new_from_node_args(ast, 2, RNODE_WHILE(node)->nd_cond, RNODE_WHILE(node)->nd_body),
|
||||
return rb_ary_push(rb_ary_new_from_node_args(vast, 2, RNODE_WHILE(node)->nd_cond, RNODE_WHILE(node)->nd_body),
|
||||
RBOOL(RNODE_WHILE(node)->nd_state));
|
||||
case NODE_ITER:
|
||||
case NODE_FOR:
|
||||
return rb_ary_new_from_node_args(ast, 2, RNODE_ITER(node)->nd_iter, RNODE_ITER(node)->nd_body);
|
||||
return rb_ary_new_from_node_args(vast, 2, RNODE_ITER(node)->nd_iter, RNODE_ITER(node)->nd_body);
|
||||
case NODE_FOR_MASGN:
|
||||
return rb_ary_new_from_node_args(ast, 1, RNODE_FOR_MASGN(node)->nd_var);
|
||||
return rb_ary_new_from_node_args(vast, 1, RNODE_FOR_MASGN(node)->nd_var);
|
||||
case NODE_BREAK:
|
||||
return rb_ary_new_from_node_args(ast, 1, RNODE_BREAK(node)->nd_stts);
|
||||
return rb_ary_new_from_node_args(vast, 1, RNODE_BREAK(node)->nd_stts);
|
||||
case NODE_NEXT:
|
||||
return rb_ary_new_from_node_args(ast, 1, RNODE_NEXT(node)->nd_stts);
|
||||
return rb_ary_new_from_node_args(vast, 1, RNODE_NEXT(node)->nd_stts);
|
||||
case NODE_RETURN:
|
||||
return rb_ary_new_from_node_args(ast, 1, RNODE_RETURN(node)->nd_stts);
|
||||
return rb_ary_new_from_node_args(vast, 1, RNODE_RETURN(node)->nd_stts);
|
||||
case NODE_REDO:
|
||||
return rb_ary_new_from_node_args(ast, 0);
|
||||
return rb_ary_new_from_node_args(vast, 0);
|
||||
case NODE_RETRY:
|
||||
return rb_ary_new_from_node_args(ast, 0);
|
||||
return rb_ary_new_from_node_args(vast, 0);
|
||||
case NODE_BEGIN:
|
||||
return rb_ary_new_from_node_args(ast, 1, RNODE_BEGIN(node)->nd_body);
|
||||
return rb_ary_new_from_node_args(vast, 1, RNODE_BEGIN(node)->nd_body);
|
||||
case NODE_RESCUE:
|
||||
return rb_ary_new_from_node_args(ast, 3, RNODE_RESCUE(node)->nd_head, RNODE_RESCUE(node)->nd_resq, RNODE_RESCUE(node)->nd_else);
|
||||
return rb_ary_new_from_node_args(vast, 3, RNODE_RESCUE(node)->nd_head, RNODE_RESCUE(node)->nd_resq, RNODE_RESCUE(node)->nd_else);
|
||||
case NODE_RESBODY:
|
||||
return rb_ary_new_from_node_args(ast, 3, RNODE_RESBODY(node)->nd_args, RNODE_RESBODY(node)->nd_body, RNODE_RESBODY(node)->nd_next);
|
||||
return rb_ary_new_from_node_args(vast, 3, RNODE_RESBODY(node)->nd_args, RNODE_RESBODY(node)->nd_body, RNODE_RESBODY(node)->nd_next);
|
||||
case NODE_ENSURE:
|
||||
return rb_ary_new_from_node_args(ast, 2, RNODE_ENSURE(node)->nd_head, RNODE_ENSURE(node)->nd_ensr);
|
||||
return rb_ary_new_from_node_args(vast, 2, RNODE_ENSURE(node)->nd_head, RNODE_ENSURE(node)->nd_ensr);
|
||||
case NODE_AND:
|
||||
case NODE_OR:
|
||||
{
|
||||
VALUE ary = rb_ary_new();
|
||||
|
||||
while (1) {
|
||||
rb_ary_push(ary, NEW_CHILD(ast, RNODE_AND(node)->nd_1st));
|
||||
rb_ary_push(ary, NEW_CHILD(vast, RNODE_AND(node)->nd_1st));
|
||||
if (!RNODE_AND(node)->nd_2nd || !nd_type_p(RNODE_AND(node)->nd_2nd, type))
|
||||
break;
|
||||
node = RNODE_AND(node)->nd_2nd;
|
||||
}
|
||||
rb_ary_push(ary, NEW_CHILD(ast, RNODE_AND(node)->nd_2nd));
|
||||
rb_ary_push(ary, NEW_CHILD(vast, RNODE_AND(node)->nd_2nd));
|
||||
return ary;
|
||||
}
|
||||
case NODE_MASGN:
|
||||
if (NODE_NAMED_REST_P(RNODE_MASGN(node)->nd_args)) {
|
||||
return rb_ary_new_from_node_args(ast, 3, RNODE_MASGN(node)->nd_value, RNODE_MASGN(node)->nd_head, RNODE_MASGN(node)->nd_args);
|
||||
return rb_ary_new_from_node_args(vast, 3, RNODE_MASGN(node)->nd_value, RNODE_MASGN(node)->nd_head, RNODE_MASGN(node)->nd_args);
|
||||
}
|
||||
else {
|
||||
return rb_ary_new_from_args(3, NEW_CHILD(ast, RNODE_MASGN(node)->nd_value),
|
||||
NEW_CHILD(ast, RNODE_MASGN(node)->nd_head),
|
||||
return rb_ary_new_from_args(3, NEW_CHILD(vast, RNODE_MASGN(node)->nd_value),
|
||||
NEW_CHILD(vast, RNODE_MASGN(node)->nd_head),
|
||||
no_name_rest());
|
||||
}
|
||||
case NODE_LASGN:
|
||||
if (NODE_REQUIRED_KEYWORD_P(RNODE_LASGN(node)->nd_value)) {
|
||||
return rb_ary_new_from_args(2, var_name(RNODE_LASGN(node)->nd_vid), ID2SYM(rb_intern("NODE_SPECIAL_REQUIRED_KEYWORD")));
|
||||
}
|
||||
return rb_ary_new_from_args(2, var_name(RNODE_LASGN(node)->nd_vid), NEW_CHILD(ast, RNODE_LASGN(node)->nd_value));
|
||||
return rb_ary_new_from_args(2, var_name(RNODE_LASGN(node)->nd_vid), NEW_CHILD(vast, RNODE_LASGN(node)->nd_value));
|
||||
case NODE_DASGN:
|
||||
if (NODE_REQUIRED_KEYWORD_P(RNODE_DASGN(node)->nd_value)) {
|
||||
return rb_ary_new_from_args(2, var_name(RNODE_DASGN(node)->nd_vid), ID2SYM(rb_intern("NODE_SPECIAL_REQUIRED_KEYWORD")));
|
||||
}
|
||||
return rb_ary_new_from_args(2, var_name(RNODE_DASGN(node)->nd_vid), NEW_CHILD(ast, RNODE_DASGN(node)->nd_value));
|
||||
return rb_ary_new_from_args(2, var_name(RNODE_DASGN(node)->nd_vid), NEW_CHILD(vast, RNODE_DASGN(node)->nd_value));
|
||||
case NODE_IASGN:
|
||||
return rb_ary_new_from_args(2, var_name(RNODE_IASGN(node)->nd_vid), NEW_CHILD(ast, RNODE_IASGN(node)->nd_value));
|
||||
return rb_ary_new_from_args(2, var_name(RNODE_IASGN(node)->nd_vid), NEW_CHILD(vast, RNODE_IASGN(node)->nd_value));
|
||||
case NODE_CVASGN:
|
||||
return rb_ary_new_from_args(2, var_name(RNODE_CVASGN(node)->nd_vid), NEW_CHILD(ast, RNODE_CVASGN(node)->nd_value));
|
||||
return rb_ary_new_from_args(2, var_name(RNODE_CVASGN(node)->nd_vid), NEW_CHILD(vast, RNODE_CVASGN(node)->nd_value));
|
||||
case NODE_GASGN:
|
||||
return rb_ary_new_from_args(2, var_name(RNODE_GASGN(node)->nd_vid), NEW_CHILD(ast, RNODE_GASGN(node)->nd_value));
|
||||
return rb_ary_new_from_args(2, var_name(RNODE_GASGN(node)->nd_vid), NEW_CHILD(vast, RNODE_GASGN(node)->nd_value));
|
||||
case NODE_CDECL:
|
||||
if (RNODE_CDECL(node)->nd_vid) {
|
||||
return rb_ary_new_from_args(2, ID2SYM(RNODE_CDECL(node)->nd_vid), NEW_CHILD(ast, RNODE_CDECL(node)->nd_value));
|
||||
return rb_ary_new_from_args(2, ID2SYM(RNODE_CDECL(node)->nd_vid), NEW_CHILD(vast, RNODE_CDECL(node)->nd_value));
|
||||
}
|
||||
return rb_ary_new_from_args(3, NEW_CHILD(ast, RNODE_CDECL(node)->nd_else), ID2SYM(RNODE_COLON2(RNODE_CDECL(node)->nd_else)->nd_mid), NEW_CHILD(ast, RNODE_CDECL(node)->nd_value));
|
||||
return rb_ary_new_from_args(3, NEW_CHILD(vast, RNODE_CDECL(node)->nd_else), ID2SYM(RNODE_COLON2(RNODE_CDECL(node)->nd_else)->nd_mid), NEW_CHILD(vast, RNODE_CDECL(node)->nd_value));
|
||||
case NODE_OP_ASGN1:
|
||||
return rb_ary_new_from_args(4, NEW_CHILD(ast, RNODE_OP_ASGN1(node)->nd_recv),
|
||||
return rb_ary_new_from_args(4, NEW_CHILD(vast, RNODE_OP_ASGN1(node)->nd_recv),
|
||||
ID2SYM(RNODE_OP_ASGN1(node)->nd_mid),
|
||||
NEW_CHILD(ast, RNODE_OP_ASGN1(node)->nd_index),
|
||||
NEW_CHILD(ast, RNODE_OP_ASGN1(node)->nd_rvalue));
|
||||
NEW_CHILD(vast, RNODE_OP_ASGN1(node)->nd_index),
|
||||
NEW_CHILD(vast, RNODE_OP_ASGN1(node)->nd_rvalue));
|
||||
case NODE_OP_ASGN2:
|
||||
return rb_ary_new_from_args(5, NEW_CHILD(ast, RNODE_OP_ASGN2(node)->nd_recv),
|
||||
return rb_ary_new_from_args(5, NEW_CHILD(vast, RNODE_OP_ASGN2(node)->nd_recv),
|
||||
RBOOL(RNODE_OP_ASGN2(node)->nd_aid),
|
||||
ID2SYM(RNODE_OP_ASGN2(node)->nd_vid),
|
||||
ID2SYM(RNODE_OP_ASGN2(node)->nd_mid),
|
||||
NEW_CHILD(ast, RNODE_OP_ASGN2(node)->nd_value));
|
||||
NEW_CHILD(vast, RNODE_OP_ASGN2(node)->nd_value));
|
||||
case NODE_OP_ASGN_AND:
|
||||
return rb_ary_new_from_args(3, NEW_CHILD(ast, RNODE_OP_ASGN_AND(node)->nd_head), ID2SYM(idANDOP),
|
||||
NEW_CHILD(ast, RNODE_OP_ASGN_AND(node)->nd_value));
|
||||
return rb_ary_new_from_args(3, NEW_CHILD(vast, RNODE_OP_ASGN_AND(node)->nd_head), ID2SYM(idANDOP),
|
||||
NEW_CHILD(vast, RNODE_OP_ASGN_AND(node)->nd_value));
|
||||
case NODE_OP_ASGN_OR:
|
||||
return rb_ary_new_from_args(3, NEW_CHILD(ast, RNODE_OP_ASGN_OR(node)->nd_head), ID2SYM(idOROP),
|
||||
NEW_CHILD(ast, RNODE_OP_ASGN_OR(node)->nd_value));
|
||||
return rb_ary_new_from_args(3, NEW_CHILD(vast, RNODE_OP_ASGN_OR(node)->nd_head), ID2SYM(idOROP),
|
||||
NEW_CHILD(vast, RNODE_OP_ASGN_OR(node)->nd_value));
|
||||
case NODE_OP_CDECL:
|
||||
return rb_ary_new_from_args(3, NEW_CHILD(ast, RNODE_OP_CDECL(node)->nd_head),
|
||||
return rb_ary_new_from_args(3, NEW_CHILD(vast, RNODE_OP_CDECL(node)->nd_head),
|
||||
ID2SYM(RNODE_OP_CDECL(node)->nd_aid),
|
||||
NEW_CHILD(ast, RNODE_OP_CDECL(node)->nd_value));
|
||||
NEW_CHILD(vast, RNODE_OP_CDECL(node)->nd_value));
|
||||
case NODE_CALL:
|
||||
return rb_ary_new_from_args(3, NEW_CHILD(ast, RNODE_CALL(node)->nd_recv),
|
||||
return rb_ary_new_from_args(3, NEW_CHILD(vast, RNODE_CALL(node)->nd_recv),
|
||||
ID2SYM(RNODE_CALL(node)->nd_mid),
|
||||
NEW_CHILD(ast, RNODE_CALL(node)->nd_args));
|
||||
NEW_CHILD(vast, RNODE_CALL(node)->nd_args));
|
||||
case NODE_OPCALL:
|
||||
return rb_ary_new_from_args(3, NEW_CHILD(ast, RNODE_OPCALL(node)->nd_recv),
|
||||
return rb_ary_new_from_args(3, NEW_CHILD(vast, RNODE_OPCALL(node)->nd_recv),
|
||||
ID2SYM(RNODE_OPCALL(node)->nd_mid),
|
||||
NEW_CHILD(ast, RNODE_OPCALL(node)->nd_args));
|
||||
NEW_CHILD(vast, RNODE_OPCALL(node)->nd_args));
|
||||
case NODE_QCALL:
|
||||
return rb_ary_new_from_args(3, NEW_CHILD(ast, RNODE_QCALL(node)->nd_recv),
|
||||
return rb_ary_new_from_args(3, NEW_CHILD(vast, RNODE_QCALL(node)->nd_recv),
|
||||
ID2SYM(RNODE_QCALL(node)->nd_mid),
|
||||
NEW_CHILD(ast, RNODE_QCALL(node)->nd_args));
|
||||
NEW_CHILD(vast, RNODE_QCALL(node)->nd_args));
|
||||
case NODE_FCALL:
|
||||
return rb_ary_new_from_args(2, ID2SYM(RNODE_FCALL(node)->nd_mid),
|
||||
NEW_CHILD(ast, RNODE_FCALL(node)->nd_args));
|
||||
NEW_CHILD(vast, RNODE_FCALL(node)->nd_args));
|
||||
case NODE_VCALL:
|
||||
return rb_ary_new_from_args(1, ID2SYM(RNODE_VCALL(node)->nd_mid));
|
||||
case NODE_SUPER:
|
||||
return rb_ary_new_from_node_args(ast, 1, RNODE_SUPER(node)->nd_args);
|
||||
return rb_ary_new_from_node_args(vast, 1, RNODE_SUPER(node)->nd_args);
|
||||
case NODE_ZSUPER:
|
||||
return rb_ary_new_from_node_args(ast, 0);
|
||||
return rb_ary_new_from_node_args(vast, 0);
|
||||
case NODE_LIST:
|
||||
return dump_array(ast, RNODE_LIST(node));
|
||||
return dump_array(vast, RNODE_LIST(node));
|
||||
case NODE_ZLIST:
|
||||
return rb_ary_new_from_node_args(ast, 0);
|
||||
return rb_ary_new_from_node_args(vast, 0);
|
||||
case NODE_HASH:
|
||||
return rb_ary_new_from_node_args(ast, 1, RNODE_HASH(node)->nd_head);
|
||||
return rb_ary_new_from_node_args(vast, 1, RNODE_HASH(node)->nd_head);
|
||||
case NODE_YIELD:
|
||||
return rb_ary_new_from_node_args(ast, 1, RNODE_YIELD(node)->nd_head);
|
||||
return rb_ary_new_from_node_args(vast, 1, RNODE_YIELD(node)->nd_head);
|
||||
case NODE_LVAR:
|
||||
return rb_ary_new_from_args(1, var_name(RNODE_LVAR(node)->nd_vid));
|
||||
case NODE_DVAR:
|
||||
|
@ -519,11 +523,11 @@ node_children(rb_ast_t *ast, const NODE *node)
|
|||
return rb_ary_new_from_args(1, rb_node_regx_string_val(node));
|
||||
case NODE_MATCH2:
|
||||
if (RNODE_MATCH2(node)->nd_args) {
|
||||
return rb_ary_new_from_node_args(ast, 3, RNODE_MATCH2(node)->nd_recv, RNODE_MATCH2(node)->nd_value, RNODE_MATCH2(node)->nd_args);
|
||||
return rb_ary_new_from_node_args(vast, 3, RNODE_MATCH2(node)->nd_recv, RNODE_MATCH2(node)->nd_value, RNODE_MATCH2(node)->nd_args);
|
||||
}
|
||||
return rb_ary_new_from_node_args(ast, 2, RNODE_MATCH2(node)->nd_recv, RNODE_MATCH2(node)->nd_value);
|
||||
return rb_ary_new_from_node_args(vast, 2, RNODE_MATCH2(node)->nd_recv, RNODE_MATCH2(node)->nd_value);
|
||||
case NODE_MATCH3:
|
||||
return rb_ary_new_from_node_args(ast, 2, RNODE_MATCH3(node)->nd_recv, RNODE_MATCH3(node)->nd_value);
|
||||
return rb_ary_new_from_node_args(vast, 2, RNODE_MATCH3(node)->nd_recv, RNODE_MATCH3(node)->nd_value);
|
||||
case NODE_STR:
|
||||
case NODE_XSTR:
|
||||
return rb_ary_new_from_args(1, rb_node_str_string_val(node));
|
||||
|
@ -538,7 +542,7 @@ node_children(rb_ast_t *ast, const NODE *node)
|
|||
case NODE_REGX:
|
||||
return rb_ary_new_from_args(1, rb_node_regx_string_val(node));
|
||||
case NODE_ONCE:
|
||||
return rb_ary_new_from_node_args(ast, 1, RNODE_ONCE(node)->nd_body);
|
||||
return rb_ary_new_from_node_args(vast, 1, RNODE_ONCE(node)->nd_body);
|
||||
case NODE_DSTR:
|
||||
case NODE_DXSTR:
|
||||
case NODE_DREGX:
|
||||
|
@ -547,91 +551,91 @@ node_children(rb_ast_t *ast, const NODE *node)
|
|||
struct RNode_LIST *n = RNODE_DSTR(node)->nd_next;
|
||||
VALUE head = Qnil, next = Qnil;
|
||||
if (n) {
|
||||
head = NEW_CHILD(ast, n->nd_head);
|
||||
next = NEW_CHILD(ast, n->nd_next);
|
||||
head = NEW_CHILD(vast, n->nd_head);
|
||||
next = NEW_CHILD(vast, n->nd_next);
|
||||
}
|
||||
return rb_ary_new_from_args(3, rb_node_dstr_string_val(node), head, next);
|
||||
}
|
||||
case NODE_SYM:
|
||||
return rb_ary_new_from_args(1, rb_node_sym_string_val(node));
|
||||
case NODE_EVSTR:
|
||||
return rb_ary_new_from_node_args(ast, 1, RNODE_EVSTR(node)->nd_body);
|
||||
return rb_ary_new_from_node_args(vast, 1, RNODE_EVSTR(node)->nd_body);
|
||||
case NODE_ARGSCAT:
|
||||
return rb_ary_new_from_node_args(ast, 2, RNODE_ARGSCAT(node)->nd_head, RNODE_ARGSCAT(node)->nd_body);
|
||||
return rb_ary_new_from_node_args(vast, 2, RNODE_ARGSCAT(node)->nd_head, RNODE_ARGSCAT(node)->nd_body);
|
||||
case NODE_ARGSPUSH:
|
||||
return rb_ary_new_from_node_args(ast, 2, RNODE_ARGSPUSH(node)->nd_head, RNODE_ARGSPUSH(node)->nd_body);
|
||||
return rb_ary_new_from_node_args(vast, 2, RNODE_ARGSPUSH(node)->nd_head, RNODE_ARGSPUSH(node)->nd_body);
|
||||
case NODE_SPLAT:
|
||||
return rb_ary_new_from_node_args(ast, 1, RNODE_SPLAT(node)->nd_head);
|
||||
return rb_ary_new_from_node_args(vast, 1, RNODE_SPLAT(node)->nd_head);
|
||||
case NODE_BLOCK_PASS:
|
||||
return rb_ary_new_from_node_args(ast, 2, RNODE_BLOCK_PASS(node)->nd_head, RNODE_BLOCK_PASS(node)->nd_body);
|
||||
return rb_ary_new_from_node_args(vast, 2, RNODE_BLOCK_PASS(node)->nd_head, RNODE_BLOCK_PASS(node)->nd_body);
|
||||
case NODE_DEFN:
|
||||
return rb_ary_new_from_args(2, ID2SYM(RNODE_DEFN(node)->nd_mid), NEW_CHILD(ast, RNODE_DEFN(node)->nd_defn));
|
||||
return rb_ary_new_from_args(2, ID2SYM(RNODE_DEFN(node)->nd_mid), NEW_CHILD(vast, RNODE_DEFN(node)->nd_defn));
|
||||
case NODE_DEFS:
|
||||
return rb_ary_new_from_args(3, NEW_CHILD(ast, RNODE_DEFS(node)->nd_recv), ID2SYM(RNODE_DEFS(node)->nd_mid), NEW_CHILD(ast, RNODE_DEFS(node)->nd_defn));
|
||||
return rb_ary_new_from_args(3, NEW_CHILD(vast, RNODE_DEFS(node)->nd_recv), ID2SYM(RNODE_DEFS(node)->nd_mid), NEW_CHILD(vast, RNODE_DEFS(node)->nd_defn));
|
||||
case NODE_ALIAS:
|
||||
return rb_ary_new_from_node_args(ast, 2, RNODE_ALIAS(node)->nd_1st, RNODE_ALIAS(node)->nd_2nd);
|
||||
return rb_ary_new_from_node_args(vast, 2, RNODE_ALIAS(node)->nd_1st, RNODE_ALIAS(node)->nd_2nd);
|
||||
case NODE_VALIAS:
|
||||
return rb_ary_new_from_args(2, ID2SYM(RNODE_VALIAS(node)->nd_alias), ID2SYM(RNODE_VALIAS(node)->nd_orig));
|
||||
case NODE_UNDEF:
|
||||
return rb_ary_new_from_node_args(ast, 1, RNODE_UNDEF(node)->nd_undef);
|
||||
return rb_ary_new_from_node_args(vast, 1, RNODE_UNDEF(node)->nd_undef);
|
||||
case NODE_CLASS:
|
||||
return rb_ary_new_from_node_args(ast, 3, RNODE_CLASS(node)->nd_cpath, RNODE_CLASS(node)->nd_super, RNODE_CLASS(node)->nd_body);
|
||||
return rb_ary_new_from_node_args(vast, 3, RNODE_CLASS(node)->nd_cpath, RNODE_CLASS(node)->nd_super, RNODE_CLASS(node)->nd_body);
|
||||
case NODE_MODULE:
|
||||
return rb_ary_new_from_node_args(ast, 2, RNODE_MODULE(node)->nd_cpath, RNODE_MODULE(node)->nd_body);
|
||||
return rb_ary_new_from_node_args(vast, 2, RNODE_MODULE(node)->nd_cpath, RNODE_MODULE(node)->nd_body);
|
||||
case NODE_SCLASS:
|
||||
return rb_ary_new_from_node_args(ast, 2, RNODE_SCLASS(node)->nd_recv, RNODE_SCLASS(node)->nd_body);
|
||||
return rb_ary_new_from_node_args(vast, 2, RNODE_SCLASS(node)->nd_recv, RNODE_SCLASS(node)->nd_body);
|
||||
case NODE_COLON2:
|
||||
return rb_ary_new_from_args(2, NEW_CHILD(ast, RNODE_COLON2(node)->nd_head), ID2SYM(RNODE_COLON2(node)->nd_mid));
|
||||
return rb_ary_new_from_args(2, NEW_CHILD(vast, RNODE_COLON2(node)->nd_head), ID2SYM(RNODE_COLON2(node)->nd_mid));
|
||||
case NODE_COLON3:
|
||||
return rb_ary_new_from_args(1, ID2SYM(RNODE_COLON3(node)->nd_mid));
|
||||
case NODE_DOT2:
|
||||
case NODE_DOT3:
|
||||
case NODE_FLIP2:
|
||||
case NODE_FLIP3:
|
||||
return rb_ary_new_from_node_args(ast, 2, RNODE_DOT2(node)->nd_beg, RNODE_DOT2(node)->nd_end);
|
||||
return rb_ary_new_from_node_args(vast, 2, RNODE_DOT2(node)->nd_beg, RNODE_DOT2(node)->nd_end);
|
||||
case NODE_SELF:
|
||||
return rb_ary_new_from_node_args(ast, 0);
|
||||
return rb_ary_new_from_node_args(vast, 0);
|
||||
case NODE_NIL:
|
||||
return rb_ary_new_from_node_args(ast, 0);
|
||||
return rb_ary_new_from_node_args(vast, 0);
|
||||
case NODE_TRUE:
|
||||
return rb_ary_new_from_node_args(ast, 0);
|
||||
return rb_ary_new_from_node_args(vast, 0);
|
||||
case NODE_FALSE:
|
||||
return rb_ary_new_from_node_args(ast, 0);
|
||||
return rb_ary_new_from_node_args(vast, 0);
|
||||
case NODE_ERRINFO:
|
||||
return rb_ary_new_from_node_args(ast, 0);
|
||||
return rb_ary_new_from_node_args(vast, 0);
|
||||
case NODE_DEFINED:
|
||||
return rb_ary_new_from_node_args(ast, 1, RNODE_DEFINED(node)->nd_head);
|
||||
return rb_ary_new_from_node_args(vast, 1, RNODE_DEFINED(node)->nd_head);
|
||||
case NODE_POSTEXE:
|
||||
return rb_ary_new_from_node_args(ast, 1, RNODE_POSTEXE(node)->nd_body);
|
||||
return rb_ary_new_from_node_args(vast, 1, RNODE_POSTEXE(node)->nd_body);
|
||||
case NODE_ATTRASGN:
|
||||
return rb_ary_new_from_args(3, NEW_CHILD(ast, RNODE_ATTRASGN(node)->nd_recv), ID2SYM(RNODE_ATTRASGN(node)->nd_mid), NEW_CHILD(ast, RNODE_ATTRASGN(node)->nd_args));
|
||||
return rb_ary_new_from_args(3, NEW_CHILD(vast, RNODE_ATTRASGN(node)->nd_recv), ID2SYM(RNODE_ATTRASGN(node)->nd_mid), NEW_CHILD(vast, RNODE_ATTRASGN(node)->nd_args));
|
||||
case NODE_LAMBDA:
|
||||
return rb_ary_new_from_node_args(ast, 1, RNODE_LAMBDA(node)->nd_body);
|
||||
return rb_ary_new_from_node_args(vast, 1, RNODE_LAMBDA(node)->nd_body);
|
||||
case NODE_OPT_ARG:
|
||||
return rb_ary_new_from_node_args(ast, 2, RNODE_OPT_ARG(node)->nd_body, RNODE_OPT_ARG(node)->nd_next);
|
||||
return rb_ary_new_from_node_args(vast, 2, RNODE_OPT_ARG(node)->nd_body, RNODE_OPT_ARG(node)->nd_next);
|
||||
case NODE_KW_ARG:
|
||||
return rb_ary_new_from_node_args(ast, 2, RNODE_KW_ARG(node)->nd_body, RNODE_KW_ARG(node)->nd_next);
|
||||
return rb_ary_new_from_node_args(vast, 2, RNODE_KW_ARG(node)->nd_body, RNODE_KW_ARG(node)->nd_next);
|
||||
case NODE_POSTARG:
|
||||
if (NODE_NAMED_REST_P(RNODE_POSTARG(node)->nd_1st)) {
|
||||
return rb_ary_new_from_node_args(ast, 2, RNODE_POSTARG(node)->nd_1st, RNODE_POSTARG(node)->nd_2nd);
|
||||
return rb_ary_new_from_node_args(vast, 2, RNODE_POSTARG(node)->nd_1st, RNODE_POSTARG(node)->nd_2nd);
|
||||
}
|
||||
return rb_ary_new_from_args(2, no_name_rest(),
|
||||
NEW_CHILD(ast, RNODE_POSTARG(node)->nd_2nd));
|
||||
NEW_CHILD(vast, RNODE_POSTARG(node)->nd_2nd));
|
||||
case NODE_ARGS:
|
||||
{
|
||||
struct rb_args_info *ainfo = &RNODE_ARGS(node)->nd_ainfo;
|
||||
return rb_ary_new_from_args(10,
|
||||
INT2NUM(ainfo->pre_args_num),
|
||||
NEW_CHILD(ast, ainfo->pre_init),
|
||||
NEW_CHILD(ast, (NODE *)ainfo->opt_args),
|
||||
NEW_CHILD(vast, ainfo->pre_init),
|
||||
NEW_CHILD(vast, (NODE *)ainfo->opt_args),
|
||||
var_name(ainfo->first_post_arg),
|
||||
INT2NUM(ainfo->post_args_num),
|
||||
NEW_CHILD(ast, ainfo->post_init),
|
||||
NEW_CHILD(vast, ainfo->post_init),
|
||||
(ainfo->rest_arg == NODE_SPECIAL_EXCESSIVE_COMMA
|
||||
? ID2SYM(rb_intern("NODE_SPECIAL_EXCESSIVE_COMMA"))
|
||||
: var_name(ainfo->rest_arg)),
|
||||
(ainfo->no_kwarg ? Qfalse : NEW_CHILD(ast, (NODE *)ainfo->kw_args)),
|
||||
(ainfo->no_kwarg ? Qfalse : NEW_CHILD(ast, ainfo->kw_rest_arg)),
|
||||
(ainfo->no_kwarg ? Qfalse : NEW_CHILD(vast, (NODE *)ainfo->kw_args)),
|
||||
(ainfo->no_kwarg ? Qfalse : NEW_CHILD(vast, ainfo->kw_rest_arg)),
|
||||
var_name(ainfo->block_arg));
|
||||
}
|
||||
case NODE_SCOPE:
|
||||
|
@ -642,35 +646,35 @@ node_children(rb_ast_t *ast, const NODE *node)
|
|||
for (i = 0; i < size; i++) {
|
||||
rb_ary_push(locals, var_name(tbl->ids[i]));
|
||||
}
|
||||
return rb_ary_new_from_args(3, locals, NEW_CHILD(ast, (NODE *)RNODE_SCOPE(node)->nd_args), NEW_CHILD(ast, RNODE_SCOPE(node)->nd_body));
|
||||
return rb_ary_new_from_args(3, locals, NEW_CHILD(vast, (NODE *)RNODE_SCOPE(node)->nd_args), NEW_CHILD(vast, RNODE_SCOPE(node)->nd_body));
|
||||
}
|
||||
case NODE_ARYPTN:
|
||||
{
|
||||
VALUE rest = rest_arg(ast, RNODE_ARYPTN(node)->rest_arg);
|
||||
VALUE rest = rest_arg(vast, RNODE_ARYPTN(node)->rest_arg);
|
||||
return rb_ary_new_from_args(4,
|
||||
NEW_CHILD(ast, RNODE_ARYPTN(node)->nd_pconst),
|
||||
NEW_CHILD(ast, RNODE_ARYPTN(node)->pre_args),
|
||||
NEW_CHILD(vast, RNODE_ARYPTN(node)->nd_pconst),
|
||||
NEW_CHILD(vast, RNODE_ARYPTN(node)->pre_args),
|
||||
rest,
|
||||
NEW_CHILD(ast, RNODE_ARYPTN(node)->post_args));
|
||||
NEW_CHILD(vast, RNODE_ARYPTN(node)->post_args));
|
||||
}
|
||||
case NODE_FNDPTN:
|
||||
{
|
||||
VALUE pre_rest = rest_arg(ast, RNODE_FNDPTN(node)->pre_rest_arg);
|
||||
VALUE post_rest = rest_arg(ast, RNODE_FNDPTN(node)->post_rest_arg);
|
||||
VALUE pre_rest = rest_arg(vast, RNODE_FNDPTN(node)->pre_rest_arg);
|
||||
VALUE post_rest = rest_arg(vast, RNODE_FNDPTN(node)->post_rest_arg);
|
||||
return rb_ary_new_from_args(4,
|
||||
NEW_CHILD(ast, RNODE_FNDPTN(node)->nd_pconst),
|
||||
NEW_CHILD(vast, RNODE_FNDPTN(node)->nd_pconst),
|
||||
pre_rest,
|
||||
NEW_CHILD(ast, RNODE_FNDPTN(node)->args),
|
||||
NEW_CHILD(vast, RNODE_FNDPTN(node)->args),
|
||||
post_rest);
|
||||
}
|
||||
case NODE_HSHPTN:
|
||||
{
|
||||
VALUE kwrest = RNODE_HSHPTN(node)->nd_pkwrestarg == NODE_SPECIAL_NO_REST_KEYWORD ? ID2SYM(rb_intern("NODE_SPECIAL_NO_REST_KEYWORD")) :
|
||||
NEW_CHILD(ast, RNODE_HSHPTN(node)->nd_pkwrestarg);
|
||||
NEW_CHILD(vast, RNODE_HSHPTN(node)->nd_pkwrestarg);
|
||||
|
||||
return rb_ary_new_from_args(3,
|
||||
NEW_CHILD(ast, RNODE_HSHPTN(node)->nd_pconst),
|
||||
NEW_CHILD(ast, RNODE_HSHPTN(node)->nd_pkwargs),
|
||||
NEW_CHILD(vast, RNODE_HSHPTN(node)->nd_pconst),
|
||||
NEW_CHILD(vast, RNODE_HSHPTN(node)->nd_pkwargs),
|
||||
kwrest);
|
||||
}
|
||||
case NODE_LINE:
|
||||
|
@ -680,7 +684,7 @@ node_children(rb_ast_t *ast, const NODE *node)
|
|||
case NODE_ENCODING:
|
||||
return rb_ary_new_from_args(1, rb_node_encoding_val(node));
|
||||
case NODE_ERROR:
|
||||
return rb_ary_new_from_node_args(ast, 0);
|
||||
return rb_ary_new_from_node_args(vast, 0);
|
||||
case NODE_ARGS_AUX:
|
||||
case NODE_LAST:
|
||||
break;
|
||||
|
@ -695,7 +699,7 @@ ast_node_children(rb_execution_context_t *ec, VALUE self)
|
|||
struct ASTNodeData *data;
|
||||
TypedData_Get_Struct(self, struct ASTNodeData, &rb_node_type, data);
|
||||
|
||||
return node_children(data->ast, data->node);
|
||||
return node_children(data->vast, data->node);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
@ -739,13 +743,15 @@ ast_node_all_tokens(rb_execution_context_t *ec, VALUE self)
|
|||
{
|
||||
long i;
|
||||
struct ASTNodeData *data;
|
||||
rb_ast_t *ast;
|
||||
rb_parser_ary_t *parser_tokens;
|
||||
rb_parser_ast_token_t *parser_token;
|
||||
VALUE str, loc, token, all_tokens;
|
||||
|
||||
TypedData_Get_Struct(self, struct ASTNodeData, &rb_node_type, data);
|
||||
ast = rb_ruby_ast_data_get(data->vast);
|
||||
|
||||
parser_tokens = data->ast->node_buffer->tokens;
|
||||
parser_tokens = ast->node_buffer->tokens;
|
||||
if (parser_tokens == NULL) {
|
||||
return Qnil;
|
||||
}
|
||||
|
@ -792,8 +798,10 @@ static VALUE
|
|||
ast_node_script_lines(rb_execution_context_t *ec, VALUE self)
|
||||
{
|
||||
struct ASTNodeData *data;
|
||||
rb_ast_t *ast;
|
||||
TypedData_Get_Struct(self, struct ASTNodeData, &rb_node_type, data);
|
||||
rb_parser_ary_t *ret = data->ast->body.script_lines;
|
||||
ast = rb_ruby_ast_data_get(data->vast);
|
||||
rb_parser_ary_t *ret = ast->body.script_lines;
|
||||
if (!ret || FIXNUM_P((VALUE)ret)) return Qnil;
|
||||
return rb_parser_build_script_lines_from(ret);
|
||||
}
|
||||
|
|
18
compile.c
18
compile.c
|
@ -1478,16 +1478,11 @@ new_child_iseq(rb_iseq_t *iseq, const NODE *const node,
|
|||
VALUE name, const rb_iseq_t *parent, enum rb_iseq_type type, int line_no)
|
||||
{
|
||||
rb_iseq_t *ret_iseq;
|
||||
rb_ast_body_t ast;
|
||||
|
||||
ast.root = node;
|
||||
ast.frozen_string_literal = -1;
|
||||
ast.coverage_enabled = -1;
|
||||
ast.script_lines = NULL;
|
||||
VALUE vast = rb_ruby_ast_new(node, NULL);
|
||||
|
||||
debugs("[new_child_iseq]> ---------------------------------------\n");
|
||||
int isolated_depth = ISEQ_COMPILE_DATA(iseq)->isolated_depth;
|
||||
ret_iseq = rb_iseq_new_with_opt(&ast, name,
|
||||
ret_iseq = rb_iseq_new_with_opt(vast, name,
|
||||
rb_iseq_path(iseq), rb_iseq_realpath(iseq),
|
||||
line_no, parent,
|
||||
isolated_depth ? isolated_depth + 1 : 0,
|
||||
|
@ -8753,15 +8748,10 @@ compile_builtin_mandatory_only_method(rb_iseq_t *iseq, const NODE *node, const N
|
|||
scope_node.nd_body = mandatory_node(iseq, node);
|
||||
scope_node.nd_args = &args_node;
|
||||
|
||||
rb_ast_body_t ast = {
|
||||
.root = RNODE(&scope_node),
|
||||
.frozen_string_literal = -1,
|
||||
.coverage_enabled = -1,
|
||||
.script_lines = NULL
|
||||
};
|
||||
VALUE vast = rb_ruby_ast_new(RNODE(&scope_node), NULL);
|
||||
|
||||
ISEQ_BODY(iseq)->mandatory_only_iseq =
|
||||
rb_iseq_new_with_opt(&ast, rb_iseq_base_label(iseq),
|
||||
rb_iseq_new_with_opt(vast, rb_iseq_base_label(iseq),
|
||||
rb_iseq_path(iseq), rb_iseq_realpath(iseq),
|
||||
nd_line(line_node), NULL, 0,
|
||||
ISEQ_TYPE_METHOD, ISEQ_COMPILE_DATA(iseq)->option,
|
||||
|
|
7
imemo.c
7
imemo.c
|
@ -130,7 +130,7 @@ rb_imemo_memsize(VALUE obj)
|
|||
size_t size = 0;
|
||||
switch (imemo_type(obj)) {
|
||||
case imemo_ast:
|
||||
size += rb_ast_memsize((rb_ast_t *)obj);
|
||||
rb_bug("imemo_ast is obsolete");
|
||||
|
||||
break;
|
||||
case imemo_callcache:
|
||||
|
@ -273,7 +273,7 @@ rb_imemo_mark_and_move(VALUE obj, bool reference_updating)
|
|||
{
|
||||
switch (imemo_type(obj)) {
|
||||
case imemo_ast:
|
||||
// TODO: Make AST decoupled from IMEMO
|
||||
rb_bug("imemo_ast is obsolete");
|
||||
|
||||
break;
|
||||
case imemo_callcache: {
|
||||
|
@ -513,8 +513,7 @@ rb_imemo_free(VALUE obj)
|
|||
{
|
||||
switch (imemo_type(obj)) {
|
||||
case imemo_ast:
|
||||
rb_ast_free((rb_ast_t *)obj);
|
||||
RB_DEBUG_COUNTER_INC(obj_imemo_ast);
|
||||
rb_bug("imemo_ast is obsolete");
|
||||
|
||||
break;
|
||||
case imemo_callcache:
|
||||
|
|
|
@ -39,7 +39,7 @@ enum imemo_type {
|
|||
imemo_ment = 6,
|
||||
imemo_iseq = 7,
|
||||
imemo_tmpbuf = 8,
|
||||
imemo_ast = 9,
|
||||
imemo_ast = 9, // Obsolete due to the universal parser
|
||||
imemo_parser_strterm = 10,
|
||||
imemo_callinfo = 11,
|
||||
imemo_callcache = 12,
|
||||
|
|
|
@ -22,7 +22,7 @@ rb_parser_t *rb_parser_params_new(void);
|
|||
#endif
|
||||
VALUE rb_parser_set_context(VALUE, const struct rb_iseq_struct *, int);
|
||||
VALUE rb_parser_new(void);
|
||||
rb_ast_t *rb_parser_compile_string_path(VALUE vparser, VALUE fname, VALUE src, int line);
|
||||
VALUE rb_parser_compile_string_path(VALUE vparser, VALUE fname, VALUE src, int line);
|
||||
VALUE rb_str_new_parser_string(rb_parser_string_t *str);
|
||||
VALUE rb_str_new_mutable_parser_string(rb_parser_string_t *str);
|
||||
VALUE rb_parser_lex_get_str(struct lex_pointer_string *ptr_str);
|
||||
|
@ -48,15 +48,15 @@ VALUE rb_parser_set_yydebug(VALUE, VALUE);
|
|||
VALUE rb_parser_build_script_lines_from(rb_parser_ary_t *script_lines);
|
||||
void rb_parser_aset_script_lines_for(VALUE path, rb_parser_ary_t *script_lines);
|
||||
void rb_parser_set_options(VALUE, int, int, int, int);
|
||||
void *rb_parser_load_file(VALUE parser, VALUE name);
|
||||
VALUE rb_parser_load_file(VALUE parser, VALUE name);
|
||||
void rb_parser_set_script_lines(VALUE vparser);
|
||||
void rb_parser_error_tolerant(VALUE vparser);
|
||||
void rb_parser_keep_tokens(VALUE vparser);
|
||||
|
||||
rb_ast_t *rb_parser_compile_string(VALUE, const char*, VALUE, int);
|
||||
rb_ast_t *rb_parser_compile_file_path(VALUE vparser, VALUE fname, VALUE input, int line);
|
||||
rb_ast_t *rb_parser_compile_generic(VALUE vparser, rb_parser_lex_gets_func *lex_gets, VALUE fname, VALUE input, int line);
|
||||
rb_ast_t *rb_parser_compile_array(VALUE vparser, VALUE fname, VALUE array, int start);
|
||||
VALUE rb_parser_compile_string(VALUE, const char*, VALUE, int);
|
||||
VALUE rb_parser_compile_file_path(VALUE vparser, VALUE fname, VALUE input, int line);
|
||||
VALUE rb_parser_compile_generic(VALUE vparser, rb_parser_lex_gets_func *lex_gets, VALUE fname, VALUE input, int line);
|
||||
VALUE rb_parser_compile_array(VALUE vparser, VALUE fname, VALUE array, int start);
|
||||
|
||||
enum lex_state_bits {
|
||||
EXPR_BEG_bit, /* ignore newline, +/- is a sign. */
|
||||
|
@ -97,4 +97,7 @@ enum lex_state_e {
|
|||
EXPR_NONE = 0
|
||||
};
|
||||
|
||||
VALUE rb_ruby_ast_new(const NODE *const root, rb_parser_ary_t *script_lines);
|
||||
rb_ast_t *rb_ruby_ast_data_get(VALUE vast);
|
||||
|
||||
#endif /* INTERNAL_RUBY_PARSE_H */
|
||||
|
|
76
iseq.c
76
iseq.c
|
@ -839,31 +839,32 @@ make_compile_option_value(rb_compile_option_t *option)
|
|||
}
|
||||
|
||||
rb_iseq_t *
|
||||
rb_iseq_new(const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE realpath,
|
||||
rb_iseq_new(const VALUE vast, VALUE name, VALUE path, VALUE realpath,
|
||||
const rb_iseq_t *parent, enum rb_iseq_type type)
|
||||
{
|
||||
return rb_iseq_new_with_opt(ast, name, path, realpath, 0, parent,
|
||||
return rb_iseq_new_with_opt(vast, name, path, realpath, 0, parent,
|
||||
0, type, &COMPILE_OPTION_DEFAULT,
|
||||
Qnil);
|
||||
}
|
||||
|
||||
static int
|
||||
ast_line_count(const rb_ast_body_t *ast)
|
||||
ast_line_count(const VALUE vast)
|
||||
{
|
||||
if (ast->script_lines == NULL) {
|
||||
rb_ast_t *ast = rb_ruby_ast_data_get(vast);
|
||||
if (!ast || !ast->body.script_lines) {
|
||||
// this occurs when failed to parse the source code with a syntax error
|
||||
return 0;
|
||||
}
|
||||
if (!FIXNUM_P((VALUE)ast->script_lines)) {
|
||||
return (int)ast->script_lines->len;
|
||||
if (!FIXNUM_P((VALUE)ast->body.script_lines)) {
|
||||
return (int)ast->body.script_lines->len;
|
||||
}
|
||||
return FIX2INT((VALUE)ast->script_lines);
|
||||
return FIX2INT((VALUE)ast->body.script_lines);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
iseq_setup_coverage(VALUE coverages, VALUE path, const rb_ast_body_t *ast, int line_offset)
|
||||
iseq_setup_coverage(VALUE coverages, VALUE path, const VALUE vast, int line_offset)
|
||||
{
|
||||
int line_count = line_offset + ast_line_count(ast);
|
||||
int line_count = line_offset + ast_line_count(vast);
|
||||
|
||||
if (line_count >= 0) {
|
||||
int len = (rb_get_coverage_mode() & COVERAGE_TARGET_ONESHOT_LINES) ? 0 : line_count;
|
||||
|
@ -878,21 +879,21 @@ iseq_setup_coverage(VALUE coverages, VALUE path, const rb_ast_body_t *ast, int l
|
|||
}
|
||||
|
||||
static inline void
|
||||
iseq_new_setup_coverage(VALUE path, const rb_ast_body_t *ast, int line_offset)
|
||||
iseq_new_setup_coverage(VALUE path, const VALUE vast, int line_offset)
|
||||
{
|
||||
VALUE coverages = rb_get_coverages();
|
||||
|
||||
if (RTEST(coverages)) {
|
||||
iseq_setup_coverage(coverages, path, ast, line_offset);
|
||||
iseq_setup_coverage(coverages, path, vast, line_offset);
|
||||
}
|
||||
}
|
||||
|
||||
rb_iseq_t *
|
||||
rb_iseq_new_top(const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE realpath, const rb_iseq_t *parent)
|
||||
rb_iseq_new_top(const VALUE vast, VALUE name, VALUE path, VALUE realpath, const rb_iseq_t *parent)
|
||||
{
|
||||
iseq_new_setup_coverage(path, ast, 0);
|
||||
iseq_new_setup_coverage(path, vast, 0);
|
||||
|
||||
return rb_iseq_new_with_opt(ast, name, path, realpath, 0, parent, 0,
|
||||
return rb_iseq_new_with_opt(vast, name, path, realpath, 0, parent, 0,
|
||||
ISEQ_TYPE_TOP, &COMPILE_OPTION_DEFAULT,
|
||||
Qnil);
|
||||
}
|
||||
|
@ -910,11 +911,11 @@ pm_iseq_new_top(pm_scope_node_t *node, VALUE name, VALUE path, VALUE realpath, c
|
|||
}
|
||||
|
||||
rb_iseq_t *
|
||||
rb_iseq_new_main(const rb_ast_body_t *ast, VALUE path, VALUE realpath, const rb_iseq_t *parent, int opt)
|
||||
rb_iseq_new_main(const VALUE vast, VALUE path, VALUE realpath, const rb_iseq_t *parent, int opt)
|
||||
{
|
||||
iseq_new_setup_coverage(path, ast, 0);
|
||||
iseq_new_setup_coverage(path, vast, 0);
|
||||
|
||||
return rb_iseq_new_with_opt(ast, rb_fstring_lit("<main>"),
|
||||
return rb_iseq_new_with_opt(vast, rb_fstring_lit("<main>"),
|
||||
path, realpath, 0,
|
||||
parent, 0, ISEQ_TYPE_MAIN, opt ? &COMPILE_OPTION_DEFAULT : &COMPILE_OPTION_FALSE,
|
||||
Qnil);
|
||||
|
@ -935,16 +936,16 @@ pm_iseq_new_main(pm_scope_node_t *node, VALUE path, VALUE realpath, const rb_ise
|
|||
}
|
||||
|
||||
rb_iseq_t *
|
||||
rb_iseq_new_eval(const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE realpath, int first_lineno, const rb_iseq_t *parent, int isolated_depth)
|
||||
rb_iseq_new_eval(const VALUE vast, VALUE name, VALUE path, VALUE realpath, int first_lineno, const rb_iseq_t *parent, int isolated_depth)
|
||||
{
|
||||
if (rb_get_coverage_mode() & COVERAGE_TARGET_EVAL) {
|
||||
VALUE coverages = rb_get_coverages();
|
||||
if (RTEST(coverages) && RTEST(path) && !RTEST(rb_hash_has_key(coverages, path))) {
|
||||
iseq_setup_coverage(coverages, path, ast, first_lineno - 1);
|
||||
iseq_setup_coverage(coverages, path, vast, first_lineno - 1);
|
||||
}
|
||||
}
|
||||
|
||||
return rb_iseq_new_with_opt(ast, name, path, realpath, first_lineno,
|
||||
return rb_iseq_new_with_opt(vast, name, path, realpath, first_lineno,
|
||||
parent, isolated_depth, ISEQ_TYPE_EVAL, &COMPILE_OPTION_DEFAULT,
|
||||
Qnil);
|
||||
}
|
||||
|
@ -972,27 +973,29 @@ iseq_translate(rb_iseq_t *iseq)
|
|||
}
|
||||
|
||||
rb_iseq_t *
|
||||
rb_iseq_new_with_opt(const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE realpath,
|
||||
rb_iseq_new_with_opt(const VALUE vast, VALUE name, VALUE path, VALUE realpath,
|
||||
int first_lineno, const rb_iseq_t *parent, int isolated_depth,
|
||||
enum rb_iseq_type type, const rb_compile_option_t *option,
|
||||
VALUE script_lines)
|
||||
{
|
||||
const NODE *node = ast ? ast->root : 0;
|
||||
rb_ast_t *ast = rb_ruby_ast_data_get(vast);
|
||||
rb_ast_body_t *body = ast ? &ast->body : NULL;
|
||||
const NODE *node = body ? body->root : 0;
|
||||
/* TODO: argument check */
|
||||
rb_iseq_t *iseq = iseq_alloc();
|
||||
rb_compile_option_t new_opt;
|
||||
|
||||
if (!option) option = &COMPILE_OPTION_DEFAULT;
|
||||
if (ast) {
|
||||
if (body) {
|
||||
new_opt = *option;
|
||||
option = set_compile_option_from_ast(&new_opt, ast);
|
||||
option = set_compile_option_from_ast(&new_opt, body);
|
||||
}
|
||||
|
||||
if (!NIL_P(script_lines)) {
|
||||
// noop
|
||||
}
|
||||
else if (ast && !FIXNUM_P((VALUE)ast->script_lines) && ast->script_lines) {
|
||||
script_lines = rb_parser_build_script_lines_from(ast->script_lines);
|
||||
else if (body && !FIXNUM_P((VALUE)body->script_lines) && body->script_lines) {
|
||||
script_lines = rb_parser_build_script_lines_from(body->script_lines);
|
||||
}
|
||||
else if (parent) {
|
||||
script_lines = ISEQ_BODY(parent)->variable.script_lines;
|
||||
|
@ -1214,9 +1217,10 @@ rb_iseq_compile_with_option(VALUE src, VALUE file, VALUE realpath, VALUE line, V
|
|||
#else
|
||||
# define INITIALIZED /* volatile */
|
||||
#endif
|
||||
rb_ast_t *(*parse)(VALUE vparser, VALUE fname, VALUE file, int start);
|
||||
VALUE (*parse)(VALUE vparser, VALUE fname, VALUE file, int start);
|
||||
int ln;
|
||||
rb_ast_t *INITIALIZED ast;
|
||||
VALUE INITIALIZED vast;
|
||||
rb_ast_t *ast;
|
||||
VALUE name = rb_fstring_lit("<compiled>");
|
||||
|
||||
/* safe results first */
|
||||
|
@ -1232,20 +1236,22 @@ rb_iseq_compile_with_option(VALUE src, VALUE file, VALUE realpath, VALUE line, V
|
|||
}
|
||||
{
|
||||
const VALUE parser = rb_parser_new();
|
||||
const rb_iseq_t *outer_scope = rb_iseq_new(NULL, name, name, Qnil, 0, ISEQ_TYPE_TOP);
|
||||
const rb_iseq_t *outer_scope = rb_iseq_new(Qnil, name, name, Qnil, 0, ISEQ_TYPE_TOP);
|
||||
VALUE outer_scope_v = (VALUE)outer_scope;
|
||||
rb_parser_set_context(parser, outer_scope, FALSE);
|
||||
if (ruby_vm_keep_script_lines) rb_parser_set_script_lines(parser);
|
||||
RB_GC_GUARD(outer_scope_v);
|
||||
ast = (*parse)(parser, file, src, ln);
|
||||
vast = (*parse)(parser, file, src, ln);
|
||||
}
|
||||
|
||||
if (!ast->body.root) {
|
||||
ast = rb_ruby_ast_data_get(vast);
|
||||
|
||||
if (!ast || !ast->body.root) {
|
||||
rb_ast_dispose(ast);
|
||||
rb_exc_raise(GET_EC()->errinfo);
|
||||
}
|
||||
else {
|
||||
iseq = rb_iseq_new_with_opt(&ast->body, name, file, realpath, ln,
|
||||
iseq = rb_iseq_new_with_opt(vast, name, file, realpath, ln,
|
||||
NULL, 0, ISEQ_TYPE_TOP, &option,
|
||||
Qnil);
|
||||
rb_ast_dispose(ast);
|
||||
|
@ -1606,6 +1612,7 @@ iseqw_s_compile_file(int argc, VALUE *argv, VALUE self)
|
|||
VALUE file, opt = Qnil;
|
||||
VALUE parser, f, exc = Qnil, ret;
|
||||
rb_ast_t *ast;
|
||||
VALUE vast;
|
||||
rb_compile_option_t option;
|
||||
int i;
|
||||
|
||||
|
@ -1624,7 +1631,8 @@ iseqw_s_compile_file(int argc, VALUE *argv, VALUE self)
|
|||
|
||||
parser = rb_parser_new();
|
||||
rb_parser_set_context(parser, NULL, FALSE);
|
||||
ast = (rb_ast_t *)rb_parser_load_file(parser, file);
|
||||
vast = rb_parser_load_file(parser, file);
|
||||
ast = rb_ruby_ast_data_get(vast);
|
||||
if (!ast->body.root) exc = GET_EC()->errinfo;
|
||||
|
||||
rb_io_close(f);
|
||||
|
@ -1635,7 +1643,7 @@ iseqw_s_compile_file(int argc, VALUE *argv, VALUE self)
|
|||
|
||||
make_compile_option(&option, opt);
|
||||
|
||||
ret = iseqw_new(rb_iseq_new_with_opt(&ast->body, rb_fstring_lit("<main>"),
|
||||
ret = iseqw_new(rb_iseq_new_with_opt(vast, rb_fstring_lit("<main>"),
|
||||
file,
|
||||
rb_realpath_internal(Qnil, file, 1),
|
||||
1, NULL, 0, ISEQ_TYPE_TOP, &option,
|
||||
|
|
6
load.c
6
load.c
|
@ -762,11 +762,13 @@ load_iseq_eval(rb_execution_context_t *ec, VALUE fname)
|
|||
}
|
||||
else {
|
||||
rb_ast_t *ast;
|
||||
VALUE vast;
|
||||
VALUE parser = rb_parser_new();
|
||||
rb_parser_set_context(parser, NULL, FALSE);
|
||||
ast = (rb_ast_t *)rb_parser_load_file(parser, fname);
|
||||
vast = rb_parser_load_file(parser, fname);
|
||||
ast = rb_ruby_ast_data_get(vast);
|
||||
|
||||
iseq = rb_iseq_new_top(&ast->body, rb_fstring_lit("<top (required)>"),
|
||||
iseq = rb_iseq_new_top(vast, rb_fstring_lit("<top (required)>"),
|
||||
fname, realpath_internal_cached(realpath_map, fname), NULL);
|
||||
rb_ast_dispose(ast);
|
||||
}
|
||||
|
|
|
@ -12,16 +12,17 @@
|
|||
static struct st_table *loaded_builtin_table;
|
||||
#endif
|
||||
|
||||
rb_ast_t *rb_builtin_ast(const char *feature_name, VALUE *name_str);
|
||||
VALUE rb_builtin_vast(const char *feature_name, VALUE *name_str);
|
||||
|
||||
static const rb_iseq_t *
|
||||
builtin_iseq_load(const char *feature_name, const struct rb_builtin_function *table)
|
||||
{
|
||||
VALUE name_str = 0;
|
||||
rb_ast_t *ast = rb_builtin_ast(feature_name, &name_str);
|
||||
rb_ast_t *ast;
|
||||
VALUE vast = rb_builtin_vast(feature_name, &name_str);
|
||||
rb_vm_t *vm = GET_VM();
|
||||
|
||||
if (!ast) {
|
||||
if (NIL_P(vast)) {
|
||||
rb_fatal("builtin_iseq_load: can not find %s; "
|
||||
"probably miniprelude.c is out of date",
|
||||
feature_name);
|
||||
|
@ -39,7 +40,8 @@ builtin_iseq_load(const char *feature_name, const struct rb_builtin_function *ta
|
|||
.coverage_enabled = FALSE,
|
||||
.debug_level = 0,
|
||||
};
|
||||
const rb_iseq_t *iseq = rb_iseq_new_with_opt(&ast->body, name_str, name_str, Qnil, 0, NULL, 0, ISEQ_TYPE_TOP, &optimization, Qnil);
|
||||
ast = rb_ruby_ast_data_get(vast);
|
||||
const rb_iseq_t *iseq = rb_iseq_new_with_opt(vast, name_str, name_str, Qnil, 0, NULL, 0, ISEQ_TYPE_TOP, &optimization, Qnil);
|
||||
GET_VM()->builtin_function_table = NULL;
|
||||
|
||||
rb_ast_dispose(ast);
|
||||
|
|
67
node.c
67
node.c
|
@ -304,14 +304,16 @@ rb_ast_t *
|
|||
rb_ast_new(const rb_parser_config_t *config)
|
||||
{
|
||||
node_buffer_t *nb = rb_node_buffer_new(config);
|
||||
return config->ast_new((VALUE)nb);
|
||||
return config->ast_new(nb);
|
||||
}
|
||||
#else
|
||||
rb_ast_t *
|
||||
rb_ast_new(void)
|
||||
{
|
||||
node_buffer_t *nb = rb_node_buffer_new();
|
||||
return IMEMO_NEW(rb_ast_t, imemo_ast, (VALUE)nb);
|
||||
rb_ast_t *ast = ruby_xcalloc(1, sizeof(rb_ast_t));
|
||||
ast->node_buffer = nb;
|
||||
return ast;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -348,14 +350,26 @@ script_lines_free(rb_ast_t *ast, rb_parser_ary_t *script_lines)
|
|||
void
|
||||
rb_ast_free(rb_ast_t *ast)
|
||||
{
|
||||
if (ast->node_buffer) {
|
||||
/* TODO
|
||||
* The current impl. of rb_ast_free() and rb_ast_dispose() is complicated.
|
||||
* Upcoming task of changing `ast->node_buffer->config` to `ast->config`,
|
||||
* that is based on "deIMEMO" of `rb_ast_t *`, will let us simplify the code.
|
||||
*/
|
||||
#ifdef UNIVERSAL_PARSER
|
||||
if (ast && ast->node_buffer) {
|
||||
void (*free_func)(void *) = xfree;
|
||||
if (ast->body.script_lines && !FIXNUM_P((VALUE)ast->body.script_lines)) {
|
||||
script_lines_free(ast, ast->body.script_lines);
|
||||
ast->body.script_lines = NULL;
|
||||
}
|
||||
rb_node_buffer_free(ast, ast->node_buffer);
|
||||
ast->node_buffer = 0;
|
||||
free_func(ast);
|
||||
}
|
||||
#else
|
||||
rb_ast_dispose(ast);
|
||||
xfree(ast);
|
||||
#endif
|
||||
}
|
||||
|
||||
static size_t
|
||||
|
@ -373,20 +387,63 @@ buffer_list_size(node_buffer_list_t *nb)
|
|||
size_t
|
||||
rb_ast_memsize(const rb_ast_t *ast)
|
||||
{
|
||||
size_t size = 0;
|
||||
size_t size = sizeof(rb_ast_t);
|
||||
node_buffer_t *nb = ast->node_buffer;
|
||||
rb_parser_ary_t *tokens = NULL;
|
||||
struct rb_ast_local_table_link *link = NULL;
|
||||
rb_parser_ary_t *script_lines = ast->body.script_lines;
|
||||
|
||||
long i;
|
||||
|
||||
if (nb) {
|
||||
size += sizeof(node_buffer_t);
|
||||
size += buffer_list_size(&nb->buffer_list);
|
||||
link = nb->local_tables;
|
||||
tokens = nb->tokens;
|
||||
}
|
||||
|
||||
while (link) {
|
||||
size += sizeof(struct rb_ast_local_table_link);
|
||||
size += link->size * sizeof(ID);
|
||||
link = link->next;
|
||||
}
|
||||
|
||||
if (tokens) {
|
||||
size += sizeof(rb_parser_ary_t);
|
||||
for (i = 0; i < tokens->len; i++) {
|
||||
size += sizeof(rb_parser_ast_token_t);
|
||||
rb_parser_ast_token_t *token = tokens->data[i];
|
||||
size += sizeof(rb_parser_string_t);
|
||||
size += token->str->len + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (script_lines && !FIXNUM_P((VALUE)script_lines)) {
|
||||
size += sizeof(rb_parser_ary_t);
|
||||
for (i = 0; i < script_lines->len; i++) {
|
||||
size += sizeof(rb_parser_string_t);
|
||||
size += ((rb_parser_string_t *)script_lines->data[i])->len + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
void
|
||||
rb_ast_dispose(rb_ast_t *ast)
|
||||
{
|
||||
rb_ast_free(ast);
|
||||
#ifdef UNIVERSAL_PARSER
|
||||
// noop. See the comment in rb_ast_free().
|
||||
#else
|
||||
if (ast && ast->node_buffer) {
|
||||
if (ast->body.script_lines && !FIXNUM_P((VALUE)ast->body.script_lines)) {
|
||||
script_lines_free(ast, ast->body.script_lines);
|
||||
ast->body.script_lines = NULL;
|
||||
}
|
||||
rb_node_buffer_free(ast, ast->node_buffer);
|
||||
ast->node_buffer = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
VALUE
|
||||
|
|
1
parse.y
1
parse.y
|
@ -15809,7 +15809,6 @@ rb_ruby_parser_mark(void *ptr)
|
|||
struct parser_params *p = (struct parser_params*)ptr;
|
||||
|
||||
rb_gc_mark(p->ruby_sourcefile_string);
|
||||
rb_gc_mark((VALUE)p->ast);
|
||||
#ifndef RIPPER
|
||||
rb_gc_mark(p->error_buffer);
|
||||
#else
|
||||
|
|
2
proc.c
2
proc.c
|
@ -3467,7 +3467,7 @@ proc_binding(VALUE self)
|
|||
env = VM_ENV_ENVVAL_PTR(block->as.captured.ep);
|
||||
env = env_clone(env, method_cref(method));
|
||||
/* set empty iseq */
|
||||
empty = rb_iseq_new(NULL, name, name, Qnil, 0, ISEQ_TYPE_TOP);
|
||||
empty = rb_iseq_new(Qnil, name, name, Qnil, 0, ISEQ_TYPE_TOP);
|
||||
RB_OBJ_WRITE(env, &env->iseq, empty);
|
||||
break;
|
||||
}
|
||||
|
|
38
ruby.c
38
ruby.c
|
@ -225,7 +225,7 @@ cmdline_options_init(ruby_cmdline_options_t *opt)
|
|||
return opt;
|
||||
}
|
||||
|
||||
static rb_ast_t *load_file(VALUE parser, VALUE fname, VALUE f, int script,
|
||||
static VALUE load_file(VALUE parser, VALUE fname, VALUE f, int script,
|
||||
ruby_cmdline_options_t *opt);
|
||||
static VALUE open_load_file(VALUE fname_v, int *xflag);
|
||||
static void forbid_setid(const char *, const ruby_cmdline_options_t *);
|
||||
|
@ -2056,10 +2056,11 @@ show_help(const char *progname, int help)
|
|||
usage(progname, help, tty, columns);
|
||||
}
|
||||
|
||||
static rb_ast_t *
|
||||
static VALUE
|
||||
process_script(ruby_cmdline_options_t *opt)
|
||||
{
|
||||
rb_ast_t *ast;
|
||||
VALUE vast;
|
||||
VALUE parser = rb_parser_new();
|
||||
const unsigned int dump = opt->dump;
|
||||
|
||||
|
@ -2079,7 +2080,7 @@ process_script(ruby_cmdline_options_t *opt)
|
|||
ruby_set_script_name(progname);
|
||||
rb_parser_set_options(parser, opt->do_print, opt->do_loop,
|
||||
opt->do_line, opt->do_split);
|
||||
ast = rb_parser_compile_string(parser, opt->script, opt->e_script, 1);
|
||||
vast = rb_parser_compile_string(parser, opt->script, opt->e_script, 1);
|
||||
}
|
||||
else {
|
||||
VALUE f;
|
||||
|
@ -2087,13 +2088,14 @@ process_script(ruby_cmdline_options_t *opt)
|
|||
f = open_load_file(opt->script_name, &xflag);
|
||||
opt->xflag = xflag != 0;
|
||||
rb_parser_set_context(parser, 0, f == rb_stdin);
|
||||
ast = load_file(parser, opt->script_name, f, 1, opt);
|
||||
vast = load_file(parser, opt->script_name, f, 1, opt);
|
||||
}
|
||||
ast = rb_ruby_ast_data_get(vast);
|
||||
if (!ast->body.root) {
|
||||
rb_ast_dispose(ast);
|
||||
return NULL;
|
||||
return Qnil;
|
||||
}
|
||||
return ast;
|
||||
return vast;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2237,6 +2239,7 @@ process_options_global_setup(const ruby_cmdline_options_t *opt, const rb_iseq_t
|
|||
static VALUE
|
||||
process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
|
||||
{
|
||||
VALUE vast = Qnil;
|
||||
struct {
|
||||
rb_ast_t *ast;
|
||||
pm_parse_result_t prism;
|
||||
|
@ -2471,7 +2474,8 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
|
|||
}
|
||||
|
||||
if (!(*rb_ruby_prism_ptr())) {
|
||||
if (!(result.ast = process_script(opt))) return Qfalse;
|
||||
vast = process_script(opt);
|
||||
if (!(result.ast = rb_ruby_ast_data_get(vast))) return Qfalse;
|
||||
}
|
||||
else {
|
||||
prism_script(opt, &result.prism);
|
||||
|
@ -2553,7 +2557,7 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
|
|||
}
|
||||
else {
|
||||
rb_ast_t *ast = result.ast;
|
||||
iseq = rb_iseq_new_main(&ast->body, opt->script_name, path, parent, optimize);
|
||||
iseq = rb_iseq_new_main(vast, opt->script_name, path, parent, optimize);
|
||||
rb_ast_dispose(ast);
|
||||
}
|
||||
}
|
||||
|
@ -2604,7 +2608,7 @@ load_file_internal(VALUE argp_v)
|
|||
ruby_cmdline_options_t *opt = argp->opt;
|
||||
VALUE f = argp->f;
|
||||
int line_start = 1;
|
||||
rb_ast_t *ast = 0;
|
||||
VALUE vast = Qnil;
|
||||
rb_encoding *enc;
|
||||
ID set_encoding;
|
||||
|
||||
|
@ -2702,10 +2706,10 @@ load_file_internal(VALUE argp_v)
|
|||
if (NIL_P(f)) {
|
||||
f = rb_str_new(0, 0);
|
||||
rb_enc_associate(f, enc);
|
||||
return (VALUE)rb_parser_compile_string_path(parser, orig_fname, f, line_start);
|
||||
return rb_parser_compile_string_path(parser, orig_fname, f, line_start);
|
||||
}
|
||||
rb_funcall(f, set_encoding, 2, rb_enc_from_encoding(enc), rb_str_new_cstr("-"));
|
||||
ast = rb_parser_compile_file_path(parser, orig_fname, f, line_start);
|
||||
vast = rb_parser_compile_file_path(parser, orig_fname, f, line_start);
|
||||
rb_funcall(f, set_encoding, 1, rb_parser_encoding(parser));
|
||||
if (script && rb_parser_end_seen_p(parser)) {
|
||||
/*
|
||||
|
@ -2723,7 +2727,7 @@ load_file_internal(VALUE argp_v)
|
|||
rb_define_global_const("DATA", f);
|
||||
argp->f = Qnil;
|
||||
}
|
||||
return (VALUE)ast;
|
||||
return vast;
|
||||
}
|
||||
|
||||
/* disabling O_NONBLOCK, and returns 0 on success, otherwise errno */
|
||||
|
@ -2832,7 +2836,7 @@ restore_load_file(VALUE arg)
|
|||
return Qnil;
|
||||
}
|
||||
|
||||
static rb_ast_t *
|
||||
static VALUE
|
||||
load_file(VALUE parser, VALUE fname, VALUE f, int script, ruby_cmdline_options_t *opt)
|
||||
{
|
||||
struct load_file_arg arg;
|
||||
|
@ -2841,7 +2845,7 @@ load_file(VALUE parser, VALUE fname, VALUE f, int script, ruby_cmdline_options_t
|
|||
arg.script = script;
|
||||
arg.opt = opt;
|
||||
arg.f = f;
|
||||
return (rb_ast_t *)rb_ensure(load_file_internal, (VALUE)&arg,
|
||||
return rb_ensure(load_file_internal, (VALUE)&arg,
|
||||
restore_load_file, (VALUE)&arg);
|
||||
}
|
||||
|
||||
|
@ -2855,10 +2859,12 @@ rb_load_file(const char *fname)
|
|||
void *
|
||||
rb_load_file_str(VALUE fname_v)
|
||||
{
|
||||
return rb_parser_load_file(rb_parser_new(), fname_v);
|
||||
VALUE vast;
|
||||
vast = rb_parser_load_file(rb_parser_new(), fname_v);
|
||||
return (void *)rb_ruby_ast_data_get(vast);
|
||||
}
|
||||
|
||||
void *
|
||||
VALUE
|
||||
rb_parser_load_file(VALUE parser, VALUE fname_v)
|
||||
{
|
||||
ruby_cmdline_options_t opt;
|
||||
|
|
|
@ -293,9 +293,11 @@ arg_error(void)
|
|||
}
|
||||
|
||||
static rb_ast_t *
|
||||
ast_new(VALUE nb)
|
||||
ast_new(node_buffer_t *nb)
|
||||
{
|
||||
return IMEMO_NEW(rb_ast_t, imemo_ast, nb);
|
||||
rb_ast_t *ast = ruby_xcalloc(1, sizeof(rb_ast_t));
|
||||
ast->node_buffer = nb;
|
||||
return ast;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
@ -742,69 +744,95 @@ parser_compile_generic(struct ruby_parser *parser, rb_parser_lex_gets_func *lex_
|
|||
return rb_parser_compile(parser->parser_params, lex_gets, fname, (rb_parser_input_data)input, start);
|
||||
}
|
||||
|
||||
rb_ast_t*
|
||||
static void
|
||||
ast_free(void *ptr)
|
||||
{
|
||||
rb_ast_t *ast = (rb_ast_t *)ptr;
|
||||
if (ast) {
|
||||
rb_ast_free(ast);
|
||||
}
|
||||
}
|
||||
|
||||
static const rb_data_type_t ast_data_type = {
|
||||
"AST",
|
||||
{
|
||||
NULL,
|
||||
ast_free,
|
||||
NULL, // No dsize() because this object does not appear in ObjectSpace.
|
||||
},
|
||||
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
||||
};
|
||||
|
||||
static VALUE
|
||||
ast_alloc(void)
|
||||
{
|
||||
rb_ast_t *ast;
|
||||
return TypedData_Make_Struct(0, rb_ast_t, &ast_data_type, ast);
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_parser_compile_file_path(VALUE vparser, VALUE fname, VALUE file, int start)
|
||||
{
|
||||
struct ruby_parser *parser;
|
||||
rb_ast_t *ast;
|
||||
VALUE vast = ast_alloc();
|
||||
|
||||
TypedData_Get_Struct(vparser, struct ruby_parser, &ruby_parser_data_type, parser);
|
||||
ast = parser_compile_file_path(parser, fname, file, start);
|
||||
DATA_PTR(vast) = parser_compile_file_path(parser, fname, file, start);
|
||||
RB_GC_GUARD(vparser);
|
||||
|
||||
return ast;
|
||||
return vast;
|
||||
}
|
||||
|
||||
rb_ast_t*
|
||||
VALUE
|
||||
rb_parser_compile_array(VALUE vparser, VALUE fname, VALUE array, int start)
|
||||
{
|
||||
struct ruby_parser *parser;
|
||||
rb_ast_t *ast;
|
||||
VALUE vast = ast_alloc();
|
||||
|
||||
TypedData_Get_Struct(vparser, struct ruby_parser, &ruby_parser_data_type, parser);
|
||||
ast = parser_compile_array(parser, fname, array, start);
|
||||
DATA_PTR(vast) = parser_compile_array(parser, fname, array, start);
|
||||
RB_GC_GUARD(vparser);
|
||||
|
||||
return ast;
|
||||
return vast;
|
||||
}
|
||||
|
||||
rb_ast_t*
|
||||
VALUE
|
||||
rb_parser_compile_generic(VALUE vparser, rb_parser_lex_gets_func *lex_gets, VALUE fname, VALUE input, int start)
|
||||
{
|
||||
struct ruby_parser *parser;
|
||||
rb_ast_t *ast;
|
||||
VALUE vast = ast_alloc();
|
||||
|
||||
TypedData_Get_Struct(vparser, struct ruby_parser, &ruby_parser_data_type, parser);
|
||||
ast = parser_compile_generic(parser, lex_gets, fname, input, start);
|
||||
DATA_PTR(vast) = parser_compile_generic(parser, lex_gets, fname, input, start);
|
||||
RB_GC_GUARD(vparser);
|
||||
|
||||
return ast;
|
||||
return vast;
|
||||
}
|
||||
|
||||
rb_ast_t*
|
||||
VALUE
|
||||
rb_parser_compile_string(VALUE vparser, const char *f, VALUE s, int line)
|
||||
{
|
||||
struct ruby_parser *parser;
|
||||
rb_ast_t *ast;
|
||||
VALUE vast = ast_alloc();
|
||||
|
||||
TypedData_Get_Struct(vparser, struct ruby_parser, &ruby_parser_data_type, parser);
|
||||
ast = parser_compile_string(parser, f, s, line);
|
||||
DATA_PTR(vast) = parser_compile_string(parser, f, s, line);
|
||||
RB_GC_GUARD(vparser);
|
||||
|
||||
return ast;
|
||||
return vast;
|
||||
}
|
||||
|
||||
rb_ast_t*
|
||||
VALUE
|
||||
rb_parser_compile_string_path(VALUE vparser, VALUE f, VALUE s, int line)
|
||||
{
|
||||
struct ruby_parser *parser;
|
||||
rb_ast_t *ast;
|
||||
VALUE vast = ast_alloc();
|
||||
|
||||
TypedData_Get_Struct(vparser, struct ruby_parser, &ruby_parser_data_type, parser);
|
||||
ast = parser_compile_string_path(parser, f, s, line);
|
||||
DATA_PTR(vast) = parser_compile_string_path(parser, f, s, line);
|
||||
RB_GC_GUARD(vparser);
|
||||
|
||||
return ast;
|
||||
return vast;
|
||||
}
|
||||
|
||||
VALUE
|
||||
|
@ -1086,3 +1114,26 @@ rb_parser_aset_script_lines_for(VALUE path, rb_parser_ary_t *lines)
|
|||
script_lines = rb_parser_build_script_lines_from(lines);
|
||||
rb_hash_aset(hash, path, script_lines);
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_ruby_ast_new(const NODE *const root, rb_parser_ary_t *script_lines)
|
||||
{
|
||||
VALUE vast = ast_alloc();
|
||||
rb_ast_t *ast = DATA_PTR(vast);
|
||||
ast->body = (rb_ast_body_t){
|
||||
.root = root,
|
||||
.frozen_string_literal = -1,
|
||||
.coverage_enabled = -1,
|
||||
.script_lines = script_lines
|
||||
};
|
||||
return vast;
|
||||
}
|
||||
|
||||
rb_ast_t *
|
||||
rb_ruby_ast_data_get(VALUE vast)
|
||||
{
|
||||
rb_ast_t *ast;
|
||||
if (NIL_P(vast)) return NULL;
|
||||
TypedData_Get_Struct(vast, rb_ast_t, &ast_data_type, ast);
|
||||
return ast;
|
||||
}
|
||||
|
|
|
@ -1208,7 +1208,7 @@ typedef struct RNode_ERROR {
|
|||
(n)->flags=(((n)->flags&~NODE_TYPEMASK)|((((unsigned long)(t))<<NODE_TYPESHIFT)&NODE_TYPEMASK))
|
||||
|
||||
typedef struct node_buffer_struct node_buffer_t;
|
||||
/* T_IMEMO/ast */
|
||||
|
||||
typedef struct rb_ast_body_struct {
|
||||
const NODE *root;
|
||||
rb_parser_ary_t *script_lines;
|
||||
|
@ -1219,7 +1219,6 @@ typedef struct rb_ast_body_struct {
|
|||
signed int coverage_enabled:2; /* -1: not specified, 0: false, 1: true */
|
||||
} rb_ast_body_t;
|
||||
typedef struct rb_ast_struct {
|
||||
VALUE flags;
|
||||
node_buffer_t *node_buffer;
|
||||
rb_ast_body_t body;
|
||||
} rb_ast_t;
|
||||
|
@ -1251,8 +1250,7 @@ typedef struct rb_parser_config_struct {
|
|||
void *(*nonempty_memcpy)(void *dest, const void *src, size_t t, size_t n);
|
||||
void *(*xmalloc_mul_add)(size_t x, size_t y, size_t z);
|
||||
|
||||
/* imemo */
|
||||
rb_ast_t *(*ast_new)(VALUE nb);
|
||||
rb_ast_t *(*ast_new)(node_buffer_t *nb);
|
||||
|
||||
// VALUE rb_suppress_tracing(VALUE (*func)(VALUE), VALUE arg);
|
||||
VALUE (*compile_callback)(VALUE (*func)(VALUE), VALUE arg);
|
||||
|
|
|
@ -141,37 +141,39 @@ COMPILER_WARNING_POP
|
|||
#define PRELUDE_NAME(n) rb_usascii_str_new_static(prelude_name##n, sizeof(prelude_name##n)-1)
|
||||
#define PRELUDE_CODE(n) rb_utf8_str_new_static(prelude_code##n.L0, sizeof(prelude_code##n))
|
||||
|
||||
static rb_ast_t *
|
||||
prelude_ast(VALUE name, VALUE code, int line)
|
||||
static VALUE
|
||||
prelude_vast(VALUE name, VALUE code, int line)
|
||||
{
|
||||
rb_ast_t *ast = rb_parser_compile_string_path(rb_parser_new(), name, code, line);
|
||||
rb_ast_t *ast;
|
||||
VALUE vast = rb_parser_compile_string_path(rb_parser_new(), name, code, line);
|
||||
ast = rb_ruby_ast_data_get(vast);
|
||||
if (!ast || !ast->body.root) {
|
||||
if (ast) rb_ast_dispose(ast);
|
||||
rb_exc_raise(rb_errinfo());
|
||||
}
|
||||
return ast;
|
||||
return vast;
|
||||
}
|
||||
|
||||
% end
|
||||
% if @builtin_count > 0
|
||||
#define PRELUDE_AST(n, name_str, start_line) \
|
||||
#define PRELUDE_VAST(n, name_str, start_line) \
|
||||
(((sizeof(prelude_name<%='##'%><%=%>n) - prefix_len - 2) == namelen) && \
|
||||
(strncmp(prelude_name<%='##'%><%=%>n + prefix_len, feature_name, namelen) == 0) ? \
|
||||
prelude_ast((name_str) = PRELUDE_NAME(n), PRELUDE_CODE(n), start_line) : 0)
|
||||
prelude_vast((name_str) = PRELUDE_NAME(n), PRELUDE_CODE(n), start_line) : Qnil)
|
||||
|
||||
rb_ast_t *
|
||||
rb_builtin_ast(const char *feature_name, VALUE *name_str)
|
||||
VALUE
|
||||
rb_builtin_vast(const char *feature_name, VALUE *name_str)
|
||||
{
|
||||
const size_t prefix_len = rb_strlen_lit("<internal:");
|
||||
size_t namelen = strlen(feature_name);
|
||||
rb_ast_t *ast = 0;
|
||||
VALUE vast = Qnil;
|
||||
|
||||
% @preludes.each_value do |i, prelude, lines, sub, start_line|
|
||||
% if sub
|
||||
if ((ast = PRELUDE_AST(<%=i%><%=%>, *name_str, <%=start_line%>)) != 0) return ast;
|
||||
if (!NIL_P(vast = PRELUDE_VAST(<%=i%><%=%>, *name_str, <%=start_line%>))) return vast;
|
||||
% end
|
||||
% end
|
||||
return ast;
|
||||
return vast;
|
||||
}
|
||||
|
||||
% end
|
||||
|
@ -196,8 +198,10 @@ prelude_eval(VALUE code, VALUE name, int line)
|
|||
0, /* int debug_level; */
|
||||
};
|
||||
|
||||
rb_ast_t *ast = prelude_ast(name, code, line);
|
||||
rb_iseq_eval(rb_iseq_new_with_opt(&ast->body, name, name, Qnil, line,
|
||||
rb_ast_t *ast;
|
||||
VALUE vast = prelude_vast(name, code, line);
|
||||
ast = rb_ruby_ast_data_get(vast);
|
||||
rb_iseq_eval(rb_iseq_new_with_opt(vast, name, name, Qnil, line,
|
||||
NULL, 0, ISEQ_TYPE_TOP, &optimization,
|
||||
Qnil));
|
||||
rb_ast_dispose(ast);
|
||||
|
|
14
vm.c
14
vm.c
|
@ -1463,7 +1463,6 @@ rb_binding_add_dynavars(VALUE bindval, rb_binding_t *bind, int dyncount, const I
|
|||
const rb_env_t *env;
|
||||
rb_execution_context_t *ec = GET_EC();
|
||||
const rb_iseq_t *base_iseq, *iseq;
|
||||
rb_ast_body_t ast;
|
||||
rb_node_scope_t tmp_node;
|
||||
|
||||
if (dyncount < 0) return 0;
|
||||
|
@ -1481,17 +1480,14 @@ rb_binding_add_dynavars(VALUE bindval, rb_binding_t *bind, int dyncount, const I
|
|||
tmp_node.nd_body = 0;
|
||||
tmp_node.nd_args = 0;
|
||||
|
||||
ast.root = RNODE(&tmp_node);
|
||||
ast.frozen_string_literal = -1;
|
||||
ast.coverage_enabled = -1;
|
||||
ast.script_lines = (rb_parser_ary_t *)INT2FIX(-1);
|
||||
VALUE vast = rb_ruby_ast_new(RNODE(&tmp_node), (rb_parser_ary_t *)INT2FIX(-1));
|
||||
|
||||
if (base_iseq) {
|
||||
iseq = rb_iseq_new(&ast, ISEQ_BODY(base_iseq)->location.label, path, realpath, base_iseq, ISEQ_TYPE_EVAL);
|
||||
iseq = rb_iseq_new(vast, ISEQ_BODY(base_iseq)->location.label, path, realpath, base_iseq, ISEQ_TYPE_EVAL);
|
||||
}
|
||||
else {
|
||||
VALUE tempstr = rb_fstring_lit("<temp>");
|
||||
iseq = rb_iseq_new_top(&ast, tempstr, tempstr, tempstr, NULL);
|
||||
iseq = rb_iseq_new_top(vast, tempstr, tempstr, tempstr, NULL);
|
||||
}
|
||||
tmp_node.nd_tbl = 0; /* reset table */
|
||||
ALLOCV_END(idtmp);
|
||||
|
@ -2864,7 +2860,7 @@ rb_vm_call_cfunc(VALUE recv, VALUE (*func)(VALUE), VALUE arg,
|
|||
{
|
||||
rb_execution_context_t *ec = GET_EC();
|
||||
const rb_control_frame_t *reg_cfp = ec->cfp;
|
||||
const rb_iseq_t *iseq = rb_iseq_new(0, filename, filename, Qnil, 0, ISEQ_TYPE_TOP);
|
||||
const rb_iseq_t *iseq = rb_iseq_new(Qnil, filename, filename, Qnil, 0, ISEQ_TYPE_TOP);
|
||||
VALUE val;
|
||||
|
||||
vm_push_frame(ec, iseq, VM_FRAME_MAGIC_TOP | VM_ENV_FLAG_LOCAL | VM_FRAME_FLAG_FINISH,
|
||||
|
@ -4179,7 +4175,7 @@ Init_VM(void)
|
|||
rb_vm_t *vm = ruby_current_vm_ptr;
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
VALUE filename = rb_fstring_lit("<main>");
|
||||
const rb_iseq_t *iseq = rb_iseq_new(0, filename, filename, Qnil, 0, ISEQ_TYPE_TOP);
|
||||
const rb_iseq_t *iseq = rb_iseq_new(Qnil, filename, filename, Qnil, 0, ISEQ_TYPE_TOP);
|
||||
|
||||
// Ractor setup
|
||||
rb_ractor_main_setup(vm, th->ractor, th);
|
||||
|
|
10
vm_core.h
10
vm_core.h
|
@ -1209,11 +1209,11 @@ typedef enum {
|
|||
RUBY_SYMBOL_EXPORT_BEGIN
|
||||
|
||||
/* node -> iseq */
|
||||
rb_iseq_t *rb_iseq_new (const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE realpath, const rb_iseq_t *parent, enum rb_iseq_type);
|
||||
rb_iseq_t *rb_iseq_new_top (const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE realpath, const rb_iseq_t *parent);
|
||||
rb_iseq_t *rb_iseq_new_main (const rb_ast_body_t *ast, VALUE path, VALUE realpath, const rb_iseq_t *parent, int opt);
|
||||
rb_iseq_t *rb_iseq_new_eval (const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE realpath, int first_lineno, const rb_iseq_t *parent, int isolated_depth);
|
||||
rb_iseq_t *rb_iseq_new_with_opt(const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE realpath, int first_lineno, const rb_iseq_t *parent, int isolated_depth,
|
||||
rb_iseq_t *rb_iseq_new (const VALUE vast, VALUE name, VALUE path, VALUE realpath, const rb_iseq_t *parent, enum rb_iseq_type);
|
||||
rb_iseq_t *rb_iseq_new_top (const VALUE vast, VALUE name, VALUE path, VALUE realpath, const rb_iseq_t *parent);
|
||||
rb_iseq_t *rb_iseq_new_main (const VALUE vast, VALUE path, VALUE realpath, const rb_iseq_t *parent, int opt);
|
||||
rb_iseq_t *rb_iseq_new_eval (const VALUE vast, VALUE name, VALUE path, VALUE realpath, int first_lineno, const rb_iseq_t *parent, int isolated_depth);
|
||||
rb_iseq_t *rb_iseq_new_with_opt(const VALUE vast, VALUE name, VALUE path, VALUE realpath, int first_lineno, const rb_iseq_t *parent, int isolated_depth,
|
||||
enum rb_iseq_type, const rb_compile_option_t*,
|
||||
VALUE script_lines);
|
||||
|
||||
|
|
|
@ -1753,6 +1753,7 @@ eval_make_iseq(VALUE src, VALUE fname, int line,
|
|||
const VALUE parser = rb_parser_new();
|
||||
const rb_iseq_t *const parent = vm_block_iseq(base_block);
|
||||
rb_iseq_t *iseq = NULL;
|
||||
VALUE vast;
|
||||
rb_ast_t *ast;
|
||||
int isolated_depth = 0;
|
||||
|
||||
|
@ -1790,10 +1791,13 @@ eval_make_iseq(VALUE src, VALUE fname, int line,
|
|||
|
||||
rb_parser_set_context(parser, parent, FALSE);
|
||||
if (ruby_vm_keep_script_lines) rb_parser_set_script_lines(parser);
|
||||
ast = rb_parser_compile_string_path(parser, fname, src, line);
|
||||
vast = rb_parser_compile_string_path(parser, fname, src, line);
|
||||
|
||||
ast = rb_ruby_ast_data_get(vast);
|
||||
|
||||
if (ast->body.root) {
|
||||
ast->body.coverage_enabled = coverage_enabled;
|
||||
iseq = rb_iseq_new_eval(&ast->body,
|
||||
iseq = rb_iseq_new_eval(vast,
|
||||
ISEQ_BODY(parent)->location.label,
|
||||
fname, Qnil, line,
|
||||
parent, isolated_depth);
|
||||
|
|
Загрузка…
Ссылка в новой задаче