summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog51
-rwxr-xr-xbin/erb2
-rw-r--r--env.h32
-rw-r--r--eval.c135
-rw-r--r--lib/cgi.rb2
-rw-r--r--lib/monitor.rb12
-rw-r--r--object.c24
-rw-r--r--rubysig.h17
-rw-r--r--st.c26
9 files changed, 214 insertions, 87 deletions
diff --git a/ChangeLog b/ChangeLog
index 66068301b1..2f15bd72f9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
diff --git a/bin/erb b/bin/erb
index 32f8102ecf..a6fcd5370c 100755
--- a/bin/erb
+++ b/bin/erb
@@ -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
diff --git a/env.h b/env.h
index e47536bb5f..9f14c2c65f 100644
--- a/env.h
+++ b/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 */
diff --git a/eval.c b/eval.c
index e88500d2c4..5932a1bba3 100644
--- a/eval.c
+++ b/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)";
@@ -6424,6 +6409,38 @@ rb_obj_instance_eval(int argc, VALUE *argv, VALUE 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
* mod.module_eval {|| block } => 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;
diff --git a/lib/cgi.rb b/lib/cgi.rb
index 1f5a3b0701..43122212d5 100644
--- a/lib/cgi.rb
+++ b/lib/cgi.rb
@@ -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)
diff --git a/lib/monitor.rb b/lib/monitor.rb
index c1ce7815ea..e56480b763 100644
--- a/lib/monitor.rb
+++ b/lib/monitor.rb
@@ -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
#
diff --git a/object.c b/object.c
index 694fcf3159..9f39ec3117 100644
--- a/object.c
+++ b/object.c
@@ -729,6 +729,22 @@ nil_to_s(VALUE obj)
/*
* 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"
*
* Always returns the string "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);
diff --git a/rubysig.h b/rubysig.h
index 840e1487a4..ac5519c13a 100644
--- a/rubysig.h
+++ b/rubysig.h
@@ -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
diff --git a/st.c b/st.c
index 812b57fd0f..5aa202fe7d 100644
--- a/st.c
+++ b/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--;
}
}