Commit 1fa63930 authored by Yukihiro Matsumoto's avatar Yukihiro Matsumoto

check object type before retrieving instance variabls; close #311

parent 2d781f5c
......@@ -49,6 +49,7 @@ int mrb_const_defined_at(mrb_state *mrb, struct RClass *klass, mrb_sym id);
mrb_value mrb_f_global_variables(mrb_state *mrb, mrb_value self);
mrb_value mrb_gv_get(mrb_state *mrb, mrb_sym sym);
void mrb_gv_set(mrb_state *mrb, mrb_sym sym, mrb_value val);
mrb_value mrb_obj_instance_variables(mrb_state*, mrb_value);
/* GC functions */
void mrb_gc_mark_gv(mrb_state*);
......
......@@ -708,46 +708,6 @@ mrb_obj_ivar_set(mrb_state *mrb, mrb_value self)
return val;
}
/* 15.3.1.3.23 */
/*
* call-seq:
* obj.instance_variables -> array
*
* Returns an array of instance variable names for the receiver. Note
* that simply defining an accessor does not create the corresponding
* instance variable.
*
* class Fred
* attr_accessor :a1
* def initialize
* @iv = 3
* end
* end
* Fred.new.instance_variables #=> [:@iv]
*/
mrb_value
mrb_obj_instance_variables(mrb_state *mrb, mrb_value self)
{
mrb_value ary;
kh_iv_t *h = RCLASS_IV_TBL(self);
khint_t i;
const char* p;
ary = mrb_ary_new(mrb);
if (h) {
for (i=0;i<kh_end(h);i++) {
if (kh_exist(h, i)) {
p = mrb_sym2name(mrb, kh_key(h,i));
if (*p == '@') {
if (mrb_type(kh_value(h, i)) != MRB_TT_UNDEF)
mrb_ary_push(mrb, ary, mrb_str_new_cstr(mrb, p));
}
}
}
}
return ary;
}
/* 15.3.1.3.24 */
/* 15.3.1.3.26 */
/*
......
......@@ -185,6 +185,50 @@ mrb_vm_iv_set(mrb_state *mrb, mrb_sym sym, mrb_value v)
mrb_iv_set(mrb, mrb->stack[0], sym, v);
}
/* 15.3.1.3.23 */
/*
* call-seq:
* obj.instance_variables -> array
*
* Returns an array of instance variable names for the receiver. Note
* that simply defining an accessor does not create the corresponding
* instance variable.
*
* class Fred
* attr_accessor :a1
* def initialize
* @iv = 3
* end
* end
* Fred.new.instance_variables #=> [:@iv]
*/
mrb_value
mrb_obj_instance_variables(mrb_state *mrb, mrb_value self)
{
mrb_value ary;
kh_iv_t *h;
khint_t i;
int len;
const char* p;
ary = mrb_ary_new(mrb);
if (obj_iv_p(self)) {
h = ROBJECT_IVPTR(self);
if (h) {
for (i=0;i<kh_end(h);i++) {
if (kh_exist(h, i)) {
p = mrb_sym2name_len(mrb, kh_key(h,i), &len);
if (len > 1 && *p == '@') {
if (mrb_type(kh_value(h, i)) != MRB_TT_UNDEF)
mrb_ary_push(mrb, ary, mrb_str_new(mrb, p, len));
}
}
}
}
}
return ary;
}
mrb_value
mrb_vm_cv_get(mrb_state *mrb, mrb_sym sym)
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment