Changeset 439 for EcnlProtoTool/trunk/mruby-2.1.1/src/variable.c
- 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/src/variable.c
r331 r439 10 10 #include <mruby/proc.h> 11 11 #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 19 16 #endif 20 17 21 18 typedef 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]; 24 21 struct segment *next; 25 22 } segment; … … 32 29 } iv_tbl; 33 30 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. */ 42 32 static iv_tbl* 43 33 iv_new(mrb_state *mrb) … … 53 43 } 54 44 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. */ 64 46 static void 65 47 iv_put(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value val) 66 48 { 67 segment *seg = t->rootseg;49 segment *seg; 68 50 segment *prev = NULL; 69 51 segment *matched_seg = NULL; … … 71 53 size_t i; 72 54 55 if (t == NULL) return; 56 seg = t->rootseg; 73 57 while (seg) { 74 for (i=0; i<MRB_ SEGMENT_SIZE; i++) {58 for (i=0; i<MRB_IV_SEGMENT_SIZE; i++) { 75 59 mrb_sym key = seg->key[i]; 76 60 /* Found room in last segment after last_len */ … … 96 80 97 81 /* Not found */ 98 t->size++;99 82 if (matched_seg) { 100 83 matched_seg->key[matched_idx] = sym; 101 84 matched_seg->val[matched_idx] = val; 85 t->size++; 102 86 return; 103 87 } 104 88 105 89 seg = (segment*)mrb_malloc(mrb, sizeof(segment)); 106 if (!seg) return;107 90 seg->next = NULL; 108 91 seg->key[0] = sym; 109 92 seg->val[0] = val; 110 93 t->last_len = 1; 94 t->size++; 111 95 if (prev) { 112 96 prev->next = seg; … … 117 101 } 118 102 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. */ 131 104 static mrb_bool 132 105 iv_get(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value *vp) … … 135 108 size_t i; 136 109 110 if (t == NULL) return FALSE; 137 111 seg = t->rootseg; 138 112 while (seg) { 139 for (i=0; i<MRB_ SEGMENT_SIZE; i++) {113 for (i=0; i<MRB_IV_SEGMENT_SIZE; i++) { 140 114 mrb_sym key = seg->key[i]; 141 115 … … 153 127 } 154 128 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. */ 166 130 static mrb_bool 167 131 iv_del(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value *vp) … … 170 134 size_t i; 171 135 136 if (t == NULL) return FALSE; 172 137 seg = t->rootseg; 173 138 while (seg) { 174 for (i=0; i<MRB_ SEGMENT_SIZE; i++) {139 for (i=0; i<MRB_IV_SEGMENT_SIZE; i++) { 175 140 mrb_sym key = seg->key[i]; 176 141 … … 190 155 } 191 156 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. */ 158 static void 159 iv_foreach(mrb_state *mrb, iv_tbl *t, mrb_iv_foreach_func *func, void *p) 194 160 { 195 161 segment *seg; 196 162 size_t i; 197 int n; 198 163 164 if (t == NULL) return; 199 165 seg = t->rootseg; 200 166 while (seg) { 201 for (i=0; i<MRB_ SEGMENT_SIZE; i++) {167 for (i=0; i<MRB_IV_SEGMENT_SIZE; i++) { 202 168 mrb_sym key = seg->key[i]; 203 169 204 170 /* no value in last segment after last_len */ 205 171 if (!seg->next && i >= t->last_len) { 206 return FALSE;172 return; 207 173 } 208 174 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; 214 177 } 215 178 } … … 217 180 seg = seg->next; 218 181 } 219 return TRUE; 220 } 221 182 return; 183 } 184 185 /* Get the size of the instance variable table. */ 222 186 static size_t 223 187 iv_size(mrb_state *mrb, iv_tbl *t) … … 226 190 size_t size = 0; 227 191 228 if ( !t) return 0;192 if (t == NULL) return 0; 229 193 if (t->size > 0) return t->size; 230 194 seg = t->rootseg; … … 235 199 } 236 200 seg = seg->next; 237 size += MRB_ SEGMENT_SIZE;201 size += MRB_IV_SEGMENT_SIZE; 238 202 } 239 203 /* empty iv_tbl */ … … 241 205 } 242 206 207 /* Copy the instance variable table. */ 243 208 static iv_tbl* 244 209 iv_copy(mrb_state *mrb, iv_tbl *t) … … 253 218 254 219 while (seg != NULL) { 255 for (i=0; i<MRB_ SEGMENT_SIZE; i++) {220 for (i=0; i<MRB_IV_SEGMENT_SIZE; i++) { 256 221 mrb_sym key = seg->key[i]; 257 222 mrb_value val = seg->val[i]; … … 267 232 } 268 233 234 /* Free memory of the instance variable table. */ 269 235 static void 270 236 iv_free(mrb_state *mrb, iv_tbl *t) … … 281 247 } 282 248 283 #else284 285 #include <mruby/khash.h>286 287 #ifndef MRB_IVHASH_INIT_SIZE288 #define MRB_IVHASH_INIT_SIZE 8289 #endif290 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 void305 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_bool315 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_bool329 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_bool347 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_t368 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 void385 iv_free(mrb_state *mrb, iv_tbl *t)386 {387 kh_destroy(iv, mrb, &t->h);388 }389 390 #endif391 392 249 static int 393 250 iv_mark_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p) … … 400 257 mark_tbl(mrb_state *mrb, iv_tbl *t) 401 258 { 402 if (t) { 403 iv_foreach(mrb, t, iv_mark_i, 0); 404 } 259 iv_foreach(mrb, t, iv_mark_i, 0); 405 260 } 406 261 … … 485 340 } 486 341 342 static inline void assign_class_name(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v); 343 344 void 345 mrb_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 487 355 MRB_API void 488 356 mrb_obj_iv_set(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v) 489 357 { 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. */ 363 MRB_API void 364 mrb_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 370 static inline mrb_bool 371 namespace_p(enum mrb_vtype tt) 372 { 373 return tt == MRB_TT_CLASS || tt == MRB_TT_MODULE ? TRUE : FALSE; 374 } 375 376 static inline void 377 assign_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 } 515 400 } 516 401 … … 545 430 } 546 431 547 #define identchar(c) (ISALNUM(c) || (c) == '_' || !ISASCII(c))548 549 432 MRB_API mrb_bool 550 mrb_iv_ p(mrb_state *mrb, mrb_sym iv_name)433 mrb_iv_name_sym_p(mrb_state *mrb, mrb_sym iv_name) 551 434 { 552 435 const char *s; 553 mrb_int i,len;554 555 s = mrb_sym 2name_len(mrb, iv_name, &len);436 mrb_int len; 437 438 s = mrb_sym_name_len(mrb, iv_name, &len); 556 439 if (len < 2) return FALSE; 557 440 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 445 MRB_API void 446 mrb_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); 570 450 } 571 451 } … … 604 484 mrb_str_cat_lit(mrb, str, ", "); 605 485 } 606 s = mrb_sym 2name_len(mrb, sym, &len);486 s = mrb_sym_name_len(mrb, sym, &len); 607 487 mrb_str_cat(mrb, str, s, len); 608 488 mrb_str_cat_lit(mrb, str, "="); 609 if (mrb_ type(v) == MRB_TT_OBJECT) {489 if (mrb_object_p(v)) { 610 490 ins = mrb_any_to_s(mrb, v); 611 491 } … … 625 505 if (len > 0) { 626 506 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); 628 508 629 509 mrb_str_cat_lit(mrb, str, "-<"); 630 510 mrb_str_cat_cstr(mrb, str, cn); 631 511 mrb_str_cat_lit(mrb, str, ":"); 632 mrb_str_c oncat(mrb, str, mrb_ptr_to_str(mrb, obj));512 mrb_str_cat_str(mrb, str, mrb_ptr_to_str(mrb, obj)); 633 513 634 514 iv_foreach(mrb, t, inspect_i, &str); … … 646 526 mrb_value val; 647 527 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)) { 649 530 return val; 650 531 } 651 532 } 652 533 return mrb_undef_value(); 653 }654 655 mrb_value656 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 void663 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);667 534 } 668 535 … … 675 542 676 543 ary = *(mrb_value*)p; 677 s = mrb_sym 2name_len(mrb, sym, &len);544 s = mrb_sym_name_len(mrb, sym, &len); 678 545 if (len > 1 && s[0] == '@' && s[1] != '@') { 679 546 mrb_ary_push(mrb, ary, mrb_symbol_value(sym)); … … 705 572 706 573 ary = mrb_ary_new(mrb); 707 if (obj_iv_p(self) && mrb_obj_ptr(self)->iv) {574 if (obj_iv_p(self)) { 708 575 iv_foreach(mrb, mrb_obj_ptr(self)->iv, iv_i, &ary); 709 576 } … … 719 586 720 587 ary = *(mrb_value*)p; 721 s = mrb_sym 2name_len(mrb, sym, &len);588 s = mrb_sym_name_len(mrb, sym, &len); 722 589 if (len > 2 && s[0] == '@' && s[1] == '@') { 723 590 mrb_ary_push(mrb, ary, mrb_symbol_value(sym)); … … 729 596 /* 730 597 * call-seq: 731 * mod.class_variables -> array598 * mod.class_variables(inherit=true) -> array 732 599 * 733 600 * Returns an array of the names of class variables in <i>mod</i>. … … 747 614 mrb_value ary; 748 615 struct RClass *c; 749 616 mrb_bool inherit = TRUE; 617 618 mrb_get_args(mrb, "|b", &inherit); 750 619 ary = mrb_ary_new(mrb); 751 620 c = mrb_class_ptr(mod); 752 621 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; 756 624 c = c->super; 757 625 } … … 759 627 } 760 628 761 MRB_APImrb_value629 mrb_value 762 630 mrb_mod_cv_get(mrb_state *mrb, struct RClass *c, mrb_sym sym) 763 631 { … … 790 658 } 791 659 } 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); 794 661 /* not reached */ 795 662 return mrb_nil_value(); … … 808 675 809 676 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; 818 684 } 819 685 c = c->super; … … 840 706 } 841 707 708 mrb_check_frozen(mrb, c); 842 709 if (!c->iv) { 843 710 c->iv = iv_new(mrb); 844 711 } 845 712 713 iv_put(mrb, c->iv, sym, v); 846 714 mrb_write_barrier(mrb, (struct RBasic*)c); 847 iv_put(mrb, c->iv, sym, v);848 715 } 849 716 … … 854 721 } 855 722 856 MRB_APImrb_bool723 mrb_bool 857 724 mrb_mod_cv_defined(mrb_state *mrb, struct RClass * c, mrb_sym sym) 858 725 { 859 726 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; 864 729 c = c->super; 865 730 } … … 877 742 mrb_vm_cv_get(mrb_state *mrb, mrb_sym sym) 878 743 { 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 } 883 753 return mrb_mod_cv_get(mrb, c, sym); 884 754 } … … 887 757 mrb_vm_cv_set(mrb_state *mrb, mrb_sym sym, mrb_value v) 888 758 { 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 } 892 767 mrb_mod_cv_set(mrb, c, sym, v); 893 768 } … … 912 787 struct RClass *c = base; 913 788 mrb_value v; 914 iv_tbl *t;915 789 mrb_bool retry = FALSE; 916 790 mrb_value name; … … 919 793 while (c) { 920 794 if (c->iv) { 921 t = c->iv; 922 if (iv_get(mrb, t, sym, &v)) 795 if (iv_get(mrb, c->iv, sym, &v)) 923 796 return v; 924 797 } 925 798 c = c->super; 926 799 } 927 if (!retry && base && base->tt == MRB_TT_MODULE) {800 if (!retry && base->tt == MRB_TT_MODULE) { 928 801 c = mrb->object_class; 929 802 retry = TRUE; … … 944 817 mrb_vm_const_get(mrb_state *mrb, mrb_sym sym) 945 818 { 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)) { 954 844 return v; 955 845 } 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; 972 847 } 973 848 return const_get(mrb, c, sym); … … 978 853 { 979 854 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 } 980 858 mrb_iv_set(mrb, mod, sym, v); 981 859 } … … 984 862 mrb_vm_const_set(mrb_state *mrb, mrb_sym sym, mrb_value v) 985 863 { 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); 989 867 mrb_obj_iv_set(mrb, (struct RObject*)c, sym, v); 990 868 } … … 1017 895 1018 896 ary = *(mrb_value*)p; 1019 s = mrb_sym 2name_len(mrb, sym, &len);897 s = mrb_sym_name_len(mrb, sym, &len); 1020 898 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 } 1022 908 } 1023 909 return 0; … … 1041 927 ary = mrb_ary_new(mrb); 1042 928 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); 1046 930 if (!inherit) break; 1047 931 c = c->super; … … 1056 940 mrb_value v; 1057 941 1058 if (!mrb->globals) {1059 return mrb_nil_value();1060 }1061 942 if (iv_get(mrb, mrb->globals, sym, &v)) 1062 943 return v; … … 1070 951 1071 952 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; 1077 956 iv_put(mrb, t, sym, v); 1078 957 } … … 1081 960 mrb_gv_remove(mrb_state *mrb, mrb_sym sym) 1082 961 { 1083 if (!mrb->globals) {1084 return;1085 }1086 962 iv_del(mrb, mrb->globals, sym, NULL); 1087 963 } … … 1112 988 iv_tbl *t = mrb->globals; 1113 989 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); 1126 992 return ary; 1127 993 } … … 1132 998 struct RClass *klass = mrb_class_ptr(mod); 1133 999 struct RClass *tmp; 1134 mrb_bool mod_retry = 0;1000 mrb_bool mod_retry = FALSE; 1135 1001 1136 1002 tmp = klass; 1137 1003 retry: 1138 1004 while (tmp) { 1139 if ( tmp->iv &&iv_get(mrb, tmp->iv, id, NULL)) {1005 if (iv_get(mrb, tmp->iv, id, NULL)) { 1140 1006 return TRUE; 1141 1007 } … … 1144 1010 } 1145 1011 if (!exclude && !mod_retry && (klass->tt == MRB_TT_MODULE)) { 1146 mod_retry = 1;1012 mod_retry = TRUE; 1147 1013 tmp = mrb->object_class; 1148 1014 goto retry; … … 1187 1053 } 1188 1054 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 } 1055 static mrb_sym 1056 find_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 1068 static struct RClass* 1069 outer_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 1085 static mrb_bool 1086 detect_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 1101 mrb_value 1102 mrb_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 1133 mrb_bool 1134 mrb_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.