- Timestamp:
- Jan 21, 2018, 12:10:09 AM (6 years ago)
- Location:
- EcnlProtoTool/trunk/mruby-1.3.0
- Files:
-
- 1 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-struct/src/struct.c
r321 r331 6 6 7 7 #include <string.h> 8 #include "mruby.h"9 #include "mruby/array.h"10 #include "mruby/string.h"11 #include "mruby/class.h"12 #include "mruby/variable.h"13 #include "mruby/hash.h"14 #include "mruby/range.h"8 #include <mruby.h> 9 #include <mruby/array.h> 10 #include <mruby/string.h> 11 #include <mruby/class.h> 12 #include <mruby/variable.h> 13 #include <mruby/hash.h> 14 #include <mruby/range.h> 15 15 16 16 #define RSTRUCT_LEN(st) mrb_ary_ptr(st)->len … … 62 62 } 63 63 if (RSTRUCT_LEN(s) != RARRAY_LEN(members)) { 64 mrb_raisef(mrb, E_TYPE_ERROR, 65 "struct size differs (%S required %S given)", 66 mrb_fixnum_value(RARRAY_LEN(members)), mrb_fixnum_value(RSTRUCT_LEN(s))); 64 if (RSTRUCT_LEN(s) == 0) { /* probably uninitialized */ 65 mrb_ary_resize(mrb, s, RARRAY_LEN(members)); 66 } 67 else { 68 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))); 71 } 67 72 } 68 73 return members; … … 80 85 } 81 86 87 static void 88 mrb_struct_modify(mrb_state *mrb, mrb_value strct) 89 { 90 if (MRB_FROZEN_P(mrb_basic_ptr(strct))) { 91 mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen struct"); 92 } 93 94 mrb_write_barrier(mrb, mrb_basic_ptr(strct)); 95 } 96 82 97 /* 15.2.18.4.6 */ 83 98 /* … … 99 114 } 100 115 101 static mrb_value 102 mrb_struct_getmember(mrb_state *mrb, mrb_value obj, mrb_sym id) 103 { 104 mrb_value members, slot, *ptr; 105 const mrb_value *ptr_members; 106 mrb_int i, len; 107 108 ptr = RSTRUCT_PTR(obj); 109 members = struct_members(mrb, obj); 110 ptr_members = RARRAY_PTR(members); 111 slot = mrb_symbol_value(id); 112 len = RARRAY_LEN(members); 113 for (i=0; i<len; i++) { 114 if (mrb_obj_equal(mrb, ptr_members[i], slot)) { 115 return ptr[i]; 116 } 117 } 118 mrb_raisef(mrb, E_INDEX_ERROR, "'%S' is not a struct member", mrb_sym2str(mrb, id)); 119 return mrb_nil_value(); /* not reached */ 120 } 116 static mrb_value struct_aref_sym(mrb_state *mrb, mrb_value obj, mrb_sym id); 121 117 122 118 static mrb_value 123 119 mrb_struct_ref(mrb_state *mrb, mrb_value obj) 124 120 { 125 return mrb_struct_getmember(mrb, obj, mrb->c->ci->mid); 126 } 127 128 static mrb_value mrb_struct_ref0(mrb_state* mrb, mrb_value obj) {return RSTRUCT_PTR(obj)[0];} 129 static mrb_value mrb_struct_ref1(mrb_state* mrb, mrb_value obj) {return RSTRUCT_PTR(obj)[1];} 130 static mrb_value mrb_struct_ref2(mrb_state* mrb, mrb_value obj) {return RSTRUCT_PTR(obj)[2];} 131 static mrb_value mrb_struct_ref3(mrb_state* mrb, mrb_value obj) {return RSTRUCT_PTR(obj)[3];} 132 static mrb_value mrb_struct_ref4(mrb_state* mrb, mrb_value obj) {return RSTRUCT_PTR(obj)[4];} 133 static mrb_value mrb_struct_ref5(mrb_state* mrb, mrb_value obj) {return RSTRUCT_PTR(obj)[5];} 134 static mrb_value mrb_struct_ref6(mrb_state* mrb, mrb_value obj) {return RSTRUCT_PTR(obj)[6];} 135 static mrb_value mrb_struct_ref7(mrb_state* mrb, mrb_value obj) {return RSTRUCT_PTR(obj)[7];} 136 static mrb_value mrb_struct_ref8(mrb_state* mrb, mrb_value obj) {return RSTRUCT_PTR(obj)[8];} 137 static mrb_value mrb_struct_ref9(mrb_state* mrb, mrb_value obj) {return RSTRUCT_PTR(obj)[9];} 138 139 #define numberof(array) (int)(sizeof(array) / sizeof((array)[0])) 140 #define N_REF_FUNC numberof(ref_func) 141 142 static const mrb_func_t ref_func[] = { 143 mrb_struct_ref0, 144 mrb_struct_ref1, 145 mrb_struct_ref2, 146 mrb_struct_ref3, 147 mrb_struct_ref4, 148 mrb_struct_ref5, 149 mrb_struct_ref6, 150 mrb_struct_ref7, 151 mrb_struct_ref8, 152 mrb_struct_ref9, 153 }; 121 return struct_aref_sym(mrb, obj, mrb->c->ci->mid); 122 } 154 123 155 124 static mrb_sym … … 172 141 } 173 142 174 static mrb_value 175 mrb_struct_set(mrb_state *mrb, mrb_value obj, mrb_value val) 176 { 143 static mrb_value mrb_struct_aset_sym(mrb_state *mrb, mrb_value s, mrb_sym id, mrb_value val); 144 145 static mrb_value 146 mrb_struct_set_m(mrb_state *mrb, mrb_value obj) 147 { 148 mrb_value val; 149 177 150 const char *name; 178 mrb_int i, len,slen;151 mrb_int slen; 179 152 mrb_sym mid; 180 mrb_value members, slot, *ptr; 181 const mrb_value *ptr_members;153 154 mrb_get_args(mrb, "o", &val); 182 155 183 156 /* get base id */ … … 185 158 mid = mrb_intern(mrb, name, slen-1); /* omit last "=" */ 186 159 187 members = struct_members(mrb, obj); 188 ptr_members = RARRAY_PTR(members); 189 len = RARRAY_LEN(members); 190 ptr = RSTRUCT_PTR(obj); 191 for (i=0; i<len; i++) { 192 slot = ptr_members[i]; 193 if (mrb_symbol(slot) == mid) { 194 return ptr[i] = val; 195 } 196 } 197 mrb_raisef(mrb, E_INDEX_ERROR, "'%S' is not a struct member", mrb_sym2str(mrb, mid)); 198 return mrb_nil_value(); /* not reached */ 199 } 200 201 static mrb_value 202 mrb_struct_set_m(mrb_state *mrb, mrb_value obj) 203 { 204 mrb_value val; 205 206 mrb_get_args(mrb, "o", &val); 207 return mrb_struct_set(mrb, obj, val); 160 return mrb_struct_aset_sym(mrb, obj, mid, val); 208 161 } 209 162 … … 235 188 236 189 if (is_local_id(mrb, name) || is_const_id(mrb, name)) { 237 if (i < N_REF_FUNC) { 238 mrb_define_method_id(mrb, c, id, ref_func[i], MRB_ARGS_NONE()); 239 } 240 else { 241 mrb_define_method_id(mrb, c, id, mrb_struct_ref, MRB_ARGS_NONE()); 242 } 190 mrb_define_method_id(mrb, c, id, mrb_struct_ref, MRB_ARGS_NONE()); 243 191 mrb_define_method_id(mrb, c, mrb_id_attrset(mrb, id), mrb_struct_set_m, MRB_ARGS_REQ(1)); 244 192 mrb_gc_arena_restore(mrb, ai); … … 266 214 if (mrb_const_defined_at(mrb, mrb_obj_value(klass), id)) { 267 215 mrb_warn(mrb, "redefining constant Struct::%S", name); 268 /* ?rb_mod_remove_const(klass, mrb_sym2name(mrb, id)); */216 mrb_const_remove(mrb, mrb_obj_value(klass), id); 269 217 } 270 218 c = mrb_define_class_under(mrb, klass, RSTRING_PTR(name), klass); … … 336 284 else { 337 285 if (argc > 0) name = argv[0]; 338 if (argc > 1) rest = argv[1]; 339 if (mrb_array_p(rest)) { 340 if (!mrb_nil_p(name) && mrb_symbol_p(name)) { 341 /* 1stArgument:symbol -> name=nil rest=argv[0]-[n] */ 342 mrb_ary_unshift(mrb, rest, name); 343 name = mrb_nil_value(); 344 } 345 } 346 else { 347 pargv = &argv[1]; 348 argcnt = argc-1; 349 if (!mrb_nil_p(name) && mrb_symbol_p(name)) { 350 /* 1stArgument:symbol -> name=nil rest=argv[0]-[n] */ 351 name = mrb_nil_value(); 352 pargv = &argv[0]; 353 argcnt++; 354 } 355 rest = mrb_ary_new_from_values(mrb, argcnt, pargv); 356 } 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++; 293 } 294 rest = mrb_ary_new_from_values(mrb, argcnt, pargv); 357 295 for (i=0; i<RARRAY_LEN(rest); i++) { 358 296 id = mrb_obj_to_sym(mrb, RARRAY_PTR(rest)[i]); … … 360 298 } 361 299 } 362 st = make_struct(mrb, name, rest, struct_class(mrb));300 st = make_struct(mrb, name, rest, mrb_class_ptr(klass)); 363 301 if (!mrb_nil_p(b)) { 364 mrb_yield_with_class(mrb, b, 1, &st, st, mrb_class_ptr( klass));302 mrb_yield_with_class(mrb, b, 1, &st, st, mrb_class_ptr(st)); 365 303 } 366 304 … … 419 357 { 420 358 mrb_value s; 421 mrb_int i, len;422 359 423 360 mrb_get_args(mrb, "o", &s); … … 430 367 mrb_raise(mrb, E_TYPE_ERROR, "corrupted struct"); 431 368 } 432 if (RSTRUCT_LEN(copy) != RSTRUCT_LEN(s)) { 433 mrb_raise(mrb, E_TYPE_ERROR, "struct size mismatch"); 434 } 435 len = RSTRUCT_LEN(copy); 436 for (i = 0; i < len; i++) { 437 mrb_ary_set(mrb, copy, i, RSTRUCT_PTR(s)[i]); 438 } 369 mrb_ary_replace(mrb, copy, s); 439 370 return copy; 440 371 } 441 372 442 373 static mrb_value 443 struct_aref_sym(mrb_state *mrb, mrb_value s, mrb_sym id)444 { 445 mrb_value *ptr, members;374 struct_aref_sym(mrb_state *mrb, mrb_value obj, mrb_sym id) 375 { 376 mrb_value members, *ptr; 446 377 const mrb_value *ptr_members; 447 378 mrb_int i, len; 448 379 449 ptr = RSTRUCT_PTR(s); 450 members = struct_members(mrb, s); 380 members = struct_members(mrb, obj); 451 381 ptr_members = RARRAY_PTR(members); 452 382 len = RARRAY_LEN(members); 383 ptr = RSTRUCT_PTR(obj); 453 384 for (i=0; i<len; i++) { 454 if (mrb_symbol(ptr_members[i]) == id) { 385 mrb_value slot = ptr_members[i]; 386 if (mrb_symbol_p(slot) && mrb_symbol(slot) == id) { 455 387 return ptr[i]; 456 388 } 457 389 } 458 mrb_raisef(mrb, E_INDEX_ERROR, " no member '%S' in struct", mrb_sym2str(mrb, id));390 mrb_raisef(mrb, E_INDEX_ERROR, "'%S' is not a struct member", mrb_sym2str(mrb, id)); 459 391 return mrb_nil_value(); /* not reached */ 460 392 } … … 504 436 505 437 if (mrb_nil_p(sym)) { 506 mrb_ raisef(mrb, E_INDEX_ERROR, "no member '%S' in struct", idx);438 mrb_name_error(mrb, mrb_intern_str(mrb, idx), "no member '%S' in struct", idx); 507 439 } 508 440 idx = sym; … … 523 455 members = struct_members(mrb, s); 524 456 len = RARRAY_LEN(members); 525 if (RSTRUCT_LEN(s) != len) {526 mrb_raisef(mrb, E_TYPE_ERROR,527 "struct size differs (%S required %S given)",528 mrb_fixnum_value(len), mrb_fixnum_value(RSTRUCT_LEN(s)));529 }530 457 ptr = RSTRUCT_PTR(s); 531 458 ptr_members = RARRAY_PTR(members); 532 459 for (i=0; i<len; i++) { 533 460 if (mrb_symbol(ptr_members[i]) == id) { 461 mrb_struct_modify(mrb, s); 534 462 ptr[i] = val; 535 463 return val; 536 464 } 537 465 } 538 mrb_ raisef(mrb, E_INDEX_ERROR, "no member '%S' in struct", mrb_sym2str(mrb, id));466 mrb_name_error(mrb, id, "no member '%S' in struct", mrb_sym2str(mrb, id)); 539 467 return val; /* not reach */ 540 468 } … … 575 503 576 504 if (mrb_nil_p(sym)) { 577 mrb_ raisef(mrb, E_INDEX_ERROR, "no member '%S' in struct", idx);505 mrb_name_error(mrb, mrb_intern_str(mrb, idx), "no member '%S' in struct", idx); 578 506 } 579 507 idx = sym; … … 595 523 mrb_fixnum_value(i), mrb_fixnum_value(RSTRUCT_LEN(s))); 596 524 } 525 mrb_struct_modify(mrb, s); 597 526 return RSTRUCT_PTR(s)[i] = val; 598 527 } … … 720 649 mrb_int i; 721 650 722 members = struct_ s_members(mrb, mrb_class(mrb, self));651 members = struct_members(mrb, self); 723 652 ret = mrb_hash_new_capa(mrb, RARRAY_LEN(members)); 724 653 … … 761 690 struct RClass *st; 762 691 st = mrb_define_class(mrb, "Struct", mrb->object_class); 692 MRB_SET_INSTANCE_TT(st, MRB_TT_ARRAY); 763 693 764 694 mrb_define_class_method(mrb, st, "new", mrb_struct_s_def, MRB_ARGS_ANY()); /* 15.2.18.3.1 */ … … 777 707 mrb_define_method(mrb, st, "values", mrb_struct_to_a, MRB_ARGS_NONE()); 778 708 mrb_define_method(mrb, st, "to_h", mrb_struct_to_h, MRB_ARGS_NONE()); 779 mrb_define_method(mrb, st, "values_at", mrb_struct_values_at, MRB_ARGS_ NONE());709 mrb_define_method(mrb, st, "values_at", mrb_struct_values_at, MRB_ARGS_ANY()); 780 710 } 781 711
Note:
See TracChangeset
for help on using the changeset viewer.