summaryrefslogtreecommitdiffhomepage
path: root/src/variable.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/variable.c')
-rw-r--r--src/variable.c91
1 files changed, 55 insertions, 36 deletions
diff --git a/src/variable.c b/src/variable.c
index 348d1e3e3..dce598835 100644
--- a/src/variable.c
+++ b/src/variable.c
@@ -79,19 +79,19 @@ iv_put(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value val)
}
/* Not found */
- t->size++;
if (matched_seg) {
matched_seg->key[matched_idx] = sym;
matched_seg->val[matched_idx] = val;
+ t->size++;
return;
}
seg = (segment*)mrb_malloc(mrb, sizeof(segment));
- if (!seg) return;
seg->next = NULL;
seg->key[0] = sym;
seg->val[0] = val;
t->last_len = 1;
+ t->size++;
if (prev) {
prev->next = seg;
}
@@ -341,23 +341,24 @@ mrb_iv_get(mrb_state *mrb, mrb_value obj, mrb_sym sym)
static inline void assign_class_name(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v);
-MRB_API void
-mrb_obj_iv_set(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v)
+void
+mrb_obj_iv_set_force(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v)
{
- iv_tbl *t;
-
- if (MRB_FROZEN_P(obj)) {
- mrb_raisef(mrb, E_FROZEN_ERROR, "can't modify frozen %S", mrb_obj_value(obj));
- }
assign_class_name(mrb, obj, sym, v);
if (!obj->iv) {
obj->iv = iv_new(mrb);
}
- t = obj->iv;
- iv_put(mrb, t, sym, v);
+ iv_put(mrb, obj->iv, sym, v);
mrb_write_barrier(mrb, (struct RBasic*)obj);
}
+MRB_API void
+mrb_obj_iv_set(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v)
+{
+ mrb_check_frozen(mrb, obj);
+ mrb_obj_iv_set_force(mrb, obj, sym, v);
+}
+
/* Iterates over the instance variable table. */
MRB_API void
mrb_iv_foreach(mrb_state *mrb, mrb_value obj, mrb_iv_foreach_func *func, void *p)
@@ -377,7 +378,7 @@ assign_class_name(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v)
{
if (namespace_p(obj->tt) && namespace_p(mrb_type(v))) {
struct RObject *c = mrb_obj_ptr(v);
- if (obj != c && ISUPPER(mrb_sym2name(mrb, sym)[0])) {
+ if (obj != c && ISUPPER(mrb_sym_name_len(mrb, sym, NULL)[0])) {
mrb_sym id_classname = mrb_intern_lit(mrb, "__classname__");
mrb_value o = mrb_obj_iv_get(mrb, c, id_classname);
@@ -387,10 +388,10 @@ assign_class_name(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v)
if (mrb_nil_p(o)) {
if ((struct RClass *)obj == mrb->object_class) {
- mrb_obj_iv_set(mrb, c, id_classname, mrb_symbol_value(sym));
+ mrb_obj_iv_set_force(mrb, c, id_classname, mrb_symbol_value(sym));
}
else {
- mrb_obj_iv_set(mrb, c, id_outer, mrb_obj_value(obj));
+ mrb_obj_iv_set_force(mrb, c, id_outer, mrb_obj_value(obj));
}
}
}
@@ -434,7 +435,7 @@ mrb_iv_name_sym_p(mrb_state *mrb, mrb_sym iv_name)
const char *s;
mrb_int len;
- s = mrb_sym2name_len(mrb, iv_name, &len);
+ s = mrb_sym_name_len(mrb, iv_name, &len);
if (len < 2) return FALSE;
if (s[0] != '@') return FALSE;
if (ISDIGIT(s[1])) return FALSE;
@@ -445,7 +446,7 @@ MRB_API void
mrb_iv_name_sym_check(mrb_state *mrb, mrb_sym iv_name)
{
if (!mrb_iv_name_sym_p(mrb, iv_name)) {
- mrb_name_error(mrb, iv_name, "'%S' is not allowed as an instance variable name", mrb_sym2str(mrb, iv_name));
+ mrb_name_error(mrb, iv_name, "'%n' is not allowed as an instance variable name", iv_name);
}
}
@@ -482,10 +483,10 @@ inspect_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p)
else {
mrb_str_cat_lit(mrb, str, ", ");
}
- s = mrb_sym2name_len(mrb, sym, &len);
+ s = mrb_sym_name_len(mrb, sym, &len);
mrb_str_cat(mrb, str, s, len);
mrb_str_cat_lit(mrb, str, "=");
- if (mrb_type(v) == MRB_TT_OBJECT) {
+ if (mrb_object_p(v)) {
ins = mrb_any_to_s(mrb, v);
}
else {
@@ -524,6 +525,7 @@ mrb_iv_remove(mrb_state *mrb, mrb_value obj, mrb_sym sym)
iv_tbl *t = mrb_obj_ptr(obj)->iv;
mrb_value val;
+ mrb_check_frozen(mrb, mrb_obj_ptr(obj));
if (iv_del(mrb, t, sym, &val)) {
return val;
}
@@ -539,7 +541,7 @@ iv_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p)
mrb_int len;
ary = *(mrb_value*)p;
- s = mrb_sym2name_len(mrb, sym, &len);
+ s = mrb_sym_name_len(mrb, sym, &len);
if (len > 1 && s[0] == '@' && s[1] != '@') {
mrb_ary_push(mrb, ary, mrb_symbol_value(sym));
}
@@ -583,7 +585,7 @@ cv_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p)
mrb_int len;
ary = *(mrb_value*)p;
- s = mrb_sym2name_len(mrb, sym, &len);
+ s = mrb_sym_name_len(mrb, sym, &len);
if (len > 2 && s[0] == '@' && s[1] == '@') {
mrb_ary_push(mrb, ary, mrb_symbol_value(sym));
}
@@ -593,7 +595,7 @@ cv_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p)
/* 15.2.2.4.19 */
/*
* call-seq:
- * mod.class_variables -> array
+ * mod.class_variables(inherit=true) -> array
*
* Returns an array of the names of class variables in <i>mod</i>.
*
@@ -611,11 +613,14 @@ mrb_mod_class_variables(mrb_state *mrb, mrb_value mod)
{
mrb_value ary;
struct RClass *c;
+ mrb_bool inherit = TRUE;
+ mrb_get_args(mrb, "|b", &inherit);
ary = mrb_ary_new(mrb);
c = mrb_class_ptr(mod);
while (c) {
iv_foreach(mrb, c->iv, cv_i, &ary);
+ if (!inherit) break;
c = c->super;
}
return ary;
@@ -652,8 +657,7 @@ mrb_mod_cv_get(mrb_state *mrb, struct RClass *c, mrb_sym sym)
if (given) return v;
}
}
- mrb_name_error(mrb, sym, "uninitialized class variable %S in %S",
- mrb_sym2str(mrb, sym), mrb_obj_value(cls));
+ mrb_name_error(mrb, sym, "uninitialized class variable %n in %C", sym, cls);
/* not reached */
return mrb_nil_value();
}
@@ -673,6 +677,7 @@ mrb_mod_cv_set(mrb_state *mrb, struct RClass *c, mrb_sym sym, mrb_value v)
iv_tbl *t = c->iv;
if (iv_get(mrb, t, sym, NULL)) {
+ mrb_check_frozen(mrb, c);
iv_put(mrb, t, sym, v);
mrb_write_barrier(mrb, (struct RBasic*)c);
return;
@@ -700,6 +705,7 @@ mrb_mod_cv_set(mrb_state *mrb, struct RClass *c, mrb_sym sym, mrb_value v)
c = cls;
}
+ mrb_check_frozen(mrb, c);
if (!c->iv) {
c->iv = iv_new(mrb);
}
@@ -737,7 +743,13 @@ mrb_vm_cv_get(mrb_state *mrb, mrb_sym sym)
{
struct RClass *c;
- c = MRB_PROC_TARGET_CLASS(mrb->c->ci->proc);
+ struct RProc *p = mrb->c->ci->proc;
+
+ for (;;) {
+ c = MRB_PROC_TARGET_CLASS(p);
+ if (c->tt != MRB_TT_SCLASS) break;
+ p = p->upper;
+ }
return mrb_mod_cv_get(mrb, c, sym);
}
@@ -745,8 +757,13 @@ void
mrb_vm_cv_set(mrb_state *mrb, mrb_sym sym, mrb_value v)
{
struct RClass *c;
+ struct RProc *p = mrb->c->ci->proc;
- c = MRB_PROC_TARGET_CLASS(mrb->c->ci->proc);
+ for (;;) {
+ c = MRB_PROC_TARGET_CLASS(p);
+ if (c->tt != MRB_TT_SCLASS) break;
+ p = p->upper;
+ }
mrb_mod_cv_set(mrb, c, sym, v);
}
@@ -877,9 +894,17 @@ const_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p)
mrb_int len;
ary = *(mrb_value*)p;
- s = mrb_sym2name_len(mrb, sym, &len);
+ s = mrb_sym_name_len(mrb, sym, &len);
if (len >= 1 && ISUPPER(s[0])) {
- mrb_ary_push(mrb, ary, mrb_symbol_value(sym));
+ mrb_int i, alen = RARRAY_LEN(ary);
+
+ for (i=0; i<alen; i++) {
+ if (mrb_symbol(RARRAY_PTR(ary)[i]) == sym)
+ break;
+ }
+ if (i==alen) {
+ mrb_ary_push(mrb, ary, mrb_symbol_value(sym));
+ }
}
return 0;
}
@@ -962,16 +987,8 @@ mrb_f_global_variables(mrb_state *mrb, mrb_value self)
{
iv_tbl *t = mrb->globals;
mrb_value ary = mrb_ary_new(mrb);
- size_t i;
- char buf[3];
iv_foreach(mrb, t, gv_i, &ary);
- buf[0] = '$';
- buf[2] = 0;
- for (i = 1; i <= 9; ++i) {
- buf[1] = (char)(i + '0');
- mrb_ary_push(mrb, ary, mrb_symbol_value(mrb_intern(mrb, buf, 2)));
- }
return ary;
}
@@ -1100,12 +1117,13 @@ mrb_class_find_path(mrb_state *mrb, struct RClass *c)
mrb_str_cat_cstr(mrb, path, str);
mrb_str_cat_cstr(mrb, path, "::");
- str = mrb_sym2name_len(mrb, name, &len);
+ str = mrb_sym_name_len(mrb, name, &len);
mrb_str_cat(mrb, path, str, len);
if (RSTRING_PTR(path)[0] != '#') {
iv_del(mrb, c->iv, mrb_intern_lit(mrb, "__outer__"), NULL);
iv_put(mrb, c->iv, mrb_intern_lit(mrb, "__classname__"), path);
mrb_field_write_barrier_value(mrb, (struct RBasic*)c, path);
+ MRB_SET_FROZEN_FLAG(mrb_obj_ptr(path));
}
return path;
}
@@ -1116,6 +1134,7 @@ mrb_bool
mrb_ident_p(const char *s, mrb_int len)
{
mrb_int i;
+
for (i = 0; i < len; i++) {
if (!identchar(s[i])) return FALSE;
}