Ignore:
Timestamp:
Jul 9, 2020, 8:51:43 AM (4 years ago)
Author:
coas-nagasima
Message:

mrubyを2.1.1に更新

Location:
EcnlProtoTool/trunk/mruby-2.1.1
Files:
1 edited
1 moved

Legend:

Unmodified
Added
Removed
  • EcnlProtoTool/trunk/mruby-2.1.1/src/variable.c

    r331 r439  
    1010#include <mruby/proc.h>
    1111#include <mruby/string.h>
    12 
    13 typedef int (iv_foreach_func)(mrb_state*,mrb_sym,mrb_value,void*);
    14 
    15 #ifdef MRB_USE_IV_SEGLIST
    16 
    17 #ifndef MRB_SEGMENT_SIZE
    18 #define MRB_SEGMENT_SIZE 4
     12#include <mruby/variable.h>
     13
     14#ifndef MRB_IV_SEGMENT_SIZE
     15#define MRB_IV_SEGMENT_SIZE 4
    1916#endif
    2017
    2118typedef struct segment {
    22   mrb_sym key[MRB_SEGMENT_SIZE];
    23   mrb_value val[MRB_SEGMENT_SIZE];
     19  mrb_sym key[MRB_IV_SEGMENT_SIZE];
     20  mrb_value val[MRB_IV_SEGMENT_SIZE];
    2421  struct segment *next;
    2522} segment;
     
    3229} iv_tbl;
    3330
    34 /*
    35  * Creates the instance variable table.
    36  *
    37  * Parameters
    38  *   mrb
    39  * Returns
    40  *   the instance variable table.
    41  */
     31/* Creates the instance variable table. */
    4232static iv_tbl*
    4333iv_new(mrb_state *mrb)
     
    5343}
    5444
    55 /*
    56  * Set the value for the symbol in the instance variable table.
    57  *
    58  * Parameters
    59  *   mrb
    60  *   t     the instance variable table to be set in.
    61  *   sym   the symbol to be used as the key.
    62  *   val   the value to be set.
    63  */
     45/* Set the value for the symbol in the instance variable table. */
    6446static void
    6547iv_put(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value val)
    6648{
    67   segment *seg = t->rootseg;
     49  segment *seg;
    6850  segment *prev = NULL;
    6951  segment *matched_seg = NULL;
     
    7153  size_t i;
    7254
     55  if (t == NULL) return;
     56  seg = t->rootseg;
    7357  while (seg) {
    74     for (i=0; i<MRB_SEGMENT_SIZE; i++) {
     58    for (i=0; i<MRB_IV_SEGMENT_SIZE; i++) {
    7559      mrb_sym key = seg->key[i];
    7660      /* Found room in last segment after last_len */
     
    9680
    9781  /* Not found */
    98   t->size++;
    9982  if (matched_seg) {
    10083    matched_seg->key[matched_idx] = sym;
    10184    matched_seg->val[matched_idx] = val;
     85    t->size++;
    10286    return;
    10387  }
    10488
    10589  seg = (segment*)mrb_malloc(mrb, sizeof(segment));
    106   if (!seg) return;
    10790  seg->next = NULL;
    10891  seg->key[0] = sym;
    10992  seg->val[0] = val;
    11093  t->last_len = 1;
     94  t->size++;
    11195  if (prev) {
    11296    prev->next = seg;
     
    117101}
    118102
    119 /*
    120  * Get a value for a symbol from the instance variable table.
    121  *
    122  * Parameters
    123  *   mrb
    124  *   t     the variable table to be searched.
    125  *   sym   the symbol to be used as the key.
    126  *   vp    the value pointer. Receives the value if the specified symbol is
    127  *         contained in the instance variable table.
    128  * Returns
    129  *   true if the specified symbol is contained in the instance variable table.
    130  */
     103/* Get a value for a symbol from the instance variable table. */
    131104static mrb_bool
    132105iv_get(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value *vp)
     
    135108  size_t i;
    136109
     110  if (t == NULL) return FALSE;
    137111  seg = t->rootseg;
    138112  while (seg) {
    139     for (i=0; i<MRB_SEGMENT_SIZE; i++) {
     113    for (i=0; i<MRB_IV_SEGMENT_SIZE; i++) {
    140114      mrb_sym key = seg->key[i];
    141115
     
    153127}
    154128
    155 /*
    156  * Deletes the value for the symbol from the instance variable table.
    157  *
    158  * Parameters
    159  *   t    the variable table to be searched.
    160  *   sym  the symbol to be used as the key.
    161  *   vp   the value pointer. Receive the deleted value if the symbol is
    162  *        contained in the instance variable table.
    163  * Returns
    164  *   true if the specified symbol is contained in the instance variable table.
    165  */
     129/* Deletes the value for the symbol from the instance variable table. */
    166130static mrb_bool
    167131iv_del(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value *vp)
     
    170134  size_t i;
    171135
     136  if (t == NULL) return FALSE;
    172137  seg = t->rootseg;
    173138  while (seg) {
    174     for (i=0; i<MRB_SEGMENT_SIZE; i++) {
     139    for (i=0; i<MRB_IV_SEGMENT_SIZE; i++) {
    175140      mrb_sym key = seg->key[i];
    176141
     
    190155}
    191156
    192 static mrb_bool
    193 iv_foreach(mrb_state *mrb, iv_tbl *t, iv_foreach_func *func, void *p)
     157/* Iterates over the instance variable table. */
     158static void
     159iv_foreach(mrb_state *mrb, iv_tbl *t, mrb_iv_foreach_func *func, void *p)
    194160{
    195161  segment *seg;
    196162  size_t i;
    197   int n;
    198 
     163
     164  if (t == NULL) return;
    199165  seg = t->rootseg;
    200166  while (seg) {
    201     for (i=0; i<MRB_SEGMENT_SIZE; i++) {
     167    for (i=0; i<MRB_IV_SEGMENT_SIZE; i++) {
    202168      mrb_sym key = seg->key[i];
    203169
    204170      /* no value in last segment after last_len */
    205171      if (!seg->next && i >= t->last_len) {
    206         return FALSE;
     172        return;
    207173      }
    208174      if (key != 0) {
    209         n =(*func)(mrb, key, seg->val[i], p);
    210         if (n > 0) return FALSE;
    211         if (n < 0) {
    212           t->size--;
    213           seg->key[i] = 0;
     175        if ((*func)(mrb, key, seg->val[i], p) != 0) {
     176          return;
    214177        }
    215178      }
     
    217180    seg = seg->next;
    218181  }
    219   return TRUE;
    220 }
    221 
     182  return;
     183}
     184
     185/* Get the size of the instance variable table. */
    222186static size_t
    223187iv_size(mrb_state *mrb, iv_tbl *t)
     
    226190  size_t size = 0;
    227191
    228   if (!t) return 0;
     192  if (t == NULL) return 0;
    229193  if (t->size > 0) return t->size;
    230194  seg = t->rootseg;
     
    235199    }
    236200    seg = seg->next;
    237     size += MRB_SEGMENT_SIZE;
     201    size += MRB_IV_SEGMENT_SIZE;
    238202  }
    239203  /* empty iv_tbl */
     
    241205}
    242206
     207/* Copy the instance variable table. */
    243208static iv_tbl*
    244209iv_copy(mrb_state *mrb, iv_tbl *t)
     
    253218
    254219  while (seg != NULL) {
    255     for (i=0; i<MRB_SEGMENT_SIZE; i++) {
     220    for (i=0; i<MRB_IV_SEGMENT_SIZE; i++) {
    256221      mrb_sym key = seg->key[i];
    257222      mrb_value val = seg->val[i];
     
    267232}
    268233
     234/* Free memory of the instance variable table. */
    269235static void
    270236iv_free(mrb_state *mrb, iv_tbl *t)
     
    281247}
    282248
    283 #else
    284 
    285 #include <mruby/khash.h>
    286 
    287 #ifndef MRB_IVHASH_INIT_SIZE
    288 #define MRB_IVHASH_INIT_SIZE 8
    289 #endif
    290 
    291 KHASH_DECLARE(iv, mrb_sym, mrb_value, TRUE)
    292 KHASH_DEFINE(iv, mrb_sym, mrb_value, TRUE, kh_int_hash_func, kh_int_hash_equal)
    293 
    294 typedef struct iv_tbl {
    295   khash_t(iv) h;
    296 } iv_tbl;
    297 
    298 static iv_tbl*
    299 iv_new(mrb_state *mrb)
    300 {
    301   return (iv_tbl*)kh_init_size(iv, mrb, MRB_IVHASH_INIT_SIZE);
    302 }
    303 
    304 static void
    305 iv_put(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value val)
    306 {
    307   khash_t(iv) *h = &t->h;
    308   khiter_t k;
    309 
    310   k = kh_put(iv, mrb, h, sym);
    311   kh_value(h, k) = val;
    312 }
    313 
    314 static mrb_bool
    315 iv_get(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value *vp)
    316 {
    317   khash_t(iv) *h = &t->h;
    318   khiter_t k;
    319 
    320   k = kh_get(iv, mrb, h, sym);
    321   if (k != kh_end(h)) {
    322     if (vp) *vp = kh_value(h, k);
    323     return TRUE;
    324   }
    325   return FALSE;
    326 }
    327 
    328 static mrb_bool
    329 iv_del(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value *vp)
    330 {
    331   khash_t(iv) *h = &t->h;
    332   khiter_t k;
    333 
    334   if (h) {
    335     k = kh_get(iv, mrb, h, sym);
    336     if (k != kh_end(h)) {
    337       mrb_value val = kh_value(h, k);
    338       kh_del(iv, mrb, h, k);
    339       if (vp) *vp = val;
    340       return TRUE;
    341     }
    342   }
    343   return FALSE;
    344 }
    345 
    346 static mrb_bool
    347 iv_foreach(mrb_state *mrb, iv_tbl *t, iv_foreach_func *func, void *p)
    348 {
    349   khash_t(iv) *h = &t->h;
    350   khiter_t k;
    351   int n;
    352 
    353   if (h) {
    354     for (k = kh_begin(h); k != kh_end(h); k++) {
    355       if (kh_exist(h, k)) {
    356         n = (*func)(mrb, kh_key(h, k), kh_value(h, k), p);
    357         if (n > 0) return FALSE;
    358         if (n < 0) {
    359           kh_del(iv, mrb, h, k);
    360         }
    361       }
    362     }
    363   }
    364   return TRUE;
    365 }
    366 
    367 static size_t
    368 iv_size(mrb_state *mrb, iv_tbl *t)
    369 {
    370   khash_t(iv) *h;
    371 
    372   if (t && (h = &t->h)) {
    373     return kh_size(h);
    374   }
    375   return 0;
    376 }
    377 
    378 static iv_tbl*
    379 iv_copy(mrb_state *mrb, iv_tbl *t)
    380 {
    381   return (iv_tbl*)kh_copy(iv, mrb, &t->h);
    382 }
    383 
    384 static void
    385 iv_free(mrb_state *mrb, iv_tbl *t)
    386 {
    387   kh_destroy(iv, mrb, &t->h);
    388 }
    389 
    390 #endif
    391 
    392249static int
    393250iv_mark_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p)
     
    400257mark_tbl(mrb_state *mrb, iv_tbl *t)
    401258{
    402   if (t) {
    403     iv_foreach(mrb, t, iv_mark_i, 0);
    404   }
     259  iv_foreach(mrb, t, iv_mark_i, 0);
    405260}
    406261
     
    485340}
    486341
     342static inline void assign_class_name(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v);
     343
     344void
     345mrb_obj_iv_set_force(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v)
     346{
     347  assign_class_name(mrb, obj, sym, v);
     348  if (!obj->iv) {
     349    obj->iv = iv_new(mrb);
     350  }
     351  iv_put(mrb, obj->iv, sym, v);
     352  mrb_write_barrier(mrb, (struct RBasic*)obj);
     353}
     354
    487355MRB_API void
    488356mrb_obj_iv_set(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v)
    489357{
    490   iv_tbl *t = obj->iv;
    491 
    492   if (MRB_FROZEN_P(obj)) {
    493     mrb_raisef(mrb, E_RUNTIME_ERROR, "can't modify frozen %S", mrb_obj_value(obj));
    494   }
    495   if (!t) {
    496     t = obj->iv = iv_new(mrb);
    497   }
    498   mrb_write_barrier(mrb, (struct RBasic*)obj);
    499   iv_put(mrb, t, sym, v);
    500 }
    501 
    502 MRB_API void
    503 mrb_obj_iv_ifnone(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v)
    504 {
    505   iv_tbl *t = obj->iv;
    506 
    507   if (!t) {
    508     t = obj->iv = iv_new(mrb);
    509   }
    510   else if (iv_get(mrb, t, sym, &v)) {
    511     return;
    512   }
    513   mrb_write_barrier(mrb, (struct RBasic*)obj);
    514   iv_put(mrb, t, sym, v);
     358  mrb_check_frozen(mrb, obj);
     359  mrb_obj_iv_set_force(mrb, obj, sym, v);
     360}
     361
     362/* Iterates over the instance variable table. */
     363MRB_API void
     364mrb_iv_foreach(mrb_state *mrb, mrb_value obj, mrb_iv_foreach_func *func, void *p)
     365{
     366  if (!obj_iv_p(obj)) return;
     367  iv_foreach(mrb, mrb_obj_ptr(obj)->iv, func, p);
     368}
     369
     370static inline mrb_bool
     371namespace_p(enum mrb_vtype tt)
     372{
     373  return tt == MRB_TT_CLASS || tt == MRB_TT_MODULE ? TRUE : FALSE;
     374}
     375
     376static inline void
     377assign_class_name(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v)
     378{
     379  if (namespace_p(obj->tt) && namespace_p(mrb_type(v))) {
     380    struct RObject *c = mrb_obj_ptr(v);
     381    if (obj != c && ISUPPER(mrb_sym_name_len(mrb, sym, NULL)[0])) {
     382      mrb_sym id_classname = mrb_intern_lit(mrb, "__classname__");
     383      mrb_value o = mrb_obj_iv_get(mrb, c, id_classname);
     384
     385      if (mrb_nil_p(o)) {
     386        mrb_sym id_outer = mrb_intern_lit(mrb, "__outer__");
     387        o = mrb_obj_iv_get(mrb, c, id_outer);
     388
     389        if (mrb_nil_p(o)) {
     390          if ((struct RClass *)obj == mrb->object_class) {
     391            mrb_obj_iv_set_force(mrb, c, id_classname, mrb_symbol_value(sym));
     392          }
     393          else {
     394            mrb_obj_iv_set_force(mrb, c, id_outer, mrb_obj_value(obj));
     395          }
     396        }
     397      }
     398    }
     399  }
    515400}
    516401
     
    545430}
    546431
    547 #define identchar(c) (ISALNUM(c) || (c) == '_' || !ISASCII(c))
    548 
    549432MRB_API mrb_bool
    550 mrb_iv_p(mrb_state *mrb, mrb_sym iv_name)
     433mrb_iv_name_sym_p(mrb_state *mrb, mrb_sym iv_name)
    551434{
    552435  const char *s;
    553   mrb_int i, len;
    554 
    555   s = mrb_sym2name_len(mrb, iv_name, &len);
     436  mrb_int len;
     437
     438  s = mrb_sym_name_len(mrb, iv_name, &len);
    556439  if (len < 2) return FALSE;
    557440  if (s[0] != '@') return FALSE;
    558   if (s[1] == '@') return FALSE;
    559   for (i=1; i<len; i++) {
    560     if (!identchar(s[i])) return FALSE;
    561   }
    562   return TRUE;
    563 }
    564 
    565 MRB_API void
    566 mrb_iv_check(mrb_state *mrb, mrb_sym iv_name)
    567 {
    568   if (!mrb_iv_p(mrb, iv_name)) {
    569     mrb_name_error(mrb, iv_name, "'%S' is not allowed as an instance variable name", mrb_sym2str(mrb, iv_name));
     441  if (ISDIGIT(s[1])) return FALSE;
     442  return mrb_ident_p(s+1, len-1);
     443}
     444
     445MRB_API void
     446mrb_iv_name_sym_check(mrb_state *mrb, mrb_sym iv_name)
     447{
     448  if (!mrb_iv_name_sym_p(mrb, iv_name)) {
     449    mrb_name_error(mrb, iv_name, "'%n' is not allowed as an instance variable name", iv_name);
    570450  }
    571451}
     
    604484    mrb_str_cat_lit(mrb, str, ", ");
    605485  }
    606   s = mrb_sym2name_len(mrb, sym, &len);
     486  s = mrb_sym_name_len(mrb, sym, &len);
    607487  mrb_str_cat(mrb, str, s, len);
    608488  mrb_str_cat_lit(mrb, str, "=");
    609   if (mrb_type(v) == MRB_TT_OBJECT) {
     489  if (mrb_object_p(v)) {
    610490    ins = mrb_any_to_s(mrb, v);
    611491  }
     
    625505  if (len > 0) {
    626506    const char *cn = mrb_obj_classname(mrb, mrb_obj_value(obj));
    627     mrb_value str = mrb_str_buf_new(mrb, 30);
     507    mrb_value str = mrb_str_new_capa(mrb, 30);
    628508
    629509    mrb_str_cat_lit(mrb, str, "-<");
    630510    mrb_str_cat_cstr(mrb, str, cn);
    631511    mrb_str_cat_lit(mrb, str, ":");
    632     mrb_str_concat(mrb, str, mrb_ptr_to_str(mrb, obj));
     512    mrb_str_cat_str(mrb, str, mrb_ptr_to_str(mrb, obj));
    633513
    634514    iv_foreach(mrb, t, inspect_i, &str);
     
    646526    mrb_value val;
    647527
    648     if (t && iv_del(mrb, t, sym, &val)) {
     528    mrb_check_frozen(mrb, mrb_obj_ptr(obj));
     529    if (iv_del(mrb, t, sym, &val)) {
    649530      return val;
    650531    }
    651532  }
    652533  return mrb_undef_value();
    653 }
    654 
    655 mrb_value
    656 mrb_vm_iv_get(mrb_state *mrb, mrb_sym sym)
    657 {
    658   /* get self */
    659   return mrb_iv_get(mrb, mrb->c->stack[0], sym);
    660 }
    661 
    662 void
    663 mrb_vm_iv_set(mrb_state *mrb, mrb_sym sym, mrb_value v)
    664 {
    665   /* get self */
    666   mrb_iv_set(mrb, mrb->c->stack[0], sym, v);
    667534}
    668535
     
    675542
    676543  ary = *(mrb_value*)p;
    677   s = mrb_sym2name_len(mrb, sym, &len);
     544  s = mrb_sym_name_len(mrb, sym, &len);
    678545  if (len > 1 && s[0] == '@' && s[1] != '@') {
    679546    mrb_ary_push(mrb, ary, mrb_symbol_value(sym));
     
    705572
    706573  ary = mrb_ary_new(mrb);
    707   if (obj_iv_p(self) && mrb_obj_ptr(self)->iv) {
     574  if (obj_iv_p(self)) {
    708575    iv_foreach(mrb, mrb_obj_ptr(self)->iv, iv_i, &ary);
    709576  }
     
    719586
    720587  ary = *(mrb_value*)p;
    721   s = mrb_sym2name_len(mrb, sym, &len);
     588  s = mrb_sym_name_len(mrb, sym, &len);
    722589  if (len > 2 && s[0] == '@' && s[1] == '@') {
    723590    mrb_ary_push(mrb, ary, mrb_symbol_value(sym));
     
    729596/*
    730597 *  call-seq:
    731  *     mod.class_variables   -> array
     598 *     mod.class_variables(inherit=true)   -> array
    732599 *
    733600 *  Returns an array of the names of class variables in <i>mod</i>.
     
    747614  mrb_value ary;
    748615  struct RClass *c;
    749 
     616  mrb_bool inherit = TRUE;
     617
     618  mrb_get_args(mrb, "|b", &inherit);
    750619  ary = mrb_ary_new(mrb);
    751620  c = mrb_class_ptr(mod);
    752621  while (c) {
    753     if (c->iv) {
    754       iv_foreach(mrb, c->iv, cv_i, &ary);
    755     }
     622    iv_foreach(mrb, c->iv, cv_i, &ary);
     623    if (!inherit) break;
    756624    c = c->super;
    757625  }
     
    759627}
    760628
    761 MRB_API mrb_value
     629mrb_value
    762630mrb_mod_cv_get(mrb_state *mrb, struct RClass *c, mrb_sym sym)
    763631{
     
    790658    }
    791659  }
    792   mrb_name_error(mrb, sym, "uninitialized class variable %S in %S",
    793                  mrb_sym2str(mrb, sym), mrb_obj_value(cls));
     660  mrb_name_error(mrb, sym, "uninitialized class variable %n in %C", sym, cls);
    794661  /* not reached */
    795662  return mrb_nil_value();
     
    808675
    809676  while (c) {
    810     if (c->iv) {
    811       iv_tbl *t = c->iv;
    812 
    813       if (iv_get(mrb, t, sym, NULL)) {
    814         mrb_write_barrier(mrb, (struct RBasic*)c);
    815         iv_put(mrb, t, sym, v);
    816         return;
    817       }
     677    iv_tbl *t = c->iv;
     678
     679    if (iv_get(mrb, t, sym, NULL)) {
     680      mrb_check_frozen(mrb, c);
     681      iv_put(mrb, t, sym, v);
     682      mrb_write_barrier(mrb, (struct RBasic*)c);
     683      return;
    818684    }
    819685    c = c->super;
     
    840706  }
    841707
     708  mrb_check_frozen(mrb, c);
    842709  if (!c->iv) {
    843710    c->iv = iv_new(mrb);
    844711  }
    845712
     713  iv_put(mrb, c->iv, sym, v);
    846714  mrb_write_barrier(mrb, (struct RBasic*)c);
    847   iv_put(mrb, c->iv, sym, v);
    848715}
    849716
     
    854721}
    855722
    856 MRB_API mrb_bool
     723mrb_bool
    857724mrb_mod_cv_defined(mrb_state *mrb, struct RClass * c, mrb_sym sym)
    858725{
    859726  while (c) {
    860     if (c->iv) {
    861       iv_tbl *t = c->iv;
    862       if (iv_get(mrb, t, sym, NULL)) return TRUE;
    863     }
     727    iv_tbl *t = c->iv;
     728    if (iv_get(mrb, t, sym, NULL)) return TRUE;
    864729    c = c->super;
    865730  }
     
    877742mrb_vm_cv_get(mrb_state *mrb, mrb_sym sym)
    878743{
    879   struct RClass *c = mrb->c->ci->proc->target_class;
    880 
    881   if (!c) c = mrb->c->ci->target_class;
    882 
     744  struct RClass *c;
     745
     746  struct RProc *p = mrb->c->ci->proc;
     747
     748  for (;;) {
     749    c = MRB_PROC_TARGET_CLASS(p);
     750    if (c->tt != MRB_TT_SCLASS) break;
     751    p = p->upper;
     752  }
    883753  return mrb_mod_cv_get(mrb, c, sym);
    884754}
     
    887757mrb_vm_cv_set(mrb_state *mrb, mrb_sym sym, mrb_value v)
    888758{
    889   struct RClass *c = mrb->c->ci->proc->target_class;
    890 
    891   if (!c) c = mrb->c->ci->target_class;
     759  struct RClass *c;
     760  struct RProc *p = mrb->c->ci->proc;
     761
     762  for (;;) {
     763    c = MRB_PROC_TARGET_CLASS(p);
     764    if (c->tt != MRB_TT_SCLASS) break;
     765    p = p->upper;
     766  }
    892767  mrb_mod_cv_set(mrb, c, sym, v);
    893768}
     
    912787  struct RClass *c = base;
    913788  mrb_value v;
    914   iv_tbl *t;
    915789  mrb_bool retry = FALSE;
    916790  mrb_value name;
     
    919793  while (c) {
    920794    if (c->iv) {
    921       t = c->iv;
    922       if (iv_get(mrb, t, sym, &v))
     795      if (iv_get(mrb, c->iv, sym, &v))
    923796        return v;
    924797    }
    925798    c = c->super;
    926799  }
    927   if (!retry && base && base->tt == MRB_TT_MODULE) {
     800  if (!retry && base->tt == MRB_TT_MODULE) {
    928801    c = mrb->object_class;
    929802    retry = TRUE;
     
    944817mrb_vm_const_get(mrb_state *mrb, mrb_sym sym)
    945818{
    946   struct RClass *c = mrb->c->ci->proc->target_class;
    947 
    948   if (!c) c = mrb->c->ci->target_class;
    949   if (c) {
    950     struct RClass *c2;
    951     mrb_value v;
    952 
    953     if (c->iv && iv_get(mrb, c->iv, sym, &v)) {
     819  struct RClass *c;
     820  struct RClass *c2;
     821  mrb_value v;
     822  struct RProc *proc;
     823
     824  c = MRB_PROC_TARGET_CLASS(mrb->c->ci->proc);
     825  if (iv_get(mrb, c->iv, sym, &v)) {
     826    return v;
     827  }
     828  c2 = c;
     829  while (c2 && c2->tt == MRB_TT_SCLASS) {
     830    mrb_value klass;
     831
     832    if (!iv_get(mrb, c2->iv, mrb_intern_lit(mrb, "__attached__"), &klass)) {
     833      c2 = NULL;
     834      break;
     835    }
     836    c2 = mrb_class_ptr(klass);
     837  }
     838  if (c2 && (c2->tt == MRB_TT_CLASS || c2->tt == MRB_TT_MODULE)) c = c2;
     839  mrb_assert(!MRB_PROC_CFUNC_P(mrb->c->ci->proc));
     840  proc = mrb->c->ci->proc;
     841  while (proc) {
     842    c2 = MRB_PROC_TARGET_CLASS(proc);
     843    if (c2 && iv_get(mrb, c2->iv, sym, &v)) {
    954844      return v;
    955845    }
    956     c2 = c;
    957     while (c2 && c2->tt == MRB_TT_SCLASS) {
    958       mrb_value klass;
    959       klass = mrb_obj_iv_get(mrb, (struct RObject *)c2,
    960                              mrb_intern_lit(mrb, "__attached__"));
    961       c2 = mrb_class_ptr(klass);
    962     }
    963     if (c2->tt == MRB_TT_CLASS || c2->tt == MRB_TT_MODULE) c = c2;
    964     c2 = c;
    965     for (;;) {
    966       c2 = mrb_class_outer_module(mrb, c2);
    967       if (!c2) break;
    968       if (c2->iv && iv_get(mrb, c2->iv, sym, &v)) {
    969         return v;
    970       }
    971     }
     846    proc = proc->upper;
    972847  }
    973848  return const_get(mrb, c, sym);
     
    978853{
    979854  mod_const_check(mrb, mod);
     855  if (mrb_type(v) == MRB_TT_CLASS || mrb_type(v) == MRB_TT_MODULE) {
     856    mrb_class_name_class(mrb, mrb_class_ptr(mod), mrb_class_ptr(v), sym);
     857  }
    980858  mrb_iv_set(mrb, mod, sym, v);
    981859}
     
    984862mrb_vm_const_set(mrb_state *mrb, mrb_sym sym, mrb_value v)
    985863{
    986   struct RClass *c = mrb->c->ci->proc->target_class;
    987 
    988   if (!c) c = mrb->c->ci->target_class;
     864  struct RClass *c;
     865
     866  c = MRB_PROC_TARGET_CLASS(mrb->c->ci->proc);
    989867  mrb_obj_iv_set(mrb, (struct RObject*)c, sym, v);
    990868}
     
    1017895
    1018896  ary = *(mrb_value*)p;
    1019   s = mrb_sym2name_len(mrb, sym, &len);
     897  s = mrb_sym_name_len(mrb, sym, &len);
    1020898  if (len >= 1 && ISUPPER(s[0])) {
    1021     mrb_ary_push(mrb, ary, mrb_symbol_value(sym));
     899    mrb_int i, alen = RARRAY_LEN(ary);
     900
     901    for (i=0; i<alen; i++) {
     902      if (mrb_symbol(RARRAY_PTR(ary)[i]) == sym)
     903        break;
     904    }
     905    if (i==alen) {
     906      mrb_ary_push(mrb, ary, mrb_symbol_value(sym));
     907    }
    1022908  }
    1023909  return 0;
     
    1041927  ary = mrb_ary_new(mrb);
    1042928  while (c) {
    1043     if (c->iv) {
    1044       iv_foreach(mrb, c->iv, const_i, &ary);
    1045     }
     929    iv_foreach(mrb, c->iv, const_i, &ary);
    1046930    if (!inherit) break;
    1047931    c = c->super;
     
    1056940  mrb_value v;
    1057941
    1058   if (!mrb->globals) {
    1059     return mrb_nil_value();
    1060   }
    1061942  if (iv_get(mrb, mrb->globals, sym, &v))
    1062943    return v;
     
    1070951
    1071952  if (!mrb->globals) {
    1072     t = mrb->globals = iv_new(mrb);
    1073   }
    1074   else {
    1075     t = mrb->globals;
    1076   }
     953    mrb->globals = iv_new(mrb);
     954  }
     955  t = mrb->globals;
    1077956  iv_put(mrb, t, sym, v);
    1078957}
     
    1081960mrb_gv_remove(mrb_state *mrb, mrb_sym sym)
    1082961{
    1083   if (!mrb->globals) {
    1084     return;
    1085   }
    1086962  iv_del(mrb, mrb->globals, sym, NULL);
    1087963}
     
    1112988  iv_tbl *t = mrb->globals;
    1113989  mrb_value ary = mrb_ary_new(mrb);
    1114   size_t i;
    1115   char buf[3];
    1116 
    1117   if (t) {
    1118     iv_foreach(mrb, t, gv_i, &ary);
    1119   }
    1120   buf[0] = '$';
    1121   buf[2] = 0;
    1122   for (i = 1; i <= 9; ++i) {
    1123     buf[1] = (char)(i + '0');
    1124     mrb_ary_push(mrb, ary, mrb_symbol_value(mrb_intern(mrb, buf, 2)));
    1125   }
     990
     991  iv_foreach(mrb, t, gv_i, &ary);
    1126992  return ary;
    1127993}
     
    1132998  struct RClass *klass = mrb_class_ptr(mod);
    1133999  struct RClass *tmp;
    1134   mrb_bool mod_retry = 0;
     1000  mrb_bool mod_retry = FALSE;
    11351001
    11361002  tmp = klass;
    11371003retry:
    11381004  while (tmp) {
    1139     if (tmp->iv && iv_get(mrb, tmp->iv, id, NULL)) {
     1005    if (iv_get(mrb, tmp->iv, id, NULL)) {
    11401006      return TRUE;
    11411007    }
     
    11441010  }
    11451011  if (!exclude && !mod_retry && (klass->tt == MRB_TT_MODULE)) {
    1146     mod_retry = 1;
     1012    mod_retry = TRUE;
    11471013    tmp = mrb->object_class;
    11481014    goto retry;
     
    11871053}
    11881054
    1189 mrb_sym
    1190 mrb_class_sym(mrb_state *mrb, struct RClass *c, struct RClass *outer)
    1191 {
    1192   mrb_value name;
    1193 
    1194   name = mrb_obj_iv_get(mrb, (struct RObject*)c, mrb_intern_lit(mrb, "__classid__"));
    1195   if (mrb_nil_p(name)) {
    1196 
    1197     if (!outer) return 0;
    1198     else {
    1199       struct csym_arg arg;
    1200 
    1201       arg.c = c;
    1202       arg.sym = 0;
    1203       iv_foreach(mrb, outer->iv, csym_i, &arg);
    1204       return arg.sym;
    1205     }
    1206   }
    1207   return mrb_symbol(name);
    1208 }
     1055static mrb_sym
     1056find_class_sym(mrb_state *mrb, struct RClass *outer, struct RClass *c)
     1057{
     1058  struct csym_arg arg;
     1059
     1060  if (!outer) return 0;
     1061  if (outer == c) return 0;
     1062  arg.c = c;
     1063  arg.sym = 0;
     1064  iv_foreach(mrb, outer->iv, csym_i, &arg);
     1065  return arg.sym;
     1066}
     1067
     1068static struct RClass*
     1069outer_class(mrb_state *mrb, struct RClass *c)
     1070{
     1071  mrb_value ov;
     1072
     1073  ov = mrb_obj_iv_get(mrb, (struct RObject*)c, mrb_intern_lit(mrb, "__outer__"));
     1074  if (mrb_nil_p(ov)) return NULL;
     1075  switch (mrb_type(ov)) {
     1076  case MRB_TT_CLASS:
     1077  case MRB_TT_MODULE:
     1078    return mrb_class_ptr(ov);
     1079  default:
     1080    break;
     1081  }
     1082  return NULL;
     1083}
     1084
     1085static mrb_bool
     1086detect_outer_loop(mrb_state *mrb, struct RClass *c)
     1087{
     1088  struct RClass *t = c;         /* tortoise */
     1089  struct RClass *h = c;         /* hare */
     1090
     1091  for (;;) {
     1092    if (h == NULL) return FALSE;
     1093    h = outer_class(mrb, h);
     1094    if (h == NULL) return FALSE;
     1095    h = outer_class(mrb, h);
     1096    t = outer_class(mrb, t);
     1097    if (t == h) return TRUE;
     1098  }
     1099}
     1100
     1101mrb_value
     1102mrb_class_find_path(mrb_state *mrb, struct RClass *c)
     1103{
     1104  struct RClass *outer;
     1105  mrb_value path;
     1106  mrb_sym name;
     1107  const char *str;
     1108  mrb_int len;
     1109
     1110  if (detect_outer_loop(mrb, c)) return mrb_nil_value();
     1111  outer = outer_class(mrb, c);
     1112  if (outer == NULL) return mrb_nil_value();
     1113  name = find_class_sym(mrb, outer, c);
     1114  if (name == 0) return mrb_nil_value();
     1115  str = mrb_class_name(mrb, outer);
     1116  path = mrb_str_new_capa(mrb, 40);
     1117  mrb_str_cat_cstr(mrb, path, str);
     1118  mrb_str_cat_cstr(mrb, path, "::");
     1119
     1120  str = mrb_sym_name_len(mrb, name, &len);
     1121  mrb_str_cat(mrb, path, str, len);
     1122  if (RSTRING_PTR(path)[0] != '#') {
     1123    iv_del(mrb, c->iv, mrb_intern_lit(mrb, "__outer__"), NULL);
     1124    iv_put(mrb, c->iv, mrb_intern_lit(mrb, "__classname__"), path);
     1125    mrb_field_write_barrier_value(mrb, (struct RBasic*)c, path);
     1126    path = mrb_str_dup(mrb, path);
     1127  }
     1128  return path;
     1129}
     1130
     1131#define identchar(c) (ISALNUM(c) || (c) == '_' || !ISASCII(c))
     1132
     1133mrb_bool
     1134mrb_ident_p(const char *s, mrb_int len)
     1135{
     1136  mrb_int i;
     1137
     1138  for (i = 0; i < len; i++) {
     1139    if (!identchar(s[i])) return FALSE;
     1140  }
     1141  return TRUE;
     1142}
Note: See TracChangeset for help on using the changeset viewer.