Esempio n. 1
0
void
rb_attr(VALUE klass, ID id, int read, int write, int ex)
{
    const char *name;
    int noex;

    if (!ex) {
	noex = NOEX_PUBLIC;
    }
    else {
	// TODO honor current scope ex
	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");
    }
    rb_vm_define_attr((Class)klass, name, read, write, noex);
    if (write) {
	rb_objc_define_kvo_setter(klass, id);
    }
}
Esempio n. 2
0
static VALUE
make_struct(VALUE name, VALUE members, VALUE klass)
{
    VALUE nstr;
    ID id;
    long i, len;

    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_ivar_set(nstr, id_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);
    len = RARRAY_LEN(members);
    for (i=0; i< len; i++) {
	ID id = SYM2ID(RARRAY_AT(members, i));
	if (rb_is_local_id(id) || rb_is_const_id(id)) {
	    long j = i; /* Needed for block data reference. */
	/* Struct attribute reader */
	rb_objc_define_method(nstr, rb_id2name(id),
		pl_imp_implementationWithBlock(^(VALUE obj) {
		    return RSTRUCT_PTR(obj)[j];
		}), 0);
	/* Struct attribute writer */
	rb_objc_define_method(nstr, rb_id2name(rb_id_attrset(id)),
		pl_imp_implementationWithBlock(^(VALUE obj, VALUE val) {
		    VALUE *ptr = RSTRUCT_PTR(obj);
		    rb_struct_modify(obj);
		    GC_WB(&ptr[i], val);
		    return val;
		}), 1);
Esempio n. 3
0
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;
}
Esempio n. 4
0
static int
collect_local_variables_in_iseq(rb_iseq_t *iseq, const VALUE ary)
{
    int i;
    if (!iseq) return 0;
    for (i = 0; i < iseq->local_table_size; i++) {
	ID lid = iseq->local_table[i];
	if (rb_is_local_id(lid)) {
	    rb_ary_push(ary, ID2SYM(lid));
	}
    }
    return 1;
}
Esempio n. 5
0
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;
}
Esempio n. 6
0
void
rb_attr(VALUE klass, ID id, int read, int write, int ex)
{
    if (!rb_is_local_id(id) && !rb_is_const_id(id)) {
	rb_name_error(id, "invalid attribute name `%s'", rb_id2name(id));
    }
    const char *name = rb_id2name(id);
    if (name == NULL) {
	rb_raise(rb_eArgError, "argument needs to be symbol or string");
    }
    rb_vm_define_attr((Class)klass, name, read, write);
    if (write) {
	rb_objc_define_kvo_setter(klass, id);
    }
}
Esempio n. 7
0
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;
}
Esempio n. 8
0
static VALUE
inspect_struct(VALUE s, VALUE dummy, int recur)
{
    VALUE cname = rb_class_name(rb_obj_class(s));
    VALUE members, str = rb_str_new2("#<struct ");
    VALUE *ptr, *ptr_members;
    long i, len;
    char first = RSTRING_PTR(cname)[0];

    if (recur || first != '#') {
	rb_str_append(str, cname);
    }
    if (recur) {
	return rb_str_cat2(str, ":...>");
    }

    members = rb_struct_members(s);
    ptr_members = RARRAY_PTR(members);
    ptr = RSTRUCT_PTR(s);
    len = RSTRUCT_LEN(s);
    for (i=0; i<len; i++) {
	VALUE slot;
	ID id;

	if (i > 0) {
	    rb_str_cat2(str, ", ");
	}
	else if (first != '#') {
	    rb_str_cat2(str, " ");
	}
	slot = ptr_members[i];
	id = SYM2ID(slot);
	if (rb_is_local_id(id) || rb_is_const_id(id)) {
	    rb_str_append(str, rb_id2str(id));
	}
	else {
	    rb_str_append(str, rb_inspect(slot));
	}
	rb_str_cat2(str, "=");
	rb_str_append(str, rb_inspect(ptr[i]));
    }
    rb_str_cat2(str, ">");
    OBJ_INFECT(str, s);

    return str;
}
Esempio n. 9
0
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);
    }
}
Esempio n. 10
0
static VALUE
inspect_struct(VALUE s, VALUE dummy, int recur)
{
    const char *cname = rb_class2name(rb_obj_class(s));
    VALUE str, members;
    long i;

    if (recur) {
	return rb_sprintf("#<struct %s:...>", cname);
    }

    members = rb_struct_members(s);
    if (cname[0] == '#') {
	str = rb_str_new2("#<struct ");
    }
    else {
	str = rb_sprintf("#<struct %s ", cname);
    }
    for (i=0; i<RSTRUCT_LEN(s); i++) {
	VALUE slot;
	ID id;

	if (i > 0) {
	    rb_str_cat2(str, ", ");
	}
	slot = RARRAY_AT(members, i);
	id = SYM2ID(slot);
	if (rb_is_local_id(id) || rb_is_const_id(id)) {
	    rb_str_buf_append(str, rb_id2str(id));
	}
	else {
	    rb_str_buf_append(str, rb_inspect(slot));
	}
	rb_str_cat2(str, "=");
	rb_str_buf_append(str, rb_inspect(RSTRUCT_PTR(s)[i]));
    }
    rb_str_cat2(str, ">");
    OBJ_INFECT(str, s);

    return str;
}
Esempio n. 11
0
static VALUE
inspect_struct(VALUE s)
{
    const char *cname = rb_class2name(rb_obj_class(s));
    VALUE str, members;
    long i;

    members = rb_struct_members(s);
    str = rb_str_buf_new2("#<struct ");
    rb_str_cat2(str, cname);
    rb_str_cat2(str, " ");
    for (i=0; i<RSTRUCT(s)->len; i++) {
	VALUE slot;
	ID id;
	const char *p;

	if (i > 0) {
	    rb_str_cat2(str, ", ");
	}
	slot = RARRAY(members)->ptr[i];
	id = SYM2ID(slot);
	if (rb_is_local_id(id) || rb_is_const_id(id)) {
	    p = rb_id2name(id);
	    rb_str_cat2(str, p);
	}
	else {
	    rb_str_append(str, rb_inspect(slot));
	}
	rb_str_cat2(str, "=");
	rb_str_append(str, rb_inspect(RSTRUCT(s)->ptr[i]));
    }
    rb_str_cat2(str, ">");
    OBJ_INFECT(str, s);

    return str;
}