From 3e9e2bd4ed14de63e8e18e779a5e8c1060ea5bcf Mon Sep 17 00:00:00 2001 From: matz Date: Sat, 30 Oct 2004 06:56:18 +0000 Subject: * eval.c (rb_eval): NODE_XSTR should pass copy of literal string. * array.c (rb_ary_update): a[n,m]=nil no longer works as element deletion. * enum.c (enum_sort_by): protect continuation jump in. [ruby-dev:24642] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@7145 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 12 +++++ Makefile.in | 2 +- array.c | 6 +-- configure.in | 5 -- enum.c | 3 ++ eval.c | 9 ++-- ext/win32ole/win32ole.c | 2 +- gc.c | 6 +-- node.h | 7 +-- parse.y | 17 ++++-- regcomp.c | 15 +++++- regexec.c | 111 +++++++++++++++++--------------------- regint.h | 2 + regparse.c | 1 + regparse.h | 3 ++ test/ripper/test_parser_events.rb | 2 +- variable.c | 2 +- 17 files changed, 116 insertions(+), 89 deletions(-) diff --git a/ChangeLog b/ChangeLog index a0389c239e..167b363a8f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,18 @@ Sat Oct 30 15:24:41 2004 Masaki Suketa * ext/win32ole/tests/testOLETYPELIB.rb: add WIN32OLE_TYPELIB class. +Sat Oct 30 06:53:24 2004 Peter Vanbroekhoven + + * eval.c (rb_eval): NODE_XSTR should pass copy of literal string. + +Sat Oct 30 00:19:40 2004 Yukihiro Matsumoto + + * array.c (rb_ary_update): a[n,m]=nil no longer works as element + deletion. + + * enum.c (enum_sort_by): protect continuation jump in. + [ruby-dev:24642] + Fri Oct 29 21:27:51 2004 Nobuyoshi Nakada * io.c (rb_io_check_initialized): new function to check uninitialized diff --git a/Makefile.in b/Makefile.in index f722bc7926..21469a7fec 100644 --- a/Makefile.in +++ b/Makefile.in @@ -6,7 +6,7 @@ srcdir = @srcdir@ VPATH = $(srcdir):$(srcdir)/missing CC = @CC@ -YACC = @YACC@ +YACC = bison -y PURIFY = AUTOCONF = autoconf @SET_MAKE@ diff --git a/array.c b/array.c index 8c202a1fdc..8d173d8a06 100644 --- a/array.c +++ b/array.c @@ -1091,7 +1091,7 @@ rb_ary_update(ary, beg, len, rpl) } rb_ary_modify(ary); - if (NIL_P(rpl)) { + if (rpl == Qundef) { rlen = 0; } else { @@ -1683,7 +1683,7 @@ ary_sort_check(data) struct ary_sort_data *data; { if (RARRAY(data->ary)->ptr != data->ptr || RARRAY(data->ary)->len != data->len) { - rb_raise(rb_eArgError, "array modified during sort"); + rb_raise(rb_eRuntimeError, "array modified during sort"); } } @@ -2085,7 +2085,7 @@ rb_ary_slice_bang(argc, argv, ary) pos = RARRAY(ary)->len + pos; } arg2 = rb_ary_subseq(ary, pos, len); - rb_ary_update(ary, pos, len, Qnil); /* Qnil/rb_ary_new2(0) */ + rb_ary_update(ary, pos, len, Qundef); /* Qnil/rb_ary_new2(0) */ return arg2; } diff --git a/configure.in b/configure.in index e0da54413d..2ca62ff04b 100644 --- a/configure.in +++ b/configure.in @@ -157,11 +157,6 @@ AC_SUBST(OUTFLAG) RUBY_MINGW32 -AC_PROG_YACC -if test "$YACC" = "yacc"; then - AC_DEFINE([OLD_YACC]) -fi - AC_CHECK_TOOL(RANLIB, ranlib, :) AC_CHECK_TOOL(AR, ar) if test -z "$AR"; then diff --git a/enum.c b/enum.c index bcb62c418a..8e3531092c 100644 --- a/enum.c +++ b/enum.c @@ -494,6 +494,9 @@ enum_sort_by(obj) if (RARRAY(ary)->len > 1) { qsort(RARRAY(ary)->ptr, RARRAY(ary)->len, sizeof(VALUE), sort_by_cmp, 0); } + if (RBASIC(ary)->klass) { + rb_raise(rb_eRuntimeError, "sort_by reentered"); + } for (i=0; ilen; i++) { RARRAY(ary)->ptr[i] = RNODE(RARRAY(ary)->ptr[i])->u2.value; } diff --git a/eval.c b/eval.c index a8df3ebd1b..e26e1652cc 100644 --- a/eval.c +++ b/eval.c @@ -3640,7 +3640,7 @@ rb_eval(self, n) break; case NODE_XSTR: - result = rb_funcall(self, '`', 1, node->nd_lit); + result = rb_funcall(self, '`', 1, rb_str_new3(node->nd_lit)); break; case NODE_LIT: @@ -3731,7 +3731,7 @@ rb_eval(self, n) if (NIL_P(ruby_class)) { rb_raise(rb_eTypeError, "no class to undef method"); } - rb_undef(ruby_class, node->nd_mid); + rb_undef(ruby_class, rb_to_id(rb_eval(self, node->u2.node))); result = Qnil; break; @@ -3739,12 +3739,13 @@ rb_eval(self, n) if (NIL_P(ruby_class)) { rb_raise(rb_eTypeError, "no class to make alias"); } - rb_alias(ruby_class, node->nd_new, node->nd_old); + rb_alias(ruby_class, rb_to_id(rb_eval(self, node->u1.node)), + rb_to_id(rb_eval(self, node->u2.node))); result = Qnil; break; case NODE_VALIAS: - rb_alias_variable(node->nd_new, node->nd_old); + rb_alias_variable(node->u1.id, node->u2.id); result = Qnil; break; diff --git a/ext/win32ole/win32ole.c b/ext/win32ole/win32ole.c index be230daf90..4715a4d44a 100644 --- a/ext/win32ole/win32ole.c +++ b/ext/win32ole/win32ole.c @@ -1816,7 +1816,7 @@ fole_initialize(argc, argv, self) SysFreeString(pBuf); if(FAILED(hr)) { ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, - "Unknown OLE server `%s'", + "Unknown OLE server: `%s'", StringValuePtr(svr_name)); } diff --git a/gc.c b/gc.c index 180e9b5f3a..e7c4130bfb 100644 --- a/gc.c +++ b/gc.c @@ -806,6 +806,8 @@ gc_mark_children(ptr, lev) case NODE_OP_ASGN_OR: case NODE_OP_ASGN_AND: case NODE_MODULE: + case NODE_ALIAS: + case NODE_VALIAS: gc_mark((VALUE)obj->as.node.u1.node, lev); /* fall through */ case NODE_METHOD: /* 2 */ @@ -820,6 +822,7 @@ gc_mark_children(ptr, lev) case NODE_COLON3: case NODE_OPT_N: case NODE_EVSTR: + case NODE_UNDEF: ptr = (VALUE)obj->as.node.u2.node; goto again; @@ -859,11 +862,8 @@ gc_mark_children(ptr, lev) case NODE_CVAR: case NODE_NTH_REF: case NODE_BACK_REF: - case NODE_ALIAS: - case NODE_VALIAS: case NODE_REDO: case NODE_RETRY: - case NODE_UNDEF: case NODE_SELF: case NODE_NIL: case NODE_TRUE: diff --git a/node.h b/node.h index 3eb8e8716a..df822462e5 100644 --- a/node.h +++ b/node.h @@ -217,9 +217,6 @@ typedef struct RNode { #define nd_noex u1.id #define nd_defn u3.node -#define nd_old u1.id -#define nd_new u2.id - #define nd_cfnc u1.cfunc #define nd_argc u2.argc @@ -319,8 +316,8 @@ typedef struct RNode { #define NEW_SVALUE(a) NEW_NODE(NODE_SVALUE,a,0,0) #define NEW_BLOCK_ARG(v) NEW_NODE(NODE_BLOCK_ARG,v,0,local_cnt(v)) #define NEW_BLOCK_PASS(b) NEW_NODE(NODE_BLOCK_PASS,0,b,0) -#define NEW_ALIAS(n,o) NEW_NODE(NODE_ALIAS,o,n,0) -#define NEW_VALIAS(n,o) NEW_NODE(NODE_VALIAS,o,n,0) +#define NEW_ALIAS(n,o) NEW_NODE(NODE_ALIAS,n,o,0) +#define NEW_VALIAS(n,o) NEW_NODE(NODE_VALIAS,n,o,0) #define NEW_UNDEF(i) NEW_NODE(NODE_UNDEF,0,i,0) #define NEW_CLASS(n,b,s) NEW_NODE(NODE_CLASS,n,NEW_SCOPE(b),(s)) #define NEW_SCLASS(r,b) NEW_NODE(NODE_SCLASS,r,NEW_SCOPE(b),0) diff --git a/parse.y b/parse.y index 4b5c02774c..51a37da65b 100644 --- a/parse.y +++ b/parse.y @@ -490,9 +490,9 @@ static void ripper_compile_error _((struct parser_params*, const char *fmt, ...) %type f_arglist f_args f_optarg f_opt f_block_arg opt_f_block_arg %type assoc_list assocs assoc kwargs undef_list backref string_dvar %type for_var block_var opt_block_var block_par -%type brace_block cmd_brace_block do_block lhs none +%type brace_block cmd_brace_block do_block lhs none fitem %type mlhs mlhs_head mlhs_basic mlhs_entry mlhs_item mlhs_node -%type fitem variable sym symbol operation operation2 operation3 +%type fsym variable sym symbol operation operation2 operation3 %type cname fname op f_rest_arg %type f_norm_arg f_arg /*%%%*/ @@ -1511,10 +1511,21 @@ fname : tIDENTIFIER } ; -fitem : fname +fsym : fname | symbol ; +fitem : fsym + { + /*%%%*/ + $$ = NEW_LIT(ID2SYM($1)); + /*% + $$ = dispatch1(symbol_literal, $1); + %*/ + } + | dsym + ; + undef_list : fitem { /*%%%*/ diff --git a/regcomp.c b/regcomp.c index de44cfe037..b1a7b0ad14 100644 --- a/regcomp.c +++ b/regcomp.c @@ -684,7 +684,16 @@ compile_range_repeat_node(QualifierNode* qn, int target_len, int empty_info, r = compile_tree_empty_check(qn->target, reg, empty_info); if (r) return r; - r = add_opcode(reg, qn->greedy ? OP_REPEAT_INC : OP_REPEAT_INC_NG); + if ( + #ifdef USE_SUBEXP_CALL + reg->num_call > 0 || + #endif + IS_QUALIFIER_IN_REPEAT(qn)) { + r = add_opcode(reg, qn->greedy ? OP_REPEAT_INC_SG : OP_REPEAT_INC_NG_SG); + } + else { + r = add_opcode(reg, qn->greedy ? OP_REPEAT_INC : OP_REPEAT_INC_NG); + } if (r) return r; r = add_mem_num(reg, num_repeat); /* OP_REPEAT ID */ return r; @@ -3057,6 +3066,10 @@ setup_tree(Node* node, regex_t* reg, int state, ScanEnv* env) QualifierNode* qn = &(NQUALIFIER(node)); Node* target = qn->target; + if ((state & IN_REPEAT) != 0) { + qn->state |= NST_IN_REPEAT; + } + if (IS_REPEAT_INFINITE(qn->upper) || qn->upper >= 1) { r = get_min_match_length(target, &d, env); if (r) break; diff --git a/regexec.c b/regexec.c index 1bae0d9516..7c8ffa47a9 100644 --- a/regexec.c +++ b/regexec.c @@ -1053,6 +1053,7 @@ match_at(regex_t* reg, UChar* str, UChar* end, UChar* sstart, char *alloca_base; StackType *stk_alloc, *stk_base, *stk, *stk_end; StackType *stkp; /* used as any purpose. */ + StackIndex si; StackIndex *repeat_stk; StackIndex *mem_start_stk, *mem_end_stk; n = reg->num_repeat + reg->num_mem * 2; @@ -2170,79 +2171,67 @@ match_at(regex_t* reg, UChar* str, UChar* end, UChar* sstart, break; case OP_REPEAT_INC: STAT_OP_IN(OP_REPEAT_INC); - { - StackIndex si; + GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */ + si = repeat_stk[mem]; + stkp = STACK_AT(si); - GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */ -#ifdef USE_SUBEXP_CALL - if (reg->num_call > 0) { - STACK_GET_REPEAT(mem, stkp); - si = GET_STACK_INDEX(stkp); - } - else { - si = repeat_stk[mem]; - stkp = STACK_AT(si); - } -#else - si = repeat_stk[mem]; - stkp = STACK_AT(si); -#endif - stkp->u.repeat.count++; - if (stkp->u.repeat.count == reg->repeat_range[mem].upper) { - /* end of repeat. Nothing to do. */ - } - else if (stkp->u.repeat.count >= reg->repeat_range[mem].lower) { - STACK_PUSH_ALT(p, s, sprev); - p = stkp->u.repeat.pcode; - } - else { - p = stkp->u.repeat.pcode; - } - STACK_PUSH_REPEAT_INC(si); + repeat_inc: + stkp->u.repeat.count++; + if (stkp->u.repeat.count == reg->repeat_range[mem].upper) { + /* end of repeat. Nothing to do. */ + } + else if (stkp->u.repeat.count >= reg->repeat_range[mem].lower) { + STACK_PUSH_ALT(p, s, sprev); + p = stkp->u.repeat.pcode; } + else { + p = stkp->u.repeat.pcode; + } + STACK_PUSH_REPEAT_INC(si); STAT_OP_OUT; continue; break; - case OP_REPEAT_INC_NG: STAT_OP_IN(OP_REPEAT_INC_NG); - { - StackIndex si; - - GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */ -#ifdef USE_SUBEXP_CALL - if (reg->num_call > 0) { - STACK_GET_REPEAT(mem, stkp); - si = GET_STACK_INDEX(stkp); - } - else { - si = repeat_stk[mem]; - stkp = STACK_AT(si); - } -#else - si = repeat_stk[mem]; - stkp = STACK_AT(si); -#endif - stkp->u.repeat.count++; - if (stkp->u.repeat.count < reg->repeat_range[mem].upper) { - if (stkp->u.repeat.count >= reg->repeat_range[mem].lower) { - UChar* pcode = stkp->u.repeat.pcode; + case OP_REPEAT_INC_SG: STAT_OP_IN(OP_REPEAT_INC_SG); + GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */ + STACK_GET_REPEAT(mem, stkp); + si = GET_STACK_INDEX(stkp); + goto repeat_inc; + break; - STACK_PUSH_REPEAT_INC(si); - STACK_PUSH_ALT(pcode, s, sprev); - } - else { - p = stkp->u.repeat.pcode; - STACK_PUSH_REPEAT_INC(si); - } - } - else if (stkp->u.repeat.count == reg->repeat_range[mem].upper) { - STACK_PUSH_REPEAT_INC(si); - } + case OP_REPEAT_INC_NG: STAT_OP_IN(OP_REPEAT_INC_NG); + GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */ + si = repeat_stk[mem]; + stkp = STACK_AT(si); + + repeat_inc_ng: + stkp->u.repeat.count++; + if (stkp->u.repeat.count < reg->repeat_range[mem].upper) { + if (stkp->u.repeat.count >= reg->repeat_range[mem].lower) { + UChar* pcode = stkp->u.repeat.pcode; + + STACK_PUSH_REPEAT_INC(si); + STACK_PUSH_ALT(pcode, s, sprev); + } + else { + p = stkp->u.repeat.pcode; + STACK_PUSH_REPEAT_INC(si); + } + } + else if (stkp->u.repeat.count == reg->repeat_range[mem].upper) { + STACK_PUSH_REPEAT_INC(si); } STAT_OP_OUT; continue; break; + case OP_REPEAT_INC_NG_SG: STAT_OP_IN(OP_REPEAT_INC_NG_SG); + GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */ + STACK_GET_REPEAT(mem, stkp); + si = GET_STACK_INDEX(stkp); + goto repeat_inc_ng; + break; + case OP_PUSH_POS: STAT_OP_IN(OP_PUSH_POS); STACK_PUSH_POS(s, sprev); STAT_OP_OUT; diff --git a/regint.h b/regint.h index bcc5fa5fc4..ccbc359301 100644 --- a/regint.h +++ b/regint.h @@ -500,6 +500,8 @@ enum OpCode { OP_REPEAT_NG, /* {n,m}? (non greedy) */ OP_REPEAT_INC, OP_REPEAT_INC_NG, /* non greedy */ + OP_REPEAT_INC_SG, /* search and get in stack */ + OP_REPEAT_INC_NG_SG, /* search and get in stack (non greedy) */ OP_NULL_CHECK_START, /* null loop checker start */ OP_NULL_CHECK_END, /* null loop checker end */ OP_NULL_CHECK_END_MEMST, /* null loop checker end (with capture status) */ diff --git a/regparse.c b/regparse.c index 632e15c30a..67bcbec5eb 100644 --- a/regparse.c +++ b/regparse.c @@ -1058,6 +1058,7 @@ node_new_qualifier(int lower, int upper, int by_number) Node* node = node_new(); CHECK_NULL_RETURN(node); node->type = N_QUALIFIER; + NQUALIFIER(node).state = 0; NQUALIFIER(node).target = NULL; NQUALIFIER(node).lower = lower; NQUALIFIER(node).upper = upper; diff --git a/regparse.h b/regparse.h index b2726becbd..a4acd92208 100644 --- a/regparse.h +++ b/regparse.h @@ -96,6 +96,7 @@ typedef struct { } CClassNode; typedef struct { + int state; struct _Node* target; int lower; int upper; @@ -121,6 +122,7 @@ typedef struct { #define NST_ADDR_FIXED (1<<9) #define NST_NAMED_GROUP (1<<10) #define NST_NAME_REF (1<<11) +#define NST_IN_REPEAT (1<<12) /* STK_REPEAT is nested in match stack. */ #define SET_EFFECT_STATUS(node,f) (node)->u.effect.state |= (f) #define CLEAR_EFFECT_STATUS(node,f) (node)->u.effect.state &= ~(f) @@ -140,6 +142,7 @@ typedef struct { #define IS_CALL_RECURSION(cn) (((cn)->state & NST_RECURSION) != 0) #define IS_CALL_NAME_REF(cn) (((cn)->state & NST_NAME_REF) != 0) #define IS_BACKREF_NAME_REF(bn) (((bn)->state & NST_NAME_REF) != 0) +#define IS_QUALIFIER_IN_REPEAT(qn) (((qn)->state & NST_IN_REPEAT) != 0) typedef struct { int state; diff --git a/test/ripper/test_parser_events.rb b/test/ripper/test_parser_events.rb index db16ec5f17..445321a497 100644 --- a/test/ripper/test_parser_events.rb +++ b/test/ripper/test_parser_events.rb @@ -50,7 +50,7 @@ class TestRipper_ParserEvents < Test::Unit::TestCase end def test_alias - assert_equal '[alias(a,b)]', parse('alias a b') + assert_equal '[alias(symbol_literal(a),symbol_literal(b))]', parse('alias a b') end def test_var_alias diff --git a/variable.c b/variable.c index 695202cd7d..9a9399721a 100644 --- a/variable.c +++ b/variable.c @@ -967,7 +967,7 @@ rb_free_generic_ivar(obj) { st_table *tbl; -// if (!generic_iv_tbl) return; + if (!generic_iv_tbl) return; if (st_delete(generic_iv_tbl, &obj, (st_data_t *)&tbl)) st_free_table(tbl); } -- cgit v1.2.3