Revision: 1939 http://trac.macosforge.org/projects/ruby/changeset/1939 Author: lsansonetti@apple.com Date: 2009-06-26 16:09:59 -0700 (Fri, 26 Jun 2009) Log Message: ----------- implemented thread locals Modified Paths: -------------- MacRuby/branches/experimental/hash.c MacRuby/branches/experimental/include/ruby/intern.h MacRuby/branches/experimental/thread.c MacRuby/branches/experimental/vm.cpp MacRuby/branches/experimental/vm.h Modified: MacRuby/branches/experimental/hash.c =================================================================== --- MacRuby/branches/experimental/hash.c 2009-06-26 22:10:11 UTC (rev 1938) +++ MacRuby/branches/experimental/hash.c 2009-06-26 23:09:59 UTC (rev 1939) @@ -751,14 +751,14 @@ * h #=> {2=>"b", 3=>"c"} */ -static VALUE rb_hash_keys(VALUE, SEL); +static VALUE rb_hash_keys_imp(VALUE, SEL); static VALUE rb_hash_shift(VALUE hash, SEL sel) { VALUE keys, key, val; - keys = rb_hash_keys(hash, 0); + keys = rb_hash_keys_imp(hash, 0); if (RARRAY_LEN(keys) == 0) { struct rb_objc_hash_struct *s = rb_objc_hash_get_struct(hash); @@ -1243,7 +1243,7 @@ */ static VALUE -rb_hash_keys(VALUE hash, SEL sel) +rb_hash_keys_imp(VALUE hash, SEL sel) { VALUE ary; @@ -1253,6 +1253,12 @@ return ary; } +VALUE +rb_hash_keys(VALUE hash) +{ + return rb_hash_keys_imp(hash, 0); +} + static int values_i(VALUE key, VALUE value, VALUE ary) { @@ -1300,12 +1306,17 @@ */ static VALUE -rb_hash_has_key(VALUE hash, SEL sel, VALUE key) +rb_hash_has_key_imp(VALUE hash, SEL sel, VALUE key) { - if (CFDictionaryContainsKey((CFDictionaryRef)hash, (const void *)RB2OC(key))) - return Qtrue; + return CFDictionaryContainsKey((CFDictionaryRef)hash, + (const void *)RB2OC(key)) + ? Qtrue : Qfalse; +} - return Qfalse; +VALUE +rb_hash_has_key(VALUE hash, VALUE key) +{ + return rb_hash_has_key_imp(hash, 0, key); } /* @@ -1426,7 +1437,7 @@ rb_hash_update_block_i(VALUE key, VALUE value, VALUE hash) { if (key == Qundef) return ST_CONTINUE; - if (rb_hash_has_key(hash, 0, key)) { + if (rb_hash_has_key_imp(hash, 0, key)) { value = rb_yield_values(3, key, rb_hash_aref(hash, key), value); } rb_hash_aset(hash, key, value); @@ -2364,7 +2375,7 @@ void *keys; static SEL objectEnumerator = 0; PREPARE_RCV(rcv); - keys = (void *)rb_hash_keys((VALUE)rcv, 0); + keys = (void *)rb_hash_keys_imp((VALUE)rcv, 0); RESTORE_RCV(rcv); if (objectEnumerator == 0) objectEnumerator = sel_registerName("objectEnumerator"); @@ -2536,7 +2547,7 @@ rb_objc_define_method(rb_cHash, "each_pair", rb_hash_each_pair, 0); rb_objc_define_method(rb_cHash, "each", rb_hash_each_pair, 0); - rb_objc_define_method(rb_cHash, "keys", rb_hash_keys, 0); + rb_objc_define_method(rb_cHash, "keys", rb_hash_keys_imp, 0); rb_objc_define_method(rb_cHash, "values", rb_hash_values, 0); rb_objc_define_method(rb_cHash, "values_at", rb_hash_values_at, -1); @@ -2560,11 +2571,11 @@ rb_objc_define_method(rb_cHash, "rassoc", rb_hash_rassoc, 1); rb_objc_define_method(rb_cHash, "flatten", rb_hash_flatten, -1); - rb_objc_define_method(rb_cHash, "include?", rb_hash_has_key, 1); - rb_objc_define_method(rb_cHash, "member?", rb_hash_has_key, 1); - rb_objc_define_method(rb_cHash, "has_key?", rb_hash_has_key, 1); + rb_objc_define_method(rb_cHash, "include?", rb_hash_has_key_imp, 1); + rb_objc_define_method(rb_cHash, "member?", rb_hash_has_key_imp, 1); + rb_objc_define_method(rb_cHash, "has_key?", rb_hash_has_key_imp, 1); rb_objc_define_method(rb_cHash, "has_value?", rb_hash_has_value, 1); - rb_objc_define_method(rb_cHash, "key?", rb_hash_has_key, 1); + rb_objc_define_method(rb_cHash, "key?", rb_hash_has_key_imp, 1); rb_objc_define_method(rb_cHash, "value?", rb_hash_has_value, 1); rb_objc_define_method(rb_cHash, "compare_by_identity", rb_hash_compare_by_id, 0); Modified: MacRuby/branches/experimental/include/ruby/intern.h =================================================================== --- MacRuby/branches/experimental/include/ruby/intern.h 2009-06-26 22:10:11 UTC (rev 1938) +++ MacRuby/branches/experimental/include/ruby/intern.h 2009-06-26 23:09:59 UTC (rev 1939) @@ -364,6 +364,8 @@ VALUE rb_hash_aset(VALUE, VALUE, VALUE); //VALUE rb_hash_delete_if(VALUE); VALUE rb_hash_delete(VALUE,VALUE); +VALUE rb_hash_has_key(VALUE hash, VALUE key); +VALUE rb_hash_keys(VALUE hash); struct st_table *rb_hash_tbl(VALUE); int rb_path_check(const char*); int rb_env_path_tainted(void); Modified: MacRuby/branches/experimental/thread.c =================================================================== --- MacRuby/branches/experimental/thread.c 2009-06-26 22:10:11 UTC (rev 1938) +++ MacRuby/branches/experimental/thread.c 2009-06-26 23:09:59 UTC (rev 1939) @@ -658,9 +658,13 @@ */ static VALUE -rb_thread_aref(VALUE thread, VALUE id) +rb_thread_aref(VALUE thread, SEL sel, VALUE key) { - // TODO + key = ID2SYM(rb_to_id(key)); + VALUE h = rb_vm_thread_locals(thread, false); + if (h != Qnil) { + return rb_hash_aref(h, key); + } return Qnil; } @@ -673,10 +677,10 @@ */ static VALUE -rb_thread_aset(VALUE self, ID id, VALUE val) +rb_thread_aset(VALUE self, SEL sel, ID key, VALUE val) { - // TODO - return Qnil; + key = ID2SYM(rb_to_id(key)); + return rb_hash_aset(rb_vm_thread_locals(self, true), key, val); } /* @@ -693,10 +697,14 @@ */ static VALUE -rb_thread_key_p(VALUE self, VALUE key) +rb_thread_key_p(VALUE self, SEL sel, VALUE key) { - // TODO - return Qnil; + key = ID2SYM(rb_to_id(key)); + VALUE h = rb_vm_thread_locals(self, false); + if (h == Qnil) { + return Qfalse; + } + return rb_hash_has_key(h, key); } int @@ -721,10 +729,10 @@ */ static VALUE -rb_thread_keys(VALUE self) +rb_thread_keys(VALUE self, SEL sel) { - // TODO - return Qnil; + VALUE h = rb_vm_thread_locals(self, false); + return h == Qnil ? rb_ary_new() : rb_hash_keys(h); } /* @@ -1339,10 +1347,10 @@ rb_objc_define_method(rb_cThread, "exit", rb_thread_kill, 0); rb_objc_define_method(rb_cThread, "run", rb_thread_run, 0); rb_objc_define_method(rb_cThread, "wakeup", rb_thread_wakeup, 0); - rb_define_method(rb_cThread, "[]", rb_thread_aref, 1); - rb_define_method(rb_cThread, "[]=", rb_thread_aset, 2); - rb_define_method(rb_cThread, "key?", rb_thread_key_p, 1); - rb_define_method(rb_cThread, "keys", rb_thread_keys, 0); + rb_objc_define_method(rb_cThread, "[]", rb_thread_aref, 1); + rb_objc_define_method(rb_cThread, "[]=", rb_thread_aset, 2); + rb_objc_define_method(rb_cThread, "key?", rb_thread_key_p, 1); + rb_objc_define_method(rb_cThread, "keys", rb_thread_keys, 0); rb_define_method(rb_cThread, "priority", rb_thread_priority, 0); rb_define_method(rb_cThread, "priority=", rb_thread_priority_set, 1); rb_objc_define_method(rb_cThread, "status", rb_thread_status, 0); Modified: MacRuby/branches/experimental/vm.cpp =================================================================== --- MacRuby/branches/experimental/vm.cpp 2009-06-26 22:10:11 UTC (rev 1938) +++ MacRuby/branches/experimental/vm.cpp 2009-06-26 23:09:59 UTC (rev 1939) @@ -4448,6 +4448,17 @@ } extern "C" +VALUE +rb_vm_thread_locals(VALUE thread, bool create_storage) +{ + rb_vm_thread_t *t = GetThreadPtr(thread); + if (t->locals == Qnil && create_storage) { + GC_WB(&t->locals, rb_hash_new()); + } + return t->locals; +} + +extern "C" void rb_vm_thread_pre_init(rb_vm_thread_t *t, rb_vm_block_t *body, int argc, const VALUE *argv, void *vm) @@ -4476,6 +4487,7 @@ t->vm = vm; t->value = Qundef; + t->locals = Qnil; t->status = THREAD_ALIVE; t->in_cond_wait = false; Modified: MacRuby/branches/experimental/vm.h =================================================================== --- MacRuby/branches/experimental/vm.h 2009-06-26 22:10:11 UTC (rev 1938) +++ MacRuby/branches/experimental/vm.h 2009-06-26 23:09:59 UTC (rev 1939) @@ -91,6 +91,7 @@ pthread_cond_t sleep_cond; rb_vm_thread_status_t status; bool in_cond_wait; + VALUE locals; // a Hash object or Qnil } rb_vm_thread_t; typedef struct rb_vm_outer { @@ -343,6 +344,7 @@ VALUE rb_vm_current_thread(void); VALUE rb_vm_main_thread(void); VALUE rb_vm_threads(void); +VALUE rb_vm_thread_locals(VALUE thread, bool create_storage); void rb_vm_thread_wakeup(rb_vm_thread_t *t); void rb_vm_thread_cancel(rb_vm_thread_t *t);
participants (1)
-
source_changes@macosforge.org