Changeset 439 for EcnlProtoTool/trunk/mruby-2.1.1/src
- Timestamp:
- Jul 9, 2020, 8:51:43 AM (4 years ago)
- Location:
- EcnlProtoTool/trunk/mruby-2.1.1
- Files:
-
- 1 deleted
- 26 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
EcnlProtoTool/trunk/mruby-2.1.1/src/array.c
r331 r439 10 10 #include <mruby/string.h> 11 11 #include <mruby/range.h> 12 #include <mruby/proc.h> 13 #include <mruby/opcode.h> 12 14 #include "value_array.h" 13 15 … … 15 17 #define ARY_SHRINK_RATIO 5 /* must be larger than 2 */ 16 18 #define ARY_C_MAX_SIZE (SIZE_MAX / sizeof(mrb_value)) 17 #define ARY_MAX_SIZE (( ARY_C_MAX_SIZE < (size_t)MRB_INT_MAX) ? (mrb_int)ARY_C_MAX_SIZE : MRB_INT_MAX-1)19 #define ARY_MAX_SIZE ((mrb_int)((ARY_C_MAX_SIZE < (size_t)MRB_INT_MAX) ? ARY_C_MAX_SIZE : MRB_INT_MAX-1)) 18 20 19 21 static struct RArray* … … 29 31 30 32 a = (struct RArray*)mrb_obj_alloc(mrb, MRB_TT_ARRAY, mrb->array_class); 31 a->ptr = (mrb_value *)mrb_malloc(mrb, blen); 32 a->aux.capa = capa; 33 a->len = 0; 33 if (capa <= MRB_ARY_EMBED_LEN_MAX) { 34 ARY_SET_EMBED_LEN(a, 0); 35 } 36 else { 37 a->as.heap.ptr = (mrb_value *)mrb_malloc(mrb, blen); 38 a->as.heap.aux.capa = capa; 39 a->as.heap.len = 0; 40 } 34 41 35 42 return a; … … 73 80 } 74 81 82 static struct RArray* 83 ary_new_from_values(mrb_state *mrb, mrb_int size, const mrb_value *vals) 84 { 85 struct RArray *a = ary_new_capa(mrb, size); 86 87 array_copy(ARY_PTR(a), vals, size); 88 ARY_SET_LEN(a, size); 89 90 return a; 91 } 92 75 93 MRB_API mrb_value 76 94 mrb_ary_new_from_values(mrb_state *mrb, mrb_int size, const mrb_value *vals) 77 95 { 78 struct RArray *a = ary_new_capa(mrb, size); 79 80 array_copy(a->ptr, vals, size); 81 a->len = size; 82 96 struct RArray *a = ary_new_from_values(mrb, size, vals); 83 97 return mrb_obj_value(a); 84 98 } … … 90 104 91 105 a = ary_new_capa(mrb, 2); 92 a->ptr[0] = car;93 a->ptr[1] = cdr;94 a->len = 2;106 ARY_PTR(a)[0] = car; 107 ARY_PTR(a)[1] = cdr; 108 ARY_SET_LEN(a, 2); 95 109 return mrb_obj_value(a); 96 110 } … … 107 121 108 122 static void 123 ary_modify_check(mrb_state *mrb, struct RArray *a) 124 { 125 mrb_check_frozen(mrb, a); 126 } 127 128 static void 109 129 ary_modify(mrb_state *mrb, struct RArray *a) 110 130 { 111 if (MRB_FROZEN_P(a)) { 112 mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen array"); 113 } 131 ary_modify_check(mrb, a); 114 132 115 133 if (ARY_SHARED_P(a)) { 116 mrb_shared_array *shared = a->a ux.shared;117 118 if (shared->refcnt == 1 && a-> ptr == shared->ptr) {119 a-> ptr = shared->ptr;120 a->a ux.capa = a->len;134 mrb_shared_array *shared = a->as.heap.aux.shared; 135 136 if (shared->refcnt == 1 && a->as.heap.ptr == shared->ptr) { 137 a->as.heap.ptr = shared->ptr; 138 a->as.heap.aux.capa = a->as.heap.len; 121 139 mrb_free(mrb, shared); 122 140 } … … 125 143 mrb_int len; 126 144 127 p = a-> ptr;128 len = a-> len * sizeof(mrb_value);145 p = a->as.heap.ptr; 146 len = a->as.heap.len * sizeof(mrb_value); 129 147 ptr = (mrb_value *)mrb_malloc(mrb, len); 130 148 if (p) { 131 array_copy(ptr, p, a-> len);149 array_copy(ptr, p, a->as.heap.len); 132 150 } 133 a-> ptr = ptr;134 a->a ux.capa = a->len;151 a->as.heap.ptr = ptr; 152 a->as.heap.aux.capa = a->as.heap.len; 135 153 mrb_ary_decref(mrb, shared); 136 154 } … … 149 167 ary_make_shared(mrb_state *mrb, struct RArray *a) 150 168 { 151 if (!ARY_SHARED_P(a) ) {169 if (!ARY_SHARED_P(a) && !ARY_EMBED_P(a)) { 152 170 mrb_shared_array *shared = (mrb_shared_array *)mrb_malloc(mrb, sizeof(mrb_shared_array)); 171 mrb_value *ptr = a->as.heap.ptr; 172 mrb_int len = a->as.heap.len; 153 173 154 174 shared->refcnt = 1; 155 if (a->a ux.capa > a->len) {156 a-> ptr = shared->ptr = (mrb_value *)mrb_realloc(mrb, a->ptr, sizeof(mrb_value)*a->len+1);175 if (a->as.heap.aux.capa > len) { 176 a->as.heap.ptr = shared->ptr = (mrb_value *)mrb_realloc(mrb, ptr, sizeof(mrb_value)*len+1); 157 177 } 158 178 else { 159 shared->ptr = a->ptr;160 } 161 shared->len = a->len;162 a->a ux.shared = shared;179 shared->ptr = ptr; 180 } 181 shared->len = len; 182 a->as.heap.aux.shared = shared; 163 183 ARY_SET_SHARED_FLAG(a); 164 184 } … … 168 188 ary_expand_capa(mrb_state *mrb, struct RArray *a, mrb_int len) 169 189 { 170 mrb_int capa = a->aux.capa;171 172 if (len > ARY_MAX_SIZE ) {190 mrb_int capa = ARY_CAPA(a); 191 192 if (len > ARY_MAX_SIZE || len < 0) { 173 193 size_error: 174 194 mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); 175 195 } 176 196 177 if (capa == 0) {197 if (capa < ARY_DEFAULT_LEN) { 178 198 capa = ARY_DEFAULT_LEN; 179 199 } … … 190 210 } 191 211 192 if (capa > a->aux.capa) { 193 mrb_value *expanded_ptr = (mrb_value *)mrb_realloc(mrb, a->ptr, sizeof(mrb_value)*capa); 194 195 a->aux.capa = capa; 196 a->ptr = expanded_ptr; 212 if (ARY_EMBED_P(a)) { 213 mrb_value *ptr = ARY_EMBED_PTR(a); 214 mrb_int len = ARY_EMBED_LEN(a); 215 mrb_value *expanded_ptr = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value)*capa); 216 217 ARY_UNSET_EMBED_FLAG(a); 218 array_copy(expanded_ptr, ptr, len); 219 a->as.heap.len = len; 220 a->as.heap.aux.capa = capa; 221 a->as.heap.ptr = expanded_ptr; 222 } 223 else if (capa > a->as.heap.aux.capa) { 224 mrb_value *expanded_ptr = (mrb_value *)mrb_realloc(mrb, a->as.heap.ptr, sizeof(mrb_value)*capa); 225 226 a->as.heap.aux.capa = capa; 227 a->as.heap.ptr = expanded_ptr; 197 228 } 198 229 } … … 201 232 ary_shrink_capa(mrb_state *mrb, struct RArray *a) 202 233 { 203 mrb_int capa = a->aux.capa; 204 234 235 mrb_int capa; 236 237 if (ARY_EMBED_P(a)) return; 238 239 capa = a->as.heap.aux.capa; 205 240 if (capa < ARY_DEFAULT_LEN * 2) return; 206 if (capa <= a-> len * ARY_SHRINK_RATIO) return;241 if (capa <= a->as.heap.len * ARY_SHRINK_RATIO) return; 207 242 208 243 do { … … 212 247 break; 213 248 } 214 } while (capa > a-> len * ARY_SHRINK_RATIO);215 216 if (capa > a-> len && capa < a->aux.capa) {217 a->a ux.capa = capa;218 a-> ptr = (mrb_value *)mrb_realloc(mrb, a->ptr, sizeof(mrb_value)*capa);249 } while (capa > a->as.heap.len * ARY_SHRINK_RATIO); 250 251 if (capa > a->as.heap.len && capa < a->as.heap.aux.capa) { 252 a->as.heap.aux.capa = capa; 253 a->as.heap.ptr = (mrb_value *)mrb_realloc(mrb, a->as.heap.ptr, sizeof(mrb_value)*capa); 219 254 } 220 255 } … … 229 264 old_len = RARRAY_LEN(ary); 230 265 if (old_len != new_len) { 231 a->len = new_len;232 266 if (new_len < old_len) { 233 267 ary_shrink_capa(mrb, a); … … 235 269 else { 236 270 ary_expand_capa(mrb, a, new_len); 237 ary_fill_with_nil(a->ptr + old_len, new_len - old_len); 238 } 271 ary_fill_with_nil(ARY_PTR(a) + old_len, new_len - old_len); 272 } 273 ARY_SET_LEN(a, new_len); 239 274 } 240 275 … … 250 285 struct RArray *a; 251 286 252 mrb_get_args(mrb, "* ", &vals, &len);287 mrb_get_args(mrb, "*!", &vals, &len); 253 288 ary = mrb_ary_new_from_values(mrb, len, vals); 254 289 a = mrb_ary_ptr(ary); … … 258 293 } 259 294 295 static void ary_replace(mrb_state*, struct RArray*, struct RArray*); 296 260 297 static void 261 298 ary_concat(mrb_state *mrb, struct RArray *a, struct RArray *a2) … … 263 300 mrb_int len; 264 301 265 if (a2->len > ARY_MAX_SIZE - a->len) { 302 if (ARY_LEN(a) == 0) { 303 ary_replace(mrb, a, a2); 304 return; 305 } 306 if (ARY_LEN(a2) > ARY_MAX_SIZE - ARY_LEN(a)) { 266 307 mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); 267 308 } 268 len = a->len + a2->len;309 len = ARY_LEN(a) + ARY_LEN(a2); 269 310 270 311 ary_modify(mrb, a); 271 if ( a->aux.capa< len) {312 if (ARY_CAPA(a) < len) { 272 313 ary_expand_capa(mrb, a, len); 273 314 } 274 array_copy( a->ptr+a->len, a2->ptr, a2->len);315 array_copy(ARY_PTR(a)+ARY_LEN(a), ARY_PTR(a2), ARY_LEN(a2)); 275 316 mrb_write_barrier(mrb, (struct RBasic*)a); 276 a->len = len;317 ARY_SET_LEN(a, len); 277 318 } 278 319 … … 301 342 struct RArray *a2; 302 343 mrb_value *ptr; 303 mrb_int blen ;344 mrb_int blen, len1; 304 345 305 346 mrb_get_args(mrb, "a", &ptr, &blen); 306 if (ARY_MAX_SIZE - blen < a1->len) {347 if (ARY_MAX_SIZE - blen < ARY_LEN(a1)) { 307 348 mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); 308 349 } 309 a2 = ary_new_capa(mrb, a1->len + blen); 310 array_copy(a2->ptr, a1->ptr, a1->len); 311 array_copy(a2->ptr + a1->len, ptr, blen); 312 a2->len = a1->len + blen; 350 len1 = ARY_LEN(a1); 351 a2 = ary_new_capa(mrb, len1 + blen); 352 array_copy(ARY_PTR(a2), ARY_PTR(a1), len1); 353 array_copy(ARY_PTR(a2) + len1, ptr, blen); 354 ARY_SET_LEN(a2, len1+blen); 313 355 314 356 return mrb_obj_value(a2); 315 357 } 316 358 359 #define ARY_REPLACE_SHARED_MIN 20 360 317 361 static void 318 ary_replace(mrb_state *mrb, struct RArray *a, mrb_value *argv, mrb_int len) 319 { 320 ary_modify(mrb, a); 321 if (a->aux.capa < len) 362 ary_replace(mrb_state *mrb, struct RArray *a, struct RArray *b) 363 { 364 mrb_int len = ARY_LEN(b); 365 366 ary_modify_check(mrb, a); 367 if (a == b) return; 368 if (ARY_SHARED_P(a)) { 369 mrb_ary_decref(mrb, a->as.heap.aux.shared); 370 a->as.heap.aux.capa = 0; 371 a->as.heap.len = 0; 372 a->as.heap.ptr = NULL; 373 ARY_UNSET_SHARED_FLAG(a); 374 } 375 if (ARY_SHARED_P(b)) { 376 shared_b: 377 if (ARY_EMBED_P(a)) { 378 ARY_UNSET_EMBED_FLAG(a); 379 } 380 else { 381 mrb_free(mrb, a->as.heap.ptr); 382 } 383 a->as.heap.ptr = b->as.heap.ptr; 384 a->as.heap.len = len; 385 a->as.heap.aux.shared = b->as.heap.aux.shared; 386 a->as.heap.aux.shared->refcnt++; 387 ARY_SET_SHARED_FLAG(a); 388 mrb_write_barrier(mrb, (struct RBasic*)a); 389 return; 390 } 391 if (!mrb_frozen_p(b) && len > ARY_REPLACE_SHARED_MIN) { 392 ary_make_shared(mrb, b); 393 goto shared_b; 394 } 395 if (ARY_CAPA(a) < len) 322 396 ary_expand_capa(mrb, a, len); 323 array_copy( a->ptr, argv, len);397 array_copy(ARY_PTR(a), ARY_PTR(b), len); 324 398 mrb_write_barrier(mrb, (struct RBasic*)a); 325 a->len = len;399 ARY_SET_LEN(a, len); 326 400 } 327 401 … … 333 407 334 408 if (a1 != a2) { 335 ary_replace(mrb, a1, a2 ->ptr, a2->len);409 ary_replace(mrb, a1, a2); 336 410 } 337 411 } … … 354 428 struct RArray *a2; 355 429 mrb_value *ptr; 356 mrb_int times ;430 mrb_int times, len1; 357 431 358 432 mrb_get_args(mrb, "i", ×); … … 361 435 } 362 436 if (times == 0) return mrb_ary_new(mrb); 363 if (ARY_MAX_SIZE / times < a1->len) {437 if (ARY_MAX_SIZE / times < ARY_LEN(a1)) { 364 438 mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); 365 439 } 366 a2 = ary_new_capa(mrb, a1->len * times); 367 ptr = a2->ptr; 440 len1 = ARY_LEN(a1); 441 a2 = ary_new_capa(mrb, len1 * times); 442 ARY_SET_LEN(a2, len1 * times); 443 ptr = ARY_PTR(a2); 368 444 while (times--) { 369 array_copy(ptr, a1->ptr, a1->len); 370 ptr += a1->len; 371 a2->len += a1->len; 445 array_copy(ptr, ARY_PTR(a1), len1); 446 ptr += len1; 372 447 } 373 448 … … 379 454 { 380 455 struct RArray *a = mrb_ary_ptr(self); 381 382 if (a->len > 1) { 456 mrb_int len = ARY_LEN(a); 457 458 if (len > 1) { 383 459 mrb_value *p1, *p2; 384 460 385 461 ary_modify(mrb, a); 386 p1 = a->ptr;387 p2 = a->ptr + a->len - 1;462 p1 = ARY_PTR(a); 463 p2 = p1 + len - 1; 388 464 389 465 while (p1 < p2) { … … 399 475 mrb_ary_reverse(mrb_state *mrb, mrb_value self) 400 476 { 401 struct RArray *a = mrb_ary_ptr(self), *b = ary_new_capa(mrb, a->len); 402 403 if (a->len > 0) { 477 struct RArray *a = mrb_ary_ptr(self), *b = ary_new_capa(mrb, ARY_LEN(a)); 478 mrb_int len = ARY_LEN(a); 479 480 if (len > 0) { 404 481 mrb_value *p1, *p2, *e; 405 482 406 p1 = a->ptr;407 e = p1 + a->len;408 p2 = b->ptr + a->len - 1;483 p1 = ARY_PTR(a); 484 e = p1 + len; 485 p2 = ARY_PTR(b) + len - 1; 409 486 while (p1 < e) { 410 487 *p2-- = *p1++; 411 488 } 412 b->len = a->len;489 ARY_SET_LEN(b, len); 413 490 } 414 491 return mrb_obj_value(b); … … 419 496 { 420 497 struct RArray *a = mrb_ary_ptr(ary); 498 mrb_int len = ARY_LEN(a); 421 499 422 500 ary_modify(mrb, a); 423 if (a->len == a->aux.capa) 424 ary_expand_capa(mrb, a, a->len + 1); 425 a->ptr[a->len++] = elem; 501 if (len == ARY_CAPA(a)) 502 ary_expand_capa(mrb, a, len + 1); 503 ARY_PTR(a)[len] = elem; 504 ARY_SET_LEN(a, len+1); 426 505 mrb_field_write_barrier_value(mrb, (struct RBasic*)a, elem); 427 506 } … … 431 510 { 432 511 mrb_value *argv; 433 mrb_int len; 434 435 mrb_get_args(mrb, "*", &argv, &len); 436 while (len--) { 437 mrb_ary_push(mrb, self, *argv++); 438 } 512 mrb_int len, len2, alen; 513 struct RArray *a; 514 515 mrb_get_args(mrb, "*!", &argv, &alen); 516 a = mrb_ary_ptr(self); 517 ary_modify(mrb, a); 518 len = ARY_LEN(a); 519 len2 = len + alen; 520 if (ARY_CAPA(a) < len2) { 521 ary_expand_capa(mrb, a, len2); 522 } 523 array_copy(ARY_PTR(a)+len, argv, alen); 524 ARY_SET_LEN(a, len2); 525 mrb_write_barrier(mrb, (struct RBasic*)a); 439 526 440 527 return self; … … 445 532 { 446 533 struct RArray *a = mrb_ary_ptr(ary); 447 448 ary_modify(mrb, a); 449 if (a->len == 0) return mrb_nil_value(); 450 return a->ptr[--a->len]; 534 mrb_int len = ARY_LEN(a); 535 536 ary_modify_check(mrb, a); 537 if (len == 0) return mrb_nil_value(); 538 ARY_SET_LEN(a, len-1); 539 return ARY_PTR(a)[len-1]; 451 540 } 452 541 … … 457 546 { 458 547 struct RArray *a = mrb_ary_ptr(self); 548 mrb_int len = ARY_LEN(a); 459 549 mrb_value val; 460 550 461 ary_modify (mrb, a);462 if ( a->len == 0) return mrb_nil_value();551 ary_modify_check(mrb, a); 552 if (len == 0) return mrb_nil_value(); 463 553 if (ARY_SHARED_P(a)) { 464 554 L_SHIFT: 465 val = a-> ptr[0];466 a-> ptr++;467 a-> len--;555 val = a->as.heap.ptr[0]; 556 a->as.heap.ptr++; 557 a->as.heap.len--; 468 558 return val; 469 559 } 470 if ( a->len > ARY_SHIFT_SHARED_MIN) {560 if (len > ARY_SHIFT_SHARED_MIN) { 471 561 ary_make_shared(mrb, a); 472 562 goto L_SHIFT; 473 563 } 474 564 else { 475 mrb_value *ptr = a->ptr;476 mrb_int size = a->len;565 mrb_value *ptr = ARY_PTR(a); 566 mrb_int size = len; 477 567 478 568 val = *ptr; … … 481 571 ++ptr; 482 572 } 483 --a->len;573 ARY_SET_LEN(a, len-1); 484 574 } 485 575 return val; … … 494 584 { 495 585 struct RArray *a = mrb_ary_ptr(self); 586 mrb_int len = ARY_LEN(a); 496 587 497 588 if (ARY_SHARED_P(a) 498 && a->a ux.shared->refcnt == 1 /* shared only referenced from this array */499 && a-> ptr - a->aux.shared->ptr >= 1) /* there's room for unshifted item */ {500 a-> ptr--;501 a-> ptr[0] = item;589 && a->as.heap.aux.shared->refcnt == 1 /* shared only referenced from this array */ 590 && a->as.heap.ptr - a->as.heap.aux.shared->ptr >= 1) /* there's room for unshifted item */ { 591 a->as.heap.ptr--; 592 a->as.heap.ptr[0] = item; 502 593 } 503 594 else { 595 mrb_value *ptr; 596 504 597 ary_modify(mrb, a); 505 if (a->aux.capa < a->len + 1) 506 ary_expand_capa(mrb, a, a->len + 1); 507 value_move(a->ptr + 1, a->ptr, a->len); 508 a->ptr[0] = item; 509 } 510 a->len++; 598 if (ARY_CAPA(a) < len + 1) 599 ary_expand_capa(mrb, a, len + 1); 600 ptr = ARY_PTR(a); 601 value_move(ptr + 1, ptr, len); 602 ptr[0] = item; 603 } 604 ARY_SET_LEN(a, len+1); 511 605 mrb_field_write_barrier_value(mrb, (struct RBasic*)a, item); 512 606 … … 518 612 { 519 613 struct RArray *a = mrb_ary_ptr(self); 520 mrb_value *vals; 521 mrb_int len; 522 523 mrb_get_args(mrb, "*", &vals, &len); 524 if (len > ARY_MAX_SIZE - a->len) { 614 mrb_value *vals, *ptr; 615 mrb_int alen, len; 616 617 mrb_get_args(mrb, "*!", &vals, &alen); 618 if (alen == 0) { 619 ary_modify_check(mrb, a); 620 return self; 621 } 622 len = ARY_LEN(a); 623 if (alen > ARY_MAX_SIZE - len) { 525 624 mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); 526 625 } 527 626 if (ARY_SHARED_P(a) 528 && a->aux.shared->refcnt == 1 /* shared only referenced from this array */ 529 && a->ptr - a->aux.shared->ptr >= len) /* there's room for unshifted item */ { 530 a->ptr -= len; 627 && a->as.heap.aux.shared->refcnt == 1 /* shared only referenced from this array */ 628 && a->as.heap.ptr - a->as.heap.aux.shared->ptr >= alen) /* there's room for unshifted item */ { 629 ary_modify_check(mrb, a); 630 a->as.heap.ptr -= alen; 631 ptr = a->as.heap.ptr; 531 632 } 532 633 else { 634 mrb_bool same = vals == ARY_PTR(a); 533 635 ary_modify(mrb, a); 534 if (len == 0) return self; 535 if (a->aux.capa < a->len + len) 536 ary_expand_capa(mrb, a, a->len + len); 537 value_move(a->ptr + len, a->ptr, a->len); 538 } 539 array_copy(a->ptr, vals, len); 540 a->len += len; 541 while (len--) { 542 mrb_field_write_barrier_value(mrb, (struct RBasic*)a, vals[len]); 636 if (ARY_CAPA(a) < len + alen) 637 ary_expand_capa(mrb, a, len + alen); 638 ptr = ARY_PTR(a); 639 value_move(ptr + alen, ptr, len); 640 if (same) vals = ptr; 641 } 642 array_copy(ptr, vals, alen); 643 ARY_SET_LEN(a, len+alen); 644 while (alen--) { 645 mrb_field_write_barrier_value(mrb, (struct RBasic*)a, vals[alen]); 543 646 } 544 647 … … 550 653 { 551 654 struct RArray *a = mrb_ary_ptr(ary); 655 mrb_int len = ARY_LEN(a); 552 656 553 657 /* range check */ 554 if (n < 0) n += a->len;555 if (n < 0 || a->len <= n) return mrb_nil_value();556 557 return a->ptr[n];658 if (n < 0) n += len; 659 if (n < 0 || len <= n) return mrb_nil_value(); 660 661 return ARY_PTR(a)[n]; 558 662 } 559 663 … … 562 666 { 563 667 struct RArray *a = mrb_ary_ptr(ary); 668 mrb_int len = ARY_LEN(a); 564 669 565 670 ary_modify(mrb, a); 566 671 /* range check */ 567 672 if (n < 0) { 568 n += a->len;673 n += len; 569 674 if (n < 0) { 570 mrb_raisef(mrb, E_INDEX_ERROR, "index % S out of array", mrb_fixnum_value(n - a->len));571 } 572 } 573 if ( a->len <= n) {574 if ( a->aux.capa<= n)675 mrb_raisef(mrb, E_INDEX_ERROR, "index %i out of array", n - len); 676 } 677 } 678 if (len <= n) { 679 if (ARY_CAPA(a) <= n) 575 680 ary_expand_capa(mrb, a, n + 1); 576 ary_fill_with_nil( a->ptr + a->len, n + 1 - a->len);577 a->len = n + 1;578 } 579 580 a->ptr[n] = val;681 ary_fill_with_nil(ARY_PTR(a) + len, n + 1 - len); 682 ARY_SET_LEN(a, n+1); 683 } 684 685 ARY_PTR(a)[n] = val; 581 686 mrb_field_write_barrier_value(mrb, (struct RBasic*)a, val); 582 687 } … … 585 690 ary_dup(mrb_state *mrb, struct RArray *a) 586 691 { 587 struct RArray *d = ary_new_capa(mrb, a->len); 588 589 ary_replace(mrb, d, a->ptr, a->len); 590 return d; 692 return ary_new_from_values(mrb, ARY_LEN(a), ARY_PTR(a)); 591 693 } 592 694 … … 595 697 { 596 698 struct RArray *a = mrb_ary_ptr(ary); 699 mrb_int alen = ARY_LEN(a); 597 700 const mrb_value *argv; 598 701 mrb_int argc; … … 602 705 603 706 /* len check */ 604 if (len < 0) mrb_raisef(mrb, E_INDEX_ERROR, "negative length (% S)", mrb_fixnum_value(len));707 if (len < 0) mrb_raisef(mrb, E_INDEX_ERROR, "negative length (%i)", len); 605 708 606 709 /* range check */ 607 710 if (head < 0) { 608 head += a ->len;711 head += alen; 609 712 if (head < 0) { 610 713 mrb_raise(mrb, E_INDEX_ERROR, "index is out of array"); … … 612 715 } 613 716 tail = head + len; 614 if (a ->len < len || a->len < tail) {615 len = a ->len - head;717 if (alen < len || alen < tail) { 718 len = alen - head; 616 719 } 617 720 … … 620 723 argc = RARRAY_LEN(rpl); 621 724 argv = RARRAY_PTR(rpl); 622 if (argv == a->ptr) {725 if (argv == ARY_PTR(a)) { 623 726 struct RArray *r; 624 727 … … 627 730 } 628 731 r = ary_dup(mrb, a); 629 argv = r->ptr;732 argv = ARY_PTR(r); 630 733 } 631 734 } … … 634 737 argv = &rpl; 635 738 } 636 if (head >= a ->len) {739 if (head >= alen) { 637 740 if (head > ARY_MAX_SIZE - argc) { 638 mrb_raisef(mrb, E_INDEX_ERROR, "index % S too big", mrb_fixnum_value(head));741 mrb_raisef(mrb, E_INDEX_ERROR, "index %i too big", head); 639 742 } 640 743 len = head + argc; 641 if (len > a->aux.capa) {744 if (len > ARY_CAPA(a)) { 642 745 ary_expand_capa(mrb, a, head + argc); 643 746 } 644 ary_fill_with_nil( a->ptr + a->len, head - a->len);747 ary_fill_with_nil(ARY_PTR(a) + alen, head - alen); 645 748 if (argc > 0) { 646 array_copy( a->ptr+ head, argv, argc);647 } 648 a->len = len;749 array_copy(ARY_PTR(a) + head, argv, argc); 750 } 751 ARY_SET_LEN(a, len); 649 752 } 650 753 else { 651 mrb_int alen;652 653 if (a ->len - len > ARY_MAX_SIZE - argc) {654 mrb_raisef(mrb, E_INDEX_ERROR, "index % S too big", mrb_fixnum_value(a->len + argc - len));655 } 656 alen = a->len + argc - len;657 if ( alen > a->aux.capa) {658 ary_expand_capa(mrb, a, alen);754 mrb_int newlen; 755 756 if (alen - len > ARY_MAX_SIZE - argc) { 757 mrb_raisef(mrb, E_INDEX_ERROR, "index %i too big", alen + argc - len); 758 } 759 newlen = alen + argc - len; 760 if (newlen > ARY_CAPA(a)) { 761 ary_expand_capa(mrb, a, newlen); 659 762 } 660 763 661 764 if (len != argc) { 765 mrb_value *ptr = ARY_PTR(a); 662 766 tail = head + len; 663 value_move( a->ptr + head + argc, a->ptr + tail, a->len - tail);664 a->len = alen;767 value_move(ptr + head + argc, ptr + tail, alen - tail); 768 ARY_SET_LEN(a, newlen); 665 769 } 666 770 if (argc > 0) { 667 value_move( a->ptr+ head, argv, argc);771 value_move(ARY_PTR(a) + head, argv, argc); 668 772 } 669 773 } … … 687 791 struct RArray *b; 688 792 793 if (!ARY_SHARED_P(a) && len <= ARY_SHIFT_SHARED_MIN) { 794 return mrb_ary_new_from_values(mrb, len, ARY_PTR(a)+beg); 795 } 689 796 ary_make_shared(mrb, a); 690 797 b = (struct RArray*)mrb_obj_alloc(mrb, MRB_TT_ARRAY, mrb->array_class); 691 b-> ptr = a->ptr + beg;692 b-> len = len;693 b->a ux.shared = a->aux.shared;694 b->a ux.shared->refcnt++;798 b->as.heap.ptr = a->as.heap.ptr + beg; 799 b->as.heap.len = len; 800 b->as.heap.aux.shared = a->as.heap.aux.shared; 801 b->as.heap.aux.shared->refcnt++; 695 802 ARY_SET_SHARED_FLAG(b); 696 803 … … 704 811 return mrb_fixnum(index); 705 812 } 813 #ifndef MRB_WITHOUT_FLOAT 706 814 else if (mrb_float_p(index)) { 707 815 return (mrb_int)mrb_float(index); 708 816 } 817 #endif 709 818 else { 710 819 mrb_int i, argc; 711 820 mrb_value *argv; 712 821 713 mrb_get_args(mrb, "i* ", &i, &argv, &argc);822 mrb_get_args(mrb, "i*!", &i, &argv, &argc); 714 823 return i; 715 824 } … … 747 856 { 748 857 struct RArray *a = mrb_ary_ptr(self); 749 mrb_int i, len ;858 mrb_int i, len, alen; 750 859 mrb_value index; 751 860 … … 754 863 /* a[n..m] */ 755 864 case MRB_TT_RANGE: 756 if (mrb_range_beg_len(mrb, index, &i, &len, a->len, TRUE) == 1) {865 if (mrb_range_beg_len(mrb, index, &i, &len, ARY_LEN(a), TRUE) == MRB_RANGE_OK) { 757 866 return ary_subseq(mrb, a, i, len); 758 867 } … … 768 877 769 878 i = aget_index(mrb, index); 770 if (i < 0) i += a->len; 771 if (i < 0 || a->len < i) return mrb_nil_value(); 879 alen = ARY_LEN(a); 880 if (i < 0) i += alen; 881 if (i < 0 || alen < i) return mrb_nil_value(); 772 882 if (len < 0) return mrb_nil_value(); 773 if (a ->len == i) return mrb_ary_new(mrb);774 if (len > a ->len - i) len = a->len - i;883 if (alen == i) return mrb_ary_new(mrb); 884 if (len > alen - i) len = alen - i; 775 885 776 886 return ary_subseq(mrb, a, i, len); … … 822 932 /* a[n..m] = v */ 823 933 switch (mrb_range_beg_len(mrb, v1, &i, &len, RARRAY_LEN(self), FALSE)) { 824 case 0: /* not range */934 case MRB_RANGE_TYPE_MISMATCH: 825 935 mrb_ary_set(mrb, self, aget_index(mrb, v1), v2); 826 936 break; 827 case 1: /* range */937 case MRB_RANGE_OK: 828 938 mrb_ary_splice(mrb, self, i, len, v2); 829 939 break; 830 case 2: /* out of range */831 mrb_raisef(mrb, E_RANGE_ERROR, "% Sout of range", v1);940 case MRB_RANGE_OUT: 941 mrb_raisef(mrb, E_RANGE_ERROR, "%v out of range", v1); 832 942 break; 833 943 } … … 847 957 mrb_value val; 848 958 mrb_value *ptr; 849 mrb_int len ;959 mrb_int len, alen; 850 960 851 961 mrb_get_args(mrb, "i", &index); 852 if (index < 0) index += a->len; 853 if (index < 0 || a->len <= index) return mrb_nil_value(); 962 alen = ARY_LEN(a); 963 if (index < 0) index += alen; 964 if (index < 0 || alen <= index) return mrb_nil_value(); 854 965 855 966 ary_modify(mrb, a); 856 val = a->ptr[index]; 857 858 ptr = a->ptr + index; 859 len = a->len - index; 967 ptr = ARY_PTR(a); 968 val = ptr[index]; 969 970 ptr += index; 971 len = alen - index; 860 972 while (--len) { 861 973 *ptr = *(ptr+1); 862 974 ++ptr; 863 975 } 864 --a->len;976 ARY_SET_LEN(a, alen-1); 865 977 866 978 ary_shrink_capa(mrb, a); … … 873 985 { 874 986 struct RArray *a = mrb_ary_ptr(self); 875 mrb_int size; 876 877 if (mrb_get_args(mrb, "|i", &size) == 0) { 878 return (a->len > 0)? a->ptr[0]: mrb_nil_value(); 879 } 987 mrb_int size, alen; 988 989 if (mrb_get_argc(mrb) == 0) { 990 return (ARY_LEN(a) > 0)? ARY_PTR(a)[0]: mrb_nil_value(); 991 } 992 mrb_get_args(mrb, "|i", &size); 880 993 if (size < 0) { 881 994 mrb_raise(mrb, E_ARGUMENT_ERROR, "negative array size"); 882 995 } 883 996 884 if (size > a->len) size = a->len; 997 alen = ARY_LEN(a); 998 if (size > alen) size = alen; 885 999 if (ARY_SHARED_P(a)) { 886 1000 return ary_subseq(mrb, a, 0, size); 887 1001 } 888 return mrb_ary_new_from_values(mrb, size, a->ptr);1002 return mrb_ary_new_from_values(mrb, size, ARY_PTR(a)); 889 1003 } 890 1004 … … 893 1007 { 894 1008 struct RArray *a = mrb_ary_ptr(self); 895 mrb_int size; 896 897 if (mrb_get_args(mrb, "|i", &size) == 0) 898 return (a->len > 0)? a->ptr[a->len - 1]: mrb_nil_value(); 1009 mrb_int n, size, alen; 1010 1011 n = mrb_get_args(mrb, "|i", &size); 1012 alen = ARY_LEN(a); 1013 if (n == 0) { 1014 return (alen > 0) ? ARY_PTR(a)[alen - 1]: mrb_nil_value(); 1015 } 899 1016 900 1017 if (size < 0) { 901 1018 mrb_raise(mrb, E_ARGUMENT_ERROR, "negative array size"); 902 1019 } 903 if (size > a ->len) size = a->len;1020 if (size > alen) size = alen; 904 1021 if (ARY_SHARED_P(a) || size > ARY_DEFAULT_LEN) { 905 return ary_subseq(mrb, a, a ->len - size, size);906 } 907 return mrb_ary_new_from_values(mrb, size, a->ptr + a->len - size);1022 return ary_subseq(mrb, a, alen - size, size); 1023 } 1024 return mrb_ary_new_from_values(mrb, size, ARY_PTR(a) + alen - size); 908 1025 } 909 1026 … … 944 1061 mrb_ary_splat(mrb_state *mrb, mrb_value v) 945 1062 { 946 mrb_value a , recv_class;1063 mrb_value a; 947 1064 948 1065 if (mrb_array_p(v)) { … … 955 1072 956 1073 a = mrb_funcall(mrb, v, "to_a", 0); 957 if (mrb_array_p(a)) { 958 return a; 959 } 960 else if (mrb_nil_p(a)) { 1074 if (mrb_nil_p(a)) { 961 1075 return mrb_ary_new_from_values(mrb, 1, &v); 962 1076 } 963 else { 964 recv_class = mrb_obj_value(mrb_obj_class(mrb, v)); 965 mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S to Array (%S#to_a gives %S)", 966 recv_class, 967 recv_class, 968 mrb_obj_value(mrb_obj_class(mrb, a)) 969 ); 970 /* not reached */ 971 return mrb_undef_value(); 972 } 1077 mrb_ensure_array_type(mrb, a); 1078 return a; 973 1079 } 974 1080 … … 978 1084 struct RArray *a = mrb_ary_ptr(self); 979 1085 980 return mrb_fixnum_value( a->len);1086 return mrb_fixnum_value(ARY_LEN(a)); 981 1087 } 982 1088 … … 988 1094 ary_modify(mrb, a); 989 1095 if (ARY_SHARED_P(a)) { 990 mrb_ary_decref(mrb, a->a ux.shared);1096 mrb_ary_decref(mrb, a->as.heap.aux.shared); 991 1097 ARY_UNSET_SHARED_FLAG(a); 992 1098 } 993 else { 994 mrb_free(mrb, a->ptr); 995 } 996 a->len = 0; 997 a->aux.capa = 0; 998 a->ptr = 0; 1099 else if (!ARY_EMBED_P(a)){ 1100 mrb_free(mrb, a->as.heap.ptr); 1101 } 1102 ARY_SET_EMBED_LEN(a, 0); 999 1103 1000 1104 return self; … … 1002 1106 1003 1107 static mrb_value 1108 mrb_ary_clear_m(mrb_state *mrb, mrb_value self) 1109 { 1110 return mrb_ary_clear(mrb, self); 1111 } 1112 1113 static mrb_value 1004 1114 mrb_ary_empty_p(mrb_state *mrb, mrb_value self) 1005 1115 { 1006 1116 struct RArray *a = mrb_ary_ptr(self); 1007 1117 1008 return mrb_bool_value(a->len == 0); 1009 } 1010 1011 MRB_API mrb_value 1012 mrb_check_array_type(mrb_state *mrb, mrb_value ary) 1013 { 1014 return mrb_check_convert_type(mrb, ary, MRB_TT_ARRAY, "Array", "to_ary"); 1118 return mrb_bool_value(ARY_LEN(a) == 0); 1015 1119 } 1016 1120 … … 1021 1125 offset += RARRAY_LEN(ary); 1022 1126 } 1023 return ary_elt(ary, offset); 1127 if (offset < 0 || RARRAY_LEN(ary) <= offset) { 1128 return mrb_nil_value(); 1129 } 1130 return RARRAY_PTR(ary)[offset]; 1024 1131 } 1025 1132 … … 1039 1146 mrb_ary_push(mrb, list, ary); 1040 1147 1041 result = mrb_str_ buf_new(mrb, 64);1148 result = mrb_str_new_capa(mrb, 64); 1042 1149 1043 1150 for (i=0; i<RARRAY_LEN(ary); i++) { … … 1065 1172 goto str_join; 1066 1173 } 1067 tmp = mrb_check_ convert_type(mrb, val, MRB_TT_ARRAY, "Array", "to_ary");1174 tmp = mrb_check_array_type(mrb, val); 1068 1175 if (!mrb_nil_p(tmp)) { 1069 1176 val = tmp; … … 1139 1246 } 1140 1247 1248 /* internal method to convert multi-value to single value */ 1249 static mrb_value 1250 mrb_ary_svalue(mrb_state *mrb, mrb_value ary) 1251 { 1252 switch (RARRAY_LEN(ary)) { 1253 case 0: 1254 return mrb_nil_value(); 1255 case 1: 1256 return RARRAY_PTR(ary)[0]; 1257 default: 1258 return ary; 1259 } 1260 } 1261 1262 static const mrb_code each_iseq[] = { 1263 OP_ENTER, 0x0, 0x00, 0x1, /* OP_ENTER 0:0:0:0:0:0:1 */ 1264 OP_JMPIF, 0x1, 0x0, 19, /* OP_JMPIF R1 19 */ 1265 OP_LOADSELF, 0x3, /* OP_LOADSELF R3 */ 1266 OP_LOADSYM, 0x4, 0x0, /* OP_LOADSYM R4 :each*/ 1267 OP_SEND, 0x3, 0x1, 0x1, /* OP_SEND R3 :to_enum 1 */ 1268 OP_RETURN, 0x3, /* OP_RETURN R3 */ 1269 OP_LOADI_0, 0x2, /* OP_LOADI_0 R2 */ 1270 OP_JMP, 0x0, 43, /* OP_JMP 49 */ 1271 OP_MOVE, 0x3, 0x1, /* OP_MOVE R3 R1 */ 1272 OP_LOADSELF, 0x4, /* OP_LOADSELF R4 */ 1273 OP_MOVE, 0x5, 0x2, /* OP_MOVE R5 R2 */ 1274 OP_SEND, 0x4, 0x2, 0x1, /* OP_SEND R4 :[] 1 */ 1275 OP_SEND, 0x3, 0x3, 0x1, /* OP_SEND R3 :call 1 */ 1276 OP_ADDI, 0x2, 1, /* OP_ADDI R3 1 */ 1277 OP_MOVE, 0x3, 0x2, /* OP_MOVE R3 R2 */ 1278 OP_LOADSELF, 0x4, /* OP_LOADSELF R4 */ 1279 OP_SEND, 0x4, 0x4, 0x0, /* OP_SEND R4 :length 0 */ 1280 OP_LT, 0x3, /* OP_LT R3 */ 1281 OP_JMPIF, 0x3, 0x0, 24, /* OP_JMPIF R3 24 */ 1282 OP_RETURN, 0x0 /* OP_RETURN R3 */ 1283 }; 1284 1285 static void 1286 init_ary_each(mrb_state *mrb, struct RClass *ary) 1287 { 1288 struct RProc *p; 1289 mrb_method_t m; 1290 mrb_irep *each_irep = (mrb_irep*)mrb_malloc(mrb, sizeof(mrb_irep)); 1291 static const mrb_irep mrb_irep_zero = { 0 }; 1292 1293 *each_irep = mrb_irep_zero; 1294 each_irep->syms = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym)*5); 1295 each_irep->syms[0] = mrb_intern_lit(mrb, "each"); 1296 each_irep->syms[1] = mrb_intern_lit(mrb, "to_enum"); 1297 each_irep->syms[2] = mrb_intern_lit(mrb, "[]"); 1298 each_irep->syms[3] = mrb_intern_lit(mrb, "call"); 1299 each_irep->syms[4] = mrb_intern_lit(mrb, "length"); 1300 each_irep->slen = 5; 1301 each_irep->flags = MRB_ISEQ_NO_FREE; 1302 each_irep->iseq = each_iseq; 1303 each_irep->ilen = sizeof(each_iseq); 1304 each_irep->nregs = 7; 1305 each_irep->nlocals = 3; 1306 p = mrb_proc_new(mrb, each_irep); 1307 p->flags |= MRB_PROC_SCOPE | MRB_PROC_STRICT; 1308 MRB_METHOD_FROM_PROC(m, p); 1309 mrb_define_method_raw(mrb, ary, mrb_intern_lit(mrb, "each"), m); 1310 } 1311 1141 1312 void 1142 1313 mrb_init_array(mrb_state *mrb) … … 1144 1315 struct RClass *a; 1145 1316 1146 mrb->array_class = a = mrb_define_class(mrb, "Array", mrb->object_class); /* 15.2.12 */1317 mrb->array_class = a = mrb_define_class(mrb, "Array", mrb->object_class); /* 15.2.12 */ 1147 1318 MRB_SET_INSTANCE_TT(a, MRB_TT_ARRAY); 1148 1319 1149 mrb_define_class_method(mrb, a, "[]", mrb_ary_s_create, MRB_ARGS_ANY()); /* 15.2.12.4.1 */ 1150 1151 mrb_define_method(mrb, a, "+", mrb_ary_plus, MRB_ARGS_REQ(1)); /* 15.2.12.5.1 */ 1152 mrb_define_method(mrb, a, "*", mrb_ary_times, MRB_ARGS_REQ(1)); /* 15.2.12.5.2 */ 1153 mrb_define_method(mrb, a, "<<", mrb_ary_push_m, MRB_ARGS_REQ(1)); /* 15.2.12.5.3 */ 1154 mrb_define_method(mrb, a, "[]", mrb_ary_aget, MRB_ARGS_ANY()); /* 15.2.12.5.4 */ 1155 mrb_define_method(mrb, a, "[]=", mrb_ary_aset, MRB_ARGS_ANY()); /* 15.2.12.5.5 */ 1156 mrb_define_method(mrb, a, "clear", mrb_ary_clear, MRB_ARGS_NONE()); /* 15.2.12.5.6 */ 1157 mrb_define_method(mrb, a, "concat", mrb_ary_concat_m, MRB_ARGS_REQ(1)); /* 15.2.12.5.8 */ 1158 mrb_define_method(mrb, a, "delete_at", mrb_ary_delete_at, MRB_ARGS_REQ(1)); /* 15.2.12.5.9 */ 1159 mrb_define_method(mrb, a, "empty?", mrb_ary_empty_p, MRB_ARGS_NONE()); /* 15.2.12.5.12 */ 1160 mrb_define_method(mrb, a, "first", mrb_ary_first, MRB_ARGS_OPT(1)); /* 15.2.12.5.13 */ 1161 mrb_define_method(mrb, a, "index", mrb_ary_index_m, MRB_ARGS_REQ(1)); /* 15.2.12.5.14 */ 1162 mrb_define_method(mrb, a, "initialize_copy", mrb_ary_replace_m, MRB_ARGS_REQ(1)); /* 15.2.12.5.16 */ 1163 mrb_define_method(mrb, a, "join", mrb_ary_join_m, MRB_ARGS_ANY()); /* 15.2.12.5.17 */ 1164 mrb_define_method(mrb, a, "last", mrb_ary_last, MRB_ARGS_ANY()); /* 15.2.12.5.18 */ 1165 mrb_define_method(mrb, a, "length", mrb_ary_size, MRB_ARGS_NONE()); /* 15.2.12.5.19 */ 1166 mrb_define_method(mrb, a, "pop", mrb_ary_pop, MRB_ARGS_NONE()); /* 15.2.12.5.21 */ 1167 mrb_define_method(mrb, a, "push", mrb_ary_push_m, MRB_ARGS_ANY()); /* 15.2.12.5.22 */ 1168 mrb_define_method(mrb, a, "append", mrb_ary_push_m, MRB_ARGS_ANY()); 1169 mrb_define_method(mrb, a, "replace", mrb_ary_replace_m, MRB_ARGS_REQ(1)); /* 15.2.12.5.23 */ 1170 mrb_define_method(mrb, a, "reverse", mrb_ary_reverse, MRB_ARGS_NONE()); /* 15.2.12.5.24 */ 1171 mrb_define_method(mrb, a, "reverse!", mrb_ary_reverse_bang, MRB_ARGS_NONE()); /* 15.2.12.5.25 */ 1172 mrb_define_method(mrb, a, "rindex", mrb_ary_rindex_m, MRB_ARGS_REQ(1)); /* 15.2.12.5.26 */ 1173 mrb_define_method(mrb, a, "shift", mrb_ary_shift, MRB_ARGS_NONE()); /* 15.2.12.5.27 */ 1174 mrb_define_method(mrb, a, "size", mrb_ary_size, MRB_ARGS_NONE()); /* 15.2.12.5.28 */ 1175 mrb_define_method(mrb, a, "slice", mrb_ary_aget, MRB_ARGS_ANY()); /* 15.2.12.5.29 */ 1176 mrb_define_method(mrb, a, "unshift", mrb_ary_unshift_m, MRB_ARGS_ANY()); /* 15.2.12.5.30 */ 1177 mrb_define_method(mrb, a, "prepend", mrb_ary_unshift_m, MRB_ARGS_ANY()); 1320 mrb_define_class_method(mrb, a, "[]", mrb_ary_s_create, MRB_ARGS_ANY()); /* 15.2.12.4.1 */ 1321 1322 mrb_define_method(mrb, a, "+", mrb_ary_plus, MRB_ARGS_REQ(1)); /* 15.2.12.5.1 */ 1323 mrb_define_method(mrb, a, "*", mrb_ary_times, MRB_ARGS_REQ(1)); /* 15.2.12.5.2 */ 1324 mrb_define_method(mrb, a, "<<", mrb_ary_push_m, MRB_ARGS_REQ(1)); /* 15.2.12.5.3 */ 1325 mrb_define_method(mrb, a, "[]", mrb_ary_aget, MRB_ARGS_ARG(1,1)); /* 15.2.12.5.4 */ 1326 mrb_define_method(mrb, a, "[]=", mrb_ary_aset, MRB_ARGS_ARG(2,1)); /* 15.2.12.5.5 */ 1327 mrb_define_method(mrb, a, "clear", mrb_ary_clear_m, MRB_ARGS_NONE()); /* 15.2.12.5.6 */ 1328 mrb_define_method(mrb, a, "concat", mrb_ary_concat_m, MRB_ARGS_REQ(1)); /* 15.2.12.5.8 */ 1329 mrb_define_method(mrb, a, "delete_at", mrb_ary_delete_at, MRB_ARGS_REQ(1)); /* 15.2.12.5.9 */ 1330 mrb_define_method(mrb, a, "empty?", mrb_ary_empty_p, MRB_ARGS_NONE()); /* 15.2.12.5.12 */ 1331 mrb_define_method(mrb, a, "first", mrb_ary_first, MRB_ARGS_OPT(1)); /* 15.2.12.5.13 */ 1332 mrb_define_method(mrb, a, "index", mrb_ary_index_m, MRB_ARGS_REQ(1)); /* 15.2.12.5.14 */ 1333 mrb_define_method(mrb, a, "initialize_copy", mrb_ary_replace_m, MRB_ARGS_REQ(1)); /* 15.2.12.5.16 */ 1334 mrb_define_method(mrb, a, "join", mrb_ary_join_m, MRB_ARGS_OPT(1)); /* 15.2.12.5.17 */ 1335 mrb_define_method(mrb, a, "last", mrb_ary_last, MRB_ARGS_OPT(1)); /* 15.2.12.5.18 */ 1336 mrb_define_method(mrb, a, "length", mrb_ary_size, MRB_ARGS_NONE()); /* 15.2.12.5.19 */ 1337 mrb_define_method(mrb, a, "pop", mrb_ary_pop, MRB_ARGS_NONE()); /* 15.2.12.5.21 */ 1338 mrb_define_method(mrb, a, "push", mrb_ary_push_m, MRB_ARGS_ANY()); /* 15.2.12.5.22 */ 1339 mrb_define_method(mrb, a, "replace", mrb_ary_replace_m, MRB_ARGS_REQ(1)); /* 15.2.12.5.23 */ 1340 mrb_define_method(mrb, a, "reverse", mrb_ary_reverse, MRB_ARGS_NONE()); /* 15.2.12.5.24 */ 1341 mrb_define_method(mrb, a, "reverse!", mrb_ary_reverse_bang, MRB_ARGS_NONE()); /* 15.2.12.5.25 */ 1342 mrb_define_method(mrb, a, "rindex", mrb_ary_rindex_m, MRB_ARGS_REQ(1)); /* 15.2.12.5.26 */ 1343 mrb_define_method(mrb, a, "shift", mrb_ary_shift, MRB_ARGS_NONE()); /* 15.2.12.5.27 */ 1344 mrb_define_method(mrb, a, "size", mrb_ary_size, MRB_ARGS_NONE()); /* 15.2.12.5.28 */ 1345 mrb_define_method(mrb, a, "slice", mrb_ary_aget, MRB_ARGS_ARG(1,1)); /* 15.2.12.5.29 */ 1346 mrb_define_method(mrb, a, "unshift", mrb_ary_unshift_m, MRB_ARGS_ANY()); /* 15.2.12.5.30 */ 1178 1347 1179 1348 mrb_define_method(mrb, a, "__ary_eq", mrb_ary_eq, MRB_ARGS_REQ(1)); 1180 1349 mrb_define_method(mrb, a, "__ary_cmp", mrb_ary_cmp, MRB_ARGS_REQ(1)); 1181 mrb_define_method(mrb, a, "__ary_index", mrb_ary_index_m, MRB_ARGS_REQ(1)); /* kept for mruby-array-ext */ 1182 } 1350 mrb_define_method(mrb, a, "__ary_index", mrb_ary_index_m, MRB_ARGS_REQ(1)); /* kept for mruby-array-ext */ 1351 mrb_define_method(mrb, a, "__svalue", mrb_ary_svalue, MRB_ARGS_NONE()); 1352 1353 init_ary_each(mrb, a); 1354 } -
EcnlProtoTool/trunk/mruby-2.1.1/src/backtrace.c
r331 r439 17 17 18 18 struct backtrace_location { 19 int lineno; 19 int32_t lineno; 20 mrb_sym method_id; 20 21 const char *filename; 21 mrb_sym method_id;22 22 }; 23 23 24 typedef void (*each_backtrace_func)(mrb_state*, int i,struct backtrace_location*, void*);24 typedef void (*each_backtrace_func)(mrb_state*, const struct backtrace_location*, void*); 25 25 26 26 static const mrb_data_type bt_type = { "Backtrace", mrb_free }; 27 27 28 static void 29 each_backtrace(mrb_state *mrb, mrb_int ciidx, mrb_code *pc0, each_backtrace_func func, void *data) 30 { 31 int i, j; 28 mrb_value mrb_exc_inspect(mrb_state *mrb, mrb_value exc); 29 mrb_value mrb_unpack_backtrace(mrb_state *mrb, mrb_value backtrace); 30 31 static void 32 each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, const mrb_code *pc0, each_backtrace_func func, void *data) 33 { 34 ptrdiff_t i; 32 35 33 36 if (ciidx >= mrb->c->ciend - mrb->c->cibase) 34 37 ciidx = 10; /* ciidx is broken... */ 35 38 36 for (i=ciidx , j=0; i >= 0; i--,j++) {39 for (i=ciidx; i >= 0; i--) { 37 40 struct backtrace_location loc; 38 41 mrb_callinfo *ci; 39 42 mrb_irep *irep; 40 mrb_code *pc;43 const mrb_code *pc; 41 44 42 45 ci = &mrb->c->cibase[i]; … … 52 55 } 53 56 else if (i+1 <= ciidx) { 54 pc = mrb->c->cibase[i+1].pc - 1; 57 if (!mrb->c->cibase[i + 1].pc) continue; 58 pc = &mrb->c->cibase[i+1].pc[-1]; 55 59 } 56 60 else { 57 61 pc = pc0; 58 62 } 59 loc.filename = mrb_debug_get_filename(irep, (uint32_t)(pc - irep->iseq)); 60 loc.lineno = mrb_debug_get_line(irep, (uint32_t)(pc - irep->iseq)); 61 63 64 loc.lineno = mrb_debug_get_line(mrb, irep, pc - irep->iseq); 62 65 if (loc.lineno == -1) continue; 63 66 67 loc.filename = mrb_debug_get_filename(mrb, irep, pc - irep->iseq); 64 68 if (!loc.filename) { 65 69 loc.filename = "(unknown)"; … … 67 71 68 72 loc.method_id = ci->mid; 69 func(mrb, j,&loc, data);73 func(mrb, &loc, data); 70 74 } 71 75 } … … 74 78 75 79 static void 76 print_backtrace(mrb_state *mrb, mrb_value backtrace) 77 { 78 int i, n; 80 print_backtrace(mrb_state *mrb, struct RObject *exc, mrb_value backtrace) 81 { 82 mrb_int i; 83 mrb_int n = RARRAY_LEN(backtrace); 84 mrb_value *loc, mesg; 79 85 FILE *stream = stderr; 80 86 81 if (!mrb_array_p(backtrace)) return; 82 fprintf(stream, "trace:\n"); 83 84 n = RARRAY_LEN(backtrace); 85 for (i=0; n--; i++) { 86 mrb_value entry = RARRAY_PTR(backtrace)[n]; 87 88 if (mrb_string_p(entry)) { 89 fprintf(stream, "\t[%d] %.*s\n", i, (int)RSTRING_LEN(entry), RSTRING_PTR(entry)); 90 } 91 } 92 } 93 94 static void 95 print_packed_backtrace(mrb_state *mrb, mrb_value packed) 96 { 97 FILE *stream = stderr; 98 struct backtrace_location *bt; 99 int n, i; 100 101 bt = (struct backtrace_location*)mrb_data_check_get_ptr(mrb, packed, &bt_type); 102 if (bt == NULL) { 103 mrb_raise(mrb, E_RUNTIME_ERROR, "broken backtrace"); 104 } 105 n = (mrb_int)RDATA(packed)->flags; 106 107 fprintf(stream, "trace:\n"); 108 for (i = 0; n--; i++) { 109 int ai = mrb_gc_arena_save(mrb); 110 struct backtrace_location *entry = &bt[n]; 111 if (entry->filename == NULL) continue; 112 fprintf(stream, "\t[%d] %s:%d", (int)i, entry->filename, entry->lineno); 113 if (entry->method_id != 0) { 114 const char *method_name; 115 116 method_name = mrb_sym2name(mrb, entry->method_id); 117 fprintf(stream, ":in %s", method_name); 118 mrb_gc_arena_restore(mrb, ai); 119 } 120 fprintf(stream, "\n"); 121 } 87 if (n != 0) { 88 fprintf(stream, "trace (most recent call last):\n"); 89 for (i=n-1,loc=&RARRAY_PTR(backtrace)[i]; i>0; i--,loc--) { 90 if (mrb_string_p(*loc)) { 91 fprintf(stream, "\t[%d] %.*s\n", 92 (int)i, (int)RSTRING_LEN(*loc), RSTRING_PTR(*loc)); 93 } 94 } 95 if (mrb_string_p(*loc)) { 96 fprintf(stream, "%.*s: ", (int)RSTRING_LEN(*loc), RSTRING_PTR(*loc)); 97 } 98 } 99 mesg = mrb_exc_inspect(mrb, mrb_obj_value(exc)); 100 fprintf(stream, "%.*s\n", (int)RSTRING_LEN(mesg), RSTRING_PTR(mesg)); 122 101 } 123 102 … … 138 117 backtrace = mrb_obj_iv_get(mrb, mrb->exc, mrb_intern_lit(mrb, "backtrace")); 139 118 if (mrb_nil_p(backtrace)) return; 140 if (mrb_array_p(backtrace)) { 141 print_backtrace(mrb, backtrace); 142 } 143 else { 144 print_packed_backtrace(mrb, backtrace); 145 } 119 if (!mrb_array_p(backtrace)) backtrace = mrb_unpack_backtrace(mrb, backtrace); 120 print_backtrace(mrb, mrb->exc, backtrace); 146 121 } 147 122 #else … … 155 130 156 131 static void 132 count_backtrace_i(mrb_state *mrb, 133 const struct backtrace_location *loc, 134 void *data) 135 { 136 int *lenp = (int*)data; 137 138 (*lenp)++; 139 } 140 141 static void 157 142 pack_backtrace_i(mrb_state *mrb, 158 int i, 159 struct backtrace_location *loc, 143 const struct backtrace_location *loc, 160 144 void *data) 161 145 { 162 struct backtrace_location *entry = (struct backtrace_location*)data; 163 164 entry[i] = *loc; 146 struct backtrace_location **pptr = (struct backtrace_location**)data; 147 struct backtrace_location *ptr = *pptr; 148 149 *ptr = *loc; 150 *pptr = ptr+1; 165 151 } 166 152 … … 170 156 struct RData *backtrace; 171 157 ptrdiff_t ciidx = mrb->c->ci - mrb->c->cibase; 172 mrb_int len = (ciidx+1)*sizeof(struct backtrace_location); 158 int len = 0; 159 int size; 173 160 void *ptr; 174 161 175 ptr = mrb_malloc(mrb, len); 176 memset(ptr, 0, len); 162 each_backtrace(mrb, ciidx, mrb->c->ci->pc, count_backtrace_i, &len); 163 size = len * sizeof(struct backtrace_location); 164 ptr = mrb_malloc(mrb, size); 177 165 backtrace = mrb_data_object_alloc(mrb, NULL, ptr, &bt_type); 178 backtrace->flags = (u nsigned int)ciidx+1;179 each_backtrace(mrb, ciidx, mrb->c->ci->pc, pack_backtrace_i, ptr);166 backtrace->flags = (uint32_t)len; 167 each_backtrace(mrb, ciidx, mrb->c->ci->pc, pack_backtrace_i, &ptr); 180 168 return mrb_obj_value(backtrace); 181 169 } … … 184 172 mrb_keep_backtrace(mrb_state *mrb, mrb_value exc) 185 173 { 174 mrb_sym sym = mrb_intern_lit(mrb, "backtrace"); 186 175 mrb_value backtrace; 187 int ai = mrb_gc_arena_save(mrb); 188 176 int ai; 177 178 if (mrb_iv_defined(mrb, exc, sym)) return; 179 ai = mrb_gc_arena_save(mrb); 189 180 backtrace = packed_backtrace(mrb); 190 mrb_iv_set(mrb, exc, mrb_intern_lit(mrb, "backtrace"), backtrace);181 mrb_iv_set(mrb, exc, sym, backtrace); 191 182 mrb_gc_arena_restore(mrb, ai); 192 183 } … … 195 186 mrb_unpack_backtrace(mrb_state *mrb, mrb_value backtrace) 196 187 { 197 struct backtrace_location *bt;188 const struct backtrace_location *bt; 198 189 mrb_int n, i; 199 200 if (mrb_nil_p(backtrace)) return mrb_ary_new_capa(mrb, 0); 190 int ai; 191 192 if (mrb_nil_p(backtrace)) { 193 empty_backtrace: 194 return mrb_ary_new_capa(mrb, 0); 195 } 201 196 if (mrb_array_p(backtrace)) return backtrace; 202 197 bt = (struct backtrace_location*)mrb_data_check_get_ptr(mrb, backtrace, &bt_type); 203 if (bt == NULL) { 204 mrb_raise(mrb, E_RUNTIME_ERROR, "broken backtrace"); 205 } 198 if (bt == NULL) goto empty_backtrace; 206 199 n = (mrb_int)RDATA(backtrace)->flags; 207 200 backtrace = mrb_ary_new_capa(mrb, n); 201 ai = mrb_gc_arena_save(mrb); 208 202 for (i = 0; i < n; i++) { 209 int ai = mrb_gc_arena_save(mrb); 210 struct backtrace_location *entry = &bt[i]; 203 const struct backtrace_location *entry = &bt[i]; 211 204 mrb_value btline; 212 205 213 if (entry->filename == NULL) continue; 214 btline = mrb_format(mrb, "%S:%S", 215 mrb_str_new_cstr(mrb, entry->filename), 216 mrb_fixnum_value(entry->lineno)); 206 btline = mrb_format(mrb, "%s:%d", entry->filename, (int)entry->lineno); 217 207 if (entry->method_id != 0) { 218 208 mrb_str_cat_lit(mrb, btline, ":in "); 219 mrb_str_cat_cstr(mrb, btline, mrb_sym 2name(mrb, entry->method_id));209 mrb_str_cat_cstr(mrb, btline, mrb_sym_name(mrb, entry->method_id)); 220 210 } 221 211 mrb_ary_push(mrb, backtrace, btline); -
EcnlProtoTool/trunk/mruby-2.1.1/src/class.c
r331 r439 8 8 #include <mruby.h> 9 9 #include <mruby/array.h> 10 #include <mruby/hash.h> 10 11 #include <mruby/class.h> 11 12 #include <mruby/numeric.h> … … 16 17 #include <mruby/data.h> 17 18 #include <mruby/istruct.h> 18 19 KHASH_DEFINE(mt, mrb_sym, struct RProc*, TRUE, kh_int_hash_func, kh_int_hash_equal) 19 #include <mruby/opcode.h> 20 21 KHASH_DEFINE(mt, mrb_sym, mrb_method_t, TRUE, kh_int_hash_func, kh_int_hash_equal) 20 22 21 23 void … … 28 30 for (k = kh_begin(h); k != kh_end(h); k++) { 29 31 if (kh_exist(h, k)) { 30 struct RProc *m = kh_value(h, k); 31 if (m) { 32 mrb_gc_mark(mrb, (struct RBasic*)m); 32 mrb_method_t m = kh_value(h, k); 33 34 if (MRB_METHOD_PROC_P(m)) { 35 struct RProc *p = MRB_METHOD_PROC(m); 36 mrb_gc_mark(mrb, (struct RBasic*)p); 33 37 } 34 38 } … … 51 55 } 52 56 53 static void 54 name_class(mrb_state *mrb, struct RClass *c, mrb_sym name) 55 { 56 mrb_obj_iv_set(mrb, (struct RObject*)c, 57 mrb_intern_lit(mrb, "__classid__"), mrb_symbol_value(name)); 57 void 58 mrb_class_name_class(mrb_state *mrb, struct RClass *outer, struct RClass *c, mrb_sym id) 59 { 60 mrb_value name; 61 mrb_sym nsym = mrb_intern_lit(mrb, "__classname__"); 62 63 if (mrb_obj_iv_defined(mrb, (struct RObject*)c, nsym)) return; 64 if (outer == NULL || outer == mrb->object_class) { 65 name = mrb_symbol_value(id); 66 } 67 else { 68 name = mrb_class_path(mrb, outer); 69 if (mrb_nil_p(name)) { /* unnamed outer class */ 70 if (outer != mrb->object_class && outer != c) { 71 mrb_obj_iv_set_force(mrb, (struct RObject*)c, mrb_intern_lit(mrb, "__outer__"), 72 mrb_obj_value(outer)); 73 } 74 return; 75 } 76 else { 77 mrb_int len; 78 const char *n = mrb_sym_name_len(mrb, id, &len); 79 80 mrb_str_cat_lit(mrb, name, "::"); 81 mrb_str_cat(mrb, name, n, len); 82 } 83 } 84 mrb_obj_iv_set_force(mrb, (struct RObject*)c, nsym, name); 85 } 86 87 mrb_bool 88 mrb_const_name_p(mrb_state *mrb, const char *name, mrb_int len) 89 { 90 return len > 0 && ISUPPER(name[0]) && mrb_ident_p(name+1, len-1); 58 91 } 59 92 … … 61 94 setup_class(mrb_state *mrb, struct RClass *outer, struct RClass *c, mrb_sym id) 62 95 { 63 name_class(mrb, c, id);96 mrb_class_name_class(mrb, outer, c, id); 64 97 mrb_obj_iv_set(mrb, (struct RObject*)outer, id, mrb_obj_value(c)); 65 if (outer != mrb->object_class) {66 mrb_obj_iv_set(mrb, (struct RObject*)c, mrb_intern_lit(mrb, "__outer__"),67 mrb_obj_value(outer));68 }69 98 } 70 99 … … 78 107 if (o->c->tt == MRB_TT_SCLASS) return; 79 108 sc = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_SCLASS, mrb->class_class); 109 sc->flags |= MRB_FL_CLASS_IS_INHERITED; 80 110 sc->mt = kh_init(mt, mrb); 81 111 sc->iv = 0; … … 104 134 mrb_field_write_barrier(mrb, (struct RBasic*)sc, (struct RBasic*)o); 105 135 mrb_obj_iv_set(mrb, (struct RObject*)sc, mrb_intern_lit(mrb, "__attached__"), mrb_obj_value(o)); 106 } 107 108 static struct RClass * 136 sc->flags |= o->flags & MRB_FL_OBJ_IS_FROZEN; 137 } 138 139 static mrb_value 140 class_name_str(mrb_state *mrb, struct RClass* c) 141 { 142 mrb_value path = mrb_class_path(mrb, c); 143 if (mrb_nil_p(path)) { 144 path = c->tt == MRB_TT_MODULE ? mrb_str_new_lit(mrb, "#<Module:") : 145 mrb_str_new_lit(mrb, "#<Class:"); 146 mrb_str_cat_str(mrb, path, mrb_ptr_to_str(mrb, c)); 147 mrb_str_cat_lit(mrb, path, ">"); 148 } 149 return path; 150 } 151 152 static struct RClass* 109 153 class_from_sym(mrb_state *mrb, struct RClass *klass, mrb_sym id) 110 154 { … … 115 159 } 116 160 117 static struct RClass 161 static struct RClass* 118 162 module_from_sym(mrb_state *mrb, struct RClass *klass, mrb_sym id) 119 163 { … … 137 181 } 138 182 139 MRB_API struct RClass*140 mrb_class_outer_module(mrb_state *mrb, struct RClass *c)141 {142 mrb_value outer;143 struct RClass *cls;144 145 outer = mrb_obj_iv_get(mrb, (struct RObject*)c, mrb_intern_lit(mrb, "__outer__"));146 if (mrb_nil_p(outer)) return NULL;147 cls = mrb_class_ptr(outer);148 if (cls->tt == MRB_TT_SCLASS)149 {150 mrb_value klass;151 klass = mrb_obj_iv_get(mrb, (struct RObject *)cls,152 mrb_intern_lit(mrb, "__attached__"));153 if (class_ptr_p(klass)) {154 cls = mrb_class_ptr(klass);155 }156 }157 return cls;158 }159 160 183 static void 161 184 check_if_class_or_module(mrb_state *mrb, mrb_value obj) 162 185 { 163 186 if (!class_ptr_p(obj)) { 164 mrb_raisef(mrb, E_TYPE_ERROR, "% S is not a class/module", mrb_inspect(mrb, obj));187 mrb_raisef(mrb, E_TYPE_ERROR, "%!v is not a class/module", obj); 165 188 } 166 189 } … … 192 215 } 193 216 194 MRB_APIstruct RClass*217 struct RClass* 195 218 mrb_vm_define_module(mrb_state *mrb, mrb_value outer, mrb_sym id) 196 219 { … … 199 222 mrb_value old = mrb_const_get(mrb, outer, id); 200 223 201 if ( mrb_type(old) != MRB_TT_MODULE) {202 mrb_raisef(mrb, E_TYPE_ERROR, "% S is not a module", mrb_inspect(mrb, old));224 if (!mrb_module_p(old)) { 225 mrb_raisef(mrb, E_TYPE_ERROR, "%!v is not a module", old); 203 226 } 204 227 return mrb_class_ptr(old); … … 233 256 MRB_CLASS_ORIGIN(c); 234 257 if (super && mrb_class_real(c->super) != super) { 235 mrb_raisef(mrb, E_TYPE_ERROR, "superclass mismatch for Class %S (%S not %S)", 236 mrb_sym2str(mrb, name), 237 mrb_obj_value(c->super), mrb_obj_value(super)); 258 mrb_raisef(mrb, E_TYPE_ERROR, "superclass mismatch for Class %n (%C not %C)", 259 name, c->super, super); 238 260 } 239 261 return c; … … 250 272 { 251 273 if (!super) { 252 mrb_warn(mrb, "no super class for '% S', Object assumed", mrb_sym2str(mrb, name));274 mrb_warn(mrb, "no super class for '%n', Object assumed", name); 253 275 } 254 276 return define_class(mrb, name, super, mrb->object_class); … … 261 283 } 262 284 263 static mrb_value mrb_bob_init(mrb_state *mrb, mrb_value cv); 285 static mrb_value mrb_bob_init(mrb_state *mrb, mrb_value); 286 #ifdef MRB_METHOD_CACHE 287 static void mc_clear_all(mrb_state *mrb); 288 static void mc_clear_by_id(mrb_state *mrb, struct RClass*, mrb_sym); 289 #else 290 #define mc_clear_all(mrb) 291 #define mc_clear_by_id(mrb,c,s) 292 #endif 264 293 265 294 static void … … 271 300 if (!super) 272 301 super = mrb->object_class; 302 super->flags |= MRB_FL_CLASS_IS_INHERITED; 273 303 s = mrb_obj_value(super); 304 mrb_mc_clear_by_class(mrb, klass); 274 305 mid = mrb_intern_lit(mrb, "inherited"); 275 306 if (!mrb_func_basic_p(mrb, s, mid, mrb_bob_init)) { 276 307 mrb_value c = mrb_obj_value(klass); 277 mrb_funcall_argv(mrb, mrb_obj_value(super), mid, 1, &c);278 } 279 } 280 281 MRB_APIstruct RClass*308 mrb_funcall_argv(mrb, s, mid, 1, &c); 309 } 310 } 311 312 struct RClass* 282 313 mrb_vm_define_class(mrb_state *mrb, mrb_value outer, mrb_value super, mrb_sym id) 283 314 { … … 286 317 287 318 if (!mrb_nil_p(super)) { 288 if (mrb_type(super) != MRB_TT_CLASS) { 289 mrb_raisef(mrb, E_TYPE_ERROR, "superclass must be a Class (%S given)", 290 mrb_inspect(mrb, super)); 319 if (!mrb_class_p(super)) { 320 mrb_raisef(mrb, E_TYPE_ERROR, "superclass must be a Class (%!v given)", super); 291 321 } 292 322 s = mrb_class_ptr(super); … … 299 329 mrb_value old = mrb_const_get(mrb, outer, id); 300 330 301 if ( mrb_type(old) != MRB_TT_CLASS) {302 mrb_raisef(mrb, E_TYPE_ERROR, "% S is not a class", mrb_inspect(mrb, old));331 if (!mrb_class_p(old)) { 332 mrb_raisef(mrb, E_TYPE_ERROR, "%!v is not a class", old); 303 333 } 304 334 c = mrb_class_ptr(old); … … 306 336 /* check super class */ 307 337 if (mrb_class_real(c->super) != s) { 308 mrb_raisef(mrb, E_TYPE_ERROR, "superclass mismatch for class % S", old);338 mrb_raisef(mrb, E_TYPE_ERROR, "superclass mismatch for class %v", old); 309 339 } 310 340 } … … 337 367 } 338 368 339 MRB_API struct RClass 369 MRB_API struct RClass* 340 370 mrb_class_get_under(mrb_state *mrb, struct RClass *outer, const char *name) 341 371 { … … 343 373 } 344 374 345 MRB_API struct RClass 375 MRB_API struct RClass* 346 376 mrb_class_get(mrb_state *mrb, const char *name) 347 377 { … … 349 379 } 350 380 351 MRB_API struct RClass 381 MRB_API struct RClass* 352 382 mrb_exc_get(mrb_state *mrb, const char *name) 353 383 { … … 356 386 mrb_intern_cstr(mrb, name)); 357 387 358 if ( mrb_type(c) != MRB_TT_CLASS) {388 if (!mrb_class_p(c)) { 359 389 mrb_raise(mrb, mrb->eException_class, "exception corrupted"); 360 390 } … … 369 399 } 370 400 371 MRB_API struct RClass 401 MRB_API struct RClass* 372 402 mrb_module_get_under(mrb_state *mrb, struct RClass *outer, const char *name) 373 403 { … … 375 405 } 376 406 377 MRB_API struct RClass 407 MRB_API struct RClass* 378 408 mrb_module_get(mrb_state *mrb, const char *name) 379 409 { … … 384 414 * Defines a class under the namespace of \a outer. 385 415 * \param outer a class which contains the new class. 386 * \param idname of the new class416 * \param name name of the new class 387 417 * \param super a class from which the new class will derive. 388 418 * NULL means \c Object class. … … 397 427 * \a super, the function just returns the defined class. 398 428 */ 399 MRB_API struct RClass 429 MRB_API struct RClass* 400 430 mrb_define_class_under(mrb_state *mrb, struct RClass *outer, const char *name, struct RClass *super) 401 431 { … … 405 435 #if 0 406 436 if (!super) { 407 mrb_warn(mrb, "no super class for '%S::%S', Object assumed", 408 mrb_obj_value(outer), mrb_sym2str(mrb, id)); 437 mrb_warn(mrb, "no super class for '%C::%n', Object assumed", outer, id); 409 438 } 410 439 #endif … … 415 444 416 445 MRB_API void 417 mrb_define_method_raw(mrb_state *mrb, struct RClass *c, mrb_sym mid, struct RProc *p)446 mrb_define_method_raw(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_method_t m) 418 447 { 419 448 khash_t(mt) *h; … … 422 451 h = c->mt; 423 452 424 if (MRB_FROZEN_P(c)) { 425 if (c->tt == MRB_TT_MODULE) 426 mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen module"); 427 else 428 mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen class"); 429 } 453 mrb_check_frozen(mrb, c); 430 454 if (!h) h = c->mt = kh_init(mt, mrb); 431 455 k = kh_put(mt, mrb, h, mid); 432 kh_value(h, k) = p; 433 if (p) { 456 kh_value(h, k) = m; 457 if (MRB_METHOD_PROC_P(m) && !MRB_METHOD_UNDEF_P(m)) { 458 struct RProc *p = MRB_METHOD_PROC(m); 459 460 p->flags |= MRB_PROC_SCOPE; 434 461 p->c = NULL; 435 mrb_field_write_barrier(mrb, (struct RBasic *)c, (struct RBasic *)p); 436 } 462 mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)p); 463 if (!MRB_PROC_ENV_P(p)) { 464 MRB_PROC_SET_TARGET_CLASS(p, c); 465 } 466 } 467 mc_clear_by_id(mrb, c, mid); 437 468 } 438 469 … … 440 471 mrb_define_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_func_t func, mrb_aspec aspec) 441 472 { 442 struct RProc *p;473 mrb_method_t m; 443 474 int ai = mrb_gc_arena_save(mrb); 444 475 445 p = mrb_proc_new_cfunc(mrb, func); 446 p->target_class = c; 447 mrb_define_method_raw(mrb, c, mid, p); 476 MRB_METHOD_FROM_FUNC(m, func); 477 if (aspec == MRB_ARGS_NONE()) { 478 MRB_METHOD_NOARG_SET(m); 479 } 480 mrb_define_method_raw(mrb, c, mid, m); 448 481 mrb_gc_arena_restore(mrb, ai); 449 482 } … … 459 492 mrb_notimplement(mrb_state *mrb) 460 493 { 461 const char *str;462 mrb_int len;463 494 mrb_callinfo *ci = mrb->c->ci; 464 495 465 496 if (ci->mid) { 466 str = mrb_sym2name_len(mrb, ci->mid, &len); 467 mrb_raisef(mrb, E_NOTIMP_ERROR, 468 "%S() function is unimplemented on this machine", 469 mrb_str_new_static(mrb, str, (size_t)len)); 497 mrb_raisef(mrb, E_NOTIMP_ERROR, "%n() function is unimplemented on this machine", ci->mid); 470 498 } 471 499 } … … 481 509 482 510 static mrb_value 483 check_type(mrb_state *mrb, mrb_value val, enum mrb_vtype t, const char *c, const char *m)484 {485 mrb_value tmp;486 487 tmp = mrb_check_convert_type(mrb, val, t, c, m);488 if (mrb_nil_p(tmp)) {489 mrb_raisef(mrb, E_TYPE_ERROR, "expected %S", mrb_str_new_cstr(mrb, c));490 }491 return tmp;492 }493 494 static mrb_value495 to_str(mrb_state *mrb, mrb_value val)496 {497 return check_type(mrb, val, MRB_TT_STRING, "String", "to_str");498 }499 500 static mrb_value501 511 to_ary(mrb_state *mrb, mrb_value val) 502 512 { 503 return check_type(mrb, val, MRB_TT_ARRAY, "Array", "to_ary"); 513 mrb_check_type(mrb, val, MRB_TT_ARRAY); 514 return val; 504 515 } 505 516 … … 507 518 to_hash(mrb_state *mrb, mrb_value val) 508 519 { 509 return check_type(mrb, val, MRB_TT_HASH, "Hash", "to_hash"); 510 } 511 512 static mrb_sym 513 to_sym(mrb_state *mrb, mrb_value ss) 514 { 515 if (mrb_type(ss) == MRB_TT_SYMBOL) { 516 return mrb_symbol(ss); 517 } 518 else if (mrb_string_p(ss)) { 519 return mrb_intern_str(mrb, to_str(mrb, ss)); 520 } 521 else { 522 mrb_value obj = mrb_funcall(mrb, ss, "inspect", 0); 523 mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a symbol", obj); 524 /* not reached */ 525 return 0; 526 } 527 } 520 mrb_check_type(mrb, val, MRB_TT_HASH); 521 return val; 522 } 523 524 #define to_sym(mrb, ss) mrb_obj_to_sym(mrb, ss) 525 526 MRB_API mrb_int 527 mrb_get_argc(mrb_state *mrb) 528 { 529 mrb_int argc = mrb->c->ci->argc; 530 531 if (argc < 0) { 532 struct RArray *a = mrb_ary_ptr(mrb->c->stack[1]); 533 534 argc = ARY_LEN(a); 535 } 536 return argc; 537 } 538 539 MRB_API mrb_value* 540 mrb_get_argv(mrb_state *mrb) 541 { 542 mrb_int argc = mrb->c->ci->argc; 543 mrb_value *array_argv = mrb->c->stack + 1; 544 if (argc < 0) { 545 struct RArray *a = mrb_ary_ptr(*array_argv); 546 547 array_argv = ARY_PTR(a); 548 } 549 return array_argv; 550 } 551 552 void mrb_hash_check_kdict(mrb_state *mrb, mrb_value self); 528 553 529 554 /* … … 539 564 ---------------------------------------------------------------------------------------------- 540 565 o: Object [mrb_value] 541 C: class/module [mrb_value]566 C: Class/Module [mrb_value] 542 567 S: String [mrb_value] when ! follows, the value may be nil 543 568 A: Array [mrb_value] when ! follows, the value may be nil … … 546 571 z: String [char*] NUL terminated string; z! gives NULL for nil 547 572 a: Array [mrb_value*,mrb_int] Receive two arguments; a! gives (NULL,0) for nil 548 f: Float [mrb_float] 549 i: Integer [mrb_int] 550 b: Boolean [mrb_bool] 551 n: Symbol [mrb_sym] 552 d: Data [void*,mrb_data_type const] 2nd argument will be used to check data type so it won't be modified 553 I: Inline struct [void*] 554 &: Block [mrb_value] 555 *: rest argument [mrb_value*,mrb_int] Receive the rest of the arguments as an array. 556 |: optional Next argument of '|' and later are optional. 557 ?: optional given [mrb_bool] true if preceding argument (optional) is given. 573 f: Fixnum/Float [mrb_float] 574 i: Fixnum/Float [mrb_int] 575 b: boolean [mrb_bool] 576 n: String/Symbol [mrb_sym] 577 d: data [void*,mrb_data_type const] 2nd argument will be used to check data type so it won't be modified; when ! follows, the value may be nil 578 I: inline struct [void*] 579 &: block [mrb_value] &! raises exception if no block given 580 *: rest argument [mrb_value*,mrb_int] The rest of the arguments as an array; *! avoid copy of the stack 581 |: optional Following arguments are optional 582 ?: optional given [mrb_bool] true if preceding argument (optional) is given 583 ':': keyword args [mrb_kwargs const] Get keyword arguments 558 584 */ 559 585 MRB_API mrb_int 560 586 mrb_get_args(mrb_state *mrb, const char *format, ...) 561 587 { 588 const char *fmt = format; 562 589 char c; 563 int i = 0;590 mrb_int i = 0; 564 591 va_list ap; 565 int argc = mrb->c->ci->argc;566 int arg_i = 0;567 mrb_bool ar ray_argv;592 mrb_int argc = mrb->c->ci->argc; 593 mrb_value *array_argv = mrb->c->stack+1; 594 mrb_bool argv_on_stack = argc >= 0; 568 595 mrb_bool opt = FALSE; 596 mrb_bool opt_skip = TRUE; 569 597 mrb_bool given = TRUE; 570 598 mrb_value kdict; 599 mrb_bool reqkarg = FALSE; 600 mrb_int needargc = 0; 601 602 if (!argv_on_stack) { 603 struct RArray *a = mrb_ary_ptr(*array_argv); 604 array_argv = ARY_PTR(a); 605 argc = ARY_LEN(a); 606 } 571 607 va_start(ap, format); 572 if (argc < 0) { 573 struct RArray *a = mrb_ary_ptr(mrb->c->stack[1]); 574 575 argc = a->len; 576 array_argv = TRUE; 608 609 #define ARGV array_argv 610 611 while ((c = *fmt++)) { 612 switch (c) { 613 case '|': 614 opt = TRUE; 615 break; 616 case '*': 617 opt_skip = FALSE; 618 if (!reqkarg) reqkarg = strchr(fmt, ':') ? TRUE : FALSE; 619 goto check_exit; 620 case '!': 621 break; 622 case ':': 623 reqkarg = TRUE; 624 /* fall through */ 625 case '&': case '?': 626 if (opt) opt_skip = FALSE; 627 break; 628 default: 629 if (!opt) needargc ++; 630 break; 631 } 632 } 633 634 check_exit: 635 if (reqkarg && argc > needargc && mrb_hash_p(kdict = ARGV[argc - 1])) { 636 mrb_hash_check_kdict(mrb, kdict); 637 argc --; 577 638 } 578 639 else { 579 array_argv = FALSE; 580 } 581 582 #define ARGV \ 583 (array_argv ? mrb_ary_ptr(mrb->c->stack[1])->ptr : (mrb->c->stack + 1)) 584 640 kdict = mrb_nil_value(); 641 } 642 643 opt = FALSE; 644 i = 0; 585 645 while ((c = *format++)) { 646 mrb_value *argv = ARGV; 647 mrb_bool altmode; 648 586 649 switch (c) { 587 case '|': case '*': case '&': case '?': 650 case '|': case '*': case '&': case '?': case ':': 588 651 break; 589 652 default: … … 599 662 } 600 663 664 if (*format == '!') { 665 format ++; 666 altmode = TRUE; 667 } 668 else { 669 altmode = FALSE; 670 } 671 601 672 switch (c) { 602 673 case 'o': … … 606 677 p = va_arg(ap, mrb_value*); 607 678 if (i < argc) { 608 *p = ARGV[arg_i++]; 609 i++; 679 *p = argv[i++]; 610 680 } 611 681 } … … 619 689 mrb_value ss; 620 690 621 ss = ARGV[arg_i++];691 ss = argv[i++]; 622 692 if (!class_ptr_p(ss)) { 623 mrb_raisef(mrb, E_TYPE_ERROR, "% Sis not class/module", ss);693 mrb_raisef(mrb, E_TYPE_ERROR, "%v is not class/module", ss); 624 694 } 625 695 *p = ss; 626 i++;627 696 } 628 697 } … … 633 702 634 703 p = va_arg(ap, mrb_value*); 635 if (*format == '!') { 636 format++; 637 if (i < argc && mrb_nil_p(ARGV[arg_i])) { 638 *p = ARGV[arg_i++]; 639 i++; 640 break; 704 if (i < argc) { 705 *p = argv[i++]; 706 if (!(altmode && mrb_nil_p(*p))) { 707 mrb_to_str(mrb, *p); 641 708 } 642 }643 if (i < argc) {644 *p = to_str(mrb, ARGV[arg_i++]);645 i++;646 709 } 647 710 } … … 652 715 653 716 p = va_arg(ap, mrb_value*); 654 if (*format == '!') { 655 format++; 656 if (i < argc && mrb_nil_p(ARGV[arg_i])) { 657 *p = ARGV[arg_i++]; 658 i++; 659 break; 717 if (i < argc) { 718 *p = argv[i++]; 719 if (!(altmode && mrb_nil_p(*p))) { 720 *p = to_ary(mrb, *p); 660 721 } 661 }662 if (i < argc) {663 *p = to_ary(mrb, ARGV[arg_i++]);664 i++;665 722 } 666 723 } … … 671 728 672 729 p = va_arg(ap, mrb_value*); 673 if (*format == '!') { 674 format++; 675 if (i < argc && mrb_nil_p(ARGV[arg_i])) { 676 *p = ARGV[arg_i++]; 677 i++; 678 break; 730 if (i < argc) { 731 *p = argv[i++]; 732 if (!(altmode && mrb_nil_p(*p))) { 733 *p = to_hash(mrb, *p); 679 734 } 680 }681 if (i < argc) {682 *p = to_hash(mrb, ARGV[arg_i++]);683 i++;684 735 } 685 736 } … … 693 744 ps = va_arg(ap, char**); 694 745 pl = va_arg(ap, mrb_int*); 695 if ( *format == '!') {696 format++;697 if ( i < argc && mrb_nil_p(ARGV[arg_i])) {746 if (i < argc) { 747 ss = argv[i++]; 748 if (altmode && mrb_nil_p(ss)) { 698 749 *ps = NULL; 699 750 *pl = 0; 700 i++; arg_i++;701 break;702 751 } 703 } 704 if (i < argc) { 705 ss = to_str(mrb, ARGV[arg_i++]); 706 *ps = RSTRING_PTR(ss); 707 *pl = RSTRING_LEN(ss); 708 i++; 752 else { 753 mrb_to_str(mrb, ss); 754 *ps = RSTRING_PTR(ss); 755 *pl = RSTRING_LEN(ss); 756 } 709 757 } 710 758 } … … 716 764 717 765 ps = va_arg(ap, const char**); 718 if ( *format == '!') {719 format++;720 if ( i < argc && mrb_nil_p(ARGV[arg_i])) {766 if (i < argc) { 767 ss = argv[i++]; 768 if (altmode && mrb_nil_p(ss)) { 721 769 *ps = NULL; 722 i++; arg_i++;723 break;724 770 } 725 } 726 if (i < argc) { 727 ss = to_str(mrb, ARGV[arg_i++]); 728 *ps = mrb_string_value_cstr(mrb, &ss); 729 i++; 771 else { 772 mrb_to_str(mrb, ss); 773 *ps = RSTRING_CSTR(mrb, ss); 774 } 730 775 } 731 776 } … … 740 785 pb = va_arg(ap, mrb_value**); 741 786 pl = va_arg(ap, mrb_int*); 742 if ( *format == '!') {743 format++;744 if ( i < argc && mrb_nil_p(ARGV[arg_i])) {787 if (i < argc) { 788 aa = argv[i++]; 789 if (altmode && mrb_nil_p(aa)) { 745 790 *pb = 0; 746 791 *pl = 0; 747 i++; arg_i++;748 break;749 792 } 750 } 751 if (i < argc) { 752 aa = to_ary(mrb, ARGV[arg_i++]); 753 a = mrb_ary_ptr(aa); 754 *pb = a->ptr; 755 *pl = a->len; 756 i++; 793 else { 794 aa = to_ary(mrb, aa); 795 a = mrb_ary_ptr(aa); 796 *pb = ARY_PTR(a); 797 *pl = ARY_LEN(a); 798 } 757 799 } 758 800 } … … 765 807 p = va_arg(ap, void**); 766 808 if (i < argc) { 767 ss = ARGV[arg_i];768 if ( mrb_type(ss) != MRB_TT_ISTRUCT)809 ss = argv[i++]; 810 if (!mrb_istruct_p(ss)) 769 811 { 770 mrb_raisef(mrb, E_TYPE_ERROR, "% Sis not inline struct", ss);812 mrb_raisef(mrb, E_TYPE_ERROR, "%v is not inline struct", ss); 771 813 } 772 814 *p = mrb_istruct_ptr(ss); 773 arg_i++; 774 i++; 775 } 776 } 777 break; 815 } 816 } 817 break; 818 #ifndef MRB_WITHOUT_FLOAT 778 819 case 'f': 779 820 { … … 782 823 p = va_arg(ap, mrb_float*); 783 824 if (i < argc) { 784 *p = mrb_to_flo(mrb, ARGV[arg_i]); 785 arg_i++; 786 i++; 787 } 788 } 789 break; 825 *p = mrb_to_flo(mrb, argv[i++]); 826 } 827 } 828 break; 829 #endif 790 830 case 'i': 791 831 { … … 794 834 p = va_arg(ap, mrb_int*); 795 835 if (i < argc) { 796 switch (mrb_type(ARGV[arg_i])) { 797 case MRB_TT_FIXNUM: 798 *p = mrb_fixnum(ARGV[arg_i]); 799 break; 800 case MRB_TT_FLOAT: 801 { 802 mrb_float f = mrb_float(ARGV[arg_i]); 803 804 if (!FIXABLE_FLOAT(f)) { 805 mrb_raise(mrb, E_RANGE_ERROR, "float too big for int"); 806 } 807 *p = (mrb_int)f; 808 } 809 break; 810 case MRB_TT_STRING: 811 mrb_raise(mrb, E_TYPE_ERROR, "no implicit conversion of String into Integer"); 812 break; 813 default: 814 *p = mrb_fixnum(mrb_Integer(mrb, ARGV[arg_i])); 815 break; 816 } 817 arg_i++; 818 i++; 836 *p = mrb_fixnum(mrb_to_int(mrb, argv[i++])); 819 837 } 820 838 } … … 825 843 826 844 if (i < argc) { 827 mrb_value b = ARGV[arg_i++];845 mrb_value b = argv[i++]; 828 846 *boolp = mrb_test(b); 829 i++;830 847 } 831 848 } … … 839 856 mrb_value ss; 840 857 841 ss = ARGV[arg_i++];858 ss = argv[i++]; 842 859 *symp = to_sym(mrb, ss); 843 i++;844 860 } 845 861 } … … 852 868 datap = va_arg(ap, void**); 853 869 type = va_arg(ap, struct mrb_data_type const*); 854 if ( *format == '!') {855 format++;856 if ( i < argc && mrb_nil_p(ARGV[arg_i])) {870 if (i < argc) { 871 mrb_value dd = argv[i++]; 872 if (altmode && mrb_nil_p(dd)) { 857 873 *datap = 0; 858 i++; arg_i++;859 break;860 874 } 861 } 862 if (i < argc) { 863 *datap = mrb_data_get_ptr(mrb, ARGV[arg_i++], type); 864 ++i; 875 else { 876 *datap = mrb_data_get_ptr(mrb, dd, type); 877 } 865 878 } 866 879 } … … 878 891 bp = mrb->c->stack + mrb->c->ci->argc + 1; 879 892 } 893 if (altmode && mrb_nil_p(*bp)) { 894 mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given"); 895 } 880 896 *p = *bp; 881 897 } 882 898 break; 883 899 case '|': 900 if (opt_skip && i == argc) goto finish; 884 901 opt = TRUE; 885 902 break; … … 897 914 mrb_value **var; 898 915 mrb_int *pl; 916 mrb_bool nocopy = (altmode || !argv_on_stack) ? TRUE : FALSE; 899 917 900 918 var = va_arg(ap, mrb_value**); … … 903 921 *pl = argc-i; 904 922 if (*pl > 0) { 905 *var = ARGV + arg_i; 923 if (nocopy) { 924 *var = argv+i; 925 } 926 else { 927 mrb_value args = mrb_ary_new_from_values(mrb, *pl, argv+i); 928 RARRAY(args)->c = NULL; 929 *var = RARRAY_PTR(args); 930 } 906 931 } 907 932 i = argc; 908 arg_i += *pl;909 933 } 910 934 else { … … 914 938 } 915 939 break; 940 941 case ':': 942 { 943 mrb_value ksrc = mrb_hash_p(kdict) ? mrb_hash_dup(mrb, kdict) : mrb_hash_new(mrb); 944 const mrb_kwargs *kwargs = va_arg(ap, const mrb_kwargs*); 945 mrb_value *rest; 946 947 if (kwargs == NULL) { 948 rest = NULL; 949 } 950 else { 951 uint32_t kwnum = kwargs->num; 952 uint32_t required = kwargs->required; 953 const char *const *kname = kwargs->table; 954 mrb_value *values = kwargs->values; 955 uint32_t j; 956 const uint32_t keyword_max = 40; 957 958 if (kwnum > keyword_max || required > kwnum) { 959 mrb_raise(mrb, E_ARGUMENT_ERROR, "keyword number is too large"); 960 } 961 962 for (j = required; j > 0; j --, kname ++, values ++) { 963 mrb_value k = mrb_symbol_value(mrb_intern_cstr(mrb, *kname)); 964 if (!mrb_hash_key_p(mrb, ksrc, k)) { 965 mrb_raisef(mrb, E_ARGUMENT_ERROR, "missing keyword: %s", *kname); 966 } 967 *values = mrb_hash_delete_key(mrb, ksrc, k); 968 mrb_gc_protect(mrb, *values); 969 } 970 971 for (j = kwnum - required; j > 0; j --, kname ++, values ++) { 972 mrb_value k = mrb_symbol_value(mrb_intern_cstr(mrb, *kname)); 973 if (mrb_hash_key_p(mrb, ksrc, k)) { 974 *values = mrb_hash_delete_key(mrb, ksrc, k); 975 mrb_gc_protect(mrb, *values); 976 } 977 else { 978 *values = mrb_undef_value(); 979 } 980 } 981 982 rest = kwargs->rest; 983 } 984 985 if (rest) { 986 *rest = ksrc; 987 } 988 else if (!mrb_hash_empty_p(mrb, ksrc)) { 989 ksrc = mrb_hash_keys(mrb, ksrc); 990 ksrc = RARRAY_PTR(ksrc)[0]; 991 mrb_raisef(mrb, E_ARGUMENT_ERROR, "unknown keyword: %v", ksrc); 992 } 993 } 994 break; 995 916 996 default: 917 mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid argument specifier % S", mrb_str_new(mrb, &c, 1));997 mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid argument specifier %c", c); 918 998 break; 919 999 } … … 925 1005 mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments"); 926 1006 } 1007 1008 finish: 927 1009 va_end(ap); 928 1010 return i; … … 983 1065 int superclass_seen = 0; 984 1066 985 if (m->flags & MRB_FL AG_IS_PREPENDED)1067 if (m->flags & MRB_FL_CLASS_IS_PREPENDED) 986 1068 goto skip; 987 1069 … … 990 1072 991 1073 p = c->super; 992 while (p) {1074 while (p) { 993 1075 if (p->tt == MRB_TT_ICLASS) { 994 1076 if (p->mt == m->mt) { … … 1006 1088 1007 1089 ic = include_class_new(mrb, m, ins_pos->super); 1090 m->flags |= MRB_FL_CLASS_IS_INHERITED; 1008 1091 ins_pos->super = ic; 1009 mrb_field_write_barrier(mrb, (struct RBasic*)ins_pos, (struct RBasic*)ins_pos->super); 1092 mrb_field_write_barrier(mrb, (struct RBasic*)ins_pos, (struct RBasic*)ic); 1093 mrb_mc_clear_by_class(mrb, ins_pos); 1010 1094 ins_pos = ic; 1011 1095 skip: 1012 1096 m = m->super; 1013 1097 } 1098 mc_clear_all(mrb); 1014 1099 return 0; 1015 1100 } … … 1018 1103 mrb_include_module(mrb_state *mrb, struct RClass *c, struct RClass *m) 1019 1104 { 1020 int changed = include_module_at(mrb, c, find_origin(c), m, 1);1021 if ( changed< 0) {1105 mrb_check_frozen(mrb, c); 1106 if (include_module_at(mrb, c, find_origin(c), m, 1) < 0) { 1022 1107 mrb_raise(mrb, E_ARGUMENT_ERROR, "cyclic include detected"); 1023 1108 } … … 1030 1115 int changed = 0; 1031 1116 1032 if (!(c->flags & MRB_FLAG_IS_PREPENDED)) { 1117 mrb_check_frozen(mrb, c); 1118 if (!(c->flags & MRB_FL_CLASS_IS_PREPENDED)) { 1033 1119 origin = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_ICLASS, c); 1034 origin->flags |= MRB_FL AG_IS_ORIGIN;1120 origin->flags |= MRB_FL_CLASS_IS_ORIGIN | MRB_FL_CLASS_IS_INHERITED; 1035 1121 origin->super = c->super; 1036 1122 c->super = origin; … … 1038 1124 c->mt = kh_init(mt, mrb); 1039 1125 mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)origin); 1040 c->flags |= MRB_FL AG_IS_PREPENDED;1126 c->flags |= MRB_FL_CLASS_IS_PREPENDED; 1041 1127 } 1042 1128 changed = include_module_at(mrb, c, c, m, 0); … … 1115 1201 mrb_ary_push(mrb, result, mrb_obj_value(c->c)); 1116 1202 } 1117 else if (!(c->flags & MRB_FL AG_IS_PREPENDED)) {1203 else if (!(c->flags & MRB_FL_CLASS_IS_PREPENDED)) { 1118 1204 mrb_ary_push(mrb, result, mrb_obj_value(c)); 1119 1205 } … … 1133 1219 mrb_include_module(mrb, mrb_class_ptr(mrb_singleton_class(mrb, obj)), mrb_class_ptr(mod)); 1134 1220 return mod; 1135 }1136 1137 static mrb_value1138 mrb_mod_included_modules(mrb_state *mrb, mrb_value self)1139 {1140 mrb_value result;1141 struct RClass *c = mrb_class_ptr(self);1142 struct RClass *origin = c;1143 1144 MRB_CLASS_ORIGIN(origin);1145 result = mrb_ary_new(mrb);1146 while (c) {1147 if (c != origin && c->tt == MRB_TT_ICLASS) {1148 if (c->c->tt == MRB_TT_MODULE) {1149 mrb_ary_push(mrb, result, mrb_obj_value(c->c));1150 }1151 }1152 c = c->super;1153 }1154 1155 return result;1156 1221 } 1157 1222 … … 1167 1232 } 1168 1233 return mod; 1169 }1170 1171 mrb_value mrb_class_instance_method_list(mrb_state*, mrb_bool, struct RClass*, int);1172 1173 /* 15.2.2.4.33 */1174 /*1175 * call-seq:1176 * mod.instance_methods(include_super=true) -> array1177 *1178 * Returns an array containing the names of the public and protected instance1179 * methods in the receiver. For a module, these are the public and protected methods;1180 * for a class, they are the instance (not singleton) methods. With no1181 * argument, or with an argument that is <code>false</code>, the1182 * instance methods in <i>mod</i> are returned, otherwise the methods1183 * in <i>mod</i> and <i>mod</i>'s superclasses are returned.1184 *1185 * module A1186 * def method1() end1187 * end1188 * class B1189 * def method2() end1190 * end1191 * class C < B1192 * def method3() end1193 * end1194 *1195 * A.instance_methods #=> [:method1]1196 * B.instance_methods(false) #=> [:method2]1197 * C.instance_methods(false) #=> [:method3]1198 * C.instance_methods(true).length #=> 431199 */1200 1201 static mrb_value1202 mrb_mod_instance_methods(mrb_state *mrb, mrb_value mod)1203 {1204 struct RClass *c = mrb_class_ptr(mod);1205 mrb_bool recur = TRUE;1206 mrb_get_args(mrb, "|b", &recur);1207 return mrb_class_instance_method_list(mrb, recur, c, 0);1208 1234 } 1209 1235 … … 1233 1259 case MRB_TT_SYMBOL: 1234 1260 case MRB_TT_FIXNUM: 1261 #ifndef MRB_WITHOUT_FLOAT 1235 1262 case MRB_TT_FLOAT: 1263 #endif 1236 1264 mrb_raise(mrb, E_TYPE_ERROR, "can't define singleton"); 1237 1265 return mrb_nil_value(); /* not reached */ … … 1264 1292 } 1265 1293 1266 MRB_API struct RProc* 1294 #ifdef MRB_METHOD_CACHE 1295 static void 1296 mc_clear_all(mrb_state *mrb) 1297 { 1298 struct mrb_cache_entry *mc = mrb->cache; 1299 int i; 1300 1301 for (i=0; i<MRB_METHOD_CACHE_SIZE; i++) { 1302 mc[i].c = 0; 1303 } 1304 } 1305 1306 void 1307 mrb_mc_clear_by_class(mrb_state *mrb, struct RClass *c) 1308 { 1309 struct mrb_cache_entry *mc = mrb->cache; 1310 int i; 1311 1312 if (c->flags & MRB_FL_CLASS_IS_INHERITED) { 1313 mc_clear_all(mrb); 1314 c->flags &= ~MRB_FL_CLASS_IS_INHERITED; 1315 return; 1316 } 1317 for (i=0; i<MRB_METHOD_CACHE_SIZE; i++) { 1318 if (mc[i].c == c) mc[i].c = 0; 1319 } 1320 } 1321 1322 static void 1323 mc_clear_by_id(mrb_state *mrb, struct RClass *c, mrb_sym mid) 1324 { 1325 struct mrb_cache_entry *mc = mrb->cache; 1326 int i; 1327 1328 if (c->flags & MRB_FL_CLASS_IS_INHERITED) { 1329 mc_clear_all(mrb); 1330 c->flags &= ~MRB_FL_CLASS_IS_INHERITED; 1331 return; 1332 } 1333 for (i=0; i<MRB_METHOD_CACHE_SIZE; i++) { 1334 if (mc[i].c == c || mc[i].mid == mid) 1335 mc[i].c = 0; 1336 } 1337 } 1338 #endif 1339 1340 MRB_API mrb_method_t 1267 1341 mrb_method_search_vm(mrb_state *mrb, struct RClass **cp, mrb_sym mid) 1268 1342 { 1269 1343 khiter_t k; 1270 struct RProc *m;1344 mrb_method_t m; 1271 1345 struct RClass *c = *cp; 1346 #ifdef MRB_METHOD_CACHE 1347 struct RClass *oc = c; 1348 int h = kh_int_hash_func(mrb, ((intptr_t)oc) ^ mid) & (MRB_METHOD_CACHE_SIZE-1); 1349 struct mrb_cache_entry *mc = &mrb->cache[h]; 1350 1351 if (mc->c == c && mc->mid == mid) { 1352 *cp = mc->c0; 1353 return mc->m; 1354 } 1355 #endif 1272 1356 1273 1357 while (c) { … … 1278 1362 if (k != kh_end(h)) { 1279 1363 m = kh_value(h, k); 1280 if ( !m) break;1364 if (MRB_METHOD_UNDEF_P(m)) break; 1281 1365 *cp = c; 1366 #ifdef MRB_METHOD_CACHE 1367 mc->c = oc; 1368 mc->c0 = c; 1369 mc->mid = mid; 1370 mc->m = m; 1371 #endif 1282 1372 return m; 1283 1373 } … … 1285 1375 c = c->super; 1286 1376 } 1287 return NULL; /* no method */ 1288 } 1289 1290 MRB_API struct RProc* 1377 MRB_METHOD_FROM_PROC(m, NULL); 1378 return m; /* no method */ 1379 } 1380 1381 MRB_API mrb_method_t 1291 1382 mrb_method_search(mrb_state *mrb, struct RClass* c, mrb_sym mid) 1292 1383 { 1293 struct RProc *m;1384 mrb_method_t m; 1294 1385 1295 1386 m = mrb_method_search_vm(mrb, &c, mid); 1296 if (!m) { 1297 mrb_value inspect = mrb_funcall(mrb, mrb_obj_value(c), "inspect", 0); 1298 if (mrb_string_p(inspect) && RSTRING_LEN(inspect) > 64) { 1299 inspect = mrb_any_to_s(mrb, mrb_obj_value(c)); 1300 } 1301 mrb_name_error(mrb, mid, "undefined method '%S' for class %S", 1302 mrb_sym2str(mrb, mid), inspect); 1387 if (MRB_METHOD_UNDEF_P(m)) { 1388 mrb_name_error(mrb, mid, "undefined method '%n' for class %C", mid, c); 1303 1389 } 1304 1390 return m; 1305 1391 } 1306 1392 1307 static mrb_value 1308 attr_reader(mrb_state *mrb, mrb_value obj) 1309 { 1310 mrb_value name = mrb_proc_cfunc_env_get(mrb, 0); 1311 return mrb_iv_get(mrb, obj, to_sym(mrb, name)); 1312 } 1313 1314 static mrb_value 1315 mrb_mod_attr_reader(mrb_state *mrb, mrb_value mod) 1393 #define ONSTACK_ALLOC_MAX 32 1394 1395 static mrb_sym 1396 prepare_name_common(mrb_state *mrb, mrb_sym sym, const char *prefix, const char *suffix) 1397 { 1398 char onstack[ONSTACK_ALLOC_MAX]; 1399 mrb_int sym_len; 1400 const char *sym_str = mrb_sym_name_len(mrb, sym, &sym_len); 1401 size_t prefix_len = prefix ? strlen(prefix) : 0; 1402 size_t suffix_len = suffix ? strlen(suffix) : 0; 1403 size_t name_len = sym_len + prefix_len + suffix_len; 1404 char *buf = name_len > sizeof(onstack) ? (char *)mrb_alloca(mrb, name_len) : onstack; 1405 char *p = buf; 1406 1407 if (prefix_len > 0) { 1408 memcpy(p, prefix, prefix_len); 1409 p += prefix_len; 1410 } 1411 1412 memcpy(p, sym_str, sym_len); 1413 p += sym_len; 1414 1415 if (suffix_len > 0) { 1416 memcpy(p, suffix, suffix_len); 1417 p += suffix_len; 1418 } 1419 1420 return mrb_intern(mrb, buf, name_len); 1421 } 1422 1423 static mrb_value 1424 prepare_ivar_name(mrb_state *mrb, mrb_sym sym) 1425 { 1426 sym = prepare_name_common(mrb, sym, "@", NULL); 1427 mrb_iv_name_sym_check(mrb, sym); 1428 return mrb_symbol_value(sym); 1429 } 1430 1431 static mrb_sym 1432 prepare_writer_name(mrb_state *mrb, mrb_sym sym) 1433 { 1434 return prepare_name_common(mrb, sym, NULL, "="); 1435 } 1436 1437 static mrb_value 1438 mod_attr_define(mrb_state *mrb, mrb_value mod, mrb_value (*accessor)(mrb_state *, mrb_value), mrb_sym (*access_name)(mrb_state *, mrb_sym)) 1316 1439 { 1317 1440 struct RClass *c = mrb_class_ptr(mod); … … 1323 1446 ai = mrb_gc_arena_save(mrb); 1324 1447 for (i=0; i<argc; i++) { 1325 mrb_value name, str; 1326 mrb_sym method, sym; 1448 mrb_value name; 1449 mrb_sym method; 1450 struct RProc *p; 1451 mrb_method_t m; 1327 1452 1328 1453 method = to_sym(mrb, argv[i]); 1329 name = mrb_sym2str(mrb, method); 1330 str = mrb_str_buf_new(mrb, RSTRING_LEN(name)+1); 1331 mrb_str_cat_lit(mrb, str, "@"); 1332 mrb_str_cat_str(mrb, str, name); 1333 sym = mrb_intern_str(mrb, str); 1334 mrb_iv_check(mrb, sym); 1335 name = mrb_symbol_value(sym); 1336 mrb_define_method_raw(mrb, c, method, 1337 mrb_proc_new_cfunc_with_env(mrb, attr_reader, 1, &name)); 1454 name = prepare_ivar_name(mrb, method); 1455 if (access_name) { 1456 method = access_name(mrb, method); 1457 } 1458 1459 p = mrb_proc_new_cfunc_with_env(mrb, accessor, 1, &name); 1460 MRB_METHOD_FROM_PROC(m, p); 1461 mrb_define_method_raw(mrb, c, method, m); 1338 1462 mrb_gc_arena_restore(mrb, ai); 1339 1463 } 1340 1464 return mrb_nil_value(); 1465 } 1466 1467 static mrb_value 1468 attr_reader(mrb_state *mrb, mrb_value obj) 1469 { 1470 mrb_value name = mrb_proc_cfunc_env_get(mrb, 0); 1471 return mrb_iv_get(mrb, obj, to_sym(mrb, name)); 1472 } 1473 1474 static mrb_value 1475 mrb_mod_attr_reader(mrb_state *mrb, mrb_value mod) 1476 { 1477 return mod_attr_define(mrb, mod, attr_reader, NULL); 1341 1478 } 1342 1479 … … 1355 1492 mrb_mod_attr_writer(mrb_state *mrb, mrb_value mod) 1356 1493 { 1357 struct RClass *c = mrb_class_ptr(mod); 1358 mrb_value *argv; 1359 mrb_int argc, i; 1360 int ai; 1361 1362 mrb_get_args(mrb, "*", &argv, &argc); 1363 ai = mrb_gc_arena_save(mrb); 1364 for (i=0; i<argc; i++) { 1365 mrb_value name, str, attr; 1366 mrb_sym method, sym; 1367 1368 method = to_sym(mrb, argv[i]); 1369 1370 /* prepare iv name (@name) */ 1371 name = mrb_sym2str(mrb, method); 1372 str = mrb_str_buf_new(mrb, RSTRING_LEN(name)+1); 1373 mrb_str_cat_lit(mrb, str, "@"); 1374 mrb_str_cat_str(mrb, str, name); 1375 sym = mrb_intern_str(mrb, str); 1376 mrb_iv_check(mrb, sym); 1377 attr = mrb_symbol_value(sym); 1378 1379 /* prepare method name (name=) */ 1380 str = mrb_str_buf_new(mrb, RSTRING_LEN(str)); 1381 mrb_str_cat_str(mrb, str, name); 1382 mrb_str_cat_lit(mrb, str, "="); 1383 method = mrb_intern_str(mrb, str); 1384 1385 mrb_define_method_raw(mrb, c, method, 1386 mrb_proc_new_cfunc_with_env(mrb, attr_writer, 1, &attr)); 1387 mrb_gc_arena_restore(mrb, ai); 1388 } 1389 return mrb_nil_value(); 1494 return mod_attr_define(mrb, mod, attr_writer, prepare_writer_name); 1390 1495 } 1391 1496 … … 1402 1507 if (ttype == 0) ttype = MRB_TT_OBJECT; 1403 1508 if (ttype <= MRB_TT_CPTR) { 1404 mrb_raisef(mrb, E_TYPE_ERROR, "can't create instance of % S", cv);1509 mrb_raisef(mrb, E_TYPE_ERROR, "can't create instance of %v", cv); 1405 1510 } 1406 1511 o = (struct RObject*)mrb_obj_alloc(mrb, ttype, c); … … 1420 1525 */ 1421 1526 1422 MRB_APImrb_value1527 mrb_value 1423 1528 mrb_instance_new(mrb_state *mrb, mrb_value cv) 1424 1529 { … … 1426 1531 mrb_value *argv; 1427 1532 mrb_int argc; 1428 1429 mrb_get_args(mrb, "*&", &argv, &argc, &blk); 1533 mrb_sym init; 1534 1535 mrb_get_args(mrb, "*!&", &argv, &argc, &blk); 1430 1536 obj = mrb_instance_alloc(mrb, cv); 1431 mrb_funcall_with_block(mrb, obj, mrb_intern_lit(mrb, "initialize"), argc, argv, blk); 1432 1537 init = mrb_intern_lit(mrb, "initialize"); 1538 if (!mrb_func_basic_p(mrb, obj, init, mrb_bob_init)) { 1539 mrb_funcall_with_block(mrb, obj, init, argc, argv, blk); 1540 } 1433 1541 return obj; 1434 1542 } … … 1474 1582 new_class = mrb_obj_value(mrb_class_new(mrb, mrb_class_ptr(super))); 1475 1583 mid = mrb_intern_lit(mrb, "initialize"); 1476 if (!mrb_func_basic_p(mrb, new_class, mid, mrb_bob_init)) { 1584 if (mrb_func_basic_p(mrb, new_class, mid, mrb_class_initialize)) { 1585 mrb_class_initialize(mrb, new_class); 1586 } 1587 else { 1477 1588 mrb_funcall_with_block(mrb, new_class, mid, n, &super, blk); 1478 1589 } … … 1559 1670 mrb_obj_respond_to(mrb_state *mrb, struct RClass* c, mrb_sym mid) 1560 1671 { 1561 khiter_t k; 1562 1563 while (c) { 1564 khash_t(mt) *h = c->mt; 1565 1566 if (h) { 1567 k = kh_get(mt, mrb, h, mid); 1568 if (k != kh_end(h)) { 1569 if (kh_value(h, k)) { 1570 return TRUE; /* method exists */ 1571 } 1572 else { 1573 return FALSE; /* undefined method */ 1574 } 1575 } 1576 } 1577 c = c->super; 1578 } 1579 return FALSE; /* no method */ 1672 mrb_method_t m; 1673 1674 m = mrb_method_search_vm(mrb, &c, mid); 1675 if (MRB_METHOD_UNDEF_P(m)) { 1676 return FALSE; 1677 } 1678 return TRUE; 1580 1679 } 1581 1680 … … 1590 1689 { 1591 1690 mrb_value path; 1592 const char *name; 1593 mrb_sym classpath = mrb_intern_lit(mrb, "__classpath__"); 1594 1595 path = mrb_obj_iv_get(mrb, (struct RObject*)c, classpath); 1691 mrb_sym nsym = mrb_intern_lit(mrb, "__classname__"); 1692 1693 path = mrb_obj_iv_get(mrb, (struct RObject*)c, nsym); 1596 1694 if (mrb_nil_p(path)) { 1597 struct RClass *outer = mrb_class_outer_module(mrb, c); 1598 mrb_sym sym = mrb_class_sym(mrb, c, outer); 1599 mrb_int len; 1600 1601 if (sym == 0) { 1602 return mrb_nil_value(); 1603 } 1604 else if (outer && outer != c && outer != mrb->object_class) { 1605 mrb_value base = mrb_class_path(mrb, outer); 1606 path = mrb_str_buf_new(mrb, 0); 1607 if (mrb_nil_p(base)) { 1608 mrb_str_cat_lit(mrb, path, "#<Class:"); 1609 mrb_str_concat(mrb, path, mrb_ptr_to_str(mrb, outer)); 1610 mrb_str_cat_lit(mrb, path, ">"); 1611 } 1612 else { 1613 mrb_str_concat(mrb, path, base); 1614 } 1615 mrb_str_cat_lit(mrb, path, "::"); 1616 name = mrb_sym2name_len(mrb, sym, &len); 1617 mrb_str_cat(mrb, path, name, len); 1618 } 1619 else { 1620 name = mrb_sym2name_len(mrb, sym, &len); 1621 path = mrb_str_new(mrb, name, len); 1622 } 1623 if (!MRB_FROZEN_P(c)) { 1624 mrb_obj_iv_set(mrb, (struct RObject*)c, classpath, path); 1625 } 1695 /* no name (yet) */ 1696 return mrb_class_find_path(mrb, c); 1697 } 1698 else if (mrb_symbol_p(path)) { 1699 /* toplevel class/module */ 1700 return mrb_sym_str(mrb, mrb_symbol(path)); 1626 1701 } 1627 1702 return mrb_str_dup(mrb, path); 1628 1703 } 1629 1704 1630 MRB_API struct RClass 1705 MRB_API struct RClass* 1631 1706 mrb_class_real(struct RClass* cl) 1632 1707 { 1633 if (cl == 0) 1634 return NULL; 1708 if (cl == 0) return NULL; 1635 1709 while ((cl->tt == MRB_TT_SCLASS) || (cl->tt == MRB_TT_ICLASS)) { 1636 1710 cl = cl->super; 1711 if (cl == 0) return NULL; 1637 1712 } 1638 1713 return cl; … … 1642 1717 mrb_class_name(mrb_state *mrb, struct RClass* c) 1643 1718 { 1644 mrb_value path = mrb_class_path(mrb, c); 1645 if (mrb_nil_p(path)) { 1646 path = mrb_str_new_lit(mrb, "#<Class:"); 1647 mrb_str_concat(mrb, path, mrb_ptr_to_str(mrb, c)); 1648 mrb_str_cat_lit(mrb, path, ">"); 1649 } 1650 return RSTRING_PTR(path); 1719 mrb_value name = class_name_str(mrb, c); 1720 return RSTRING_PTR(name); 1651 1721 } 1652 1722 … … 1667 1737 { 1668 1738 if (super->tt != MRB_TT_CLASS) { 1669 mrb_raisef(mrb, E_TYPE_ERROR, "superclass must be a Class (% S given)", mrb_obj_value(super));1739 mrb_raisef(mrb, E_TYPE_ERROR, "superclass must be a Class (%C given)", super); 1670 1740 } 1671 1741 if (super->tt == MRB_TT_SCLASS) { … … 1734 1804 mrb_alias_method(mrb_state *mrb, struct RClass *c, mrb_sym a, mrb_sym b) 1735 1805 { 1736 struct RProc *m = mrb_method_search(mrb, c, b); 1737 1806 mrb_method_t m = mrb_method_search(mrb, c, b); 1807 1808 if (!MRB_METHOD_CFUNC_P(m)) { 1809 struct RProc *p = MRB_METHOD_PROC(m); 1810 1811 if (MRB_PROC_ENV_P(p)) { 1812 MRB_PROC_ENV(p)->mid = b; 1813 } 1814 else { 1815 struct RClass *tc = MRB_PROC_TARGET_CLASS(p); 1816 struct REnv *e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, NULL); 1817 1818 e->mid = b; 1819 if (tc) { 1820 e->c = tc; 1821 mrb_field_write_barrier(mrb, (struct RBasic*)e, (struct RBasic*)tc); 1822 } 1823 p->e.env = e; 1824 p->flags |= MRB_PROC_ENVSET; 1825 } 1826 } 1738 1827 mrb_define_method_raw(mrb, c, a, m); 1739 1828 } … … 1741 1830 /*! 1742 1831 * Defines an alias of a method. 1832 * \param mrb the mruby state 1743 1833 * \param klass the class which the original method belongs to 1744 1834 * \param name1 a new name for the method … … 1760 1850 */ 1761 1851 1762 staticmrb_value1852 mrb_value 1763 1853 mrb_mod_to_s(mrb_state *mrb, mrb_value klass) 1764 1854 { 1765 mrb_value str; 1766 1767 if (mrb_type(klass) == MRB_TT_SCLASS) { 1855 1856 if (mrb_sclass_p(klass)) { 1768 1857 mrb_value v = mrb_iv_get(mrb, klass, mrb_intern_lit(mrb, "__attached__")); 1769 1770 str = mrb_str_new_lit(mrb, "#<Class:"); 1858 mrb_value str = mrb_str_new_lit(mrb, "#<Class:"); 1771 1859 1772 1860 if (class_ptr_p(v)) { … … 1779 1867 } 1780 1868 else { 1781 struct RClass *c; 1782 mrb_value path; 1783 1784 str = mrb_str_buf_new(mrb, 32); 1785 c = mrb_class_ptr(klass); 1786 path = mrb_class_path(mrb, c); 1787 1788 if (mrb_nil_p(path)) { 1789 switch (mrb_type(klass)) { 1790 case MRB_TT_CLASS: 1791 mrb_str_cat_lit(mrb, str, "#<Class:"); 1792 break; 1793 1794 case MRB_TT_MODULE: 1795 mrb_str_cat_lit(mrb, str, "#<Module:"); 1796 break; 1797 1798 default: 1799 /* Shouldn't be happened? */ 1800 mrb_str_cat_lit(mrb, str, "#<??????:"); 1801 break; 1802 } 1803 mrb_str_concat(mrb, str, mrb_ptr_to_str(mrb, c)); 1804 return mrb_str_cat_lit(mrb, str, ">"); 1805 } 1806 else { 1807 return path; 1808 } 1869 return class_name_str(mrb, mrb_class_ptr(klass)); 1809 1870 } 1810 1871 } … … 1818 1879 mrb_get_args(mrb, "nn", &new_name, &old_name); 1819 1880 mrb_alias_method(mrb, c, new_name, old_name); 1820 return m rb_nil_value();1881 return mod; 1821 1882 } 1822 1883 … … 1824 1885 undef_method(mrb_state *mrb, struct RClass *c, mrb_sym a) 1825 1886 { 1887 mrb_method_t m; 1888 1889 MRB_METHOD_FROM_PROC(m, NULL); 1890 mrb_define_method_raw(mrb, c, a, m); 1891 } 1892 1893 void 1894 mrb_undef_method_id(mrb_state *mrb, struct RClass *c, mrb_sym a) 1895 { 1826 1896 if (!mrb_obj_respond_to(mrb, c, a)) { 1827 mrb_name_error(mrb, a, "undefined method '%S' for class '%S'", mrb_sym2str(mrb, a), mrb_obj_value(c)); 1828 } 1829 else { 1830 mrb_define_method_raw(mrb, c, a, NULL); 1831 } 1897 mrb_name_error(mrb, a, "undefined method '%n' for class '%C'", a, c); 1898 } 1899 undef_method(mrb, c, a); 1832 1900 } 1833 1901 … … 1853 1921 mrb_get_args(mrb, "*", &argv, &argc); 1854 1922 while (argc--) { 1855 undef_method(mrb, c, to_sym(mrb, *argv));1923 mrb_undef_method_id(mrb, c, to_sym(mrb, *argv)); 1856 1924 argv++; 1857 1925 } … … 1859 1927 } 1860 1928 1861 static mrb_value1862 mod_define_method(mrb_state *mrb, mrb_value self)1863 {1864 struct RClass *c = mrb_class_ptr(self);1865 struct RProc *p;1866 mrb_sym mid;1867 mrb_value proc = mrb_undef_value();1868 mrb_value blk;1869 1870 mrb_get_args(mrb, "n|o&", &mid, &proc, &blk);1871 switch (mrb_type(proc)) {1872 case MRB_TT_PROC:1873 blk = proc;1874 break;1875 case MRB_TT_UNDEF:1876 /* ignored */1877 break;1878 default:1879 mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %S (expected Proc)", mrb_obj_value(mrb_obj_class(mrb, proc)));1880 break;1881 }1882 if (mrb_nil_p(blk)) {1883 mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");1884 }1885 p = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class);1886 mrb_proc_copy(p, mrb_proc_ptr(blk));1887 p->flags |= MRB_PROC_STRICT;1888 mrb_define_method_raw(mrb, c, mid, p);1889 return mrb_symbol_value(mid);1890 }1891 1892 1929 static void 1893 check_cv_name_str(mrb_state *mrb, mrb_value str) 1894 { 1895 const char *s = RSTRING_PTR(str); 1896 mrb_int len = RSTRING_LEN(str); 1897 1898 if (len < 3 || !(s[0] == '@' && s[1] == '@')) { 1899 mrb_name_error(mrb, mrb_intern_str(mrb, str), "'%S' is not allowed as a class variable name", str); 1900 } 1901 } 1902 1903 static void 1904 check_cv_name_sym(mrb_state *mrb, mrb_sym id) 1905 { 1906 check_cv_name_str(mrb, mrb_sym2str(mrb, id)); 1907 } 1908 1909 /* 15.2.2.4.16 */ 1910 /* 1911 * call-seq: 1912 * obj.class_variable_defined?(symbol) -> true or false 1913 * 1914 * Returns <code>true</code> if the given class variable is defined 1915 * in <i>obj</i>. 1916 * 1917 * class Fred 1918 * @@foo = 99 1919 * end 1920 * Fred.class_variable_defined?(:@@foo) #=> true 1921 * Fred.class_variable_defined?(:@@bar) #=> false 1922 */ 1923 1924 static mrb_value 1925 mrb_mod_cvar_defined(mrb_state *mrb, mrb_value mod) 1930 check_const_name_sym(mrb_state *mrb, mrb_sym id) 1931 { 1932 mrb_int len; 1933 const char *name = mrb_sym_name_len(mrb, id, &len); 1934 if (!mrb_const_name_p(mrb, name, len)) { 1935 mrb_name_error(mrb, id, "wrong constant name %n", id); 1936 } 1937 } 1938 1939 static mrb_value 1940 mrb_mod_const_defined(mrb_state *mrb, mrb_value mod) 1926 1941 { 1927 1942 mrb_sym id; 1943 mrb_bool inherit = TRUE; 1944 1945 mrb_get_args(mrb, "n|b", &id, &inherit); 1946 check_const_name_sym(mrb, id); 1947 if (inherit) { 1948 return mrb_bool_value(mrb_const_defined(mrb, mod, id)); 1949 } 1950 return mrb_bool_value(mrb_const_defined_at(mrb, mod, id)); 1951 } 1952 1953 static mrb_value 1954 mrb_const_get_sym(mrb_state *mrb, mrb_value mod, mrb_sym id) 1955 { 1956 check_const_name_sym(mrb, id); 1957 return mrb_const_get(mrb, mod, id); 1958 } 1959 1960 static mrb_value 1961 mrb_mod_const_get(mrb_state *mrb, mrb_value mod) 1962 { 1963 mrb_value path; 1964 mrb_sym id; 1965 char *ptr; 1966 mrb_int off, end, len; 1967 1968 mrb_get_args(mrb, "o", &path); 1969 1970 if (mrb_symbol_p(path)) { 1971 /* const get with symbol */ 1972 id = mrb_symbol(path); 1973 return mrb_const_get_sym(mrb, mod, id); 1974 } 1975 1976 /* const get with class path string */ 1977 path = mrb_ensure_string_type(mrb, path); 1978 ptr = RSTRING_PTR(path); 1979 len = RSTRING_LEN(path); 1980 off = 0; 1981 1982 while (off < len) { 1983 end = mrb_str_index_lit(mrb, path, "::", off); 1984 end = (end == -1) ? len : end; 1985 id = mrb_intern(mrb, ptr+off, end-off); 1986 mod = mrb_const_get_sym(mrb, mod, id); 1987 if (end == len) 1988 off = end; 1989 else { 1990 off = end + 2; 1991 if (off == len) { /* trailing "::" */ 1992 mrb_name_error(mrb, id, "wrong constant name '%v'", path); 1993 } 1994 } 1995 } 1996 1997 return mod; 1998 } 1999 2000 static mrb_value 2001 mrb_mod_const_set(mrb_state *mrb, mrb_value mod) 2002 { 2003 mrb_sym id; 2004 mrb_value value; 2005 2006 mrb_get_args(mrb, "no", &id, &value); 2007 check_const_name_sym(mrb, id); 2008 mrb_const_set(mrb, mod, id, value); 2009 return value; 2010 } 2011 2012 static mrb_value 2013 mrb_mod_remove_const(mrb_state *mrb, mrb_value mod) 2014 { 2015 mrb_sym id; 2016 mrb_value val; 1928 2017 1929 2018 mrb_get_args(mrb, "n", &id); 1930 check_cv_name_sym(mrb, id); 1931 return mrb_bool_value(mrb_cv_defined(mrb, mod, id)); 1932 } 1933 1934 /* 15.2.2.4.17 */ 1935 /* 1936 * call-seq: 1937 * mod.class_variable_get(symbol) -> obj 1938 * 1939 * Returns the value of the given class variable (or throws a 1940 * <code>NameError</code> exception). The <code>@@</code> part of the 1941 * variable name should be included for regular class variables 1942 * 1943 * class Fred 1944 * @@foo = 99 1945 * end 1946 * Fred.class_variable_get(:@@foo) #=> 99 1947 */ 1948 1949 static mrb_value 1950 mrb_mod_cvar_get(mrb_state *mrb, mrb_value mod) 1951 { 1952 mrb_sym id; 1953 1954 mrb_get_args(mrb, "n", &id); 1955 check_cv_name_sym(mrb, id); 1956 return mrb_cv_get(mrb, mod, id); 1957 } 1958 1959 /* 15.2.2.4.18 */ 1960 /* 1961 * call-seq: 1962 * obj.class_variable_set(symbol, obj) -> obj 1963 * 1964 * Sets the class variable names by <i>symbol</i> to 1965 * <i>object</i>. 1966 * 1967 * class Fred 1968 * @@foo = 99 1969 * def foo 1970 * @@foo 1971 * end 1972 * end 1973 * Fred.class_variable_set(:@@foo, 101) #=> 101 1974 * Fred.new.foo #=> 101 1975 */ 1976 1977 static mrb_value 1978 mrb_mod_cvar_set(mrb_state *mrb, mrb_value mod) 1979 { 1980 mrb_value value; 1981 mrb_sym id; 1982 1983 mrb_get_args(mrb, "no", &id, &value); 1984 check_cv_name_sym(mrb, id); 1985 mrb_cv_set(mrb, mod, id, value); 1986 return value; 1987 } 1988 1989 /* 15.2.2.4.39 */ 1990 /* 1991 * call-seq: 1992 * remove_class_variable(sym) -> obj 1993 * 1994 * Removes the definition of the <i>sym</i>, returning that 1995 * constant's value. 1996 * 1997 * class Dummy 1998 * @@var = 99 1999 * puts @@var 2000 * p class_variables 2001 * remove_class_variable(:@@var) 2002 * p class_variables 2003 * end 2004 * 2005 * <em>produces:</em> 2006 * 2007 * 99 2008 * [:@@var] 2009 * [] 2010 */ 2011 2012 static mrb_value 2013 mrb_mod_remove_cvar(mrb_state *mrb, mrb_value mod) 2014 { 2015 mrb_value val; 2016 mrb_sym id; 2017 2018 mrb_get_args(mrb, "n", &id); 2019 check_cv_name_sym(mrb, id); 2020 2019 check_const_name_sym(mrb, id); 2021 2020 val = mrb_iv_remove(mrb, mod, id); 2022 if (!mrb_undef_p(val)) return val; 2023 2024 if (mrb_cv_defined(mrb, mod, id)) { 2025 mrb_name_error(mrb, id, "cannot remove %S for %S", 2026 mrb_sym2str(mrb, id), mod); 2027 } 2028 2029 mrb_name_error(mrb, id, "class variable %S not defined for %S", 2030 mrb_sym2str(mrb, id), mod); 2031 2032 /* not reached */ 2033 return mrb_nil_value(); 2021 if (mrb_undef_p(val)) { 2022 mrb_name_error(mrb, id, "constant %n not defined", id); 2023 } 2024 return val; 2025 } 2026 2027 static mrb_value 2028 mrb_mod_const_missing(mrb_state *mrb, mrb_value mod) 2029 { 2030 mrb_sym sym; 2031 2032 mrb_get_args(mrb, "n", &sym); 2033 2034 if (mrb_class_real(mrb_class_ptr(mod)) != mrb->object_class) { 2035 mrb_name_error(mrb, sym, "uninitialized constant %v::%n", mod, sym); 2036 } 2037 else { 2038 mrb_name_error(mrb, sym, "uninitialized constant %n", sym); 2039 } 2040 /* not reached */ 2041 return mrb_nil_value(); 2034 2042 } 2035 2043 … … 2070 2078 } 2071 2079 2072 static void 2073 remove_method(mrb_state *mrb, mrb_value mod, mrb_sym mid) 2074 { 2075 struct RClass *c = mrb_class_ptr(mod); 2076 khash_t(mt) *h = find_origin(c)->mt; 2077 khiter_t k; 2078 2079 if (h) { 2080 k = kh_get(mt, mrb, h, mid); 2081 if (k != kh_end(h)) { 2082 kh_del(mt, mrb, h, k); 2083 mrb_funcall(mrb, mod, "method_removed", 1, mrb_symbol_value(mid)); 2084 return; 2085 } 2086 } 2087 2088 mrb_name_error(mrb, mid, "method '%S' not defined in %S", 2089 mrb_sym2str(mrb, mid), mod); 2090 } 2091 2092 /* 15.2.2.4.41 */ 2093 /* 2094 * call-seq: 2095 * remove_method(symbol) -> self 2096 * 2097 * Removes the method identified by _symbol_ from the current 2098 * class. For an example, see <code>Module.undef_method</code>. 2099 */ 2100 2101 static mrb_value 2102 mrb_mod_remove_method(mrb_state *mrb, mrb_value mod) 2103 { 2104 mrb_int argc; 2105 mrb_value *argv; 2106 2107 mrb_get_args(mrb, "*", &argv, &argc); 2108 while (argc--) { 2109 remove_method(mrb, mod, to_sym(mrb, *argv)); 2110 argv++; 2111 } 2112 return mod; 2113 } 2114 2115 2116 2117 static void 2118 check_const_name_str(mrb_state *mrb, mrb_value str) 2119 { 2120 if (RSTRING_LEN(str) < 1 || !ISUPPER(*RSTRING_PTR(str))) { 2121 mrb_name_error(mrb, mrb_intern_str(mrb, str), "wrong constant name %S", str); 2122 } 2123 } 2124 2125 static void 2126 check_const_name_sym(mrb_state *mrb, mrb_sym id) 2127 { 2128 check_const_name_str(mrb, mrb_sym2str(mrb, id)); 2129 } 2130 2131 static mrb_value 2132 const_defined(mrb_state *mrb, mrb_value mod, mrb_sym id, mrb_bool inherit) 2133 { 2134 if (inherit) { 2135 return mrb_bool_value(mrb_const_defined(mrb, mod, id)); 2136 } 2137 return mrb_bool_value(mrb_const_defined_at(mrb, mod, id)); 2138 } 2139 2140 static mrb_value 2141 mrb_mod_const_defined(mrb_state *mrb, mrb_value mod) 2142 { 2143 mrb_sym id; 2144 mrb_bool inherit = TRUE; 2145 2146 mrb_get_args(mrb, "n|b", &id, &inherit); 2147 check_const_name_sym(mrb, id); 2148 return const_defined(mrb, mod, id, inherit); 2149 } 2150 2151 static mrb_value 2152 mrb_mod_const_get(mrb_state *mrb, mrb_value mod) 2153 { 2154 mrb_sym id; 2155 2156 mrb_get_args(mrb, "n", &id); 2157 check_const_name_sym(mrb, id); 2158 return mrb_const_get(mrb, mod, id); 2159 } 2160 2161 static mrb_value 2162 mrb_mod_const_set(mrb_state *mrb, mrb_value mod) 2163 { 2164 mrb_sym id; 2165 mrb_value value; 2166 2167 mrb_get_args(mrb, "no", &id, &value); 2168 check_const_name_sym(mrb, id); 2169 mrb_const_set(mrb, mod, id, value); 2170 return value; 2171 } 2172 2173 static mrb_value 2174 mrb_mod_remove_const(mrb_state *mrb, mrb_value mod) 2175 { 2176 mrb_sym id; 2177 mrb_value val; 2178 2179 mrb_get_args(mrb, "n", &id); 2180 check_const_name_sym(mrb, id); 2181 val = mrb_iv_remove(mrb, mod, id); 2182 if (mrb_undef_p(val)) { 2183 mrb_name_error(mrb, id, "constant %S not defined", mrb_sym2str(mrb, id)); 2184 } 2185 return val; 2186 } 2187 2188 static mrb_value 2189 mrb_mod_const_missing(mrb_state *mrb, mrb_value mod) 2190 { 2191 mrb_sym sym; 2192 2193 mrb_get_args(mrb, "n", &sym); 2194 2195 if (mrb_class_real(mrb_class_ptr(mod)) != mrb->object_class) { 2196 mrb_name_error(mrb, sym, "uninitialized constant %S::%S", 2197 mod, 2198 mrb_sym2str(mrb, sym)); 2199 } 2200 else { 2201 mrb_name_error(mrb, sym, "uninitialized constant %S", 2202 mrb_sym2str(mrb, sym)); 2203 } 2204 /* not reached */ 2205 return mrb_nil_value(); 2206 } 2207 2208 static mrb_value 2209 mrb_mod_s_constants(mrb_state *mrb, mrb_value mod) 2210 { 2211 mrb_raise(mrb, E_NOTIMP_ERROR, "Module.constants not implemented"); 2212 return mrb_nil_value(); /* not reached */ 2080 static mrb_value 2081 mod_define_method(mrb_state *mrb, mrb_value self) 2082 { 2083 struct RClass *c = mrb_class_ptr(self); 2084 struct RProc *p; 2085 mrb_method_t m; 2086 mrb_sym mid; 2087 mrb_value proc = mrb_undef_value(); 2088 mrb_value blk; 2089 2090 mrb_get_args(mrb, "n|o&", &mid, &proc, &blk); 2091 switch (mrb_type(proc)) { 2092 case MRB_TT_PROC: 2093 blk = proc; 2094 break; 2095 case MRB_TT_UNDEF: 2096 /* ignored */ 2097 break; 2098 default: 2099 mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %T (expected Proc)", proc); 2100 break; 2101 } 2102 if (mrb_nil_p(blk)) { 2103 mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given"); 2104 } 2105 p = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class); 2106 mrb_proc_copy(p, mrb_proc_ptr(blk)); 2107 p->flags |= MRB_PROC_STRICT; 2108 MRB_METHOD_FROM_PROC(m, p); 2109 mrb_define_method_raw(mrb, c, mid, m); 2110 return mrb_symbol_value(mid); 2111 } 2112 2113 static mrb_value 2114 top_define_method(mrb_state *mrb, mrb_value self) 2115 { 2116 return mod_define_method(mrb, mrb_obj_value(mrb->object_class)); 2213 2117 } 2214 2118 … … 2225 2129 } 2226 2130 2227 MRB_API mrb_value 2131 static mrb_value 2132 mrb_mod_dup(mrb_state *mrb, mrb_value self) 2133 { 2134 mrb_value mod = mrb_obj_clone(mrb, self); 2135 MRB_UNSET_FROZEN_FLAG(mrb_obj_ptr(mod)); 2136 return mod; 2137 } 2138 2139 static mrb_value 2228 2140 mrb_mod_module_function(mrb_state *mrb, mrb_value mod) 2229 2141 { … … 2231 2143 mrb_int argc, i; 2232 2144 mrb_sym mid; 2233 struct RProc *method_rproc;2145 mrb_method_t m; 2234 2146 struct RClass *rclass; 2235 2147 int ai; … … 2251 2163 mid = mrb_symbol(argv[i]); 2252 2164 rclass = mrb_class_ptr(mod); 2253 m ethod_rproc= mrb_method_search(mrb, rclass, mid);2165 m = mrb_method_search(mrb, rclass, mid); 2254 2166 2255 2167 prepare_singleton_class(mrb, (struct RBasic*)rclass); 2256 2168 ai = mrb_gc_arena_save(mrb); 2257 mrb_define_method_raw(mrb, rclass->c, mid, m ethod_rproc);2169 mrb_define_method_raw(mrb, rclass->c, mid, m); 2258 2170 mrb_gc_arena_restore(mrb, ai); 2259 2171 } … … 2266 2178 /* implementation of instance_eval */ 2267 2179 mrb_value mrb_obj_instance_eval(mrb_state*, mrb_value); 2180 2181 static mrb_value 2182 inspect_main(mrb_state *mrb, mrb_value mod) 2183 { 2184 return mrb_str_new_lit(mrb, "main"); 2185 } 2186 2187 static const mrb_code new_iseq[] = { 2188 OP_ENTER, 0x0, 0x10, 0x1, /* OP_ENTER 0:0:1:0:0:0:1 */ 2189 OP_LOADSELF, 0x3, /* OP_LOADSELF R3 */ 2190 OP_SEND, 0x3, 0x0, 0x0, /* OP_SEND R3 :allocate 0 */ 2191 OP_MOVE, 0x0, 0x3, /* OP_MOVE R0 R3 */ 2192 OP_MOVE, 0x4, 0x1, /* OP_MOVE R4 R1 */ 2193 OP_MOVE, 0x5, 0x2, /* OP_MOVE R5 R2 */ 2194 OP_SENDVB, 0x3, 0x1, /* OP_SENDVB R4 :initialize */ 2195 OP_RETURN, 0x0 /* OP_RETURN R0 */ 2196 }; 2197 2198 static void 2199 init_class_new(mrb_state *mrb, struct RClass *cls) 2200 { 2201 struct RProc *p; 2202 mrb_method_t m; 2203 mrb_irep *new_irep = (mrb_irep*)mrb_malloc(mrb, sizeof(mrb_irep)); 2204 static const mrb_irep mrb_irep_zero = { 0 }; 2205 2206 *new_irep = mrb_irep_zero; 2207 new_irep->syms = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym)*2); 2208 new_irep->syms[0] = mrb_intern_lit(mrb, "allocate"); 2209 new_irep->syms[1] = mrb_intern_lit(mrb, "initialize"); 2210 new_irep->slen = 2; 2211 new_irep->flags = MRB_ISEQ_NO_FREE; 2212 new_irep->iseq = new_iseq; 2213 new_irep->ilen = sizeof(new_iseq); 2214 new_irep->nregs = 6; 2215 new_irep->nlocals = 3; 2216 p = mrb_proc_new(mrb, new_irep); 2217 MRB_METHOD_FROM_PROC(m, p); 2218 mrb_define_method_raw(mrb, cls, mrb_intern_lit(mrb, "new"), m); 2219 } 2268 2220 2269 2221 void … … 2289 2241 /* name basic classes */ 2290 2242 mrb_define_const(mrb, bob, "BasicObject", mrb_obj_value(bob)); 2291 mrb_define_const(mrb, obj, "BasicObject", mrb_obj_value(bob));2292 2243 mrb_define_const(mrb, obj, "Object", mrb_obj_value(obj)); 2293 2244 mrb_define_const(mrb, obj, "Module", mrb_obj_value(mod)); … … 2295 2246 2296 2247 /* name each classes */ 2297 name_class(mrb, bob, mrb_intern_lit(mrb, "BasicObject"));2298 name_class(mrb, obj, mrb_intern_lit(mrb, "Object"));/* 15.2.1 */2299 name_class(mrb, mod, mrb_intern_lit(mrb, "Module"));/* 15.2.2 */2300 name_class(mrb, cls, mrb_intern_lit(mrb, "Class"));/* 15.2.3 */2248 mrb_class_name_class(mrb, NULL, bob, mrb_intern_lit(mrb, "BasicObject")); 2249 mrb_class_name_class(mrb, NULL, obj, mrb_intern_lit(mrb, "Object")); /* 15.2.1 */ 2250 mrb_class_name_class(mrb, NULL, mod, mrb_intern_lit(mrb, "Module")); /* 15.2.2 */ 2251 mrb_class_name_class(mrb, NULL, cls, mrb_intern_lit(mrb, "Class")); /* 15.2.3 */ 2301 2252 2302 2253 mrb->proc_class = mrb_define_class(mrb, "Proc", mrb->object_class); /* 15.2.17 */ … … 2308 2259 mrb_define_method(mrb, bob, "==", mrb_obj_equal_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.1 */ 2309 2260 mrb_define_method(mrb, bob, "!=", mrb_obj_not_equal_m, MRB_ARGS_REQ(1)); 2310 mrb_define_method(mrb, bob, "__id__", mrb_obj_id_m, MRB_ARGS_NONE()); /* 15.3.1.3.3 */ 2311 mrb_define_method(mrb, bob, "__send__", mrb_f_send, MRB_ARGS_ANY()); /* 15.3.1.3.4 */ 2312 mrb_define_method(mrb, bob, "instance_eval", mrb_obj_instance_eval, MRB_ARGS_ANY()); /* 15.3.1.3.18 */ 2313 2314 mrb_define_class_method(mrb, cls, "new", mrb_class_new_class, MRB_ARGS_OPT(1)); 2261 mrb_define_method(mrb, bob, "__id__", mrb_obj_id_m, MRB_ARGS_NONE()); /* 15.3.1.3.4 */ 2262 mrb_define_method(mrb, bob, "__send__", mrb_f_send, MRB_ARGS_REQ(1)|MRB_ARGS_REST()|MRB_ARGS_BLOCK()); /* 15.3.1.3.5 */ 2263 mrb_define_method(mrb, bob, "equal?", mrb_obj_equal_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.11 */ 2264 mrb_define_method(mrb, bob, "instance_eval", mrb_obj_instance_eval, MRB_ARGS_OPT(1)|MRB_ARGS_BLOCK()); /* 15.3.1.3.18 */ 2265 2266 mrb_define_class_method(mrb, cls, "new", mrb_class_new_class, MRB_ARGS_OPT(1)|MRB_ARGS_BLOCK()); 2267 mrb_define_method(mrb, cls, "allocate", mrb_instance_alloc, MRB_ARGS_NONE()); 2315 2268 mrb_define_method(mrb, cls, "superclass", mrb_class_superclass, MRB_ARGS_NONE()); /* 15.2.3.3.4 */ 2316 mrb_define_method(mrb, cls, "new", mrb_instance_new, MRB_ARGS_ANY()); /* 15.2.3.3.3 */2317 2269 mrb_define_method(mrb, cls, "initialize", mrb_class_initialize, MRB_ARGS_OPT(1)); /* 15.2.3.3.1 */ 2318 2270 mrb_define_method(mrb, cls, "inherited", mrb_bob_init, MRB_ARGS_REQ(1)); 2319 2271 2272 init_class_new(mrb, cls); 2273 2320 2274 MRB_SET_INSTANCE_TT(mod, MRB_TT_MODULE); 2321 mrb_define_method(mrb, mod, "class_variable_defined?", mrb_mod_cvar_defined, MRB_ARGS_REQ(1)); /* 15.2.2.4.16 */2322 mrb_define_method(mrb, mod, "class_variable_get", mrb_mod_cvar_get, MRB_ARGS_REQ(1)); /* 15.2.2.4.17 */2323 mrb_define_method(mrb, mod, "class_variable_set", mrb_mod_cvar_set, MRB_ARGS_REQ(2)); /* 15.2.2.4.18 */2324 2275 mrb_define_method(mrb, mod, "extend_object", mrb_mod_extend_object, MRB_ARGS_REQ(1)); /* 15.2.2.4.25 */ 2325 2276 mrb_define_method(mrb, mod, "extended", mrb_bob_init, MRB_ARGS_REQ(1)); /* 15.2.2.4.26 */ … … 2330 2281 mrb_define_method(mrb, mod, "class_eval", mrb_mod_module_eval, MRB_ARGS_ANY()); /* 15.2.2.4.15 */ 2331 2282 mrb_define_method(mrb, mod, "included", mrb_bob_init, MRB_ARGS_REQ(1)); /* 15.2.2.4.29 */ 2332 mrb_define_method(mrb, mod, "included_modules", mrb_mod_included_modules, MRB_ARGS_NONE()); /* 15.2.2.4.30 */2333 2283 mrb_define_method(mrb, mod, "initialize", mrb_mod_initialize, MRB_ARGS_NONE()); /* 15.2.2.4.31 */ 2334 mrb_define_method(mrb, mod, "instance_methods", mrb_mod_instance_methods, MRB_ARGS_ANY()); /* 15.2.2.4.33 */2335 mrb_define_method(mrb, mod, "method_defined?", mrb_mod_method_defined, MRB_ARGS_REQ(1)); /* 15.2.2.4.34 */2336 2284 mrb_define_method(mrb, mod, "module_eval", mrb_mod_module_eval, MRB_ARGS_ANY()); /* 15.2.2.4.35 */ 2337 2285 mrb_define_method(mrb, mod, "module_function", mrb_mod_module_function, MRB_ARGS_ANY()); … … 2339 2287 mrb_define_method(mrb, mod, "protected", mrb_mod_dummy_visibility, MRB_ARGS_ANY()); /* 15.2.2.4.37 */ 2340 2288 mrb_define_method(mrb, mod, "public", mrb_mod_dummy_visibility, MRB_ARGS_ANY()); /* 15.2.2.4.38 */ 2341 mrb_define_method(mrb, mod, "remove_class_variable", mrb_mod_remove_cvar, MRB_ARGS_REQ(1)); /* 15.2.2.4.39 */2342 mrb_define_method(mrb, mod, "remove_method", mrb_mod_remove_method, MRB_ARGS_ANY()); /* 15.2.2.4.41 */2343 mrb_define_method(mrb, mod, "method_removed", mrb_bob_init, MRB_ARGS_REQ(1));2344 2289 mrb_define_method(mrb, mod, "attr_reader", mrb_mod_attr_reader, MRB_ARGS_ANY()); /* 15.2.2.4.13 */ 2345 2290 mrb_define_method(mrb, mod, "attr_writer", mrb_mod_attr_writer, MRB_ARGS_ANY()); /* 15.2.2.4.14 */ … … 2352 2297 mrb_define_method(mrb, mod, "const_get", mrb_mod_const_get, MRB_ARGS_REQ(1)); /* 15.2.2.4.21 */ 2353 2298 mrb_define_method(mrb, mod, "const_set", mrb_mod_const_set, MRB_ARGS_REQ(2)); /* 15.2.2.4.23 */ 2354 mrb_define_method(mrb, mod, "constants", mrb_mod_constants, MRB_ARGS_OPT(1)); /* 15.2.2.4.24 */2355 2299 mrb_define_method(mrb, mod, "remove_const", mrb_mod_remove_const, MRB_ARGS_REQ(1)); /* 15.2.2.4.40 */ 2356 2300 mrb_define_method(mrb, mod, "const_missing", mrb_mod_const_missing, MRB_ARGS_REQ(1)); 2301 mrb_define_method(mrb, mod, "method_defined?", mrb_mod_method_defined, MRB_ARGS_REQ(1)); /* 15.2.2.4.34 */ 2357 2302 mrb_define_method(mrb, mod, "define_method", mod_define_method, MRB_ARGS_ARG(1,1)); 2358 mrb_define_method(mrb, mod, "class_variables", mrb_mod_class_variables, MRB_ARGS_NONE()); /* 15.2.2.4.19 */ 2359 mrb_define_method(mrb, mod, "===", mrb_mod_eqq, MRB_ARGS_REQ(1)); 2360 mrb_define_class_method(mrb, mod, "constants", mrb_mod_s_constants, MRB_ARGS_ANY()); /* 15.2.2.3.1 */ 2303 mrb_define_method(mrb, mod, "===", mrb_mod_eqq, MRB_ARGS_REQ(1)); /* 15.2.2.4.7 */ 2304 mrb_define_method(mrb, mod, "dup", mrb_mod_dup, MRB_ARGS_NONE()); 2361 2305 2362 2306 mrb_undef_method(mrb, cls, "append_features"); 2307 mrb_undef_method(mrb, cls, "prepend_features"); 2363 2308 mrb_undef_method(mrb, cls, "extend_object"); 2364 } 2309 mrb_undef_method(mrb, cls, "module_function"); 2310 2311 mrb->top_self = (struct RObject*)mrb_obj_alloc(mrb, MRB_TT_OBJECT, mrb->object_class); 2312 mrb_define_singleton_method(mrb, mrb->top_self, "inspect", inspect_main, MRB_ARGS_NONE()); 2313 mrb_define_singleton_method(mrb, mrb->top_self, "to_s", inspect_main, MRB_ARGS_NONE()); 2314 mrb_define_singleton_method(mrb, mrb->top_self, "define_method", top_define_method, MRB_ARGS_ARG(1,1)); 2315 } -
EcnlProtoTool/trunk/mruby-2.1.1/src/codedump.c
r331 r439 7 7 8 8 #ifndef MRB_DISABLE_STDIO 9 static int10 print_r(mrb_state *mrb, mrb_irep *irep, size_t n , int pre)9 static void 10 print_r(mrb_state *mrb, mrb_irep *irep, size_t n) 11 11 { 12 12 size_t i; 13 13 14 if (n == 0) return 0;14 if (n == 0) return; 15 15 16 16 for (i=0; i+1<irep->nlocals; i++) { 17 17 if (irep->lv[i].r == n) { 18 18 mrb_sym sym = irep->lv[i].name; 19 if (pre) printf(" "); 20 printf("R%d:%s", (int)n, mrb_sym2name(mrb, sym)); 21 return 1; 19 printf(" R%d:%s", (int)n, mrb_sym_dump(mrb, sym)); 20 break; 22 21 } 23 22 } 24 return 0; 25 } 26 27 #define RA 1 28 #define RB 2 29 #define RAB 3 23 } 30 24 31 25 static void 32 print_lv(mrb_state *mrb, mrb_irep *irep, mrb_code c, int r) 33 { 34 int pre = 0; 35 36 if (!irep->lv 37 || ((!(r & RA) || GETARG_A(c) >= irep->nlocals) 38 && (!(r & RB) || GETARG_B(c) >= irep->nlocals))) { 26 print_lv_a(mrb_state *mrb, mrb_irep *irep, uint16_t a) 27 { 28 if (!irep->lv || a >= irep->nlocals || a == 0) { 39 29 printf("\n"); 40 30 return; 41 31 } 42 printf("\t; "); 43 if (r & RA) { 44 pre = print_r(mrb, irep, GETARG_A(c), 0); 45 } 46 if (r & RB) { 47 print_r(mrb, irep, GETARG_B(c), pre); 48 } 32 printf("\t;"); 33 print_r(mrb, irep, a); 49 34 printf("\n"); 50 35 } 51 #endif 36 37 static void 38 print_lv_ab(mrb_state *mrb, mrb_irep *irep, uint16_t a, uint16_t b) 39 { 40 if (!irep->lv || (a >= irep->nlocals && b >= irep->nlocals) || a+b == 0) { 41 printf("\n"); 42 return; 43 } 44 printf("\t;"); 45 if (a > 0) print_r(mrb, irep, a); 46 if (b > 0) print_r(mrb, irep, b); 47 printf("\n"); 48 } 49 50 static void 51 print_header(mrb_state *mrb, mrb_irep *irep, ptrdiff_t i) 52 { 53 int32_t line; 54 55 line = mrb_debug_get_line(mrb, irep, i); 56 if (line < 0) { 57 printf(" "); 58 } 59 else { 60 printf("%5d ", line); 61 } 62 63 printf("%03d ", (int)i); 64 } 65 66 #define CASE(insn,ops) case insn: FETCH_ ## ops (); L_ ## insn 52 67 53 68 static void 54 69 codedump(mrb_state *mrb, mrb_irep *irep) 55 70 { 56 #ifndef MRB_DISABLE_STDIO57 int i;58 71 int ai; 59 mrb_code c; 72 const mrb_code *pc, *pcend; 73 mrb_code ins; 60 74 const char *file = NULL, *next_file; 61 int32_t line;62 75 63 76 if (!irep) return; 64 printf("irep %p nregs=%d nlocals=%d pools=%d syms=%d reps=%d\n", (void*)irep, 65 irep->nregs, irep->nlocals, (int)irep->plen, (int)irep->slen, (int)irep->rlen); 66 67 for (i = 0; i < (int)irep->ilen; i++) { 77 printf("irep %p nregs=%d nlocals=%d pools=%d syms=%d reps=%d iseq=%d\n", (void*)irep, 78 irep->nregs, irep->nlocals, (int)irep->plen, (int)irep->slen, (int)irep->rlen, (int)irep->ilen); 79 80 if (irep->lv) { 81 int i; 82 83 printf("local variable names:\n"); 84 for (i = 1; i < irep->nlocals; ++i) { 85 char const *s = mrb_sym_dump(mrb, irep->lv[i - 1].name); 86 int n = irep->lv[i - 1].r ? irep->lv[i - 1].r : i; 87 printf(" R%d:%s\n", n, s ? s : ""); 88 } 89 } 90 91 pc = irep->iseq; 92 pcend = pc + irep->ilen; 93 while (pc < pcend) { 94 ptrdiff_t i; 95 uint32_t a; 96 uint16_t b; 97 uint8_t c; 98 68 99 ai = mrb_gc_arena_save(mrb); 69 100 70 next_file = mrb_debug_get_filename(irep, i); 101 i = pc - irep->iseq; 102 next_file = mrb_debug_get_filename(mrb, irep, i); 71 103 if (next_file && file != next_file) { 72 104 printf("file: %s\n", next_file); 73 105 file = next_file; 74 106 } 75 line = mrb_debug_get_line(irep, i); 76 if (line < 0) { 77 printf(" "); 78 } 79 else { 80 printf("%5d ", line); 81 } 82 83 printf("%03d ", i); 84 c = irep->iseq[i]; 85 switch (GET_OPCODE(c)) { 86 case OP_NOP: 107 print_header(mrb, irep, i); 108 ins = READ_B(); 109 switch (ins) { 110 CASE(OP_NOP, Z): 87 111 printf("OP_NOP\n"); 88 112 break; 89 case OP_MOVE:90 printf("OP_MOVE\tR%d\tR%d\t", GETARG_A(c), GETARG_B(c));91 print_lv (mrb, irep, c, RAB);92 break; 93 case OP_LOADL:113 CASE(OP_MOVE, BB): 114 printf("OP_MOVE\tR%d\tR%d\t", a, b); 115 print_lv_ab(mrb, irep, a, b); 116 break; 117 CASE(OP_LOADL, BB): 94 118 { 95 mrb_value v = irep->pool[ GETARG_Bx(c)];119 mrb_value v = irep->pool[b]; 96 120 mrb_value s = mrb_inspect(mrb, v); 97 printf("OP_LOADL\tR%d\tL(%d)\t; %s", GETARG_A(c), GETARG_Bx(c), RSTRING_PTR(s));121 printf("OP_LOADL\tR%d\tL(%d)\t; %s", a, b, RSTRING_PTR(s)); 98 122 } 99 print_lv(mrb, irep, c, RA); 100 break; 101 case OP_LOADI: 102 printf("OP_LOADI\tR%d\t%d\t", GETARG_A(c), GETARG_sBx(c)); 103 print_lv(mrb, irep, c, RA); 104 break; 105 case OP_LOADSYM: 106 printf("OP_LOADSYM\tR%d\t:%s", GETARG_A(c), 107 mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)])); 108 print_lv(mrb, irep, c, RA); 109 break; 110 case OP_LOADNIL: 111 printf("OP_LOADNIL\tR%d\t\t", GETARG_A(c)); 112 print_lv(mrb, irep, c, RA); 113 break; 114 case OP_LOADSELF: 115 printf("OP_LOADSELF\tR%d\t\t", GETARG_A(c)); 116 print_lv(mrb, irep, c, RA); 117 break; 118 case OP_LOADT: 119 printf("OP_LOADT\tR%d\t\t", GETARG_A(c)); 120 print_lv(mrb, irep, c, RA); 121 break; 122 case OP_LOADF: 123 printf("OP_LOADF\tR%d\t\t", GETARG_A(c)); 124 print_lv(mrb, irep, c, RA); 125 break; 126 case OP_GETGLOBAL: 127 printf("OP_GETGLOBAL\tR%d\t:%s", GETARG_A(c), 128 mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)])); 129 print_lv(mrb, irep, c, RA); 130 break; 131 case OP_SETGLOBAL: 132 printf("OP_SETGLOBAL\t:%s\tR%d\t", 133 mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]), 134 GETARG_A(c)); 135 print_lv(mrb, irep, c, RA); 136 break; 137 case OP_GETCONST: 138 printf("OP_GETCONST\tR%d\t:%s", GETARG_A(c), 139 mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)])); 140 print_lv(mrb, irep, c, RA); 141 break; 142 case OP_SETCONST: 143 printf("OP_SETCONST\t:%s\tR%d\t", 144 mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]), 145 GETARG_A(c)); 146 print_lv(mrb, irep, c, RA); 147 break; 148 case OP_GETMCNST: 149 printf("OP_GETMCNST\tR%d\tR%d::%s", GETARG_A(c), GETARG_A(c), 150 mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)])); 151 print_lv(mrb, irep, c, RAB); 152 break; 153 case OP_SETMCNST: 154 printf("OP_SETMCNST\tR%d::%s\tR%d", GETARG_A(c)+1, 155 mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]), 156 GETARG_A(c)); 157 print_lv(mrb, irep, c, RA); 158 break; 159 case OP_GETIV: 160 printf("OP_GETIV\tR%d\t%s", GETARG_A(c), 161 mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)])); 162 print_lv(mrb, irep, c, RA); 163 break; 164 case OP_SETIV: 165 printf("OP_SETIV\t%s\tR%d", 166 mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]), 167 GETARG_A(c)); 168 print_lv(mrb, irep, c, RA); 169 break; 170 case OP_GETUPVAR: 171 printf("OP_GETUPVAR\tR%d\t%d\t%d", 172 GETARG_A(c), GETARG_B(c), GETARG_C(c)); 173 print_lv(mrb, irep, c, RA); 174 break; 175 case OP_SETUPVAR: 176 printf("OP_SETUPVAR\tR%d\t%d\t%d", 177 GETARG_A(c), GETARG_B(c), GETARG_C(c)); 178 print_lv(mrb, irep, c, RA); 179 break; 180 case OP_GETCV: 181 printf("OP_GETCV\tR%d\t%s", GETARG_A(c), 182 mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)])); 183 print_lv(mrb, irep, c, RA); 184 break; 185 case OP_SETCV: 186 printf("OP_SETCV\t%s\tR%d", 187 mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]), 188 GETARG_A(c)); 189 print_lv(mrb, irep, c, RA); 190 break; 191 case OP_JMP: 192 printf("OP_JMP\t%03d\n", i+GETARG_sBx(c)); 193 break; 194 case OP_JMPIF: 195 printf("OP_JMPIF\tR%d\t%03d\n", GETARG_A(c), i+GETARG_sBx(c)); 196 break; 197 case OP_JMPNOT: 198 printf("OP_JMPNOT\tR%d\t%03d\n", GETARG_A(c), i+GETARG_sBx(c)); 199 break; 200 case OP_SEND: 201 printf("OP_SEND\tR%d\t:%s\t%d\n", GETARG_A(c), 202 mrb_sym2name(mrb, irep->syms[GETARG_B(c)]), 203 GETARG_C(c)); 204 break; 205 case OP_SENDB: 206 printf("OP_SENDB\tR%d\t:%s\t%d\n", GETARG_A(c), 207 mrb_sym2name(mrb, irep->syms[GETARG_B(c)]), 208 GETARG_C(c)); 209 break; 210 case OP_TAILCALL: 211 printf("OP_TAILCALL\tR%d\t:%s\t%d\n", GETARG_A(c), 212 mrb_sym2name(mrb, irep->syms[GETARG_B(c)]), 213 GETARG_C(c)); 214 break; 215 case OP_SUPER: 216 printf("OP_SUPER\tR%d\t%d\n", GETARG_A(c), 217 GETARG_C(c)); 218 break; 219 case OP_ARGARY: 220 printf("OP_ARGARY\tR%d\t%d:%d:%d:%d", GETARG_A(c), 221 (GETARG_Bx(c)>>10)&0x3f, 222 (GETARG_Bx(c)>>9)&0x1, 223 (GETARG_Bx(c)>>4)&0x1f, 224 (GETARG_Bx(c)>>0)&0xf); 225 print_lv(mrb, irep, c, RA); 226 break; 227 228 case OP_ENTER: 123 print_lv_a(mrb, irep, a); 124 break; 125 CASE(OP_LOADI, BB): 126 printf("OP_LOADI\tR%d\t%d\t", a, b); 127 print_lv_a(mrb, irep, a); 128 break; 129 CASE(OP_LOADINEG, BB): 130 printf("OP_LOADI\tR%d\t-%d\t", a, b); 131 print_lv_a(mrb, irep, a); 132 break; 133 CASE(OP_LOADI__1, B): 134 printf("OP_LOADI__1\tR%d\t\t", a); 135 print_lv_a(mrb, irep, a); 136 break; 137 CASE(OP_LOADI_0, B): goto L_LOADI; 138 CASE(OP_LOADI_1, B): goto L_LOADI; 139 CASE(OP_LOADI_2, B): goto L_LOADI; 140 CASE(OP_LOADI_3, B): goto L_LOADI; 141 CASE(OP_LOADI_4, B): goto L_LOADI; 142 CASE(OP_LOADI_5, B): goto L_LOADI; 143 CASE(OP_LOADI_6, B): goto L_LOADI; 144 CASE(OP_LOADI_7, B): 145 L_LOADI: 146 printf("OP_LOADI_%d\tR%d\t\t", ins-(int)OP_LOADI_0, a); 147 print_lv_a(mrb, irep, a); 148 break; 149 CASE(OP_LOADSYM, BB): 150 printf("OP_LOADSYM\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b])); 151 print_lv_a(mrb, irep, a); 152 break; 153 CASE(OP_LOADNIL, B): 154 printf("OP_LOADNIL\tR%d\t\t", a); 155 print_lv_a(mrb, irep, a); 156 break; 157 CASE(OP_LOADSELF, B): 158 printf("OP_LOADSELF\tR%d\t\t", a); 159 print_lv_a(mrb, irep, a); 160 break; 161 CASE(OP_LOADT, B): 162 printf("OP_LOADT\tR%d\t\t", a); 163 print_lv_a(mrb, irep, a); 164 break; 165 CASE(OP_LOADF, B): 166 printf("OP_LOADF\tR%d\t\t", a); 167 print_lv_a(mrb, irep, a); 168 break; 169 CASE(OP_GETGV, BB): 170 printf("OP_GETGV\tR%d\t:%s", a, mrb_sym_dump(mrb, irep->syms[b])); 171 print_lv_a(mrb, irep, a); 172 break; 173 CASE(OP_SETGV, BB): 174 printf("OP_SETGV\t:%s\tR%d", mrb_sym_dump(mrb, irep->syms[b]), a); 175 print_lv_a(mrb, irep, a); 176 break; 177 CASE(OP_GETSV, BB): 178 printf("OP_GETSV\tR%d\t:%s", a, mrb_sym_dump(mrb, irep->syms[b])); 179 print_lv_a(mrb, irep, a); 180 break; 181 CASE(OP_SETSV, BB): 182 printf("OP_SETSV\t:%s\tR%d", mrb_sym_dump(mrb, irep->syms[b]), a); 183 print_lv_a(mrb, irep, a); 184 break; 185 CASE(OP_GETCONST, BB): 186 printf("OP_GETCONST\tR%d\t:%s", a, mrb_sym_dump(mrb, irep->syms[b])); 187 print_lv_a(mrb, irep, a); 188 break; 189 CASE(OP_SETCONST, BB): 190 printf("OP_SETCONST\t:%s\tR%d", mrb_sym_dump(mrb, irep->syms[b]), a); 191 print_lv_a(mrb, irep, a); 192 break; 193 CASE(OP_GETMCNST, BB): 194 printf("OP_GETMCNST\tR%d\tR%d::%s", a, a, mrb_sym_dump(mrb, irep->syms[b])); 195 print_lv_a(mrb, irep, a); 196 break; 197 CASE(OP_SETMCNST, BB): 198 printf("OP_SETMCNST\tR%d::%s\tR%d", a+1, mrb_sym_dump(mrb, irep->syms[b]), a); 199 print_lv_a(mrb, irep, a); 200 break; 201 CASE(OP_GETIV, BB): 202 printf("OP_GETIV\tR%d\t%s", a, mrb_sym_dump(mrb, irep->syms[b])); 203 print_lv_a(mrb, irep, a); 204 break; 205 CASE(OP_SETIV, BB): 206 printf("OP_SETIV\t%s\tR%d", mrb_sym_dump(mrb, irep->syms[b]), a); 207 print_lv_a(mrb, irep, a); 208 break; 209 CASE(OP_GETUPVAR, BBB): 210 printf("OP_GETUPVAR\tR%d\t%d\t%d", a, b, c); 211 print_lv_a(mrb, irep, a); 212 break; 213 CASE(OP_SETUPVAR, BBB): 214 printf("OP_SETUPVAR\tR%d\t%d\t%d", a, b, c); 215 print_lv_a(mrb, irep, a); 216 break; 217 CASE(OP_GETCV, BB): 218 printf("OP_GETCV\tR%d\t%s", a, mrb_sym_dump(mrb, irep->syms[b])); 219 print_lv_a(mrb, irep, a); 220 break; 221 CASE(OP_SETCV, BB): 222 printf("OP_SETCV\t%s\tR%d", mrb_sym_dump(mrb, irep->syms[b]), a); 223 print_lv_a(mrb, irep, a); 224 break; 225 CASE(OP_JMP, S): 226 printf("OP_JMP\t\t%03d\n", a); 227 break; 228 CASE(OP_JMPIF, BS): 229 printf("OP_JMPIF\tR%d\t%03d\t", a, b); 230 print_lv_a(mrb, irep, a); 231 break; 232 CASE(OP_JMPNOT, BS): 233 printf("OP_JMPNOT\tR%d\t%03d\t", a, b); 234 print_lv_a(mrb, irep, a); 235 break; 236 CASE(OP_JMPNIL, BS): 237 printf("OP_JMPNIL\tR%d\t%03d\t", a, b); 238 print_lv_a(mrb, irep, a); 239 break; 240 CASE(OP_SENDV, BB): 241 printf("OP_SENDV\tR%d\t:%s\n", a, mrb_sym_dump(mrb, irep->syms[b])); 242 break; 243 CASE(OP_SENDVB, BB): 244 printf("OP_SENDVB\tR%d\t:%s\n", a, mrb_sym_dump(mrb, irep->syms[b])); 245 break; 246 CASE(OP_SEND, BBB): 247 printf("OP_SEND\tR%d\t:%s\t%d\n", a, mrb_sym_dump(mrb, irep->syms[b]), c); 248 break; 249 CASE(OP_SENDB, BBB): 250 printf("OP_SENDB\tR%d\t:%s\t%d\n", a, mrb_sym_dump(mrb, irep->syms[b]), c); 251 break; 252 CASE(OP_CALL, Z): 253 printf("OP_CALL\n"); 254 break; 255 CASE(OP_SUPER, BB): 256 printf("OP_SUPER\tR%d\t%d\n", a, b); 257 break; 258 CASE(OP_ARGARY, BS): 259 printf("OP_ARGARY\tR%d\t%d:%d:%d:%d (%d)", a, 260 (b>>11)&0x3f, 261 (b>>10)&0x1, 262 (b>>5)&0x1f, 263 (b>>4)&0x1, 264 (b>>0)&0xf); 265 print_lv_a(mrb, irep, a); 266 break; 267 CASE(OP_ENTER, W): 229 268 printf("OP_ENTER\t%d:%d:%d:%d:%d:%d:%d\n", 230 (GETARG_Ax(c)>>18)&0x1f, 231 (GETARG_Ax(c)>>13)&0x1f, 232 (GETARG_Ax(c)>>12)&0x1, 233 (GETARG_Ax(c)>>7)&0x1f, 234 (GETARG_Ax(c)>>2)&0x1f, 235 (GETARG_Ax(c)>>1)&0x1, 236 GETARG_Ax(c) & 0x1); 237 break; 238 case OP_RETURN: 239 printf("OP_RETURN\tR%d", GETARG_A(c)); 240 switch (GETARG_B(c)) { 241 case OP_R_NORMAL: 242 printf("\tnormal\t"); break; 243 case OP_R_RETURN: 244 printf("\treturn\t"); break; 245 case OP_R_BREAK: 246 printf("\tbreak\t"); break; 247 default: 248 printf("\tbroken\t"); break; 269 MRB_ASPEC_REQ(a), 270 MRB_ASPEC_OPT(a), 271 MRB_ASPEC_REST(a), 272 MRB_ASPEC_POST(a), 273 MRB_ASPEC_KEY(a), 274 MRB_ASPEC_KDICT(a), 275 MRB_ASPEC_BLOCK(a)); 276 break; 277 CASE(OP_KEY_P, BB): 278 printf("OP_KEY_P\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b])); 279 print_lv_a(mrb, irep, a); 280 break; 281 CASE(OP_KEYEND, Z): 282 printf("OP_KEYEND\n"); 283 break; 284 CASE(OP_KARG, BB): 285 printf("OP_KARG\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b])); 286 print_lv_a(mrb, irep, a); 287 break; 288 CASE(OP_RETURN, B): 289 printf("OP_RETURN\tR%d\t\t", a); 290 print_lv_a(mrb, irep, a); 291 break; 292 CASE(OP_RETURN_BLK, B): 293 printf("OP_RETURN_BLK\tR%d\t\t", a); 294 print_lv_a(mrb, irep, a); 295 break; 296 CASE(OP_BREAK, B): 297 printf("OP_BREAK\tR%d\t\t", a); 298 print_lv_a(mrb, irep, a); 299 break; 300 CASE(OP_BLKPUSH, BS): 301 printf("OP_BLKPUSH\tR%d\t%d:%d:%d:%d (%d)", a, 302 (b>>11)&0x3f, 303 (b>>10)&0x1, 304 (b>>5)&0x1f, 305 (b>>4)&0x1, 306 (b>>0)&0xf); 307 print_lv_a(mrb, irep, a); 308 break; 309 CASE(OP_LAMBDA, BB): 310 printf("OP_LAMBDA\tR%d\tI(%d:%p)\n", a, b, irep->reps[b]); 311 break; 312 CASE(OP_BLOCK, BB): 313 printf("OP_BLOCK\tR%d\tI(%d:%p)\n", a, b, irep->reps[b]); 314 break; 315 CASE(OP_METHOD, BB): 316 printf("OP_METHOD\tR%d\tI(%d:%p)\n", a, b, irep->reps[b]); 317 break; 318 CASE(OP_RANGE_INC, B): 319 printf("OP_RANGE_INC\tR%d\n", a); 320 break; 321 CASE(OP_RANGE_EXC, B): 322 printf("OP_RANGE_EXC\tR%d\n", a); 323 break; 324 CASE(OP_DEF, BB): 325 printf("OP_DEF\tR%d\t:%s\n", a, mrb_sym_dump(mrb, irep->syms[b])); 326 break; 327 CASE(OP_UNDEF, B): 328 printf("OP_UNDEF\t:%s\n", mrb_sym_dump(mrb, irep->syms[a])); 329 break; 330 CASE(OP_ALIAS, BB): 331 printf("OP_ALIAS\t:%s\t%s\n", mrb_sym_dump(mrb, irep->syms[a]), mrb_sym_dump(mrb, irep->syms[b])); 332 break; 333 CASE(OP_ADD, B): 334 printf("OP_ADD\tR%d\t\n", a); 335 break; 336 CASE(OP_ADDI, BB): 337 printf("OP_ADDI\tR%d\t%d\n", a, b); 338 break; 339 CASE(OP_SUB, B): 340 printf("OP_SUB\tR%d\t\n", a); 341 break; 342 CASE(OP_SUBI, BB): 343 printf("OP_SUBI\tR%d\t%d\n", a, b); 344 break; 345 CASE(OP_MUL, B): 346 printf("OP_MUL\tR%d\t\n", a); 347 break; 348 CASE(OP_DIV, B): 349 printf("OP_DIV\tR%d\t\n", a); 350 break; 351 CASE(OP_LT, B): 352 printf("OP_LT\t\tR%d\t\n", a); 353 break; 354 CASE(OP_LE, B): 355 printf("OP_LE\t\tR%d\t\n", a); 356 break; 357 CASE(OP_GT, B): 358 printf("OP_GT\t\tR%d\t\n", a); 359 break; 360 CASE(OP_GE, B): 361 printf("OP_GE\t\tR%d\t\n", a); 362 break; 363 CASE(OP_EQ, B): 364 printf("OP_EQ\t\tR%d\t\n", a); 365 break; 366 CASE(OP_ARRAY, BB): 367 printf("OP_ARRAY\tR%d\t%d\t", a, b); 368 print_lv_a(mrb, irep, a); 369 break; 370 CASE(OP_ARRAY2, BBB): 371 printf("OP_ARRAY\tR%d\tR%d\t%d\t", a, b, c); 372 print_lv_ab(mrb, irep, a, b); 373 break; 374 CASE(OP_ARYCAT, B): 375 printf("OP_ARYCAT\tR%d\t", a); 376 print_lv_a(mrb, irep, a); 377 break; 378 CASE(OP_ARYPUSH, B): 379 printf("OP_ARYPUSH\tR%d\t", a); 380 print_lv_a(mrb, irep, a); 381 break; 382 CASE(OP_ARYDUP, B): 383 printf("OP_ARYDUP\tR%d\t", a); 384 print_lv_a(mrb, irep, a); 385 break; 386 CASE(OP_AREF, BBB): 387 printf("OP_AREF\tR%d\tR%d\t%d", a, b, c); 388 print_lv_ab(mrb, irep, a, b); 389 break; 390 CASE(OP_ASET, BBB): 391 printf("OP_ASET\tR%d\tR%d\t%d", a, b, c); 392 print_lv_ab(mrb, irep, a, b); 393 break; 394 CASE(OP_APOST, BBB): 395 printf("OP_APOST\tR%d\t%d\t%d", a, b, c); 396 print_lv_a(mrb, irep, a); 397 break; 398 CASE(OP_INTERN, B): 399 printf("OP_INTERN\tR%d", a); 400 print_lv_a(mrb, irep, a); 401 break; 402 CASE(OP_STRING, BB): 403 { 404 mrb_value v = irep->pool[b]; 405 mrb_value s = mrb_str_dump(mrb, mrb_str_new(mrb, RSTRING_PTR(v), RSTRING_LEN(v))); 406 printf("OP_STRING\tR%d\tL(%d)\t; %s", a, b, RSTRING_PTR(s)); 249 407 } 250 print_lv(mrb, irep, c, RA); 251 break; 252 case OP_BLKPUSH: 253 printf("OP_BLKPUSH\tR%d\t%d:%d:%d:%d", GETARG_A(c), 254 (GETARG_Bx(c)>>10)&0x3f, 255 (GETARG_Bx(c)>>9)&0x1, 256 (GETARG_Bx(c)>>4)&0x1f, 257 (GETARG_Bx(c)>>0)&0xf); 258 print_lv(mrb, irep, c, RA); 259 break; 260 261 case OP_LAMBDA: 262 printf("OP_LAMBDA\tR%d\tI(%+d)\t", GETARG_A(c), GETARG_b(c)+1); 263 switch (GETARG_c(c)) { 264 case OP_L_METHOD: 265 printf("method"); break; 266 case OP_L_BLOCK: 267 printf("block"); break; 268 case OP_L_LAMBDA: 269 printf("lambda"); break; 270 } 271 print_lv(mrb, irep, c, RA); 272 break; 273 case OP_RANGE: 274 printf("OP_RANGE\tR%d\tR%d\t%d", GETARG_A(c), GETARG_B(c), GETARG_C(c)); 275 print_lv(mrb, irep, c, RAB); 276 break; 277 case OP_METHOD: 278 printf("OP_METHOD\tR%d\t:%s", GETARG_A(c), 279 mrb_sym2name(mrb, irep->syms[GETARG_B(c)])); 280 print_lv(mrb, irep, c, RA); 281 break; 282 283 case OP_ADD: 284 printf("OP_ADD\tR%d\t:%s\t%d\n", GETARG_A(c), 285 mrb_sym2name(mrb, irep->syms[GETARG_B(c)]), 286 GETARG_C(c)); 287 break; 288 case OP_ADDI: 289 printf("OP_ADDI\tR%d\t:%s\t%d\n", GETARG_A(c), 290 mrb_sym2name(mrb, irep->syms[GETARG_B(c)]), 291 GETARG_C(c)); 292 break; 293 case OP_SUB: 294 printf("OP_SUB\tR%d\t:%s\t%d\n", GETARG_A(c), 295 mrb_sym2name(mrb, irep->syms[GETARG_B(c)]), 296 GETARG_C(c)); 297 break; 298 case OP_SUBI: 299 printf("OP_SUBI\tR%d\t:%s\t%d\n", GETARG_A(c), 300 mrb_sym2name(mrb, irep->syms[GETARG_B(c)]), 301 GETARG_C(c)); 302 break; 303 case OP_MUL: 304 printf("OP_MUL\tR%d\t:%s\t%d\n", GETARG_A(c), 305 mrb_sym2name(mrb, irep->syms[GETARG_B(c)]), 306 GETARG_C(c)); 307 break; 308 case OP_DIV: 309 printf("OP_DIV\tR%d\t:%s\t%d\n", GETARG_A(c), 310 mrb_sym2name(mrb, irep->syms[GETARG_B(c)]), 311 GETARG_C(c)); 312 break; 313 case OP_LT: 314 printf("OP_LT\tR%d\t:%s\t%d\n", GETARG_A(c), 315 mrb_sym2name(mrb, irep->syms[GETARG_B(c)]), 316 GETARG_C(c)); 317 break; 318 case OP_LE: 319 printf("OP_LE\tR%d\t:%s\t%d\n", GETARG_A(c), 320 mrb_sym2name(mrb, irep->syms[GETARG_B(c)]), 321 GETARG_C(c)); 322 break; 323 case OP_GT: 324 printf("OP_GT\tR%d\t:%s\t%d\n", GETARG_A(c), 325 mrb_sym2name(mrb, irep->syms[GETARG_B(c)]), 326 GETARG_C(c)); 327 break; 328 case OP_GE: 329 printf("OP_GE\tR%d\t:%s\t%d\n", GETARG_A(c), 330 mrb_sym2name(mrb, irep->syms[GETARG_B(c)]), 331 GETARG_C(c)); 332 break; 333 case OP_EQ: 334 printf("OP_EQ\t\tR%d\t:%s\t%d\n", GETARG_A(c), 335 mrb_sym2name(mrb, irep->syms[GETARG_B(c)]), 336 GETARG_C(c)); 337 break; 338 339 case OP_STOP: 340 printf("OP_STOP\n"); 341 break; 342 343 case OP_ARRAY: 344 printf("OP_ARRAY\tR%d\tR%d\t%d", GETARG_A(c), GETARG_B(c), GETARG_C(c)); 345 print_lv(mrb, irep, c, RAB); 346 break; 347 case OP_ARYCAT: 348 printf("OP_ARYCAT\tR%d\tR%d\t", GETARG_A(c), GETARG_B(c)); 349 print_lv(mrb, irep, c, RAB); 350 break; 351 case OP_ARYPUSH: 352 printf("OP_ARYPUSH\tR%d\tR%d\t", GETARG_A(c), GETARG_B(c)); 353 print_lv(mrb, irep, c, RAB); 354 break; 355 case OP_AREF: 356 printf("OP_AREF\tR%d\tR%d\t%d", GETARG_A(c), GETARG_B(c), GETARG_C(c)); 357 print_lv(mrb, irep, c, RAB); 358 break; 359 case OP_APOST: 360 printf("OP_APOST\tR%d\t%d\t%d", GETARG_A(c), GETARG_B(c), GETARG_C(c)); 361 print_lv(mrb, irep, c, RA); 362 break; 363 case OP_STRING: 408 print_lv_a(mrb, irep, a); 409 break; 410 CASE(OP_STRCAT, B): 411 printf("OP_STRCAT\tR%d\t", a); 412 print_lv_a(mrb, irep, a); 413 break; 414 CASE(OP_HASH, BB): 415 printf("OP_HASH\tR%d\t%d\t", a, b); 416 print_lv_a(mrb, irep, a); 417 break; 418 CASE(OP_HASHADD, BB): 419 printf("OP_HASHADD\tR%d\t%d\t", a, b); 420 print_lv_a(mrb, irep, a); 421 break; 422 CASE(OP_HASHCAT, B): 423 printf("OP_HASHCAT\tR%d\t", a); 424 print_lv_a(mrb, irep, a); 425 break; 426 427 CASE(OP_OCLASS, B): 428 printf("OP_OCLASS\tR%d\t\t", a); 429 print_lv_a(mrb, irep, a); 430 break; 431 CASE(OP_CLASS, BB): 432 printf("OP_CLASS\tR%d\t:%s", a, mrb_sym_dump(mrb, irep->syms[b])); 433 print_lv_a(mrb, irep, a); 434 break; 435 CASE(OP_MODULE, BB): 436 printf("OP_MODULE\tR%d\t:%s", a, mrb_sym_dump(mrb, irep->syms[b])); 437 print_lv_a(mrb, irep, a); 438 break; 439 CASE(OP_EXEC, BB): 440 printf("OP_EXEC\tR%d\tI(%d:%p)", a, b, irep->reps[b]); 441 print_lv_a(mrb, irep, a); 442 break; 443 CASE(OP_SCLASS, B): 444 printf("OP_SCLASS\tR%d\t", a); 445 print_lv_a(mrb, irep, a); 446 break; 447 CASE(OP_TCLASS, B): 448 printf("OP_TCLASS\tR%d\t\t", a); 449 print_lv_a(mrb, irep, a); 450 break; 451 CASE(OP_ERR, B): 364 452 { 365 mrb_value v = irep->pool[GETARG_Bx(c)]; 366 mrb_value s = mrb_str_dump(mrb, mrb_str_new(mrb, RSTRING_PTR(v), RSTRING_LEN(v))); 367 printf("OP_STRING\tR%d\tL(%d)\t; %s", GETARG_A(c), GETARG_Bx(c), RSTRING_PTR(s)); 368 } 369 print_lv(mrb, irep, c, RA); 370 break; 371 case OP_STRCAT: 372 printf("OP_STRCAT\tR%d\tR%d\t", GETARG_A(c), GETARG_B(c)); 373 print_lv(mrb, irep, c, RAB); 374 break; 375 case OP_HASH: 376 printf("OP_HASH\tR%d\tR%d\t%d", GETARG_A(c), GETARG_B(c), GETARG_C(c)); 377 print_lv(mrb, irep, c, RAB); 378 break; 379 380 case OP_OCLASS: 381 printf("OP_OCLASS\tR%d\t\t", GETARG_A(c)); 382 print_lv(mrb, irep, c, RA); 383 break; 384 case OP_CLASS: 385 printf("OP_CLASS\tR%d\t:%s", GETARG_A(c), 386 mrb_sym2name(mrb, irep->syms[GETARG_B(c)])); 387 print_lv(mrb, irep, c, RA); 388 break; 389 case OP_MODULE: 390 printf("OP_MODULE\tR%d\t:%s", GETARG_A(c), 391 mrb_sym2name(mrb, irep->syms[GETARG_B(c)])); 392 print_lv(mrb, irep, c, RA); 393 break; 394 case OP_EXEC: 395 printf("OP_EXEC\tR%d\tI(%+d)", GETARG_A(c), GETARG_Bx(c)+1); 396 print_lv(mrb, irep, c, RA); 397 break; 398 case OP_SCLASS: 399 printf("OP_SCLASS\tR%d\tR%d\t", GETARG_A(c), GETARG_B(c)); 400 print_lv(mrb, irep, c, RAB); 401 break; 402 case OP_TCLASS: 403 printf("OP_TCLASS\tR%d\t\t", GETARG_A(c)); 404 print_lv(mrb, irep, c, RA); 405 break; 406 case OP_ERR: 407 { 408 mrb_value v = irep->pool[GETARG_Bx(c)]; 453 mrb_value v = irep->pool[a]; 409 454 mrb_value s = mrb_str_dump(mrb, mrb_str_new(mrb, RSTRING_PTR(v), RSTRING_LEN(v))); 410 455 printf("OP_ERR\t%s\n", RSTRING_PTR(s)); 411 456 } 412 457 break; 413 case OP_EPUSH: 414 printf("OP_EPUSH\t:I(%+d)\n", GETARG_Bx(c)+1); 415 break; 416 case OP_ONERR: 417 printf("OP_ONERR\t%03d\n", i+GETARG_sBx(c)); 418 break; 419 case OP_RESCUE: 420 { 421 int a = GETARG_A(c); 422 int b = GETARG_B(c); 423 int cnt = GETARG_C(c); 424 425 if (b == 0) { 426 printf("OP_RESCUE\tR%d\t\t%s", a, cnt ? "cont" : ""); 427 print_lv(mrb, irep, c, RA); 428 break; 429 } 430 else { 431 printf("OP_RESCUE\tR%d\tR%d\t%s", a, b, cnt ? "cont" : ""); 432 print_lv(mrb, irep, c, RAB); 433 break; 434 } 458 CASE(OP_EPUSH, B): 459 printf("OP_EPUSH\t\t:I(%d:%p)\n", a, irep->reps[a]); 460 break; 461 CASE(OP_ONERR, S): 462 printf("OP_ONERR\t%03d\n", a); 463 break; 464 CASE(OP_EXCEPT, B): 465 printf("OP_EXCEPT\tR%d\t\t", a); 466 print_lv_a(mrb, irep, a); 467 break; 468 CASE(OP_RESCUE, BB): 469 printf("OP_RESCUE\tR%d\tR%d", a, b); 470 print_lv_ab(mrb, irep, a, b); 471 break; 472 CASE(OP_RAISE, B): 473 printf("OP_RAISE\tR%d\t\t", a); 474 print_lv_a(mrb, irep, a); 475 break; 476 CASE(OP_POPERR, B): 477 printf("OP_POPERR\t%d\t\t\n", a); 478 break; 479 CASE(OP_EPOP, B): 480 printf("OP_EPOP\t%d\n", a); 481 break; 482 483 CASE(OP_DEBUG, BBB): 484 printf("OP_DEBUG\t%d\t%d\t%d\n", a, b, c); 485 break; 486 487 CASE(OP_STOP, Z): 488 printf("OP_STOP\n"); 489 break; 490 491 CASE(OP_EXT1, Z): 492 ins = READ_B(); 493 printf("OP_EXT1\n"); 494 print_header(mrb, irep, pc-irep->iseq-2); 495 switch (ins) { 496 #define OPCODE(i,x) case OP_ ## i: FETCH_ ## x ## _1 (); goto L_OP_ ## i; 497 #include "mruby/ops.h" 498 #undef OPCODE 435 499 } 436 500 break; 437 case OP_RAISE: 438 printf("OP_RAISE\tR%d\t\t", GETARG_A(c)); 439 print_lv(mrb, irep, c, RA); 440 break; 441 case OP_POPERR: 442 printf("OP_POPERR\t%d\t\t\n", GETARG_A(c)); 443 break; 444 case OP_EPOP: 445 printf("OP_EPOP\t%d\n", GETARG_A(c)); 501 CASE(OP_EXT2, Z): 502 ins = READ_B(); 503 printf("OP_EXT2\n"); 504 print_header(mrb, irep, pc-irep->iseq-2); 505 switch (ins) { 506 #define OPCODE(i,x) case OP_ ## i: FETCH_ ## x ## _2 (); goto L_OP_ ## i; 507 #include "mruby/ops.h" 508 #undef OPCODE 509 } 510 break; 511 CASE(OP_EXT3, Z): 512 ins = READ_B(); 513 printf("OP_EXT3\n"); 514 print_header(mrb, irep, pc-irep->iseq-2); 515 switch (ins) { 516 #define OPCODE(i,x) case OP_ ## i: FETCH_ ## x ## _3 (); goto L_OP_ ## i; 517 #include "mruby/ops.h" 518 #undef OPCODE 519 } 446 520 break; 447 521 448 522 default: 449 printf("OP_unknown %d\t%d\t%d\t%d\n", GET_OPCODE(c), 450 GETARG_A(c), GETARG_B(c), GETARG_C(c)); 523 printf("OP_unknown (0x%x)\n", ins); 451 524 break; 452 525 } … … 454 527 } 455 528 printf("\n"); 456 #endif457 529 } 458 530 … … 460 532 codedump_recur(mrb_state *mrb, mrb_irep *irep) 461 533 { 462 size_t i;534 int i; 463 535 464 536 codedump(mrb, irep); … … 467 539 } 468 540 } 541 #endif 469 542 470 543 void 471 544 mrb_codedump_all(mrb_state *mrb, struct RProc *proc) 472 545 { 546 #ifndef MRB_DISABLE_STDIO 473 547 codedump_recur(mrb, proc->body.irep); 474 } 548 #endif 549 } -
EcnlProtoTool/trunk/mruby-2.1.1/src/debug.c
r331 r439 4 4 #include <mruby/debug.h> 5 5 6 static mrb_irep_debug_info_file 6 static mrb_irep_debug_info_file* 7 7 get_file(mrb_irep_debug_info *info, uint32_t pc) 8 8 { … … 52 52 53 53 MRB_API char const* 54 mrb_debug_get_filename(mrb_ irep *irep, uint32_t pc)55 { 56 if (irep && pc < irep->ilen) {54 mrb_debug_get_filename(mrb_state *mrb, mrb_irep *irep, ptrdiff_t pc) 55 { 56 if (irep && pc >= 0 && pc < irep->ilen) { 57 57 mrb_irep_debug_info_file* f = NULL; 58 if (!irep->debug_info) { return irep->filename; }59 else if ((f = get_file(irep->debug_info, pc))) {60 return f->filename;58 if (!irep->debug_info) return NULL; 59 else if ((f = get_file(irep->debug_info, (uint32_t)pc))) { 60 return mrb_sym_name_len(mrb, f->filename_sym, NULL); 61 61 } 62 62 } … … 65 65 66 66 MRB_API int32_t 67 mrb_debug_get_line(mrb_ irep *irep, uint32_t pc)68 { 69 if (irep && pc < irep->ilen) {67 mrb_debug_get_line(mrb_state *mrb, mrb_irep *irep, ptrdiff_t pc) 68 { 69 if (irep && pc >= 0 && pc < irep->ilen) { 70 70 mrb_irep_debug_info_file* f = NULL; 71 71 if (!irep->debug_info) { 72 return irep->lines? irep->lines[pc] :-1;73 } 74 else if ((f = get_file(irep->debug_info, pc))) {72 return -1; 73 } 74 else if ((f = get_file(irep->debug_info, (uint32_t)pc))) { 75 75 switch (f->line_type) { 76 76 case mrb_debug_line_ary: … … 109 109 } 110 110 111 MRB_API mrb_irep_debug_info 111 MRB_API mrb_irep_debug_info* 112 112 mrb_debug_info_alloc(mrb_state *mrb, mrb_irep *irep) 113 113 { … … 122 122 } 123 123 124 MRB_API mrb_irep_debug_info_file * 125 mrb_debug_info_append_file(mrb_state *mrb, mrb_irep *irep, 124 MRB_API mrb_irep_debug_info_file* 125 mrb_debug_info_append_file(mrb_state *mrb, mrb_irep_debug_info *d, 126 const char *filename, uint16_t *lines, 126 127 uint32_t start_pos, uint32_t end_pos) 127 128 { 128 mrb_irep_debug_info *info; 129 mrb_irep_debug_info_file *ret; 129 mrb_irep_debug_info_file *f; 130 130 uint32_t file_pc_count; 131 131 size_t fn_len; 132 mrb_int len;133 132 uint32_t i; 134 133 135 if (! irep->debug_info) { return NULL; }136 137 mrb_assert(irep->filename); 138 mrb_assert( irep->lines);139 140 info = irep->debug_info; 141 142 if (info->flen > 0 && strcmp(irep->filename, info->files[info->flen - 1]->filename) == 0) {143 return NULL;144 }145 146 ret = (mrb_irep_debug_info_file *)mrb_malloc(mrb, sizeof(*ret)); 147 info->files =148 149 info->files150 ? mrb_realloc(mrb, info->files, sizeof(mrb_irep_debug_info_file*) * (info->flen + 1))134 if (!d) return NULL; 135 if (start_pos == end_pos) return NULL; 136 137 mrb_assert(filename); 138 mrb_assert(lines); 139 140 if (d->flen > 0) { 141 const char *fn = mrb_sym_name_len(mrb, d->files[d->flen - 1]->filename_sym, NULL); 142 if (strcmp(filename, fn) == 0) 143 return NULL; 144 } 145 146 f = (mrb_irep_debug_info_file*)mrb_malloc(mrb, sizeof(*f)); 147 d->files = (mrb_irep_debug_info_file**)( 148 d->files 149 ? mrb_realloc(mrb, d->files, sizeof(mrb_irep_debug_info_file*) * (d->flen + 1)) 151 150 : mrb_malloc(mrb, sizeof(mrb_irep_debug_info_file*))); 152 info->files[info->flen++] = ret;151 d->files[d->flen++] = f; 153 152 154 153 file_pc_count = end_pos - start_pos; 155 154 156 ret->start_pos = start_pos; 157 info->pc_count = end_pos; 158 159 fn_len = strlen(irep->filename); 160 ret->filename_sym = mrb_intern(mrb, irep->filename, fn_len); 161 len = 0; 162 ret->filename = mrb_sym2name_len(mrb, ret->filename_sym, &len); 163 164 ret->line_type = select_line_type(irep->lines + start_pos, end_pos - start_pos); 165 ret->lines.ptr = NULL; 166 167 switch (ret->line_type) { 155 f->start_pos = start_pos; 156 d->pc_count = end_pos; 157 158 fn_len = strlen(filename); 159 f->filename_sym = mrb_intern(mrb, filename, fn_len); 160 161 f->line_type = select_line_type(lines + start_pos, end_pos - start_pos); 162 f->lines.ptr = NULL; 163 164 switch (f->line_type) { 168 165 case mrb_debug_line_ary: 169 ret->line_entry_count = file_pc_count;170 ret->lines.ary = (uint16_t*)mrb_malloc(mrb, sizeof(uint16_t) * file_pc_count);166 f->line_entry_count = file_pc_count; 167 f->lines.ary = (uint16_t*)mrb_malloc(mrb, sizeof(uint16_t) * file_pc_count); 171 168 for (i = 0; i < file_pc_count; ++i) { 172 ret->lines.ary[i] = irep->lines[start_pos + i];169 f->lines.ary[i] = lines[start_pos + i]; 173 170 } 174 171 break; … … 177 174 uint16_t prev_line = 0; 178 175 mrb_irep_debug_info_line m; 179 ret->lines.flat_map = (mrb_irep_debug_info_line*)mrb_malloc(mrb, sizeof(mrb_irep_debug_info_line) * 1);180 ret->line_entry_count = 0;176 f->lines.flat_map = (mrb_irep_debug_info_line*)mrb_malloc(mrb, sizeof(mrb_irep_debug_info_line) * 1); 177 f->line_entry_count = 0; 181 178 for (i = 0; i < file_pc_count; ++i) { 182 if ( irep->lines[start_pos + i] == prev_line) { continue; }183 184 ret->lines.flat_map = (mrb_irep_debug_info_line*)mrb_realloc(185 mrb, ret->lines.flat_map,186 sizeof(mrb_irep_debug_info_line) * ( ret->line_entry_count + 1));179 if (lines[start_pos + i] == prev_line) { continue; } 180 181 f->lines.flat_map = (mrb_irep_debug_info_line*)mrb_realloc( 182 mrb, f->lines.flat_map, 183 sizeof(mrb_irep_debug_info_line) * (f->line_entry_count + 1)); 187 184 m.start_pos = start_pos + i; 188 m.line = irep->lines[start_pos + i];189 ret->lines.flat_map[ret->line_entry_count] = m;185 m.line = lines[start_pos + i]; 186 f->lines.flat_map[f->line_entry_count] = m; 190 187 191 188 /* update */ 192 ++ ret->line_entry_count;193 prev_line = irep->lines[start_pos + i];189 ++f->line_entry_count; 190 prev_line = lines[start_pos + i]; 194 191 } 195 192 } break; … … 198 195 } 199 196 200 return ret;197 return f; 201 198 } 202 199 -
EcnlProtoTool/trunk/mruby-2.1.1/src/dump.c
r331 r439 7 7 #include <string.h> 8 8 #include <limits.h> 9 #include <math.h> 9 10 #include <mruby/dump.h> 10 11 #include <mruby/string.h> … … 16 17 #define FLAG_BYTEORDER_NONATIVE 0 17 18 19 #ifndef MRB_WITHOUT_FLOAT 18 20 #ifdef MRB_USE_FLOAT 19 #define MRB_FLOAT_FMT "%. 8e"21 #define MRB_FLOAT_FMT "%.9g" 20 22 #else 21 #define MRB_FLOAT_FMT "%.16e" 23 #define MRB_FLOAT_FMT "%.17g" 24 #endif 22 25 #endif 23 26 … … 80 83 { 81 84 uint8_t *cur = buf; 82 uint32_t iseq_no;83 85 84 86 cur += uint32_to_bin(irep->ilen, cur); /* number of opcode */ 85 87 cur += write_padding(cur); 86 switch (flags & DUMP_ENDIAN_NAT) { 87 case DUMP_ENDIAN_BIG: 88 if (bigendian_p()) goto native; 89 for (iseq_no = 0; iseq_no < irep->ilen; iseq_no++) { 90 cur += uint32_to_bin(irep->iseq[iseq_no], cur); /* opcode */ 91 } 92 break; 93 case DUMP_ENDIAN_LIL: 94 if (!bigendian_p()) goto native; 95 for (iseq_no = 0; iseq_no < irep->ilen; iseq_no++) { 96 cur += uint32l_to_bin(irep->iseq[iseq_no], cur); /* opcode */ 97 } 98 break; 99 100 native: 101 case DUMP_ENDIAN_NAT: 102 memcpy(cur, irep->iseq, irep->ilen * sizeof(mrb_code)); 103 cur += irep->ilen * sizeof(mrb_code); 104 break; 105 } 88 memcpy(cur, irep->iseq, irep->ilen * sizeof(mrb_code)); 89 cur += irep->ilen * sizeof(mrb_code); 106 90 107 91 return cur - buf; 108 92 } 109 93 94 #ifndef MRB_WITHOUT_FLOAT 95 static mrb_value 96 float_to_str(mrb_state *mrb, mrb_value flt) 97 { 98 mrb_float f = mrb_float(flt); 99 100 if (isinf(f)) { 101 return f < 0 ? mrb_str_new_lit(mrb, "I") : mrb_str_new_lit(mrb, "i"); 102 } 103 return mrb_float_to_str(mrb, flt, MRB_FLOAT_FMT); 104 } 105 #endif 110 106 111 107 static size_t 112 108 get_pool_block_size(mrb_state *mrb, mrb_irep *irep) 113 109 { 110 int pool_no; 114 111 size_t size = 0; 115 size_t pool_no;116 112 mrb_value str; 117 113 … … 132 128 break; 133 129 130 #ifndef MRB_WITHOUT_FLOAT 134 131 case MRB_TT_FLOAT: 135 str = mrb_float_to_str(mrb, irep->pool[pool_no], MRB_FLOAT_FMT);132 str = float_to_str(mrb, irep->pool[pool_no]); 136 133 { 137 134 mrb_int len = RSTRING_LEN(str); … … 140 137 } 141 138 break; 139 #endif 142 140 143 141 case MRB_TT_STRING: … … 161 159 write_pool_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf) 162 160 { 163 size_t pool_no;161 int pool_no; 164 162 uint8_t *cur = buf; 165 163 uint16_t len; … … 178 176 break; 179 177 178 #ifndef MRB_WITHOUT_FLOAT 180 179 case MRB_TT_FLOAT: 181 180 cur += uint8_to_bin(IREP_TT_FLOAT, cur); /* data type */ 182 str = mrb_float_to_str(mrb, irep->pool[pool_no], MRB_FLOAT_FMT);181 str = float_to_str(mrb, irep->pool[pool_no]); 183 182 break; 183 #endif 184 184 185 185 case MRB_TT_STRING: … … 214 214 { 215 215 size_t size = 0; 216 uint32_t sym_no;216 int sym_no; 217 217 mrb_int len; 218 218 … … 221 221 size += sizeof(uint16_t); /* snl(n) */ 222 222 if (irep->syms[sym_no] != 0) { 223 mrb_sym 2name_len(mrb, irep->syms[sym_no], &len);223 mrb_sym_name_len(mrb, irep->syms[sym_no], &len); 224 224 size += len + 1; /* sn(n) + null char */ 225 225 } … … 232 232 write_syms_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf) 233 233 { 234 uint32_t sym_no;234 int sym_no; 235 235 uint8_t *cur = buf; 236 236 const char *name; … … 242 242 mrb_int len; 243 243 244 name = mrb_sym 2name_len(mrb, irep->syms[sym_no], &len);244 name = mrb_sym_name_len(mrb, irep->syms[sym_no], &len); 245 245 246 246 mrb_assert_int_fit(mrb_int, len, uint16_t, UINT16_MAX); … … 274 274 { 275 275 size_t size = 0; 276 size_t irep_no;276 int irep_no; 277 277 278 278 size = get_irep_record_size_1(mrb, irep); … … 286 286 write_irep_record(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, size_t *irep_record_size, uint8_t flags) 287 287 { 288 uint32_t i;288 int i; 289 289 uint8_t *src = bin; 290 290 … … 367 367 } 368 368 369 static int370 write_section_lineno_header(mrb_state *mrb, size_t section_size, uint8_t *bin)371 {372 struct rite_section_lineno_header *header = (struct rite_section_lineno_header*)bin;373 374 memcpy(header->section_ident, RITE_SECTION_LINENO_IDENT, sizeof(header->section_ident));375 uint32_to_bin((uint32_t)section_size, header->section_size);376 377 return MRB_DUMP_OK;378 }379 380 static size_t381 get_lineno_record_size(mrb_state *mrb, mrb_irep *irep)382 {383 size_t size = 0;384 385 size += sizeof(uint32_t); /* record size */386 size += sizeof(uint16_t); /* filename size */387 if (irep->filename) {388 size += strlen(irep->filename); /* filename */389 }390 size += sizeof(uint32_t); /* niseq */391 if (irep->lines) {392 size += sizeof(uint16_t) * irep->ilen; /* lineno */393 }394 395 return size;396 }397 398 static size_t399 write_lineno_record_1(mrb_state *mrb, mrb_irep *irep, uint8_t* bin)400 {401 uint8_t *cur = bin;402 size_t iseq_no;403 size_t filename_len;404 ptrdiff_t diff;405 406 cur += sizeof(uint32_t); /* record size */407 408 if (irep->filename) {409 filename_len = strlen(irep->filename);410 }411 else {412 filename_len = 0;413 }414 mrb_assert_int_fit(size_t, filename_len, uint16_t, UINT16_MAX);415 cur += uint16_to_bin((uint16_t)filename_len, cur); /* filename size */416 417 if (filename_len) {418 memcpy(cur, irep->filename, filename_len);419 cur += filename_len; /* filename */420 }421 422 if (irep->lines) {423 mrb_assert_int_fit(size_t, irep->ilen, uint32_t, UINT32_MAX);424 cur += uint32_to_bin((uint32_t)(irep->ilen), cur); /* niseq */425 for (iseq_no = 0; iseq_no < irep->ilen; iseq_no++) {426 cur += uint16_to_bin(irep->lines[iseq_no], cur); /* opcode */427 }428 }429 else {430 cur += uint32_to_bin(0, cur); /* niseq */431 }432 433 diff = cur - bin;434 mrb_assert_int_fit(ptrdiff_t, diff, uint32_t, UINT32_MAX);435 436 uint32_to_bin((uint32_t)diff, bin); /* record size */437 438 mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX);439 return (size_t)diff;440 }441 442 static size_t443 write_lineno_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin)444 {445 size_t i;446 size_t rlen, size = 0;447 448 rlen = write_lineno_record_1(mrb, irep, bin);449 bin += rlen;450 size += rlen;451 for (i=0; i<irep->rlen; i++) {452 rlen = write_lineno_record(mrb, irep, bin);453 bin += rlen;454 size += rlen;455 }456 return size;457 }458 459 static int460 write_section_lineno(mrb_state *mrb, mrb_irep *irep, uint8_t *bin)461 {462 size_t section_size = 0;463 size_t rlen = 0; /* size of irep record */464 uint8_t *cur = bin;465 466 if (mrb == NULL || bin == NULL) {467 return MRB_DUMP_INVALID_ARGUMENT;468 }469 470 cur += sizeof(struct rite_section_lineno_header);471 section_size += sizeof(struct rite_section_lineno_header);472 473 rlen = write_lineno_record(mrb, irep, cur);474 section_size += rlen;475 476 write_section_lineno_header(mrb, section_size, bin);477 478 return MRB_DUMP_OK;479 }480 481 369 static size_t 482 370 get_debug_record_size(mrb_state *mrb, mrb_irep *irep) … … 484 372 size_t ret = 0; 485 373 uint16_t f_idx; 486 size_t i;374 int i; 487 375 488 376 ret += sizeof(uint32_t); /* record size */ … … 532 420 { 533 421 mrb_sym *filenames = *fp; 534 size_t i,size = 0;422 size_t size = 0; 535 423 mrb_irep_debug_info *di = irep->debug_info; 424 int i; 536 425 537 426 mrb_assert(lp); … … 548 437 549 438 /* filename */ 550 mrb_sym 2name_len(mrb, file->filename_sym, &filename_len);439 mrb_sym_name_len(mrb, file->filename_sym, &filename_len); 551 440 size += sizeof(uint16_t) + (size_t)filename_len; 552 441 } … … 606 495 ret = cur - bin; 607 496 mrb_assert_int_fit(ptrdiff_t, ret, uint32_t, UINT32_MAX); 608 uint32_to_bin( ret, bin);497 uint32_to_bin((uint32_t)ret, bin); 609 498 610 499 mrb_assert_int_fit(ptrdiff_t, ret, size_t, SIZE_MAX); … … 616 505 { 617 506 size_t size, len; 618 size_t irep_no;507 int irep_no; 619 508 620 509 size = len = write_debug_record_1(mrb, irep, bin, filenames, filenames_len); … … 652 541 section_size += sizeof(uint16_t); 653 542 for (i = 0; i < filenames_len; ++i) { 654 sym = mrb_sym 2name_len(mrb, filenames[i], &sym_len);543 sym = mrb_sym_name_len(mrb, filenames[i], &sym_len); 655 544 mrb_assert(sym); 656 cur += uint16_to_bin( sym_len, cur);545 cur += uint16_to_bin((uint16_t)sym_len, cur); 657 546 memcpy(cur, sym, sym_len); 658 547 cur += sym_len; … … 666 555 memcpy(header->section_ident, RITE_SECTION_DEBUG_IDENT, sizeof(header->section_ident)); 667 556 mrb_assert(section_size <= INT32_MAX); 668 uint32_to_bin( section_size, header->section_size);557 uint32_to_bin((uint32_t)section_size, header->section_size); 669 558 670 559 return MRB_DUMP_OK; … … 674 563 create_lv_sym_table(mrb_state *mrb, const mrb_irep *irep, mrb_sym **syms, uint32_t *syms_len) 675 564 { 676 size_t i;565 int i; 677 566 678 567 if (*syms == NULL) { … … 706 595 707 596 for (i = 0; i < syms_len; ++i) { 708 str = mrb_sym 2name_len(mrb, syms[i], &str_len);709 cur += uint16_to_bin( str_len, cur);597 str = mrb_sym_name_len(mrb, syms[i], &str_len); 598 cur += uint16_to_bin((uint16_t)str_len, cur); 710 599 memcpy(cur, str, str_len); 711 600 cur += str_len; … … 721 610 { 722 611 uint8_t *cur = *start; 723 size_t i;612 int i; 724 613 725 614 for (i = 0; i + 1 < irep->nlocals; ++i) { … … 749 638 get_lv_record_size(mrb_state *mrb, mrb_irep *irep) 750 639 { 751 size_t ret = 0, i; 640 size_t ret = 0; 641 int i; 752 642 753 643 ret += (sizeof(uint16_t) + sizeof(uint16_t)) * (irep->nlocals - 1); … … 769 659 for (i = 0; i < syms_len; ++i) { 770 660 mrb_int str_len; 771 mrb_sym 2name_len(mrb, syms[i], &str_len);661 mrb_sym_name_len(mrb, syms[i], &str_len); 772 662 ret += str_len; 773 663 } … … 807 697 diff = cur - start; 808 698 mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX); 809 uint32_to_bin( diff, header->section_size);699 uint32_to_bin((uint32_t)diff, header->section_size); 810 700 811 701 lv_section_exit: … … 842 732 uint32_to_bin((uint32_t)binary_size, header->binary_size); 843 733 844 offset = ( &(header->binary_crc[0]) - bin) + sizeof(uint16_t);734 offset = (uint32_t)((&(header->binary_crc[0]) - bin) + sizeof(uint16_t)); 845 735 crc = calc_crc_16_ccitt(bin + offset, binary_size - offset, 0); 846 736 uint16_to_bin(crc, header->binary_crc); … … 850 740 851 741 static mrb_bool 852 is_debug_info_defined(mrb_irep *irep)853 { 854 size_t i;742 debug_info_defined_p(mrb_irep *irep) 743 { 744 int i; 855 745 856 746 if (!irep->debug_info) return FALSE; 857 747 for (i=0; i<irep->rlen; i++) { 858 if (! is_debug_info_defined(irep->reps[i])) return FALSE;748 if (!debug_info_defined_p(irep->reps[i])) return FALSE; 859 749 } 860 750 return TRUE; … … 862 752 863 753 static mrb_bool 864 is_lv_defined(mrb_irep *irep)865 { 866 size_t i;754 lv_defined_p(mrb_irep *irep) 755 { 756 int i; 867 757 868 758 if (irep->lv) { return TRUE; } 869 759 870 760 for (i = 0; i < irep->rlen; ++i) { 871 if ( is_lv_defined(irep->reps[i])) { return TRUE; }761 if (lv_defined_p(irep->reps[i])) { return TRUE; } 872 762 } 873 763 … … 898 788 size_t section_lineno_size = 0, section_lv_size = 0; 899 789 uint8_t *cur = NULL; 900 mrb_bool const debug_info_defined = is_debug_info_defined(irep), lv_defined = is_lv_defined(irep);790 mrb_bool const debug_info_defined = debug_info_defined_p(irep), lv_defined = lv_defined_p(irep); 901 791 mrb_sym *lv_syms = NULL; uint32_t lv_syms_len = 0; 902 792 mrb_sym *filenames = NULL; uint16_t filenames_len = 0; … … 923 813 section_lineno_size += get_debug_record_size(mrb, irep); 924 814 } 925 else {926 section_lineno_size += sizeof(struct rite_section_lineno_header);927 section_lineno_size += get_lineno_record_size(mrb, irep);928 }929 815 } 930 816 … … 954 840 if (debug_info_defined) { 955 841 result = write_section_debug(mrb, irep, cur, filenames, filenames_len); 956 } 957 else { 958 result = write_section_lineno(mrb, irep, cur); 959 } 960 if (result != MRB_DUMP_OK) { 961 goto error_exit; 842 if (result != MRB_DUMP_OK) { 843 goto error_exit; 844 } 962 845 } 963 846 cur += section_lineno_size; … … 1061 944 } 1062 945 if (fprintf(fp, 946 "#ifdef __cplusplus\n" 1063 947 "extern const uint8_t %s[];\n" 948 "#endif\n" 1064 949 "const uint8_t\n" 1065 950 "#if defined __GNUC__\n" -
EcnlProtoTool/trunk/mruby-2.1.1/src/enum.c
r331 r439 6 6 7 7 #include <mruby.h> 8 #include <mruby/proc.h> 9 10 /* internal method `__update_hash(oldhash, index, itemhash)` */ 11 static mrb_value 12 enum_update_hash(mrb_state *mrb, mrb_value self) 13 { 14 mrb_int hash; 15 mrb_int index; 16 mrb_int hv; 17 18 mrb_get_args(mrb, "iii", &hash, &index, &hv); 19 hash ^= ((uint32_t)hv << (index % 16)); 20 21 return mrb_fixnum_value(hash); 22 } 8 23 9 24 void 10 25 mrb_init_enumerable(mrb_state *mrb) 11 26 { 12 mrb_define_module(mrb, "Enumerable"); /* 15.3.2 */ 27 struct RClass *enumerable; 28 enumerable = mrb_define_module(mrb, "Enumerable"); /* 15.3.2 */ 29 mrb_define_module_function(mrb, enumerable, "__update_hash", enum_update_hash, MRB_ARGS_REQ(3)); 13 30 } 14 -
EcnlProtoTool/trunk/mruby-2.1.1/src/error.c
r331 r439 14 14 #include <mruby/string.h> 15 15 #include <mruby/variable.h> 16 #include <mruby/debug.h>17 16 #include <mruby/error.h> 18 17 #include <mruby/class.h> … … 29 28 mrb_exc_new_str(mrb_state *mrb, struct RClass* c, mrb_value str) 30 29 { 31 str = mrb_str_to_str(mrb, str);30 mrb_to_str(mrb, str); 32 31 return mrb_obj_new(mrb, c, 1, &str); 33 32 } … … 45 44 { 46 45 mrb_value mesg; 47 mrb_int argc; 48 mrb_value *argv; 49 50 if (mrb_get_args(mrb, "|o*", &mesg, &argv, &argc) >= 1) { 46 47 if (mrb_get_args(mrb, "|o", &mesg) == 1) { 51 48 mrb_iv_set(mrb, exc, mrb_intern_lit(mrb, "mesg"), mesg); 52 49 } … … 72 69 mrb_value exc; 73 70 mrb_value a; 74 int argc;71 mrb_int argc; 75 72 76 73 argc = mrb_get_args(mrb, "|o", &a); … … 91 88 */ 92 89 93 staticmrb_value90 mrb_value 94 91 exc_to_s(mrb_state *mrb, mrb_value exc) 95 92 { … … 131 128 */ 132 129 133 static mrb_value 134 exc_inspect(mrb_state *mrb, mrb_value exc) 135 { 136 mrb_value str, mesg, file, line; 137 mrb_bool append_mesg; 138 const char *cname; 139 140 mesg = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "mesg")); 141 file = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "file")); 142 line = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "line")); 143 144 append_mesg = !mrb_nil_p(mesg); 145 if (append_mesg) { 146 mesg = mrb_obj_as_string(mrb, mesg); 147 append_mesg = RSTRING_LEN(mesg) > 0; 148 } 149 150 cname = mrb_obj_classname(mrb, exc); 151 str = mrb_str_new_cstr(mrb, cname); 152 if (mrb_string_p(file) && mrb_fixnum_p(line)) { 153 if (append_mesg) { 154 str = mrb_format(mrb, "%S:%S:%S (%S)", file, line, mesg, str); 155 } 156 else { 157 str = mrb_format(mrb, "%S:%S:%S", file, line, str); 158 } 159 } 160 else if (append_mesg) { 161 str = mrb_format(mrb, "%S:%S", str, mesg); 162 } 163 return str; 130 mrb_value 131 mrb_exc_inspect(mrb_state *mrb, mrb_value exc) 132 { 133 mrb_value mesg = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "mesg")); 134 mrb_value cname = mrb_mod_to_s(mrb, mrb_obj_value(mrb_obj_class(mrb, exc))); 135 mesg = mrb_obj_as_string(mrb, mesg); 136 return RSTRING_LEN(mesg) == 0 ? cname : mrb_format(mrb, "%v (%v)", mesg, cname); 164 137 } 165 138 … … 195 168 } 196 169 197 static void198 exc_debug_info(mrb_state *mrb, struct RObject *exc)199 {200 mrb_callinfo *ci = mrb->c->ci;201 mrb_code *pc = ci->pc;202 203 while (ci >= mrb->c->cibase) {204 mrb_code *err = ci->err;205 206 if (!err && pc) err = pc - 1;207 if (err && ci->proc && !MRB_PROC_CFUNC_P(ci->proc)) {208 mrb_irep *irep = ci->proc->body.irep;209 210 int32_t const line = mrb_debug_get_line(irep, (uint32_t)(err - irep->iseq));211 char const* file = mrb_debug_get_filename(irep, (uint32_t)(err - irep->iseq));212 if (line != -1 && file) {213 mrb_obj_iv_set(mrb, exc, mrb_intern_lit(mrb, "file"), mrb_str_new_cstr(mrb, file));214 mrb_obj_iv_set(mrb, exc, mrb_intern_lit(mrb, "line"), mrb_fixnum_value(line));215 return;216 }217 }218 pc = ci->pc;219 ci--;220 }221 }222 223 170 void 224 171 mrb_exc_set(mrb_state *mrb, mrb_value exc) … … 229 176 else { 230 177 mrb->exc = mrb_obj_ptr(exc); 231 if (!mrb->gc.out_of_memory) { 232 exc_debug_info(mrb, mrb->exc); 178 if (mrb->gc.arena_idx > 0 && 179 (struct RBasic*)mrb->exc == mrb->gc.arena[mrb->gc.arena_idx-1]) { 180 mrb->gc.arena_idx--; 181 } 182 if (!mrb->gc.out_of_memory && !mrb_frozen_p(mrb->exc)) { 233 183 mrb_keep_backtrace(mrb, exc); 234 184 } … … 239 189 mrb_exc_raise(mrb_state *mrb, mrb_value exc) 240 190 { 241 if (!mrb_obj_is_kind_of(mrb, exc, mrb->eException_class)) { 242 mrb_raise(mrb, E_TYPE_ERROR, "exception object expected"); 243 } 244 mrb_exc_set(mrb, exc); 191 if (mrb_break_p(exc)) { 192 mrb->exc = mrb_obj_ptr(exc); 193 } 194 else { 195 if (!mrb_obj_is_kind_of(mrb, exc, mrb->eException_class)) { 196 mrb_raise(mrb, E_TYPE_ERROR, "exception object expected"); 197 } 198 mrb_exc_set(mrb, exc); 199 } 245 200 if (!mrb->jmp) { 246 201 mrb_p(mrb, exc); … … 256 211 } 257 212 213 /* 214 * <code>vsprintf</code> like formatting. 215 * 216 * The syntax of a format sequence is as follows. 217 * 218 * %[modifier]specifier 219 * 220 * The modifiers are: 221 * 222 * ----------+------------------------------------------------------------ 223 * Modifier | Meaning 224 * ----------+------------------------------------------------------------ 225 * ! | Convert to string by corresponding `inspect` instead of 226 * | corresponding `to_s`. 227 * ----------+------------------------------------------------------------ 228 * 229 * The specifiers are: 230 * 231 * ----------+----------------+-------------------------------------------- 232 * Specifier | Argument Type | Note 233 * ----------+----------------+-------------------------------------------- 234 * c | char | 235 * d | int | 236 * f | mrb_float | 237 * i | mrb_int | 238 * l | char*, size_t | Arguments are string and length. 239 * n | mrb_sym | 240 * s | char* | Argument is NUL terminated string. 241 * t | mrb_value | Convert to type (class) of object. 242 * v,S | mrb_value | 243 * C | struct RClass* | 244 * T | mrb_value | Convert to real type (class) of object. 245 * Y | mrb_value | Same as `!v` if argument is `true`, `false` 246 * | | or `nil`, otherwise same as `T`. 247 * % | - | Convert to percent sign itself (no argument 248 * | | taken). 249 * ----------+----------------+-------------------------------------------- 250 */ 258 251 MRB_API mrb_value 259 252 mrb_vformat(mrb_state *mrb, const char *format, va_list ap) 260 253 { 261 const char *p = format; 262 const char *b = p; 263 ptrdiff_t size; 264 mrb_value ary = mrb_ary_new_capa(mrb, 4); 254 const char *chars, *p = format, *b = format, *e; 255 char ch; 256 size_t len; 257 mrb_int i; 258 struct RClass *cls; 259 mrb_bool inspect = FALSE; 260 mrb_value result = mrb_str_new_capa(mrb, 128), obj, str; 265 261 int ai = mrb_gc_arena_save(mrb); 266 262 267 263 while (*p) { 268 264 const char c = *p++; 269 265 e = p; 270 266 if (c == '%') { 271 if (*p == 'S') { 272 size = p - b - 1; 273 mrb_ary_push(mrb, ary, mrb_str_new(mrb, b, size)); 274 mrb_ary_push(mrb, ary, va_arg(ap, mrb_value)); 275 b = p + 1; 267 if (*p == '!') { 268 inspect = TRUE; 269 ++p; 276 270 } 271 if (!*p) break; 272 switch (*p) { 273 case 'c': 274 ch = (char)va_arg(ap, int); 275 chars = &ch; 276 len = 1; 277 goto L_cat; 278 case 'd': case 'i': 279 #if MRB_INT_MAX < INT_MAX 280 i = (mrb_int)va_arg(ap, int); 281 #else 282 i = *p == 'd' ? (mrb_int)va_arg(ap, int) : va_arg(ap, mrb_int); 283 #endif 284 obj = mrb_fixnum_value(i); 285 goto L_cat_obj; 286 #ifndef MRB_WITHOUT_FLOAT 287 case 'f': 288 obj = mrb_float_value(mrb, (mrb_float)va_arg(ap, double)); 289 goto L_cat_obj; 290 #endif 291 case 'l': 292 chars = va_arg(ap, char*); 293 len = va_arg(ap, size_t); 294 L_cat: 295 if (inspect) { 296 obj = mrb_str_new(mrb, chars, len); 297 goto L_cat_obj; 298 } 299 mrb_str_cat(mrb, result, b, e - b - 1); 300 mrb_str_cat(mrb, result, chars, len); 301 b = ++p; 302 mrb_gc_arena_restore(mrb, ai); 303 break; 304 case 'n': 305 #if UINT32_MAX < INT_MAX 306 obj = mrb_symbol_value((mrb_sym)va_arg(ap, int)); 307 #else 308 obj = mrb_symbol_value(va_arg(ap, mrb_sym)); 309 #endif 310 goto L_cat_obj; 311 case 's': 312 chars = va_arg(ap, char*); 313 len = strlen(chars); 314 goto L_cat; 315 case 't': 316 cls = mrb_class(mrb, va_arg(ap, mrb_value)); 317 goto L_cat_class; 318 case 'v': case 'S': 319 obj = va_arg(ap, mrb_value); 320 L_cat_obj: 321 str = (inspect ? mrb_inspect : mrb_obj_as_string)(mrb, obj); 322 chars = RSTRING_PTR(str); 323 len = RSTRING_LEN(str); 324 inspect = FALSE; 325 goto L_cat; 326 case 'C': 327 cls = va_arg(ap, struct RClass*); 328 L_cat_class: 329 obj = mrb_obj_value(cls); 330 goto L_cat_obj; 331 case 'T': 332 obj = va_arg(ap, mrb_value); 333 L_cat_real_class_of: 334 cls = mrb_obj_class(mrb, obj); 335 goto L_cat_class; 336 case 'Y': 337 obj = va_arg(ap, mrb_value); 338 if (!mrb_test(obj) || mrb_true_p(obj)) { 339 inspect = TRUE; 340 goto L_cat_obj; 341 } 342 else { 343 goto L_cat_real_class_of; 344 } 345 case '%': 346 L_cat_current: 347 chars = p; 348 len = 1; 349 goto L_cat; 350 default: 351 mrb_raisef(mrb, E_ARGUMENT_ERROR, "malformed format string - %%%c", *p); 352 } 277 353 } 278 354 else if (c == '\\') { 279 if (*p) { 280 size = p - b - 1; 281 mrb_ary_push(mrb, ary, mrb_str_new(mrb, b, size)); 282 mrb_ary_push(mrb, ary, mrb_str_new(mrb, p, 1)); 283 b = ++p; 284 } 285 else { 286 break; 287 } 288 } 289 mrb_gc_arena_restore(mrb, ai); 290 } 291 if (b == format) { 292 return mrb_str_new_cstr(mrb, format); 293 } 294 else { 295 size = p - b; 296 if (size > 0) { 297 mrb_ary_push(mrb, ary, mrb_str_new(mrb, b, size)); 298 mrb_gc_arena_restore(mrb, ai); 299 } 300 return mrb_ary_join(mrb, ary, mrb_nil_value()); 301 } 355 if (!*p) break; 356 goto L_cat_current; 357 358 } 359 } 360 361 mrb_str_cat(mrb, result, b, p - b); 362 return result; 302 363 } 303 364 … … 319 380 { 320 381 mrb_value mesg; 382 static int called = 0; 321 383 322 384 mesg = mrb_vformat(mrb, fmt, ap); … … 327 389 argv[0] = mesg; 328 390 } 391 if (called) 392 mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err)); 393 called = 1; 329 394 mrb_exc_raise(mrb, mrb_obj_new(mrb, c, argc+1, argv)); 330 395 } … … 363 428 fputs("warning: ", stderr); 364 429 fwrite(RSTRING_PTR(str), RSTRING_LEN(str), 1, stderr); 430 putc('\n', stderr); 365 431 va_end(ap); 366 432 #endif … … 384 450 385 451 MRB_API mrb_value 386 mrb_make_exception(mrb_state *mrb, int argc, const mrb_value *argv)452 mrb_make_exception(mrb_state *mrb, mrb_int argc, const mrb_value *argv) 387 453 { 388 454 mrb_value mesg; … … 420 486 break; 421 487 default: 422 mrb_ raisef(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (%S for 0..3)", mrb_fixnum_value(argc));488 mrb_argnum_error(mrb, argc, 0, 3); 423 489 break; 424 490 } … … 470 536 } 471 537 538 MRB_API mrb_noreturn void 539 mrb_frozen_error(mrb_state *mrb, void *frozen_obj) 540 { 541 mrb_raisef(mrb, E_FROZEN_ERROR, "can't modify frozen %t", mrb_obj_value(frozen_obj)); 542 } 543 544 MRB_API mrb_noreturn void 545 mrb_argnum_error(mrb_state *mrb, mrb_int argc, int min, int max) 546 { 547 #define FMT(exp) "wrong number of arguments (given %i, expected " exp ")" 548 if (min == max) 549 mrb_raisef(mrb, E_ARGUMENT_ERROR, FMT("%d"), argc, min); 550 else if (max < 0) 551 mrb_raisef(mrb, E_ARGUMENT_ERROR, FMT("%d+"), argc, min); 552 else 553 mrb_raisef(mrb, E_ARGUMENT_ERROR, FMT("%d..%d"), argc, min, max); 554 #undef FMT 555 } 556 472 557 void 473 558 mrb_init_exception(mrb_state *mrb) … … 477 562 mrb->eException_class = exception = mrb_define_class(mrb, "Exception", mrb->object_class); /* 15.2.22 */ 478 563 MRB_SET_INSTANCE_TT(exception, MRB_TT_EXCEPTION); 479 mrb_define_class_method(mrb, exception, "exception", mrb_instance_new, MRB_ARGS_ ANY());480 mrb_define_method(mrb, exception, "exception", exc_exception, MRB_ARGS_ ANY());481 mrb_define_method(mrb, exception, "initialize", exc_initialize, MRB_ARGS_ ANY());564 mrb_define_class_method(mrb, exception, "exception", mrb_instance_new, MRB_ARGS_OPT(1)); 565 mrb_define_method(mrb, exception, "exception", exc_exception, MRB_ARGS_OPT(1)); 566 mrb_define_method(mrb, exception, "initialize", exc_initialize, MRB_ARGS_OPT(1)); 482 567 mrb_define_method(mrb, exception, "to_s", exc_to_s, MRB_ARGS_NONE()); 483 568 mrb_define_method(mrb, exception, "message", exc_message, MRB_ARGS_NONE()); 484 mrb_define_method(mrb, exception, "inspect", exc_inspect,MRB_ARGS_NONE());569 mrb_define_method(mrb, exception, "inspect", mrb_exc_inspect, MRB_ARGS_NONE()); 485 570 mrb_define_method(mrb, exception, "backtrace", mrb_exc_backtrace, MRB_ARGS_NONE()); 486 571 mrb_define_method(mrb, exception, "set_backtrace", exc_set_backtrace, MRB_ARGS_REQ(1)); -
EcnlProtoTool/trunk/mruby-2.1.1/src/etc.c
r331 r439 1 1 /* 2 ** etc.c -2 ** etc.c 3 3 ** 4 4 ** See Copyright Notice in mruby.h … … 9 9 #include <mruby/data.h> 10 10 #include <mruby/class.h> 11 #include <mruby/re.h>12 #include <mruby/irep.h>13 11 14 12 MRB_API struct RData* … … 27 25 mrb_data_check_type(mrb_state *mrb, mrb_value obj, const mrb_data_type *type) 28 26 { 29 if ( mrb_type(obj) != MRB_TT_DATA) {27 if (!mrb_data_p(obj)) { 30 28 mrb_check_type(mrb, obj, MRB_TT_DATA); 31 29 } … … 34 32 35 33 if (t2) { 36 mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type % S (expected %S)",37 mrb_str_new_cstr(mrb, t2->struct_name), mrb_str_new_cstr(mrb, type->struct_name));34 mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %s (expected %s)", 35 t2->struct_name, type->struct_name); 38 36 } 39 37 else { 40 struct RClass *c = mrb_class(mrb, obj); 41 42 mrb_raisef(mrb, E_TYPE_ERROR, "uninitialized %S (expected %S)", 43 mrb_obj_value(c), mrb_str_new_cstr(mrb, type->struct_name)); 38 mrb_raisef(mrb, E_TYPE_ERROR, "uninitialized %t (expected %s)", 39 obj, type->struct_name); 44 40 } 45 41 } … … 49 45 mrb_data_check_get_ptr(mrb_state *mrb, mrb_value obj, const mrb_data_type *type) 50 46 { 51 if ( mrb_type(obj) != MRB_TT_DATA) {47 if (!mrb_data_p(obj)) { 52 48 return NULL; 53 49 } … … 68 64 mrb_obj_to_sym(mrb_state *mrb, mrb_value name) 69 65 { 70 mrb_sym id; 71 72 switch (mrb_type(name)) { 73 default: 74 name = mrb_check_string_type(mrb, name); 75 if (mrb_nil_p(name)) { 76 name = mrb_inspect(mrb, name); 77 mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a symbol", name); 78 } 79 /* fall through */ 80 case MRB_TT_STRING: 81 name = mrb_str_intern(mrb, name); 82 /* fall through */ 83 case MRB_TT_SYMBOL: 84 id = mrb_symbol(name); 85 } 86 return id; 66 if (mrb_symbol_p(name)) return mrb_symbol(name); 67 if (mrb_string_p(name)) return mrb_intern_str(mrb, name); 68 mrb_raisef(mrb, E_TYPE_ERROR, "%!v is not a symbol nor a string", name); 69 return 0; /* not reached */ 87 70 } 88 71 89 72 MRB_API mrb_int 73 #ifdef MRB_WITHOUT_FLOAT 74 mrb_fixnum_id(mrb_int f) 75 #else 90 76 mrb_float_id(mrb_float f) 77 #endif 91 78 { 92 79 const char *p = (const char*)&f; 93 80 int len = sizeof(f); 94 mrb_int id = 0; 95 81 uint32_t id = 0; 82 83 #ifndef MRB_WITHOUT_FLOAT 84 /* normalize -0.0 to 0.0 */ 85 if (f == 0) f = 0.0; 86 #endif 96 87 while (len--) { 97 88 id = id*65599 + *p; … … 100 91 id = id + (id>>5); 101 92 102 return id;93 return (mrb_int)id; 103 94 } 104 95 … … 124 115 return MakeID(mrb_symbol(obj)); 125 116 case MRB_TT_FIXNUM: 117 #ifdef MRB_WITHOUT_FLOAT 118 return MakeID(mrb_fixnum_id(mrb_fixnum(obj))); 119 #else 126 120 return MakeID2(mrb_float_id((mrb_float)mrb_fixnum(obj)), MRB_TT_FLOAT); 127 121 case MRB_TT_FLOAT: 128 122 return MakeID(mrb_float_id(mrb_float(obj))); 123 #endif 129 124 case MRB_TT_STRING: 130 125 case MRB_TT_OBJECT: … … 147 142 148 143 #ifdef MRB_WORD_BOXING 144 #ifndef MRB_WITHOUT_FLOAT 149 145 MRB_API mrb_value 150 146 mrb_word_boxing_float_value(mrb_state *mrb, mrb_float f) … … 154 150 v.value.p = mrb_obj_alloc(mrb, MRB_TT_FLOAT, mrb->float_class); 155 151 v.value.fp->f = f; 152 MRB_SET_FROZEN_FLAG(v.value.bp); 156 153 return v; 157 154 } … … 164 161 nf->c = mrb->float_class; 165 162 nf->f = f; 163 MRB_SET_FROZEN_FLAG(nf); 166 164 return mrb_obj_value(nf); 167 165 } 166 #endif /* MRB_WITHOUT_FLOAT */ 168 167 169 168 MRB_API mrb_value … … 177 176 } 178 177 #endif /* MRB_WORD_BOXING */ 179 180 MRB_API mrb_bool181 mrb_regexp_p(mrb_state *mrb, mrb_value v)182 {183 if (mrb->flags & MRB_STATE_NO_REGEXP) {184 return FALSE;185 }186 if ((mrb->flags & MRB_STATE_REGEXP) || mrb_class_defined(mrb, REGEXP_CLASS)) {187 mrb->flags |= MRB_STATE_REGEXP;188 return mrb_obj_is_kind_of(mrb, v, mrb_class_get(mrb, REGEXP_CLASS));189 }190 else {191 mrb->flags |= MRB_STATE_REGEXP;192 mrb->flags |= MRB_STATE_NO_REGEXP;193 }194 return FALSE;195 }196 178 197 179 #if defined _MSC_VER && _MSC_VER < 1900 -
EcnlProtoTool/trunk/mruby-2.1.1/src/fmt_fp.c
r331 r439 1 #ifndef MRB_WITHOUT_FLOAT 2 #if defined(MRB_DISABLE_STDIO) || defined(_WIN32) || defined(_WIN64) 1 3 /* 2 4 … … 29 31 #include <limits.h> 30 32 #include <string.h> 31 #include <stdint.h>32 33 #include <math.h> 33 34 #include <float.h> … … 62 63 #define PAD_SIZE 256 63 64 static void 64 pad(struct fmt_args *f, char c, int w, int l, int fl)65 pad(struct fmt_args *f, char c, ptrdiff_t w, ptrdiff_t l, uint8_t fl) 65 66 { 66 67 char pad[PAD_SIZE]; … … 92 93 93 94 static int 94 fmt_fp(struct fmt_args *f, long double y, int w, int p, int fl, int t)95 fmt_fp(struct fmt_args *f, long double y, ptrdiff_t p, uint8_t fl, int t) 95 96 { 96 97 uint32_t big[(LDBL_MANT_DIG+28)/29 + 1 // mantissa expansion … … 98 99 uint32_t *a, *d, *r, *z; 99 100 uint32_t i; 100 int e2=0, e, j, l; 101 int e2=0, e, j; 102 ptrdiff_t l; 101 103 char buf[9+LDBL_MANT_DIG/4], *s; 102 104 const char *prefix="-0X+0X 0X-0x+0x 0x"; 103 int pl;105 ptrdiff_t pl; 104 106 char ebuf0[3*sizeof(int)], *ebuf=&ebuf0[3*sizeof(int)], *estr; 105 107 … … 116 118 const char *ss = (t&32)?"inf":"INF"; 117 119 if (y!=y) ss=(t&32)?"nan":"NAN"; 118 pad(f, ' ', w, 3+pl, fl&~ZERO_PAD);120 pad(f, ' ', 0, 3+pl, fl&~ZERO_PAD); 119 121 out(f, prefix, pl); 120 122 out(f, ss, 3); 121 pad(f, ' ', w, 3+pl, fl^LEFT_ADJ);122 return MAX(w, 3+pl);123 pad(f, ' ', 0, 3+pl, fl^LEFT_ADJ); 124 return 3+(int)pl; 123 125 } 124 126 … … 128 130 if ((t|32)=='a') { 129 131 long double round = 8.0; 130 int re;132 ptrdiff_t re; 131 133 132 134 if (t&32) prefix += 9; … … 168 170 l = (s-buf) + (ebuf-estr); 169 171 170 pad(f, ' ', w, pl+l, fl);172 pad(f, ' ', 0, pl+l, fl); 171 173 out(f, prefix, pl); 172 pad(f, '0', w, pl+l, fl^ZERO_PAD);174 pad(f, '0', 0, pl+l, fl^ZERO_PAD); 173 175 out(f, buf, s-buf); 174 176 pad(f, '0', l-(ebuf-estr)-(s-buf), 0, 0); 175 177 out(f, estr, ebuf-estr); 176 pad(f, ' ', w, pl+l, fl^LEFT_ADJ);177 return MAX(w, pl+l);178 pad(f, ' ', 0, pl+l, fl^LEFT_ADJ); 179 return (int)pl+(int)l; 178 180 } 179 181 if (p<0) p=6; … … 203 205 while (e2<0) { 204 206 uint32_t carry=0, *b; 205 int sh=MIN(9,-e2), need=1+( p+LDBL_MANT_DIG/3+8)/9;207 int sh=MIN(9,-e2), need=1+((int)p+LDBL_MANT_DIG/3+8)/9; 206 208 for (d=a; d<z; d++) { 207 209 uint32_t rm = *d & ((1<<sh)-1); … … 217 219 } 218 220 219 if (a<z) for (i=10, e=9*( r-a); *a>=i; i*=10, e++);221 if (a<z) for (i=10, e=9*(int)(r-a); *a>=i; i*=10, e++); 220 222 else e=0; 221 223 222 224 /* Perform rounding: j is precision after the radix (possibly neg) */ 223 j = p - ((t|32)!='f')*e - ((t|32)=='g' && p);225 j = (int)p - ((t|32)!='f')*e - ((t|32)=='g' && p); 224 226 if (j < 9*(z-r-1)) { 225 227 uint32_t x; … … 248 250 (*d)++; 249 251 } 250 for (i=10, e=9*( r-a); *a>=i; i*=10, e++);252 for (i=10, e=9*(int)(r-a); *a>=i; i*=10, e++); 251 253 } 252 254 } … … 287 289 } 288 290 289 pad(f, ' ', w, pl+l, fl);291 pad(f, ' ', 0, pl+l, fl); 290 292 out(f, prefix, pl); 291 pad(f, '0', w, pl+l, fl^ZERO_PAD);293 pad(f, '0', 0, pl+l, fl^ZERO_PAD); 292 294 293 295 if ((t|32)=='f') { … … 318 320 } 319 321 out(f, ss, MIN(buf+9-ss, p)); 320 p -= buf+9-ss;322 p -= (int)(buf+9-ss); 321 323 } 322 324 pad(f, '0', p+18, 18, 0); … … 324 326 } 325 327 326 pad(f, ' ', w, pl+l, fl^LEFT_ADJ);327 328 return MAX(w, pl+l);328 pad(f, ' ', 0, pl+l, fl^LEFT_ADJ); 329 330 return (int)pl+(int)l; 329 331 } 330 332 … … 332 334 fmt_core(struct fmt_args *f, const char *fmt, mrb_float flo) 333 335 { 334 int p;336 ptrdiff_t p; 335 337 336 338 if (*fmt != '%') { … … 352 354 case 'e': case 'f': case 'g': case 'a': 353 355 case 'E': case 'F': case 'G': case 'A': 354 return fmt_fp(f, flo, 0,p, 0, *fmt);356 return fmt_fp(f, flo, p, 0, *fmt); 355 357 default: 356 358 return -1; … … 364 366 365 367 f.mrb = mrb; 366 f.str = mrb_str_ buf_new(mrb, 24);368 f.str = mrb_str_new_capa(mrb, 24); 367 369 if (fmt_core(&f, fmt, mrb_float(flo)) < 0) { 368 370 mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid format string"); … … 370 372 return f.str; 371 373 } 374 #else /* MRB_DISABLE_STDIO || _WIN32 || _WIN64 */ 375 #include <mruby.h> 376 #include <stdio.h> 377 378 mrb_value 379 mrb_float_to_str(mrb_state *mrb, mrb_value flo, const char *fmt) 380 { 381 char buf[25]; 382 383 snprintf(buf, sizeof(buf), fmt, mrb_float(flo)); 384 return mrb_str_new_cstr(mrb, buf); 385 } 386 #endif /* MRB_DISABLE_STDIO || _WIN32 || _WIN64 */ 387 #endif -
EcnlProtoTool/trunk/mruby-2.1.1/src/gc.c
r331 r439 11 11 #include <mruby/class.h> 12 12 #include <mruby/data.h> 13 #include <mruby/istruct.h> 13 14 #include <mruby/hash.h> 14 15 #include <mruby/proc.h> … … 110 111 struct RRange range; 111 112 struct RData data; 113 struct RIStruct istruct; 112 114 struct RProc proc; 113 115 struct REnv env; 116 struct RFiber fiber; 114 117 struct RException exc; 115 118 struct RBreak brk; 116 119 #ifdef MRB_WORD_BOXING 120 #ifndef MRB_WITHOUT_FLOAT 117 121 struct RFloat floatv; 122 #endif 118 123 struct RCptr cptr; 119 124 #endif … … 176 181 #define GC_STEP_SIZE 1024 177 182 178 /* white: 0 11, black: 100, gray: 000 */183 /* white: 001 or 010, black: 100, gray: 000 */ 179 184 #define GC_GRAY 0 180 185 #define GC_WHITE_A 1 … … 273 278 } 274 279 280 MRB_API void* 281 mrb_alloca(mrb_state *mrb, size_t size) 282 { 283 struct RString *s; 284 s = (struct RString*)mrb_obj_alloc(mrb, MRB_TT_STRING, mrb->string_class); 285 return s->as.heap.ptr = (char*)mrb_malloc(mrb, size); 286 } 287 288 static mrb_bool 289 heap_p(mrb_gc *gc, struct RBasic *object) 290 { 291 mrb_heap_page* page; 292 293 page = gc->heaps; 294 while (page) { 295 RVALUE *p; 296 297 p = objects(page); 298 if (&p[0].as.basic <= object && object <= &p[MRB_HEAP_PAGE_SIZE].as.basic) { 299 return TRUE; 300 } 301 page = page->next; 302 } 303 return FALSE; 304 } 305 275 306 MRB_API mrb_bool 276 307 mrb_object_dead_p(mrb_state *mrb, struct RBasic *object) { 277 return is_dead(&mrb->gc, object); 308 mrb_gc *gc = &mrb->gc; 309 if (!heap_p(gc, object)) return TRUE; 310 return is_dead(gc, object); 278 311 } 279 312 … … 343 376 #define DEFAULT_GC_INTERVAL_RATIO 200 344 377 #define DEFAULT_GC_STEP_RATIO 200 345 #define DEFAULT_MAJOR_GC_INC_RATIO 200 378 #define MAJOR_GC_INC_RATIO 120 379 #define MAJOR_GC_TOOMANY 10000 346 380 #define is_generational(gc) ((gc)->generational) 347 381 #define is_major_gc(gc) (is_generational(gc) && (gc)->full) … … 374 408 static void obj_free(mrb_state *mrb, struct RBasic *obj, int end); 375 409 376 void410 static void 377 411 free_heap(mrb_state *mrb, mrb_gc *gc) 378 412 { … … 413 447 if (gc->arena_idx >= gc->arena_capa) { 414 448 /* extend arena */ 415 gc->arena_capa = (int)(gc->arena_capa * 1.5);449 gc->arena_capa = (int)(gc->arena_capa * 3 / 2); 416 450 gc->arena = (struct RBasic**)mrb_realloc(mrb, gc->arena, sizeof(struct RBasic*)*gc->arena_capa); 417 451 } … … 441 475 mrb_gc_register(mrb_state *mrb, mrb_value obj) 442 476 { 443 mrb_sym root = mrb_intern_lit(mrb, GC_ROOT_NAME); 444 mrb_value table = mrb_gv_get(mrb, root); 445 446 if (mrb_nil_p(table) || mrb_type(table) != MRB_TT_ARRAY) { 477 mrb_sym root; 478 mrb_value table; 479 480 if (mrb_immediate_p(obj)) return; 481 root = mrb_intern_lit(mrb, GC_ROOT_NAME); 482 table = mrb_gv_get(mrb, root); 483 if (mrb_nil_p(table) || !mrb_array_p(table)) { 447 484 table = mrb_ary_new(mrb); 448 485 mrb_gv_set(mrb, root, table); … … 455 492 mrb_gc_unregister(mrb_state *mrb, mrb_value obj) 456 493 { 457 mrb_sym root = mrb_intern_lit(mrb, GC_ROOT_NAME);458 mrb_value table = mrb_gv_get(mrb, root);494 mrb_sym root; 495 mrb_value table; 459 496 struct RArray *a; 460 497 mrb_int i; 461 498 499 if (mrb_immediate_p(obj)) return; 500 root = mrb_intern_lit(mrb, GC_ROOT_NAME); 501 table = mrb_gv_get(mrb, root); 462 502 if (mrb_nil_p(table)) return; 463 if ( mrb_type(table) != MRB_TT_ARRAY) {503 if (!mrb_array_p(table)) { 464 504 mrb_gv_set(mrb, root, mrb_nil_value()); 465 505 return; … … 467 507 a = mrb_ary_ptr(table); 468 508 mrb_ary_modify(mrb, a); 469 for (i = 0; i < a->len; i++) { 470 if (mrb_obj_eq(mrb, a->ptr[i], obj)) { 471 a->len--; 472 memmove(&a->ptr[i], &a->ptr[i + 1], (a->len - i) * sizeof(a->ptr[i])); 509 for (i = 0; i < ARY_LEN(a); i++) { 510 if (mrb_ptr(ARY_PTR(a)[i]) == mrb_ptr(obj)) { 511 mrb_int len = ARY_LEN(a)-1; 512 mrb_value *ptr = ARY_PTR(a); 513 514 ARY_SET_LEN(a, len); 515 memmove(&ptr[i], &ptr[i + 1], (len - i) * sizeof(mrb_value)); 473 516 break; 474 517 } … … 480 523 { 481 524 struct RBasic *p; 482 static const RVALUE RVALUE_zero = { { { MRB_TT_FALSE } } };525 static const RVALUE RVALUE_zero = { { { NULL, NULL, MRB_TT_FALSE } } }; 483 526 mrb_gc *gc = &mrb->gc; 484 527 … … 501 544 ttype != MRB_TT_ENV && 502 545 ttype != tt) { 503 mrb_raisef(mrb, E_TYPE_ERROR, "allocation failure of % S", mrb_obj_value(cls));546 mrb_raisef(mrb, E_TYPE_ERROR, "allocation failure of %C", cls); 504 547 } 505 548 } … … 543 586 } 544 587 588 static int 589 ci_nregs(mrb_callinfo *ci) 590 { 591 struct RProc *p = ci->proc; 592 int n = 0; 593 594 if (!p) { 595 if (ci->argc < 0) return 3; 596 return ci->argc+2; 597 } 598 if (!MRB_PROC_CFUNC_P(p) && p->body.irep) { 599 n = p->body.irep->nregs; 600 } 601 if (ci->argc < 0) { 602 if (n < 3) n = 3; /* self + args + blk */ 603 } 604 if (ci->argc > n) { 605 n = ci->argc + 2; /* self + blk */ 606 } 607 return n; 608 } 609 545 610 static void 546 611 mark_context_stack(mrb_state *mrb, struct mrb_context *c) … … 549 614 size_t e; 550 615 mrb_value nil; 551 int nregs;552 616 553 617 if (c->stack == NULL) return; 554 618 e = c->stack - c->stbase; 555 619 if (c->ci) { 556 nregs = c->ci->argc + 2; 557 if (c->ci->nregs > nregs) 558 nregs = c->ci->nregs; 559 e += nregs; 620 e += ci_nregs(c->ci); 560 621 } 561 622 if (c->stbase + e > c->stend) e = c->stend - c->stbase; … … 579 640 int i; 580 641 mrb_callinfo *ci; 642 643 start: 644 if (c->status == MRB_FIBER_TERMINATED) return; 581 645 582 646 /* mark VM stack */ … … 592 656 } 593 657 /* mark ensure stack */ 594 for (i=0; i<c->esize; i++) { 595 if (c->ensure[i] == NULL) break; 658 for (i=0; i<c->eidx; i++) { 596 659 mrb_gc_mark(mrb, (struct RBasic*)c->ensure[i]); 597 660 } … … 599 662 mrb_gc_mark(mrb, (struct RBasic*)c->fib); 600 663 if (c->prev) { 601 mark_context(mrb, c->prev); 664 c = c->prev; 665 goto start; 602 666 } 603 667 } … … 614 678 { 615 679 struct RClass *c = (struct RClass*)obj; 616 if (MRB_FLAG_TEST(c, MRB_FL AG_IS_ORIGIN))680 if (MRB_FLAG_TEST(c, MRB_FL_CLASS_IS_ORIGIN)) 617 681 mrb_gc_mark_mt(mrb, c); 618 682 mrb_gc_mark(mrb, (struct RBasic*)((struct RClass*)obj)->super); … … 641 705 struct RProc *p = (struct RProc*)obj; 642 706 643 mrb_gc_mark(mrb, (struct RBasic*)p-> env);644 mrb_gc_mark(mrb, (struct RBasic*)p-> target_class);707 mrb_gc_mark(mrb, (struct RBasic*)p->upper); 708 mrb_gc_mark(mrb, (struct RBasic*)p->e.env); 645 709 } 646 710 break; … … 651 715 mrb_int i, len; 652 716 653 if (MRB_ENV_STACK_SHARED_P(e)) { 654 if (e->cxt.c->fib) { 655 mrb_gc_mark(mrb, (struct RBasic*)e->cxt.c->fib); 656 } 657 break; 717 if (MRB_ENV_STACK_SHARED_P(e) && e->cxt && e->cxt->fib) { 718 mrb_gc_mark(mrb, (struct RBasic*)e->cxt->fib); 658 719 } 659 720 len = MRB_ENV_STACK_LEN(e); … … 677 738 size_t i, e; 678 739 679 for (i=0,e= a->len; i<e; i++) {680 mrb_gc_mark_value(mrb, a->ptr[i]);740 for (i=0,e=ARY_LEN(a); i<e; i++) { 741 mrb_gc_mark_value(mrb, ARY_PTR(a)[i]); 681 742 } 682 743 } … … 689 750 690 751 case MRB_TT_STRING: 752 if (RSTR_FSHARED_P(obj)) { 753 struct RString *s = (struct RString*)obj; 754 mrb_gc_mark(mrb, (struct RBasic*)s->as.heap.aux.fshared); 755 } 691 756 break; 692 757 693 758 case MRB_TT_RANGE: 694 { 695 struct RRange *r = (struct RRange*)obj; 696 697 if (r->edges) { 698 mrb_gc_mark_value(mrb, r->edges->beg); 699 mrb_gc_mark_value(mrb, r->edges->end); 700 } 701 } 759 mrb_gc_mark_range(mrb, (struct RRange*)obj); 702 760 break; 703 761 … … 728 786 return; 729 787 788 #ifndef MRB_WITHOUT_FLOAT 730 789 case MRB_TT_FLOAT: 731 790 #ifdef MRB_WORD_BOXING … … 733 792 #else 734 793 return; 794 #endif 735 795 #endif 736 796 … … 748 808 mrb_gc_free_mt(mrb, (struct RClass*)obj); 749 809 mrb_gc_free_iv(mrb, (struct RObject*)obj); 810 mrb_mc_clear_by_class(mrb, (struct RClass*)obj); 750 811 break; 751 812 case MRB_TT_ICLASS: 752 if (MRB_FLAG_TEST(obj, MRB_FL AG_IS_ORIGIN))813 if (MRB_FLAG_TEST(obj, MRB_FL_CLASS_IS_ORIGIN)) 753 814 mrb_gc_free_mt(mrb, (struct RClass*)obj); 815 mrb_mc_clear_by_class(mrb, (struct RClass*)obj); 754 816 break; 755 817 case MRB_TT_ENV: … … 759 821 if (MRB_ENV_STACK_SHARED_P(e)) { 760 822 /* cannot be freed */ 761 return; 823 e->stack = NULL; 824 break; 762 825 } 763 826 mrb_free(mrb, e->stack); … … 770 833 struct mrb_context *c = ((struct RFiber*)obj)->cxt; 771 834 772 if (!end && c && c != mrb->root_c) { 773 mrb_callinfo *ci = c->ci; 774 mrb_callinfo *ce = c->cibase; 775 776 while (ce <= ci) { 777 struct REnv *e = ci->env; 778 if (e && !is_dead(&mrb->gc, e) && 779 e->tt == MRB_TT_ENV && MRB_ENV_STACK_SHARED_P(e)) { 780 mrb_env_unshare(mrb, e); 835 if (c && c != mrb->root_c) { 836 if (!end && c->status != MRB_FIBER_TERMINATED) { 837 mrb_callinfo *ci = c->ci; 838 mrb_callinfo *ce = c->cibase; 839 840 while (ce <= ci) { 841 struct REnv *e = ci->env; 842 if (e && !mrb_object_dead_p(mrb, (struct RBasic*)e) && 843 e->tt == MRB_TT_ENV && MRB_ENV_STACK_SHARED_P(e)) { 844 mrb_env_unshare(mrb, e); 845 } 846 ci--; 781 847 } 782 ci--;783 848 } 784 849 mrb_free_context(mrb, c); … … 789 854 case MRB_TT_ARRAY: 790 855 if (ARY_SHARED_P(obj)) 791 mrb_ary_decref(mrb, ((struct RArray*)obj)->a ux.shared);792 else 793 mrb_free(mrb, ((struct RArray*)obj)-> ptr);856 mrb_ary_decref(mrb, ((struct RArray*)obj)->as.heap.aux.shared); 857 else if (!ARY_EMBED_P(obj)) 858 mrb_free(mrb, ((struct RArray*)obj)->as.heap.ptr); 794 859 break; 795 860 … … 808 873 809 874 if (!MRB_PROC_CFUNC_P(p) && p->body.irep) { 810 mrb_irep_decref(mrb, p->body.irep); 875 mrb_irep *irep = p->body.irep; 876 if (end) { 877 mrb_irep_cutref(mrb, irep); 878 } 879 mrb_irep_decref(mrb, irep); 811 880 } 812 881 } … … 814 883 815 884 case MRB_TT_RANGE: 816 mrb_ free(mrb, ((struct RRange*)obj)->edges);885 mrb_gc_free_range(mrb, ((struct RRange*)obj)); 817 886 break; 818 887 … … 858 927 mrb_gc_mark(mrb, (struct RBasic*)mrb->array_class); 859 928 mrb_gc_mark(mrb, (struct RBasic*)mrb->hash_class); 860 929 mrb_gc_mark(mrb, (struct RBasic*)mrb->range_class); 930 931 #ifndef MRB_WITHOUT_FLOAT 861 932 mrb_gc_mark(mrb, (struct RBasic*)mrb->float_class); 933 #endif 862 934 mrb_gc_mark(mrb, (struct RBasic*)mrb->fixnum_class); 863 935 mrb_gc_mark(mrb, (struct RBasic*)mrb->true_class); … … 918 990 919 991 case MRB_TT_ENV: 920 children += (int)obj->flags;992 children += MRB_ENV_STACK_LEN(obj); 921 993 break; 922 994 … … 927 999 mrb_callinfo *ci; 928 1000 929 if (!c) break; 1001 if (!c || c->status == MRB_FIBER_TERMINATED) break; 1002 930 1003 /* mark stack */ 931 1004 i = c->stack - c->stbase; 932 if (c->ci) i += c->ci->nregs; 1005 1006 if (c->ci) { 1007 i += ci_nregs(c->ci); 1008 } 933 1009 if (c->stbase + i > c->stend) i = c->stend - c->stbase; 934 1010 children += i; … … 949 1025 { 950 1026 struct RArray *a = (struct RArray*)obj; 951 children += a->len;1027 children += ARY_LEN(a); 952 1028 } 953 1029 break; … … 1190 1266 1191 1267 if (is_major_gc(gc)) { 1192 gc->majorgc_old_threshold = gc->live_after_mark/100 * DEFAULT_MAJOR_GC_INC_RATIO; 1268 size_t threshold = gc->live_after_mark/100 * MAJOR_GC_INC_RATIO; 1269 1193 1270 gc->full = FALSE; 1271 if (threshold < MAJOR_GC_TOOMANY) { 1272 gc->majorgc_old_threshold = threshold; 1273 } 1274 else { 1275 /* too many objects allocated during incremental GC, */ 1276 /* instead of increasing threshold, invoke full GC. */ 1277 mrb_full_gc(mrb); 1278 } 1194 1279 } 1195 1280 else if (is_minor_gc(gc)) { … … 1229 1314 1230 1315 if (is_generational(gc)) { 1231 gc->majorgc_old_threshold = gc->live_after_mark/100 * DEFAULT_MAJOR_GC_INC_RATIO;1316 gc->majorgc_old_threshold = gc->live_after_mark/100 * MAJOR_GC_INC_RATIO; 1232 1317 gc->full = FALSE; 1233 1318 } … … 1240 1325 { 1241 1326 mrb_full_gc(mrb); 1242 }1243 1244 MRB_API int1245 mrb_gc_arena_save(mrb_state *mrb)1246 {1247 return mrb->gc.arena_idx;1248 }1249 1250 MRB_API void1251 mrb_gc_arena_restore(mrb_state *mrb, int idx)1252 {1253 mrb_gc *gc = &mrb->gc;1254 1255 #ifndef MRB_GC_FIXED_ARENA1256 int capa = gc->arena_capa;1257 1258 if (idx < capa / 2) {1259 capa = (int)(capa * 0.66);1260 if (capa < MRB_GC_ARENA_SIZE) {1261 capa = MRB_GC_ARENA_SIZE;1262 }1263 if (capa != gc->arena_capa) {1264 gc->arena = (struct RBasic**)mrb_realloc(mrb, gc->arena, sizeof(struct RBasic*)*capa);1265 gc->arena_capa = capa;1266 }1267 }1268 #endif1269 gc->arena_idx = idx;1270 1327 } 1271 1328 … … 1407 1464 1408 1465 mrb_get_args(mrb, "i", &ratio); 1409 mrb->gc.interval_ratio = ratio;1466 mrb->gc.interval_ratio = (int)ratio; 1410 1467 return mrb_nil_value(); 1411 1468 } … … 1440 1497 1441 1498 mrb_get_args(mrb, "i", &ratio); 1442 mrb->gc.step_ratio = ratio;1499 mrb->gc.step_ratio = (int)ratio; 1443 1500 return mrb_nil_value(); 1444 1501 } … … 1458 1515 else if (!is_generational(gc) && enable) { 1459 1516 incremental_gc_until(mrb, gc, MRB_GC_STATE_ROOT); 1460 gc->majorgc_old_threshold = gc->live_after_mark/100 * DEFAULT_MAJOR_GC_INC_RATIO;1517 gc->majorgc_old_threshold = gc->live_after_mark/100 * MAJOR_GC_INC_RATIO; 1461 1518 gc->full = FALSE; 1462 1519 } … … 1523 1580 mrb_bool iterating = mrb->gc.iterating; 1524 1581 1582 mrb_full_gc(mrb); 1525 1583 mrb->gc.iterating = TRUE; 1526 1584 if (iterating) { … … 1535 1593 gc_each_objects(mrb, &mrb->gc, callback, data); 1536 1594 mrb->jmp = prev_jmp; 1537 mrb->gc.iterating = iterating; 1595 mrb->gc.iterating = iterating; 1538 1596 } MRB_CATCH(&c_jmp) { 1539 1597 mrb->gc.iterating = iterating; … … 1554 1612 { 1555 1613 struct RClass *gc; 1614 1615 mrb_static_assert(sizeof(RVALUE) <= sizeof(void*) * 6, 1616 "RVALUE size must be within 6 words"); 1556 1617 1557 1618 gc = mrb_define_module(mrb, "GC"); -
EcnlProtoTool/trunk/mruby-2.1.1/src/hash.c
r331 r439 9 9 #include <mruby/class.h> 10 10 #include <mruby/hash.h> 11 #include <mruby/khash.h>12 11 #include <mruby/string.h> 13 12 #include <mruby/variable.h> 14 13 14 #ifndef MRB_WITHOUT_FLOAT 15 15 /* a function to get hash value of a float number */ 16 16 mrb_int mrb_float_id(mrb_float f); 17 18 static inline khint_t 19 mrb_hash_ht_hash_func(mrb_state *mrb, mrb_value key) 20 { 21 enum mrb_vtype t = mrb_type(key); 17 #endif 18 19 #ifndef MRB_HT_INIT_SIZE 20 #define MRB_HT_INIT_SIZE 4 21 #endif 22 #define HT_SEG_INCREASE_RATIO 6 / 5 23 24 struct segkv { 25 mrb_value key; 26 mrb_value val; 27 }; 28 29 typedef struct segment { 30 uint16_t size; 31 struct segment *next; 32 struct segkv e[]; 33 } segment; 34 35 typedef struct segindex { 36 size_t size; 37 size_t capa; 38 struct segkv *table[]; 39 } segindex; 40 41 /* hash table structure */ 42 typedef struct htable { 43 segment *rootseg; 44 segment *lastseg; 45 mrb_int size; 46 uint16_t last_len; 47 segindex *index; 48 } htable; 49 50 static /* inline */ size_t 51 ht_hash_func(mrb_state *mrb, htable *t, mrb_value key) 52 { 53 enum mrb_vtype tt = mrb_type(key); 22 54 mrb_value hv; 23 const char *p;24 mrb_int i, len;25 khint_t h;26 27 switch (t ) {55 size_t h; 56 segindex *index = t->index; 57 size_t capa = index ? index->capa : 0; 58 59 switch (tt) { 28 60 case MRB_TT_STRING: 29 p = RSTRING_PTR(key); 30 len = RSTRING_LEN(key); 31 h = 0; 32 for (i=0; i<len; i++) { 33 h = (h << 5) - h + *p++; 34 } 35 return h; 36 61 h = mrb_str_hash(mrb, key); 62 break; 63 64 case MRB_TT_TRUE: 65 case MRB_TT_FALSE: 37 66 case MRB_TT_SYMBOL: 38 h = (khint_t)mrb_symbol(key);39 return kh_int_hash_func(mrb, h);40 41 67 case MRB_TT_FIXNUM: 42 h = (khint_t)mrb_float_id((mrb_float)mrb_fixnum(key)); 43 return kh_int_hash_func(mrb, h); 44 68 #ifndef MRB_WITHOUT_FLOAT 45 69 case MRB_TT_FLOAT: 46 h = (khint_t)mrb_float_id(mrb_float(key)); 47 return kh_int_hash_func(mrb, h); 70 #endif 71 h = (size_t)mrb_obj_id(key); 72 break; 48 73 49 74 default: 50 75 hv = mrb_funcall(mrb, key, "hash", 0); 51 h = (khint_t)t ^ mrb_fixnum(hv); 52 return kh_int_hash_func(mrb, h); 53 } 54 } 55 56 static inline khint_t 57 mrb_hash_ht_hash_equal(mrb_state *mrb, mrb_value a, mrb_value b) 58 { 59 enum mrb_vtype t = mrb_type(a); 60 61 switch (t) { 76 h = (size_t)t ^ (size_t)mrb_fixnum(hv); 77 break; 78 } 79 if (index && (index != t->index || capa != index->capa)) { 80 mrb_raise(mrb, E_RUNTIME_ERROR, "hash modified"); 81 } 82 return ((h)^((h)<<2)^((h)>>2)); 83 } 84 85 static inline mrb_bool 86 ht_hash_equal(mrb_state *mrb, htable *t, mrb_value a, mrb_value b) 87 { 88 enum mrb_vtype tt = mrb_type(a); 89 90 switch (tt) { 62 91 case MRB_TT_STRING: 63 92 return mrb_str_equal(mrb, a, b); 64 93 65 94 case MRB_TT_SYMBOL: 66 if ( mrb_type(b) != MRB_TT_SYMBOL) return FALSE;95 if (!mrb_symbol_p(b)) return FALSE; 67 96 return mrb_symbol(a) == mrb_symbol(b); 68 97 … … 71 100 case MRB_TT_FIXNUM: 72 101 return mrb_fixnum(a) == mrb_fixnum(b); 102 #ifndef MRB_WITHOUT_FLOAT 73 103 case MRB_TT_FLOAT: 74 104 return (mrb_float)mrb_fixnum(a) == mrb_float(b); 105 #endif 75 106 default: 76 107 return FALSE; 77 108 } 78 109 110 #ifndef MRB_WITHOUT_FLOAT 79 111 case MRB_TT_FLOAT: 80 112 switch (mrb_type(b)) { … … 86 118 return FALSE; 87 119 } 120 #endif 88 121 89 122 default: 90 return mrb_eql(mrb, a, b); 91 } 92 } 93 94 KHASH_DEFINE (ht, mrb_value, mrb_hash_value, TRUE, mrb_hash_ht_hash_func, mrb_hash_ht_hash_equal) 123 { 124 segindex *index = t->index; 125 size_t capa = index ? index->capa : 0; 126 mrb_bool eql = mrb_eql(mrb, a, b); 127 if (index && (index != t->index || capa != index->capa)) { 128 mrb_raise(mrb, E_RUNTIME_ERROR, "hash modified"); 129 } 130 return eql; 131 } 132 } 133 } 134 135 /* Creates the hash table. */ 136 static htable* 137 ht_new(mrb_state *mrb) 138 { 139 htable *t; 140 141 t = (htable*)mrb_malloc(mrb, sizeof(htable)); 142 t->size = 0; 143 t->rootseg = NULL; 144 t->lastseg = NULL; 145 t->last_len = 0; 146 t->index = NULL; 147 148 return t; 149 } 150 151 #define power2(v) do { \ 152 v--;\ 153 v |= v >> 1;\ 154 v |= v >> 2;\ 155 v |= v >> 4;\ 156 v |= v >> 8;\ 157 v |= v >> 16;\ 158 v++;\ 159 } while (0) 160 161 #ifndef UPPER_BOUND 162 #define UPPER_BOUND(x) ((x)>>2|(x)>>1) 163 #endif 164 165 #define HT_MASK(index) ((index->capa)-1) 166 167 /* Build index for the hash table */ 168 static void 169 ht_index(mrb_state *mrb, htable *t) 170 { 171 size_t size = (size_t)t->size; 172 size_t mask; 173 segindex *index = t->index; 174 segment *seg; 175 size_t i; 176 177 /* allocate index table */ 178 if (index && index->size >= UPPER_BOUND(index->capa)) { 179 size = index->capa+1; 180 } 181 power2(size); 182 if (!index || index->capa < size) { 183 index = (segindex*)mrb_realloc_simple(mrb, index, sizeof(segindex)+sizeof(struct segkv*)*size); 184 if (index == NULL) { 185 mrb_free(mrb, t->index); 186 t->index = NULL; 187 return; 188 } 189 t->index = index; 190 } 191 index->size = t->size; 192 index->capa = size; 193 for (i=0; i<size; i++) { 194 index->table[i] = NULL; 195 } 196 197 /* rebuld index */ 198 mask = HT_MASK(index); 199 seg = t->rootseg; 200 while (seg) { 201 for (i=0; i<seg->size; i++) { 202 mrb_value key; 203 size_t k, step = 0; 204 205 if (!seg->next && i >= (size_t)t->last_len) { 206 return; 207 } 208 key = seg->e[i].key; 209 if (mrb_undef_p(key)) continue; 210 k = ht_hash_func(mrb, t, key) & mask; 211 while (index->table[k]) { 212 k = (k+(++step)) & mask; 213 } 214 index->table[k] = &seg->e[i]; 215 } 216 seg = seg->next; 217 } 218 } 219 220 /* Compacts the hash table removing deleted entries. */ 221 static void 222 ht_compact(mrb_state *mrb, htable *t) 223 { 224 segment *seg; 225 uint16_t i, i2; 226 segment *seg2 = NULL; 227 mrb_int size = 0; 228 229 if (t == NULL) return; 230 seg = t->rootseg; 231 if (t->index && (size_t)t->size == t->index->size) { 232 ht_index(mrb, t); 233 return; 234 } 235 while (seg) { 236 for (i=0; i<seg->size; i++) { 237 mrb_value k = seg->e[i].key; 238 239 if (!seg->next && i >= t->last_len) { 240 goto exit; 241 } 242 if (mrb_undef_p(k)) { /* found deleted key */ 243 if (seg2 == NULL) { 244 seg2 = seg; 245 i2 = i; 246 } 247 } 248 else { 249 size++; 250 if (seg2 != NULL) { 251 seg2->e[i2++] = seg->e[i]; 252 if (i2 >= seg2->size) { 253 seg2 = seg2->next; 254 i2 = 0; 255 } 256 } 257 } 258 } 259 seg = seg->next; 260 } 261 exit: 262 /* reached at end */ 263 t->size = size; 264 if (seg2) { 265 seg = seg2->next; 266 seg2->next = NULL; 267 t->last_len = i2; 268 t->lastseg = seg2; 269 while (seg) { 270 seg2 = seg->next; 271 mrb_free(mrb, seg); 272 seg = seg2; 273 } 274 } 275 if (t->index) { 276 ht_index(mrb, t); 277 } 278 } 279 280 static segment* 281 segment_alloc(mrb_state *mrb, segment *seg) 282 { 283 uint32_t size; 284 285 if (!seg) size = MRB_HT_INIT_SIZE; 286 else { 287 size = seg->size*HT_SEG_INCREASE_RATIO + 1; 288 if (size > UINT16_MAX) size = UINT16_MAX; 289 } 290 291 seg = (segment*)mrb_malloc(mrb, sizeof(segment)+sizeof(struct segkv)*size); 292 seg->size = size; 293 seg->next = NULL; 294 295 return seg; 296 } 297 298 /* Set the value for the key in the indexed table. */ 299 static void 300 ht_index_put(mrb_state *mrb, htable *t, mrb_value key, mrb_value val) 301 { 302 segindex *index = t->index; 303 size_t k, sp, step = 0, mask; 304 segment *seg; 305 306 if (index->size >= UPPER_BOUND(index->capa)) { 307 /* need to expand table */ 308 ht_compact(mrb, t); 309 index = t->index; 310 } 311 mask = HT_MASK(index); 312 sp = index->capa; 313 k = ht_hash_func(mrb, t, key) & mask; 314 while (index->table[k]) { 315 mrb_value key2 = index->table[k]->key; 316 if (mrb_undef_p(key2)) { 317 if (sp == index->capa) sp = k; 318 } 319 else if (ht_hash_equal(mrb, t, key, key2)) { 320 index->table[k]->val = val; 321 return; 322 } 323 k = (k+(++step)) & mask; 324 } 325 if (sp < index->capa) { 326 k = sp; 327 } 328 329 /* put the value at the last */ 330 seg = t->lastseg; 331 if (t->last_len < seg->size) { 332 index->table[k] = &seg->e[t->last_len++]; 333 } 334 else { /* append a new segment */ 335 seg->next = segment_alloc(mrb, seg); 336 seg = seg->next; 337 seg->next = NULL; 338 t->lastseg = seg; 339 t->last_len = 1; 340 index->table[k] = &seg->e[0]; 341 } 342 index->table[k]->key = key; 343 index->table[k]->val = val; 344 index->size++; 345 t->size++; 346 } 347 348 /* Set the value for the key in the hash table. */ 349 static void 350 ht_put(mrb_state *mrb, htable *t, mrb_value key, mrb_value val) 351 { 352 segment *seg; 353 mrb_int i, deleted = 0; 354 355 if (t == NULL) return; 356 if (t->index) { 357 ht_index_put(mrb, t, key, val); 358 return; 359 } 360 seg = t->rootseg; 361 while (seg) { 362 for (i=0; i<seg->size; i++) { 363 mrb_value k = seg->e[i].key; 364 /* Found room in last segment after last_len */ 365 if (!seg->next && i >= t->last_len) { 366 seg->e[i].key = key; 367 seg->e[i].val = val; 368 t->last_len = i+1; 369 t->size++; 370 return; 371 } 372 if (mrb_undef_p(k)) { 373 deleted++; 374 continue; 375 } 376 if (ht_hash_equal(mrb, t, k, key)) { 377 seg->e[i].val = val; 378 return; 379 } 380 } 381 seg = seg->next; 382 } 383 /* Not found */ 384 385 /* Compact if last segment has room */ 386 if (deleted > 0 && deleted > MRB_HT_INIT_SIZE) { 387 ht_compact(mrb, t); 388 } 389 t->size++; 390 391 /* check if thre's room after compaction */ 392 if (t->lastseg && t->last_len < t->lastseg->size) { 393 seg = t->lastseg; 394 i = t->last_len; 395 } 396 else { 397 /* append new segment */ 398 seg = segment_alloc(mrb, t->lastseg); 399 i = 0; 400 if (t->rootseg == NULL) { 401 t->rootseg = seg; 402 } 403 else { 404 t->lastseg->next = seg; 405 } 406 t->lastseg = seg; 407 } 408 seg->e[i].key = key; 409 seg->e[i].val = val; 410 t->last_len = i+1; 411 if (t->index == NULL && t->size > MRB_HT_INIT_SIZE*4) { 412 ht_index(mrb, t); 413 } 414 } 415 416 /* Get a value for a key from the indexed table. */ 417 static mrb_bool 418 ht_index_get(mrb_state *mrb, htable *t, mrb_value key, mrb_value *vp) 419 { 420 segindex *index = t->index; 421 size_t mask = HT_MASK(index); 422 size_t k = ht_hash_func(mrb, t, key) & mask; 423 size_t step = 0; 424 425 while (index->table[k]) { 426 mrb_value key2 = index->table[k]->key; 427 if (!mrb_undef_p(key2) && ht_hash_equal(mrb, t, key, key2)) { 428 if (vp) *vp = index->table[k]->val; 429 return TRUE; 430 } 431 k = (k+(++step)) & mask; 432 } 433 return FALSE; 434 } 435 436 /* Get a value for a key from the hash table. */ 437 static mrb_bool 438 ht_get(mrb_state *mrb, htable *t, mrb_value key, mrb_value *vp) 439 { 440 segment *seg; 441 mrb_int i; 442 443 if (t == NULL) return FALSE; 444 if (t->index) { 445 return ht_index_get(mrb, t, key, vp); 446 } 447 448 seg = t->rootseg; 449 while (seg) { 450 for (i=0; i<seg->size; i++) { 451 mrb_value k = seg->e[i].key; 452 453 if (!seg->next && i >= t->last_len) { 454 return FALSE; 455 } 456 if (mrb_undef_p(k)) continue; 457 if (ht_hash_equal(mrb, t, k, key)) { 458 if (vp) *vp = seg->e[i].val; 459 return TRUE; 460 } 461 } 462 seg = seg->next; 463 } 464 return FALSE; 465 } 466 467 /* Deletes the value for the symbol from the hash table. */ 468 /* Deletion is done by overwriting keys by `undef`. */ 469 static mrb_bool 470 ht_del(mrb_state *mrb, htable *t, mrb_value key, mrb_value *vp) 471 { 472 segment *seg; 473 mrb_int i; 474 475 if (t == NULL) return FALSE; 476 seg = t->rootseg; 477 while (seg) { 478 for (i=0; i<seg->size; i++) { 479 mrb_value key2; 480 481 if (!seg->next && i >= t->last_len) { 482 /* not found */ 483 return FALSE; 484 } 485 key2 = seg->e[i].key; 486 if (!mrb_undef_p(key2) && ht_hash_equal(mrb, t, key, key2)) { 487 if (vp) *vp = seg->e[i].val; 488 seg->e[i].key = mrb_undef_value(); 489 t->size--; 490 return TRUE; 491 } 492 } 493 seg = seg->next; 494 } 495 return FALSE; 496 } 497 498 /* Iterates over the hash table. */ 499 static void 500 ht_foreach(mrb_state *mrb, htable *t, mrb_hash_foreach_func *func, void *p) 501 { 502 segment *seg; 503 mrb_int i; 504 505 if (t == NULL) return; 506 seg = t->rootseg; 507 while (seg) { 508 for (i=0; i<seg->size; i++) { 509 /* no value in last segment after last_len */ 510 if (!seg->next && i >= t->last_len) { 511 return; 512 } 513 if (mrb_undef_p(seg->e[i].key)) continue; 514 if ((*func)(mrb, seg->e[i].key, seg->e[i].val, p) != 0) 515 return; 516 } 517 seg = seg->next; 518 } 519 } 520 521 /* Iterates over the hash table. */ 522 MRB_API void 523 mrb_hash_foreach(mrb_state *mrb, struct RHash *hash, mrb_hash_foreach_func *func, void *p) 524 { 525 ht_foreach(mrb, hash->ht, func, p); 526 } 527 528 /* Copy the hash table. */ 529 static htable* 530 ht_copy(mrb_state *mrb, htable *t) 531 { 532 segment *seg; 533 htable *t2; 534 mrb_int i; 535 536 seg = t->rootseg; 537 t2 = ht_new(mrb); 538 if (t->size == 0) return t2; 539 540 while (seg) { 541 for (i=0; i<seg->size; i++) { 542 mrb_value key = seg->e[i].key; 543 mrb_value val = seg->e[i].val; 544 545 if ((seg->next == NULL) && (i >= t->last_len)) { 546 return t2; 547 } 548 if (mrb_undef_p(key)) continue; /* skip deleted key */ 549 ht_put(mrb, t2, key, val); 550 } 551 seg = seg->next; 552 } 553 return t2; 554 } 555 556 /* Free memory of the hash table. */ 557 static void 558 ht_free(mrb_state *mrb, htable *t) 559 { 560 segment *seg; 561 562 if (!t) return; 563 seg = t->rootseg; 564 while (seg) { 565 segment *p = seg; 566 seg = seg->next; 567 mrb_free(mrb, p); 568 } 569 if (t->index) mrb_free(mrb, t->index); 570 mrb_free(mrb, t); 571 } 95 572 96 573 static void mrb_hash_modify(mrb_state *mrb, mrb_value hash); 97 574 98 575 static inline mrb_value 99 mrb_hash_ht_key(mrb_state *mrb, mrb_value key)100 { 101 if (mrb_string_p(key) && ! MRB_FROZEN_P(mrb_str_ptr(key))) {576 ht_key(mrb_state *mrb, mrb_value key) 577 { 578 if (mrb_string_p(key) && !mrb_frozen_p(mrb_str_ptr(key))) { 102 579 key = mrb_str_dup(mrb, key); 103 580 MRB_SET_FROZEN_FLAG(mrb_str_ptr(key)); … … 106 583 } 107 584 108 #define KEY(key) mrb_hash_ht_key(mrb, key) 585 #define KEY(key) ht_key(mrb, key) 586 587 static int 588 hash_mark_i(mrb_state *mrb, mrb_value key, mrb_value val, void *p) 589 { 590 mrb_gc_mark_value(mrb, key); 591 mrb_gc_mark_value(mrb, val); 592 return 0; 593 } 109 594 110 595 void 111 596 mrb_gc_mark_hash(mrb_state *mrb, struct RHash *hash) 112 597 { 113 khiter_t k; 114 khash_t(ht) *h = hash->ht; 115 116 if (!h) return; 117 for (k = kh_begin(h); k != kh_end(h); k++) { 118 if (kh_exist(h, k)) { 119 mrb_value key = kh_key(h, k); 120 mrb_value val = kh_value(h, k).v; 121 122 mrb_gc_mark_value(mrb, key); 123 mrb_gc_mark_value(mrb, val); 124 } 125 } 598 ht_foreach(mrb, hash->ht, hash_mark_i, NULL); 126 599 } 127 600 … … 130 603 { 131 604 if (!hash->ht) return 0; 132 return kh_size(hash->ht)*2;605 return hash->ht->size*2; 133 606 } 134 607 … … 136 609 mrb_gc_free_hash(mrb_state *mrb, struct RHash *hash) 137 610 { 138 if (hash->ht) kh_destroy(ht, mrb, hash->ht); 139 } 140 611 ht_free(mrb, hash->ht); 612 } 613 614 MRB_API mrb_value 615 mrb_hash_new(mrb_state *mrb) 616 { 617 struct RHash *h; 618 619 h = (struct RHash*)mrb_obj_alloc(mrb, MRB_TT_HASH, mrb->hash_class); 620 h->ht = 0; 621 h->iv = 0; 622 return mrb_obj_value(h); 623 } 141 624 142 625 MRB_API mrb_value … … 146 629 147 630 h = (struct RHash*)mrb_obj_alloc(mrb, MRB_TT_HASH, mrb->hash_class); 148 h->ht = kh_init(ht, mrb); 149 if (capa > 0) { 150 kh_resize(ht, mrb, h->ht, capa); 151 } 631 /* preallocate hash table */ 632 h->ht = ht_new(mrb); 633 /* capacity ignored */ 152 634 h->iv = 0; 153 635 return mrb_obj_value(h); 154 636 } 155 637 156 MRB_API mrb_value157 mrb_hash_new(mrb_state *mrb)158 {159 return mrb_hash_new_capa(mrb, 0);160 }161 162 638 static mrb_value mrb_hash_default(mrb_state *mrb, mrb_value hash); 163 639 static mrb_value hash_default(mrb_state *mrb, mrb_value hash, mrb_value key); 164 640 641 static mrb_value 642 mrb_hash_init_copy(mrb_state *mrb, mrb_value self) 643 { 644 mrb_value orig; 645 struct RHash* copy; 646 htable *orig_h; 647 mrb_value ifnone, vret; 648 649 mrb_get_args(mrb, "o", &orig); 650 if (mrb_obj_equal(mrb, self, orig)) return self; 651 if ((mrb_type(self) != mrb_type(orig)) || (mrb_obj_class(mrb, self) != mrb_obj_class(mrb, orig))) { 652 mrb_raise(mrb, E_TYPE_ERROR, "initialize_copy should take same class object"); 653 } 654 655 orig_h = RHASH_TBL(self); 656 copy = (struct RHash*)mrb_obj_alloc(mrb, MRB_TT_HASH, mrb->hash_class); 657 copy->ht = ht_copy(mrb, orig_h); 658 659 if (MRB_RHASH_DEFAULT_P(self)) { 660 copy->flags |= MRB_HASH_DEFAULT; 661 } 662 if (MRB_RHASH_PROCDEFAULT_P(self)) { 663 copy->flags |= MRB_HASH_PROC_DEFAULT; 664 } 665 vret = mrb_obj_value(copy); 666 ifnone = RHASH_IFNONE(self); 667 if (!mrb_nil_p(ifnone)) { 668 mrb_iv_set(mrb, vret, mrb_intern_lit(mrb, "ifnone"), ifnone); 669 } 670 return vret; 671 } 672 673 static int 674 check_kdict_i(mrb_state *mrb, mrb_value key, mrb_value val, void *data) 675 { 676 if (!mrb_symbol_p(key)) { 677 mrb_raise(mrb, E_ARGUMENT_ERROR, "keyword argument hash with non symbol keys"); 678 } 679 return 0; 680 } 681 682 void 683 mrb_hash_check_kdict(mrb_state *mrb, mrb_value self) 684 { 685 htable *t; 686 687 t = RHASH_TBL(self); 688 if (!t || t->size == 0) return; 689 ht_foreach(mrb, t, check_kdict_i, NULL); 690 } 691 692 MRB_API mrb_value 693 mrb_hash_dup(mrb_state *mrb, mrb_value self) 694 { 695 struct RHash* copy; 696 htable *orig_h; 697 698 orig_h = RHASH_TBL(self); 699 copy = (struct RHash*)mrb_obj_alloc(mrb, MRB_TT_HASH, mrb->hash_class); 700 copy->ht = orig_h ? ht_copy(mrb, orig_h) : NULL; 701 return mrb_obj_value(copy); 702 } 703 165 704 MRB_API mrb_value 166 705 mrb_hash_get(mrb_state *mrb, mrb_value hash, mrb_value key) 167 706 { 168 khash_t(ht) *h = RHASH_TBL(hash); 169 khiter_t k; 707 mrb_value val; 170 708 mrb_sym mid; 171 709 172 if (h) { 173 k = kh_get(ht, mrb, h, key); 174 if (k != kh_end(h)) 175 return kh_value(h, k).v; 710 if (ht_get(mrb, RHASH_TBL(hash), key, &val)) { 711 return val; 176 712 } 177 713 … … 187 723 mrb_hash_fetch(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value def) 188 724 { 189 khash_t(ht) *h = RHASH_TBL(hash); 190 khiter_t k; 191 192 if (h) { 193 k = kh_get(ht, mrb, h, key); 194 if (k != kh_end(h)) 195 return kh_value(h, k).v; 196 } 197 725 mrb_value val; 726 727 if (ht_get(mrb, RHASH_TBL(hash), key, &val)) { 728 return val; 729 } 198 730 /* not found */ 199 731 return def; … … 203 735 mrb_hash_set(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value val) 204 736 { 205 khash_t(ht) *h;206 khiter_t k;207 int r;208 209 737 mrb_hash_modify(mrb, hash); 210 h = RHASH_TBL(hash); 211 212 if (!h) h = RHASH_TBL(hash) = kh_init(ht, mrb); 213 k = kh_put2(ht, mrb, h, key, &r); 214 kh_value(h, k).v = val; 215 216 if (r != 0) { 217 /* expand */ 218 int ai = mrb_gc_arena_save(mrb); 219 key = kh_key(h, k) = KEY(key); 220 mrb_gc_arena_restore(mrb, ai); 221 kh_value(h, k).n = kh_size(h)-1; 222 } 223 738 739 key = KEY(key); 740 ht_put(mrb, RHASH_TBL(hash), key, val); 224 741 mrb_field_write_barrier_value(mrb, (struct RBasic*)RHASH(hash), key); 225 742 mrb_field_write_barrier_value(mrb, (struct RBasic*)RHASH(hash), val); … … 227 744 } 228 745 229 static mrb_value230 mrb_hash_dup(mrb_state *mrb, mrb_value hash)231 {232 struct RHash* ret;233 khash_t(ht) *h, *ret_h;234 khiter_t k, ret_k;235 mrb_value ifnone, vret;236 237 h = RHASH_TBL(hash);238 ret = (struct RHash*)mrb_obj_alloc(mrb, MRB_TT_HASH, mrb->hash_class);239 ret->ht = kh_init(ht, mrb);240 241 if (h && kh_size(h) > 0) {242 ret_h = ret->ht;243 244 for (k = kh_begin(h); k != kh_end(h); k++) {245 if (kh_exist(h, k)) {246 int ai = mrb_gc_arena_save(mrb);247 ret_k = kh_put(ht, mrb, ret_h, KEY(kh_key(h, k)));248 mrb_gc_arena_restore(mrb, ai);249 kh_val(ret_h, ret_k).v = kh_val(h, k).v;250 kh_val(ret_h, ret_k).n = kh_size(ret_h)-1;251 }252 }253 }254 255 if (MRB_RHASH_DEFAULT_P(hash)) {256 ret->flags |= MRB_HASH_DEFAULT;257 }258 if (MRB_RHASH_PROCDEFAULT_P(hash)) {259 ret->flags |= MRB_HASH_PROC_DEFAULT;260 }261 vret = mrb_obj_value(ret);262 ifnone = RHASH_IFNONE(hash);263 if (!mrb_nil_p(ifnone)) {264 mrb_iv_set(mrb, vret, mrb_intern_lit(mrb, "ifnone"), ifnone);265 }266 return vret;267 }268 269 MRB_API mrb_value270 mrb_check_hash_type(mrb_state *mrb, mrb_value hash)271 {272 return mrb_check_convert_type(mrb, hash, MRB_TT_HASH, "Hash", "to_hash");273 }274 275 MRB_API khash_t(ht)*276 mrb_hash_tbl(mrb_state *mrb, mrb_value hash)277 {278 khash_t(ht) *h = RHASH_TBL(hash);279 280 if (!h) {281 return RHASH_TBL(hash) = kh_init(ht, mrb);282 }283 return h;284 }285 286 746 static void 287 747 mrb_hash_modify(mrb_state *mrb, mrb_value hash) 288 748 { 289 if (MRB_FROZEN_P(mrb_hash_ptr(hash))) {290 mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen hash");291 }292 mrb_hash_tbl(mrb, hash);749 mrb_check_frozen(mrb, mrb_hash_ptr(hash)); 750 if (!RHASH_TBL(hash)) { 751 RHASH_TBL(hash) = ht_new(mrb); 752 } 293 753 } 294 754 … … 340 800 if (!mrb_nil_p(block)) { 341 801 if (ifnone_p) { 342 mrb_ raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments");802 mrb_argnum_error(mrb, 1, 0, 0); 343 803 } 344 804 RHASH(hash)->flags |= MRB_HASH_PROC_DEFAULT; … … 530 990 mrb_hash_delete_key(mrb_state *mrb, mrb_value hash, mrb_value key) 531 991 { 532 khash_t(ht) *h = RHASH_TBL(hash); 533 khiter_t k; 534 mrb_value delVal; 535 mrb_int n; 536 537 if (h) { 538 k = kh_get(ht, mrb, h, key); 539 if (k != kh_end(h)) { 540 delVal = kh_value(h, k).v; 541 n = kh_value(h, k).n; 542 kh_del(ht, mrb, h, k); 543 for (k = kh_begin(h); k != kh_end(h); k++) { 544 if (!kh_exist(h, k)) continue; 545 if (kh_value(h, k).n > n) kh_value(h, k).n--; 546 } 547 return delVal; 548 } 992 htable *t = RHASH_TBL(hash); 993 mrb_value del_val; 994 995 if (ht_del(mrb, t, key, &del_val)) { 996 return del_val; 549 997 } 550 998 … … 553 1001 } 554 1002 555 /* 15.2.13.4.8 */556 /*557 * call-seq:558 * hsh.delete(key) -> value559 * hsh.delete(key) {| key | block } -> value560 *561 * Deletes and returns a key-value pair from <i>hsh</i> whose key is562 * equal to <i>key</i>. If the key is not found, returns the563 * <em>default value</em>. If the optional code block is given and the564 * key is not found, pass in the key and return the result of565 * <i>block</i>.566 *567 * h = { "a" => 100, "b" => 200 }568 * h.delete("a") #=> 100569 * h.delete("z") #=> nil570 * h.delete("z") { |el| "#{el} not found" } #=> "z not found"571 *572 */573 1003 static mrb_value 574 1004 mrb_hash_delete(mrb_state *mrb, mrb_value self) … … 581 1011 } 582 1012 1013 /* find first element in the hash table, and remove it. */ 1014 static void 1015 ht_shift(mrb_state *mrb, htable *t, mrb_value *kp, mrb_value *vp) 1016 { 1017 segment *seg = t->rootseg; 1018 mrb_int i; 1019 1020 while (seg) { 1021 for (i=0; i<seg->size; i++) { 1022 mrb_value key; 1023 1024 if (!seg->next && i >= t->last_len) { 1025 return; 1026 } 1027 key = seg->e[i].key; 1028 if (mrb_undef_p(key)) continue; 1029 *kp = key; 1030 *vp = seg->e[i].val; 1031 /* delete element */ 1032 seg->e[i].key = mrb_undef_value(); 1033 t->size--; 1034 return; 1035 } 1036 seg = seg->next; 1037 } 1038 } 1039 583 1040 /* 15.2.13.4.24 */ 584 1041 /* … … 598 1055 mrb_hash_shift(mrb_state *mrb, mrb_value hash) 599 1056 { 600 khash_t(ht) *h = RHASH_TBL(hash); 601 khiter_t k; 602 mrb_value delKey, delVal; 1057 htable *t = RHASH_TBL(hash); 603 1058 604 1059 mrb_hash_modify(mrb, hash); 605 if (h && kh_size(h) > 0) { 606 for (k = kh_begin(h); k != kh_end(h); k++) { 607 if (!kh_exist(h, k)) continue; 608 609 delKey = kh_key(h, k); 610 mrb_gc_protect(mrb, delKey); 611 delVal = mrb_hash_delete_key(mrb, hash, delKey); 612 mrb_gc_protect(mrb, delVal); 613 614 return mrb_assoc_new(mrb, delKey, delVal); 615 } 1060 if (t && t->size > 0) { 1061 mrb_value del_key, del_val; 1062 1063 ht_shift(mrb, t, &del_key, &del_val); 1064 mrb_gc_protect(mrb, del_key); 1065 mrb_gc_protect(mrb, del_val); 1066 return mrb_assoc_new(mrb, del_key, del_val); 616 1067 } 617 1068 … … 642 1093 mrb_hash_clear(mrb_state *mrb, mrb_value hash) 643 1094 { 644 khash_t(ht) *h= RHASH_TBL(hash);1095 htable *t = RHASH_TBL(hash); 645 1096 646 1097 mrb_hash_modify(mrb, hash); 647 if (h) kh_clear(ht, mrb, h); 1098 if (t) { 1099 ht_free(mrb, t); 1100 RHASH_TBL(hash) = NULL; 1101 } 648 1102 return hash; 649 1103 } … … 678 1132 } 679 1133 1134 MRB_API mrb_int 1135 mrb_hash_size(mrb_state *mrb, mrb_value hash) 1136 { 1137 htable *t = RHASH_TBL(hash); 1138 1139 if (!t) return 0; 1140 return t->size; 1141 } 1142 680 1143 /* 15.2.13.4.20 */ 681 1144 /* 15.2.13.4.25 */ … … 695 1158 mrb_hash_size_m(mrb_state *mrb, mrb_value self) 696 1159 { 697 khash_t(ht) *h = RHASH_TBL(self); 698 699 if (!h) return mrb_fixnum_value(0); 700 return mrb_fixnum_value(kh_size(h)); 1160 mrb_int size = mrb_hash_size(mrb, self); 1161 return mrb_fixnum_value(size); 1162 } 1163 1164 MRB_API mrb_bool 1165 mrb_hash_empty_p(mrb_state *mrb, mrb_value self) 1166 { 1167 htable *t = RHASH_TBL(self); 1168 1169 if (!t) return TRUE; 1170 return t->size == 0; 701 1171 } 702 1172 … … 711 1181 * 712 1182 */ 713 MRB_API mrb_value 714 mrb_hash_empty_p(mrb_state *mrb, mrb_value self) 715 { 716 khash_t(ht) *h = RHASH_TBL(self); 717 718 if (h) return mrb_bool_value(kh_size(h) == 0); 719 return mrb_true_value(); 720 } 721 722 /* 15.2.13.4.29 (x)*/ 723 /* 724 * call-seq: 725 * hsh.to_hash => hsh 726 * 727 * Returns +self+. 728 */ 729 730 static mrb_value 731 mrb_hash_to_hash(mrb_state *mrb, mrb_value hash) 732 { 733 return hash; 1183 static mrb_value 1184 mrb_hash_empty_m(mrb_state *mrb, mrb_value self) 1185 { 1186 return mrb_bool_value(mrb_hash_empty_p(mrb, self)); 1187 } 1188 1189 static int 1190 hash_keys_i(mrb_state *mrb, mrb_value key, mrb_value val, void *p) 1191 { 1192 mrb_ary_push(mrb, *(mrb_value*)p, key); 1193 return 0; 734 1194 } 735 1195 … … 750 1210 mrb_hash_keys(mrb_state *mrb, mrb_value hash) 751 1211 { 752 khash_t(ht) *h = RHASH_TBL(hash); 753 khiter_t k; 754 mrb_int end; 1212 htable *t = RHASH_TBL(hash); 1213 mrb_int size; 755 1214 mrb_value ary; 756 mrb_value *p; 757 758 if (!h || kh_size(h) == 0) return mrb_ary_new(mrb); 759 ary = mrb_ary_new_capa(mrb, kh_size(h)); 760 end = kh_size(h)-1; 761 mrb_ary_set(mrb, ary, end, mrb_nil_value()); 762 p = mrb_ary_ptr(ary)->ptr; 763 for (k = kh_begin(h); k != kh_end(h); k++) { 764 if (kh_exist(h, k)) { 765 mrb_value kv = kh_key(h, k); 766 mrb_hash_value hv = kh_value(h, k); 767 768 if (hv.n <= end) { 769 p[hv.n] = kv; 770 } 771 else { 772 p[end] = kv; 773 } 774 } 775 } 1215 1216 if (!t || (size = t->size) == 0) 1217 return mrb_ary_new(mrb); 1218 ary = mrb_ary_new_capa(mrb, size); 1219 ht_foreach(mrb, t, hash_keys_i, (void*)&ary); 776 1220 return ary; 1221 } 1222 1223 static int 1224 hash_vals_i(mrb_state *mrb, mrb_value key, mrb_value val, void *p) 1225 { 1226 mrb_ary_push(mrb, *(mrb_value*)p, val); 1227 return 0; 777 1228 } 778 1229 … … 793 1244 mrb_hash_values(mrb_state *mrb, mrb_value hash) 794 1245 { 795 khash_t(ht) *h= RHASH_TBL(hash);796 khiter_t k;1246 htable *t = RHASH_TBL(hash); 1247 mrb_int size; 797 1248 mrb_value ary; 798 1249 799 if (!h) return mrb_ary_new(mrb); 800 ary = mrb_ary_new_capa(mrb, kh_size(h)); 801 for (k = kh_begin(h); k != kh_end(h); k++) { 802 if (kh_exist(h, k)) { 803 mrb_hash_value hv = kh_value(h, k); 804 805 mrb_ary_set(mrb, ary, hv.n, hv.v); 806 } 807 } 1250 if (!t || (size = t->size) == 0) 1251 return mrb_ary_new(mrb); 1252 ary = mrb_ary_new_capa(mrb, size); 1253 ht_foreach(mrb, t, hash_vals_i, (void*)&ary); 808 1254 return ary; 809 1255 } … … 828 1274 */ 829 1275 1276 MRB_API mrb_bool 1277 mrb_hash_key_p(mrb_state *mrb, mrb_value hash, mrb_value key) 1278 { 1279 htable *t; 1280 1281 t = RHASH_TBL(hash); 1282 if (ht_get(mrb, t, key, NULL)) { 1283 return TRUE; 1284 } 1285 return FALSE; 1286 } 1287 830 1288 static mrb_value 831 1289 mrb_hash_has_key(mrb_state *mrb, mrb_value hash) 832 1290 { 833 1291 mrb_value key; 834 khash_t(ht) *h; 835 khiter_t k; 1292 mrb_bool key_p; 836 1293 837 1294 mrb_get_args(mrb, "o", &key); 838 839 h = RHASH_TBL(hash); 840 if (h) { 841 k = kh_get(ht, mrb, h, key); 842 return mrb_bool_value(k != kh_end(h)); 843 } 844 return mrb_false_value(); 1295 key_p = mrb_hash_key_p(mrb, hash, key); 1296 return mrb_bool_value(key_p); 1297 } 1298 1299 struct has_v_arg { 1300 mrb_bool found; 1301 mrb_value val; 1302 }; 1303 1304 static int 1305 hash_has_value_i(mrb_state *mrb, mrb_value key, mrb_value val, void *p) 1306 { 1307 struct has_v_arg *arg = (struct has_v_arg*)p; 1308 1309 if (mrb_equal(mrb, arg->val, val)) { 1310 arg->found = TRUE; 1311 return 1; 1312 } 1313 return 0; 845 1314 } 846 1315 … … 864 1333 { 865 1334 mrb_value val; 866 khash_t(ht) *h; 867 khiter_t k; 868 1335 struct has_v_arg arg; 1336 869 1337 mrb_get_args(mrb, "o", &val); 870 h = RHASH_TBL(hash); 871 872 if (h) { 873 for (k = kh_begin(h); k != kh_end(h); k++) { 874 if (!kh_exist(h, k)) continue; 875 876 if (mrb_equal(mrb, kh_value(h, k).v, val)) { 877 return mrb_true_value(); 878 } 879 } 880 } 881 return mrb_false_value(); 1338 arg.found = FALSE; 1339 arg.val = val; 1340 ht_foreach(mrb, RHASH_TBL(hash), hash_has_value_i, &arg); 1341 return mrb_bool_value(arg.found); 1342 } 1343 1344 static int 1345 merge_i(mrb_state *mrb, mrb_value key, mrb_value val, void *data) 1346 { 1347 htable *h1 = (htable*)data; 1348 1349 ht_put(mrb, h1, key, val); 1350 return 0; 1351 } 1352 1353 MRB_API void 1354 mrb_hash_merge(mrb_state *mrb, mrb_value hash1, mrb_value hash2) 1355 { 1356 htable *h1, *h2; 1357 1358 mrb_hash_modify(mrb, hash1); 1359 hash2 = mrb_ensure_hash_type(mrb, hash2); 1360 h1 = RHASH_TBL(hash1); 1361 h2 = RHASH_TBL(hash2); 1362 1363 if (!h2) return; 1364 if (!h1) { 1365 RHASH_TBL(hash1) = ht_copy(mrb, h2); 1366 return; 1367 } 1368 ht_foreach(mrb, h2, merge_i, h1); 1369 mrb_write_barrier(mrb, (struct RBasic*)RHASH(hash1)); 1370 return; 1371 } 1372 1373 /* 1374 * call-seq: 1375 * hsh.rehash -> hsh 1376 * 1377 * Rebuilds the hash based on the current hash values for each key. If 1378 * values of key objects have changed since they were inserted, this 1379 * method will reindex <i>hsh</i>. 1380 * 1381 * keys = (1..17).map{|n| [n]} 1382 * k = keys[0] 1383 * h = {} 1384 * keys.each{|key| h[key] = key[0]} 1385 * h #=> { [1]=> 1, [2]=> 2, [3]=> 3, [4]=> 4, [5]=> 5, [6]=> 6, [7]=> 7, 1386 * [8]=> 8, [9]=> 9,[10]=>10,[11]=>11,[12]=>12,[13]=>13,[14]=>14, 1387 * [15]=>15,[16]=>16,[17]=>17} 1388 * h[k] #=> 1 1389 * k[0] = keys.size + 1 1390 * h #=> {[18]=> 1, [2]=> 2, [3]=> 3, [4]=> 4, [5]=> 5, [6]=> 6, [7]=> 7, 1391 * [8]=> 8, [9]=> 9,[10]=>10,[11]=>11,[12]=>12,[13]=>13,[14]=>14, 1392 * [15]=>15,[16]=>16,[17]=>17} 1393 * h[k] #=> nil 1394 * h.rehash 1395 * h[k] #=> 1 1396 */ 1397 static mrb_value 1398 mrb_hash_rehash(mrb_state *mrb, mrb_value self) 1399 { 1400 ht_compact(mrb, RHASH_TBL(self)); 1401 return self; 882 1402 } 883 1403 … … 890 1410 MRB_SET_INSTANCE_TT(h, MRB_TT_HASH); 891 1411 1412 mrb_define_method(mrb, h, "initialize_copy", mrb_hash_init_copy, MRB_ARGS_REQ(1)); 892 1413 mrb_define_method(mrb, h, "[]", mrb_hash_aget, MRB_ARGS_REQ(1)); /* 15.2.13.4.2 */ 893 1414 mrb_define_method(mrb, h, "[]=", mrb_hash_aset, MRB_ARGS_REQ(2)); /* 15.2.13.4.3 */ 894 1415 mrb_define_method(mrb, h, "clear", mrb_hash_clear, MRB_ARGS_NONE()); /* 15.2.13.4.4 */ 895 mrb_define_method(mrb, h, "default", mrb_hash_default, MRB_ARGS_ ANY()); /* 15.2.13.4.5 */1416 mrb_define_method(mrb, h, "default", mrb_hash_default, MRB_ARGS_OPT(1)); /* 15.2.13.4.5 */ 896 1417 mrb_define_method(mrb, h, "default=", mrb_hash_set_default, MRB_ARGS_REQ(1)); /* 15.2.13.4.6 */ 897 1418 mrb_define_method(mrb, h, "default_proc", mrb_hash_default_proc,MRB_ARGS_NONE()); /* 15.2.13.4.7 */ 898 1419 mrb_define_method(mrb, h, "default_proc=", mrb_hash_set_default_proc,MRB_ARGS_REQ(1)); /* 15.2.13.4.7 */ 899 1420 mrb_define_method(mrb, h, "__delete", mrb_hash_delete, MRB_ARGS_REQ(1)); /* core of 15.2.13.4.8 */ 900 mrb_define_method(mrb, h, "empty?", mrb_hash_empty_ p, MRB_ARGS_NONE()); /* 15.2.13.4.12 */1421 mrb_define_method(mrb, h, "empty?", mrb_hash_empty_m, MRB_ARGS_NONE()); /* 15.2.13.4.12 */ 901 1422 mrb_define_method(mrb, h, "has_key?", mrb_hash_has_key, MRB_ARGS_REQ(1)); /* 15.2.13.4.13 */ 902 1423 mrb_define_method(mrb, h, "has_value?", mrb_hash_has_value, MRB_ARGS_REQ(1)); /* 15.2.13.4.14 */ 903 1424 mrb_define_method(mrb, h, "include?", mrb_hash_has_key, MRB_ARGS_REQ(1)); /* 15.2.13.4.15 */ 904 mrb_define_method(mrb, h, "initialize", mrb_hash_init, MRB_ARGS_OPT(1) ); /* 15.2.13.4.16 */1425 mrb_define_method(mrb, h, "initialize", mrb_hash_init, MRB_ARGS_OPT(1)|MRB_ARGS_BLOCK()); /* 15.2.13.4.16 */ 905 1426 mrb_define_method(mrb, h, "key?", mrb_hash_has_key, MRB_ARGS_REQ(1)); /* 15.2.13.4.18 */ 906 1427 mrb_define_method(mrb, h, "keys", mrb_hash_keys, MRB_ARGS_NONE()); /* 15.2.13.4.19 */ … … 908 1429 mrb_define_method(mrb, h, "member?", mrb_hash_has_key, MRB_ARGS_REQ(1)); /* 15.2.13.4.21 */ 909 1430 mrb_define_method(mrb, h, "shift", mrb_hash_shift, MRB_ARGS_NONE()); /* 15.2.13.4.24 */ 910 mrb_define_method(mrb, h, "dup", mrb_hash_dup, MRB_ARGS_NONE());911 1431 mrb_define_method(mrb, h, "size", mrb_hash_size_m, MRB_ARGS_NONE()); /* 15.2.13.4.25 */ 912 1432 mrb_define_method(mrb, h, "store", mrb_hash_aset, MRB_ARGS_REQ(2)); /* 15.2.13.4.26 */ 913 1433 mrb_define_method(mrb, h, "value?", mrb_hash_has_value, MRB_ARGS_REQ(1)); /* 15.2.13.4.27 */ 914 1434 mrb_define_method(mrb, h, "values", mrb_hash_values, MRB_ARGS_NONE()); /* 15.2.13.4.28 */ 915 916 mrb_define_method(mrb, h, "to_hash", mrb_hash_to_hash, MRB_ARGS_NONE()); /* 15.2.13.4.29 (x)*/ 917 } 1435 mrb_define_method(mrb, h, "rehash", mrb_hash_rehash, MRB_ARGS_NONE()); 1436 } -
EcnlProtoTool/trunk/mruby-2.1.1/src/kernel.c
r331 r439 15 15 #include <mruby/istruct.h> 16 16 17 typedef enum {18 NOEX_PUBLIC = 0x00,19 NOEX_NOSUPER = 0x01,20 NOEX_PRIVATE = 0x02,21 NOEX_PROTECTED = 0x04,22 NOEX_MASK = 0x06,23 NOEX_BASIC = 0x08,24 NOEX_UNDEF = NOEX_NOSUPER,25 NOEX_MODFUNC = 0x12,26 NOEX_SUPER = 0x20,27 NOEX_VCALL = 0x40,28 NOEX_RESPONDS = 0x8029 } mrb_method_flag_t;30 31 17 MRB_API mrb_bool 32 18 mrb_func_basic_p(mrb_state *mrb, mrb_value obj, mrb_sym mid, mrb_func_t func) 33 19 { 34 struct RProc *me = mrb_method_search(mrb, mrb_class(mrb, obj), mid); 35 if (MRB_PROC_CFUNC_P(me) && (me->body.func == func)) 20 struct RClass *c = mrb_class(mrb, obj); 21 mrb_method_t m = mrb_method_search_vm(mrb, &c, mid); 22 struct RProc *p; 23 24 if (MRB_METHOD_UNDEF_P(m)) return FALSE; 25 if (MRB_METHOD_FUNC_P(m)) 26 return MRB_METHOD_FUNC(m) == func; 27 p = MRB_METHOD_PROC(m); 28 if (MRB_PROC_CFUNC_P(p) && (MRB_PROC_CFUNC(p) == func)) 36 29 return TRUE; 37 30 return FALSE; … … 61 54 mrb_obj_inspect(mrb_state *mrb, mrb_value obj) 62 55 { 63 if ( (mrb_type(obj) == MRB_TT_OBJECT) && mrb_obj_basic_to_s_p(mrb, obj)) {56 if (mrb_object_p(obj) && mrb_obj_basic_to_s_p(mrb, obj)) { 64 57 return mrb_obj_iv_inspect(mrb, mrb_obj_ptr(obj)); 65 58 } … … 135 128 mrb_f_block_given_p_m(mrb_state *mrb, mrb_value self) 136 129 { 137 mrb_callinfo *ci = mrb->c->ci; 130 mrb_callinfo *ci = &mrb->c->ci[-1]; 131 mrb_callinfo *cibase = mrb->c->cibase; 138 132 mrb_value *bp; 139 140 bp = ci->stackent + 1; 141 ci--;142 if (ci <= mrb->c->cibase) {133 struct RProc *p; 134 135 if (ci <= cibase) { 136 /* toplevel does not have block */ 143 137 return mrb_false_value(); 144 138 } 145 /* block_given? called within block; check upper scope */ 146 if (ci->proc->env) { 147 struct REnv *e = ci->proc->env; 148 149 while (e->c) { 150 e = (struct REnv*)e->c; 151 } 139 p = ci->proc; 140 /* search method/class/module proc */ 141 while (p) { 142 if (MRB_PROC_SCOPE_P(p)) break; 143 p = p->upper; 144 } 145 if (p == NULL) return mrb_false_value(); 146 /* search ci corresponding to proc */ 147 while (cibase < ci) { 148 if (ci->proc == p) break; 149 ci--; 150 } 151 if (ci == cibase) { 152 return mrb_false_value(); 153 } 154 else if (ci->env) { 155 struct REnv *e = ci->env; 156 int bidx; 157 152 158 /* top-level does not have block slot (always false) */ 153 159 if (e->stack == mrb->c->stbase) 154 160 return mrb_false_value(); 155 if (e->stack && e->cioff < 0) { 156 /* use saved block arg position */ 157 bp = &e->stack[-e->cioff]; 158 ci = 0; /* no callinfo available */ 161 /* use saved block arg position */ 162 bidx = MRB_ENV_BIDX(e); 163 /* bidx may be useless (e.g. define_method) */ 164 if (bidx >= MRB_ENV_STACK_LEN(e)) 165 return mrb_false_value(); 166 bp = &e->stack[bidx]; 167 } 168 else { 169 bp = ci[1].stackent+1; 170 if (ci->argc >= 0) { 171 bp += ci->argc; 159 172 } 160 173 else { 161 ci = e->cxt.c->cibase + e->cioff; 162 bp = ci[1].stackent + 1; 163 } 164 } 165 if (ci && ci->argc > 0) { 166 bp += ci->argc; 174 bp++; 175 } 167 176 } 168 177 if (mrb_nil_p(*bp)) … … 231 240 /* if the origin is not the same as the class, then the origin and 232 241 the current class need to be copied */ 233 if (sc->flags & MRB_FL AG_IS_PREPENDED) {242 if (sc->flags & MRB_FL_CLASS_IS_PREPENDED) { 234 243 struct RClass *c0 = sc->super; 235 244 struct RClass *c1 = dc; 236 245 237 246 /* copy prepended iclasses */ 238 while (!(c0->flags & MRB_FL AG_IS_ORIGIN)) {247 while (!(c0->flags & MRB_FL_CLASS_IS_ORIGIN)) { 239 248 c1->super = mrb_class_ptr(mrb_obj_dup(mrb, mrb_obj_value(c0))); 240 249 c1 = c1->super; … … 242 251 } 243 252 c1->super = mrb_class_ptr(mrb_obj_dup(mrb, mrb_obj_value(c0))); 244 c1->super->flags |= MRB_FL AG_IS_ORIGIN;253 c1->super->flags |= MRB_FL_CLASS_IS_ORIGIN; 245 254 } 246 255 if (sc->mt) { … … 258 267 { 259 268 switch (mrb_type(obj)) { 269 case MRB_TT_ICLASS: 270 copy_class(mrb, dest, obj); 271 return; 260 272 case MRB_TT_CLASS: 261 273 case MRB_TT_MODULE: 262 274 copy_class(mrb, dest, obj); 263 /* fall through */ 275 mrb_iv_copy(mrb, dest, obj); 276 mrb_iv_remove(mrb, dest, mrb_intern_lit(mrb, "__classname__")); 277 break; 264 278 case MRB_TT_OBJECT: 265 279 case MRB_TT_SCLASS: … … 312 326 313 327 if (mrb_immediate_p(self)) { 314 mrb_raisef(mrb, E_TYPE_ERROR, "can't clone % S", self);315 } 316 if (mrb_ type(self) == MRB_TT_SCLASS) {328 mrb_raisef(mrb, E_TYPE_ERROR, "can't clone %v", self); 329 } 330 if (mrb_sclass_p(self)) { 317 331 mrb_raise(mrb, E_TYPE_ERROR, "can't clone singleton class"); 318 332 } 319 333 p = (struct RObject*)mrb_obj_alloc(mrb, mrb_type(self), mrb_obj_class(mrb, self)); 320 334 p->c = mrb_singleton_class_clone(mrb, self); 335 mrb_field_write_barrier(mrb, (struct RBasic*)p, (struct RBasic*)p->c); 321 336 clone = mrb_obj_value(p); 322 337 init_copy(mrb, clone, self); 338 p->flags |= mrb_obj_ptr(self)->flags & MRB_FL_OBJ_IS_FROZEN; 323 339 324 340 return clone; … … 351 367 352 368 if (mrb_immediate_p(obj)) { 353 mrb_raisef(mrb, E_TYPE_ERROR, "can't dup % S", obj);354 } 355 if (mrb_ type(obj) == MRB_TT_SCLASS) {369 mrb_raisef(mrb, E_TYPE_ERROR, "can't dup %v", obj); 370 } 371 if (mrb_sclass_p(obj)) { 356 372 mrb_raise(mrb, E_TYPE_ERROR, "can't dup singleton class"); 357 373 } … … 369 385 370 386 if (argc == 0) { 371 mrb_ raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (at least 1)");387 mrb_argnum_error(mrb, argc, 1, -1); 372 388 } 373 389 for (i = 0; i < argc; i++) { … … 411 427 mrb_value *argv; 412 428 mrb_int argc; 413 mrb_value args;414 429 415 430 mrb_get_args(mrb, "*", &argv, &argc); 416 args = mrb_ary_new_from_values(mrb, argc, argv);417 argv = (mrb_value*)RARRAY_PTR(args);418 431 return mrb_obj_extend(mrb, argc, argv, self); 419 432 } 420 433 421 staticmrb_value434 MRB_API mrb_value 422 435 mrb_obj_freeze(mrb_state *mrb, mrb_value self) 423 436 { 424 struct RBasic *b; 425 426 switch (mrb_type(self)) { 427 case MRB_TT_FALSE: 428 case MRB_TT_TRUE: 429 case MRB_TT_FIXNUM: 430 case MRB_TT_SYMBOL: 431 case MRB_TT_FLOAT: 432 return self; 433 default: 434 break; 435 } 436 437 b = mrb_basic_ptr(self); 438 if (!MRB_FROZEN_P(b)) { 439 MRB_SET_FROZEN_FLAG(b); 437 if (!mrb_immediate_p(self)) { 438 struct RBasic *b = mrb_basic_ptr(self); 439 if (!mrb_frozen_p(b)) { 440 MRB_SET_FROZEN_FLAG(b); 441 if (b->c->tt == MRB_TT_SCLASS) MRB_SET_FROZEN_FLAG(b->c); 442 } 440 443 } 441 444 return self; … … 445 448 mrb_obj_frozen(mrb_state *mrb, mrb_value self) 446 449 { 447 struct RBasic *b; 448 449 switch (mrb_type(self)) { 450 case MRB_TT_FALSE: 451 case MRB_TT_TRUE: 452 case MRB_TT_FIXNUM: 453 case MRB_TT_SYMBOL: 454 case MRB_TT_FLOAT: 455 return mrb_true_value(); 456 default: 457 break; 458 } 459 460 b = mrb_basic_ptr(self); 461 if (!MRB_FROZEN_P(b)) { 462 return mrb_false_value(); 463 } 464 return mrb_true_value(); 450 return mrb_bool_value(mrb_immediate_p(self) || mrb_frozen_p(mrb_basic_ptr(self))); 465 451 } 466 452 … … 476 462 * <code>Fixnum</code> will be truncated before being used. 477 463 */ 478 MRB_APImrb_value464 static mrb_value 479 465 mrb_obj_hash(mrb_state *mrb, mrb_value self) 480 466 { … … 520 506 521 507 return mrb_bool_value(mrb_obj_is_instance_of(mrb, self, mrb_class_ptr(arg))); 522 }523 524 /* 15.3.1.3.20 */525 /*526 * call-seq:527 * obj.instance_variable_defined?(symbol) -> true or false528 *529 * Returns <code>true</code> if the given instance variable is530 * defined in <i>obj</i>.531 *532 * class Fred533 * def initialize(p1, p2)534 * @a, @b = p1, p2535 * end536 * end537 * fred = Fred.new('cat', 99)538 * fred.instance_variable_defined?(:@a) #=> true539 * fred.instance_variable_defined?("@b") #=> true540 * fred.instance_variable_defined?("@c") #=> false541 */542 static mrb_value543 mrb_obj_ivar_defined(mrb_state *mrb, mrb_value self)544 {545 mrb_sym sym;546 547 mrb_get_args(mrb, "n", &sym);548 mrb_iv_check(mrb, sym);549 return mrb_bool_value(mrb_iv_defined(mrb, self, sym));550 }551 552 /* 15.3.1.3.21 */553 /*554 * call-seq:555 * obj.instance_variable_get(symbol) -> obj556 *557 * Returns the value of the given instance variable, or nil if the558 * instance variable is not set. The <code>@</code> part of the559 * variable name should be included for regular instance560 * variables. Throws a <code>NameError</code> exception if the561 * supplied symbol is not valid as an instance variable name.562 *563 * class Fred564 * def initialize(p1, p2)565 * @a, @b = p1, p2566 * end567 * end568 * fred = Fred.new('cat', 99)569 * fred.instance_variable_get(:@a) #=> "cat"570 * fred.instance_variable_get("@b") #=> 99571 */572 static mrb_value573 mrb_obj_ivar_get(mrb_state *mrb, mrb_value self)574 {575 mrb_sym iv_name;576 577 mrb_get_args(mrb, "n", &iv_name);578 mrb_iv_check(mrb, iv_name);579 return mrb_iv_get(mrb, self, iv_name);580 }581 582 /* 15.3.1.3.22 */583 /*584 * call-seq:585 * obj.instance_variable_set(symbol, obj) -> obj586 *587 * Sets the instance variable names by <i>symbol</i> to588 * <i>object</i>, thereby frustrating the efforts of the class's589 * author to attempt to provide proper encapsulation. The variable590 * did not have to exist prior to this call.591 *592 * class Fred593 * def initialize(p1, p2)594 * @a, @b = p1, p2595 * end596 * end597 * fred = Fred.new('cat', 99)598 * fred.instance_variable_set(:@a, 'dog') #=> "dog"599 * fred.instance_variable_set(:@c, 'cat') #=> "cat"600 * fred.inspect #=> "#<Fred:0x401b3da8 @a=\"dog\", @b=99, @c=\"cat\">"601 */602 static mrb_value603 mrb_obj_ivar_set(mrb_state *mrb, mrb_value self)604 {605 mrb_sym iv_name;606 mrb_value val;607 608 mrb_get_args(mrb, "no", &iv_name, &val);609 mrb_iv_check(mrb, iv_name);610 mrb_iv_set(mrb, self, iv_name, val);611 return val;612 508 } 613 509 … … 652 548 KHASH_DEFINE(st, mrb_sym, char, FALSE, kh_int_hash_func, kh_int_hash_equal) 653 549 654 static void655 method_entry_loop(mrb_state *mrb, struct RClass* klass, khash_t(st)* set)656 {657 khint_t i;658 659 khash_t(mt) *h = klass->mt;660 if (!h) return;661 for (i=0;i<kh_end(h);i++) {662 if (kh_exist(h, i) && kh_value(h, i)) {663 kh_put(st, mrb, set, kh_key(h, i));664 }665 }666 }667 668 mrb_value669 mrb_class_instance_method_list(mrb_state *mrb, mrb_bool recur, struct RClass* klass, int obj)670 {671 khint_t i;672 mrb_value ary;673 mrb_bool prepended = FALSE;674 struct RClass* oldklass;675 khash_t(st)* set = kh_init(st, mrb);676 677 if (!recur && (klass->flags & MRB_FLAG_IS_PREPENDED)) {678 MRB_CLASS_ORIGIN(klass);679 prepended = TRUE;680 }681 682 oldklass = 0;683 while (klass && (klass != oldklass)) {684 method_entry_loop(mrb, klass, set);685 if ((klass->tt == MRB_TT_ICLASS && !prepended) ||686 (klass->tt == MRB_TT_SCLASS)) {687 }688 else {689 if (!recur) break;690 }691 oldklass = klass;692 klass = klass->super;693 }694 695 ary = mrb_ary_new(mrb);696 for (i=0;i<kh_end(set);i++) {697 if (kh_exist(set, i)) {698 mrb_ary_push(mrb, ary, mrb_symbol_value(kh_key(set, i)));699 }700 }701 kh_destroy(st, mrb, set);702 703 return ary;704 }705 706 static mrb_value707 mrb_obj_singleton_methods(mrb_state *mrb, mrb_bool recur, mrb_value obj)708 {709 khint_t i;710 mrb_value ary;711 struct RClass* klass;712 khash_t(st)* set = kh_init(st, mrb);713 714 klass = mrb_class(mrb, obj);715 716 if (klass && (klass->tt == MRB_TT_SCLASS)) {717 method_entry_loop(mrb, klass, set);718 klass = klass->super;719 }720 if (recur) {721 while (klass && ((klass->tt == MRB_TT_SCLASS) || (klass->tt == MRB_TT_ICLASS))) {722 method_entry_loop(mrb, klass, set);723 klass = klass->super;724 }725 }726 727 ary = mrb_ary_new(mrb);728 for (i=0;i<kh_end(set);i++) {729 if (kh_exist(set, i)) {730 mrb_ary_push(mrb, ary, mrb_symbol_value(kh_key(set, i)));731 }732 }733 kh_destroy(st, mrb, set);734 735 return ary;736 }737 738 static mrb_value739 mrb_obj_methods(mrb_state *mrb, mrb_bool recur, mrb_value obj, mrb_method_flag_t flag)740 {741 return mrb_class_instance_method_list(mrb, recur, mrb_class(mrb, obj), 0);742 }743 /* 15.3.1.3.31 */744 /*745 * call-seq:746 * obj.methods -> array747 *748 * Returns a list of the names of methods publicly accessible in749 * <i>obj</i>. This will include all the methods accessible in750 * <i>obj</i>'s ancestors.751 *752 * class Klass753 * def kMethod()754 * end755 * end756 * k = Klass.new757 * k.methods[0..9] #=> [:kMethod, :respond_to?, :nil?, :is_a?,758 * # :class, :instance_variable_set,759 * # :methods, :extend, :__send__, :instance_eval]760 * k.methods.length #=> 42761 */762 static mrb_value763 mrb_obj_methods_m(mrb_state *mrb, mrb_value self)764 {765 mrb_bool recur = TRUE;766 mrb_get_args(mrb, "|b", &recur);767 return mrb_obj_methods(mrb, recur, self, (mrb_method_flag_t)0); /* everything but private */768 }769 770 550 /* 15.3.1.3.32 */ 771 551 /* … … 780 560 { 781 561 return mrb_false_value(); 782 }783 784 /* 15.3.1.3.36 */785 /*786 * call-seq:787 * obj.private_methods(all=true) -> array788 *789 * Returns the list of private methods accessible to <i>obj</i>. If790 * the <i>all</i> parameter is set to <code>false</code>, only those methods791 * in the receiver will be listed.792 */793 static mrb_value794 mrb_obj_private_methods(mrb_state *mrb, mrb_value self)795 {796 mrb_bool recur = TRUE;797 mrb_get_args(mrb, "|b", &recur);798 return mrb_obj_methods(mrb, recur, self, NOEX_PRIVATE); /* private attribute not define */799 }800 801 /* 15.3.1.3.37 */802 /*803 * call-seq:804 * obj.protected_methods(all=true) -> array805 *806 * Returns the list of protected methods accessible to <i>obj</i>. If807 * the <i>all</i> parameter is set to <code>false</code>, only those methods808 * in the receiver will be listed.809 */810 static mrb_value811 mrb_obj_protected_methods(mrb_state *mrb, mrb_value self)812 {813 mrb_bool recur = TRUE;814 mrb_get_args(mrb, "|b", &recur);815 return mrb_obj_methods(mrb, recur, self, NOEX_PROTECTED); /* protected attribute not define */816 }817 818 /* 15.3.1.3.38 */819 /*820 * call-seq:821 * obj.public_methods(all=true) -> array822 *823 * Returns the list of public methods accessible to <i>obj</i>. If824 * the <i>all</i> parameter is set to <code>false</code>, only those methods825 * in the receiver will be listed.826 */827 static mrb_value828 mrb_obj_public_methods(mrb_state *mrb, mrb_value self)829 {830 mrb_bool recur = TRUE;831 mrb_get_args(mrb, "|b", &recur);832 return mrb_obj_methods(mrb, recur, self, NOEX_PUBLIC); /* public attribute not define */833 562 } 834 563 … … 858 587 { 859 588 mrb_value a[2], exc; 860 int argc;589 mrb_int argc; 861 590 862 591 … … 910 639 911 640 mrb_get_args(mrb, "n", &sym); 912 mrb_iv_ check(mrb, sym);641 mrb_iv_name_sym_check(mrb, sym); 913 642 val = mrb_iv_remove(mrb, self, sym); 914 643 if (mrb_undef_p(val)) { 915 mrb_name_error(mrb, sym, "instance variable % S not defined", mrb_sym2str(mrb, sym));644 mrb_name_error(mrb, sym, "instance variable %n not defined", sym); 916 645 } 917 646 return val; … … 921 650 mrb_method_missing(mrb_state *mrb, mrb_sym name, mrb_value self, mrb_value args) 922 651 { 923 mrb_sym inspect; 924 mrb_value repr; 925 926 inspect = mrb_intern_lit(mrb, "inspect"); 927 if (mrb->c->ci > mrb->c->cibase && mrb->c->ci[-1].mid == inspect) { 928 /* method missing in inspect; avoid recursion */ 929 repr = mrb_any_to_s(mrb, self); 930 } 931 else if (mrb_respond_to(mrb, self, inspect) && mrb->c->ci - mrb->c->cibase < 16) { 932 repr = mrb_funcall_argv(mrb, self, inspect, 0, 0); 933 if (mrb_string_p(repr) && RSTRING_LEN(repr) > 64) { 934 repr = mrb_any_to_s(mrb, self); 935 } 936 } 937 else { 938 repr = mrb_any_to_s(mrb, self); 939 } 940 941 mrb_no_method_error(mrb, name, args, "undefined method '%S' for %S", 942 mrb_sym2str(mrb, name), repr); 652 mrb_no_method_error(mrb, name, args, "undefined method '%n'", name); 943 653 } 944 654 … … 976 686 * r.mm #=> 2000 977 687 */ 978 #ifdef MRB_DEFAULT_METHOD_MISSING979 688 static mrb_value 980 689 mrb_obj_missing(mrb_state *mrb, mrb_value mod) … … 984 693 mrb_int alen; 985 694 986 mrb_get_args(mrb, "n* ", &name, &a, &alen);695 mrb_get_args(mrb, "n*!", &name, &a, &alen); 987 696 mrb_method_missing(mrb, name, mod, mrb_ary_new_from_values(mrb, alen, a)); 988 697 /* not reached */ 989 698 return mrb_nil_value(); 990 699 } 991 #endif992 700 993 701 static inline mrb_bool … … 996 704 return mrb_respond_to(mrb, obj, id); 997 705 } 706 998 707 /* 15.3.1.3.43 */ 999 708 /* … … 1015 724 obj_respond_to(mrb_state *mrb, mrb_value self) 1016 725 { 1017 mrb_value mid;1018 726 mrb_sym id, rtm_id; 1019 mrb_bool priv = FALSE, respond_to_p = TRUE; 1020 1021 mrb_get_args(mrb, "o|b", &mid, &priv); 1022 1023 if (mrb_symbol_p(mid)) { 1024 id = mrb_symbol(mid); 1025 } 1026 else { 1027 mrb_value tmp; 1028 if (mrb_string_p(mid)) { 1029 tmp = mrb_check_intern_str(mrb, mid); 1030 } 1031 else { 1032 tmp = mrb_check_string_type(mrb, mid); 1033 if (mrb_nil_p(tmp)) { 1034 tmp = mrb_inspect(mrb, mid); 1035 mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a symbol", tmp); 1036 } 1037 tmp = mrb_check_intern_str(mrb, tmp); 1038 } 1039 if (mrb_nil_p(tmp)) { 1040 respond_to_p = FALSE; 1041 } 1042 else { 1043 id = mrb_symbol(tmp); 1044 } 1045 } 1046 1047 if (respond_to_p) { 1048 respond_to_p = basic_obj_respond_to(mrb, self, id, !priv); 1049 } 1050 727 mrb_bool priv = FALSE, respond_to_p; 728 729 mrb_get_args(mrb, "n|b", &id, &priv); 730 respond_to_p = basic_obj_respond_to(mrb, self, id, !priv); 1051 731 if (!respond_to_p) { 1052 732 rtm_id = mrb_intern_lit(mrb, "respond_to_missing?"); 1053 733 if (basic_obj_respond_to(mrb, self, rtm_id, !priv)) { 1054 734 mrb_value args[2], v; 1055 args[0] = m id;735 args[0] = mrb_symbol_value(id); 1056 736 args[1] = mrb_bool_value(priv); 1057 737 v = mrb_funcall_argv(mrb, self, rtm_id, 2, args); … … 1060 740 } 1061 741 return mrb_bool_value(respond_to_p); 1062 }1063 1064 /* 15.3.1.3.45 */1065 /*1066 * call-seq:1067 * obj.singleton_methods(all=true) -> array1068 *1069 * Returns an array of the names of singleton methods for <i>obj</i>.1070 * If the optional <i>all</i> parameter is true, the list will include1071 * methods in modules included in <i>obj</i>.1072 * Only public and protected singleton methods are returned.1073 *1074 * module Other1075 * def three() end1076 * end1077 *1078 * class Single1079 * def Single.four() end1080 * end1081 *1082 * a = Single.new1083 *1084 * def a.one()1085 * end1086 *1087 * class << a1088 * include Other1089 * def two()1090 * end1091 * end1092 *1093 * Single.singleton_methods #=> [:four]1094 * a.singleton_methods(false) #=> [:two, :one]1095 * a.singleton_methods #=> [:two, :one, :three]1096 */1097 static mrb_value1098 mrb_obj_singleton_methods_m(mrb_state *mrb, mrb_value self)1099 {1100 mrb_bool recur = TRUE;1101 mrb_get_args(mrb, "|b", &recur);1102 return mrb_obj_singleton_methods(mrb, recur, self);1103 }1104 1105 static mrb_value1106 mod_define_singleton_method(mrb_state *mrb, mrb_value self)1107 {1108 struct RProc *p;1109 mrb_sym mid;1110 mrb_value blk = mrb_nil_value();1111 1112 mrb_get_args(mrb, "n&", &mid, &blk);1113 if (mrb_nil_p(blk)) {1114 mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");1115 }1116 p = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class);1117 mrb_proc_copy(p, mrb_proc_ptr(blk));1118 p->flags |= MRB_PROC_STRICT;1119 mrb_define_method_raw(mrb, mrb_class_ptr(mrb_singleton_class(mrb, self)), mid, p);1120 return mrb_symbol_value(mid);1121 742 } 1122 743 … … 1138 759 } 1139 760 1140 static mrb_value1141 mrb_local_variables(mrb_state *mrb, mrb_value self)1142 {1143 struct RProc *proc;1144 mrb_value vars;1145 struct mrb_irep *irep;1146 size_t i;1147 1148 proc = mrb->c->ci[-1].proc;1149 1150 if (MRB_PROC_CFUNC_P(proc)) {1151 return mrb_ary_new(mrb);1152 }1153 1154 irep = proc->body.irep;1155 if (!irep->lv) {1156 return mrb_ary_new(mrb);1157 }1158 vars = mrb_hash_new(mrb);1159 for (i = 0; i + 1 < irep->nlocals; ++i) {1160 if (irep->lv[i].name) {1161 mrb_hash_set(mrb, vars, mrb_symbol_value(irep->lv[i].name), mrb_true_value());1162 }1163 }1164 if (proc->env) {1165 struct REnv *e = proc->env;1166 1167 while (e) {1168 if (MRB_ENV_STACK_SHARED_P(e) &&1169 !MRB_PROC_CFUNC_P(e->cxt.c->cibase[e->cioff].proc)) {1170 irep = e->cxt.c->cibase[e->cioff].proc->body.irep;1171 if (irep->lv) {1172 for (i = 0; i + 1 < irep->nlocals; ++i) {1173 if (irep->lv[i].name) {1174 mrb_hash_set(mrb, vars, mrb_symbol_value(irep->lv[i].name), mrb_true_value());1175 }1176 }1177 }1178 }1179 e = (struct REnv*)e->c;1180 }1181 }1182 1183 return mrb_hash_keys(mrb, vars);1184 }1185 1186 761 mrb_value mrb_obj_equal_m(mrb_state *mrb, mrb_value); 762 1187 763 void 1188 764 mrb_init_kernel(mrb_state *mrb) … … 1192 768 mrb->kernel_module = krn = mrb_define_module(mrb, "Kernel"); /* 15.3.1 */ 1193 769 mrb_define_class_method(mrb, krn, "block_given?", mrb_f_block_given_p_m, MRB_ARGS_NONE()); /* 15.3.1.2.2 */ 1194 mrb_define_class_method(mrb, krn, "global_variables", mrb_f_global_variables, MRB_ARGS_NONE()); /* 15.3.1.2.4 */1195 770 mrb_define_class_method(mrb, krn, "iterator?", mrb_f_block_given_p_m, MRB_ARGS_NONE()); /* 15.3.1.2.5 */ 1196 mrb_define_class_method(mrb, krn, "local_variables", mrb_local_variables, MRB_ARGS_NONE()); /* 15.3.1.2.7 */1197 771 ; /* 15.3.1.2.11 */ 1198 772 mrb_define_class_method(mrb, krn, "raise", mrb_f_raise, MRB_ARGS_OPT(2)); /* 15.3.1.2.12 */ 1199 773 1200 mrb_define_method(mrb, krn, "singleton_class", mrb_singleton_class, MRB_ARGS_NONE());1201 774 1202 775 mrb_define_method(mrb, krn, "===", mrb_equal_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.2 */ … … 1206 779 mrb_define_method(mrb, krn, "dup", mrb_obj_dup, MRB_ARGS_NONE()); /* 15.3.1.3.9 */ 1207 780 mrb_define_method(mrb, krn, "eql?", mrb_obj_equal_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.10 */ 1208 mrb_define_method(mrb, krn, "equal?", mrb_obj_equal_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.11 */1209 781 mrb_define_method(mrb, krn, "extend", mrb_obj_extend_m, MRB_ARGS_ANY()); /* 15.3.1.3.13 */ 1210 782 mrb_define_method(mrb, krn, "freeze", mrb_obj_freeze, MRB_ARGS_NONE()); 1211 783 mrb_define_method(mrb, krn, "frozen?", mrb_obj_frozen, MRB_ARGS_NONE()); 1212 mrb_define_method(mrb, krn, "global_variables", mrb_f_global_variables, MRB_ARGS_NONE()); /* 15.3.1.3.14 */1213 784 mrb_define_method(mrb, krn, "hash", mrb_obj_hash, MRB_ARGS_NONE()); /* 15.3.1.3.15 */ 1214 785 mrb_define_method(mrb, krn, "initialize_copy", mrb_obj_init_copy, MRB_ARGS_REQ(1)); /* 15.3.1.3.16 */ 1215 786 mrb_define_method(mrb, krn, "inspect", mrb_obj_inspect, MRB_ARGS_NONE()); /* 15.3.1.3.17 */ 1216 787 mrb_define_method(mrb, krn, "instance_of?", obj_is_instance_of, MRB_ARGS_REQ(1)); /* 15.3.1.3.19 */ 1217 mrb_define_method(mrb, krn, "instance_variable_defined?", mrb_obj_ivar_defined, MRB_ARGS_REQ(1)); /* 15.3.1.3.20 */ 1218 mrb_define_method(mrb, krn, "instance_variable_get", mrb_obj_ivar_get, MRB_ARGS_REQ(1)); /* 15.3.1.3.21 */ 1219 mrb_define_method(mrb, krn, "instance_variable_set", mrb_obj_ivar_set, MRB_ARGS_REQ(2)); /* 15.3.1.3.22 */ 1220 mrb_define_method(mrb, krn, "instance_variables", mrb_obj_instance_variables, MRB_ARGS_NONE()); /* 15.3.1.3.23 */ 788 1221 789 mrb_define_method(mrb, krn, "is_a?", mrb_obj_is_kind_of_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.24 */ 1222 790 mrb_define_method(mrb, krn, "iterator?", mrb_f_block_given_p_m, MRB_ARGS_NONE()); /* 15.3.1.3.25 */ 1223 791 mrb_define_method(mrb, krn, "kind_of?", mrb_obj_is_kind_of_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.26 */ 1224 mrb_define_method(mrb, krn, "local_variables", mrb_local_variables, MRB_ARGS_NONE()); /* 15.3.1.3.28 */1225 #ifdef MRB_DEFAULT_METHOD_MISSING1226 792 mrb_define_method(mrb, krn, "method_missing", mrb_obj_missing, MRB_ARGS_ANY()); /* 15.3.1.3.30 */ 1227 #endif1228 mrb_define_method(mrb, krn, "methods", mrb_obj_methods_m, MRB_ARGS_OPT(1)); /* 15.3.1.3.31 */1229 793 mrb_define_method(mrb, krn, "nil?", mrb_false, MRB_ARGS_NONE()); /* 15.3.1.3.32 */ 1230 794 mrb_define_method(mrb, krn, "object_id", mrb_obj_id_m, MRB_ARGS_NONE()); /* 15.3.1.3.33 */ 1231 mrb_define_method(mrb, krn, "private_methods", mrb_obj_private_methods, MRB_ARGS_OPT(1)); /* 15.3.1.3.36 */1232 mrb_define_method(mrb, krn, "protected_methods", mrb_obj_protected_methods, MRB_ARGS_OPT(1)); /* 15.3.1.3.37 */1233 mrb_define_method(mrb, krn, "public_methods", mrb_obj_public_methods, MRB_ARGS_OPT(1)); /* 15.3.1.3.38 */1234 795 mrb_define_method(mrb, krn, "raise", mrb_f_raise, MRB_ARGS_ANY()); /* 15.3.1.3.40 */ 1235 796 mrb_define_method(mrb, krn, "remove_instance_variable", mrb_obj_remove_instance_variable,MRB_ARGS_REQ(1)); /* 15.3.1.3.41 */ 1236 mrb_define_method(mrb, krn, "respond_to?", obj_respond_to, MRB_ARGS_ANY()); /* 15.3.1.3.43 */ 1237 mrb_define_method(mrb, krn, "send", mrb_f_send, MRB_ARGS_ANY()); /* 15.3.1.3.44 */ 1238 mrb_define_method(mrb, krn, "singleton_methods", mrb_obj_singleton_methods_m, MRB_ARGS_OPT(1)); /* 15.3.1.3.45 */ 1239 mrb_define_method(mrb, krn, "define_singleton_method", mod_define_singleton_method, MRB_ARGS_ANY()); 797 mrb_define_method(mrb, krn, "respond_to?", obj_respond_to, MRB_ARGS_ARG(1,1)); /* 15.3.1.3.43 */ 1240 798 mrb_define_method(mrb, krn, "to_s", mrb_any_to_s, MRB_ARGS_NONE()); /* 15.3.1.3.46 */ 1241 799 mrb_define_method(mrb, krn, "__case_eqq", mrb_obj_ceqq, MRB_ARGS_REQ(1)); /* internal */ 800 mrb_define_method(mrb, krn, "__to_int", mrb_to_int, MRB_ARGS_NONE()); /* internal */ 801 mrb_define_method(mrb, krn, "__to_str", mrb_to_str, MRB_ARGS_NONE()); /* internal */ 1242 802 1243 803 mrb_include_module(mrb, mrb->object_class, mrb->kernel_module); 1244 mrb_alias_method(mrb, mrb->module_class, mrb_intern_lit(mrb, "dup"), mrb_intern_lit(mrb, "clone")); 1245 } 804 } -
EcnlProtoTool/trunk/mruby-2.1.1/src/load.c
r331 r439 8 8 #include <stdlib.h> 9 9 #include <string.h> 10 #include <math.h> 10 11 #include <mruby/dump.h> 11 12 #include <mruby/irep.h> … … 25 26 #define FLAG_SRC_STATIC 0 26 27 27 #define SIZE_ERROR_MUL(nmemb, size) (( nmemb) > SIZE_MAX / (size))28 #define SIZE_ERROR_MUL(nmemb, size) ((size_t)(nmemb) > SIZE_MAX / (size)) 28 29 29 30 static size_t … … 41 42 } 42 43 44 #ifndef MRB_WITHOUT_FLOAT 45 double mrb_str_len_to_dbl(mrb_state *mrb, const char *s, size_t len, mrb_bool badcheck); 46 47 static double 48 str_to_double(mrb_state *mrb, const char *p, size_t len) 49 { 50 /* `i`, `inf`, `infinity` */ 51 if (len > 0 && p[0] == 'i') return INFINITY; 52 53 /* `I`, `-inf`, `-infinity` */ 54 if (p[0] == 'I' || (len > 1 && p[0] == '-' && p[1] == 'i')) return -INFINITY; 55 return mrb_str_len_to_dbl(mrb, p, len, TRUE); 56 } 57 #endif 58 59 mrb_value mrb_str_len_to_inum(mrb_state *mrb, const char *str, mrb_int len, mrb_int base, int badcheck); 60 43 61 static mrb_irep* 44 62 read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flags) 45 63 { 46 size_t i;64 int i; 47 65 const uint8_t *src = bin; 48 66 ptrdiff_t diff; 49 67 uint16_t tt, pool_data_len, snl; 50 size_t plen;68 int plen; 51 69 int ai = mrb_gc_arena_save(mrb); 52 70 mrb_irep *irep = mrb_add_irep(mrb); … … 69 87 /* Binary Data Section */ 70 88 /* ISEQ BLOCK */ 71 irep->ilen = ( size_t)bin_to_uint32(src);89 irep->ilen = (uint16_t)bin_to_uint32(src); 72 90 src += sizeof(uint32_t); 73 91 src += skip_padding(src); … … 80 98 (flags & FLAG_BYTEORDER_NATIVE)) { 81 99 irep->iseq = (mrb_code*)src; 82 src += sizeof( uint32_t) * irep->ilen;100 src += sizeof(mrb_code) * irep->ilen; 83 101 irep->flags |= MRB_ISEQ_NO_FREE; 84 102 } 85 103 else { 86 irep->iseq = (mrb_code *)mrb_malloc(mrb, sizeof(mrb_code) * irep->ilen); 87 if (flags & FLAG_BYTEORDER_NATIVE) { 88 memcpy(irep->iseq, src, sizeof(uint32_t) * irep->ilen); 89 src += sizeof(uint32_t) * irep->ilen; 90 } 91 else if (flags & FLAG_BYTEORDER_BIG) { 92 for (i = 0; i < irep->ilen; i++) { 93 irep->iseq[i] = (mrb_code)bin_to_uint32(src); /* iseq */ 94 src += sizeof(uint32_t); 95 } 96 } 97 else { 98 for (i = 0; i < irep->ilen; i++) { 99 irep->iseq[i] = (mrb_code)bin_to_uint32l(src); /* iseq */ 100 src += sizeof(uint32_t); 101 } 102 } 104 size_t data_len = sizeof(mrb_code) * irep->ilen; 105 void *buf = mrb_malloc(mrb, data_len); 106 irep->iseq = (mrb_code *)buf; 107 memcpy(buf, src, data_len); 108 src += data_len; 103 109 } 104 110 } 105 111 106 112 /* POOL BLOCK */ 107 plen = (size_t)bin_to_uint32(src); /* number of pool */113 plen = bin_to_uint32(src); /* number of pool */ 108 114 src += sizeof(uint32_t); 109 115 if (plen > 0) { … … 114 120 115 121 for (i = 0; i < plen; i++) { 116 mrb_value s; 122 const char *s; 123 mrb_bool st = (flags & FLAG_SRC_MALLOC)==0; 117 124 118 125 tt = *src++; /* pool TT */ 119 126 pool_data_len = bin_to_uint16(src); /* pool data length */ 120 127 src += sizeof(uint16_t); 121 if (flags & FLAG_SRC_MALLOC) { 122 s = mrb_str_new(mrb, (char *)src, pool_data_len); 123 } 124 else { 125 s = mrb_str_new_static(mrb, (char *)src, pool_data_len); 126 } 128 s = (const char*)src; 127 129 src += pool_data_len; 128 130 switch (tt) { /* pool data */ 129 case IREP_TT_FIXNUM: 130 irep->pool[i] = mrb_str_to_inum(mrb, s, 10, FALSE); 131 case IREP_TT_FIXNUM: { 132 mrb_value num = mrb_str_len_to_inum(mrb, s, pool_data_len, 10, FALSE); 133 #ifdef MRB_WITHOUT_FLOAT 134 irep->pool[i] = num; 135 #else 136 irep->pool[i] = mrb_float_p(num)? mrb_float_pool(mrb, mrb_float(num)) : num; 137 #endif 138 } 131 139 break; 132 140 141 #ifndef MRB_WITHOUT_FLOAT 133 142 case IREP_TT_FLOAT: 134 irep->pool[i] = mrb_float_pool(mrb, mrb_str_to_dbl(mrb, s, FALSE));143 irep->pool[i] = mrb_float_pool(mrb, str_to_double(mrb, s, pool_data_len)); 135 144 break; 145 #endif 136 146 137 147 case IREP_TT_STRING: 138 irep->pool[i] = mrb_str_pool(mrb, s );148 irep->pool[i] = mrb_str_pool(mrb, s, pool_data_len, st); 139 149 break; 140 150 … … 150 160 151 161 /* SYMS BLOCK */ 152 irep->slen = ( size_t)bin_to_uint32(src); /* syms length */162 irep->slen = (uint16_t)bin_to_uint32(src); /* syms length */ 153 163 src += sizeof(uint32_t); 154 164 if (irep->slen > 0) { … … 192 202 { 193 203 mrb_irep *irep = read_irep_record_1(mrb, bin, len, flags); 194 size_t i;204 int i; 195 205 196 206 if (irep == NULL) { … … 222 232 223 233 static int 224 read_lineno_record_1(mrb_state *mrb, const uint8_t *bin, mrb_irep *irep, size_t *len)225 {226 size_t i, fname_len, niseq;227 char *fname;228 uint16_t *lines;229 230 *len = 0;231 bin += sizeof(uint32_t); /* record size */232 *len += sizeof(uint32_t);233 fname_len = bin_to_uint16(bin);234 bin += sizeof(uint16_t);235 *len += sizeof(uint16_t);236 fname = (char *)mrb_malloc(mrb, fname_len + 1);237 memcpy(fname, bin, fname_len);238 fname[fname_len] = '\0';239 bin += fname_len;240 *len += fname_len;241 242 niseq = (size_t)bin_to_uint32(bin);243 bin += sizeof(uint32_t); /* niseq */244 *len += sizeof(uint32_t);245 246 if (SIZE_ERROR_MUL(niseq, sizeof(uint16_t))) {247 return MRB_DUMP_GENERAL_FAILURE;248 }249 lines = (uint16_t *)mrb_malloc(mrb, niseq * sizeof(uint16_t));250 for (i = 0; i < niseq; i++) {251 lines[i] = bin_to_uint16(bin);252 bin += sizeof(uint16_t); /* niseq */253 *len += sizeof(uint16_t);254 }255 256 irep->filename = fname;257 irep->lines = lines;258 return MRB_DUMP_OK;259 }260 261 static int262 read_lineno_record(mrb_state *mrb, const uint8_t *bin, mrb_irep *irep, size_t *lenp)263 {264 int result = read_lineno_record_1(mrb, bin, irep, lenp);265 size_t i;266 267 if (result != MRB_DUMP_OK) return result;268 for (i = 0; i < irep->rlen; i++) {269 size_t len;270 271 result = read_lineno_record(mrb, bin, irep->reps[i], &len);272 if (result != MRB_DUMP_OK) break;273 bin += len;274 *lenp += len;275 }276 return result;277 }278 279 static int280 read_section_lineno(mrb_state *mrb, const uint8_t *bin, mrb_irep *irep)281 {282 size_t len;283 284 len = 0;285 bin += sizeof(struct rite_section_lineno_header);286 287 /* Read Binary Data Section */288 return read_lineno_record(mrb, bin, irep, &len);289 }290 291 static int292 234 read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, size_t *record_len, const mrb_sym *filenames, size_t filenames_len) 293 235 { 294 236 const uint8_t *bin = start; 295 237 ptrdiff_t diff; 296 size_t record_size , i;238 size_t record_size; 297 239 uint16_t f_idx; 240 int i; 298 241 299 242 if (irep->debug_info) { return MRB_DUMP_INVALID_IREP; } 300 243 301 244 irep->debug_info = (mrb_irep_debug_info*)mrb_malloc(mrb, sizeof(mrb_irep_debug_info)); 302 irep->debug_info->pc_count = irep->ilen;245 irep->debug_info->pc_count = (uint32_t)irep->ilen; 303 246 304 247 record_size = (size_t)bin_to_uint32(bin); … … 312 255 mrb_irep_debug_info_file *file; 313 256 uint16_t filename_idx; 314 mrb_int len;315 257 316 258 file = (mrb_irep_debug_info_file *)mrb_malloc(mrb, sizeof(*file)); … … 325 267 mrb_assert(filename_idx < filenames_len); 326 268 file->filename_sym = filenames[filename_idx]; 327 len = 0;328 file->filename = mrb_sym2name_len(mrb, file->filename_sym, &len);329 269 330 270 file->line_entry_count = bin_to_uint32(bin); … … 433 373 { 434 374 const uint8_t *bin = start; 435 size_t i;436 375 ptrdiff_t diff; 376 int i; 437 377 438 378 irep->lv = (struct mrb_locals*)mrb_malloc(mrb, sizeof(struct mrb_locals) * (irep->nlocals - 1)); … … 517 457 518 458 static int 519 read_binary_header(const uint8_t *bin, size_t *bin_size, uint16_t *crc, uint8_t *flags)459 read_binary_header(const uint8_t *bin, size_t bufsize, size_t *bin_size, uint16_t *crc, uint8_t *flags) 520 460 { 521 461 const struct rite_binary_header *header = (const struct rite_binary_header *)bin; 462 463 if (bufsize < sizeof(struct rite_binary_header)) { 464 return MRB_DUMP_READ_FAULT; 465 } 522 466 523 467 if (memcmp(header->binary_ident, RITE_BINARY_IDENT, sizeof(header->binary_ident)) == 0) { … … 537 481 } 538 482 483 if (memcmp(header->binary_version, RITE_BINARY_FORMAT_VER, sizeof(header->binary_version)) != 0) { 484 return MRB_DUMP_INVALID_FILE_HEADER; 485 } 486 539 487 if (crc) { 540 488 *crc = bin_to_uint16(header->binary_crc); … … 542 490 *bin_size = (size_t)bin_to_uint32(header->binary_size); 543 491 492 if (bufsize < *bin_size) { 493 return MRB_DUMP_READ_FAULT; 494 } 495 544 496 return MRB_DUMP_OK; 545 497 } 546 498 547 499 static mrb_irep* 548 read_irep(mrb_state *mrb, const uint8_t *bin, uint8_t flags)500 read_irep(mrb_state *mrb, const uint8_t *bin, size_t bufsize, uint8_t flags) 549 501 { 550 502 int result; … … 559 511 } 560 512 561 result = read_binary_header(bin, &bin_size, &crc, &flags);513 result = read_binary_header(bin, bufsize, &bin_size, &crc, &flags); 562 514 if (result != MRB_DUMP_OK) { 563 515 return NULL; … … 576 528 if (!irep) return NULL; 577 529 } 578 else if (memcmp(section_header->section_ident, RITE_SECTION_LINENO_IDENT, sizeof(section_header->section_ident)) == 0) {579 if (!irep) return NULL; /* corrupted data */580 result = read_section_lineno(mrb, bin, irep);581 if (result < MRB_DUMP_OK) {582 return NULL;583 }584 }585 530 else if (memcmp(section_header->section_ident, RITE_SECTION_DEBUG_IDENT, sizeof(section_header->section_ident)) == 0) { 586 531 if (!irep) return NULL; /* corrupted data */ … … 606 551 mrb_read_irep(mrb_state *mrb, const uint8_t *bin) 607 552 { 608 #if def MRB_USE_ETEXT_EDATA553 #if defined(MRB_USE_LINK_TIME_RO_DATA_P) || defined(MRB_USE_CUSTOM_RO_DATA_P) 609 554 uint8_t flags = mrb_ro_data_p((char*)bin) ? FLAG_SRC_STATIC : FLAG_SRC_MALLOC; 610 555 #else … … 612 557 #endif 613 558 614 return read_irep(mrb, bin, flags); 559 return read_irep(mrb, bin, (size_t)-1, flags); 560 } 561 562 MRB_API mrb_irep* 563 mrb_read_irep_buf(mrb_state *mrb, const void *buf, size_t bufsize) 564 { 565 return read_irep(mrb, (const uint8_t *)buf, bufsize, FLAG_SRC_MALLOC); 615 566 } 616 567 … … 623 574 } 624 575 625 MRB_API mrb_value 626 mrb_load_irep_cxt(mrb_state *mrb, const uint8_t *bin, mrbc_context *c) 627 { 628 mrb_irep *irep = mrb_read_irep(mrb, bin); 576 void mrb_codedump_all(mrb_state*, struct RProc*); 577 578 static mrb_value 579 load_irep(mrb_state *mrb, mrb_irep *irep, mrbc_context *c) 580 { 629 581 struct RProc *proc; 630 582 … … 634 586 } 635 587 proc = mrb_proc_new(mrb, irep); 588 proc->c = NULL; 636 589 mrb_irep_decref(mrb, irep); 590 if (c && c->dump_result) mrb_codedump_all(mrb, proc); 637 591 if (c && c->no_exec) return mrb_obj_value(proc); 638 592 return mrb_top_run(mrb, proc, mrb_top_self(mrb), 0); … … 640 594 641 595 MRB_API mrb_value 596 mrb_load_irep_cxt(mrb_state *mrb, const uint8_t *bin, mrbc_context *c) 597 { 598 return load_irep(mrb, mrb_read_irep(mrb, bin), c); 599 } 600 601 MRB_API mrb_value 602 mrb_load_irep_buf_cxt(mrb_state *mrb, const void *buf, size_t bufsize, mrbc_context *c) 603 { 604 return load_irep(mrb, mrb_read_irep_buf(mrb, buf, bufsize), c); 605 } 606 607 MRB_API mrb_value 642 608 mrb_load_irep(mrb_state *mrb, const uint8_t *bin) 643 609 { 644 610 return mrb_load_irep_cxt(mrb, bin, NULL); 611 } 612 613 MRB_API mrb_value 614 mrb_load_irep_buf(mrb_state *mrb, const void *buf, size_t bufsize) 615 { 616 return mrb_load_irep_buf_cxt(mrb, buf, bufsize, NULL); 645 617 } 646 618 … … 665 637 goto irep_exit; 666 638 } 667 result = read_binary_header(buf, &buf_size, NULL, &flags);639 result = read_binary_header(buf, (size_t)-1, &buf_size, NULL, &flags); 668 640 if (result != MRB_DUMP_OK || buf_size <= header_size) { 669 641 goto irep_exit; … … 674 646 goto irep_exit; 675 647 } 676 irep = read_irep(mrb, buf, FLAG_SRC_MALLOC);648 irep = read_irep(mrb, buf, (size_t)-1, FLAG_SRC_MALLOC); 677 649 678 650 irep_exit: … … 681 653 } 682 654 683 void mrb_codedump_all(mrb_state*, struct RProc*);684 685 655 MRB_API mrb_value 686 656 mrb_load_irep_file_cxt(mrb_state *mrb, FILE* fp, mrbc_context *c) 687 657 { 688 mrb_irep *irep = mrb_read_irep_file(mrb, fp); 689 mrb_value val; 690 struct RProc *proc; 691 692 if (!irep) { 693 irep_error(mrb); 694 return mrb_nil_value(); 695 } 696 proc = mrb_proc_new(mrb, irep); 697 mrb_irep_decref(mrb, irep); 698 if (c && c->dump_result) mrb_codedump_all(mrb, proc); 699 if (c && c->no_exec) return mrb_obj_value(proc); 700 val = mrb_top_run(mrb, proc, mrb_top_self(mrb), 0); 701 return val; 658 return load_irep(mrb, mrb_read_irep_file(mrb, fp), c); 702 659 } 703 660 -
EcnlProtoTool/trunk/mruby-2.1.1/src/mruby_core.rake
r331 r439 12 12 objs += %w(vm error).map { |v| compile_as_cxx "#{current_dir}/#{v}.c", "#{current_build_dir}/#{v}.cxx" } 13 13 end 14 self.libmruby << objs14 self.libmruby_objs << objs 15 15 16 file lib file("#{build_dir}/lib/libmruby_core")=> objs do |t|16 file libmruby_core_static => objs do |t| 17 17 archiver.run t.name, t.prerequisites 18 18 end -
EcnlProtoTool/trunk/mruby-2.1.1/src/numeric.c
r331 r439 5 5 */ 6 6 7 #ifndef MRB_WITHOUT_FLOAT 7 8 #include <float.h> 9 #include <math.h> 10 #endif 8 11 #include <limits.h> 9 #include <math.h>10 12 #include <stdlib.h> 13 #include <string.h> 11 14 12 15 #include <mruby.h> … … 16 19 #include <mruby/class.h> 17 20 21 #ifndef MRB_WITHOUT_FLOAT 18 22 #ifdef MRB_USE_FLOAT 19 23 #define trunc(f) truncf(f) … … 21 25 #define ceil(f) ceilf(f) 22 26 #define fmod(x,y) fmodf(x,y) 23 #define MRB_FLO_TO_STR_FMT "%.7g" 24 #else 25 #define MRB_FLO_TO_STR_FMT "%.14g" 26 #endif 27 27 #define FLO_TO_STR_PREC 8 28 #else 29 #define FLO_TO_STR_PREC 16 30 #endif 31 #endif 32 33 #ifndef MRB_WITHOUT_FLOAT 28 34 MRB_API mrb_float 29 35 mrb_to_flo(mrb_state *mrb, mrb_value val) … … 40 46 } 41 47 48 MRB_API mrb_value 49 mrb_int_value(mrb_state *mrb, mrb_float f) 50 { 51 if (FIXABLE_FLOAT(f)) { 52 return mrb_fixnum_value((mrb_int)f); 53 } 54 return mrb_float_value(mrb, f); 55 } 56 #endif 57 42 58 /* 43 59 * call-seq: … … 50 66 */ 51 67 static mrb_value 52 num_pow(mrb_state *mrb, mrb_value x) 53 { 54 mrb_value y; 68 integral_pow(mrb_state *mrb, mrb_value x) 69 { 70 mrb_value y; 71 #ifndef MRB_WITHOUT_FLOAT 55 72 mrb_float d; 73 #endif 56 74 57 75 mrb_get_args(mrb, "o", &y); … … 62 80 mrb_int result = 1; 63 81 64 if (exp < 0) goto float_pow; 82 if (exp < 0) 83 #ifdef MRB_WITHOUT_FLOAT 84 return mrb_fixnum_value(0); 85 #else 86 goto float_pow; 87 #endif 65 88 for (;;) { 66 89 if (exp & 1) { 67 90 if (mrb_int_mul_overflow(result, base, &result)) { 91 #ifndef MRB_WITHOUT_FLOAT 68 92 goto float_pow; 93 #endif 69 94 } 70 95 } … … 72 97 if (exp == 0) break; 73 98 if (mrb_int_mul_overflow(base, base, &base)) { 99 #ifndef MRB_WITHOUT_FLOAT 74 100 goto float_pow; 101 #endif 75 102 } 76 103 } 77 104 return mrb_fixnum_value(result); 78 105 } 106 #ifdef MRB_WITHOUT_FLOAT 107 mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value"); 108 #else 79 109 float_pow: 80 110 d = pow(mrb_to_flo(mrb, x), mrb_to_flo(mrb, y)); 81 111 return mrb_float_value(mrb, d); 112 #endif 113 } 114 115 static mrb_value 116 integral_idiv(mrb_state *mrb, mrb_value x) 117 { 118 #ifdef MRB_WITHOUT_FLOAT 119 mrb_value y; 120 121 mrb_get_args(mrb, "o", &y); 122 if (!mrb_fixnum_p(y)) { 123 mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value"); 124 } 125 return mrb_fixnum_value(mrb_fixnum(x) / mrb_fixnum(y)); 126 #else 127 mrb_float y; 128 129 mrb_get_args(mrb, "f", &y); 130 return mrb_int_value(mrb, mrb_to_flo(mrb, x) / y); 131 #endif 82 132 } 83 133 … … 93 143 */ 94 144 95 mrb_value96 mrb_num_div(mrb_state *mrb, mrb_value x, mrb_value y)97 {98 return mrb_float_value(mrb, mrb_to_flo(mrb, x) / mrb_to_flo(mrb, y));99 }100 101 145 /* 15.2.9.3.19(x) */ 102 146 /* … … 108 152 109 153 static mrb_value 110 num_div(mrb_state *mrb, mrb_value x) 111 { 154 integral_div(mrb_state *mrb, mrb_value x) 155 { 156 #ifdef MRB_WITHOUT_FLOAT 157 mrb_value y; 158 159 mrb_get_args(mrb, "o", &y); 160 if (!mrb_fixnum_p(y)) { 161 mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value"); 162 } 163 return mrb_fixnum_value(mrb_fixnum(x) / mrb_fixnum(y)); 164 #else 112 165 mrb_float y; 113 166 114 167 mrb_get_args(mrb, "f", &y); 115 168 return mrb_float_value(mrb, mrb_to_flo(mrb, x) / y); 116 } 117 169 #endif 170 } 171 172 static mrb_value 173 integral_coerce_step_counter(mrb_state *mrb, mrb_value self) 174 { 175 mrb_value num, step; 176 177 mrb_get_args(mrb, "oo", &num, &step); 178 179 #ifndef MRB_WITHOUT_FLOAT 180 if (mrb_float_p(self) || mrb_float_p(num) || mrb_float_p(step)) { 181 return mrb_Float(mrb, self); 182 } 183 #endif 184 185 return self; 186 } 187 188 #ifndef MRB_WITHOUT_FLOAT 118 189 /******************************************************************** 119 190 * … … 139 210 flo_to_s(mrb_state *mrb, mrb_value flt) 140 211 { 141 if (isnan(mrb_float(flt))) { 212 mrb_float f = mrb_float(flt); 213 214 if (isinf(f)) { 215 return f < 0 ? mrb_str_new_lit(mrb, "-Infinity") 216 : mrb_str_new_lit(mrb, "Infinity"); 217 } 218 else if (isnan(f)) { 142 219 return mrb_str_new_lit(mrb, "NaN"); 143 220 } 144 return mrb_float_to_str(mrb, flt, MRB_FLO_TO_STR_FMT); 221 else { 222 char fmt[] = "%." MRB_STRINGIZE(FLO_TO_STR_PREC) "g"; 223 mrb_value str = mrb_float_to_str(mrb, flt, fmt); 224 mrb_int len; 225 char *begp, *p, *endp; 226 227 insert_dot_zero: 228 begp = RSTRING_PTR(str); 229 len = RSTRING_LEN(str); 230 for (p = begp, endp = p + len; p < endp; ++p) { 231 if (*p == '.') { 232 return str; 233 } 234 else if (*p == 'e') { 235 ptrdiff_t e_pos = p - begp; 236 mrb_str_cat(mrb, str, ".0", 2); 237 p = RSTRING_PTR(str) + e_pos; 238 memmove(p + 2, p, len - e_pos); 239 memcpy(p, ".0", 2); 240 return str; 241 } 242 } 243 244 if (FLO_TO_STR_PREC + (begp[0] == '-') <= len) { 245 --fmt[sizeof(fmt) - 3]; /* %.16g(%.8g) -> %.15g(%.7g) */ 246 str = mrb_float_to_str(mrb, flt, fmt); 247 goto insert_dot_zero; 248 } 249 250 return str; 251 } 145 252 } 146 253 … … 182 289 183 290 static void 184 flodivmod(mrb_state *mrb, mrb_float x, mrb_float y, mrb_float *divp, mrb_float *modp) 185 { 186 mrb_float div; 187 mrb_float mod; 188 291 flodivmod(mrb_state *mrb, double x, double y, mrb_float *divp, mrb_float *modp) 292 { 293 double div, mod; 294 295 if (isnan(y)) { 296 /* y is NaN so all results are NaN */ 297 div = mod = y; 298 goto exit; 299 } 189 300 if (y == 0.0) { 190 div = INFINITY; 301 if (x == 0) div = NAN; 302 else if (x > 0.0) div = INFINITY; 303 else div = -INFINITY; /* x < 0.0 */ 191 304 mod = NAN; 305 goto exit; 306 } 307 if ((x == 0.0) || (isinf(y) && !isinf(x))) { 308 mod = x; 192 309 } 193 310 else { 194 311 mod = fmod(x, y); 195 if (isinf(x) && isfinite(y)) 196 div = x; 197 else 198 div = (x - mod) / y; 199 if (y*mod < 0) { 200 mod += y; 201 div -= 1.0; 202 } 203 } 204 312 } 313 if (isinf(x) && !isinf(y)) { 314 div = x; 315 } 316 else { 317 div = (x - mod) / y; 318 if (modp && divp) div = round(div); 319 } 320 if (div == 0) div = 0.0; 321 if (mod == 0) mod = 0.0; 322 if (y*mod < 0) { 323 mod += y; 324 div -= 1.0; 325 } 326 exit: 205 327 if (modp) *modp = mod; 206 328 if (divp) *divp = div; … … 230 352 return mrb_float_value(mrb, mod); 231 353 } 354 #endif 232 355 233 356 /* 15.2.8.3.16 */ … … 253 376 } 254 377 378 #ifndef MRB_WITHOUT_FLOAT 255 379 static mrb_value 256 380 flo_eql(mrb_state *mrb, mrb_value x) … … 260 384 mrb_get_args(mrb, "o", &y); 261 385 if (!mrb_float_p(y)) return mrb_false_value(); 262 return mrb_bool_value(mrb_float(x) == (mrb_float)mrb_fixnum(y));386 return mrb_bool_value(mrb_float(x) == mrb_float(y)); 263 387 } 264 388 … … 312 436 int64_value(mrb_state *mrb, int64_t v) 313 437 { 314 if ( FIXABLE(v)) {438 if (TYPED_FIXABLE(v,int64_t)) { 315 439 return mrb_fixnum_value((mrb_int)v); 316 440 } … … 322 446 { 323 447 int64_t v1; 324 mrb_get_args(mrb, "");325 448 v1 = (int64_t)mrb_float(x); 326 449 return int64_value(mrb, ~v1); … … 375 498 while (width++) { 376 499 val /= 2; 500 if (val < 1.0) { 501 val = 0; 502 break; 503 } 377 504 } 378 505 #if defined(_ISOC99_SOURCE) 379 506 val = trunc(val); 380 507 #else 381 val = val > 0 ? floor(val) : ceil(val); 508 if (val > 0){ 509 val = floor(val); 510 } else { 511 val = ceil(val); 512 } 382 513 #endif 383 514 if (val == 0 && mrb_float(x) < 0) { … … 390 521 } 391 522 } 392 if (FIXABLE_FLOAT(val)) { 393 return mrb_fixnum_value((mrb_int)val); 394 } 395 return mrb_float_value(mrb, val); 396 } 397 398 static mrb_value 399 flo_lshift(mrb_state *mrb, mrb_value x) 523 return mrb_int_value(mrb, val); 524 } 525 526 static mrb_value 527 flo_rshift(mrb_state *mrb, mrb_value x) 400 528 { 401 529 mrb_int width; … … 406 534 407 535 static mrb_value 408 flo_ rshift(mrb_state *mrb, mrb_value x)536 flo_lshift(mrb_state *mrb, mrb_value x) 409 537 { 410 538 mrb_int width; … … 412 540 mrb_get_args(mrb, "i", &width); 413 541 return flo_shift(mrb, x, width); 414 }415 416 /* 15.2.8.3.18 */417 /*418 * call-seq:419 * flt.hash -> integer420 *421 * Returns a hash code for this float.422 */423 static mrb_value424 flo_hash(mrb_state *mrb, mrb_value num)425 {426 mrb_float d;427 char *c;428 size_t i;429 mrb_int hash;430 431 d = (mrb_float)mrb_fixnum(num);432 /* normalize -0.0 to 0.0 */433 if (d == 0) d = 0.0;434 c = (char*)&d;435 for (hash=0,i=0; i<sizeof(mrb_float); i++) {436 hash = (hash * 971) ^ (unsigned char)c[i];437 }438 if (hash < 0) hash = -hash;439 return mrb_fixnum_value(hash);440 542 } 441 543 … … 525 627 526 628 mrb_check_num_exact(mrb, f); 527 if (!FIXABLE_FLOAT(f)) { 528 return mrb_float_value(mrb, f); 529 } 530 return mrb_fixnum_value((mrb_int)f); 629 return mrb_int_value(mrb, f); 531 630 } 532 631 … … 551 650 552 651 mrb_check_num_exact(mrb, f); 553 if (!FIXABLE_FLOAT(f)) { 554 return mrb_float_value(mrb, f); 555 } 556 return mrb_fixnum_value((mrb_int)f); 652 return mrb_int_value(mrb, f); 557 653 } 558 654 … … 605 701 f = 1.0; 606 702 i = ndigits >= 0 ? ndigits : -ndigits; 703 if (ndigits > DBL_DIG+2) return num; 607 704 while (--i >= 0) 608 705 f = f*10.0; … … 635 732 return mrb_float_value(mrb, number); 636 733 } 637 return mrb_ fixnum_value((mrb_int)number);734 return mrb_int_value(mrb, number); 638 735 } 639 736 … … 643 740 * call-seq: 644 741 * flt.to_i -> integer 645 * flt.to_int -> integer646 742 * flt.truncate -> integer 647 743 * … … 658 754 659 755 mrb_check_num_exact(mrb, f); 660 if (!FIXABLE_FLOAT(f)) { 661 return mrb_float_value(mrb, f); 662 } 663 return mrb_fixnum_value((mrb_int)f); 756 return mrb_int_value(mrb, f); 664 757 } 665 758 … … 669 762 return mrb_bool_value(isnan(mrb_float(num))); 670 763 } 764 #endif 671 765 672 766 /* … … 682 776 * call-seq: 683 777 * int.to_i -> integer 684 * int.to_int -> integer685 778 * 686 779 * As <i>int</i> is already an <code>Integer</code>, all these … … 694 787 } 695 788 696 mrb_value697 mrb_fixnum_mul(mrb_state *mrb, mrb_value x, mrb_value y)789 static mrb_value 790 fixnum_mul(mrb_state *mrb, mrb_value x, mrb_value y) 698 791 { 699 792 mrb_int a; … … 706 799 b = mrb_fixnum(y); 707 800 if (mrb_int_mul_overflow(a, b, &c)) { 801 #ifndef MRB_WITHOUT_FLOAT 708 802 return mrb_float_value(mrb, (mrb_float)a * (mrb_float)b); 803 #endif 709 804 } 710 805 return mrb_fixnum_value(c); 711 806 } 807 #ifdef MRB_WITHOUT_FLOAT 808 mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value"); 809 #else 712 810 return mrb_float_value(mrb, (mrb_float)a * mrb_to_flo(mrb, y)); 811 #endif 812 } 813 814 MRB_API mrb_value 815 mrb_num_mul(mrb_state *mrb, mrb_value x, mrb_value y) 816 { 817 if (mrb_fixnum_p(x)) { 818 return fixnum_mul(mrb, x, y); 819 } 820 #ifndef MRB_WITHOUT_FLOAT 821 if (mrb_float_p(x)) { 822 return mrb_float_value(mrb, mrb_float(x) * mrb_to_flo(mrb, y)); 823 } 824 #endif 825 mrb_raise(mrb, E_TYPE_ERROR, "no number multiply"); 826 return mrb_nil_value(); /* not reached */ 713 827 } 714 828 … … 729 843 730 844 mrb_get_args(mrb, "o", &y); 731 return mrb_fixnum_mul(mrb, x, y);845 return fixnum_mul(mrb, x, y); 732 846 } 733 847 … … 774 888 { 775 889 mrb_value y; 776 mrb_int a ;890 mrb_int a, b; 777 891 778 892 mrb_get_args(mrb, "o", &y); 779 893 a = mrb_fixnum(x); 780 if (mrb_fixnum_p(y)) { 781 mrb_int b, mod; 782 783 if ((b=mrb_fixnum(y)) == 0) { 894 if (mrb_fixnum_p(y) && a != MRB_INT_MIN && (b=mrb_fixnum(y)) != MRB_INT_MIN) { 895 mrb_int mod; 896 897 if (b == 0) { 898 #ifdef MRB_WITHOUT_FLOAT 899 /* ZeroDivisionError */ 900 return mrb_fixnum_value(0); 901 #else 902 if (a > 0) return mrb_float_value(mrb, INFINITY); 903 if (a < 0) return mrb_float_value(mrb, INFINITY); 784 904 return mrb_float_value(mrb, NAN); 785 } 786 fixdivmod(mrb, a, b, 0, &mod); 905 #endif 906 } 907 fixdivmod(mrb, a, b, NULL, &mod); 787 908 return mrb_fixnum_value(mod); 788 909 } 910 #ifdef MRB_WITHOUT_FLOAT 911 mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value"); 912 #else 789 913 else { 790 914 mrb_float mod; 791 915 792 flodivmod(mrb, (mrb_float)a, mrb_to_flo(mrb, y), 0, &mod);916 flodivmod(mrb, (mrb_float)a, mrb_to_flo(mrb, y), NULL, &mod); 793 917 return mrb_float_value(mrb, mod); 794 918 } 919 #endif 795 920 } 796 921 … … 812 937 813 938 if (mrb_fixnum(y) == 0) { 814 return mrb_assoc_new(mrb, mrb_float_value(mrb, INFINITY), 815 mrb_float_value(mrb, NAN)); 939 #ifdef MRB_WITHOUT_FLOAT 940 return mrb_assoc_new(mrb, mrb_fixnum_value(0), mrb_fixnum_value(0)); 941 #else 942 return mrb_assoc_new(mrb, ((mrb_fixnum(x) == 0) ? 943 mrb_float_value(mrb, NAN): 944 mrb_float_value(mrb, INFINITY)), 945 mrb_float_value(mrb, NAN)); 946 #endif 816 947 } 817 948 fixdivmod(mrb, mrb_fixnum(x), mrb_fixnum(y), &div, &mod); 818 949 return mrb_assoc_new(mrb, mrb_fixnum_value(div), mrb_fixnum_value(mod)); 819 950 } 951 #ifdef MRB_WITHOUT_FLOAT 952 mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value"); 953 #else 820 954 else { 821 955 mrb_float div, mod; … … 823 957 824 958 flodivmod(mrb, (mrb_float)mrb_fixnum(x), mrb_to_flo(mrb, y), &div, &mod); 825 a = mrb_ float_value(mrb, (mrb_int)div);959 a = mrb_int_value(mrb, div); 826 960 b = mrb_float_value(mrb, mod); 827 961 return mrb_assoc_new(mrb, a, b); 828 962 } 829 } 830 963 #endif 964 } 965 966 #ifndef MRB_WITHOUT_FLOAT 831 967 static mrb_value 832 968 flo_divmod(mrb_state *mrb, mrb_value x) … … 839 975 840 976 flodivmod(mrb, mrb_float(x), mrb_to_flo(mrb, y), &div, &mod); 841 a = mrb_ float_value(mrb, (mrb_int)div);977 a = mrb_int_value(mrb, div); 842 978 b = mrb_float_value(mrb, mod); 843 979 return mrb_assoc_new(mrb, a, b); 844 980 } 981 #endif 845 982 846 983 /* 15.2.8.3.7 */ … … 865 1002 case MRB_TT_FIXNUM: 866 1003 return mrb_bool_value(mrb_fixnum(x) == mrb_fixnum(y)); 1004 #ifndef MRB_WITHOUT_FLOAT 867 1005 case MRB_TT_FLOAT: 868 1006 return mrb_bool_value((mrb_float)mrb_fixnum(x) == mrb_float(y)); 1007 #endif 869 1008 default: 870 1009 return mrb_false_value(); … … 891 1030 } 892 1031 1032 #ifdef MRB_WITHOUT_FLOAT 1033 #define bit_op(x,y,op1,op2) do {\ 1034 return mrb_fixnum_value(mrb_fixnum(x) op2 mrb_fixnum(y));\ 1035 } while(0) 1036 #else 893 1037 static mrb_value flo_and(mrb_state *mrb, mrb_value x); 894 1038 static mrb_value flo_or(mrb_state *mrb, mrb_value x); … … 896 1040 #define bit_op(x,y,op1,op2) do {\ 897 1041 if (mrb_fixnum_p(y)) return mrb_fixnum_value(mrb_fixnum(x) op2 mrb_fixnum(y));\ 898 return flo_ ## op1(mrb, mrb_float_value(mrb, mrb_fixnum(x)));\1042 return flo_ ## op1(mrb, mrb_float_value(mrb, (mrb_float)mrb_fixnum(x)));\ 899 1043 } while(0) 1044 #endif 900 1045 901 1046 /* 15.2.8.3.9 */ … … 956 1101 { 957 1102 if (width < 0) { /* mrb_int overflow */ 1103 #ifdef MRB_WITHOUT_FLOAT 1104 return mrb_fixnum_value(0); 1105 #else 958 1106 return mrb_float_value(mrb, INFINITY); 1107 #endif 959 1108 } 960 1109 if (val > 0) { 961 1110 if ((width > NUMERIC_SHIFT_WIDTH_MAX) || 962 1111 (val > (MRB_INT_MAX >> width))) { 1112 #ifdef MRB_WITHOUT_FLOAT 1113 return mrb_fixnum_value(-1); 1114 #else 963 1115 goto bit_overflow; 964 } 1116 #endif 1117 } 1118 return mrb_fixnum_value(val << width); 965 1119 } 966 1120 else { 967 1121 if ((width > NUMERIC_SHIFT_WIDTH_MAX) || 968 (val < (MRB_INT_MIN >> width))) { 1122 (val <= (MRB_INT_MIN >> width))) { 1123 #ifdef MRB_WITHOUT_FLOAT 1124 return mrb_fixnum_value(0); 1125 #else 969 1126 goto bit_overflow; 970 } 971 } 972 973 return mrb_fixnum_value(val << width); 974 1127 #endif 1128 } 1129 return mrb_fixnum_value(val * ((mrb_int)1 << width)); 1130 } 1131 1132 #ifndef MRB_WITHOUT_FLOAT 975 1133 bit_overflow: 976 1134 { … … 981 1139 return mrb_float_value(mrb, f); 982 1140 } 1141 #endif 983 1142 } 984 1143 … … 1057 1216 */ 1058 1217 1218 #ifndef MRB_WITHOUT_FLOAT 1059 1219 static mrb_value 1060 1220 fix_to_f(mrb_state *mrb, mrb_value num) … … 1070 1230 * to numerical classes which don't support them. 1071 1231 * 1072 * Float::INFINITY.to_ r1232 * Float::INFINITY.to_i 1073 1233 * 1074 1234 * <em>raises the exception:</em> … … 1089 1249 mrb_float d = mrb_float(x); 1090 1250 1091 if (isinf(d)) { 1092 mrb_raise(mrb, E_FLOATDOMAIN_ERROR, d < 0 ? "-Infinity" : "Infinity"); 1093 } 1094 if (isnan(d)) { 1095 mrb_raise(mrb, E_FLOATDOMAIN_ERROR, "NaN"); 1096 } 1251 mrb_check_num_exact(mrb, d); 1097 1252 if (FIXABLE_FLOAT(d)) { 1098 1253 z = (mrb_int)d; 1099 1254 } 1100 1255 else { 1101 mrb_raisef(mrb, E_ ARGUMENT_ERROR, "number (%S) too big for integer", x);1256 mrb_raisef(mrb, E_RANGE_ERROR, "number (%v) too big for integer", x); 1102 1257 } 1103 1258 } 1104 1259 return mrb_fixnum_value(z); 1105 1260 } 1106 1107 mrb_value 1108 mrb_fixnum_plus(mrb_state *mrb, mrb_value x, mrb_value y) 1261 #endif 1262 1263 static mrb_value 1264 fixnum_plus(mrb_state *mrb, mrb_value x, mrb_value y) 1109 1265 { 1110 1266 mrb_int a; … … 1117 1273 b = mrb_fixnum(y); 1118 1274 if (mrb_int_add_overflow(a, b, &c)) { 1275 #ifndef MRB_WITHOUT_FLOAT 1119 1276 return mrb_float_value(mrb, (mrb_float)a + (mrb_float)b); 1277 #endif 1120 1278 } 1121 1279 return mrb_fixnum_value(c); 1122 1280 } 1281 #ifdef MRB_WITHOUT_FLOAT 1282 mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value"); 1283 #else 1123 1284 return mrb_float_value(mrb, (mrb_float)a + mrb_to_flo(mrb, y)); 1285 #endif 1286 } 1287 1288 MRB_API mrb_value 1289 mrb_num_plus(mrb_state *mrb, mrb_value x, mrb_value y) 1290 { 1291 if (mrb_fixnum_p(x)) { 1292 return fixnum_plus(mrb, x, y); 1293 } 1294 #ifndef MRB_WITHOUT_FLOAT 1295 if (mrb_float_p(x)) { 1296 return mrb_float_value(mrb, mrb_float(x) + mrb_to_flo(mrb, y)); 1297 } 1298 #endif 1299 mrb_raise(mrb, E_TYPE_ERROR, "no number addition"); 1300 return mrb_nil_value(); /* not reached */ 1124 1301 } 1125 1302 … … 1139 1316 1140 1317 mrb_get_args(mrb, "o", &other); 1141 return mrb_fixnum_plus(mrb, self, other);1142 } 1143 1144 mrb_value1145 mrb_fixnum_minus(mrb_state *mrb, mrb_value x, mrb_value y)1318 return fixnum_plus(mrb, self, other); 1319 } 1320 1321 static mrb_value 1322 fixnum_minus(mrb_state *mrb, mrb_value x, mrb_value y) 1146 1323 { 1147 1324 mrb_int a; … … 1153 1330 b = mrb_fixnum(y); 1154 1331 if (mrb_int_sub_overflow(a, b, &c)) { 1332 #ifndef MRB_WITHOUT_FLOAT 1155 1333 return mrb_float_value(mrb, (mrb_float)a - (mrb_float)b); 1334 #endif 1156 1335 } 1157 1336 return mrb_fixnum_value(c); 1158 1337 } 1338 #ifdef MRB_WITHOUT_FLOAT 1339 mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value"); 1340 #else 1159 1341 return mrb_float_value(mrb, (mrb_float)a - mrb_to_flo(mrb, y)); 1342 #endif 1343 } 1344 1345 MRB_API mrb_value 1346 mrb_num_minus(mrb_state *mrb, mrb_value x, mrb_value y) 1347 { 1348 if (mrb_fixnum_p(x)) { 1349 return fixnum_minus(mrb, x, y); 1350 } 1351 #ifndef MRB_WITHOUT_FLOAT 1352 if (mrb_float_p(x)) { 1353 return mrb_float_value(mrb, mrb_float(x) - mrb_to_flo(mrb, y)); 1354 } 1355 #endif 1356 mrb_raise(mrb, E_TYPE_ERROR, "no number subtraction"); 1357 return mrb_nil_value(); /* not reached */ 1160 1358 } 1161 1359 … … 1176 1374 1177 1375 mrb_get_args(mrb, "o", &other); 1178 return mrb_fixnum_minus(mrb, self, other);1376 return fixnum_minus(mrb, self, other); 1179 1377 } 1180 1378 1181 1379 1182 1380 MRB_API mrb_value 1183 mrb_fixnum_to_str(mrb_state *mrb, mrb_value x, int base)1381 mrb_fixnum_to_str(mrb_state *mrb, mrb_value x, mrb_int base) 1184 1382 { 1185 1383 char buf[MRB_INT_BIT+1]; … … 1188 1386 1189 1387 if (base < 2 || 36 < base) { 1190 mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid radix % S", mrb_fixnum_value(base));1388 mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid radix %i", base); 1191 1389 } 1192 1390 … … 1232 1430 mrb_get_args(mrb, "|i", &base); 1233 1431 return mrb_fixnum_to_str(mrb, self, base); 1432 } 1433 1434 /* compare two numbers: (1:0:-1; -2 for error) */ 1435 static mrb_int 1436 cmpnum(mrb_state *mrb, mrb_value v1, mrb_value v2) 1437 { 1438 #ifdef MRB_WITHOUT_FLOAT 1439 mrb_int x, y; 1440 #else 1441 mrb_float x, y; 1442 #endif 1443 1444 #ifdef MRB_WITHOUT_FLOAT 1445 x = mrb_fixnum(v1); 1446 #else 1447 x = mrb_to_flo(mrb, v1); 1448 #endif 1449 switch (mrb_type(v2)) { 1450 case MRB_TT_FIXNUM: 1451 #ifdef MRB_WITHOUT_FLOAT 1452 y = mrb_fixnum(v2); 1453 #else 1454 y = (mrb_float)mrb_fixnum(v2); 1455 #endif 1456 break; 1457 #ifndef MRB_WITHOUT_FLOAT 1458 case MRB_TT_FLOAT: 1459 y = mrb_float(v2); 1460 break; 1461 #endif 1462 default: 1463 return -2; 1464 } 1465 if (x > y) 1466 return 1; 1467 else { 1468 if (x < y) 1469 return -1; 1470 return 0; 1471 } 1234 1472 } 1235 1473 … … 1246 1484 */ 1247 1485 static mrb_value 1248 num_cmp(mrb_state *mrb, mrb_value self)1486 integral_cmp(mrb_state *mrb, mrb_value self) 1249 1487 { 1250 1488 mrb_value other; 1251 mrb_ float x, y;1489 mrb_int n; 1252 1490 1253 1491 mrb_get_args(mrb, "o", &other); 1254 1255 x = mrb_to_flo(mrb, self); 1256 switch (mrb_type(other)) { 1492 n = cmpnum(mrb, self, other); 1493 if (n == -2) return mrb_nil_value(); 1494 return mrb_fixnum_value(n); 1495 } 1496 1497 static mrb_noreturn void 1498 cmperr(mrb_state *mrb, mrb_value v1, mrb_value v2) 1499 { 1500 mrb_raisef(mrb, E_ARGUMENT_ERROR, "comparison of %t with %t failed", v1, v2); 1501 } 1502 1503 static mrb_value 1504 integral_lt(mrb_state *mrb, mrb_value self) 1505 { 1506 mrb_value other; 1507 mrb_int n; 1508 1509 mrb_get_args(mrb, "o", &other); 1510 n = cmpnum(mrb, self, other); 1511 if (n == -2) cmperr(mrb, self, other); 1512 if (n < 0) return mrb_true_value(); 1513 return mrb_false_value(); 1514 } 1515 1516 static mrb_value 1517 integral_le(mrb_state *mrb, mrb_value self) 1518 { 1519 mrb_value other; 1520 mrb_int n; 1521 1522 mrb_get_args(mrb, "o", &other); 1523 n = cmpnum(mrb, self, other); 1524 if (n == -2) cmperr(mrb, self, other); 1525 if (n <= 0) return mrb_true_value(); 1526 return mrb_false_value(); 1527 } 1528 1529 static mrb_value 1530 integral_gt(mrb_state *mrb, mrb_value self) 1531 { 1532 mrb_value other; 1533 mrb_int n; 1534 1535 mrb_get_args(mrb, "o", &other); 1536 n = cmpnum(mrb, self, other); 1537 if (n == -2) cmperr(mrb, self, other); 1538 if (n > 0) return mrb_true_value(); 1539 return mrb_false_value(); 1540 } 1541 1542 static mrb_value 1543 integral_ge(mrb_state *mrb, mrb_value self) 1544 { 1545 mrb_value other; 1546 mrb_int n; 1547 1548 mrb_get_args(mrb, "o", &other); 1549 n = cmpnum(mrb, self, other); 1550 if (n == -2) cmperr(mrb, self, other); 1551 if (n >= 0) return mrb_true_value(); 1552 return mrb_false_value(); 1553 } 1554 1555 MRB_API mrb_int 1556 mrb_cmp(mrb_state *mrb, mrb_value obj1, mrb_value obj2) 1557 { 1558 mrb_value v; 1559 1560 switch (mrb_type(obj1)) { 1257 1561 case MRB_TT_FIXNUM: 1258 y = (mrb_float)mrb_fixnum(other);1259 break;1260 1562 case MRB_TT_FLOAT: 1261 y = mrb_float(other); 1262 break; 1563 return cmpnum(mrb, obj1, obj2); 1564 case MRB_TT_STRING: 1565 if (!mrb_string_p(obj2)) 1566 return -2; 1567 return mrb_str_cmp(mrb, obj1, obj2); 1263 1568 default: 1264 return mrb_nil_value(); 1265 } 1266 if (x > y) 1267 return mrb_fixnum_value(1); 1268 else { 1269 if (x < y) 1270 return mrb_fixnum_value(-1); 1271 return mrb_fixnum_value(0); 1272 } 1569 v = mrb_funcall(mrb, obj1, "<=>", 1, obj2); 1570 if (mrb_nil_p(v) || !mrb_fixnum_p(v)) 1571 return -2; 1572 return mrb_fixnum(v); 1573 } 1574 } 1575 1576 static mrb_value 1577 num_finite_p(mrb_state *mrb, mrb_value self) 1578 { 1579 return mrb_true_value(); 1580 } 1581 1582 static mrb_value 1583 num_infinite_p(mrb_state *mrb, mrb_value self) 1584 { 1585 return mrb_false_value(); 1273 1586 } 1274 1587 … … 1281 1594 * and <code>other</code>. 1282 1595 */ 1596 #ifndef MRB_WITHOUT_FLOAT 1283 1597 static mrb_value 1284 1598 flo_plus(mrb_state *mrb, mrb_value x) … … 1289 1603 return mrb_float_value(mrb, mrb_float(x) + mrb_to_flo(mrb, y)); 1290 1604 } 1605 #endif 1291 1606 1292 1607 /* ------------------------------------------------------------------------*/ … … 1294 1609 mrb_init_numeric(mrb_state *mrb) 1295 1610 { 1296 struct RClass *numeric, *integer, *fixnum, *fl; 1611 struct RClass *numeric, *integer, *fixnum, *integral; 1612 #ifndef MRB_WITHOUT_FLOAT 1613 struct RClass *fl; 1614 #endif 1615 1616 integral = mrb_define_module(mrb, "Integral"); 1617 mrb_define_method(mrb, integral,"**", integral_pow, MRB_ARGS_REQ(1)); 1618 mrb_define_method(mrb, integral,"/", integral_div, MRB_ARGS_REQ(1)); /* 15.2.{8,9}.3.6 */ 1619 mrb_define_method(mrb, integral,"quo", integral_div, MRB_ARGS_REQ(1)); /* 15.2.7.4.5 (x) */ 1620 mrb_define_method(mrb, integral,"div", integral_idiv, MRB_ARGS_REQ(1)); 1621 mrb_define_method(mrb, integral,"<=>", integral_cmp, MRB_ARGS_REQ(1)); /* 15.2.{8,9}.3.1 */ 1622 mrb_define_method(mrb, integral,"<", integral_lt, MRB_ARGS_REQ(1)); 1623 mrb_define_method(mrb, integral,"<=", integral_le, MRB_ARGS_REQ(1)); 1624 mrb_define_method(mrb, integral,">", integral_gt, MRB_ARGS_REQ(1)); 1625 mrb_define_method(mrb, integral,">=", integral_ge, MRB_ARGS_REQ(1)); 1626 mrb_define_method(mrb, integral,"__coerce_step_counter", integral_coerce_step_counter, MRB_ARGS_REQ(2)); 1297 1627 1298 1628 /* Numeric Class */ 1299 1629 numeric = mrb_define_class(mrb, "Numeric", mrb->object_class); /* 15.2.7 */ 1300 1301 mrb_define_method(mrb, numeric, "**", num_pow, MRB_ARGS_REQ(1)); 1302 mrb_define_method(mrb, numeric, "/", num_div, MRB_ARGS_REQ(1)); /* 15.2.8.3.4 */ 1303 mrb_define_method(mrb, numeric, "quo", num_div, MRB_ARGS_REQ(1)); /* 15.2.7.4.5 (x) */ 1304 mrb_define_method(mrb, numeric, "<=>", num_cmp, MRB_ARGS_REQ(1)); /* 15.2.9.3.6 */ 1630 mrb_define_method(mrb, numeric, "finite?", num_finite_p, MRB_ARGS_NONE()); 1631 mrb_define_method(mrb, numeric, "infinite?",num_infinite_p, MRB_ARGS_NONE()); 1305 1632 1306 1633 /* Integer Class */ … … 1310 1637 mrb_define_method(mrb, integer, "to_i", int_to_i, MRB_ARGS_NONE()); /* 15.2.8.3.24 */ 1311 1638 mrb_define_method(mrb, integer, "to_int", int_to_i, MRB_ARGS_NONE()); 1312 mrb_define_method(mrb, integer, "ceil", int_to_i, MRB_ARGS_REQ(1)); /* 15.2.8.3.8 (x) */ 1313 mrb_define_method(mrb, integer, "floor", int_to_i, MRB_ARGS_REQ(1)); /* 15.2.8.3.10 (x) */ 1314 mrb_define_method(mrb, integer, "round", int_to_i, MRB_ARGS_REQ(1)); /* 15.2.8.3.12 (x) */ 1315 mrb_define_method(mrb, integer, "truncate", int_to_i, MRB_ARGS_REQ(1)); /* 15.2.8.3.15 (x) */ 1639 #ifndef MRB_WITHOUT_FLOAT 1640 mrb_define_method(mrb, integer, "ceil", int_to_i, MRB_ARGS_NONE()); /* 15.2.8.3.8 (x) */ 1641 mrb_define_method(mrb, integer, "floor", int_to_i, MRB_ARGS_NONE()); /* 15.2.8.3.10 (x) */ 1642 mrb_define_method(mrb, integer, "round", int_to_i, MRB_ARGS_NONE()); /* 15.2.8.3.12 (x) */ 1643 mrb_define_method(mrb, integer, "truncate", int_to_i, MRB_ARGS_NONE()); /* 15.2.8.3.15 (x) */ 1644 #endif 1316 1645 1317 1646 /* Fixnum Class */ … … 1329 1658 mrb_define_method(mrb, fixnum, ">>", fix_rshift, MRB_ARGS_REQ(1)); /* 15.2.8.3.13 */ 1330 1659 mrb_define_method(mrb, fixnum, "eql?", fix_eql, MRB_ARGS_REQ(1)); /* 15.2.8.3.16 */ 1331 mrb_define_method(mrb, fixnum, "hash", flo_hash, MRB_ARGS_NONE()); /* 15.2.8.3.18 */ 1660 #ifndef MRB_WITHOUT_FLOAT 1332 1661 mrb_define_method(mrb, fixnum, "to_f", fix_to_f, MRB_ARGS_NONE()); /* 15.2.8.3.23 */ 1333 mrb_define_method(mrb, fixnum, "to_s", fix_to_s, MRB_ARGS_NONE()); /* 15.2.8.3.25 */ 1334 mrb_define_method(mrb, fixnum, "inspect", fix_to_s, MRB_ARGS_NONE()); 1662 #endif 1663 mrb_define_method(mrb, fixnum, "to_s", fix_to_s, MRB_ARGS_OPT(1)); /* 15.2.8.3.25 */ 1664 mrb_define_method(mrb, fixnum, "inspect", fix_to_s, MRB_ARGS_OPT(1)); 1335 1665 mrb_define_method(mrb, fixnum, "divmod", fix_divmod, MRB_ARGS_REQ(1)); /* 15.2.8.3.30 (x) */ 1336 1666 1667 #ifndef MRB_WITHOUT_FLOAT 1337 1668 /* Float Class */ 1338 1669 mrb->float_class = fl = mrb_define_class(mrb, "Float", numeric); /* 15.2.9 */ … … 1348 1679 mrb_define_method(mrb, fl, "|", flo_or, MRB_ARGS_REQ(1)); 1349 1680 mrb_define_method(mrb, fl, "^", flo_xor, MRB_ARGS_REQ(1)); 1350 mrb_define_method(mrb, fl, ">>", flo_ lshift, MRB_ARGS_REQ(1));1351 mrb_define_method(mrb, fl, "<<", flo_ rshift, MRB_ARGS_REQ(1));1681 mrb_define_method(mrb, fl, ">>", flo_rshift, MRB_ARGS_REQ(1)); 1682 mrb_define_method(mrb, fl, "<<", flo_lshift, MRB_ARGS_REQ(1)); 1352 1683 mrb_define_method(mrb, fl, "ceil", flo_ceil, MRB_ARGS_NONE()); /* 15.2.9.3.8 */ 1353 1684 mrb_define_method(mrb, fl, "finite?", flo_finite_p, MRB_ARGS_NONE()); /* 15.2.9.3.9 */ … … 1372 1703 mrb_define_const(mrb, fl, "NAN", mrb_float_value(mrb, NAN)); 1373 1704 #endif 1374 } 1705 1706 mrb_include_module(mrb, fl, integral); 1707 #endif 1708 } -
EcnlProtoTool/trunk/mruby-2.1.1/src/object.c
r331 r439 25 25 return (mrb_symbol(v1) == mrb_symbol(v2)); 26 26 27 #ifndef MRB_WITHOUT_FLOAT 27 28 case MRB_TT_FLOAT: 28 29 return (mrb_float(v1) == mrb_float(v2)); 30 #endif 29 31 30 32 default: … … 82 84 nil_to_s(mrb_state *mrb, mrb_value obj) 83 85 { 84 return mrb_str_new (mrb, 0, 0);86 return mrb_str_new_frozen(mrb, 0, 0); 85 87 } 86 88 … … 88 90 nil_inspect(mrb_state *mrb, mrb_value obj) 89 91 { 90 return mrb_str_new_lit (mrb, "nil");92 return mrb_str_new_lit_frozen(mrb, "nil"); 91 93 } 92 94 … … 149 151 true_to_s(mrb_state *mrb, mrb_value obj) 150 152 { 151 return mrb_str_new_lit (mrb, "true");153 return mrb_str_new_lit_frozen(mrb, "true"); 152 154 } 153 155 … … 256 258 false_to_s(mrb_state *mrb, mrb_value obj) 257 259 { 258 return mrb_str_new_lit (mrb, "false");260 return mrb_str_new_lit_frozen(mrb, "false"); 259 261 } 260 262 … … 296 298 297 299 static mrb_value 298 inspect_type(mrb_state *mrb, mrb_value val)299 {300 if (mrb_type(val) == MRB_TT_FALSE || mrb_type(val) == MRB_TT_TRUE) {301 return mrb_inspect(mrb, val);302 }303 else {304 return mrb_str_new_cstr(mrb, mrb_obj_classname(mrb, val));305 }306 }307 308 static mrb_value309 300 convert_type(mrb_state *mrb, mrb_value val, const char *tname, const char *method, mrb_bool raise) 310 301 { … … 314 305 if (!mrb_respond_to(mrb, val, m)) { 315 306 if (raise) { 316 mrb_raisef(mrb, E_TYPE_ERROR, "can't convert % S into %S", inspect_type(mrb, val), mrb_str_new_cstr(mrb, tname));307 mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %Y into %s", val, tname); 317 308 } 318 309 return mrb_nil_value(); 319 310 } 320 311 return mrb_funcall_argv(mrb, val, m, 0, 0); 321 }322 323 MRB_API mrb_value324 mrb_check_to_integer(mrb_state *mrb, mrb_value val, const char *method)325 {326 mrb_value v;327 328 if (mrb_fixnum_p(val)) return val;329 v = convert_type(mrb, val, "Integer", method, FALSE);330 if (mrb_nil_p(v) || !mrb_fixnum_p(v)) {331 return mrb_nil_value();332 }333 return v;334 312 } 335 313 … … 342 320 v = convert_type(mrb, val, tname, method, TRUE); 343 321 if (mrb_type(v) != type) { 344 mrb_raisef(mrb, E_TYPE_ERROR, "%S cannot be converted to %S by #%S", val, 345 mrb_str_new_cstr(mrb, tname), mrb_str_new_cstr(mrb, method)); 322 mrb_raisef(mrb, E_TYPE_ERROR, "%v cannot be converted to %s by #%s", val, tname, method); 346 323 } 347 324 return v; … … 374 351 {MRB_TT_SCLASS, "SClass"}, 375 352 {MRB_TT_PROC, "Proc"}, 353 #ifndef MRB_WITHOUT_FLOAT 376 354 {MRB_TT_FLOAT, "Float"}, 355 #endif 377 356 {MRB_TT_ARRAY, "Array"}, 378 357 {MRB_TT_HASH, "Hash"}, … … 406 385 etype = "Fixnum"; 407 386 } 408 else if (mrb_ type(x) == MRB_TT_SYMBOL) {387 else if (mrb_symbol_p(x)) { 409 388 etype = "Symbol"; 410 389 } … … 415 394 etype = mrb_obj_classname(mrb, x); 416 395 } 417 mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type % S (expected %S)",418 mrb_str_new_cstr(mrb, etype), mrb_str_new_cstr(mrb, type->name));396 mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %s (expected %s)", 397 etype, type->name); 419 398 } 420 399 type++; 421 400 } 422 mrb_raisef(mrb, E_TYPE_ERROR, "unknown type %S (%S given)", 423 mrb_fixnum_value(t), mrb_fixnum_value(mrb_type(x))); 401 mrb_raisef(mrb, E_TYPE_ERROR, "unknown type %d (%d given)", t, mrb_type(x)); 424 402 } 425 403 } … … 439 417 mrb_any_to_s(mrb_state *mrb, mrb_value obj) 440 418 { 441 mrb_value str = mrb_str_ buf_new(mrb, 20);419 mrb_value str = mrb_str_new_capa(mrb, 20); 442 420 const char *cname = mrb_obj_classname(mrb, obj); 443 421 444 422 mrb_str_cat_lit(mrb, str, "#<"); 445 423 mrb_str_cat_cstr(mrb, str, cname); 446 mrb_str_cat_lit(mrb, str, ":"); 447 mrb_str_concat(mrb, str, mrb_ptr_to_str(mrb, mrb_ptr(obj))); 424 if (!mrb_immediate_p(obj)) { 425 mrb_str_cat_lit(mrb, str, ":"); 426 mrb_str_cat_str(mrb, str, mrb_ptr_to_str(mrb, mrb_ptr(obj))); 427 } 448 428 mrb_str_cat_lit(mrb, str, ">"); 449 429 … … 502 482 } 503 483 504 static mrb_value505 mrb_to_integer(mrb_state *mrb, mrb_value val, const char *method)506 {507 mrb_value v;508 509 if (mrb_fixnum_p(val)) return val;510 v = convert_type(mrb, val, "Integer", method, TRUE);511 if (!mrb_obj_is_kind_of(mrb, v, mrb->fixnum_class)) {512 mrb_value type = inspect_type(mrb, val);513 mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S to Integer (%S#%S gives %S)",514 type, type, mrb_str_new_cstr(mrb, method), inspect_type(mrb, v));515 }516 return v;517 }518 519 484 MRB_API mrb_value 520 485 mrb_to_int(mrb_state *mrb, mrb_value val) 521 486 { 522 return mrb_to_integer(mrb, val, "to_int"); 523 } 524 525 MRB_API mrb_value 526 mrb_convert_to_integer(mrb_state *mrb, mrb_value val, int base) 487 488 if (!mrb_fixnum_p(val)) { 489 #ifndef MRB_WITHOUT_FLOAT 490 if (mrb_float_p(val)) { 491 return mrb_flo_to_fixnum(mrb, val); 492 } 493 #endif 494 mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %Y to Integer", val); 495 } 496 return val; 497 } 498 499 MRB_API mrb_value 500 mrb_convert_to_integer(mrb_state *mrb, mrb_value val, mrb_int base) 527 501 { 528 502 mrb_value tmp; … … 530 504 if (mrb_nil_p(val)) { 531 505 if (base != 0) goto arg_error; 532 506 mrb_raise(mrb, E_TYPE_ERROR, "can't convert nil into Integer"); 533 507 } 534 508 switch (mrb_type(val)) { 509 #ifndef MRB_WITHOUT_FLOAT 535 510 case MRB_TT_FLOAT: 536 511 if (base != 0) goto arg_error; 537 else {538 mrb_float f = mrb_float(val);539 if (FIXABLE_FLOAT(f)) {540 break;541 }542 }543 512 return mrb_flo_to_fixnum(mrb, val); 513 #endif 544 514 545 515 case MRB_TT_FIXNUM: … … 563 533 mrb_raise(mrb, E_ARGUMENT_ERROR, "base specified for non string value"); 564 534 } 565 tmp = convert_type(mrb, val, "Integer", "to_int", FALSE); 566 if (mrb_nil_p(tmp)) { 567 return mrb_to_integer(mrb, val, "to_i"); 568 } 569 return tmp; 535 /* to raise TypeError */ 536 return mrb_to_int(mrb, val); 570 537 } 571 538 … … 576 543 } 577 544 545 #ifndef MRB_WITHOUT_FLOAT 578 546 MRB_API mrb_value 579 547 mrb_Float(mrb_state *mrb, mrb_value val) … … 596 564 } 597 565 } 566 #endif 567 568 MRB_API mrb_value 569 mrb_to_str(mrb_state *mrb, mrb_value val) 570 { 571 return mrb_ensure_string_type(mrb, val); 572 } 573 574 /* obsolete: use mrb_ensure_string_type() instead */ 575 MRB_API mrb_value 576 mrb_string_type(mrb_state *mrb, mrb_value str) 577 { 578 return mrb_ensure_string_type(mrb, str); 579 } 580 581 MRB_API mrb_value 582 mrb_ensure_string_type(mrb_state *mrb, mrb_value str) 583 { 584 if (!mrb_string_p(str)) { 585 mrb_raisef(mrb, E_TYPE_ERROR, "%Y cannot be converted to String", str); 586 } 587 return str; 588 } 589 590 MRB_API mrb_value 591 mrb_check_string_type(mrb_state *mrb, mrb_value str) 592 { 593 if (!mrb_string_p(str)) return mrb_nil_value(); 594 return str; 595 } 596 597 MRB_API mrb_value 598 mrb_ensure_array_type(mrb_state *mrb, mrb_value ary) 599 { 600 if (!mrb_array_p(ary)) { 601 mrb_raisef(mrb, E_TYPE_ERROR, "%Y cannot be converted to Array", ary); 602 } 603 return ary; 604 } 605 606 MRB_API mrb_value 607 mrb_check_array_type(mrb_state *mrb, mrb_value ary) 608 { 609 if (!mrb_array_p(ary)) return mrb_nil_value(); 610 return ary; 611 } 612 613 MRB_API mrb_value 614 mrb_ensure_hash_type(mrb_state *mrb, mrb_value hash) 615 { 616 if (!mrb_hash_p(hash)) { 617 mrb_raisef(mrb, E_TYPE_ERROR, "%Y cannot be converted to Hash", hash); 618 } 619 return hash; 620 } 621 622 MRB_API mrb_value 623 mrb_check_hash_type(mrb_state *mrb, mrb_value hash) 624 { 625 if (!mrb_hash_p(hash)) return mrb_nil_value(); 626 return hash; 627 } 598 628 599 629 MRB_API mrb_value -
EcnlProtoTool/trunk/mruby-2.1.1/src/pool.c
r331 r439 5 5 */ 6 6 7 #include <stddef.h>8 #include <stdint.h>9 7 #include <string.h> 10 8 #include <mruby.h> … … 26 24 /* end of configuration section */ 27 25 26 /* Disable MSVC warning "C4200: nonstandard extension used: zero-sized array 27 * in struct/union" when in C++ mode */ 28 #ifdef _MSC_VER 29 #pragma warning(push) 30 #pragma warning(disable : 4200) 31 #endif 32 28 33 struct mrb_pool_page { 29 34 struct mrb_pool_page *next; … … 33 38 char page[]; 34 39 }; 40 41 #ifdef _MSC_VER 42 #pragma warning(pop) 43 #endif 35 44 36 45 struct mrb_pool { -
EcnlProtoTool/trunk/mruby-2.1.1/src/print.c
r331 r439 32 32 { 33 33 mrb_print_backtrace(mrb); 34 printstr(mrb_funcall(mrb, mrb_obj_value(mrb->exc), "inspect", 0), stderr);35 34 } 36 35 -
EcnlProtoTool/trunk/mruby-2.1.1/src/proc.c
r331 r439 10 10 #include <mruby/opcode.h> 11 11 12 static mrb_code call_iseq[] = {13 MKOP_A(OP_CALL, 0),12 static const mrb_code call_iseq[] = { 13 OP_CALL, 14 14 }; 15 15 16 struct RProc 16 struct RProc* 17 17 mrb_proc_new(mrb_state *mrb, mrb_irep *irep) 18 18 { … … 21 21 22 22 p = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class); 23 p->target_class = 0;24 23 if (ci) { 25 if (ci->proc) 26 p->target_class = ci->proc->target_class; 27 if (!p->target_class) 28 p->target_class = ci->target_class; 24 struct RClass *tc = NULL; 25 26 if (ci->proc) { 27 tc = MRB_PROC_TARGET_CLASS(ci->proc); 28 } 29 if (tc == NULL) { 30 tc = ci->target_class; 31 } 32 p->upper = ci->proc; 33 p->e.target_class = tc; 29 34 } 30 35 p->body.irep = irep; 31 p->env = 0;32 36 mrb_irep_incref(mrb, irep); 33 37 … … 36 40 37 41 static struct REnv* 38 env_new(mrb_state *mrb, int nlocals)42 env_new(mrb_state *mrb, mrb_int nlocals) 39 43 { 40 44 struct REnv *e; 41 42 e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, (struct RClass*)mrb->c->ci->proc->env); 43 MRB_SET_ENV_STACK_LEN(e, nlocals); 44 e->cxt.c = mrb->c; 45 e->cioff = mrb->c->ci - mrb->c->cibase; 45 mrb_callinfo *ci = mrb->c->ci; 46 int bidx; 47 48 e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, NULL); 49 MRB_ENV_SET_STACK_LEN(e, nlocals); 50 bidx = ci->argc; 51 if (ci->argc < 0) bidx = 2; 52 else bidx += 1; 53 MRB_ENV_SET_BIDX(e, bidx); 54 e->mid = ci->mid; 46 55 e->stack = mrb->c->stack; 56 e->cxt = mrb->c; 47 57 48 58 return e; … … 50 60 51 61 static void 52 closure_setup(mrb_state *mrb, struct RProc *p, int nlocals) 53 { 54 struct REnv *e; 55 56 if (!mrb->c->ci->env) { 57 e = env_new(mrb, nlocals); 58 mrb->c->ci->env = e; 59 } 60 else { 61 e = mrb->c->ci->env; 62 } 63 p->env = e; 64 mrb_field_write_barrier(mrb, (struct RBasic *)p, (struct RBasic *)p->env); 65 } 66 67 struct RProc * 62 closure_setup(mrb_state *mrb, struct RProc *p) 63 { 64 mrb_callinfo *ci = mrb->c->ci; 65 struct RProc *up = p->upper; 66 struct REnv *e = NULL; 67 68 if (ci && ci->env) { 69 e = ci->env; 70 } 71 else if (up) { 72 struct RClass *tc = MRB_PROC_TARGET_CLASS(p); 73 74 e = env_new(mrb, up->body.irep->nlocals); 75 ci->env = e; 76 if (tc) { 77 e->c = tc; 78 mrb_field_write_barrier(mrb, (struct RBasic*)e, (struct RBasic*)tc); 79 } 80 if (MRB_PROC_ENV_P(up) && MRB_PROC_ENV(up)->cxt == NULL) { 81 e->mid = MRB_PROC_ENV(up)->mid; 82 } 83 } 84 if (e) { 85 p->e.env = e; 86 p->flags |= MRB_PROC_ENVSET; 87 mrb_field_write_barrier(mrb, (struct RBasic*)p, (struct RBasic*)e); 88 } 89 } 90 91 struct RProc* 68 92 mrb_closure_new(mrb_state *mrb, mrb_irep *irep) 69 93 { 70 94 struct RProc *p = mrb_proc_new(mrb, irep); 71 95 72 closure_setup(mrb, p , mrb->c->ci->proc->body.irep->nlocals);96 closure_setup(mrb, p); 73 97 return p; 74 98 } 75 99 76 MRB_API struct RProc 100 MRB_API struct RProc* 77 101 mrb_proc_new_cfunc(mrb_state *mrb, mrb_func_t func) 78 102 { … … 81 105 p = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class); 82 106 p->body.func = func; 83 p->flags |= MRB_PROC_CFUNC; 84 p->env = 0; 107 p->flags |= MRB_PROC_CFUNC_FL; 108 p->upper = 0; 109 p->e.target_class = 0; 85 110 86 111 return p; 87 112 } 88 113 89 MRB_API struct RProc 114 MRB_API struct RProc* 90 115 mrb_proc_new_cfunc_with_env(mrb_state *mrb, mrb_func_t func, mrb_int argc, const mrb_value *argv) 91 116 { … … 94 119 int i; 95 120 96 p->env = e = env_new(mrb, argc); 97 mrb_field_write_barrier(mrb, (struct RBasic *)p, (struct RBasic *)p->env); 121 p->e.env = e = env_new(mrb, argc); 122 p->flags |= MRB_PROC_ENVSET; 123 mrb_field_write_barrier(mrb, (struct RBasic*)p, (struct RBasic*)e); 98 124 MRB_ENV_UNSHARE_STACK(e); 99 125 e->stack = (mrb_value*)mrb_malloc(mrb, sizeof(mrb_value) * argc); … … 111 137 } 112 138 113 MRB_API struct RProc 139 MRB_API struct RProc* 114 140 mrb_closure_new_cfunc(mrb_state *mrb, mrb_func_t func, int nlocals) 115 141 { … … 121 147 { 122 148 struct RProc *p = mrb->c->ci->proc; 123 struct REnv *e = p->env;124 125 if (! MRB_PROC_CFUNC_P(p)) {149 struct REnv *e; 150 151 if (!p || !MRB_PROC_CFUNC_P(p)) { 126 152 mrb_raise(mrb, E_TYPE_ERROR, "Can't get cfunc env from non-cfunc proc."); 127 153 } 154 e = MRB_PROC_ENV(p); 128 155 if (!e) { 129 156 mrb_raise(mrb, E_TYPE_ERROR, "Can't get cfunc env from cfunc Proc without REnv."); 130 157 } 131 158 if (idx < 0 || MRB_ENV_STACK_LEN(e) <= idx) { 132 mrb_raisef(mrb, E_INDEX_ERROR, "Env index out of range: % S (expected: 0 <= index < %S)",133 mrb_fixnum_value(idx), mrb_fixnum_value(MRB_ENV_STACK_LEN(e)));159 mrb_raisef(mrb, E_INDEX_ERROR, "Env index out of range: %i (expected: 0 <= index < %i)", 160 idx, MRB_ENV_STACK_LEN(e)); 134 161 } 135 162 … … 140 167 mrb_proc_copy(struct RProc *a, struct RProc *b) 141 168 { 169 if (a->body.irep) { 170 /* already initialized proc */ 171 return; 172 } 142 173 a->flags = b->flags; 143 174 a->body = b->body; … … 145 176 a->body.irep->refcnt++; 146 177 } 147 a->target_class = b->target_class; 148 a->env = b->env; 178 a->upper = b->upper; 179 a->e.env = b->e.env; 180 /* a->e.target_class = a->e.target_class; */ 149 181 } 150 182 … … 156 188 struct RProc *p; 157 189 158 mrb_get_args(mrb, "&", &blk); 159 if (mrb_nil_p(blk)) { 160 /* Calling Proc.new without a block is not implemented yet */ 161 mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Proc object without a block"); 162 } 190 /* Calling Proc.new without a block is not implemented yet */ 191 mrb_get_args(mrb, "&!", &blk); 163 192 p = (struct RProc *)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb_class_ptr(proc_class)); 164 193 mrb_proc_copy(p, mrb_proc_ptr(blk)); 165 194 proc = mrb_obj_value(p); 166 mrb_funcall_with_block(mrb, proc, mrb_intern_lit(mrb, "initialize"), 0, NULL, blk); 195 mrb_funcall_with_block(mrb, proc, mrb_intern_lit(mrb, "initialize"), 0, NULL, proc); 196 if (!MRB_PROC_STRICT_P(p) && 197 mrb->c->ci > mrb->c->cibase && MRB_PROC_ENV(p) == mrb->c->ci[-1].env) { 198 p->flags |= MRB_PROC_ORPHAN; 199 } 167 200 return proc; 168 201 } … … 174 207 175 208 mrb_get_args(mrb, "o", &proc); 176 if ( mrb_type(proc) != MRB_TT_PROC) {209 if (!mrb_proc_p(proc)) { 177 210 mrb_raise(mrb, E_ARGUMENT_ERROR, "not a proc"); 178 211 } … … 181 214 } 182 215 183 int184 mrb_proc_cfunc_p(struct RProc *p)185 {186 return MRB_PROC_CFUNC_P(p);187 }188 189 mrb_value190 mrb_proc_call_cfunc(mrb_state *mrb, struct RProc *p, mrb_value self)191 {192 return (p->body.func)(mrb, self);193 }194 195 216 /* 15.2.17.4.2 */ 196 217 static mrb_value 197 mrb_proc_arity(mrb_state *mrb, mrb_value self) 198 { 199 struct RProc *p = mrb_proc_ptr(self); 200 struct mrb_irep *irep; 201 mrb_code *iseq; 202 mrb_aspec aspec; 203 int ma, op, ra, pa, arity; 204 205 if (MRB_PROC_CFUNC_P(p)) { 206 /* TODO cfunc aspec not implemented yet */ 207 return mrb_fixnum_value(-1); 208 } 209 210 irep = p->body.irep; 211 if (!irep) { 212 return mrb_fixnum_value(0); 213 } 214 215 iseq = irep->iseq; 216 /* arity is depend on OP_ENTER */ 217 if (GET_OPCODE(*iseq) != OP_ENTER) { 218 return mrb_fixnum_value(0); 219 } 220 221 aspec = GETARG_Ax(*iseq); 222 ma = MRB_ASPEC_REQ(aspec); 223 op = MRB_ASPEC_OPT(aspec); 224 ra = MRB_ASPEC_REST(aspec); 225 pa = MRB_ASPEC_POST(aspec); 226 arity = ra || (MRB_PROC_STRICT_P(p) && op) ? -(ma + pa + 1) : ma + pa; 227 228 return mrb_fixnum_value(arity); 218 proc_arity(mrb_state *mrb, mrb_value self) 219 { 220 return mrb_fixnum_value(mrb_proc_arity(mrb_proc_ptr(self))); 229 221 } 230 222 … … 248 240 mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Proc object without a block"); 249 241 } 250 if ( mrb_type(blk) != MRB_TT_PROC) {242 if (!mrb_proc_p(blk)) { 251 243 mrb_raise(mrb, E_ARGUMENT_ERROR, "not a proc"); 252 244 } … … 261 253 } 262 254 255 mrb_int 256 mrb_proc_arity(const struct RProc *p) 257 { 258 struct mrb_irep *irep; 259 const mrb_code *pc; 260 mrb_aspec aspec; 261 int ma, op, ra, pa, arity; 262 263 if (MRB_PROC_CFUNC_P(p)) { 264 /* TODO cfunc aspec not implemented yet */ 265 return -1; 266 } 267 268 irep = p->body.irep; 269 if (!irep) { 270 return 0; 271 } 272 273 pc = irep->iseq; 274 /* arity is depend on OP_ENTER */ 275 if (*pc != OP_ENTER) { 276 return 0; 277 } 278 279 aspec = PEEK_W(pc+1); 280 ma = MRB_ASPEC_REQ(aspec); 281 op = MRB_ASPEC_OPT(aspec); 282 ra = MRB_ASPEC_REST(aspec); 283 pa = MRB_ASPEC_POST(aspec); 284 arity = ra || (MRB_PROC_STRICT_P(p) && op) ? -(ma + pa + 1) : ma + pa; 285 286 return arity; 287 } 288 263 289 void 264 290 mrb_init_proc(mrb_state *mrb) 265 291 { 266 struct RProc *m; 292 struct RProc *p; 293 mrb_method_t m; 267 294 mrb_irep *call_irep = (mrb_irep *)mrb_malloc(mrb, sizeof(mrb_irep)); 268 295 static const mrb_irep mrb_irep_zero = { 0 }; … … 274 301 call_irep->nregs = 2; /* receiver and block */ 275 302 276 mrb_define_class_method(mrb, mrb->proc_class, "new", mrb_proc_s_new, MRB_ARGS_ ANY());303 mrb_define_class_method(mrb, mrb->proc_class, "new", mrb_proc_s_new, MRB_ARGS_NONE()|MRB_ARGS_BLOCK()); 277 304 mrb_define_method(mrb, mrb->proc_class, "initialize_copy", mrb_proc_init_copy, MRB_ARGS_REQ(1)); 278 mrb_define_method(mrb, mrb->proc_class, "arity", mrb_proc_arity, MRB_ARGS_NONE()); 279 280 m = mrb_proc_new(mrb, call_irep); 305 mrb_define_method(mrb, mrb->proc_class, "arity", proc_arity, MRB_ARGS_NONE()); 306 307 p = mrb_proc_new(mrb, call_irep); 308 MRB_METHOD_FROM_PROC(m, p); 281 309 mrb_define_method_raw(mrb, mrb->proc_class, mrb_intern_lit(mrb, "call"), m); 282 310 mrb_define_method_raw(mrb, mrb->proc_class, mrb_intern_lit(mrb, "[]"), m); 283 311 284 mrb_define_class_method(mrb, mrb->kernel_module, "lambda", proc_lambda, MRB_ARGS_NONE() ); /* 15.3.1.2.6 */285 mrb_define_method(mrb, mrb->kernel_module, "lambda", proc_lambda, MRB_ARGS_NONE() ); /* 15.3.1.3.27 */286 } 312 mrb_define_class_method(mrb, mrb->kernel_module, "lambda", proc_lambda, MRB_ARGS_NONE()|MRB_ARGS_BLOCK()); /* 15.3.1.2.6 */ 313 mrb_define_method(mrb, mrb->kernel_module, "lambda", proc_lambda, MRB_ARGS_NONE()|MRB_ARGS_BLOCK()); /* 15.3.1.3.27 */ 314 } -
EcnlProtoTool/trunk/mruby-2.1.1/src/range.c
r331 r439 11 11 #include <mruby/array.h> 12 12 13 #define RANGE_CLASS (mrb_class_get(mrb, "Range")) 14 15 MRB_API struct RRange* 16 mrb_range_ptr(mrb_state *mrb, mrb_value v) 17 { 18 struct RRange *r = (struct RRange*)mrb_ptr(v); 19 20 if (r->edges == NULL) { 21 mrb_raise(mrb, E_ARGUMENT_ERROR, "uninitialized range"); 22 } 23 return r; 24 } 13 #define RANGE_INITIALIZED_MASK 1 14 #define RANGE_INITIALIZED(p) ((p)->flags |= RANGE_INITIALIZED_MASK) 15 #define RANGE_INITIALIZED_P(p) ((p)->flags & RANGE_INITIALIZED_MASK) 25 16 26 17 static void 27 range_check(mrb_state *mrb, mrb_value a, mrb_value b) 28 { 29 mrb_value ans; 18 r_check(mrb_state *mrb, mrb_value a, mrb_value b) 19 { 30 20 enum mrb_vtype ta; 31 21 enum mrb_vtype tb; 22 mrb_int n; 32 23 33 24 ta = mrb_type(a); 34 25 tb = mrb_type(b); 26 #ifdef MRB_WITHOUT_FLOAT 27 if (ta == MRB_TT_FIXNUM && tb == MRB_TT_FIXNUM ) { 28 #else 35 29 if ((ta == MRB_TT_FIXNUM || ta == MRB_TT_FLOAT) && 36 30 (tb == MRB_TT_FIXNUM || tb == MRB_TT_FLOAT)) { 31 #endif 37 32 return; 38 33 } 39 34 40 ans = mrb_funcall(mrb, a, "<=>", 1, b); 41 if (mrb_nil_p(ans)) { 42 /* can not be compared */ 35 n = mrb_cmp(mrb, a, b); 36 if (n == -2) { /* can not be compared */ 43 37 mrb_raise(mrb, E_ARGUMENT_ERROR, "bad value for range"); 44 38 } 45 39 } 46 40 47 MRB_API mrb_value 48 mrb_range_new(mrb_state *mrb, mrb_value beg, mrb_value end, mrb_bool excl) 49 { 50 struct RRange *r; 51 52 range_check(mrb, beg, end); 53 r = (struct RRange*)mrb_obj_alloc(mrb, MRB_TT_RANGE, RANGE_CLASS); 41 static mrb_bool 42 r_le(mrb_state *mrb, mrb_value a, mrb_value b) 43 { 44 mrb_int n = mrb_cmp(mrb, a, b); 45 46 if (n == 0 || n == -1) return TRUE; 47 return FALSE; 48 } 49 50 static mrb_bool 51 r_gt(mrb_state *mrb, mrb_value a, mrb_value b) 52 { 53 return mrb_cmp(mrb, a, b) == 1; 54 } 55 56 static mrb_bool 57 r_ge(mrb_state *mrb, mrb_value a, mrb_value b) 58 { 59 mrb_int n = mrb_cmp(mrb, a, b); 60 61 if (n == 0 || n == 1) return TRUE; 62 return FALSE; 63 } 64 65 static void 66 range_ptr_alloc_edges(mrb_state *mrb, struct RRange *r) 67 { 68 #ifndef MRB_RANGE_EMBED 54 69 r->edges = (mrb_range_edges *)mrb_malloc(mrb, sizeof(mrb_range_edges)); 55 r->edges->beg = beg; 56 r->edges->end = end; 57 r->excl = excl; 58 return mrb_range_value(r); 70 #endif 71 } 72 73 static struct RRange * 74 range_ptr_init(mrb_state *mrb, struct RRange *r, mrb_value beg, mrb_value end, mrb_bool excl) 75 { 76 r_check(mrb, beg, end); 77 78 if (r) { 79 if (RANGE_INITIALIZED_P(r)) { 80 /* Ranges are immutable, so that they should be initialized only once. */ 81 mrb_name_error(mrb, mrb_intern_lit(mrb, "initialize"), "'initialize' called twice"); 82 } 83 else { 84 range_ptr_alloc_edges(mrb, r); 85 } 86 } 87 else { 88 r = (struct RRange*)mrb_obj_alloc(mrb, MRB_TT_RANGE, mrb->range_class); 89 range_ptr_alloc_edges(mrb, r); 90 } 91 92 RANGE_BEG(r) = beg; 93 RANGE_END(r) = end; 94 RANGE_EXCL(r) = excl; 95 RANGE_INITIALIZED(r); 96 97 return r; 98 } 99 100 static void 101 range_ptr_replace(mrb_state *mrb, struct RRange *r, mrb_value beg, mrb_value end, mrb_bool excl) 102 { 103 range_ptr_init(mrb, r, beg, end, excl); 104 mrb_write_barrier(mrb, (struct RBasic*)r); 59 105 } 60 106 … … 66 112 * Returns the first object in <i>rng</i>. 67 113 */ 68 mrb_value 69 mrb_range_beg(mrb_state *mrb, mrb_value range) 70 { 71 struct RRange *r = mrb_range_ptr(mrb, range); 72 73 return r->edges->beg; 114 static mrb_value 115 range_beg(mrb_state *mrb, mrb_value range) 116 { 117 return mrb_range_beg(mrb, range); 74 118 } 75 119 … … 84 128 * (1...10).end #=> 10 85 129 */ 86 87 mrb_value 88 mrb_range_end(mrb_state *mrb, mrb_value range) 89 { 90 struct RRange *r = mrb_range_ptr(mrb, range); 91 92 return r->edges->end; 130 static mrb_value 131 range_end(mrb_state *mrb, mrb_value range) 132 { 133 return mrb_range_end(mrb, range); 93 134 } 94 135 … … 99 140 * Returns <code>true</code> if <i>range</i> excludes its end value. 100 141 */ 101 mrb_value 102 mrb_range_excl(mrb_state *mrb, mrb_value range) 103 { 104 struct RRange *r = mrb_range_ptr(mrb, range); 105 106 return mrb_bool_value(r->excl); 107 } 108 109 static void 110 range_init(mrb_state *mrb, mrb_value range, mrb_value beg, mrb_value end, mrb_bool exclude_end) 111 { 112 struct RRange *r = mrb_range_raw_ptr(range); 113 114 range_check(mrb, beg, end); 115 r->excl = exclude_end; 116 if (!r->edges) { 117 r->edges = (mrb_range_edges *)mrb_malloc(mrb, sizeof(mrb_range_edges)); 118 } 119 r->edges->beg = beg; 120 r->edges->end = end; 121 } 142 static mrb_value 143 range_excl(mrb_state *mrb, mrb_value range) 144 { 145 return mrb_bool_value(mrb_range_excl_p(mrb, range)); 146 } 147 122 148 /* 123 149 * call-seq: … … 128 154 * the end object; otherwise, it will be excluded. 129 155 */ 130 131 mrb_value 132 mrb_range_initialize(mrb_state *mrb, mrb_value range) 156 static mrb_value 157 range_initialize(mrb_state *mrb, mrb_value range) 133 158 { 134 159 mrb_value beg, end; 135 mrb_bool exclusive; 136 int n; 137 138 n = mrb_get_args(mrb, "oo|b", &beg, &end, &exclusive); 139 if (n != 3) { 140 exclusive = FALSE; 141 } 142 /* Ranges are immutable, so that they should be initialized only once. */ 143 if (mrb_range_raw_ptr(range)->edges) { 144 mrb_name_error(mrb, mrb_intern_lit(mrb, "initialize"), "`initialize' called twice"); 145 } 146 range_init(mrb, range, beg, end, exclusive); 160 mrb_bool exclusive = FALSE; 161 162 mrb_get_args(mrb, "oo|b", &beg, &end, &exclusive); 163 range_ptr_replace(mrb, mrb_range_raw_ptr(range), beg, end, exclusive); 147 164 return range; 148 165 } 166 149 167 /* 150 168 * call-seq: … … 159 177 * (0..2) == Range.new(0,2) #=> true 160 178 * (0..2) == (0...2) #=> false 161 * 162 */ 163 164 mrb_value 165 mrb_range_eq(mrb_state *mrb, mrb_value range) 179 */ 180 static mrb_value 181 range_eq(mrb_state *mrb, mrb_value range) 166 182 { 167 183 struct RRange *rr; 168 184 struct RRange *ro; 169 mrb_value obj, v1, v2; 185 mrb_value obj; 186 mrb_bool v1, v2; 170 187 171 188 mrb_get_args(mrb, "o", &obj); … … 178 195 rr = mrb_range_ptr(mrb, range); 179 196 ro = mrb_range_ptr(mrb, obj); 180 v1 = mrb_ funcall(mrb, rr->edges->beg, "==", 1, ro->edges->beg);181 v2 = mrb_ funcall(mrb, rr->edges->end, "==", 1, ro->edges->end);182 if (! mrb_bool(v1) || !mrb_bool(v2) || rr->excl != ro->excl) {197 v1 = mrb_equal(mrb, RANGE_BEG(rr), RANGE_BEG(ro)); 198 v2 = mrb_equal(mrb, RANGE_END(rr), RANGE_END(ro)); 199 if (!v1 || !v2 || RANGE_EXCL(rr) != RANGE_EXCL(ro)) { 183 200 return mrb_false_value(); 184 201 } 185 202 return mrb_true_value(); 186 }187 188 static mrb_bool189 r_le(mrb_state *mrb, mrb_value a, mrb_value b)190 {191 mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); /* compare result */192 /* output :a < b => -1, a = b => 0, a > b => +1 */193 194 if (mrb_fixnum_p(r)) {195 mrb_int c = mrb_fixnum(r);196 if (c == 0 || c == -1) return TRUE;197 }198 199 return FALSE;200 }201 202 static mrb_bool203 r_gt(mrb_state *mrb, mrb_value a, mrb_value b)204 {205 mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b);206 /* output :a < b => -1, a = b => 0, a > b => +1 */207 208 return mrb_fixnum_p(r) && mrb_fixnum(r) == 1;209 }210 211 static mrb_bool212 r_ge(mrb_state *mrb, mrb_value a, mrb_value b)213 {214 mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); /* compare result */215 /* output :a < b => -1, a = b => 0, a > b => +1 */216 217 if (mrb_fixnum_p(r)) {218 mrb_int c = mrb_fixnum(r);219 if (c == 0 || c == 1) return TRUE;220 }221 222 return FALSE;223 203 } 224 204 … … 228 208 * range.member?(val) => true or false 229 209 * range.include?(val) => true or false 230 * 231 */ 232 mrb_value 233 mrb_range_include(mrb_state *mrb, mrb_value range) 210 */ 211 static mrb_value 212 range_include(mrb_state *mrb, mrb_value range) 234 213 { 235 214 mrb_value val; … … 240 219 mrb_get_args(mrb, "o", &val); 241 220 242 beg = r->edges->beg;243 end = r->edges->end;244 include_p = r_le(mrb, beg, val) && /* beg <= val */245 ( r->excl? r_gt(mrb, end, val) /* end > val */246 : r_ge(mrb, end, val)); /* end >= val */221 beg = RANGE_BEG(r); 222 end = RANGE_END(r); 223 include_p = r_le(mrb, beg, val) && /* beg <= val */ 224 (RANGE_EXCL(r) ? r_gt(mrb, end, val) /* end > val */ 225 : r_ge(mrb, end, val)); /* end >= val */ 247 226 248 227 return mrb_bool_value(include_p); 249 }250 251 MRB_API mrb_int252 mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_bool trunc)253 {254 mrb_int beg, end;255 struct RRange *r;256 257 if (mrb_type(range) != MRB_TT_RANGE) return 0;258 r = mrb_range_ptr(mrb, range);259 260 beg = mrb_int(mrb, r->edges->beg);261 end = mrb_int(mrb, r->edges->end);262 263 if (beg < 0) {264 beg += len;265 if (beg < 0) return 2;266 }267 268 if (trunc) {269 if (beg > len) return 2;270 if (end > len) end = len;271 }272 273 if (end < 0) end += len;274 if (!r->excl && (!trunc || end < len))275 end++; /* include end point */276 len = end - beg;277 if (len < 0) len = 0;278 279 *begp = beg;280 *lenp = len;281 return 1;282 228 } 283 229 … … 289 235 * Convert this range object to a printable form. 290 236 */ 291 292 237 static mrb_value 293 238 range_to_s(mrb_state *mrb, mrb_value range) … … 296 241 struct RRange *r = mrb_range_ptr(mrb, range); 297 242 298 str = mrb_obj_as_string(mrb, r->edges->beg);299 str2 = mrb_obj_as_string(mrb, r->edges->end);243 str = mrb_obj_as_string(mrb, RANGE_BEG(r)); 244 str2 = mrb_obj_as_string(mrb, RANGE_END(r)); 300 245 str = mrb_str_dup(mrb, str); 301 mrb_str_cat(mrb, str, "...", r->excl? 3 : 2);246 mrb_str_cat(mrb, str, "...", RANGE_EXCL(r) ? 3 : 2); 302 247 mrb_str_cat_str(mrb, str, str2); 303 248 … … 314 259 * objects). 315 260 */ 316 317 261 static mrb_value 318 262 range_inspect(mrb_state *mrb, mrb_value range) … … 321 265 struct RRange *r = mrb_range_ptr(mrb, range); 322 266 323 str = mrb_inspect(mrb, r->edges->beg);324 str2 = mrb_inspect(mrb, r->edges->end);267 str = mrb_inspect(mrb, RANGE_BEG(r)); 268 str2 = mrb_inspect(mrb, RANGE_END(r)); 325 269 str = mrb_str_dup(mrb, str); 326 mrb_str_cat(mrb, str, "...", r->excl? 3 : 2);270 mrb_str_cat(mrb, str, "...", RANGE_EXCL(r) ? 3 : 2); 327 271 mrb_str_cat_str(mrb, str, str2); 328 272 … … 342 286 * (0..2).eql?(Range.new(0,2)) #=> true 343 287 * (0..2).eql?(0...2) #=> false 344 * 345 */ 346 288 */ 347 289 static mrb_value 348 290 range_eql(mrb_state *mrb, mrb_value range) … … 354 296 355 297 if (mrb_obj_equal(mrb, range, obj)) return mrb_true_value(); 356 if (!mrb_obj_is_kind_of(mrb, obj, RANGE_CLASS)) { 357 return mrb_false_value(); 358 } 359 if (mrb_type(obj) != MRB_TT_RANGE) return mrb_false_value(); 298 if (!mrb_obj_is_kind_of(mrb, obj, mrb->range_class)) return mrb_false_value(); 299 if (!mrb_range_p(obj)) return mrb_false_value(); 360 300 361 301 r = mrb_range_ptr(mrb, range); 362 302 o = mrb_range_ptr(mrb, obj); 363 if (!mrb_eql(mrb, r->edges->beg, o->edges->beg) ||364 !mrb_eql(mrb, r->edges->end, o->edges->end) ||365 ( r->excl != o->excl)) {303 if (!mrb_eql(mrb, RANGE_BEG(r), RANGE_BEG(o)) || 304 !mrb_eql(mrb, RANGE_END(r), RANGE_END(o)) || 305 (RANGE_EXCL(r) != RANGE_EXCL(o))) { 366 306 return mrb_false_value(); 367 307 } … … 384 324 385 325 r = mrb_range_ptr(mrb, src); 386 range_ init(mrb, copy, r->edges->beg, r->edges->end, r->excl);326 range_ptr_replace(mrb, mrb_range_raw_ptr(copy), RANGE_BEG(r), RANGE_END(r), RANGE_EXCL(r)); 387 327 388 328 return copy; … … 400 340 mrb_ary_push(mrb, result, func(mrb, obj, mrb_fixnum(argv[i]))); 401 341 } 402 else if (mrb_range_beg_len(mrb, argv[i], &beg, &len, olen, FALSE) == 1) {342 else if (mrb_range_beg_len(mrb, argv[i], &beg, &len, olen, FALSE) == MRB_RANGE_OK) { 403 343 mrb_int const end = olen < beg + len ? olen : beg + len; 404 344 for (j = beg; j < end; ++j) { … … 411 351 } 412 352 else { 413 mrb_raisef(mrb, E_TYPE_ERROR, "invalid values selector: % S", argv[i]);353 mrb_raisef(mrb, E_TYPE_ERROR, "invalid values selector: %v", argv[i]); 414 354 } 415 355 } 416 356 417 357 return result; 358 } 359 360 void 361 mrb_gc_mark_range(mrb_state *mrb, struct RRange *r) 362 { 363 if (RANGE_INITIALIZED_P(r)) { 364 mrb_gc_mark_value(mrb, RANGE_BEG(r)); 365 mrb_gc_mark_value(mrb, RANGE_END(r)); 366 } 367 } 368 369 MRB_API struct RRange* 370 mrb_range_ptr(mrb_state *mrb, mrb_value range) 371 { 372 struct RRange *r = mrb_range_raw_ptr(range); 373 374 /* check for if #initialize_copy was removed [#3320] */ 375 if (!RANGE_INITIALIZED_P(r)) { 376 mrb_raise(mrb, E_ARGUMENT_ERROR, "uninitialized range"); 377 } 378 return r; 379 } 380 381 MRB_API mrb_value 382 mrb_range_new(mrb_state *mrb, mrb_value beg, mrb_value end, mrb_bool excl) 383 { 384 struct RRange *r = range_ptr_init(mrb, NULL, beg, end, excl); 385 return mrb_range_value(r); 386 } 387 388 MRB_API enum mrb_range_beg_len 389 mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_bool trunc) 390 { 391 mrb_int beg, end; 392 struct RRange *r; 393 394 if (!mrb_range_p(range)) return MRB_RANGE_TYPE_MISMATCH; 395 r = mrb_range_ptr(mrb, range); 396 397 beg = mrb_int(mrb, RANGE_BEG(r)); 398 end = mrb_int(mrb, RANGE_END(r)); 399 400 if (beg < 0) { 401 beg += len; 402 if (beg < 0) return MRB_RANGE_OUT; 403 } 404 405 if (trunc) { 406 if (beg > len) return MRB_RANGE_OUT; 407 if (end > len) end = len; 408 } 409 410 if (end < 0) end += len; 411 if (!RANGE_EXCL(r) && (!trunc || end < len)) end++; /* include end point */ 412 len = end - beg; 413 if (len < 0) len = 0; 414 415 *begp = beg; 416 *lenp = len; 417 return MRB_RANGE_OK; 418 418 } 419 419 … … 424 424 425 425 r = mrb_define_class(mrb, "Range", mrb->object_class); /* 15.2.14 */ 426 mrb->range_class = r; 426 427 MRB_SET_INSTANCE_TT(r, MRB_TT_RANGE); 427 428 428 mrb_define_method(mrb, r, "begin", mrb_range_beg, MRB_ARGS_NONE()); /* 15.2.14.4.3 */ 429 mrb_define_method(mrb, r, "end", mrb_range_end, MRB_ARGS_NONE()); /* 15.2.14.4.5 */ 430 mrb_define_method(mrb, r, "==", mrb_range_eq, MRB_ARGS_REQ(1)); /* 15.2.14.4.1 */ 431 mrb_define_method(mrb, r, "===", mrb_range_include, MRB_ARGS_REQ(1)); /* 15.2.14.4.2 */ 432 mrb_define_method(mrb, r, "exclude_end?", mrb_range_excl, MRB_ARGS_NONE()); /* 15.2.14.4.6 */ 433 mrb_define_method(mrb, r, "first", mrb_range_beg, MRB_ARGS_NONE()); /* 15.2.14.4.7 */ 434 mrb_define_method(mrb, r, "include?", mrb_range_include, MRB_ARGS_REQ(1)); /* 15.2.14.4.8 */ 435 mrb_define_method(mrb, r, "initialize", mrb_range_initialize, MRB_ARGS_ANY()); /* 15.2.14.4.9 */ 436 mrb_define_method(mrb, r, "last", mrb_range_end, MRB_ARGS_NONE()); /* 15.2.14.4.10 */ 437 mrb_define_method(mrb, r, "member?", mrb_range_include, MRB_ARGS_REQ(1)); /* 15.2.14.4.11 */ 438 429 mrb_define_method(mrb, r, "begin", range_beg, MRB_ARGS_NONE()); /* 15.2.14.4.3 */ 430 mrb_define_method(mrb, r, "end", range_end, MRB_ARGS_NONE()); /* 15.2.14.4.5 */ 431 mrb_define_method(mrb, r, "==", range_eq, MRB_ARGS_REQ(1)); /* 15.2.14.4.1 */ 432 mrb_define_method(mrb, r, "===", range_include, MRB_ARGS_REQ(1)); /* 15.2.14.4.2 */ 433 mrb_define_method(mrb, r, "exclude_end?", range_excl, MRB_ARGS_NONE()); /* 15.2.14.4.6 */ 434 mrb_define_method(mrb, r, "first", range_beg, MRB_ARGS_NONE()); /* 15.2.14.4.7 */ 435 mrb_define_method(mrb, r, "include?", range_include, MRB_ARGS_REQ(1)); /* 15.2.14.4.8 */ 436 mrb_define_method(mrb, r, "initialize", range_initialize, MRB_ARGS_ANY()); /* 15.2.14.4.9 */ 437 mrb_define_method(mrb, r, "last", range_end, MRB_ARGS_NONE()); /* 15.2.14.4.10 */ 438 mrb_define_method(mrb, r, "member?", range_include, MRB_ARGS_REQ(1)); /* 15.2.14.4.11 */ 439 439 mrb_define_method(mrb, r, "to_s", range_to_s, MRB_ARGS_NONE()); /* 15.2.14.4.12(x) */ 440 440 mrb_define_method(mrb, r, "inspect", range_inspect, MRB_ARGS_NONE()); /* 15.2.14.4.13(x) */ -
EcnlProtoTool/trunk/mruby-2.1.1/src/state.c
r331 r439 12 12 #include <mruby/debug.h> 13 13 #include <mruby/string.h> 14 #include <mruby/class.h> 14 15 15 16 void mrb_init_core(mrb_state*); … … 18 19 void mrb_gc_init(mrb_state*, mrb_gc *gc); 19 20 void mrb_gc_destroy(mrb_state*, mrb_gc *gc); 20 21 static mrb_value22 inspect_main(mrb_state *mrb, mrb_value mod)23 {24 return mrb_str_new_lit(mrb, "main");25 }26 21 27 22 MRB_API mrb_state* … … 32 27 mrb_state *mrb; 33 28 29 if (f == NULL) f = mrb_default_allocf; 34 30 mrb = (mrb_state *)(f)(NULL, NULL, sizeof(mrb_state), ud); 35 31 if (mrb == NULL) return NULL; … … 62 58 } 63 59 64 struct alloca_header {65 struct alloca_header *next;66 char buf[];67 };68 69 MRB_API void*70 mrb_alloca(mrb_state *mrb, size_t size)71 {72 struct alloca_header *p;73 74 p = (struct alloca_header*) mrb_malloc(mrb, sizeof(struct alloca_header)+size);75 p->next = mrb->mems;76 mrb->mems = p;77 return (void*)p->buf;78 }79 80 static void81 mrb_alloca_free(mrb_state *mrb)82 {83 struct alloca_header *p;84 struct alloca_header *tmp;85 86 if (mrb == NULL) return;87 p = mrb->mems;88 89 while (p) {90 tmp = p;91 p = p->next;92 mrb_free(mrb, tmp);93 }94 }95 96 60 MRB_API mrb_state* 97 61 mrb_open(void) … … 112 76 113 77 if (!disable_gems) { 78 #ifndef DISABLE_GEMS 114 79 mrb_init_mrbgems(mrb); 115 80 mrb_gc_arena_restore(mrb, 0); 81 #endif 116 82 } 117 83 return mrb; … … 136 102 137 103 void 104 mrb_irep_cutref(mrb_state *mrb, mrb_irep *irep) 105 { 106 mrb_irep *tmp; 107 int i; 108 109 for (i=0; i<irep->rlen; i++) { 110 tmp = irep->reps[i]; 111 irep->reps[i] = NULL; 112 if (tmp) mrb_irep_decref(mrb, tmp); 113 } 114 } 115 116 void 138 117 mrb_irep_free(mrb_state *mrb, mrb_irep *irep) 139 118 { 140 size_t i;119 int i; 141 120 142 121 if (!(irep->flags & MRB_ISEQ_NO_FREE)) 143 mrb_free(mrb, irep->iseq);122 mrb_free(mrb, (void*)irep->iseq); 144 123 if (irep->pool) for (i=0; i<irep->plen; i++) { 145 if (mrb_ type(irep->pool[i]) == MRB_TT_STRING) {124 if (mrb_string_p(irep->pool[i])) { 146 125 mrb_gc_free_str(mrb, RSTRING(irep->pool[i])); 147 126 mrb_free(mrb, mrb_obj_ptr(irep->pool[i])); 148 127 } 149 #if def MRB_WORD_BOXING150 else if (mrb_ type(irep->pool[i]) == MRB_TT_FLOAT) {128 #if defined(MRB_WORD_BOXING) && !defined(MRB_WITHOUT_FLOAT) 129 else if (mrb_float_p(irep->pool[i])) { 151 130 mrb_free(mrb, mrb_obj_ptr(irep->pool[i])); 152 131 } … … 156 135 mrb_free(mrb, irep->syms); 157 136 for (i=0; i<irep->rlen; i++) { 158 mrb_irep_decref(mrb, irep->reps[i]); 137 if (irep->reps[i]) 138 mrb_irep_decref(mrb, irep->reps[i]); 159 139 } 160 140 mrb_free(mrb, irep->reps); 161 141 mrb_free(mrb, irep->lv); 162 if (irep->own_filename) {163 mrb_free(mrb, (void *)irep->filename);164 }165 mrb_free(mrb, irep->lines);166 142 mrb_debug_info_free(mrb, irep->debug_info); 167 143 mrb_free(mrb, irep); 168 }169 170 mrb_value171 mrb_str_pool(mrb_state *mrb, mrb_value str)172 {173 struct RString *s = mrb_str_ptr(str);174 struct RString *ns;175 char *ptr;176 mrb_int len;177 178 ns = (struct RString *)mrb_malloc(mrb, sizeof(struct RString));179 ns->tt = MRB_TT_STRING;180 ns->c = mrb->string_class;181 182 if (RSTR_NOFREE_P(s)) {183 ns->flags = MRB_STR_NOFREE;184 ns->as.heap.ptr = s->as.heap.ptr;185 ns->as.heap.len = s->as.heap.len;186 ns->as.heap.aux.capa = 0;187 }188 else {189 ns->flags = 0;190 if (RSTR_EMBED_P(s)) {191 ptr = s->as.ary;192 len = RSTR_EMBED_LEN(s);193 }194 else {195 ptr = s->as.heap.ptr;196 len = s->as.heap.len;197 }198 199 if (len < RSTRING_EMBED_LEN_MAX) {200 RSTR_SET_EMBED_FLAG(ns);201 RSTR_SET_EMBED_LEN(ns, len);202 if (ptr) {203 memcpy(ns->as.ary, ptr, len);204 }205 ns->as.ary[len] = '\0';206 }207 else {208 ns->as.heap.ptr = (char *)mrb_malloc(mrb, (size_t)len+1);209 ns->as.heap.len = len;210 ns->as.heap.aux.capa = len;211 if (ptr) {212 memcpy(ns->as.heap.ptr, ptr, len);213 }214 ns->as.heap.ptr[len] = '\0';215 }216 }217 return mrb_obj_value(ns);218 144 } 219 145 … … 246 172 247 173 /* free */ 174 mrb_gc_destroy(mrb, &mrb->gc); 175 mrb_free_context(mrb, mrb->root_c); 248 176 mrb_gc_free_gv(mrb); 249 mrb_free_context(mrb, mrb->root_c);250 177 mrb_free_symtbl(mrb); 251 mrb_alloca_free(mrb);252 mrb_gc_destroy(mrb, &mrb->gc);253 178 mrb_free(mrb, mrb); 254 179 } … … 263 188 *irep = mrb_irep_zero; 264 189 irep->refcnt = 1; 265 irep->own_filename = FALSE;266 190 267 191 return irep; … … 271 195 mrb_top_self(mrb_state *mrb) 272 196 { 273 if (!mrb->top_self) {274 mrb->top_self = (struct RObject*)mrb_obj_alloc(mrb, MRB_TT_OBJECT, mrb->object_class);275 mrb_define_singleton_method(mrb, mrb->top_self, "inspect", inspect_main, MRB_ARGS_NONE());276 mrb_define_singleton_method(mrb, mrb->top_self, "to_s", inspect_main, MRB_ARGS_NONE());277 }278 197 return mrb_obj_value(mrb->top_self); 279 198 } -
EcnlProtoTool/trunk/mruby-2.1.1/src/string.c
r331 r439 9 9 #endif 10 10 11 #ifndef MRB_WITHOUT_FLOAT 11 12 #include <float.h> 13 #include <math.h> 14 #endif 12 15 #include <limits.h> 13 16 #include <stddef.h> … … 19 22 #include <mruby/range.h> 20 23 #include <mruby/string.h> 21 #include <mruby/ re.h>24 #include <mruby/numeric.h> 22 25 23 26 typedef struct mrb_shared_string { 24 mrb_bool nofree : 1;25 27 int refcnt; 28 mrb_ssize capa; 26 29 char *ptr; 27 mrb_int len;28 30 } mrb_shared_string; 29 31 … … 31 33 32 34 #define mrb_obj_alloc_string(mrb) ((struct RString*)mrb_obj_alloc((mrb), MRB_TT_STRING, (mrb)->string_class)) 35 36 static struct RString* 37 str_init_normal_capa(mrb_state *mrb, struct RString *s, 38 const char *p, size_t len, size_t capa) 39 { 40 char *dst = (char *)mrb_malloc(mrb, capa + 1); 41 if (p) memcpy(dst, p, len); 42 dst[len] = '\0'; 43 s->as.heap.ptr = dst; 44 s->as.heap.len = (mrb_ssize)len; 45 s->as.heap.aux.capa = (mrb_ssize)capa; 46 RSTR_UNSET_TYPE_FLAG(s); 47 return s; 48 } 49 50 static struct RString* 51 str_init_normal(mrb_state *mrb, struct RString *s, const char *p, size_t len) 52 { 53 return str_init_normal_capa(mrb, s, p, len, len); 54 } 55 56 static struct RString* 57 str_init_embed(struct RString *s, const char *p, size_t len) 58 { 59 if (p) memcpy(RSTR_EMBED_PTR(s), p, len); 60 RSTR_EMBED_PTR(s)[len] = '\0'; 61 RSTR_SET_TYPE_FLAG(s, EMBED); 62 RSTR_SET_EMBED_LEN(s, len); 63 return s; 64 } 65 66 static struct RString* 67 str_init_nofree(struct RString *s, const char *p, size_t len) 68 { 69 s->as.heap.ptr = (char *)p; 70 s->as.heap.len = (mrb_ssize)len; 71 s->as.heap.aux.capa = 0; /* nofree */ 72 RSTR_SET_TYPE_FLAG(s, NOFREE); 73 return s; 74 } 75 76 static struct RString* 77 str_init_shared(mrb_state *mrb, const struct RString *orig, struct RString *s, mrb_shared_string *shared) 78 { 79 if (shared) { 80 shared->refcnt++; 81 } 82 else { 83 shared = (mrb_shared_string *)mrb_malloc(mrb, sizeof(mrb_shared_string)); 84 shared->refcnt = 1; 85 shared->ptr = orig->as.heap.ptr; 86 shared->capa = orig->as.heap.aux.capa; 87 } 88 s->as.heap.ptr = orig->as.heap.ptr; 89 s->as.heap.len = orig->as.heap.len; 90 s->as.heap.aux.shared = shared; 91 RSTR_SET_TYPE_FLAG(s, SHARED); 92 return s; 93 } 94 95 static struct RString* 96 str_init_fshared(const struct RString *orig, struct RString *s, struct RString *fshared) 97 { 98 s->as.heap.ptr = orig->as.heap.ptr; 99 s->as.heap.len = orig->as.heap.len; 100 s->as.heap.aux.fshared = fshared; 101 RSTR_SET_TYPE_FLAG(s, FSHARED); 102 return s; 103 } 104 105 static struct RString* 106 str_init_modifiable(mrb_state *mrb, struct RString *s, const char *p, size_t len) 107 { 108 if (RSTR_EMBEDDABLE_P(len)) { 109 return str_init_embed(s, p, len); 110 } 111 else { 112 return str_init_normal(mrb, s, p, len); 113 } 114 } 33 115 34 116 static struct RString* 35 117 str_new_static(mrb_state *mrb, const char *p, size_t len) 36 118 { 37 struct RString *s; 38 39 if (len >= MRB_INT_MAX) { 119 if (RSTR_EMBEDDABLE_P(len)) { 120 return str_init_embed(mrb_obj_alloc_string(mrb), p, len); 121 } 122 if (len >= MRB_SSIZE_MAX) { 40 123 mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big"); 41 124 } 42 s = mrb_obj_alloc_string(mrb); 43 s->as.heap.len = len; 44 s->as.heap.aux.capa = 0; /* nofree */ 45 s->as.heap.ptr = (char *)p; 46 s->flags = MRB_STR_NOFREE; 47 48 return s; 125 return str_init_nofree(mrb_obj_alloc_string(mrb), p, len); 49 126 } 50 127 … … 52 129 str_new(mrb_state *mrb, const char *p, size_t len) 53 130 { 131 if (RSTR_EMBEDDABLE_P(len)) { 132 return str_init_embed(mrb_obj_alloc_string(mrb), p, len); 133 } 134 if (len >= MRB_SSIZE_MAX) { 135 mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big"); 136 } 137 if (p && mrb_ro_data_p(p)) { 138 return str_init_nofree(mrb_obj_alloc_string(mrb), p, len); 139 } 140 return str_init_normal(mrb, mrb_obj_alloc_string(mrb), p, len); 141 } 142 143 static inline void 144 str_with_class(struct RString *s, mrb_value obj) 145 { 146 s->c = mrb_str_ptr(obj)->c; 147 } 148 149 static mrb_value 150 mrb_str_new_empty(mrb_state *mrb, mrb_value str) 151 { 152 struct RString *s = str_new(mrb, 0, 0); 153 154 str_with_class(s, str); 155 return mrb_obj_value(s); 156 } 157 158 MRB_API mrb_value 159 mrb_str_new_capa(mrb_state *mrb, size_t capa) 160 { 54 161 struct RString *s; 55 162 56 if (p && mrb_ro_data_p(p)) { 57 return str_new_static(mrb, p, len); 58 } 59 s = mrb_obj_alloc_string(mrb); 60 if (len < RSTRING_EMBED_LEN_MAX) { 61 RSTR_SET_EMBED_FLAG(s); 62 RSTR_SET_EMBED_LEN(s, len); 63 if (p) { 64 memcpy(s->as.ary, p, len); 65 } 163 if (RSTR_EMBEDDABLE_P(capa)) { 164 s = str_init_embed(mrb_obj_alloc_string(mrb), NULL, 0); 165 } 166 else if (capa >= MRB_SSIZE_MAX) { 167 mrb_raise(mrb, E_ARGUMENT_ERROR, "string capacity size too big"); 168 /* not reached */ 169 s = NULL; 66 170 } 67 171 else { 68 if (len >= MRB_INT_MAX) { 69 mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big"); 70 } 71 s->as.heap.len = len; 72 s->as.heap.aux.capa = len; 73 s->as.heap.ptr = (char *)mrb_malloc(mrb, len+1); 74 if (p) { 75 memcpy(s->as.heap.ptr, p, len); 76 } 77 } 78 RSTR_PTR(s)[len] = '\0'; 79 return s; 80 } 81 82 static inline void 83 str_with_class(mrb_state *mrb, struct RString *s, mrb_value obj) 84 { 85 s->c = mrb_str_ptr(obj)->c; 86 } 87 88 static mrb_value 89 mrb_str_new_empty(mrb_state *mrb, mrb_value str) 90 { 91 struct RString *s = str_new(mrb, 0, 0); 92 93 str_with_class(mrb, s, str); 172 s = str_init_normal_capa(mrb, mrb_obj_alloc_string(mrb), NULL, 0, capa); 173 } 174 94 175 return mrb_obj_value(s); 95 176 } … … 102 183 mrb_str_buf_new(mrb_state *mrb, size_t capa) 103 184 { 104 struct RString *s;105 106 s = mrb_obj_alloc_string(mrb);107 108 if (capa >= MRB_INT_MAX) {109 mrb_raise(mrb, E_ARGUMENT_ERROR, "string capacity size too big");110 }111 185 if (capa < MRB_STR_BUF_MIN_SIZE) { 112 186 capa = MRB_STR_BUF_MIN_SIZE; 113 187 } 114 s->as.heap.len = 0; 115 s->as.heap.aux.capa = capa; 116 s->as.heap.ptr = (char *)mrb_malloc(mrb, capa+1); 117 RSTR_PTR(s)[0] = '\0'; 118 119 return mrb_obj_value(s); 188 return mrb_str_new_capa(mrb, capa); 120 189 } 121 190 … … 123 192 resize_capa(mrb_state *mrb, struct RString *s, size_t capacity) 124 193 { 125 #if SIZE_MAX > MRB_ INT_MAX126 mrb_assert(capacity < MRB_ INT_MAX);194 #if SIZE_MAX > MRB_SSIZE_MAX 195 mrb_assert(capacity < MRB_SSIZE_MAX); 127 196 #endif 128 197 if (RSTR_EMBED_P(s)) { 129 if (RSTRING_EMBED_LEN_MAX < capacity) { 130 char *const tmp = (char *)mrb_malloc(mrb, capacity+1); 131 const mrb_int len = RSTR_EMBED_LEN(s); 132 memcpy(tmp, s->as.ary, len); 133 RSTR_UNSET_EMBED_FLAG(s); 134 s->as.heap.ptr = tmp; 135 s->as.heap.len = len; 136 s->as.heap.aux.capa = (mrb_int)capacity; 198 if (!RSTR_EMBEDDABLE_P(capacity)) { 199 str_init_normal_capa(mrb, s, RSTR_EMBED_PTR(s), RSTR_EMBED_LEN(s), capacity); 137 200 } 138 201 } 139 202 else { 140 203 s->as.heap.ptr = (char*)mrb_realloc(mrb, RSTR_PTR(s), capacity+1); 141 s->as.heap.aux.capa = (mrb_int)capacity; 142 } 143 } 144 145 static void 146 str_buf_cat(mrb_state *mrb, struct RString *s, const char *ptr, size_t len) 147 { 148 size_t capa; 149 size_t total; 150 ptrdiff_t off = -1; 151 152 if (len == 0) return; 153 mrb_str_modify(mrb, s); 154 if (ptr >= RSTR_PTR(s) && ptr <= RSTR_PTR(s) + (size_t)RSTR_LEN(s)) { 155 off = ptr - RSTR_PTR(s); 156 } 157 158 capa = RSTR_CAPA(s); 159 if (capa <= RSTRING_EMBED_LEN_MAX) 160 capa = RSTRING_EMBED_LEN_MAX+1; 161 162 total = RSTR_LEN(s)+len; 163 if (total >= MRB_INT_MAX) { 164 size_error: 165 mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big"); 166 } 167 if (capa <= total) { 168 while (total > capa) { 169 if (capa <= MRB_INT_MAX / 2) { 170 capa *= 2; 171 } 172 else { 173 capa = total; 174 } 175 } 176 if (capa < total || capa > MRB_INT_MAX) { 177 goto size_error; 178 } 179 resize_capa(mrb, s, capa); 180 } 181 if (off != -1) { 182 ptr = RSTR_PTR(s) + off; 183 } 184 memcpy(RSTR_PTR(s) + RSTR_LEN(s), ptr, len); 185 mrb_assert_int_fit(size_t, total, mrb_int, MRB_INT_MAX); 186 RSTR_SET_LEN(s, total); 187 RSTR_PTR(s)[total] = '\0'; /* sentinel */ 204 s->as.heap.aux.capa = (mrb_ssize)capacity; 205 } 188 206 } 189 207 … … 194 212 } 195 213 196 /*197 * call-seq: (Caution! NULL string)198 * String.new(str="") => new_str199 *200 * Returns a new string object containing a copy of <i>str</i>.201 */202 203 214 MRB_API mrb_value 204 215 mrb_str_new_cstr(mrb_state *mrb, const char *p) … … 231 242 shared->refcnt--; 232 243 if (shared->refcnt == 0) { 233 if (!shared->nofree) { 234 mrb_free(mrb, shared->ptr); 235 } 244 mrb_free(mrb, shared->ptr); 236 245 mrb_free(mrb, shared); 246 } 247 } 248 249 static void 250 str_modify_keep_ascii(mrb_state *mrb, struct RString *s) 251 { 252 if (RSTR_SHARED_P(s)) { 253 mrb_shared_string *shared = s->as.heap.aux.shared; 254 255 if (shared->refcnt == 1 && s->as.heap.ptr == shared->ptr) { 256 s->as.heap.aux.capa = shared->capa; 257 s->as.heap.ptr[s->as.heap.len] = '\0'; 258 RSTR_UNSET_SHARED_FLAG(s); 259 mrb_free(mrb, shared); 260 } 261 else { 262 str_init_modifiable(mrb, s, s->as.heap.ptr, (size_t)s->as.heap.len); 263 str_decref(mrb, shared); 264 } 265 } 266 else if (RSTR_NOFREE_P(s) || RSTR_FSHARED_P(s)) { 267 str_init_modifiable(mrb, s, s->as.heap.ptr, (size_t)s->as.heap.len); 268 } 269 } 270 271 static void 272 check_null_byte(mrb_state *mrb, mrb_value str) 273 { 274 mrb_to_str(mrb, str); 275 if (memchr(RSTRING_PTR(str), '\0', RSTRING_LEN(str))) { 276 mrb_raise(mrb, E_ARGUMENT_ERROR, "string contains null byte"); 237 277 } 238 278 } … … 245 285 else if (RSTR_SHARED_P(str)) 246 286 str_decref(mrb, str->as.heap.aux.shared); 247 else if (!RSTR_NOFREE_P(str) )287 else if (!RSTR_NOFREE_P(str) && !RSTR_FSHARED_P(str)) 248 288 mrb_free(mrb, str->as.heap.ptr); 249 289 } … … 262 302 }; 263 303 264 staticmrb_int265 utf8len(const char* p, const char* e)304 mrb_int 305 mrb_utf8len(const char* p, const char* e) 266 306 { 267 307 mrb_int len; 268 308 mrb_int i; 269 309 310 if ((unsigned char)*p < 0x80) return 1; 270 311 len = utf8len_codepage[(unsigned char)*p]; 271 if (p + len > e) return 1; 312 if (len == 1) return 1; 313 if (len > e - p) return 1; 272 314 for (i = 1; i < len; ++i) 273 315 if ((p[i] & 0xc0) != 0x80) … … 276 318 } 277 319 320 mrb_int 321 mrb_utf8_strlen(const char *str, mrb_int byte_len) 322 { 323 mrb_int total = 0; 324 const char *p = str; 325 const char *e = p + byte_len; 326 327 while (p < e) { 328 p += mrb_utf8len(p, e); 329 total++; 330 } 331 return total; 332 } 333 278 334 static mrb_int 279 utf8_strlen(mrb_value str, mrb_int len) 280 { 281 mrb_int total = 0; 282 char* p = RSTRING_PTR(str); 283 char* e = p; 284 if (RSTRING(str)->flags & MRB_STR_NO_UTF) { 285 return RSTRING_LEN(str); 286 } 287 e += len < 0 ? RSTRING_LEN(str) : len; 288 while (p<e) { 289 p += utf8len(p, e); 290 total++; 291 } 292 if (RSTRING_LEN(str) == total) { 293 RSTRING(str)->flags |= MRB_STR_NO_UTF; 294 } 295 return total; 296 } 297 298 #define RSTRING_CHAR_LEN(s) utf8_strlen(s, -1) 335 utf8_strlen(mrb_value str) 336 { 337 struct RString *s = mrb_str_ptr(str); 338 mrb_int byte_len = RSTR_LEN(s); 339 340 if (RSTR_ASCII_P(s)) { 341 return byte_len; 342 } 343 else { 344 mrb_int utf8_len = mrb_utf8_strlen(RSTR_PTR(s), byte_len); 345 if (byte_len == utf8_len) RSTR_SET_ASCII_FLAG(s); 346 return utf8_len; 347 } 348 } 349 350 #define RSTRING_CHAR_LEN(s) utf8_strlen(s) 299 351 300 352 /* map character index to byte offset index */ … … 302 354 chars2bytes(mrb_value s, mrb_int off, mrb_int idx) 303 355 { 304 mrb_int i, b, n; 305 const char *p = RSTRING_PTR(s) + off; 306 const char *e = RSTRING_END(s); 307 308 for (b=i=0; p<e && i<idx; i++) { 309 n = utf8len(p, e); 310 b += n; 311 p += n; 312 } 313 return b; 356 if (RSTR_ASCII_P(mrb_str_ptr(s))) { 357 return idx; 358 } 359 else { 360 mrb_int i, b, n; 361 const char *p = RSTRING_PTR(s) + off; 362 const char *e = RSTRING_END(s); 363 364 for (b=i=0; p<e && i<idx; i++) { 365 n = mrb_utf8len(p, e); 366 b += n; 367 p += n; 368 } 369 return b; 370 } 314 371 } 315 372 316 373 /* map byte offset to character index */ 317 374 static mrb_int 318 bytes2chars(char *p, mrb_int bi)319 { 320 mrb_int i, b,n;321 322 for (b=i=0; b<bi; i++) {323 n = utf8len_codepage[(unsigned char)*p]; 324 b += n;325 p += n;326 } 327 if ( b != bi) return -1;375 bytes2chars(char *p, mrb_int len, mrb_int bi) 376 { 377 const char *e = p + (size_t)len; 378 const char *pivot = p + bi; 379 mrb_int i; 380 381 for (i = 0; p < pivot; i ++) { 382 p += mrb_utf8len(p, e); 383 } 384 if (p != pivot) return -1; 328 385 return i; 386 } 387 388 static const char * 389 char_adjust(const char *beg, const char *end, const char *ptr) 390 { 391 if ((ptr > beg || ptr < end) && (*ptr & 0xc0) == 0x80) { 392 const int utf8_adjust_max = 3; 393 const char *p; 394 395 if (ptr - beg > utf8_adjust_max) { 396 beg = ptr - utf8_adjust_max; 397 } 398 399 p = ptr; 400 while (p > beg) { 401 p --; 402 if ((*p & 0xc0) != 0x80) { 403 int clen = mrb_utf8len(p, end); 404 if (clen > ptr - p) return p; 405 break; 406 } 407 } 408 } 409 410 return ptr; 411 } 412 413 static const char * 414 char_backtrack(const char *ptr, const char *end) 415 { 416 if (ptr < end) { 417 const int utf8_bytelen_max = 4; 418 const char *p; 419 420 if (end - ptr > utf8_bytelen_max) { 421 ptr = end - utf8_bytelen_max; 422 } 423 424 p = end; 425 while (p > ptr) { 426 p --; 427 if ((*p & 0xc0) != 0x80) { 428 int clen = utf8len_codepage[(unsigned char)*p]; 429 if (clen == end - p) { return p; } 430 break; 431 } 432 } 433 } 434 435 return end - 1; 436 } 437 438 static mrb_int 439 str_index_str_by_char_search(mrb_state *mrb, const char *p, const char *pend, const char *s, const mrb_int slen, mrb_int off) 440 { 441 /* Based on Quick Search algorithm (Boyer-Moore-Horspool algorithm) */ 442 443 ptrdiff_t qstable[1 << CHAR_BIT]; 444 445 /* Preprocessing */ 446 { 447 mrb_int i; 448 449 for (i = 0; i < 1 << CHAR_BIT; i ++) { 450 qstable[i] = slen; 451 } 452 for (i = 0; i < slen; i ++) { 453 qstable[(unsigned char)s[i]] = slen - (i + 1); 454 } 455 } 456 457 /* Searching */ 458 while (p < pend && pend - p >= slen) { 459 const char *pivot; 460 461 if (memcmp(p, s, slen) == 0) { 462 return off; 463 } 464 465 pivot = p + qstable[(unsigned char)p[slen - 1]]; 466 if (pivot >= pend || pivot < p /* overflowed */) { return -1; } 467 468 do { 469 p += mrb_utf8len(p, pend); 470 off ++; 471 } while (p < pivot); 472 } 473 474 return -1; 475 } 476 477 static mrb_int 478 str_index_str_by_char(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int pos) 479 { 480 const char *p = RSTRING_PTR(str); 481 const char *pend = p + RSTRING_LEN(str); 482 const char *s = RSTRING_PTR(sub); 483 const mrb_int slen = RSTRING_LEN(sub); 484 mrb_int off = pos; 485 486 for (; pos > 0; pos --) { 487 if (pend - p < 1) { return -1; } 488 p += mrb_utf8len(p, pend); 489 } 490 491 if (slen < 1) { return off; } 492 493 return str_index_str_by_char_search(mrb, p, pend, s, slen, off); 329 494 } 330 495 … … 333 498 #define RSTRING_CHAR_LEN(s) RSTRING_LEN(s) 334 499 #define chars2bytes(p, off, ci) (ci) 335 #define bytes2chars(p, bi) (bi) 500 #define bytes2chars(p, end, bi) (bi) 501 #define char_adjust(beg, end, ptr) (ptr) 502 #define char_backtrack(ptr, end) ((end) - 1) 336 503 #define BYTES_ALIGN_CHECK(pos) 504 #define str_index_str_by_char(mrb, str, sub, pos) str_index_str(mrb, str, sub, pos) 505 #endif 506 507 #ifndef MRB_QS_SHORT_STRING_LENGTH 508 #define MRB_QS_SHORT_STRING_LENGTH 2048 337 509 #endif 338 510 … … 340 512 mrb_memsearch_qs(const unsigned char *xs, mrb_int m, const unsigned char *ys, mrb_int n) 341 513 { 342 const unsigned char *x = xs, *xe = xs + m; 343 const unsigned char *y = ys; 344 int i, qstable[256]; 345 346 /* Preprocessing */ 347 for (i = 0; i < 256; ++i) 348 qstable[i] = m + 1; 349 for (; x < xe; ++x) 350 qstable[*x] = xe - x; 351 /* Searching */ 352 for (; y + m <= ys + n; y += *(qstable + y[m])) { 353 if (*xs == *y && memcmp(xs, y, m) == 0) 354 return y - ys; 355 } 356 return -1; 514 if (n + m < MRB_QS_SHORT_STRING_LENGTH) { 515 const unsigned char *y = ys; 516 const unsigned char *ye = ys+n-m+1; 517 518 for (;;) { 519 y = (const unsigned char*)memchr(y, xs[0], (size_t)(ye-y)); 520 if (y == NULL) return -1; 521 if (memcmp(xs, y, m) == 0) { 522 return (mrb_int)(y - ys); 523 } 524 y++; 525 } 526 return -1; 527 } 528 else { 529 const unsigned char *x = xs, *xe = xs + m; 530 const unsigned char *y = ys; 531 int i; 532 ptrdiff_t qstable[256]; 533 534 /* Preprocessing */ 535 for (i = 0; i < 256; ++i) 536 qstable[i] = m + 1; 537 for (; x < xe; ++x) 538 qstable[*x] = xe - x; 539 /* Searching */ 540 for (; y + m <= ys + n; y += *(qstable + y[m])) { 541 if (*xs == *y && memcmp(xs, y, m) == 0) 542 return (mrb_int)(y - ys); 543 } 544 return -1; 545 } 357 546 } 358 547 … … 373 562 374 563 if (ys) 375 return ys - y;564 return (mrb_int)(ys - y); 376 565 else 377 566 return -1; … … 381 570 382 571 static void 383 str_make_shared(mrb_state *mrb, struct RString *s) 384 { 385 if (!RSTR_SHARED_P(s)) { 386 mrb_shared_string *shared = (mrb_shared_string *)mrb_malloc(mrb, sizeof(mrb_shared_string)); 387 388 shared->refcnt = 1; 389 if (RSTR_EMBED_P(s)) { 390 const mrb_int len = RSTR_EMBED_LEN(s); 391 char *const tmp = (char *)mrb_malloc(mrb, len+1); 392 memcpy(tmp, s->as.ary, len); 393 tmp[len] = '\0'; 394 RSTR_UNSET_EMBED_FLAG(s); 395 s->as.heap.ptr = tmp; 396 s->as.heap.len = len; 397 shared->nofree = FALSE; 398 shared->ptr = s->as.heap.ptr; 399 } 400 else if (RSTR_NOFREE_P(s)) { 401 shared->nofree = TRUE; 402 shared->ptr = s->as.heap.ptr; 403 RSTR_UNSET_NOFREE_FLAG(s); 404 } 405 else { 406 shared->nofree = FALSE; 407 if (s->as.heap.aux.capa > s->as.heap.len) { 408 s->as.heap.ptr = shared->ptr = (char *)mrb_realloc(mrb, s->as.heap.ptr, s->as.heap.len+1); 409 } 410 else { 411 shared->ptr = s->as.heap.ptr; 412 } 413 } 414 shared->len = s->as.heap.len; 415 s->as.heap.aux.shared = shared; 416 RSTR_SET_SHARED_FLAG(s); 417 } 418 } 419 420 static mrb_value 421 byte_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len) 572 str_share(mrb_state *mrb, struct RString *orig, struct RString *s) 573 { 574 size_t len = (size_t)orig->as.heap.len; 575 576 mrb_assert(!RSTR_EMBED_P(orig)); 577 if (RSTR_NOFREE_P(orig)) { 578 str_init_nofree(s, orig->as.heap.ptr, len); 579 } 580 else if (RSTR_SHARED_P(orig)) { 581 str_init_shared(mrb, orig, s, orig->as.heap.aux.shared); 582 } 583 else if (RSTR_FSHARED_P(orig)) { 584 str_init_fshared(orig, s, orig->as.heap.aux.fshared); 585 } 586 else if (mrb_frozen_p(orig) && !RSTR_POOL_P(orig)) { 587 str_init_fshared(orig, s, orig); 588 } 589 else { 590 if (orig->as.heap.aux.capa > orig->as.heap.len) { 591 orig->as.heap.ptr = (char *)mrb_realloc(mrb, orig->as.heap.ptr, len+1); 592 orig->as.heap.aux.capa = (mrb_ssize)len; 593 } 594 str_init_shared(mrb, orig, s, NULL); 595 str_init_shared(mrb, orig, orig, s->as.heap.aux.shared); 596 } 597 } 598 599 mrb_value 600 mrb_str_pool(mrb_state *mrb, const char *p, mrb_int len, mrb_bool nofree) 601 { 602 struct RString *s = (struct RString *)mrb_malloc(mrb, sizeof(struct RString)); 603 604 s->tt = MRB_TT_STRING; 605 s->c = mrb->string_class; 606 s->flags = 0; 607 608 if (RSTR_EMBEDDABLE_P(len)) { 609 str_init_embed(s, p, len); 610 } 611 else if (nofree) { 612 str_init_nofree(s, p, len); 613 } 614 else { 615 str_init_normal(mrb, s, p, len); 616 } 617 RSTR_SET_POOL_FLAG(s); 618 MRB_SET_FROZEN_FLAG(s); 619 return mrb_obj_value(s); 620 } 621 622 mrb_value 623 mrb_str_byte_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len) 422 624 { 423 625 struct RString *orig, *s; 424 mrb_shared_string *shared;425 626 426 627 orig = mrb_str_ptr(str); 427 if (RSTR_EMBED_P(orig) || RSTR_LEN(orig) == 0) { 428 s = str_new(mrb, orig->as.ary+beg, len); 628 s = mrb_obj_alloc_string(mrb); 629 if (RSTR_EMBEDDABLE_P(len)) { 630 str_init_embed(s, RSTR_PTR(orig)+beg, len); 429 631 } 430 632 else { 431 str_make_shared(mrb, orig); 432 shared = orig->as.heap.aux.shared; 433 s = mrb_obj_alloc_string(mrb); 434 s->as.heap.ptr = orig->as.heap.ptr + beg; 435 s->as.heap.len = len; 436 s->as.heap.aux.shared = shared; 437 RSTR_SET_SHARED_FLAG(s); 438 shared->refcnt++; 439 } 440 633 str_share(mrb, orig, s); 634 s->as.heap.ptr += (mrb_ssize)beg; 635 s->as.heap.len = (mrb_ssize)len; 636 } 637 RSTR_COPY_ASCII_FLAG(s, orig); 441 638 return mrb_obj_value(s); 639 } 640 641 static void 642 str_range_to_bytes(mrb_value str, mrb_int *pos, mrb_int *len) 643 { 644 *pos = chars2bytes(str, 0, *pos); 645 *len = chars2bytes(str, *pos, *len); 442 646 } 443 647 #ifdef MRB_UTF8_STRING … … 445 649 str_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len) 446 650 { 447 beg = chars2bytes(str, 0, beg); 448 len = chars2bytes(str, beg, len); 449 450 return byte_subseq(mrb, str, beg, len); 651 str_range_to_bytes(str, &beg, &len); 652 return mrb_str_byte_subseq(mrb, str, beg, len); 451 653 } 452 654 #else 453 #define str_subseq(mrb, str, beg, len) byte_subseq(mrb, str, beg, len)655 #define str_subseq(mrb, str, beg, len) mrb_str_byte_subseq(mrb, str, beg, len) 454 656 #endif 455 657 658 mrb_bool 659 mrb_str_beg_len(mrb_int str_len, mrb_int *begp, mrb_int *lenp) 660 { 661 if (str_len < *begp || *lenp < 0) return FALSE; 662 if (*begp < 0) { 663 *begp += str_len; 664 if (*begp < 0) return FALSE; 665 } 666 if (*lenp > str_len - *begp) 667 *lenp = str_len - *begp; 668 if (*lenp <= 0) { 669 *lenp = 0; 670 } 671 return TRUE; 672 } 673 456 674 static mrb_value 457 675 str_substr(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len) 458 676 { 459 mrb_int clen = RSTRING_CHAR_LEN(str); 460 461 if (len < 0) return mrb_nil_value(); 462 if (clen == 0) { 463 len = 0; 464 } 465 else if (beg < 0) { 466 beg = clen + beg; 467 } 468 if (beg > clen) return mrb_nil_value(); 469 if (beg < 0) { 470 beg += clen; 471 if (beg < 0) return mrb_nil_value(); 472 } 473 if (len > clen - beg) 474 len = clen - beg; 475 if (len <= 0) { 476 len = 0; 477 } 478 return str_subseq(mrb, str, beg, len); 479 } 480 481 static mrb_int 482 str_index(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int offset) 677 return mrb_str_beg_len(RSTRING_CHAR_LEN(str), &beg, &len) ? 678 str_subseq(mrb, str, beg, len) : mrb_nil_value(); 679 } 680 681 MRB_API mrb_int 682 mrb_str_index(mrb_state *mrb, mrb_value str, const char *sptr, mrb_int slen, mrb_int offset) 483 683 { 484 684 mrb_int pos; 485 char *s , *sptr;486 mrb_int len , slen;685 char *s; 686 mrb_int len; 487 687 488 688 len = RSTRING_LEN(str); 489 slen = RSTRING_LEN(sub);490 689 if (offset < 0) { 491 690 offset += len; … … 499 698 if (slen == 0) return offset; 500 699 /* need proceed one character at a time */ 501 sptr = RSTRING_PTR(sub);502 slen = RSTRING_LEN(sub);503 700 len = RSTRING_LEN(str) - offset; 504 701 pos = mrb_memsearch(sptr, slen, s, len); … … 507 704 } 508 705 509 static void 510 check_frozen(mrb_state *mrb, struct RString *s) 511 { 512 if (MRB_FROZEN_P(s)) { 513 mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen string"); 514 } 706 static mrb_int 707 str_index_str(mrb_state *mrb, mrb_value str, mrb_value str2, mrb_int offset) 708 { 709 const char *ptr; 710 mrb_int len; 711 712 ptr = RSTRING_PTR(str2); 713 len = RSTRING_LEN(str2); 714 715 return mrb_str_index(mrb, str, ptr, len, offset); 515 716 } 516 717 … … 518 719 str_replace(mrb_state *mrb, struct RString *s1, struct RString *s2) 519 720 { 520 longlen;521 522 check_frozen(mrb, s1);721 size_t len; 722 723 mrb_check_frozen(mrb, s1); 523 724 if (s1 == s2) return mrb_obj_value(s1); 524 s1->flags &= ~MRB_STR_NO_UTF; 525 s1->flags |= s2->flags&MRB_STR_NO_UTF; 526 len = RSTR_LEN(s2); 725 RSTR_COPY_ASCII_FLAG(s1, s2); 527 726 if (RSTR_SHARED_P(s1)) { 528 727 str_decref(mrb, s1->as.heap.aux.shared); 529 728 } 530 else if (!RSTR_EMBED_P(s1) && !RSTR_NOFREE_P(s1)) { 729 else if (!RSTR_EMBED_P(s1) && !RSTR_NOFREE_P(s1) && !RSTR_FSHARED_P(s1) 730 && s1->as.heap.ptr) { 531 731 mrb_free(mrb, s1->as.heap.ptr); 532 732 } 533 733 534 RSTR_UNSET_NOFREE_FLAG(s1); 535 536 if (RSTR_SHARED_P(s2)) { 537 L_SHARE: 538 RSTR_UNSET_EMBED_FLAG(s1); 539 s1->as.heap.ptr = s2->as.heap.ptr; 540 s1->as.heap.len = len; 541 s1->as.heap.aux.shared = s2->as.heap.aux.shared; 542 RSTR_SET_SHARED_FLAG(s1); 543 s1->as.heap.aux.shared->refcnt++; 734 len = (size_t)RSTR_LEN(s2); 735 if (RSTR_EMBEDDABLE_P(len)) { 736 str_init_embed(s1, RSTR_PTR(s2), len); 544 737 } 545 738 else { 546 if (len <= RSTRING_EMBED_LEN_MAX) { 547 RSTR_UNSET_SHARED_FLAG(s1); 548 RSTR_SET_EMBED_FLAG(s1); 549 memcpy(s1->as.ary, RSTR_PTR(s2), len); 550 RSTR_SET_EMBED_LEN(s1, len); 551 } 552 else { 553 str_make_shared(mrb, s2); 554 goto L_SHARE; 555 } 739 str_share(mrb, s2, s1); 556 740 } 557 741 … … 562 746 str_rindex(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int pos) 563 747 { 564 c har *s, *sbeg, *t;748 const char *s, *sbeg, *t; 565 749 struct RString *ps = mrb_str_ptr(str); 566 750 mrb_int len = RSTRING_LEN(sub); … … 575 759 t = RSTRING_PTR(sub); 576 760 if (len) { 761 s = char_adjust(sbeg, sbeg + RSTR_LEN(ps), s); 577 762 while (sbeg <= s) { 578 763 if (memcmp(s, t, len) == 0) { 579 return s - RSTR_PTR(ps);580 } 581 s --;764 return (mrb_int)(s - RSTR_PTR(ps)); 765 } 766 s = char_backtrack(sbeg, s); 582 767 } 583 768 return -1; … … 607 792 608 793 char* 609 mrb_utf8_from_locale(const char *str, size_t len)794 mrb_utf8_from_locale(const char *str, int len) 610 795 { 611 796 wchar_t* wcsp; 612 797 char* mbsp; 613 size_t mbssize, wcssize;798 int mbssize, wcssize; 614 799 615 800 if (len == 0) 616 801 return strdup(""); 617 802 if (len == -1) 618 len = strlen(str);803 len = (int)strlen(str); 619 804 wcssize = MultiByteToWideChar(GetACP(), 0, str, len, NULL, 0); 620 805 wcsp = (wchar_t*) malloc((wcssize + 1) * sizeof(wchar_t)); … … 637 822 638 823 char* 639 mrb_locale_from_utf8(const char *utf8, size_t len)824 mrb_locale_from_utf8(const char *utf8, int len) 640 825 { 641 826 wchar_t* wcsp; 642 827 char* mbsp; 643 size_t mbssize, wcssize;828 int mbssize, wcssize; 644 829 645 830 if (len == 0) 646 831 return strdup(""); 647 832 if (len == -1) 648 len = strlen(utf8);833 len = (int)strlen(utf8); 649 834 wcssize = MultiByteToWideChar(CP_UTF8, 0, utf8, len, NULL, 0); 650 835 wcsp = (wchar_t*) malloc((wcssize + 1) * sizeof(wchar_t)); … … 667 852 668 853 MRB_API void 854 mrb_str_modify_keep_ascii(mrb_state *mrb, struct RString *s) 855 { 856 mrb_check_frozen(mrb, s); 857 str_modify_keep_ascii(mrb, s); 858 } 859 860 MRB_API void 669 861 mrb_str_modify(mrb_state *mrb, struct RString *s) 670 862 { 671 check_frozen(mrb, s); 672 s->flags &= ~MRB_STR_NO_UTF; 673 if (RSTR_SHARED_P(s)) { 674 mrb_shared_string *shared = s->as.heap.aux.shared; 675 676 if (shared->nofree == 0 && shared->refcnt == 1 && s->as.heap.ptr == shared->ptr) { 677 s->as.heap.ptr = shared->ptr; 678 s->as.heap.aux.capa = shared->len; 679 RSTR_PTR(s)[s->as.heap.len] = '\0'; 680 mrb_free(mrb, shared); 681 } 682 else { 683 char *ptr, *p; 684 mrb_int len; 685 686 p = RSTR_PTR(s); 687 len = s->as.heap.len; 688 if (len < RSTRING_EMBED_LEN_MAX) { 689 RSTR_SET_EMBED_FLAG(s); 690 RSTR_SET_EMBED_LEN(s, len); 691 ptr = RSTR_PTR(s); 692 } 693 else { 694 ptr = (char *)mrb_malloc(mrb, (size_t)len + 1); 695 s->as.heap.ptr = ptr; 696 s->as.heap.aux.capa = len; 697 } 698 if (p) { 699 memcpy(ptr, p, len); 700 } 701 ptr[len] = '\0'; 702 str_decref(mrb, shared); 703 } 704 RSTR_UNSET_SHARED_FLAG(s); 705 return; 706 } 707 if (RSTR_NOFREE_P(s)) { 708 char *p = s->as.heap.ptr; 709 mrb_int len = s->as.heap.len; 710 711 RSTR_UNSET_NOFREE_FLAG(s); 712 if (len < RSTRING_EMBED_LEN_MAX) { 713 RSTR_SET_EMBED_FLAG(s); 714 RSTR_SET_EMBED_LEN(s, len); 715 } 716 else { 717 s->as.heap.ptr = (char *)mrb_malloc(mrb, (size_t)len+1); 718 s->as.heap.aux.capa = len; 719 } 720 if (p) { 721 memcpy(RSTR_PTR(s), p, len); 722 } 723 RSTR_PTR(s)[len] = '\0'; 724 return; 725 } 863 mrb_str_modify_keep_ascii(mrb, s); 864 RSTR_UNSET_ASCII_FLAG(s); 726 865 } 727 866 … … 732 871 struct RString *s = mrb_str_ptr(str); 733 872 873 if (len < 0) { 874 mrb_raise(mrb, E_ARGUMENT_ERROR, "negative (or overflowed) string size"); 875 } 734 876 mrb_str_modify(mrb, s); 735 877 slen = RSTR_LEN(s); … … 749 891 struct RString *s; 750 892 751 if (!mrb_string_p(str0)) { 752 mrb_raise(mrb, E_TYPE_ERROR, "expected String"); 753 } 754 893 check_null_byte(mrb, str0); 755 894 s = str_new(mrb, RSTRING_PTR(str0), RSTRING_LEN(str0)); 756 if ((strlen(RSTR_PTR(s)) ^ RSTR_LEN(s)) != 0) {757 mrb_raise(mrb, E_ARGUMENT_ERROR, "string contains null byte");758 }759 895 return RSTR_PTR(s); 760 896 } 761 897 762 /*763 * call-seq: (Caution! String("abcd") change)764 * String("abcdefg") = String("abcd") + String("efg")765 *766 * Returns a new string object containing a copy of <i>str</i>.767 */768 898 MRB_API void 769 899 mrb_str_concat(mrb_state *mrb, mrb_value self, mrb_value other) 770 900 { 771 struct RString *s1 = mrb_str_ptr(self), *s2; 772 mrb_int len; 773 774 mrb_str_modify(mrb, s1); 775 if (!mrb_string_p(other)) { 776 other = mrb_str_to_str(mrb, other); 777 } 778 s2 = mrb_str_ptr(other); 779 if (RSTR_LEN(s2) == 0) { 780 return; 781 } 782 len = RSTR_LEN(s1) + RSTR_LEN(s2); 783 784 if (len < 0 || len >= MRB_INT_MAX) { 785 mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big"); 786 } 787 if (RSTRING_CAPA(self) < len) { 788 resize_capa(mrb, s1, len); 789 } 790 memcpy(RSTR_PTR(s1)+RSTR_LEN(s1), RSTR_PTR(s2), RSTR_LEN(s2)); 791 RSTR_SET_LEN(s1, len); 792 RSTR_PTR(s1)[len] = '\0'; 793 } 794 795 /* 796 * call-seq: (Caution! String("abcd") remain) 797 * String("abcdefg") = String("abcd") + String("efg") 798 * 799 * Returns a new string object containing a copy of <i>str</i>. 800 */ 901 other = mrb_str_to_str(mrb, other); 902 mrb_str_cat_str(mrb, self, other); 903 } 904 801 905 MRB_API mrb_value 802 906 mrb_str_plus(mrb_state *mrb, mrb_value a, mrb_value b) … … 816 920 817 921 /* 818 * call-seq: (Caution! String("abcd") remain) for stack_argument 819 * String("abcdefg") = String("abcd") + String("efg") 820 * 821 * Returns a new string object containing a copy of <i>str</i>. 922 * call-seq: 923 * str + other_str -> new_str 924 * 925 * Concatenation---Returns a new <code>String</code> containing 926 * <i>other_str</i> concatenated to <i>str</i>. 927 * 928 * "Hello from " + self.to_s #=> "Hello from main" 822 929 */ 823 930 static mrb_value … … 873 980 mrb_raise(mrb, E_ARGUMENT_ERROR, "negative argument"); 874 981 } 875 if (times && MRB_ INT_MAX / times < RSTRING_LEN(self)) {982 if (times && MRB_SSIZE_MAX / times < RSTRING_LEN(self)) { 876 983 mrb_raise(mrb, E_ARGUMENT_ERROR, "argument too big"); 877 984 } … … 879 986 len = RSTRING_LEN(self)*times; 880 987 str2 = str_new(mrb, 0, len); 881 str_with_class( mrb,str2, self);988 str_with_class(str2, self); 882 989 p = RSTR_PTR(str2); 883 990 if (len > 0) { … … 891 998 } 892 999 p[RSTR_LEN(str2)] = '\0'; 1000 RSTR_COPY_ASCII_FLAG(str2, mrb_str_ptr(self)); 893 1001 894 1002 return mrb_obj_value(str2); … … 959 1067 mrb_get_args(mrb, "o", &str2); 960 1068 if (!mrb_string_p(str2)) { 961 if (!mrb_respond_to(mrb, str2, mrb_intern_lit(mrb, "to_s"))) { 962 return mrb_nil_value(); 963 } 964 else if (!mrb_respond_to(mrb, str2, mrb_intern_lit(mrb, "<=>"))) { 965 return mrb_nil_value(); 966 } 967 else { 968 mrb_value tmp = mrb_funcall(mrb, str2, "<=>", 1, str1); 969 970 if (!mrb_nil_p(tmp)) return mrb_nil_value(); 971 if (!mrb_fixnum_p(tmp)) { 972 return mrb_funcall(mrb, mrb_fixnum_value(0), "-", 1, tmp); 973 } 974 result = -mrb_fixnum(tmp); 975 } 1069 return mrb_nil_value(); 976 1070 } 977 1071 else { … … 995 1089 mrb_str_equal(mrb_state *mrb, mrb_value str1, mrb_value str2) 996 1090 { 997 if (mrb_immediate_p(str2)) return FALSE; 998 if (!mrb_string_p(str2)) { 999 if (mrb_nil_p(str2)) return FALSE; 1000 if (!mrb_respond_to(mrb, str2, mrb_intern_lit(mrb, "to_str"))) { 1001 return FALSE; 1002 } 1003 str2 = mrb_funcall(mrb, str2, "to_str", 0); 1004 return mrb_equal(mrb, str2, str1); 1005 } 1091 if (!mrb_string_p(str2)) return FALSE; 1006 1092 return str_eql(mrb, str1, str2); 1007 1093 } … … 1028 1114 } 1029 1115 /* ---------------------------------- */ 1116 1030 1117 MRB_API mrb_value 1031 1118 mrb_str_to_str(mrb_state *mrb, mrb_value str) 1032 1119 { 1033 mrb_value s; 1034 1035 if (!mrb_string_p(str)) { 1036 s = mrb_check_convert_type(mrb, str, MRB_TT_STRING, "String", "to_str"); 1037 if (mrb_nil_p(s)) { 1038 s = mrb_convert_type(mrb, str, MRB_TT_STRING, "String", "to_s"); 1039 } 1040 return s; 1041 } 1042 return str; 1043 } 1044 1120 switch (mrb_type(str)) { 1121 case MRB_TT_STRING: 1122 return str; 1123 case MRB_TT_SYMBOL: 1124 return mrb_sym_str(mrb, mrb_symbol(str)); 1125 case MRB_TT_FIXNUM: 1126 return mrb_fixnum_to_str(mrb, str, 10); 1127 case MRB_TT_CLASS: 1128 case MRB_TT_MODULE: 1129 return mrb_mod_to_s(mrb, str); 1130 default: 1131 return mrb_convert_type(mrb, str, MRB_TT_STRING, "String", "to_s"); 1132 } 1133 } 1134 1135 /* obslete: use RSTRING_PTR() */ 1045 1136 MRB_API const char* 1046 mrb_string_value_ptr(mrb_state *mrb, mrb_value ptr)1047 { 1048 mrb_value str = mrb_str_to_str(mrb, ptr);1137 mrb_string_value_ptr(mrb_state *mrb, mrb_value str) 1138 { 1139 str = mrb_str_to_str(mrb, str); 1049 1140 return RSTRING_PTR(str); 1050 1141 } 1051 1142 1143 /* obslete: use RSTRING_LEN() */ 1052 1144 MRB_API mrb_int 1053 1145 mrb_string_value_len(mrb_state *mrb, mrb_value ptr) 1054 1146 { 1055 mrb_value str = mrb_str_to_str(mrb, ptr); 1056 return RSTRING_LEN(str); 1057 } 1058 1059 void 1060 mrb_noregexp(mrb_state *mrb, mrb_value self) 1061 { 1062 mrb_raise(mrb, E_NOTIMP_ERROR, "Regexp class not implemented"); 1063 } 1064 1065 void 1066 mrb_regexp_check(mrb_state *mrb, mrb_value obj) 1067 { 1068 if (mrb_regexp_p(mrb, obj)) { 1069 mrb_noregexp(mrb, obj); 1070 } 1147 mrb_to_str(mrb, ptr); 1148 return RSTRING_LEN(ptr); 1071 1149 } 1072 1150 … … 1077 1155 struct RString *dup = str_new(mrb, 0, 0); 1078 1156 1079 str_with_class( mrb,dup, str);1157 str_with_class(dup, str); 1080 1158 return str_replace(mrb, dup, s); 1081 1159 } 1082 1160 1083 static mrb_value 1084 mrb_str_aref(mrb_state *mrb, mrb_value str, mrb_value indx) 1085 { 1086 mrb_int idx; 1087 1088 mrb_regexp_check(mrb, indx); 1089 switch (mrb_type(indx)) { 1090 case MRB_TT_FIXNUM: 1091 idx = mrb_fixnum(indx); 1092 1093 num_index: 1094 str = str_substr(mrb, str, idx, 1); 1095 if (!mrb_nil_p(str) && RSTRING_LEN(str) == 0) return mrb_nil_value(); 1096 return str; 1097 1098 case MRB_TT_STRING: 1099 if (str_index(mrb, str, indx, 0) != -1) 1100 return mrb_str_dup(mrb, indx); 1101 return mrb_nil_value(); 1102 1103 case MRB_TT_RANGE: 1104 goto range_arg; 1105 1106 default: 1107 indx = mrb_Integer(mrb, indx); 1108 if (mrb_nil_p(indx)) { 1109 range_arg: 1110 { 1111 mrb_int beg, len; 1112 1113 len = RSTRING_CHAR_LEN(str); 1114 switch (mrb_range_beg_len(mrb, indx, &beg, &len, len, TRUE)) { 1115 case 1: 1116 return str_subseq(mrb, str, beg, len); 1117 case 2: 1118 return mrb_nil_value(); 1161 enum str_convert_range { 1162 /* `beg` and `len` are byte unit in `0 ... str.bytesize` */ 1163 STR_BYTE_RANGE_CORRECTED = 1, 1164 1165 /* `beg` and `len` are char unit in any range */ 1166 STR_CHAR_RANGE = 2, 1167 1168 /* `beg` and `len` are char unit in `0 ... str.size` */ 1169 STR_CHAR_RANGE_CORRECTED = 3, 1170 1171 /* `beg` is out of range */ 1172 STR_OUT_OF_RANGE = -1 1173 }; 1174 1175 static enum str_convert_range 1176 str_convert_range(mrb_state *mrb, mrb_value str, mrb_value indx, mrb_value alen, mrb_int *beg, mrb_int *len) 1177 { 1178 if (!mrb_undef_p(alen)) { 1179 *beg = mrb_int(mrb, indx); 1180 *len = mrb_int(mrb, alen); 1181 return STR_CHAR_RANGE; 1182 } 1183 else { 1184 switch (mrb_type(indx)) { 1185 case MRB_TT_FIXNUM: 1186 *beg = mrb_fixnum(indx); 1187 *len = 1; 1188 return STR_CHAR_RANGE; 1189 1190 case MRB_TT_STRING: 1191 *beg = str_index_str(mrb, str, indx, 0); 1192 if (*beg < 0) { break; } 1193 *len = RSTRING_LEN(indx); 1194 return STR_BYTE_RANGE_CORRECTED; 1195 1196 case MRB_TT_RANGE: 1197 goto range_arg; 1198 1199 default: 1200 indx = mrb_to_int(mrb, indx); 1201 if (mrb_fixnum_p(indx)) { 1202 *beg = mrb_fixnum(indx); 1203 *len = 1; 1204 return STR_CHAR_RANGE; 1205 } 1206 range_arg: 1207 *len = RSTRING_CHAR_LEN(str); 1208 switch (mrb_range_beg_len(mrb, indx, beg, len, *len, TRUE)) { 1209 case MRB_RANGE_OK: 1210 return STR_CHAR_RANGE_CORRECTED; 1211 case MRB_RANGE_OUT: 1212 return STR_OUT_OF_RANGE; 1119 1213 default: 1120 1214 break; 1121 }1122 1215 } 1216 1123 1217 mrb_raise(mrb, E_TYPE_ERROR, "can't convert to Fixnum"); 1124 } 1125 idx = mrb_fixnum(indx); 1126 goto num_index; 1127 } 1128 return mrb_nil_value(); /* not reached */ 1218 } 1219 } 1220 return STR_OUT_OF_RANGE; 1221 } 1222 1223 static mrb_value 1224 mrb_str_aref(mrb_state *mrb, mrb_value str, mrb_value indx, mrb_value alen) 1225 { 1226 mrb_int beg, len; 1227 1228 switch (str_convert_range(mrb, str, indx, alen, &beg, &len)) { 1229 case STR_CHAR_RANGE_CORRECTED: 1230 return str_subseq(mrb, str, beg, len); 1231 case STR_CHAR_RANGE: 1232 str = str_substr(mrb, str, beg, len); 1233 if (mrb_undef_p(alen) && !mrb_nil_p(str) && RSTRING_LEN(str) == 0) return mrb_nil_value(); 1234 return str; 1235 case STR_BYTE_RANGE_CORRECTED: 1236 if (mrb_string_p(indx)) { 1237 return mrb_str_dup(mrb, indx); 1238 } 1239 else { 1240 return mrb_str_byte_subseq(mrb, str, beg, len); 1241 } 1242 case STR_OUT_OF_RANGE: 1243 default: 1244 return mrb_nil_value(); 1245 } 1129 1246 } 1130 1247 … … 1136 1253 * str[fixnum, fixnum] => new_str or nil 1137 1254 * str[range] => new_str or nil 1138 * str[regexp] => new_str or nil1139 * str[regexp, fixnum] => new_str or nil1140 1255 * str[other_str] => new_str or nil 1141 1256 * str.slice(fixnum) => fixnum or nil … … 1173 1288 { 1174 1289 mrb_value a1, a2; 1175 int argc; 1176 1177 argc = mrb_get_args(mrb, "o|o", &a1, &a2); 1178 if (argc == 2) { 1179 mrb_int n1, n2; 1180 1181 mrb_regexp_check(mrb, a1); 1182 mrb_get_args(mrb, "ii", &n1, &n2); 1183 return str_substr(mrb, str, n1, n2); 1184 } 1185 if (argc != 1) { 1186 mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (%S for 1)", mrb_fixnum_value(argc)); 1187 } 1188 return mrb_str_aref(mrb, str, a1); 1290 1291 if (mrb_get_args(mrb, "o|o", &a1, &a2) == 1) { 1292 a2 = mrb_undef_value(); 1293 } 1294 1295 return mrb_str_aref(mrb, str, a1, a2); 1296 } 1297 1298 static mrb_noreturn void 1299 str_out_of_index(mrb_state *mrb, mrb_value index) 1300 { 1301 mrb_raisef(mrb, E_INDEX_ERROR, "index %v out of string", index); 1302 } 1303 1304 static mrb_value 1305 str_replace_partial(mrb_state *mrb, mrb_value src, mrb_int pos, mrb_int end, mrb_value rep) 1306 { 1307 const mrb_int shrink_threshold = 256; 1308 struct RString *str = mrb_str_ptr(src); 1309 mrb_int len = RSTR_LEN(str); 1310 mrb_int replen, newlen; 1311 char *strp; 1312 1313 if (end > len) { end = len; } 1314 1315 if (pos < 0 || pos > len) { 1316 str_out_of_index(mrb, mrb_fixnum_value(pos)); 1317 } 1318 1319 replen = (mrb_nil_p(rep) ? 0 : RSTRING_LEN(rep)); 1320 newlen = replen + len - (end - pos); 1321 1322 if (newlen >= MRB_SSIZE_MAX || newlen < replen /* overflowed */) { 1323 mrb_raise(mrb, E_RUNTIME_ERROR, "string size too big"); 1324 } 1325 1326 mrb_str_modify(mrb, str); 1327 1328 if (len < newlen) { 1329 resize_capa(mrb, str, newlen); 1330 } 1331 1332 strp = RSTR_PTR(str); 1333 1334 memmove(strp + newlen - (len - end), strp + end, len - end); 1335 if (!mrb_nil_p(rep)) { 1336 memmove(strp + pos, RSTRING_PTR(rep), replen); 1337 } 1338 RSTR_SET_LEN(str, newlen); 1339 strp[newlen] = '\0'; 1340 1341 if (len - newlen >= shrink_threshold) { 1342 resize_capa(mrb, str, newlen); 1343 } 1344 1345 return src; 1346 } 1347 1348 #define IS_EVSTR(p,e) ((p) < (e) && (*(p) == '$' || *(p) == '@' || *(p) == '{')) 1349 1350 static mrb_value 1351 str_escape(mrb_state *mrb, mrb_value str, mrb_bool inspect) 1352 { 1353 const char *p, *pend; 1354 char buf[4]; /* `\x??` or UTF-8 character */ 1355 mrb_value result = mrb_str_new_lit(mrb, "\""); 1356 #ifdef MRB_UTF8_STRING 1357 uint32_t ascii_flag = MRB_STR_ASCII; 1358 #endif 1359 1360 p = RSTRING_PTR(str); pend = RSTRING_END(str); 1361 for (;p < pend; p++) { 1362 unsigned char c, cc; 1363 #ifdef MRB_UTF8_STRING 1364 if (inspect) { 1365 mrb_int clen = mrb_utf8len(p, pend); 1366 if (clen > 1) { 1367 mrb_int i; 1368 1369 for (i=0; i<clen; i++) { 1370 buf[i] = p[i]; 1371 } 1372 mrb_str_cat(mrb, result, buf, clen); 1373 p += clen-1; 1374 ascii_flag = 0; 1375 continue; 1376 } 1377 } 1378 #endif 1379 c = *p; 1380 if (c == '"'|| c == '\\' || (c == '#' && IS_EVSTR(p+1, pend))) { 1381 buf[0] = '\\'; buf[1] = c; 1382 mrb_str_cat(mrb, result, buf, 2); 1383 continue; 1384 } 1385 if (ISPRINT(c)) { 1386 buf[0] = c; 1387 mrb_str_cat(mrb, result, buf, 1); 1388 continue; 1389 } 1390 switch (c) { 1391 case '\n': cc = 'n'; break; 1392 case '\r': cc = 'r'; break; 1393 case '\t': cc = 't'; break; 1394 case '\f': cc = 'f'; break; 1395 case '\013': cc = 'v'; break; 1396 case '\010': cc = 'b'; break; 1397 case '\007': cc = 'a'; break; 1398 case 033: cc = 'e'; break; 1399 default: cc = 0; break; 1400 } 1401 if (cc) { 1402 buf[0] = '\\'; 1403 buf[1] = (char)cc; 1404 mrb_str_cat(mrb, result, buf, 2); 1405 continue; 1406 } 1407 else { 1408 buf[0] = '\\'; 1409 buf[1] = 'x'; 1410 buf[3] = mrb_digitmap[c % 16]; c /= 16; 1411 buf[2] = mrb_digitmap[c % 16]; 1412 mrb_str_cat(mrb, result, buf, 4); 1413 continue; 1414 } 1415 } 1416 mrb_str_cat_lit(mrb, result, "\""); 1417 #ifdef MRB_UTF8_STRING 1418 if (inspect) { 1419 mrb_str_ptr(str)->flags |= ascii_flag; 1420 mrb_str_ptr(result)->flags |= ascii_flag; 1421 } 1422 else { 1423 RSTR_SET_ASCII_FLAG(mrb_str_ptr(result)); 1424 } 1425 #endif 1426 1427 return result; 1428 } 1429 1430 static void 1431 mrb_str_aset(mrb_state *mrb, mrb_value str, mrb_value indx, mrb_value alen, mrb_value replace) 1432 { 1433 mrb_int beg, len, charlen; 1434 1435 mrb_to_str(mrb, replace); 1436 1437 switch (str_convert_range(mrb, str, indx, alen, &beg, &len)) { 1438 case STR_OUT_OF_RANGE: 1439 default: 1440 mrb_raise(mrb, E_INDEX_ERROR, "string not matched"); 1441 case STR_CHAR_RANGE: 1442 if (len < 0) { 1443 mrb_raisef(mrb, E_INDEX_ERROR, "negative length %v", alen); 1444 } 1445 charlen = RSTRING_CHAR_LEN(str); 1446 if (beg < 0) { beg += charlen; } 1447 if (beg < 0 || beg > charlen) { str_out_of_index(mrb, indx); } 1448 /* fall through */ 1449 case STR_CHAR_RANGE_CORRECTED: 1450 str_range_to_bytes(str, &beg, &len); 1451 /* fall through */ 1452 case STR_BYTE_RANGE_CORRECTED: 1453 str_replace_partial(mrb, str, beg, beg + len, replace); 1454 } 1455 } 1456 1457 /* 1458 * call-seq: 1459 * str[fixnum] = replace 1460 * str[fixnum, fixnum] = replace 1461 * str[range] = replace 1462 * str[other_str] = replace 1463 * 1464 * Modify +self+ by replacing the content of +self+. 1465 * The portion of the string affected is determined using the same criteria as +String#[]+. 1466 */ 1467 static mrb_value 1468 mrb_str_aset_m(mrb_state *mrb, mrb_value str) 1469 { 1470 mrb_value indx, alen, replace; 1471 1472 switch (mrb_get_args(mrb, "oo|S!", &indx, &alen, &replace)) { 1473 case 2: 1474 replace = alen; 1475 alen = mrb_undef_value(); 1476 break; 1477 case 3: 1478 break; 1479 } 1480 mrb_str_aset(mrb, str, indx, alen, replace); 1481 return str; 1189 1482 } 1190 1483 … … 1209 1502 struct RString *s = mrb_str_ptr(str); 1210 1503 1211 mrb_str_modify (mrb, s);1504 mrb_str_modify_keep_ascii(mrb, s); 1212 1505 if (RSTR_LEN(s) == 0 || !RSTR_PTR(s)) return mrb_nil_value(); 1213 1506 p = RSTR_PTR(s); pend = RSTR_PTR(s) + RSTR_LEN(s); … … 1267 1560 struct RString *s = mrb_str_ptr(str); 1268 1561 1269 mrb_str_modify(mrb, s);1270 1562 argc = mrb_get_args(mrb, "|S", &rs); 1563 mrb_str_modify_keep_ascii(mrb, s); 1271 1564 len = RSTR_LEN(s); 1272 1565 if (argc == 0) { … … 1330 1623 * 1331 1624 * Returns a new <code>String</code> with the given record separator removed 1332 * from the end of <i>str</i> (if present). If <code>$/</code> has not been 1333 * changed from the default Ruby record separator, then <code>chomp</code> also 1334 * removes carriage return characters (that is it will remove <code>\n</code>, 1625 * from the end of <i>str</i> (if present). <code>chomp</code> also removes 1626 * carriage return characters (that is it will remove <code>\n</code>, 1335 1627 * <code>\r</code>, and <code>\r\n</code>). 1336 1628 * … … 1367 1659 struct RString *s = mrb_str_ptr(str); 1368 1660 1369 mrb_str_modify (mrb, s);1661 mrb_str_modify_keep_ascii(mrb, s); 1370 1662 if (RSTR_LEN(s) > 0) { 1371 1663 mrb_int len; … … 1374 1666 const char* e = p + RSTR_LEN(s); 1375 1667 while (p<e) { 1376 mrb_int clen = utf8len(p, e);1668 mrb_int clen = mrb_utf8len(p, e); 1377 1669 if (p + clen>=e) break; 1378 1670 p += clen; … … 1436 1728 struct RString *s = mrb_str_ptr(str); 1437 1729 1438 mrb_str_modify (mrb, s);1730 mrb_str_modify_keep_ascii(mrb, s); 1439 1731 p = RSTR_PTR(s); 1440 1732 pend = RSTR_PTR(s) + RSTR_LEN(s); … … 1504 1796 1505 1797 mrb_get_args(mrb, "o", &str2); 1506 eql_p = (mrb_ type(str2) == MRB_TT_STRING) && str_eql(mrb, self, str2);1798 eql_p = (mrb_string_p(str2)) && str_eql(mrb, self, str2); 1507 1799 1508 1800 return mrb_bool_value(eql_p); … … 1515 1807 } 1516 1808 1517 mrb_int1809 uint32_t 1518 1810 mrb_str_hash(mrb_state *mrb, mrb_value str) 1519 1811 { … … 1522 1814 mrb_int len = RSTR_LEN(s); 1523 1815 char *p = RSTR_PTR(s); 1524 mrb_int key = 0;1816 uint64_t key = 0; 1525 1817 1526 1818 while (len--) { … … 1528 1820 p++; 1529 1821 } 1530 return key + (key>>5);1822 return (uint32_t)(key + (key>>5)); 1531 1823 } 1532 1824 … … 1564 1856 1565 1857 mrb_get_args(mrb, "S", &str2); 1566 if (str_index (mrb, self, str2, 0) < 0)1858 if (str_index_str(mrb, self, str2, 0) < 0) 1567 1859 return mrb_bool_value(FALSE); 1568 1860 return mrb_bool_value(TRUE); … … 1573 1865 * call-seq: 1574 1866 * str.index(substring [, offset]) => fixnum or nil 1575 * str.index(fixnum [, offset]) => fixnum or nil1576 * str.index(regexp [, offset]) => fixnum or nil1577 1867 * 1578 1868 * Returns the index of the first occurrence of the given 1579 * <i>substring</i>, 1580 * character (<i>fixnum</i>), or pattern (<i>regexp</i>) in <i>str</i>. 1581 * Returns 1582 * <code>nil</code> if not found. 1869 * <i>substring</i>. Returns <code>nil</code> if not found. 1583 1870 * If the second parameter is present, it 1584 1871 * specifies the position in the string to begin the search. 1585 1872 * 1586 * "hello".index(' e') #=> 11873 * "hello".index('l') #=> 2 1587 1874 * "hello".index('lo') #=> 3 1588 1875 * "hello".index('a') #=> nil 1589 * "hello".index(101) #=> 1(101=0x65='e') 1590 * "hello".index(/[aeiou]/, -3) #=> 4 1591 */ 1592 static mrb_value 1593 mrb_str_index(mrb_state *mrb, mrb_value str) 1594 { 1595 mrb_value *argv; 1596 mrb_int argc; 1876 * "hello".index('l', -2) #=> 3 1877 */ 1878 static mrb_value 1879 mrb_str_index_m(mrb_state *mrb, mrb_value str) 1880 { 1597 1881 mrb_value sub; 1598 mrb_int pos, clen; 1599 1600 mrb_get_args(mrb, "*", &argv, &argc); 1601 if (argc == 2) { 1602 mrb_get_args(mrb, "oi", &sub, &pos); 1603 } 1604 else { 1882 mrb_int pos; 1883 1884 if (mrb_get_args(mrb, "S|i", &sub, &pos) == 1) { 1605 1885 pos = 0; 1606 if (argc > 0) 1607 sub = argv[0]; 1608 else 1609 sub = mrb_nil_value(); 1610 } 1611 mrb_regexp_check(mrb, sub); 1612 clen = RSTRING_CHAR_LEN(str); 1613 if (pos < 0) { 1886 } 1887 else if (pos < 0) { 1888 mrb_int clen = RSTRING_CHAR_LEN(str); 1614 1889 pos += clen; 1615 1890 if (pos < 0) { … … 1617 1892 } 1618 1893 } 1619 if (pos > clen) return mrb_nil_value(); 1620 pos = chars2bytes(str, 0, pos); 1621 1622 switch (mrb_type(sub)) { 1623 default: { 1624 mrb_value tmp; 1625 1626 tmp = mrb_check_string_type(mrb, sub); 1627 if (mrb_nil_p(tmp)) { 1628 mrb_raisef(mrb, E_TYPE_ERROR, "type mismatch: %S given", sub); 1629 } 1630 sub = tmp; 1631 } 1632 /* fall through */ 1633 case MRB_TT_STRING: 1634 pos = str_index(mrb, str, sub, pos); 1635 break; 1636 } 1894 pos = str_index_str_by_char(mrb, str, sub, pos); 1637 1895 1638 1896 if (pos == -1) return mrb_nil_value(); 1639 pos = bytes2chars(RSTRING_PTR(str), pos);1640 1897 BYTES_ALIGN_CHECK(pos); 1641 1898 return mrb_fixnum_value(pos); 1642 1899 } 1643 1644 #define STR_REPLACE_SHARED_MIN 101645 1900 1646 1901 /* 15.2.10.5.24 */ … … 1712 1967 mrb_obj_as_string(mrb_state *mrb, mrb_value obj) 1713 1968 { 1714 mrb_value str;1715 1716 1969 if (mrb_string_p(obj)) { 1717 1970 return obj; 1718 1971 } 1719 str = mrb_funcall(mrb, obj, "to_s", 0); 1720 if (!mrb_string_p(str)) 1721 return mrb_any_to_s(mrb, obj); 1722 return str; 1972 return mrb_str_to_str(mrb, obj); 1723 1973 } 1724 1974 … … 1753 2003 } 1754 2004 1755 MRB_API mrb_value 1756 mrb_string_type(mrb_state *mrb, mrb_value str)1757 { 1758 return mrb_convert_type(mrb, str, MRB_TT_STRING, "String", "to_str");1759 } 1760 1761 MRB_API mrb_value 1762 mrb_check_string_type(mrb_state *mrb, mrb_value str) 1763 { 1764 return mrb_check_convert_type(mrb, str, MRB_TT_STRING, "String", "to_str");2005 static inline void 2006 str_reverse(char *p, char *e) 2007 { 2008 char c; 2009 2010 while (p < e) { 2011 c = *p; 2012 *p++ = *e; 2013 *e-- = c; 2014 } 1765 2015 } 1766 2016 … … 1775 2025 mrb_str_reverse_bang(mrb_state *mrb, mrb_value str) 1776 2026 { 2027 struct RString *s = mrb_str_ptr(str); 2028 char *p, *e; 2029 1777 2030 #ifdef MRB_UTF8_STRING 1778 2031 mrb_int utf8_len = RSTRING_CHAR_LEN(str); 1779 mrb_int len = RSTRING_LEN(str); 1780 1781 if (utf8_len == len) goto bytes; 1782 if (utf8_len > 1) { 1783 char *buf; 1784 char *p, *e, *r; 1785 1786 mrb_str_modify(mrb, mrb_str_ptr(str)); 1787 len = RSTRING_LEN(str); 1788 buf = (char*)mrb_malloc(mrb, (size_t)len); 1789 p = buf; 1790 e = buf + len; 1791 1792 memcpy(buf, RSTRING_PTR(str), len); 1793 r = RSTRING_PTR(str) + len; 1794 2032 mrb_int len = RSTR_LEN(s); 2033 2034 if (utf8_len < 2) return str; 2035 if (utf8_len < len) { 2036 mrb_str_modify(mrb, s); 2037 p = RSTR_PTR(s); 2038 e = p + RSTR_LEN(s); 1795 2039 while (p<e) { 1796 mrb_int clen = utf8len(p, e); 1797 r -= clen; 1798 memcpy(r, p, clen); 2040 mrb_int clen = mrb_utf8len(p, e); 2041 str_reverse(p, p + clen - 1); 1799 2042 p += clen; 1800 2043 } 1801 mrb_free(mrb, buf); 2044 goto bytes; 2045 } 2046 #endif 2047 2048 if (RSTR_LEN(s) > 1) { 2049 mrb_str_modify(mrb, s); 2050 goto bytes; 1802 2051 } 1803 2052 return str; 1804 2053 1805 2054 bytes: 1806 #endif 1807 { 1808 struct RString *s = mrb_str_ptr(str); 1809 char *p, *e; 1810 char c; 1811 1812 mrb_str_modify(mrb, s); 1813 if (RSTR_LEN(s) > 1) { 1814 p = RSTR_PTR(s); 1815 e = p + RSTR_LEN(s) - 1; 1816 while (p < e) { 1817 c = *p; 1818 *p++ = *e; 1819 *e-- = c; 1820 } 1821 } 1822 return str; 1823 } 2055 p = RSTR_PTR(s); 2056 e = p + RSTR_LEN(s) - 1; 2057 str_reverse(p, e); 2058 return str; 1824 2059 } 1825 2060 … … 1845 2080 /* 1846 2081 * call-seq: 1847 * str.rindex(substring [, fixnum]) => fixnum or nil 1848 * str.rindex(fixnum [, fixnum]) => fixnum or nil 1849 * str.rindex(regexp [, fixnum]) => fixnum or nil 1850 * 1851 * Returns the index of the last occurrence of the given <i>substring</i>, 1852 * character (<i>fixnum</i>), or pattern (<i>regexp</i>) in <i>str</i>. Returns 1853 * <code>nil</code> if not found. If the second parameter is present, it 1854 * specifies the position in the string to end the search---characters beyond 1855 * this point will not be considered. 2082 * str.rindex(substring [, offset]) => fixnum or nil 2083 * 2084 * Returns the index of the last occurrence of the given <i>substring</i>. 2085 * Returns <code>nil</code> if not found. If the second parameter is 2086 * present, it specifies the position in the string to end the 2087 * search---characters beyond this point will not be considered. 1856 2088 * 1857 2089 * "hello".rindex('e') #=> 1 1858 2090 * "hello".rindex('l') #=> 3 1859 2091 * "hello".rindex('a') #=> nil 1860 * "hello".rindex(101) #=> 1 1861 * "hello".rindex(/[aeiou]/, -2) #=> 1 2092 * "hello".rindex('l', 2) #=> 2 1862 2093 */ 1863 2094 static mrb_value 1864 2095 mrb_str_rindex(mrb_state *mrb, mrb_value str) 1865 2096 { 1866 mrb_value *argv;1867 mrb_int argc;1868 2097 mrb_value sub; 1869 2098 mrb_int pos, len = RSTRING_CHAR_LEN(str); 1870 2099 1871 mrb_get_args(mrb, "*", &argv, &argc); 1872 if (argc == 2) { 1873 mrb_get_args(mrb, "oi", &sub, &pos); 2100 if (mrb_get_args(mrb, "S|i", &sub, &pos) == 1) { 2101 pos = len; 2102 } 2103 else { 1874 2104 if (pos < 0) { 1875 2105 pos += len; 1876 2106 if (pos < 0) { 1877 mrb_regexp_check(mrb, sub);1878 2107 return mrb_nil_value(); 1879 2108 } … … 1881 2110 if (pos > len) pos = len; 1882 2111 } 1883 else {1884 pos = len;1885 if (argc > 0)1886 sub = argv[0];1887 else1888 sub = mrb_nil_value();1889 }1890 2112 pos = chars2bytes(str, 0, pos); 1891 mrb_regexp_check(mrb, sub); 1892 1893 switch (mrb_type(sub)) { 1894 default: { 1895 mrb_value tmp; 1896 1897 tmp = mrb_check_string_type(mrb, sub); 1898 if (mrb_nil_p(tmp)) { 1899 mrb_raisef(mrb, E_TYPE_ERROR, "type mismatch: %S given", sub); 1900 } 1901 sub = tmp; 1902 } 1903 /* fall through */ 1904 case MRB_TT_STRING: 1905 pos = str_rindex(mrb, str, sub, pos); 1906 if (pos >= 0) { 1907 pos = bytes2chars(RSTRING_PTR(str), pos); 1908 BYTES_ALIGN_CHECK(pos); 1909 return mrb_fixnum_value(pos); 1910 } 1911 break; 1912 1913 } /* end of switch (TYPE(sub)) */ 2113 pos = str_rindex(mrb, str, sub, pos); 2114 if (pos >= 0) { 2115 pos = bytes2chars(RSTRING_PTR(str), RSTRING_LEN(str), pos); 2116 BYTES_ALIGN_CHECK(pos); 2117 return mrb_fixnum_value(pos); 2118 } 1914 2119 return mrb_nil_value(); 1915 2120 } … … 1919 2124 /* 1920 2125 * call-seq: 1921 * str.split( pattern="\n", [limit]) => anArray2126 * str.split(separator=nil, [limit]) => anArray 1922 2127 * 1923 2128 * Divides <i>str</i> into substrings based on a delimiter, returning an array 1924 2129 * of these substrings. 1925 2130 * 1926 * If <i> pattern</i> is a <code>String</code>, then its contents are used as1927 * the delimiter when splitting <i>str</i>. If <i> pattern</i> is a single2131 * If <i>separator</i> is a <code>String</code>, then its contents are used as 2132 * the delimiter when splitting <i>str</i>. If <i>separator</i> is a single 1928 2133 * space, <i>str</i> is split on whitespace, with leading whitespace and runs 1929 2134 * of contiguous whitespace characters ignored. 1930 2135 * 1931 * If <i>pattern</i> is a <code>Regexp</code>, <i>str</i> is divided where the 1932 * pattern matches. Whenever the pattern matches a zero-length string, 1933 * <i>str</i> is split into individual characters. 1934 * 1935 * If <i>pattern</i> is omitted, the value of <code>$;</code> is used. If 1936 * <code>$;</code> is <code>nil</code> (which is the default), <i>str</i> is 1937 * split on whitespace as if ' ' were specified. 2136 * If <i>separator</i> is omitted or <code>nil</code> (which is the default), 2137 * <i>str</i> is split on whitespace as if ' ' were specified. 1938 2138 * 1939 2139 * If the <i>limit</i> parameter is omitted, trailing null fields are … … 1946 2146 * " now's the time".split #=> ["now's", "the", "time"] 1947 2147 * " now's the time".split(' ') #=> ["now's", "the", "time"] 1948 * " now's the time".split(/ /) #=> ["", "now's", "", "the", "time"]1949 * "hello".split(//) #=> ["h", "e", "l", "l", "o"]1950 * "hello".split(//, 3) #=> ["h", "e", "llo"]1951 2148 * 1952 2149 * "mellow yellow".split("ello") #=> ["m", "w y", "w"] … … 1959 2156 mrb_str_split_m(mrb_state *mrb, mrb_value str) 1960 2157 { 1961 int argc;2158 mrb_int argc; 1962 2159 mrb_value spat = mrb_nil_value(); 1963 enum {awk, string , regexp} split_type = string;2160 enum {awk, string} split_type = string; 1964 2161 mrb_int i = 0; 1965 2162 mrb_int beg; … … 1983 2180 split_type = awk; 1984 2181 } 1985 else { 1986 if (mrb_string_p(spat)) { 1987 split_type = string; 1988 if (RSTRING_LEN(spat) == 1 && RSTRING_PTR(spat)[0] == ' ') { 1989 split_type = awk; 1990 } 1991 } 1992 else { 1993 mrb_noregexp(mrb, str); 1994 } 2182 else if (!mrb_string_p(spat)) { 2183 mrb_raise(mrb, E_TYPE_ERROR, "expected String"); 2184 } 2185 else if (RSTRING_LEN(spat) == 1 && RSTRING_PTR(spat)[0] == ' ') { 2186 split_type = awk; 1995 2187 } 1996 2188 … … 2018 2210 } 2019 2211 else if (ISSPACE(c)) { 2020 mrb_ary_push(mrb, result, byte_subseq(mrb, str, beg, end-beg));2212 mrb_ary_push(mrb, result, mrb_str_byte_subseq(mrb, str, beg, end-beg)); 2021 2213 mrb_gc_arena_restore(mrb, ai); 2022 2214 skip = TRUE; … … 2029 2221 } 2030 2222 } 2031 else if (split_type == string) {2223 else { /* split_type == string */ 2032 2224 mrb_int str_len = RSTRING_LEN(str); 2033 2225 mrb_int pat_len = RSTRING_LEN(spat); … … 2043 2235 end = chars2bytes(str, idx, 1); 2044 2236 } 2045 mrb_ary_push(mrb, result, byte_subseq(mrb, str, idx, end));2237 mrb_ary_push(mrb, result, mrb_str_byte_subseq(mrb, str, idx, end)); 2046 2238 mrb_gc_arena_restore(mrb, ai); 2047 2239 idx += end + pat_len; … … 2050 2242 beg = idx; 2051 2243 } 2052 else {2053 mrb_noregexp(mrb, str);2054 }2055 2244 if (RSTRING_LEN(str) > 0 && (lim_p || RSTRING_LEN(str) > beg || lim < 0)) { 2056 2245 if (RSTRING_LEN(str) == beg) { … … 2058 2247 } 2059 2248 else { 2060 tmp = byte_subseq(mrb, str, beg, RSTRING_LEN(str)-beg);2249 tmp = mrb_str_byte_subseq(mrb, str, beg, RSTRING_LEN(str)-beg); 2061 2250 } 2062 2251 mrb_ary_push(mrb, result, tmp); … … 2072 2261 } 2073 2262 2074 MRB_APImrb_value2075 mrb_str_len_to_inum(mrb_state *mrb, const char *str, size_t len,int base, int badcheck)2263 mrb_value 2264 mrb_str_len_to_inum(mrb_state *mrb, const char *str, mrb_int len, mrb_int base, int badcheck) 2076 2265 { 2077 2266 const char *p = str; … … 2156 2345 default: 2157 2346 if (base < 2 || 36 < base) { 2158 mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal radix % S", mrb_fixnum_value(base));2347 mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal radix %i", base); 2159 2348 } 2160 2349 break; … … 2183 2372 p--; 2184 2373 } 2185 if (p == pend ) {2374 if (p == pend || *p == '_') { 2186 2375 if (badcheck) goto bad; 2187 2376 return mrb_fixnum_value(0); … … 2209 2398 n += c; 2210 2399 if (n > (uint64_t)MRB_INT_MAX + (sign ? 0 : 1)) { 2211 mrb_raisef(mrb, E_ARGUMENT_ERROR, "string (%S) too big for integer", 2212 mrb_str_new(mrb, str, pend-str)); 2400 #ifndef MRB_WITHOUT_FLOAT 2401 if (base == 10) { 2402 return mrb_float_value(mrb, mrb_str_to_dbl(mrb, mrb_str_new(mrb, str, len), badcheck)); 2403 } 2404 else 2405 #endif 2406 { 2407 mrb_raisef(mrb, E_RANGE_ERROR, "string (%l) too big for integer", str, pend-str); 2408 } 2213 2409 } 2214 2410 } 2215 2411 val = (mrb_int)n; 2216 2412 if (badcheck) { 2217 if (p == str) goto bad; /* no number */ 2413 if (p == str) goto bad; /* no number */ 2414 if (*(p - 1) == '_') goto bad; /* trailing '_' */ 2218 2415 while (p<pend && ISSPACE(*p)) p++; 2219 if (p<pend) goto bad; /* trailing garbage */2416 if (p<pend) goto bad; /* trailing garbage */ 2220 2417 } 2221 2418 … … 2225 2422 /* not reached */ 2226 2423 bad: 2227 mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid string for number(%S)", 2228 mrb_inspect(mrb, mrb_str_new(mrb, str, pend-str))); 2424 mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid string for number(%!l)", str, pend-str); 2229 2425 /* not reached */ 2230 2426 return mrb_fixnum_value(0); … … 2232 2428 2233 2429 MRB_API mrb_value 2234 mrb_cstr_to_inum(mrb_state *mrb, const char *str, int base, intbadcheck)2430 mrb_cstr_to_inum(mrb_state *mrb, const char *str, mrb_int base, mrb_bool badcheck) 2235 2431 { 2236 2432 return mrb_str_len_to_inum(mrb, str, strlen(str), base, badcheck); 2237 2433 } 2238 2434 2435 /* obslete: use RSTRING_CSTR() or mrb_string_cstr() */ 2239 2436 MRB_API const char* 2240 2437 mrb_string_value_cstr(mrb_state *mrb, mrb_value *ptr) 2241 2438 { 2242 mrb_value str = mrb_str_to_str(mrb, *ptr); 2243 struct RString *ps = mrb_str_ptr(str); 2244 mrb_int len = mrb_str_strlen(mrb, ps); 2245 char *p = RSTR_PTR(ps); 2246 2247 if (!p || p[len] != '\0') { 2248 if (MRB_FROZEN_P(ps)) { 2249 *ptr = str = mrb_str_dup(mrb, str); 2250 ps = mrb_str_ptr(str); 2251 } 2252 mrb_str_modify(mrb, ps); 2253 return RSTR_PTR(ps); 2254 } 2255 return p; 2439 struct RString *ps; 2440 const char *p; 2441 mrb_int len; 2442 2443 check_null_byte(mrb, *ptr); 2444 ps = mrb_str_ptr(*ptr); 2445 p = RSTR_PTR(ps); 2446 len = RSTR_LEN(ps); 2447 if (p[len] == '\0') { 2448 return p; 2449 } 2450 2451 /* 2452 * Even after str_modify_keep_ascii(), NULL termination is not ensured if 2453 * RSTR_SET_LEN() is used explicitly (e.g. String#delete_suffix!). 2454 */ 2455 str_modify_keep_ascii(mrb, ps); 2456 RSTR_PTR(ps)[len] = '\0'; 2457 return RSTR_PTR(ps); 2458 } 2459 2460 MRB_API const char* 2461 mrb_string_cstr(mrb_state *mrb, mrb_value str) 2462 { 2463 return mrb_string_value_cstr(mrb, &str); 2256 2464 } 2257 2465 … … 2262 2470 mrb_int len; 2263 2471 2264 s = mrb_string_value_ptr(mrb, str); 2472 mrb_to_str(mrb, str); 2473 s = RSTRING_PTR(str); 2265 2474 len = RSTRING_LEN(str); 2266 2475 return mrb_str_len_to_inum(mrb, s, len, base, badcheck); … … 2295 2504 mrb_get_args(mrb, "|i", &base); 2296 2505 if (base < 0) { 2297 mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal radix % S", mrb_fixnum_value(base));2506 mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal radix %i", base); 2298 2507 } 2299 2508 return mrb_str_to_inum(mrb, self, base, FALSE); 2300 2509 } 2301 2510 2302 MRB_API double 2303 mrb_cstr_to_dbl(mrb_state *mrb, const char * p, mrb_bool badcheck) 2304 { 2511 #ifndef MRB_WITHOUT_FLOAT 2512 double 2513 mrb_str_len_to_dbl(mrb_state *mrb, const char *s, size_t len, mrb_bool badcheck) 2514 { 2515 char buf[DBL_DIG * 4 + 20]; 2516 const char *p = s, *p2; 2517 const char *pend = p + len; 2305 2518 char *end; 2306 char buf[DBL_DIG * 4 + 10]; 2519 char *n; 2520 char prev = 0; 2307 2521 double d; 2308 2309 enum {max_width = 20}; 2522 mrb_bool dot = FALSE; 2310 2523 2311 2524 if (!p) return 0.0; 2312 while (ISSPACE(*p)) p++; 2313 2314 if (!badcheck && p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) { 2315 return 0.0; 2316 } 2525 while (p<pend && ISSPACE(*p)) p++; 2526 p2 = p; 2527 2528 if (pend - p > 2 && p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) { 2529 mrb_value x; 2530 2531 if (!badcheck) return 0.0; 2532 x = mrb_str_len_to_inum(mrb, p, pend-p, 0, badcheck); 2533 if (mrb_fixnum_p(x)) 2534 d = (double)mrb_fixnum(x); 2535 else /* if (mrb_float_p(x)) */ 2536 d = mrb_float(x); 2537 return d; 2538 } 2539 while (p < pend) { 2540 if (!*p) { 2541 if (badcheck) { 2542 mrb_raise(mrb, E_ARGUMENT_ERROR, "string for Float contains null byte"); 2543 /* not reached */ 2544 } 2545 pend = p; 2546 p = p2; 2547 goto nocopy; 2548 } 2549 if (!badcheck && *p == ' ') { 2550 pend = p; 2551 p = p2; 2552 goto nocopy; 2553 } 2554 if (*p == '_') break; 2555 p++; 2556 } 2557 p = p2; 2558 n = buf; 2559 while (p < pend) { 2560 char c = *p++; 2561 if (c == '.') dot = TRUE; 2562 if (c == '_') { 2563 /* remove an underscore between digits */ 2564 if (n == buf || !ISDIGIT(prev) || p == pend) { 2565 if (badcheck) goto bad; 2566 break; 2567 } 2568 } 2569 else if (badcheck && prev == '_' && !ISDIGIT(c)) goto bad; 2570 else { 2571 const char *bend = buf+sizeof(buf)-1; 2572 if (n==bend) { /* buffer overflow */ 2573 if (dot) break; /* cut off remaining fractions */ 2574 return INFINITY; 2575 } 2576 *n++ = c; 2577 } 2578 prev = c; 2579 } 2580 *n = '\0'; 2581 p = buf; 2582 pend = n; 2583 nocopy: 2317 2584 d = mrb_float_read(p, &end); 2318 2585 if (p == end) { 2319 2586 if (badcheck) { 2320 2587 bad: 2321 mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid string for float(% S)", mrb_str_new_cstr(mrb, p));2588 mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid string for float(%!s)", s); 2322 2589 /* not reached */ 2323 2590 } 2324 2591 return d; 2325 2592 } 2326 if (*end) { 2327 char *n = buf; 2328 char *e = buf + sizeof(buf) - 1; 2329 char prev = 0; 2330 2331 while (p < end && n < e) prev = *n++ = *p++; 2332 while (*p) { 2333 if (*p == '_') { 2334 /* remove underscores between digits */ 2335 if (badcheck) { 2336 if (n == buf || !ISDIGIT(prev)) goto bad; 2337 ++p; 2338 if (!ISDIGIT(*p)) goto bad; 2339 } 2340 else { 2341 while (*++p == '_'); 2342 continue; 2343 } 2344 } 2345 prev = *p++; 2346 if (n < e) *n++ = prev; 2347 } 2348 *n = '\0'; 2349 p = buf; 2350 2351 if (!badcheck && p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) { 2352 return 0.0; 2353 } 2354 2355 d = mrb_float_read(p, &end); 2356 if (badcheck) { 2357 if (!end || p == end) goto bad; 2358 while (*end && ISSPACE(*end)) end++; 2359 if (*end) goto bad; 2360 } 2593 if (badcheck) { 2594 if (!end || p == end) goto bad; 2595 while (end<pend && ISSPACE(*end)) end++; 2596 if (end<pend) goto bad; 2361 2597 } 2362 2598 return d; 2599 } 2600 2601 MRB_API double 2602 mrb_cstr_to_dbl(mrb_state *mrb, const char *s, mrb_bool badcheck) 2603 { 2604 return mrb_str_len_to_dbl(mrb, s, strlen(s), badcheck); 2363 2605 } 2364 2606 … … 2366 2608 mrb_str_to_dbl(mrb_state *mrb, mrb_value str, mrb_bool badcheck) 2367 2609 { 2368 char *s; 2369 mrb_int len; 2370 2371 str = mrb_str_to_str(mrb, str); 2372 s = RSTRING_PTR(str); 2373 len = RSTRING_LEN(str); 2374 if (s) { 2375 if (badcheck && memchr(s, '\0', len)) { 2376 mrb_raise(mrb, E_ARGUMENT_ERROR, "string for Float contains null byte"); 2377 } 2378 if (s[len]) { /* no sentinel somehow */ 2379 struct RString *temp_str = str_new(mrb, s, len); 2380 s = RSTR_PTR(temp_str); 2381 } 2382 } 2383 return mrb_cstr_to_dbl(mrb, s, badcheck); 2610 return mrb_str_len_to_dbl(mrb, RSTRING_PTR(str), RSTRING_LEN(str), badcheck); 2384 2611 } 2385 2612 … … 2403 2630 return mrb_float_value(mrb, mrb_str_to_dbl(mrb, self, FALSE)); 2404 2631 } 2632 #endif 2405 2633 2406 2634 /* 15.2.10.5.40 */ … … 2408 2636 * call-seq: 2409 2637 * str.to_s => str 2410 * str.to_str => str2411 2638 * 2412 2639 * Returns the receiver. … … 2436 2663 mrb_bool modify = FALSE; 2437 2664 2438 mrb_str_modify (mrb, s);2665 mrb_str_modify_keep_ascii(mrb, s); 2439 2666 p = RSTRING_PTR(str); 2440 2667 pend = RSTRING_END(str); … … 2472 2699 } 2473 2700 2474 #define IS_EVSTR(p,e) ((p) < (e) && (*(p) == '$' || *(p) == '@' || *(p) == '{'))2475 2476 2701 /* 2477 2702 * call-seq: … … 2484 2709 mrb_str_dump(mrb_state *mrb, mrb_value str) 2485 2710 { 2486 mrb_int len; 2487 const char *p, *pend; 2488 char *q; 2489 struct RString *result; 2490 2491 len = 2; /* "" */ 2492 p = RSTRING_PTR(str); pend = p + RSTRING_LEN(str); 2493 while (p < pend) { 2494 unsigned char c = *p++; 2495 switch (c) { 2496 case '"': case '\\': 2497 case '\n': case '\r': 2498 case '\t': case '\f': 2499 case '\013': case '\010': case '\007': case '\033': 2500 len += 2; 2501 break; 2502 2503 case '#': 2504 len += IS_EVSTR(p, pend) ? 2 : 1; 2505 break; 2506 2507 default: 2508 if (ISPRINT(c)) { 2509 len++; 2510 } 2511 else { 2512 len += 4; /* \NNN */ 2513 } 2514 break; 2515 } 2516 } 2517 2518 result = str_new(mrb, 0, len); 2519 str_with_class(mrb, result, str); 2520 p = RSTRING_PTR(str); pend = p + RSTRING_LEN(str); 2521 q = RSTR_PTR(result); 2522 *q++ = '"'; 2523 while (p < pend) { 2524 unsigned char c = *p++; 2525 2526 switch (c) { 2527 case '"': 2528 case '\\': 2529 *q++ = '\\'; 2530 *q++ = c; 2531 break; 2532 2533 case '\n': 2534 *q++ = '\\'; 2535 *q++ = 'n'; 2536 break; 2537 2538 case '\r': 2539 *q++ = '\\'; 2540 *q++ = 'r'; 2541 break; 2542 2543 case '\t': 2544 *q++ = '\\'; 2545 *q++ = 't'; 2546 break; 2547 2548 case '\f': 2549 *q++ = '\\'; 2550 *q++ = 'f'; 2551 break; 2552 2553 case '\013': 2554 *q++ = '\\'; 2555 *q++ = 'v'; 2556 break; 2557 2558 case '\010': 2559 *q++ = '\\'; 2560 *q++ = 'b'; 2561 break; 2562 2563 case '\007': 2564 *q++ = '\\'; 2565 *q++ = 'a'; 2566 break; 2567 2568 case '\033': 2569 *q++ = '\\'; 2570 *q++ = 'e'; 2571 break; 2572 2573 case '#': 2574 if (IS_EVSTR(p, pend)) *q++ = '\\'; 2575 *q++ = '#'; 2576 break; 2577 2578 default: 2579 if (ISPRINT(c)) { 2580 *q++ = c; 2581 } 2582 else { 2583 *q++ = '\\'; 2584 q[2] = '0' + c % 8; c /= 8; 2585 q[1] = '0' + c % 8; c /= 8; 2586 q[0] = '0' + c % 8; 2587 q += 3; 2588 } 2589 } 2590 } 2591 *q = '"'; 2592 return mrb_obj_value(result); 2711 return str_escape(mrb, str, FALSE); 2593 2712 } 2594 2713 … … 2596 2715 mrb_str_cat(mrb_state *mrb, mrb_value str, const char *ptr, size_t len) 2597 2716 { 2598 str_buf_cat(mrb, mrb_str_ptr(str), ptr, len); 2717 struct RString *s = mrb_str_ptr(str); 2718 size_t capa; 2719 size_t total; 2720 ptrdiff_t off = -1; 2721 2722 if (len == 0) return str; 2723 mrb_str_modify(mrb, s); 2724 if (ptr >= RSTR_PTR(s) && ptr <= RSTR_PTR(s) + (size_t)RSTR_LEN(s)) { 2725 off = ptr - RSTR_PTR(s); 2726 } 2727 2728 capa = RSTR_CAPA(s); 2729 total = RSTR_LEN(s)+len; 2730 if (total >= MRB_SSIZE_MAX) { 2731 size_error: 2732 mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big"); 2733 } 2734 if (capa <= total) { 2735 if (capa == 0) capa = 1; 2736 while (capa <= total) { 2737 if (capa <= MRB_SSIZE_MAX / 2) { 2738 capa *= 2; 2739 } 2740 else { 2741 capa = total+1; 2742 } 2743 } 2744 if (capa <= total || capa > MRB_SSIZE_MAX) { 2745 goto size_error; 2746 } 2747 resize_capa(mrb, s, capa); 2748 } 2749 if (off != -1) { 2750 ptr = RSTR_PTR(s) + off; 2751 } 2752 memcpy(RSTR_PTR(s) + RSTR_LEN(s), ptr, len); 2753 mrb_assert_int_fit(size_t, total, mrb_ssize, MRB_SSIZE_MAX); 2754 RSTR_SET_LEN(s, total); 2755 RSTR_PTR(s)[total] = '\0'; /* sentinel */ 2599 2756 return str; 2600 2757 } … … 2609 2766 mrb_str_cat_str(mrb_state *mrb, mrb_value str, mrb_value str2) 2610 2767 { 2768 if (mrb_str_ptr(str) == mrb_str_ptr(str2)) { 2769 mrb_str_modify(mrb, mrb_str_ptr(str)); 2770 } 2611 2771 return mrb_str_cat(mrb, str, RSTRING_PTR(str2), RSTRING_LEN(str2)); 2612 2772 } … … 2615 2775 mrb_str_append(mrb_state *mrb, mrb_value str1, mrb_value str2) 2616 2776 { 2617 str2 = mrb_str_to_str(mrb, str2);2777 mrb_to_str(mrb, str2); 2618 2778 return mrb_str_cat_str(mrb, str1, str2); 2619 2779 } 2620 2621 #define CHAR_ESC_LEN 13 /* sizeof(\x{ hex of 32bit unsigned int } \0) */2622 2780 2623 2781 /* … … 2635 2793 mrb_str_inspect(mrb_state *mrb, mrb_value str) 2636 2794 { 2637 const char *p, *pend; 2638 char buf[CHAR_ESC_LEN + 1]; 2639 mrb_value result = mrb_str_new_lit(mrb, "\""); 2640 2641 p = RSTRING_PTR(str); pend = RSTRING_END(str); 2642 for (;p < pend; p++) { 2643 unsigned char c, cc; 2644 #ifdef MRB_UTF8_STRING 2645 mrb_int clen; 2646 2647 clen = utf8len(p, pend); 2648 if (clen > 1) { 2649 mrb_int i; 2650 2651 for (i=0; i<clen; i++) { 2652 buf[i] = p[i]; 2653 } 2654 mrb_str_cat(mrb, result, buf, clen); 2655 p += clen-1; 2656 continue; 2657 } 2658 #endif 2659 c = *p; 2660 if (c == '"'|| c == '\\' || (c == '#' && IS_EVSTR(p+1, pend))) { 2661 buf[0] = '\\'; buf[1] = c; 2662 mrb_str_cat(mrb, result, buf, 2); 2663 continue; 2664 } 2665 if (ISPRINT(c)) { 2666 buf[0] = c; 2667 mrb_str_cat(mrb, result, buf, 1); 2668 continue; 2669 } 2670 switch (c) { 2671 case '\n': cc = 'n'; break; 2672 case '\r': cc = 'r'; break; 2673 case '\t': cc = 't'; break; 2674 case '\f': cc = 'f'; break; 2675 case '\013': cc = 'v'; break; 2676 case '\010': cc = 'b'; break; 2677 case '\007': cc = 'a'; break; 2678 case 033: cc = 'e'; break; 2679 default: cc = 0; break; 2680 } 2681 if (cc) { 2682 buf[0] = '\\'; 2683 buf[1] = (char)cc; 2684 mrb_str_cat(mrb, result, buf, 2); 2685 continue; 2686 } 2687 else { 2688 buf[0] = '\\'; 2689 buf[3] = '0' + c % 8; c /= 8; 2690 buf[2] = '0' + c % 8; c /= 8; 2691 buf[1] = '0' + c % 8; 2692 mrb_str_cat(mrb, result, buf, 4); 2693 continue; 2694 } 2695 } 2696 mrb_str_cat_lit(mrb, result, "\""); 2697 2698 return result; 2795 return str_escape(mrb, str, TRUE); 2699 2796 } 2700 2797 … … 2722 2819 } 2723 2820 2821 /* 2822 * call-seq: 2823 * str.getbyte(index) -> 0 .. 255 2824 * 2825 * returns the <i>index</i>th byte as an integer. 2826 */ 2827 static mrb_value 2828 mrb_str_getbyte(mrb_state *mrb, mrb_value str) 2829 { 2830 mrb_int pos; 2831 mrb_get_args(mrb, "i", &pos); 2832 2833 if (pos < 0) 2834 pos += RSTRING_LEN(str); 2835 if (pos < 0 || RSTRING_LEN(str) <= pos) 2836 return mrb_nil_value(); 2837 2838 return mrb_fixnum_value((unsigned char)RSTRING_PTR(str)[pos]); 2839 } 2840 2841 /* 2842 * call-seq: 2843 * str.setbyte(index, integer) -> integer 2844 * 2845 * modifies the <i>index</i>th byte as <i>integer</i>. 2846 */ 2847 static mrb_value 2848 mrb_str_setbyte(mrb_state *mrb, mrb_value str) 2849 { 2850 mrb_int pos, byte; 2851 mrb_int len; 2852 2853 mrb_get_args(mrb, "ii", &pos, &byte); 2854 2855 len = RSTRING_LEN(str); 2856 if (pos < -len || len <= pos) 2857 mrb_raisef(mrb, E_INDEX_ERROR, "index %i out of string", pos); 2858 if (pos < 0) 2859 pos += len; 2860 2861 mrb_str_modify(mrb, mrb_str_ptr(str)); 2862 byte &= 0xff; 2863 RSTRING_PTR(str)[pos] = (unsigned char)byte; 2864 return mrb_fixnum_value((unsigned char)byte); 2865 } 2866 2867 /* 2868 * call-seq: 2869 * str.byteslice(integer) -> new_str or nil 2870 * str.byteslice(integer, integer) -> new_str or nil 2871 * str.byteslice(range) -> new_str or nil 2872 * 2873 * Byte Reference---If passed a single Integer, returns a 2874 * substring of one byte at that position. If passed two Integer 2875 * objects, returns a substring starting at the offset given by the first, and 2876 * a length given by the second. If given a Range, a substring containing 2877 * bytes at offsets given by the range is returned. In all three cases, if 2878 * an offset is negative, it is counted from the end of <i>str</i>. Returns 2879 * <code>nil</code> if the initial offset falls outside the string, the length 2880 * is negative, or the beginning of the range is greater than the end. 2881 * The encoding of the resulted string keeps original encoding. 2882 * 2883 * "hello".byteslice(1) #=> "e" 2884 * "hello".byteslice(-1) #=> "o" 2885 * "hello".byteslice(1, 2) #=> "el" 2886 * "\x80\u3042".byteslice(1, 3) #=> "\u3042" 2887 * "\x03\u3042\xff".byteslice(1..3) #=> "\u3042" 2888 */ 2889 static mrb_value 2890 mrb_str_byteslice(mrb_state *mrb, mrb_value str) 2891 { 2892 mrb_value a1, a2; 2893 mrb_int str_len = RSTRING_LEN(str), beg, len; 2894 mrb_bool empty = TRUE; 2895 2896 if (mrb_get_args(mrb, "o|o", &a1, &a2) == 2) { 2897 beg = mrb_fixnum(mrb_to_int(mrb, a1)); 2898 len = mrb_fixnum(mrb_to_int(mrb, a2)); 2899 } 2900 else if (mrb_range_p(a1)) { 2901 if (mrb_range_beg_len(mrb, a1, &beg, &len, str_len, TRUE) != MRB_RANGE_OK) { 2902 return mrb_nil_value(); 2903 } 2904 } 2905 else { 2906 beg = mrb_fixnum(mrb_to_int(mrb, a1)); 2907 len = 1; 2908 empty = FALSE; 2909 } 2910 2911 if (mrb_str_beg_len(str_len, &beg, &len) && (empty || len != 0)) { 2912 return mrb_str_byte_subseq(mrb, str, beg, len); 2913 } 2914 else { 2915 return mrb_nil_value(); 2916 } 2917 } 2918 2724 2919 /* ---------------------------*/ 2725 2920 void … … 2728 2923 struct RClass *s; 2729 2924 2730 mrb_static_assert(RSTRING_EMBED_LEN_MAX < (1 << 5), "pointer size too big for embedded string"); 2925 mrb_static_assert(RSTRING_EMBED_LEN_MAX < (1 << MRB_STR_EMBED_LEN_BIT), 2926 "pointer size too big for embedded string"); 2731 2927 2732 2928 mrb->string_class = s = mrb_define_class(mrb, "String", mrb->object_class); /* 15.2.10 */ … … 2740 2936 mrb_define_method(mrb, s, "*", mrb_str_times, MRB_ARGS_REQ(1)); /* 15.2.10.5.5 */ 2741 2937 mrb_define_method(mrb, s, "[]", mrb_str_aref_m, MRB_ARGS_ANY()); /* 15.2.10.5.6 */ 2938 mrb_define_method(mrb, s, "[]=", mrb_str_aset_m, MRB_ARGS_ANY()); 2742 2939 mrb_define_method(mrb, s, "capitalize", mrb_str_capitalize, MRB_ARGS_NONE()); /* 15.2.10.5.7 */ 2743 2940 mrb_define_method(mrb, s, "capitalize!", mrb_str_capitalize_bang, MRB_ARGS_NONE()); /* 15.2.10.5.8 */ … … 2753 2950 mrb_define_method(mrb, s, "hash", mrb_str_hash_m, MRB_ARGS_NONE()); /* 15.2.10.5.20 */ 2754 2951 mrb_define_method(mrb, s, "include?", mrb_str_include, MRB_ARGS_REQ(1)); /* 15.2.10.5.21 */ 2755 mrb_define_method(mrb, s, "index", mrb_str_index , MRB_ARGS_ANY()); /* 15.2.10.5.22 */2952 mrb_define_method(mrb, s, "index", mrb_str_index_m, MRB_ARGS_ARG(1,1)); /* 15.2.10.5.22 */ 2756 2953 mrb_define_method(mrb, s, "initialize", mrb_str_init, MRB_ARGS_REQ(1)); /* 15.2.10.5.23 */ 2757 2954 mrb_define_method(mrb, s, "initialize_copy", mrb_str_replace, MRB_ARGS_REQ(1)); /* 15.2.10.5.24 */ … … 2766 2963 mrb_define_method(mrb, s, "split", mrb_str_split_m, MRB_ARGS_ANY()); /* 15.2.10.5.35 */ 2767 2964 2965 #ifndef MRB_WITHOUT_FLOAT 2768 2966 mrb_define_method(mrb, s, "to_f", mrb_str_to_f, MRB_ARGS_NONE()); /* 15.2.10.5.38 */ 2967 #endif 2769 2968 mrb_define_method(mrb, s, "to_i", mrb_str_to_i, MRB_ARGS_ANY()); /* 15.2.10.5.39 */ 2770 2969 mrb_define_method(mrb, s, "to_s", mrb_str_to_s, MRB_ARGS_NONE()); /* 15.2.10.5.40 */ … … 2775 2974 mrb_define_method(mrb, s, "inspect", mrb_str_inspect, MRB_ARGS_NONE()); /* 15.2.10.5.46(x) */ 2776 2975 mrb_define_method(mrb, s, "bytes", mrb_str_bytes, MRB_ARGS_NONE()); 2777 } 2778 2779 /* 2780 * Source code for the "strtod" library procedure. 2976 2977 mrb_define_method(mrb, s, "getbyte", mrb_str_getbyte, MRB_ARGS_REQ(1)); 2978 mrb_define_method(mrb, s, "setbyte", mrb_str_setbyte, MRB_ARGS_REQ(2)); 2979 mrb_define_method(mrb, s, "byteslice", mrb_str_byteslice, MRB_ARGS_ARG(1,1)); 2980 } 2981 2982 #ifndef MRB_WITHOUT_FLOAT 2983 /* 2984 * Source code for the "strtod" library procedure. 2781 2985 * 2782 2986 * Copyright (c) 1988-1993 The Regents of the University of California. … … 2804 3008 static const double powersOf10[] = {/* Table giving binary powers of 10. Entry */ 2805 3009 10., /* is 10^2^i. Used to convert decimal */ 2806 100., 3010 100., /* exponents into floating-point numbers. */ 2807 3011 1.0e4, 2808 3012 1.0e8, … … 2816 3020 MRB_API double 2817 3021 mrb_float_read(const char *string, char **endPtr) 2818 /* const char *string; 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 /* char **endPtr; 2831 3022 /* const char *string; A decimal ASCII floating-point number, 3023 * optionally preceded by white space. 3024 * Must have form "-I.FE-X", where I is the 3025 * integer part of the mantissa, F is the 3026 * fractional part of the mantissa, and X 3027 * is the exponent. Either of the signs 3028 * may be "+", "-", or omitted. Either I 3029 * or F may be omitted, or both. The decimal 3030 * point isn't necessary unless F is present. 3031 * The "E" may actually be an "e". E and X 3032 * may both be omitted (but not just one). 3033 */ 3034 /* char **endPtr; If non-NULL, store terminating character's 3035 * address here. */ 2832 3036 { 2833 3037 int sign, expSign = FALSE; 2834 3038 double fraction, dblExp; 2835 3039 const double *d; 2836 registerconst char *p;2837 registerint c;2838 int exp = 0; 2839 int fracExp = 0; 2840 2841 2842 2843 2844 2845 2846 2847 2848 int mantSize; 2849 int decPt; 2850 2851 const char *pExp; 2852 3040 const char *p; 3041 int c; 3042 int exp = 0; /* Exponent read from "EX" field. */ 3043 int fracExp = 0; /* Exponent that derives from the fractional 3044 * part. Under normal circumstatnces, it is 3045 * the negative of the number of digits in F. 3046 * However, if I is very long, the last digits 3047 * of I get dropped (otherwise a long I with a 3048 * large negative exponent could cause an 3049 * unnecessary overflow on I alone). In this 3050 * case, fracExp is incremented one for each 3051 * dropped digit. */ 3052 int mantSize; /* Number of digits in mantissa. */ 3053 int decPt; /* Number of mantissa digits BEFORE decimal 3054 * point. */ 3055 const char *pExp; /* Temporarily holds location of exponent 3056 * in string. */ 2853 3057 2854 3058 /* … … 2857 3061 2858 3062 p = string; 2859 while ( isspace(*p)) {2860 3063 while (ISSPACE(*p)) { 3064 p += 1; 2861 3065 } 2862 3066 if (*p == '-') { 2863 2864 3067 sign = TRUE; 3068 p += 1; 2865 3069 } 2866 3070 else { 2867 2868 2869 2870 3071 if (*p == '+') { 3072 p += 1; 3073 } 3074 sign = FALSE; 2871 3075 } 2872 3076 … … 2879 3083 for (mantSize = 0; ; mantSize += 1) 2880 3084 { 2881 2882 if (!isdigit(c)) {2883 2884 2885 2886 2887 2888 3085 c = *p; 3086 if (!ISDIGIT(c)) { 3087 if ((c != '.') || (decPt >= 0)) { 3088 break; 3089 } 3090 decPt = mantSize; 3091 } 3092 p += 1; 2889 3093 } 2890 3094 … … 2899 3103 p -= mantSize; 2900 3104 if (decPt < 0) { 2901 3105 decPt = mantSize; 2902 3106 } 2903 3107 else { 2904 mantSize -= 1;/* One of the digits was the point. */3108 mantSize -= 1; /* One of the digits was the point. */ 2905 3109 } 2906 3110 if (mantSize > 18) { 2907 2908 2909 2910 2911 2912 2913 3111 if (decPt - 18 > 29999) { 3112 fracExp = 29999; 3113 } 3114 else { 3115 fracExp = decPt - 18; 3116 } 3117 mantSize = 18; 2914 3118 } 2915 3119 else { 2916 3120 fracExp = decPt - mantSize; 2917 3121 } 2918 3122 if (mantSize == 0) { 2919 2920 2921 3123 fraction = 0.0; 3124 p = string; 3125 goto done; 2922 3126 } 2923 3127 else { 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 3128 int frac1, frac2; 3129 frac1 = 0; 3130 for ( ; mantSize > 9; mantSize -= 1) 3131 { 3132 c = *p; 3133 p += 1; 3134 if (c == '.') { 3135 c = *p; 3136 p += 1; 3137 } 3138 frac1 = 10*frac1 + (c - '0'); 3139 } 3140 frac2 = 0; 3141 for (; mantSize > 0; mantSize -= 1) 3142 { 3143 c = *p; 3144 p += 1; 3145 if (c == '.') { 3146 c = *p; 3147 p += 1; 3148 } 3149 frac2 = 10*frac2 + (c - '0'); 3150 } 3151 fraction = (1.0e9 * frac1) + frac2; 2948 3152 } 2949 3153 … … 2954 3158 p = pExp; 2955 3159 if ((*p == 'E') || (*p == 'e')) { 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 while (isdigit(*p)) {2968 2969 2970 2971 2972 2973 3160 p += 1; 3161 if (*p == '-') { 3162 expSign = TRUE; 3163 p += 1; 3164 } 3165 else { 3166 if (*p == '+') { 3167 p += 1; 3168 } 3169 expSign = FALSE; 3170 } 3171 while (ISDIGIT(*p)) { 3172 exp = exp * 10 + (*p - '0'); 3173 if (exp > 19999) { 3174 exp = 19999; 3175 } 3176 p += 1; 3177 } 2974 3178 } 2975 3179 if (expSign) { 2976 3180 exp = fracExp - exp; 2977 3181 } 2978 3182 else { 2979 3183 exp = fracExp + exp; 2980 3184 } 2981 3185 … … 2988 3192 2989 3193 if (exp < 0) { 2990 2991 3194 expSign = TRUE; 3195 exp = -exp; 2992 3196 } 2993 3197 else { 2994 3198 expSign = FALSE; 2995 3199 } 2996 3200 if (exp > maxExponent) { 2997 2998 3201 exp = maxExponent; 3202 errno = ERANGE; 2999 3203 } 3000 3204 dblExp = 1.0; 3001 3205 for (d = powersOf10; exp != 0; exp >>= 1, d += 1) { 3002 3003 3004 3206 if (exp & 01) { 3207 dblExp *= *d; 3208 } 3005 3209 } 3006 3210 if (expSign) { 3007 3211 fraction /= dblExp; 3008 3212 } 3009 3213 else { 3010 3214 fraction *= dblExp; 3011 3215 } 3012 3216 3013 3217 done: 3014 3218 if (endPtr != NULL) { 3015 3219 *endPtr = (char *) p; 3016 3220 } 3017 3221 3018 3222 if (sign) { 3019 3223 return -fraction; 3020 3224 } 3021 3225 return fraction; 3022 3226 } 3227 #endif -
EcnlProtoTool/trunk/mruby-2.1.1/src/symbol.c
r331 r439 16 16 typedef struct symbol_name { 17 17 mrb_bool lit : 1; 18 uint8_t prev; 18 19 uint16_t len; 19 20 const char *name; 20 21 } symbol_name; 21 22 22 static inline khint_t 23 sym_hash_func(mrb_state *mrb, mrb_sym s) 24 { 25 khint_t h = 0; 26 size_t i, len = mrb->symtbl[s].len; 27 const char *p = mrb->symtbl[s].name; 28 29 for (i=0; i<len; i++) { 30 h = (h << 5) - h + *p++; 31 } 32 return h; 33 } 34 #define sym_hash_equal(mrb,a, b) (mrb->symtbl[a].len == mrb->symtbl[b].len && memcmp(mrb->symtbl[a].name, mrb->symtbl[b].name, mrb->symtbl[a].len) == 0) 35 36 KHASH_DECLARE(n2s, mrb_sym, mrb_sym, FALSE) 37 KHASH_DEFINE (n2s, mrb_sym, mrb_sym, FALSE, sym_hash_func, sym_hash_equal) 38 /* ------------------------------------------------------ */ 23 #define SYMBOL_INLINE_BIT_POS 1 24 #define SYMBOL_INLINE_LOWER_BIT_POS 2 25 #define SYMBOL_INLINE (1 << (SYMBOL_INLINE_BIT_POS - 1)) 26 #define SYMBOL_INLINE_LOWER (1 << (SYMBOL_INLINE_LOWER_BIT_POS - 1)) 27 #define SYMBOL_NORMAL_SHIFT SYMBOL_INLINE_BIT_POS 28 #define SYMBOL_INLINE_SHIFT SYMBOL_INLINE_LOWER_BIT_POS 29 #ifdef MRB_ENABLE_ALL_SYMBOLS 30 # define SYMBOL_INLINE_P(sym) FALSE 31 # define SYMBOL_INLINE_LOWER_P(sym) FALSE 32 # define sym_inline_pack(name, len) 0 33 # define sym_inline_unpack(sym, buf, lenp) NULL 34 #else 35 # define SYMBOL_INLINE_P(sym) ((sym) & SYMBOL_INLINE) 36 # define SYMBOL_INLINE_LOWER_P(sym) ((sym) & SYMBOL_INLINE_LOWER) 37 #endif 39 38 40 39 static void … … 46 45 } 47 46 47 #ifndef MRB_ENABLE_ALL_SYMBOLS 48 static const char pack_table[] = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; 49 50 static mrb_sym 51 sym_inline_pack(const char *name, size_t len) 52 { 53 const size_t lower_length_max = (MRB_SYMBOL_BIT - 2) / 5; 54 const size_t mix_length_max = (MRB_SYMBOL_BIT - 2) / 6; 55 56 char c; 57 const char *p; 58 size_t i; 59 mrb_sym sym = 0; 60 mrb_bool lower = TRUE; 61 62 if (len > lower_length_max) return 0; /* too long */ 63 for (i=0; i<len; i++) { 64 uint32_t bits; 65 66 c = name[i]; 67 if (c == 0) return 0; /* NUL in name */ 68 p = strchr(pack_table, (int)c); 69 if (p == 0) return 0; /* non alnum char */ 70 bits = (uint32_t)(p - pack_table)+1; 71 if (bits > 27) lower = FALSE; 72 if (i >= mix_length_max) break; 73 sym |= bits<<(i*6+SYMBOL_INLINE_SHIFT); 74 } 75 if (lower) { 76 sym = 0; 77 for (i=0; i<len; i++) { 78 uint32_t bits; 79 80 c = name[i]; 81 p = strchr(pack_table, (int)c); 82 bits = (uint32_t)(p - pack_table)+1; 83 sym |= bits<<(i*5+SYMBOL_INLINE_SHIFT); 84 } 85 return sym | SYMBOL_INLINE | SYMBOL_INLINE_LOWER; 86 } 87 if (len > mix_length_max) return 0; 88 return sym | SYMBOL_INLINE; 89 } 90 91 static const char* 92 sym_inline_unpack(mrb_sym sym, char *buf, mrb_int *lenp) 93 { 94 int bit_per_char = SYMBOL_INLINE_LOWER_P(sym) ? 5 : 6; 95 int i; 96 97 mrb_assert(SYMBOL_INLINE_P(sym)); 98 99 for (i=0; i<30/bit_per_char; i++) { 100 uint32_t bits = sym>>(i*bit_per_char+SYMBOL_INLINE_SHIFT) & ((1<<bit_per_char)-1); 101 if (bits == 0) break; 102 buf[i] = pack_table[bits-1];; 103 } 104 buf[i] = '\0'; 105 if (lenp) *lenp = i; 106 return buf; 107 } 108 #endif 109 110 static uint8_t 111 symhash(const char *key, size_t len) 112 { 113 uint32_t hash, i; 114 115 for(hash = i = 0; i < len; ++i) { 116 hash += key[i]; 117 hash += (hash << 10); 118 hash ^= (hash >> 6); 119 } 120 hash += (hash << 3); 121 hash ^= (hash >> 11); 122 hash += (hash << 15); 123 return hash & 0xff; 124 } 125 126 static mrb_sym 127 find_symbol(mrb_state *mrb, const char *name, size_t len, uint8_t *hashp) 128 { 129 mrb_sym i; 130 symbol_name *sname; 131 uint8_t hash; 132 133 /* inline symbol */ 134 i = sym_inline_pack(name, len); 135 if (i > 0) return i; 136 137 hash = symhash(name, len); 138 if (hashp) *hashp = hash; 139 140 i = mrb->symhash[hash]; 141 if (i == 0) return 0; 142 do { 143 sname = &mrb->symtbl[i]; 144 if (sname->len == len && memcmp(sname->name, name, len) == 0) { 145 return i<<SYMBOL_NORMAL_SHIFT; 146 } 147 if (sname->prev == 0xff) { 148 i -= 0xff; 149 sname = &mrb->symtbl[i]; 150 while (mrb->symtbl < sname) { 151 if (sname->len == len && memcmp(sname->name, name, len) == 0) { 152 return (mrb_sym)(sname - mrb->symtbl)<<SYMBOL_NORMAL_SHIFT; 153 } 154 sname--; 155 } 156 return 0; 157 } 158 i -= sname->prev; 159 } while (sname->prev > 0); 160 return 0; 161 } 162 48 163 static mrb_sym 49 164 sym_intern(mrb_state *mrb, const char *name, size_t len, mrb_bool lit) 50 165 { 51 khash_t(n2s) *h = mrb->name2sym;52 symbol_name *sname = mrb->symtbl; /* symtbl[0] for working memory */53 khiter_t k;54 166 mrb_sym sym; 55 char *p; 167 symbol_name *sname; 168 uint8_t hash; 56 169 57 170 sym_validate_len(mrb, len); 58 if (sname) { 59 sname->lit = lit; 60 sname->len = (uint16_t)len; 61 sname->name = name; 62 k = kh_get(n2s, mrb, h, 0); 63 if (k != kh_end(h)) 64 return kh_key(h, k); 65 } 171 sym = find_symbol(mrb, name, len, &hash); 172 if (sym > 0) return sym; 66 173 67 174 /* registering a new symbol */ … … 69 176 if (mrb->symcapa < sym) { 70 177 if (mrb->symcapa == 0) mrb->symcapa = 100; 71 else mrb->symcapa = (size_t)(mrb->symcapa * 1.2);178 else mrb->symcapa = (size_t)(mrb->symcapa * 6 / 5); 72 179 mrb->symtbl = (symbol_name*)mrb_realloc(mrb, mrb->symtbl, sizeof(symbol_name)*(mrb->symcapa+1)); 73 180 } … … 79 186 } 80 187 else { 81 p = (char *)mrb_malloc(mrb, len+1);188 char *p = (char *)mrb_malloc(mrb, len+1); 82 189 memcpy(p, name, len); 83 190 p[len] = 0; … … 85 192 sname->lit = FALSE; 86 193 } 87 kh_put(n2s, mrb, h, sym); 88 89 return sym; 194 if (mrb->symhash[hash]) { 195 mrb_sym i = sym - mrb->symhash[hash]; 196 if (i > 0xff) 197 sname->prev = 0xff; 198 else 199 sname->prev = i; 200 } 201 else { 202 sname->prev = 0; 203 } 204 mrb->symhash[hash] = sym; 205 206 return sym<<SYMBOL_NORMAL_SHIFT; 90 207 } 91 208 … … 117 234 mrb_check_intern(mrb_state *mrb, const char *name, size_t len) 118 235 { 119 khash_t(n2s) *h = mrb->name2sym; 120 symbol_name *sname = mrb->symtbl; 121 khiter_t k; 236 mrb_sym sym; 122 237 123 238 sym_validate_len(mrb, len); 124 sname->len = (uint16_t)len; 125 sname->name = name; 126 127 k = kh_get(n2s, mrb, h, 0); 128 if (k != kh_end(h)) { 129 return mrb_symbol_value(kh_key(h, k)); 130 } 239 sym = find_symbol(mrb, name, len, NULL); 240 if (sym > 0) return mrb_symbol_value(sym); 131 241 return mrb_nil_value(); 132 242 } … … 135 245 mrb_check_intern_cstr(mrb_state *mrb, const char *name) 136 246 { 137 return mrb_check_intern(mrb, name, (mrb_int)strlen(name));247 return mrb_check_intern(mrb, name, strlen(name)); 138 248 } 139 249 … … 144 254 } 145 255 146 /* lenp must be a pointer to a size_t variable */ 147 MRB_API const char* 148 mrb_sym2name_len(mrb_state *mrb, mrb_sym sym, mrb_int *lenp) 149 { 256 static const char* 257 sym2name_len(mrb_state *mrb, mrb_sym sym, char *buf, mrb_int *lenp) 258 { 259 if (SYMBOL_INLINE_P(sym)) return sym_inline_unpack(sym, buf, lenp); 260 261 sym >>= SYMBOL_NORMAL_SHIFT; 150 262 if (sym == 0 || mrb->symidx < sym) { 151 263 if (lenp) *lenp = 0; … … 155 267 if (lenp) *lenp = mrb->symtbl[sym].len; 156 268 return mrb->symtbl[sym].name; 269 } 270 271 MRB_API const char* 272 mrb_sym_name_len(mrb_state *mrb, mrb_sym sym, mrb_int *lenp) 273 { 274 return sym2name_len(mrb, sym, mrb->symbuf, lenp); 157 275 } 158 276 … … 168 286 } 169 287 mrb_free(mrb, mrb->symtbl); 170 kh_destroy(n2s, mrb, mrb->name2sym);171 288 } 172 289 … … 174 291 mrb_init_symtbl(mrb_state *mrb) 175 292 { 176 mrb->name2sym = kh_init(n2s, mrb);177 293 } 178 294 … … 210 326 */ 211 327 212 213 /* 15.2.11.3.1 */214 /*215 * call-seq:216 * sym == obj -> true or false217 *218 * Equality---If <i>sym</i> and <i>obj</i> are exactly the same219 * symbol, returns <code>true</code>.220 */221 222 static mrb_value223 sym_equal(mrb_state *mrb, mrb_value sym1)224 {225 mrb_value sym2;226 227 mrb_get_args(mrb, "o", &sym2);228 229 return mrb_bool_value(mrb_obj_equal(mrb, sym1, sym2));230 }231 232 328 /* 15.2.11.3.2 */ 233 329 /* 15.2.11.3.3 */ … … 242 338 */ 243 339 static mrb_value 244 mrb_sym_to_s(mrb_state *mrb, mrb_value sym) 245 { 246 mrb_sym id = mrb_symbol(sym); 247 const char *p; 248 mrb_int len; 249 250 p = mrb_sym2name_len(mrb, id, &len); 251 return mrb_str_new_static(mrb, p, len); 340 sym_to_s(mrb_state *mrb, mrb_value sym) 341 { 342 return mrb_sym_str(mrb, mrb_symbol(sym)); 252 343 } 253 344 … … 388 479 case '!': case '?': case '=': ++m; 389 480 default: break; 390 }391 481 } 482 } 392 483 break; 393 484 } … … 404 495 char *sp; 405 496 406 name = mrb_sym 2name_len(mrb, id, &len);497 name = mrb_sym_name_len(mrb, id, &len); 407 498 str = mrb_str_new(mrb, 0, len+1); 408 499 sp = RSTRING_PTR(str); 409 RSTRING_PTR(str)[0] = ':';500 sp[0] = ':'; 410 501 memcpy(sp+1, name, len); 411 502 mrb_assert_int_fit(mrb_int, len, size_t, SIZE_MAX); 412 503 if (!symname_p(name) || strlen(name) != (size_t)len) { 413 str = mrb_str_ dump(mrb, str);504 str = mrb_str_inspect(mrb, str); 414 505 sp = RSTRING_PTR(str); 415 506 sp[0] = ':'; 416 507 sp[1] = '"'; 417 508 } 509 #ifdef MRB_UTF8_STRING 510 if (SYMBOL_INLINE_P(id)) RSTR_SET_ASCII_FLAG(mrb_str_ptr(str)); 511 #endif 418 512 return str; 419 513 } 420 514 421 515 MRB_API mrb_value 422 mrb_sym 2str(mrb_state *mrb, mrb_sym sym)516 mrb_sym_str(mrb_state *mrb, mrb_sym sym) 423 517 { 424 518 mrb_int len; 425 const char *name = mrb_sym 2name_len(mrb, sym, &len);519 const char *name = mrb_sym_name_len(mrb, sym, &len); 426 520 427 521 if (!name) return mrb_undef_value(); /* can't happen */ 522 if (SYMBOL_INLINE_P(sym)) { 523 mrb_value str = mrb_str_new(mrb, name, len); 524 RSTR_SET_ASCII_FLAG(mrb_str_ptr(str)); 525 return str; 526 } 428 527 return mrb_str_new_static(mrb, name, len); 429 528 } 430 529 530 static const char* 531 sym_name(mrb_state *mrb, mrb_sym sym, mrb_bool dump) 532 { 533 mrb_int len; 534 const char *name = mrb_sym_name_len(mrb, sym, &len); 535 536 if (!name) return NULL; 537 if (strlen(name) == (size_t)len && (!dump || symname_p(name))) { 538 return name; 539 } 540 else { 541 mrb_value str = SYMBOL_INLINE_P(sym) ? 542 mrb_str_new(mrb, name, len) : mrb_str_new_static(mrb, name, len); 543 str = mrb_str_dump(mrb, str); 544 return RSTRING_PTR(str); 545 } 546 } 547 431 548 MRB_API const char* 432 mrb_sym2name(mrb_state *mrb, mrb_sym sym) 433 { 434 mrb_int len; 435 const char *name = mrb_sym2name_len(mrb, sym, &len); 436 437 if (!name) return NULL; 438 if (symname_p(name) && strlen(name) == (size_t)len) { 439 return name; 440 } 441 else { 442 mrb_value str = mrb_str_dump(mrb, mrb_str_new_static(mrb, name, len)); 443 return RSTRING_PTR(str); 444 } 549 mrb_sym_name(mrb_state *mrb, mrb_sym sym) 550 { 551 return sym_name(mrb, sym, FALSE); 552 } 553 554 MRB_API const char* 555 mrb_sym_dump(mrb_state *mrb, mrb_sym sym) 556 { 557 return sym_name(mrb, sym, TRUE); 445 558 } 446 559 … … 454 567 455 568 mrb_get_args(mrb, "o", &s2); 456 if ( mrb_type(s2) != MRB_TT_SYMBOL) return mrb_nil_value();569 if (!mrb_symbol_p(s2)) return mrb_nil_value(); 457 570 sym1 = mrb_symbol(s1); 458 571 sym2 = mrb_symbol(s2); … … 462 575 int retval; 463 576 mrb_int len, len1, len2; 464 465 p1 = mrb_sym2name_len(mrb, sym1, &len1); 466 p2 = mrb_sym2name_len(mrb, sym2, &len2); 577 char buf1[8], buf2[8]; 578 579 p1 = sym2name_len(mrb, sym1, buf1, &len1); 580 p2 = sym2name_len(mrb, sym2, buf2, &len2); 467 581 len = lesser(len1, len2); 468 582 retval = memcmp(p1, p2, len); … … 482 596 struct RClass *sym; 483 597 484 mrb->symbol_class = sym = mrb_define_class(mrb, "Symbol", mrb->object_class); 598 mrb->symbol_class = sym = mrb_define_class(mrb, "Symbol", mrb->object_class); /* 15.2.11 */ 485 599 MRB_SET_INSTANCE_TT(sym, MRB_TT_SYMBOL); 486 600 mrb_undef_class_method(mrb, sym, "new"); 487 601 488 mrb_define_method(mrb, sym, "===", sym_equal, MRB_ARGS_REQ(1)); /* 15.2.11.3.1 */ 489 mrb_define_method(mrb, sym, "id2name", mrb_sym_to_s, MRB_ARGS_NONE()); /* 15.2.11.3.2 */ 490 mrb_define_method(mrb, sym, "to_s", mrb_sym_to_s, MRB_ARGS_NONE()); /* 15.2.11.3.3 */ 491 mrb_define_method(mrb, sym, "to_sym", sym_to_sym, MRB_ARGS_NONE()); /* 15.2.11.3.4 */ 492 mrb_define_method(mrb, sym, "inspect", sym_inspect, MRB_ARGS_NONE()); /* 15.2.11.3.5(x) */ 493 mrb_define_method(mrb, sym, "<=>", sym_cmp, MRB_ARGS_REQ(1)); 494 } 602 mrb_define_method(mrb, sym, "id2name", sym_to_s, MRB_ARGS_NONE()); /* 15.2.11.3.2 */ 603 mrb_define_method(mrb, sym, "to_s", sym_to_s, MRB_ARGS_NONE()); /* 15.2.11.3.3 */ 604 mrb_define_method(mrb, sym, "to_sym", sym_to_sym, MRB_ARGS_NONE()); /* 15.2.11.3.4 */ 605 mrb_define_method(mrb, sym, "inspect", sym_inspect, MRB_ARGS_NONE()); /* 15.2.11.3.5(x) */ 606 mrb_define_method(mrb, sym, "<=>", sym_cmp, MRB_ARGS_REQ(1)); 607 } -
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 } -
EcnlProtoTool/trunk/mruby-2.1.1/src/vm.c
r331 r439 7 7 #include <stddef.h> 8 8 #include <stdarg.h> 9 #ifndef MRB_WITHOUT_FLOAT 9 10 #include <math.h> 11 #endif 10 12 #include <mruby.h> 11 13 #include <mruby/array.h> … … 23 25 #include <mruby/throw.h> 24 26 25 #if ndef MRB_DISABLE_STDIO27 #ifdef MRB_DISABLE_STDIO 26 28 #if defined(__cplusplus) 27 29 extern "C" { … … 52 54 #ifndef MRB_FUNCALL_DEPTH_MAX 53 55 #define MRB_FUNCALL_DEPTH_MAX 512 56 #endif 57 58 /* Maximum depth of ecall() recursion. */ 59 #ifndef MRB_ECALL_DEPTH_MAX 60 #define MRB_ECALL_DEPTH_MAX 512 54 61 #endif 55 62 … … 66 73 #endif 67 74 68 #define ARENA_RESTORE(mrb,ai) (mrb)->gc.arena_idx = (ai) 75 76 #ifndef MRB_GC_FIXED_ARENA 77 static void 78 mrb_gc_arena_shrink(mrb_state *mrb, int idx) 79 { 80 mrb_gc *gc = &mrb->gc; 81 int capa = gc->arena_capa; 82 83 if (idx < capa / 4) { 84 capa >>= 2; 85 if (capa < MRB_GC_ARENA_SIZE) { 86 capa = MRB_GC_ARENA_SIZE; 87 } 88 if (capa != gc->arena_capa) { 89 gc->arena = (struct RBasic**)mrb_realloc(mrb, gc->arena, sizeof(struct RBasic*)*capa); 90 gc->arena_capa = capa; 91 } 92 } 93 } 94 #else 95 #define mrb_gc_arena_shrink(mrb,idx) 96 #endif 69 97 70 98 #define CALL_MAXARGS 127 … … 116 144 117 145 static inline void 118 envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase, size_t size)146 envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase, size_t oldsize) 119 147 { 120 148 mrb_callinfo *ci = mrb->c->cibase; … … 126 154 127 155 if (e && MRB_ENV_STACK_SHARED_P(e) && 128 (st = e->stack) && oldbase <= st && st < oldbase+ size) {156 (st = e->stack) && oldbase <= st && st < oldbase+oldsize) { 129 157 ptrdiff_t off = e->stack - oldbase; 130 158 131 159 e->stack = newbase + off; 132 160 } 161 162 if (ci->proc && MRB_PROC_ENV_P(ci->proc) && ci->env != MRB_PROC_ENV(ci->proc)) { 163 e = MRB_PROC_ENV(ci->proc); 164 165 if (e && MRB_ENV_STACK_SHARED_P(e) && 166 (st = e->stack) && oldbase <= st && st < oldbase+oldsize) { 167 ptrdiff_t off = e->stack - oldbase; 168 169 e->stack = newbase + off; 170 } 171 } 172 133 173 ci->stackent = newbase + (ci->stackent - oldbase); 134 174 ci++; … … 139 179 140 180 static void 141 stack_extend_alloc(mrb_state *mrb, int room)181 stack_extend_alloc(mrb_state *mrb, mrb_int room) 142 182 { 143 183 mrb_value *oldbase = mrb->c->stbase; … … 149 189 if (off > size) size = off; 150 190 #ifdef MRB_STACK_EXTEND_DOUBLING 151 if ( room <= size)191 if ((size_t)room <= size) 152 192 size *= 2; 153 193 else … … 168 208 } 169 209 stack_clear(&(newstack[oldsize]), size - oldsize); 170 envadjust(mrb, oldbase, newstack, size);210 envadjust(mrb, oldbase, newstack, oldsize); 171 211 mrb->c->stbase = newstack; 172 212 mrb->c->stack = mrb->c->stbase + off; … … 180 220 } 181 221 182 static inlinevoid183 stack_extend(mrb_state *mrb,int room)222 MRB_API void 223 mrb_stack_extend(mrb_state *mrb, mrb_int room) 184 224 { 185 225 if (mrb->c->stack + room >= mrb->c->stend) { … … 191 231 uvenv(mrb_state *mrb, int up) 192 232 { 193 struct REnv *e = mrb->c->ci->proc->env; 233 struct RProc *proc = mrb->c->ci->proc; 234 struct REnv *e; 194 235 195 236 while (up--) { 196 if (!e) return NULL; 197 e = (struct REnv*)e->c; 198 } 199 return e; 200 } 201 202 static inline mrb_bool 203 is_strict(mrb_state *mrb, struct REnv *e) 204 { 205 int cioff = e->cioff; 206 207 if (MRB_ENV_STACK_SHARED_P(e) && e->cxt.c->cibase[cioff].proc && 208 MRB_PROC_STRICT_P(e->cxt.c->cibase[cioff].proc)) { 209 return TRUE; 210 } 211 return FALSE; 212 } 213 214 static inline struct REnv* 215 top_env(mrb_state *mrb, struct RProc *proc) 216 { 217 struct REnv *e = proc->env; 218 219 if (is_strict(mrb, e)) return e; 220 while (e->c) { 221 e = (struct REnv*)e->c; 222 if (is_strict(mrb, e)) return e; 223 } 224 return e; 237 proc = proc->upper; 238 if (!proc) return NULL; 239 } 240 e = MRB_PROC_ENV(proc); 241 if (e) return e; /* proc has enclosed env */ 242 else { 243 mrb_callinfo *ci = mrb->c->ci; 244 mrb_callinfo *cb = mrb->c->cibase; 245 246 while (cb <= ci) { 247 if (ci->proc == proc) { 248 return ci->env; 249 } 250 ci--; 251 } 252 } 253 return NULL; 254 } 255 256 static inline struct RProc* 257 top_proc(mrb_state *mrb, struct RProc *proc) 258 { 259 while (proc->upper) { 260 if (MRB_PROC_SCOPE_P(proc) || MRB_PROC_STRICT_P(proc)) 261 return proc; 262 proc = proc->upper; 263 } 264 return proc; 225 265 } 226 266 … … 229 269 #define CI_ACC_RESUMED -3 230 270 231 static mrb_callinfo*271 static inline mrb_callinfo* 232 272 cipush(mrb_state *mrb) 233 273 { 234 274 struct mrb_context *c = mrb->c; 275 static const mrb_callinfo ci_zero = { 0 }; 235 276 mrb_callinfo *ci = c->ci; 236 277 … … 245 286 } 246 287 ci = ++c->ci; 288 *ci = ci_zero; 247 289 ci->epos = mrb->c->eidx; 248 290 ci->ridx = ridx; 249 ci->env = 0;250 ci->pc = 0;251 ci->err = 0;252 ci->proc = 0;253 ci->acc = 0;254 291 255 292 return ci; 256 293 } 257 294 258 MRB_APIvoid295 void 259 296 mrb_env_unshare(mrb_state *mrb, struct REnv *e) 260 297 { 261 size_t len = (size_t)MRB_ENV_STACK_LEN(e); 262 ptrdiff_t cioff = e->cioff; 263 mrb_value *p; 264 265 if (!MRB_ENV_STACK_SHARED_P(e)) return; 266 if (e->cxt.c != mrb->c) return; 267 if (e->cioff == 0 && e->cxt.c == mrb->root_c) return; 268 MRB_ENV_UNSHARE_STACK(e); 269 if (!e->c) { 270 /* save block argument position (negated) */ 271 e->cioff = -e->cxt.c->cibase[cioff].argc-1; 272 } 273 e->cxt.mid = e->cxt.c->cibase[cioff].mid; 274 p = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value)*len); 275 if (len > 0) { 276 stack_copy(p, e->stack, len); 277 } 278 e->stack = p; 279 mrb_write_barrier(mrb, (struct RBasic *)e); 280 } 281 282 static void 298 if (e == NULL) return; 299 else { 300 size_t len = (size_t)MRB_ENV_STACK_LEN(e); 301 mrb_value *p; 302 303 if (!MRB_ENV_STACK_SHARED_P(e)) return; 304 if (e->cxt != mrb->c) return; 305 if (e == mrb->c->cibase->env) return; /* for mirb */ 306 p = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value)*len); 307 if (len > 0) { 308 stack_copy(p, e->stack, len); 309 } 310 e->stack = p; 311 MRB_ENV_UNSHARE_STACK(e); 312 mrb_write_barrier(mrb, (struct RBasic *)e); 313 } 314 } 315 316 static inline void 283 317 cipop(mrb_state *mrb) 284 318 { … … 287 321 288 322 c->ci--; 289 290 if (env) { 291 mrb_env_unshare(mrb, env); 292 } 323 if (env) mrb_env_unshare(mrb, env); 293 324 } 294 325 … … 296 327 297 328 static void 298 ecall(mrb_state *mrb , int i)329 ecall(mrb_state *mrb) 299 330 { 300 331 struct RProc *p; 301 mrb_callinfo *ci = mrb->c->ci;302 mrb_ value *self = mrb->c->stack;332 struct mrb_context *c = mrb->c; 333 mrb_callinfo *ci = c->ci; 303 334 struct RObject *exc; 335 struct REnv *env; 304 336 ptrdiff_t cioff; 305 337 int ai = mrb_gc_arena_save(mrb); 338 uint16_t i = --c->eidx; 339 int nregs; 306 340 307 341 if (i<0) return; 308 if (ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) { 342 /* restrict total call depth of ecall() */ 343 if (++mrb->ecall_nest > MRB_ECALL_DEPTH_MAX) { 309 344 mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err)); 310 345 } 311 p = mrb->c->ensure[i];346 p = c->ensure[i]; 312 347 if (!p) return; 313 mrb->c->ensure[i] = NULL; 314 cioff = ci - mrb->c->cibase; 348 mrb_assert(!MRB_PROC_CFUNC_P(p)); 349 c->ensure[i] = NULL; 350 nregs = p->upper->body.irep->nregs; 351 if (ci->proc && !MRB_PROC_CFUNC_P(ci->proc) && 352 ci->proc->body.irep->nregs > nregs) { 353 nregs = ci->proc->body.irep->nregs; 354 } 355 cioff = ci - c->cibase; 315 356 ci = cipush(mrb); 316 357 ci->stackent = mrb->c->stack; … … 319 360 ci->argc = 0; 320 361 ci->proc = p; 321 ci->nregs = p->body.irep->nregs; 322 ci->target_class = p->target_class; 323 mrb->c->stack = mrb->c->stack + ci[-1].nregs; 362 ci->target_class = MRB_PROC_TARGET_CLASS(p); 363 env = MRB_PROC_ENV(p); 364 mrb_assert(env); 365 c->stack += nregs; 324 366 exc = mrb->exc; mrb->exc = 0; 325 367 if (exc) { 326 368 mrb_gc_protect(mrb, mrb_obj_value(exc)); 327 369 } 328 mrb_run(mrb, p, *self); 329 mrb->c->ci = mrb->c->cibase + cioff; 370 if (mrb->c->fib) { 371 mrb_gc_protect(mrb, mrb_obj_value(mrb->c->fib)); 372 } 373 mrb_run(mrb, p, env->stack[0]); 374 mrb->c = c; 375 c->ci = c->cibase + cioff; 330 376 if (!mrb->exc) mrb->exc = exc; 331 377 mrb_gc_arena_restore(mrb, ai); 378 mrb->ecall_nest--; 332 379 } 333 380 … … 356 403 } 357 404 405 static int 406 ci_nregs(mrb_callinfo *ci) 407 { 408 struct RProc *p; 409 int n = 0; 410 411 if (!ci) return 3; 412 p = ci->proc; 413 if (!p) { 414 if (ci->argc < 0) return 3; 415 return ci->argc+2; 416 } 417 if (!MRB_PROC_CFUNC_P(p) && p->body.irep) { 418 n = p->body.irep->nregs; 419 } 420 if (ci->argc < 0) { 421 if (n < 3) n = 3; /* self + args + blk */ 422 } 423 if (ci->argc > n) { 424 n = ci->argc + 2; /* self + blk */ 425 } 426 return n; 427 } 428 358 429 MRB_API mrb_value 359 430 mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc, const mrb_value *argv, mrb_value blk) 360 431 { 361 432 mrb_value val; 433 int ai = mrb_gc_arena_save(mrb); 362 434 363 435 if (!mrb->jmp) { … … 383 455 } 384 456 else { 385 struct RProc *p;457 mrb_method_t m; 386 458 struct RClass *c; 387 459 mrb_callinfo *ci; 388 int n ;460 int n = ci_nregs(mrb->c->ci); 389 461 ptrdiff_t voff = -1; 390 462 … … 392 464 stack_init(mrb); 393 465 } 394 n = mrb->c->ci->nregs;395 466 if (argc < 0) { 396 mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative argc for funcall (% S)", mrb_fixnum_value(argc));467 mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative argc for funcall (%i)", argc); 397 468 } 398 469 c = mrb_class(mrb, self); 399 p= mrb_method_search_vm(mrb, &c, mid);400 if ( !p) {470 m = mrb_method_search_vm(mrb, &c, mid); 471 if (MRB_METHOD_UNDEF_P(m)) { 401 472 mrb_sym missing = mrb_intern_lit(mrb, "method_missing"); 402 473 mrb_value args = mrb_ary_new_from_values(mrb, argc, argv); 403 p= mrb_method_search_vm(mrb, &c, missing);404 if ( !p) {474 m = mrb_method_search_vm(mrb, &c, missing); 475 if (MRB_METHOD_UNDEF_P(m)) { 405 476 mrb_method_missing(mrb, mid, self, args); 406 477 } 407 478 mrb_ary_unshift(mrb, args, mrb_symbol_value(mid)); 408 stack_extend(mrb, n+2);479 mrb_stack_extend(mrb, n+2); 409 480 mrb->c->stack[n+1] = args; 410 481 argc = -1; … … 415 486 ci = cipush(mrb); 416 487 ci->mid = mid; 417 ci->proc = p;418 488 ci->stackent = mrb->c->stack; 419 ci->argc = argc;489 ci->argc = (int)argc; 420 490 ci->target_class = c; 421 491 mrb->c->stack = mrb->c->stack + n; 492 if (argc < 0) argc = 1; 422 493 if (mrb->c->stbase <= argv && argv < mrb->c->stend) { 423 494 voff = argv - mrb->c->stbase; 424 495 } 425 if (MRB_PROC_CFUNC_P(p)) { 426 ci->nregs = argc + 2; 427 stack_extend(mrb, ci->nregs); 428 } 429 else if (argc >= CALL_MAXARGS) { 496 if (argc >= CALL_MAXARGS) { 430 497 mrb_value args = mrb_ary_new_from_values(mrb, argc, argv); 431 stack_extend(mrb, ci->nregs); 498 432 499 mrb->c->stack[1] = args; 433 500 ci->argc = -1; 434 501 argc = 1; 435 502 } 436 else { 437 if (argc < 0) argc = 1; 438 ci->nregs = p->body.irep->nregs + argc; 439 stack_extend(mrb, ci->nregs); 503 mrb_stack_extend(mrb, argc + 2); 504 if (MRB_METHOD_PROC_P(m)) { 505 struct RProc *p = MRB_METHOD_PROC(m); 506 507 ci->proc = p; 508 if (!MRB_PROC_CFUNC_P(p)) { 509 mrb_stack_extend(mrb, p->body.irep->nregs + argc); 510 } 440 511 } 441 512 if (voff >= 0) { … … 448 519 mrb->c->stack[argc+1] = blk; 449 520 450 if (MRB_PROC_CFUNC_P(p)) { 451 int ai = mrb_gc_arena_save(mrb); 452 521 if (MRB_METHOD_CFUNC_P(m)) { 453 522 ci->acc = CI_ACC_DIRECT; 454 val = p->body.func(mrb, self);523 val = MRB_METHOD_CFUNC(m)(mrb, self); 455 524 mrb->c->stack = mrb->c->ci->stackent; 456 525 cipop(mrb); 457 mrb_gc_arena_restore(mrb, ai);458 526 } 459 527 else { 460 528 ci->acc = CI_ACC_SKIP; 461 val = mrb_run(mrb, p, self); 462 } 463 } 529 val = mrb_run(mrb, MRB_METHOD_PROC(m), self); 530 } 531 } 532 mrb_gc_arena_restore(mrb, ai); 464 533 mrb_gc_protect(mrb, val); 465 534 return val; … … 476 545 { 477 546 mrb_callinfo *ci = mrb->c->ci; 547 int keep, nregs; 478 548 479 549 mrb->c->stack[0] = self; 480 550 ci->proc = p; 481 ci->target_class = p->target_class;482 551 if (MRB_PROC_CFUNC_P(p)) { 483 return p->body.func(mrb, self); 484 } 485 if (ci->argc < 0) { 486 stack_extend(mrb, (p->body.irep->nregs < 3) ? 3 : p->body.irep->nregs); 552 return MRB_PROC_CFUNC(p)(mrb, self); 553 } 554 nregs = p->body.irep->nregs; 555 if (ci->argc < 0) keep = 3; 556 else keep = ci->argc + 2; 557 if (nregs < keep) { 558 mrb_stack_extend(mrb, keep); 487 559 } 488 560 else { 489 stack_extend(mrb, p->body.irep->nregs);490 }491 492 ci->nregs = p->body.irep->nregs; 561 mrb_stack_extend(mrb, nregs); 562 stack_clear(mrb->c->stack+keep, nregs-keep); 563 } 564 493 565 ci = cipush(mrb); 494 ci->nregs = 0;495 566 ci->target_class = 0; 496 567 ci->pc = p->body.irep->iseq; … … 520 591 * k.send :hello, "gentle", "readers" #=> "Hello gentle readers" 521 592 */ 522 MRB_APImrb_value593 mrb_value 523 594 mrb_f_send(mrb_state *mrb, mrb_value self) 524 595 { … … 526 597 mrb_value block, *argv, *regs; 527 598 mrb_int argc, i, len; 528 struct RProc *p;599 mrb_method_t m; 529 600 struct RClass *c; 530 601 mrb_callinfo *ci; … … 538 609 539 610 c = mrb_class(mrb, self); 540 p = mrb_method_search_vm(mrb, &c, name); 541 542 if (!p) { /* call method_mising */ 611 m = mrb_method_search_vm(mrb, &c, name); 612 if (MRB_METHOD_UNDEF_P(m)) { /* call method_mising */ 543 613 goto funcall; 544 614 } … … 558 628 } 559 629 560 return mrb_exec_irep(mrb, self, p); 630 if (MRB_METHOD_CFUNC_P(m)) { 631 if (MRB_METHOD_PROC_P(m)) { 632 ci->proc = MRB_METHOD_PROC(m); 633 } 634 return MRB_METHOD_CFUNC(m)(mrb, self); 635 } 636 return mrb_exec_irep(mrb, self, MRB_METHOD_PROC(m)); 561 637 } 562 638 … … 566 642 struct RProc *p; 567 643 mrb_callinfo *ci; 568 mrb_int max = 3;644 int nregs; 569 645 570 646 if (mrb_nil_p(blk)) { … … 582 658 ci->mid = ci[-1].mid; 583 659 if (MRB_PROC_CFUNC_P(p)) { 584 stack_extend(mrb, 3);660 mrb_stack_extend(mrb, 3); 585 661 mrb->c->stack[0] = self; 586 662 mrb->c->stack[1] = self; 587 663 mrb->c->stack[2] = mrb_nil_value(); 588 return p->body.func(mrb, self);589 } 590 ci->nregs = p->body.irep->nregs;591 if ( max < ci->nregs) max = ci->nregs;592 stack_extend(mrb, max);664 return MRB_PROC_CFUNC(p)(mrb, self); 665 } 666 nregs = p->body.irep->nregs; 667 if (nregs < 3) nregs = 3; 668 mrb_stack_extend(mrb, nregs); 593 669 mrb->c->stack[0] = self; 594 670 mrb->c->stack[1] = self; 595 mrb->c->stack[2] = mrb_nil_value();671 stack_clear(mrb->c->stack+2, nregs-2); 596 672 ci = cipush(mrb); 597 ci->nregs = 0;598 673 ci->target_class = 0; 599 674 ci->pc = p->body.irep->iseq; … … 659 734 case MRB_TT_SYMBOL: 660 735 case MRB_TT_FIXNUM: 736 #ifndef MRB_WITHOUT_FLOAT 661 737 case MRB_TT_FLOAT: 738 #endif 662 739 c = 0; 663 740 break; … … 676 753 mrb_sym mid = mrb->c->ci->mid; 677 754 mrb_callinfo *ci; 678 int n = mrb->c->ci->nregs;679 755 mrb_value val; 756 int n; 680 757 681 758 if (mrb_nil_p(b)) { 682 759 mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given"); 683 760 } 684 if (mrb->c->ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) { 761 ci = mrb->c->ci; 762 n = ci_nregs(ci); 763 if (ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) { 685 764 mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err)); 686 765 } … … 690 769 ci->proc = p; 691 770 ci->stackent = mrb->c->stack; 692 ci->argc = argc;771 ci->argc = (int)argc; 693 772 ci->target_class = c; 694 773 ci->acc = CI_ACC_SKIP; 774 n = MRB_PROC_CFUNC_P(p) ? (int)(argc+2) : p->body.irep->nregs; 695 775 mrb->c->stack = mrb->c->stack + n; 696 if (MRB_PROC_CFUNC_P(p)) { 697 ci->nregs = argc + 2; 698 stack_extend(mrb, ci->nregs); 699 } 700 else { 701 ci->nregs = p->body.irep->nregs; 702 stack_extend(mrb, ci->nregs); 703 } 776 mrb_stack_extend(mrb, n); 704 777 705 778 mrb->c->stack[0] = self; … … 710 783 711 784 if (MRB_PROC_CFUNC_P(p)) { 712 val = p->body.func(mrb, self);785 val = MRB_PROC_CFUNC(p)(mrb, self); 713 786 mrb->c->stack = mrb->c->ci->stackent; 787 cipop(mrb); 714 788 } 715 789 else { 716 int cioff = mrb->c->ci - mrb->c->cibase;717 790 val = mrb_run(mrb, p, self); 718 mrb->c->ci = mrb->c->cibase + cioff; 719 } 720 cipop(mrb); 791 } 721 792 return val; 722 793 } … … 727 798 struct RProc *p = mrb_proc_ptr(b); 728 799 729 return mrb_yield_with_class(mrb, b, argc, argv, p->env->stack[0], p->target_class);800 return mrb_yield_with_class(mrb, b, argc, argv, MRB_PROC_ENV(p)->stack[0], MRB_PROC_TARGET_CLASS(p)); 730 801 } 731 802 … … 735 806 struct RProc *p = mrb_proc_ptr(b); 736 807 737 return mrb_yield_with_class(mrb, b, 1, &arg, p->env->stack[0], p->target_class);808 return mrb_yield_with_class(mrb, b, 1, &arg, MRB_PROC_ENV(p)->stack[0], MRB_PROC_TARGET_CLASS(p)); 738 809 } 739 810 … … 747 818 mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given"); 748 819 } 749 if ( mrb_type(b) != MRB_TT_PROC) {820 if (!mrb_proc_p(b)) { 750 821 mrb_raise(mrb, E_TYPE_ERROR, "not a block"); 751 822 } … … 754 825 ci = mrb->c->ci; 755 826 756 stack_extend(mrb, 3);827 mrb_stack_extend(mrb, 3); 757 828 mrb->c->stack[1] = mrb_ary_new_from_values(mrb, argc, argv); 758 829 mrb->c->stack[2] = mrb_nil_value(); … … 767 838 768 839 brk = (struct RBreak*)mrb_obj_alloc(mrb, MRB_TT_BREAK, NULL); 769 brk->iv = NULL; 770 brk->proc = p; 771 brk->val = val; 840 mrb_break_proc_set(brk, p); 841 mrb_break_value_set(brk, val); 772 842 773 843 return brk; … … 789 859 mrb_value exc; 790 860 791 msg = mrb_str_ buf_new(mrb, sizeof(lead) + 7);861 msg = mrb_str_new_capa(mrb, sizeof(lead) + 7); 792 862 mrb_str_cat(mrb, msg, lead, sizeof(lead) - 1); 793 863 mrb_str_cat(mrb, msg, kind_str[kind], kind_str_len[kind]); … … 810 880 } 811 881 if (mrb->c->ci->mid) { 812 str = mrb_format(mrb, "'%S': wrong number of arguments (%S for %S)", 813 mrb_sym2str(mrb, mrb->c->ci->mid), 814 mrb_fixnum_value(argc), mrb_fixnum_value(num)); 882 str = mrb_format(mrb, "'%n': wrong number of arguments (%i for %i)", 883 mrb->c->ci->mid, argc, num); 815 884 } 816 885 else { 817 str = mrb_format(mrb, "wrong number of arguments (%S for %S)", 818 mrb_fixnum_value(argc), mrb_fixnum_value(num)); 886 str = mrb_format(mrb, "wrong number of arguments (%i for %i)", argc, num); 819 887 } 820 888 exc = mrb_exc_new_str(mrb, E_ARGUMENT_ERROR, str); … … 822 890 } 823 891 824 #define ERR_PC_SET(mrb , pc) mrb->c->ci->err = pc;825 #define ERR_PC_CLR(mrb) 892 #define ERR_PC_SET(mrb) mrb->c->ci->err = pc0; 893 #define ERR_PC_CLR(mrb) mrb->c->ci->err = 0; 826 894 #ifdef MRB_ENABLE_DEBUG_HOOK 827 895 #define CODE_FETCH_HOOK(mrb, irep, pc, regs) if ((mrb)->code_fetch_hook) (mrb)->code_fetch_hook((mrb), (irep), (pc), (regs)); … … 836 904 #endif 837 905 838 906 #ifndef MRB_DISABLE_DIRECT_THREADING 839 907 #if defined __GNUC__ || defined __clang__ || defined __INTEL_COMPILER 840 908 #define DIRECT_THREADED 841 909 #endif 910 #endif /* ifndef MRB_DISABLE_DIRECT_THREADING */ 842 911 843 912 #ifndef DIRECT_THREADED 844 913 845 #define INIT_DISPATCH for (;;) { i = BYTECODE_DECODER(*pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); switch (GET_OPCODE(i)) {846 #define CASE( op) case op:847 #define NEXT pc++;break848 #define JUMP break914 #define INIT_DISPATCH for (;;) { insn = BYTECODE_DECODER(*pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); switch (insn) { 915 #define CASE(insn,ops) case insn: pc0=pc++; FETCH_ ## ops ();; L_ ## insn ## _BODY: 916 #define NEXT break 917 #define JUMP NEXT 849 918 #define END_DISPATCH }} 850 919 … … 852 921 853 922 #define INIT_DISPATCH JUMP; return mrb_nil_value(); 854 #define CASE( op) L_ ## op:855 #define NEXT i =BYTECODE_DECODER(*++pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); goto *optable[GET_OPCODE(i)]856 #define JUMP i=BYTECODE_DECODER(*pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); goto *optable[GET_OPCODE(i)]923 #define CASE(insn,ops) L_ ## insn: pc0=pc++; FETCH_ ## ops (); L_ ## insn ## _BODY: 924 #define NEXT insn=BYTECODE_DECODER(*pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); goto *optable[insn] 925 #define JUMP NEXT 857 926 858 927 #define END_DISPATCH … … 866 935 mrb_value result; 867 936 struct mrb_context *c = mrb->c; 868 int cioff = c->ci - c->cibase;937 ptrdiff_t cioff = c->ci - c->cibase; 869 938 unsigned int nregs = irep->nregs; 870 939 … … 874 943 if (stack_keep > nregs) 875 944 nregs = stack_keep; 876 stack_extend(mrb, nregs);945 mrb_stack_extend(mrb, nregs); 877 946 stack_clear(c->stack + stack_keep, nregs - stack_keep); 878 947 c->stack[0] = self; 879 948 result = mrb_vm_exec(mrb, proc, irep->iseq); 880 if (c->ci - c->cibase > cioff) {881 c->ci = c->cibase + cioff;882 }883 949 if (mrb->c != c) { 884 950 if (mrb->c->fib) { … … 887 953 mrb->c = c; 888 954 } 955 else if (c->ci - c->cibase > cioff) { 956 c->ci = c->cibase + cioff; 957 } 889 958 return result; 890 959 } 891 960 961 static mrb_bool 962 check_target_class(mrb_state *mrb) 963 { 964 if (!mrb->c->ci->target_class) { 965 mrb_value exc = mrb_exc_new_str_lit(mrb, E_TYPE_ERROR, "no target class or module"); 966 mrb_exc_set(mrb, exc); 967 return FALSE; 968 } 969 return TRUE; 970 } 971 972 void mrb_hash_check_kdict(mrb_state *mrb, mrb_value self); 973 892 974 MRB_API mrb_value 893 mrb_vm_exec(mrb_state *mrb, struct RProc *proc, mrb_code *pc) 894 { 895 /* mrb_assert(mrb_proc_cfunc_p(proc)) */ 975 mrb_vm_exec(mrb_state *mrb, struct RProc *proc, const mrb_code *pc) 976 { 977 /* mrb_assert(MRB_PROC_CFUNC_P(proc)) */ 978 const mrb_code *pc0 = pc; 896 979 mrb_irep *irep = proc->body.irep; 897 980 mrb_value *pool = irep->pool; 898 981 mrb_sym *syms = irep->syms; 899 mrb_code i ;982 mrb_code insn; 900 983 int ai = mrb_gc_arena_save(mrb); 901 984 struct mrb_jmpbuf *prev_jmp = mrb->jmp; 902 985 struct mrb_jmpbuf c_jmp; 986 uint32_t a; 987 uint16_t b; 988 uint8_t c; 989 mrb_sym mid; 903 990 904 991 #ifdef DIRECT_THREADED 905 992 static void *optable[] = { 906 &&L_OP_NOP, &&L_OP_MOVE, 907 &&L_OP_LOADL, &&L_OP_LOADI, &&L_OP_LOADSYM, &&L_OP_LOADNIL, 908 &&L_OP_LOADSELF, &&L_OP_LOADT, &&L_OP_LOADF, 909 &&L_OP_GETGLOBAL, &&L_OP_SETGLOBAL, &&L_OP_GETSPECIAL, &&L_OP_SETSPECIAL, 910 &&L_OP_GETIV, &&L_OP_SETIV, &&L_OP_GETCV, &&L_OP_SETCV, 911 &&L_OP_GETCONST, &&L_OP_SETCONST, &&L_OP_GETMCNST, &&L_OP_SETMCNST, 912 &&L_OP_GETUPVAR, &&L_OP_SETUPVAR, 913 &&L_OP_JMP, &&L_OP_JMPIF, &&L_OP_JMPNOT, 914 &&L_OP_ONERR, &&L_OP_RESCUE, &&L_OP_POPERR, &&L_OP_RAISE, &&L_OP_EPUSH, &&L_OP_EPOP, 915 &&L_OP_SEND, &&L_OP_SENDB, &&L_OP_FSEND, 916 &&L_OP_CALL, &&L_OP_SUPER, &&L_OP_ARGARY, &&L_OP_ENTER, 917 &&L_OP_KARG, &&L_OP_KDICT, &&L_OP_RETURN, &&L_OP_TAILCALL, &&L_OP_BLKPUSH, 918 &&L_OP_ADD, &&L_OP_ADDI, &&L_OP_SUB, &&L_OP_SUBI, &&L_OP_MUL, &&L_OP_DIV, 919 &&L_OP_EQ, &&L_OP_LT, &&L_OP_LE, &&L_OP_GT, &&L_OP_GE, 920 &&L_OP_ARRAY, &&L_OP_ARYCAT, &&L_OP_ARYPUSH, &&L_OP_AREF, &&L_OP_ASET, &&L_OP_APOST, 921 &&L_OP_STRING, &&L_OP_STRCAT, &&L_OP_HASH, 922 &&L_OP_LAMBDA, &&L_OP_RANGE, &&L_OP_OCLASS, 923 &&L_OP_CLASS, &&L_OP_MODULE, &&L_OP_EXEC, 924 &&L_OP_METHOD, &&L_OP_SCLASS, &&L_OP_TCLASS, 925 &&L_OP_DEBUG, &&L_OP_STOP, &&L_OP_ERR, 993 #define OPCODE(x,_) &&L_OP_ ## x, 994 #include "mruby/ops.h" 995 #undef OPCODE 926 996 }; 927 997 #endif … … 934 1004 if (exc_catched) { 935 1005 exc_catched = FALSE; 1006 mrb_gc_arena_restore(mrb, ai); 936 1007 if (mrb->exc && mrb->exc->tt == MRB_TT_BREAK) 937 1008 goto L_BREAK; … … 940 1011 mrb->jmp = &c_jmp; 941 1012 mrb->c->ci->proc = proc; 942 mrb->c->ci->nregs = irep->nregs;943 1013 944 1014 #define regs (mrb->c->stack) 945 1015 INIT_DISPATCH { 946 CASE(OP_NOP ) {1016 CASE(OP_NOP, Z) { 947 1017 /* do nothing */ 948 1018 NEXT; 949 1019 } 950 1020 951 CASE(OP_MOVE) { 952 /* A B R(A) := R(B) */ 953 int a = GETARG_A(i); 954 int b = GETARG_B(i); 1021 CASE(OP_MOVE, BB) { 955 1022 regs[a] = regs[b]; 956 1023 NEXT; 957 1024 } 958 1025 959 CASE(OP_LOADL) { 960 /* A Bx R(A) := Pool(Bx) */ 961 int a = GETARG_A(i); 962 int bx = GETARG_Bx(i); 1026 CASE(OP_LOADL, BB) { 963 1027 #ifdef MRB_WORD_BOXING 964 mrb_value val = pool[bx]; 1028 mrb_value val = pool[b]; 1029 #ifndef MRB_WITHOUT_FLOAT 965 1030 if (mrb_float_p(val)) { 966 1031 val = mrb_float_value(mrb, mrb_float(val)); 967 1032 } 1033 #endif 968 1034 regs[a] = val; 969 1035 #else 970 regs[a] = pool[bx]; 971 #endif 972 NEXT; 973 } 974 975 CASE(OP_LOADI) { 976 /* A sBx R(A) := sBx */ 977 SET_INT_VALUE(regs[GETARG_A(i)], GETARG_sBx(i)); 978 NEXT; 979 } 980 981 CASE(OP_LOADSYM) { 982 /* A Bx R(A) := Syms(Bx) */ 983 int a = GETARG_A(i); 984 int bx = GETARG_Bx(i); 985 SET_SYM_VALUE(regs[a], syms[bx]); 986 NEXT; 987 } 988 989 CASE(OP_LOADSELF) { 990 /* A R(A) := self */ 991 int a = GETARG_A(i); 1036 regs[a] = pool[b]; 1037 #endif 1038 NEXT; 1039 } 1040 1041 CASE(OP_LOADI, BB) { 1042 SET_INT_VALUE(regs[a], b); 1043 NEXT; 1044 } 1045 1046 CASE(OP_LOADINEG, BB) { 1047 SET_INT_VALUE(regs[a], -b); 1048 NEXT; 1049 } 1050 1051 CASE(OP_LOADI__1,B) goto L_LOADI; 1052 CASE(OP_LOADI_0,B) goto L_LOADI; 1053 CASE(OP_LOADI_1,B) goto L_LOADI; 1054 CASE(OP_LOADI_2,B) goto L_LOADI; 1055 CASE(OP_LOADI_3,B) goto L_LOADI; 1056 CASE(OP_LOADI_4,B) goto L_LOADI; 1057 CASE(OP_LOADI_5,B) goto L_LOADI; 1058 CASE(OP_LOADI_6,B) goto L_LOADI; 1059 CASE(OP_LOADI_7, B) { 1060 L_LOADI: 1061 SET_INT_VALUE(regs[a], (mrb_int)insn - (mrb_int)OP_LOADI_0); 1062 NEXT; 1063 } 1064 1065 CASE(OP_LOADSYM, BB) { 1066 SET_SYM_VALUE(regs[a], syms[b]); 1067 NEXT; 1068 } 1069 1070 CASE(OP_LOADNIL, B) { 1071 SET_NIL_VALUE(regs[a]); 1072 NEXT; 1073 } 1074 1075 CASE(OP_LOADSELF, B) { 992 1076 regs[a] = regs[0]; 993 1077 NEXT; 994 1078 } 995 1079 996 CASE(OP_LOADT) { 997 /* A R(A) := true */ 998 int a = GETARG_A(i); 1080 CASE(OP_LOADT, B) { 999 1081 SET_TRUE_VALUE(regs[a]); 1000 1082 NEXT; 1001 1083 } 1002 1084 1003 CASE(OP_LOADF) { 1004 /* A R(A) := false */ 1005 int a = GETARG_A(i); 1085 CASE(OP_LOADF, B) { 1006 1086 SET_FALSE_VALUE(regs[a]); 1007 1087 NEXT; 1008 1088 } 1009 1089 1010 CASE(OP_GETGLOBAL) { 1011 /* A Bx R(A) := getglobal(Syms(Bx)) */ 1012 int a = GETARG_A(i); 1013 int bx = GETARG_Bx(i); 1014 mrb_value val = mrb_gv_get(mrb, syms[bx]); 1090 CASE(OP_GETGV, BB) { 1091 mrb_value val = mrb_gv_get(mrb, syms[b]); 1015 1092 regs[a] = val; 1016 1093 NEXT; 1017 1094 } 1018 1095 1019 CASE(OP_SETGLOBAL) { 1020 /* A Bx setglobal(Syms(Bx), R(A)) */ 1021 int a = GETARG_A(i); 1022 int bx = GETARG_Bx(i); 1023 mrb_gv_set(mrb, syms[bx], regs[a]); 1024 NEXT; 1025 } 1026 1027 CASE(OP_GETSPECIAL) { 1028 /* A Bx R(A) := Special[Bx] */ 1029 int a = GETARG_A(i); 1030 int bx = GETARG_Bx(i); 1031 mrb_value val = mrb_vm_special_get(mrb, bx); 1096 CASE(OP_SETGV, BB) { 1097 mrb_gv_set(mrb, syms[b], regs[a]); 1098 NEXT; 1099 } 1100 1101 CASE(OP_GETSV, BB) { 1102 mrb_value val = mrb_vm_special_get(mrb, b); 1032 1103 regs[a] = val; 1033 1104 NEXT; 1034 1105 } 1035 1106 1036 CASE(OP_SETSPECIAL) { 1037 /* A Bx Special[Bx] := R(A) */ 1038 int a = GETARG_A(i); 1039 int bx = GETARG_Bx(i); 1040 mrb_vm_special_set(mrb, bx, regs[a]); 1041 NEXT; 1042 } 1043 1044 CASE(OP_GETIV) { 1045 /* A Bx R(A) := ivget(Bx) */ 1046 int a = GETARG_A(i); 1047 int bx = GETARG_Bx(i); 1048 mrb_value val = mrb_vm_iv_get(mrb, syms[bx]); 1049 regs[a] = val; 1050 NEXT; 1051 } 1052 1053 CASE(OP_SETIV) { 1054 /* A Bx ivset(Syms(Bx),R(A)) */ 1055 int a = GETARG_A(i); 1056 int bx = GETARG_Bx(i); 1057 mrb_vm_iv_set(mrb, syms[bx], regs[a]); 1058 NEXT; 1059 } 1060 1061 CASE(OP_GETCV) { 1062 /* A Bx R(A) := cvget(Syms(Bx)) */ 1063 int a = GETARG_A(i); 1064 int bx = GETARG_Bx(i); 1107 CASE(OP_SETSV, BB) { 1108 mrb_vm_special_set(mrb, b, regs[a]); 1109 NEXT; 1110 } 1111 1112 CASE(OP_GETIV, BB) { 1113 regs[a] = mrb_iv_get(mrb, regs[0], syms[b]); 1114 NEXT; 1115 } 1116 1117 CASE(OP_SETIV, BB) { 1118 mrb_iv_set(mrb, regs[0], syms[b], regs[a]); 1119 NEXT; 1120 } 1121 1122 CASE(OP_GETCV, BB) { 1065 1123 mrb_value val; 1066 ERR_PC_SET(mrb , pc);1067 val = mrb_vm_cv_get(mrb, syms[b x]);1124 ERR_PC_SET(mrb); 1125 val = mrb_vm_cv_get(mrb, syms[b]); 1068 1126 ERR_PC_CLR(mrb); 1069 1127 regs[a] = val; … … 1071 1129 } 1072 1130 1073 CASE(OP_SETCV) { 1074 /* A Bx cvset(Syms(Bx),R(A)) */ 1075 int a = GETARG_A(i); 1076 int bx = GETARG_Bx(i); 1077 mrb_vm_cv_set(mrb, syms[bx], regs[a]); 1078 NEXT; 1079 } 1080 1081 CASE(OP_GETCONST) { 1082 /* A Bx R(A) := constget(Syms(Bx)) */ 1131 CASE(OP_SETCV, BB) { 1132 mrb_vm_cv_set(mrb, syms[b], regs[a]); 1133 NEXT; 1134 } 1135 1136 CASE(OP_GETCONST, BB) { 1083 1137 mrb_value val; 1084 int a = GETARG_A(i); 1085 int bx = GETARG_Bx(i); 1086 mrb_sym sym = syms[bx]; 1087 1088 ERR_PC_SET(mrb, pc); 1138 mrb_sym sym = syms[b]; 1139 1140 ERR_PC_SET(mrb); 1089 1141 val = mrb_vm_const_get(mrb, sym); 1090 1142 ERR_PC_CLR(mrb); … … 1093 1145 } 1094 1146 1095 CASE(OP_SETCONST) { 1096 /* A Bx constset(Syms(Bx),R(A)) */ 1097 int a = GETARG_A(i); 1098 int bx = GETARG_Bx(i); 1099 mrb_vm_const_set(mrb, syms[bx], regs[a]); 1100 NEXT; 1101 } 1102 1103 CASE(OP_GETMCNST) { 1104 /* A Bx R(A) := R(A)::Syms(Bx) */ 1147 CASE(OP_SETCONST, BB) { 1148 mrb_vm_const_set(mrb, syms[b], regs[a]); 1149 NEXT; 1150 } 1151 1152 CASE(OP_GETMCNST, BB) { 1105 1153 mrb_value val; 1106 int a = GETARG_A(i); 1107 int bx = GETARG_Bx(i); 1108 1109 ERR_PC_SET(mrb, pc); 1110 val = mrb_const_get(mrb, regs[a], syms[bx]); 1154 1155 ERR_PC_SET(mrb); 1156 val = mrb_const_get(mrb, regs[a], syms[b]); 1111 1157 ERR_PC_CLR(mrb); 1112 1158 regs[a] = val; … … 1114 1160 } 1115 1161 1116 CASE(OP_SETMCNST) { 1117 /* A Bx R(A+1)::Syms(Bx) := R(A) */ 1118 int a = GETARG_A(i); 1119 int bx = GETARG_Bx(i); 1120 mrb_const_set(mrb, regs[a+1], syms[bx], regs[a]); 1121 NEXT; 1122 } 1123 1124 CASE(OP_GETUPVAR) { 1125 /* A B C R(A) := uvget(B,C) */ 1126 int a = GETARG_A(i); 1127 int b = GETARG_B(i); 1128 int c = GETARG_C(i); 1162 CASE(OP_SETMCNST, BB) { 1163 mrb_const_set(mrb, regs[a+1], syms[b], regs[a]); 1164 NEXT; 1165 } 1166 1167 CASE(OP_GETUPVAR, BBB) { 1129 1168 mrb_value *regs_a = regs + a; 1130 1169 struct REnv *e = uvenv(mrb, c); 1131 1170 1132 if (!e) { 1171 if (e && b < MRB_ENV_STACK_LEN(e)) { 1172 *regs_a = e->stack[b]; 1173 } 1174 else { 1133 1175 *regs_a = mrb_nil_value(); 1134 1176 } 1135 else { 1136 *regs_a = e->stack[b]; 1137 } 1138 NEXT; 1139 } 1140 1141 CASE(OP_SETUPVAR) { 1142 /* A B C uvset(B,C,R(A)) */ 1143 int a = GETARG_A(i); 1144 int b = GETARG_B(i); 1145 int c = GETARG_C(i); 1146 1177 NEXT; 1178 } 1179 1180 CASE(OP_SETUPVAR, BBB) { 1147 1181 struct REnv *e = uvenv(mrb, c); 1148 1182 … … 1158 1192 } 1159 1193 1160 CASE(OP_JMP) { 1161 /* sBx pc+=sBx */ 1162 int sbx = GETARG_sBx(i); 1163 pc += sbx; 1194 CASE(OP_JMP, S) { 1195 pc = irep->iseq+a; 1164 1196 JUMP; 1165 1197 } 1166 1167 CASE(OP_JMPIF) { 1168 /* A sBx if R(A) pc+=sBx */ 1169 int a = GETARG_A(i); 1170 int sbx = GETARG_sBx(i); 1198 CASE(OP_JMPIF, BS) { 1171 1199 if (mrb_test(regs[a])) { 1172 pc += sbx;1200 pc = irep->iseq+b; 1173 1201 JUMP; 1174 1202 } 1175 1203 NEXT; 1176 1204 } 1177 1178 CASE(OP_JMPNOT) { 1179 /* A sBx if !R(A) pc+=sBx */ 1180 int a = GETARG_A(i); 1181 int sbx = GETARG_sBx(i); 1205 CASE(OP_JMPNOT, BS) { 1182 1206 if (!mrb_test(regs[a])) { 1183 pc += sbx;1207 pc = irep->iseq+b; 1184 1208 JUMP; 1185 1209 } 1186 1210 NEXT; 1187 1211 } 1188 1189 CASE(OP_ONERR) { 1190 /* sBx pc+=sBx on exception */ 1191 int sbx = GETARG_sBx(i); 1212 CASE(OP_JMPNIL, BS) { 1213 if (mrb_nil_p(regs[a])) { 1214 pc = irep->iseq+b; 1215 JUMP; 1216 } 1217 NEXT; 1218 } 1219 1220 CASE(OP_ONERR, S) { 1221 /* check rescue stack */ 1222 if (mrb->c->ci->ridx == UINT16_MAX-1) { 1223 mrb_value exc = mrb_exc_new_str_lit(mrb, E_RUNTIME_ERROR, "too many nested rescues"); 1224 mrb_exc_set(mrb, exc); 1225 goto L_RAISE; 1226 } 1227 /* expand rescue stack */ 1192 1228 if (mrb->c->rsize <= mrb->c->ci->ridx) { 1193 1229 if (mrb->c->rsize == 0) mrb->c->rsize = RESCUE_STACK_INIT_SIZE; 1194 else mrb->c->rsize *= 2; 1195 mrb->c->rescue = (mrb_code **)mrb_realloc(mrb, mrb->c->rescue, sizeof(mrb_code*) * mrb->c->rsize); 1196 } 1197 mrb->c->rescue[mrb->c->ci->ridx++] = pc + sbx; 1198 NEXT; 1199 } 1200 1201 CASE(OP_RESCUE) { 1202 /* A B R(A) := exc; clear(exc); R(B) := matched (bool) */ 1203 int a = GETARG_A(i); 1204 int b = GETARG_B(i); 1205 int c = GETARG_C(i); 1206 mrb_value exc; 1207 1208 if (c == 0) { 1209 exc = mrb_obj_value(mrb->exc); 1210 mrb->exc = 0; 1211 } 1212 else { /* continued; exc taken from R(A) */ 1213 exc = regs[a]; 1214 } 1215 if (b != 0) { 1216 mrb_value e = regs[b]; 1217 struct RClass *ec; 1218 1219 switch (mrb_type(e)) { 1220 case MRB_TT_CLASS: 1221 case MRB_TT_MODULE: 1222 break; 1223 default: 1224 { 1225 mrb_value exc; 1226 1227 exc = mrb_exc_new_str_lit(mrb, E_TYPE_ERROR, 1228 "class or module required for rescue clause"); 1229 mrb_exc_set(mrb, exc); 1230 goto L_RAISE; 1231 } 1232 } 1233 ec = mrb_class_ptr(e); 1234 regs[b] = mrb_bool_value(mrb_obj_is_kind_of(mrb, exc, ec)); 1235 } 1236 if (a != 0 && c == 0) { 1237 regs[a] = exc; 1238 } 1239 NEXT; 1240 } 1241 1242 CASE(OP_POPERR) { 1243 /* A A.times{rescue_pop()} */ 1244 int a = GETARG_A(i); 1245 1246 while (a--) { 1247 mrb->c->ci->ridx--; 1248 } 1249 NEXT; 1250 } 1251 1252 CASE(OP_RAISE) { 1253 /* A raise(R(A)) */ 1254 int a = GETARG_A(i); 1255 1230 else { 1231 mrb->c->rsize *= 2; 1232 if (mrb->c->rsize <= mrb->c->ci->ridx) { 1233 mrb->c->rsize = UINT16_MAX; 1234 } 1235 } 1236 mrb->c->rescue = (uint16_t*)mrb_realloc(mrb, mrb->c->rescue, sizeof(uint16_t)*mrb->c->rsize); 1237 } 1238 /* push rescue stack */ 1239 mrb->c->rescue[mrb->c->ci->ridx++] = a; 1240 NEXT; 1241 } 1242 1243 CASE(OP_EXCEPT, B) { 1244 mrb_value exc = mrb_obj_value(mrb->exc); 1245 mrb->exc = 0; 1246 regs[a] = exc; 1247 NEXT; 1248 } 1249 CASE(OP_RESCUE, BB) { 1250 mrb_value exc = regs[a]; /* exc on stack */ 1251 mrb_value e = regs[b]; 1252 struct RClass *ec; 1253 1254 switch (mrb_type(e)) { 1255 case MRB_TT_CLASS: 1256 case MRB_TT_MODULE: 1257 break; 1258 default: 1259 { 1260 mrb_value exc; 1261 1262 exc = mrb_exc_new_str_lit(mrb, E_TYPE_ERROR, 1263 "class or module required for rescue clause"); 1264 mrb_exc_set(mrb, exc); 1265 goto L_RAISE; 1266 } 1267 } 1268 ec = mrb_class_ptr(e); 1269 regs[b] = mrb_bool_value(mrb_obj_is_kind_of(mrb, exc, ec)); 1270 NEXT; 1271 } 1272 1273 CASE(OP_POPERR, B) { 1274 mrb->c->ci->ridx -= a; 1275 NEXT; 1276 } 1277 1278 CASE(OP_RAISE, B) { 1256 1279 mrb_exc_set(mrb, regs[a]); 1257 1280 goto L_RAISE; 1258 1281 } 1259 1282 1260 CASE(OP_EPUSH) { 1261 /* Bx ensure_push(SEQ[Bx]) */ 1262 int bx = GETARG_Bx(i); 1283 CASE(OP_EPUSH, B) { 1263 1284 struct RProc *p; 1264 1285 1265 p = mrb_closure_new(mrb, irep->reps[bx]); 1266 /* push ensure_stack */ 1286 p = mrb_closure_new(mrb, irep->reps[a]); 1287 /* check ensure stack */ 1288 if (mrb->c->eidx == UINT16_MAX-1) { 1289 mrb_value exc = mrb_exc_new_str_lit(mrb, E_RUNTIME_ERROR, "too many nested ensures"); 1290 mrb_exc_set(mrb, exc); 1291 goto L_RAISE; 1292 } 1293 /* expand ensure stack */ 1267 1294 if (mrb->c->esize <= mrb->c->eidx+1) { 1268 1295 if (mrb->c->esize == 0) mrb->c->esize = ENSURE_STACK_INIT_SIZE; 1269 else mrb->c->esize *= 2; 1270 mrb->c->ensure = (struct RProc **)mrb_realloc(mrb, mrb->c->ensure, sizeof(struct RProc*) * mrb->c->esize); 1271 } 1296 else { 1297 mrb->c->esize *= 2; 1298 if (mrb->c->esize <= mrb->c->eidx) { 1299 mrb->c->esize = UINT16_MAX; 1300 } 1301 } 1302 mrb->c->ensure = (struct RProc**)mrb_realloc(mrb, mrb->c->ensure, sizeof(struct RProc*)*mrb->c->esize); 1303 } 1304 /* push ensure stack */ 1272 1305 mrb->c->ensure[mrb->c->eidx++] = p; 1273 1306 mrb->c->ensure[mrb->c->eidx] = NULL; 1274 ARENA_RESTORE(mrb, ai); 1275 NEXT; 1276 } 1277 1278 CASE(OP_EPOP) { 1279 /* A A.times{ensure_pop().call} */ 1280 int a = GETARG_A(i); 1307 mrb_gc_arena_restore(mrb, ai); 1308 NEXT; 1309 } 1310 1311 CASE(OP_EPOP, B) { 1281 1312 mrb_callinfo *ci = mrb->c->ci; 1282 int n, epos = ci->epos; 1283 1284 for (n=0; n<a && mrb->c->eidx > epos; n++) { 1285 ecall(mrb, --mrb->c->eidx); 1286 ARENA_RESTORE(mrb, ai); 1287 } 1288 NEXT; 1289 } 1290 1291 CASE(OP_LOADNIL) { 1292 /* A R(A) := nil */ 1293 int a = GETARG_A(i); 1294 1295 SET_NIL_VALUE(regs[a]); 1296 NEXT; 1297 } 1298 1299 CASE(OP_SENDB) { 1300 /* A B C R(A) := call(R(A),Syms(B),R(A+1),...,R(A+C),&R(A+C+1))*/ 1301 /* fall through */ 1313 unsigned int n, epos = ci->epos; 1314 mrb_value self = regs[0]; 1315 struct RClass *target_class = ci->target_class; 1316 1317 if (mrb->c->eidx <= epos) { 1318 NEXT; 1319 } 1320 1321 if (a > (int)mrb->c->eidx - epos) 1322 a = mrb->c->eidx - epos; 1323 for (n=0; n<a; n++) { 1324 int nregs = irep->nregs; 1325 1326 proc = mrb->c->ensure[epos+n]; 1327 mrb->c->ensure[epos+n] = NULL; 1328 if (proc == NULL) continue; 1329 irep = proc->body.irep; 1330 ci = cipush(mrb); 1331 ci->mid = ci[-1].mid; 1332 ci->argc = 0; 1333 ci->proc = proc; 1334 ci->stackent = mrb->c->stack; 1335 ci->target_class = target_class; 1336 ci->pc = pc; 1337 ci->acc = nregs; 1338 mrb->c->stack += ci->acc; 1339 mrb_stack_extend(mrb, irep->nregs); 1340 regs[0] = self; 1341 pc = irep->iseq; 1342 } 1343 pool = irep->pool; 1344 syms = irep->syms; 1345 mrb->c->eidx = epos; 1346 JUMP; 1347 } 1348 1349 CASE(OP_SENDV, BB) { 1350 c = CALL_MAXARGS; 1351 goto L_SEND; 1302 1352 }; 1303 1353 1304 L_SEND: 1305 CASE(OP_SEND) { 1306 /* A B C R(A) := call(R(A),Syms(B),R(A+1),...,R(A+C)) */ 1307 int a = GETARG_A(i); 1308 int n = GETARG_C(i); 1309 struct RProc *m; 1310 struct RClass *c; 1354 CASE(OP_SENDVB, BB) { 1355 c = CALL_MAXARGS; 1356 goto L_SENDB; 1357 }; 1358 1359 CASE(OP_SEND, BBB) 1360 L_SEND: 1361 { 1362 /* push nil after arguments */ 1363 int bidx = (c == CALL_MAXARGS) ? a+2 : a+c+1; 1364 SET_NIL_VALUE(regs[bidx]); 1365 goto L_SENDB; 1366 }; 1367 L_SEND_SYM: 1368 { 1369 /* push nil after arguments */ 1370 int bidx = (c == CALL_MAXARGS) ? a+2 : a+c+1; 1371 SET_NIL_VALUE(regs[bidx]); 1372 goto L_SENDB_SYM; 1373 }; 1374 1375 CASE(OP_SENDB, BBB) 1376 L_SENDB: 1377 mid = syms[b]; 1378 L_SENDB_SYM: 1379 { 1380 int argc = (c == CALL_MAXARGS) ? -1 : c; 1381 int bidx = (argc < 0) ? a+2 : a+c+1; 1382 mrb_method_t m; 1383 struct RClass *cls; 1311 1384 mrb_callinfo *ci = mrb->c->ci; 1312 mrb_value recv, result; 1313 mrb_sym mid = syms[GETARG_B(i)]; 1314 int bidx; 1315 mrb_value blk; 1385 mrb_value recv, blk; 1386 1387 mrb_assert(bidx < irep->nregs); 1316 1388 1317 1389 recv = regs[a]; 1318 if (n == CALL_MAXARGS) { 1319 bidx = a+2; 1320 } 1321 else { 1322 bidx = a+n+1; 1323 } 1324 if (GET_OPCODE(i) != OP_SENDB) { 1325 if (bidx >= ci->nregs) { 1326 stack_extend(mrb, bidx+1); 1327 ci->nregs = bidx+1; 1328 } 1329 SET_NIL_VALUE(regs[bidx]); 1330 blk = mrb_nil_value(); 1331 } 1332 else { 1333 blk = regs[bidx]; 1334 if (!mrb_nil_p(blk) && mrb_type(blk) != MRB_TT_PROC) { 1335 if (bidx >= ci->nregs) { 1336 stack_extend(mrb, bidx+1); 1337 ci->nregs = bidx+1; 1338 } 1339 result = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc"); 1340 blk = regs[bidx] = result; 1341 } 1342 } 1343 c = mrb_class(mrb, recv); 1344 m = mrb_method_search_vm(mrb, &c, mid); 1345 if (!m) { 1346 mrb_value sym = mrb_symbol_value(mid); 1390 blk = regs[bidx]; 1391 if (!mrb_nil_p(blk) && !mrb_proc_p(blk)) { 1392 blk = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc"); 1393 /* The stack might have been reallocated during mrb_convert_type(), 1394 see #3622 */ 1395 regs[bidx] = blk; 1396 } 1397 cls = mrb_class(mrb, recv); 1398 m = mrb_method_search_vm(mrb, &cls, mid); 1399 if (MRB_METHOD_UNDEF_P(m)) { 1347 1400 mrb_sym missing = mrb_intern_lit(mrb, "method_missing"); 1348 1349 m = mrb_method_search_vm(mrb, &c, missing); 1350 if (!m) { 1351 mrb_value args; 1352 1353 if (n == CALL_MAXARGS) { 1354 args = regs[a+1]; 1355 } 1356 else { 1357 args = mrb_ary_new_from_values(mrb, n, regs+a+1); 1358 } 1359 ERR_PC_SET(mrb, pc); 1401 m = mrb_method_search_vm(mrb, &cls, missing); 1402 if (MRB_METHOD_UNDEF_P(m) || (missing == mrb->c->ci->mid && mrb_obj_eq(mrb, regs[0], recv))) { 1403 mrb_value args = (argc < 0) ? regs[a+1] : mrb_ary_new_from_values(mrb, c, regs+a+1); 1404 ERR_PC_SET(mrb); 1360 1405 mrb_method_missing(mrb, mid, recv, args); 1361 1406 } 1407 if (argc >= 0) { 1408 if (a+2 >= irep->nregs) { 1409 mrb_stack_extend(mrb, a+3); 1410 } 1411 regs[a+1] = mrb_ary_new_from_values(mrb, c, regs+a+1); 1412 regs[a+2] = blk; 1413 argc = -1; 1414 } 1415 mrb_ary_unshift(mrb, regs[a+1], mrb_symbol_value(mid)); 1362 1416 mid = missing; 1363 if (n != CALL_MAXARGS) {1364 if (a+2 >= irep->nregs) {1365 stack_extend(mrb, a+3);1366 }1367 regs[a+1] = mrb_ary_new_from_values(mrb, n, regs+a+1);1368 regs[a+2] = blk;1369 n = CALL_MAXARGS;1370 }1371 mrb_ary_unshift(mrb, regs[a+1], sym);1372 1417 } 1373 1418 … … 1375 1420 ci = cipush(mrb); 1376 1421 ci->mid = mid; 1377 ci->proc = m;1378 1422 ci->stackent = mrb->c->stack; 1379 ci->target_class = c; 1380 1381 ci->pc = pc + 1; 1423 ci->target_class = cls; 1424 ci->argc = argc; 1425 1426 ci->pc = pc; 1382 1427 ci->acc = a; 1383 1428 … … 1385 1430 mrb->c->stack += a; 1386 1431 1387 if (MRB_PROC_CFUNC_P(m)) { 1388 if (n == CALL_MAXARGS) { 1389 ci->argc = -1; 1390 ci->nregs = 3; 1432 if (MRB_METHOD_CFUNC_P(m)) { 1433 if (MRB_METHOD_PROC_P(m)) { 1434 struct RProc *p = MRB_METHOD_PROC(m); 1435 1436 ci->proc = p; 1437 recv = p->body.func(mrb, recv); 1438 } 1439 else if (MRB_METHOD_NOARG_P(m) && 1440 (argc > 0 || (argc == -1 && RARRAY_LEN(regs[1]) != 0))) { 1441 argnum_error(mrb, 0); 1442 goto L_RAISE; 1391 1443 } 1392 1444 else { 1393 ci->argc = n; 1394 ci->nregs = n + 2; 1395 } 1396 result = m->body.func(mrb, recv); 1445 recv = MRB_METHOD_FUNC(m)(mrb, recv); 1446 } 1397 1447 mrb_gc_arena_restore(mrb, ai); 1448 mrb_gc_arena_shrink(mrb, ai); 1398 1449 if (mrb->exc) goto L_RAISE; 1399 1450 ci = mrb->c->ci; 1400 if (GET_OPCODE(i) == OP_SENDB) { 1401 if (mrb_type(blk) == MRB_TT_PROC) { 1402 struct RProc *p = mrb_proc_ptr(blk); 1403 1404 if (p && !MRB_PROC_STRICT_P(p) && p->env == ci[-1].env) { 1405 p->flags |= MRB_PROC_ORPHAN; 1406 } 1451 if (mrb_proc_p(blk)) { 1452 struct RProc *p = mrb_proc_ptr(blk); 1453 if (p && !MRB_PROC_STRICT_P(p) && MRB_PROC_ENV(p) == ci[-1].env) { 1454 p->flags |= MRB_PROC_ORPHAN; 1407 1455 } 1408 1456 } … … 1410 1458 if (ci->acc == CI_ACC_RESUMED) { 1411 1459 mrb->jmp = prev_jmp; 1412 return re sult;1460 return recv; 1413 1461 } 1414 1462 else { … … 1420 1468 } 1421 1469 } 1422 mrb->c->stack[0] = re sult;1470 mrb->c->stack[0] = recv; 1423 1471 /* pop stackpos */ 1424 1472 mrb->c->stack = ci->stackent; … … 1429 1477 else { 1430 1478 /* setup environment for calling method */ 1431 proc = mrb->c->ci->proc = m;1432 irep = m->body.irep;1479 proc = ci->proc = MRB_METHOD_PROC(m); 1480 irep = proc->body.irep; 1433 1481 pool = irep->pool; 1434 1482 syms = irep->syms; 1435 ci->nregs = irep->nregs; 1436 if (n == CALL_MAXARGS) { 1437 ci->argc = -1; 1438 stack_extend(mrb, (irep->nregs < 3) ? 3 : irep->nregs); 1439 } 1440 else { 1441 ci->argc = n; 1442 stack_extend(mrb, irep->nregs); 1443 } 1483 mrb_stack_extend(mrb, (argc < 0 && irep->nregs < 3) ? 3 : irep->nregs); 1444 1484 pc = irep->iseq; 1445 1485 JUMP; … … 1447 1487 } 1448 1488 1449 CASE(OP_FSEND) { 1450 /* A B C R(A) := fcall(R(A),Syms(B),R(A+1),... ,R(A+C-1)) */ 1451 /* not implemented yet */ 1452 NEXT; 1453 } 1454 1455 CASE(OP_CALL) { 1456 /* A R(A) := self.call(frame.argc, frame.argv) */ 1489 CASE(OP_CALL, Z) { 1457 1490 mrb_callinfo *ci; 1458 1491 mrb_value recv = mrb->c->stack[0]; … … 1461 1494 /* replace callinfo */ 1462 1495 ci = mrb->c->ci; 1463 ci->target_class = m->target_class;1496 ci->target_class = MRB_PROC_TARGET_CLASS(m); 1464 1497 ci->proc = m; 1465 if (m->env) { 1466 mrb_sym mid; 1467 1468 if (MRB_ENV_STACK_SHARED_P(m->env)) { 1469 mid = m->env->cxt.c->cibase[m->env->cioff].mid; 1470 } 1471 else { 1472 mid = m->env->cxt.mid; 1473 } 1474 if (mid) ci->mid = mid; 1475 if (!m->env->stack) { 1476 m->env->stack = mrb->c->stack; 1498 if (MRB_PROC_ENV_P(m)) { 1499 struct REnv *e = MRB_PROC_ENV(m); 1500 1501 ci->mid = e->mid; 1502 if (!e->stack) { 1503 e->stack = mrb->c->stack; 1477 1504 } 1478 1505 } … … 1480 1507 /* prepare stack */ 1481 1508 if (MRB_PROC_CFUNC_P(m)) { 1482 recv = m->body.func(mrb, recv);1509 recv = MRB_PROC_CFUNC(m)(mrb, recv); 1483 1510 mrb_gc_arena_restore(mrb, ai); 1511 mrb_gc_arena_shrink(mrb, ai); 1484 1512 if (mrb->exc) goto L_RAISE; 1485 1513 /* pop stackpos */ … … 1500 1528 if (!irep) { 1501 1529 mrb->c->stack[0] = mrb_nil_value(); 1502 goto L_RETURN; 1530 a = 0; 1531 c = OP_R_NORMAL; 1532 goto L_OP_RETURN_BODY; 1503 1533 } 1504 1534 pool = irep->pool; 1505 1535 syms = irep->syms; 1506 ci->nregs = irep->nregs; 1507 stack_extend(mrb, irep->nregs); 1536 mrb_stack_extend(mrb, irep->nregs); 1508 1537 if (ci->argc < 0) { 1509 1538 if (irep->nregs > 3) { … … 1514 1543 stack_clear(regs+ci->argc+2, irep->nregs-ci->argc-2); 1515 1544 } 1516 if ( m->env) {1517 regs[0] = m->env->stack[0];1545 if (MRB_PROC_ENV_P(m)) { 1546 regs[0] = MRB_PROC_ENV(m)->stack[0]; 1518 1547 } 1519 1548 pc = irep->iseq; … … 1522 1551 } 1523 1552 1524 CASE(OP_SUPER) { 1525 /* A C R(A) := super(R(A+1),... ,R(A+C+1)) */ 1526 mrb_value recv; 1553 CASE(OP_SUPER, BB) { 1554 int argc = (b == CALL_MAXARGS) ? -1 : b; 1555 int bidx = (argc < 0) ? a+2 : a+b+1; 1556 mrb_method_t m; 1557 struct RClass *cls; 1527 1558 mrb_callinfo *ci = mrb->c->ci; 1528 struct RProc *m;1529 struct R Class *c;1559 mrb_value recv, blk; 1560 struct RProc *p = ci->proc; 1530 1561 mrb_sym mid = ci->mid; 1531 int a = GETARG_A(i);1532 int n = GETARG_C(i); 1533 mrb_value blk;1534 int bidx;1535 1536 if (mid == 0 || !ci->target_class) {1537 mrb_value exc; 1538 1539 exc = mrb_exc_new_str_lit(mrb, E_NOMETHOD_ERROR, "super called outside of method");1562 struct RClass* target_class = MRB_PROC_TARGET_CLASS(p); 1563 1564 if (MRB_PROC_ENV_P(p) && p->e.env->mid && p->e.env->mid != mid) { /* alias support */ 1565 mid = p->e.env->mid; /* restore old mid */ 1566 } 1567 mrb_assert(bidx < irep->nregs); 1568 1569 if (mid == 0 || !target_class) { 1570 mrb_value exc = mrb_exc_new_str_lit(mrb, E_NOMETHOD_ERROR, "super called outside of method"); 1540 1571 mrb_exc_set(mrb, exc); 1541 1572 goto L_RAISE; 1542 1573 } 1574 if (target_class->tt == MRB_TT_MODULE) { 1575 target_class = ci->target_class; 1576 if (target_class->tt != MRB_TT_ICLASS) { 1577 mrb_value exc = mrb_exc_new_str_lit(mrb, E_RUNTIME_ERROR, "superclass info lost [mruby limitations]"); 1578 mrb_exc_set(mrb, exc); 1579 goto L_RAISE; 1580 } 1581 } 1543 1582 recv = regs[0]; 1544 c = mrb->c->ci->target_class->super; 1545 m = mrb_method_search_vm(mrb, &c, mid); 1546 if (!m) { 1583 if (!mrb_obj_is_kind_of(mrb, recv, target_class)) { 1584 mrb_value exc = mrb_exc_new_str_lit(mrb, E_TYPE_ERROR, 1585 "self has wrong type to call super in this context"); 1586 mrb_exc_set(mrb, exc); 1587 goto L_RAISE; 1588 } 1589 blk = regs[bidx]; 1590 if (!mrb_nil_p(blk) && !mrb_proc_p(blk)) { 1591 blk = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc"); 1592 /* The stack or ci stack might have been reallocated during 1593 mrb_convert_type(), see #3622 and #3784 */ 1594 regs[bidx] = blk; 1595 ci = mrb->c->ci; 1596 } 1597 cls = target_class->super; 1598 m = mrb_method_search_vm(mrb, &cls, mid); 1599 if (MRB_METHOD_UNDEF_P(m)) { 1547 1600 mrb_sym missing = mrb_intern_lit(mrb, "method_missing"); 1548 m = mrb_method_search_vm(mrb, &c, missing); 1549 if (!m) { 1550 mrb_value args; 1551 1552 if (n == CALL_MAXARGS) { 1553 args = regs[a+1]; 1554 } 1555 else { 1556 args = mrb_ary_new_from_values(mrb, n, regs+a+1); 1557 } 1558 ERR_PC_SET(mrb, pc); 1601 1602 if (mid != missing) { 1603 cls = mrb_class(mrb, recv); 1604 } 1605 m = mrb_method_search_vm(mrb, &cls, missing); 1606 if (MRB_METHOD_UNDEF_P(m)) { 1607 mrb_value args = (argc < 0) ? regs[a+1] : mrb_ary_new_from_values(mrb, b, regs+a+1); 1608 ERR_PC_SET(mrb); 1559 1609 mrb_method_missing(mrb, mid, recv, args); 1560 1610 } 1561 1611 mid = missing; 1562 if (n == CALL_MAXARGS-1) { 1563 regs[a+1] = mrb_ary_new_from_values(mrb, n, regs+a+1); 1564 n++; 1565 } 1566 if (n == CALL_MAXARGS) { 1567 mrb_ary_unshift(mrb, regs[a+1], mrb_symbol_value(ci->mid)); 1568 } 1569 else { 1570 value_move(regs+a+2, regs+a+1, ++n); 1571 SET_SYM_VALUE(regs[a+1], ci->mid); 1572 } 1573 } 1574 1575 if (n == CALL_MAXARGS) { 1576 bidx = a+2; 1577 } 1578 else { 1579 bidx = a+n+1; 1580 } 1581 blk = regs[bidx]; 1582 if (!mrb_nil_p(blk) && mrb_type(blk) != MRB_TT_PROC) { 1583 mrb_value result; 1584 1585 if (bidx >= ci->nregs) { 1586 stack_extend(mrb, bidx+1); 1587 ci->nregs = bidx+1; 1588 } 1589 result = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc"); 1590 regs[bidx] = result; 1612 if (argc >= 0) { 1613 if (a+2 >= irep->nregs) { 1614 mrb_stack_extend(mrb, a+3); 1615 } 1616 regs[a+1] = mrb_ary_new_from_values(mrb, b, regs+a+1); 1617 regs[a+2] = blk; 1618 argc = -1; 1619 } 1620 mrb_ary_unshift(mrb, regs[a+1], mrb_symbol_value(ci->mid)); 1591 1621 } 1592 1622 … … 1594 1624 ci = cipush(mrb); 1595 1625 ci->mid = mid; 1596 ci->proc = m;1597 1626 ci->stackent = mrb->c->stack; 1598 ci->target_class = c; 1599 ci->pc = pc + 1; 1600 if (n == CALL_MAXARGS) { 1601 ci->argc = -1; 1602 } 1603 else { 1604 ci->argc = n; 1605 } 1627 ci->target_class = cls; 1628 ci->pc = pc; 1629 ci->argc = argc; 1606 1630 1607 1631 /* prepare stack */ … … 1609 1633 mrb->c->stack[0] = recv; 1610 1634 1611 if (MRB_ PROC_CFUNC_P(m)) {1635 if (MRB_METHOD_CFUNC_P(m)) { 1612 1636 mrb_value v; 1613 1637 1614 if (n == CALL_MAXARGS) { 1615 ci->nregs = 3; 1616 } 1617 else { 1618 ci->nregs = n + 2; 1619 } 1620 v = m->body.func(mrb, recv); 1638 if (MRB_METHOD_PROC_P(m)) { 1639 ci->proc = MRB_METHOD_PROC(m); 1640 } 1641 v = MRB_METHOD_CFUNC(m)(mrb, recv); 1621 1642 mrb_gc_arena_restore(mrb, ai); 1622 1643 if (mrb->exc) goto L_RAISE; … … 1647 1668 1648 1669 /* setup environment for calling method */ 1649 ci->proc = m;1650 irep = m->body.irep;1670 proc = ci->proc = MRB_METHOD_PROC(m); 1671 irep = proc->body.irep; 1651 1672 pool = irep->pool; 1652 1673 syms = irep->syms; 1653 ci->nregs = irep->nregs; 1654 if (n == CALL_MAXARGS) { 1655 stack_extend(mrb, (irep->nregs < 3) ? 3 : irep->nregs); 1656 } 1657 else { 1658 stack_extend(mrb, irep->nregs); 1659 } 1674 mrb_stack_extend(mrb, (argc < 0 && irep->nregs < 3) ? 3 : irep->nregs); 1660 1675 pc = irep->iseq; 1661 1676 JUMP; … … 1663 1678 } 1664 1679 1665 CASE(OP_ARGARY) { 1666 /* A Bx R(A) := argument array (16=6:1:5:4) */ 1667 int a = GETARG_A(i); 1668 int bx = GETARG_Bx(i); 1669 int m1 = (bx>>10)&0x3f; 1670 int r = (bx>>9)&0x1; 1671 int m2 = (bx>>4)&0x1f; 1672 int lv = (bx>>0)&0xf; 1680 CASE(OP_ARGARY, BS) { 1681 int m1 = (b>>11)&0x3f; 1682 int r = (b>>10)&0x1; 1683 int m2 = (b>>5)&0x1f; 1684 int kd = (b>>4)&0x1; 1685 int lv = (b>>0)&0xf; 1673 1686 mrb_value *stack; 1674 1687 … … 1685 1698 struct REnv *e = uvenv(mrb, lv-1); 1686 1699 if (!e) goto L_NOSUPER; 1700 if (MRB_ENV_STACK_LEN(e) <= m1+r+m2+kd+1) 1701 goto L_NOSUPER; 1687 1702 stack = e->stack + 1; 1688 1703 } 1689 1704 if (r == 0) { 1690 regs[a] = mrb_ary_new_from_values(mrb, m1+m2 , stack);1705 regs[a] = mrb_ary_new_from_values(mrb, m1+m2+kd, stack); 1691 1706 } 1692 1707 else { … … 1698 1713 struct RArray *ary = mrb_ary_ptr(stack[m1]); 1699 1714 1700 pp = ary->ptr;1701 len = ary->len;1702 } 1703 regs[a] = mrb_ary_new_capa(mrb, m1+len+m2 );1715 pp = ARY_PTR(ary); 1716 len = (int)ARY_LEN(ary); 1717 } 1718 regs[a] = mrb_ary_new_capa(mrb, m1+len+m2+kd); 1704 1719 rest = mrb_ary_ptr(regs[a]); 1705 1720 if (m1 > 0) { 1706 stack_copy( rest->ptr, stack, m1);1721 stack_copy(ARY_PTR(rest), stack, m1); 1707 1722 } 1708 1723 if (len > 0) { 1709 stack_copy( rest->ptr+m1, pp, len);1724 stack_copy(ARY_PTR(rest)+m1, pp, len); 1710 1725 } 1711 1726 if (m2 > 0) { 1712 stack_copy(rest->ptr+m1+len, stack+m1+1, m2); 1713 } 1714 rest->len = m1+len+m2; 1727 stack_copy(ARY_PTR(rest)+m1+len, stack+m1+1, m2); 1728 } 1729 if (kd) { 1730 stack_copy(ARY_PTR(rest)+m1+len+m2, stack+m1+m2+1, kd); 1731 } 1732 ARY_SET_LEN(rest, m1+len+m2+kd); 1715 1733 } 1716 1734 regs[a+1] = stack[m1+r+m2]; 1717 ARENA_RESTORE(mrb, ai); 1718 NEXT; 1719 } 1720 1721 CASE(OP_ENTER) { 1722 /* Ax arg setup according to flags (23=5:5:1:5:5:1:1) */ 1723 /* number of optional arguments times OP_JMP should follow */ 1724 mrb_aspec ax = GETARG_Ax(i); 1725 int m1 = MRB_ASPEC_REQ(ax); 1726 int o = MRB_ASPEC_OPT(ax); 1727 int r = MRB_ASPEC_REST(ax); 1728 int m2 = MRB_ASPEC_POST(ax); 1735 mrb_gc_arena_restore(mrb, ai); 1736 NEXT; 1737 } 1738 1739 CASE(OP_ENTER, W) { 1740 int m1 = MRB_ASPEC_REQ(a); 1741 int o = MRB_ASPEC_OPT(a); 1742 int r = MRB_ASPEC_REST(a); 1743 int m2 = MRB_ASPEC_POST(a); 1744 int kd = (MRB_ASPEC_KEY(a) > 0 || MRB_ASPEC_KDICT(a))? 1 : 0; 1729 1745 /* unused 1730 int k = MRB_ASPEC_KEY(ax); 1731 int kd = MRB_ASPEC_KDICT(ax); 1732 int b = MRB_ASPEC_BLOCK(ax); 1746 int b = MRB_ASPEC_BLOCK(a); 1733 1747 */ 1734 1748 int argc = mrb->c->ci->argc; 1735 1749 mrb_value *argv = regs+1; 1736 mrb_value *argv0 = argv; 1737 int len = m1 + o + r + m2; 1750 mrb_value * const argv0 = argv; 1751 int const len = m1 + o + r + m2; 1752 int const blk_pos = len + kd + 1; 1738 1753 mrb_value *blk = &argv[argc < 0 ? 1 : argc]; 1739 1754 mrb_value kdict; 1755 int kargs = kd; 1756 1757 /* arguments is passed with Array */ 1740 1758 if (argc < 0) { 1741 1759 struct RArray *ary = mrb_ary_ptr(regs[1]); 1742 argv = ary->ptr;1743 argc = ary->len;1760 argv = ARY_PTR(ary); 1761 argc = (int)ARY_LEN(ary); 1744 1762 mrb_gc_protect(mrb, regs[1]); 1745 1763 } 1764 1765 /* strict argument check */ 1746 1766 if (mrb->c->ci->proc && MRB_PROC_STRICT_P(mrb->c->ci->proc)) { 1747 if (argc >= 0) { 1748 if (argc < m1 + m2 || (r == 0 && argc > len)) { 1767 if (argc < m1 + m2 || (r == 0 && argc > len + kd)) { 1768 argnum_error(mrb, m1+m2); 1769 goto L_RAISE; 1770 } 1771 } 1772 /* extract first argument array to arguments */ 1773 else if (len > 1 && argc == 1 && mrb_array_p(argv[0])) { 1774 mrb_gc_protect(mrb, argv[0]); 1775 argc = (int)RARRAY_LEN(argv[0]); 1776 argv = RARRAY_PTR(argv[0]); 1777 } 1778 1779 if (kd) { 1780 /* check last arguments is hash if method takes keyword arguments */ 1781 if (argc == m1+m2) { 1782 kdict = mrb_hash_new(mrb); 1783 kargs = 0; 1784 } 1785 else { 1786 if (argv && argc > 0 && mrb_hash_p(argv[argc-1])) { 1787 kdict = argv[argc-1]; 1788 mrb_hash_check_kdict(mrb, kdict); 1789 } 1790 else if (r || argc <= m1+m2+o 1791 || !(mrb->c->ci->proc && MRB_PROC_STRICT_P(mrb->c->ci->proc))) { 1792 kdict = mrb_hash_new(mrb); 1793 kargs = 0; 1794 } 1795 else { 1749 1796 argnum_error(mrb, m1+m2); 1750 1797 goto L_RAISE; 1751 1798 } 1752 }1753 }1754 else if (len > 1 && argc == 1 && mrb_array_p(argv[0])) {1755 mrb_gc_protect(mrb, argv[0]);1756 argc = mrb_ary_ptr(argv[0])->len;1757 argv = mrb_ary_ptr(argv[0])->ptr; 1758 }1759 if (argc < len) {1799 if (MRB_ASPEC_KEY(a) > 0) { 1800 kdict = mrb_hash_dup(mrb, kdict); 1801 } 1802 } 1803 } 1804 1805 /* no rest arguments */ 1806 if (argc-kargs < len) { 1760 1807 int mlen = m2; 1761 1808 if (argc < m1+m2) { 1762 if (m1 < argc) 1763 mlen = argc - m1; 1764 else 1765 mlen = 0; 1766 } 1767 regs[len+1] = *blk; /* move block */ 1768 SET_NIL_VALUE(regs[argc+1]); 1809 mlen = m1 < argc ? argc - m1 : 0; 1810 } 1811 regs[blk_pos] = *blk; /* move block */ 1812 if (kd) regs[len + 1] = kdict; 1813 1814 /* copy mandatory and optional arguments */ 1769 1815 if (argv0 != argv) { 1770 1816 value_move(®s[1], argv, argc-mlen); /* m1 + o */ … … 1773 1819 stack_clear(®s[argc+1], m1-argc); 1774 1820 } 1821 /* copy post mandatory arguments */ 1775 1822 if (mlen) { 1776 1823 value_move(®s[len-m2+1], &argv[argc-mlen], mlen); … … 1779 1826 stack_clear(®s[len-m2+mlen+1], m2-mlen); 1780 1827 } 1828 /* initalize rest arguments with empty Array */ 1781 1829 if (r) { 1782 1830 regs[m1+o+1] = mrb_ary_new_capa(mrb, 0); 1783 1831 } 1784 if (o == 0 || argc < m1+m2) pc++;1785 else1786 pc += argc - m1 - m2 + 1;1832 /* skip initailizer of passed arguments */ 1833 if (o > 0 && argc-kargs > m1+m2) 1834 pc += (argc - kargs - m1 - m2)*3; 1787 1835 } 1788 1836 else { 1789 1837 int rnum = 0; 1790 1838 if (argv0 != argv) { 1791 regs[len+1] = *blk; /* move block */ 1839 regs[blk_pos] = *blk; /* move block */ 1840 if (kd) regs[len + 1] = kdict; 1792 1841 value_move(®s[1], argv, m1+o); 1793 1842 } 1794 1843 if (r) { 1795 rnum = argc-m1-o-m2; 1796 regs[m1+o+1] = mrb_ary_new_from_values(mrb, rnum, argv+m1+o); 1844 mrb_value ary; 1845 1846 rnum = argc-m1-o-m2-kargs; 1847 ary = mrb_ary_new_from_values(mrb, rnum, argv+m1+o); 1848 regs[m1+o+1] = ary; 1797 1849 } 1798 1850 if (m2) { … … 1802 1854 } 1803 1855 if (argv0 == argv) { 1804 regs[len+1] = *blk; /* move block */ 1805 } 1806 pc += o + 1; 1807 } 1808 mrb->c->ci->argc = len; 1856 regs[blk_pos] = *blk; /* move block */ 1857 if (kd) regs[len + 1] = kdict; 1858 } 1859 pc += o*3; 1860 } 1861 1862 /* format arguments for generated code */ 1863 mrb->c->ci->argc = len + kd; 1864 1809 1865 /* clear local (but non-argument) variables */ 1810 if (irep->nlocals- len-2> 0) {1811 stack_clear(®s[ len+2], irep->nlocals-len-2);1866 if (irep->nlocals-blk_pos-1 > 0) { 1867 stack_clear(®s[blk_pos+1], irep->nlocals-blk_pos-1); 1812 1868 } 1813 1869 JUMP; 1814 1870 } 1815 1871 1816 CASE(OP_KARG) { 1817 /* A B C R(A) := kdict[Syms(B)]; if C kdict.rm(Syms(B)) */ 1818 /* if C == 2; raise unless kdict.empty? */ 1819 /* OP_JMP should follow to skip init code */ 1820 NEXT; 1821 } 1822 1823 CASE(OP_KDICT) { 1824 /* A C R(A) := kdict */ 1825 NEXT; 1826 } 1827 1872 CASE(OP_KARG, BB) { 1873 mrb_value k = mrb_symbol_value(syms[b]); 1874 mrb_value kdict = regs[mrb->c->ci->argc]; 1875 1876 if (!mrb_hash_p(kdict) || !mrb_hash_key_p(mrb, kdict, k)) { 1877 mrb_value str = mrb_format(mrb, "missing keyword: %v", k); 1878 mrb_exc_set(mrb, mrb_exc_new_str(mrb, E_ARGUMENT_ERROR, str)); 1879 goto L_RAISE; 1880 } 1881 regs[a] = mrb_hash_get(mrb, kdict, k); 1882 mrb_hash_delete_key(mrb, kdict, k); 1883 NEXT; 1884 } 1885 1886 CASE(OP_KEY_P, BB) { 1887 mrb_value k = mrb_symbol_value(syms[b]); 1888 mrb_value kdict = regs[mrb->c->ci->argc]; 1889 mrb_bool key_p = FALSE; 1890 1891 if (mrb_hash_p(kdict)) { 1892 key_p = mrb_hash_key_p(mrb, kdict, k); 1893 } 1894 regs[a] = mrb_bool_value(key_p); 1895 NEXT; 1896 } 1897 1898 CASE(OP_KEYEND, Z) { 1899 mrb_value kdict = regs[mrb->c->ci->argc]; 1900 1901 if (mrb_hash_p(kdict) && !mrb_hash_empty_p(mrb, kdict)) { 1902 mrb_value keys = mrb_hash_keys(mrb, kdict); 1903 mrb_value key1 = RARRAY_PTR(keys)[0]; 1904 mrb_value str = mrb_format(mrb, "unknown keyword: %v", key1); 1905 mrb_exc_set(mrb, mrb_exc_new_str(mrb, E_ARGUMENT_ERROR, str)); 1906 goto L_RAISE; 1907 } 1908 NEXT; 1909 } 1910 1911 CASE(OP_BREAK, B) { 1912 c = OP_R_BREAK; 1913 goto L_RETURN; 1914 } 1915 CASE(OP_RETURN_BLK, B) { 1916 c = OP_R_RETURN; 1917 goto L_RETURN; 1918 } 1919 CASE(OP_RETURN, B) 1920 c = OP_R_NORMAL; 1828 1921 L_RETURN: 1829 i = MKOP_AB(OP_RETURN, GETARG_A(i), OP_R_NORMAL); 1830 /* fall through */ 1831 CASE(OP_RETURN) { 1832 /* A B return R(A) (B=normal,in-block return/break) */ 1833 mrb_callinfo *ci; 1922 { 1923 mrb_callinfo *ci; 1924 1925 #define ecall_adjust() do {\ 1926 ptrdiff_t cioff = ci - mrb->c->cibase;\ 1927 ecall(mrb);\ 1928 ci = mrb->c->cibase + cioff;\ 1929 } while (0) 1834 1930 1835 1931 ci = mrb->c->ci; … … 1843 1939 blk = regs[ci->argc+1]; 1844 1940 } 1845 if (mrb_ type(blk) == MRB_TT_PROC) {1941 if (mrb_proc_p(blk)) { 1846 1942 struct RProc *p = mrb_proc_ptr(blk); 1847 1943 1848 if (!MRB_PROC_STRICT_P(p roc) &&1849 ci > mrb->c->cibase && p->env== ci[-1].env) {1944 if (!MRB_PROC_STRICT_P(p) && 1945 ci > mrb->c->cibase && MRB_PROC_ENV(p) == ci[-1].env) { 1850 1946 p->flags |= MRB_PROC_ORPHAN; 1851 1947 } … … 1855 1951 if (mrb->exc) { 1856 1952 mrb_callinfo *ci0; 1857 mrb_value *stk;1858 1953 1859 1954 L_RAISE: … … 1863 1958 goto L_RESCUE; 1864 1959 } 1865 stk = mrb->c->stack;1866 1960 while (ci[0].ridx == ci[-1].ridx) { 1867 1961 cipop(mrb); … … 1873 1967 ci = mrb->c->ci; 1874 1968 if (ci == mrb->c->cibase) { 1875 mrb->c->stack = stk;1876 1969 if (ci->ridx == 0) { 1877 1970 L_FTOP: /* fiber top */ … … 1883 1976 struct mrb_context *c = mrb->c; 1884 1977 1885 if (c->fib) {1886 mrb_write_barrier(mrb, (struct RBasic*)c->fib);1978 while (c->eidx > ci->epos) { 1979 ecall_adjust(); 1887 1980 } 1981 c->status = MRB_FIBER_TERMINATED; 1888 1982 mrb->c = c->prev; 1889 1983 c->prev = NULL; … … 1896 1990 if (ci[0].ridx == ci[-1].ridx) { 1897 1991 while (mrb->c->eidx > ci->epos) { 1898 ecall(mrb, --mrb->c->eidx); 1899 ci = mrb->c->ci; 1992 ecall_adjust(); 1900 1993 } 1901 1994 } … … 1907 2000 pool = irep->pool; 1908 2001 syms = irep->syms; 1909 if (ci !=ci0) {2002 if (ci < ci0) { 1910 2003 mrb->c->stack = ci[1].stackent; 1911 2004 } 1912 stack_extend(mrb, irep->nregs);1913 pc = mrb->c->rescue[--ci->ridx];2005 mrb_stack_extend(mrb, irep->nregs); 2006 pc = irep->iseq+mrb->c->rescue[--ci->ridx]; 1914 2007 } 1915 2008 else { 1916 2009 int acc; 1917 2010 mrb_value v; 1918 1919 v = regs[GETARG_A(i)]; 2011 struct RProc *dst; 2012 2013 ci = mrb->c->ci; 2014 v = regs[a]; 1920 2015 mrb_gc_protect(mrb, v); 1921 switch ( GETARG_B(i)) {2016 switch (c) { 1922 2017 case OP_R_RETURN: 1923 2018 /* Fall through to OP_R_NORMAL otherwise */ 1924 if (ci->acc >=0 && proc->env && !MRB_PROC_STRICT_P(proc)) { 1925 struct REnv *e = top_env(mrb, proc); 1926 mrb_callinfo *ce; 1927 1928 if (!MRB_ENV_STACK_SHARED_P(e) || e->cxt.c != mrb->c) { 1929 localjump_error(mrb, LOCALJUMP_ERROR_RETURN); 1930 goto L_RAISE; 2019 if (ci->acc >=0 && MRB_PROC_ENV_P(proc) && !MRB_PROC_STRICT_P(proc)) { 2020 mrb_callinfo *cibase = mrb->c->cibase; 2021 dst = top_proc(mrb, proc); 2022 2023 if (MRB_PROC_ENV_P(dst)) { 2024 struct REnv *e = MRB_PROC_ENV(dst); 2025 2026 if (!MRB_ENV_STACK_SHARED_P(e) || (e->cxt && e->cxt != mrb->c)) { 2027 localjump_error(mrb, LOCALJUMP_ERROR_RETURN); 2028 goto L_RAISE; 2029 } 1931 2030 } 1932 1933 ce = mrb->c->cibase + e->cioff; 1934 while (ci >= ce) { 1935 if (ci->env) { 1936 mrb_env_unshare(mrb, ci->env); 1937 } 2031 while (cibase <= ci && ci->proc != dst) { 1938 2032 if (ci->acc < 0) { 1939 2033 localjump_error(mrb, LOCALJUMP_ERROR_RETURN); … … 1942 2036 ci--; 1943 2037 } 1944 if (c e == mrb->c->cibase) {2038 if (ci <= cibase) { 1945 2039 localjump_error(mrb, LOCALJUMP_ERROR_RETURN); 1946 2040 goto L_RAISE; 1947 2041 } 1948 mrb->c->stack = mrb->c->ci->stackent;1949 mrb->c->ci = ce;1950 2042 break; 1951 2043 } 2044 /* fallthrough */ 1952 2045 case OP_R_NORMAL: 1953 2046 NORMAL_RETURN: 1954 2047 if (ci == mrb->c->cibase) { 1955 if (!mrb->c->prev) { /* toplevel return */ 1956 localjump_error(mrb, LOCALJUMP_ERROR_RETURN); 1957 goto L_RAISE; 2048 struct mrb_context *c = mrb->c; 2049 2050 if (!c->prev) { /* toplevel return */ 2051 regs[irep->nlocals] = v; 2052 goto L_STOP; 1958 2053 } 1959 if ( mrb->c->prev->ci == mrb->c->prev->cibase) {2054 if (c->prev->ci == c->prev->cibase) { 1960 2055 mrb_value exc = mrb_exc_new_str_lit(mrb, E_FIBER_ERROR, "double resume"); 1961 2056 mrb_exc_set(mrb, exc); 1962 2057 goto L_RAISE; 1963 2058 } 1964 while ( mrb->c->eidx > 0) {1965 ecall(mrb , --mrb->c->eidx);2059 while (c->eidx > 0) { 2060 ecall(mrb); 1966 2061 } 1967 2062 /* automatic yield at the end */ 1968 mrb->c->status = MRB_FIBER_TERMINATED; 1969 mrb->c = mrb->c->prev; 2063 c->status = MRB_FIBER_TERMINATED; 2064 mrb->c = c->prev; 2065 c->prev = NULL; 1970 2066 mrb->c->status = MRB_FIBER_RUNNING; 1971 }1972 ci = mrb->c->ci;2067 ci = mrb->c->ci; 2068 } 1973 2069 break; 1974 2070 case OP_R_BREAK: 1975 2071 if (MRB_PROC_STRICT_P(proc)) goto NORMAL_RETURN; 1976 if (MRB_PROC_ORPHAN_P(proc)) { 2072 if (MRB_PROC_ORPHAN_P(proc)) { 1977 2073 mrb_value exc; 1978 2074 … … 1983 2079 goto L_RAISE; 1984 2080 } 1985 if (! proc->env || !MRB_ENV_STACK_SHARED_P(proc->env)) {2081 if (!MRB_PROC_ENV_P(proc) || !MRB_ENV_STACK_SHARED_P(MRB_PROC_ENV(proc))) { 1986 2082 goto L_BREAK_ERROR; 1987 2083 } 2084 else { 2085 struct REnv *e = MRB_PROC_ENV(proc); 2086 2087 if (e->cxt != mrb->c) { 2088 goto L_BREAK_ERROR; 2089 } 2090 } 2091 while (mrb->c->eidx > mrb->c->ci->epos) { 2092 ecall_adjust(); 2093 } 1988 2094 /* break from fiber block */ 1989 if ( mrb->c->ci == mrb->c->cibase && mrb->c->ci->pc) {2095 if (ci == mrb->c->cibase && ci->pc) { 1990 2096 struct mrb_context *c = mrb->c; 1991 2097 1992 while (mrb->c->eidx > 0) {1993 ecall(mrb, --mrb->c->eidx);1994 }1995 2098 mrb->c = c->prev; 1996 2099 c->prev = NULL; … … 1998 2101 } 1999 2102 if (ci->acc < 0) { 2000 while (mrb->c->eidx > mrb->c->ci->epos) { 2001 ecall(mrb, --mrb->c->eidx); 2002 } 2003 ARENA_RESTORE(mrb, ai); 2103 mrb_gc_arena_restore(mrb, ai); 2004 2104 mrb->c->vmexec = FALSE; 2005 2105 mrb->exc = (struct RObject*)break_new(mrb, proc, v); … … 2009 2109 if (FALSE) { 2010 2110 L_BREAK: 2011 v = ((struct RBreak*)mrb->exc)->val;2012 proc = ((struct RBreak*)mrb->exc)->proc;2111 v = mrb_break_value_get((struct RBreak*)mrb->exc); 2112 proc = mrb_break_proc_get((struct RBreak*)mrb->exc); 2013 2113 mrb->exc = NULL; 2014 2114 ci = mrb->c->ci; 2015 2115 } 2016 2116 mrb->c->stack = ci->stackent; 2017 mrb->c->ci = mrb->c->cibase + proc->env->cioff + 1; 2018 while (ci > mrb->c->ci) { 2019 if (ci->env) { 2020 mrb_env_unshare(mrb, ci->env); 2021 } 2117 proc = proc->upper; 2118 while (mrb->c->cibase < ci && ci[-1].proc != proc) { 2022 2119 if (ci[-1].acc == CI_ACC_SKIP) { 2023 mrb->c->ci = ci; 2120 while (ci < mrb->c->ci) { 2121 cipop(mrb); 2122 } 2024 2123 goto L_BREAK_ERROR; 2025 2124 } 2026 2125 ci--; 2126 } 2127 if (ci == mrb->c->cibase) { 2128 goto L_BREAK_ERROR; 2027 2129 } 2028 2130 break; … … 2031 2133 break; 2032 2134 } 2033 while (mrb->c->eidx > mrb->c->ci->epos) { 2034 ecall(mrb, --mrb->c->eidx); 2035 } 2036 if (mrb->c->vmexec && !mrb->c->ci->target_class) { 2037 ARENA_RESTORE(mrb, ai); 2135 while (ci < mrb->c->ci) { 2136 cipop(mrb); 2137 } 2138 ci[0].ridx = ci[-1].ridx; 2139 while (mrb->c->eidx > ci->epos) { 2140 ecall_adjust(); 2141 } 2142 if (mrb->c->vmexec && !ci->target_class) { 2143 mrb_gc_arena_restore(mrb, ai); 2038 2144 mrb->c->vmexec = FALSE; 2039 2145 mrb->jmp = prev_jmp; 2040 2146 return v; 2041 2147 } 2042 ci = mrb->c->ci;2043 2148 acc = ci->acc; 2044 2149 mrb->c->stack = ci->stackent; 2045 2150 cipop(mrb); 2046 2151 if (acc == CI_ACC_SKIP || acc == CI_ACC_DIRECT) { 2047 ARENA_RESTORE(mrb, ai);2152 mrb_gc_arena_restore(mrb, ai); 2048 2153 mrb->jmp = prev_jmp; 2049 2154 return v; 2050 2155 } 2051 2156 pc = ci->pc; 2052 DEBUG(fprintf(stderr, "from :%s\n", mrb_sym2name(mrb, ci->mid))); 2157 ci = mrb->c->ci; 2158 DEBUG(fprintf(stderr, "from :%s\n", mrb_sym_name(mrb, ci->mid))); 2053 2159 proc = mrb->c->ci->proc; 2054 2160 irep = proc->body.irep; … … 2057 2163 2058 2164 regs[acc] = v; 2059 ARENA_RESTORE(mrb, ai);2165 mrb_gc_arena_restore(mrb, ai); 2060 2166 } 2061 2167 JUMP; 2062 2168 } 2063 2169 2064 CASE(OP_TAILCALL) { 2065 /* A B C return call(R(A),Syms(B),R(A+1),... ,R(A+C+1)) */ 2066 int a = GETARG_A(i); 2067 int n = GETARG_C(i); 2068 struct RProc *m; 2069 struct RClass *c; 2070 mrb_callinfo *ci; 2071 mrb_value recv; 2072 mrb_sym mid = syms[GETARG_B(i)]; 2073 2074 recv = regs[a]; 2075 c = mrb_class(mrb, recv); 2076 m = mrb_method_search_vm(mrb, &c, mid); 2077 if (!m) { 2078 mrb_value sym = mrb_symbol_value(mid); 2079 mrb_sym missing = mrb_intern_lit(mrb, "method_missing"); 2080 m = mrb_method_search_vm(mrb, &c, missing); 2081 if (!m) { 2082 mrb_value args; 2083 2084 if (n == CALL_MAXARGS) { 2085 args = regs[a+1]; 2086 } 2087 else { 2088 args = mrb_ary_new_from_values(mrb, n, regs+a+1); 2089 } 2090 ERR_PC_SET(mrb, pc); 2091 mrb_method_missing(mrb, mid, recv, args); 2092 } 2093 mid = missing; 2094 if (n == CALL_MAXARGS) { 2095 mrb_ary_unshift(mrb, regs[a+1], sym); 2096 } 2097 else { 2098 value_move(regs+a+2, regs+a+1, ++n); 2099 regs[a+1] = sym; 2100 } 2101 } 2102 2103 /* replace callinfo */ 2104 ci = mrb->c->ci; 2105 ci->mid = mid; 2106 ci->target_class = c; 2107 if (n == CALL_MAXARGS) { 2108 ci->argc = -1; 2109 } 2110 else { 2111 ci->argc = n; 2112 } 2113 2114 /* move stack */ 2115 value_move(mrb->c->stack, ®s[a], ci->argc+1); 2116 2117 if (MRB_PROC_CFUNC_P(m)) { 2118 mrb_value v = m->body.func(mrb, recv); 2119 mrb->c->stack[0] = v; 2120 mrb_gc_arena_restore(mrb, ai); 2121 goto L_RETURN; 2122 } 2123 else { 2124 /* setup environment for calling method */ 2125 irep = m->body.irep; 2126 pool = irep->pool; 2127 syms = irep->syms; 2128 if (ci->argc < 0) { 2129 stack_extend(mrb, (irep->nregs < 3) ? 3 : irep->nregs); 2130 } 2131 else { 2132 stack_extend(mrb, irep->nregs); 2133 } 2134 pc = irep->iseq; 2135 } 2136 JUMP; 2137 } 2138 2139 CASE(OP_BLKPUSH) { 2140 /* A Bx R(A) := block (16=6:1:5:4) */ 2141 int a = GETARG_A(i); 2142 int bx = GETARG_Bx(i); 2143 int m1 = (bx>>10)&0x3f; 2144 int r = (bx>>9)&0x1; 2145 int m2 = (bx>>4)&0x1f; 2146 int lv = (bx>>0)&0xf; 2170 CASE(OP_BLKPUSH, BS) { 2171 int m1 = (b>>11)&0x3f; 2172 int r = (b>>10)&0x1; 2173 int m2 = (b>>5)&0x1f; 2174 int kd = (b>>4)&0x1; 2175 int lv = (b>>0)&0xf; 2147 2176 mrb_value *stack; 2148 2177 … … 2150 2179 else { 2151 2180 struct REnv *e = uvenv(mrb, lv-1); 2152 if (!e || e->cioff == 0||2153 (!MRB_ENV_STACK_SHARED_P(e) && e->cxt.mid == 0)) {2181 if (!e || (!MRB_ENV_STACK_SHARED_P(e) && e->mid == 0) || 2182 MRB_ENV_STACK_LEN(e) <= m1+r+m2+1) { 2154 2183 localjump_error(mrb, LOCALJUMP_ERROR_YIELD); 2155 2184 goto L_RAISE; … … 2161 2190 goto L_RAISE; 2162 2191 } 2163 regs[a] = stack[m1+r+m2 ];2192 regs[a] = stack[m1+r+m2+kd]; 2164 2193 NEXT; 2165 2194 } 2166 2195 2167 2196 #define TYPES2(a,b) ((((uint16_t)(a))<<8)|(((uint16_t)(b))&0xff)) 2168 #define OP_MATH_BODY(op,v1,v2) do {\ 2169 v1(regs[a]) = v1(regs[a]) op v2(regs[a+1]);\ 2170 } while(0) 2171 2172 CASE(OP_ADD) { 2173 /* A B C R(A) := R(A)+R(A+1) (Syms[B]=:+,C=1)*/ 2174 int a = GETARG_A(i); 2197 #define OP_MATH(op_name) \ 2198 /* need to check if op is overridden */ \ 2199 switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) { \ 2200 OP_MATH_CASE_FIXNUM(op_name); \ 2201 OP_MATH_CASE_FLOAT(op_name, fixnum, float); \ 2202 OP_MATH_CASE_FLOAT(op_name, float, fixnum); \ 2203 OP_MATH_CASE_FLOAT(op_name, float, float); \ 2204 OP_MATH_CASE_STRING_##op_name(); \ 2205 default: \ 2206 c = 1; \ 2207 mid = mrb_intern_lit(mrb, MRB_STRINGIZE(OP_MATH_OP_##op_name)); \ 2208 goto L_SEND_SYM; \ 2209 } \ 2210 NEXT; 2211 #define OP_MATH_CASE_FIXNUM(op_name) \ 2212 case TYPES2(MRB_TT_FIXNUM, MRB_TT_FIXNUM): \ 2213 { \ 2214 mrb_int x = mrb_fixnum(regs[a]), y = mrb_fixnum(regs[a+1]), z; \ 2215 if (mrb_int_##op_name##_overflow(x, y, &z)) \ 2216 OP_MATH_OVERFLOW_INT(op_name, x, y, z); \ 2217 else \ 2218 SET_INT_VALUE(regs[a], z); \ 2219 } \ 2220 break 2221 #ifdef MRB_WITHOUT_FLOAT 2222 #define OP_MATH_CASE_FLOAT(op_name, t1, t2) (void)0 2223 #define OP_MATH_OVERFLOW_INT(op_name, x, y, z) SET_INT_VALUE(regs[a], z) 2224 #else 2225 #define OP_MATH_CASE_FLOAT(op_name, t1, t2) \ 2226 case TYPES2(OP_MATH_TT_##t1, OP_MATH_TT_##t2): \ 2227 { \ 2228 mrb_float z = mrb_##t1(regs[a]) OP_MATH_OP_##op_name mrb_##t2(regs[a+1]); \ 2229 SET_FLOAT_VALUE(mrb, regs[a], z); \ 2230 } \ 2231 break 2232 #define OP_MATH_OVERFLOW_INT(op_name, x, y, z) \ 2233 SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x OP_MATH_OP_##op_name (mrb_float)y) 2234 #endif 2235 #define OP_MATH_CASE_STRING_add() \ 2236 case TYPES2(MRB_TT_STRING, MRB_TT_STRING): \ 2237 regs[a] = mrb_str_plus(mrb, regs[a], regs[a+1]); \ 2238 mrb_gc_arena_restore(mrb, ai); \ 2239 break 2240 #define OP_MATH_CASE_STRING_sub() (void)0 2241 #define OP_MATH_CASE_STRING_mul() (void)0 2242 #define OP_MATH_OP_add + 2243 #define OP_MATH_OP_sub - 2244 #define OP_MATH_OP_mul * 2245 #define OP_MATH_TT_fixnum MRB_TT_FIXNUM 2246 #define OP_MATH_TT_float MRB_TT_FLOAT 2247 2248 CASE(OP_ADD, B) { 2249 OP_MATH(add); 2250 } 2251 2252 CASE(OP_SUB, B) { 2253 OP_MATH(sub); 2254 } 2255 2256 CASE(OP_MUL, B) { 2257 OP_MATH(mul); 2258 } 2259 2260 CASE(OP_DIV, B) { 2261 #ifndef MRB_WITHOUT_FLOAT 2262 double x, y, f; 2263 #endif 2175 2264 2176 2265 /* need to check if op is overridden */ 2177 2266 switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) { 2178 2267 case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM): 2179 { 2180 mrb_int x, y, z; 2181 mrb_value *regs_a = regs + a; 2182 2183 x = mrb_fixnum(regs_a[0]); 2184 y = mrb_fixnum(regs_a[1]); 2185 if (mrb_int_add_overflow(x, y, &z)) { 2186 SET_FLOAT_VALUE(mrb, regs_a[0], (mrb_float)x + (mrb_float)y); 2187 break; 2188 } 2189 SET_INT_VALUE(regs[a], z); 2190 } 2191 break; 2192 case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT): 2193 { 2194 mrb_int x = mrb_fixnum(regs[a]); 2195 mrb_float y = mrb_float(regs[a+1]); 2196 SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x + y); 2197 } 2198 break; 2199 case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM): 2200 #ifdef MRB_WORD_BOXING 2201 { 2202 mrb_float x = mrb_float(regs[a]); 2203 mrb_int y = mrb_fixnum(regs[a+1]); 2204 SET_FLOAT_VALUE(mrb, regs[a], x + y); 2205 } 2206 #else 2207 OP_MATH_BODY(+,mrb_float,mrb_fixnum); 2208 #endif 2209 break; 2210 case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT): 2211 #ifdef MRB_WORD_BOXING 2212 { 2213 mrb_float x = mrb_float(regs[a]); 2214 mrb_float y = mrb_float(regs[a+1]); 2215 SET_FLOAT_VALUE(mrb, regs[a], x + y); 2216 } 2217 #else 2218 OP_MATH_BODY(+,mrb_float,mrb_float); 2219 #endif 2220 break; 2221 case TYPES2(MRB_TT_STRING,MRB_TT_STRING): 2222 regs[a] = mrb_str_plus(mrb, regs[a], regs[a+1]); 2223 break; 2224 default: 2225 goto L_SEND; 2226 } 2227 ARENA_RESTORE(mrb, ai); 2228 NEXT; 2229 } 2230 2231 CASE(OP_SUB) { 2232 /* A B C R(A) := R(A)-R(A+1) (Syms[B]=:-,C=1)*/ 2233 int a = GETARG_A(i); 2234 2235 /* need to check if op is overridden */ 2236 switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) { 2237 case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM): 2238 { 2239 mrb_int x, y, z; 2240 2241 x = mrb_fixnum(regs[a]); 2242 y = mrb_fixnum(regs[a+1]); 2243 if (mrb_int_sub_overflow(x, y, &z)) { 2244 SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x - (mrb_float)y); 2245 break; 2246 } 2247 SET_INT_VALUE(regs[a], z); 2248 } 2249 break; 2250 case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT): 2251 { 2252 mrb_int x = mrb_fixnum(regs[a]); 2253 mrb_float y = mrb_float(regs[a+1]); 2254 SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x - y); 2255 } 2256 break; 2257 case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM): 2258 #ifdef MRB_WORD_BOXING 2259 { 2260 mrb_float x = mrb_float(regs[a]); 2261 mrb_int y = mrb_fixnum(regs[a+1]); 2262 SET_FLOAT_VALUE(mrb, regs[a], x - y); 2263 } 2264 #else 2265 OP_MATH_BODY(-,mrb_float,mrb_fixnum); 2266 #endif 2267 break; 2268 case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT): 2269 #ifdef MRB_WORD_BOXING 2270 { 2271 mrb_float x = mrb_float(regs[a]); 2272 mrb_float y = mrb_float(regs[a+1]); 2273 SET_FLOAT_VALUE(mrb, regs[a], x - y); 2274 } 2275 #else 2276 OP_MATH_BODY(-,mrb_float,mrb_float); 2277 #endif 2278 break; 2279 default: 2280 goto L_SEND; 2281 } 2282 NEXT; 2283 } 2284 2285 CASE(OP_MUL) { 2286 /* A B C R(A) := R(A)*R(A+1) (Syms[B]=:*,C=1)*/ 2287 int a = GETARG_A(i); 2288 2289 /* need to check if op is overridden */ 2290 switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) { 2291 case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM): 2292 { 2293 mrb_int x, y, z; 2294 2295 x = mrb_fixnum(regs[a]); 2296 y = mrb_fixnum(regs[a+1]); 2297 if (mrb_int_mul_overflow(x, y, &z)) { 2298 SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x * (mrb_float)y); 2299 break; 2300 } 2301 SET_INT_VALUE(regs[a], z); 2302 } 2303 break; 2304 case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT): 2305 { 2306 mrb_int x = mrb_fixnum(regs[a]); 2307 mrb_float y = mrb_float(regs[a+1]); 2308 SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x * y); 2309 } 2310 break; 2311 case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM): 2312 #ifdef MRB_WORD_BOXING 2313 { 2314 mrb_float x = mrb_float(regs[a]); 2315 mrb_int y = mrb_fixnum(regs[a+1]); 2316 SET_FLOAT_VALUE(mrb, regs[a], x * y); 2317 } 2318 #else 2319 OP_MATH_BODY(*,mrb_float,mrb_fixnum); 2320 #endif 2321 break; 2322 case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT): 2323 #ifdef MRB_WORD_BOXING 2324 { 2325 mrb_float x = mrb_float(regs[a]); 2326 mrb_float y = mrb_float(regs[a+1]); 2327 SET_FLOAT_VALUE(mrb, regs[a], x * y); 2328 } 2329 #else 2330 OP_MATH_BODY(*,mrb_float,mrb_float); 2331 #endif 2332 break; 2333 default: 2334 goto L_SEND; 2335 } 2336 NEXT; 2337 } 2338 2339 CASE(OP_DIV) { 2340 /* A B C R(A) := R(A)/R(A+1) (Syms[B]=:/,C=1)*/ 2341 int a = GETARG_A(i); 2342 2343 /* need to check if op is overridden */ 2344 switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) { 2345 case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM): 2268 #ifdef MRB_WITHOUT_FLOAT 2346 2269 { 2347 2270 mrb_int x = mrb_fixnum(regs[a]); 2348 2271 mrb_int y = mrb_fixnum(regs[a+1]); 2349 SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x / (mrb_float)y); 2350 } 2272 SET_INT_VALUE(regs[a], y ? x / y : 0); 2273 } 2274 break; 2275 #else 2276 x = (mrb_float)mrb_fixnum(regs[a]); 2277 y = (mrb_float)mrb_fixnum(regs[a+1]); 2351 2278 break; 2352 2279 case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT): 2353 { 2354 mrb_int x = mrb_fixnum(regs[a]); 2355 mrb_float y = mrb_float(regs[a+1]); 2356 SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x / y); 2357 } 2280 x = (mrb_float)mrb_fixnum(regs[a]); 2281 y = mrb_float(regs[a+1]); 2358 2282 break; 2359 2283 case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM): 2360 #ifdef MRB_WORD_BOXING 2361 { 2362 mrb_float x = mrb_float(regs[a]); 2363 mrb_int y = mrb_fixnum(regs[a+1]); 2364 SET_FLOAT_VALUE(mrb, regs[a], x / y); 2365 } 2366 #else 2367 OP_MATH_BODY(/,mrb_float,mrb_fixnum); 2368 #endif 2284 x = mrb_float(regs[a]); 2285 y = (mrb_float)mrb_fixnum(regs[a+1]); 2369 2286 break; 2370 2287 case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT): 2371 #ifdef MRB_WORD_BOXING 2372 { 2373 mrb_float x = mrb_float(regs[a]); 2374 mrb_float y = mrb_float(regs[a+1]); 2375 SET_FLOAT_VALUE(mrb, regs[a], x / y); 2376 } 2288 x = mrb_float(regs[a]); 2289 y = mrb_float(regs[a+1]); 2290 break; 2291 #endif 2292 default: 2293 c = 1; 2294 mid = mrb_intern_lit(mrb, "/"); 2295 goto L_SEND_SYM; 2296 } 2297 2298 #ifndef MRB_WITHOUT_FLOAT 2299 if (y == 0) { 2300 if (x > 0) f = INFINITY; 2301 else if (x < 0) f = -INFINITY; 2302 else /* if (x == 0) */ f = NAN; 2303 } 2304 else { 2305 f = x / y; 2306 } 2307 SET_FLOAT_VALUE(mrb, regs[a], f); 2308 #endif 2309 NEXT; 2310 } 2311 2312 #define OP_MATHI(op_name) \ 2313 /* need to check if op is overridden */ \ 2314 switch (mrb_type(regs[a])) { \ 2315 OP_MATHI_CASE_FIXNUM(op_name); \ 2316 OP_MATHI_CASE_FLOAT(op_name); \ 2317 default: \ 2318 SET_INT_VALUE(regs[a+1], b); \ 2319 c = 1; \ 2320 mid = mrb_intern_lit(mrb, MRB_STRINGIZE(OP_MATH_OP_##op_name)); \ 2321 goto L_SEND_SYM; \ 2322 } \ 2323 NEXT; 2324 #define OP_MATHI_CASE_FIXNUM(op_name) \ 2325 case MRB_TT_FIXNUM: \ 2326 { \ 2327 mrb_int x = mrb_fixnum(regs[a]), y = (mrb_int)b, z; \ 2328 if (mrb_int_##op_name##_overflow(x, y, &z)) \ 2329 OP_MATH_OVERFLOW_INT(op_name, x, y, z); \ 2330 else \ 2331 SET_INT_VALUE(regs[a], z); \ 2332 } \ 2333 break 2334 #ifdef MRB_WITHOUT_FLOAT 2335 #define OP_MATHI_CASE_FLOAT(op_name) (void)0 2377 2336 #else 2378 OP_MATH_BODY(/,mrb_float,mrb_float); 2379 #endif 2380 break; 2381 default: 2382 goto L_SEND; 2383 } 2384 #ifdef MRB_NAN_BOXING 2385 if (isnan(mrb_float(regs[a]))) { 2386 mrb_value v = mrb_float_value(mrb, mrb_float(regs[a])); 2387 regs[a] = v; 2388 } 2389 #endif 2390 NEXT; 2391 } 2392 2393 CASE(OP_ADDI) { 2394 /* A B C R(A) := R(A)+C (Syms[B]=:+)*/ 2395 int a = GETARG_A(i); 2396 2397 /* need to check if + is overridden */ 2398 switch (mrb_type(regs[a])) { 2399 case MRB_TT_FIXNUM: 2400 { 2401 mrb_int x = mrb_fixnum(regs[a]); 2402 mrb_int y = GETARG_C(i); 2403 mrb_int z; 2404 2405 if (mrb_int_add_overflow(x, y, &z)) { 2406 SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x + (mrb_float)y); 2407 break; 2408 } 2409 SET_INT_VALUE(regs[a], z); 2410 } 2411 break; 2412 case MRB_TT_FLOAT: 2413 #ifdef MRB_WORD_BOXING 2414 { 2415 mrb_float x = mrb_float(regs[a]); 2416 SET_FLOAT_VALUE(mrb, regs[a], x + GETARG_C(i)); 2417 } 2337 #define OP_MATHI_CASE_FLOAT(op_name) \ 2338 case MRB_TT_FLOAT: \ 2339 { \ 2340 mrb_float z = mrb_float(regs[a]) OP_MATH_OP_##op_name b; \ 2341 SET_FLOAT_VALUE(mrb, regs[a], z); \ 2342 } \ 2343 break 2344 #endif 2345 2346 CASE(OP_ADDI, BB) { 2347 OP_MATHI(add); 2348 } 2349 2350 CASE(OP_SUBI, BB) { 2351 OP_MATHI(sub); 2352 } 2353 2354 #define OP_CMP_BODY(op,v1,v2) (v1(regs[a]) op v2(regs[a+1])) 2355 2356 #ifdef MRB_WITHOUT_FLOAT 2357 #define OP_CMP(op) do {\ 2358 int result;\ 2359 /* need to check if - is overridden */\ 2360 switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) {\ 2361 case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM):\ 2362 result = OP_CMP_BODY(op,mrb_fixnum,mrb_fixnum);\ 2363 break;\ 2364 default:\ 2365 c = 1;\ 2366 mid = mrb_intern_lit(mrb, # op);\ 2367 goto L_SEND_SYM;\ 2368 }\ 2369 if (result) {\ 2370 SET_TRUE_VALUE(regs[a]);\ 2371 }\ 2372 else {\ 2373 SET_FALSE_VALUE(regs[a]);\ 2374 }\ 2375 } while(0) 2418 2376 #else 2419 mrb_float(regs[a]) += GETARG_C(i);2420 #endif2421 break;2422 default:2423 SET_INT_VALUE(regs[a+1], GETARG_C(i));2424 i = MKOP_ABC(OP_SEND, a, GETARG_B(i), 1);2425 goto L_SEND;2426 }2427 NEXT;2428 }2429 2430 CASE(OP_SUBI) {2431 /* A B C R(A) := R(A)-C (Syms[B]=:-)*/2432 int a = GETARG_A(i);2433 mrb_value *regs_a = regs + a;2434 2435 /* need to check if + is overridden */2436 switch (mrb_type(regs_a[0])) {2437 case MRB_TT_FIXNUM:2438 {2439 mrb_int x = mrb_fixnum(regs_a[0]);2440 mrb_int y = GETARG_C(i);2441 mrb_int z;2442 2443 if (mrb_int_sub_overflow(x, y, &z)) {2444 SET_FLOAT_VALUE(mrb, regs_a[0], (mrb_float)x - (mrb_float)y);2445 }2446 else {2447 SET_INT_VALUE(regs_a[0], z);2448 }2449 }2450 break;2451 case MRB_TT_FLOAT:2452 #ifdef MRB_WORD_BOXING2453 {2454 mrb_float x = mrb_float(regs[a]);2455 SET_FLOAT_VALUE(mrb, regs[a], x - GETARG_C(i));2456 }2457 #else2458 mrb_float(regs_a[0]) -= GETARG_C(i);2459 #endif2460 break;2461 default:2462 SET_INT_VALUE(regs_a[1], GETARG_C(i));2463 i = MKOP_ABC(OP_SEND, a, GETARG_B(i), 1);2464 goto L_SEND;2465 }2466 NEXT;2467 }2468 2469 #define OP_CMP_BODY(op,v1,v2) (v1(regs[a]) op v2(regs[a+1]))2470 2471 2377 #define OP_CMP(op) do {\ 2472 2378 int result;\ … … 2486 2392 break;\ 2487 2393 default:\ 2488 goto L_SEND;\ 2394 c = 1;\ 2395 mid = mrb_intern_lit(mrb, # op);\ 2396 goto L_SEND_SYM;\ 2489 2397 }\ 2490 2398 if (result) {\ … … 2495 2403 }\ 2496 2404 } while(0) 2497 2498 CASE(OP_EQ) { 2499 /* A B C R(A) := R(A)==R(A+1) (Syms[B]=:==,C=1)*/ 2500 int a = GETARG_A(i); 2405 #endif 2406 2407 CASE(OP_EQ, B) { 2501 2408 if (mrb_obj_eq(mrb, regs[a], regs[a+1])) { 2502 2409 SET_TRUE_VALUE(regs[a]); … … 2508 2415 } 2509 2416 2510 CASE(OP_LT) { 2511 /* A B C R(A) := R(A)<R(A+1) (Syms[B]=:<,C=1)*/ 2512 int a = GETARG_A(i); 2417 CASE(OP_LT, B) { 2513 2418 OP_CMP(<); 2514 2419 NEXT; 2515 2420 } 2516 2421 2517 CASE(OP_LE) { 2518 /* A B C R(A) := R(A)<=R(A+1) (Syms[B]=:<=,C=1)*/ 2519 int a = GETARG_A(i); 2422 CASE(OP_LE, B) { 2520 2423 OP_CMP(<=); 2521 2424 NEXT; 2522 2425 } 2523 2426 2524 CASE(OP_GT) { 2525 /* A B C R(A) := R(A)>R(A+1) (Syms[B]=:>,C=1)*/ 2526 int a = GETARG_A(i); 2427 CASE(OP_GT, B) { 2527 2428 OP_CMP(>); 2528 2429 NEXT; 2529 2430 } 2530 2431 2531 CASE(OP_GE) { 2532 /* A B C R(A) := R(A)>=R(A+1) (Syms[B]=:>=,C=1)*/ 2533 int a = GETARG_A(i); 2432 CASE(OP_GE, B) { 2534 2433 OP_CMP(>=); 2535 2434 NEXT; 2536 2435 } 2537 2436 2538 CASE(OP_ARRAY) { 2539 /* A B C R(A) := ary_new(R(B),R(B+1)..R(B+C)) */ 2540 int a = GETARG_A(i); 2541 int b = GETARG_B(i); 2542 int c = GETARG_C(i); 2437 CASE(OP_ARRAY, BB) { 2438 mrb_value v = mrb_ary_new_from_values(mrb, b, ®s[a]); 2439 regs[a] = v; 2440 mrb_gc_arena_restore(mrb, ai); 2441 NEXT; 2442 } 2443 CASE(OP_ARRAY2, BBB) { 2543 2444 mrb_value v = mrb_ary_new_from_values(mrb, c, ®s[b]); 2544 2445 regs[a] = v; 2545 ARENA_RESTORE(mrb, ai); 2546 NEXT; 2547 } 2548 2549 CASE(OP_ARYCAT) { 2550 /* A B mrb_ary_concat(R(A),R(B)) */ 2551 int a = GETARG_A(i); 2552 int b = GETARG_B(i); 2553 mrb_value splat = mrb_ary_splat(mrb, regs[b]); 2554 mrb_ary_concat(mrb, regs[a], splat); 2555 ARENA_RESTORE(mrb, ai); 2556 NEXT; 2557 } 2558 2559 CASE(OP_ARYPUSH) { 2560 /* A B R(A).push(R(B)) */ 2561 int a = GETARG_A(i); 2562 int b = GETARG_B(i); 2563 mrb_ary_push(mrb, regs[a], regs[b]); 2564 NEXT; 2565 } 2566 2567 CASE(OP_AREF) { 2568 /* A B C R(A) := R(B)[C] */ 2569 int a = GETARG_A(i); 2570 int b = GETARG_B(i); 2571 int c = GETARG_C(i); 2446 mrb_gc_arena_restore(mrb, ai); 2447 NEXT; 2448 } 2449 2450 CASE(OP_ARYCAT, B) { 2451 mrb_value splat = mrb_ary_splat(mrb, regs[a+1]); 2452 if (mrb_nil_p(regs[a])) { 2453 regs[a] = splat; 2454 } 2455 else { 2456 mrb_ary_concat(mrb, regs[a], splat); 2457 } 2458 mrb_gc_arena_restore(mrb, ai); 2459 NEXT; 2460 } 2461 2462 CASE(OP_ARYPUSH, B) { 2463 mrb_ary_push(mrb, regs[a], regs[a+1]); 2464 NEXT; 2465 } 2466 2467 CASE(OP_ARYDUP, B) { 2468 mrb_value ary = regs[a]; 2469 if (mrb_array_p(ary)) { 2470 ary = mrb_ary_new_from_values(mrb, RARRAY_LEN(ary), RARRAY_PTR(ary)); 2471 } 2472 else { 2473 ary = mrb_ary_new_from_values(mrb, 1, &ary); 2474 } 2475 regs[a] = ary; 2476 NEXT; 2477 } 2478 2479 CASE(OP_AREF, BBB) { 2572 2480 mrb_value v = regs[b]; 2573 2481 … … 2587 2495 } 2588 2496 2589 CASE(OP_ASET) { 2590 /* A B C R(B)[C] := R(A) */ 2591 int a = GETARG_A(i); 2592 int b = GETARG_B(i); 2593 int c = GETARG_C(i); 2497 CASE(OP_ASET, BBB) { 2594 2498 mrb_ary_set(mrb, regs[b], c, regs[a]); 2595 2499 NEXT; 2596 2500 } 2597 2501 2598 CASE(OP_APOST) { 2599 /* A B C *R(A),R(A+1)..R(A+C) := R(A) */ 2600 int a = GETARG_A(i); 2502 CASE(OP_APOST, BBB) { 2601 2503 mrb_value v = regs[a]; 2602 int pre = GETARG_B(i);2603 int post = GETARG_C(i);2504 int pre = b; 2505 int post = c; 2604 2506 struct RArray *ary; 2605 2507 int len, idx; … … 2609 2511 } 2610 2512 ary = mrb_ary_ptr(v); 2611 len = ary->len;2513 len = (int)ARY_LEN(ary); 2612 2514 if (len > pre + post) { 2613 v = mrb_ary_new_from_values(mrb, len - pre - post, ary->ptr+pre);2515 v = mrb_ary_new_from_values(mrb, len - pre - post, ARY_PTR(ary)+pre); 2614 2516 regs[a++] = v; 2615 2517 while (post--) { 2616 regs[a++] = ary->ptr[len-post-1];2518 regs[a++] = ARY_PTR(ary)[len-post-1]; 2617 2519 } 2618 2520 } … … 2621 2523 regs[a++] = v; 2622 2524 for (idx=0; idx+pre<len; idx++) { 2623 regs[a+idx] = ary->ptr[pre+idx];2525 regs[a+idx] = ARY_PTR(ary)[pre+idx]; 2624 2526 } 2625 2527 while (idx < post) { … … 2628 2530 } 2629 2531 } 2630 ARENA_RESTORE(mrb, ai); 2631 NEXT; 2632 } 2633 2634 CASE(OP_STRING) { 2635 /* A Bx R(A) := str_new(Lit(Bx)) */ 2636 mrb_value str = mrb_str_dup(mrb, pool[GETARG_Bx(i)]); 2637 regs[GETARG_A(i)] = str; 2638 ARENA_RESTORE(mrb, ai); 2639 NEXT; 2640 } 2641 2642 CASE(OP_STRCAT) { 2643 /* A B R(A).concat(R(B)) */ 2644 mrb_str_concat(mrb, regs[GETARG_A(i)], regs[GETARG_B(i)]); 2645 NEXT; 2646 } 2647 2648 CASE(OP_HASH) { 2649 /* A B C R(A) := hash_new(R(B),R(B+1)..R(B+C)) */ 2650 int b = GETARG_B(i); 2651 int c = GETARG_C(i); 2652 int lim = b+c*2; 2653 mrb_value hash = mrb_hash_new_capa(mrb, c); 2654 2655 while (b < lim) { 2656 mrb_hash_set(mrb, hash, regs[b], regs[b+1]); 2657 b+=2; 2658 } 2659 regs[GETARG_A(i)] = hash; 2660 ARENA_RESTORE(mrb, ai); 2661 NEXT; 2662 } 2663 2664 CASE(OP_LAMBDA) { 2665 /* A b c R(A) := lambda(SEQ[b],c) (b:c = 14:2) */ 2532 mrb_gc_arena_restore(mrb, ai); 2533 NEXT; 2534 } 2535 2536 CASE(OP_INTERN, B) { 2537 mrb_sym sym = mrb_intern_str(mrb, regs[a]); 2538 2539 regs[a] = mrb_symbol_value(sym); 2540 mrb_gc_arena_restore(mrb, ai); 2541 NEXT; 2542 } 2543 2544 CASE(OP_STRING, BB) { 2545 mrb_value str = mrb_str_dup(mrb, pool[b]); 2546 2547 regs[a] = str; 2548 mrb_gc_arena_restore(mrb, ai); 2549 NEXT; 2550 } 2551 2552 CASE(OP_STRCAT, B) { 2553 mrb_str_concat(mrb, regs[a], regs[a+1]); 2554 NEXT; 2555 } 2556 2557 CASE(OP_HASH, BB) { 2558 mrb_value hash = mrb_hash_new_capa(mrb, b); 2559 int i; 2560 int lim = a+b*2; 2561 2562 for (i=a; i<lim; i+=2) { 2563 mrb_hash_set(mrb, hash, regs[i], regs[i+1]); 2564 } 2565 regs[a] = hash; 2566 mrb_gc_arena_restore(mrb, ai); 2567 NEXT; 2568 } 2569 2570 CASE(OP_HASHADD, BB) { 2571 mrb_value hash; 2572 int i; 2573 int lim = a+b*2+1; 2574 2575 hash = mrb_ensure_hash_type(mrb, regs[a]); 2576 for (i=a+1; i<lim; i+=2) { 2577 mrb_hash_set(mrb, hash, regs[i], regs[i+1]); 2578 } 2579 mrb_gc_arena_restore(mrb, ai); 2580 NEXT; 2581 } 2582 CASE(OP_HASHCAT, B) { 2583 mrb_value hash = mrb_ensure_hash_type(mrb, regs[a]); 2584 2585 mrb_hash_merge(mrb, hash, regs[a+1]); 2586 mrb_gc_arena_restore(mrb, ai); 2587 NEXT; 2588 } 2589 2590 CASE(OP_LAMBDA, BB) 2591 c = OP_L_LAMBDA; 2592 L_MAKE_LAMBDA: 2593 { 2666 2594 struct RProc *p; 2667 int c = GETARG_c(i);2595 mrb_irep *nirep = irep->reps[b]; 2668 2596 2669 2597 if (c & OP_L_CAPTURE) { 2670 p = mrb_closure_new(mrb, irep->reps[GETARG_b(i)]);2598 p = mrb_closure_new(mrb, nirep); 2671 2599 } 2672 2600 else { 2673 p = mrb_proc_new(mrb, irep->reps[GETARG_b(i)]); 2601 p = mrb_proc_new(mrb, nirep); 2602 p->flags |= MRB_PROC_SCOPE; 2674 2603 } 2675 2604 if (c & OP_L_STRICT) p->flags |= MRB_PROC_STRICT; 2676 regs[GETARG_A(i)] = mrb_obj_value(p); 2677 ARENA_RESTORE(mrb, ai); 2678 NEXT; 2679 } 2680 2681 CASE(OP_OCLASS) { 2682 /* A R(A) := ::Object */ 2683 regs[GETARG_A(i)] = mrb_obj_value(mrb->object_class); 2684 NEXT; 2685 } 2686 2687 CASE(OP_CLASS) { 2688 /* A B R(A) := newclass(R(A),Syms(B),R(A+1)) */ 2605 regs[a] = mrb_obj_value(p); 2606 mrb_gc_arena_restore(mrb, ai); 2607 NEXT; 2608 } 2609 CASE(OP_BLOCK, BB) { 2610 c = OP_L_BLOCK; 2611 goto L_MAKE_LAMBDA; 2612 } 2613 CASE(OP_METHOD, BB) { 2614 c = OP_L_METHOD; 2615 goto L_MAKE_LAMBDA; 2616 } 2617 2618 CASE(OP_RANGE_INC, B) { 2619 mrb_value val = mrb_range_new(mrb, regs[a], regs[a+1], FALSE); 2620 regs[a] = val; 2621 mrb_gc_arena_restore(mrb, ai); 2622 NEXT; 2623 } 2624 2625 CASE(OP_RANGE_EXC, B) { 2626 mrb_value val = mrb_range_new(mrb, regs[a], regs[a+1], TRUE); 2627 regs[a] = val; 2628 mrb_gc_arena_restore(mrb, ai); 2629 NEXT; 2630 } 2631 2632 CASE(OP_OCLASS, B) { 2633 regs[a] = mrb_obj_value(mrb->object_class); 2634 NEXT; 2635 } 2636 2637 CASE(OP_CLASS, BB) { 2689 2638 struct RClass *c = 0, *baseclass; 2690 int a = GETARG_A(i);2691 2639 mrb_value base, super; 2692 mrb_sym id = syms[ GETARG_B(i)];2640 mrb_sym id = syms[b]; 2693 2641 2694 2642 base = regs[a]; 2695 2643 super = regs[a+1]; 2696 2644 if (mrb_nil_p(base)) { 2697 baseclass = mrb->c->ci->proc->target_class; 2698 if (!baseclass) baseclass = mrb->c->ci->target_class; 2699 2645 baseclass = MRB_PROC_TARGET_CLASS(mrb->c->ci->proc); 2700 2646 base = mrb_obj_value(baseclass); 2701 2647 } 2702 2648 c = mrb_vm_define_class(mrb, base, super, id); 2703 2649 regs[a] = mrb_obj_value(c); 2704 ARENA_RESTORE(mrb, ai); 2705 NEXT; 2706 } 2707 2708 CASE(OP_MODULE) { 2709 /* A B R(A) := newmodule(R(A),Syms(B)) */ 2710 struct RClass *c = 0, *baseclass; 2711 int a = GETARG_A(i); 2650 mrb_gc_arena_restore(mrb, ai); 2651 NEXT; 2652 } 2653 2654 CASE(OP_MODULE, BB) { 2655 struct RClass *cls = 0, *baseclass; 2712 2656 mrb_value base; 2713 mrb_sym id = syms[ GETARG_B(i)];2657 mrb_sym id = syms[b]; 2714 2658 2715 2659 base = regs[a]; 2716 2660 if (mrb_nil_p(base)) { 2717 baseclass = mrb->c->ci->proc->target_class; 2718 if (!baseclass) baseclass = mrb->c->ci->target_class; 2719 2661 baseclass = MRB_PROC_TARGET_CLASS(mrb->c->ci->proc); 2720 2662 base = mrb_obj_value(baseclass); 2721 2663 } 2722 c = mrb_vm_define_module(mrb, base, id); 2723 regs[a] = mrb_obj_value(c); 2724 ARENA_RESTORE(mrb, ai); 2725 NEXT; 2726 } 2727 2728 CASE(OP_EXEC) { 2729 /* A Bx R(A) := blockexec(R(A),SEQ[Bx]) */ 2730 int a = GETARG_A(i); 2664 cls = mrb_vm_define_module(mrb, base, id); 2665 regs[a] = mrb_obj_value(cls); 2666 mrb_gc_arena_restore(mrb, ai); 2667 NEXT; 2668 } 2669 2670 CASE(OP_EXEC, BB) { 2731 2671 mrb_callinfo *ci; 2732 2672 mrb_value recv = regs[a]; 2733 2673 struct RProc *p; 2674 mrb_irep *nirep = irep->reps[b]; 2734 2675 2735 2676 /* prepare closure */ 2736 p = mrb_ closure_new(mrb, irep->reps[GETARG_Bx(i)]);2677 p = mrb_proc_new(mrb, nirep); 2737 2678 p->c = NULL; 2738 2739 /* prepare stack */ 2679 mrb_field_write_barrier(mrb, (struct RBasic*)p, (struct RBasic*)proc); 2680 MRB_PROC_SET_TARGET_CLASS(p, mrb_class_ptr(recv)); 2681 p->flags |= MRB_PROC_SCOPE; 2682 2683 /* prepare call stack */ 2740 2684 ci = cipush(mrb); 2741 ci->pc = pc + 1;2685 ci->pc = pc; 2742 2686 ci->acc = a; 2743 2687 ci->mid = 0; … … 2749 2693 mrb->c->stack += a; 2750 2694 2751 /* setup closure */ 2752 p->target_class = ci->target_class; 2695 /* setup block to call */ 2753 2696 ci->proc = p; 2754 2697 … … 2756 2699 pool = irep->pool; 2757 2700 syms = irep->syms; 2758 stack_extend(mrb, irep->nregs);2701 mrb_stack_extend(mrb, irep->nregs); 2759 2702 stack_clear(regs+1, irep->nregs-1); 2760 ci->nregs = irep->nregs;2761 2703 pc = irep->iseq; 2762 2704 JUMP; 2763 2705 } 2764 2706 2765 CASE(OP_METHOD) { 2766 /* A B R(A).newmethod(Syms(B),R(A+1)) */ 2767 int a = GETARG_A(i); 2768 struct RClass *c = mrb_class_ptr(regs[a]); 2707 CASE(OP_DEF, BB) { 2708 struct RClass *target = mrb_class_ptr(regs[a]); 2769 2709 struct RProc *p = mrb_proc_ptr(regs[a+1]); 2770 2771 mrb_define_method_raw(mrb, c, syms[GETARG_B(i)], p); 2772 ARENA_RESTORE(mrb, ai); 2773 NEXT; 2774 } 2775 2776 CASE(OP_SCLASS) { 2777 /* A B R(A) := R(B).singleton_class */ 2778 regs[GETARG_A(i)] = mrb_singleton_class(mrb, regs[GETARG_B(i)]); 2779 ARENA_RESTORE(mrb, ai); 2780 NEXT; 2781 } 2782 2783 CASE(OP_TCLASS) { 2784 /* A R(A) := target_class */ 2785 if (!mrb->c->ci->target_class) { 2786 mrb_value exc = mrb_exc_new_str_lit(mrb, E_TYPE_ERROR, "no target class or module"); 2787 mrb_exc_set(mrb, exc); 2788 goto L_RAISE; 2789 } 2790 regs[GETARG_A(i)] = mrb_obj_value(mrb->c->ci->target_class); 2791 NEXT; 2792 } 2793 2794 CASE(OP_RANGE) { 2795 /* A B C R(A) := range_new(R(B),R(B+1),C) */ 2796 int b = GETARG_B(i); 2797 mrb_value val = mrb_range_new(mrb, regs[b], regs[b+1], GETARG_C(i)); 2798 regs[GETARG_A(i)] = val; 2799 ARENA_RESTORE(mrb, ai); 2800 NEXT; 2801 } 2802 2803 CASE(OP_DEBUG) { 2804 /* A B C debug print R(A),R(B),R(C) */ 2710 mrb_method_t m; 2711 2712 MRB_METHOD_FROM_PROC(m, p); 2713 mrb_define_method_raw(mrb, target, syms[b], m); 2714 mrb_gc_arena_restore(mrb, ai); 2715 NEXT; 2716 } 2717 2718 CASE(OP_SCLASS, B) { 2719 regs[a] = mrb_singleton_class(mrb, regs[a]); 2720 mrb_gc_arena_restore(mrb, ai); 2721 NEXT; 2722 } 2723 2724 CASE(OP_TCLASS, B) { 2725 if (!check_target_class(mrb)) goto L_RAISE; 2726 regs[a] = mrb_obj_value(mrb->c->ci->target_class); 2727 NEXT; 2728 } 2729 2730 CASE(OP_ALIAS, BB) { 2731 struct RClass *target; 2732 2733 if (!check_target_class(mrb)) goto L_RAISE; 2734 target = mrb->c->ci->target_class; 2735 mrb_alias_method(mrb, target, syms[a], syms[b]); 2736 NEXT; 2737 } 2738 CASE(OP_UNDEF, B) { 2739 struct RClass *target; 2740 2741 if (!check_target_class(mrb)) goto L_RAISE; 2742 target = mrb->c->ci->target_class; 2743 mrb_undef_method_id(mrb, target, syms[a]); 2744 NEXT; 2745 } 2746 2747 CASE(OP_DEBUG, Z) { 2748 FETCH_BBB(); 2805 2749 #ifdef MRB_ENABLE_DEBUG_HOOK 2806 2750 mrb->debug_op_hook(mrb, irep, pc, regs); 2807 2751 #else 2808 2752 #ifndef MRB_DISABLE_STDIO 2809 printf("OP_DEBUG %d %d %d\n", GETARG_A(i), GETARG_B(i), GETARG_C(i));2753 printf("OP_DEBUG %d %d %d\n", a, b, c); 2810 2754 #else 2811 2755 abort(); … … 2815 2759 } 2816 2760 2817 CASE(OP_STOP) { 2761 CASE(OP_ERR, B) { 2762 mrb_value msg = mrb_str_dup(mrb, pool[a]); 2763 mrb_value exc; 2764 2765 exc = mrb_exc_new_str(mrb, E_LOCALJUMP_ERROR, msg); 2766 ERR_PC_SET(mrb); 2767 mrb_exc_set(mrb, exc); 2768 goto L_RAISE; 2769 } 2770 2771 CASE(OP_EXT1, Z) { 2772 insn = READ_B(); 2773 switch (insn) { 2774 #define OPCODE(insn,ops) case OP_ ## insn: FETCH_ ## ops ## _1(); goto L_OP_ ## insn ## _BODY; 2775 #include "mruby/ops.h" 2776 #undef OPCODE 2777 } 2778 pc--; 2779 NEXT; 2780 } 2781 CASE(OP_EXT2, Z) { 2782 insn = READ_B(); 2783 switch (insn) { 2784 #define OPCODE(insn,ops) case OP_ ## insn: FETCH_ ## ops ## _2(); goto L_OP_ ## insn ## _BODY; 2785 #include "mruby/ops.h" 2786 #undef OPCODE 2787 } 2788 pc--; 2789 NEXT; 2790 } 2791 CASE(OP_EXT3, Z) { 2792 uint8_t insn = READ_B(); 2793 switch (insn) { 2794 #define OPCODE(insn,ops) case OP_ ## insn: FETCH_ ## ops ## _3(); goto L_OP_ ## insn ## _BODY; 2795 #include "mruby/ops.h" 2796 #undef OPCODE 2797 } 2798 pc--; 2799 NEXT; 2800 } 2801 2802 CASE(OP_STOP, Z) { 2818 2803 /* stop VM */ 2819 2804 L_STOP: 2820 { 2821 int epos = mrb->c->ci->epos; 2822 2823 while (mrb->c->eidx > epos) { 2824 ecall(mrb, --mrb->c->eidx); 2825 } 2826 } 2805 while (mrb->c->eidx > 0) { 2806 ecall(mrb); 2807 } 2808 mrb->c->cibase->ridx = 0; 2827 2809 ERR_PC_CLR(mrb); 2828 2810 mrb->jmp = prev_jmp; … … 2832 2814 return regs[irep->nlocals]; 2833 2815 } 2834 2835 CASE(OP_ERR) {2836 /* Bx raise RuntimeError with message Lit(Bx) */2837 mrb_value msg = mrb_str_dup(mrb, pool[GETARG_Bx(i)]);2838 mrb_value exc;2839 2840 if (GETARG_A(i) == 0) {2841 exc = mrb_exc_new_str(mrb, E_RUNTIME_ERROR, msg);2842 }2843 else {2844 exc = mrb_exc_new_str(mrb, E_LOCALJUMP_ERROR, msg);2845 }2846 mrb_exc_set(mrb, exc);2847 goto L_RAISE;2848 }2849 2816 } 2850 2817 END_DISPATCH; 2851 2818 #undef regs 2852 2853 2819 } 2854 2820 MRB_CATCH(&c_jmp) { … … 2884 2850 } 2885 2851 ci = cipush(mrb); 2852 ci->stackent = mrb->c->stack; 2886 2853 ci->mid = 0; 2887 ci->nregs = 1; /* protect the receiver */2888 2854 ci->acc = CI_ACC_SKIP; 2889 2855 ci->target_class = mrb->object_class; 2890 2856 v = mrb_vm_run(mrb, proc, self, stack_keep); 2891 cipop(mrb);2892 2857 2893 2858 return v;
Note:
See TracChangeset
for help on using the changeset viewer.