зеркало из https://github.com/github/ruby.git
* 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:
Родитель
a0d50fa3c4
Коммит
46603a78af
|
@ -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
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
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
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);
|
||||
|
||||
|
|
63
eval_load.c
63
eval_load.c
|
@ -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
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
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
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
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, "e->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
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
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;
|
||||
}
|
||||
|
|
10
yarvcore.c
10
yarvcore.c
|
@ -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 */
|
||||
|
|
Загрузка…
Ссылка в новой задаче