Revision: 1483 http://trac.macosforge.org/projects/ruby/changeset/1483 Author: lsansonetti@apple.com Date: 2009-04-23 20:45:14 -0700 (Thu, 23 Apr 2009) Log Message: ----------- more Boxed work Modified Paths: -------------- MacRuby/branches/experimental/objc.m MacRuby/branches/experimental/roxor.cpp MacRuby/branches/experimental/spec/macruby/struct_spec.rb Modified: MacRuby/branches/experimental/objc.m =================================================================== --- MacRuby/branches/experimental/objc.m 2009-04-24 02:47:49 UTC (rev 1482) +++ MacRuby/branches/experimental/objc.m 2009-04-24 03:45:14 UTC (rev 1483) @@ -62,7 +62,7 @@ struct st_table *imethods; } bs_element_indexed_class_t; -VALUE rb_cBoxed; +//VALUE rb_cBoxed; static ID rb_ivar_type; static VALUE bs_const_magic_cookie = Qnil; @@ -2182,6 +2182,7 @@ return v; } +#if 0 static bs_element_boxed_t * rb_klass_get_bs_boxed(VALUE recv) { @@ -2202,6 +2203,7 @@ } return NULL; } +#endif #if 0 static VALUE @@ -2342,7 +2344,6 @@ return str; } -#endif static VALUE rb_boxed_objc_type(VALUE recv, SEL sel) @@ -2358,7 +2359,9 @@ return rb_str_new2(type); } +#endif +#if 0 static VALUE rb_boxed_is_opaque(VALUE recv, SEL sel) { @@ -2390,6 +2393,7 @@ } return ary; } +#endif #if 0 static ffi_cif *struct_reader_cif = NULL; @@ -2757,6 +2761,7 @@ return Qtrue; } +#if 0 static const char * imp_rb_boxed_objCType(void *rcv, SEL sel) { @@ -2776,7 +2781,9 @@ bs_boxed = rb_klass_get_bs_boxed(CLASS_OF(rcv)); assert(rb_objc_rval_copy_boxed_data((VALUE)rcv, bs_boxed, buffer)); } +#endif +#if 0 static void rb_install_boxed_primitives(void) { @@ -2789,6 +2796,7 @@ rb_objc_install_method(klass, @selector(getValue:), (IMP)imp_rb_boxed_getValue); } +#endif static const char * resources_path(char *path, size_t len) @@ -3247,12 +3255,14 @@ rb_objc_retain((const void *)( bs_const_magic_cookie = rb_str_new2("bs_const_magic_cookie"))); +#if 0 rb_cBoxed = rb_define_class("Boxed", (VALUE)objc_getClass("NSValue")); RCLASS_SET_VERSION_FLAG(rb_cBoxed, RCLASS_IS_OBJECT_SUBCLASS); rb_objc_define_method(*(VALUE *)rb_cBoxed, "type", rb_boxed_objc_type, 0); rb_objc_define_method(*(VALUE *)rb_cBoxed, "opaque?", rb_boxed_is_opaque, 0); rb_objc_define_method(*(VALUE *)rb_cBoxed, "fields", rb_boxed_fields, 0); rb_install_boxed_primitives(); +#endif rb_cPointer = rb_define_class("Pointer", rb_cObject); rb_undef_alloc_func(rb_cPointer); Modified: MacRuby/branches/experimental/roxor.cpp =================================================================== --- MacRuby/branches/experimental/roxor.cpp 2009-04-24 02:47:49 UTC (rev 1482) +++ MacRuby/branches/experimental/roxor.cpp 2009-04-24 03:45:14 UTC (rev 1483) @@ -499,6 +499,7 @@ bs_classes_class_methods, bs_classes_instance_methods; bs_element_method_t *find_bs_method(Class klass, SEL sel); + rb_vm_bs_boxed_t *find_bs_boxed(std::string type); rb_vm_bs_boxed_t *find_bs_struct(std::string type); #if ROXOR_ULTRA_LAZY_JIT @@ -8477,12 +8478,15 @@ static ID boxed_ivar_type = 0; static inline rb_vm_bs_boxed_t * -locate_bs_boxed(VALUE klass) +locate_bs_boxed(VALUE klass, const bool struct_only=false) { VALUE type = rb_ivar_get(klass, boxed_ivar_type); assert(type != Qnil); - rb_vm_bs_boxed_t *bs_boxed = GET_VM()->find_bs_struct(RSTRING_PTR(type)); + rb_vm_bs_boxed_t *bs_boxed = GET_VM()->find_bs_boxed(RSTRING_PTR(type)); assert(bs_boxed != NULL); + if (struct_only) { + assert(bs_boxed->is_struct()); + } return bs_boxed; } @@ -8490,7 +8494,7 @@ rb_vm_struct_fake_new(VALUE rcv, SEL sel, int argc, VALUE *argv) { // Generate the real #new method. - rb_vm_bs_boxed_t *bs_boxed = locate_bs_boxed(rcv); + rb_vm_bs_boxed_t *bs_boxed = locate_bs_boxed(rcv, true); Function *f = RoxorCompiler::shared->compile_bs_struct_new(bs_boxed); IMP imp = GET_VM()->compile(f); @@ -8513,7 +8517,7 @@ } assert(buf[s - 1] == '='); buf[s - 1] = '\0'; - rb_vm_bs_boxed_t *bs_boxed = locate_bs_boxed(CLASS_OF(rcv)); + rb_vm_bs_boxed_t *bs_boxed = locate_bs_boxed(CLASS_OF(rcv), true); int field = -1; for (unsigned i = 0; i < bs_boxed->as.s->fields_count; i++) { const char *fname = bs_boxed->as.s->fields[i].name; @@ -8552,7 +8556,7 @@ return Qfalse; } - rb_vm_bs_boxed_t *bs_boxed = locate_bs_boxed(klass); + rb_vm_bs_boxed_t *bs_boxed = locate_bs_boxed(klass, true); VALUE *rcv_data; VALUE *val_data; @@ -8575,7 +8579,7 @@ VALUE *rcv_data; Data_Get_Struct(rcv, VALUE, rcv_data); - rb_vm_bs_boxed_t *bs_boxed = locate_bs_boxed(CLASS_OF(rcv)); + rb_vm_bs_boxed_t *bs_boxed = locate_bs_boxed(CLASS_OF(rcv), true); for (unsigned i = 0; i < bs_boxed->as.s->fields_count; i++) { rb_str_cat2(str, " "); rb_str_cat2(str, bs_boxed->as.s->fields[i].name); @@ -8592,7 +8596,7 @@ rb_vm_struct_dup(VALUE rcv, SEL sel) { VALUE klass = CLASS_OF(rcv); - rb_vm_bs_boxed_t *bs_boxed = locate_bs_boxed(klass); + rb_vm_bs_boxed_t *bs_boxed = locate_bs_boxed(klass, true); VALUE *rcv_data; Data_Get_Struct(rcv, VALUE, rcv_data); @@ -8667,6 +8671,49 @@ return true; } +static VALUE +rb_boxed_objc_type(VALUE rcv, SEL sel) +{ + return rb_ivar_get(rcv, boxed_ivar_type); +} + +static VALUE +rb_boxed_is_opaque(VALUE rcv, SEL sel) +{ + rb_vm_bs_boxed_t *bs_boxed = locate_bs_boxed(rcv); + return bs_boxed->bs_type == BS_ELEMENT_OPAQUE ? Qtrue : Qfalse; +} + +static VALUE +rb_boxed_fields(VALUE rcv, SEL sel) +{ + rb_vm_bs_boxed_t *bs_boxed = locate_bs_boxed(rcv); + VALUE ary = rb_ary_new(); + if (bs_boxed->bs_type == BS_ELEMENT_STRUCT) { + for (unsigned i = 0; i < bs_boxed->as.s->fields_count; i++) { + VALUE field = ID2SYM(rb_intern(bs_boxed->as.s->fields[i].name)); + rb_ary_push(ary, field); + } + } + return ary; +} + +VALUE rb_cBoxed; + +static void +Init_Boxed(void) +{ + boxed_ivar_type = rb_intern("__octype__"); + + rb_cBoxed = rb_define_class("Boxed", rb_cObject); + rb_objc_define_method(*(VALUE *)rb_cBoxed, "type", + (void *)rb_boxed_objc_type, 0); + rb_objc_define_method(*(VALUE *)rb_cBoxed, "opaque?", + (void *)rb_boxed_is_opaque, 0); + rb_objc_define_method(*(VALUE *)rb_cBoxed, "fields", + (void *)rb_boxed_fields, 0); +} + static inline void index_bs_class_methods(const char *name, std::map<std::string, std::map<SEL, bs_element_method_t *> *> &map, @@ -8721,7 +8768,7 @@ } inline rb_vm_bs_boxed_t * -RoxorVM::find_bs_struct(std::string type) +RoxorVM::find_bs_boxed(std::string type) { std::map<std::string, rb_vm_bs_boxed_t *>::iterator iter = bs_boxed.find(type); @@ -8730,10 +8777,16 @@ return NULL; } - rb_vm_bs_boxed_t *boxed = iter->second; - return boxed->is_struct() ? boxed : NULL; + return iter->second; } +inline rb_vm_bs_boxed_t * +RoxorVM::find_bs_struct(std::string type) +{ + rb_vm_bs_boxed_t *boxed = find_bs_boxed(type); + return boxed->is_struct() ? boxed : NULL; +} + static inline void register_bs_class(bs_element_class_t *bs_class) { @@ -9079,7 +9132,7 @@ bs_const_magic_cookie = rb_str_new2("bs_const_magic_cookie"); rb_objc_retain((void *)bs_const_magic_cookie); - boxed_ivar_type = rb_intern("__octype__"); + Init_Boxed(); } extern "C" Modified: MacRuby/branches/experimental/spec/macruby/struct_spec.rb =================================================================== --- MacRuby/branches/experimental/spec/macruby/struct_spec.rb 2009-04-24 02:47:49 UTC (rev 1482) +++ MacRuby/branches/experimental/spec/macruby/struct_spec.rb 2009-04-24 03:45:14 UTC (rev 1483) @@ -181,4 +181,28 @@ r2.size = NSSize.new(3, 4) r.should == r2 end + + it "returns the list of fields when the #fields class method is called" do + NSPoint.fields.should == [:x, :y] + NSSize.fields.should == [:width, :height] + NSRect.fields.should == [:origin, :size] + end + + it "returns false when the #opaque? class method is called" do + NSPoint.opaque?.should == false + NSSize.opaque?.should == false + NSRect.opaque?.should == false + end + + it "returns its Objective-C encoding type when then #type class method is called" do + if RUBY_ARCH == 'x86_64' + NSPoint.type.should == '{CGPoint=dd}' + NSSize.type.should == '{CGSize=dd}' + NSRect.type.should == '{CGRect={CGPoint=dd}{CGSize=dd}}' + else + NSPoint.type.should == '{_NSPoint=ff}' + NSSize.type.should == '{_NSSize=ff}' + NSRect.type.should == '{_NSRect={_NSPoint=ff}{_NSSize=ff}}' + end + end end
participants (1)
-
source_changes@macosforge.org