1 /** ##skip
-*- mode
:c
; style
:ruby
-*-
2 insns.def
- YARV instruction definitions
5 created at
: 04/01/01 01:17:55 JST
7 Copyright (C
) 2004-2007 Koichi Sasada
13 @e
: english description
14 @j
: japanese description
19 (instruction_operands
, ..
)
43 /**********************************************************/
44 /* deal with variables
*/
45 /**********************************************************/
49 @e get local variable
value (which is pointed by idx
).
50 @j idx ‚ÅŽw’肳‚ꂽƒ��
[ƒJƒ‹•Ï�”‚ðƒXƒ^ƒbƒN‚É’u‚�B
58 val
= *(GET_LFP() - idx
);
63 @e set local variable
value (which is pointed by idx
) as val.
64 @j idx ‚ÅŽw’肳‚ꂽƒ��
[ƒJƒ‹•Ï�”‚ð val ‚É�Ý’è‚·‚é�B
72 (*(GET_LFP() - idx)) = val;
77 @e get special local variable ($~, $_, ..) value.
78 @j “ÁŽê‚ȃ��[ƒJƒ‹•Ï�”�i$~, $_, ...�j‚Ì’l‚𓾂é�B
82 (VALUE key, rb_num_t type)
86 val = vm_getspecial(th, GET_LFP(), key, type);
91 @e set special local variable ($~, $_, ...) value as obj.
92 @j “Á•Ê‚ȃ��[ƒJƒ‹•Ï�”�i$~, $_, ...�j‚Ì’l‚ð‚ð�Ý’è‚·‚é�B
100 lfp_svar_set(th, GET_LFP(), key, obj);
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
112 (dindex_t idx, rb_num_t level)
117 VALUE *dfp2 = GET_DFP();
118 for (i = 0; i < level; i++) {
119 dfp2 = GET_PREV_DFP(dfp2);
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
133 (dindex_t idx, rb_num_t level)
138 VALUE *dfp2 = GET_DFP();
139 for (i = 0; i < level; i++) {
140 dfp2 = GET_PREV_DFP(dfp2);
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
157 val = rb_ivar_get(GET_SELF(), id);
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
172 rb_ivar_set(GET_SELF(), id, val);
177 @e get class variable id of klass as val.
178 @j Œ»�݂̃XƒR�[ƒv‚̃Nƒ‰ƒX•Ï�” id ‚Ì’l‚𓾂é�B
186 NODE * const cref = vm_get_cref(GET_ISEQ(), GET_LFP(), GET_DFP());
187 val = rb_cvar_get(vm_get_cvar_base(cref), id);
192 @e set class variable id of klass as val.
193 @j klass ‚̃Nƒ‰ƒX•Ï�” id ‚ð val ‚É‚·‚é�B
201 NODE * const cref = vm_get_cref(GET_ISEQ(), GET_LFP(), GET_DFP());
202 rb_cvar_set(vm_get_cvar_base(cref), id, val);
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
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
223 val = vm_get_ev_const(th, GET_ISEQ(), klass, id, 0);
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
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
242 (VALUE val, VALUE cbase)
245 vm_check_if_namespace(cbase);
246 rb_const_set(cbase, id, val);
247 INC_VM_STATE_VERSION();
252 @e get global variable id.
253 @j ƒOƒ��[ƒoƒ‹•Ï�” id ‚Ì’l‚𓾂é�B
261 val = GET_GLOBAL(entry);
266 @e set global variable id as val.
267 @j ƒOƒ��[ƒoƒ‹•Ï�” id ‚Ì’l‚ð�Ý’è‚·‚é�B
275 SET_GLOBAL(entry, val);
279 /**********************************************************/
280 /* deal with values */
281 /**********************************************************/
286 @j ƒXƒ^ƒbƒN‚É nil ‚ðƒvƒbƒVƒ…‚·‚é�B
300 @j ƒXƒ^ƒbƒN‚É self ‚ðƒvƒbƒVƒ…‚·‚é�B
314 @j ƒXƒ^ƒbƒN‚É cbase ‚ðƒvƒbƒVƒ…‚·‚é�B
322 val = vm_get_cbase(GET_ISEQ(), GET_LFP(), GET_DFP());
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.
343 @e put string val. string will be copied.
344 @j •¶Žš—ñ‚ð‚ðƒRƒs�[‚µ‚ăXƒ^ƒbƒN‚ɃvƒbƒVƒ…‚·‚é�B
352 val = rb_str_new3(str);
357 @e put concatenate strings
358 @j ƒXƒ^ƒbƒNƒgƒbƒv‚Ì•¶Žš—ñ‚ð n ŒÂ˜AŒ‹‚µ�CŒ‹‰Ê‚ðƒXƒ^ƒbƒN‚ɃvƒbƒVƒ…‚·‚é�B
364 (VALUE val) // inc += 1 - num;
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);
379 @j to_str ‚ÌŒ‹‰Ê‚ðƒXƒ^ƒbƒN‚ɃvƒbƒVƒ…‚·‚é�B
387 val = rb_obj_as_string(val);
393 @j •¶Žš—ñ str ‚ð�³‹K•\Œ»‚ɃRƒ“ƒpƒCƒ‹‚µ‚ăXƒ^ƒbƒN‚ɃvƒbƒVƒ…‚·‚é�B
394 ƒRƒ“ƒpƒCƒ‹Žž�Copt ‚ð�³‹K•\Œ»‚̃IƒvƒVƒ‡ƒ“‚Æ‚·‚é�B
398 (rb_num_t opt, rb_num_t cnt)
400 (VALUE val) // inc += 1 - cnt;
402 VALUE rb_reg_new_ary(VALUE ary, int options);
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));
410 val = rb_reg_new_ary(ary, opt);
416 @j �V‚µ‚¢”z—ñ‚ðƒXƒ^ƒbƒN�ã‚Ì num ŒÂ‚Ì’l‚Å�‰Šú‰»‚µ‚Ä�¶�¬‚µƒvƒbƒVƒ…‚·‚é�B
422 (VALUE val) // inc += 1 - num;
424 val = rb_ary_new4((long)num, STACK_ADDR_FROM_TOP(num));
431 @j ”z—ñ ary ‚ð dup ‚µ‚ăXƒ^ƒbƒN‚ɃvƒbƒVƒ…‚·‚é�B
439 val = rb_ary_dup(ary);
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?
456 (rb_num_t num, rb_num_t flag)
458 (...) // inc += num - 1 + (flag & 1 ? 1 : 0);
460 vm_expandarray(GET_CFP(), ary, num, flag);
466 @j “ñ‚‚̔z—ñ ary1, ary2 ‚ð˜AŒ‹‚µƒXƒ^ƒbƒN‚ÖƒvƒbƒVƒ…‚·‚é�B
471 (VALUE ary1, VALUE ary2st)
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");
479 tmp1 = rb_ary_new3(1, ary1);
483 tmp2 = rb_ary_new3(1, ary2);
487 tmp1 = rb_ary_dup(ary1);
489 ary = rb_ary_concat(tmp1, tmp2);
495 @j ”z—ñ ary ‚ɑ΂µ‚Ä to_a ‚ðŒÄ‚Ñ�o‚·�B
503 VALUE tmp = rb_check_convert_type(ary, T_ARRAY, "Array", "to_a");
505 tmp = rb_ary_new3(1, ary);
512 @e check value is included in ary
513 @j ”z—ñ ary ‚É—v‘f obj ‚ª“ü‚Á‚Ä‚¢‚é‚©‚Ç‚¤‚©ƒ`ƒFƒbƒN�Bcase/when ‚Å—˜—p‚·‚é�B
518 (VALUE obj, VALUE ary)
519 (VALUE obj, VALUE result)
524 if (TYPE(ary) != T_ARRAY) {
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))) {
541 for (i = 0; i < RARRAY_LEN(ary); i++) {
542 if (RTEST(RARRAY_PTR(ary)[i])) {
543 obj = result = Qtrue;
553 @j �V‚µ‚¢ƒnƒbƒVƒ…‚ðƒXƒ^ƒbƒNƒgƒbƒv‚Ì n ŒÂ‚ð�‰Šú’l‚Æ‚µ‚Ä�¶�¬‚·‚é�B
554 n ‚̓L�[‚Æ’l‚̃yƒA‚È‚Ì‚Å 2 ‚Ì”{�”‚Å‚È‚¯‚ê‚΂Ȃç‚È‚¢�B
560 (VALUE val) // inc += 1 - num;
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);
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
581 (VALUE low, VALUE high)
584 val = rb_range_new(low, high, flag);
587 /**********************************************************/
588 /* deal with stack operation */
589 /**********************************************************/
594 @j ƒXƒ^ƒbƒN‚©‚çˆê‚ƒ|ƒbƒv‚·‚é�B
608 @e duplicate stack top.
609 @j ƒXƒ^ƒbƒNƒgƒbƒv‚ðƒRƒs�[‚µ‚ăXƒ^ƒbƒN‚ɃvƒbƒVƒ…‚·‚é�B
615 (VALUE val1, VALUE val2)
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
632 VALUE *sp = STACK_ADDR_FROM_TOP(n);
633 for (i = 0; i < n; i++) {
643 @j ƒXƒ^ƒbƒNƒgƒbƒv‚Ì 2 ‚‚̒l‚ðŒðŠ·‚·‚é�B
648 (VALUE val, VALUE obj)
649 (VALUE obj, VALUE val)
656 @e for stack caching.
657 @j ƒXƒ^ƒbƒNƒLƒƒƒbƒVƒ“ƒO‚Ì�ó‘Ô‚ð’²�®‚·‚邽‚ß‚É•K—v‚È–½—ß�B
663 (VALUE val) // inc += 0;
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
677 (VALUE val) // inc += 1;
684 @e set Nth stack entry to stack top
685 @j ƒXƒ^ƒbƒNƒgƒbƒv‚Ì’l‚ð n ŒÂ–ڂ̃Xƒ^ƒbƒN‚ɃRƒs�[
691 (VALUE val) // inc += 0
698 @e empt current stack
699 @j current stack ‚ð‹ó‚É‚·‚é�B
711 /**********************************************************/
712 /* deal with setting */
713 /**********************************************************/
717 @e define (singleton) method id as body
718 @j �i“ÁˆÙ�jƒ�ƒ\ƒbƒh id ‚ð body ‚Æ‚µ‚Ä’è‹`‚·‚é�B
722 (ID id, ISEQ body, rb_num_t is_singleton)
726 NODE *cref = vm_get_cref(GET_ISEQ(), GET_LFP(), GET_DFP());
727 vm_define_method(th, obj, id, body, is_singleton, cref);
732 @e make alias (if v_p is Qtrue, make valias)
733 @j alias ‚ð�ì‚é�B‚à‚µ v_p ‚ª Qtrue ‚È‚ç�Avalias (global variable) ‚ð�ì‚é�B
738 (VALUE sym1, VALUE sym2)
742 rb_alias_variable(SYM2ID(sym1), SYM2ID(sym2));
745 const VALUE klass = vm_get_cbase(GET_ISEQ(), GET_LFP(), GET_DFP());
746 rb_alias(klass, SYM2ID(sym1), SYM2ID(sym2));
761 const VALUE klass = vm_get_cbase(GET_ISEQ(), GET_LFP(), GET_DFP());
762 rb_undef(klass, SYM2ID(sym));
763 INC_VM_STATE_VERSION();
773 (rb_num_t type, VALUE obj, VALUE needstr)
783 if (rb_ivar_defined(GET_SELF(), SYM2ID(obj))) {
784 expr_type = "instance-variable";
788 klass = vm_get_cbase(GET_ISEQ(), GET_LFP(), GET_DFP());
791 if (rb_gvar_defined((struct global_entry *)(obj
& ~
1))) {
792 expr_type
= "global-variable";
796 klass
= vm_get_cbase(GET_ISEQ(), GET_LFP(), GET_DFP());
797 if (rb_cvar_defined(klass
, SYM2ID(obj
))) {
798 expr_type
= "class variable";
803 if (vm_get_ev_const(th
, GET_ISEQ(), klass
, SYM2ID(obj
), 1)) {
804 expr_type
= "constant";
809 if (rb_method_boundp(klass
, SYM2ID(obj
), 0)) {
810 expr_type
= "method";
813 case DEFINED_METHOD
:{
814 VALUE klass
= CLASS_OF(v
);
815 NODE
*method
= (NODE *)
rb_method_node(klass
, SYM2ID(obj
));
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";
829 if (GET_BLOCK_PTR()) {
833 case DEFINED_ZSUPER
:{
834 rb_iseq_t
*ip
= GET_ISEQ();
836 if (ip
->defined_method_id
) {
839 ip
= ip
->parent_iseq
;
842 VALUE klass
= vm_search_normal_superclass(ip
->klass
, GET_SELF());
843 if (rb_method_boundp(klass
, ip
->defined_method_id
, 0)) {
850 val
= vm_getspecial(th
, GET_LFP(), Qfalse
, FIX2INT(obj
));
852 expr_type
= "global-variable";
857 rb_bug("unimplemented defined? type (VM)");
860 if (expr_type
!= 0) {
861 if (needstr
!= Qfalse
) {
862 val
= rb_str_new2(expr_type
);
873 @j
END{} ‚ɑΉž‚·‚邽‚߂Ƀuƒ�ƒbƒN‚ð“o˜^‚·‚é�B
881 rb_block_t
*blockptr
;
883 extern void
rb_call_end_proc(VALUE data
);
885 blockptr
= RUBY_VM_GET_BLOCK_PTR_IN_CFP(GET_CFP());
886 blockptr
->iseq
= blockiseq
;
889 proc
= vm_make_proc(th
, GET_CFP(), blockptr
);
890 rb_set_end_proc(rb_call_end_proc
, proc
);
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 /**********************************************************/
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
923 (ID id, ISEQ class_iseq, rb_num_t define_type)
924 (VALUE cbase, VALUE super)
929 switch ((int)define_type) {
931 /* val is dummy. classdef returns class scope value */
937 vm_check_if_namespace(cbase);
940 if (rb_const_defined_at(cbase, id)) {
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) {
949 tmp = rb_class_real(RCLASS_SUPER(klass));
952 rb_raise(rb_eTypeError, "superclass mismatch for class %s",
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);
966 /* val is dummy. classdef returns class scope value */
968 klass = rb_singleton_class(cbase);
971 /* val is dummy. classdef returns class scope value */
974 vm_check_if_namespace(cbase);
977 if (rb_const_defined_at(cbase, id)) {
978 klass = rb_const_get_at(cbase, id);
980 if (TYPE(klass) != T_MODULE) {
981 rb_raise(rb_eTypeError, "%s is not a module", rb_id2name(id));
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);
992 rb_bug("unknown defineclass type: %d", (int)define_type);
995 COPY_CREF(class_iseq->cref_stack, vm_cref_push(th, klass, NOEX_PUBLIC));
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);
1004 INC_VM_STATE_VERSION();
1009 /**********************************************************/
1010 /* deal with control flow 2: method/iterator */
1011 /**********************************************************/
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 )
1026 (ID op_id, rb_num_t op_argc, ISEQ blockiseq, rb_num_t op_flag, IC ic)
1028 (VALUE val) // inc += - (op_argc + ((op_flag & VM_CALL_ARGS_BLOCKARG_BIT) ? 1 : 0));
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;
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);
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
1060 (rb_num_t op_argc, ISEQ blockiseq, rb_num_t op_flag)
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);
1069 const VALUE flag = VM_CALL_SUPER_BIT | VM_CALL_FCALL_BIT;
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);
1080 @e yield(args) # args.size => num, flag shows expand argument or not
1081 @j yield ‚ðŽÀ�s‚·‚é�B
1082 yield(args) # args.size => num
1086 (rb_num_t num, rb_num_t flag)
1088 (VALUE val) // inc += 1 - num;
1090 val = vm_invoke_block(th, GET_CFP(), num, flag);
1091 if (val == Qundef) {
1099 @e return from this scope.
1100 @j ‚±‚̃XƒR�[ƒv‚©‚甲‚¯‚é�B
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();
1122 @e return from this vm loop
1123 @j VM loop ‚©‚甲‚¯‚é�B
1131 #if OPT_CALL_THREADED_CODE
1132 rb_bug("unused instruction on OPT_CALL_THREADED_CODE");
1139 /**********************************************************/
1140 /* deal with control flow 3: exception */
1141 /**********************************************************/
1146 @j ‘åˆæƒWƒƒƒ“ƒv‚ð�s‚¤�B
1150 (rb_num_t throw_state)
1154 RUBY_VM_CHECK_INTS();
1155 val = vm_throw(th, GET_CFP(), throw_state, throwobj);
1156 THROW_EXCEPTION(val);
1160 /**********************************************************/
1161 /* deal with control flow 4: local jump */
1162 /**********************************************************/
1166 @e set PC to (PC + dst).
1167 @j PC ‚ð (PC + dst) ‚É‚·‚é�B
1175 RUBY_VM_CHECK_INTS();
1181 @e if val is not false or nil, set PC to (PC + dst).
1182 @j ‚à‚µ val ‚ª false ‚© nil ‚Å‚È‚¯‚ê‚Î�APC ‚ð (PC + dst) ‚É‚·‚é�B
1191 RUBY_VM_CHECK_INTS();
1198 @e if val is false or nil, set PC to (PC + dst).
1199 @j ‚à‚µ val ‚ª false ‚© nil ‚È‚ç‚Î�APC ‚ð (PC + dst) ‚É‚·‚é�B
1208 RUBY_VM_CHECK_INTS();
1214 /**********************************************************/
1216 /**********************************************************/
1221 @j ƒCƒ“ƒ‰ƒCƒ“ƒLƒƒƒbƒVƒ…‚ª—LŒø‚È‚ç�A’l‚ðƒXƒ^ƒbƒN‚ɃvƒbƒVƒ…‚µ‚Ä dst ‚ÖƒWƒƒƒ“ƒv‚·‚é�B
1229 if (ic->ic_vmstat == GET_VM_STATE_VERSION()) {
1241 @e inline cache (once)
1242 @j once ‚ðŽÀŒ»‚·‚é�B
1250 if (ic->ic_vmstat) {
1263 @j ƒCƒ“ƒ‰ƒCƒ“ƒLƒƒƒbƒVƒ…‚Ì’l‚ð�Ý’è‚·‚é�B
1271 IC ic = GET_CONST_INLINE_CACHE(dst);
1274 ic->ic_vmstat = GET_VM_STATE_VERSION();
1280 @j case •¶‚Å�A‰Â”\‚È‚ç•\ˆø‚«‚ŃWƒƒƒ“ƒv‚·‚é�B
1284 (CDHASH hash, OFFSET else_offset)
1289 /* TODO: if some === method is overrided */
1293 if (st_lookup(RHASH_TBL(hash), key, &val)) {
1304 @e check environment
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();
1322 /** simple functions */
1327 @j �Å“K‰»‚³‚ꂽ X+Y�B
1332 (VALUE recv, VALUE obj)
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)));
1358 val = rb_big_plus(rb_int2big(a), rb_int2big(b));
1364 else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
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));
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);
1383 else if (HEAP_CLASS_OF(recv) == rb_cArray &&
1384 BASIC_OP_UNREDEFINED_P(BOP_PLUS)) {
1385 val = rb_ary_plus(recv, obj);
1389 goto INSN_LABEL(normal_dispatch);
1393 INSN_LABEL(normal_dispatch):
1396 CALL_SIMPLE_METHOD(1, idPLUS, recv);
1403 @j �Å“K‰»‚³‚ꂽ X-Y�B
1408 (VALUE recv, VALUE obj)
1411 if (FIXNUM_2_P(recv, obj) &&
1412 BASIC_OP_UNREDEFINED_P(BOP_MINUS)) {
1423 val = rb_big_minus(rb_int2big(a), rb_int2big(b));
1430 CALL_SIMPLE_METHOD(1, idMINUS, recv);
1437 @j �Å“K‰»‚³‚ꂽ X*Y�B
1442 (VALUE recv, VALUE obj)
1445 if (FIXNUM_2_P(recv, obj) &&
1446 BASIC_OP_UNREDEFINED_P(BOP_MULT)) {
1457 if (FIXABLE(c) && c / a == b) {
1461 val = rb_big_mul(rb_int2big(a), rb_int2big(b));
1465 else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
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));
1476 goto INSN_LABEL(normal_dispatch);
1480 INSN_LABEL(normal_dispatch):
1483 CALL_SIMPLE_METHOD(1, idMULT, recv);
1490 @j �Å“K‰»‚³‚ꂽ X/Y�B
1495 (VALUE recv, VALUE obj)
1498 if (FIXNUM_2_P(recv, obj) &&
1499 BASIC_OP_UNREDEFINED_P(BOP_DIV)) {
1505 /* copied from numeric.c#fixdivmod */
1508 goto INSN_LABEL(normal_dispatch);
1522 if ((mod < 0 && y > 0) || (mod > 0 && y < 0)) {
1527 val = LONG2NUM(div);
1529 else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
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));
1540 goto INSN_LABEL(normal_dispatch);
1544 INSN_LABEL(normal_dispatch):
1547 CALL_SIMPLE_METHOD(1, idDIV, recv);
1554 @j �Å“K‰»‚³‚ꂽ X%Y�B
1559 (VALUE recv, VALUE obj)
1562 if (FIXNUM_2_P(recv, obj) &&
1563 BASIC_OP_UNREDEFINED_P(BOP_MOD)) {
1569 /* copied from numeric.c#fixdivmod */
1587 if ((mod < 0 && y > 0) || (mod > 0 && y < 0)) {
1592 val = LONG2FIX(mod);
1594 else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
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);
1611 div = (x - mod) / y;
1616 val = DOUBLE2NUM(mod);
1619 goto INSN_LABEL(normal_dispatch);
1623 INSN_LABEL(normal_dispatch):
1626 CALL_SIMPLE_METHOD(1, idMOD, recv);
1633 @j �Å“K‰»‚³‚ꂽ X==Y�B
1638 (VALUE recv, VALUE obj)
1641 val = opt_eq_func(recv, obj, ic);
1643 if (val == Qundef) {
1647 CALL_SIMPLE_METHOD(1, idEq, recv);
1654 @j �Å“K‰»‚³‚ꂽ X!=Y�B
1659 (VALUE recv, VALUE obj)
1662 extern VALUE rb_obj_not_equal(VALUE obj1, VALUE obj2);
1663 NODE *mn = vm_method_search(idNeq, CLASS_OF(recv), ic1);
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) {
1678 CALL_SIMPLE_METHOD(1, idNeq, recv);
1685 @j �Å“K‰»‚³‚ꂽ X<Y�B
1690 (VALUE recv, VALUE obj)
1693 if (FIXNUM_2_P(recv, obj) &&
1694 BASIC_OP_UNREDEFINED_P(BOP_LT)) {
1695 SIGNED_VALUE a = recv, b = obj;
1707 CALL_SIMPLE_METHOD(1, idLT, recv);
1714 @j �Å“K‰»‚³‚ꂽ X<=Y�B
1719 (VALUE recv, VALUE obj)
1722 if (FIXNUM_2_P(recv, obj) &&
1723 BASIC_OP_UNREDEFINED_P(BOP_LE)) {
1724 SIGNED_VALUE a = recv, b = obj;
1737 CALL_SIMPLE_METHOD(1, idLE, recv);
1744 @j �Å“K‰»‚³‚ꂽ X>Y�B
1749 (VALUE recv, VALUE obj)
1752 if (FIXNUM_2_P(recv, obj) &&
1753 BASIC_OP_UNREDEFINED_P(BOP_GT)) {
1754 SIGNED_VALUE a = recv, b = obj;
1766 CALL_SIMPLE_METHOD(1, idGT, recv);
1773 @j �Å“K‰»‚³‚ꂽ X>=Y�B
1778 (VALUE recv, VALUE obj)
1781 if (FIXNUM_2_P(recv, obj) &&
1782 BASIC_OP_UNREDEFINED_P(BOP_GE)) {
1783 SIGNED_VALUE a = recv, b = obj;
1795 CALL_SIMPLE_METHOD(1, idGE, recv);
1802 @j �Å“K‰»‚³‚ꂽ X<<Y�B
1807 (VALUE recv, VALUE obj)
1810 if (!SPECIAL_CONST_P(recv)) {
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);
1822 goto INSN_LABEL(normal_dispatch);
1826 INSN_LABEL(normal_dispatch):
1829 CALL_SIMPLE_METHOD(1, idLTLT, recv);
1836 @j �Å“K‰»‚³‚ꂽ recv[obj]�B
1841 (VALUE recv, VALUE obj)
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);
1852 goto INSN_LABEL(normal_dispatch);
1856 INSN_LABEL(normal_dispatch):
1859 CALL_SIMPLE_METHOD(1, idAREF, recv);
1866 @j �Å“K‰»‚³‚ꂽ recv[obj] = set�B
1871 (VALUE recv, VALUE obj, VALUE set)
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);
1880 else if (HEAP_CLASS_OF(recv) == rb_cHash) {
1881 rb_hash_aset(recv, obj, set);
1885 goto INSN_LABEL(normal_dispatch);
1889 INSN_LABEL(normal_dispatch):
1893 CALL_SIMPLE_METHOD(2, idASET, recv);
1900 @j �Å“K‰»‚³‚ꂽ recv.length()�B
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));
1920 goto INSN_LABEL(normal_dispatch);
1924 INSN_LABEL(normal_dispatch):
1926 CALL_SIMPLE_METHOD(0, idLength, recv);
1933 @j �Å“K‰»‚³‚ꂽ recv.succ()�B
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)));
1953 goto INSN_LABEL(normal_dispatch);
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);
1967 goto INSN_LABEL(normal_dispatch);
1971 INSN_LABEL(normal_dispatch):
1973 CALL_SIMPLE_METHOD(0, idSucc, recv);
1980 @j �Å“K‰»‚³‚ꂽ recv.!()�B
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;
1996 CALL_SIMPLE_METHOD(0, idNot, recv);
2003 @e optimized regexp match
2004 @j �Å“K‰»‚³‚ꂽ�³‹K•\Œ»ƒ}ƒbƒ`�B
2012 val = rb_reg_match(r, obj);
2017 @e optimized regexp match 2
2018 @j �Å“K‰»‚³‚ꂽ�³‹K•\Œ»ƒ}ƒbƒ` 2
2023 (VALUE obj2, VALUE obj1)
2026 if (TYPE(obj2) == T_STRING) {
2027 val = rb_reg_match(obj1, obj2);
2030 val = rb_funcall(obj2, idEqTilde, 1, obj1);
2036 @e call native compiled method
2037 @j ƒlƒCƒeƒBƒuƒRƒ“ƒpƒCƒ‹‚µ‚½ƒ�ƒ\ƒbƒh‚ð‹N“®�B
2041 (rb_insn_func_t funcptr)
2045 reg_cfp = (funcptr)(th, reg_cfp);
2048 VALUE err = th->errinfo;
2050 THROW_EXCEPTION(err);
2068 ret = rb_str_new2("a bit of bacon, lettuce and tomato");
2073 @e The Answer to Life, the Universe, and Everything
2074 @j �l�¶�A‰F’ˆ�A‚·‚ׂĂ̓š‚¦�B