* include/ruby/{intern,ruby}.h, compile.[ch], error.c, eval.c,

eval_load.c, gc.c, iseq.c, main.c, parse.y, re.c, ruby.c,
  yarvcore.[ch] (ruby_eval_tree, ruby_sourcefile, ruby_sourceline,
  ruby_nerrs): purge global variables.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12700 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2007-07-05 08:12:18 +00:00
Родитель a0d50fa3c4
Коммит 46603a78af
16 изменённых файлов: 496 добавлений и 471 удалений

Просмотреть файл

@ -1,3 +1,10 @@
Thu Jul 5 17:12:16 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
* include/ruby/{intern,ruby}.h, compile.[ch], error.c, eval.c,
eval_load.c, gc.c, iseq.c, main.c, parse.y, re.c, ruby.c,
yarvcore.[ch] (ruby_eval_tree, ruby_sourcefile, ruby_sourceline,
ruby_nerrs): purge global variables.
Thu Jul 5 16:37:34 2007 NAKAMURA Usaku <usa@ruby-lang.org>
* numeric.c (int_pow): fix previous nubu's commit.

265
compile.c
Просмотреть файл

@ -181,27 +181,29 @@ rb_iseq_compile(VALUE self, NODE *node)
}
}
else {
if (iseq->type == ISEQ_TYPE_METHOD ||
iseq->type == ISEQ_TYPE_CLASS ||
iseq->type == ISEQ_TYPE_BLOCK ||
iseq->type == ISEQ_TYPE_EVAL ||
iseq->type == ISEQ_TYPE_TOP) {
switch (iseq->type) {
case ISEQ_TYPE_METHOD:
case ISEQ_TYPE_CLASS:
case ISEQ_TYPE_BLOCK:
case ISEQ_TYPE_EVAL:
case ISEQ_TYPE_TOP:
dpn(node);
rb_bug("compile/should not be reached: %s:%d", __FILE__, __LINE__);
}
else if (iseq->type == ISEQ_TYPE_RESCUE) {
rb_compile_error(ERROR_ARGS "compile/should not be reached: %s:%d",
__FILE__, __LINE__);
break;
case ISEQ_TYPE_RESCUE:
set_exception_tbl(iseq);
COMPILE(ret, "rescue", node);
}
else if (iseq->type == ISEQ_TYPE_ENSURE) {
break;
case ISEQ_TYPE_ENSURE:
set_exception_tbl(iseq);
COMPILE_POPED(ret, "ensure", node);
}
else if (iseq->type == ISEQ_TYPE_DEFINED_GUARD) {
break;
case ISEQ_TYPE_DEFINED_GUARD:
COMPILE(ret, "defined guard", node);
}
else {
rb_bug("unknown scope");
break;
default:
rb_compile_error(ERROR_ARGS "unknown scope");
}
}
@ -317,7 +319,8 @@ verify_list(char *info, LINK_ANCHOR *anchor)
}
if (flag != 0) {
rb_bug("list verify error: %08x (%s)", flag, info);
rb_compile_error(ERROR_ARGS "list verify error: %08x (%s)",
flag, info);
}
#endif
}
@ -669,14 +672,14 @@ iseq_setup(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
debugs("[compile step 3.2 (iseq_insns_unification)]\n");
iseq_insns_unification(iseq, anchor);
if (CPDEBUG > 5)
dump_disasm_list(FIRST_ELEMENT(anchor));
dump_disasm_list(FIRST_ELEMENT(anchor));
}
if (iseq->compile_data->option->stack_caching) {
debugs("[compile step 3.3 (set_sequence_stackcaching)]\n");
set_sequence_stackcaching(iseq, anchor);
if (CPDEBUG > 5)
dump_disasm_list(FIRST_ELEMENT(anchor));
dump_disasm_list(FIRST_ELEMENT(anchor));
}
debugs("[compile step 4.1 (set_sequence)]\n");
@ -738,35 +741,31 @@ get_dyna_var_idx_at_raw(rb_iseq_t *iseq, ID id)
}
static int
get_local_var_idx(rb_iseq_t *iseq, ID id)
get_local_var_idx(rb_iseq_t *iseq, ID id, NODE *node)
{
int idx = get_dyna_var_idx_at_raw(iseq->local_iseq, id);
if (idx == -1) {
dpi(id);
rb_bug("get_local_var_idx: -1");
rb_compile_error(ERROR_ARGS "get_local_var_idx: -1");
}
return idx;
}
static int
get_dyna_var_idx(rb_iseq_t *iseq, ID id, int *level, int *ls)
get_dyna_var_idx(rb_iseq_t *iseq, ID id, int *level, int *ls, NODE *node)
{
int lv = 0, idx;
while (iseq) {
if ((idx = get_dyna_var_idx_at_raw(iseq, id)) >= 0) {
*level = lv;
*ls = iseq->local_size;
return idx;
}
while (iseq ? (idx = get_dyna_var_idx_at_raw(iseq, id)) < 0 :
(rb_compile_error(ERROR_ARGS "get_dyna_var_idx: -1"), 0)) {
iseq = iseq->parent_iseq;
lv++;
}
rb_bug("get_dyna_var_idx: -1");
return -1;
*level = lv;
*ls = iseq->local_size;
return idx;
}
static int
@ -783,8 +782,9 @@ set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *optargs, NODE *node_args)
NODE *node_init = 0;
if (nd_type(node_args) != NODE_ARGS) {
rb_bug("set_arguments: NODE_ARGS is expected, but %s",
ruby_node_name(nd_type(node_args)));
NODE *node = node_args;
rb_compile_error(ERROR_ARGS "set_arguments: NODE_ARGS is expected, but %s",
ruby_node_name(nd_type(node_args)));
}
/*
@ -864,7 +864,8 @@ set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *optargs, NODE *node_args)
iseq->arg_rest = get_dyna_var_idx_at_raw(iseq, rest_id);
if (iseq->arg_rest == -1) {
rb_bug("arg_rest: -1");
NODE *node = node_aux;
rb_compile_error(ERROR_ARGS "arg_rest: -1");
}
if (iseq->arg_post_start == 0) {
@ -958,7 +959,7 @@ set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
LINK_ELEMENT *list;
VALUE *generated_iseq;
int k, pos, sp, stack_max = 0;
int k, pos, sp, stack_max = 0, line = 0;
/* set label position */
list = FIRST_ELEMENT(anchor);
@ -969,6 +970,7 @@ set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
{
iobj = (INSN *)list;
pos += insn_data_length(iobj);
line = iobj->line_no;
k += 1;
break;
@ -988,7 +990,8 @@ set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
default:
dump_disasm_list(FIRST_ELEMENT(anchor));
dump_disasm_list(list);
rb_bug("error: set_sequence");
rb_compile_error(RSTRING_PTR(iseq->filename), line,
"error: set_sequence");
break;
}
list = list->next;
@ -1032,8 +1035,9 @@ set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
/* operand check */
if (iobj->operand_size != len - 1) {
dump_disasm_list(list);
rb_bug("operand size miss! (%d for %d)",
iobj->operand_size, len - 1);
rb_compile_error(RSTRING_PTR(iseq->filename), iobj->line_no,
"operand size miss! (%d for %d)",
iobj->operand_size, len - 1);
return 0;
}
@ -1046,7 +1050,9 @@ set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
/* label(destination position) */
lobj = (LABEL *)operands[j];
if (lobj->set != Qtrue) {
rb_bug("unknown label");
rb_compile_error(RSTRING_PTR(iseq->filename),
iobj->line_no,
"unknown label");
}
if (lobj->sp == -1) {
lobj->sp = sp;
@ -1070,7 +1076,9 @@ set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
lobj = (LABEL *)(lv & ~1);
if (lobj->set != Qtrue) {
rb_bug("unknown label");
rb_compile_error(RSTRING_PTR(iseq->filename),
iobj->line_no,
"unknown label");
}
rb_hash_aset(map, obj,
INT2FIX(lobj->position - (pos+len)));
@ -1120,7 +1128,8 @@ set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
}
break;
default:
rb_bug("unknown operand type: %c", type);
rb_compile_error(RSTRING_PTR(iseq->filename), iobj->line_no,
"unknown operand type: %c", type);
return 0;
}
}
@ -1602,7 +1611,7 @@ iseq_insns_unification(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
#include "opt_sc.inc"
static int
insn_set_sc_state(INSN *iobj, int state)
insn_set_sc_state(rb_iseq_t *iseq, INSN *iobj, int state)
{
int nstate;
int insn_id;
@ -1620,7 +1629,8 @@ insn_set_sc_state(INSN *iobj, int state)
dump_disasm_list((LINK_ELEMENT *)iobj);
dump_disasm_list((LINK_ELEMENT *)lobj);
printf("\n-- %d, %d\n", lobj->sc_state, nstate);
rb_bug("insn_set_sc_state error\n");
rb_compile_error(RSTRING_PTR(iseq->filename), iobj->lineno,
"insn_set_sc_state error\n");
return 0;
}
}
@ -1721,7 +1731,7 @@ set_sequence_stackcaching(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
case SCS_XX:
goto normal_insn;
default:
rb_bug("unreachable");
rb_compile_error(ERROR_ARGS "unreachable");
}
/* remove useless pop */
REMOVE_ELEM(list);
@ -1732,7 +1742,7 @@ set_sequence_stackcaching(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
/* none */
} /* end of switch */
normal_insn:
state = insn_set_sc_state(iobj, state);
state = insn_set_sc_state(iseq, iobj, state);
break;
}
case ISEQ_ELEMENT_LABEL:
@ -1834,8 +1844,8 @@ compile_array_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE* node_root,
if (nd_type(node) != NODE_ZARRAY) {
while (node) {
if (nd_type(node) != NODE_ARRAY) {
rb_bug("compile_array: This node is not NODE_ARRAY, but %s",
ruby_node_name(nd_type(node)));
rb_compile_error(ERROR_ARGS "compile_array: This node is not NODE_ARRAY, but %s",
ruby_node_name(nd_type(node)));
}
i++;
@ -1848,8 +1858,10 @@ compile_array_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE* node_root,
}
if (len != i) {
if (0) rb_bug("node error: compile_array (%d: %d-%d)",
(int)nd_line(node_root), len, i);
if (0) {
rb_compile_error(ERROR_ARGS "node error: compile_array (%d: %d-%d)",
(int)nd_line(node_root), len, i);
}
len = i;
}
@ -1884,13 +1896,15 @@ compile_array(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE* node_root, VALUE opt_p)
static VALUE
case_when_optimizable_literal(NODE * node)
{
if (nd_type(node) == NODE_LIT) {
switch (nd_type(node)) {
case NODE_LIT: {
VALUE v = node->nd_lit;
if (SYMBOL_P(v) || rb_obj_is_kind_of(v, rb_cNumeric)) {
return v;
}
}
else if (nd_type(node) == NODE_STR) {
break;
}
case NODE_STR:
return node->nd_lit;
}
return Qfalse;
@ -1984,11 +1998,13 @@ compile_massign(rb_iseq_t *iseq, LINK_ANCHOR *ret,
int rlen = rhsn->nd_alen;
int max = rlen > llen ? rlen : llen;
int i, si = 0;
int rline = nd_line(rhsn);
for (i = 0; i < max; i++) {
if (i < rlen && i < llen) {
/* a, b = c, d */
COMPILE(ret, "masgn val1", rhsn->nd_head);
rline = nd_line(rhsn);
rhsn = rhsn->nd_next;
}
else if (i < rlen) {
@ -1998,6 +2014,7 @@ compile_massign(rb_iseq_t *iseq, LINK_ANCHOR *ret,
si++;
COMPILE(ret, "masgn rhs for lhs splat",
rhsn->nd_head);
rline = nd_line(rhsn);
rhsn = rhsn->nd_next;
}
break;
@ -2011,12 +2028,12 @@ compile_massign(rb_iseq_t *iseq, LINK_ANCHOR *ret,
}
else if (i < llen) {
/* a, b, c = c, d */
ADD_INSN(ret, 0, putnil);
ADD_INSN(ret, rline, putnil);
}
}
if (lhs_splat) {
ADD_INSN1(ret, 0, newarray, INT2FIX(si));
ADD_INSN1(ret, rline, newarray, INT2FIX(si));
}
break;
}
@ -2041,7 +2058,7 @@ compile_massign(rb_iseq_t *iseq, LINK_ANCHOR *ret,
COMPILE(ret, "rhs to ary (splat/default)", rhsn);
ADD_INSN2(ret, nd_line(rhsn), expandarray, INT2FIX(llen),
INT2FIX(lhs_splat));
/* rb_bug("unknown rhs: %s", ruby_node_name(nd_type(rhsn))); */
/* rb_compile_error(ERROR_ARGS "unknown rhs: %s", ruby_node_name(nd_type(rhsn))); */
}
}
else {
@ -2051,8 +2068,8 @@ compile_massign(rb_iseq_t *iseq, LINK_ANCHOR *ret,
if (lhs_splat) {
if (nd_type(splatn) == NODE_POSTARG) {
int num = splatn->nd_2nd->nd_alen;
NODE *n = splatn->nd_2nd;
int num = n->nd_alen;
ADD_INSN (ret, nd_line(n), dup);
ADD_INSN2(ret, nd_line(n), expandarray, INT2FIX(num), INT2FIX(2));
@ -2116,7 +2133,7 @@ compile_colon2(rb_iseq_t *iseq, NODE * node,
static int
compile_cpath(LINK_ANCHOR *ret, rb_iseq_t *iseq, NODE *cpath)
{
if(cpath->nd_head) {
if (cpath->nd_head) {
COMPILE(ret, "nd_else->nd_head", cpath->nd_head);
}
else if (nd_type(cpath) == NODE_COLON2) {
@ -2170,7 +2187,7 @@ defined_expr(rb_iseq_t *iseq, LINK_ANCHOR *ret,
ADD_INSNL(ret, nd_line(node), jump, lfinish);
ADD_LABEL(ret, lcont);
}
} while ((vals = vals->nd_next));
} while ((vals = vals->nd_next) != NULL);
}
case NODE_STR:
case NODE_LIT:
@ -2354,7 +2371,7 @@ defined_expr(rb_iseq_t *iseq, LINK_ANCHOR *ret,
ADD_CATCH_ENTRY(CATCH_TYPE_ENSURE, lstart, lend, ensure, lfinish);
return 1;
/* rb_bug("unimplemented defined: %s", ruby_node_name(nd_type(node))); */
/* rb_compile_error(ERROR_ARGS "unimplemented defined: %s", ruby_node_name(nd_type(node))); */
} /* end of default */
}
@ -2377,26 +2394,18 @@ defined_expr(rb_iseq_t *iseq, LINK_ANCHOR *ret,
static VALUE
make_name_for_block(rb_iseq_t *iseq)
{
char buf[BUFSIZE];
if (iseq->parent_iseq == 0) {
snprintf(buf, BUFSIZE, "block in %s", RSTRING_PTR(iseq->name));
return rb_sprintf("block in %s", RSTRING_PTR(iseq->name));
}
else {
int level = 1;
rb_iseq_t *ip = iseq;
while (1) {
if (ip->local_iseq != ip) {
ip = ip->parent_iseq;
}
else {
break;
}
while (ip->local_iseq != ip) {
ip = ip->parent_iseq;
level++;
}
snprintf(buf, BUFSIZE, "block (%d levels) in %s", level,
RSTRING_PTR(ip->name));
return rb_sprintf("block (%d levels) in %s", level, RSTRING_PTR(ip->name));
}
return rb_str_new2(buf);
}
static void
@ -2504,7 +2513,9 @@ setup_args(rb_iseq_t *iseq, LINK_ANCHOR *args, NODE *argn, unsigned long *flag)
break;
}
default: {
rb_bug("setup_arg: unknown node: %s\n", ruby_node_name(nd_type(argn)));
NODE *node = argn;
rb_compile_error(ERROR_ARGS "setup_arg: unknown node: %s\n",
ruby_node_name(nd_type(argn)));
}
}
}
@ -2537,14 +2548,12 @@ setup_args(rb_iseq_t *iseq, LINK_ANCHOR *args, NODE *argn, unsigned long *flag)
static int
iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
{
int type;
enum node_type type;
if (node == 0) {
if (!poped) {
debug_node_start("NODE_NIL(implicit)");
debug_node_end();
ADD_INSN(ret, 0, putnil);
return COMPILE_OK;
debugs("node: NODE_NIL(implicit)\n");
ADD_INSN(ret, iseq->compile_data->last_line, putnil);
}
return COMPILE_OK;
}
@ -2617,7 +2626,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
type = nd_type(node);
if (type != NODE_WHEN) {
COMPILE_ERROR(("NODE_CASE: unexpected node. must be NODE_WHEN, but %s", ruby_node_name(type)));
COMPILE_ERROR((ERROR_ARGS "NODE_CASE: unexpected node. must be NODE_WHEN, but %s", ruby_node_name(type)));
}
endlabel = NEW_LABEL(nd_line(node));
@ -2653,11 +2662,12 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
ADD_INSNL(cond_seq, nd_line(val), branchif, l1);
}
else {
rb_bug("NODE_CASAE: unknown node (%s)", ruby_node_name(nd_type(vals)));
rb_compile_error(ERROR_ARGS "NODE_CASAE: unknown node (%s)",
ruby_node_name(nd_type(vals)));
}
}
else {
rb_bug("NODE_CASAE: must be NODE_ARRAY, but 0\n");
rb_compile_error(ERROR_ARGS "NODE_CASAE: must be NODE_ARRAY, but 0");
}
node = node->nd_next;
@ -2741,7 +2751,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
ADD_INSNL(ret, nd_line(val), branchif, l1);
}
else {
rb_bug("err");
rb_compile_error(ERROR_ARGS "err");
}
node = node->nd_next;
}
@ -2801,7 +2811,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
if (node->nd_state == Qundef) {
/* ADD_INSN(ret, nd_line(node), putundef); */
rb_bug("unsupported: putundef");
rb_compile_error(ERROR_ARGS "unsupported: putundef");
}
else {
ADD_INSN(ret, nd_line(node), putnil);
@ -2881,7 +2891,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
INT2FIX(level | 0x02) /* TAG_BREAK */ );
}
else if (iseq->type == ISEQ_TYPE_EVAL) {
COMPILE_ERROR(("Can't escape from eval with break"));
COMPILE_ERROR((ERROR_ARGS "Can't escape from eval with break"));
}
else {
rb_iseq_t *ip = iseq->parent_iseq;
@ -2901,7 +2911,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
}
ip = ip->parent_iseq;
}
COMPILE_ERROR(("Illegal break"));
COMPILE_ERROR((ERROR_ARGS "Illegal break"));
}
break;
}
@ -2920,7 +2930,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
iseq->compile_data->end_label);
}
else if (iseq->type == ISEQ_TYPE_EVAL) {
COMPILE_ERROR(("Can't escape from eval with next"));
COMPILE_ERROR((ERROR_ARGS "Can't escape from eval with next"));
}
else {
rb_iseq_t *ip = iseq->parent_iseq;
@ -2942,7 +2952,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
INT2FIX(level | 0x03) /* TAG_NEXT */ );
}
else {
COMPILE_ERROR(("Illegal next"));
COMPILE_ERROR((ERROR_ARGS "Illegal next"));
}
}
break;
@ -2957,7 +2967,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
}
}
else if (iseq->type == ISEQ_TYPE_EVAL) {
COMPILE_ERROR(("Can't escape from eval with redo"));
COMPILE_ERROR((ERROR_ARGS "Can't escape from eval with redo"));
}
else if (iseq->compile_data->start_label) {
ADD_INSNL(ret, nd_line(node), jump,
@ -2974,7 +2984,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
break;
}
else if (ip->type == ISEQ_TYPE_EVAL) {
COMPILE_ERROR(("Can't escape from eval with redo"));
COMPILE_ERROR((ERROR_ARGS "Can't escape from eval with redo"));
}
else if (ip->compile_data->redo_label != 0) {
break;
@ -2987,7 +2997,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
INT2FIX(level | 0x05) /* TAG_REDO */ );
}
else {
COMPILE_ERROR(("Illegal redo"));
COMPILE_ERROR((ERROR_ARGS "Illegal redo"));
}
}
break;
@ -3000,7 +3010,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
INT2FIX(0x04) /* TAG_RETRY */ );
}
else {
COMPILE_ERROR(("Illegal retry"));
COMPILE_ERROR((ERROR_ARGS "Illegal retry"));
}
break;
}
@ -3158,7 +3168,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
case NODE_LASGN:{
ID id = node->nd_vid;
int idx = iseq->local_iseq->local_size - get_local_var_idx(iseq, id);
int idx = iseq->local_iseq->local_size - get_local_var_idx(iseq, id, node);
debugs("lvar: %s idx: %d\n", rb_id2name(id), idx);
COMPILE(ret, "rvalue", node->nd_value);
@ -3180,10 +3190,11 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
ADD_INSN(ret, nd_line(node), dup);
}
idx = get_dyna_var_idx(iseq, node->nd_vid, &lv, &ls);
idx = get_dyna_var_idx(iseq, node->nd_vid, &lv, &ls, node);
if (idx < 0) {
rb_bug("NODE_DASGN(_CURR): unknown id (%s)", rb_id2name(node->nd_vid));
rb_compile_error(ERROR_ARGS "NODE_DASGN(_CURR): unknown id (%s)",
rb_id2name(node->nd_vid));
}
ADD_INSN2(ret, nd_line(node), setdynamic,
@ -3492,7 +3503,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
}
}
else {
rb_bug("illegal goto/label format");
rb_compile_error(ERROR_ARGS "illegal goto/label format");
}
@ -3666,7 +3677,8 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
break;
default:
rb_bug("can't make hash with this node: %s", ruby_node_name(type));
rb_compile_error(ERROR_ARGS "can't make hash with this node: %s",
ruby_node_name(type));
}
ADD_INSN1(ret, nd_line(node), newhash, size);
@ -3681,7 +3693,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
while (is) {
if (is->type == ISEQ_TYPE_TOP || is->type == ISEQ_TYPE_CLASS) {
COMPILE_ERROR(("Illegal return"));
COMPILE_ERROR((ERROR_ARGS "Illegal return"));
break;
}
else {
@ -3712,7 +3724,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
unsigned long flag = 0;
if (iseq->type == ISEQ_TYPE_TOP || iseq->type == ISEQ_TYPE_CLASS) {
COMPILE_ERROR(("Illegal yield"));
COMPILE_ERROR((ERROR_ARGS "Illegal yield"));
}
if (node->nd_head) {
@ -3733,7 +3745,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
case NODE_LVAR:{
if (!poped) {
ID id = node->nd_vid;
int idx = iseq->local_iseq->local_size - get_local_var_idx(iseq, id);
int idx = iseq->local_iseq->local_size - get_local_var_idx(iseq, id, node);
debugs("id: %s idx: %d\n", rb_id2name(id), idx);
ADD_INSN1(ret, nd_line(node), getlocal, INT2FIX(idx));
@ -3744,9 +3756,9 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
int lv, idx, ls;
debugi("nd_vid", node->nd_vid);
if (!poped) {
idx = get_dyna_var_idx(iseq, node->nd_vid, &lv, &ls);
idx = get_dyna_var_idx(iseq, node->nd_vid, &lv, &ls, node);
if (idx < 0) {
rb_bug("unknown dvar (%s)", rb_id2name(node->nd_vid));
rb_compile_error(ERROR_ARGS "unknown dvar (%s)", rb_id2name(node->nd_vid));
}
ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(ls - idx),
INT2FIX(lv));
@ -4001,7 +4013,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
if (nd_type(node->u1.node) != NODE_LIT ||
nd_type(node->u2.node) != NODE_LIT) {
rb_bug("alias args must be NODE_LIT");
rb_compile_error(ERROR_ARGS "alias args must be NODE_LIT");
}
s1 = node->u1.node->nd_lit;
s2 = node->u2.node->nd_lit;
@ -4023,7 +4035,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
}
case NODE_UNDEF:{
if (nd_type(node->u2.node) != NODE_LIT) {
rb_bug("undef args must be NODE_LIT");
rb_compile_error(ERROR_ARGS "undef args must be NODE_LIT");
}
ADD_INSN1(ret, nd_line(node), undef,
ID2SYM(rb_to_id(node->u2.node->nd_lit)));
@ -4052,7 +4064,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
VALUE iseqval = NEW_CHILD_ISEQVAL(
node->nd_body,
rb_sprintf("<module:%s>", rb_id2name(node->nd_cpath->nd_mid)),
ISEQ_TYPE_CLASS);
ISEQ_TYPE_CLASS);
COMPILE(ret, "mbase", node->nd_cpath->nd_head);
ADD_INSN (ret, nd_line(node), putnil); /* dummy */
@ -4347,7 +4359,8 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
break;
}
default:
rb_bug("iseq_compile_each: unknown node: %s", ruby_node_name(type));
rb_compile_error(ERROR_ARGS "iseq_compile_each: unknown node: %s",
ruby_node_name(type));
return Qnil;
}
@ -4381,10 +4394,8 @@ static VALUE
insn_data_to_s_detail(INSN *iobj)
{
VALUE str = rb_str_new(0, 0);
char buff[0x100];
snprintf(buff, sizeof(buff), "%-16s", insn_name(iobj->insn_id));
rb_str_cat2(str, buff);
str = rb_sprintf("%-16s", insn_name(iobj->insn_id));
if (iobj->operands) {
char *types = insn_op_types(iobj->insn_id);
int j;
@ -4434,7 +4445,7 @@ insn_data_to_s_detail(INSN *iobj)
rb_str_cat2(str, "<ch>");
break;
default:{
rb_bug("unknown operand type: %c", type);
rb_raise(rb_eSyntaxError, "unknown operand type: %c", type);
}
}
if (types[j + 1]) {
@ -4479,8 +4490,7 @@ dump_disasm_list(struct iseq_link_element *link)
}
default:
/* ignore */
printf("%ld\n", FIX2LONG(link->type));
rb_bug("dump_disasm_list error");
rb_raise(rb_eSyntaxError, "dump_disasm_list error: %ld\n", FIX2LONG(link->type));
}
link = link->next;
}
@ -4536,7 +4546,8 @@ get_exception_sym2type(VALUE sym)
if (sym == symBreak) return CATCH_TYPE_BREAK;
if (sym == symRedo) return CATCH_TYPE_REDO;
if (sym == symNext) return CATCH_TYPE_NEXT;
rb_bug("get_exception_sym2type");
rb_raise(rb_eSyntaxError, "invalid exception symbol: %s",
RSTRING_PTR(rb_inspect(sym)));
return 0;
}
@ -4547,13 +4558,17 @@ iseq_build_exception(rb_iseq_t *iseq, struct st_table *labels_table,
int i;
for (i=0; i<RARRAY_LEN(exception); i++) {
VALUE v = rb_ary_entry(exception, i);
VALUE *ptr = RARRAY_PTR(v);
VALUE type = get_exception_sym2type(ptr[0]);
VALUE eiseqval;
VALUE v, type, *ptr, eiseqval;
LABEL *lstart, *lend, *lcont;
int sp;
RB_GC_GUARD(v) = rb_convert_type(RARRAY_PTR(exception)[i], T_ARRAY,
"Array", "to_ary");
if (RARRAY_LEN(v) != 6) {
rb_raise(rb_eSyntaxError, "wrong exception entry");
}
ptr = RARRAY_PTR(v);
type = get_exception_sym2type(ptr[0]);
if (ptr[1] == Qnil) {
eiseqval = 0;
}
@ -4607,14 +4622,17 @@ iseq_build_body(rb_iseq_t *iseq, LINK_ANCHOR *anchor,
VALUE insn_id;
VALUE insn;
insn = rb_ary_entry(obj, 0);
insn = (argc < 0) ? Qnil : RARRAY_PTR(obj)[0];
if (st_lookup(insn_table, insn, &insn_id) == 0) {
/* TODO: exception */
rb_raise(rb_eRuntimeError, "unknown instruction: %s", rb_inspect(insn));
RB_GC_GUARD(insn) = rb_inspect(insn);
rb_compile_error(RSTRING_PTR(iseq->filename), line_no,
"unknown instruction: %s", RSTRING_PTR(insn));
}
if (argc != insn_len(insn_id)-1) {
rb_raise(rb_eRuntimeError, "operand size mismatch");
rb_compile_error(RSTRING_PTR(iseq->filename), line_no,
"operand size mismatch");
}
if (argc > 0) {
@ -4623,9 +4641,9 @@ iseq_build_body(rb_iseq_t *iseq, LINK_ANCHOR *anchor,
VALUE op = rb_ary_entry(obj, j+1);
switch (insn_op_type(insn_id, j)) {
case TS_OFFSET: {
LABEL *label = register_label(iseq, labels_table, op);
argv[j] = (VALUE)label;
break;
LABEL *label = register_label(iseq, labels_table, op);
argv[j] = (VALUE)label;
break;
}
case TS_LINDEX:
case TS_DINDEX:
@ -4646,7 +4664,7 @@ iseq_build_body(rb_iseq_t *iseq, LINK_ANCHOR *anchor,
argv[j] = op;
}
else {
rb_raise(rb_eRuntimeError, "ISEQ is required");
rb_raise(rb_eSyntaxError, "ISEQ is required");
}
iseq_add_mark_object(iseq, argv[j]);
}
@ -4681,7 +4699,7 @@ iseq_build_body(rb_iseq_t *iseq, LINK_ANCHOR *anchor,
}
break;
default:
rb_bug("unknown operand: %c", insn_op_type(insn_id, j));
rb_raise(rb_eSyntaxError, "unknown operand: %c", insn_op_type(insn_id, j));
}
}
}
@ -4725,7 +4743,8 @@ iseq_build_from_ary(rb_iseq_t *iseq, VALUE locals, VALUE args,
iseq->local_size = opt + iseq->local_table_size;
for (i=0; i<RARRAY_LEN(locals); i++) {
tbl[i] = SYM2ID(CHECK_SYMBOL(RARRAY_PTR(locals)[i]));
VALUE lv = RARRAY_PTR(locals)[i];
tbl[i] = FIXNUM_P(lv) ? FIX2INT(lv) : SYM2ID(CHECK_SYMBOL(lv));
}
/* args */

Просмотреть файл

@ -37,6 +37,8 @@
#define CPDEBUG 2
#endif
NORETURN(PRINTF_ARGS(void rb_compile_bug(const char*, int, const char*, ...), 3, 4));
#if CPDEBUG > 0
#define debugp(header, value) \
@ -205,6 +207,8 @@ r_value(VALUE value)
break; \
}
#define ERROR_ARGS (node)->nd_file, nd_line(node),
#define COMPILE_OK 1
#define COMPILE_NG 0

74
error.c
Просмотреть файл

@ -24,10 +24,9 @@
#endif
extern const char ruby_version[], ruby_release_date[], ruby_platform[];
int ruby_nerrs;
static int
err_position_0(char *buf, long len, const char *file, long line)
err_position_0(char *buf, long len, const char *file, int line)
{
if (!file) {
return 0;
@ -46,12 +45,6 @@ err_position(char *buf, long len)
return err_position_0(buf, len, rb_sourcefile(), rb_sourceline());
}
static int
compile_position(char *buf, long len)
{
return err_position_0(buf, len, rb_sourcefile(), rb_sourceline());
}
static void
err_snprintf(char *buf, long len, const char *fmt, va_list args)
{
@ -64,11 +57,11 @@ err_snprintf(char *buf, long len, const char *fmt, va_list args)
}
static void
compile_snprintf(char *buf, long len, const char *fmt, va_list args)
compile_snprintf(char *buf, long len, const char *file, int line, const char *fmt, va_list args)
{
long n;
n = compile_position(buf, len);
n = err_position_0(buf, len, file, line);
if (len > n) {
vsnprintf((char*)buf+n, len-n, fmt, args);
}
@ -77,16 +70,15 @@ compile_snprintf(char *buf, long len, const char *fmt, va_list args)
static void err_append(const char*);
void
rb_compile_error(const char *fmt, ...)
rb_compile_error(const char *file, int line, const char *fmt, ...)
{
va_list args;
char buf[BUFSIZ];
va_start(args, fmt);
compile_snprintf(buf, BUFSIZ, fmt, args);
compile_snprintf(buf, BUFSIZ, file, line, fmt, args);
va_end(args);
err_append(buf);
ruby_nerrs++;
}
void
@ -102,19 +94,19 @@ rb_compile_error_append(const char *fmt, ...)
}
static void
compile_warn_print(const char *fmt, va_list args)
compile_warn_print(const char *file, int line, const char *fmt, va_list args)
{
char buf[BUFSIZ];
int len;
compile_snprintf(buf, BUFSIZ, fmt, args);
compile_snprintf(buf, BUFSIZ, file, line, fmt, args);
len = strlen(buf);
buf[len++] = '\n';
rb_write_error2(buf, len);
}
void
rb_compile_warn(const char *fmt, ...)
rb_compile_warn(const char *file, int line, const char *fmt, ...)
{
char buf[BUFSIZ];
va_list args;
@ -124,13 +116,13 @@ rb_compile_warn(const char *fmt, ...)
snprintf(buf, BUFSIZ, "warning: %s", fmt);
va_start(args, fmt);
compile_warn_print(buf, args);
compile_warn_print(file, line, buf, args);
va_end(args);
}
/* rb_compile_warning() reports only in verbose mode */
void
rb_compile_warning(const char *fmt, ...)
rb_compile_warning(const char *file, int line, const char *fmt, ...)
{
char buf[BUFSIZ];
va_list args;
@ -140,7 +132,7 @@ rb_compile_warning(const char *fmt, ...)
snprintf(buf, BUFSIZ, "warning: %s", fmt);
va_start(args, fmt);
compile_warn_print(buf, args);
compile_warn_print(file, line, buf, args);
va_end(args);
}
@ -207,24 +199,43 @@ rb_warn_m(VALUE self, VALUE mesg)
void yarv_bug(void);
void
rb_bug(const char *fmt, ...)
static void
report_bug(const char *file, int line, const char *fmt, va_list args)
{
char buf[BUFSIZ];
va_list args;
FILE *out = stderr;
int len = err_position(buf, BUFSIZ);
int len = err_position_0(buf, BUFSIZ, file, line);
if (fwrite(buf, 1, len, out) == len ||
fwrite(buf, 1, len, (out = stdout)) == len) {
yarv_bug();
fputs("[BUG] ", out);
va_start(args, fmt);
vfprintf(out, fmt, args);
va_end(args);
fprintf(out, "\nruby %s (%s) [%s]\n\n",
ruby_version, ruby_release_date, ruby_platform);
}
}
void
rb_bug(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
report_bug(rb_sourcefile(), rb_sourceline(), fmt, args);
va_end(args);
abort();
}
void
rb_compile_bug(const char *file, int line, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
report_bug(file, line, fmt, args);
va_end(args);
abort();
}
@ -1531,12 +1542,15 @@ static void
err_append(const char *s)
{
rb_thread_t *th = GET_THREAD();
VALUE err = th->errinfo;
if (th->parse_in_eval) {
if (NIL_P(th->errinfo)) {
th->errinfo = rb_exc_new2(rb_eSyntaxError, s);
if (!RTEST(err)) {
err = rb_exc_new2(rb_eSyntaxError, s);
th->errinfo = err;
}
else {
VALUE str = rb_obj_as_string(GET_THREAD()->errinfo);
VALUE str = rb_obj_as_string(err);
rb_str_cat2(str, "\n");
rb_str_cat2(str, s);
@ -1544,6 +1558,10 @@ err_append(const char *s)
}
}
else {
if (!RTEST(err)) {
err = rb_exc_new2(rb_eSyntaxError, "compile error");
th->errinfo = err;
}
rb_write_error(s);
rb_write_error("\n");
}

61
eval.c
Просмотреть файл

@ -32,7 +32,6 @@ VALUE rb_eSysStackError;
VALUE exception_error;
VALUE sysstack_error;
extern int ruby_nerrs;
extern VALUE ruby_top_self;
static VALUE eval(VALUE, VALUE, VALUE, const char *, int);
@ -108,21 +107,23 @@ ruby_init(void)
ruby_running = 1;
}
void
void *
ruby_options(int argc, char **argv)
{
int state;
void *tree = 0;
Init_stack((void *)&state);
PUSH_TAG();
if ((state = EXEC_TAG()) == 0) {
SAVE_ROOT_JMPBUF(GET_THREAD(), ruby_process_options(argc, argv));
SAVE_ROOT_JMPBUF(GET_THREAD(), tree = ruby_process_options(argc, argv));
}
else {
rb_clear_trace_func();
exit(error_handle(state));
}
POP_TAG();
return tree;
}
static void
@ -212,65 +213,47 @@ ruby_cleanup(int ex)
return ex;
}
extern NODE *ruby_eval_tree;
static int
ruby_exec_internal(void)
int
ruby_exec_node(void *n)
{
int state;
VALUE val;
NODE *node = n;
rb_thread_t *th = GET_THREAD();
if (!ruby_eval_tree) return 0;
if (!node) return 0;
PUSH_TAG();
if ((state = EXEC_TAG()) == 0) {
SAVE_ROOT_JMPBUF(th, {
th->base_block = 0;
val = yarvcore_eval_parsed(ruby_eval_tree, rb_str_new2(ruby_sourcefile));
val = yarvcore_eval_parsed(node, rb_str_new2(node->nd_file));
});
}
POP_TAG();
return state;
}
int
ruby_exec(void)
{
volatile NODE *tmp;
Init_stack((void *)&tmp);
return ruby_exec_internal();
}
void
ruby_stop(int ex)
{
exit(ruby_cleanup(ex));
}
void
ruby_run(void)
int
ruby_run_node(void *n)
{
int state;
static int ex;
if (ruby_nerrs > 0) {
exit(EXIT_FAILURE);
if (!n) {
return EXIT_FAILURE;
}
state = ruby_exec();
if (state && !ex) {
ex = state;
}
ruby_stop(ex);
Init_stack((void *)&n);
return ruby_cleanup(ruby_exec_node(n));
}
VALUE
rb_eval_string(const char *str)
{
return eval(ruby_top_self, rb_str_new2(str), Qnil, "(eval)", 0);
return eval(ruby_top_self, rb_str_new2(str), Qnil, "(eval)", 1);
}
VALUE
@ -662,6 +645,8 @@ rb_longjmp(int tag, VALUE mesg)
{
VALUE at;
rb_thread_t *th = GET_THREAD();
const char *file;
int line = 0;
if (thread_set_raised(th)) {
th->errinfo = exception_error;
@ -674,7 +659,9 @@ rb_longjmp(int tag, VALUE mesg)
mesg = rb_exc_new(rb_eRuntimeError, 0, 0);
}
if (ruby_sourcefile && !NIL_P(mesg)) {
file = rb_sourcefile();
if (file) line = rb_sourceline();
if (file && !NIL_P(mesg)) {
at = get_backtrace(mesg);
if (NIL_P(at)) {
at = make_backtrace();
@ -695,7 +682,7 @@ rb_longjmp(int tag, VALUE mesg)
e = rb_obj_as_string(e);
warn_printf("Exception `%s' at %s:%d - %s\n",
rb_obj_classname(GET_THREAD()->errinfo),
rb_sourcefile(), rb_sourceline(), RSTRING_PTR(e));
file, line, RSTRING_PTR(e));
}
POP_TAG();
if (status == TAG_FATAL && GET_THREAD()->errinfo == exception_error) {
@ -1105,7 +1092,7 @@ rb_rescue2(VALUE (*b_proc) (ANYARGS), VALUE data1, VALUE (*r_proc) (ANYARGS),
VALUE eclass;
va_init_list(args, data2);
while (eclass = va_arg(args, VALUE)) {
while ((eclass = va_arg(args, VALUE)) != 0) {
if (rb_obj_is_kind_of(th->errinfo, eclass)) {
handle = Qtrue;
break;
@ -2662,8 +2649,6 @@ Init_eval(void)
__send = rb_intern("__send");
__send_bang = rb_intern("__send!");
rb_global_variable((VALUE *)&ruby_eval_tree);
rb_define_virtual_variable("$@", errat_getter, errat_setter);
rb_define_virtual_variable("$!", errinfo_getter, errinfo_setter);

Просмотреть файл

@ -130,33 +130,6 @@ VALUE rb_load_path;
NORETURN(static void load_failed _((VALUE)));
RUBY_EXTERN NODE *ruby_eval_tree;
static VALUE
rb_load_internal(char *file)
{
NODE *node;
VALUE iseq;
rb_thread_t *th = GET_THREAD();
{
th->parse_in_eval++;
node = (NODE *)rb_load_file(file);
th->parse_in_eval--;
node = ruby_eval_tree;
}
if (ruby_nerrs > 0) {
return 0;
}
iseq = rb_iseq_new(node, rb_str_new2("<top (required)>"),
rb_str_new2(file), Qfalse, ISEQ_TYPE_TOP);
rb_thread_eval(GET_THREAD(), iseq);
return 0;
}
void
rb_load(VALUE fname, int wrap)
{
@ -165,6 +138,8 @@ rb_load(VALUE fname, int wrap)
rb_thread_t *th = GET_THREAD();
VALUE wrapper = th->top_wrapper;
VALUE self = th->top_self;
volatile int parse_in_eval;
volatile int loaded = Qfalse;
FilePathValue(fname);
fname = rb_str_new4(fname);
@ -172,7 +147,7 @@ rb_load(VALUE fname, int wrap)
if (!tmp) {
load_failed(fname);
}
fname = tmp;
RB_GC_GUARD(fname) = rb_str_new4(tmp);
th->errinfo = Qnil; /* ensure */
@ -187,18 +162,28 @@ rb_load(VALUE fname, int wrap)
rb_extend_object(th->top_self, th->top_wrapper);
}
parse_in_eval = th->parse_in_eval;
PUSH_TAG();
state = EXEC_TAG();
if (state == 0) {
rb_load_internal(RSTRING_PTR(fname));
NODE *node;
VALUE iseq;
th->parse_in_eval++;
node = (NODE *)rb_load_file(RSTRING_PTR(fname));
th->parse_in_eval--;
loaded = Qtrue;
iseq = rb_iseq_new(node, rb_str_new2("<top (required)>"),
fname, Qfalse, ISEQ_TYPE_TOP);
rb_thread_eval(th, iseq);
}
POP_TAG();
th->parse_in_eval = parse_in_eval;
th->top_self = self;
th->top_wrapper = wrapper;
if (ruby_nerrs > 0) {
ruby_nerrs = 0;
if (!loaded) {
rb_exc_raise(GET_THREAD()->errinfo);
}
if (state) {
@ -318,7 +303,7 @@ rb_f_require(VALUE obj, VALUE fname)
}
static int
search_required(VALUE fname, VALUE *path)
search_required(VALUE fname, volatile VALUE *path)
{
VALUE tmp;
char *ext, *ftptr;
@ -330,7 +315,7 @@ search_required(VALUE fname, VALUE *path)
if (strcmp(".rb", ext) == 0) {
if (rb_feature_p(ftptr, ext, Qtrue))
return 'r';
if (tmp = rb_find_file(fname)) {
if ((tmp = rb_find_file(fname)) != 0) {
tmp = rb_file_expand_path(tmp, Qnil);
ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
if (!rb_feature_p(ftptr, ext, Qtrue))
@ -355,7 +340,7 @@ search_required(VALUE fname, VALUE *path)
#else
rb_str_cat2(tmp, DLEXT);
OBJ_FREEZE(tmp);
if (tmp = rb_find_file(tmp)) {
if ((tmp = rb_find_file(tmp)) != 0) {
tmp = rb_file_expand_path(tmp, Qnil);
ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
if (!rb_feature_p(ftptr, ext, Qfalse))
@ -367,7 +352,7 @@ search_required(VALUE fname, VALUE *path)
else if (IS_DLEXT(ext)) {
if (rb_feature_p(ftptr, ext, Qfalse))
return 's';
if (tmp = rb_find_file(fname)) {
if ((tmp = rb_find_file(fname)) != 0) {
tmp = rb_file_expand_path(tmp, Qnil);
ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
if (!rb_feature_p(ftptr, ext, Qfalse))
@ -450,8 +435,6 @@ rb_require_safe(VALUE fname, int safe)
break;
case 's':
ruby_sourcefile = rb_source_filename(RSTRING_PTR(path));
ruby_sourceline = 0;
handle = (long)rb_vm_call_cfunc(ruby_top_self, load_ext,
path, 0, path);
rb_ary_push(ruby_dln_librefs, LONG2NUM(handle));
@ -498,11 +481,9 @@ init_ext_call(VALUE arg)
void
ruby_init_ext(const char *name, void (*init)(void))
{
ruby_sourcefile = rb_source_filename(name);
ruby_sourceline = 0;
if (load_lock(name)) {
rb_vm_call_cfunc(ruby_top_self, init_ext_call, (VALUE)init, 0, rb_str_new2(name));
rb_vm_call_cfunc(ruby_top_self, init_ext_call, (VALUE)init,
0, rb_str_new2(name));
rb_provide(name);
load_unlock(name);
}

26
gc.c
Просмотреть файл

@ -529,6 +529,21 @@ rb_newobj(void)
#endif
}
NODE*
rb_node_newnode(enum node_type type, VALUE a0, VALUE a1, VALUE a2)
{
NODE *n = (NODE*)rb_newobj();
n->flags |= T_NODE;
nd_set_type(n, type);
n->u1.value = a0;
n->u2.value = a1;
n->u3.value = a2;
return n;
}
VALUE
rb_data_object_alloc(VALUE klass, void *datap, RUBY_DATA_FUNC dmark, RUBY_DATA_FUNC dfree)
{
@ -634,8 +649,8 @@ rb_source_filename(const char *f)
return (char *)name + 1;
}
static void
mark_source_filename(char *f)
void
rb_mark_source_filename(char *f)
{
if (f) {
f[-1] = 1;
@ -843,7 +858,7 @@ gc_mark_children(VALUE ptr, int lev)
break;
case T_NODE:
mark_source_filename(obj->as.node.nd_file);
rb_mark_source_filename(obj->as.node.nd_file);
switch (nd_type(obj)) {
case NODE_IF: /* 1,2,3 */
case NODE_FOR:
@ -1119,7 +1134,6 @@ gc_sweep(void)
if (free_min < FREE_MIN)
free_min = FREE_MIN;
mark_source_filename(ruby_sourcefile);
if (source_filenames) {
st_foreach(source_filenames, sweep_source_filename, 0);
}
@ -1426,8 +1440,8 @@ garbage_collect(void)
rb_gc_mark_parser();
/* gc_mark objects whose marking are not completed*/
while (!MARK_STACK_EMPTY){
if (mark_stack_overflow){
while (!MARK_STACK_EMPTY) {
if (mark_stack_overflow) {
gc_mark_all();
}
else {

Просмотреть файл

@ -160,14 +160,13 @@ VALUE rb_enumeratorize(VALUE, VALUE, int, VALUE *);
argc, argv); \
} while (0)
/* error.c */
RUBY_EXTERN int ruby_nerrs;
VALUE rb_exc_new(VALUE, const char*, long);
VALUE rb_exc_new2(VALUE, const char*);
VALUE rb_exc_new3(VALUE, VALUE);
PRINTF_ARGS(NORETURN(void rb_loaderror(const char*, ...)), 1, 2);
PRINTF_ARGS(NORETURN(void rb_name_error(ID, const char*, ...)), 2, 3);
NORETURN(void rb_invalid_str(const char*, const char*));
PRINTF_ARGS(void rb_compile_error(const char*, ...), 1, 2);
PRINTF_ARGS(void rb_compile_error(const char*, int, const char*, ...), 3, 4);
PRINTF_ARGS(void rb_compile_error_append(const char*, ...), 1, 2);
NORETURN(void rb_load_fail(const char*));
NORETURN(void rb_error_frozen(const char*));
@ -454,7 +453,7 @@ VALUE rb_reg_match_pre(VALUE);
VALUE rb_reg_match_post(VALUE);
VALUE rb_reg_match_last(VALUE);
VALUE rb_reg_new(const char*, long, int);
VALUE rb_reg_compile(const char*, long, int);
VALUE rb_reg_compile(const char*, long, int, const char*, int);
VALUE rb_reg_match(VALUE, VALUE);
VALUE rb_reg_match2(VALUE);
int rb_reg_options(VALUE);
@ -467,8 +466,7 @@ void *rb_load_file(const char*);
void ruby_script(const char*);
void ruby_prog_init(void);
void ruby_set_argv(int, char**);
void ruby_process_options(int, char**);
void ruby_load_script(void);
void *ruby_process_options(int, char**);
void ruby_init_loadpath(void);
void ruby_incpush(const char*);
/* signal.c */

Просмотреть файл

@ -299,6 +299,8 @@ enum ruby_value_type {
#define TYPE(x) rb_type((VALUE)(x))
#define RB_GC_GUARD(v) (*(volatile VALUE *)&(v))
void rb_check_type(VALUE,int);
#define Check_Type(v,t) rb_check_type((VALUE)(v),t)
@ -701,11 +703,11 @@ NORETURN(void rb_notimplement(void));
/* reports if `-w' specified */
PRINTF_ARGS(void rb_warning(const char*, ...), 1, 2);
PRINTF_ARGS(void rb_compile_warning(const char*, ...), 1, 2);
PRINTF_ARGS(void rb_compile_warning(const char *, int, const char*, ...), 3, 4);
PRINTF_ARGS(void rb_sys_warning(const char*, ...), 1, 2);
/* reports always */
PRINTF_ARGS(void rb_warn(const char*, ...), 1, 2);
PRINTF_ARGS(void rb_compile_warn(const char*, ...), 1, 2);
PRINTF_ARGS(void rb_compile_warn(const char *, int, const char*, ...), 3, 4);
VALUE rb_each(VALUE);
VALUE rb_yield(VALUE);
@ -735,7 +737,8 @@ void ruby_init_stack(VALUE*);
ruby_init_stack(&variable_in_this_stack_frame);
#endif
void ruby_init(void);
void ruby_options(int, char**);
void *ruby_options(int, char**);
int ruby_run_node(void *);
NORETURN(void ruby_run(void));
RUBY_EXTERN VALUE rb_mKernel;

24
iseq.c
Просмотреть файл

@ -192,13 +192,13 @@ static VALUE
cleanup_iseq_build(rb_iseq_t *iseq)
{
struct iseq_compile_data *data = iseq->compile_data;
VALUE err = data->err_info;
iseq->compile_data = 0;
compile_data_free(data);
if (ruby_nerrs > 0) {
VALUE str = rb_str_buf_new2("compile error");
ruby_nerrs = 0;
rb_exc_raise(rb_exc_new3(rb_eSyntaxError, str));
if (RTEST(err)) {
rb_funcall2(err, rb_intern("set_backtrace"), 1, &iseq->filename);
rb_exc_raise(err);
}
return Qtrue;
}
@ -375,7 +375,11 @@ iseq_load(VALUE self, VALUE data, VALUE parent, VALUE opt)
}
if (st_lookup(type_map, type, &iseq_type) == 0) {
rb_raise(rb_eTypeError, "unsupport type: %p", type);
const char *typename = rb_id2name(type);
if (typename)
rb_raise(rb_eTypeError, "unsupport type: :%s", typename);
else
rb_raise(rb_eTypeError, "unsupport type: %p", (void *)type);
}
if (parent == Qnil) {
@ -404,11 +408,11 @@ iseq_s_load(int argc, VALUE *argv, VALUE self)
static NODE *
compile_string(VALUE str, VALUE file, VALUE line)
{
NODE *node;
node = rb_compile_string(StringValueCStr(file), str, NUM2INT(line));
VALUE parser = rb_parser_new();
NODE *node = rb_parser_compile_string(parser, StringValueCStr(file),
str, NUM2INT(line));
if (ruby_nerrs > 0) {
ruby_nerrs = 0;
if (!node) {
rb_exc_raise(GET_THREAD()->errinfo); /* TODO: check err */
}
return node;
@ -822,7 +826,7 @@ ruby_iseq_disasm(VALUE self)
return str;
}
char *
const char *
ruby_node_name(int node)
{
switch (node) {

4
main.c
Просмотреть файл

@ -43,8 +43,6 @@ main(int argc, char **argv, char **envp)
{
RUBY_INIT_STACK;
ruby_init();
ruby_options(argc, argv);
ruby_run();
return ruby_run_node(ruby_options(argc, argv));
}
return 0;
}

260
parse.y
Просмотреть файл

@ -58,11 +58,6 @@
((id)&ID_SCOPE_MASK) == ID_INSTANCE || \
((id)&ID_SCOPE_MASK) == ID_CLASS))
#ifndef RIPPER
char *ruby_sourcefile; /* current source file */
int ruby_sourceline; /* current line no. */
#endif
enum lex_state_e {
EXPR_BEG, /* ignore newline, +/- is a sign. */
EXPR_END, /* newline significant, +/- is a operator. */
@ -238,15 +233,17 @@ struct parser_params {
int parser_ruby__end__seen;
int line_count;
int has_shebang;
int parser_ruby_sourceline; /* current line no. */
#ifndef RIPPER
/* Ruby core only */
char *parser_ruby_sourcefile; /* current source file */
NODE *parser_eval_tree_begin;
NODE *parser_eval_tree;
VALUE debug_lines;
int nerr;
#else
/* Ripper only */
int parser_ruby_sourceline;
VALUE parser_ruby_sourcefile;
const char *tokp;
VALUE delayed;
@ -302,9 +299,9 @@ static int parser_yyerror(struct parser_params*, const char*);
#define lex_gets (parser->parser_lex_gets)
#define lvtbl (parser->parser_lvtbl)
#define ruby__end__seen (parser->parser_ruby__end__seen)
#ifdef RIPPER
#define ruby_sourceline (parser->parser_ruby_sourceline)
#define ruby_sourcefile (parser->parser_ruby_sourcefile)
#ifdef RIPPER
#else
#define ruby_debug_lines (parser->debug_lines)
#endif
@ -315,6 +312,9 @@ static int yylex(void*, void*);
#define yyparse ruby_yyparse
#define yydebug ruby_yydebug
static NODE* node_newnode(struct parser_params *, enum node_type, VALUE, VALUE, VALUE);
#define rb_node_newnode(type, a1, a2, a3) node_newnode(parser, type, a1, a2, a3)
static NODE *cond_gen(struct parser_params*,NODE*);
#define cond(node) cond_gen(parser, node)
static NODE *logop_gen(struct parser_params*,enum node_type,NODE*,NODE*);
@ -332,17 +332,27 @@ static NODE *remove_begin(NODE*);
#define void_expr(node) void_expr_gen(parser, (node) = remove_begin(node))
static void void_stmts_gen(struct parser_params*,NODE*);
#define void_stmts(node) void_stmts_gen(parser, node)
static void reduce_nodes(NODE**);
static void block_dup_check(NODE*,NODE*);
static void reduce_nodes_gen(struct parser_params*,NODE**);
#define reduce_nodes(n) reduce_nodes_gen(parser,n)
static void block_dup_check_gen(struct parser_params*,NODE*,NODE*);
#define block_dup_check(n1,n2) block_dup_check_gen(parser,n1,n2)
static NODE *block_append(NODE*,NODE*);
static NODE *list_append(NODE*,NODE*);
static NODE *list_concat(NODE*,NODE*);
static NODE *arg_append(NODE*,NODE*);
static NODE *arg_concat(NODE*,NODE*);
static NODE *literal_concat(NODE*,NODE*);
static NODE *new_evstr(NODE*);
static NODE *evstr2dstr(NODE*);
static NODE *block_append_gen(struct parser_params*,NODE*,NODE*);
#define block_append(h,t) block_append_gen(parser,h,t)
static NODE *list_append_gen(struct parser_params*,NODE*,NODE*);
#define list_append(l,i) list_append_gen(parser,l,i)
static NODE *list_concat_gen(struct parser_params*,NODE*,NODE*);
#define list_concat(h,t) list_concat_gen(parser,h,t)
static NODE *arg_append_gen(struct parser_params*,NODE*,NODE*);
#define arg_append(h,t) arg_append_gen(parser,h,t)
static NODE *arg_concat_gen(struct parser_params*,NODE*,NODE*);
#define arg_concat(h,t) arg_concat_gen(parser,h,t)
static NODE *literal_concat_gen(struct parser_params*,NODE*,NODE*);
#define literal_concat(h,t) literal_concat_gen(parser,h,t)
static NODE *new_evstr_gen(struct parser_params*,NODE*);
#define new_evstr(n) new_evstr_gen(parser,n)
static NODE *evstr2dstr_gen(struct parser_params*,NODE*);
#define evstr2dstr(n) evstr2dstr_gen(parser,n)
static NODE *call_op_gen(struct parser_params*,NODE*,ID,int,NODE*);
#define call_op(recv,id,narg,arg1) call_op_gen(parser, recv,id,narg,arg1)
@ -353,9 +363,11 @@ static void shadowing_lvar_gen(struct parser_params*,ID);
#define shadowing_lvar(name) shadowing_lvar_gen(parser, name)
static NODE *negate_lit(NODE*);
static NODE *ret_args(NODE*);
static NODE *ret_args_gen(struct parser_params*,NODE*);
#define ret_args(node) ret_args_gen(parser, node)
static NODE *arg_blk_pass(NODE*,NODE*);
static NODE *new_yield(NODE*);
static NODE *new_yield_gen(struct parser_params*,NODE*);
#define new_yield(node) new_yield_gen(parser, node)
static NODE *gettable_gen(struct parser_params*,ID);
#define gettable(id) gettable_gen(parser,id)
@ -368,7 +380,8 @@ static NODE *aryset_gen(struct parser_params*,NODE*,NODE*);
static NODE *attrset_gen(struct parser_params*,NODE*,ID);
#define attrset(node,id) attrset_gen(parser, node, id)
static void rb_backref_error(NODE*);
static void rb_backref_error_gen(struct parser_params*,NODE*);
#define rb_backref_error(n) rb_backref_error_gen(parser,n)
static NODE *node_assign_gen(struct parser_params*,NODE*,NODE*);
#define node_assign(node1, node2) node_assign_gen(parser, node1, node2)
@ -492,11 +505,11 @@ static VALUE ripper_id2sym(ID);
#endif
#ifndef RIPPER
# define rb_warn0(fmt) rb_compile_warn(fmt)
# define rb_warnI(fmt,a) rb_compile_warn(fmt,a)
# define rb_warnS(fmt,a) rb_compile_warn(fmt,a)
# define rb_warning0(fmt) rb_compile_warning(fmt)
# define rb_warningS(fmt,a) rb_compile_warning(fmt,a)
# define rb_warn0(fmt) rb_compile_warn(ruby_sourcefile, ruby_sourceline, fmt)
# define rb_warnI(fmt,a) rb_compile_warn(ruby_sourcefile, ruby_sourceline, fmt, a)
# define rb_warnS(fmt,a) rb_compile_warn(ruby_sourcefile, ruby_sourceline, fmt, a)
# define rb_warning0(fmt) rb_compile_warning(ruby_sourcefile, ruby_sourceline, fmt)
# define rb_warningS(fmt,a) rb_compile_warning(ruby_sourcefile, ruby_sourceline, fmt, a)
#else
# define rb_warn0(fmt) ripper_warn0(parser, fmt)
# define rb_warnI(fmt,a) ripper_warnI(parser, fmt, a)
@ -516,8 +529,8 @@ static void ripper_compile_error(struct parser_params*, const char *fmt, ...);
# define compile_error ripper_compile_error
# define PARSER_ARG parser,
#else
# define compile_error rb_compile_error
# define PARSER_ARG
# define compile_error parser->nerr++,rb_compile_error
# define PARSER_ARG ruby_sourcefile, ruby_sourceline,
#endif
#ifdef RIPPER
@ -772,7 +785,7 @@ compstmt : stmts opt_terms
stmts : none
{
/*%%%*/
$$ = NEW_NIL();
$$ = NEW_BEGIN(0);
/*%
$$ = dispatch2(stmts_add, dispatch0(stmts_new),
dispatch0(void_stmt));
@ -3603,7 +3616,8 @@ regexp : tREGEXP_BEG xstring_contents tREGEXP_END
int options = $3;
NODE *node = $2;
if (!node) {
node = NEW_LIT(rb_reg_compile("", 0, options & ~RE_OPTION_ONCE));
node = NEW_LIT(rb_reg_compile("", 0, options & ~RE_OPTION_ONCE,
ruby_sourcefile, ruby_sourceline));
}
else switch (nd_type(node)) {
case NODE_STR:
@ -3612,7 +3626,8 @@ regexp : tREGEXP_BEG xstring_contents tREGEXP_END
nd_set_type(node, NODE_LIT);
node->nd_lit = rb_reg_compile(RSTRING_PTR(src),
RSTRING_LEN(src),
options & ~RE_OPTION_ONCE);
options & ~RE_OPTION_ONCE,
ruby_sourcefile, ruby_sourceline);
}
break;
default:
@ -4295,7 +4310,7 @@ singleton : var_ref
{
/*%%%*/
$$ = $1;
value_expr($$);
value_expr($1);
/*%
$$ = $1;
%*/
@ -4542,7 +4557,7 @@ parser_yyerror(struct parser_params *parser, const char *msg)
char *buf;
int len, i;
rb_compile_error("%s", msg);
compile_error(PARSER_ARG "%s", msg);
p = lex_p;
while (lex_pbeg <= p) {
if (*p == '\n') break;
@ -4609,6 +4624,7 @@ yycompile(struct parser_params *parser, const char *f, int line)
{
int n;
const char *kcode_save;
NODE *tree;
if (!compile_for_eval && rb_safe_level() == 0) {
ruby_debug_lines = ruby_suppress_tracing(debug_lines, (VALUE)f);
@ -4631,14 +4647,17 @@ yycompile(struct parser_params *parser, const char *f, int line)
rb_set_kcode(kcode_save);
lex_strterm = 0;
if (parser->nerr) {
return 0;
}
tree = ruby_eval_tree;
if (!tree) {
tree = NEW_NIL();
}
if (ruby_eval_tree_begin) {
NODE *scope = ruby_eval_tree;
scope->nd_body = NEW_PRELUDE(ruby_eval_tree_begin, scope->nd_body);
return scope;
}
else {
return ruby_eval_tree;
tree->nd_body = NEW_PRELUDE(ruby_eval_tree_begin, tree->nd_body);
}
return tree;
}
#endif /* !RIPPER */
@ -5058,7 +5077,7 @@ parser_regx_options(struct parser_params *parser)
if (toklen()) {
tokfix();
compile_error(PARSER_ARG "unknown regexp option%s - %s",
toklen() > 1 ? "s" : "", tok());
toklen() > 1 ? "s" : "", tok());
}
return options | kcode;
}
@ -5163,7 +5182,7 @@ parser_tokadd_string(struct parser_params *parser,
}
if (!c && (func & STR_FUNC_SYMBOL)) {
func &= ~STR_FUNC_SYMBOL;
rb_compile_error(PARSER_ARG "symbol cannot contain '\\0'");
compile_error(PARSER_ARG "symbol cannot contain '\\0'");
continue;
}
tokadd(c);
@ -5171,20 +5190,8 @@ parser_tokadd_string(struct parser_params *parser,
return c;
}
#define NEW_STRTERM0(func, term, paren) \
#define NEW_STRTERM(func, term, paren) \
rb_node_newnode(NODE_STRTERM, (func), (term) | ((paren) << (CHAR_BIT * 2)), 0)
#ifndef RIPPER
# define NEW_STRTERM(func, term, paren) NEW_STRTERM0(func, term, paren)
#else
# define NEW_STRTERM(func, term, paren) ripper_new_strterm(parser, func, term, paren)
static NODE *
ripper_new_strterm(struct parser_params *parser, VALUE func, VALUE term, VALUE paren)
{
NODE *node = NEW_STRTERM0(func, term, paren);
nd_set_line(node, ruby_sourceline);
return node;
}
#endif
static int
parser_parse_string(struct parser_params *parser, NODE *quote)
@ -5229,12 +5236,12 @@ parser_parse_string(struct parser_params *parser, NODE *quote)
if (tokadd_string(func, term, paren, &quote->nd_nest) == -1) {
if (func & STR_FUNC_REGEXP) {
ruby_sourceline = nd_line(quote);
rb_compile_error(PARSER_ARG "unterminated regexp meets end of file");
compile_error(PARSER_ARG "unterminated regexp meets end of file");
return tREGEXP_END;
}
else {
ruby_sourceline = nd_line(quote);
rb_compile_error(PARSER_ARG "unterminated string meets end of file");
compile_error(PARSER_ARG "unterminated string meets end of file");
return tSTRING_END;
}
}
@ -5271,7 +5278,7 @@ parser_heredoc_identifier(struct parser_params *parser)
do {tokadd(c);} while (--len > 0 && (c = nextc()) != -1);
}
if (c == -1) {
rb_compile_error(PARSER_ARG "unterminated here document identifier");
compile_error(PARSER_ARG "unterminated here document identifier");
return 0;
}
break;
@ -5370,7 +5377,7 @@ parser_here_document(struct parser_params *parser, NODE *here)
if ((c = nextc()) == -1) {
error:
rb_compile_error(PARSER_ARG "can't find string \"%s\" anywhere before EOF", eos);
compile_error(PARSER_ARG "can't find string \"%s\" anywhere before EOF", eos);
heredoc_restore(lex_strterm);
lex_strterm = 0;
return 0;
@ -5442,18 +5449,18 @@ parser_here_document(struct parser_params *parser, NODE *here)
#ifndef RIPPER
static void
arg_ambiguous(void)
arg_ambiguous_gen(struct parser_params *parser)
{
rb_warning0("ambiguous first argument; put parentheses or even spaces");
}
#else
static void
ripper_arg_ambiguous(struct parser_params *parser)
arg_ambiguous_gen(struct parser_params *parser)
{
dispatch0(arg_ambiguous);
}
#define arg_ambiguous() ripper_arg_ambiguous(parser)
#endif
#define arg_ambiguous() arg_ambiguous_gen(parser)
static int
lvar_defined_gen(struct parser_params *parser, ID id)
@ -5791,7 +5798,7 @@ parser_yylex(struct parser_params *parser)
#endif
c = nextc();
if (c == -1) {
rb_compile_error(PARSER_ARG "embedded document meets end of file");
compile_error(PARSER_ARG "embedded document meets end of file");
return 0;
}
if (c != '=') continue;
@ -5919,7 +5926,7 @@ parser_yylex(struct parser_params *parser)
}
c = nextc();
if (c == -1) {
rb_compile_error(PARSER_ARG "incomplete character syntax");
compile_error(PARSER_ARG "incomplete character syntax");
return 0;
}
uc = (unsigned char)c;
@ -6539,7 +6546,7 @@ parser_yylex(struct parser_params *parser)
}
}
if (c == -1 || term == -1) {
rb_compile_error(PARSER_ARG "unterminated quoted string meets end of file");
compile_error(PARSER_ARG "unterminated quoted string meets end of file");
return 0;
}
paren = term;
@ -6659,7 +6666,7 @@ parser_yylex(struct parser_params *parser)
tokfix();
set_yylval_id(rb_intern(tok()));
if (!is_global_id(yylval_id())) {
rb_compile_error(PARSER_ARG "invalid global variable `%s'", rb_id2name(yylval.id));
compile_error(PARSER_ARG "invalid global variable `%s'", rb_id2name(yylval.id));
return 0;
}
return tGVAR;
@ -6711,10 +6718,10 @@ parser_yylex(struct parser_params *parser)
}
if (ISDIGIT(c)) {
if (tokidx == 1) {
rb_compile_error(PARSER_ARG "`@%c' is not allowed as an instance variable name", c);
compile_error(PARSER_ARG "`@%c' is not allowed as an instance variable name", c);
}
else {
rb_compile_error(PARSER_ARG "`@@%c' is not allowed as a class variable name", c);
compile_error(PARSER_ARG "`@@%c' is not allowed as a class variable name", c);
}
return 0;
}
@ -6743,7 +6750,7 @@ parser_yylex(struct parser_params *parser)
default:
uc = (unsigned char)c;
if (!is_identchar(uc)) {
rb_compile_error(PARSER_ARG "Invalid char `\\%03o' in expression", c);
compile_error(PARSER_ARG "Invalid char `\\%03o' in expression", c);
goto retry;
}
@ -6914,20 +6921,12 @@ yylex(void *p)
}
#ifndef RIPPER
NODE*
rb_node_newnode(enum node_type type, VALUE a0, VALUE a1, VALUE a2)
static NODE*
node_newnode(struct parser_params *parser, enum node_type type, VALUE a0, VALUE a1, VALUE a2)
{
NODE *n = (NODE*)rb_newobj();
n->flags |= T_NODE;
nd_set_type(n, type);
NODE *n = (rb_node_newnode)(type, a0, a1, a2);
nd_set_line(n, ruby_sourceline);
n->nd_file = ruby_sourcefile;
n->u1.value = a0;
n->u2.value = a1;
n->u3.value = a2;
return n;
}
@ -6965,23 +6964,17 @@ fixpos(NODE *node, NODE *orig)
static void
parser_warning(NODE *node, const char *mesg)
{
int line = ruby_sourceline;
ruby_sourceline = nd_line(node);
rb_warningS("%s", mesg);
ruby_sourceline = line;
rb_compile_warning(node->nd_file, nd_line(node), "%s", mesg);
}
static void
parser_warn(NODE *node, const char *mesg)
{
int line = ruby_sourceline;
ruby_sourceline = nd_line(node);
rb_warnS("%s", mesg);
ruby_sourceline = line;
rb_compile_warn(node->nd_file, nd_line(node), "%s", mesg);
}
static NODE*
block_append(NODE *head, NODE *tail)
block_append_gen(struct parser_params *parser, NODE *head, NODE *tail)
{
NODE *end, *h = head, *nd;
@ -7035,7 +7028,7 @@ block_append(NODE *head, NODE *tail)
/* append item to the list */
static NODE*
list_append(NODE *list, NODE *item)
list_append_gen(struct parser_params *parser, NODE *list, NODE *item)
{
NODE *last;
@ -7055,7 +7048,7 @@ list_append(NODE *list, NODE *item)
/* concat two lists */
static NODE*
list_concat(NODE *head, NODE *tail)
list_concat_gen(struct parser_params *parser, NODE *head, NODE *tail)
{
NODE *last;
@ -7080,7 +7073,7 @@ list_concat(NODE *head, NODE *tail)
/* concat two string literals */
static NODE *
literal_concat(NODE *head, NODE *tail)
literal_concat_gen(struct parser_params *parser, NODE *head, NODE *tail)
{
enum node_type htype;
@ -7129,7 +7122,7 @@ literal_concat(NODE *head, NODE *tail)
}
static NODE *
evstr2dstr(NODE *node)
evstr2dstr_gen(struct parser_params *parser, NODE *node)
{
if (nd_type(node) == NODE_EVSTR) {
node = list_append(NEW_DSTR(rb_str_new(0, 0)), node);
@ -7138,7 +7131,7 @@ evstr2dstr(NODE *node)
}
static NODE *
new_evstr(NODE *node)
new_evstr_gen(struct parser_params *parser, NODE *node)
{
NODE *head = node;
@ -7238,7 +7231,7 @@ gettable_gen(struct parser_params *parser, ID id)
else if (is_class_id(id)) {
return NEW_CVAR(id);
}
rb_compile_error("identifier %s is not valid", rb_id2name(id));
compile_error(PARSER_ARG "identifier %s is not valid to get", rb_id2name(id));
return 0;
}
@ -7301,9 +7294,7 @@ assignable_gen(struct parser_params *parser, ID id, NODE *val)
else if (is_class_id(id)) {
return NEW_CVASGN(id, val);
}
else {
rb_compile_error("identifier %s is not valid", rb_id2name(id));
}
compile_error(PARSER_ARG "identifier %s is not valid to set", rb_id2name(id));
return 0;
}
@ -7349,10 +7340,10 @@ aryset_gen(struct parser_params *parser, NODE *recv, NODE *idx)
}
static void
block_dup_check(NODE *node1, NODE *node2)
block_dup_check_gen(struct parser_params *parser, NODE *node1, NODE *node2)
{
if (node2 && node1 && nd_type(node1) == NODE_BLOCK_PASS) {
compile_error("both block arg and actual block given");
compile_error(PARSER_ARG "both block arg and actual block given");
}
}
@ -7375,20 +7366,20 @@ attrset_gen(struct parser_params *parser, NODE *recv, ID id)
}
static void
rb_backref_error(NODE *node)
rb_backref_error_gen(struct parser_params *parser, NODE *node)
{
switch (nd_type(node)) {
case NODE_NTH_REF:
rb_compile_error("Can't set variable $%ld", node->nd_nth);
compile_error(PARSER_ARG "Can't set variable $%ld", node->nd_nth);
break;
case NODE_BACK_REF:
rb_compile_error("Can't set variable $%c", (int)node->nd_nth);
compile_error(PARSER_ARG "Can't set variable $%c", (int)node->nd_nth);
break;
}
}
static NODE *
arg_concat(NODE *node1, NODE *node2)
arg_concat_gen(struct parser_params *parser, NODE *node1, NODE *node2)
{
if (!node2) return node1;
if (nd_type(node1) == NODE_BLOCK_PASS) {
@ -7399,7 +7390,7 @@ arg_concat(NODE *node1, NODE *node2)
}
static NODE *
arg_append(NODE *node1, NODE *node2)
arg_append_gen(struct parser_params *parser, NODE *node1, NODE *node2)
{
if (!node1) return NEW_LIST(node2);
switch (nd_type(node1)) {
@ -7413,8 +7404,9 @@ arg_append(NODE *node1, NODE *node2)
}
}
#define arg_add(n1, n2) arg_add_gen(parser,n1,n2)
static NODE *
arg_add(NODE *node1, NODE *node2)
arg_add_gen(struct parser_params *parser, NODE *node1, NODE *node2)
{
if (!node1) return NEW_LIST(node2);
switch (nd_type(node1)) {
@ -7628,7 +7620,7 @@ remove_begin(NODE *node)
}
static void
reduce_nodes(NODE **body)
reduce_nodes_gen(struct parser_params *parser, NODE **body)
{
NODE *node = *body;
@ -7720,9 +7712,9 @@ assign_in_cond(struct parser_params *parser, NODE *node)
}
static int
e_option_supplied(void)
e_option_supplied(NODE *node)
{
if (strcmp(ruby_sourcefile, "-e") == 0)
if (strcmp(node->nd_file, "-e") == 0)
return Qtrue;
return Qfalse;
}
@ -7730,13 +7722,13 @@ e_option_supplied(void)
static void
warn_unless_e_option(NODE *node, const char *str)
{
if (!e_option_supplied()) parser_warn(node, str);
if (!e_option_supplied(node)) parser_warn(node, str);
}
static void
warning_unless_e_option(NODE *node, const char *str)
{
if (!e_option_supplied()) parser_warning(node, str);
if (!e_option_supplied(node)) parser_warning(node, str);
}
static NODE *cond0(struct parser_params*,NODE*);
@ -7746,7 +7738,7 @@ range_op(struct parser_params *parser, NODE *node)
{
enum node_type type;
if (!e_option_supplied()) return node;
if (!e_option_supplied(node)) return node;
if (node == 0) return 0;
value_expr(node);
@ -7810,7 +7802,7 @@ cond0(struct parser_params *parser, NODE *node)
node->nd_end = range_op(parser, node->nd_end);
if (nd_type(node) == NODE_DOT2) nd_set_type(node,NODE_FLIP2);
else if (nd_type(node) == NODE_DOT3) nd_set_type(node, NODE_FLIP3);
if (!e_option_supplied()) {
if (!e_option_supplied(node)) {
int b = literal_node(node->nd_beg);
int e = literal_node(node->nd_end);
if ((b == 1 && e == 1) || (b + e >= 2 && RTEST(ruby_verbose))) {
@ -7875,18 +7867,18 @@ cond_negative(NODE **nodep)
}
static void
no_blockarg(NODE *node)
no_blockarg(struct parser_params *parser, NODE *node)
{
if (node && nd_type(node) == NODE_BLOCK_PASS) {
rb_compile_error("block argument should not be given");
compile_error(PARSER_ARG "block argument should not be given");
}
}
static NODE *
ret_args(NODE *node)
ret_args_gen(struct parser_params *parser, NODE *node)
{
if (node) {
no_blockarg(node);
no_blockarg(parser, node);
if (nd_type(node) == NODE_ARRAY) {
if (node->nd_next == 0) {
node = node->nd_head;
@ -7900,12 +7892,12 @@ ret_args(NODE *node)
}
static NODE *
new_yield(NODE *node)
new_yield_gen(struct parser_params *parser, NODE *node)
{
long state = Qtrue;
if (node) {
no_blockarg(node);
no_blockarg(parser, node);
if (node && nd_type(node) == NODE_SPLAT) {
state = Qtrue;
}
@ -8081,7 +8073,7 @@ dyna_pop_gen(struct parser_params *parser)
static int
dyna_in_block_gen(struct parser_params *parser)
{
return lvtbl->vars->prev != DVARS_TOPSCOPE;
return POINTER_P(lvtbl->vars) && lvtbl->vars->prev != DVARS_TOPSCOPE;
}
static int
@ -8123,10 +8115,14 @@ rb_gc_mark_parser(void)
}
NODE*
rb_parser_append_print(NODE *node)
rb_parser_append_print(VALUE vparser, NODE *node)
{
NODE *prelude = 0;
NODE *scope = node;
struct parser_params *parser;
Data_Get_Struct(vparser, struct parser_params, parser);
node = node->nd_body;
if (node && (nd_type(node) == NODE_PRELUDE)) {
@ -8149,10 +8145,13 @@ rb_parser_append_print(NODE *node)
}
NODE *
rb_parser_while_loop(NODE *node, int chop, int split)
rb_parser_while_loop(VALUE vparser, NODE *node, int chop, int split)
{
NODE *prelude = 0;
NODE *scope = node;
struct parser_params *parser;
Data_Get_Struct(vparser, struct parser_params, parser);
node = node->nd_body;
@ -8276,6 +8275,7 @@ Init_sym(void)
global_symbols.id_str = st_init_numtable_with_size(1000);
global_symbols.ivar2_id = st_init_table_with_size(&ivar2_hash_type, 1000);
global_symbols.id_ivar2 = st_init_numtable_with_size(1000);
rb_intern2("", 0);
}
void
@ -8626,6 +8626,7 @@ parser_initialize(struct parser_params *parser)
parser->parser_lvtbl = 0;
parser->parser_ruby__end__seen = 0;
#ifndef RIPPER
parser->parser_ruby_sourcefile = 0;
parser->parser_eval_tree_begin = 0;
parser->parser_eval_tree = 0;
#else
@ -8641,6 +8642,8 @@ parser_initialize(struct parser_params *parser)
#endif
}
extern void rb_mark_source_filename(char *);
static void
parser_mark(void *ptr)
{
@ -8653,6 +8656,7 @@ parser_mark(void *ptr)
rb_gc_mark((VALUE)p->parser_eval_tree_begin) ;
rb_gc_mark((VALUE)p->parser_eval_tree) ;
rb_gc_mark(p->debug_lines);
rb_mark_source_filename(p->parser_ruby_sourcefile);
#else
rb_gc_mark(p->parser_ruby_sourcefile);
rb_gc_mark(p->delayed);
@ -8720,12 +8724,12 @@ rb_parser_end_seen_p(VALUE vparser)
#ifdef YYMALLOC
#define HEAPCNT(n, size) ((n) * (size) / sizeof(YYSTYPE))
#define NEWHEAP() rb_node_newnode(NODE_ALLOCA, 0, (VALUE)parserp->heap, 0)
#define ADD2HEAP(n, c, p) ((parserp->heap = (n))->u1.node = (p), \
#define NEWHEAP() rb_node_newnode(NODE_ALLOCA, 0, (VALUE)parser->heap, 0)
#define ADD2HEAP(n, c, p) ((parser->heap = (n))->u1.node = (p), \
(n)->u3.cnt = (c), (p))
void *
rb_parser_malloc(struct parser_params *parserp, size_t size)
rb_parser_malloc(struct parser_params *parser, size_t size)
{
size_t cnt = HEAPCNT(1, size);
NODE *n = NEWHEAP();
@ -8735,7 +8739,7 @@ rb_parser_malloc(struct parser_params *parserp, size_t size)
}
void *
rb_parser_calloc(struct parser_params *parserp, size_t nelem, size_t size)
rb_parser_calloc(struct parser_params *parser, size_t nelem, size_t size)
{
size_t cnt = HEAPCNT(nelem, size);
NODE *n = NEWHEAP();
@ -8745,12 +8749,12 @@ rb_parser_calloc(struct parser_params *parserp, size_t nelem, size_t size)
}
void *
rb_parser_realloc(struct parser_params *parserp, void *ptr, size_t size)
rb_parser_realloc(struct parser_params *parser, void *ptr, size_t size)
{
NODE *n;
size_t cnt = HEAPCNT(1, size);
if (ptr && (n = parserp->heap) != NULL) {
if (ptr && (n = parser->heap) != NULL) {
do {
if (n->u1.node == ptr) {
n->u1.node = ptr = xrealloc(ptr, size);
@ -8765,9 +8769,9 @@ rb_parser_realloc(struct parser_params *parserp, void *ptr, size_t size)
}
void
rb_parser_free(struct parser_params *parserp, void *ptr)
rb_parser_free(struct parser_params *parser, void *ptr)
{
NODE **prev = &parserp->heap, *n;
NODE **prev = &parser->heap, *n;
while ((n = *prev) != NULL) {
if (n->u1.node == ptr) {

70
re.c
Просмотреть файл

@ -21,6 +21,8 @@
VALUE rb_eRegexpError;
typedef char onig_errmsg_buffer[ONIG_MAX_ERROR_MESSAGE_LEN];
#define BEG(no) regs->beg[no]
#define END(no) regs->end[no]
@ -595,14 +597,11 @@ rb_reg_to_s(VALUE re)
}
static void
rb_reg_raise(const char *s, long len, const char *err, VALUE re, int ce)
rb_reg_raise(const char *s, long len, const char *err, VALUE re)
{
VALUE desc = rb_reg_desc(s, len, re);
if (ce)
rb_compile_error("%s: %s", err, RSTRING_PTR(desc));
else
rb_raise(rb_eRegexpError, "%s: %s", err, RSTRING_PTR(desc));
rb_raise(rb_eRegexpError, "%s: %s", err, RSTRING_PTR(desc));
}
@ -685,10 +684,9 @@ rb_reg_kcode_m(VALUE re)
}
static Regexp*
make_regexp(const char *s, long len, int flags, int ce)
make_regexp(const char *s, long len, int flags, onig_errmsg_buffer err)
{
Regexp *rp;
char err[ONIG_MAX_ERROR_MESSAGE_LEN];
int r;
OnigErrorInfo einfo;
@ -705,7 +703,7 @@ make_regexp(const char *s, long len, int flags, int ce)
OnigDefaultSyntax);
if (r) {
onig_error_code_to_str((UChar*)err, r);
rb_reg_raise(s, len, err, 0, ce);
return 0;
}
r = onig_compile(rp, (UChar*)s, (UChar*)(s + len), &einfo);
@ -713,7 +711,6 @@ make_regexp(const char *s, long len, int flags, int ce)
if (r != 0) {
onig_free(rp);
(void )onig_error_code_to_str((UChar*)err, r, &einfo);
rb_reg_raise(s, len, err, 0, ce);
return 0;
}
return rp;
@ -907,7 +904,7 @@ rb_reg_prepare_re(VALUE re)
}
if (need_recompile) {
char err[ONIG_MAX_ERROR_MESSAGE_LEN];
onig_errmsg_buffer err;
int r;
OnigErrorInfo einfo;
regex_t *reg, *reg2;
@ -924,8 +921,8 @@ rb_reg_prepare_re(VALUE re)
reg->options, onigenc_get_default_encoding(),
OnigDefaultSyntax, &einfo);
if (r) {
onig_error_code_to_str((UChar*)err, r, &einfo);
rb_reg_raise((char* )pattern, RREGEXP(re)->len, err, re, Qfalse);
onig_error_code_to_str((UChar*)err, r, &einfo);
rb_reg_raise((char* )pattern, RREGEXP(re)->len, err, re);
}
RREGEXP(re)->ptr = reg2;
@ -1016,9 +1013,9 @@ rb_reg_search(VALUE re, VALUE str, long pos, long reverse)
return result;
}
else {
char err[ONIG_MAX_ERROR_MESSAGE_LEN];
onig_errmsg_buffer err;
onig_error_code_to_str((UChar*)err, result);
rb_reg_raise(RREGEXP(re)->str, RREGEXP(re)->len, err, 0, Qfalse);
rb_reg_raise(RREGEXP(re)->str, RREGEXP(re)->len, err, 0);
}
}
@ -1460,10 +1457,9 @@ match_inspect(VALUE match)
VALUE rb_cRegexp;
static void
static int
rb_reg_initialize(VALUE obj, const char *s, long len,
int options,
int ce) /* call rb_compile_error() */
int options, onig_errmsg_buffer err)
{
struct RRegexp *re = RREGEXP(obj);
@ -1486,7 +1482,8 @@ rb_reg_initialize(VALUE obj, const char *s, long len,
options |= ONIG_OPTION_IGNORECASE;
FL_SET(re, REG_CASESTATE);
}
re->ptr = make_regexp(s, len, options & ARG_REG_OPTION_MASK, ce);
re->ptr = make_regexp(s, len, options & ARG_REG_OPTION_MASK, err);
if (!re->ptr) return -1;
re->str = ALLOC_N(char, len+1);
memcpy(re->str, s, len);
re->str[len] = '\0';
@ -1494,7 +1491,7 @@ rb_reg_initialize(VALUE obj, const char *s, long len,
if (options & ARG_KCODE_MASK) {
kcode_reset_option();
}
if (ce) FL_SET(obj, REG_LITERAL);
return 0;
}
static VALUE
@ -1514,18 +1511,27 @@ VALUE
rb_reg_new(const char *s, long len, int options)
{
VALUE re = rb_reg_s_alloc(rb_cRegexp);
char err[ONIG_MAX_ERROR_MESSAGE_LEN];
rb_reg_initialize(re, s, len, options, Qfalse);
return (VALUE)re;
if (rb_reg_initialize(re, s, len, options, err) != 0) {
rb_reg_raise(s, len, err, re);
}
return re;
}
VALUE
rb_reg_compile(const char *s, long len, int options)
rb_reg_compile(const char *s, long len, int options, const char *file, int line)
{
VALUE re = rb_reg_s_alloc(rb_cRegexp);
char err[ONIG_MAX_ERROR_MESSAGE_LEN];
rb_reg_initialize(re, s, len, options, Qtrue);
return (VALUE)re;
if (rb_reg_initialize(re, s, len, options, err) != 0) {
VALUE desc = rb_reg_desc(s, len, re);
rb_compile_error(file, line, "%s: %s", err, RSTRING_PTR(desc));
}
FL_SET(re, REG_LITERAL);
return re;
}
static int case_cache;
@ -1805,6 +1811,7 @@ rb_reg_match_m(int argc, VALUE *argv, VALUE re)
static VALUE
rb_reg_initialize_m(int argc, VALUE *argv, VALUE self)
{
onig_errmsg_buffer err;
const char *s;
long len;
int flags = 0;
@ -1838,7 +1845,9 @@ rb_reg_initialize_m(int argc, VALUE *argv, VALUE self)
s = StringValuePtr(argv[0]);
len = RSTRING_LEN(argv[0]);
}
rb_reg_initialize(self, s, len, flags, Qfalse);
if (rb_reg_initialize(self, s, len, flags, err) != 0) {
rb_reg_raise(s, len, err, self);
}
return self;
}
@ -2081,6 +2090,10 @@ rb_reg_s_union(int argc, VALUE *argv)
static VALUE
rb_reg_init_copy(VALUE copy, VALUE re)
{
onig_errmsg_buffer err;
const char *s;
long len;
if (copy == re) return copy;
rb_check_frozen(copy);
/* need better argument type check */
@ -2088,8 +2101,11 @@ rb_reg_init_copy(VALUE copy, VALUE re)
rb_raise(rb_eTypeError, "wrong argument type");
}
rb_reg_check(re);
rb_reg_initialize(copy, RREGEXP(re)->str, RREGEXP(re)->len,
rb_reg_options(re), Qfalse);
s = RREGEXP(re)->str;
len = RREGEXP(re)->len;
if (rb_reg_initialize(copy, s, len, rb_reg_options(re), err) != 0) {
rb_reg_raise(s, len, err, copy);
}
return copy;
}

80
ruby.c
Просмотреть файл

@ -63,8 +63,7 @@ extern int ruby_yydebug;
char *ruby_inplace_mode = Qfalse;
static void load_stdin(void);
static NODE *load_file(const char *, int);
static NODE *load_file(VALUE, const char *, int);
static void forbid_setid(const char *);
static VALUE do_loop = Qfalse, do_print = Qfalse;
@ -374,14 +373,9 @@ extern void Init_ext(void);
static void
require_libraries(void)
{
extern NODE *ruby_eval_tree;
NODE *save[3];
struct req_list *list = req_list_head.next;
struct req_list *tmp;
save[0] = ruby_eval_tree;
save[1] = NEW_BEGIN(0);
ruby_eval_tree = 0;
Init_ext(); /* should be called here for some reason :-( */
req_list_last = 0;
while (list) {
@ -396,8 +390,6 @@ require_libraries(void)
list = tmp;
}
req_list_head.next = 0;
ruby_eval_tree = save[0];
rb_gc_force_recycle((VALUE)save[1]);
}
static void
@ -464,7 +456,7 @@ process_sflag(void)
sflag = 0;
}
static void proc_options(int argc, char **argv);
static NODE *proc_options(int argc, char **argv);
static char *
moreswitches(const char *s)
@ -487,16 +479,15 @@ moreswitches(const char *s)
return (char *)s;
}
NODE *ruby_eval_tree;
static void
static NODE *
proc_options(int argc, char **argv)
{
char *argv0 = argv[0];
int do_search;
const char *s;
char *script = 0;
NODE *volatile script_node = 0;
NODE *tree;
VALUE parser;
int version = 0;
int copyright = 0;
@ -504,7 +495,7 @@ proc_options(int argc, char **argv)
VALUE e_script = Qfalse;
if (argc == 0)
return;
return 0;
do_search = Qfalse;
@ -780,7 +771,7 @@ proc_options(int argc, char **argv)
switch_end:
if (argv0 == 0)
return;
return 0;
if (rb_safe_level() == 0 && (s = getenv("RUBYOPT"))) {
while (ISSPACE(*s))
@ -855,8 +846,6 @@ proc_options(int argc, char **argv)
}
if (!script)
script = argv[0];
script = ruby_sourcefile = rb_source_filename(script);
script_node = NEW_BEGIN(0);
}
#if defined DOSISH || defined __CYGWIN__
/* assume that we can change argv[n] if never change its length. */
@ -872,16 +861,16 @@ proc_options(int argc, char **argv)
process_sflag();
ruby_init_loadpath();
ruby_sourcefile = rb_source_filename(argv0);
parser = rb_parser_new();
if (e_script) {
require_libraries();
ruby_eval_tree = rb_compile_string(script, e_script, 1);
}
else if (strlen(script) == 1 && script[0] == '-') {
load_stdin();
tree = rb_parser_compile_string(parser, script, e_script, 1);
}
else {
load_file(script, 1);
if (script[0] == '-' && !script[1]) {
forbid_setid("program input from stdin");
}
tree = load_file(parser, script, 1);
}
process_sflag();
@ -891,13 +880,14 @@ proc_options(int argc, char **argv)
FL_UNSET(rb_argv, FL_TAINT);
FL_UNSET(rb_load_path, FL_TAINT);
}
return tree;
}
static NODE *
load_file(const char *fname, int script)
load_file(VALUE parser, const char *fname, int script)
{
extern VALUE rb_stdin;
volatile VALUE parser;
VALUE f;
int line_start = 1;
NODE *tree = 0;
@ -949,11 +939,7 @@ load_file(const char *fname, int script)
c = rb_io_getc(f);
if (c == INT2FIX('#')) {
c = rb_io_getc(f);
if (c == INT2FIX('!')) {
line = rb_io_gets(f);
if (NIL_P(line))
return 0;
if (c == INT2FIX('!') && !NIL_P(line = rb_io_gets(f))) {
if ((p = strstr(RSTRING_PTR(line), "ruby")) == 0) {
/* not ruby script, kick the program */
char **argv;
@ -983,8 +969,6 @@ load_file(const char *fname, int script)
argv[0] = path;
execv(path, argv);
ruby_sourcefile = rb_source_filename(fname);
ruby_sourceline = 1;
rb_fatal("Can't exec %s", path);
}
@ -1013,11 +997,8 @@ load_file(const char *fname, int script)
rb_io_ungetc(f, c);
}
require_libraries(); /* Why here? unnatural */
if (NIL_P(c))
return 0;
}
parser = rb_parser_new();
ruby_eval_tree = tree = (NODE *)rb_parser_compile_file(parser, fname, f, line_start);
tree = (NODE *)rb_parser_compile_file(parser, fname, f, line_start);
if (script && rb_parser_end_seen_p(parser)) {
rb_define_global_const("DATA", f);
}
@ -1030,14 +1011,7 @@ load_file(const char *fname, int script)
void *
rb_load_file(const char *fname)
{
return load_file(fname, 0);
}
static void
load_stdin(void)
{
forbid_setid("program input from stdin");
load_file("-", 1);
return load_file(rb_parser_new(), fname, 0);
}
VALUE rb_progname;
@ -1155,7 +1129,6 @@ ruby_script(const char *name)
{
if (name) {
rb_progname = rb_tainted_str_new2(name);
ruby_sourcefile = rb_source_filename(name);
}
}
@ -1211,7 +1184,6 @@ ruby_prog_init(void)
{
init_ids();
ruby_sourcefile = rb_source_filename("ruby");
rb_define_hooked_variable("$VERBOSE", &ruby_verbose, 0, verbose_setter);
rb_define_hooked_variable("$-v", &ruby_verbose, 0, verbose_setter);
rb_define_hooked_variable("$-w", &ruby_verbose, 0, verbose_setter);
@ -1263,9 +1235,11 @@ ruby_set_argv(int argc, char **argv)
NODE *rb_parser_append_print(NODE *);
NODE *rb_parser_while_loop(NODE *, int, int);
void
void *
ruby_process_options(int argc, char **argv)
{
NODE *tree;
origargc = argc;
origargv = argv;
@ -1275,17 +1249,17 @@ ruby_process_options(int argc, char **argv)
dln_argv0 = argv[0];
#endif
set_arg0space();
proc_options(argc, argv);
tree = proc_options(argc, argv);
if (do_check && ruby_nerrs == 0) {
if (do_check && tree) {
printf("Syntax OK\n");
exit(0);
}
if (do_print) {
ruby_eval_tree = rb_parser_append_print(ruby_eval_tree);
tree = rb_parser_append_print(tree);
}
if (do_loop) {
ruby_eval_tree =
rb_parser_while_loop(ruby_eval_tree, do_line, do_split);
tree = rb_parser_while_loop(tree, do_line, do_split);
}
return tree;
}

Просмотреть файл

@ -76,16 +76,16 @@ ID id__send_bang;
rb_thread_t *ruby_current_thread = 0;
rb_vm_t *ruby_current_vm = 0;
RUBY_EXTERN int ruby_nerrs;
static NODE *
compile_string(VALUE str, VALUE file, VALUE line)
{
VALUE parser = rb_parser_new();
NODE *node;
node = rb_compile_string(StringValueCStr(file), str, NUM2INT(line));
if (ruby_nerrs > 0) {
ruby_nerrs = 0;
node = rb_parser_compile_string(parser, StringValueCStr(file),
str, NUM2INT(line));
if (!node) {
rb_exc_raise(GET_THREAD()->errinfo); /* TODO: check err */
}
return node;

Просмотреть файл

@ -537,7 +537,7 @@ VALUE rb_iseq_new_with_opt(NODE*, VALUE, VALUE, VALUE, VALUE, const rb_compile_o
VALUE ruby_iseq_disasm(VALUE self);
VALUE ruby_iseq_disasm_insn(VALUE str, VALUE *iseqval, int pos,
rb_iseq_t *iseq, VALUE child);
char *ruby_node_name(int node);
const char *ruby_node_name(int node);
/* each thread has this size stack : 2MB */