aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2007-07-05 08:12:18 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2007-07-05 08:12:18 +0000
commit46603a78afde1386f92b38f9b16ca86daa93ad88 (patch)
treef3594fecc31b6f210f95143c7a20c2ea55ae68ce
parenta0d50fa3c494ea5afb98c05be049a0cde6fde28d (diff)
downloadruby-46603a78afde1386f92b38f9b16ca86daa93ad88.tar.gz
* 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
-rw-r--r--ChangeLog7
-rw-r--r--compile.c265
-rw-r--r--compile.h4
-rw-r--r--error.c74
-rw-r--r--eval.c61
-rw-r--r--eval_load.c63
-rw-r--r--gc.c26
-rw-r--r--include/ruby/intern.h8
-rw-r--r--include/ruby/ruby.h9
-rw-r--r--iseq.c24
-rw-r--r--main.c4
-rw-r--r--parse.y262
-rw-r--r--re.c70
-rw-r--r--ruby.c80
-rw-r--r--yarvcore.c10
-rw-r--r--yarvcore.h2
16 files changed, 497 insertions, 472 deletions
diff --git a/ChangeLog b/ChangeLog
index 4a8fc9ee7c..ea733b166a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
diff --git a/compile.c b/compile.c
index 3b6a0edc5b..3e237e7f37 100644
--- a/compile.c
+++ b/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 */
diff --git a/compile.h b/compile.h
index c2764a7bf0..e298008e93 100644
--- a/compile.h
+++ b/compile.h
@@ -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
diff --git a/error.c b/error.c
index d2b5a0ef71..4bdc028bd4 100644
--- a/error.c
+++ b/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");
}
diff --git a/eval.c b/eval.c
index 48d6449404..ffe297e5a2 100644
--- a/eval.c
+++ b/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);
diff --git a/eval_load.c b/eval_load.c
index 49a4afaa8c..3974513b16 100644
--- a/eval_load.c
+++ b/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);
}
diff --git a/gc.c b/gc.c
index a21ced7bd9..d596d10735 100644
--- a/gc.c
+++ b/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 {
diff --git a/include/ruby/intern.h b/include/ruby/intern.h
index 9c597f0f64..77663fd5f0 100644
--- a/include/ruby/intern.h
+++ b/include/ruby/intern.h
@@ -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 */
diff --git a/include/ruby/ruby.h b/include/ruby/ruby.h
index e6c16e82bb..059c145265 100644
--- a/include/ruby/ruby.h
+++ b/include/ruby/ruby.h
@@ -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;
diff --git a/iseq.c b/iseq.c
index 7e1b40c5fb..55ff9952b3 100644
--- a/iseq.c
+++ b/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) {
diff --git a/main.c b/main.c
index 24fbc2e9f3..09c0bdb8bf 100644
--- a/main.c
+++ b/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;
}
diff --git a/parse.y b/parse.y
index c1b74fa074..deb86f5d07 100644
--- a/parse.y
+++ b/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 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 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_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 (ruby_eval_tree_begin) {
- NODE *scope = ruby_eval_tree;
- scope->nd_body = NEW_PRELUDE(ruby_eval_tree_begin, scope->nd_body);
- return scope;
+ if (parser->nerr) {
+ return 0;
}
- else {
- return ruby_eval_tree;
+ tree = ruby_eval_tree;
+ if (!tree) {
+ tree = NEW_NIL();
+ }
+ if (ruby_eval_tree_begin) {
+ tree->nd_body = NEW_PRELUDE(ruby_eval_tree_begin, tree->nd_body);
}
+ return tree;
}
#endif /* !RIPPER */
@@ -5058,7 +5077,7 @@ parser_regx_options(struct parser_params *parser)
if (toklen()) {
tokfix();
compile_error(PARSER_ARG "unknown regexp option%s - %s",
- toklen() > 1 ? "s" : "", tok());
+ toklen() > 1 ? "s" : "", tok());
}
return options | kcode;
}
@@ -5163,7 +5182,7 @@ parser_tokadd_string(struct parser_params *parser,
}
if (!c && (func & STR_FUNC_SYMBOL)) {
func &= ~STR_FUNC_SYMBOL;
- rb_compile_error(PARSER_ARG "symbol cannot contain '\\0'");
+ compile_error(PARSER_ARG "symbol cannot contain '\\0'");
continue;
}
tokadd(c);
@@ -5171,20 +5190,8 @@ parser_tokadd_string(struct parser_params *parser,
return c;
}
-#define NEW_STRTERM0(func, term, paren) \
+#define NEW_STRTERM(func, term, paren) \
rb_node_newnode(NODE_STRTERM, (func), (term) | ((paren) << (CHAR_BIT * 2)), 0)
-#ifndef RIPPER
-# define NEW_STRTERM(func, term, paren) NEW_STRTERM0(func, term, paren)
-#else
-# define NEW_STRTERM(func, term, paren) ripper_new_strterm(parser, func, term, paren)
-static NODE *
-ripper_new_strterm(struct parser_params *parser, VALUE func, VALUE term, VALUE paren)
-{
- NODE *node = NEW_STRTERM0(func, term, paren);
- nd_set_line(node, ruby_sourceline);
- return node;
-}
-#endif
static int
parser_parse_string(struct parser_params *parser, NODE *quote)
@@ -5229,12 +5236,12 @@ parser_parse_string(struct parser_params *parser, NODE *quote)
if (tokadd_string(func, term, paren, &quote->nd_nest) == -1) {
if (func & STR_FUNC_REGEXP) {
ruby_sourceline = nd_line(quote);
- rb_compile_error(PARSER_ARG "unterminated regexp meets end of file");
+ compile_error(PARSER_ARG "unterminated regexp meets end of file");
return tREGEXP_END;
}
else {
ruby_sourceline = nd_line(quote);
- rb_compile_error(PARSER_ARG "unterminated string meets end of file");
+ compile_error(PARSER_ARG "unterminated string meets end of file");
return tSTRING_END;
}
}
@@ -5271,7 +5278,7 @@ parser_heredoc_identifier(struct parser_params *parser)
do {tokadd(c);} while (--len > 0 && (c = nextc()) != -1);
}
if (c == -1) {
- rb_compile_error(PARSER_ARG "unterminated here document identifier");
+ compile_error(PARSER_ARG "unterminated here document identifier");
return 0;
}
break;
@@ -5370,7 +5377,7 @@ parser_here_document(struct parser_params *parser, NODE *here)
if ((c = nextc()) == -1) {
error:
- rb_compile_error(PARSER_ARG "can't find string \"%s\" anywhere before EOF", eos);
+ compile_error(PARSER_ARG "can't find string \"%s\" anywhere before EOF", eos);
heredoc_restore(lex_strterm);
lex_strterm = 0;
return 0;
@@ -5442,18 +5449,18 @@ parser_here_document(struct parser_params *parser, NODE *here)
#ifndef RIPPER
static void
-arg_ambiguous(void)
+arg_ambiguous_gen(struct parser_params *parser)
{
rb_warning0("ambiguous first argument; put parentheses or even spaces");
}
#else
static void
-ripper_arg_ambiguous(struct parser_params *parser)
+arg_ambiguous_gen(struct parser_params *parser)
{
dispatch0(arg_ambiguous);
}
-#define arg_ambiguous() ripper_arg_ambiguous(parser)
#endif
+#define arg_ambiguous() arg_ambiguous_gen(parser)
static int
lvar_defined_gen(struct parser_params *parser, ID id)
@@ -5791,7 +5798,7 @@ parser_yylex(struct parser_params *parser)
#endif
c = nextc();
if (c == -1) {
- rb_compile_error(PARSER_ARG "embedded document meets end of file");
+ compile_error(PARSER_ARG "embedded document meets end of file");
return 0;
}
if (c != '=') continue;
@@ -5919,7 +5926,7 @@ parser_yylex(struct parser_params *parser)
}
c = nextc();
if (c == -1) {
- rb_compile_error(PARSER_ARG "incomplete character syntax");
+ compile_error(PARSER_ARG "incomplete character syntax");
return 0;
}
uc = (unsigned char)c;
@@ -6539,7 +6546,7 @@ parser_yylex(struct parser_params *parser)
}
}
if (c == -1 || term == -1) {
- rb_compile_error(PARSER_ARG "unterminated quoted string meets end of file");
+ compile_error(PARSER_ARG "unterminated quoted string meets end of file");
return 0;
}
paren = term;
@@ -6659,7 +6666,7 @@ parser_yylex(struct parser_params *parser)
tokfix();
set_yylval_id(rb_intern(tok()));
if (!is_global_id(yylval_id())) {
- rb_compile_error(PARSER_ARG "invalid global variable `%s'", rb_id2name(yylval.id));
+ compile_error(PARSER_ARG "invalid global variable `%s'", rb_id2name(yylval.id));
return 0;
}
return tGVAR;
@@ -6711,10 +6718,10 @@ parser_yylex(struct parser_params *parser)
}
if (ISDIGIT(c)) {
if (tokidx == 1) {
- rb_compile_error(PARSER_ARG "`@%c' is not allowed as an instance variable name", c);
+ compile_error(PARSER_ARG "`@%c' is not allowed as an instance variable name", c);
}
else {
- rb_compile_error(PARSER_ARG "`@@%c' is not allowed as a class variable name", c);
+ compile_error(PARSER_ARG "`@@%c' is not allowed as a class variable name", c);
}
return 0;
}
@@ -6743,7 +6750,7 @@ parser_yylex(struct parser_params *parser)
default:
uc = (unsigned char)c;
if (!is_identchar(uc)) {
- rb_compile_error(PARSER_ARG "Invalid char `\\%03o' in expression", c);
+ compile_error(PARSER_ARG "Invalid char `\\%03o' in expression", c);
goto retry;
}
@@ -6914,20 +6921,12 @@ yylex(void *p)
}
#ifndef RIPPER
-NODE*
-rb_node_newnode(enum node_type type, VALUE a0, VALUE a1, VALUE a2)
+static NODE*
+node_newnode(struct parser_params *parser, enum node_type type, VALUE a0, VALUE a1, VALUE a2)
{
- NODE *n = (NODE*)rb_newobj();
-
- n->flags |= T_NODE;
- nd_set_type(n, type);
+ NODE *n = (rb_node_newnode)(type, a0, a1, a2);
nd_set_line(n, ruby_sourceline);
n->nd_file = ruby_sourcefile;
-
- n->u1.value = a0;
- n->u2.value = a1;
- n->u3.value = a2;
-
return n;
}
@@ -6965,23 +6964,17 @@ fixpos(NODE *node, NODE *orig)
static void
parser_warning(NODE *node, const char *mesg)
{
- int line = ruby_sourceline;
- ruby_sourceline = nd_line(node);
- rb_warningS("%s", mesg);
- ruby_sourceline = line;
+ rb_compile_warning(node->nd_file, nd_line(node), "%s", mesg);
}
static void
parser_warn(NODE *node, const char *mesg)
{
- int line = ruby_sourceline;
- ruby_sourceline = nd_line(node);
- rb_warnS("%s", mesg);
- ruby_sourceline = line;
+ rb_compile_warn(node->nd_file, nd_line(node), "%s", mesg);
}
static NODE*
-block_append(NODE *head, NODE *tail)
+block_append_gen(struct parser_params *parser, NODE *head, NODE *tail)
{
NODE *end, *h = head, *nd;
@@ -7035,7 +7028,7 @@ block_append(NODE *head, NODE *tail)
/* append item to the list */
static NODE*
-list_append(NODE *list, NODE *item)
+list_append_gen(struct parser_params *parser, NODE *list, NODE *item)
{
NODE *last;
@@ -7055,7 +7048,7 @@ list_append(NODE *list, NODE *item)
/* concat two lists */
static NODE*
-list_concat(NODE *head, NODE *tail)
+list_concat_gen(struct parser_params *parser, NODE *head, NODE *tail)
{
NODE *last;
@@ -7080,7 +7073,7 @@ list_concat(NODE *head, NODE *tail)
/* concat two string literals */
static NODE *
-literal_concat(NODE *head, NODE *tail)
+literal_concat_gen(struct parser_params *parser, NODE *head, NODE *tail)
{
enum node_type htype;
@@ -7129,7 +7122,7 @@ literal_concat(NODE *head, NODE *tail)
}
static NODE *
-evstr2dstr(NODE *node)
+evstr2dstr_gen(struct parser_params *parser, NODE *node)
{
if (nd_type(node) == NODE_EVSTR) {
node = list_append(NEW_DSTR(rb_str_new(0, 0)), node);
@@ -7138,7 +7131,7 @@ evstr2dstr(NODE *node)
}
static NODE *
-new_evstr(NODE *node)
+new_evstr_gen(struct parser_params *parser, NODE *node)
{
NODE *head = node;
@@ -7238,7 +7231,7 @@ gettable_gen(struct parser_params *parser, ID id)
else if (is_class_id(id)) {
return NEW_CVAR(id);
}
- rb_compile_error("identifier %s is not valid", rb_id2name(id));
+ compile_error(PARSER_ARG "identifier %s is not valid to get", rb_id2name(id));
return 0;
}
@@ -7301,9 +7294,7 @@ assignable_gen(struct parser_params *parser, ID id, NODE *val)
else if (is_class_id(id)) {
return NEW_CVASGN(id, val);
}
- else {
- rb_compile_error("identifier %s is not valid", rb_id2name(id));
- }
+ compile_error(PARSER_ARG "identifier %s is not valid to set", rb_id2name(id));
return 0;
}
@@ -7349,10 +7340,10 @@ aryset_gen(struct parser_params *parser, NODE *recv, NODE *idx)
}
static void
-block_dup_check(NODE *node1, NODE *node2)
+block_dup_check_gen(struct parser_params *parser, NODE *node1, NODE *node2)
{
if (node2 && node1 && nd_type(node1) == NODE_BLOCK_PASS) {
- compile_error("both block arg and actual block given");
+ compile_error(PARSER_ARG "both block arg and actual block given");
}
}
@@ -7375,20 +7366,20 @@ attrset_gen(struct parser_params *parser, NODE *recv, ID id)
}
static void
-rb_backref_error(NODE *node)
+rb_backref_error_gen(struct parser_params *parser, NODE *node)
{
switch (nd_type(node)) {
case NODE_NTH_REF:
- rb_compile_error("Can't set variable $%ld", node->nd_nth);
+ compile_error(PARSER_ARG "Can't set variable $%ld", node->nd_nth);
break;
case NODE_BACK_REF:
- rb_compile_error("Can't set variable $%c", (int)node->nd_nth);
+ compile_error(PARSER_ARG "Can't set variable $%c", (int)node->nd_nth);
break;
}
}
static NODE *
-arg_concat(NODE *node1, NODE *node2)
+arg_concat_gen(struct parser_params *parser, NODE *node1, NODE *node2)
{
if (!node2) return node1;
if (nd_type(node1) == NODE_BLOCK_PASS) {
@@ -7399,7 +7390,7 @@ arg_concat(NODE *node1, NODE *node2)
}
static NODE *
-arg_append(NODE *node1, NODE *node2)
+arg_append_gen(struct parser_params *parser, NODE *node1, NODE *node2)
{
if (!node1) return NEW_LIST(node2);
switch (nd_type(node1)) {
@@ -7413,8 +7404,9 @@ arg_append(NODE *node1, NODE *node2)
}
}
+#define arg_add(n1, n2) arg_add_gen(parser,n1,n2)
static NODE *
-arg_add(NODE *node1, NODE *node2)
+arg_add_gen(struct parser_params *parser, NODE *node1, NODE *node2)
{
if (!node1) return NEW_LIST(node2);
switch (nd_type(node1)) {
@@ -7628,7 +7620,7 @@ remove_begin(NODE *node)
}
static void
-reduce_nodes(NODE **body)
+reduce_nodes_gen(struct parser_params *parser, NODE **body)
{
NODE *node = *body;
@@ -7720,9 +7712,9 @@ assign_in_cond(struct parser_params *parser, NODE *node)
}
static int
-e_option_supplied(void)
+e_option_supplied(NODE *node)
{
- if (strcmp(ruby_sourcefile, "-e") == 0)
+ if (strcmp(node->nd_file, "-e") == 0)
return Qtrue;
return Qfalse;
}
@@ -7730,13 +7722,13 @@ e_option_supplied(void)
static void
warn_unless_e_option(NODE *node, const char *str)
{
- if (!e_option_supplied()) parser_warn(node, str);
+ if (!e_option_supplied(node)) parser_warn(node, str);
}
static void
warning_unless_e_option(NODE *node, const char *str)
{
- if (!e_option_supplied()) parser_warning(node, str);
+ if (!e_option_supplied(node)) parser_warning(node, str);
}
static NODE *cond0(struct parser_params*,NODE*);
@@ -7746,7 +7738,7 @@ range_op(struct parser_params *parser, NODE *node)
{
enum node_type type;
- if (!e_option_supplied()) return node;
+ if (!e_option_supplied(node)) return node;
if (node == 0) return 0;
value_expr(node);
@@ -7810,7 +7802,7 @@ cond0(struct parser_params *parser, NODE *node)
node->nd_end = range_op(parser, node->nd_end);
if (nd_type(node) == NODE_DOT2) nd_set_type(node,NODE_FLIP2);
else if (nd_type(node) == NODE_DOT3) nd_set_type(node, NODE_FLIP3);
- if (!e_option_supplied()) {
+ if (!e_option_supplied(node)) {
int b = literal_node(node->nd_beg);
int e = literal_node(node->nd_end);
if ((b == 1 && e == 1) || (b + e >= 2 && RTEST(ruby_verbose))) {
@@ -7875,18 +7867,18 @@ cond_negative(NODE **nodep)
}
static void
-no_blockarg(NODE *node)
+no_blockarg(struct parser_params *parser, NODE *node)
{
if (node && nd_type(node) == NODE_BLOCK_PASS) {
- rb_compile_error("block argument should not be given");
+ compile_error(PARSER_ARG "block argument should not be given");
}
}
static NODE *
-ret_args(NODE *node)
+ret_args_gen(struct parser_params *parser, NODE *node)
{
if (node) {
- no_blockarg(node);
+ no_blockarg(parser, node);
if (nd_type(node) == NODE_ARRAY) {
if (node->nd_next == 0) {
node = node->nd_head;
@@ -7900,12 +7892,12 @@ ret_args(NODE *node)
}
static NODE *
-new_yield(NODE *node)
+new_yield_gen(struct parser_params *parser, NODE *node)
{
long state = Qtrue;
if (node) {
- no_blockarg(node);
+ no_blockarg(parser, node);
if (node && nd_type(node) == NODE_SPLAT) {
state = Qtrue;
}
@@ -8081,7 +8073,7 @@ dyna_pop_gen(struct parser_params *parser)
static int
dyna_in_block_gen(struct parser_params *parser)
{
- return lvtbl->vars->prev != DVARS_TOPSCOPE;
+ return POINTER_P(lvtbl->vars) && lvtbl->vars->prev != DVARS_TOPSCOPE;
}
static int
@@ -8123,10 +8115,14 @@ rb_gc_mark_parser(void)
}
NODE*
-rb_parser_append_print(NODE *node)
+rb_parser_append_print(VALUE vparser, NODE *node)
{
NODE *prelude = 0;
NODE *scope = node;
+ struct parser_params *parser;
+
+ Data_Get_Struct(vparser, struct parser_params, parser);
+
node = node->nd_body;
if (node && (nd_type(node) == NODE_PRELUDE)) {
@@ -8149,10 +8145,13 @@ rb_parser_append_print(NODE *node)
}
NODE *
-rb_parser_while_loop(NODE *node, int chop, int split)
+rb_parser_while_loop(VALUE vparser, NODE *node, int chop, int split)
{
NODE *prelude = 0;
NODE *scope = node;
+ struct parser_params *parser;
+
+ Data_Get_Struct(vparser, struct parser_params, parser);
node = node->nd_body;
@@ -8276,6 +8275,7 @@ Init_sym(void)
global_symbols.id_str = st_init_numtable_with_size(1000);
global_symbols.ivar2_id = st_init_table_with_size(&ivar2_hash_type, 1000);
global_symbols.id_ivar2 = st_init_numtable_with_size(1000);
+ rb_intern2("", 0);
}
void
@@ -8626,6 +8626,7 @@ parser_initialize(struct parser_params *parser)
parser->parser_lvtbl = 0;
parser->parser_ruby__end__seen = 0;
#ifndef RIPPER
+ parser->parser_ruby_sourcefile = 0;
parser->parser_eval_tree_begin = 0;
parser->parser_eval_tree = 0;
#else
@@ -8641,6 +8642,8 @@ parser_initialize(struct parser_params *parser)
#endif
}
+extern void rb_mark_source_filename(char *);
+
static void
parser_mark(void *ptr)
{
@@ -8653,6 +8656,7 @@ parser_mark(void *ptr)
rb_gc_mark((VALUE)p->parser_eval_tree_begin) ;
rb_gc_mark((VALUE)p->parser_eval_tree) ;
rb_gc_mark(p->debug_lines);
+ rb_mark_source_filename(p->parser_ruby_sourcefile);
#else
rb_gc_mark(p->parser_ruby_sourcefile);
rb_gc_mark(p->delayed);
@@ -8720,12 +8724,12 @@ rb_parser_end_seen_p(VALUE vparser)
#ifdef YYMALLOC
#define HEAPCNT(n, size) ((n) * (size) / sizeof(YYSTYPE))
-#define NEWHEAP() rb_node_newnode(NODE_ALLOCA, 0, (VALUE)parserp->heap, 0)
-#define ADD2HEAP(n, c, p) ((parserp->heap = (n))->u1.node = (p), \
+#define NEWHEAP() rb_node_newnode(NODE_ALLOCA, 0, (VALUE)parser->heap, 0)
+#define ADD2HEAP(n, c, p) ((parser->heap = (n))->u1.node = (p), \
(n)->u3.cnt = (c), (p))
void *
-rb_parser_malloc(struct parser_params *parserp, size_t size)
+rb_parser_malloc(struct parser_params *parser, size_t size)
{
size_t cnt = HEAPCNT(1, size);
NODE *n = NEWHEAP();
@@ -8735,7 +8739,7 @@ rb_parser_malloc(struct parser_params *parserp, size_t size)
}
void *
-rb_parser_calloc(struct parser_params *parserp, size_t nelem, size_t size)
+rb_parser_calloc(struct parser_params *parser, size_t nelem, size_t size)
{
size_t cnt = HEAPCNT(nelem, size);
NODE *n = NEWHEAP();
@@ -8745,12 +8749,12 @@ rb_parser_calloc(struct parser_params *parserp, size_t nelem, size_t size)
}
void *
-rb_parser_realloc(struct parser_params *parserp, void *ptr, size_t size)
+rb_parser_realloc(struct parser_params *parser, void *ptr, size_t size)
{
NODE *n;
size_t cnt = HEAPCNT(1, size);
- if (ptr && (n = parserp->heap) != NULL) {
+ if (ptr && (n = parser->heap) != NULL) {
do {
if (n->u1.node == ptr) {
n->u1.node = ptr = xrealloc(ptr, size);
@@ -8765,9 +8769,9 @@ rb_parser_realloc(struct parser_params *parserp, void *ptr, size_t size)
}
void
-rb_parser_free(struct parser_params *parserp, void *ptr)
+rb_parser_free(struct parser_params *parser, void *ptr)
{
- NODE **prev = &parserp->heap, *n;
+ NODE **prev = &parser->heap, *n;
while ((n = *prev) != NULL) {
if (n->u1.node == ptr) {
diff --git a/re.c b/re.c
index ec82593395..f8af10a7f3 100644
--- a/re.c
+++ b/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;
}
diff --git a/ruby.c b/ruby.c
index c126274c4a..e58d069382 100644
--- a/ruby.c
+++ b/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;
}
diff --git a/yarvcore.c b/yarvcore.c
index 2273ef81cb..b25de4afc4 100644
--- a/yarvcore.c
+++ b/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;
diff --git a/yarvcore.h b/yarvcore.h
index d72ed96951..149a57fd10 100644
--- a/yarvcore.h
+++ b/yarvcore.h
@@ -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 */