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 i.e. Fixnum, true, false, nil, and so on.
315 @j ƒIƒuƒWƒFƒNƒg val ‚ðƒXƒ^ƒbƒN‚ɃvƒbƒVƒ…‚·‚é�B
316 i.e. Fixnum, true, false, nil, and so on.
329 @e put special object. "value_type" is for expansion.
330 @j “Á•Ê‚ȃIƒuƒWƒFƒNƒg val ‚ðƒXƒ^ƒbƒN‚ɃvƒbƒVƒ…‚·‚é�B
331 ƒIƒuƒWƒFƒNƒg‚ÌŽí—Þ‚Í value_type ‚É‚æ‚é�D
335 (rb_num_t value_type)
339 switch (value_type) {
340 case VM_SPECIAL_OBJECT_VMCORE:
341 val = rb_mRubyVMFrozenCore;
343 case VM_SPECIAL_OBJECT_CBASE:
344 val = vm_get_cbase(GET_ISEQ(), GET_LFP(), GET_DFP());
347 rb_bug("putspecialobject insn: unknown value_type");
367 @e put string val. string will be copied.
368 @j •¶Žš—ñ‚ð‚ðƒRƒs�[‚µ‚ăXƒ^ƒbƒN‚ɃvƒbƒVƒ…‚·‚é�B
376 val = rb_str_new3(str);
381 @e put concatenate strings
382 @j ƒXƒ^ƒbƒNƒgƒbƒv‚Ì•¶Žš—ñ‚ð n ŒÂ˜AŒ‹‚µ�CŒ‹‰Ê‚ðƒXƒ^ƒbƒN‚ɃvƒbƒVƒ…‚·‚é�B
388 (VALUE val) // inc += 1 - num;
392 val = rb_str_new(0, 0);
393 for (i = num - 1; i >= 0; i--) {
394 const VALUE v = TOPN(i);
395 rb_str_append(val, v);
403 @j to_str ‚ÌŒ‹‰Ê‚ðƒXƒ^ƒbƒN‚ɃvƒbƒVƒ…‚·‚é�B
411 val = rb_obj_as_string(val);
417 @j •¶Žš—ñ str ‚ð�³‹K•\Œ»‚ɃRƒ“ƒpƒCƒ‹‚µ‚ăXƒ^ƒbƒN‚ɃvƒbƒVƒ…‚·‚é�B
418 ƒRƒ“ƒpƒCƒ‹Žž�Copt ‚ð�³‹K•\Œ»‚̃IƒvƒVƒ‡ƒ“‚Æ‚·‚é�B
422 (rb_num_t opt, rb_num_t cnt)
424 (VALUE val) // inc += 1 - cnt;
426 VALUE rb_reg_new_ary(VALUE ary, int options);
428 const VALUE ary = rb_ary_new2(cnt);
429 RBASIC(ary)->klass = 0;
430 for (i = 0; i < cnt; i++) {
431 rb_ary_store(ary, cnt-i-1, TOPN(i));
434 val = rb_reg_new_ary(ary, opt);
440 @j �V‚µ‚¢”z—ñ‚ðƒXƒ^ƒbƒN�ã‚Ì num ŒÂ‚Ì’l‚Å�‰Šú‰»‚µ‚Ä�¶�¬‚µƒvƒbƒVƒ…‚·‚é�B
446 (VALUE val) // inc += 1 - num;
448 val = rb_ary_new4((long)num, STACK_ADDR_FROM_TOP(num));
455 @j ”z—ñ ary ‚ð dup ‚µ‚ăXƒ^ƒbƒN‚ɃvƒbƒVƒ…‚·‚é�B
463 val = rb_ary_dup(ary);
468 @e expand array to num objects.
469 @j ƒXƒ^ƒbƒNƒgƒbƒv‚̃IƒuƒWƒFƒNƒg‚ª”z—ñ‚Å‚ ‚ê‚Î�A‚»‚ê‚ð“WŠJ‚·‚é�B
470 ”z—ñƒIƒuƒWƒFƒNƒg‚Ì—v‘f�”‚ª numˆÈ‰º‚È‚ç‚Î�A‘ã‚í‚è‚É nil ‚ð�Ï‚Þ�BnumˆÈ�ã‚È‚ç�A
471 numˆÈ�ã‚Ì—v‘f‚Í�Ø‚èŽÌ‚Ä‚é�B
472 ”z—ñƒIƒuƒWƒFƒNƒg‚Å‚È‚¯‚ê‚Î�Anum - 1 ŒÂ‚Ì nil ‚ð�Ï‚Þ�B
473 ‚à‚µ flag ‚ª�^‚È‚ç�AŽc‚è—v‘f‚Ì”z—ñ‚ð�Ï‚Þ
474 flag: 0x01 - �ÅŒã‚ð”z—ñ‚É
475 flag: 0x02 - postarg —p
476 flag: 0x04 - reverse?
480 (rb_num_t num, rb_num_t flag)
482 (...) // inc += num - 1 + (flag & 1 ? 1 : 0);
484 vm_expandarray(GET_CFP(), ary, num, flag);
490 @j “ñ‚‚̔z—ñ ary1, ary2 ‚ð˜AŒ‹‚µƒXƒ^ƒbƒN‚ÖƒvƒbƒVƒ…‚·‚é�B
495 (VALUE ary1, VALUE ary2st)
498 const VALUE ary2 = ary2st;
499 VALUE tmp1 = rb_check_convert_type(ary1, T_ARRAY, "Array", "to_a");
500 VALUE tmp2 = rb_check_convert_type(ary2, T_ARRAY, "Array", "to_a");
503 tmp1 = rb_ary_new3(1, ary1);
507 tmp2 = rb_ary_new3(1, ary2);
511 tmp1 = rb_ary_dup(ary1);
513 ary = rb_ary_concat(tmp1, tmp2);
519 @j ”z—ñ ary ‚ɑ΂µ‚Ä to_a ‚ðŒÄ‚Ñ�o‚·�B
527 VALUE tmp = rb_check_convert_type(ary, T_ARRAY, "Array", "to_a");
529 tmp = rb_ary_new3(1, ary);
536 @e check value is included in ary
537 @j ”z—ñ ary ‚É—v‘f obj ‚ª“ü‚Á‚Ä‚¢‚é‚©‚Ç‚¤‚©ƒ`ƒFƒbƒN�Bcase/when ‚Å—˜—p‚·‚é�B
542 (VALUE obj, VALUE ary)
543 (VALUE obj, VALUE result)
548 if (TYPE(ary) != T_ARRAY) {
554 for (i = 0; i < RARRAY_LEN(ary); i++) {
555 /* TODO: fix me (use another method dispatch) */
556 if (RTEST(rb_funcall2(RARRAY_PTR(ary)[i], idEqq, 1, &obj))) {
565 for (i = 0; i < RARRAY_LEN(ary); i++) {
566 if (RTEST(RARRAY_PTR(ary)[i])) {
567 obj = result = Qtrue;
577 @j �V‚µ‚¢ƒnƒbƒVƒ…‚ðƒXƒ^ƒbƒNƒgƒbƒv‚Ì n ŒÂ‚ð�‰Šú’l‚Æ‚µ‚Ä�¶�¬‚·‚é�B
578 n ‚̓L�[‚Æ’l‚̃yƒA‚È‚Ì‚Å 2 ‚Ì”{�”‚Å‚È‚¯‚ê‚΂Ȃç‚È‚¢�B
584 (VALUE val) // inc += 1 - num;
589 for (i = num; i > 0; i -= 2) {
590 const VALUE v = TOPN(i - 2);
591 const VALUE k = TOPN(i - 1);
592 rb_hash_aset(val, k, v);
599 @e put new Range object.(Range.new(low, high, flag))
600 @j Range.new(low, high, flag) ‚̂悤‚ȃIƒuƒWƒFƒNƒg‚ð�¶�¬‚µƒXƒ^ƒbƒN‚ɃvƒbƒVƒ…‚·‚é�B
605 (VALUE low, VALUE high)
608 val = rb_range_new(low, high, flag);
611 /**********************************************************/
612 /* deal with stack operation */
613 /**********************************************************/
618 @j ƒXƒ^ƒbƒN‚©‚çˆê‚ƒ|ƒbƒv‚·‚é�B
632 @e duplicate stack top.
633 @j ƒXƒ^ƒbƒNƒgƒbƒv‚ðƒRƒs�[‚µ‚ăXƒ^ƒbƒN‚ɃvƒbƒVƒ…‚·‚é�B
639 (VALUE val1, VALUE val2)
646 @e duplicate stack top n elements
647 @j ƒXƒ^ƒbƒNƒgƒbƒv‚Ì n ŒÂ‚ðƒRƒs�[‚µ‚ăXƒ^ƒbƒN‚ɃvƒbƒVƒ…‚·‚é�B
656 VALUE *sp = STACK_ADDR_FROM_TOP(n);
657 for (i = 0; i < n; i++) {
667 @j ƒXƒ^ƒbƒNƒgƒbƒv‚Ì 2 ‚‚̒l‚ðŒðŠ·‚·‚é�B
672 (VALUE val, VALUE obj)
673 (VALUE obj, VALUE val)
680 @e for stack caching.
681 @j ƒXƒ^ƒbƒNƒLƒƒƒbƒVƒ“ƒO‚Ì�ó‘Ô‚ð’²�®‚·‚邽‚ß‚É•K—v‚È–½—ß�B
687 (VALUE val) // inc += 0;
694 @e get nth stack value from stack top
695 @j ƒXƒ^ƒbƒNƒgƒbƒv‚©‚ç n ŒÂ–Ú‚ðƒXƒ^ƒbƒN‚ɃvƒbƒVƒ…‚·‚é�B
701 (VALUE val) // inc += 1;
708 @e set Nth stack entry to stack top
709 @j ƒXƒ^ƒbƒNƒgƒbƒv‚Ì’l‚ð n ŒÂ–ڂ̃Xƒ^ƒbƒN‚ɃRƒs�[
715 (VALUE val) // inc += 0
722 @e empt current stack
723 @j current stack ‚ð‹ó‚É‚·‚é�B
735 /**********************************************************/
736 /* deal with setting */
737 /**********************************************************/
746 (rb_num_t type, VALUE obj, VALUE needstr)
751 const char *expr_type = 0;
756 if (rb_ivar_defined(GET_SELF(), SYM2ID(obj))) {
757 expr_type = "instance-variable";
761 klass = vm_get_cbase(GET_ISEQ(), GET_LFP(), GET_DFP());
764 if (rb_gvar_defined((struct global_entry *)(obj
& ~
1))) {
765 expr_type
= "global-variable";
769 klass
= vm_get_cbase(GET_ISEQ(), GET_LFP(), GET_DFP());
770 if (rb_cvar_defined(klass
, SYM2ID(obj
))) {
771 expr_type
= "class variable";
776 if (vm_get_ev_const(th
, GET_ISEQ(), klass
, SYM2ID(obj
), 1)) {
777 expr_type
= "constant";
782 if (rb_method_boundp(klass
, SYM2ID(obj
), 0)) {
783 expr_type
= "method";
786 case DEFINED_METHOD
:{
787 VALUE klass
= CLASS_OF(v
);
788 NODE
*method
= (NODE *)
rb_method_node(klass
, SYM2ID(obj
));
791 if (!(method
->nd_noex
& NOEX_PRIVATE
)) {
792 if (!((method
->nd_noex
& NOEX_PROTECTED
) &&
793 !rb_obj_is_kind_of(GET_SELF(),
794 rb_class_real(klass
)))) {
795 expr_type
= "method";
802 if (GET_BLOCK_PTR()) {
806 case DEFINED_ZSUPER
:{
807 rb_iseq_t
*ip
= GET_ISEQ();
809 if (ip
->defined_method_id
) {
812 ip
= ip
->parent_iseq
;
815 VALUE klass
= vm_search_normal_superclass(ip
->klass
, GET_SELF());
816 if (rb_method_boundp(klass
, ip
->defined_method_id
, 0)) {
823 val
= vm_getspecial(th
, GET_LFP(), Qfalse
, FIX2INT(obj
));
825 expr_type
= "global-variable";
830 rb_bug("unimplemented defined? type (VM)");
833 if (expr_type
!= 0) {
834 if (needstr
!= Qfalse
) {
835 val
= rb_str_new2(expr_type
);
854 rb_event_flag_t flag
= nf
;
856 EXEC_EVENT_HOOK(th
, flag
, GET_SELF(), 0, 0 /* TODO
: id
, klass
*/);
859 /**********************************************************/
860 /* deal with control flow
1: class
/module
*/
861 /**********************************************************/
866 enter class definition scope. if super is Qfalse
, and clsas
867 "klass" is defined
, it
's redefine. otherwise, define "klass" class.
868 @j ƒNƒ‰ƒX’è‹`ƒXƒR�[ƒv‚ÖˆÚ�s‚·‚é�B
869 ‚à‚µ super ‚ª Qfalse ‚Å klassƒNƒ‰ƒX‚ª’è‹`‚³‚ê‚Ä‚¢‚ê‚Î�Ä’è‹`‚Å‚ ‚é�B
870 ‚»‚¤‚Å‚È‚¯‚ê‚Î�Aklass ƒNƒ‰ƒX‚ð’è‹`‚·‚é�B
874 (ID id, ISEQ class_iseq, rb_num_t define_type)
875 (VALUE cbase, VALUE super)
880 switch ((int)define_type) {
882 /* val is dummy. classdef returns class scope value */
888 vm_check_if_namespace(cbase);
891 if (rb_const_defined_at(cbase, id)) {
893 klass = rb_const_get_at(cbase, id);
894 if (TYPE(klass) != T_CLASS) {
895 rb_raise(rb_eTypeError, "%s is not a class", rb_id2name(id));
898 if (super != rb_cObject) {
900 tmp = rb_class_real(RCLASS_SUPER(klass));
903 rb_raise(rb_eTypeError, "superclass mismatch for class %s",
909 /* new class declaration */
910 klass = rb_define_class_id(id, super);
911 rb_set_class_path(klass, cbase, rb_id2name(id));
912 rb_const_set(cbase, id, klass);
913 rb_class_inherited(super, klass);
917 /* val is dummy. classdef returns class scope value */
919 klass = rb_singleton_class(cbase);
922 /* val is dummy. classdef returns class scope value */
925 vm_check_if_namespace(cbase);
928 if (rb_const_defined_at(cbase, id)) {
929 klass = rb_const_get_at(cbase, id);
931 if (TYPE(klass) != T_MODULE) {
932 rb_raise(rb_eTypeError, "%s is not a module", rb_id2name(id));
936 /* new module declaration */
937 klass = rb_define_module_id(id);
938 rb_set_class_path(klass, cbase, rb_id2name(id));
939 rb_const_set(cbase, id, klass);
943 rb_bug("unknown defineclass type: %d", (int)define_type);
946 COPY_CREF(class_iseq->cref_stack, vm_cref_push(th, klass, NOEX_PUBLIC));
949 vm_push_frame(th, class_iseq,
950 VM_FRAME_MAGIC_CLASS, klass, (VALUE) GET_DFP() | 0x02,
951 class_iseq->iseq_encoded, GET_SP(), 0,
952 class_iseq->local_size);
955 INC_VM_STATE_VERSION();
960 /**********************************************************/
961 /* deal with control flow 2: method/iterator */
962 /**********************************************************/
966 @e obj.send(id, args..) # args.size => num
967 @j ƒ�ƒ\ƒbƒhŒÄ‚Ñ�o‚µ‚ð�s‚¤�B
968 obj.send(id, args..) # args.size => num
969 flag & VM_CALL_ARGS_SPLAT_BIT != 0 -> splat last arg
970 flag & VM_CALL_ARGS_BLOCKARG_BIT != 0 -> Proc as Block
971 flag & VM_CALL_FCALL_BIT != 0 -> FCALL ( func() )
972 flag & VM_CALL_VCALL_BIT != 0 -> VCALL ( func )
977 (ID op_id, rb_num_t op_argc, ISEQ blockiseq, rb_num_t op_flag, IC ic)
979 (VALUE val) // inc += - (op_argc + ((op_flag & VM_CALL_ARGS_BLOCKARG_BIT) ? 1 : 0));
983 rb_block_t *blockptr = 0;
984 rb_num_t num = caller_setup_args(th, GET_CFP(), op_flag, op_argc,
985 (rb_iseq_t *)blockiseq, &blockptr);
986 rb_num_t flag = op_flag;
990 recv = (flag & VM_CALL_FCALL_BIT) ? GET_SELF() : TOPN(num);
991 klass = CLASS_OF(recv);
992 mn = vm_method_search(id, klass, ic);
994 /* send/funcall optimization */
995 if (flag & VM_CALL_SEND_BIT) {
996 vm_send_optimize(GET_CFP(), &mn, &flag, &num, &id, klass);
999 CALL_METHOD(num, blockptr, flag, id, mn, recv, klass);
1004 @e super(args) # args.size => num
1005 @j super ‚ðŽÀ�s‚·‚é�B
1006 super(args) # args.size => num
1007 flag “™ƒIƒyƒ‰ƒ“ƒh‚̈Ӗ¡‚Í send ‚Æ“¯‚¶�B
1011 (rb_num_t op_argc, ISEQ blockiseq, rb_num_t op_flag)
1013 (VALUE val) // inc += - (op_argc + ((op_flag & VM_CALL_ARGS_BLOCKARG_BIT) ? 1 : 0));
1015 rb_block_t *blockptr = !(op_flag & VM_CALL_ARGS_BLOCKARG_BIT) ? GET_BLOCK_PTR() : 0;
1016 int num = caller_setup_args(th, GET_CFP(), op_flag, op_argc, blockiseq, &blockptr);
1020 const VALUE flag = VM_CALL_SUPER_BIT | VM_CALL_FCALL_BIT;
1023 vm_search_superclass(GET_CFP(), GET_ISEQ(), recv, TOPN(num), &id, &klass);
1024 mn = rb_method_node(klass, id);
1026 CALL_METHOD(num, blockptr, flag, id, mn, recv, klass);
1031 @e yield(args) # args.size => num, flag shows expand argument or not
1032 @j yield ‚ðŽÀ�s‚·‚é�B
1033 yield(args) # args.size => num
1037 (rb_num_t num, rb_num_t flag)
1039 (VALUE val) // inc += 1 - num;
1041 val = vm_invoke_block(th, GET_CFP(), num, flag);
1042 if (val == Qundef) {
1050 @e return from this scope.
1051 @j ‚±‚̃XƒR�[ƒv‚©‚甲‚¯‚é�B
1059 if (OPT_CHECKED_RUN) {
1060 if (reg_cfp->sp != reg_cfp->bp) {
1061 rb_bug("Stack consistency error (sp: %"PRIdPTRDIFF", bp: %"PRIdPTRDIFF")",
1062 VM_SP_CNT(th, reg_cfp->sp), VM_SP_CNT(th, reg_cfp->bp));
1066 RUBY_VM_CHECK_INTS();
1073 @e return from this vm loop
1074 @j VM loop ‚©‚甲‚¯‚é�B
1082 #if OPT_CALL_THREADED_CODE
1083 rb_bug("unused instruction on OPT_CALL_THREADED_CODE");
1090 /**********************************************************/
1091 /* deal with control flow 3: exception */
1092 /**********************************************************/
1097 @j ‘åˆæƒWƒƒƒ“ƒv‚ð�s‚¤�B
1101 (rb_num_t throw_state)
1105 RUBY_VM_CHECK_INTS();
1106 val = vm_throw(th, GET_CFP(), throw_state, throwobj);
1107 THROW_EXCEPTION(val);
1111 /**********************************************************/
1112 /* deal with control flow 4: local jump */
1113 /**********************************************************/
1117 @e set PC to (PC + dst).
1118 @j PC ‚ð (PC + dst) ‚É‚·‚é�B
1126 RUBY_VM_CHECK_INTS();
1132 @e if val is not false or nil, set PC to (PC + dst).
1133 @j ‚à‚µ val ‚ª false ‚© nil ‚Å‚È‚¯‚ê‚Î�APC ‚ð (PC + dst) ‚É‚·‚é�B
1142 RUBY_VM_CHECK_INTS();
1149 @e if val is false or nil, set PC to (PC + dst).
1150 @j ‚à‚µ val ‚ª false ‚© nil ‚È‚ç‚Î�APC ‚ð (PC + dst) ‚É‚·‚é�B
1159 RUBY_VM_CHECK_INTS();
1165 /**********************************************************/
1167 /**********************************************************/
1172 @j ƒCƒ“ƒ‰ƒCƒ“ƒLƒƒƒbƒVƒ…‚ª—LŒø‚È‚ç�A’l‚ðƒXƒ^ƒbƒN‚ɃvƒbƒVƒ…‚µ‚Ä dst ‚ÖƒWƒƒƒ“ƒv‚·‚é�B
1180 if (ic->ic_vmstat == GET_VM_STATE_VERSION()) {
1192 @e inline cache (once)
1193 @j once ‚ðŽÀŒ»‚·‚é�B
1201 if (ic->ic_vmstat) {
1214 @j ƒCƒ“ƒ‰ƒCƒ“ƒLƒƒƒbƒVƒ…‚Ì’l‚ð�Ý’è‚·‚é�B
1222 IC ic = GET_CONST_INLINE_CACHE(dst);
1225 ic->ic_vmstat = GET_VM_STATE_VERSION();
1231 @j case •¶‚Å�A‰Â”\‚È‚ç•\ˆø‚«‚ŃWƒƒƒ“ƒv‚·‚é�B
1235 (CDHASH hash, OFFSET else_offset)
1240 /* TODO: if some === method is overrided */
1244 if (st_lookup(RHASH_TBL(hash), key, &val)) {
1255 @e check environment
1264 if (GET_CFP()->bp != GET_DFP() + 1) {
1265 VALUE *new_dfp = GET_CFP()->bp - 1;
1266 /* TODO: copy env and clean stack at creating env? */
1267 *new_dfp = *GET_DFP();
1273 /** simple functions */
1278 @j �Å“K‰»‚³‚ꂽ X+Y�B
1283 (VALUE recv, VALUE obj)
1290 else if (FIXNUM_2_P(recv, obj) &&
1291 BASIC_OP_UNREDEFINED_P(BOP_PLUS)) {
1292 /* fixnum + fixnum */
1293 #ifndef LONG_LONG_VALUE
1294 val = (recv + (obj & (~1)));
1295 if ((~(recv ^ obj) & (recv ^ val)) &
1296 ((VALUE)0x01 << ((sizeof(VALUE) * CHAR_BIT) - 1))) {
1297 val = rb_big_plus(rb_int2big(FIX2LONG(recv)),
1298 rb_int2big(FIX2LONG(obj)));
1309 val = rb_big_plus(rb_int2big(a), rb_int2big(b));
1315 else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
1319 else if (HEAP_CLASS_OF(recv) == rb_cFloat &&
1320 HEAP_CLASS_OF(obj) == rb_cFloat &&
1321 BASIC_OP_UNREDEFINED_P(BOP_PLUS)) {
1322 val = DOUBLE2NUM(RFLOAT_VALUE(recv) + RFLOAT_VALUE(obj));
1327 else if (HEAP_CLASS_OF(recv) == rb_cString &&
1328 HEAP_CLASS_OF(obj) == rb_cString &&
1329 BASIC_OP_UNREDEFINED_P(BOP_PLUS)) {
1330 val = rb_str_plus(recv, obj);
1334 else if (HEAP_CLASS_OF(recv) == rb_cArray &&
1335 BASIC_OP_UNREDEFINED_P(BOP_PLUS)) {
1336 val = rb_ary_plus(recv, obj);
1340 goto INSN_LABEL(normal_dispatch);
1344 INSN_LABEL(normal_dispatch):
1347 CALL_SIMPLE_METHOD(1, idPLUS, recv);
1354 @j �Å“K‰»‚³‚ꂽ X-Y�B
1359 (VALUE recv, VALUE obj)
1362 if (FIXNUM_2_P(recv, obj) &&
1363 BASIC_OP_UNREDEFINED_P(BOP_MINUS)) {
1374 val = rb_big_minus(rb_int2big(a), rb_int2big(b));
1381 CALL_SIMPLE_METHOD(1, idMINUS, recv);
1388 @j �Å“K‰»‚³‚ꂽ X*Y�B
1393 (VALUE recv, VALUE obj)
1396 if (FIXNUM_2_P(recv, obj) &&
1397 BASIC_OP_UNREDEFINED_P(BOP_MULT)) {
1408 if (FIXABLE(c) && c / a == b) {
1412 val = rb_big_mul(rb_int2big(a), rb_int2big(b));
1416 else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
1420 else if (HEAP_CLASS_OF(recv) == rb_cFloat &&
1421 HEAP_CLASS_OF(obj) == rb_cFloat &&
1422 BASIC_OP_UNREDEFINED_P(BOP_MULT)) {
1423 val = DOUBLE2NUM(RFLOAT_VALUE(recv) * RFLOAT_VALUE(obj));
1427 goto INSN_LABEL(normal_dispatch);
1431 INSN_LABEL(normal_dispatch):
1434 CALL_SIMPLE_METHOD(1, idMULT, recv);
1441 @j �Å“K‰»‚³‚ꂽ X/Y�B
1446 (VALUE recv, VALUE obj)
1449 if (FIXNUM_2_P(recv, obj) &&
1450 BASIC_OP_UNREDEFINED_P(BOP_DIV)) {
1456 /* copied from numeric.c#fixdivmod */
1459 goto INSN_LABEL(normal_dispatch);
1473 if ((mod < 0 && y > 0) || (mod > 0 && y < 0)) {
1478 val = LONG2NUM(div);
1480 else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
1484 else if (HEAP_CLASS_OF(recv) == rb_cFloat &&
1485 HEAP_CLASS_OF(obj) == rb_cFloat &&
1486 BASIC_OP_UNREDEFINED_P(BOP_DIV)) {
1487 val = DOUBLE2NUM(RFLOAT_VALUE(recv) / RFLOAT_VALUE(obj));
1491 goto INSN_LABEL(normal_dispatch);
1495 INSN_LABEL(normal_dispatch):
1498 CALL_SIMPLE_METHOD(1, idDIV, recv);
1505 @j �Å“K‰»‚³‚ꂽ X%Y�B
1510 (VALUE recv, VALUE obj)
1513 if (FIXNUM_2_P(recv, obj) &&
1514 BASIC_OP_UNREDEFINED_P(BOP_MOD)) {
1520 /* copied from numeric.c#fixdivmod */
1538 if ((mod < 0 && y > 0) || (mod > 0 && y < 0)) {
1543 val = LONG2FIX(mod);
1545 else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
1548 else if (HEAP_CLASS_OF(recv) == rb_cFloat &&
1549 HEAP_CLASS_OF(obj) == rb_cFloat &&
1550 BASIC_OP_UNREDEFINED_P(BOP_MOD)) {
1551 double x = RFLOAT_VALUE(recv);
1552 double y = RFLOAT_VALUE(obj);
1562 div = (x - mod) / y;
1567 val = DOUBLE2NUM(mod);
1570 goto INSN_LABEL(normal_dispatch);
1574 INSN_LABEL(normal_dispatch):
1577 CALL_SIMPLE_METHOD(1, idMOD, recv);
1584 @j �Å“K‰»‚³‚ꂽ X==Y�B
1589 (VALUE recv, VALUE obj)
1592 val = opt_eq_func(recv, obj, ic);
1594 if (val == Qundef) {
1598 CALL_SIMPLE_METHOD(1, idEq, recv);
1605 @j �Å“K‰»‚³‚ꂽ X!=Y�B
1610 (VALUE recv, VALUE obj)
1613 extern VALUE rb_obj_not_equal(VALUE obj1, VALUE obj2);
1614 NODE *mn = vm_method_search(idNeq, CLASS_OF(recv), ic1);
1617 if (check_cfunc(mn, rb_obj_not_equal)) {
1618 val = opt_eq_func(recv, obj, ic2);
1620 if (val != Qundef) {
1621 val = RTEST(val) ? Qfalse : Qtrue;
1625 if (val == Qundef) {
1629 CALL_SIMPLE_METHOD(1, idNeq, recv);
1636 @j �Å“K‰»‚³‚ꂽ X<Y�B
1641 (VALUE recv, VALUE obj)
1644 if (FIXNUM_2_P(recv, obj) &&
1645 BASIC_OP_UNREDEFINED_P(BOP_LT)) {
1646 SIGNED_VALUE a = recv, b = obj;
1658 CALL_SIMPLE_METHOD(1, idLT, recv);
1665 @j �Å“K‰»‚³‚ꂽ X<=Y�B
1670 (VALUE recv, VALUE obj)
1673 if (FIXNUM_2_P(recv, obj) &&
1674 BASIC_OP_UNREDEFINED_P(BOP_LE)) {
1675 SIGNED_VALUE a = recv, b = obj;
1688 CALL_SIMPLE_METHOD(1, idLE, recv);
1695 @j �Å“K‰»‚³‚ꂽ X>Y�B
1700 (VALUE recv, VALUE obj)
1703 if (FIXNUM_2_P(recv, obj) &&
1704 BASIC_OP_UNREDEFINED_P(BOP_GT)) {
1705 SIGNED_VALUE a = recv, b = obj;
1717 CALL_SIMPLE_METHOD(1, idGT, recv);
1724 @j �Å“K‰»‚³‚ꂽ X>=Y�B
1729 (VALUE recv, VALUE obj)
1732 if (FIXNUM_2_P(recv, obj) &&
1733 BASIC_OP_UNREDEFINED_P(BOP_GE)) {
1734 SIGNED_VALUE a = recv, b = obj;
1746 CALL_SIMPLE_METHOD(1, idGE, recv);
1753 @j �Å“K‰»‚³‚ꂽ X<<Y�B
1758 (VALUE recv, VALUE obj)
1761 if (!SPECIAL_CONST_P(recv)) {
1764 else if (HEAP_CLASS_OF(recv) == rb_cString &&
1765 BASIC_OP_UNREDEFINED_P(BOP_LTLT)) {
1766 val = rb_str_concat(recv, obj);
1768 else if (HEAP_CLASS_OF(recv) == rb_cArray &&
1769 BASIC_OP_UNREDEFINED_P(BOP_LTLT)) {
1770 val = rb_ary_push(recv, obj);
1773 goto INSN_LABEL(normal_dispatch);
1777 INSN_LABEL(normal_dispatch):
1780 CALL_SIMPLE_METHOD(1, idLTLT, recv);
1787 @j �Å“K‰»‚³‚ꂽ recv[obj]�B
1792 (VALUE recv, VALUE obj)
1795 if (!SPECIAL_CONST_P(recv) && BASIC_OP_UNREDEFINED_P(BOP_AREF)) {
1796 if (HEAP_CLASS_OF(recv) == rb_cArray && FIXNUM_P(obj)) {
1797 val = rb_ary_entry(recv, FIX2LONG(obj));
1799 else if (HEAP_CLASS_OF(recv) == rb_cHash) {
1800 val = rb_hash_aref(recv, obj);
1803 goto INSN_LABEL(normal_dispatch);
1807 INSN_LABEL(normal_dispatch):
1810 CALL_SIMPLE_METHOD(1, idAREF, recv);
1817 @j �Å“K‰»‚³‚ꂽ recv[obj] = set�B
1822 (VALUE recv, VALUE obj, VALUE set)
1825 if (!SPECIAL_CONST_P(recv) &&
1826 BASIC_OP_UNREDEFINED_P(BOP_ASET)) {
1827 if (HEAP_CLASS_OF(recv) == rb_cArray && FIXNUM_P(obj)) {
1828 rb_ary_store(recv, FIX2LONG(obj), set);
1831 else if (HEAP_CLASS_OF(recv) == rb_cHash) {
1832 rb_hash_aset(recv, obj, set);
1836 goto INSN_LABEL(normal_dispatch);
1840 INSN_LABEL(normal_dispatch):
1844 CALL_SIMPLE_METHOD(2, idASET, recv);
1851 @j �Å“K‰»‚³‚ꂽ recv.length()�B
1859 if (!SPECIAL_CONST_P(recv) &&
1860 BASIC_OP_UNREDEFINED_P(BOP_LENGTH)) {
1861 if (HEAP_CLASS_OF(recv) == rb_cString) {
1862 val = rb_str_length(recv);
1864 else if (HEAP_CLASS_OF(recv) == rb_cArray) {
1865 val = LONG2NUM(RARRAY_LEN(recv));
1867 else if (HEAP_CLASS_OF(recv) == rb_cHash) {
1868 val = INT2FIX(RHASH_SIZE(recv));
1871 goto INSN_LABEL(normal_dispatch);
1875 INSN_LABEL(normal_dispatch):
1877 CALL_SIMPLE_METHOD(0, idLength, recv);
1884 @j �Å“K‰»‚³‚ꂽ recv.succ()�B
1892 if (SPECIAL_CONST_P(recv)) {
1893 if (FIXNUM_P(recv) &&
1894 BASIC_OP_UNREDEFINED_P(BOP_SUCC)) {
1895 const VALUE obj = INT2FIX(1);
1896 /* fixnum + INT2FIX(1) */
1897 val = (recv + (obj & (~1)));
1898 if ((~(recv ^ obj) & (recv ^ val)) & ((unsigned long)LONG_MAX + 1)) {
1899 val = rb_big_plus(rb_int2big(FIX2LONG(recv)),
1900 rb_int2big(FIX2LONG(obj)));
1904 goto INSN_LABEL(normal_dispatch);
1908 if (HEAP_CLASS_OF(recv) == rb_cString &&
1909 BASIC_OP_UNREDEFINED_P(BOP_SUCC)) {
1910 val = rb_str_succ(recv);
1912 else if (HEAP_CLASS_OF(recv) == rb_cTime &&
1913 BASIC_OP_UNREDEFINED_P(BOP_SUCC)) {
1914 val = rb_time_succ(recv);
1918 goto INSN_LABEL(normal_dispatch);
1922 INSN_LABEL(normal_dispatch):
1924 CALL_SIMPLE_METHOD(0, idSucc, recv);
1931 @j �Å“K‰»‚³‚ꂽ recv.!()�B
1939 extern VALUE rb_obj_not(VALUE obj);
1940 NODE *mn = vm_method_search(idNot, CLASS_OF(recv), ic);
1942 if (check_cfunc(mn, rb_obj_not)) {
1943 val = RTEST(recv) ? Qfalse : Qtrue;
1947 CALL_SIMPLE_METHOD(0, idNot, recv);
1954 @e optimized regexp match
1955 @j �Å“K‰»‚³‚ꂽ�³‹K•\Œ»ƒ}ƒbƒ`�B
1963 val = rb_reg_match(r, obj);
1968 @e optimized regexp match 2
1969 @j �Å“K‰»‚³‚ꂽ�³‹K•\Œ»ƒ}ƒbƒ` 2
1974 (VALUE obj2, VALUE obj1)
1977 if (TYPE(obj2) == T_STRING) {
1978 val = rb_reg_match(obj1, obj2);
1981 val = rb_funcall(obj2, idEqTilde, 1, obj1);
1987 @e call native compiled method
1988 @j ƒlƒCƒeƒBƒuƒRƒ“ƒpƒCƒ‹‚µ‚½ƒ�ƒ\ƒbƒh‚ð‹N“®�B
1992 (rb_insn_func_t funcptr)
1996 reg_cfp = (funcptr)(th, reg_cfp);
1999 VALUE err = th->errinfo;
2001 THROW_EXCEPTION(err);
2019 ret = rb_str_new2("a bit of bacon, lettuce and tomato");
2024 @e The Answer to Life, the Universe, and Everything
2025 @j �l�¶�A‰F’ˆ�A‚·‚ׂĂ̓š‚¦�B