* bin/erb (ERB::Main::run): typo fixed. [ruby-core:06337]

* env.h: move struct METHOD and struct BLOCK from eval.c to
  support NodeWrap and ParseTree.

* rubysig.h (CHECK_INTS): prevent signal handler to run during
  critical section.  [ruby-core:04039]

* eval.c (load_wait): need not to call rb_thread_schedule()
  explicitly.  [ruby-core:04039]

* eval.c (rb_thread_schedule): clear rb_thread_critical.
  [ruby-core:04039]

* eval.c (rb_obj_instance_exec): create instance_exec and
  module_exec which pass arguments to the block.

* eval.c (rb_f_funcall): rename fcall to funcall to follow
  tradition.

* st.c (st_free_table): do not call free() but xfree().
  [ruby-core:06205]

* eval.c (splat_value): call rb_Array() to convert svalue to
  values.  [ruby-dev:27397]

* lib/cgi.rb (CGI::Cookie::parse): Cookies from Nokia devices may
  not be parsed correctly.  A patch from August Z. Flatby
  (augustzf) in [ruby-Patches-2595].  [ruby-core:06183]

* object.c (rb_Array): Array() to raise error for objects without
  to_ary, nor to_a.

* object.c (nil_to_a): revert NilClass#to_a.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9436 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
matz 2005-10-21 09:00:02 +00:00
Родитель 73f94bb851
Коммит 5b014a7427
9 изменённых файлов: 214 добавлений и 87 удалений

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

@ -1,3 +1,7 @@
Fri Oct 21 17:49:32 2005 Yukihiro Matsumoto <matz@ruby-lang.org>
* bin/erb (ERB::Main::run): typo fixed. [ruby-core:06337]
Fri Oct 21 15:42:28 2005 Hirokazu Yamamoto <ocean@m2.ccsnet.ne.jp>
* intern.h, struct.c (rb_struct_iv_get): constified.
@ -89,6 +93,11 @@ Mon Oct 17 09:42:50 2005 NAKAMURA Usaku <usa@ruby-lang.org>
* win32/configure.bat (srcdir, target): ditto.
Mon Oct 17 05:01:50 2005 Yukihiro Matsumoto <matz@ruby-lang.org>
* env.h: move struct METHOD and struct BLOCK from eval.c to
support NodeWrap and ParseTree.
Sun Oct 16 22:16:51 2005 Nobuyoshi Nakada <nobu@ruby-lang.org>
* ext/extmk.rb: omit non-existing directories.
@ -100,6 +109,17 @@ Sun Oct 16 14:40:54 2005 Masatoshi SEKI <m_seki@mva.biglobe.ne.jp>
* test/rinda/test_rinda.rb: test it.
Sun Oct 16 03:38:07 2005 Yukihiro Matsumoto <matz@ruby-lang.org>
* rubysig.h (CHECK_INTS): prevent signal handler to run during
critical section. [ruby-core:04039]
* eval.c (load_wait): need not to call rb_thread_schedule()
explicitly. [ruby-core:04039]
* eval.c (rb_thread_schedule): clear rb_thread_critical.
[ruby-core:04039]
Sun Oct 16 00:13:14 2005 NAKAMURA Usaku <usa@ruby-lang.org>
* win32/configure.bat: remove unnecessary line which prevents
@ -134,6 +154,14 @@ Fri Oct 14 16:39:37 2005 GOTOU Yuuzou <gotoyuzo@notwork.org>
It is harmful to permit the access to ~/public_html by default.
suggested by Hiroyuki Iwatsuki.
Fri Oct 14 04:58:38 2005 Yukihiro Matsumoto <matz@ruby-lang.org>
* eval.c (rb_obj_instance_exec): create instance_exec and
module_exec which pass arguments to the block.
* eval.c (rb_f_funcall): rename fcall to funcall to follow
tradition.
Thu Oct 13 23:29:51 2005 Nobuyoshi Nakada <nobu@ruby-lang.org>
* parse.y (HEAPCNT): bison allocates indivisible size.
@ -167,6 +195,11 @@ Tue Oct 11 21:41:58 2005 Nobuyoshi Nakada <nobu@ruby-lang.org>
* eval.c (rb_respond_to): conform to Object#respond_to?. [ruby-dev:27411]
Tue Oct 11 00:01:21 2005 Yukihiro Matsumoto <matz@ruby-lang.org>
* st.c (st_free_table): do not call free() but xfree().
[ruby-core:06205]
Sat Oct 8 19:49:42 2005 Nobuyoshi Nakada <nobu@ruby-lang.org>
* eval.c (Init_Binding): add Binding#dup method. [yarv-dev:666]
@ -193,6 +226,24 @@ Sat Oct 8 19:49:42 2005 Nobuyoshi Nakada <nobu@ruby-lang.org>
* test/net/http/test_http.rb: removed superfluous splatting stars.
Fri Oct 7 16:41:43 2005 Yukihiro Matsumoto <matz@ruby-lang.org>
* eval.c (splat_value): call rb_Array() to convert svalue to
values. [ruby-dev:27397]
Fri Oct 7 09:54:00 2005 Yukihiro Matsumoto <matz@ruby-lang.org>
* lib/cgi.rb (CGI::Cookie::parse): Cookies from Nokia devices may
not be parsed correctly. A patch from August Z. Flatby
(augustzf) in [ruby-Patches-2595]. [ruby-core:06183]
Thu Oct 6 22:51:30 2005 Yukihiro Matsumoto <matz@ruby-lang.org>
* object.c (rb_Array): Array() to raise error for objects without
to_ary, nor to_a.
* object.c (nil_to_a): revert NilClass#to_a.
Thu Oct 6 20:10:38 2005 Minero Aoki <aamine@loveruby.net>
* ext/strscan/strscan.c (strscan_free): remove useless code.

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

@ -60,7 +60,7 @@ class ERB
$DEBUG = true
when '-r' # require
require ARGV.req_arg
when '-S' # sacurity level
when '-S' # security level
arg = ARGV.req_arg
raise "invalid safe_level #{arg.dump}" unless arg =~ /^[0-4]$/
safe_level = arg.to_i

32
env.h
Просмотреть файл

@ -56,4 +56,36 @@ struct RVarmap {
};
RUBY_EXTERN struct RVarmap *ruby_dyna_vars;
struct METHOD {
VALUE klass, rklass;
VALUE recv;
ID id, oid;
int safe_level;
struct RNode *body;
};
struct BLOCK {
struct RNode *var;
struct RNode *body;
VALUE self;
struct FRAME frame;
struct SCOPE *scope;
VALUE klass;
struct RNode *cref;
int iter;
int vmode;
int flags;
int uniq;
struct RVarmap *dyna_vars;
VALUE orig_thread;
VALUE wrapper;
VALUE block_obj;
struct BLOCK *outer;
struct BLOCK *prev;
};
#define BLOCK_D_SCOPE 1
#define BLOCK_LAMBDA 2
#define BLOCK_FROM_METHOD 4
#endif /* ENV_H */

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

@ -689,30 +689,6 @@ static unsigned long frame_unique = 0;
ruby_frame = _frame.prev; \
} while (0)
struct BLOCK {
NODE *var;
NODE *body;
VALUE self;
struct FRAME frame;
struct SCOPE *scope;
VALUE klass;
NODE *cref;
int iter;
int vmode;
int flags;
int uniq;
struct RVarmap *dyna_vars;
VALUE orig_thread;
VALUE wrapper;
VALUE block_obj;
struct BLOCK *outer;
struct BLOCK *prev;
};
#define BLOCK_D_SCOPE 1
#define BLOCK_LAMBDA 2
#define BLOCK_FROM_METHOD 4
static struct BLOCK *ruby_block;
static unsigned long block_unique = 0;
@ -2641,7 +2617,7 @@ avalue_splat(VALUE v)
static VALUE
splat_value(VALUE v)
{
return rb_values_from_ary(rb_convert_type(v, T_ARRAY, "Array", "to_a"));
return rb_values_from_ary(rb_Array(v));
}
static VALUE
@ -5827,7 +5803,7 @@ rb_apply(VALUE recv, ID mid, VALUE args)
}
static VALUE
send_fcall(int argc, VALUE *argv, VALUE recv, int scope)
send_funcall(int argc, VALUE *argv, VALUE recv, int scope)
{
VALUE vid;
@ -5869,25 +5845,25 @@ rb_f_send(int argc, VALUE *argv, VALUE recv)
{
int scope = (ruby_frame->flags & FRAME_FUNC) ? 1 : 0;
return send_fcall(argc, argv, recv, scope);
return send_funcall(argc, argv, recv, scope);
}
/*
* call-seq:
* obj.fcall(symbol [, args...]) => obj
* obj.funcall(symbol [, args...]) => obj
*
* Invokes the method identified by _symbol_, passing it any
* arguments specified. Unlike send, which calls private methods only
* when it is invoked in function call style, fcall always aware of
* when it is invoked in function call style, funcall always aware of
* private methods.
*
* 1.fcall(:puts, "hello") # prints "foo"
* 1.funcall(:puts, "hello") # prints "foo"
*/
static VALUE
rb_f_fcall(int argc, VALUE *argv, VALUE recv)
rb_f_funcall(int argc, VALUE *argv, VALUE recv)
{
return send_fcall(argc, argv, recv, 1);
return send_funcall(argc, argv, recv, 1);
}
VALUE
@ -6336,16 +6312,25 @@ eval_under(VALUE under, VALUE self, VALUE src, const char *file, int line)
}
static VALUE
yield_under_i(VALUE self)
yield_under_i(VALUE arg)
{
return rb_yield_0(self, self, ruby_class, YIELD_PUBLIC_DEF, Qfalse);
VALUE *args = (VALUE *)arg;
VALUE avalue = Qtrue;
if (args[0] == Qundef) {
avalue = Qfalse;
args[0] = args[1];
}
return rb_yield_0(args[0], args[1], ruby_class, YIELD_PUBLIC_DEF, avalue);
}
/* block eval under the class/module context */
static VALUE
yield_under(VALUE under, VALUE self)
yield_under(VALUE under, VALUE self, VALUE values)
{
return exec_under(yield_under_i, under, 0, self);
VALUE args[4];
args[0] = values;
args[1] = self;
return exec_under(yield_under_i, under, 0, (VALUE)args);
}
static VALUE
@ -6355,7 +6340,7 @@ specific_eval(int argc, VALUE *argv, VALUE klass, VALUE self)
if (argc > 0) {
rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)", argc);
}
return yield_under(klass, self);
return yield_under(klass, self, Qundef);
}
else {
char *file = "(eval)";
@ -6422,6 +6407,38 @@ rb_obj_instance_eval(int argc, VALUE *argv, VALUE self)
return specific_eval(argc, argv, klass, self);
}
/*
* call-seq:
* obj.instance_exec(arg...) {|var...| block } => obj
*
* Executes the given block within the context of the receiver
* (_obj_). In order to set the context, the variable +self+ is set
* to _obj_ while the code is executing, giving the code access to
* _obj_'s instance variables. Arguments are passed as block parameters.
*
* class Klass
* def initialize
* @secret = 99
* end
* end
* k = Klass.new
* k.instance_eval(5) {|x| @secret+x } #=> 104
*/
VALUE
rb_obj_instance_exec(int argc, VALUE *argv, VALUE self)
{
VALUE klass;
if (FIXNUM_P(self) || SYMBOL_P(self)) {
klass = Qnil;
}
else {
klass = rb_singleton_class(self);
}
return yield_under(klass, self, rb_values_new2(argc, argv));
}
/*
* call-seq:
* mod.class_eval(string [, filename [, lineno]]) => obj
@ -6452,6 +6469,32 @@ rb_mod_module_eval(int argc, VALUE *argv, VALUE mod)
return specific_eval(argc, argv, mod, mod);
}
/*
* call-seq:
* mod.module_exec(arg...) {|var...| block } => obj
* mod.class_exec(arg...) {|var...| block } => obj
*
* Evaluates the given block in the context of the class/module.
* The method defined in the block will belong to the receiver.
*
* class Thing
* end
* Thing.class_exec{
* def hello() "Hello there!" end
* }
* puts Thing.new.hello()
*
* <em>produces:</em>
*
* Hello there!
*/
VALUE
rb_mod_module_exec(int argc, VALUE *argv, VALUE mod)
{
return yield_under(mod, mod, rb_values_new2(argc, argv));
}
VALUE rb_load_path;
NORETURN(static void load_failed(VALUE));
@ -6699,10 +6742,9 @@ load_wait(char *ftptr)
if (!loading_tbl) return Qfalse;
if (!st_lookup(loading_tbl, (st_data_t)ftptr, &th)) return Qfalse;
if ((rb_thread_t)th == curr_thread) return Qtrue;
do {
if ((rb_thread_t)th == curr_thread) return Qtrue;
CHECK_INTS;
rb_thread_schedule();
} while (st_lookup(loading_tbl, (st_data_t)ftptr, &th));
return Qtrue;
}
@ -7579,8 +7621,9 @@ Init_eval(void)
rb_define_method(rb_mKernel, "send", rb_f_send, -1);
rb_define_method(rb_mKernel, "__send__", rb_f_send, -1);
rb_define_method(rb_mKernel, "fcall", rb_f_fcall, -1);
rb_define_method(rb_mKernel, "funcall", rb_f_funcall, -1);
rb_define_method(rb_mKernel, "instance_eval", rb_obj_instance_eval, -1);
rb_define_method(rb_mKernel, "instance_exec", rb_obj_instance_exec, -1);
rb_define_private_method(rb_cModule, "append_features", rb_mod_append_features, 1);
rb_define_private_method(rb_cModule, "extend_object", rb_mod_extend_object, 1);
@ -7597,6 +7640,8 @@ Init_eval(void)
rb_define_method(rb_cModule, "private_class_method", rb_mod_private_method, -1);
rb_define_method(rb_cModule, "module_eval", rb_mod_module_eval, -1);
rb_define_method(rb_cModule, "class_eval", rb_mod_module_eval, -1);
rb_define_method(rb_cModule, "module_exec", rb_mod_module_exec, -1);
rb_define_method(rb_cModule, "class_exec", rb_mod_module_exec, -1);
rb_undef_method(rb_cClass, "module_function");
@ -8545,14 +8590,6 @@ block_pass(VALUE self, NODE *node)
(VALUE)&arg, rb_eval(self, node->nd_body));
}
struct METHOD {
VALUE klass, rklass;
VALUE recv;
ID id, oid;
int safe_level;
NODE *body;
};
static void
bm_mark(struct METHOD *data)
{
@ -10353,7 +10390,7 @@ rb_thread_schedule(void)
rb_bug("cross-thread violation on rb_thread_schedule()");
}
#endif
rb_thread_pending = 0;
rb_thread_pending = rb_thread_critical = 0;
if (curr_thread == curr_thread->next
&& curr_thread->status == THREAD_RUNNABLE)
return;

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

@ -880,7 +880,7 @@ class CGI
cookies = Hash.new([])
return cookies unless raw_cookie
raw_cookie.split(/[;,] /).each do |pairs|
raw_cookie.split(/[;,]\s?/).each do |pairs|
name, values = pairs.split('=',2)
next unless name and values
name = CGI::unescape(name)

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

@ -87,11 +87,11 @@ module MonitorMixin
class Timeout < Exception; end
def wait(timeout = nil)
@monitor.fcall(:mon_check_owner)
@monitor.funcall(:mon_check_owner)
timer = create_timer(timeout)
Thread.critical = true
count = @monitor.fcall(:mon_exit_for_cond)
count = @monitor.funcall(:mon_exit_for_cond)
@waiters.push(Thread.current)
begin
@ -107,7 +107,7 @@ module MonitorMixin
if @waiters.include?(Thread.current) # interrupted?
@waiters.delete(Thread.current)
end
@monitor.fcall(:mon_enter_for_cond, count)
@monitor.funcall(:mon_enter_for_cond, count)
Thread.critical = false
end
end
@ -125,7 +125,7 @@ module MonitorMixin
end
def signal
@monitor.fcall(:mon_check_owner)
@monitor.funcall(:mon_check_owner)
Thread.critical = true
t = @waiters.shift
t.wakeup if t
@ -134,7 +134,7 @@ module MonitorMixin
end
def broadcast
@monitor.fcall(:mon_check_owner)
@monitor.funcall(:mon_check_owner)
Thread.critical = true
for t in @waiters
t.wakeup
@ -172,7 +172,7 @@ module MonitorMixin
def self.extend_object(obj)
super(obj)
obj.fcall(:mon_initialize)
obj.funcall(:mon_initialize)
end
#

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

@ -727,6 +727,22 @@ nil_to_s(VALUE obj)
return rb_str_new2("");
}
/*
* call-seq:
* nil.to_a => []
*
* Always returns an empty array.
*
* nil.to_a #=> []
*/
static VALUE
nil_to_a(obj)
VALUE obj;
{
return rb_ary_new2(0);
}
/*
* call-seq:
* nil.inspect => "nil"
@ -2236,10 +2252,7 @@ rb_Array(VALUE val)
VALUE tmp = rb_check_array_type(val);
if (NIL_P(tmp)) {
tmp = rb_check_convert_type(val, T_ARRAY, "Array", "to_a");
if (NIL_P(tmp)) {
return rb_ary_new3(1, val);
}
return rb_convert_type(val, T_ARRAY, "Array", "to_a");
}
return tmp;
}
@ -2250,8 +2263,6 @@ rb_Array(VALUE val)
*
* Returns <i>arg</i> as an <code>Array</code>. First tries to call
* <i>arg</i><code>.to_ary</code>, then <i>arg</i><code>.to_a</code>.
* If both fail, creates a single element array containing <i>arg</i>
* (unless <i>arg</i> is <code>nil</code>).
*
* Array(1..5) #=> [1, 2, 3, 4, 5]
*/
@ -2433,6 +2444,7 @@ Init_Object(void)
rb_define_method(rb_cNilClass, "to_i", nil_to_i, 0);
rb_define_method(rb_cNilClass, "to_f", nil_to_f, 0);
rb_define_method(rb_cNilClass, "to_s", nil_to_s, 0);
rb_define_method(rb_cNilClass, "to_a", nil_to_a, 0);
rb_define_method(rb_cNilClass, "inspect", nil_inspect, 0);
rb_define_method(rb_cNilClass, "&", false_and, 1);
rb_define_method(rb_cNilClass, "|", false_or, 1);

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

@ -82,10 +82,9 @@ void rb_thread_schedule(void);
#if defined(HAVE_SETITIMER) || defined(_THREAD_SAFE)
RUBY_EXTERN int rb_thread_pending;
# define CHECK_INTS do {\
if (!rb_prohibit_interrupt) {\
if (!(rb_prohibit_interrupt | rb_thread_critical)) {\
if (rb_thread_pending) rb_thread_schedule();\
if (rb_trap_pending) rb_trap_exec();\
if (rb_thread_pending && !rb_thread_critical)\
rb_thread_schedule();\
}\
} while (0)
#else
@ -93,15 +92,13 @@ RUBY_EXTERN int rb_thread_pending;
RUBY_EXTERN int rb_thread_tick;
#define THREAD_TICK 500
#define CHECK_INTS do {\
if (!rb_prohibit_interrupt) {\
if (rb_trap_pending) rb_trap_exec();\
if (!rb_thread_critical) {\
if (rb_thread_tick-- <= 0) {\
rb_thread_tick = THREAD_TICK;\
rb_thread_schedule();\
}\
if (!(rb_prohibit_interrupt | rb_thread_critical)) {\
if (rb_thread_tick-- <= 0) {\
rb_thread_tick = THREAD_TICK;
rb_thread_schedule();
}\
}\
if (rb_trap_pending) rb_trap_exec();\
} while (0)
#endif

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

@ -4,12 +4,10 @@
#include "config.h"
#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
#include <malloc.h>
#endif
#include <string.h>
#ifdef NOT_RUBY
#include "regint.h"
@ -216,12 +214,12 @@ st_free_table(st_table *table)
ptr = table->bins[i];
while (ptr != 0) {
next = ptr->next;
free(ptr);
xfree(ptr);
ptr = next;
}
}
free(table->bins);
free(table);
xfree(table->bins);
xfree(table);
}
#define PTR_NOT_EQUAL(table, ptr, hash_val, key) \
@ -330,7 +328,7 @@ rehash(register st_table *table)
ptr = next;
}
}
free(table->bins);
xfree(table->bins);
table->num_bins = new_num_bins;
table->bins = new_bins;
}
@ -352,7 +350,7 @@ st_copy(st_table *old_table)
Calloc((unsigned)num_bins, sizeof(st_table_entry*));
if (new_table->bins == 0) {
free(new_table);
xfree(new_table);
return 0;
}
@ -362,8 +360,8 @@ st_copy(st_table *old_table)
while (ptr != 0) {
entry = alloc(st_table_entry);
if (entry == 0) {
free(new_table->bins);
free(new_table);
xfree(new_table->bins);
xfree(new_table);
return 0;
}
*entry = *ptr;
@ -395,7 +393,7 @@ st_delete(register st_table *table, register st_data_t *key, st_data_t *value)
table->num_entries--;
if (value != 0) *value = ptr->record;
*key = ptr->key;
free(ptr);
xfree(ptr);
return 1;
}
@ -406,7 +404,7 @@ st_delete(register st_table *table, register st_data_t *key, st_data_t *value)
table->num_entries--;
if (value != 0) *value = tmp->record;
*key = tmp->key;
free(tmp);
xfree(tmp);
return 1;
}
}
@ -496,7 +494,7 @@ st_foreach(st_table *table, int (*func)(ANYARGS), st_data_t arg)
last->next = ptr->next;
}
ptr = ptr->next;
free(tmp);
xfree(tmp);
table->num_entries--;
}
}