* io.c (rb_open_file): encoding in mode string was ignored if perm is
[ruby-svn.git] / insns.def
bloba695630ea6409ae6103dcc7b31bcb320b9ae813c
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 some object.
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.
318 DEFINE_INSN
319 putobject
320 (VALUE val)
322 (VALUE val)
324 /* */
328 @c put
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
333 DEFINE_INSN
334 putspecialobject
335 (rb_num_t value_type)
337 (VALUE val)
339 switch (value_type) {
340 case VM_SPECIAL_OBJECT_VMCORE:
341 val = rb_mRubyVMFrozenCore;
342 break;
343 case VM_SPECIAL_OBJECT_CBASE:
344 val = vm_get_cbase(GET_ISEQ(), GET_LFP(), GET_DFP());
345 break;
346 default:
347 rb_bug("putspecialobject insn: unknown value_type");
352 @c put
353 @e put iseq value.
354 @j put iseq value.
356 DEFINE_INSN
357 putiseq
358 (ISEQ iseq)
360 (VALUE ret)
362 ret = iseq->self;
366 @c put
367 @e put string val. string will be copied.
368 @j •¶Žš—ñ‚ð‚ðƒRƒs�[‚µ‚ăXƒ^ƒbƒN‚ɃvƒbƒVƒ…‚·‚é�B
370 DEFINE_INSN
371 putstring
372 (VALUE str)
374 (VALUE val)
376 val = rb_str_new3(str);
380 @c put
381 @e put concatenate strings
382 @j ƒXƒ^ƒbƒNƒgƒbƒv‚Ì•¶Žš—ñ‚ð n ŒÂ˜AŒ‹‚µ�CŒ‹‰Ê‚ðƒXƒ^ƒbƒN‚ɃvƒbƒVƒ…‚·‚é�B
384 DEFINE_INSN
385 concatstrings
386 (rb_num_t num)
387 (...)
388 (VALUE val) // inc += 1 - num;
390 int i;
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);
397 POPN(num);
401 @c put
402 @e to_str
403 @j to_str ‚ÌŒ‹‰Ê‚ðƒXƒ^ƒbƒN‚ɃvƒbƒVƒ…‚·‚é�B
405 DEFINE_INSN
406 tostring
408 (VALUE val)
409 (VALUE val)
411 val = rb_obj_as_string(val);
415 @c put
416 @e to Regexp
417 @j •¶Žš—ñ str ‚ð�³‹K•\Œ»‚ɃRƒ“ƒpƒCƒ‹‚µ‚ăXƒ^ƒbƒN‚ɃvƒbƒVƒ…‚·‚é�B
418 ƒRƒ“ƒpƒCƒ‹Žž�Copt ‚ð�³‹K•\Œ»‚̃IƒvƒVƒ‡ƒ“‚Æ‚·‚é�B
420 DEFINE_INSN
421 toregexp
422 (rb_num_t opt, rb_num_t cnt)
423 (...)
424 (VALUE val) // inc += 1 - cnt;
426 VALUE rb_reg_new_ary(VALUE ary, int options);
427 int i;
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));
433 POPN(cnt);
434 val = rb_reg_new_ary(ary, opt);
438 @c put
439 @e put new array.
440 @j �V‚µ‚¢”z—ñ‚ðƒXƒ^ƒbƒN�ã‚Ì num ŒÂ‚Ì’l‚Å�‰Šú‰»‚µ‚Ä�¶�¬‚µƒvƒbƒVƒ…‚·‚é�B
442 DEFINE_INSN
443 newarray
444 (rb_num_t num)
445 (...)
446 (VALUE val) // inc += 1 - num;
448 val = rb_ary_new4((long)num, STACK_ADDR_FROM_TOP(num));
449 POPN(num);
453 @c put
454 @e dup array
455 @j ”z—ñ ary ‚ð dup ‚µ‚ăXƒ^ƒbƒN‚ɃvƒbƒVƒ…‚·‚é�B
457 DEFINE_INSN
458 duparray
459 (VALUE ary)
461 (VALUE val)
463 val = rb_ary_dup(ary);
467 @c put
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?
478 DEFINE_INSN
479 expandarray
480 (rb_num_t num, rb_num_t flag)
481 (..., VALUE ary)
482 (...) // inc += num - 1 + (flag & 1 ? 1 : 0);
484 vm_expandarray(GET_CFP(), ary, num, flag);
488 @c put
489 @e concat two arrays
490 @j “ñ‚‚̔z—ñ ary1, ary2 ‚ð˜AŒ‹‚µƒXƒ^ƒbƒN‚ÖƒvƒbƒVƒ…‚·‚é�B
492 DEFINE_INSN
493 concatarray
495 (VALUE ary1, VALUE ary2st)
496 (VALUE ary)
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");
502 if (NIL_P(tmp1)) {
503 tmp1 = rb_ary_new3(1, ary1);
506 if (NIL_P(tmp2)) {
507 tmp2 = rb_ary_new3(1, ary2);
510 if (tmp1 == ary1) {
511 tmp1 = rb_ary_dup(ary1);
513 ary = rb_ary_concat(tmp1, tmp2);
517 @c put
518 @e splat array
519 @j ”z—ñ ary ‚ɑ΂µ‚Ä to_a ‚ðŒÄ‚Ñ�o‚·�B
521 DEFINE_INSN
522 splatarray
523 (VALUE flag)
524 (VALUE ary)
525 (VALUE obj)
527 VALUE tmp = rb_check_convert_type(ary, T_ARRAY, "Array", "to_a");
528 if (NIL_P(tmp)) {
529 tmp = rb_ary_new3(1, ary);
531 obj = tmp;
535 @c put
536 @e check value is included in ary
537 @j ”z—ñ ary ‚É—v‘f obj ‚ª“ü‚Á‚Ä‚¢‚é‚©‚Ç‚¤‚©ƒ`ƒFƒbƒN�Bcase/when ‚Å—˜—p‚·‚é�B
539 DEFINE_INSN
540 checkincludearray
541 (VALUE flag)
542 (VALUE obj, VALUE ary)
543 (VALUE obj, VALUE result)
545 int i;
546 result = Qfalse;
548 if (TYPE(ary) != T_ARRAY) {
549 ary = rb_Array(ary);
552 if (flag == Qtrue) {
553 /* NODE_CASE */
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))) {
557 result = Qtrue;
558 break;
562 else {
563 obj = Qfalse;
564 /* NODE_WHEN */
565 for (i = 0; i < RARRAY_LEN(ary); i++) {
566 if (RTEST(RARRAY_PTR(ary)[i])) {
567 obj = result = Qtrue;
568 break;
575 @c put
576 @e put new Hash.
577 @j �V‚µ‚¢ƒnƒbƒVƒ…‚ðƒXƒ^ƒbƒNƒgƒbƒv‚Ì n ŒÂ‚ð�‰Šú’l‚Æ‚µ‚Ä�¶�¬‚·‚é�B
578 n ‚̓L�[‚Æ’l‚̃yƒA‚È‚Ì‚Å 2 ‚Ì”{�”‚Å‚È‚¯‚ê‚΂Ȃç‚È‚¢�B
580 DEFINE_INSN
581 newhash
582 (rb_num_t num)
583 (...)
584 (VALUE val) // inc += 1 - num;
586 int i;
587 val = rb_hash_new();
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);
594 POPN(num);
598 @c put
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
602 DEFINE_INSN
603 newrange
604 (rb_num_t flag)
605 (VALUE low, VALUE high)
606 (VALUE val)
608 val = rb_range_new(low, high, flag);
611 /**********************************************************/
612 /* deal with stack operation */
613 /**********************************************************/
616 @c stack
617 @e pop from stack.
618 @j ƒXƒ^ƒbƒN‚©‚çˆê‚ƒ|ƒbƒv‚·‚é�B
620 DEFINE_INSN
623 (VALUE val)
626 val = val;
627 /* none */
631 @c stack
632 @e duplicate stack top.
633 @j ƒXƒ^ƒbƒNƒgƒbƒv‚ðƒRƒs�[‚µ‚ăXƒ^ƒbƒN‚ɃvƒbƒVƒ…‚·‚é�B
635 DEFINE_INSN
638 (VALUE val)
639 (VALUE val1, VALUE val2)
641 val1 = val2 = val;
645 @c stack
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
649 DEFINE_INSN
650 dupn
651 (rb_num_t n)
652 (...)
653 (...) // inc += n;
655 int i;
656 VALUE *sp = STACK_ADDR_FROM_TOP(n);
657 for (i = 0; i < n; i++) {
658 GET_SP()[i] = sp[i];
660 INC_SP(n);
665 @c stack
666 @e swap top 2 vals
667 @j ƒXƒ^ƒbƒNƒgƒbƒv‚Ì 2 ‚‚̒l‚ðŒðŠ·‚·‚é�B
669 DEFINE_INSN
670 swap
672 (VALUE val, VALUE obj)
673 (VALUE obj, VALUE val)
675 /* none */
679 @c stack
680 @e for stack caching.
681 @j ƒXƒ^ƒbƒNƒLƒƒƒbƒVƒ“ƒO‚Ì�ó‘Ô‚ð’²�®‚·‚邽‚ß‚É•K—v‚È–½—ß�B
683 DEFINE_INSN
684 reput
686 (..., VALUE val)
687 (VALUE val) // inc += 0;
689 /* none */
693 @c stack
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
697 DEFINE_INSN
698 topn
699 (rb_num_t n)
700 (...)
701 (VALUE val) // inc += 1;
703 val = TOPN(n);
707 @c stack
708 @e set Nth stack entry to stack top
709 @j ƒXƒ^ƒbƒNƒgƒbƒv‚Ì’l‚ð n ŒÂ–ڂ̃Xƒ^ƒbƒN‚ɃRƒs�[
711 DEFINE_INSN
712 setn
713 (rb_num_t n)
714 (..., VALUE val)
715 (VALUE val) // inc += 0
717 TOPN(n-1) = val;
721 @c stack
722 @e empt current stack
723 @j current stack ‚ð‹ó‚É‚·‚é�B
725 DEFINE_INSN
726 adjuststack
727 (rb_num_t n)
728 (...)
729 (...) // inc -= n
731 DEC_SP(n);
735 /**********************************************************/
736 /* deal with setting */
737 /**********************************************************/
740 @c setting
741 @e defined?
742 @j defined? ‚ð�s‚¤�B
744 DEFINE_INSN
745 defined
746 (rb_num_t type, VALUE obj, VALUE needstr)
747 (VALUE v)
748 (VALUE val)
750 VALUE klass;
751 const char *expr_type = 0;
752 val = Qnil;
754 switch (type) {
755 case DEFINED_IVAR:
756 if (rb_ivar_defined(GET_SELF(), SYM2ID(obj))) {
757 expr_type = "instance-variable";
759 break;
760 case DEFINED_IVAR2:
761 klass = vm_get_cbase(GET_ISEQ(), GET_LFP(), GET_DFP());
762 break;
763 case DEFINED_GVAR:
764 if (rb_gvar_defined((struct global_entry *)(obj & ~1))) {
765 expr_type = "global-variable";
767 break;
768 case DEFINED_CVAR:
769 klass = vm_get_cbase(GET_ISEQ(), GET_LFP(), GET_DFP());
770 if (rb_cvar_defined(klass, SYM2ID(obj))) {
771 expr_type = "class variable";
773 break;
774 case DEFINED_CONST:
775 klass = v;
776 if (vm_get_ev_const(th, GET_ISEQ(), klass, SYM2ID(obj), 1)) {
777 expr_type = "constant";
779 break;
780 case DEFINED_FUNC:
781 klass = CLASS_OF(v);
782 if (rb_method_boundp(klass, SYM2ID(obj), 0)) {
783 expr_type = "method";
785 break;
786 case DEFINED_METHOD:{
787 VALUE klass = CLASS_OF(v);
788 NODE *method = (NODE *) rb_method_node(klass, SYM2ID(obj));
790 if (method) {
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";
799 break;
801 case DEFINED_YIELD:
802 if (GET_BLOCK_PTR()) {
803 expr_type = "yield";
805 break;
806 case DEFINED_ZSUPER:{
807 rb_iseq_t *ip = GET_ISEQ();
808 while (ip) {
809 if (ip->defined_method_id) {
810 break;
812 ip = ip->parent_iseq;
814 if (ip) {
815 VALUE klass = vm_search_normal_superclass(ip->klass, GET_SELF());
816 if (rb_method_boundp(klass, ip->defined_method_id, 0)) {
817 expr_type = "super";
820 break;
822 case DEFINED_REF:{
823 val = vm_getspecial(th, GET_LFP(), Qfalse, FIX2INT(obj));
824 if (val != Qnil) {
825 expr_type = "global-variable";
827 break;
829 default:
830 rb_bug("unimplemented defined? type (VM)");
831 break;
833 if (expr_type != 0) {
834 if (needstr != Qfalse) {
835 val = rb_str_new2(expr_type);
837 else {
838 val = Qtrue;
844 @c setting
845 @e trace
846 @j trace —p‚Ì–½—ß�B
848 DEFINE_INSN
849 trace
850 (rb_num_t nf)
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 /**********************************************************/
864 @c class/module
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
872 DEFINE_INSN
873 defineclass
874 (ID id, ISEQ class_iseq, rb_num_t define_type)
875 (VALUE cbase, VALUE super)
876 (VALUE val)
878 VALUE klass;
880 switch ((int)define_type) {
881 case 0:
882 /* val is dummy. classdef returns class scope value */
884 if (super == Qnil) {
885 super = rb_cObject;
888 vm_check_if_namespace(cbase);
890 /* find klass */
891 if (rb_const_defined_at(cbase, id)) {
892 /* already exist */
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) {
899 VALUE tmp;
900 tmp = rb_class_real(RCLASS_SUPER(klass));
902 if (tmp != super) {
903 rb_raise(rb_eTypeError, "superclass mismatch for class %s",
904 rb_id2name(id));
908 else {
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);
915 break;
916 case 1:
917 /* val is dummy. classdef returns class scope value */
918 /* super is dummy */
919 klass = rb_singleton_class(cbase);
920 break;
921 case 2:
922 /* val is dummy. classdef returns class scope value */
923 /* super is dummy */
925 vm_check_if_namespace(cbase);
927 /* find klass */
928 if (rb_const_defined_at(cbase, id)) {
929 klass = rb_const_get_at(cbase, id);
930 /* already exist */
931 if (TYPE(klass) != T_MODULE) {
932 rb_raise(rb_eTypeError, "%s is not a module", rb_id2name(id));
935 else {
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);
941 break;
942 default:
943 rb_bug("unknown defineclass type: %d", (int)define_type);
946 COPY_CREF(class_iseq->cref_stack, vm_cref_push(th, klass, NOEX_PUBLIC));
948 /* enter scope */
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);
953 RESTORE_REGS();
955 INC_VM_STATE_VERSION();
956 NEXT_INSN();
960 /**********************************************************/
961 /* deal with control flow 2: method/iterator */
962 /**********************************************************/
965 @c method/iterator
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 )
975 DEFINE_INSN
976 send
977 (ID op_id, rb_num_t op_argc, ISEQ blockiseq, rb_num_t op_flag, IC ic)
978 (...)
979 (VALUE val) // inc += - (op_argc + ((op_flag & VM_CALL_ARGS_BLOCKARG_BIT) ? 1 : 0));
981 NODE *mn;
982 VALUE recv, klass;
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;
987 ID id = op_id;
989 /* get receiver */
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);
1003 @c method/iterator
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
1009 DEFINE_INSN
1010 invokesuper
1011 (rb_num_t op_argc, ISEQ blockiseq, rb_num_t op_flag)
1012 (...)
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);
1017 VALUE recv, klass;
1018 NODE *mn;
1019 ID id;
1020 const VALUE flag = VM_CALL_SUPER_BIT | VM_CALL_FCALL_BIT;
1022 recv = GET_SELF();
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);
1030 @c method/iterator
1031 @e yield(args) # args.size => num, flag shows expand argument or not
1032 @j yield ‚ðŽÀ�s‚·‚é�B
1033 yield(args) # args.size => num
1035 DEFINE_INSN
1036 invokeblock
1037 (rb_num_t num, rb_num_t flag)
1038 (...)
1039 (VALUE val) // inc += 1 - num;
1041 val = vm_invoke_block(th, GET_CFP(), num, flag);
1042 if (val == Qundef) {
1043 RESTORE_REGS();
1044 NEXT_INSN();
1049 @c method/iterator
1050 @e return from this scope.
1051 @j ‚±‚̃XƒR�[ƒv‚©‚甲‚¯‚é�B
1053 DEFINE_INSN
1054 leave
1056 (VALUE val)
1057 (VALUE val)
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();
1067 vm_pop_frame(th);
1068 RESTORE_REGS();
1072 @c method/iterator
1073 @e return from this vm loop
1074 @j VM loop ‚©‚甲‚¯‚é�B
1076 DEFINE_INSN
1077 finish
1079 (VALUE val)
1080 (VALUE val)
1082 #if OPT_CALL_THREADED_CODE
1083 rb_bug("unused instruction on OPT_CALL_THREADED_CODE");
1084 #else
1085 th->cfp++;
1086 return val;
1087 #endif
1090 /**********************************************************/
1091 /* deal with control flow 3: exception */
1092 /**********************************************************/
1095 @c exception
1096 @e longjump
1097 @j ‘åˆæƒWƒƒƒ“ƒv‚ð�s‚¤�B
1099 DEFINE_INSN
1100 throw
1101 (rb_num_t throw_state)
1102 (VALUE throwobj)
1103 (VALUE val)
1105 RUBY_VM_CHECK_INTS();
1106 val = vm_throw(th, GET_CFP(), throw_state, throwobj);
1107 THROW_EXCEPTION(val);
1108 /* unreachable */
1111 /**********************************************************/
1112 /* deal with control flow 4: local jump */
1113 /**********************************************************/
1116 @c jump
1117 @e set PC to (PC + dst).
1118 @j PC ‚ð (PC + dst) ‚É‚·‚é�B
1120 DEFINE_INSN
1121 jump
1122 (OFFSET dst)
1126 RUBY_VM_CHECK_INTS();
1127 JUMP(dst);
1131 @c jump
1132 @e if val is not false or nil, set PC to (PC + dst).
1133 @j ‚à‚µ val ‚ª false ‚© nil ‚Å‚È‚¯‚ê‚Î�APC ‚ð (PC + dst) ‚É‚·‚é�B
1135 DEFINE_INSN
1136 branchif
1137 (OFFSET dst)
1138 (VALUE val)
1141 if (RTEST(val)) {
1142 RUBY_VM_CHECK_INTS();
1143 JUMP(dst);
1148 @c jump
1149 @e if val is false or nil, set PC to (PC + dst).
1150 @j ‚à‚µ val ‚ª false ‚© nil ‚È‚ç‚Î�APC ‚ð (PC + dst) ‚É‚·‚é�B
1152 DEFINE_INSN
1153 branchunless
1154 (OFFSET dst)
1155 (VALUE val)
1158 if (!RTEST(val)) {
1159 RUBY_VM_CHECK_INTS();
1160 JUMP(dst);
1165 /**********************************************************/
1166 /* for optimize */
1167 /**********************************************************/
1170 @c optimize
1171 @e inline cache
1172 @j ƒCƒ“ƒ‰ƒCƒ“ƒLƒƒƒbƒVƒ…‚ª—LŒø‚È‚ç�A’l‚ðƒXƒ^ƒbƒN‚ɃvƒbƒVƒ…‚µ‚Ä dst ‚ÖƒWƒƒƒ“ƒv‚·‚é�B
1174 DEFINE_INSN
1175 getinlinecache
1176 (IC ic, OFFSET dst)
1178 (VALUE val)
1180 if (ic->ic_vmstat == GET_VM_STATE_VERSION()) {
1181 val = ic->ic_value;
1182 JUMP(dst);
1184 else {
1185 /* none */
1186 val = Qnil;
1191 @c optimize
1192 @e inline cache (once)
1193 @j once ‚ðŽÀŒ»‚·‚é�B
1195 DEFINE_INSN
1196 onceinlinecache
1197 (IC ic, OFFSET dst)
1199 (VALUE val)
1201 if (ic->ic_vmstat) {
1202 val = ic->ic_value;
1203 JUMP(dst);
1205 else {
1206 /* none */
1207 val = Qnil;
1212 @c optimize
1213 @e set inline cache
1214 @j ƒCƒ“ƒ‰ƒCƒ“ƒLƒƒƒbƒVƒ…‚Ì’l‚ð�Ý’è‚·‚é�B
1216 DEFINE_INSN
1217 setinlinecache
1218 (OFFSET dst)
1219 (VALUE val)
1220 (VALUE val)
1222 IC ic = GET_CONST_INLINE_CACHE(dst);
1224 ic->ic_value = val;
1225 ic->ic_vmstat = GET_VM_STATE_VERSION();
1229 @c optimize
1230 @e case dispatcher
1231 @j case •¶‚Å�A‰Â”\‚È‚ç•\ˆø‚«‚ŃWƒƒƒ“ƒv‚·‚é�B
1233 DEFINE_INSN
1234 opt_case_dispatch
1235 (CDHASH hash, OFFSET else_offset)
1236 (..., VALUE key)
1237 () // inc += -1;
1239 if (0) {
1240 /* TODO: if some === method is overrided */
1242 else {
1243 VALUE val;
1244 if (st_lookup(RHASH_TBL(hash), key, &val)) {
1245 JUMP(FIX2INT(val));
1247 else {
1248 JUMP(else_offset);
1254 @c optimize
1255 @e check environment
1256 @j �«—ˆ‚ÌŠg’£—p�B
1258 DEFINE_INSN
1259 opt_checkenv
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();
1268 SET_DFP(new_dfp);
1273 /** simple functions */
1276 @c optimize
1277 @e optimized X+Y.
1278 @j �Å“K‰»‚³‚ꂽ X+Y�B
1280 DEFINE_INSN
1281 opt_plus
1283 (VALUE recv, VALUE obj)
1284 (VALUE val)
1286 if (0) {
1289 #if 1
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)));
1300 #else
1301 long a, b, c;
1302 a = FIX2LONG(recv);
1303 b = FIX2LONG(obj);
1304 c = a + b;
1305 if (FIXABLE(c)) {
1306 val = LONG2FIX(c);
1308 else {
1309 val = rb_big_plus(rb_int2big(a), rb_int2big(b));
1311 #endif
1313 #endif
1315 else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
1316 if (0) {
1318 #if 1
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));
1324 #endif
1326 #if 1
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);
1332 #endif
1333 #if 1
1334 else if (HEAP_CLASS_OF(recv) == rb_cArray &&
1335 BASIC_OP_UNREDEFINED_P(BOP_PLUS)) {
1336 val = rb_ary_plus(recv, obj);
1338 #endif
1339 else {
1340 goto INSN_LABEL(normal_dispatch);
1343 else {
1344 INSN_LABEL(normal_dispatch):
1345 PUSH(recv);
1346 PUSH(obj);
1347 CALL_SIMPLE_METHOD(1, idPLUS, recv);
1352 @c optimize
1353 @e optimized X-Y.
1354 @j �Å“K‰»‚³‚ꂽ X-Y�B
1356 DEFINE_INSN
1357 opt_minus
1359 (VALUE recv, VALUE obj)
1360 (VALUE val)
1362 if (FIXNUM_2_P(recv, obj) &&
1363 BASIC_OP_UNREDEFINED_P(BOP_MINUS)) {
1364 long a, b, c;
1366 a = FIX2LONG(recv);
1367 b = FIX2LONG(obj);
1368 c = a - b;
1370 if (FIXABLE(c)) {
1371 val = LONG2FIX(c);
1373 else {
1374 val = rb_big_minus(rb_int2big(a), rb_int2big(b));
1377 else {
1378 /* other */
1379 PUSH(recv);
1380 PUSH(obj);
1381 CALL_SIMPLE_METHOD(1, idMINUS, recv);
1386 @c optimize
1387 @e optimized X*Y.
1388 @j �Å“K‰»‚³‚ꂽ X*Y�B
1390 DEFINE_INSN
1391 opt_mult
1393 (VALUE recv, VALUE obj)
1394 (VALUE val)
1396 if (FIXNUM_2_P(recv, obj) &&
1397 BASIC_OP_UNREDEFINED_P(BOP_MULT)) {
1398 long a, b, c;
1400 a = FIX2LONG(recv);
1401 if (a == 0) {
1402 val = recv;
1404 else {
1405 b = FIX2LONG(obj);
1406 c = a * b;
1408 if (FIXABLE(c) && c / a == b) {
1409 val = LONG2FIX(c);
1411 else {
1412 val = rb_big_mul(rb_int2big(a), rb_int2big(b));
1416 else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
1417 if (0) {
1419 #if 1
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));
1425 #endif
1426 else {
1427 goto INSN_LABEL(normal_dispatch);
1430 else {
1431 INSN_LABEL(normal_dispatch):
1432 PUSH(recv);
1433 PUSH(obj);
1434 CALL_SIMPLE_METHOD(1, idMULT, recv);
1439 @c optimize
1440 @e optimized X/Y.
1441 @j �Å“K‰»‚³‚ꂽ X/Y�B
1443 DEFINE_INSN
1444 opt_div
1446 (VALUE recv, VALUE obj)
1447 (VALUE val)
1449 if (FIXNUM_2_P(recv, obj) &&
1450 BASIC_OP_UNREDEFINED_P(BOP_DIV)) {
1451 long x, y, div;
1453 x = FIX2LONG(recv);
1454 y = FIX2LONG(obj);
1456 /* copied from numeric.c#fixdivmod */
1457 long mod;
1458 if (y == 0)
1459 goto INSN_LABEL(normal_dispatch);
1460 if (y < 0) {
1461 if (x < 0)
1462 div = -x / -y;
1463 else
1464 div = -(x / -y);
1466 else {
1467 if (x < 0)
1468 div = -(-x / y);
1469 else
1470 div = x / y;
1472 mod = x - div * y;
1473 if ((mod < 0 && y > 0) || (mod > 0 && y < 0)) {
1474 mod += y;
1475 div -= 1;
1478 val = LONG2NUM(div);
1480 else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
1481 if (0) {
1483 #if 1
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));
1489 #endif
1490 else {
1491 goto INSN_LABEL(normal_dispatch);
1494 else {
1495 INSN_LABEL(normal_dispatch):
1496 PUSH(recv);
1497 PUSH(obj);
1498 CALL_SIMPLE_METHOD(1, idDIV, recv);
1503 @c optimize
1504 @e optimized X%Y.
1505 @j �Å“K‰»‚³‚ꂽ X%Y�B
1507 DEFINE_INSN
1508 opt_mod
1510 (VALUE recv, VALUE obj)
1511 (VALUE val)
1513 if (FIXNUM_2_P(recv, obj) &&
1514 BASIC_OP_UNREDEFINED_P(BOP_MOD)) {
1515 long x, y, mod;
1517 x = FIX2LONG(recv);
1518 y = FIX2LONG(obj);
1520 /* copied from numeric.c#fixdivmod */
1521 long div;
1523 if (y == 0)
1524 rb_num_zerodiv();
1525 if (y < 0) {
1526 if (x < 0)
1527 div = -x / -y;
1528 else
1529 div = -(x / -y);
1531 else {
1532 if (x < 0)
1533 div = -(-x / y);
1534 else
1535 div = x / y;
1537 mod = x - div * y;
1538 if ((mod < 0 && y > 0) || (mod > 0 && y < 0)) {
1539 mod += y;
1540 div -= 1;
1543 val = LONG2FIX(mod);
1545 else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
1546 if (0) {
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);
1553 double div, mod;
1556 double z;
1558 modf(x / y, &z);
1559 mod = x - z * y;
1562 div = (x - mod) / y;
1563 if (y * mod < 0) {
1564 mod += y;
1565 div -= 1.0;
1567 val = DOUBLE2NUM(mod);
1569 else {
1570 goto INSN_LABEL(normal_dispatch);
1573 else {
1574 INSN_LABEL(normal_dispatch):
1575 PUSH(recv);
1576 PUSH(obj);
1577 CALL_SIMPLE_METHOD(1, idMOD, recv);
1582 @c optimize
1583 @e optimized X==Y.
1584 @j �Å“K‰»‚³‚ꂽ X==Y�B
1586 DEFINE_INSN
1587 opt_eq
1588 (IC ic)
1589 (VALUE recv, VALUE obj)
1590 (VALUE val)
1592 val = opt_eq_func(recv, obj, ic);
1594 if (val == Qundef) {
1595 /* other */
1596 PUSH(recv);
1597 PUSH(obj);
1598 CALL_SIMPLE_METHOD(1, idEq, recv);
1603 @c optimize
1604 @e optimized X!=Y.
1605 @j �Å“K‰»‚³‚ꂽ X!=Y�B
1607 DEFINE_INSN
1608 opt_neq
1609 (IC ic1, IC ic2)
1610 (VALUE recv, VALUE obj)
1611 (VALUE val)
1613 extern VALUE rb_obj_not_equal(VALUE obj1, VALUE obj2);
1614 NODE *mn = vm_method_search(idNeq, CLASS_OF(recv), ic1);
1615 val = Qundef;
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) {
1626 /* other */
1627 PUSH(recv);
1628 PUSH(obj);
1629 CALL_SIMPLE_METHOD(1, idNeq, recv);
1634 @c optimize
1635 @e optimized X<Y.
1636 @j �Å“K‰»‚³‚ꂽ X<Y�B
1638 DEFINE_INSN
1639 opt_lt
1641 (VALUE recv, VALUE obj)
1642 (VALUE val)
1644 if (FIXNUM_2_P(recv, obj) &&
1645 BASIC_OP_UNREDEFINED_P(BOP_LT)) {
1646 SIGNED_VALUE a = recv, b = obj;
1648 if (a < b) {
1649 val = Qtrue;
1651 else {
1652 val = Qfalse;
1655 else {
1656 PUSH(recv);
1657 PUSH(obj);
1658 CALL_SIMPLE_METHOD(1, idLT, recv);
1663 @c optimize
1664 @e optimized X<=Y.
1665 @j �Å“K‰»‚³‚ꂽ X<=Y�B
1667 DEFINE_INSN
1668 opt_le
1670 (VALUE recv, VALUE obj)
1671 (VALUE val)
1673 if (FIXNUM_2_P(recv, obj) &&
1674 BASIC_OP_UNREDEFINED_P(BOP_LE)) {
1675 SIGNED_VALUE a = recv, b = obj;
1677 if (a <= b) {
1678 val = Qtrue;
1680 else {
1681 val = Qfalse;
1684 else {
1685 /* other */
1686 PUSH(recv);
1687 PUSH(obj);
1688 CALL_SIMPLE_METHOD(1, idLE, recv);
1693 @c optimize
1694 @e optimized X>Y.
1695 @j �Å“K‰»‚³‚ꂽ X>Y�B
1697 DEFINE_INSN
1698 opt_gt
1700 (VALUE recv, VALUE obj)
1701 (VALUE val)
1703 if (FIXNUM_2_P(recv, obj) &&
1704 BASIC_OP_UNREDEFINED_P(BOP_GT)) {
1705 SIGNED_VALUE a = recv, b = obj;
1707 if (a > b) {
1708 val = Qtrue;
1710 else {
1711 val = Qfalse;
1714 else {
1715 PUSH(recv);
1716 PUSH(obj);
1717 CALL_SIMPLE_METHOD(1, idGT, recv);
1722 @c optimize
1723 @e optimized X>=Y.
1724 @j �Å“K‰»‚³‚ꂽ X>=Y�B
1726 DEFINE_INSN
1727 opt_ge
1729 (VALUE recv, VALUE obj)
1730 (VALUE val)
1732 if (FIXNUM_2_P(recv, obj) &&
1733 BASIC_OP_UNREDEFINED_P(BOP_GE)) {
1734 SIGNED_VALUE a = recv, b = obj;
1736 if (a >= b) {
1737 val = Qtrue;
1739 else {
1740 val = Qfalse;
1743 else {
1744 PUSH(recv);
1745 PUSH(obj);
1746 CALL_SIMPLE_METHOD(1, idGE, recv);
1751 @c optimize
1752 @e <<
1753 @j �Å“K‰»‚³‚ꂽ X<<Y�B
1755 DEFINE_INSN
1756 opt_ltlt
1758 (VALUE recv, VALUE obj)
1759 (VALUE val)
1761 if (!SPECIAL_CONST_P(recv)) {
1762 if (0) {
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);
1772 else {
1773 goto INSN_LABEL(normal_dispatch);
1776 else {
1777 INSN_LABEL(normal_dispatch):
1778 PUSH(recv);
1779 PUSH(obj);
1780 CALL_SIMPLE_METHOD(1, idLTLT, recv);
1785 @c optimize
1786 @e []
1787 @j �Å“K‰»‚³‚ꂽ recv[obj]�B
1789 DEFINE_INSN
1790 opt_aref
1792 (VALUE recv, VALUE obj)
1793 (VALUE val)
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);
1802 else {
1803 goto INSN_LABEL(normal_dispatch);
1806 else {
1807 INSN_LABEL(normal_dispatch):
1808 PUSH(recv);
1809 PUSH(obj);
1810 CALL_SIMPLE_METHOD(1, idAREF, recv);
1815 @c optimize
1816 @e recv[obj] = set
1817 @j �Å“K‰»‚³‚ꂽ recv[obj] = set�B
1819 DEFINE_INSN
1820 opt_aset
1822 (VALUE recv, VALUE obj, VALUE set)
1823 (VALUE val)
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);
1829 val = set;
1831 else if (HEAP_CLASS_OF(recv) == rb_cHash) {
1832 rb_hash_aset(recv, obj, set);
1833 val = set;
1835 else {
1836 goto INSN_LABEL(normal_dispatch);
1839 else {
1840 INSN_LABEL(normal_dispatch):
1841 PUSH(recv);
1842 PUSH(obj);
1843 PUSH(set);
1844 CALL_SIMPLE_METHOD(2, idASET, recv);
1849 @c optimize
1850 @e optimized length
1851 @j �Å“K‰»‚³‚ꂽ recv.length()�B
1853 DEFINE_INSN
1854 opt_length
1856 (VALUE recv)
1857 (VALUE val)
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));
1870 else {
1871 goto INSN_LABEL(normal_dispatch);
1874 else {
1875 INSN_LABEL(normal_dispatch):
1876 PUSH(recv);
1877 CALL_SIMPLE_METHOD(0, idLength, recv);
1882 @c optimize
1883 @e optimized succ
1884 @j �Å“K‰»‚³‚ꂽ recv.succ()�B
1886 DEFINE_INSN
1887 opt_succ
1889 (VALUE recv)
1890 (VALUE val)
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)));
1903 else {
1904 goto INSN_LABEL(normal_dispatch);
1907 else {
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);
1916 else
1918 goto INSN_LABEL(normal_dispatch);
1921 if (0) {
1922 INSN_LABEL(normal_dispatch):
1923 PUSH(recv);
1924 CALL_SIMPLE_METHOD(0, idSucc, recv);
1929 @c optimize
1930 @e optimized not
1931 @j �Å“K‰»‚³‚ꂽ recv.!()�B
1933 DEFINE_INSN
1934 opt_not
1935 (IC ic)
1936 (VALUE recv)
1937 (VALUE val)
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;
1945 else {
1946 PUSH(recv);
1947 CALL_SIMPLE_METHOD(0, idNot, recv);
1953 @c optimize
1954 @e optimized regexp match
1955 @j �Å“K‰»‚³‚ꂽ�³‹K•\Œ»ƒ}ƒbƒ`�B
1957 DEFINE_INSN
1958 opt_regexpmatch1
1959 (VALUE r)
1960 (VALUE obj)
1961 (VALUE val)
1963 val = rb_reg_match(r, obj);
1967 @c optimize
1968 @e optimized regexp match 2
1969 @j �Å“K‰»‚³‚ꂽ�³‹K•\Œ»ƒ}ƒbƒ` 2
1971 DEFINE_INSN
1972 opt_regexpmatch2
1974 (VALUE obj2, VALUE obj1)
1975 (VALUE val)
1977 if (TYPE(obj2) == T_STRING) {
1978 val = rb_reg_match(obj1, obj2);
1980 else {
1981 val = rb_funcall(obj2, idEqTilde, 1, obj1);
1986 @c optimize
1987 @e call native compiled method
1988 @j ƒlƒCƒeƒBƒuƒRƒ“ƒpƒCƒ‹‚µ‚½ƒ�ƒ\ƒbƒh‚ð‹N“®�B
1990 DEFINE_INSN
1991 opt_call_c_function
1992 (rb_insn_func_t funcptr)
1996 reg_cfp = (funcptr)(th, reg_cfp);
1998 if (reg_cfp == 0) {
1999 VALUE err = th->errinfo;
2000 th->errinfo = Qnil;
2001 THROW_EXCEPTION(err);
2004 RESTORE_REGS();
2005 NEXT_INSN();
2009 @c joke
2010 @e BLT
2011 @j BLT
2013 DEFINE_INSN
2014 bitblt
2017 (VALUE ret)
2019 ret = rb_str_new2("a bit of bacon, lettuce and tomato");
2023 @c joke
2024 @e The Answer to Life, the Universe, and Everything
2025 @j �l�¶�A‰F’ˆ�A‚·‚ׂĂ̓š‚¦�B
2027 DEFINE_INSN
2028 answer
2031 (VALUE ret)
2033 ret = INT2FIX(42);