- Timestamp:
- Jul 9, 2020, 8:51:43 AM (4 years ago)
- 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 13 13 #include <mruby/hash.h> 14 14 #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) 18 19 19 20 static struct RClass * … … 24 25 25 26 static inline mrb_value 26 struct_ivar_get(mrb_state *mrb, mrb_value c , mrb_sym id)27 { 28 struct RClass* kclass;27 struct_ivar_get(mrb_state *mrb, mrb_value cls, mrb_sym id) 28 { 29 struct RClass* c = mrb_class_ptr(cls); 29 30 struct RClass* sclass = struct_class(mrb); 30 31 mrb_value ans; 31 32 32 33 for (;;) { 33 ans = mrb_iv_get(mrb, c, id);34 ans = mrb_iv_get(mrb, mrb_obj_value(c), id); 34 35 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) 37 38 return mrb_nil_value(); 38 c = mrb_obj_value(kclass);39 39 } 40 40 } … … 67 67 else { 68 68 mrb_raisef(mrb, E_TYPE_ERROR, 69 "struct size differs (% S required %Sgiven)",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)); 71 71 } 72 72 } … … 88 88 mrb_struct_modify(mrb_state *mrb, mrb_value strct) 89 89 { 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)); 94 91 mrb_write_barrier(mrb, mrb_basic_ptr(strct)); 95 92 } … … 114 111 } 115 112 116 static mrb_value struct_aref_sym(mrb_state *mrb, mrb_value obj, mrb_sym id);117 118 113 static mrb_value 119 114 mrb_struct_ref(mrb_state *mrb, mrb_value obj) 120 115 { 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]; 122 121 } 123 122 … … 125 124 mrb_id_attrset(mrb_state *mrb, mrb_sym id) 126 125 { 126 #define ONSTACK_ALLOC_MAX 32 127 #define ONSTACK_STRLEN_MAX (ONSTACK_ALLOC_MAX - 1) /* '=' character */ 128 127 129 const char *name; 128 130 char *buf; 129 131 mrb_int len; 130 132 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 } 134 142 memcpy(buf, name, (size_t)len); 135 143 buf[len] = '='; 136 buf[len+1] = '\0';137 144 138 145 mid = mrb_intern(mrb, buf, len+1); 139 mrb_free(mrb, buf); 146 if (buf != onstack) { 147 mrb_free(mrb, buf); 148 } 140 149 return mid; 141 150 } 142 151 143 static mrb_value mrb_struct_aset_sym(mrb_state *mrb, mrb_value s, mrb_sym id, mrb_value val);144 145 152 static mrb_value 146 153 mrb_struct_set_m(mrb_state *mrb, mrb_value obj) 147 154 { 155 mrb_int i = mrb_fixnum(mrb_proc_cfunc_env_get(mrb, 0)); 156 mrb_value *ptr; 148 157 mrb_value val; 149 158 150 const char *name;151 mrb_int slen;152 mrb_sym mid;153 154 159 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; 175 169 } 176 170 … … 185 179 for (i=0; i<len; i++) { 186 180 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 193 static mrb_value 194 make_struct(mrb_state *mrb, mrb_value name, mrb_value members, struct RClass *klass) 199 195 { 200 196 mrb_value nstr; … … 207 203 else { 208 204 /* old style: should we warn? */ 209 name = mrb_str_to_str(mrb, name);205 mrb_to_str(mrb, name); 210 206 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 % Sneeds 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); 213 209 } 214 210 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); 216 212 mrb_const_remove(mrb, mrb_obj_value(klass), id); 217 213 } … … 277 273 278 274 name = mrb_nil_value(); 279 rest = mrb_nil_value();280 275 mrb_get_args(mrb, "*&", &argv, &argc, &b); 281 276 if (argc == 0) { /* special case to avoid crash */ 282 rest = mrb_ary_new(mrb);277 mrb_argnum_error(mrb, argc, 1, -1); 283 278 } 284 279 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 } 293 292 } 294 293 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++) { 296 295 id = mrb_obj_to_sym(mrb, RARRAY_PTR(rest)[i]); 297 296 mrb_ary_set(mrb, rest, i, mrb_symbol_value(id)); 298 297 } 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(); 306 307 } 307 308 … … 347 348 mrb_int argc; 348 349 349 mrb_get_args(mrb, "* ", &argv, &argc);350 mrb_get_args(mrb, "*!", &argv, &argc); 350 351 return mrb_struct_initialize_withArg(mrb, argc, argv, self); 351 352 } … … 388 389 } 389 390 } 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); 391 392 return mrb_nil_value(); /* not reached */ 392 393 } … … 395 396 struct_aref_int(mrb_state *mrb, mrb_value s, mrb_int i) 396 397 { 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) 403 401 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]; 407 407 } 408 408 … … 436 436 437 437 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); 439 439 } 440 440 idx = sym; … … 464 464 } 465 465 } 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); 467 467 return val; /* not reach */ 468 468 } … … 503 503 504 504 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); 506 506 } 507 507 idx = sym; … … 515 515 if (i < 0) { 516 516 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)); 519 518 } 520 519 if (RSTRUCT_LEN(s) <= i) { 521 520 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)); 524 522 } 525 523 mrb_struct_modify(mrb, s);
Note:
See TracChangeset
for help on using the changeset viewer.