summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2007-12-05 07:18:52 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2007-12-05 07:18:52 +0000
commit430f5a1d61a1dae175f1e29840f7e7a91c1eaf1c (patch)
treed1d470920c2bda4178cd7d5545c46955005c4953
parent0af432ce08b33428b9dc6c5c60ffccee3f60fd77 (diff)
* proc.c (rb_proc_s_new): call initialize. [ruby-core:13824]
* proc.c (rb_proc_location): return file name and line number where the proc is defined. * thread.c (thread_s_new): call initialize. [ruby-core:13835] * thread.c (thread_initialize): split initialize method. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@14109 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog11
-rw-r--r--proc.c39
-rw-r--r--thread.c58
-rw-r--r--vm.c7
4 files changed, 100 insertions, 15 deletions
diff --git a/ChangeLog b/ChangeLog
index 30468466c7..acac149a43 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+Wed Dec 5 16:18:50 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * proc.c (rb_proc_s_new): call initialize. [ruby-core:13824]
+
+ * proc.c (rb_proc_location): return file name and line number where
+ the proc is defined.
+
+ * thread.c (thread_s_new): call initialize. [ruby-core:13835]
+
+ * thread.c (thread_initialize): split initialize method.
+
Wed Dec 5 15:25:55 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
* parse.y (rb_intern3): fix to changing encoding to default, and
diff --git a/proc.c b/proc.c
index 5f9e697f3e..d2bf571393 100644
--- a/proc.c
+++ b/proc.c
@@ -304,9 +304,12 @@ proc_new(VALUE klass, int is_lambda)
*/
static VALUE
-rb_proc_s_new(VALUE klass)
+rb_proc_s_new(int argc, VALUE *argv, VALUE klass)
{
- return proc_new(klass, Qfalse);
+ VALUE block = proc_new(klass, Qfalse);
+
+ rb_obj_call_init(block, argc, argv);
+ return block;
}
/*
@@ -471,6 +474,36 @@ rb_proc_arity(VALUE proc)
return FIX2INT(proc_arity(proc));
}
+static rb_iseq_t *
+get_proc_iseq(VALUE self)
+{
+ rb_proc_t *proc;
+ rb_iseq_t *iseq;
+
+ GetProcPtr(self, proc);
+ iseq = proc->block.iseq;
+ if (!RUBY_VM_NORMAL_ISEQ_P(iseq))
+ return 0;
+ return iseq;
+}
+
+VALUE
+rb_proc_location(VALUE self)
+{
+ rb_iseq_t *iseq = get_proc_iseq(self);
+ VALUE loc[2];
+
+ if (!iseq) return Qnil;
+ loc[0] = iseq->filename;
+ if (iseq->insn_info_table) {
+ loc[1] = INT2FIX(iseq->insn_info_table[0].line_no);
+ }
+ else {
+ loc[1] = Qnil;
+ }
+ return rb_ary_new4(2, loc);
+}
+
/*
* call-seq:
* prc == other_proc => true or false
@@ -1438,7 +1471,7 @@ Init_Proc(void)
/* Proc */
rb_cProc = rb_define_class("Proc", rb_cObject);
rb_undef_alloc_func(rb_cProc);
- rb_define_singleton_method(rb_cProc, "new", rb_proc_s_new, 0);
+ rb_define_singleton_method(rb_cProc, "new", rb_proc_s_new, -1);
rb_define_method(rb_cProc, "call", proc_call, -1);
rb_define_method(rb_cProc, "[]", proc_call, -1);
rb_define_method(rb_cProc, "yield", proc_yield, -1);
diff --git a/thread.c b/thread.c
index e03e23a1bb..8d7d538328 100644
--- a/thread.c
+++ b/thread.c
@@ -373,13 +373,10 @@ thread_start_func_2(rb_thread_t *th, VALUE *stack_start, VALUE *register_stack_s
}
static VALUE
-thread_create_core(VALUE klass, VALUE args, VALUE (*fn)(ANYARGS))
+thread_create_core(VALUE thval, VALUE args, VALUE (*fn)(ANYARGS))
{
rb_thread_t *th;
- VALUE thval;
- /* create thread object */
- thval = rb_thread_alloc(klass);
GetThreadPtr(thval, th);
/* setup thread environment */
@@ -407,15 +404,55 @@ thread_create_core(VALUE klass, VALUE args, VALUE (*fn)(ANYARGS))
*/
static VALUE
-thread_s_new(VALUE klass, VALUE args)
+thread_s_new(int argc, VALUE *argv, VALUE klass)
{
- return thread_create_core(klass, args, 0);
+ rb_thread_t *th;
+ VALUE thread = rb_thread_alloc(klass);
+ rb_obj_call_init(thread, argc, argv);
+ GetThreadPtr(thread, th);
+ if (!th->first_args) {
+ rb_raise(rb_eThreadError, "uninitialized thread - check `%s#initialize'",
+ rb_class2name(klass));
+ }
+ return thread;
+}
+
+static VALUE
+thread_start(VALUE klass, VALUE args)
+{
+ return thread_create_core(rb_thread_alloc(klass), args, 0);
+}
+
+static VALUE
+thread_initialize(VALUE thread, VALUE args)
+{
+ rb_thread_t *th;
+ if (!rb_block_given_p()) {
+ rb_raise(rb_eThreadError, "must be called with a block");
+ }
+ GetThreadPtr(thread, th);
+ if (th->first_args) {
+ VALUE rb_proc_location(VALUE self);
+ VALUE proc = th->first_proc, line, loc;
+ const char *file;
+ if (!proc || !RTEST(loc = rb_proc_location(proc))) {
+ rb_raise(rb_eThreadError, "already initialized thread");
+ }
+ fn = RSTRING_PTR(RARRAY_PTR(loc)[0]);
+ if (NIL_P(line = RARRAY_PTR(loc)[1])) {
+ rb_raise(rb_eThreadError, "already initialized thread - %s",
+ file);
+ }
+ rb_raise(rb_eThreadError, "already initialized thread - %s:%d",
+ file, NUM2INT(line));
+ }
+ return thread_create_core(thread, args, 0);
}
VALUE
rb_thread_create(VALUE (*fn)(ANYARGS), void *arg)
{
- return thread_create_core(rb_cThread, (VALUE)arg, fn);
+ return thread_create_core(rb_thread_alloc(rb_cThread), (VALUE)arg, fn);
}
@@ -2986,9 +3023,9 @@ Init_Thread(void)
{
VALUE cThGroup;
- rb_define_singleton_method(rb_cThread, "new", thread_s_new, -2);
- rb_define_singleton_method(rb_cThread, "start", thread_s_new, -2);
- rb_define_singleton_method(rb_cThread, "fork", thread_s_new, -2);
+ rb_define_singleton_method(rb_cThread, "new", thread_s_new, -1);
+ rb_define_singleton_method(rb_cThread, "start", thread_start, -2);
+ rb_define_singleton_method(rb_cThread, "fork", thread_start, -2);
rb_define_singleton_method(rb_cThread, "main", rb_thread_s_main, 0);
rb_define_singleton_method(rb_cThread, "current", thread_s_current, 0);
rb_define_singleton_method(rb_cThread, "stop", rb_thread_stop, 0);
@@ -3005,6 +3042,7 @@ Init_Thread(void)
rb_define_singleton_method(rb_cThread, "DEBUG=", rb_thread_s_debug_set, 1);
#endif
+ rb_define_method(rb_cThread, "initialize", thread_initialize, -2);
rb_define_method(rb_cThread, "raise", thread_raise_m, -1);
rb_define_method(rb_cThread, "join", thread_join_m, -1);
rb_define_method(rb_cThread, "value", thread_value, 0);
diff --git a/vm.c b/vm.c
index 02d7986942..ea9e2a5b62 100644
--- a/vm.c
+++ b/vm.c
@@ -1664,11 +1664,14 @@ static VALUE
thread_alloc(VALUE klass)
{
VALUE volatile obj;
- //rb_thread_t *th = thread_recycle_struct();
- //obj = Data_Wrap_Struct(klass, rb_thread_mark, thread_free, th);
+#ifdef USE_THREAD_RECYCLE
+ rb_thread_t *th = thread_recycle_struct();
+ obj = Data_Wrap_Struct(klass, rb_thread_mark, thread_free, th);
+#else
rb_thread_t *th;
obj = Data_Make_Struct(klass, rb_thread_t,
rb_thread_mark, thread_free, th);
+#endif
return obj;
}