Skip to content

Instantly share code, notes, and snippets.

@shyouhei
Created January 17, 2017 06:33
Show Gist options
  • Select an option

  • Save shyouhei/b51a5fd31822ed7abb93ca1fecf1e3e4 to your computer and use it in GitHub Desktop.

Select an option

Save shyouhei/b51a5fd31822ed7abb93ca1fecf1e3e4 to your computer and use it in GitHub Desktop.
-: 0:Source:insns.def
-: 0:Graph:vm.gcno
-: 0:Data:vm.gcda
-: 0:Runs:387
-: 0:Programs:1
-: 1:/** ##skip -*- mode:c; style:ruby; coding: utf-8 -*-
-: 2: insns.def - YARV instruction definitions
-: 3:
-: 4: $Author: $
-: 5: created at: 04/01/01 01:17:55 JST
-: 6:
-: 7: Copyright (C) 2004-2007 Koichi Sasada
-: 8:*/
-: 9:
-: 10:/** ##skip
-: 11: instruction comment
-: 12: @c: category
-: 13: @e: english description
-: 14: @j: japanese description
-: 15:
-: 16: instruction form:
-: 17: DEFINE_INSN
-: 18: instruction_name
-: 19: (instruction_operands, ..)
-: 20: (pop_values, ..)
-: 21: (return value)
-: 22: {
-: 23: .. // insn body
-: 24: }
-: 25:
-: 26: */
-: 27:
-: 28:
-: 29:/**
-: 30: @c nop
-: 31: @e nop
-: 32: @j nop
-: 33: */
-: 34:DEFINE_INSN
-: 35:nop
-: 36:()
-: 37:()
-: 38:()
-: 39:{
-: 40: /* none */
-: 41:}
-: 42:
-: 43:/**********************************************************/
-: 44:/* deal with variables */
-: 45:/**********************************************************/
-: 46:
-: 47:/**
-: 48: @c variable
-: 49: @e Get local variable (pointed by `idx' and `level').
-: 50: 'level' indicates the nesting depth from the current block.
-: 51: @j level, idx で指定されたローカル変数の値をスタックに置く。
-: 52: level はブロックのネストレベルで、何段上かを示す。
-: 53: */
-: 54:DEFINE_INSN
-: 55:getlocal
-: 56:(lindex_t idx, rb_num_t level)
-: 57:()
-: 58:(VALUE val)
-: 59:{
677131: 60: int i, lev = (int)level;
677131: 61: const VALUE *ep = GET_EP();
-: 62:
-: 63: /* optimized insns generated for level == (0|1) in defs/opt_operand.def */
904363: 64: for (i = 0; i < lev; i++) {
227232: 65: ep = GET_PREV_EP(ep);
-: 66: }
677131: 67: val = *(ep - idx);
-: 68:}
-: 69:
-: 70:/**
-: 71: @c variable
-: 72: @e Set a local variable (pointed to by 'idx') as val.
-: 73: 'level' indicates the nesting depth from the current block.
-: 74: @j level, idx で指定されたローカル変数の値を val にする。
-: 75: level はブロックのネストレベルで、何段上かを示す。
-: 76: */
-: 77:DEFINE_INSN
-: 78:setlocal
-: 79:(lindex_t idx, rb_num_t level)
-: 80:(VALUE val)
-: 81:()
-: 82:{
19412: 83: int i, lev = (int)level;
19412: 84: const VALUE *ep = GET_EP();
-: 85:
-: 86: /* optimized insns generated for level == (0|1) in defs/opt_operand.def */
29532: 87: for (i = 0; i < lev; i++) {
10120: 88: ep = GET_PREV_EP(ep);
-: 89: }
38824: 90: vm_env_write(ep, -(int)idx, val);
-: 91:}
-: 92:
-: 93:/**
-: 94: @c variable
-: 95: @e Get value of special local variable ($~, $_, ..).
-: 96: @j 特殊なローカル変数($~, $_, ...)の値を得る。
-: 97: */
-: 98:DEFINE_INSN
-: 99:getspecial
-: 100:(rb_num_t key, rb_num_t type)
-: 101:()
-: 102:(VALUE val)
-: 103:{
18: 104: val = vm_getspecial(th, GET_LEP(), key, type);
-: 105:}
-: 106:
-: 107:/**
-: 108: @c variable
-: 109: @e Set value of special local variable ($~, $_, ...) to obj.
-: 110: @j 特別なローカル変数($~, $_, ...)の値を設定する。
-: 111: */
-: 112:DEFINE_INSN
-: 113:setspecial
-: 114:(rb_num_t key)
-: 115:(VALUE obj)
-: 116:()
-: 117:{
4: 118: lep_svar_set(th, GET_LEP(), key, obj);
-: 119:}
-: 120:
-: 121:/**
-: 122: @c variable
-: 123: @e Get value of instance variable id of self.
-: 124: If is_local is not 0, get value of class local variable.
-: 125: @j self のインスタンス変数 id の値を得る。
-: 126: */
-: 127:DEFINE_INSN
-: 128:getinstancevariable
-: 129:(ID id, IC ic)
-: 130:()
-: 131:(VALUE val)
-: 132:{
9406: 133: val = vm_getinstancevariable(GET_SELF(), id, ic);
-: 134:}
-: 135:
-: 136:/**
-: 137: @c variable
-: 138: @e Set value of instance variable id of self to val.
-: 139: If is_local is not 0, set value of class local variable.
-: 140: @j self のインスタンス変数 id を val にする。
-: 141: */
-: 142:DEFINE_INSN
-: 143:setinstancevariable
-: 144:(ID id, IC ic)
-: 145:(VALUE val)
-: 146:()
-: 147:{
12524: 148: vm_setinstancevariable(GET_SELF(), id, val, ic);
-: 149:}
-: 150:
-: 151:/**
-: 152: @c variable
-: 153: @e Get value of class variable id of klass as val.
-: 154: @j 現在のスコープのクラス変数 id の値を得る。
-: 155: */
-: 156:DEFINE_INSN
-: 157:getclassvariable
-: 158:(ID id)
-: 159:()
-: 160:(VALUE val)
-: 161:{
10: 162: val = rb_cvar_get(vm_get_cvar_base(rb_vm_get_cref(GET_EP()), GET_CFP()), id);
-: 163:}
-: 164:
-: 165:/**
-: 166: @c variable
-: 167: @e Set value of class variable id of klass as val.
-: 168: @j klass のクラス変数 id を val にする。
-: 169: */
-: 170:DEFINE_INSN
-: 171:setclassvariable
-: 172:(ID id)
-: 173:(VALUE val)
-: 174:()
-: 175:{
4: 176: vm_ensure_not_refinement_module(GET_SELF());
8: 177: rb_cvar_set(vm_get_cvar_base(rb_vm_get_cref(GET_EP()), GET_CFP()), id, val);
-: 178:}
-: 179:
-: 180:/**
-: 181: @c variable
-: 182: @e
-: 183: Get constant variable id. If klass is Qnil, constants
-: 184: are searched in the current scope. If klass is Qfalse, constants
-: 185: are searched as top level constants. Otherwise, get constant under klass
-: 186: class or module.
-: 187: @j 定数 id の値を得る。
-: 188: klass が Qnil なら、そのスコープで得られる定数の値を得る。
-: 189: Qfalse なら、トップレベルスコープを得る。
-: 190: それ以外なら、klass クラスの下の定数を得る。
-: 191: */
-: 192:DEFINE_INSN
-: 193:getconstant
-: 194:(ID id)
-: 195:(VALUE klass)
-: 196:(VALUE val)
-: 197:{
705: 198: val = vm_get_ev_const(th, klass, id, 0);
-: 199:}
-: 200:
-: 201:/**
-: 202: @c variable
-: 203: @e
-: 204: Set constant variable id. If klass is Qfalse, constant
-: 205: is able to access in this scope. if klass is Qnil, set
-: 206: top level constant. otherwise, set constant under klass
-: 207: class or module.
-: 208:
-: 209: @j 定数 id の値を val にする。
-: 210: klass が Qfalse なら、そのスコープで得られる定数 id の値を設定する。
-: 211: Qnil なら、トップレベルスコープの値を設定する。
-: 212: それ以外なら、klass クラスの下の定数を設定する。
-: 213: */
-: 214:DEFINE_INSN
-: 215:setconstant
-: 216:(ID id)
-: 217:(VALUE val, VALUE cbase)
-: 218:()
-: 219:{
41: 220: vm_check_if_namespace(cbase);
39: 221: vm_ensure_not_refinement_module(GET_SELF());
39: 222: rb_const_set(cbase, id, val);
-: 223:}
-: 224:
-: 225:/**
-: 226: @c variable
-: 227: @e get global variable id.
-: 228: @j グローバル変数 id の値を得る。
-: 229: */
-: 230:DEFINE_INSN
-: 231:getglobal
-: 232:(GENTRY entry)
-: 233:()
-: 234:(VALUE val)
-: 235:{
4441: 236: val = GET_GLOBAL((VALUE)entry);
-: 237:}
-: 238:
-: 239:/**
-: 240: @c variable
-: 241: @e set global variable id as val.
-: 242: @j グローバル変数 id の値を設定する。
-: 243: */
-: 244:DEFINE_INSN
-: 245:setglobal
-: 246:(GENTRY entry)
-: 247:(VALUE val)
-: 248:()
-: 249:{
75: 250: SET_GLOBAL((VALUE)entry, val);
-: 251:}
-: 252:
-: 253:
-: 254:/**********************************************************/
-: 255:/* deal with values */
-: 256:/**********************************************************/
-: 257:
-: 258:/**
-: 259: @c put
-: 260: @e put nil to stack.
-: 261: @j スタックに nil をプッシュする。
-: 262: */
-: 263:DEFINE_INSN
-: 264:putnil
-: 265:()
-: 266:()
-: 267:(VALUE val)
-: 268:{
218757: 269: val = Qnil;
-: 270:}
-: 271:
-: 272:/**
-: 273: @c put
-: 274: @e put self.
-: 275: @j スタックに self をプッシュする。
-: 276: */
-: 277:DEFINE_INSN
-: 278:putself
-: 279:()
-: 280:()
-: 281:(VALUE val)
-: 282:{
11677: 283: val = GET_SELF();
-: 284:}
-: 285:
-: 286:/**
-: 287: @c put
-: 288: @e put some object.
-: 289: i.e. Fixnum, true, false, nil, and so on.
-: 290: @j オブジェクト val をスタックにプッシュする。
-: 291: i.e. Fixnum, true, false, nil, and so on.
-: 292: */
-: 293:DEFINE_INSN
-: 294:putobject
-: 295:(VALUE val)
-: 296:()
-: 297:(VALUE val)
-: 298:{
-: 299: /* */
-: 300:}
-: 301:
-: 302:/**
-: 303: @c put
-: 304: @e put special object. "value_type" is for expansion.
-: 305: @j 特別なオブジェクト val をスタックにプッシュする。
-: 306: オブジェクトの種類は value_type による.
-: 307: */
-: 308:DEFINE_INSN
-: 309:putspecialobject
-: 310:(rb_num_t value_type)
-: 311:()
-: 312:(VALUE val)
-: 313:{
1637: 314: enum vm_special_object_type type = (enum vm_special_object_type)value_type;
-: 315:
1637: 316: switch (type) {
-: 317: case VM_SPECIAL_OBJECT_VMCORE:
1058: 318: val = rb_mRubyVMFrozenCore;
1058: 319: break;
-: 320: case VM_SPECIAL_OBJECT_CBASE:
42: 321: val = vm_get_cbase(GET_EP());
42: 322: break;
-: 323: case VM_SPECIAL_OBJECT_CONST_BASE:
537: 324: val = vm_get_const_base(GET_EP());
537: 325: break;
-: 326: default:
#####: 327: rb_bug("putspecialobject insn: unknown value_type");
-: 328: }
-: 329:}
-: 330:
-: 331:/**
-: 332: @c put
-: 333: @e put iseq value.
-: 334: @j iseq をスタックにプッシュする。
-: 335: */
-: 336:DEFINE_INSN
-: 337:putiseq
-: 338:(ISEQ iseq)
-: 339:()
-: 340:(VALUE ret)
-: 341:{
1014: 342: ret = (VALUE)iseq;
-: 343:}
-: 344:
-: 345:/**
-: 346: @c put
-: 347: @e put string val. string will be copied.
-: 348: @j 文字列をコピーしてスタックにプッシュする。
-: 349: */
-: 350:DEFINE_INSN
-: 351:putstring
-: 352:(VALUE str)
-: 353:()
-: 354:(VALUE val)
-: 355:{
4755: 356: val = rb_str_resurrect(str);
-: 357:}
-: 358:
-: 359:/**
-: 360: @c put
-: 361: @e put concatenate strings
-: 362: @j スタックトップの文字列を n 個連結し,結果をスタックにプッシュする。
-: 363: */
-: 364:DEFINE_INSN
-: 365:concatstrings
-: 366:(rb_num_t num)
-: 367:(...)
-: 368:(VALUE val) // inc += 1 - num;
-: 369:{
2185: 370: val = rb_str_concat_literals(num, &TOPN(num-1));
2185: 371: POPN(num);
-: 372:}
-: 373:
-: 374:/**
-: 375: @c put
-: 376: @e push the result of to_str.
-: 377: @j to_str の結果をスタックにプッシュする。
-: 378: */
-: 379:DEFINE_INSN
-: 380:tostring
-: 381:()
-: 382:(VALUE val)
-: 383:(VALUE val)
-: 384:{
4041: 385: val = rb_obj_as_string(val);
-: 386:}
-: 387:
-: 388:/**
-: 389: @c put
-: 390: @e Freeze (dynamically) created strings. if debug_info is given, set it.
-: 391: @j (埋め込み)文字列を freeze する。もし、debug_info が与えられていれば、それを設定する。
-: 392: */
-: 393:DEFINE_INSN
-: 394:freezestring
-: 395:(VALUE debug_info)
-: 396:(VALUE str)
-: 397:(VALUE str)
-: 398:{
259: 399: if (!NIL_P(debug_info)) {
#####: 400: rb_ivar_set(str, id_debug_created_info, debug_info);
-: 401: }
259: 402: rb_str_freeze(str);
-: 403:}
-: 404:
-: 405:/**
-: 406: @c put
-: 407: @e compile str to Regexp and push it.
-: 408: opt is the option for the Regexp.
-: 409: @j 文字列 str を正規表現にコンパイルしてスタックにプッシュする。
-: 410: コンパイル時,opt を正規表現のオプションとする。
-: 411: */
-: 412:DEFINE_INSN
-: 413:toregexp
-: 414:(rb_num_t opt, rb_num_t cnt)
-: 415:(...)
-: 416:(VALUE val) // inc += 1 - cnt;
-: 417:{
-: 418: VALUE rb_reg_new_ary(VALUE ary, int options);
-: 419: rb_num_t i;
3: 420: const VALUE ary = rb_ary_tmp_new(cnt);
12: 421: for (i = 0; i < cnt; i++) {
9: 422: rb_ary_store(ary, cnt-i-1, TOPN(i));
-: 423: }
3: 424: POPN(cnt);
3: 425: val = rb_reg_new_ary(ary, (int)opt);
3: 426: rb_ary_clear(ary);
-: 427:}
-: 428:
-: 429:/**
-: 430: @c put
-: 431: @e put new array initialized with num values on the stack.
-: 432: @j 新しい配列をスタック上の num 個の値で初期化して生成しプッシュする。
-: 433: */
-: 434:DEFINE_INSN
-: 435:newarray
-: 436:(rb_num_t num)
-: 437:(...)
-: 438:(VALUE val) // inc += 1 - num;
-: 439:{
11666: 440: val = rb_ary_new4((long)num, STACK_ADDR_FROM_TOP(num));
11666: 441: POPN(num);
-: 442:}
-: 443:
-: 444:/**
-: 445: @c put
-: 446: @e dup array
-: 447: @j 配列 ary を dup してスタックにプッシュする。
-: 448: */
-: 449:DEFINE_INSN
-: 450:duparray
-: 451:(VALUE ary)
-: 452:()
-: 453:(VALUE val)
-: 454:{
41: 455: val = rb_ary_resurrect(ary);
-: 456:}
-: 457:
-: 458:/**
-: 459: @c put
-: 460: @e if TOS is an array expand, expand it to num objects.
-: 461: if the number of the array is less than num, push nils to fill.
-: 462: if it is greater than num, exceeding elements are dropped.
-: 463: unless TOS is an array, push num - 1 nils.
-: 464: if flags is non-zero, push the array of the rest elements.
-: 465: flag: 0x01 - rest args array
-: 466: flag: 0x02 - for postarg
-: 467: flag: 0x04 - reverse?
-: 468: @j スタックトップのオブジェクトが配列であれば、それを展開する。
-: 469: 配列オブジェクトの要素数が num以下ならば、代わりに nil を積む。num以上なら、
-: 470: num以上の要素は切り捨てる。
-: 471: 配列オブジェクトでなければ、num - 1 個の nil を積む。
-: 472: もし flag が真なら、残り要素の配列を積む
-: 473: flag: 0x01 - 最後を配列に
-: 474: flag: 0x02 - postarg 用
-: 475: flag: 0x04 - reverse?
-: 476: */
-: 477:DEFINE_INSN
-: 478:expandarray
-: 479:(rb_num_t num, rb_num_t flag)
-: 480:(..., VALUE ary)
-: 481:(...) // inc += num - 1 + (flag & 1 ? 1 : 0);
-: 482:{
871: 483: vm_expandarray(GET_CFP(), ary, num, (int)flag);
-: 484:}
-: 485:
-: 486:/**
-: 487: @c put
-: 488: @e concat two arrays
-: 489: @j 二つの配列 ary1, ary2 を連結しスタックへプッシュする。
-: 490: */
-: 491:DEFINE_INSN
-: 492:concatarray
-: 493:()
-: 494:(VALUE ary1, VALUE ary2st)
-: 495:(VALUE ary)
-: 496:{
#####: 497: const VALUE ary2 = ary2st;
#####: 498: VALUE tmp1 = rb_check_convert_type(ary1, T_ARRAY, "Array", "to_a");
#####: 499: VALUE tmp2 = rb_check_convert_type(ary2, T_ARRAY, "Array", "to_a");
-: 500:
#####: 501: if (NIL_P(tmp1)) {
#####: 502: tmp1 = rb_ary_new3(1, ary1);
-: 503: }
-: 504:
#####: 505: if (NIL_P(tmp2)) {
#####: 506: tmp2 = rb_ary_new3(1, ary2);
-: 507: }
-: 508:
#####: 509: if (tmp1 == ary1) {
#####: 510: tmp1 = rb_ary_dup(ary1);
-: 511: }
#####: 512: ary = rb_ary_concat(tmp1, tmp2);
-: 513:}
-: 514:
-: 515:/**
-: 516: @c put
-: 517: @e call to_a on array ary to splat
-: 518: @j splat のために配列 ary に対して to_a を呼び出す。
-: 519: */
-: 520:DEFINE_INSN
-: 521:splatarray
-: 522:(VALUE flag)
-: 523:(VALUE ary)
-: 524:(VALUE obj)
-: 525:{
20: 526: VALUE tmp = rb_check_convert_type(ary, T_ARRAY, "Array", "to_a");
20: 527: if (NIL_P(tmp)) {
#####: 528: tmp = rb_ary_new3(1, ary);
-: 529: }
20: 530: else if (RTEST(flag)) {
#####: 531: tmp = rb_ary_dup(tmp);
-: 532: }
20: 533: obj = tmp;
-: 534:}
-: 535:
-: 536:/**
-: 537: @c put
-: 538: @e put new Hash from n elements. n must be an even number.
-: 539: @j 新しいハッシュをスタックトップの n 個を初期値として生成する。
-: 540: n はキーと値のペアなので 2 の倍数でなければならない。
-: 541: */
-: 542:DEFINE_INSN
-: 543:newhash
-: 544:(rb_num_t num)
-: 545:(...)
-: 546:(VALUE val) // inc += 1 - num;
-: 547:{
-: 548: rb_num_t i;
-: 549:
-: 550: RUBY_DTRACE_CREATE_HOOK(HASH, num);
-: 551:
22: 552: val = rb_hash_new();
-: 553:
22: 554: for (i = num; i > 0; i -= 2) {
#####: 555: const VALUE v = TOPN(i - 2);
#####: 556: const VALUE k = TOPN(i - 1);
#####: 557: rb_hash_aset(val, k, v);
-: 558: }
22: 559: POPN(num);
-: 560:}
-: 561:
-: 562:/**
-: 563: @c put
-: 564: @e put new Range object.(Range.new(low, high, flag))
-: 565: @j Range.new(low, high, flag) のようなオブジェクトを生成しスタックにプッシュする。
-: 566: */
-: 567:DEFINE_INSN
-: 568:newrange
-: 569:(rb_num_t flag)
-: 570:(VALUE low, VALUE high)
-: 571:(VALUE val)
-: 572:{
6: 573: val = rb_range_new(low, high, (int)flag);
-: 574:}
-: 575:
-: 576:/**********************************************************/
-: 577:/* deal with stack operation */
-: 578:/**********************************************************/
-: 579:
-: 580:/**
-: 581: @c stack
-: 582: @e pop from stack.
-: 583: @j スタックから一つポップする。
-: 584: */
-: 585:DEFINE_INSN
-: 586:pop
-: 587:()
-: 588:(VALUE val)
-: 589:()
-: 590:{
-: 591: (void)val;
-: 592: /* none */
-: 593:}
-: 594:
-: 595:/**
-: 596: @c stack
-: 597: @e duplicate stack top.
-: 598: @j スタックトップをコピーしてスタックにプッシュする。
-: 599: */
-: 600:DEFINE_INSN
-: 601:dup
-: 602:()
-: 603:(VALUE val)
-: 604:(VALUE val1, VALUE val2)
-: 605:{
12826: 606: val1 = val2 = val;
-: 607:}
-: 608:
-: 609:/**
-: 610: @c stack
-: 611: @e duplicate stack top n elements
-: 612: @j スタックトップの n 個をコピーしてスタックにプッシュする。
-: 613: */
-: 614:DEFINE_INSN
-: 615:dupn
-: 616:(rb_num_t n)
-: 617:(...)
-: 618:(...) // inc += n;
-: 619:{
-: 620: rb_num_t i;
5: 621: VALUE *sp = STACK_ADDR_FROM_TOP(n);
15: 622: for (i = 0; i < n; i++) {
10: 623: GET_SP()[i] = sp[i];
-: 624: }
5: 625: INC_SP(n);
-: 626:}
-: 627:
-: 628:
-: 629:/**
-: 630: @c stack
-: 631: @e swap top 2 vals
-: 632: @j スタックトップの 2 つの値を交換する。
-: 633: */
-: 634:DEFINE_INSN
-: 635:swap
-: 636:()
-: 637:(VALUE val, VALUE obj)
-: 638:(VALUE obj, VALUE val)
-: 639:{
-: 640: /* none */
-: 641:}
-: 642:
-: 643:/**
-: 644: @c stack
-: 645: @e reverse stack top N order.
-: 646: @j スタックトップの n 個の値を逆転する。
-: 647: */
-: 648:DEFINE_INSN
-: 649:reverse
-: 650:(rb_num_t n)
-: 651:(...)
-: 652:(...) // inc += 0;
-: 653:{
-: 654: rb_num_t i;
#####: 655: VALUE *sp = STACK_ADDR_FROM_TOP(n);
-: 656:
#####: 657: for (i=0; i<n/2; i++) {
#####: 658: VALUE v0 = sp[i];
#####: 659: VALUE v1 = TOPN(i);
#####: 660: sp[i] = v1;
#####: 661: TOPN(i) = v0;
-: 662: }
-: 663:}
-: 664:
-: 665:/**
-: 666: @c stack
-: 667: @e for stack caching.
-: 668: @j スタックキャッシングの状態を調整するために必要な命令。
-: 669: */
-: 670:DEFINE_INSN
-: 671:reput
-: 672:()
-: 673:(..., VALUE val)
-: 674:(VALUE val) // inc += 0;
-: 675:{
-: 676: /* none */
-: 677:}
-: 678:
-: 679:/**
-: 680: @c stack
-: 681: @e get nth stack value from stack top
-: 682: @j スタックトップから n 個目をスタックにプッシュする。
-: 683: */
-: 684:DEFINE_INSN
-: 685:topn
-: 686:(rb_num_t n)
-: 687:(...)
-: 688:(VALUE val) // inc += 1;
-: 689:{
#####: 690: val = TOPN(n);
-: 691:}
-: 692:
-: 693:/**
-: 694: @c stack
-: 695: @e set Nth stack entry to stack top
-: 696: @j スタックトップの値を n 個目のスタックにコピー
-: 697: */
-: 698:DEFINE_INSN
-: 699:setn
-: 700:(rb_num_t n)
-: 701:(..., VALUE val)
-: 702:(VALUE val) // inc += 0
-: 703:{
212141: 704: TOPN(n-1) = val;
-: 705:}
-: 706:
-: 707:/**
-: 708: @c stack
-: 709: @e empty current stack
-: 710: @j current stack を空にする。
-: 711: */
-: 712:DEFINE_INSN
-: 713:adjuststack
-: 714:(rb_num_t n)
-: 715:(...)
-: 716:(...) // inc -= n
-: 717:{
7: 718: DEC_SP(n);
-: 719:}
-: 720:
-: 721:
-: 722:/**********************************************************/
-: 723:/* deal with setting */
-: 724:/**********************************************************/
-: 725:
-: 726:/**
-: 727: @c setting
-: 728: @e defined?
-: 729: @j defined? を行う。
-: 730: */
-: 731:DEFINE_INSN
-: 732:defined
-: 733:(rb_num_t op_type, VALUE obj, VALUE needstr)
-: 734:(VALUE v)
-: 735:(VALUE val)
-: 736:{
11: 737: val = vm_defined(th, GET_CFP(), op_type, obj, needstr, v);
-: 738:}
-: 739:
-: 740:/**
-: 741: @c setting
-: 742: @e check `target' matches `pattern'.
-: 743: `flag & VM_CHECKMATCH_TYPE_MASK' describe how to check pattern.
-: 744: VM_CHECKMATCH_TYPE_WHEN: ignore target and check pattern is truthy.
-: 745: VM_CHECKMATCH_TYPE_CASE: check `patten === target'.
-: 746: VM_CHECKMATCH_TYPE_RESCUE: check `pattern.kind_op?(Module) && pattern == target'.
-: 747: if `flag & VM_CHECKMATCH_ARRAY' is not 0, then `patten' is array of patterns.
-: 748: @j see above comments.
-: 749: */
-: 750:DEFINE_INSN
-: 751:checkmatch
-: 752:(rb_num_t flag)
-: 753:(VALUE target, VALUE pattern)
-: 754:(VALUE result)
-: 755:{
853: 756: enum vm_check_match_type checkmatch_type =
853: 757: (enum vm_check_match_type)(flag & VM_CHECKMATCH_TYPE_MASK);
853: 758: result = Qfalse;
-: 759:
853: 760: if (flag & VM_CHECKMATCH_ARRAY) {
-: 761: long i;
#####: 762: for (i = 0; i < RARRAY_LEN(pattern); i++) {
#####: 763: if (RTEST(check_match(RARRAY_AREF(pattern, i), target, checkmatch_type))) {
-: 764: result = Qtrue;
-: 765: break;
-: 766: }
-: 767: }
-: 768: }
-: 769: else {
853: 770: if (RTEST(check_match(pattern, target, checkmatch_type))) {
850: 771: result = Qtrue;
-: 772: }
-: 773: }
-: 774:}
-: 775:
-: 776:/**
-: 777: @c setting
-: 778: @e check keywords are specified or not.
-: 779: @j キーワードが指定されているかどうかチェックする
-: 780: */
-: 781:DEFINE_INSN
-: 782:checkkeyword
-: 783:(lindex_t kw_bits_index, rb_num_t keyword_index)
-: 784:()
-: 785:(VALUE ret)
-: 786:{
#####: 787: const VALUE *ep = GET_EP();
#####: 788: const VALUE kw_bits = *(ep - kw_bits_index);
-: 789:
#####: 790: if (FIXNUM_P(kw_bits)) {
#####: 791: int bits = FIX2INT(kw_bits);
#####: 792: ret = (bits & (0x01 << keyword_index)) ? Qfalse : Qtrue;
-: 793: }
-: 794: else {
-: 795: VM_ASSERT(RB_TYPE_P(kw_bits, T_HASH));
#####: 796: ret = rb_hash_has_key(kw_bits, INT2FIX(keyword_index)) ? Qfalse : Qtrue;
-: 797: }
-: 798:}
-: 799:
-: 800:/**
-: 801: @c setting
-: 802: @e trace
-: 803: @j trace 用の命令。
-: 804: */
-: 805:DEFINE_INSN
-: 806:trace
-: 807:(rb_num_t nf)
-: 808:()
-: 809:()
-: 810:{
752401: 811: rb_event_flag_t flag = (rb_event_flag_t)nf;
-: 812:
-: 813: if (RUBY_DTRACE_METHOD_ENTRY_ENABLED() ||
-: 814: RUBY_DTRACE_METHOD_RETURN_ENABLED() ||
-: 815: RUBY_DTRACE_CMETHOD_ENTRY_ENABLED() ||
-: 816: RUBY_DTRACE_CMETHOD_RETURN_ENABLED()) {
-: 817:
-: 818: switch (flag) {
-: 819: case RUBY_EVENT_CALL:
-: 820: RUBY_DTRACE_METHOD_ENTRY_HOOK(th, 0, 0);
-: 821: break;
-: 822: case RUBY_EVENT_C_CALL:
-: 823: RUBY_DTRACE_CMETHOD_ENTRY_HOOK(th, 0, 0);
-: 824: break;
-: 825: case RUBY_EVENT_RETURN:
-: 826: RUBY_DTRACE_METHOD_RETURN_HOOK(th, 0, 0);
-: 827: break;
-: 828: case RUBY_EVENT_C_RETURN:
-: 829: RUBY_DTRACE_CMETHOD_RETURN_HOOK(th, 0, 0);
-: 830: break;
-: 831: }
-: 832: }
-: 833:
752401: 834: EXEC_EVENT_HOOK(th, flag, GET_SELF(), 0, 0, 0 /* id and klass are resolved at callee */,
-: 835: (flag & (RUBY_EVENT_RETURN | RUBY_EVENT_B_RETURN)) ? TOPN(0) : Qundef);
-: 836:}
-: 837:
-: 838:/**********************************************************/
-: 839:/* deal with control flow 1: class/module */
-: 840:/**********************************************************/
-: 841:
-: 842:/**
-: 843: @c class/module
-: 844: @e
-: 845: enter class definition scope. if super is Qfalse, and class
-: 846: "klass" is defined, it's redefine. otherwise, define "klass" class.
-: 847: @j クラス定義スコープへ移行する。
-: 848: もし super が Qfalse で klassクラスが定義されていれば再定義である。
-: 849: そうでなければ、klass クラスを定義する。
-: 850: */
-: 851:DEFINE_INSN
-: 852:defineclass
-: 853:(ID id, ISEQ class_iseq, rb_num_t flags)
-: 854:(VALUE cbase, VALUE super)
-: 855:(VALUE val)
-: 856:{
-: 857: VALUE klass;
538: 858: rb_vm_defineclass_type_t type = VM_DEFINECLASS_TYPE(flags);
-: 859:
538: 860: switch (type) {
-: 861: case VM_DEFINECLASS_TYPE_CLASS:
-: 862: /* val is dummy. classdef returns class scope value */
-: 863:
180: 864: if (VM_DEFINECLASS_HAS_SUPERCLASS_P(flags) &&
26: 865: !RB_TYPE_P(super, T_CLASS)) {
#####: 866: rb_raise(rb_eTypeError, "superclass must be a Class (%"PRIsVALUE" given)",
-: 867: rb_obj_class(super));
-: 868: }
-: 869:
154: 870: vm_check_if_namespace(cbase);
-: 871:
-: 872: /* find klass */
153: 873: rb_autoload_load(cbase, id);
153: 874: if ((klass = vm_search_const_defined_class(cbase, id)) != 0) {
-: 875: /* already exist */
42: 876: klass = VM_DEFINECLASS_SCOPED_P(flags) ?
21: 877: rb_public_const_get_at(klass, id) : rb_const_get_at(klass, id);
21: 878: if (!RB_TYPE_P(klass, T_CLASS)) {
1: 879: rb_raise(rb_eTypeError, "%"PRIsVALUE" is not a class", rb_id2str(id));
-: 880: }
-: 881:
20: 882: if (VM_DEFINECLASS_HAS_SUPERCLASS_P(flags)) {
-: 883: VALUE tmp;
1: 884: tmp = rb_class_real(RCLASS_SUPER(klass));
-: 885:
1: 886: if (tmp != super) {
1: 887: rb_raise(rb_eTypeError, "superclass mismatch for class %"PRIsVALUE"",
-: 888: rb_id2str(id));
-: 889: }
-: 890: }
-: 891: }
-: 892: else {
132: 893: if (!VM_DEFINECLASS_HAS_SUPERCLASS_P(flags)) {
120: 894: super = rb_cObject;
-: 895: }
-: 896: /* new class declaration */
132: 897: klass = rb_define_class_id(id, super);
132: 898: rb_set_class_path_string(klass, cbase, rb_id2str(id));
132: 899: rb_const_set(cbase, id, klass);
132: 900: rb_class_inherited(super, klass);
-: 901: }
-: 902: break;
-: 903: case VM_DEFINECLASS_TYPE_SINGLETON_CLASS:
-: 904: /* val is dummy. classdef returns class scope value */
-: 905: /* super is dummy */
15: 906: klass = rb_singleton_class(cbase);
15: 907: break;
-: 908: case VM_DEFINECLASS_TYPE_MODULE:
-: 909: /* val is dummy. classdef returns class scope value */
-: 910: /* super is dummy */
-: 911:
369: 912: vm_check_if_namespace(cbase);
-: 913:
-: 914: /* find klass */
369: 915: if ((klass = vm_search_const_defined_class(cbase, id)) != 0) {
578: 916: klass = VM_DEFINECLASS_SCOPED_P(flags) ?
289: 917: rb_public_const_get_at(klass, id) : rb_const_get_at(klass, id);
-: 918: /* already exist */
289: 919: if (!RB_TYPE_P(klass, T_MODULE)) {
2: 920: rb_raise(rb_eTypeError, "%"PRIsVALUE" is not a module", rb_id2str(id));
-: 921: }
-: 922: }
-: 923: else {
-: 924: /* new module declaration */
80: 925: klass = rb_define_module_id(id);
80: 926: rb_set_class_path_string(klass, cbase, rb_id2str(id));
80: 927: rb_const_set(cbase, id, klass);
-: 928: }
-: 929: break;
-: 930: default:
#####: 931: rb_bug("unknown defineclass type: %d", (int)type);
-: 932: }
-: 933:
533: 934: rb_iseq_check(class_iseq);
-: 935:
-: 936: /* enter scope */
2665: 937: vm_push_frame(th, class_iseq, VM_FRAME_MAGIC_CLASS | VM_ENV_FLAG_LOCAL, klass,
1066: 938: GET_BLOCK_HANDLER(),
533: 939: (VALUE)vm_cref_push(th, klass, NULL, FALSE),
533: 940: class_iseq->body->iseq_encoded, GET_SP(),
533: 941: class_iseq->body->local_table_size,
533: 942: class_iseq->body->stack_max);
533: 943: RESTORE_REGS();
533: 944: NEXT_INSN();
-: 945:}
-: 946:
-: 947:
-: 948:/**********************************************************/
-: 949:/* deal with control flow 2: method/iterator */
-: 950:/**********************************************************/
-: 951:
-: 952:/**
-: 953: @c method/iterator
-: 954: @e invoke method.
-: 955: @j メソッド呼び出しを行う。ci に必要な情報が格納されている。
-: 956: */
-: 957:DEFINE_INSN
-: 958:send
-: 959:(CALL_INFO ci, CALL_CACHE cc, ISEQ blockiseq)
-: 960:(...)
-: 961:(VALUE val) // inc += - (int)(ci->orig_argc + ((ci->flag & VM_CALL_ARGS_BLOCKARG) ? 1 : 0));
-: 962:{
-: 963: struct rb_calling_info calling;
-: 964:
6179: 965: vm_caller_setup_arg_block(th, reg_cfp, &calling, ci, blockiseq, FALSE);
6179: 966: vm_search_method(ci, cc, calling.recv = TOPN(calling.argc = ci->orig_argc));
6179: 967: CALL_METHOD(&calling, ci, cc);
-: 968:}
-: 969:
-: 970:DEFINE_INSN
-: 971:opt_str_freeze
-: 972:(VALUE str)
-: 973:()
-: 974:(VALUE val)
-: 975:{
#####: 976: if (BASIC_OP_UNREDEFINED_P(BOP_FREEZE, STRING_REDEFINED_OP_FLAG)) {
-: 977: val = str;
-: 978: }
-: 979: else {
#####: 980: val = rb_funcall(rb_str_resurrect(str), idFreeze, 0);
-: 981: }
-: 982:}
-: 983:
-: 984:DEFINE_INSN
-: 985:opt_newarray_max
-: 986:(rb_num_t num)
-: 987:(...)
-: 988:(VALUE val) // inc += 1 - num;
-: 989:{
-: 990:#define id_cmp idCmp
#####: 991: if (BASIC_OP_UNREDEFINED_P(BOP_MAX, ARRAY_REDEFINED_OP_FLAG)) {
#####: 992: if (num == 0) {
-: 993: val = Qnil;
-: 994: }
-: 995: else {
#####: 996: struct cmp_opt_data cmp_opt = { 0, 0 };
#####: 997: VALUE result = Qundef;
#####: 998: rb_num_t i = num - 1;
#####: 999: result = TOPN(i);
#####: 1000: while (i-- > 0) {
#####: 1001: const VALUE v = TOPN(i);
#####: 1002: if (result == Qundef || OPTIMIZED_CMP(v, result, cmp_opt) > 0) {
#####: 1003: result = v;
-: 1004: }
-: 1005: }
#####: 1006: val = result == Qundef ? Qnil : result;
-: 1007: }
#####: 1008: POPN(num);
-: 1009: }
-: 1010: else {
#####: 1011: VALUE ary = rb_ary_new4((long)num, STACK_ADDR_FROM_TOP(num));
#####: 1012: val = rb_funcall(ary, idMax, 0);
#####: 1013: POPN(num);
-: 1014: }
-: 1015:#undef id_cmp
-: 1016:}
-: 1017:
-: 1018:DEFINE_INSN
-: 1019:opt_newarray_min
-: 1020:(rb_num_t num)
-: 1021:(...)
-: 1022:(VALUE val) // inc += 1 - num;
-: 1023:{
-: 1024:#define id_cmp idCmp
#####: 1025: if (BASIC_OP_UNREDEFINED_P(BOP_MIN, ARRAY_REDEFINED_OP_FLAG)) {
#####: 1026: if (num == 0) {
-: 1027: val = Qnil;
-: 1028: }
-: 1029: else {
#####: 1030: struct cmp_opt_data cmp_opt = { 0, 0 };
#####: 1031: VALUE result = Qundef;
#####: 1032: rb_num_t i = num - 1;
#####: 1033: result = TOPN(i);
#####: 1034: while (i-- > 0) {
#####: 1035: const VALUE v = TOPN(i);
#####: 1036: if (result == Qundef || OPTIMIZED_CMP(v, result, cmp_opt) < 0) {
#####: 1037: result = v;
-: 1038: }
-: 1039: }
#####: 1040: val = result == Qundef ? Qnil : result;
-: 1041: }
#####: 1042: POPN(num);
-: 1043: }
-: 1044: else {
#####: 1045: VALUE ary = rb_ary_new4((long)num, STACK_ADDR_FROM_TOP(num));
#####: 1046: val = rb_funcall(ary, idMin, 0);
#####: 1047: POPN(num);
-: 1048: }
-: 1049:#undef id_cmp
-: 1050:}
-: 1051:
-: 1052:/**
-: 1053: @c optimize
-: 1054: @e Invoke method without block
-: 1055: @j Invoke method without block
-: 1056: */
-: 1057:DEFINE_INSN
-: 1058:opt_send_without_block
-: 1059:(CALL_INFO ci, CALL_CACHE cc)
-: 1060:(...)
-: 1061:(VALUE val) // inc += -ci->orig_argc;
-: 1062:{
-: 1063: struct rb_calling_info calling;
38386: 1064: calling.block_handler = VM_BLOCK_HANDLER_NONE;
38386: 1065: vm_search_method(ci, cc, calling.recv = TOPN(calling.argc = ci->orig_argc));
38386: 1066: CALL_METHOD(&calling, ci, cc);
-: 1067:}
-: 1068:
-: 1069:/**
-: 1070: @c method/iterator
-: 1071: @e super(args) # args.size => num
-: 1072: @j super を実行する。ci に必要な情報が格納されている。
-: 1073: */
-: 1074:DEFINE_INSN
-: 1075:invokesuper
-: 1076:(CALL_INFO ci, CALL_CACHE cc, ISEQ blockiseq)
-: 1077:(...)
-: 1078:(VALUE val) // inc += - (int)(ci->orig_argc + ((ci->flag & VM_CALL_ARGS_BLOCKARG) ? 1 : 0));
-: 1079:{
-: 1080: struct rb_calling_info calling;
2: 1081: calling.argc = ci->orig_argc;
-: 1082:
2: 1083: vm_caller_setup_arg_block(th, reg_cfp, &calling, ci, blockiseq, TRUE);
2: 1084: calling.recv = GET_SELF();
2: 1085: vm_search_super_method(th, GET_CFP(), &calling, ci, cc);
2: 1086: CALL_METHOD(&calling, ci, cc);
-: 1087:}
-: 1088:
-: 1089:/**
-: 1090: @c method/iterator
-: 1091: @e yield(args)
-: 1092: @j yield を実行する。
-: 1093: */
-: 1094:DEFINE_INSN
-: 1095:invokeblock
-: 1096:(CALL_INFO ci)
-: 1097:(...)
-: 1098:(VALUE val) // inc += 1 - ci->orig_argc;
-: 1099:{
-: 1100: struct rb_calling_info calling;
2011: 1101: calling.argc = ci->orig_argc;
2011: 1102: calling.block_handler = VM_BLOCK_HANDLER_NONE;
2011: 1103: calling.recv = GET_SELF();
-: 1104:
2011: 1105: val = vm_invoke_block(th, GET_CFP(), &calling, ci);
1995: 1106: if (val == Qundef) {
1988: 1107: RESTORE_REGS();
1988: 1108: NEXT_INSN();
-: 1109: }
-: 1110:}
-: 1111:
-: 1112:/**
-: 1113: @c method/iterator
-: 1114: @e return from this scope.
-: 1115: @j このスコープから抜ける。
-: 1116: */
-: 1117:DEFINE_INSN
-: 1118:leave
-: 1119:()
-: 1120:(VALUE val)
-: 1121:(VALUE val)
-: 1122:{
-: 1123: if (OPT_CHECKED_RUN) {
483048: 1124: const VALUE *const bp = vm_base_ptr(reg_cfp);
241524: 1125: if (reg_cfp->sp != bp) {
#####: 1126: rb_bug("Stack consistency error (sp: %"PRIdPTRDIFF", bp: %"PRIdPTRDIFF")",
#####: 1127: VM_SP_CNT(th, reg_cfp->sp), VM_SP_CNT(th, bp));
-: 1128: }
-: 1129: }
-: 1130:
241524: 1131: RUBY_VM_CHECK_INTS(th);
-: 1132:
483048: 1133: if (vm_pop_frame(th, GET_CFP(), GET_EP())) {
-: 1134:#if OPT_CALL_THREADED_CODE
-: 1135: th->retval = val;
-: 1136: return 0;
-: 1137:#else
-: 1138: return val;
-: 1139:#endif
-: 1140: }
-: 1141: else {
12240: 1142: RESTORE_REGS();
-: 1143: }
-: 1144:}
-: 1145:
-: 1146:/**********************************************************/
-: 1147:/* deal with control flow 3: exception */
-: 1148:/**********************************************************/
-: 1149:
-: 1150:/**
-: 1151: @c exception
-: 1152: @e longjump
-: 1153: @j 大域ジャンプを行う。
-: 1154: */
-: 1155:DEFINE_INSN
-: 1156:throw
-: 1157:(rb_num_t throw_state)
-: 1158:(VALUE throwobj)
-: 1159:(VALUE val)
-: 1160:{
115: 1161: RUBY_VM_CHECK_INTS(th);
115: 1162: val = vm_throw(th, GET_CFP(), throw_state, throwobj);
115: 1163: THROW_EXCEPTION(val);
-: 1164: /* unreachable */
-: 1165:}
-: 1166:
-: 1167:/**********************************************************/
-: 1168:/* deal with control flow 4: local jump */
-: 1169:/**********************************************************/
-: 1170:
-: 1171:/**
-: 1172: @c jump
-: 1173: @e set PC to (PC + dst).
-: 1174: @j PC を (PC + dst) にする。
-: 1175: */
-: 1176:DEFINE_INSN
-: 1177:jump
-: 1178:(OFFSET dst)
-: 1179:()
-: 1180:()
-: 1181:{
2283: 1182: RUBY_VM_CHECK_INTS(th);
2283: 1183: JUMP(dst);
-: 1184:}
-: 1185:
-: 1186:/**
-: 1187: @c jump
-: 1188: @e if val is not false or nil, set PC to (PC + dst).
-: 1189: @j もし val が false か nil でなければ、PC を (PC + dst) にする。
-: 1190: */
-: 1191:DEFINE_INSN
-: 1192:branchif
-: 1193:(OFFSET dst)
-: 1194:(VALUE val)
-: 1195:()
-: 1196:{
1640: 1197: if (RTEST(val)) {
111: 1198: RUBY_VM_CHECK_INTS(th);
111: 1199: JUMP(dst);
-: 1200: }
-: 1201:}
-: 1202:
-: 1203:/**
-: 1204: @c jump
-: 1205: @e if val is false or nil, set PC to (PC + dst).
-: 1206: @j もし val が false か nil ならば、PC を (PC + dst) にする。
-: 1207: */
-: 1208:DEFINE_INSN
-: 1209:branchunless
-: 1210:(OFFSET dst)
-: 1211:(VALUE val)
-: 1212:()
-: 1213:{
12245: 1214: if (!RTEST(val)) {
6121: 1215: RUBY_VM_CHECK_INTS(th);
6121: 1216: JUMP(dst);
-: 1217: }
-: 1218:}
-: 1219:
-: 1220:/**
-: 1221: @c jump
-: 1222: @e if val is nil, set PC to (PC + dst).
-: 1223: @j もし val が nil ならば、PC を (PC + dst) にする。
-: 1224: */
-: 1225:DEFINE_INSN
-: 1226:branchnil
-: 1227:(OFFSET dst)
-: 1228:(VALUE val)
-: 1229:()
-: 1230:{
#####: 1231: if (NIL_P(val)) {
#####: 1232: RUBY_VM_CHECK_INTS(th);
#####: 1233: JUMP(dst);
-: 1234: }
-: 1235:}
-: 1236:
-: 1237:
-: 1238:/**********************************************************/
-: 1239:/* for optimize */
-: 1240:/**********************************************************/
-: 1241:
-: 1242:/**
-: 1243: @c optimize
-: 1244: @e push inline-cached value and go to dst if it is valid
-: 1245: @j インラインキャッシュが有効なら、値をスタックにプッシュして dst へジャンプする。
-: 1246: */
-: 1247:DEFINE_INSN
-: 1248:getinlinecache
-: 1249:(OFFSET dst, IC ic)
-: 1250:()
-: 1251:(VALUE val)
-: 1252:{
20737: 1253: if (ic->ic_serial == GET_GLOBAL_CONSTANT_STATE() &&
10056: 1254: (ic->ic_cref == NULL || ic->ic_cref == rb_vm_get_cref(GET_EP()))) {
10056: 1255: val = ic->ic_value.value;
10056: 1256: JUMP(dst);
-: 1257: }
-: 1258: else {
-: 1259: /* none */
-: 1260: val = Qnil;
-: 1261: }
-: 1262:}
-: 1263:
-: 1264:/**
-: 1265: @c optimize
-: 1266: @e set inline cache
-: 1267: @j インラインキャッシュの値を設定する。
-: 1268: */
-: 1269:DEFINE_INSN
-: 1270:setinlinecache
-: 1271:(IC ic)
-: 1272:(VALUE val)
-: 1273:(VALUE val)
-: 1274:{
-: 1275: VM_ASSERT(ic->ic_value.value != Qundef);
621: 1276: ic->ic_value.value = val;
621: 1277: ic->ic_serial = GET_GLOBAL_CONSTANT_STATE() - ruby_vm_const_missing_count;
621: 1278: ic->ic_cref = vm_get_const_key_cref(GET_EP());
621: 1279: ruby_vm_const_missing_count = 0;
-: 1280:}
-: 1281:
-: 1282:/**
-: 1283: @c optimize
-: 1284: @e run iseq only once
-: 1285: @j once を実現する。
-: 1286: */
-: 1287:DEFINE_INSN
-: 1288:once
-: 1289:(ISEQ iseq, IC ic)
-: 1290:()
-: 1291:(VALUE val)
-: 1292:{
#####: 1293: union iseq_inline_storage_entry *is = (union iseq_inline_storage_entry *)ic;
-: 1294:
-: 1295:#define RUNNING_THREAD_ONCE_DONE ((rb_thread_t *)(0x1))
-: 1296: retry:
#####: 1297: if (is->once.running_thread == RUNNING_THREAD_ONCE_DONE) {
#####: 1298: val = is->once.value;
-: 1299: }
#####: 1300: else if (is->once.running_thread == NULL) {
#####: 1301: is->once.running_thread = th;
#####: 1302: val = is->once.value = rb_ensure(vm_once_exec, (VALUE)iseq, vm_once_clear, (VALUE)is);
-: 1303: /* is->once.running_thread is cleared by vm_once_clear() */
#####: 1304: is->once.running_thread = RUNNING_THREAD_ONCE_DONE; /* success */
#####: 1305: rb_iseq_add_mark_object(GET_ISEQ(), val);
-: 1306: }
#####: 1307: else if (is->once.running_thread == th) {
-: 1308: /* recursive once */
#####: 1309: val = vm_once_exec((VALUE)iseq);
-: 1310: }
-: 1311: else {
-: 1312: /* waiting for finish */
#####: 1313: RUBY_VM_CHECK_INTS(th);
#####: 1314: rb_thread_schedule();
#####: 1315: goto retry;
-: 1316: }
-: 1317:}
-: 1318:
-: 1319:/**
-: 1320: @c optimize
-: 1321: @e case dispatcher, jump by table if possible
-: 1322: @j case 文で、可能なら表引きでジャンプする。
-: 1323: */
-: 1324:DEFINE_INSN
-: 1325:opt_case_dispatch
-: 1326:(CDHASH hash, OFFSET else_offset)
-: 1327:(..., VALUE key)
-: 1328:() // inc += -1;
-: 1329:{
1: 1330: switch (OBJ_BUILTIN_TYPE(key)) {
-: 1331: case -1:
-: 1332: case T_FLOAT:
-: 1333: case T_SYMBOL:
-: 1334: case T_BIGNUM:
-: 1335: case T_STRING:
1: 1336: if (BASIC_OP_UNREDEFINED_P(BOP_EQQ,
-: 1337: SYMBOL_REDEFINED_OP_FLAG |
-: 1338: INTEGER_REDEFINED_OP_FLAG |
-: 1339: FLOAT_REDEFINED_OP_FLAG |
-: 1340: NIL_REDEFINED_OP_FLAG |
-: 1341: TRUE_REDEFINED_OP_FLAG |
-: 1342: FALSE_REDEFINED_OP_FLAG |
-: 1343: STRING_REDEFINED_OP_FLAG)) {
-: 1344: st_data_t val;
1: 1345: if (RB_FLOAT_TYPE_P(key)) {
#####: 1346: double kval = RFLOAT_VALUE(key);
#####: 1347: if (!isinf(kval) && modf(kval, &kval) == 0.0) {
#####: 1348: key = FIXABLE(kval) ? LONG2FIX((long)kval) : rb_dbl2big(kval);
-: 1349: }
-: 1350: }
1: 1351: if (st_lookup(RHASH_TBL_RAW(hash), key, &val)) {
1: 1352: JUMP(FIX2INT((VALUE)val));
-: 1353: }
-: 1354: else {
#####: 1355: JUMP(else_offset);
-: 1356: }
-: 1357: }
-: 1358: }
-: 1359:}
-: 1360:
-: 1361:/** simple functions */
-: 1362:
-: 1363:/**
-: 1364: @c optimize
-: 1365: @e optimized X+Y.
-: 1366: @j 最適化された X+Y。
-: 1367: */
-: 1368:DEFINE_INSN
-: 1369:opt_plus
-: 1370:(CALL_INFO ci, CALL_CACHE cc)
-: 1371:(VALUE recv, VALUE obj)
-: 1372:(VALUE val)
-: 1373:{
2416: 1374: if (FIXNUM_2_P(recv, obj) &&
820: 1375: BASIC_OP_UNREDEFINED_P(BOP_PLUS,INTEGER_REDEFINED_OP_FLAG)) {
-: 1376: /* fixnum + fixnum */
-: 1377:#ifndef LONG_LONG_VALUE
820: 1378: VALUE msb = (VALUE)1 << ((sizeof(VALUE) * CHAR_BIT) - 1);
820: 1379: val = recv - 1 + obj;
820: 1380: if ((~(recv ^ obj) & (recv ^ val)) & msb) {
#####: 1381: val = rb_int2big((SIGNED_VALUE)((val>>1) | (recv & msb)));
-: 1382: }
-: 1383:#else
-: 1384: val = LONG2NUM(FIX2LONG(recv) + FIX2LONG(obj));
-: 1385:#endif
-: 1386: }
776: 1387: else if (FLONUM_2_P(recv, obj) &&
#####: 1388: BASIC_OP_UNREDEFINED_P(BOP_PLUS, FLOAT_REDEFINED_OP_FLAG)) {
#####: 1389: val = DBL2NUM(RFLOAT_VALUE(recv) + RFLOAT_VALUE(obj));
-: 1390: }
776: 1391: else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
771: 1392: if (RBASIC_CLASS(recv) == rb_cFloat && RBASIC_CLASS(obj) == rb_cFloat &&
#####: 1393: BASIC_OP_UNREDEFINED_P(BOP_PLUS, FLOAT_REDEFINED_OP_FLAG)) {
#####: 1394: val = DBL2NUM(RFLOAT_VALUE(recv) + RFLOAT_VALUE(obj));
-: 1395: }
1540: 1396: else if (RBASIC_CLASS(recv) == rb_cString && RBASIC_CLASS(obj) == rb_cString &&
769: 1397: BASIC_OP_UNREDEFINED_P(BOP_PLUS, STRING_REDEFINED_OP_FLAG)) {
769: 1398: val = rb_str_plus(recv, obj);
-: 1399: }
4: 1400: else if (RBASIC_CLASS(recv) == rb_cArray &&
2: 1401: BASIC_OP_UNREDEFINED_P(BOP_PLUS, ARRAY_REDEFINED_OP_FLAG)) {
2: 1402: val = rb_ary_plus(recv, obj);
-: 1403: }
-: 1404: else {
-: 1405: goto INSN_LABEL(normal_dispatch);
-: 1406: }
-: 1407: }
-: 1408: else {
-: 1409: INSN_LABEL(normal_dispatch):
5: 1410: PUSH(recv);
5: 1411: PUSH(obj);
5: 1412: CALL_SIMPLE_METHOD(recv);
-: 1413: }
-: 1414:}
-: 1415:
-: 1416:/**
-: 1417: @c optimize
-: 1418: @e optimized X-Y.
-: 1419: @j 最適化された X-Y。
-: 1420: */
-: 1421:DEFINE_INSN
-: 1422:opt_minus
-: 1423:(CALL_INFO ci, CALL_CACHE cc)
-: 1424:(VALUE recv, VALUE obj)
-: 1425:(VALUE val)
-: 1426:{
60: 1427: if (FIXNUM_2_P(recv, obj) &&
27: 1428: BASIC_OP_UNREDEFINED_P(BOP_MINUS, INTEGER_REDEFINED_OP_FLAG)) {
-: 1429: long a, b, c;
-: 1430:
27: 1431: a = FIX2LONG(recv);
27: 1432: b = FIX2LONG(obj);
27: 1433: c = a - b;
-: 1434: val = LONG2NUM(c);
-: 1435: }
6: 1436: else if (FLONUM_2_P(recv, obj) &&
#####: 1437: BASIC_OP_UNREDEFINED_P(BOP_MINUS, FLOAT_REDEFINED_OP_FLAG)) {
#####: 1438: val = DBL2NUM(RFLOAT_VALUE(recv) - RFLOAT_VALUE(obj));
-: 1439: }
6: 1440: else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
6: 1441: if (RBASIC_CLASS(recv) == rb_cFloat && RBASIC_CLASS(obj) == rb_cFloat &&
#####: 1442: BASIC_OP_UNREDEFINED_P(BOP_MINUS, FLOAT_REDEFINED_OP_FLAG)) {
#####: 1443: val = DBL2NUM(RFLOAT_VALUE(recv) - RFLOAT_VALUE(obj));
-: 1444: }
-: 1445: else {
-: 1446: goto INSN_LABEL(normal_dispatch);
-: 1447: }
-: 1448: }
-: 1449: else {
-: 1450: /* other */
-: 1451: INSN_LABEL(normal_dispatch):
6: 1452: PUSH(recv);
6: 1453: PUSH(obj);
6: 1454: CALL_SIMPLE_METHOD(recv);
-: 1455: }
-: 1456:}
-: 1457:
-: 1458:/**
-: 1459: @c optimize
-: 1460: @e optimized X*Y.
-: 1461: @j 最適化された X*Y。
-: 1462: */
-: 1463:DEFINE_INSN
-: 1464:opt_mult
-: 1465:(CALL_INFO ci, CALL_CACHE cc)
-: 1466:(VALUE recv, VALUE obj)
-: 1467:(VALUE val)
-: 1468:{
17: 1469: if (FIXNUM_2_P(recv, obj) &&
8: 1470: BASIC_OP_UNREDEFINED_P(BOP_MULT, INTEGER_REDEFINED_OP_FLAG)) {
8: 1471: val = rb_fix_mul_fix(recv, obj);
-: 1472: }
1: 1473: else if (FLONUM_2_P(recv, obj) &&
#####: 1474: BASIC_OP_UNREDEFINED_P(BOP_MULT, FLOAT_REDEFINED_OP_FLAG)) {
#####: 1475: val = DBL2NUM(RFLOAT_VALUE(recv) * RFLOAT_VALUE(obj));
-: 1476: }
1: 1477: else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
#####: 1478: if (RBASIC_CLASS(recv) == rb_cFloat && RBASIC_CLASS(obj) == rb_cFloat &&
#####: 1479: BASIC_OP_UNREDEFINED_P(BOP_MULT, FLOAT_REDEFINED_OP_FLAG)) {
#####: 1480: val = DBL2NUM(RFLOAT_VALUE(recv) * RFLOAT_VALUE(obj));
-: 1481: }
-: 1482: else {
-: 1483: goto INSN_LABEL(normal_dispatch);
-: 1484: }
-: 1485: }
-: 1486: else {
-: 1487: INSN_LABEL(normal_dispatch):
1: 1488: PUSH(recv);
1: 1489: PUSH(obj);
1: 1490: CALL_SIMPLE_METHOD(recv);
-: 1491: }
-: 1492:}
-: 1493:
-: 1494:/**
-: 1495: @c optimize
-: 1496: @e optimized X/Y.
-: 1497: @j 最適化された X/Y。
-: 1498: */
-: 1499:DEFINE_INSN
-: 1500:opt_div
-: 1501:(CALL_INFO ci, CALL_CACHE cc)
-: 1502:(VALUE recv, VALUE obj)
-: 1503:(VALUE val)
-: 1504:{
2: 1505: if (FIXNUM_2_P(recv, obj) &&
1: 1506: BASIC_OP_UNREDEFINED_P(BOP_DIV, INTEGER_REDEFINED_OP_FLAG)) {
1: 1507: if (FIX2LONG(obj) == 0) goto INSN_LABEL(normal_dispatch);
#####: 1508: val = rb_fix_div_fix(recv, obj);
-: 1509: }
#####: 1510: else if (FLONUM_2_P(recv, obj) &&
#####: 1511: BASIC_OP_UNREDEFINED_P(BOP_DIV, FLOAT_REDEFINED_OP_FLAG)) {
#####: 1512: val = DBL2NUM(RFLOAT_VALUE(recv) / RFLOAT_VALUE(obj));
-: 1513: }
#####: 1514: else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
#####: 1515: if (RBASIC_CLASS(recv) == rb_cFloat && RBASIC_CLASS(obj) == rb_cFloat &&
#####: 1516: BASIC_OP_UNREDEFINED_P(BOP_DIV, FLOAT_REDEFINED_OP_FLAG)) {
#####: 1517: val = DBL2NUM(RFLOAT_VALUE(recv) / RFLOAT_VALUE(obj));
-: 1518: }
-: 1519: else {
-: 1520: goto INSN_LABEL(normal_dispatch);
-: 1521: }
-: 1522: }
-: 1523: else {
-: 1524: INSN_LABEL(normal_dispatch):
1: 1525: PUSH(recv);
1: 1526: PUSH(obj);
1: 1527: CALL_SIMPLE_METHOD(recv);
-: 1528: }
-: 1529:}
-: 1530:
-: 1531:/**
-: 1532: @c optimize
-: 1533: @e optimized X%Y.
-: 1534: @j 最適化された X%Y。
-: 1535: */
-: 1536:DEFINE_INSN
-: 1537:opt_mod
-: 1538:(CALL_INFO ci, CALL_CACHE cc)
-: 1539:(VALUE recv, VALUE obj)
-: 1540:(VALUE val)
-: 1541:{
1542: 1542: if (FIXNUM_2_P(recv, obj) &&
771: 1543: BASIC_OP_UNREDEFINED_P(BOP_MOD, INTEGER_REDEFINED_OP_FLAG )) {
771: 1544: if (FIX2LONG(obj) == 0) goto INSN_LABEL(normal_dispatch);
771: 1545: val = rb_fix_mod_fix(recv, obj);
-: 1546: }
#####: 1547: else if (FLONUM_2_P(recv, obj) &&
#####: 1548: BASIC_OP_UNREDEFINED_P(BOP_MOD, FLOAT_REDEFINED_OP_FLAG)) {
#####: 1549: val = DBL2NUM(ruby_float_mod(RFLOAT_VALUE(recv), RFLOAT_VALUE(obj)));
-: 1550: }
#####: 1551: else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
#####: 1552: if (RBASIC_CLASS(recv) == rb_cFloat && RBASIC_CLASS(obj) == rb_cFloat &&
#####: 1553: BASIC_OP_UNREDEFINED_P(BOP_MOD, FLOAT_REDEFINED_OP_FLAG)) {
#####: 1554: val = DBL2NUM(ruby_float_mod(RFLOAT_VALUE(recv), RFLOAT_VALUE(obj)));
-: 1555: }
-: 1556: else {
-: 1557: goto INSN_LABEL(normal_dispatch);
-: 1558: }
-: 1559: }
-: 1560: else {
-: 1561: INSN_LABEL(normal_dispatch):
#####: 1562: PUSH(recv);
#####: 1563: PUSH(obj);
#####: 1564: CALL_SIMPLE_METHOD(recv);
-: 1565: }
-: 1566:}
-: 1567:
-: 1568:/**
-: 1569: @c optimize
-: 1570: @e optimized X==Y.
-: 1571: @j 最適化された X==Y。
-: 1572: */
-: 1573:DEFINE_INSN
-: 1574:opt_eq
-: 1575:(CALL_INFO ci, CALL_CACHE cc)
-: 1576:(VALUE recv, VALUE obj)
-: 1577:(VALUE val)
-: 1578:{
885: 1579: val = opt_eq_func(recv, obj, ci, cc);
-: 1580:
885: 1581: if (val == Qundef) {
-: 1582: /* other */
1: 1583: PUSH(recv);
1: 1584: PUSH(obj);
1: 1585: CALL_SIMPLE_METHOD(recv);
-: 1586: }
-: 1587:}
-: 1588:
-: 1589:/**
-: 1590: @c optimize
-: 1591: @e optimized X!=Y.
-: 1592: @j 最適化された X!=Y。
-: 1593: */
-: 1594:DEFINE_INSN
-: 1595:opt_neq
-: 1596:(CALL_INFO ci, CALL_CACHE cc, CALL_INFO ci_eq, CALL_CACHE cc_eq)
-: 1597:(VALUE recv, VALUE obj)
-: 1598:(VALUE val)
-: 1599:{
-: 1600: extern VALUE rb_obj_not_equal(VALUE obj1, VALUE obj2);
#####: 1601: vm_search_method(ci, cc, recv);
-: 1602:
#####: 1603: val = Qundef;
-: 1604:
#####: 1605: if (check_cfunc(cc->me, rb_obj_not_equal)) {
#####: 1606: val = opt_eq_func(recv, obj, ci_eq, cc_eq);
-: 1607:
#####: 1608: if (val != Qundef) {
#####: 1609: val = RTEST(val) ? Qfalse : Qtrue;
-: 1610: }
-: 1611: }
-: 1612:
#####: 1613: if (val == Qundef) {
-: 1614: /* other */
#####: 1615: PUSH(recv);
#####: 1616: PUSH(obj);
#####: 1617: CALL_SIMPLE_METHOD(recv);
-: 1618: }
-: 1619:}
-: 1620:
-: 1621:/**
-: 1622: @c optimize
-: 1623: @e optimized X<Y.
-: 1624: @j 最適化された X<Y。
-: 1625: */
-: 1626:DEFINE_INSN
-: 1627:opt_lt
-: 1628:(CALL_INFO ci, CALL_CACHE cc)
-: 1629:(VALUE recv, VALUE obj)
-: 1630:(VALUE val)
-: 1631:{
144: 1632: if (FIXNUM_2_P(recv, obj) &&
60: 1633: BASIC_OP_UNREDEFINED_P(BOP_LT, INTEGER_REDEFINED_OP_FLAG)) {
60: 1634: SIGNED_VALUE a = recv, b = obj;
-: 1635:
60: 1636: if (a < b) {
-: 1637: val = Qtrue;
-: 1638: }
-: 1639: else {
13: 1640: val = Qfalse;
-: 1641: }
-: 1642: }
24: 1643: else if (FLONUM_2_P(recv, obj) &&
#####: 1644: BASIC_OP_UNREDEFINED_P(BOP_LT, FLOAT_REDEFINED_OP_FLAG)) {
-: 1645: /* flonum is not NaN */
#####: 1646: val = RFLOAT_VALUE(recv) < RFLOAT_VALUE(obj) ? Qtrue : Qfalse;
-: 1647: }
24: 1648: else if (FLOAT_INSTANCE_P(recv) && FLOAT_INSTANCE_P(obj) &&
#####: 1649: BASIC_OP_UNREDEFINED_P(BOP_LT, FLOAT_REDEFINED_OP_FLAG)) {
#####: 1650: val = double_cmp_lt(RFLOAT_VALUE(recv), RFLOAT_VALUE(obj));
-: 1651: }
-: 1652: else {
24: 1653: PUSH(recv);
24: 1654: PUSH(obj);
24: 1655: CALL_SIMPLE_METHOD(recv);
-: 1656: }
-: 1657:}
-: 1658:
-: 1659:/**
-: 1660: @c optimize
-: 1661: @e optimized X<=Y.
-: 1662: @j 最適化された X<=Y。
-: 1663: */
-: 1664:DEFINE_INSN
-: 1665:opt_le
-: 1666:(CALL_INFO ci, CALL_CACHE cc)
-: 1667:(VALUE recv, VALUE obj)
-: 1668:(VALUE val)
-: 1669:{
#####: 1670: if (FIXNUM_2_P(recv, obj) &&
#####: 1671: BASIC_OP_UNREDEFINED_P(BOP_LE, INTEGER_REDEFINED_OP_FLAG)) {
#####: 1672: SIGNED_VALUE a = recv, b = obj;
-: 1673:
#####: 1674: if (a <= b) {
-: 1675: val = Qtrue;
-: 1676: }
-: 1677: else {
#####: 1678: val = Qfalse;
-: 1679: }
-: 1680: }
#####: 1681: else if (FLONUM_2_P(recv, obj) &&
#####: 1682: BASIC_OP_UNREDEFINED_P(BOP_LE, FLOAT_REDEFINED_OP_FLAG)) {
-: 1683: /* flonum is not NaN */
#####: 1684: val = RFLOAT_VALUE(recv) <= RFLOAT_VALUE(obj) ? Qtrue : Qfalse;
-: 1685: }
#####: 1686: else if (FLOAT_INSTANCE_P(recv) && FLOAT_INSTANCE_P(obj) &&
#####: 1687: BASIC_OP_UNREDEFINED_P(BOP_LT, FLOAT_REDEFINED_OP_FLAG)) {
#####: 1688: val = double_cmp_le(RFLOAT_VALUE(recv), RFLOAT_VALUE(obj));
-: 1689: }
-: 1690: else {
-: 1691: /* other */
#####: 1692: PUSH(recv);
#####: 1693: PUSH(obj);
#####: 1694: CALL_SIMPLE_METHOD(recv);
-: 1695: }
-: 1696:}
-: 1697:
-: 1698:/**
-: 1699: @c optimize
-: 1700: @e optimized X>Y.
-: 1701: @j 最適化された X>Y。
-: 1702: */
-: 1703:DEFINE_INSN
-: 1704:opt_gt
-: 1705:(CALL_INFO ci, CALL_CACHE cc)
-: 1706:(VALUE recv, VALUE obj)
-: 1707:(VALUE val)
-: 1708:{
46: 1709: if (FIXNUM_2_P(recv, obj) &&
23: 1710: BASIC_OP_UNREDEFINED_P(BOP_GT, INTEGER_REDEFINED_OP_FLAG)) {
23: 1711: SIGNED_VALUE a = recv, b = obj;
-: 1712:
23: 1713: if (a > b) {
-: 1714: val = Qtrue;
-: 1715: }
-: 1716: else {
19: 1717: val = Qfalse;
-: 1718: }
-: 1719: }
#####: 1720: else if (FLONUM_2_P(recv, obj) &&
#####: 1721: BASIC_OP_UNREDEFINED_P(BOP_GT, FLOAT_REDEFINED_OP_FLAG)) {
-: 1722: /* flonum is not NaN */
#####: 1723: val = RFLOAT_VALUE(recv) > RFLOAT_VALUE(obj) ? Qtrue : Qfalse;
-: 1724: }
#####: 1725: else if (FLOAT_INSTANCE_P(recv) && FLOAT_INSTANCE_P(obj) &&
#####: 1726: BASIC_OP_UNREDEFINED_P(BOP_LT, FLOAT_REDEFINED_OP_FLAG)) {
#####: 1727: val = double_cmp_gt(RFLOAT_VALUE(recv), RFLOAT_VALUE(obj));
-: 1728: }
-: 1729: else {
#####: 1730: PUSH(recv);
#####: 1731: PUSH(obj);
#####: 1732: CALL_SIMPLE_METHOD(recv);
-: 1733: }
-: 1734:}
-: 1735:
-: 1736:/**
-: 1737: @c optimize
-: 1738: @e optimized X>=Y.
-: 1739: @j 最適化された X>=Y。
-: 1740: */
-: 1741:DEFINE_INSN
-: 1742:opt_ge
-: 1743:(CALL_INFO ci, CALL_CACHE cc)
-: 1744:(VALUE recv, VALUE obj)
-: 1745:(VALUE val)
-: 1746:{
#####: 1747: if (FIXNUM_2_P(recv, obj) &&
#####: 1748: BASIC_OP_UNREDEFINED_P(BOP_GE, INTEGER_REDEFINED_OP_FLAG)) {
#####: 1749: SIGNED_VALUE a = recv, b = obj;
-: 1750:
#####: 1751: if (a >= b) {
-: 1752: val = Qtrue;
-: 1753: }
-: 1754: else {
#####: 1755: val = Qfalse;
-: 1756: }
-: 1757: }
#####: 1758: else if (FLONUM_2_P(recv, obj) &&
#####: 1759: BASIC_OP_UNREDEFINED_P(BOP_GE, FLOAT_REDEFINED_OP_FLAG)) {
-: 1760: /* flonum is not NaN */
#####: 1761: val = RFLOAT_VALUE(recv) >= RFLOAT_VALUE(obj) ? Qtrue : Qfalse;
-: 1762: }
#####: 1763: else if (FLOAT_INSTANCE_P(recv) && FLOAT_INSTANCE_P(obj) &&
#####: 1764: BASIC_OP_UNREDEFINED_P(BOP_LT, FLOAT_REDEFINED_OP_FLAG)) {
#####: 1765: val = double_cmp_ge(RFLOAT_VALUE(recv), RFLOAT_VALUE(obj));
-: 1766: }
-: 1767: else {
#####: 1768: PUSH(recv);
#####: 1769: PUSH(obj);
#####: 1770: CALL_SIMPLE_METHOD(recv);
-: 1771: }
-: 1772:}
-: 1773:
-: 1774:/**
-: 1775: @c optimize
-: 1776: @e <<
-: 1777: @j 最適化された X<<Y。
-: 1778: */
-: 1779:DEFINE_INSN
-: 1780:opt_ltlt
-: 1781:(CALL_INFO ci, CALL_CACHE cc)
-: 1782:(VALUE recv, VALUE obj)
-: 1783:(VALUE val)
-: 1784:{
480: 1785: if (!SPECIAL_CONST_P(recv)) {
481: 1786: if (RBASIC_CLASS(recv) == rb_cString &&
1: 1787: BASIC_OP_UNREDEFINED_P(BOP_LTLT, STRING_REDEFINED_OP_FLAG)) {
1: 1788: val = rb_str_concat(recv, obj);
-: 1789: }
956: 1790: else if (RBASIC_CLASS(recv) == rb_cArray &&
477: 1791: BASIC_OP_UNREDEFINED_P(BOP_LTLT, ARRAY_REDEFINED_OP_FLAG)) {
477: 1792: val = rb_ary_push(recv, obj);
-: 1793: }
-: 1794: else {
-: 1795: goto INSN_LABEL(normal_dispatch);
-: 1796: }
-: 1797: }
-: 1798: else {
-: 1799: INSN_LABEL(normal_dispatch):
2: 1800: PUSH(recv);
2: 1801: PUSH(obj);
2: 1802: CALL_SIMPLE_METHOD(recv);
-: 1803: }
-: 1804:}
-: 1805:
-: 1806:/**
-: 1807: @c optimize
-: 1808: @e []
-: 1809: @j 最適化された recv[obj]。
-: 1810: */
-: 1811:DEFINE_INSN
-: 1812:opt_aref
-: 1813:(CALL_INFO ci, CALL_CACHE cc)
-: 1814:(VALUE recv, VALUE obj)
-: 1815:(VALUE val)
-: 1816:{
1327: 1817: if (!SPECIAL_CONST_P(recv)) {
1327: 1818: if (RBASIC_CLASS(recv) == rb_cArray && BASIC_OP_UNREDEFINED_P(BOP_AREF, ARRAY_REDEFINED_OP_FLAG) && FIXNUM_P(obj)) {
778: 1819: val = rb_ary_entry(recv, FIX2LONG(obj));
-: 1820: }
549: 1821: else if (RBASIC_CLASS(recv) == rb_cHash && BASIC_OP_UNREDEFINED_P(BOP_AREF, HASH_REDEFINED_OP_FLAG)) {
549: 1822: val = rb_hash_aref(recv, obj);
-: 1823: }
-: 1824: else {
-: 1825: goto INSN_LABEL(normal_dispatch);
-: 1826: }
-: 1827: }
-: 1828: else {
-: 1829: INSN_LABEL(normal_dispatch):
#####: 1830: PUSH(recv);
#####: 1831: PUSH(obj);
#####: 1832: CALL_SIMPLE_METHOD(recv);
-: 1833: }
-: 1834:}
-: 1835:
-: 1836:/**
-: 1837: @c optimize
-: 1838: @e recv[obj] = set
-: 1839: @j 最適化された recv[obj] = set。
-: 1840: */
-: 1841:DEFINE_INSN
-: 1842:opt_aset
-: 1843:(CALL_INFO ci, CALL_CACHE cc)
-: 1844:(VALUE recv, VALUE obj, VALUE set)
-: 1845:(VALUE val)
-: 1846:{
211569: 1847: if (!SPECIAL_CONST_P(recv)) {
211569: 1848: if (RBASIC_CLASS(recv) == rb_cArray && BASIC_OP_UNREDEFINED_P(BOP_ASET, ARRAY_REDEFINED_OP_FLAG) && FIXNUM_P(obj)) {
2: 1849: rb_ary_store(recv, FIX2LONG(obj), set);
2: 1850: val = set;
-: 1851: }
211567: 1852: else if (RBASIC_CLASS(recv) == rb_cHash && BASIC_OP_UNREDEFINED_P(BOP_ASET, HASH_REDEFINED_OP_FLAG)) {
211567: 1853: rb_hash_aset(recv, obj, set);
211567: 1854: val = set;
-: 1855: }
-: 1856: else {
-: 1857: goto INSN_LABEL(normal_dispatch);
-: 1858: }
-: 1859: }
-: 1860: else {
-: 1861: INSN_LABEL(normal_dispatch):
#####: 1862: PUSH(recv);
#####: 1863: PUSH(obj);
#####: 1864: PUSH(set);
#####: 1865: CALL_SIMPLE_METHOD(recv);
-: 1866: }
-: 1867:}
-: 1868:
-: 1869:/**
-: 1870: @c optimize
-: 1871: @e recv[str] = set
-: 1872: @j 最適化された recv[str] = set。
-: 1873: */
-: 1874:DEFINE_INSN
-: 1875:opt_aset_with
-: 1876:(CALL_INFO ci, CALL_CACHE cc, VALUE key)
-: 1877:(VALUE recv, VALUE val)
-: 1878:(VALUE val)
-: 1879:{
#####: 1880: if (!SPECIAL_CONST_P(recv) && RBASIC_CLASS(recv) == rb_cHash &&
#####: 1881: BASIC_OP_UNREDEFINED_P(BOP_ASET, HASH_REDEFINED_OP_FLAG) &&
#####: 1882: rb_hash_compare_by_id_p(recv) == Qfalse) {
#####: 1883: rb_hash_aset(recv, key, val);
-: 1884: }
-: 1885: else {
#####: 1886: PUSH(recv);
#####: 1887: PUSH(rb_str_resurrect(key));
#####: 1888: PUSH(val);
#####: 1889: CALL_SIMPLE_METHOD(recv);
-: 1890: }
-: 1891:}
-: 1892:
-: 1893:/**
-: 1894: @c optimize
-: 1895: @e recv[str]
-: 1896: @j 最適化された recv[str]。
-: 1897: */
-: 1898:DEFINE_INSN
-: 1899:opt_aref_with
-: 1900:(CALL_INFO ci, CALL_CACHE cc, VALUE key)
-: 1901:(VALUE recv)
-: 1902:(VALUE val)
-: 1903:{
18: 1904: if (!SPECIAL_CONST_P(recv) && RBASIC_CLASS(recv) == rb_cHash &&
4: 1905: BASIC_OP_UNREDEFINED_P(BOP_AREF, HASH_REDEFINED_OP_FLAG) &&
2: 1906: rb_hash_compare_by_id_p(recv) == Qfalse) {
2: 1907: val = rb_hash_aref(recv, key);
-: 1908: }
-: 1909: else {
14: 1910: PUSH(recv);
14: 1911: PUSH(rb_str_resurrect(key));
14: 1912: CALL_SIMPLE_METHOD(recv);
-: 1913: }
-: 1914:}
-: 1915:
-: 1916:/**
-: 1917: @c optimize
-: 1918: @e optimized length
-: 1919: @j 最適化された recv.length()。
-: 1920: */
-: 1921:DEFINE_INSN
-: 1922:opt_length
-: 1923:(CALL_INFO ci, CALL_CACHE cc)
-: 1924:(VALUE recv)
-: 1925:(VALUE val)
-: 1926:{
1: 1927: if (!SPECIAL_CONST_P(recv)) {
1: 1928: if (RBASIC_CLASS(recv) == rb_cString &&
#####: 1929: BASIC_OP_UNREDEFINED_P(BOP_LENGTH, STRING_REDEFINED_OP_FLAG)) {
#####: 1930: val = rb_str_length(recv);
-: 1931: }
2: 1932: else if (RBASIC_CLASS(recv) == rb_cArray &&
1: 1933: BASIC_OP_UNREDEFINED_P(BOP_LENGTH, ARRAY_REDEFINED_OP_FLAG)) {
1: 1934: val = LONG2NUM(RARRAY_LEN(recv));
-: 1935: }
#####: 1936: else if (RBASIC_CLASS(recv) == rb_cHash &&
#####: 1937: BASIC_OP_UNREDEFINED_P(BOP_LENGTH, HASH_REDEFINED_OP_FLAG)) {
#####: 1938: val = INT2FIX(RHASH_SIZE(recv));
-: 1939: }
-: 1940: else {
-: 1941: goto INSN_LABEL(normal_dispatch);
-: 1942: }
-: 1943: }
-: 1944: else {
-: 1945: INSN_LABEL(normal_dispatch):
#####: 1946: PUSH(recv);
#####: 1947: CALL_SIMPLE_METHOD(recv);
-: 1948: }
-: 1949:}
-: 1950:
-: 1951:/**
-: 1952: @c optimize
-: 1953: @e optimized size
-: 1954: @j 最適化された recv.size()。
-: 1955: */
-: 1956:DEFINE_INSN
-: 1957:opt_size
-: 1958:(CALL_INFO ci, CALL_CACHE cc)
-: 1959:(VALUE recv)
-: 1960:(VALUE val)
-: 1961:{
817: 1962: if (!SPECIAL_CONST_P(recv)) {
856: 1963: if (RBASIC_CLASS(recv) == rb_cString &&
39: 1964: BASIC_OP_UNREDEFINED_P(BOP_SIZE, STRING_REDEFINED_OP_FLAG)) {
39: 1965: val = rb_str_length(recv);
-: 1966: }
1556: 1967: else if (RBASIC_CLASS(recv) == rb_cArray &&
778: 1968: BASIC_OP_UNREDEFINED_P(BOP_SIZE, ARRAY_REDEFINED_OP_FLAG)) {
778: 1969: val = LONG2NUM(RARRAY_LEN(recv));
-: 1970: }
#####: 1971: else if (RBASIC_CLASS(recv) == rb_cHash &&
#####: 1972: BASIC_OP_UNREDEFINED_P(BOP_SIZE, HASH_REDEFINED_OP_FLAG)) {
#####: 1973: val = INT2FIX(RHASH_SIZE(recv));
-: 1974: }
-: 1975: else {
-: 1976: goto INSN_LABEL(normal_dispatch);
-: 1977: }
-: 1978: }
-: 1979: else {
-: 1980: INSN_LABEL(normal_dispatch):
#####: 1981: PUSH(recv);
#####: 1982: CALL_SIMPLE_METHOD(recv);
-: 1983: }
-: 1984:}
-: 1985:
-: 1986:/**
-: 1987: @c optimize
-: 1988: @e optimized empty?
-: 1989: @j 最適化された recv.empty?()。
-: 1990: */
-: 1991:DEFINE_INSN
-: 1992:opt_empty_p
-: 1993:(CALL_INFO ci, CALL_CACHE cc)
-: 1994:(VALUE recv)
-: 1995:(VALUE val)
-: 1996:{
375: 1997: if (!SPECIAL_CONST_P(recv)) {
375: 1998: if (RBASIC_CLASS(recv) == rb_cString &&
#####: 1999: BASIC_OP_UNREDEFINED_P(BOP_EMPTY_P, STRING_REDEFINED_OP_FLAG)) {
#####: 2000: if (RSTRING_LEN(recv) == 0) val = Qtrue;
#####: 2001: else val = Qfalse;
-: 2002: }
750: 2003: else if (RBASIC_CLASS(recv) == rb_cArray &&
375: 2004: BASIC_OP_UNREDEFINED_P(BOP_EMPTY_P, ARRAY_REDEFINED_OP_FLAG)) {
375: 2005: if (RARRAY_LEN(recv) == 0) val = Qtrue;
10: 2006: else val = Qfalse;
-: 2007: }
#####: 2008: else if (RBASIC_CLASS(recv) == rb_cHash &&
#####: 2009: BASIC_OP_UNREDEFINED_P(BOP_EMPTY_P, HASH_REDEFINED_OP_FLAG)) {
#####: 2010: if (RHASH_EMPTY_P(recv)) val = Qtrue;
#####: 2011: else val = Qfalse;
-: 2012: }
-: 2013: else {
-: 2014: goto INSN_LABEL(normal_dispatch);
-: 2015: }
-: 2016: }
-: 2017: else {
-: 2018: INSN_LABEL(normal_dispatch):
#####: 2019: PUSH(recv);
#####: 2020: CALL_SIMPLE_METHOD(recv);
-: 2021: }
-: 2022:}
-: 2023:
-: 2024:/**
-: 2025: @c optimize
-: 2026: @e optimized succ
-: 2027: @j 最適化された recv.succ()。
-: 2028: */
-: 2029:DEFINE_INSN
-: 2030:opt_succ
-: 2031:(CALL_INFO ci, CALL_CACHE cc)
-: 2032:(VALUE recv)
-: 2033:(VALUE val)
-: 2034:{
#####: 2035: if (SPECIAL_CONST_P(recv)) {
#####: 2036: if (FIXNUM_P(recv) &&
#####: 2037: BASIC_OP_UNREDEFINED_P(BOP_SUCC, INTEGER_REDEFINED_OP_FLAG)) {
-: 2038: /* fixnum + INT2FIX(1) */
#####: 2039: if (recv != LONG2FIX(FIXNUM_MAX)) {
#####: 2040: val = recv - 1 + INT2FIX(1);
-: 2041: }
-: 2042: else {
#####: 2043: val = LONG2NUM(FIXNUM_MAX + 1);
-: 2044: }
-: 2045: }
-: 2046: else {
-: 2047: goto INSN_LABEL(normal_dispatch);
-: 2048: }
-: 2049: }
-: 2050: else {
#####: 2051: if (RBASIC_CLASS(recv) == rb_cString &&
#####: 2052: BASIC_OP_UNREDEFINED_P(BOP_SUCC, STRING_REDEFINED_OP_FLAG)) {
#####: 2053: val = rb_str_succ(recv);
-: 2054: }
-: 2055: else {
-: 2056: goto INSN_LABEL(normal_dispatch);
-: 2057: }
-: 2058: }
-: 2059: if (0) {
-: 2060: INSN_LABEL(normal_dispatch):
#####: 2061: PUSH(recv);
#####: 2062: CALL_SIMPLE_METHOD(recv);
-: 2063: }
-: 2064:}
-: 2065:
-: 2066:/**
-: 2067: @c optimize
-: 2068: @e optimized not
-: 2069: @j 最適化された recv.!()。
-: 2070: */
-: 2071:DEFINE_INSN
-: 2072:opt_not
-: 2073:(CALL_INFO ci, CALL_CACHE cc)
-: 2074:(VALUE recv)
-: 2075:(VALUE val)
-: 2076:{
790: 2077: vm_search_method(ci, cc, recv);
-: 2078:
1580: 2079: if (check_cfunc(cc->me, rb_obj_not)) {
790: 2080: val = RTEST(recv) ? Qfalse : Qtrue;
-: 2081: }
-: 2082: else {
#####: 2083: PUSH(recv);
#####: 2084: CALL_SIMPLE_METHOD(recv);
-: 2085: }
-: 2086:}
-: 2087:
-: 2088:
-: 2089:/**
-: 2090: @c optimize
-: 2091: @e optimized regexp match
-: 2092: @j 最適化された正規表現マッチ。
-: 2093: */
-: 2094:DEFINE_INSN
-: 2095:opt_regexpmatch1
-: 2096:(VALUE r)
-: 2097:(VALUE obj)
-: 2098:(VALUE val)
-: 2099:{
778: 2100: if (BASIC_OP_UNREDEFINED_P(BOP_MATCH, REGEXP_REDEFINED_OP_FLAG)) {
778: 2101: val = rb_reg_match(r, obj);
-: 2102: }
-: 2103: else {
#####: 2104: val = rb_funcall(r, idEqTilde, 1, obj);
-: 2105: }
-: 2106:}
-: 2107:
-: 2108:/**
-: 2109: @c optimize
-: 2110: @e optimized regexp match 2
-: 2111: @j 最適化された正規表現マッチ 2
-: 2112: */
-: 2113:DEFINE_INSN
-: 2114:opt_regexpmatch2
-: 2115:(CALL_INFO ci, CALL_CACHE cc)
-: 2116:(VALUE obj2, VALUE obj1)
-: 2117:(VALUE val)
-: 2118:{
#####: 2119: if (CLASS_OF(obj2) == rb_cString &&
#####: 2120: BASIC_OP_UNREDEFINED_P(BOP_MATCH, STRING_REDEFINED_OP_FLAG)) {
#####: 2121: val = rb_reg_match(obj1, obj2);
-: 2122: }
-: 2123: else {
#####: 2124: PUSH(obj2);
#####: 2125: PUSH(obj1);
#####: 2126: CALL_SIMPLE_METHOD(obj2);
-: 2127: }
-: 2128:}
-: 2129:
-: 2130:/**
-: 2131: @c optimize
-: 2132: @e call native compiled method
-: 2133: @j ネイティブコンパイルしたメソッドを起動。
-: 2134: */
-: 2135:DEFINE_INSN
-: 2136:opt_call_c_function
-: 2137:(rb_insn_func_t funcptr)
-: 2138:()
-: 2139:()
-: 2140:{
#####: 2141: reg_cfp = (funcptr)(th, reg_cfp);
-: 2142:
#####: 2143: if (reg_cfp == 0) {
#####: 2144: VALUE err = th->errinfo;
#####: 2145: th->errinfo = Qnil;
#####: 2146: THROW_EXCEPTION(err);
-: 2147: }
-: 2148:
#####: 2149: RESTORE_REGS();
#####: 2150: NEXT_INSN();
-: 2151:}
-: 2152:
-: 2153:/**
-: 2154: @c joke
-: 2155: @e BLT
-: 2156: @j BLT
-: 2157: */
-: 2158:DEFINE_INSN
-: 2159:bitblt
-: 2160:()
-: 2161:()
-: 2162:(VALUE ret)
-: 2163:{
#####: 2164: ret = rb_str_new2("a bit of bacon, lettuce and tomato");
-: 2165:}
-: 2166:
-: 2167:/**
-: 2168: @c joke
-: 2169: @e The Answer to Life, the Universe, and Everything
-: 2170: @j 人生、宇宙、すべての答え。
-: 2171: */
-: 2172:DEFINE_INSN
-: 2173:answer
-: 2174:()
-: 2175:()
-: 2176:(VALUE ret)
-: 2177:{
#####: 2178: ret = INT2FIX(42);
-: 2179:}
-: 2180:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment