* test/ruby/envutil.rb (assert_normal_exit): show pid when fail.
[ruby-svn.git] / insns.def
blob348f956ed61961c35084491d1ac681a60b6eb070
1 /** ##skip -*- mode:c; style:ruby -*-
2 insns.def - YARV instruction definitions
4 $Author: $
5 created at: 04/01/01 01:17:55 JST
7 Copyright (C) 2004-2007 Koichi Sasada
8 */
10 /** ##skip
11 instruction comment
12 @c: category
13 @e: english description
14 @j: japanese description
16 instruction form:
17 DEFINE_INSN
18 instrunction_name
19 (instruction_operands, ..)
20 (pop_values, ..)
21 (return value)
23 .. // insn body
29 /**
30 @c nop
31 @e nop
32 @j nop
34 DEFINE_INSN
35 nop
40 /* none */
43 /**********************************************************/
44 /* deal with variables */
45 /**********************************************************/
47 /**
48 @c variable
49 @e get local variable value (which is pointed by idx).
50 @j idx ‚ÅŽw’肳‚ꂽƒ��[ƒJƒ‹•Ï�”‚ðƒXƒ^ƒbƒN‚É’u‚­�B
52 DEFINE_INSN
53 getlocal
54 (lindex_t idx)
56 (VALUE val)
58 val = *(GET_LFP() - idx);
61 /**
62 @c variable
63 @e set local variable value (which is pointed by idx) as val.
64 @j idx ‚ÅŽw’肳‚ꂽƒ��[ƒJƒ‹•Ï�”‚ð val ‚É�Ý’è‚·‚é�B
66 DEFINE_INSN
67 setlocal
68 (lindex_t idx)
69 (VALUE val)
72 (*(GET_LFP() - idx)) = val;
75 /**
76 @c variable
77 @e get special local variable ($~, $_, ..) value.
78 @j “ÁŽê‚ȃ��[ƒJƒ‹•Ï�”�i$~, $_, ...�j‚Ì’l‚𓾂é�B
80 DEFINE_INSN
81 getspecial
82 (VALUE key, rb_num_t type)
84 (VALUE val)
86 val = vm_getspecial(th, GET_LFP(), key, type);
89 /**
90 @c variable
91 @e set special local variable ($~, $_, ...) value as obj.
92 @j “Á•Ê‚ȃ��[ƒJƒ‹•Ï�”�i$~, $_, ...�j‚Ì’l‚ð‚ð�Ý’è‚·‚é�B
94 DEFINE_INSN
95 setspecial
96 (VALUE key)
97 (VALUE obj)
100 lfp_svar_set(th, GET_LFP(), key, obj);
104 @c variable
105 @e get block local variable(which is pointed by idx and level).
106 level means nest level of block, and specify how above this variable.
107 @j level, idx ‚ÅŽw’肳‚ꂽƒuƒ�ƒbƒNƒ��[ƒJƒ‹•Ï�”‚Ì’l‚ðƒXƒ^ƒbƒN‚É’u‚­�B
108 level ‚̓uƒ�ƒbƒN‚̃lƒXƒgƒŒƒxƒ‹‚Å�A‰½’i�ã‚©‚ðŽ¦‚·�B
110 DEFINE_INSN
111 getdynamic
112 (dindex_t idx, rb_num_t level)
114 (VALUE val)
116 int i;
117 VALUE *dfp2 = GET_DFP();
118 for (i = 0; i < level; i++) {
119 dfp2 = GET_PREV_DFP(dfp2);
121 val = *(dfp2 - idx);
125 @c variable
126 @e set block local variable(which is pointed by 'idx') as val.
127 level means nest level of block, and specify how above this variable.
128 @j level, idx ‚ÅŽw’肳‚ꂽƒuƒ�ƒbƒNƒ��[ƒJƒ‹•Ï�”‚Ì’l‚ð val ‚É‚·‚é�B
129 level ‚̓uƒ�ƒbƒN‚̃lƒXƒgƒŒƒxƒ‹‚Å�A‰½’i�ã‚©‚ðŽ¦‚·�B
131 DEFINE_INSN
132 setdynamic
133 (dindex_t idx, rb_num_t level)
134 (VALUE val)
137 int i;
138 VALUE *dfp2 = GET_DFP();
139 for (i = 0; i < level; i++) {
140 dfp2 = GET_PREV_DFP(dfp2);
142 *(dfp2 - idx) = val;
146 @c variable
147 @e get instance variable id of obj.
148 if is_local is not 0, search as class local variable.
149 @j self ‚̃Cƒ“ƒXƒ^ƒ“ƒX•Ï�” id ‚Ì’l‚𓾂é�B
151 DEFINE_INSN
152 getinstancevariable
153 (ID id)
155 (VALUE val)
157 val = rb_ivar_get(GET_SELF(), id);
161 @c variable
162 @e set instance variable id of obj as val.
163 if is_local is not 0, search as class local variable.
164 @j self ‚̃Cƒ“ƒXƒ^ƒ“ƒX•Ï�” id ‚ð val ‚É‚·‚é�B
166 DEFINE_INSN
167 setinstancevariable
168 (ID id)
169 (VALUE val)
172 rb_ivar_set(GET_SELF(), id, val);
176 @c variable
177 @e get class variable id of klass as val.
178 @j Œ»�݂̃XƒR�[ƒv‚̃Nƒ‰ƒX•Ï�” id ‚Ì’l‚𓾂é�B
180 DEFINE_INSN
181 getclassvariable
182 (ID id)
184 (VALUE val)
186 NODE * const cref = vm_get_cref(GET_ISEQ(), GET_LFP(), GET_DFP());
187 val = rb_cvar_get(vm_get_cvar_base(cref), id);
191 @c variable
192 @e set class variable id of klass as val.
193 @j klass ‚̃Nƒ‰ƒX•Ï�” id ‚ð val ‚É‚·‚é�B
195 DEFINE_INSN
196 setclassvariable
197 (ID id)
198 (VALUE val)
201 NODE * const cref = vm_get_cref(GET_ISEQ(), GET_LFP(), GET_DFP());
202 rb_cvar_set(vm_get_cvar_base(cref), id, val);
206 @c variable
208 get constant variable id. if klass is Qnil, constant
209 are searched in current scope. if klass is Qfalse, constant as
210 top level constant. otherwise, get constant under klass
211 class or module.
212 @j ’è�” id ‚Ì’l‚𓾂é�B
213 klass ‚ª Qnil ‚È‚ç�A‚»‚̃XƒR�[ƒv‚Å“¾‚ç‚ê‚é’è�”‚Ì’l‚𓾂é�B
214 Qfalse ‚È‚ç�AƒgƒbƒvƒŒƒxƒ‹ƒXƒR�[ƒv‚𓾂é�B
215 ‚»‚êˆÈŠO‚È‚ç�Aklass ƒNƒ‰ƒX‚̉º‚Ì’è�”‚𓾂é�B
217 DEFINE_INSN
218 getconstant
219 (ID id)
220 (VALUE klass)
221 (VALUE val)
223 val = vm_get_ev_const(th, GET_ISEQ(), klass, id, 0);
227 @c variable
229 set constant variable id. if klass is Qfalse, constant
230 is able to access in this scope. if klass is Qnil, set
231 top level constant. otherwise, set constant under klass
232 class or module.
234 @j ’è�” id ‚Ì’l‚ð val ‚É‚·‚é�B
235 klass ‚ª Qfalse ‚È‚ç�A‚»‚̃XƒR�[ƒv‚Å“¾‚ç‚ê‚é’è�” id ‚Ì’l‚ð�Ý’è‚·‚é�B
236 Qnil ‚È‚ç�AƒgƒbƒvƒŒƒxƒ‹ƒXƒR�[ƒv‚Ì’l‚ð�Ý’è‚·‚é�B
237 ‚»‚êˆÈŠO‚È‚ç�Aklass ƒNƒ‰ƒX‚̉º‚Ì’è�”‚ð�Ý’è‚·‚é�B
239 DEFINE_INSN
240 setconstant
241 (ID id)
242 (VALUE val, VALUE cbase)
245 vm_check_if_namespace(cbase);
246 rb_const_set(cbase, id, val);
247 INC_VM_STATE_VERSION();
251 @c variable
252 @e get global variable id.
253 @j ƒOƒ��[ƒoƒ‹•Ï�” id ‚Ì’l‚𓾂é�B
255 DEFINE_INSN
256 getglobal
257 (GENTRY entry)
259 (VALUE val)
261 val = GET_GLOBAL(entry);
265 @c variable
266 @e set global variable id as val.
267 @j ƒOƒ��[ƒoƒ‹•Ï�” id ‚Ì’l‚ð�Ý’è‚·‚é�B
269 DEFINE_INSN
270 setglobal
271 (GENTRY entry)
272 (VALUE val)
275 SET_GLOBAL(entry, val);
279 /**********************************************************/
280 /* deal with values */
281 /**********************************************************/
284 @c put
285 @e put nil to stack.
286 @j ƒXƒ^ƒbƒN‚É nil ‚ðƒvƒbƒVƒ…‚·‚é�B
288 DEFINE_INSN
289 putnil
292 (VALUE val)
294 val = Qnil;
298 @c put
299 @e put self.
300 @j ƒXƒ^ƒbƒN‚É self ‚ðƒvƒbƒVƒ…‚·‚é�B
302 DEFINE_INSN
303 putself
306 (VALUE val)
308 val = GET_SELF();
312 @c put
313 @e put cbase.
314 @j ƒXƒ^ƒbƒN‚É cbase ‚ðƒvƒbƒVƒ…‚·‚é�B
316 DEFINE_INSN
317 putcbase
320 (VALUE val)
322 val = vm_get_cbase(GET_ISEQ(), GET_LFP(), GET_DFP());
326 @c put
327 @e put some object.
328 i.e. Fixnum, true, false, nil, and so on.
329 @j ƒIƒuƒWƒFƒNƒg val ‚ðƒXƒ^ƒbƒN‚ɃvƒbƒVƒ…‚·‚é�B
330 i.e. Fixnum, true, false, nil, and so on.
332 DEFINE_INSN
333 putobject
334 (VALUE val)
336 (VALUE val)
338 /* */
342 @c put
343 @e put string val. string will be copied.
344 @j •¶Žš—ñ‚ð‚ðƒRƒs�[‚µ‚ăXƒ^ƒbƒN‚ɃvƒbƒVƒ…‚·‚é�B
346 DEFINE_INSN
347 putstring
348 (VALUE str)
350 (VALUE val)
352 val = rb_str_new3(str);
356 @c put
357 @e put concatenate strings
358 @j ƒXƒ^ƒbƒNƒgƒbƒv‚Ì•¶Žš—ñ‚ð n ŒÂ˜AŒ‹‚µ�CŒ‹‰Ê‚ðƒXƒ^ƒbƒN‚ɃvƒbƒVƒ…‚·‚é�B
360 DEFINE_INSN
361 concatstrings
362 (rb_num_t num)
363 (...)
364 (VALUE val) // inc += 1 - num;
366 int i;
368 val = rb_str_new(0, 0);
369 for (i = num - 1; i >= 0; i--) {
370 const VALUE v = TOPN(i);
371 rb_str_append(val, v);
373 POPN(num);
377 @c put
378 @e to_str
379 @j to_str ‚ÌŒ‹‰Ê‚ðƒXƒ^ƒbƒN‚ɃvƒbƒVƒ…‚·‚é�B
381 DEFINE_INSN
382 tostring
384 (VALUE val)
385 (VALUE val)
387 val = rb_obj_as_string(val);
391 @c put
392 @e to Regexp
393 @j •¶Žš—ñ str ‚ð�³‹K•\Œ»‚ɃRƒ“ƒpƒCƒ‹‚µ‚ăXƒ^ƒbƒN‚ɃvƒbƒVƒ…‚·‚é�B
394 ƒRƒ“ƒpƒCƒ‹Žž�Copt ‚ð�³‹K•\Œ»‚̃IƒvƒVƒ‡ƒ“‚Æ‚·‚é�B
396 DEFINE_INSN
397 toregexp
398 (rb_num_t opt, rb_num_t cnt)
399 (...)
400 (VALUE val) // inc += 1 - cnt;
402 VALUE rb_reg_new_ary(VALUE ary, int options);
403 int i;
404 const VALUE ary = rb_ary_new2(cnt);
405 RBASIC(ary)->klass = 0;
406 for (i = 0; i < cnt; i++) {
407 rb_ary_store(ary, cnt-i-1, TOPN(i));
409 POPN(cnt);
410 val = rb_reg_new_ary(ary, opt);
414 @c put
415 @e put new array.
416 @j �V‚µ‚¢”z—ñ‚ðƒXƒ^ƒbƒN�ã‚Ì num ŒÂ‚Ì’l‚Å�‰Šú‰»‚µ‚Ä�¶�¬‚µƒvƒbƒVƒ…‚·‚é�B
418 DEFINE_INSN
419 newarray
420 (rb_num_t num)
421 (...)
422 (VALUE val) // inc += 1 - num;
424 val = rb_ary_new4((long)num, STACK_ADDR_FROM_TOP(num));
425 POPN(num);
429 @c put
430 @e dup array
431 @j ”z—ñ ary ‚ð dup ‚µ‚ăXƒ^ƒbƒN‚ɃvƒbƒVƒ…‚·‚é�B
433 DEFINE_INSN
434 duparray
435 (VALUE ary)
437 (VALUE val)
439 val = rb_ary_dup(ary);
443 @c put
444 @e expand array to num objects.
445 @j ƒXƒ^ƒbƒNƒgƒbƒv‚̃IƒuƒWƒFƒNƒg‚ª”z—ñ‚Å‚ ‚ê‚Î�A‚»‚ê‚ð“WŠJ‚·‚é�B
446 ”z—ñƒIƒuƒWƒFƒNƒg‚Ì—v‘f�”‚ª numˆÈ‰º‚È‚ç‚Î�A‘ã‚í‚è‚É nil ‚ð�Ï‚Þ�BnumˆÈ�ã‚È‚ç�A
447 numˆÈ�ã‚Ì—v‘f‚Í�Ø‚èŽÌ‚Ä‚é�B
448 ”z—ñƒIƒuƒWƒFƒNƒg‚Å‚È‚¯‚ê‚Î�Anum - 1 ŒÂ‚Ì nil ‚ð�Ï‚Þ�B
449 ‚à‚µ flag ‚ª�^‚È‚ç�AŽc‚è—v‘f‚Ì”z—ñ‚ð�Ï‚Þ
450 flag: 0x01 - �ÅŒã‚ð”z—ñ‚É
451 flag: 0x02 - postarg —p
452 flag: 0x04 - reverse?
454 DEFINE_INSN
455 expandarray
456 (rb_num_t num, rb_num_t flag)
457 (..., VALUE ary)
458 (...) // inc += num - 1 + (flag & 1 ? 1 : 0);
460 vm_expandarray(GET_CFP(), ary, num, flag);
464 @c put
465 @e concat two arrays
466 @j “ñ‚‚̔z—ñ ary1, ary2 ‚ð˜AŒ‹‚µƒXƒ^ƒbƒN‚ÖƒvƒbƒVƒ…‚·‚é�B
468 DEFINE_INSN
469 concatarray
471 (VALUE ary1, VALUE ary2st)
472 (VALUE ary)
474 const VALUE ary2 = ary2st;
475 VALUE tmp1 = rb_check_convert_type(ary1, T_ARRAY, "Array", "to_a");
476 VALUE tmp2 = rb_check_convert_type(ary2, T_ARRAY, "Array", "to_a");
478 if (NIL_P(tmp1)) {
479 tmp1 = rb_ary_new3(1, ary1);
482 if (NIL_P(tmp2)) {
483 tmp2 = rb_ary_new3(1, ary2);
486 if (tmp1 == ary1) {
487 tmp1 = rb_ary_dup(ary1);
489 ary = rb_ary_concat(tmp1, tmp2);
493 @c put
494 @e splat array
495 @j ”z—ñ ary ‚ɑ΂µ‚Ä to_a ‚ðŒÄ‚Ñ�o‚·�B
497 DEFINE_INSN
498 splatarray
499 (VALUE flag)
500 (VALUE ary)
501 (VALUE obj)
503 VALUE tmp = rb_check_convert_type(ary, T_ARRAY, "Array", "to_a");
504 if (NIL_P(tmp)) {
505 tmp = rb_ary_new3(1, ary);
507 obj = tmp;
511 @c put
512 @e check value is included in ary
513 @j ”z—ñ ary ‚É—v‘f obj ‚ª“ü‚Á‚Ä‚¢‚é‚©‚Ç‚¤‚©ƒ`ƒFƒbƒN�Bcase/when ‚Å—˜—p‚·‚é�B
515 DEFINE_INSN
516 checkincludearray
517 (VALUE flag)
518 (VALUE obj, VALUE ary)
519 (VALUE obj, VALUE result)
521 int i;
522 result = Qfalse;
524 if (TYPE(ary) != T_ARRAY) {
525 ary = rb_Array(ary);
528 if (flag == Qtrue) {
529 /* NODE_CASE */
530 for (i = 0; i < RARRAY_LEN(ary); i++) {
531 /* TODO: fix me (use another method dispatch) */
532 if (RTEST(rb_funcall2(RARRAY_PTR(ary)[i], idEqq, 1, &obj))) {
533 result = Qtrue;
534 break;
538 else {
539 obj = Qfalse;
540 /* NODE_WHEN */
541 for (i = 0; i < RARRAY_LEN(ary); i++) {
542 if (RTEST(RARRAY_PTR(ary)[i])) {
543 obj = result = Qtrue;
544 break;
551 @c put
552 @e put new Hash.
553 @j �V‚µ‚¢ƒnƒbƒVƒ…‚ðƒXƒ^ƒbƒNƒgƒbƒv‚Ì n ŒÂ‚ð�‰Šú’l‚Æ‚µ‚Ä�¶�¬‚·‚é�B
554 n ‚̓L�[‚Æ’l‚̃yƒA‚È‚Ì‚Å 2 ‚Ì”{�”‚Å‚È‚¯‚ê‚΂Ȃç‚È‚¢�B
556 DEFINE_INSN
557 newhash
558 (rb_num_t num)
559 (...)
560 (VALUE val) // inc += 1 - num;
562 int i;
563 val = rb_hash_new();
565 for (i = num; i > 0; i -= 2) {
566 const VALUE v = TOPN(i - 2);
567 const VALUE k = TOPN(i - 1);
568 rb_hash_aset(val, k, v);
570 POPN(num);
574 @c put
575 @e put new Range object.(Range.new(low, high, flag))
576 @j Range.new(low, high, flag) ‚̂悤‚ȃIƒuƒWƒFƒNƒg‚ð�¶�¬‚µƒXƒ^ƒbƒN‚ɃvƒbƒVƒ…‚·‚é�B
578 DEFINE_INSN
579 newrange
580 (rb_num_t flag)
581 (VALUE low, VALUE high)
582 (VALUE val)
584 val = rb_range_new(low, high, flag);
587 /**********************************************************/
588 /* deal with stack operation */
589 /**********************************************************/
592 @c stack
593 @e pop from stack.
594 @j ƒXƒ^ƒbƒN‚©‚çˆê‚ƒ|ƒbƒv‚·‚é�B
596 DEFINE_INSN
599 (VALUE val)
602 val = val;
603 /* none */
607 @c stack
608 @e duplicate stack top.
609 @j ƒXƒ^ƒbƒNƒgƒbƒv‚ðƒRƒs�[‚µ‚ăXƒ^ƒbƒN‚ɃvƒbƒVƒ…‚·‚é�B
611 DEFINE_INSN
614 (VALUE val)
615 (VALUE val1, VALUE val2)
617 val1 = val2 = val;
621 @c stack
622 @e duplicate stack top n elements
623 @j ƒXƒ^ƒbƒNƒgƒbƒv‚Ì n ŒÂ‚ðƒRƒs�[‚µ‚ăXƒ^ƒbƒN‚ɃvƒbƒVƒ…‚·‚é�B
625 DEFINE_INSN
626 dupn
627 (rb_num_t n)
628 (...)
629 (...) // inc += n;
631 int i;
632 VALUE *sp = STACK_ADDR_FROM_TOP(n);
633 for (i = 0; i < n; i++) {
634 GET_SP()[i] = sp[i];
636 INC_SP(n);
641 @c stack
642 @e swap top 2 vals
643 @j ƒXƒ^ƒbƒNƒgƒbƒv‚Ì 2 ‚‚̒l‚ðŒðŠ·‚·‚é�B
645 DEFINE_INSN
646 swap
648 (VALUE val, VALUE obj)
649 (VALUE obj, VALUE val)
651 /* none */
655 @c stack
656 @e for stack caching.
657 @j ƒXƒ^ƒbƒNƒLƒƒƒbƒVƒ“ƒO‚Ì�ó‘Ô‚ð’²�®‚·‚邽‚ß‚É•K—v‚È–½—ß�B
659 DEFINE_INSN
660 reput
662 (..., VALUE val)
663 (VALUE val) // inc += 0;
665 /* none */
669 @c stack
670 @e get nth stack value from stack top
671 @j ƒXƒ^ƒbƒNƒgƒbƒv‚©‚ç n ŒÂ–Ú‚ðƒXƒ^ƒbƒN‚ɃvƒbƒVƒ…‚·‚é�B
673 DEFINE_INSN
674 topn
675 (rb_num_t n)
676 (...)
677 (VALUE val) // inc += 1;
679 val = TOPN(n);
683 @c stack
684 @e set Nth stack entry to stack top
685 @j ƒXƒ^ƒbƒNƒgƒbƒv‚Ì’l‚ð n ŒÂ–ڂ̃Xƒ^ƒbƒN‚ɃRƒs�[
687 DEFINE_INSN
688 setn
689 (rb_num_t n)
690 (..., VALUE val)
691 (VALUE val) // inc += 0
693 TOPN(n-1) = val;
697 @c stack
698 @e empt current stack
699 @j current stack ‚ð‹ó‚É‚·‚é�B
701 DEFINE_INSN
702 adjuststack
703 (rb_num_t n)
704 (...)
705 (...) // inc -= n
707 DEC_SP(n);
711 /**********************************************************/
712 /* deal with setting */
713 /**********************************************************/
716 @c setting
717 @e define (singleton) method id as body
718 @j �i“ÁˆÙ�jƒ�ƒ\ƒbƒh id ‚ð body ‚Æ‚µ‚Ä’è‹`‚·‚é�B
720 DEFINE_INSN
721 definemethod
722 (ID id, ISEQ body, rb_num_t is_singleton)
723 (VALUE obj)
726 NODE *cref = vm_get_cref(GET_ISEQ(), GET_LFP(), GET_DFP());
727 vm_define_method(th, obj, id, body, is_singleton, cref);
731 @c setting
732 @e make alias (if v_p is Qtrue, make valias)
733 @j alias ‚ð�ì‚é�B‚à‚µ v_p ‚ª Qtrue ‚È‚ç�Avalias (global variable) ‚ð�ì‚é�B
735 DEFINE_INSN
736 alias
737 (VALUE v_p)
738 (VALUE sym1, VALUE sym2)
741 if (v_p == Qtrue) {
742 rb_alias_variable(SYM2ID(sym1), SYM2ID(sym2));
744 else {
745 const VALUE klass = vm_get_cbase(GET_ISEQ(), GET_LFP(), GET_DFP());
746 rb_alias(klass, SYM2ID(sym1), SYM2ID(sym2));
751 @c setting
752 @e undef
753 @j undef ‚ð�s‚¤�B
755 DEFINE_INSN
756 undef
758 (VALUE sym)
761 const VALUE klass = vm_get_cbase(GET_ISEQ(), GET_LFP(), GET_DFP());
762 rb_undef(klass, SYM2ID(sym));
763 INC_VM_STATE_VERSION();
767 @c setting
768 @e defined?
769 @j defined? ‚ð�s‚¤�B
771 DEFINE_INSN
772 defined
773 (rb_num_t type, VALUE obj, VALUE needstr)
774 (VALUE v)
775 (VALUE val)
777 VALUE klass;
778 char *expr_type = 0;
779 val = Qnil;
781 switch (type) {
782 case DEFINED_IVAR:
783 if (rb_ivar_defined(GET_SELF(), SYM2ID(obj))) {
784 expr_type = "instance-variable";
786 break;
787 case DEFINED_IVAR2:
788 klass = vm_get_cbase(GET_ISEQ(), GET_LFP(), GET_DFP());
789 break;
790 case DEFINED_GVAR:
791 if (rb_gvar_defined((struct global_entry *)(obj & ~1))) {
792 expr_type = "global-variable";
794 break;
795 case DEFINED_CVAR:
796 klass = vm_get_cbase(GET_ISEQ(), GET_LFP(), GET_DFP());
797 if (rb_cvar_defined(klass, SYM2ID(obj))) {
798 expr_type = "class variable";
800 break;
801 case DEFINED_CONST:
802 klass = v;
803 if (vm_get_ev_const(th, GET_ISEQ(), klass, SYM2ID(obj), 1)) {
804 expr_type = "constant";
806 break;
807 case DEFINED_FUNC:
808 klass = CLASS_OF(v);
809 if (rb_method_boundp(klass, SYM2ID(obj), 0)) {
810 expr_type = "method";
812 break;
813 case DEFINED_METHOD:{
814 VALUE klass = CLASS_OF(v);
815 NODE *method = (NODE *) rb_method_node(klass, SYM2ID(obj));
817 if (method) {
818 if (!(method->nd_noex & NOEX_PRIVATE)) {
819 if (!((method->nd_noex & NOEX_PROTECTED) &&
820 !rb_obj_is_kind_of(GET_SELF(),
821 rb_class_real(klass)))) {
822 expr_type = "method";
826 break;
828 case DEFINED_YIELD:
829 if (GET_BLOCK_PTR()) {
830 expr_type = "yield";
832 break;
833 case DEFINED_ZSUPER:{
834 rb_iseq_t *ip = GET_ISEQ();
835 while (ip) {
836 if (ip->defined_method_id) {
837 break;
839 ip = ip->parent_iseq;
841 if (ip) {
842 VALUE klass = vm_search_normal_superclass(ip->klass, GET_SELF());
843 if (rb_method_boundp(klass, ip->defined_method_id, 0)) {
844 expr_type = "super";
847 break;
849 case DEFINED_REF:{
850 val = vm_getspecial(th, GET_LFP(), Qfalse, FIX2INT(obj));
851 if (val != Qnil) {
852 expr_type = "global-variable";
854 break;
856 default:
857 rb_bug("unimplemented defined? type (VM)");
858 break;
860 if (expr_type != 0) {
861 if (needstr != Qfalse) {
862 val = rb_str_new2(expr_type);
864 else {
865 val = Qtrue;
871 @c setting
872 @e END{}
873 @j END{} ‚ɑΉž‚·‚邽‚߂Ƀuƒ�ƒbƒN‚ð“o˜^‚·‚é�B
875 DEFINE_INSN
876 postexe
877 (ISEQ blockiseq)
881 rb_block_t *blockptr;
882 VALUE proc;
883 extern void rb_call_end_proc(VALUE data);
885 blockptr = RUBY_VM_GET_BLOCK_PTR_IN_CFP(GET_CFP());
886 blockptr->iseq = blockiseq;
887 blockptr->proc = 0;
889 proc = vm_make_proc(th, GET_CFP(), blockptr);
890 rb_set_end_proc(rb_call_end_proc, proc);
894 @c setting
895 @e trace
896 @j trace —p‚Ì–½—ß�B
898 DEFINE_INSN
899 trace
900 (rb_num_t nf)
904 rb_event_flag_t flag = nf;
905 EXEC_EVENT_HOOK(th, flag, GET_SELF(), 0, 0 /* TODO: id, klass */);
908 /**********************************************************/
909 /* deal with control flow 1: class/module */
910 /**********************************************************/
913 @c class/module
915 enter class definition scope. if super is Qfalse, and clsas
916 "klass" is defined, it's redefine. otherwise, define "klass" class.
917 @j ƒNƒ‰ƒX’è‹`ƒXƒR�[ƒv‚ÖˆÚ�s‚·‚é�B
918 ‚à‚µ super ‚ª Qfalse ‚Å klassƒNƒ‰ƒX‚ª’è‹`‚³‚ê‚Ä‚¢‚ê‚Î�Ä’è‹`‚Å‚ ‚é�B
919 ‚»‚¤‚Å‚È‚¯‚ê‚Î�Aklass ƒNƒ‰ƒX‚ð’è‹`‚·‚é�B
921 DEFINE_INSN
922 defineclass
923 (ID id, ISEQ class_iseq, rb_num_t define_type)
924 (VALUE cbase, VALUE super)
925 (VALUE val)
927 VALUE klass;
929 switch ((int)define_type) {
930 case 0:
931 /* val is dummy. classdef returns class scope value */
933 if (super == Qnil) {
934 super = rb_cObject;
937 vm_check_if_namespace(cbase);
939 /* find klass */
940 if (rb_const_defined_at(cbase, id)) {
941 /* already exist */
942 klass = rb_const_get_at(cbase, id);
943 if (TYPE(klass) != T_CLASS) {
944 rb_raise(rb_eTypeError, "%s is not a class", rb_id2name(id));
947 if (super != rb_cObject) {
948 VALUE tmp;
949 tmp = rb_class_real(RCLASS_SUPER(klass));
951 if (tmp != super) {
952 rb_raise(rb_eTypeError, "superclass mismatch for class %s",
953 rb_id2name(id));
957 else {
958 /* new class declaration */
959 klass = rb_define_class_id(id, super);
960 rb_set_class_path(klass, cbase, rb_id2name(id));
961 rb_const_set(cbase, id, klass);
962 rb_class_inherited(super, klass);
964 break;
965 case 1:
966 /* val is dummy. classdef returns class scope value */
967 /* super is dummy */
968 klass = rb_singleton_class(cbase);
969 break;
970 case 2:
971 /* val is dummy. classdef returns class scope value */
972 /* super is dummy */
974 vm_check_if_namespace(cbase);
976 /* find klass */
977 if (rb_const_defined_at(cbase, id)) {
978 klass = rb_const_get_at(cbase, id);
979 /* already exist */
980 if (TYPE(klass) != T_MODULE) {
981 rb_raise(rb_eTypeError, "%s is not a module", rb_id2name(id));
984 else {
985 /* new module declaration */
986 klass = rb_define_module_id(id);
987 rb_set_class_path(klass, cbase, rb_id2name(id));
988 rb_const_set(cbase, id, klass);
990 break;
991 default:
992 rb_bug("unknown defineclass type: %d", (int)define_type);
995 COPY_CREF(class_iseq->cref_stack, vm_cref_push(th, klass, NOEX_PUBLIC));
997 /* enter scope */
998 vm_push_frame(th, class_iseq,
999 FRAME_MAGIC_CLASS, klass, (VALUE) GET_DFP() | 0x02,
1000 class_iseq->iseq_encoded, GET_SP(), 0,
1001 class_iseq->local_size);
1002 RESTORE_REGS();
1004 INC_VM_STATE_VERSION();
1005 NEXT_INSN();
1009 /**********************************************************/
1010 /* deal with control flow 2: method/iterator */
1011 /**********************************************************/
1014 @c method/iterator
1015 @e obj.send(id, args..) # args.size => num
1016 @j ƒ�ƒ\ƒbƒhŒÄ‚Ñ�o‚µ‚ð�s‚¤�B
1017 obj.send(id, args..) # args.size => num
1018 flag & VM_CALL_ARGS_SPLAT_BIT != 0 -> splat last arg
1019 flag & VM_CALL_ARGS_BLOCKARG_BIT != 0 -> Proc as Block
1020 flag & VM_CALL_FCALL_BIT != 0 -> FCALL ( func() )
1021 flag & VM_CALL_VCALL_BIT != 0 -> VCALL ( func )
1024 DEFINE_INSN
1025 send
1026 (ID op_id, rb_num_t op_argc, ISEQ blockiseq, rb_num_t op_flag, IC ic)
1027 (...)
1028 (VALUE val) // inc += - (op_argc + ((op_flag & VM_CALL_ARGS_BLOCKARG_BIT) ? 1 : 0));
1030 NODE *mn;
1031 VALUE recv, klass;
1032 rb_block_t *blockptr = 0;
1033 rb_num_t num = caller_setup_args(th, GET_CFP(), op_flag, op_argc,
1034 (rb_iseq_t *)blockiseq, &blockptr);
1035 rb_num_t flag = op_flag;
1036 ID id = op_id;
1038 /* get receiver */
1039 recv = (flag & VM_CALL_FCALL_BIT) ? GET_SELF() : TOPN(num);
1040 klass = CLASS_OF(recv);
1041 mn = vm_method_search(id, klass, ic);
1043 /* send/funcall optimization */
1044 if (flag & VM_CALL_SEND_BIT) {
1045 vm_send_optimize(GET_CFP(), &mn, &flag, &num, &id, klass);
1048 CALL_METHOD(num, blockptr, flag, id, mn, recv, klass);
1052 @c method/iterator
1053 @e super(args) # args.size => num
1054 @j super ‚ðŽÀ�s‚·‚é�B
1055 super(args) # args.size => num
1056 flag “™ƒIƒyƒ‰ƒ“ƒh‚̈Ӗ¡‚Í send ‚Æ“¯‚¶�B
1058 DEFINE_INSN
1059 invokesuper
1060 (rb_num_t op_argc, ISEQ blockiseq, rb_num_t op_flag)
1061 (...)
1062 (VALUE val) // inc += - (op_argc + ((op_flag & VM_CALL_ARGS_BLOCKARG_BIT) ? 1 : 0));
1064 rb_block_t *blockptr = !(op_flag & VM_CALL_ARGS_BLOCKARG_BIT) ? GET_BLOCK_PTR() : 0;
1065 int num = caller_setup_args(th, GET_CFP(), op_flag, op_argc, blockiseq, &blockptr);
1066 VALUE recv, klass;
1067 NODE *mn;
1068 ID id;
1069 const VALUE flag = VM_CALL_SUPER_BIT | VM_CALL_FCALL_BIT;
1071 recv = GET_SELF();
1072 vm_search_superclass(GET_CFP(), GET_ISEQ(), recv, TOPN(num), &id, &klass);
1073 mn = rb_method_node(klass, id);
1075 CALL_METHOD(num, blockptr, flag, id, mn, recv, klass);
1079 @c method/iterator
1080 @e yield(args) # args.size => num, flag shows expand argument or not
1081 @j yield ‚ðŽÀ�s‚·‚é�B
1082 yield(args) # args.size => num
1084 DEFINE_INSN
1085 invokeblock
1086 (rb_num_t num, rb_num_t flag)
1087 (...)
1088 (VALUE val) // inc += 1 - num;
1090 val = vm_invoke_block(th, GET_CFP(), num, flag);
1091 if (val == Qundef) {
1092 RESTORE_REGS();
1093 NEXT_INSN();
1098 @c method/iterator
1099 @e return from this scope.
1100 @j ‚±‚̃XƒR�[ƒv‚©‚甲‚¯‚é�B
1102 DEFINE_INSN
1103 leave
1105 (VALUE val)
1106 (VALUE val)
1108 if (OPT_CHECKED_RUN) {
1109 if (reg_cfp->sp != reg_cfp->bp) {
1110 rb_bug("Stack consistency error (sp: %d, bp: %d)",
1111 VM_SP_CNT(th, reg_cfp->sp), VM_SP_CNT(th, reg_cfp->bp));
1115 RUBY_VM_CHECK_INTS();
1116 vm_pop_frame(th);
1117 RESTORE_REGS();
1121 @c method/iterator
1122 @e return from this vm loop
1123 @j VM loop ‚©‚甲‚¯‚é�B
1125 DEFINE_INSN
1126 finish
1128 (VALUE val)
1129 (VALUE val)
1131 #if OPT_CALL_THREADED_CODE
1132 rb_bug("unused instruction on OPT_CALL_THREADED_CODE");
1133 #else
1134 th->cfp++;
1135 return val;
1136 #endif
1139 /**********************************************************/
1140 /* deal with control flow 3: exception */
1141 /**********************************************************/
1144 @c exception
1145 @e longjump
1146 @j ‘åˆæƒWƒƒƒ“ƒv‚ð�s‚¤�B
1148 DEFINE_INSN
1149 throw
1150 (rb_num_t throw_state)
1151 (VALUE throwobj)
1152 (VALUE val)
1154 RUBY_VM_CHECK_INTS();
1155 val = vm_throw(th, GET_CFP(), throw_state, throwobj);
1156 THROW_EXCEPTION(val);
1157 /* unreachable */
1160 /**********************************************************/
1161 /* deal with control flow 4: local jump */
1162 /**********************************************************/
1165 @c jump
1166 @e set PC to (PC + dst).
1167 @j PC ‚ð (PC + dst) ‚É‚·‚é�B
1169 DEFINE_INSN
1170 jump
1171 (OFFSET dst)
1175 RUBY_VM_CHECK_INTS();
1176 JUMP(dst);
1180 @c jump
1181 @e if val is not false or nil, set PC to (PC + dst).
1182 @j ‚à‚µ val ‚ª false ‚© nil ‚Å‚È‚¯‚ê‚Î�APC ‚ð (PC + dst) ‚É‚·‚é�B
1184 DEFINE_INSN
1185 branchif
1186 (OFFSET dst)
1187 (VALUE val)
1190 if (RTEST(val)) {
1191 RUBY_VM_CHECK_INTS();
1192 JUMP(dst);
1197 @c jump
1198 @e if val is false or nil, set PC to (PC + dst).
1199 @j ‚à‚µ val ‚ª false ‚© nil ‚È‚ç‚Î�APC ‚ð (PC + dst) ‚É‚·‚é�B
1201 DEFINE_INSN
1202 branchunless
1203 (OFFSET dst)
1204 (VALUE val)
1207 if (!RTEST(val)) {
1208 RUBY_VM_CHECK_INTS();
1209 JUMP(dst);
1214 /**********************************************************/
1215 /* for optimize */
1216 /**********************************************************/
1219 @c optimize
1220 @e inline cache
1221 @j ƒCƒ“ƒ‰ƒCƒ“ƒLƒƒƒbƒVƒ…‚ª—LŒø‚È‚ç�A’l‚ðƒXƒ^ƒbƒN‚ɃvƒbƒVƒ…‚µ‚Ä dst ‚ÖƒWƒƒƒ“ƒv‚·‚é�B
1223 DEFINE_INSN
1224 getinlinecache
1225 (IC ic, OFFSET dst)
1227 (VALUE val)
1229 if (ic->ic_vmstat == GET_VM_STATE_VERSION()) {
1230 val = ic->ic_value;
1231 JUMP(dst);
1233 else {
1234 /* none */
1235 val = Qnil;
1240 @c optimize
1241 @e inline cache (once)
1242 @j once ‚ðŽÀŒ»‚·‚é�B
1244 DEFINE_INSN
1245 onceinlinecache
1246 (IC ic, OFFSET dst)
1248 (VALUE val)
1250 if (ic->ic_vmstat) {
1251 val = ic->ic_value;
1252 JUMP(dst);
1254 else {
1255 /* none */
1256 val = Qnil;
1261 @c optimize
1262 @e set inline cache
1263 @j ƒCƒ“ƒ‰ƒCƒ“ƒLƒƒƒbƒVƒ…‚Ì’l‚ð�Ý’è‚·‚é�B
1265 DEFINE_INSN
1266 setinlinecache
1267 (OFFSET dst)
1268 (VALUE val)
1269 (VALUE val)
1271 IC ic = GET_CONST_INLINE_CACHE(dst);
1273 ic->ic_value = val;
1274 ic->ic_vmstat = GET_VM_STATE_VERSION();
1278 @c optimize
1279 @e case dispatcher
1280 @j case •¶‚Å�A‰Â”\‚È‚ç•\ˆø‚«‚ŃWƒƒƒ“ƒv‚·‚é�B
1282 DEFINE_INSN
1283 opt_case_dispatch
1284 (CDHASH hash, OFFSET else_offset)
1285 (..., VALUE key)
1286 () // inc += -1;
1288 if (0) {
1289 /* TODO: if some === method is overrided */
1291 else {
1292 VALUE val;
1293 if (st_lookup(RHASH_TBL(hash), key, &val)) {
1294 JUMP(FIX2INT(val));
1296 else {
1297 JUMP(else_offset);
1303 @c optimize
1304 @e check environment
1305 @j �«—ˆ‚ÌŠg’£—p�B
1307 DEFINE_INSN
1308 opt_checkenv
1313 if (GET_CFP()->bp != GET_DFP() + 1) {
1314 VALUE *new_dfp = GET_CFP()->bp - 1;
1315 /* TODO: copy env and clean stack at creating env? */
1316 *new_dfp = *GET_DFP();
1317 SET_DFP(new_dfp);
1322 /** simple functions */
1325 @c optimize
1326 @e optimized X+Y.
1327 @j �Å“K‰»‚³‚ꂽ X+Y�B
1329 DEFINE_INSN
1330 opt_plus
1332 (VALUE recv, VALUE obj)
1333 (VALUE val)
1335 if (0) {
1338 #if 1
1339 else if (FIXNUM_2_P(recv, obj) &&
1340 BASIC_OP_UNREDEFINED_P(BOP_PLUS)) {
1341 /* fixnum + fixnum */
1342 #ifndef LONG_LONG_VALUE
1343 val = (recv + (obj & (~1)));
1344 if ((~(recv ^ obj) & (recv ^ val)) &
1345 ((VALUE)0x01 << ((sizeof(VALUE) * CHAR_BIT) - 1))) {
1346 val = rb_big_plus(rb_int2big(FIX2LONG(recv)),
1347 rb_int2big(FIX2LONG(obj)));
1349 #else
1350 long a, b, c;
1351 a = FIX2LONG(recv);
1352 b = FIX2LONG(obj);
1353 c = a + b;
1354 if (FIXABLE(c)) {
1355 val = LONG2FIX(c);
1357 else {
1358 val = rb_big_plus(rb_int2big(a), rb_int2big(b));
1360 #endif
1362 #endif
1364 else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
1365 if (0) {
1367 #if 1
1368 else if (HEAP_CLASS_OF(recv) == rb_cFloat &&
1369 HEAP_CLASS_OF(obj) == rb_cFloat &&
1370 BASIC_OP_UNREDEFINED_P(BOP_PLUS)) {
1371 val = DOUBLE2NUM(RFLOAT_VALUE(recv) + RFLOAT_VALUE(obj));
1373 #endif
1375 #if 1
1376 else if (HEAP_CLASS_OF(recv) == rb_cString &&
1377 HEAP_CLASS_OF(obj) == rb_cString &&
1378 BASIC_OP_UNREDEFINED_P(BOP_PLUS)) {
1379 val = rb_str_plus(recv, obj);
1381 #endif
1382 #if 1
1383 else if (HEAP_CLASS_OF(recv) == rb_cArray &&
1384 BASIC_OP_UNREDEFINED_P(BOP_PLUS)) {
1385 val = rb_ary_plus(recv, obj);
1387 #endif
1388 else {
1389 goto INSN_LABEL(normal_dispatch);
1392 else {
1393 INSN_LABEL(normal_dispatch):
1394 PUSH(recv);
1395 PUSH(obj);
1396 CALL_SIMPLE_METHOD(1, idPLUS, recv);
1401 @c optimize
1402 @e optimized X-Y.
1403 @j �Å“K‰»‚³‚ꂽ X-Y�B
1405 DEFINE_INSN
1406 opt_minus
1408 (VALUE recv, VALUE obj)
1409 (VALUE val)
1411 if (FIXNUM_2_P(recv, obj) &&
1412 BASIC_OP_UNREDEFINED_P(BOP_MINUS)) {
1413 long a, b, c;
1415 a = FIX2LONG(recv);
1416 b = FIX2LONG(obj);
1417 c = a - b;
1419 if (FIXABLE(c)) {
1420 val = LONG2FIX(c);
1422 else {
1423 val = rb_big_minus(rb_int2big(a), rb_int2big(b));
1426 else {
1427 /* other */
1428 PUSH(recv);
1429 PUSH(obj);
1430 CALL_SIMPLE_METHOD(1, idMINUS, recv);
1435 @c optimize
1436 @e optimized X*Y.
1437 @j �Å“K‰»‚³‚ꂽ X*Y�B
1439 DEFINE_INSN
1440 opt_mult
1442 (VALUE recv, VALUE obj)
1443 (VALUE val)
1445 if (FIXNUM_2_P(recv, obj) &&
1446 BASIC_OP_UNREDEFINED_P(BOP_MULT)) {
1447 long a, b, c;
1449 a = FIX2LONG(recv);
1450 if (a == 0) {
1451 val = recv;
1453 else {
1454 b = FIX2LONG(obj);
1455 c = a * b;
1457 if (FIXABLE(c) && c / a == b) {
1458 val = LONG2FIX(c);
1460 else {
1461 val = rb_big_mul(rb_int2big(a), rb_int2big(b));
1465 else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
1466 if (0) {
1468 #if 1
1469 else if (HEAP_CLASS_OF(recv) == rb_cFloat &&
1470 HEAP_CLASS_OF(obj) == rb_cFloat &&
1471 BASIC_OP_UNREDEFINED_P(BOP_MULT)) {
1472 val = DOUBLE2NUM(RFLOAT_VALUE(recv) * RFLOAT_VALUE(obj));
1474 #endif
1475 else {
1476 goto INSN_LABEL(normal_dispatch);
1479 else {
1480 INSN_LABEL(normal_dispatch):
1481 PUSH(recv);
1482 PUSH(obj);
1483 CALL_SIMPLE_METHOD(1, idMULT, recv);
1488 @c optimize
1489 @e optimized X/Y.
1490 @j �Å“K‰»‚³‚ꂽ X/Y�B
1492 DEFINE_INSN
1493 opt_div
1495 (VALUE recv, VALUE obj)
1496 (VALUE val)
1498 if (FIXNUM_2_P(recv, obj) &&
1499 BASIC_OP_UNREDEFINED_P(BOP_DIV)) {
1500 long x, y, div;
1502 x = FIX2LONG(recv);
1503 y = FIX2LONG(obj);
1505 /* copied from numeric.c#fixdivmod */
1506 long mod;
1507 if (y == 0)
1508 goto INSN_LABEL(normal_dispatch);
1509 if (y < 0) {
1510 if (x < 0)
1511 div = -x / -y;
1512 else
1513 div = -(x / -y);
1515 else {
1516 if (x < 0)
1517 div = -(-x / y);
1518 else
1519 div = x / y;
1521 mod = x - div * y;
1522 if ((mod < 0 && y > 0) || (mod > 0 && y < 0)) {
1523 mod += y;
1524 div -= 1;
1527 val = LONG2NUM(div);
1529 else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
1530 if (0) {
1532 #if 1
1533 else if (HEAP_CLASS_OF(recv) == rb_cFloat &&
1534 HEAP_CLASS_OF(obj) == rb_cFloat &&
1535 BASIC_OP_UNREDEFINED_P(BOP_DIV)) {
1536 val = DOUBLE2NUM(RFLOAT_VALUE(recv) / RFLOAT_VALUE(obj));
1538 #endif
1539 else {
1540 goto INSN_LABEL(normal_dispatch);
1543 else {
1544 INSN_LABEL(normal_dispatch):
1545 PUSH(recv);
1546 PUSH(obj);
1547 CALL_SIMPLE_METHOD(1, idDIV, recv);
1552 @c optimize
1553 @e optimized X%Y.
1554 @j �Å“K‰»‚³‚ꂽ X%Y�B
1556 DEFINE_INSN
1557 opt_mod
1559 (VALUE recv, VALUE obj)
1560 (VALUE val)
1562 if (FIXNUM_2_P(recv, obj) &&
1563 BASIC_OP_UNREDEFINED_P(BOP_MOD)) {
1564 long x, y, mod;
1566 x = FIX2LONG(recv);
1567 y = FIX2LONG(obj);
1569 /* copied from numeric.c#fixdivmod */
1570 long div;
1572 if (y == 0)
1573 rb_num_zerodiv();
1574 if (y < 0) {
1575 if (x < 0)
1576 div = -x / -y;
1577 else
1578 div = -(x / -y);
1580 else {
1581 if (x < 0)
1582 div = -(-x / y);
1583 else
1584 div = x / y;
1586 mod = x - div * y;
1587 if ((mod < 0 && y > 0) || (mod > 0 && y < 0)) {
1588 mod += y;
1589 div -= 1;
1592 val = LONG2FIX(mod);
1594 else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
1595 if (0) {
1597 else if (HEAP_CLASS_OF(recv) == rb_cFloat &&
1598 HEAP_CLASS_OF(obj) == rb_cFloat &&
1599 BASIC_OP_UNREDEFINED_P(BOP_MOD)) {
1600 double x = RFLOAT_VALUE(recv);
1601 double y = RFLOAT_VALUE(obj);
1602 double div, mod;
1605 double z;
1607 modf(x / y, &z);
1608 mod = x - z * y;
1611 div = (x - mod) / y;
1612 if (y * mod < 0) {
1613 mod += y;
1614 div -= 1.0;
1616 val = DOUBLE2NUM(mod);
1618 else {
1619 goto INSN_LABEL(normal_dispatch);
1622 else {
1623 INSN_LABEL(normal_dispatch):
1624 PUSH(recv);
1625 PUSH(obj);
1626 CALL_SIMPLE_METHOD(1, idMOD, recv);
1631 @c optimize
1632 @e optimized X==Y.
1633 @j �Å“K‰»‚³‚ꂽ X==Y�B
1635 DEFINE_INSN
1636 opt_eq
1637 (IC ic)
1638 (VALUE recv, VALUE obj)
1639 (VALUE val)
1641 val = opt_eq_func(recv, obj, ic);
1643 if (val == Qundef) {
1644 /* other */
1645 PUSH(recv);
1646 PUSH(obj);
1647 CALL_SIMPLE_METHOD(1, idEq, recv);
1652 @c optimize
1653 @e optimized X!=Y.
1654 @j �Å“K‰»‚³‚ꂽ X!=Y�B
1656 DEFINE_INSN
1657 opt_neq
1658 (IC ic1, IC ic2)
1659 (VALUE recv, VALUE obj)
1660 (VALUE val)
1662 extern VALUE rb_obj_not_equal(VALUE obj1, VALUE obj2);
1663 NODE *mn = vm_method_search(idNeq, CLASS_OF(recv), ic1);
1664 val = Qundef;
1666 if (check_cfunc(mn, rb_obj_not_equal)) {
1667 val = opt_eq_func(recv, obj, ic2);
1669 if (val != Qundef) {
1670 val = RTEST(val) ? Qfalse : Qtrue;
1674 if (val == Qundef) {
1675 /* other */
1676 PUSH(recv);
1677 PUSH(obj);
1678 CALL_SIMPLE_METHOD(1, idNeq, recv);
1683 @c optimize
1684 @e optimized X<Y.
1685 @j �Å“K‰»‚³‚ꂽ X<Y�B
1687 DEFINE_INSN
1688 opt_lt
1690 (VALUE recv, VALUE obj)
1691 (VALUE val)
1693 if (FIXNUM_2_P(recv, obj) &&
1694 BASIC_OP_UNREDEFINED_P(BOP_LT)) {
1695 SIGNED_VALUE a = recv, b = obj;
1697 if (a < b) {
1698 val = Qtrue;
1700 else {
1701 val = Qfalse;
1704 else {
1705 PUSH(recv);
1706 PUSH(obj);
1707 CALL_SIMPLE_METHOD(1, idLT, recv);
1712 @c optimize
1713 @e optimized X<=Y.
1714 @j �Å“K‰»‚³‚ꂽ X<=Y�B
1716 DEFINE_INSN
1717 opt_le
1719 (VALUE recv, VALUE obj)
1720 (VALUE val)
1722 if (FIXNUM_2_P(recv, obj) &&
1723 BASIC_OP_UNREDEFINED_P(BOP_LE)) {
1724 SIGNED_VALUE a = recv, b = obj;
1726 if (a <= b) {
1727 val = Qtrue;
1729 else {
1730 val = Qfalse;
1733 else {
1734 /* other */
1735 PUSH(recv);
1736 PUSH(obj);
1737 CALL_SIMPLE_METHOD(1, idLE, recv);
1742 @c optimize
1743 @e optimized X>Y.
1744 @j �Å“K‰»‚³‚ꂽ X>Y�B
1746 DEFINE_INSN
1747 opt_gt
1749 (VALUE recv, VALUE obj)
1750 (VALUE val)
1752 if (FIXNUM_2_P(recv, obj) &&
1753 BASIC_OP_UNREDEFINED_P(BOP_GT)) {
1754 SIGNED_VALUE a = recv, b = obj;
1756 if (a > b) {
1757 val = Qtrue;
1759 else {
1760 val = Qfalse;
1763 else {
1764 PUSH(recv);
1765 PUSH(obj);
1766 CALL_SIMPLE_METHOD(1, idGT, recv);
1771 @c optimize
1772 @e optimized X>=Y.
1773 @j �Å“K‰»‚³‚ꂽ X>=Y�B
1775 DEFINE_INSN
1776 opt_ge
1778 (VALUE recv, VALUE obj)
1779 (VALUE val)
1781 if (FIXNUM_2_P(recv, obj) &&
1782 BASIC_OP_UNREDEFINED_P(BOP_GE)) {
1783 SIGNED_VALUE a = recv, b = obj;
1785 if (a >= b) {
1786 val = Qtrue;
1788 else {
1789 val = Qfalse;
1792 else {
1793 PUSH(recv);
1794 PUSH(obj);
1795 CALL_SIMPLE_METHOD(1, idGE, recv);
1800 @c optimize
1801 @e <<
1802 @j �Å“K‰»‚³‚ꂽ X<<Y�B
1804 DEFINE_INSN
1805 opt_ltlt
1807 (VALUE recv, VALUE obj)
1808 (VALUE val)
1810 if (!SPECIAL_CONST_P(recv)) {
1811 if (0) {
1813 else if (HEAP_CLASS_OF(recv) == rb_cString &&
1814 BASIC_OP_UNREDEFINED_P(BOP_LTLT)) {
1815 val = rb_str_concat(recv, obj);
1817 else if (HEAP_CLASS_OF(recv) == rb_cArray &&
1818 BASIC_OP_UNREDEFINED_P(BOP_LTLT)) {
1819 val = rb_ary_push(recv, obj);
1821 else {
1822 goto INSN_LABEL(normal_dispatch);
1825 else {
1826 INSN_LABEL(normal_dispatch):
1827 PUSH(recv);
1828 PUSH(obj);
1829 CALL_SIMPLE_METHOD(1, idLTLT, recv);
1834 @c optimize
1835 @e []
1836 @j �Å“K‰»‚³‚ꂽ recv[obj]�B
1838 DEFINE_INSN
1839 opt_aref
1841 (VALUE recv, VALUE obj)
1842 (VALUE val)
1844 if (!SPECIAL_CONST_P(recv) && BASIC_OP_UNREDEFINED_P(BOP_AREF)) {
1845 if (HEAP_CLASS_OF(recv) == rb_cArray && FIXNUM_P(obj)) {
1846 val = rb_ary_entry(recv, FIX2LONG(obj));
1848 else if (HEAP_CLASS_OF(recv) == rb_cHash) {
1849 val = rb_hash_aref(recv, obj);
1851 else {
1852 goto INSN_LABEL(normal_dispatch);
1855 else {
1856 INSN_LABEL(normal_dispatch):
1857 PUSH(recv);
1858 PUSH(obj);
1859 CALL_SIMPLE_METHOD(1, idAREF, recv);
1864 @c optimize
1865 @e recv[obj] = set
1866 @j �Å“K‰»‚³‚ꂽ recv[obj] = set�B
1868 DEFINE_INSN
1869 opt_aset
1871 (VALUE recv, VALUE obj, VALUE set)
1872 (VALUE val)
1874 if (!SPECIAL_CONST_P(recv) &&
1875 BASIC_OP_UNREDEFINED_P(BOP_ASET)) {
1876 if (HEAP_CLASS_OF(recv) == rb_cArray && FIXNUM_P(obj)) {
1877 rb_ary_store(recv, FIX2LONG(obj), set);
1878 val = set;
1880 else if (HEAP_CLASS_OF(recv) == rb_cHash) {
1881 rb_hash_aset(recv, obj, set);
1882 val = set;
1884 else {
1885 goto INSN_LABEL(normal_dispatch);
1888 else {
1889 INSN_LABEL(normal_dispatch):
1890 PUSH(recv);
1891 PUSH(obj);
1892 PUSH(set);
1893 CALL_SIMPLE_METHOD(2, idASET, recv);
1898 @c optimize
1899 @e optimized length
1900 @j �Å“K‰»‚³‚ꂽ recv.length()�B
1902 DEFINE_INSN
1903 opt_length
1905 (VALUE recv)
1906 (VALUE val)
1908 if (!SPECIAL_CONST_P(recv) &&
1909 BASIC_OP_UNREDEFINED_P(BOP_LENGTH)) {
1910 if (HEAP_CLASS_OF(recv) == rb_cString) {
1911 val = rb_str_length(recv);
1913 else if (HEAP_CLASS_OF(recv) == rb_cArray) {
1914 val = LONG2NUM(RARRAY_LEN(recv));
1916 else if (HEAP_CLASS_OF(recv) == rb_cHash) {
1917 val = INT2FIX(RHASH_SIZE(recv));
1919 else {
1920 goto INSN_LABEL(normal_dispatch);
1923 else {
1924 INSN_LABEL(normal_dispatch):
1925 PUSH(recv);
1926 CALL_SIMPLE_METHOD(0, idLength, recv);
1931 @c optimize
1932 @e optimized succ
1933 @j �Å“K‰»‚³‚ꂽ recv.succ()�B
1935 DEFINE_INSN
1936 opt_succ
1938 (VALUE recv)
1939 (VALUE val)
1941 if (SPECIAL_CONST_P(recv)) {
1942 if (FIXNUM_P(recv) &&
1943 BASIC_OP_UNREDEFINED_P(BOP_SUCC)) {
1944 const VALUE obj = INT2FIX(1);
1945 /* fixnum + INT2FIX(1) */
1946 val = (recv + (obj & (~1)));
1947 if ((~(recv ^ obj) & (recv ^ val)) & ((unsigned long)LONG_MAX + 1)) {
1948 val = rb_big_plus(rb_int2big(FIX2LONG(recv)),
1949 rb_int2big(FIX2LONG(obj)));
1952 else {
1953 goto INSN_LABEL(normal_dispatch);
1956 else {
1957 if (HEAP_CLASS_OF(recv) == rb_cString &&
1958 BASIC_OP_UNREDEFINED_P(BOP_SUCC)) {
1959 val = rb_str_succ(recv);
1961 else if (HEAP_CLASS_OF(recv) == rb_cTime &&
1962 BASIC_OP_UNREDEFINED_P(BOP_SUCC)) {
1963 val = rb_time_succ(recv);
1965 else
1967 goto INSN_LABEL(normal_dispatch);
1970 if (0) {
1971 INSN_LABEL(normal_dispatch):
1972 PUSH(recv);
1973 CALL_SIMPLE_METHOD(0, idSucc, recv);
1978 @c optimize
1979 @e optimized not
1980 @j �Å“K‰»‚³‚ꂽ recv.!()�B
1982 DEFINE_INSN
1983 opt_not
1984 (IC ic)
1985 (VALUE recv)
1986 (VALUE val)
1988 extern VALUE rb_obj_not(VALUE obj);
1989 NODE *mn = vm_method_search(idNot, CLASS_OF(recv), ic);
1991 if (check_cfunc(mn, rb_obj_not)) {
1992 val = RTEST(recv) ? Qfalse : Qtrue;
1994 else {
1995 PUSH(recv);
1996 CALL_SIMPLE_METHOD(0, idNot, recv);
2002 @c optimize
2003 @e optimized regexp match
2004 @j �Å“K‰»‚³‚ꂽ�³‹K•\Œ»ƒ}ƒbƒ`�B
2006 DEFINE_INSN
2007 opt_regexpmatch1
2008 (VALUE r)
2009 (VALUE obj)
2010 (VALUE val)
2012 val = rb_reg_match(r, obj);
2016 @c optimize
2017 @e optimized regexp match 2
2018 @j �Å“K‰»‚³‚ꂽ�³‹K•\Œ»ƒ}ƒbƒ` 2
2020 DEFINE_INSN
2021 opt_regexpmatch2
2023 (VALUE obj2, VALUE obj1)
2024 (VALUE val)
2026 if (TYPE(obj2) == T_STRING) {
2027 val = rb_reg_match(obj1, obj2);
2029 else {
2030 val = rb_funcall(obj2, idEqTilde, 1, obj1);
2035 @c optimize
2036 @e call native compiled method
2037 @j ƒlƒCƒeƒBƒuƒRƒ“ƒpƒCƒ‹‚µ‚½ƒ�ƒ\ƒbƒh‚ð‹N“®�B
2039 DEFINE_INSN
2040 opt_call_c_function
2041 (rb_insn_func_t funcptr)
2045 reg_cfp = (funcptr)(th, reg_cfp);
2047 if (reg_cfp == 0) {
2048 VALUE err = th->errinfo;
2049 th->errinfo = Qnil;
2050 THROW_EXCEPTION(err);
2053 RESTORE_REGS();
2054 NEXT_INSN();
2058 @c joke
2059 @e BLT
2060 @j BLT
2062 DEFINE_INSN
2063 bitblt
2066 (VALUE ret)
2068 ret = rb_str_new2("a bit of bacon, lettuce and tomato");
2072 @c joke
2073 @e The Answer to Life, the Universe, and Everything
2074 @j �l�¶�A‰F’ˆ�A‚·‚ׂĂ̓š‚¦�B
2076 DEFINE_INSN
2077 answer
2080 (VALUE ret)
2082 ret = INT2FIX(42);