From: nobu.nakada@... Date: 2001-05-09T07:30:17+09:00 Subject: [ruby-dev:13150] Re: instance_eval のバグ なかだです。 At Tue, 8 May 2001 16:10:02 +0900, Nobuyoshi-Nakada wrote: > それに StringValuePtr() の変更と VALUE のスコープの確認だけで > 済みそうかも? 試してみました。 BUILTIN_TYPE_P() というのは t が定数のとき専用の姑息な最適化 です。ブランチが減るのでここだけをみれば倍くらいになります。 rb_feature_p() は rb_str_to_str() の中で rb_features になにか 追加されて REALLOC が起きないとも限らないので、インデックスで回 すようにしてみました。いっそ rb_features の要素自身を String に してしまってもいいような気もしますが。 それと、関係ないですけど tcltklib.c の RSTRING(s) というのは まずいですよね。 Index: eval.c =================================================================== RCS file: /cvs/ruby/src/ruby/eval.c,v retrieving revision 1.175 diff -u -2 -p -r1.175 eval.c --- eval.c 2001/05/07 09:26:23 1.175 +++ eval.c 2001/05/08 21:38:18 @@ -5207,17 +5207,14 @@ rb_feature_p(feature, wait) int wait; { - VALUE *p, *pend; + VALUE v; char *f; - int len; + int i, len = strlen(feature); - p = RARRAY(rb_features)->ptr; - pend = p + RARRAY(rb_features)->len; - while (p < pend) { - VALUE v = *p; + for (i = 0; i < RARRAY(rb_features)->len; ++i) { + v = RARRAY(rb_features)->ptr[i]; f = StringValuePtr(v); if (strcmp(f, feature) == 0) { goto load_wait; } - len = strlen(feature); if (strncmp(f, feature, len) == 0) { if (strcmp(f+len, ".so") == 0) { @@ -5229,5 +5226,4 @@ rb_feature_p(feature, wait) } } - p++; } return Qfalse; Index: file.c =================================================================== RCS file: /cvs/ruby/src/ruby/file.c,v retrieving revision 1.54 diff -u -2 -p -r1.54 file.c --- file.c 2001/05/02 04:22:10 1.54 +++ file.c 2001/05/08 15:35:23 @@ -2207,6 +2207,5 @@ rb_find_file(file) { extern VALUE rb_load_path; - volatile VALUE vpath; - VALUE fname; + VALUE vpath, fname; char *path; struct stat st; Index: ruby.h =================================================================== RCS file: /cvs/ruby/src/ruby/ruby.h,v retrieving revision 1.45 diff -u -2 -p -r1.45 ruby.h --- ruby.h 2001/05/02 04:22:11 1.45 +++ ruby.h 2001/05/08 14:02:27 @@ -183,21 +183,26 @@ VALUE rb_uint2inum _((unsigned long)); #define TYPE(x) rb_type((VALUE)(x)) +#define BUILTIN_TYPE_P(obj, t) (\ + ((t) == T_FIXNUM) ? FIXNUM_P(obj) : \ + ((t) == T_NIL) ? NIL_P(obj) : \ + ((t) == T_FALSE) ? ((VALUE)(obj) == Qfalse) : \ + ((t) == T_TRUE) ? ((VALUE)(obj) == Qtrue) : \ + ((t) == T_UNDEF) ? ((VALUE)(obj) == Qundef) : \ + ((t) == T_SYMBOL) ? SYMBOL_P(obj) : \ + rb_builtin_type_p(obj, t)) + void rb_check_type _((VALUE,int)); #define Check_Type(v,t) rb_check_type((VALUE)(v),t) VALUE rb_str_to_str _((VALUE)); -#define StringValue(v) do {\ - if (TYPE(v) != T_STRING) v = rb_str_to_str(v);\ -} while (0) +#define StringValue(v) \ + (BUILTIN_TYPE_P(v, T_STRING) ? (v) : (v = rb_str_to_str(v))) void rb_check_safe_str _((VALUE)); /* obsolete macro - use SafeStringValue(v) */ #define Check_SafeStr(v) rb_check_safe_str((VALUE)(v)) -#define SafeStringValue(v) do {\ - if (TYPE(v) != T_STRING) v = rb_str_to_str(v);\ - rb_check_safe_str(v);\ -} while (0) +#define SafeStringValue(v) rb_check_safe_str(StringValue(v)) -#define StringValuePtr(v) \ - (((TYPE(v) != T_STRING) ? v = rb_str_to_str(v) : (v)), RSTRING(v)->ptr) +char *rb_string_value_ptr _((VALUE *)); +#define StringValuePtr(v) rb_string_value_ptr(&(v)) void rb_secure _((int)); @@ -598,4 +603,17 @@ rb_type(obj) if (SYMBOL_P(obj)) return T_SYMBOL; return BUILTIN_TYPE(obj); +} + +static inline int +#if defined(__cplusplus) +rb_builtin_type_p(VALUE obj, int t) +#else +rb_builtin_type_p(obj, t) + VALUE obj; + int t; +#endif +{ + if (SPECIAL_CONST_P(obj) || BUILTIN_TYPE(obj) != t) return Qfalse; + return Qtrue; } Index: string.c =================================================================== RCS file: /cvs/ruby/src/ruby/string.c,v retrieving revision 1.63 diff -u -2 -p -r1.63 string.c --- string.c 2001/05/06 15:01:59 1.63 +++ string.c 2001/05/08 13:51:46 @@ -140,4 +140,11 @@ rb_str_to_str(str) } +char* +rb_string_value_ptr(v) + VALUE *v; +{ + return RSTRING(StringValue(*v))->ptr; +} + static void rb_str_become(str, str2) Index: ext/tcltklib/tcltklib.c =================================================================== RCS file: /cvs/ruby/src/ruby/ext/tcltklib/tcltklib.c,v retrieving revision 1.7 diff -u -2 -p -r1.7 tcltklib.c --- ext/tcltklib/tcltklib.c 2001/05/06 15:04:02 1.7 +++ ext/tcltklib/tcltklib.c 2001/05/08 00:53:18 @@ -344,5 +344,4 @@ ip_invoke_real(argc, argv, obj) VALUE obj; { - VALUE v; struct tcltkip *ptr; /* tcltkip data struct */ int i; @@ -359,6 +358,5 @@ ip_invoke_real(argc, argv, obj) /* get the command name string */ - v = argv[0]; - cmd = StringValuePtr(v); + cmd = StringValuePtr(argv[0]); /* map from the command name to a C procedure */ @@ -373,7 +371,6 @@ ip_invoke_real(argc, argv, obj) ov = (Tcl_Obj **)ALLOCA_N(Tcl_Obj *, argc+1); for (i = 0; i < argc; ++i) { - VALUE v = argv[i]; - s = StringValuePtr(v); - ov[i] = Tcl_NewStringObj(s, RSTRING(s)->len); + s = StringValuePtr(argv[i]); + ov[i] = Tcl_NewStringObj(s, RSTRING(argv[i])->len); Tcl_IncrRefCount(ov[i]); } @@ -386,6 +383,5 @@ ip_invoke_real(argc, argv, obj) av = (char **)ALLOCA_N(char *, argc+1); for (i = 0; i < argc; ++i) { - v = argv[i]; - s = StringValuePtr(v); + s = StringValuePtr(argv[i]); av[i] = ALLOCA_N(char, strlen(s)+1); strcpy(av[i], s); -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦