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/mrbgems/mruby-struct/src/struct.c

    r331 r439  
    1313#include <mruby/hash.h>
    1414#include <mruby/range.h>
    15 
    16 #define RSTRUCT_LEN(st) mrb_ary_ptr(st)->len
    17 #define RSTRUCT_PTR(st) mrb_ary_ptr(st)->ptr
     15#include <mruby/proc.h>
     16
     17#define RSTRUCT_LEN(st) RARRAY_LEN(st)
     18#define RSTRUCT_PTR(st) RARRAY_PTR(st)
    1819
    1920static struct RClass *
     
    2425
    2526static inline mrb_value
    26 struct_ivar_get(mrb_state *mrb, mrb_value c, mrb_sym id)
    27 {
    28   struct RClass* kclass;
     27struct_ivar_get(mrb_state *mrb, mrb_value cls, mrb_sym id)
     28{
     29  struct RClass* c = mrb_class_ptr(cls);
    2930  struct RClass* sclass = struct_class(mrb);
    3031  mrb_value ans;
    3132
    3233  for (;;) {
    33     ans = mrb_iv_get(mrb, c, id);
     34    ans = mrb_iv_get(mrb, mrb_obj_value(c), id);
    3435    if (!mrb_nil_p(ans)) return ans;
    35     kclass = RCLASS_SUPER(c);
    36     if (kclass == 0 || kclass == sclass)
     36    c = c->super;
     37    if (c == sclass || c == 0)
    3738      return mrb_nil_value();
    38     c = mrb_obj_value(kclass);
    3939  }
    4040}
     
    6767    else {
    6868      mrb_raisef(mrb, E_TYPE_ERROR,
    69                  "struct size differs (%S required %S given)",
    70                  mrb_fixnum_value(RARRAY_LEN(members)), mrb_fixnum_value(RSTRUCT_LEN(s)));
     69                 "struct size differs (%i required %i given)",
     70                 RARRAY_LEN(members), RSTRUCT_LEN(s));
    7171    }
    7272  }
     
    8888mrb_struct_modify(mrb_state *mrb, mrb_value strct)
    8989{
    90   if (MRB_FROZEN_P(mrb_basic_ptr(strct))) {
    91     mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen struct");
    92   }
    93 
     90  mrb_check_frozen(mrb, mrb_basic_ptr(strct));
    9491  mrb_write_barrier(mrb, mrb_basic_ptr(strct));
    9592}
     
    114111}
    115112
    116 static mrb_value struct_aref_sym(mrb_state *mrb, mrb_value obj, mrb_sym id);
    117 
    118113static mrb_value
    119114mrb_struct_ref(mrb_state *mrb, mrb_value obj)
    120115{
    121   return struct_aref_sym(mrb, obj, mrb->c->ci->mid);
     116  mrb_int i = mrb_fixnum(mrb_proc_cfunc_env_get(mrb, 0));
     117  mrb_value *ptr = RSTRUCT_PTR(obj);
     118
     119  if (!ptr) return mrb_nil_value();
     120  return ptr[i];
    122121}
    123122
     
    125124mrb_id_attrset(mrb_state *mrb, mrb_sym id)
    126125{
     126#define ONSTACK_ALLOC_MAX 32
     127#define ONSTACK_STRLEN_MAX (ONSTACK_ALLOC_MAX - 1) /* '=' character */
     128
    127129  const char *name;
    128130  char *buf;
    129131  mrb_int len;
    130132  mrb_sym mid;
    131 
    132   name = mrb_sym2name_len(mrb, id, &len);
    133   buf = (char *)mrb_malloc(mrb, (size_t)len+2);
     133  char onstack[ONSTACK_ALLOC_MAX];
     134
     135  name = mrb_sym_name_len(mrb, id, &len);
     136  if (len > ONSTACK_STRLEN_MAX) {
     137    buf = (char *)mrb_malloc(mrb, (size_t)len+1);
     138  }
     139  else {
     140    buf = onstack;
     141  }
    134142  memcpy(buf, name, (size_t)len);
    135143  buf[len] = '=';
    136   buf[len+1] = '\0';
    137144
    138145  mid = mrb_intern(mrb, buf, len+1);
    139   mrb_free(mrb, buf);
     146  if (buf != onstack) {
     147    mrb_free(mrb, buf);
     148  }
    140149  return mid;
    141150}
    142151
    143 static mrb_value mrb_struct_aset_sym(mrb_state *mrb, mrb_value s, mrb_sym id, mrb_value val);
    144 
    145152static mrb_value
    146153mrb_struct_set_m(mrb_state *mrb, mrb_value obj)
    147154{
     155  mrb_int i = mrb_fixnum(mrb_proc_cfunc_env_get(mrb, 0));
     156  mrb_value *ptr;
    148157  mrb_value val;
    149158
    150   const char *name;
    151   mrb_int slen;
    152   mrb_sym mid;
    153 
    154159  mrb_get_args(mrb, "o", &val);
    155 
    156   /* get base id */
    157   name = mrb_sym2name_len(mrb, mrb->c->ci->mid, &slen);
    158   mid = mrb_intern(mrb, name, slen-1); /* omit last "=" */
    159 
    160   return mrb_struct_aset_sym(mrb, obj, mid, val);
    161 }
    162 
    163 static mrb_bool
    164 is_local_id(mrb_state *mrb, const char *name)
    165 {
    166   if (!name) return FALSE;
    167   return !ISUPPER(name[0]);
    168 }
    169 
    170 static mrb_bool
    171 is_const_id(mrb_state *mrb, const char *name)
    172 {
    173   if (!name) return FALSE;
    174   return ISUPPER(name[0]);
     160  mrb_struct_modify(mrb, obj);
     161  ptr = RSTRUCT_PTR(obj);
     162  if (ptr == NULL || i >= RSTRUCT_LEN(obj)) {
     163    mrb_ary_set(mrb, obj, i, val);
     164  }
     165  else {
     166    ptr[i] = val;
     167  }
     168  return val;
    175169}
    176170
     
    185179  for (i=0; i<len; i++) {
    186180    mrb_sym id = mrb_symbol(ptr_members[i]);
    187     const char *name = mrb_sym2name_len(mrb, id, NULL);
    188 
    189     if (is_local_id(mrb, name) || is_const_id(mrb, name)) {
    190       mrb_define_method_id(mrb, c, id, mrb_struct_ref, MRB_ARGS_NONE());
    191       mrb_define_method_id(mrb, c, mrb_id_attrset(mrb, id), mrb_struct_set_m, MRB_ARGS_REQ(1));
    192       mrb_gc_arena_restore(mrb, ai);
    193     }
    194   }
    195 }
    196 
    197 static mrb_value
    198 make_struct(mrb_state *mrb, mrb_value name, mrb_value members, struct RClass * klass)
     181    mrb_method_t m;
     182    mrb_value at = mrb_fixnum_value(i);
     183    struct RProc *aref = mrb_proc_new_cfunc_with_env(mrb, mrb_struct_ref, 1, &at);
     184    struct RProc *aset = mrb_proc_new_cfunc_with_env(mrb, mrb_struct_set_m, 1, &at);
     185    MRB_METHOD_FROM_PROC(m, aref);
     186    mrb_define_method_raw(mrb, c, id, m);
     187    MRB_METHOD_FROM_PROC(m, aset);
     188    mrb_define_method_raw(mrb, c, mrb_id_attrset(mrb, id), m);
     189    mrb_gc_arena_restore(mrb, ai);
     190  }
     191}
     192
     193static mrb_value
     194make_struct(mrb_state *mrb, mrb_value name, mrb_value members, struct RClass *klass)
    199195{
    200196  mrb_value nstr;
     
    207203  else {
    208204    /* old style: should we warn? */
    209     name = mrb_str_to_str(mrb, name);
     205    mrb_to_str(mrb, name);
    210206    id = mrb_obj_to_sym(mrb, name);
    211     if (!is_const_id(mrb, mrb_sym2name_len(mrb, id, NULL))) {
    212       mrb_name_error(mrb, id, "identifier %S needs to be constant", name);
     207    if (!mrb_const_name_p(mrb, RSTRING_PTR(name), RSTRING_LEN(name))) {
     208      mrb_name_error(mrb, id, "identifier %v needs to be constant", name);
    213209    }
    214210    if (mrb_const_defined_at(mrb, mrb_obj_value(klass), id)) {
    215       mrb_warn(mrb, "redefining constant Struct::%S", name);
     211      mrb_warn(mrb, "redefining constant Struct::%v", name);
    216212      mrb_const_remove(mrb, mrb_obj_value(klass), id);
    217213    }
     
    277273
    278274  name = mrb_nil_value();
    279   rest = mrb_nil_value();
    280275  mrb_get_args(mrb, "*&", &argv, &argc, &b);
    281276  if (argc == 0) { /* special case to avoid crash */
    282     rest = mrb_ary_new(mrb);
     277    mrb_argnum_error(mrb, argc, 1, -1);
    283278  }
    284279  else {
    285     if (argc > 0) name = argv[0];
    286     pargv = &argv[1];
    287     argcnt = argc-1;
    288     if (!mrb_nil_p(name) && mrb_symbol_p(name)) {
    289       /* 1stArgument:symbol -> name=nil rest=argv[0]-[n] */
    290       name = mrb_nil_value();
    291       pargv = &argv[0];
    292       argcnt++;
     280    pargv = argv;
     281    argcnt = argc;
     282    if (argc > 0) {
     283      name = argv[0];
     284      if (mrb_symbol_p(name)) {
     285        /* 1stArgument:symbol -> name=nil rest=argv[0..n] */
     286        name = mrb_nil_value();
     287      }
     288      else {
     289        pargv++;
     290        argcnt--;
     291      }
    293292    }
    294293    rest = mrb_ary_new_from_values(mrb, argcnt, pargv);
    295     for (i=0; i<RARRAY_LEN(rest); i++) {
     294    for (i=0; i<argcnt; i++) {
    296295      id = mrb_obj_to_sym(mrb, RARRAY_PTR(rest)[i]);
    297296      mrb_ary_set(mrb, rest, i, mrb_symbol_value(id));
    298297    }
    299   }
    300   st = make_struct(mrb, name, rest, mrb_class_ptr(klass));
    301   if (!mrb_nil_p(b)) {
    302     mrb_yield_with_class(mrb, b, 1, &st, st, mrb_class_ptr(st));
    303   }
    304 
    305   return st;
     298    st = make_struct(mrb, name, rest, mrb_class_ptr(klass));
     299    if (!mrb_nil_p(b)) {
     300      mrb_yield_with_class(mrb, b, 1, &st, st, mrb_class_ptr(st));
     301    }
     302
     303    return st;
     304  }
     305  /* not reached */
     306  return mrb_nil_value();
    306307}
    307308
     
    347348  mrb_int argc;
    348349
    349   mrb_get_args(mrb, "*", &argv, &argc);
     350  mrb_get_args(mrb, "*!", &argv, &argc);
    350351  return mrb_struct_initialize_withArg(mrb, argc, argv, self);
    351352}
     
    388389    }
    389390  }
    390   mrb_raisef(mrb, E_INDEX_ERROR, "'%S' is not a struct member", mrb_sym2str(mrb, id));
     391  mrb_name_error(mrb, id, "no member '%n' in struct", id);
    391392  return mrb_nil_value();       /* not reached */
    392393}
     
    395396struct_aref_int(mrb_state *mrb, mrb_value s, mrb_int i)
    396397{
    397   if (i < 0) i = RSTRUCT_LEN(s) + i;
    398   if (i < 0)
    399       mrb_raisef(mrb, E_INDEX_ERROR,
    400                  "offset %S too small for struct(size:%S)",
    401                  mrb_fixnum_value(i), mrb_fixnum_value(RSTRUCT_LEN(s)));
    402   if (RSTRUCT_LEN(s) <= i)
     398  mrb_int idx = i < 0 ? RSTRUCT_LEN(s) + i : i;
     399
     400  if (idx < 0)
    403401    mrb_raisef(mrb, E_INDEX_ERROR,
    404                "offset %S too large for struct(size:%S)",
    405                mrb_fixnum_value(i), mrb_fixnum_value(RSTRUCT_LEN(s)));
    406   return RSTRUCT_PTR(s)[i];
     402               "offset %i too small for struct(size:%i)", i, RSTRUCT_LEN(s));
     403  if (RSTRUCT_LEN(s) <= idx)
     404    mrb_raisef(mrb, E_INDEX_ERROR,
     405               "offset %i too large for struct(size:%i)", i, RSTRUCT_LEN(s));
     406  return RSTRUCT_PTR(s)[idx];
    407407}
    408408
     
    436436
    437437    if (mrb_nil_p(sym)) {
    438       mrb_name_error(mrb, mrb_intern_str(mrb, idx), "no member '%S' in struct", idx);
     438      mrb_name_error(mrb, mrb_intern_str(mrb, idx), "no member '%v' in struct", idx);
    439439    }
    440440    idx = sym;
     
    464464    }
    465465  }
    466   mrb_name_error(mrb, id, "no member '%S' in struct", mrb_sym2str(mrb, id));
     466  mrb_name_error(mrb, id, "no member '%n' in struct", id);
    467467  return val;                   /* not reach */
    468468}
     
    503503
    504504    if (mrb_nil_p(sym)) {
    505       mrb_name_error(mrb, mrb_intern_str(mrb, idx), "no member '%S' in struct", idx);
     505      mrb_name_error(mrb, mrb_intern_str(mrb, idx), "no member '%v' in struct", idx);
    506506    }
    507507    idx = sym;
     
    515515  if (i < 0) {
    516516    mrb_raisef(mrb, E_INDEX_ERROR,
    517                "offset %S too small for struct(size:%S)",
    518                mrb_fixnum_value(i), mrb_fixnum_value(RSTRUCT_LEN(s)));
     517               "offset %i too small for struct(size:%i)", i, RSTRUCT_LEN(s));
    519518  }
    520519  if (RSTRUCT_LEN(s) <= i) {
    521520    mrb_raisef(mrb, E_INDEX_ERROR,
    522                "offset %S too large for struct(size:%S)",
    523                mrb_fixnum_value(i), mrb_fixnum_value(RSTRUCT_LEN(s)));
     521               "offset %i too large for struct(size:%i)", i, RSTRUCT_LEN(s));
    524522  }
    525523  mrb_struct_modify(mrb, s);
Note: See TracChangeset for help on using the changeset viewer.