static VALUE bug_sym_attrset(VALUE self, VALUE name) { ID id = rb_to_id(name); id = rb_id_attrset(id); return ID2SYM(id); }
static VALUE setup_struct(VALUE nstr, VALUE members) { const VALUE *ptr_members; long i, len; OBJ_FREEZE(members); rb_ivar_set(nstr, id_members, members); rb_define_alloc_func(nstr, struct_alloc); rb_define_singleton_method(nstr, "new", rb_class_new_instance, -1); rb_define_singleton_method(nstr, "[]", rb_class_new_instance, -1); rb_define_singleton_method(nstr, "members", rb_struct_s_members_m, 0); ptr_members = RARRAY_CONST_PTR(members); len = RARRAY_LEN(members); for (i=0; i< len; i++) { ID id = SYM2ID(ptr_members[i]); if (i < N_REF_FUNC) { rb_define_method_id(nstr, id, ref_func[i], 0); } else { rb_define_method_id(nstr, id, rb_struct_ref, 0); } rb_define_method_id(nstr, rb_id_attrset(id), rb_struct_set, 1); } return nstr; }
static VALUE make_struct(VALUE name, VALUE members, VALUE klass) { VALUE nstr; ID id; long i, count; OBJ_FREEZE(members); if (NIL_P(name)) { nstr = rb_class_new(klass); #if !WITH_OBJC rb_make_metaclass(nstr, RBASIC(klass)->klass); #endif rb_class_inherited(klass, nstr); } else { /* old style: should we warn? */ name = rb_str_to_str(name); id = rb_to_id(name); if (!rb_is_const_id(id)) { rb_name_error(id, "identifier %s needs to be constant", StringValuePtr(name)); } if (rb_const_defined_at(klass, id)) { rb_warn("redefining constant Struct::%s", StringValuePtr(name)); rb_mod_remove_const(klass, ID2SYM(id)); } nstr = rb_define_class_under(klass, rb_id2name(id), klass); } rb_iv_set(nstr, "__size__", LONG2NUM(RARRAY_LEN(members))); rb_iv_set(nstr, "__members__", members); rb_objc_define_method(*(VALUE *)nstr, "alloc", struct_alloc, 0); rb_objc_define_method(*(VALUE *)nstr, "new", rb_class_new_instance_imp, -1); rb_objc_define_method(*(VALUE *)nstr, "[]", rb_class_new_instance_imp, -1); rb_objc_define_method(*(VALUE *)nstr, "members", rb_struct_s_members_m, 0); for (i = 0, count = RARRAY_LEN(members); i < count; i++) { ID id = SYM2ID(RARRAY_AT(members, i)); if (rb_is_local_id(id) || rb_is_const_id(id)) { if (i < N_REF_FUNC) { rb_objc_define_method(nstr, rb_id2name(id), ref_func[i], 0); } else { rb_objc_define_method(nstr, rb_id2name(id), rb_struct_ref, 0); } rb_objc_define_method(nstr, rb_id2name(rb_id_attrset(id)), rb_struct_set, 1); } } return nstr; }
static VALUE make_struct(VALUE name, VALUE members, VALUE klass) { VALUE nstr, *ptr_members; ID id; long i, len; OBJ_FREEZE(members); if (NIL_P(name)) { nstr = rb_class_new(klass); rb_make_metaclass(nstr, RBASIC(klass)->klass); rb_class_inherited(klass, nstr); } else { /* old style: should we warn? */ name = rb_str_to_str(name); id = rb_to_id(name); if (!rb_is_const_id(id)) { rb_name_error(id, "identifier %s needs to be constant", StringValuePtr(name)); } if (rb_const_defined_at(klass, id)) { rb_warn("redefining constant Struct::%s", StringValuePtr(name)); rb_mod_remove_const(klass, ID2SYM(id)); } nstr = rb_define_class_id_under(klass, id, klass); } rb_ivar_set(nstr, id_members, members); rb_define_alloc_func(nstr, struct_alloc); rb_define_singleton_method(nstr, "new", rb_class_new_instance, -1); rb_define_singleton_method(nstr, "[]", rb_class_new_instance, -1); rb_define_singleton_method(nstr, "members", rb_struct_s_members_m, 0); ptr_members = RARRAY_PTR(members); len = RARRAY_LEN(members); for (i=0; i< len; i++) { ID id = SYM2ID(ptr_members[i]); if (rb_is_local_id(id) || rb_is_const_id(id)) { if (i < N_REF_FUNC) { rb_define_method_id(nstr, id, ref_func[i], 0); } else { rb_define_method_id(nstr, id, rb_struct_ref, 0); } rb_define_method_id(nstr, rb_id_attrset(id), rb_struct_set, 1); } } return nstr; }
static VALUE make_struct(VALUE name, VALUE members, VALUE klass) { VALUE nstr; ID id; long i; OBJ_FREEZE(members); if (NIL_P(name)) { nstr = rb_class_new(klass); rb_make_metaclass(nstr, RBASIC(klass)->klass); rb_class_inherited(klass, nstr); } else { char *cname = StringValuePtr(name); id = rb_intern(cname); if (!rb_is_const_id(id)) { rb_name_error(id, "identifier %s needs to be constant", cname); } if (rb_const_defined_at(klass, id)) { rb_warn("redefining constant Struct::%s", cname); rb_mod_remove_const(klass, ID2SYM(id)); } nstr = rb_define_class_under(klass, rb_id2name(id), klass); } rb_iv_set(nstr, "__size__", LONG2NUM(RARRAY(members)->len)); rb_iv_set(nstr, "__members__", members); rb_define_alloc_func(nstr, struct_alloc); rb_define_singleton_method(nstr, "new", rb_class_new_instance, -1); rb_define_singleton_method(nstr, "[]", rb_class_new_instance, -1); rb_define_singleton_method(nstr, "members", rb_struct_s_members_m, 0); for (i=0; i< RARRAY(members)->len; i++) { ID id = SYM2ID(RARRAY(members)->ptr[i]); if (rb_is_local_id(id) || rb_is_const_id(id)) { if (i<10) { rb_define_method_id(nstr, id, ref_func[i], 0); } else { rb_define_method_id(nstr, id, rb_struct_ref, 0); } rb_define_method_id(nstr, rb_id_attrset(id), rb_struct_set, 1); } } return nstr; }
static VALUE rb_struct_set(VALUE obj, VALUE val) { VALUE members, slot; long i; members = rb_struct_members(obj); rb_struct_modify(obj); for (i=0; i<RARRAY_LEN(members); i++) { slot = RARRAY_PTR(members)[i]; if (rb_id_attrset(SYM2ID(slot)) == rb_frame_this_func()) { return RSTRUCT_PTR(obj)[i] = val; } } rb_name_error(rb_frame_this_func(), "`%s' is not a struct member", rb_id2name(rb_frame_this_func())); return Qnil; /* not reached */ }
void rb_attr(VALUE klass, ID id, int read, int write, int ex) { const char *name; ID attriv; VALUE aname; int noex; if (!ex) { noex = NOEX_PUBLIC; } else { if (SCOPE_TEST(NOEX_PRIVATE)) { noex = NOEX_PRIVATE; rb_warning((SCOPE_CHECK(NOEX_MODFUNC)) ? "attribute accessor as module_function" : "private attribute?"); } else if (SCOPE_TEST(NOEX_PROTECTED)) { noex = NOEX_PROTECTED; } else { noex = NOEX_PUBLIC; } } if (!rb_is_local_id(id) && !rb_is_const_id(id)) { rb_name_error(id, "invalid attribute name `%s'", rb_id2name(id)); } name = rb_id2name(id); if (!name) { rb_raise(rb_eArgError, "argument needs to be symbol or string"); } aname = rb_sprintf("@%s", name); rb_enc_copy(aname, rb_id2str(id)); attriv = rb_intern_str(aname); if (read) { rb_add_method(klass, id, NEW_IVAR(attriv), noex); } if (write) { rb_add_method(klass, rb_id_attrset(id), NEW_ATTRSET(attriv), noex); } }
static VALUE rb_struct_set(VALUE obj, VALUE val) { VALUE members, slot; ID id; long i; members = rb_struct_members(obj); rb_struct_modify(obj); id = ruby_frame->orig_func; for (i=0; i<RARRAY(members)->len; i++) { slot = RARRAY(members)->ptr[i]; if (rb_id_attrset(SYM2ID(slot)) == id) { return RSTRUCT(obj)->ptr[i] = val; } } rb_name_error(ruby_frame->last_func, "`%s' is not a struct member", rb_id2name(id)); return Qnil; /* not reached */ }
static VALUE rb_struct_set(VALUE obj, VALUE val) { VALUE members, slot; long i, len; members = rb_struct_members(obj); len = RARRAY_LEN(members); rb_struct_modify(obj); for (i=0; i<len; i++) { slot = RARRAY_AREF(members, i); if (rb_id_attrset(SYM2ID(slot)) == rb_frame_this_func()) { RSTRUCT_SET(obj, i, val); return val; } } rb_name_error(rb_frame_this_func(), "`%s' is not a struct member", rb_id2name(rb_frame_this_func())); UNREACHABLE; }
static VALUE rb_struct_set(VALUE obj, VALUE val) { VALUE members, slot, *ptr, *ptr_members; long i, len; members = rb_struct_members(obj); ptr_members = RARRAY_PTR(members); len = RARRAY_LEN(members); rb_struct_modify(obj); ptr = RSTRUCT_PTR(obj); for (i=0; i<len; i++) { slot = ptr_members[i]; if (rb_id_attrset(SYM2ID(slot)) == rb_frame_this_func()) { return ptr[i] = val; } } rb_name_error(rb_frame_this_func(), "`%s' is not a struct member", rb_id2name(rb_frame_this_func())); UNREACHABLE; }
void rb_attr(VALUE klass, ID id, int read, int write, int ex) { VALUE attriv; VALUE aname; rb_method_flag_t noex; if (!ex) { noex = NOEX_PUBLIC; } else { if (SCOPE_TEST(NOEX_PRIVATE)) { noex = NOEX_PRIVATE; rb_warning((SCOPE_CHECK(NOEX_MODFUNC)) ? "attribute accessor as module_function" : "private attribute?"); } else if (SCOPE_TEST(NOEX_PROTECTED)) { noex = NOEX_PROTECTED; } else { noex = NOEX_PUBLIC; } } aname = rb_id2str(rb_check_attr_id(id)); if (NIL_P(aname)) { rb_raise(rb_eArgError, "argument needs to be symbol or string"); } attriv = (VALUE)rb_intern_str(rb_sprintf("@%"PRIsVALUE, aname)); if (read) { rb_add_method(klass, id, VM_METHOD_TYPE_IVAR, (void *)attriv, noex); } if (write) { rb_add_method(klass, rb_id_attrset(id), VM_METHOD_TYPE_ATTRSET, (void *)attriv, noex); } }
static ID rb_intern_uchars(const UChar *chars, const size_t chars_len, VALUE str) { const unsigned long name_hash = rb_str_hash_uchars(chars, chars_len); LOCK(); ID id = (ID)CFDictionaryGetValue(sym_id, (const void *)name_hash); UNLOCK(); if (id != 0) { goto return_id; } if (str == Qnil) { str = rb_unicode_str_new(chars, chars_len); } rb_sym_t *sym = NULL; long pos = 0; if (chars_len > 0) { UChar c = chars[0]; switch (c) { case '$': id = ID_GLOBAL; goto new_id; case '@': if (chars_len > 1 && chars[1] == '@') { pos++; id = ID_CLASS; } else { id = ID_INSTANCE; } pos++; break; default: if (chars_len > 1 && chars[chars_len - 1] == '=') { // Attribute assignment. id = rb_intern_str(rb_str_substr(str, 0, chars_len - 1)); if (!is_attrset_id(id)) { id = rb_id_attrset(id); goto id_register; } id = ID_ATTRSET; } else if (iswupper(c)) { id = ID_CONST; } else { id = ID_LOCAL; } break; } } if (pos < chars_len && !isdigit(chars[pos])) { for (; pos < chars_len; pos++) { if (!is_identchar(chars[pos])) { break; } } } if (pos < chars_len) { id = ID_JUNK; } new_id: id |= ++last_id << ID_SCOPE_SHIFT; id_register: //printf("register %s hash %ld id %ld\n", RSTRING_PTR(str), name_hash, id); sym = sym_alloc(str, id); LOCK(); CFDictionarySetValue(sym_id, (const void *)name_hash, (const void *)id); CFDictionarySetValue(id_str, (const void *)id, (const void *)sym); UNLOCK(); return_id: return id; }