Revision: 3968 http://trac.macosforge.org/projects/ruby/changeset/3968 Author: lsansonetti@apple.com Date: 2010-04-27 22:42:04 -0700 (Tue, 27 Apr 2010) Log Message: ----------- rewrote class flags to not use the version field anymore, better typing system, fixed misc bugs Modified Paths: -------------- MacRuby/trunk/NSArray.m MacRuby/trunk/NSDictionary.m MacRuby/trunk/NSString.m MacRuby/trunk/array.c MacRuby/trunk/bridgesupport.cpp MacRuby/trunk/class.c MacRuby/trunk/dispatcher.cpp MacRuby/trunk/eval.c MacRuby/trunk/gc.c MacRuby/trunk/hash.c MacRuby/trunk/include/ruby/intern.h MacRuby/trunk/include/ruby/ruby.h MacRuby/trunk/marshal.c MacRuby/trunk/numeric.c MacRuby/trunk/objc.m MacRuby/trunk/object.c MacRuby/trunk/parse.y MacRuby/trunk/proc.c MacRuby/trunk/string.c MacRuby/trunk/variable.c MacRuby/trunk/vm.cpp MacRuby/trunk/vm_eval.c Added Paths: ----------- MacRuby/trunk/class.h Modified: MacRuby/trunk/NSArray.m =================================================================== --- MacRuby/trunk/NSArray.m 2010-04-28 03:01:10 UTC (rev 3967) +++ MacRuby/trunk/NSArray.m 2010-04-28 05:42:04 UTC (rev 3968) @@ -938,8 +938,6 @@ void Init_NSArray(void) { - rb_cNSArray = (VALUE)objc_getClass("NSArray"); - assert(rb_cNSArray != 0); rb_cArray = rb_cNSArray; rb_cNSMutableArray = (VALUE)objc_getClass("NSMutableArray"); assert(rb_cNSMutableArray != 0); Modified: MacRuby/trunk/NSDictionary.m =================================================================== --- MacRuby/trunk/NSDictionary.m 2010-04-28 03:01:10 UTC (rev 3967) +++ MacRuby/trunk/NSDictionary.m 2010-04-28 05:42:04 UTC (rev 3968) @@ -435,8 +435,6 @@ void Init_NSDictionary(void) { - rb_cNSHash = (VALUE)objc_getClass("NSDictionary"); - assert(rb_cNSHash != 0); rb_cHash = rb_cNSHash; rb_cNSMutableHash = (VALUE)objc_getClass("NSMutableDictionary"); assert(rb_cNSMutableHash != 0); Modified: MacRuby/trunk/NSString.m =================================================================== --- MacRuby/trunk/NSString.m 2010-04-28 03:01:10 UTC (rev 3967) +++ MacRuby/trunk/NSString.m 2010-04-28 05:42:04 UTC (rev 3968) @@ -204,8 +204,6 @@ void Init_NSString(void) { - rb_cNSString = (VALUE)objc_getClass("NSString"); - assert(rb_cNSString != 0); rb_cString = rb_cNSString; rb_include_module(rb_cString, rb_mComparable); rb_cNSMutableString = (VALUE)objc_getClass("NSMutableString"); Modified: MacRuby/trunk/array.c =================================================================== --- MacRuby/trunk/array.c 2010-04-28 03:01:10 UTC (rev 3967) +++ MacRuby/trunk/array.c 2010-04-28 05:42:04 UTC (rev 3968) @@ -16,6 +16,7 @@ #include "objc.h" #include "ruby/node.h" #include "vm.h" +#include "class.h" #include "array.h" VALUE rb_cRubyArray; @@ -3484,7 +3485,6 @@ Init_NSArray(); rb_cRubyArray = rb_define_class("Array", rb_cNSMutableArray); - RCLASS_SET_VERSION_FLAG(rb_cRubyArray, RCLASS_IS_ARRAY_SUBCLASS); rb_objc_define_method(*(VALUE *)rb_cRubyArray, "new", rb_class_new_instance_imp, -1); Modified: MacRuby/trunk/bridgesupport.cpp =================================================================== --- MacRuby/trunk/bridgesupport.cpp 2010-04-28 03:01:10 UTC (rev 3967) +++ MacRuby/trunk/bridgesupport.cpp 2010-04-28 05:42:04 UTC (rev 3968) @@ -25,6 +25,7 @@ #include "compiler.h" #include "bridgesupport.h" #include "objc.h" +#include "class.h" #include <execinfo.h> #include <dlfcn.h> Modified: MacRuby/trunk/class.c =================================================================== --- MacRuby/trunk/class.c 2010-04-28 03:01:10 UTC (rev 3967) +++ MacRuby/trunk/class.c 2010-04-28 05:42:04 UTC (rev 3968) @@ -14,9 +14,11 @@ #include "ruby/node.h" #include "ruby/st.h" #include <ctype.h> +#include <stdarg.h> #include "id.h" #include "vm.h" #include "objc.h" +#include "class.h" extern st_table *rb_class_tbl; @@ -35,18 +37,6 @@ == RCLASS_IS_OBJECT_SUBCLASS) { klass_version |= RCLASS_IS_OBJECT_SUBCLASS; } - if ((super_version & RCLASS_IS_ARRAY_SUBCLASS) - == RCLASS_IS_ARRAY_SUBCLASS) { - klass_version |= RCLASS_IS_ARRAY_SUBCLASS; - } - if ((super_version & RCLASS_IS_HASH_SUBCLASS) - == RCLASS_IS_HASH_SUBCLASS) { - klass_version |= RCLASS_IS_HASH_SUBCLASS; - } - if ((super_version & RCLASS_IS_STRING_SUBCLASS) - == RCLASS_IS_STRING_SUBCLASS) { - klass_version |= RCLASS_IS_STRING_SUBCLASS; - } RCLASS_SET_VERSION(ocklass, klass_version); } @@ -109,7 +99,7 @@ while (RCLASS_SINGLETON(cl)) { cl = RCLASS_SUPER(cl); } - return rb_class_real(cl); + return rb_class_real(cl, true); } VALUE rb_obj_init_copy(VALUE, SEL, VALUE); @@ -198,22 +188,7 @@ VALUE rb_objc_create_class(const char *name, VALUE super) { - VALUE klass; - - if (!RCLASS_RUBY(super)) { - const long v = RCLASS_VERSION(super); - if (v & RCLASS_IS_STRING_SUBCLASS) { - super = rb_cNSMutableString; - } - else if (v & RCLASS_IS_HASH_SUBCLASS) { - super = rb_cNSMutableHash; - } - else if (v & RCLASS_IS_ARRAY_SUBCLASS) { - super = rb_cNSMutableArray; - } - } - - klass = rb_objc_alloc_class(name, super, T_CLASS, rb_cClass); + VALUE klass = rb_objc_alloc_class(name, super, T_CLASS, rb_cClass); if (super != rb_cNSObject && super != 0 && ((RCLASS_VERSION(*(VALUE *)super) & RCLASS_HAS_ROBJECT_ALLOC) @@ -277,7 +252,7 @@ rb_obj_init_copy(clone, 0, orig); { VALUE super; - int version_flag; + unsigned long version_flag; if (!RCLASS_RUBY(orig)) { super = orig; @@ -462,7 +437,7 @@ if (TYPE(klass) != T_CLASS) { rb_raise(rb_eTypeError, "%s is not a class", name); } - if (rb_class_real(RCLASS_SUPER(klass)) != super) { + if (rb_class_real(RCLASS_SUPER(klass), true) != super) { rb_name_error(id, "%s is already defined", name); } return klass; @@ -492,7 +467,7 @@ if (TYPE(klass) != T_CLASS) { rb_raise(rb_eTypeError, "%s is not a class", name); } - if (rb_class_real(RCLASS_SUPER(klass)) != super) { + if (rb_class_real(RCLASS_SUPER(klass), true) != super) { rb_name_error(id, "%s is already defined", name); } return klass; @@ -1203,8 +1178,6 @@ rb_attr(klass, rb_intern(name), read, write, Qfalse); } -#include <stdarg.h> - int rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...) { @@ -1284,3 +1257,133 @@ rb_fatal("bad scan arg format: %s", fmt); return 0; } + +static void *rb_class_flags_key = NULL; + +static unsigned long +rb_class_get_mask(Class k) +{ + return (unsigned long)rb_objc_get_associative_ref(k, &rb_class_flags_key); +} + +static void +rb_class_set_mask(Class k, unsigned long mask) +{ + rb_objc_set_associative_ref(k, &rb_class_flags_key, (void *)mask); +} + +#define RCLASS_MASK_TYPE_SHIFT 16 + +unsigned long +rb_class_get_flags(Class k) +{ + return rb_class_get_mask(k) >> RCLASS_MASK_TYPE_SHIFT; +} + +void +rb_class_set_flags(Class k, unsigned long flags) +{ + rb_class_set_mask(k, flags << RCLASS_MASK_TYPE_SHIFT); +} + +static int +foundation_type(Class k) +{ + Class tmp = k; + do { + if (tmp == (Class)rb_cNSString) { + return T_STRING; + } + if (tmp == (Class)rb_cNSArray) { + return T_ARRAY; + } + if (tmp == (Class)rb_cNSHash) { + return T_HASH; + } + tmp = class_getSuperclass(tmp); + } + while (tmp != NULL); + return 0; +} + +int +rb_objc_type(VALUE obj) +{ + Class k = *(Class *)obj; + + if (k != NULL) { + unsigned long mask = rb_class_get_mask(k); + int type = mask & 0xff; + if (type == 0) { + // Type is not available, let's compute it. + if (k == (Class)rb_cSymbol) { + type = T_SYMBOL; + goto done; + } + if (k == (Class)rb_cFixnum) { + type = T_FIXNUM; + goto done; + } + if ((type = foundation_type(k)) != 0) { + goto done; + } + if (RCLASS_META(k)) { + if (RCLASS_MODULE(obj)) { + type = T_MODULE; + goto done; + } + else { + type = T_CLASS; + goto done; + } + } + const unsigned long flags = mask >> RCLASS_MASK_TYPE_SHIFT; + if ((flags & RCLASS_IS_OBJECT_SUBCLASS) + != RCLASS_IS_OBJECT_SUBCLASS) { + type = T_NATIVE; + goto done; + } + type = BUILTIN_TYPE(obj); + +done: + assert(type != 0); + mask |= type; + rb_class_set_mask(k, mask); + } + return type; + } + return BUILTIN_TYPE(obj); +} + +bool +rb_obj_is_native(VALUE obj) +{ + Class k = *(Class *)obj; + return k != NULL && (RCLASS_VERSION(k) & RCLASS_IS_OBJECT_SUBCLASS) + != RCLASS_IS_OBJECT_SUBCLASS; +} + +VALUE +rb_class_real(VALUE cl, bool hide_builtin_foundation_classes) +{ + if (cl == 0) { + return 0; + } + if (RCLASS_META(cl)) { + return RCLASS_MODULE(cl) ? rb_cModule : rb_cClass; + } + while (RCLASS_SINGLETON(cl)) { + cl = RCLASS_SUPER(cl); + } + if (hide_builtin_foundation_classes && !RCLASS_RUBY(cl)) { + switch (foundation_type((Class)cl)) { + case T_STRING: + return rb_cRubyString; + case T_ARRAY: + return rb_cRubyArray; + case T_HASH: + return rb_cRubyHash; + } + } + return cl; +} Added: MacRuby/trunk/class.h =================================================================== --- MacRuby/trunk/class.h (rev 0) +++ MacRuby/trunk/class.h 2010-04-28 05:42:04 UTC (rev 3968) @@ -0,0 +1,47 @@ +/* + * This file is covered by the Ruby license. See COPYING for more details. + * + * Copyright (C) 2010, Apple Inc. All rights reserved. + */ + +#ifndef __CLASS_H_ +#define __CLASS_H_ + +#if defined(__cplusplus) +extern "C" { +#endif + +#define RCLASS_IS_OBJECT_SUBCLASS (1<<1) /* class is a true RBObject subclass */ +#define RCLASS_IS_RUBY_CLASS (1<<2) /* class was created from Ruby */ +#define RCLASS_IS_MODULE (1<<3) /* class represents a Ruby Module */ +#define RCLASS_IS_SINGLETON (1<<4) /* class represents a singleton */ +#define RCLASS_IS_FROZEN (1<<5) /* class is frozen */ +#define RCLASS_IS_TAINTED (1<<6) /* class is tainted */ +#define RCLASS_IS_INCLUDED (1<<10) /* module is included */ +#define RCLASS_HAS_ROBJECT_ALLOC (1<<11) /* class uses the default RObject alloc */ +#define RCLASS_SCOPE_PRIVATE (1<<12) /* class opened for private methods */ +#define RCLASS_SCOPE_PROTECTED (1<<13) /* class opened for protected methods */ +#define RCLASS_SCOPE_MOD_FUNC (1<<14) /* class opened for module_function methods */ +#define RCLASS_KVO_CHECK_DONE (1<<15) /* class created by KVO and flags merged */ +#define RCLASS_NO_IV_SLOTS (1<<16) /* class cannot hold ivar slots (T_DATA & friends) */ + +unsigned long rb_class_get_flags(Class k); +void rb_class_set_flags(Class k, unsigned long flags); + +#define RCLASS_VERSION(m) (rb_class_get_flags((Class)m)) +#define RCLASS_SET_VERSION(m,f) (rb_class_set_flags((Class)m, (unsigned long)f)) +#define RCLASS_SET_VERSION_FLAG(m,f) (RCLASS_SET_VERSION((Class)m, (RCLASS_VERSION(m) | f))) + +#define RCLASS_RUBY(m) ((RCLASS_VERSION(m) & RCLASS_IS_RUBY_CLASS) == RCLASS_IS_RUBY_CLASS) +#define RCLASS_MODULE(m) ((RCLASS_VERSION(m) & RCLASS_IS_MODULE) == RCLASS_IS_MODULE) +#define RCLASS_SINGLETON(m) ((RCLASS_VERSION(m) & RCLASS_IS_SINGLETON) == RCLASS_IS_SINGLETON) + +CFMutableDictionaryRef rb_class_ivar_dict(VALUE); +CFMutableDictionaryRef rb_class_ivar_dict_or_create(VALUE); +void rb_class_ivar_set_dict(VALUE, CFMutableDictionaryRef); + +#if defined(__cplusplus) +} // extern "C" +#endif + +#endif // __CLASS_H_ Modified: MacRuby/trunk/dispatcher.cpp =================================================================== --- MacRuby/trunk/dispatcher.cpp 2010-04-28 03:01:10 UTC (rev 3967) +++ MacRuby/trunk/dispatcher.cpp 2010-04-28 05:42:04 UTC (rev 3968) @@ -18,6 +18,7 @@ #include "hash.h" #include "encoding.h" #include "re.h" +#include "class.h" #include <execinfo.h> #include <dlfcn.h> @@ -842,7 +843,7 @@ if (self == Qfalse) { return rb_cFalseClass; } - return rb_class_real((VALUE)klass); + return rb_class_real((VALUE)klass, true); } #if ROXOR_VM_DEBUG Modified: MacRuby/trunk/eval.c =================================================================== --- MacRuby/trunk/eval.c 2010-04-28 03:01:10 UTC (rev 3967) +++ MacRuby/trunk/eval.c 2010-04-28 05:42:04 UTC (rev 3968) @@ -14,6 +14,7 @@ #include "vm.h" #include "dtrace.h" #include "id.h" +#include "class.h" VALUE proc_invoke(VALUE, VALUE, VALUE, VALUE); Modified: MacRuby/trunk/gc.c =================================================================== --- MacRuby/trunk/gc.c 2010-04-28 03:01:10 UTC (rev 3967) +++ MacRuby/trunk/gc.c 2010-04-28 05:42:04 UTC (rev 3968) @@ -26,9 +26,7 @@ #include "objc.h" #include "vm.h" #include "id.h" -#include <stdio.h> -#include <setjmp.h> -#include <sys/types.h> +#include "class.h" #ifdef HAVE_SYS_TIME_H #include <sys/time.h> Modified: MacRuby/trunk/hash.c =================================================================== --- MacRuby/trunk/hash.c 2010-04-28 03:01:10 UTC (rev 3967) +++ MacRuby/trunk/hash.c 2010-04-28 05:42:04 UTC (rev 3968) @@ -18,6 +18,7 @@ #include "objc.h" #include "vm.h" #include "hash.h" +#include "class.h" static VALUE rhash_try_convert(VALUE, SEL, VALUE); @@ -1774,7 +1775,6 @@ id_yield = rb_intern("yield"); rb_cRubyHash = rb_define_class("Hash", rb_cNSMutableHash); - RCLASS_SET_VERSION_FLAG(rb_cRubyHash, RCLASS_IS_HASH_SUBCLASS); rb_objc_define_method(*(VALUE *)rb_cRubyHash, "new", rb_class_new_instance_imp, -1); Modified: MacRuby/trunk/include/ruby/intern.h =================================================================== --- MacRuby/trunk/include/ruby/intern.h 2010-04-28 03:01:10 UTC (rev 3967) +++ MacRuby/trunk/include/ruby/intern.h 2010-04-28 05:42:04 UTC (rev 3968) @@ -444,7 +444,7 @@ VALUE rb_obj_frozen_p(VALUE); //VALUE rb_obj_id(VALUE); VALUE rb_obj_class(VALUE); -VALUE rb_class_real(VALUE); +VALUE rb_class_real(VALUE, bool hide_builtin_foundation_classes); VALUE rb_class_inherited_p(VALUE, VALUE); VALUE rb_convert_type(VALUE,int,const char*,const char*); VALUE rb_check_convert_type(VALUE,int,const char*,const char*); Modified: MacRuby/trunk/include/ruby/ruby.h =================================================================== --- MacRuby/trunk/include/ruby/ruby.h 2010-04-28 03:01:10 UTC (rev 3967) +++ MacRuby/trunk/include/ruby/ruby.h 2010-04-28 05:42:04 UTC (rev 3968) @@ -99,11 +99,7 @@ #if SIZEOF_LONG == SIZEOF_VOIDP typedef unsigned long VALUE; -#if WITH_OBJC #define ID unsigned long -#else -typedef unsigned long ID; -#endif # define SIGNED_VALUE long # define SIZEOF_VALUE SIZEOF_LONG # define PRIdVALUE "ld" @@ -273,9 +269,6 @@ RUBY_IMMEDIATE_MASK = 0x03, RUBY_FIXNUM_FLAG = 0x01, RUBY_FIXFLOAT_FLAG = 0x03, -#if !WITH_OBJC - RUBY_SYMBOL_FLAG = 0x0e, -#endif RUBY_SPECIAL_SHIFT = 8, }; @@ -302,9 +295,6 @@ #define IMMEDIATE_MASK RUBY_IMMEDIATE_MASK #define FIXNUM_FLAG RUBY_FIXNUM_FLAG #define FIXFLOAT_FLAG RUBY_FIXFLOAT_FLAG -#if !WITH_OBJC -# define SYMBOL_FLAG RUBY_SYMBOL_FLAG -#endif #define RTEST(v) (((VALUE)(v) & ~Qnil) != 0) #define NIL_P(v) ((VALUE)(v) == Qnil) @@ -359,9 +349,7 @@ #define T_BIGNUM RUBY_T_BIGNUM #define T_FILE RUBY_T_FILE #define T_FIXNUM RUBY_T_FIXNUM -#if WITH_OBJC -# define T_NATIVE RUBY_T_NATIVE -#endif +#define T_NATIVE RUBY_T_NATIVE #define T_TRUE RUBY_T_TRUE #define T_FALSE RUBY_T_FALSE #define T_DATA RUBY_T_DATA @@ -466,12 +454,8 @@ RSTRING_PTR(x)[0]:(char)(NUM2INT(x)&0xff)) #define CHR2FIX(x) INT2FIX((long)((x)&0xff)) -#if WITH_OBJC void *rb_objc_newobj(size_t size); -# define NEWOBJ(obj,type) type *obj = (type*)rb_objc_newobj(sizeof(type)) -#else -# define NEWOBJ(obj,type) type *obj = (type*)rb_newobj() -#endif +#define NEWOBJ(obj,type) type *obj = (type*)rb_objc_newobj(sizeof(type)) #define OBJSETUP(obj,c,t) do {\ RBASIC(obj)->flags = (t);\ if (c != 0) RBASIC(obj)->klass = (c);\ @@ -499,139 +483,32 @@ VALUE *slots; /* static ivars (compilation) */ }; -#if !WITH_OBJC -typedef struct { - VALUE super; - struct st_table *iv_tbl; -} rb_classext_t; +#define RCLASS_SUPER(m) ((VALUE)class_getSuperclass((Class)m)) +#define RCLASS_SET_SUPER(m, s) (class_setSuperclass((Class)m, (Class)s)) +#define RCLASS_META(m) (class_isMetaClass((Class)m)) -struct RClass { - struct RBasic basic; - rb_classext_t *ptr; - void *ocklass; - struct st_table *m_tbl; - struct st_table *iv_index_tbl; -}; -# define RCLASS_IV_TBL(c) (RCLASS(c)->ptr->iv_tbl) -# define RCLASS_M_TBL(c) (RCLASS(c)->m_tbl) -# define RCLASS_SUPER(c) (RCLASS(c)->ptr->super) -# define RCLASS_IV_INDEX_TBL(c) (RCLASS(c)->iv_index_tbl) -# define RMODULE_IV_TBL(m) RCLASS_IV_TBL(m) -# define RMODULE_M_TBL(m) RCLASS_M_TBL(m) -# define RMODULE_SUPER(m) RCLASS_SUPER(m) -#else -# define RCLASS_IS_OBJECT_SUBCLASS (1<<12) /* class is a true RBObject subclass */ -# define RCLASS_IS_RUBY_CLASS (1<<13) /* class was created from Ruby */ -# define RCLASS_IS_MODULE (1<<14) /* class represents a Ruby Module */ -# define RCLASS_IS_SINGLETON (1<<15) /* class represents a singleton */ -# define RCLASS_IS_FROZEN (1<<16) /* class is frozen */ -# define RCLASS_IS_TAINTED (1<<17) /* class is tainted */ -# define RCLASS_IS_STRING_SUBCLASS (1<<18) /* class is a subclass of NSCFString */ -# define RCLASS_IS_ARRAY_SUBCLASS (1<<19) /* class is a subclass of NSCFArray */ -# define RCLASS_IS_HASH_SUBCLASS (1<<20) /* class is a subclass of NSCFDictionary */ -# define RCLASS_IS_INCLUDED (1<<21) /* module is included */ -# define RCLASS_IS_SET_SUBCLASS (1<<22) /* class is a subclass of NSCFSet */ -# define RCLASS_HAS_ROBJECT_ALLOC (1<<23) /* class uses the default RObject alloc */ -# define RCLASS_SCOPE_PRIVATE (1<<24) /* class opened for private methods */ -# define RCLASS_SCOPE_PROTECTED (1<<25) /* class opened for protected methods */ -# define RCLASS_SCOPE_MOD_FUNC (1<<26) /* class opened for module_function methods */ -# define RCLASS_KVO_CHECK_DONE (1<<27) /* class created by KVO and flags merged */ -# define RCLASS_NO_IV_SLOTS (1<<28) /* class cannot hold ivar slots (T_DATA & friends) */ -# define RCLASS_VERSION(m) (class_getVersion((Class)m)) -# define RCLASS_SET_VERSION(m,f) (class_setVersion((Class)m, f)) -# define RCLASS_SET_VERSION_FLAG(m,f) (class_setVersion((Class)m, (RCLASS_VERSION(m) | f))) -# define RCLASS_SUPER(m) ((VALUE)class_getSuperclass((Class)m)) -# define RCLASS_SET_SUPER(m, s) (class_setSuperclass((Class)m, (Class)s)) -# define RCLASS_META(m) (class_isMetaClass((Class)m)) -# define RCLASS_RUBY(m) ((RCLASS_VERSION(m) & RCLASS_IS_RUBY_CLASS) == RCLASS_IS_RUBY_CLASS) -# define RCLASS_MODULE(m) ((RCLASS_VERSION(m) & RCLASS_IS_MODULE) == RCLASS_IS_MODULE) -# define RCLASS_SINGLETON(m) ((RCLASS_VERSION(m) & RCLASS_IS_SINGLETON) == RCLASS_IS_SINGLETON) -CFMutableDictionaryRef rb_class_ivar_dict(VALUE); -CFMutableDictionaryRef rb_class_ivar_dict_or_create(VALUE); -void rb_class_ivar_set_dict(VALUE, CFMutableDictionaryRef); -#endif - #define RFLOAT_VALUE(v) FIXFLOAT2DBL(v) #define DOUBLE2NUM(dbl) rb_float_new(dbl) #define DBL2NUM DOUBLE2NUM #define ELTS_SHARED FL_USER2 -#if !WITH_OBJC -#define RSTRING_EMBED_LEN_MAX ((sizeof(VALUE)*3)/sizeof(char)-1) -struct RString { - struct RBasic basic; - union { - struct { - long len; - char *ptr; - union { - long capa; - VALUE shared; - } aux; - } heap; - char ary[RSTRING_EMBED_LEN_MAX]; - } as; -}; -# define RSTRING_NOEMBED FL_USER1 -# define RSTRING_EMBED_LEN_MASK (FL_USER2|FL_USER3|FL_USER4|FL_USER5|FL_USER6) -# define RSTRING_EMBED_LEN_SHIFT (FL_USHIFT+2) -# define RSTRING_LEN(str) \ - (!(RBASIC(str)->flags & RSTRING_NOEMBED) ? \ - (long)((RBASIC(str)->flags >> RSTRING_EMBED_LEN_SHIFT) & \ - (RSTRING_EMBED_LEN_MASK >> RSTRING_EMBED_LEN_SHIFT)) : \ - RSTRING(str)->as.heap.len) -# define RSTRING_PTR(str) \ - (!(RBASIC(str)->flags & RSTRING_NOEMBED) ? \ - RSTRING(str)->as.ary : \ - RSTRING(str)->as.heap.ptr) -#else const char *rb_str_cstr(VALUE); long rb_str_clen(VALUE); -# define RSTRING_PTR(str) (rb_str_cstr((VALUE)str)) -# define RSTRING_LEN(str) (rb_str_clen((VALUE)str)) -#endif +#define RSTRING_PTR(str) (rb_str_cstr((VALUE)str)) +#define RSTRING_LEN(str) (rb_str_clen((VALUE)str)) #define RSTRING_END(str) (RSTRING_PTR(str)+RSTRING_LEN(str)) -#if !WITH_OBJC -struct RArray { - struct RBasic basic; - long len; - union { - long capa; - VALUE shared; - } aux; - VALUE *ptr; -}; -# define RARRAY_LEN(a) RARRAY(a)->len -# define RARRAY_PTR(a) RARRAY(a)->ptr -# define RARRAY_AT(a,i) RARRAY_PTR(a)[i] -#else -# define RARRAY_LEN(a) (rb_ary_len((VALUE)a)) -# define RARRAY_AT(a,i) (rb_ary_elt((VALUE)a, (long)i)) +#define RARRAY_LEN(a) (rb_ary_len((VALUE)a)) +#define RARRAY_AT(a,i) (rb_ary_elt((VALUE)a, (long)i)) /* IMPORTANT: try to avoid using RARRAY_PTR if necessary, because it's * a _much_ slower operation than RARRAY_AT. RARRAY_PTR is only provided for * compatibility but should _not_ be used intensively. */ const VALUE *rb_ary_ptr(VALUE); -# define RARRAY_PTR(a) (rb_ary_ptr((VALUE)a)) -#endif +#define RARRAY_PTR(a) (rb_ary_ptr((VALUE)a)) -#if !WITH_OBJC -struct RHash { - struct RBasic basic; - struct st_table *ntbl; /* possibly 0 */ - int iter_lev; - VALUE ifnone; -}; -/* RHASH_TBL allocates st_table if not available. */ -# define RHASH_TBL(h) rb_hash_tbl(h) -# define RHASH_ITER_LEV(h) (RHASH(h)->iter_lev) -# define RHASH_IFNONE(h) (RHASH(h)->ifnone) -# define RHASH_SIZE(h) (RHASH(h)->ntbl ? RHASH(h)->ntbl->num_entries : 0) -#else -# define RHASH_SIZE(h) rb_hash_size(h) -#endif +#define RHASH_SIZE(h) rb_hash_size(h) #define RHASH_EMPTY_P(h) (RHASH_SIZE(h) == 0) struct RFile { @@ -659,7 +536,6 @@ }; #define ExtractIOStruct(obj) RFILE(obj)->fptr -//#define ExtractIOStruct(obj) RFILE(rb_io_taint_check(obj))->fptr #define DATA_PTR(dta) (RDATA(dta)->data) @@ -785,6 +661,9 @@ #define FL_USER19 (((VALUE)1)<<(FL_USHIFT+19)) #define FL_USER20 (((VALUE)1)<<(FL_USHIFT+20)) +bool rb_obj_is_native(VALUE obj); +#define NATIVE(obj) (rb_obj_is_native((VALUE)obj)) + #define SPECIAL_CONST_P(x) (IMMEDIATE_P(x) || !RTEST(x)) #define FL_ABLE(x) (!SPECIAL_CONST_P(x) && !NATIVE(x) && BUILTIN_TYPE(x) != T_NODE) @@ -795,27 +674,15 @@ #define FL_UNSET(x,f) do {if (FL_ABLE(x)) RBASIC(x)->flags &= ~(f);} while (0) #define FL_REVERSE(x,f) do {if (FL_ABLE(x)) RBASIC(x)->flags ^= (f);} while (0) -#if WITH_OBJC -# define OBJ_TAINTED(x) (int)(SPECIAL_CONST_P(x) || NATIVE(x) ? rb_obj_tainted((VALUE)x) == Qtrue : FL_TEST((x), FL_TAINT)) -# define OBJ_TAINT(x) (rb_obj_taint((VALUE)x)) -# define OBJ_UNTRUSTED(x) (int)(SPECIAL_CONST_P(x) || NATIVE(x) ? rb_obj_untrusted((VALUE)x) == Qtrue : FL_TEST((x), FL_UNTRUSTED)) -# define OBJ_UNTRUST(x) (rb_obj_untrust((VALUE)x)) -#else -# define OBJ_TAINTED(x) FL_TEST((x), FL_TAINT) -# define OBJ_TAINT(x) FL_SET((x), FL_TAINT) -# define OBJ_UNTRUSTED(x) (FL_TEST((x), FL_UNTRUSTED)) -# define OBJ_UNTRUST(x) FL_SET((x), FL_UNTRUSTED) -#endif +#define OBJ_TAINTED(x) (int)(SPECIAL_CONST_P(x) || NATIVE(x) ? rb_obj_tainted((VALUE)x) == Qtrue : FL_TEST((x), FL_TAINT)) +#define OBJ_TAINT(x) (rb_obj_taint((VALUE)x)) +#define OBJ_UNTRUSTED(x) (int)(SPECIAL_CONST_P(x) || NATIVE(x) ? rb_obj_untrusted((VALUE)x) == Qtrue : FL_TEST((x), FL_UNTRUSTED)) +#define OBJ_UNTRUST(x) (rb_obj_untrust((VALUE)x)) #define OBJ_INFECT(x,s) do {if (FL_ABLE(x) && FL_ABLE(s)) RBASIC(x)->flags |= RBASIC(s)->flags & FL_TAINT;} while (0) -#if WITH_OBJC -# define OBJ_FROZEN(x) (int)(SPECIAL_CONST_P(x) || NATIVE(x) ? rb_obj_frozen_p((VALUE)x) == Qtrue : FL_TEST((x), FL_FREEZE)) -# define OBJ_FREEZE(x) (rb_obj_freeze((VALUE)x)) -#else -# define OBJ_FROZEN(x) FL_TEST((x), FL_FREEZE) -# define OBJ_FREEZE(x) FL_SET((x), FL_FREEZE) -#endif +#define OBJ_FROZEN(x) (int)(SPECIAL_CONST_P(x) || NATIVE(x) ? rb_obj_frozen_p((VALUE)x) == Qtrue : FL_TEST((x), FL_FREEZE)) +#define OBJ_FREEZE(x) (rb_obj_freeze((VALUE)x)) #define ALLOC_N(type,n) (type*)xmalloc2((n),sizeof(type)) #define ALLOC(type) (type*)xmalloc(sizeof(type)) @@ -992,9 +859,7 @@ void *ruby_options(int, char**); int ruby_run_node(void *); -#if WITH_OBJC int macruby_main(const char *path, int argc, char **argv); -#endif RUBY_EXTERN VALUE rb_mKernel; RUBY_EXTERN VALUE rb_mComparable; @@ -1008,9 +873,7 @@ RUBY_EXTERN VALUE rb_cBasicObject; RUBY_EXTERN VALUE rb_cObject; -#if WITH_OBJC RUBY_EXTERN VALUE rb_cNSObject; -#endif RUBY_EXTERN VALUE rb_cArray; RUBY_EXTERN VALUE rb_cBignum; RUBY_EXTERN VALUE rb_cBinding; @@ -1054,7 +917,6 @@ RUBY_EXTERN VALUE rb_cEnv; RUBY_EXTERN VALUE rb_cRandom; -#if WITH_OBJC RUBY_EXTERN VALUE rb_cNSString; RUBY_EXTERN VALUE rb_cNSMutableString; RUBY_EXTERN VALUE rb_cRubyString; @@ -1068,7 +930,6 @@ RUBY_EXTERN VALUE rb_cBoxed; RUBY_EXTERN VALUE rb_cPointer; RUBY_EXTERN VALUE rb_cTopLevel; -#endif RUBY_EXTERN VALUE rb_eException; RUBY_EXTERN VALUE rb_eStandardError; @@ -1106,15 +967,6 @@ RUBY_EXTERN VALUE rb_stdin, rb_stdout, rb_stderr; -#if WITH_OBJC -static inline bool -rb_is_native(VALUE obj) { - Class k = *(Class *)obj; - return k != NULL && (RCLASS_VERSION(k) & RCLASS_IS_OBJECT_SUBCLASS) != RCLASS_IS_OBJECT_SUBCLASS; -} -#define NATIVE(obj) (rb_is_native((VALUE)obj)) -#endif - static force_inline VALUE rb_class_of(VALUE obj) { @@ -1140,10 +992,11 @@ return RBASIC(obj)->klass; } +int rb_objc_type(VALUE obj); + static force_inline int rb_type(VALUE obj) { - Class k; if (IMMEDIATE_P(obj)) { if (FIXNUM_P(obj)) { return T_FIXNUM; @@ -1154,11 +1007,6 @@ if (obj == Qtrue) { return T_TRUE; } -#if !WITH_OBJC - if (SYMBOL_P(obj)) { - return T_SYMBOL; - } -#endif if (obj == Qundef) { return T_UNDEF; } @@ -1171,47 +1019,7 @@ return T_FALSE; } } -#if WITH_OBJC - else if ((k = *(Class *)obj) != NULL) { - if (k == (Class)rb_cRubyString) { - return T_STRING; - } - if (k == (Class)rb_cRubyArray) { - return T_ARRAY; - } - if (k == (Class)rb_cRubyHash) { - return T_HASH; - } - if (RCLASS_META(k)) { - if (RCLASS_MODULE(obj)) { - return T_MODULE; - } - else { - return T_CLASS; - } - } - if (k == (Class)rb_cSymbol) { - return T_SYMBOL; - } - if (k == (Class)rb_cFixnum) { - return T_FIXNUM; - } - const long v = RCLASS_VERSION(k); - if ((v & RCLASS_IS_STRING_SUBCLASS) == RCLASS_IS_STRING_SUBCLASS) { - return T_STRING; - } - if ((v & RCLASS_IS_ARRAY_SUBCLASS) == RCLASS_IS_ARRAY_SUBCLASS) { - return T_ARRAY; - } - if ((v & RCLASS_IS_HASH_SUBCLASS) == RCLASS_IS_HASH_SUBCLASS) { - return T_HASH; - } - if (NATIVE(obj)) { - return T_NATIVE; - } - } -#endif - return BUILTIN_TYPE(obj); + return rb_objc_type(obj); } static inline void Modified: MacRuby/trunk/marshal.c =================================================================== --- MacRuby/trunk/marshal.c 2010-04-28 03:01:10 UTC (rev 3967) +++ MacRuby/trunk/marshal.c 2010-04-28 05:42:04 UTC (rev 3968) @@ -17,6 +17,7 @@ #include "encoding.h" #include "id.h" #include "re.h" +#include "class.h" #include <math.h> #ifdef HAVE_FLOAT_H @@ -208,7 +209,7 @@ (TYPE(klass) == T_CLASS ? "class" : "module"), n); } - if (rb_path2class(n) != rb_class_real(klass)) { + if (rb_path2class(n) != rb_class_real(klass, true)) { rb_raise(rb_eTypeError, "%s can't be referred", n); } return path; @@ -494,7 +495,7 @@ klass = CLASS_OF(obj); w_extended(klass, arg, check); w_byte(type, arg); - p = class2path(rb_class_real(klass)); + p = class2path(rb_class_real(klass, true)); path = RSTRING_PTR(p); w_unique(path, arg); } @@ -509,7 +510,7 @@ VALUE klass = CLASS_OF(obj); w_extended(klass, arg, Qtrue); - klass = rb_class_real(klass); + klass = rb_class_real(klass, true); #if WITH_OBJC if (!is_pure) { #else Modified: MacRuby/trunk/numeric.c =================================================================== --- MacRuby/trunk/numeric.c 2010-04-28 03:01:10 UTC (rev 3967) +++ MacRuby/trunk/numeric.c 2010-04-28 05:42:04 UTC (rev 3968) @@ -20,6 +20,7 @@ #include "vm.h" #include "id.h" #include "encoding.h" +#include "class.h" #include <unicode/utf8.h> Modified: MacRuby/trunk/objc.m =================================================================== --- MacRuby/trunk/objc.m 2010-04-28 03:01:10 UTC (rev 3967) +++ MacRuby/trunk/objc.m 2010-04-28 05:42:04 UTC (rev 3968) @@ -14,6 +14,7 @@ #include "vm.h" #include "objc.h" #include "id.h" +#include "class.h" #include <unistd.h> #include <dlfcn.h> @@ -271,31 +272,6 @@ for (int i = 0; i < count; i++) { Class k = buf[i]; if (!RCLASS_RUBY(k)) { - long v = RCLASS_VERSION(k); - if (!(v & RCLASS_IS_HASH_SUBCLASS) - && !(v & RCLASS_IS_ARRAY_SUBCLASS) - && !(v & RCLASS_IS_STRING_SUBCLASS)) { - Class k2 = k; - while (k2 != NULL) { - if (k2 == (Class)rb_cNSHash) { - v |= RCLASS_IS_HASH_SUBCLASS; - RCLASS_SET_VERSION(k, v); - break; - } - else if (k2 == (Class)rb_cNSArray) { - v |= RCLASS_IS_ARRAY_SUBCLASS; - RCLASS_SET_VERSION(k, v); - break; - } - else if (k2 == (Class)rb_cNSString) { - v |= RCLASS_IS_STRING_SUBCLASS; - RCLASS_SET_VERSION(k, v); - break; - } - k2 = class_getSuperclass(k2); - } - } - const char *name = class_getName(k); if (name[0] != '_') { ID name_id = rb_intern(name); Modified: MacRuby/trunk/object.c =================================================================== --- MacRuby/trunk/object.c 2010-04-28 03:01:10 UTC (rev 3967) +++ MacRuby/trunk/object.c 2010-04-28 05:42:04 UTC (rev 3968) @@ -24,6 +24,7 @@ #include "encoding.h" #include "array.h" #include "hash.h" +#include "class.h" VALUE rb_cBasicObject; VALUE rb_mKernel; @@ -151,34 +152,6 @@ return RTEST(result) ? Qfalse : Qtrue; } -VALUE -rb_class_real(VALUE cl) -{ - if (cl == 0) { - return 0; - } - if (RCLASS_META(cl)) { -// return rb_cClass; - return RCLASS_MODULE(cl) ? rb_cModule : rb_cClass; - } - while (RCLASS_SINGLETON(cl)) { - cl = RCLASS_SUPER(cl); - } - if (!RCLASS_RUBY(cl)) { - const long v = RCLASS_VERSION(cl); - if (v & RCLASS_IS_STRING_SUBCLASS) { - return rb_cRubyString; - } - if (v & RCLASS_IS_HASH_SUBCLASS) { - return rb_cRubyHash; - } - if (v & RCLASS_IS_ARRAY_SUBCLASS) { - return rb_cRubyArray; - } - } - return cl; -} - /* * call-seq: * obj.class => class @@ -196,7 +169,7 @@ VALUE rb_obj_class(VALUE obj) { - return rb_class_real(CLASS_OF(obj)); + return rb_class_real(CLASS_OF(obj), true); } static void @@ -384,7 +357,7 @@ static VALUE rb_nsobj_dup(VALUE obj, VALUE sel) { - VALUE klass = rb_class_real(CLASS_OF(obj)); + VALUE klass = rb_class_real(CLASS_OF(obj), true); if (class_respondsToSelector((Class)klass, selCopyWithZone)) { return (VALUE)objc_msgSend((id)obj, selCopy); } @@ -585,14 +558,14 @@ rb_raise(rb_eTypeError, "class or module required"); } - const long v = RCLASS_VERSION(cl); - if (c == rb_cRubyString && (v & RCLASS_IS_STRING_SUBCLASS)) { + const int t = TYPE(obj); + if (c == rb_cRubyString && t == T_STRING) { return Qtrue; } - if (c == rb_cRubyArray && (v & RCLASS_IS_ARRAY_SUBCLASS)) { + if (c == rb_cRubyArray && t == T_ARRAY) { return Qtrue; } - if (c == rb_cRubyHash && (v & RCLASS_IS_HASH_SUBCLASS)) { + if (c == rb_cRubyHash && t == T_HASH) { return Qtrue; } Modified: MacRuby/trunk/parse.y =================================================================== --- MacRuby/trunk/parse.y 2010-04-28 03:01:10 UTC (rev 3967) +++ MacRuby/trunk/parse.y 2010-04-28 05:42:04 UTC (rev 3968) @@ -506,6 +506,7 @@ #ifdef RIPPER #define RIPPER_VERSION "0.1.0" +#include "class.h" #include "eventids1.c" #include "eventids2.c" static ID ripper_id_gets; Modified: MacRuby/trunk/proc.c =================================================================== --- MacRuby/trunk/proc.c 2010-04-28 03:01:10 UTC (rev 3967) +++ MacRuby/trunk/proc.c 2010-04-28 05:42:04 UTC (rev 3968) @@ -10,6 +10,7 @@ #include "ruby/ruby.h" #include "ruby/node.h" #include "vm.h" +#include "class.h" #define GetCoreDataFromValue(obj, type, ptr) do { \ ptr = (type*)DATA_PTR(obj); \ Modified: MacRuby/trunk/string.c =================================================================== --- MacRuby/trunk/string.c 2010-04-28 03:01:10 UTC (rev 3967) +++ MacRuby/trunk/string.c 2010-04-28 05:42:04 UTC (rev 3968) @@ -22,6 +22,7 @@ #include "id.h" #include "ruby/node.h" #include "vm.h" +#include "class.h" #include <unicode/unum.h> #include <unicode/utrans.h> @@ -5422,7 +5423,6 @@ Init_NSString(); // rb_cRubyString is defined earlier in Init_PreVM(). - RCLASS_SET_VERSION_FLAG(rb_cRubyString, RCLASS_IS_STRING_SUBCLASS); rb_set_class_path(rb_cRubyString, rb_cObject, "String"); rb_const_set(rb_cObject, rb_intern("String"), rb_cRubyString); @@ -5935,7 +5935,7 @@ UChar rb_str_get_uchar(VALUE str, long pos) { - if (RSTR(str)) { + if (IS_RSTR(str)) { return str_get_uchar(RSTR(str), pos, true); } assert(pos >= 0 && pos < CFStringGetLength((CFStringRef)str)); @@ -5945,7 +5945,7 @@ void rb_str_append_uchar(VALUE str, UChar c) { - if (RSTR(str)) { + if (IS_RSTR(str)) { str_append_uchar(RSTR(str), c); } else { @@ -5959,7 +5959,7 @@ assert(chars != NULL && len >= 0); if (len > 0) { - if (RSTR(str)) { + if (IS_RSTR(str)) { str_concat_uchars(RSTR(str), chars, len); } else { Modified: MacRuby/trunk/variable.c =================================================================== --- MacRuby/trunk/variable.c 2010-04-28 03:01:10 UTC (rev 3967) +++ MacRuby/trunk/variable.c 2010-04-28 05:42:04 UTC (rev 3968) @@ -13,6 +13,7 @@ #include "id.h" #include "vm.h" #include "objc.h" +#include "class.h" st_table *rb_global_tbl; st_table *rb_class_tbl; @@ -333,7 +334,7 @@ VALUE rb_class_name(VALUE klass) { - return rb_class_path(rb_class_real(klass)); + return rb_class_path(rb_class_real(klass, false)); } const char * Modified: MacRuby/trunk/vm.cpp =================================================================== --- MacRuby/trunk/vm.cpp 2010-04-28 03:01:10 UTC (rev 3967) +++ MacRuby/trunk/vm.cpp 2010-04-28 05:42:04 UTC (rev 3968) @@ -49,6 +49,7 @@ #include "debugger.h" #include "objc.h" #include "dtrace.h" +#include "class.h" #include <objc/objc-exception.h> @@ -1424,7 +1425,7 @@ // Constant is already defined. check_if_module(klass); if (!(flags & DEFINE_MODULE) && super != 0) { - if (rb_class_real(RCLASS_SUPER(klass)) != super) { + if (rb_class_real(RCLASS_SUPER(klass), true) != super) { rb_raise(rb_eTypeError, "superclass mismatch for class %s", rb_class2name(klass)); } @@ -4990,8 +4991,13 @@ method_setImplementation(m, (IMP)resolveInstanceMethod_imp); // Early define some classes. - rb_cSymbol = rb_objc_create_class("Symbol", - (VALUE)objc_getClass("NSString")); + rb_cNSString = (VALUE)objc_getClass("NSString"); + assert(rb_cNSString != 0); + rb_cNSArray = (VALUE)objc_getClass("NSArray"); + assert(rb_cNSArray != 0); + rb_cNSHash = (VALUE)objc_getClass("NSDictionary"); + assert(rb_cNSHash != 0); + rb_cSymbol = rb_objc_create_class("Symbol", rb_cNSString); rb_cEncoding = rb_objc_create_class("Encoding", (VALUE)objc_getClass("NSObject")); rb_cRubyString = rb_objc_create_class("String", Modified: MacRuby/trunk/vm_eval.c =================================================================== --- MacRuby/trunk/vm_eval.c 2010-04-28 03:01:10 UTC (rev 3967) +++ MacRuby/trunk/vm_eval.c 2010-04-28 05:42:04 UTC (rev 3968) @@ -17,6 +17,7 @@ #include "vm.h" #include "objc.h" #include "id.h" +#include "class.h" #include "vm_method.c"
participants (1)
-
source_changes@macosforge.org