From 34111751b9afc0f314506a875662577a5ef23ac9 Mon Sep 17 00:00:00 2001 From: Evan Phoenix Date: Thu, 4 Feb 2010 19:21:22 -0800 Subject: [PATCH] Implement rb_obj_freeze and rb_str_freeze in C-API --- spec/capi/ext/object_spec.c | 5 +++++ spec/capi/ext/string_spec.c | 7 +++++++ spec/capi/object_spec.rb | 8 ++++++++ spec/capi/string_spec.rb | 8 ++++++++ vm/capi/object.cpp | 6 ++++++ vm/capi/ruby.h | 13 +++++-------- vm/capi/string.cpp | 4 ++++ 7 files changed, 43 insertions(+), 8 deletions(-) diff --git a/spec/capi/ext/object_spec.c b/spec/capi/ext/object_spec.c index e38e1da5a2..12ae6add1e 100644 --- a/spec/capi/ext/object_spec.c +++ b/spec/capi/ext/object_spec.c @@ -132,6 +132,10 @@ VALUE object_spec_rb_obj_id(VALUE self, VALUE obj) { return rb_obj_id(obj); } +VALUE object_spec_rb_obj_freeze(VALUE self, VALUE obj) { + return rb_obj_freeze(obj); +} + void Init_object_spec() { VALUE cls; cls = rb_define_class("CApiObjectSpecs", rb_cObject); @@ -163,4 +167,5 @@ void Init_object_spec() { rb_define_method(cls, "OBJ_TAINTED", object_spec_OBJ_TAINTED, 1); rb_define_method(cls, "rb_obj_id", object_spec_rb_obj_id, 1); + rb_define_method(cls, "rb_obj_freeze", object_spec_rb_obj_freeze, 1); } diff --git a/spec/capi/ext/string_spec.c b/spec/capi/ext/string_spec.c index 7c8068131d..f7efdca7f8 100644 --- a/spec/capi/ext/string_spec.c +++ b/spec/capi/ext/string_spec.c @@ -194,6 +194,11 @@ VALUE string_spec_STR2CSTR_replace(VALUE self, VALUE str) { return Qnil; } +VALUE string_spec_rb_str_freeze(VALUE self, VALUE str) { + rb_str_freeze(str); + return Qnil; +} + #ifdef RUBINIUS VALUE string_spec_rb_str_ptr_iterate(VALUE self, VALUE str) { int i; @@ -315,6 +320,8 @@ void Init_string_spec() { rb_define_method(cls, "STR2CSTR", string_spec_STR2CSTR, 1); rb_define_method(cls, "STR2CSTR_replace", string_spec_STR2CSTR_replace, 1); + rb_define_method(cls, "rb_str_freeze", string_spec_rb_str_freeze, 1); + #ifdef RUBINIUS rb_define_method(cls, "rb_str_ptr_iterate", string_spec_rb_str_ptr_iterate, 1); rb_define_method(cls, "rb_str_ptr_assign", string_spec_rb_str_ptr_assign, 2); diff --git a/spec/capi/object_spec.rb b/spec/capi/object_spec.rb index c346dff6ac..f454216c7d 100644 --- a/spec/capi/object_spec.rb +++ b/spec/capi/object_spec.rb @@ -240,4 +240,12 @@ def reach @o.OBJ_TAINTED(obj).should be_false end end + + describe "rb_obj_freeze" do + it "freezes the object passed to it" do + obj = "" + @o.rb_obj_freeze(obj).should == obj + obj.frozen?.should be_true + end + end end diff --git a/spec/capi/string_spec.rb b/spec/capi/string_spec.rb index f204a14beb..609fd4e290 100644 --- a/spec/capi/string_spec.rb +++ b/spec/capi/string_spec.rb @@ -336,6 +336,14 @@ def to_str end end + describe "rb_str_freeze" do + it "freezes the string" do + s = "" + @s.rb_str_freeze(s) + s.frozen?.should be_true + end + end + extended_on :rubinius do describe "rb_str_ptr" do it "returns struct with a pointer to the string's contents" do diff --git a/vm/capi/object.cpp b/vm/capi/object.cpp index 5b65d3b860..eb6aeb51cb 100644 --- a/vm/capi/object.cpp +++ b/vm/capi/object.cpp @@ -15,6 +15,12 @@ extern "C" { /* @todo implement when rbx supports frozen objects. */ } + VALUE rb_obj_freeze(VALUE hndl) { + NativeMethodEnvironment* env = NativeMethodEnvironment::get(); + env->get_object(hndl)->freeze(env->state()); + return hndl; + } + // Copied from MRI static struct types { int type; diff --git a/vm/capi/ruby.h b/vm/capi/ruby.h index fc1b7b5f87..bc7805364a 100644 --- a/vm/capi/ruby.h +++ b/vm/capi/ruby.h @@ -944,14 +944,8 @@ double rb_num2dbl(VALUE); /** Remove a previously declared global variable. */ void rb_free_global(VALUE global_handle); - /** - * Freeze object and return it. - * - * NOT supported in Rubinius. - */ - - // Things use this as an expression, so be sure it expands to be the argument. - #define rb_obj_freeze(obj) obj + /** Freeze object and return it. */ + VALUE rb_obj_freeze(VALUE obj); /** * Call method on receiver, args as varargs. Calls private methods. @@ -1295,6 +1289,9 @@ double rb_num2dbl(VALUE); void rb_str_modify(VALUE str); + /** Deprecated alias for rb_obj_freeze */ + void rb_str_freeze(VALUE str); + /** Returns a new String created from concatenating self with other. */ VALUE rb_str_plus(VALUE self_handle, VALUE other_handle); diff --git a/vm/capi/string.cpp b/vm/capi/string.cpp index 5f2f690d3d..3d05702b4b 100644 --- a/vm/capi/string.cpp +++ b/vm/capi/string.cpp @@ -102,6 +102,10 @@ extern "C" { self->unshare(env->state()); } + void rb_str_freeze(VALUE str) { + rb_obj_freeze(str); + } + VALUE rb_str_append(VALUE self_handle, VALUE other_handle) { NativeMethodEnvironment* env = NativeMethodEnvironment::get();