2007-07-01 22:59:37 -04:00
/ * * ## skip - * - mode : c ; style : ruby - * -
2007-01-16 03:52:22 -05:00
insns . def - YARV instruction definitions
$Author : $
$Date : $
created at : 04 / 01 / 01 01 : 17 : 55 JST
Copyright ( C ) 2004 - 2006 Koichi Sasada
* /
/ * * ## skip
instruction comment
@ c : category
@ e : english description
@ j : japanese description
instruction form :
DEFINE_INSN
instrunction_name
( instruction_operands , .. )
( pop_values , .. )
( return value )
{
.. / / insn body
}
* /
/ * *
@ c nop
@ e nop
@ j nop
* /
DEFINE_INSN
nop
( )
( )
( )
{
/* none */
}
/**********************************************************/
/* deal with variables */
/**********************************************************/
/ * *
@ c variable
@ e get local variable ( which is pointed by idx ) .
@ j idx <EFBFBD> Ŏ w <EFBFBD> 肳 <EFBFBD> ꂽ <EFBFBD> <EFBFBD> <EFBFBD> [ <EFBFBD> J <EFBFBD> <EFBFBD> <EFBFBD> ϐ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> X <EFBFBD> ^ <EFBFBD> b <EFBFBD> N <EFBFBD> ɒ u <EFBFBD> <EFBFBD> <EFBFBD> B
* /
DEFINE_INSN
getlocal
( lindex_t idx )
( )
( VALUE val )
{
val = * ( GET_LFP ( ) - idx ) ;
}
/ * *
@ c variable
@ e get local variable ( which is pointed by idx ) as val .
@ j idx <EFBFBD> Ŏ w <EFBFBD> 肳 <EFBFBD> ꂽ <EFBFBD> <EFBFBD> <EFBFBD> [ <EFBFBD> J <EFBFBD> <EFBFBD> <EFBFBD> ϐ <EFBFBD> <EFBFBD> <EFBFBD> val <EFBFBD> ɂ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> B
* /
DEFINE_INSN
setlocal
( lindex_t idx )
( VALUE val )
( )
{
( * ( GET_LFP ( ) - idx ) ) = val ;
}
/ * *
@ c variable
@ e get special local variable ( $ ~ , $_ , .. )
@ j <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ȃ <EFBFBD> <EFBFBD> [ <EFBFBD> J <EFBFBD> <EFBFBD> <EFBFBD> ϐ <EFBFBD> <EFBFBD> ̒ l <EFBFBD> <EFBFBD>
* /
DEFINE_INSN
getspecial
2007-05-03 05:09:14 -04:00
( rb_num_t idx , rb_num_t type )
2007-01-16 03:52:22 -05:00
( )
( VALUE val )
{
if ( type == 0 ) {
VALUE * pv = lfp_svar ( GET_LFP ( ) , idx ) ;
val = * pv ;
}
else {
VALUE backref = * lfp_svar ( GET_LFP ( ) , 1 ) ;
if ( type & 0x01 ) {
switch ( type >> 1 ) {
2007-07-01 22:59:37 -04:00
case '&' :
2007-01-16 03:52:22 -05:00
val = rb_reg_last_match ( backref ) ;
break ;
2007-07-01 22:59:37 -04:00
case '`' :
2007-01-16 03:52:22 -05:00
val = rb_reg_match_pre ( backref ) ;
break ;
2007-07-01 22:59:37 -04:00
case '\'' :
2007-01-16 03:52:22 -05:00
val = rb_reg_match_post ( backref ) ;
break ;
2007-07-01 22:59:37 -04:00
case '+' :
2007-01-16 03:52:22 -05:00
val = rb_reg_match_last ( backref ) ;
break ;
2007-07-01 22:59:37 -04:00
default :
2007-01-16 03:52:22 -05:00
rb_bug ( "unexpected back-ref" ) ;
}
}
else {
val = rb_reg_nth_match ( type >> 1 , backref ) ;
}
}
}
/ * *
@ c variable
@ e set special local variables
@ j <EFBFBD> <EFBFBD> <EFBFBD> ʂ ȃ <EFBFBD> <EFBFBD> [ <EFBFBD> J <EFBFBD> <EFBFBD> <EFBFBD> ϐ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ݒ 肷 <EFBFBD> <EFBFBD>
* /
DEFINE_INSN
setspecial
2007-05-03 05:09:14 -04:00
( rb_num_t idx )
2007-01-16 03:52:22 -05:00
( VALUE obj )
( )
{
VALUE * pv = lfp_svar ( GET_LFP ( ) , idx ) ;
* pv = obj ;
}
/ * *
@ c variable
@ e get block local variable ( which is pointed by idx and level ) .
level means nest level of block , and specify how above this variable .
@ j level , idx <EFBFBD> Ŏ w <EFBFBD> 肳 <EFBFBD> ꂽ <EFBFBD> u <EFBFBD> <EFBFBD> <EFBFBD> b <EFBFBD> N <EFBFBD> <EFBFBD> <EFBFBD> [ <EFBFBD> J <EFBFBD> <EFBFBD> <EFBFBD> ϐ <EFBFBD> <EFBFBD> ̒ l <EFBFBD> <EFBFBD> <EFBFBD> X <EFBFBD> ^ <EFBFBD> b <EFBFBD> N <EFBFBD> ɒ u <EFBFBD> <EFBFBD> <EFBFBD> B
level <EFBFBD> ̓ u <EFBFBD> <EFBFBD> <EFBFBD> b <EFBFBD> N <EFBFBD> ̃ l <EFBFBD> X <EFBFBD> g <EFBFBD> <EFBFBD> <EFBFBD> x <EFBFBD> <EFBFBD> <EFBFBD> Ł A <EFBFBD> <EFBFBD> <EFBFBD> i <EFBFBD> ォ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> B
* /
DEFINE_INSN
getdynamic
2007-05-03 05:09:14 -04:00
( dindex_t idx , rb_num_t level )
2007-01-16 03:52:22 -05:00
( )
( VALUE val )
{
int i ;
VALUE * dfp2 = GET_DFP ( ) ;
for ( i = 0 ; i < level ; i ++ ) {
dfp2 = GET_PREV_DFP ( dfp2 ) ;
}
val = * ( dfp2 - idx ) ;
}
/ * *
@ c variable
@ e set block local variable ( which is pointed by 'idx' ) as val .
level means nest level of block , and specify how above this variable .
@ j level , idx <EFBFBD> Ŏ w <EFBFBD> 肳 <EFBFBD> ꂽ <EFBFBD> u <EFBFBD> <EFBFBD> <EFBFBD> b <EFBFBD> N <EFBFBD> <EFBFBD> <EFBFBD> [ <EFBFBD> J <EFBFBD> <EFBFBD> <EFBFBD> ϐ <EFBFBD> <EFBFBD> ̒ l <EFBFBD> <EFBFBD> val <EFBFBD> ɂ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> B
level <EFBFBD> ̓ u <EFBFBD> <EFBFBD> <EFBFBD> b <EFBFBD> N <EFBFBD> ̃ l <EFBFBD> X <EFBFBD> g <EFBFBD> <EFBFBD> <EFBFBD> x <EFBFBD> <EFBFBD> <EFBFBD> Ł A <EFBFBD> <EFBFBD> <EFBFBD> i <EFBFBD> ォ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> B
* /
DEFINE_INSN
setdynamic
2007-05-03 05:09:14 -04:00
( dindex_t idx , rb_num_t level )
2007-01-16 03:52:22 -05:00
( VALUE val )
( )
{
int i ;
VALUE * dfp2 = GET_DFP ( ) ;
for ( i = 0 ; i < level ; i ++ ) {
dfp2 = GET_PREV_DFP ( dfp2 ) ;
}
* ( dfp2 - idx ) = val ;
}
/ * *
@ c variable
@ e get instance variable id of obj .
2007-02-06 00:22:17 -05:00
if is_local is not 0 , search as class local variable .
2007-01-16 03:52:22 -05:00
@ j obj <EFBFBD> ̃ C <EFBFBD> <EFBFBD> <EFBFBD> X <EFBFBD> ^ <EFBFBD> <EFBFBD> <EFBFBD> X <EFBFBD> ϐ <EFBFBD> id <EFBFBD> <EFBFBD> <EFBFBD> B
2007-02-06 00:22:17 -05:00
<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> is_local <EFBFBD> <EFBFBD> ! 0 <EFBFBD> Ȃ <EFBFBD> <EFBFBD> N <EFBFBD> <EFBFBD> <EFBFBD> X <EFBFBD> <EFBFBD> <EFBFBD> [ <EFBFBD> J <EFBFBD> <EFBFBD> <EFBFBD> ϐ <EFBFBD> <EFBFBD> <EFBFBD>
2007-01-16 03:52:22 -05:00
* /
DEFINE_INSN
getinstancevariable
* parse.y, compile.c, gc.c, insns.def, intern.h, iseq.c, node.h,
object.c, string.c, variable.c, vm_macro.def: revert private
instance variable feature, which is postponed until next major
release.
* marshal.c: TYPE_SYMBOL2 removed; MARSHAL_MINOR reverted back to
8th version.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11813 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-02-22 21:49:41 -05:00
( ID id )
2007-01-16 03:52:22 -05:00
( )
( VALUE val )
{
2007-02-04 14:17:33 -05:00
val = rb_ivar_get ( GET_SELF ( ) , id ) ;
}
2007-01-16 03:52:22 -05:00
/ * *
@ c variable
@ e set instance variable id of obj as val .
2007-02-06 00:22:17 -05:00
if is_local is not 0 , search as class local variable .
2007-01-16 03:52:22 -05:00
@ j obj <EFBFBD> ̃ C <EFBFBD> <EFBFBD> <EFBFBD> X <EFBFBD> ^ <EFBFBD> <EFBFBD> <EFBFBD> X <EFBFBD> ϐ <EFBFBD> <EFBFBD> <EFBFBD> val <EFBFBD> ɂ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> B
2007-02-06 00:22:17 -05:00
<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> is_local <EFBFBD> <EFBFBD> ! 0 <EFBFBD> Ȃ <EFBFBD> <EFBFBD> N <EFBFBD> <EFBFBD> <EFBFBD> X <EFBFBD> <EFBFBD> <EFBFBD> [ <EFBFBD> J <EFBFBD> <EFBFBD> <EFBFBD> ϐ <EFBFBD> <EFBFBD> <EFBFBD>
2007-01-16 03:52:22 -05:00
* /
DEFINE_INSN
setinstancevariable
* parse.y, compile.c, gc.c, insns.def, intern.h, iseq.c, node.h,
object.c, string.c, variable.c, vm_macro.def: revert private
instance variable feature, which is postponed until next major
release.
* marshal.c: TYPE_SYMBOL2 removed; MARSHAL_MINOR reverted back to
8th version.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11813 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-02-22 21:49:41 -05:00
( ID id )
2007-01-16 03:52:22 -05:00
( VALUE val )
( )
{
2007-02-04 14:17:33 -05:00
rb_ivar_set ( GET_SELF ( ) , id , val ) ;
}
2007-01-16 03:52:22 -05:00
/ * *
@ c variable
@ e get class variable id of klass as val .
@ j klass <EFBFBD> ̃ N <EFBFBD> <EFBFBD> <EFBFBD> X <EFBFBD> ϐ <EFBFBD> id <EFBFBD> <EFBFBD> <EFBFBD> B
* /
DEFINE_INSN
getclassvariable
( ID id )
( )
( VALUE val )
{
* vm.c: some refactoring.
* rename th_* to vm_*.
* remove unused variables functions.
* add prototypes.
* blockinlining.c, compile.c, cont.c, eval.c, eval_intern.h,
eval_jump.h, eval_load.c, inits.c, insns.def, iseq.c, parse.y,
proc.c, process.c, signal.c, thread.c, vm.c, vm_dump.c,
vm_evalbody.ci, yarvcore.c, yarvcore.h: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12603 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-24 11:42:41 -04:00
VALUE klass = vm_get_cvar_base ( th , GET_ISEQ ( ) ) ;
2007-01-16 03:52:22 -05:00
val = rb_cvar_get ( klass , id ) ;
}
/ * *
@ c variable
@ e set class variable id of klass as val .
@ j klass <EFBFBD> ̃ N <EFBFBD> <EFBFBD> <EFBFBD> X <EFBFBD> ϐ <EFBFBD> id <EFBFBD> <EFBFBD> val <EFBFBD> ɂ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> B
* /
DEFINE_INSN
setclassvariable
2007-02-04 14:15:38 -05:00
( ID id )
2007-01-16 03:52:22 -05:00
( VALUE val )
( )
{
* vm.c: some refactoring.
* rename th_* to vm_*.
* remove unused variables functions.
* add prototypes.
* blockinlining.c, compile.c, cont.c, eval.c, eval_intern.h,
eval_jump.h, eval_load.c, inits.c, insns.def, iseq.c, parse.y,
proc.c, process.c, signal.c, thread.c, vm.c, vm_dump.c,
vm_evalbody.ci, yarvcore.c, yarvcore.h: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12603 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-24 11:42:41 -04:00
rb_cvar_set ( vm_get_cvar_base ( th , GET_ISEQ ( ) ) , id , val ) ;
2007-01-16 03:52:22 -05:00
}
/ * *
@ c variable
@ e
get constant variable id . if klass is Qnil , constant
are searched in current scope . if klass is Qfalse , constant as
top level constant . otherwise , get constant under klass
class or module .
@ j
<EFBFBD> 萔 <EFBFBD> <EFBFBD> <EFBFBD> Bklass <EFBFBD> <EFBFBD> Qnil <EFBFBD> Ȃ <EFBFBD> <EFBFBD> A <EFBFBD> <EFBFBD> <EFBFBD> ̃ X <EFBFBD> R <EFBFBD> [ <EFBFBD> v <EFBFBD> œ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
<EFBFBD> <EFBFBD> <EFBFBD> 萔 <EFBFBD> <EFBFBD> <EFBFBD> BQfalse <EFBFBD> Ȃ <EFBFBD> <EFBFBD> A <EFBFBD> g <EFBFBD> b <EFBFBD> v <EFBFBD> <EFBFBD> <EFBFBD> x <EFBFBD> <EFBFBD> <EFBFBD> X <EFBFBD> R <EFBFBD> [ <EFBFBD> v <EFBFBD> <EFBFBD> <EFBFBD> B
<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ȋ O <EFBFBD> Ȃ <EFBFBD> <EFBFBD> Aklass <EFBFBD> N <EFBFBD> <EFBFBD> <EFBFBD> X <EFBFBD> ̉ <EFBFBD> <EFBFBD> ̒ 萔 <EFBFBD> <EFBFBD> <EFBFBD> B
* /
DEFINE_INSN
getconstant
( ID id )
( VALUE klass )
( VALUE val )
{
* vm.c: some refactoring.
* rename th_* to vm_*.
* remove unused variables functions.
* add prototypes.
* blockinlining.c, compile.c, cont.c, eval.c, eval_intern.h,
eval_jump.h, eval_load.c, inits.c, insns.def, iseq.c, parse.y,
proc.c, process.c, signal.c, thread.c, vm.c, vm_dump.c,
vm_evalbody.ci, yarvcore.c, yarvcore.h: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12603 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-24 11:42:41 -04:00
val = vm_get_ev_const ( th , GET_ISEQ ( ) , klass , id , 0 ) ;
2007-01-16 03:52:22 -05:00
}
/ * *
@ c variable
@ e
set constant variable id . if klass is Qfalse , constant
is able to access in this scope . if klass is Qnil , set
top level constant . otherwise , set constant under klass
class or module .
@ j
<EFBFBD> 萔 id <EFBFBD> <EFBFBD> val <EFBFBD> ɂ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Bklass <EFBFBD> <EFBFBD> Qfalse <EFBFBD> Ȃ <EFBFBD> <EFBFBD> A <EFBFBD> <EFBFBD> <EFBFBD> ̃ X <EFBFBD> R <EFBFBD> [ <EFBFBD> v
<EFBFBD> œ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 萔 <EFBFBD> <EFBFBD> <EFBFBD> ݒ <EFBFBD> id <EFBFBD> <EFBFBD> <EFBFBD> ݒ 肷 <EFBFBD> <EFBFBD> <EFBFBD> BQnil <EFBFBD> Ȃ <EFBFBD> <EFBFBD> A <EFBFBD> g <EFBFBD> b <EFBFBD> v <EFBFBD> <EFBFBD> <EFBFBD> x
<EFBFBD> <EFBFBD> <EFBFBD> X <EFBFBD> R <EFBFBD> [ <EFBFBD> v <EFBFBD> <EFBFBD> <EFBFBD> ݒ <EFBFBD> <EFBFBD> A <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ȋ O <EFBFBD> Ȃ <EFBFBD> <EFBFBD> Aklass <EFBFBD> N <EFBFBD> <EFBFBD> <EFBFBD> X <EFBFBD> ̉ <EFBFBD> <EFBFBD> ̒ 萔 <EFBFBD> <EFBFBD>
<EFBFBD> ݒ 肷 <EFBFBD> <EFBFBD> <EFBFBD> B
* /
DEFINE_INSN
setconstant
( ID id )
( VALUE val , VALUE klass )
( )
{
if ( klass == Qnil ) {
* vm.c: some refactoring.
* rename th_* to vm_*.
* remove unused variables functions.
* add prototypes.
* blockinlining.c, compile.c, cont.c, eval.c, eval_intern.h,
eval_jump.h, eval_load.c, inits.c, insns.def, iseq.c, parse.y,
proc.c, process.c, signal.c, thread.c, vm.c, vm_dump.c,
vm_evalbody.ci, yarvcore.c, yarvcore.h: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12603 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-24 11:42:41 -04:00
klass = vm_get_cbase ( th ) ;
2007-01-16 03:52:22 -05:00
}
if ( NIL_P ( klass ) ) {
rb_raise ( rb_eTypeError , "no class/module to define constant" ) ;
}
switch ( TYPE ( klass ) ) {
2007-07-01 22:59:37 -04:00
case T_CLASS :
case T_MODULE :
2007-01-16 03:52:22 -05:00
break ;
2007-07-01 22:59:37 -04:00
default : {
2007-06-15 02:55:36 -04:00
volatile VALUE tmp = rb_obj_as_string ( klass ) ;
2007-01-16 03:52:22 -05:00
rb_raise ( rb_eTypeError , "%s is not a class/module" ,
2007-06-15 02:55:36 -04:00
RSTRING_PTR ( tmp ) ) ;
2007-07-01 22:59:37 -04:00
}
2007-01-16 03:52:22 -05:00
}
rb_const_set ( klass , id , val ) ;
INC_VM_STATE_VERSION ( ) ;
}
/ * *
@ c variable
@ e get global variable id .
@ j <EFBFBD> O <EFBFBD> <EFBFBD> <EFBFBD> [ <EFBFBD> o <EFBFBD> <EFBFBD> <EFBFBD> ϐ <EFBFBD> id <EFBFBD> <EFBFBD> <EFBFBD> B
* /
DEFINE_INSN
getglobal
( GENTRY entry )
( )
( VALUE val )
{
val = GET_GLOBAL ( entry ) ;
}
/ * *
@ c variable
@ e set global variable id as val .
@ j <EFBFBD> O <EFBFBD> <EFBFBD> <EFBFBD> [ <EFBFBD> o <EFBFBD> <EFBFBD> <EFBFBD> ϐ <EFBFBD> id <EFBFBD> <EFBFBD> <EFBFBD> B
* /
DEFINE_INSN
setglobal
( GENTRY entry )
( VALUE val )
( )
{
SET_GLOBAL ( entry , val ) ;
}
/**********************************************************/
/* deal with values */
/**********************************************************/
/ * *
@ c put
@ e put nil
@ j put nil
* /
DEFINE_INSN
putnil
( )
( )
( VALUE val )
{
val = Qnil ;
}
/ * *
@ c put
@ e put self .
@ j self <EFBFBD> <EFBFBD> <EFBFBD> u <EFBFBD> <EFBFBD> <EFBFBD> B
* /
DEFINE_INSN
putself
( )
( )
( VALUE val )
{
val = GET_SELF ( ) ;
}
/ * *
@ c put
@ e put some object .
i . e . Fixnum , true , false , nil , and so on .
@ j <EFBFBD> I <EFBFBD> u <EFBFBD> W <EFBFBD> F <EFBFBD> N <EFBFBD> g <EFBFBD> <EFBFBD> <EFBFBD> u <EFBFBD> <EFBFBD> <EFBFBD> Bi . e . Fixnum , true , false , nil , and so on .
* /
DEFINE_INSN
putobject
( VALUE val )
( )
( VALUE val )
{
/* */
}
/ * *
@ c put
@ e put string val . string will be copied .
@ j <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> u <EFBFBD> <EFBFBD> <EFBFBD> B <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ̓ R <EFBFBD> s <EFBFBD> [ <EFBFBD> <EFBFBD> <EFBFBD> Ƃ <EFBFBD> <EFBFBD> B
* /
DEFINE_INSN
putstring
2007-07-02 08:49:35 -04:00
( VALUE str )
2007-01-16 03:52:22 -05:00
( )
( VALUE val )
{
2007-07-02 08:49:35 -04:00
val = rb_str_new3 ( str ) ;
2007-01-16 03:52:22 -05:00
}
/ * *
@ c put
@ e put concatenate strings
@ j <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> A <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ē u <EFBFBD> <EFBFBD> <EFBFBD> B
* /
DEFINE_INSN
concatstrings
2007-05-03 05:09:14 -04:00
( rb_num_t num )
2007-01-16 03:52:22 -05:00
( .. . )
( VALUE val ) / / inc + = 1 - num ;
{
int i ;
VALUE v ;
val = rb_str_new ( 0 , 0 ) ;
for ( i = num - 1 ; i >= 0 ; i -- ) {
v = TOPN ( i ) ;
rb_str_append ( val , v ) ;
}
POPN ( num ) ;
}
/ * *
@ c put
@ e to_str
@ j to_str
* /
DEFINE_INSN
tostring
( )
( VALUE val )
( VALUE val )
{
val = rb_obj_as_string ( val ) ;
}
/ * *
@ c put
@ e to Regexp
@ j to Regexp
* /
DEFINE_INSN
toregexp
2007-05-03 05:09:14 -04:00
( rb_num_t flag )
2007-01-16 03:52:22 -05:00
( VALUE str )
( VALUE val )
{
* vm.c: some refactoring.
* rename th_* to vm_*.
* remove unused variables functions.
* add prototypes.
* blockinlining.c, compile.c, cont.c, eval.c, eval_intern.h,
eval_jump.h, eval_load.c, inits.c, insns.def, iseq.c, parse.y,
proc.c, process.c, signal.c, thread.c, vm.c, vm_dump.c,
vm_evalbody.ci, yarvcore.c, yarvcore.h: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12603 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-24 11:42:41 -04:00
volatile VALUE tmp = str ; /* for GC */
2007-01-16 03:52:22 -05:00
val = rb_reg_new ( RSTRING_PTR ( str ) , RSTRING_LEN ( str ) , flag ) ;
}
/ * *
@ c put
@ e put new array .
@ j <EFBFBD> V <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> z <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> X <EFBFBD> ^ <EFBFBD> b <EFBFBD> N <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> num <EFBFBD> ̒ l <EFBFBD> ŏ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ē u <EFBFBD> <EFBFBD> <EFBFBD> B
* /
DEFINE_INSN
newarray
2007-05-03 05:09:14 -04:00
( rb_num_t num )
2007-01-16 03:52:22 -05:00
( .. . )
( VALUE val ) / / inc + = 1 - num ;
{
val = rb_ary_new4 ( ( long ) num , STACK_ADDR_FROM_TOP ( num ) ) ;
POPN ( num ) ;
}
/ * *
@ c put
@ e dup array
@ j <EFBFBD> z <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> dup <EFBFBD> <EFBFBD> <EFBFBD> ă X <EFBFBD> ^ <EFBFBD> b <EFBFBD> N <EFBFBD> ɒ u <EFBFBD> <EFBFBD>
* /
DEFINE_INSN
duparray
( VALUE ary )
( )
( VALUE val )
{
val = rb_ary_dup ( ary ) ;
}
/ * *
@ c put
@ e expand array to num objects .
@ j <EFBFBD> X <EFBFBD> ^ <EFBFBD> b <EFBFBD> N <EFBFBD> g <EFBFBD> b <EFBFBD> v <EFBFBD> ̃ I <EFBFBD> u <EFBFBD> W <EFBFBD> F <EFBFBD> N <EFBFBD> g <EFBFBD> <EFBFBD> <EFBFBD> z <EFBFBD> <EFBFBD> <EFBFBD> ł <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> A <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> W <EFBFBD> J <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> B
<EFBFBD> z <EFBFBD> <EFBFBD> <EFBFBD> I <EFBFBD> u <EFBFBD> W <EFBFBD> F <EFBFBD> N <EFBFBD> g <EFBFBD> ̗ v <EFBFBD> f <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> num <EFBFBD> ȉ <EFBFBD> <EFBFBD> Ȃ <EFBFBD> <EFBFBD> A <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> nil <EFBFBD> <EFBFBD> <EFBFBD> ς ށ Bnum <EFBFBD> ȏ <EFBFBD> <EFBFBD> Ȃ <EFBFBD> <EFBFBD> A
num <EFBFBD> ȏ <EFBFBD> <EFBFBD> ̗ v <EFBFBD> f <EFBFBD> ͐ <EFBFBD> <EFBFBD> ̂ Ă <EFBFBD> <EFBFBD> B
<EFBFBD> z <EFBFBD> <EFBFBD> <EFBFBD> I <EFBFBD> u <EFBFBD> W <EFBFBD> F <EFBFBD> N <EFBFBD> g <EFBFBD> ł Ȃ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Anum - 1 <EFBFBD> <EFBFBD> nil <EFBFBD> <EFBFBD> <EFBFBD> ς ށ B
<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> flag <EFBFBD> <EFBFBD> <EFBFBD> ^ <EFBFBD> Ȃ <EFBFBD> <EFBFBD> A <EFBFBD> c <EFBFBD> <EFBFBD> <EFBFBD> v <EFBFBD> f <EFBFBD> ̔ z <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ς <EFBFBD>
* /
DEFINE_INSN
expandarray
2007-05-03 05:09:14 -04:00
( rb_num_t num , rb_num_t flag )
2007-01-16 03:52:22 -05:00
( .. . , VALUE ary )
2007-06-26 14:56:15 -04:00
( .. . ) / / inc + = flag == 2 ? num : ( ( num > 0 ) ? num - 1 + ( flag ? 1 : 0 ) : num + 1 - ( flag ? 1 : 0 ) ) ;
2007-01-16 03:52:22 -05:00
{
int i ;
2007-06-26 14:56:15 -04:00
if ( flag == 2 ) {
VALUE * ptr = RARRAY_PTR ( ary ) ;
int len = RARRAY_LEN ( ary ) ;
int start = len - num ;
if ( start < 0 ) {
for ( i = 0 ; i < num - len ; i ++ ) {
PUSH ( Qnil ) ;
2007-01-16 03:52:22 -05:00
}
2007-06-26 14:56:15 -04:00
for ( i = 0 ; i < len ; i ++ ) {
PUSH ( ptr [ len - i - 1 ] ) ;
2007-01-16 03:52:22 -05:00
}
2007-06-26 14:56:15 -04:00
rb_ary_clear ( ary ) ;
}
else {
for ( i = 0 ; i < num ; i ++ ) {
PUSH ( ptr [ len - i - 1 ] ) ;
}
RARRAY_LEN ( ary ) = len - num ;
2007-01-16 03:52:22 -05:00
}
}
else {
2007-06-26 14:56:15 -04:00
if ( ( long ) num >= 0 ) {
int len ;
if ( TYPE ( ary ) ! = T_ARRAY ) {
ary = rb_ary_to_ary ( ary ) ;
}
len = RARRAY_LEN ( ary ) ;
for ( i = 0 ; i < len & & i < num ; i ++ ) {
PUSH ( RARRAY_PTR ( ary ) [ i ] ) ;
}
for ( ; i < num ; i ++ ) {
PUSH ( Qnil ) ;
}
if ( flag ) {
if ( len > num ) {
PUSH ( rb_ary_new4 ( len - num , & RARRAY_PTR ( ary ) [ num ] ) ) ;
}
else {
PUSH ( rb_ary_new ( ) ) ;
}
}
2007-01-16 03:52:22 -05:00
}
else {
2007-06-26 14:56:15 -04:00
long holdnum = - num ;
VALUE val ;
val = rb_ary_new4 ( holdnum , STACK_ADDR_FROM_TOP ( holdnum ) ) ;
if ( CLASS_OF ( ary ) == rb_cArray ) {
val = rb_ary_concat ( val , ary ) ;
}
else {
rb_ary_push ( val , ary ) ;
}
POPN ( holdnum ) ;
PUSH ( val ) ;
2007-01-16 03:52:22 -05:00
}
}
}
/ * *
@ c put
@ e concat two arrays
@ j <EFBFBD> <EFBFBD> <EFBFBD> ̔ z <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƃ <EFBFBD> <EFBFBD> Ă <EFBFBD> <EFBFBD> Ă <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* /
DEFINE_INSN
concatarray
( )
( VALUE ary1 , VALUE ary2st )
( VALUE ary )
{
VALUE ary2 = ary2st ;
if ( ary2 == Qnil ) {
ary = ary1 ;
}
else {
VALUE tmp1 = rb_check_convert_type ( ary1 , T_ARRAY , "Array" , "to_splat" ) ;
VALUE tmp2 = rb_check_convert_type ( ary2 , T_ARRAY , "Array" , "to_splat" ) ;
if ( NIL_P ( tmp1 ) ) {
tmp1 = rb_ary_new3 ( 1 , ary1 ) ;
}
if ( NIL_P ( tmp2 ) ) {
tmp2 = rb_ary_new3 ( 1 , ary2 ) ;
}
if ( tmp1 == ary1 ) {
tmp1 = rb_ary_dup ( ary1 ) ;
}
ary = rb_ary_concat ( tmp1 , tmp2 ) ;
}
}
/ * *
@ c put
@ e splat array
@ j splat array
* /
DEFINE_INSN
splatarray
( VALUE flag )
( VALUE ary )
( VALUE obj )
{
VALUE tmp = rb_check_convert_type ( ary , T_ARRAY , "Array" , "to_splat" ) ;
if ( NIL_P ( tmp ) ) {
tmp = rb_ary_new3 ( 1 , ary ) ;
}
obj = tmp ;
}
/ * *
@ c put
@ e check value is included in ary
@ j <EFBFBD> z <EFBFBD> <EFBFBD> <EFBFBD> ɗ v <EFBFBD> f <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ă <EFBFBD> <EFBFBD> 邩 <EFBFBD> ǂ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ` <EFBFBD> F <EFBFBD> b <EFBFBD> N <EFBFBD> Bcase / when <EFBFBD> Ŏ g <EFBFBD> <EFBFBD>
* /
DEFINE_INSN
checkincludearray
( VALUE flag )
( VALUE obj , VALUE ary )
( VALUE obj , VALUE result )
{
int i ;
result = Qfalse ;
if ( TYPE ( ary ) ! = T_ARRAY ) {
ary = rb_Array ( ary ) ;
}
if ( flag == Qtrue ) {
/* NODE_CASE */
for ( i = 0 ; i < RARRAY_LEN ( ary ) ; i ++ ) {
* call_cfunc.ci, compile.c, compile.h, debug.h, eval.c,
eval_error.h, eval_jump.h, eval_load.c, eval_thread.c, gc.c,
insnhelper.h, insns.def, iseq.c, main.c, numeric.c, parse.y,
range.c, regenc.h, ruby.h, signal.c, thread.c, thread_win32.ci,
vm.c, vm.h, vm_dump.c, vm_evalbody.ci, yarvcore.c, yarvcore.h:
fixed indents and non-C90 comments.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11620 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-02-02 11:26:04 -05:00
/* TODO: fix me (use another method dispatch) */
2007-01-16 03:52:22 -05:00
if ( RTEST ( rb_funcall2 ( RARRAY_PTR ( ary ) [ i ] , idEqq , 1 , & obj ) ) ) {
result = Qtrue ;
break ;
}
}
}
else {
obj = Qfalse ;
/* NODE_WHEN */
for ( i = 0 ; i < RARRAY_LEN ( ary ) ; i ++ ) {
if ( RTEST ( RARRAY_PTR ( ary ) [ i ] ) ) {
obj = result = Qtrue ;
break ;
}
}
}
}
/ * *
@ c put
@ e put new Hash .
@ j Hash . new
* /
DEFINE_INSN
newhash
2007-05-03 05:09:14 -04:00
( rb_num_t num )
2007-01-16 03:52:22 -05:00
( .. . )
( VALUE val ) / / inc + = 1 - num ;
{
int i ;
VALUE k , v ;
val = rb_hash_new ( ) ;
for ( i = num ; i > 0 ; i - = 2 ) {
v = TOPN ( i - 2 ) ;
k = TOPN ( i - 1 ) ;
rb_hash_aset ( val , k , v ) ;
}
POPN ( num ) ;
}
/ * *
@ c put
@ e put new Range object . ( Range . new ( low , high , flag ) )
@ j Range . new ( low , high , flag ) <EFBFBD> ̂ 悤 <EFBFBD> ȃ I <EFBFBD> u <EFBFBD> W <EFBFBD> F <EFBFBD> N <EFBFBD> g <EFBFBD> <EFBFBD> <EFBFBD> u <EFBFBD> <EFBFBD> <EFBFBD> B
* /
DEFINE_INSN
newrange
2007-05-03 05:09:14 -04:00
( rb_num_t flag )
2007-01-16 03:52:22 -05:00
( VALUE low , VALUE high )
( VALUE val )
{
val = rb_range_new ( low , high , flag ) ;
}
/ * *
@ c put
@ e put ! val .
@ j ! val <EFBFBD> ł <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> I <EFBFBD> u <EFBFBD> W <EFBFBD> F <EFBFBD> N <EFBFBD> g <EFBFBD> <EFBFBD> <EFBFBD> u <EFBFBD> <EFBFBD> <EFBFBD> B
* /
DEFINE_INSN
putnot
( )
( VALUE obj )
( VALUE val )
{
if ( RTEST ( obj ) ) {
val = Qfalse ;
}
else {
val = Qtrue ;
}
}
/**********************************************************/
/* deal with stack operation */
/**********************************************************/
/ * *
@ c stack
@ e pop from stack .
@ j <EFBFBD> X <EFBFBD> ^ <EFBFBD> b <EFBFBD> N <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> | <EFBFBD> b <EFBFBD> v <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> B
* /
DEFINE_INSN
pop
( )
( VALUE val )
( )
{
val = val ;
/* none */
}
/ * *
@ c stack
@ e duplicate stack top .
@ j <EFBFBD> X <EFBFBD> ^ <EFBFBD> b <EFBFBD> N <EFBFBD> g <EFBFBD> b <EFBFBD> v <EFBFBD> <EFBFBD> <EFBFBD> R <EFBFBD> s <EFBFBD> [ <EFBFBD> <EFBFBD> <EFBFBD> ă X <EFBFBD> ^ <EFBFBD> b <EFBFBD> N <EFBFBD> ɂ <EFBFBD> <EFBFBD> <EFBFBD>
* /
DEFINE_INSN
dup
( )
( VALUE val )
( VALUE val1 , VALUE val2 )
{
val1 = val2 = val ;
}
/ * *
@ c stack
@ e duplicate stack top n elements
@ j <EFBFBD> X <EFBFBD> ^ <EFBFBD> b <EFBFBD> N <EFBFBD> g <EFBFBD> b <EFBFBD> v <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> n <EFBFBD> <EFBFBD> <EFBFBD> R <EFBFBD> s <EFBFBD> [ <EFBFBD> <EFBFBD> <EFBFBD> ă X <EFBFBD> ^ <EFBFBD> b <EFBFBD> N <EFBFBD> ɂ <EFBFBD> <EFBFBD> <EFBFBD>
* /
DEFINE_INSN
dupn
2007-05-03 05:09:14 -04:00
( rb_num_t n )
2007-01-16 03:52:22 -05:00
( .. . )
( .. . ) / / inc + = n ;
{
int i ;
VALUE * sp = STACK_ADDR_FROM_TOP ( n ) ;
for ( i = 0 ; i < n ; i ++ ) {
GET_SP ( ) [ i ] = sp [ i ] ;
}
INC_SP ( n ) ;
}
/ * *
@ c stack
@ e swap top 2 vals
@ j <EFBFBD> X <EFBFBD> ^ <EFBFBD> b <EFBFBD> N <EFBFBD> g <EFBFBD> b <EFBFBD> v <EFBFBD> <EFBFBD> 2 <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> B
* /
DEFINE_INSN
swap
( )
( VALUE val , VALUE obj )
( VALUE obj , VALUE val )
{
/* none */
}
/ * *
@ c stack
@ e
@ j
* /
DEFINE_INSN
reput
( )
( .. . , VALUE val )
( VALUE val ) / / inc + = 0 ;
{
/* none */
}
/ * *
@ c stack
@ e get nth stack value from stack top
@ j <EFBFBD> X <EFBFBD> ^ <EFBFBD> b <EFBFBD> N <EFBFBD> g <EFBFBD> b <EFBFBD> v <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> n <EFBFBD> ڂ <EFBFBD> <EFBFBD> X <EFBFBD> ^ <EFBFBD> b <EFBFBD> N <EFBFBD> g <EFBFBD> b <EFBFBD> v <EFBFBD> Ƀ R <EFBFBD> s <EFBFBD> [
* /
DEFINE_INSN
topn
2007-05-03 05:09:14 -04:00
( rb_num_t n )
2007-01-16 03:52:22 -05:00
( .. . )
( VALUE val ) / / inc + = 1 ;
{
val = TOPN ( n ) ;
}
/ * *
@ c stack
@ e set Nth stack entry to stack top
@ j <EFBFBD> X <EFBFBD> ^ <EFBFBD> b <EFBFBD> N <EFBFBD> g <EFBFBD> b <EFBFBD> v <EFBFBD> ̒ l <EFBFBD> <EFBFBD> n <EFBFBD> ڂ ̃ X <EFBFBD> ^ <EFBFBD> b <EFBFBD> N <EFBFBD> Ƀ R <EFBFBD> s <EFBFBD> [
* /
DEFINE_INSN
setn
2007-05-03 05:09:14 -04:00
( rb_num_t n )
2007-01-16 03:52:22 -05:00
( .. . , VALUE val )
( VALUE val ) / / inc + = 0
{
2007-06-01 00:05:46 -04:00
TOPN ( n - 1 ) = val ;
2007-01-16 03:52:22 -05:00
}
/ * *
@ c stack
@ e empt current stack
@ j current stack <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ɂ <EFBFBD> <EFBFBD> <EFBFBD>
* /
DEFINE_INSN
emptstack
( )
( .. . )
( .. . ) / / inc = 0 ; depth = 0 ;
{
SET_SP ( GET_CFP ( ) -> bp ) ;
}
/**********************************************************/
/* deal with setting */
/**********************************************************/
/ * *
@ c setting
@ e define ( singleton ) method id as body
@ j <EFBFBD> i <EFBFBD> <EFBFBD> <EFBFBD> ف j <EFBFBD> <EFBFBD> <EFBFBD> \ <EFBFBD> b <EFBFBD> h m <EFBFBD> <EFBFBD> body <EFBFBD> Ƃ <EFBFBD> <EFBFBD> Ē <EFBFBD> <EFBFBD> ` <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> B
* /
DEFINE_INSN
definemethod
2007-05-03 05:09:14 -04:00
( ID id , ISEQ body , rb_num_t is_singleton )
2007-01-16 03:52:22 -05:00
( VALUE obj )
( )
{
* vm.c: some refactoring.
* rename th_* to vm_*.
* remove unused variables functions.
* add prototypes.
* blockinlining.c, compile.c, cont.c, eval.c, eval_intern.h,
eval_jump.h, eval_load.c, inits.c, insns.def, iseq.c, parse.y,
proc.c, process.c, signal.c, thread.c, vm.c, vm_dump.c,
vm_evalbody.ci, yarvcore.c, yarvcore.h: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12603 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-24 11:42:41 -04:00
vm_define_method ( th , obj , id , body , is_singleton ,
get_cref ( GET_ISEQ ( ) , GET_LFP ( ) ) ) ;
2007-01-16 03:52:22 -05:00
}
/ * *
@ c setting
@ e make alias ( if v_p is Qtrue , make valias )
@ j alias <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> B <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> v_p <EFBFBD> <EFBFBD> Qtrue <EFBFBD> Ȃ <EFBFBD> <EFBFBD> Avalias ( global variable ) <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* /
DEFINE_INSN
alias
( VALUE v_p , ID id1 , ID id2 )
( )
( )
{
VALUE klass ;
if ( v_p == Qtrue ) {
rb_alias_variable ( id1 , id2 ) ;
}
else {
klass = get_cref ( GET_ISEQ ( ) , GET_LFP ( ) ) -> nd_clss ;
rb_alias ( klass , id1 , id2 ) ;
}
}
/ * *
@ c setting
@ e undef
@ j undef
* /
DEFINE_INSN
undef
( ID id )
( )
( )
{
VALUE klass = get_cref ( GET_ISEQ ( ) , GET_LFP ( ) ) -> nd_clss ;
rb_undef ( klass , id ) ;
INC_VM_STATE_VERSION ( ) ;
}
/ * *
@ c setting
@ e defined ?
@ j defined ?
* /
DEFINE_INSN
defined
2007-05-03 05:09:14 -04:00
( rb_num_t type , VALUE obj , VALUE needstr )
2007-01-16 03:52:22 -05:00
( VALUE v )
( VALUE val )
{
VALUE klass ;
char * expr_type = 0 ;
char buf [ 0x10 ] ;
val = Qnil ;
switch ( type ) {
case DEFINED_IVAR :
if ( rb_ivar_defined ( GET_SELF ( ) , SYM2ID ( obj ) ) ) {
expr_type = "instance-variable" ;
2007-02-04 14:17:33 -05:00
}
break ;
case DEFINED_IVAR2 :
klass = get_cref ( GET_ISEQ ( ) , GET_LFP ( ) ) -> nd_clss ;
2007-01-16 03:52:22 -05:00
break ;
case DEFINED_GVAR :
if ( rb_gvar_defined ( ( struct global_entry * ) ( obj & ~ 1 ) ) ) {
expr_type = "global-variable" ;
}
break ;
case DEFINED_CVAR :
klass = get_cref ( GET_ISEQ ( ) , GET_LFP ( ) ) -> nd_clss ;
if ( rb_cvar_defined ( klass , SYM2ID ( obj ) ) ) {
expr_type = "class variable" ;
}
break ;
case DEFINED_CONST :
klass = v ;
* vm.c: some refactoring.
* rename th_* to vm_*.
* remove unused variables functions.
* add prototypes.
* blockinlining.c, compile.c, cont.c, eval.c, eval_intern.h,
eval_jump.h, eval_load.c, inits.c, insns.def, iseq.c, parse.y,
proc.c, process.c, signal.c, thread.c, vm.c, vm_dump.c,
vm_evalbody.ci, yarvcore.c, yarvcore.h: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12603 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-24 11:42:41 -04:00
if ( vm_get_ev_const ( th , GET_ISEQ ( ) , klass , SYM2ID ( obj ) , 1 ) ) {
2007-01-16 03:52:22 -05:00
expr_type = "constant" ;
}
break ;
case DEFINED_FUNC :
klass = CLASS_OF ( v ) ;
if ( rb_method_boundp ( klass , SYM2ID ( obj ) , 0 ) ) {
expr_type = "method" ;
}
break ;
case DEFINED_METHOD : {
VALUE klass = CLASS_OF ( v ) ;
NODE * method = ( NODE * ) rb_method_node ( klass , SYM2ID ( obj ) ) ;
if ( method ) {
if ( ! ( method -> nd_noex & NOEX_PRIVATE ) ) {
if ( ! ( ( method -> nd_noex & NOEX_PROTECTED ) & &
! rb_obj_is_kind_of ( GET_SELF ( ) ,
rb_class_real ( klass ) ) ) ) {
expr_type = "method" ;
}
}
}
break ;
}
case DEFINED_YIELD :
if ( GET_BLOCK_PTR ( ) ) {
expr_type = "yield" ;
}
break ;
case DEFINED_ZSUPER : {
* blockinlining.c, compile.c, compile.h, error.c, eval.c,
eval_intern.h, eval_jump.h, eval_load.c, eval_method.h,
eval_safe.h, gc.c, insnhelper.h, insns.def, iseq.c, proc.c,
process.c, signal.c, thread.c, thread_pthread.ci, thread_win32.ci,
vm.c, vm.h, vm_dump.c, vm_evalbody.ci, vm_macro.def,
yarv.h, yarvcore.h, yarvcore.c: change type and macro names:
* yarv_*_t -> rb_*_t
* yarv_*_struct -> rb_*_struct
* yarv_tag -> rb_vm_tag
* YARV_* -> RUBY_VM_*
* proc.c, vm.c: move functions about env object creation
from proc.c to vm.c.
* proc.c, yarvcore.c: fix rb_cVM initialization place.
* inits.c: change Init_ISeq() order (after Init_VM).
* ruby.h, proc.c: change declaration place of rb_cEnv
from proc.c to ruby.c.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11651 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-02-06 14:00:03 -05:00
rb_iseq_t * ip = GET_ISEQ ( ) ;
2007-01-16 03:52:22 -05:00
while ( ip ) {
if ( ip -> defined_method_id ) {
break ;
}
ip = ip -> parent_iseq ;
}
if ( ip ) {
2007-06-24 22:44:20 -04:00
VALUE klass = vm_search_super_klass ( ip -> klass , GET_SELF ( ) ) ;
2007-01-16 03:52:22 -05:00
if ( rb_method_boundp ( klass , ip -> defined_method_id , 0 ) ) {
expr_type = "super" ;
}
}
break ;
}
case DEFINED_REF : {
int nth = FIX2INT ( obj ) ;
VALUE backref = * lfp_svar ( GET_LFP ( ) , 1 ) ;
if ( rb_reg_nth_match ( nth , backref ) ! = Qnil ) {
snprintf ( buf , 0x10 , "$%d" , nth ) ;
expr_type = buf ;
}
break ;
}
default :
rb_bug ( "unimplemented defined? type (VM)" ) ;
break ;
}
if ( expr_type ! = 0 ) {
if ( needstr ! = Qfalse ) {
val = rb_str_new2 ( expr_type ) ;
}
else {
val = Qtrue ;
}
}
}
/ * *
@ c setting
@ e END { }
@ j END { }
* /
DEFINE_INSN
postexe
( ISEQ blockiseq )
( )
( )
{
* blockinlining.c, compile.c, compile.h, error.c, eval.c,
eval_intern.h, eval_jump.h, eval_load.c, eval_method.h,
eval_safe.h, gc.c, insnhelper.h, insns.def, iseq.c, proc.c,
process.c, signal.c, thread.c, thread_pthread.ci, thread_win32.ci,
vm.c, vm.h, vm_dump.c, vm_evalbody.ci, vm_macro.def,
yarv.h, yarvcore.h, yarvcore.c: change type and macro names:
* yarv_*_t -> rb_*_t
* yarv_*_struct -> rb_*_struct
* yarv_tag -> rb_vm_tag
* YARV_* -> RUBY_VM_*
* proc.c, vm.c: move functions about env object creation
from proc.c to vm.c.
* proc.c, yarvcore.c: fix rb_cVM initialization place.
* inits.c: change Init_ISeq() order (after Init_VM).
* ruby.h, proc.c: change declaration place of rb_cEnv
from proc.c to ruby.c.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11651 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-02-06 14:00:03 -05:00
rb_block_t * blockptr ;
2007-01-16 03:52:22 -05:00
VALUE proc ;
* blockinlining.c, compile.c, compile.h, error.c, eval.c,
eval_intern.h, eval_jump.h, eval_load.c, eval_method.h,
eval_safe.h, gc.c, insnhelper.h, insns.def, iseq.c, proc.c,
process.c, signal.c, thread.c, thread_pthread.ci, thread_win32.ci,
vm.c, vm.h, vm_dump.c, vm_evalbody.ci, vm_macro.def,
yarv.h, yarvcore.h, yarvcore.c: change type and macro names:
* yarv_*_t -> rb_*_t
* yarv_*_struct -> rb_*_struct
* yarv_tag -> rb_vm_tag
* YARV_* -> RUBY_VM_*
* proc.c, vm.c: move functions about env object creation
from proc.c to vm.c.
* proc.c, yarvcore.c: fix rb_cVM initialization place.
* inits.c: change Init_ISeq() order (after Init_VM).
* ruby.h, proc.c: change declaration place of rb_cEnv
from proc.c to ruby.c.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11651 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-02-06 14:00:03 -05:00
blockptr = RUBY_VM_GET_BLOCK_PTR_IN_CFP ( GET_CFP ( ) ) ;
2007-01-16 03:52:22 -05:00
blockptr -> iseq = blockiseq ;
blockptr -> proc = 0 ;
* vm.c: some refactoring.
* rename th_* to vm_*.
* remove unused variables functions.
* add prototypes.
* blockinlining.c, compile.c, cont.c, eval.c, eval_intern.h,
eval_jump.h, eval_load.c, inits.c, insns.def, iseq.c, parse.y,
proc.c, process.c, signal.c, thread.c, vm.c, vm_dump.c,
vm_evalbody.ci, yarvcore.c, yarvcore.h: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12603 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-24 11:42:41 -04:00
proc = vm_make_proc ( th , GET_CFP ( ) , blockptr ) ;
2007-01-16 03:52:22 -05:00
rb_set_end_proc ( call_yarv_end_proc , proc ) ;
}
/ * *
@ c setting
@ e trace
@ j trace
* /
DEFINE_INSN
trace
2007-05-03 05:09:14 -04:00
( rb_num_t nf )
2007-01-16 03:52:22 -05:00
( )
( )
{
2007-04-19 06:37:08 -04:00
rb_event_flag_t flag = nf ;
EXEC_EVENT_HOOK ( th , flag , GET_SELF ( ) , 0 , 0 /* TODO: id, klass */ ) ;
2007-01-16 03:52:22 -05:00
}
/**********************************************************/
/* deal with control flow 1: class/module */
/**********************************************************/
/ * *
@ c class / module
@ e
enter class definition scope . if super is Qfalse , and clsas
"klass" is defined , it ' s redefine . otherwise , define "klass" class .
@ j
<EFBFBD> N <EFBFBD> <EFBFBD> <EFBFBD> X <EFBFBD> <EFBFBD> <EFBFBD> ` <EFBFBD> X <EFBFBD> R <EFBFBD> [ <EFBFBD> v <EFBFBD> ֈ ڍ s <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> B <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> super <EFBFBD> <EFBFBD> Qfalse <EFBFBD> <EFBFBD> klass <EFBFBD> N <EFBFBD> <EFBFBD> <EFBFBD> X <EFBFBD> <EFBFBD>
<EFBFBD> <EFBFBD> <EFBFBD> ` <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ă <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> A <EFBFBD> Ē <EFBFBD> <EFBFBD> ` <EFBFBD> ł <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> B <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ł Ȃ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Aklass <EFBFBD> N <EFBFBD> <EFBFBD> <EFBFBD> X <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ` <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> B
* /
DEFINE_INSN
defineclass
2007-05-03 05:09:14 -04:00
( ID id , ISEQ klass_iseq , rb_num_t define_type )
2007-01-16 03:52:22 -05:00
( VALUE cbase , VALUE super )
( VALUE val )
{
VALUE klass ;
2007-07-01 22:59:37 -04:00
switch ( ( int ) define_type ) {
case 0 :
2007-01-16 03:52:22 -05:00
/* val is dummy. classdef returns class scope value */
if ( super == Qnil ) {
super = rb_cObject ;
}
2007-02-25 11:29:26 -05:00
2007-01-16 03:52:22 -05:00
if ( cbase == Qnil ) {
* vm.c: some refactoring.
* rename th_* to vm_*.
* remove unused variables functions.
* add prototypes.
* blockinlining.c, compile.c, cont.c, eval.c, eval_intern.h,
eval_jump.h, eval_load.c, inits.c, insns.def, iseq.c, parse.y,
proc.c, process.c, signal.c, thread.c, vm.c, vm_dump.c,
vm_evalbody.ci, yarvcore.c, yarvcore.h: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12603 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-24 11:42:41 -04:00
cbase = vm_get_cbase ( th ) ;
2007-01-16 03:52:22 -05:00
}
/* find klass */
if ( rb_const_defined_at ( cbase , id ) ) {
/* already exist */
klass = rb_const_get_at ( cbase , id ) ;
if ( TYPE ( klass ) ! = T_CLASS ) {
rb_raise ( rb_eTypeError , "%s is not a class" , rb_id2name ( id ) ) ;
}
if ( super ! = rb_cObject ) {
VALUE tmp ;
tmp = rb_class_real ( RCLASS ( klass ) -> super ) ;
if ( tmp ! = super ) {
rb_raise ( rb_eTypeError , "superclass mismatch for class %s" ,
rb_id2name ( id ) ) ;
}
}
}
else {
/* new class declaration */
klass = rb_define_class_id ( id , super ) ;
rb_set_class_path ( klass , cbase , rb_id2name ( id ) ) ;
rb_const_set ( cbase , id , klass ) ;
rb_class_inherited ( super , klass ) ;
}
2007-07-01 22:59:37 -04:00
break ;
case 1 :
2007-01-16 03:52:22 -05:00
/* val is dummy. classdef returns class scope value */
/* super is dummy */
klass = rb_singleton_class ( cbase ) ;
2007-07-01 22:59:37 -04:00
break ;
case 2 :
2007-01-16 03:52:22 -05:00
/* val is dummy. classdef returns class scope value */
/* super is dummy */
if ( cbase == Qnil ) {
* vm.c: some refactoring.
* rename th_* to vm_*.
* remove unused variables functions.
* add prototypes.
* blockinlining.c, compile.c, cont.c, eval.c, eval_intern.h,
eval_jump.h, eval_load.c, inits.c, insns.def, iseq.c, parse.y,
proc.c, process.c, signal.c, thread.c, vm.c, vm_dump.c,
vm_evalbody.ci, yarvcore.c, yarvcore.h: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12603 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-24 11:42:41 -04:00
cbase = vm_get_cbase ( th ) ;
2007-01-16 03:52:22 -05:00
}
/* find klass */
if ( rb_const_defined_at ( cbase , id ) ) {
klass = rb_const_get_at ( cbase , id ) ;
/* already exist */
if ( TYPE ( klass ) ! = T_MODULE ) {
rb_raise ( rb_eTypeError , "%s is not a module" , rb_id2name ( id ) ) ;
}
}
else {
/* new module declaration */
klass = rb_define_module_id ( id ) ;
rb_set_class_path ( klass , cbase , rb_id2name ( id ) ) ;
rb_const_set ( cbase , id , klass ) ;
}
2007-07-01 22:59:37 -04:00
break ;
default :
rb_bug ( "unknown defineclass type: %d" , ( int ) define_type ) ;
2007-01-16 03:52:22 -05:00
}
* vm.c: some refactoring.
* rename th_* to vm_*.
* remove unused variables functions.
* add prototypes.
* blockinlining.c, compile.c, cont.c, eval.c, eval_intern.h,
eval_jump.h, eval_load.c, inits.c, insns.def, iseq.c, parse.y,
proc.c, process.c, signal.c, thread.c, vm.c, vm_dump.c,
vm_evalbody.ci, yarvcore.c, yarvcore.h: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12603 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-24 11:42:41 -04:00
COPY_CREF ( klass_iseq -> cref_stack , vm_cref_push ( th , klass , NOEX_PUBLIC ) ) ;
2007-01-16 03:52:22 -05:00
/* enter scope */
* vm.c: some refactoring.
* rename th_* to vm_*.
* remove unused variables functions.
* add prototypes.
* blockinlining.c, compile.c, cont.c, eval.c, eval_intern.h,
eval_jump.h, eval_load.c, inits.c, insns.def, iseq.c, parse.y,
proc.c, process.c, signal.c, thread.c, vm.c, vm_dump.c,
vm_evalbody.ci, yarvcore.c, yarvcore.h: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12603 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-24 11:42:41 -04:00
vm_push_frame ( th , klass_iseq ,
FRAME_MAGIC_CLASS , klass , ( VALUE ) GET_DFP ( ) | 0x02 ,
klass_iseq -> iseq_encoded , GET_SP ( ) , 0 ,
klass_iseq -> local_size ) ;
2007-01-16 03:52:22 -05:00
RESTORE_REGS ( ) ;
INC_VM_STATE_VERSION ( ) ;
NEXT_INSN ( ) ;
}
/**********************************************************/
/* deal with control flow 2: method/iterator */
/**********************************************************/
/ * *
@ c method / iterator
@ e obj . send ( id , args .. ) # args . size = > num
@ j obj . send ( id , args .. ) # args . size = > num
flag & VM_CALL_ARGS_SPLAT_BIT ! = 0 -> splat last arg
flag & VM_CALL_ARGS_BLOCKARG_BIT ! = 0 -> Proc as Block
flag & VM_CALL_FCALL_BIT ! = 0 -> FCALL ( func ( ) )
flag & VM_CALL_VCALL_BIT ! = 0 -> VCALL ( func )
* /
DEFINE_INSN
send
2007-05-03 05:09:14 -04:00
( ID op_id , rb_num_t op_argc , ISEQ blockiseq , rb_num_t op_flag , IC ic )
2007-01-16 03:52:22 -05:00
( .. . )
( VALUE val ) / / inc + = - ( op_argc + ( ( op_flag & VM_CALL_ARGS_BLOCKARG_BIT ) ? 1 : 0 ) ) ;
{
2007-06-24 09:05:51 -04:00
NODE * mn ;
* vm.c: some refactoring.
* rename th_* to vm_*.
* remove unused variables functions.
* add prototypes.
* blockinlining.c, compile.c, cont.c, eval.c, eval_intern.h,
eval_jump.h, eval_load.c, inits.c, insns.def, iseq.c, parse.y,
proc.c, process.c, signal.c, thread.c, vm.c, vm_dump.c,
vm_evalbody.ci, yarvcore.c, yarvcore.h: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12603 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-24 11:42:41 -04:00
VALUE recv , klass ;
2007-06-24 09:05:51 -04:00
rb_block_t * blockptr = 0 ;
2007-06-25 12:05:17 -04:00
rb_num_t num = caller_setup_args ( th , GET_CFP ( ) , op_flag , op_argc , blockiseq , & blockptr ) ;
2007-06-24 09:05:51 -04:00
rb_num_t flag = op_flag ;
ID id = op_id ;
/* get receiver */
if ( flag & VM_CALL_FCALL_BIT ) {
/* method(...) */
recv = GET_SELF ( ) ;
}
else {
/* recv.method(...) */
recv = TOPN ( num ) ;
}
klass = CLASS_OF ( recv ) ;
* vm.c: some refactoring.
* rename th_* to vm_*.
* remove unused variables functions.
* add prototypes.
* blockinlining.c, compile.c, cont.c, eval.c, eval_intern.h,
eval_jump.h, eval_load.c, inits.c, insns.def, iseq.c, parse.y,
proc.c, process.c, signal.c, thread.c, vm.c, vm_dump.c,
vm_evalbody.ci, yarvcore.c, yarvcore.h: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12603 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-24 11:42:41 -04:00
mn = vm_method_search ( id , klass , ic ) ;
2007-06-24 09:05:51 -04:00
/* send/funcall optimization */
if ( ( flag & VM_CALL_SEND_BIT ) & & mn & & nd_type ( mn -> nd_body ) == NODE_CFUNC ) {
NODE * node = mn -> nd_body ;
extern VALUE rb_f_funcall ( int argc , VALUE * argv , VALUE recv ) ;
extern VALUE rb_f_send ( int argc , VALUE * argv , VALUE recv ) ;
if ( node -> nd_cfnc == rb_f_funcall | | node -> nd_cfnc == rb_f_send ) {
int i ;
VALUE sym = TOPN ( num - 1 ) ;
id = SYMBOL_P ( sym ) ? SYM2ID ( sym ) : rb_to_id ( sym ) ;
/* shift arguments */
for ( i = num - 1 ; i > 0 ; i -- ) {
TOPN ( i ) = TOPN ( i - 1 ) ;
}
mn = rb_method_node ( klass , id ) ;
num - = 1 ;
DEC_SP ( 1 ) ;
}
if ( node -> nd_cfnc == rb_f_funcall ) {
flag | = VM_CALL_FCALL_BIT ;
}
}
CALL_METHOD ( num , blockptr , flag , id , mn , recv , klass ) ;
2007-01-16 03:52:22 -05:00
}
/ * *
@ c method / iterator
@ e super ( args ) # args . size = > num
@ j super ( args ) # args . size = > num
* /
DEFINE_INSN
invokesuper
2007-06-24 09:05:51 -04:00
( rb_num_t op_argc , ISEQ blockiseq , rb_num_t op_flag )
2007-01-16 03:52:22 -05:00
( .. . )
( VALUE val ) / / inc + = - op_argc ;
{
2007-06-24 09:05:51 -04:00
rb_block_t * blockptr = 0 ;
VALUE flag = op_flag ;
2007-06-25 12:05:17 -04:00
int num = caller_setup_args ( th , GET_CFP ( ) , flag , op_argc , blockiseq , & blockptr ) ;
2007-06-24 09:05:51 -04:00
rb_iseq_t * iseq = GET_ISEQ ( ) ;
rb_iseq_t * ip = iseq ;
VALUE recv , klass ;
ID id ;
NODE * mn ;
if ( ! blockptr & & ! ( flag & VM_CALL_ARGS_BLOCKARG_BIT ) ) {
blockptr = GET_BLOCK_PTR ( ) ;
2007-01-16 03:52:22 -05:00
}
2007-06-24 09:05:51 -04:00
recv = GET_SELF ( ) ;
while ( ip & & ! ip -> klass ) {
ip = ip -> parent_iseq ;
}
if ( ip == 0 ) {
rb_raise ( rb_eNoMethodError , "super called outside of method" ) ;
}
id = ip -> defined_method_id ;
if ( ip ! = ip -> local_iseq ) {
/* defined by Module#define_method() */
rb_control_frame_t * lcfp = GET_CFP ( ) ;
while ( lcfp -> iseq ! = ip ) {
VALUE * tdfp = GET_PREV_DFP ( lcfp -> dfp ) ;
while ( 1 ) {
lcfp = RUBY_VM_PREVIOUS_CONTROL_FRAME ( lcfp ) ;
if ( lcfp -> dfp == tdfp ) {
break ;
}
}
}
id = lcfp -> method_id ;
2007-06-24 22:44:20 -04:00
klass = vm_search_super_klass ( lcfp -> method_klass , recv ) ;
2007-06-24 09:05:51 -04:00
if ( TOPN ( num ) == Qfalse ) {
/* zsuper */
2007-06-24 11:46:22 -04:00
rb_raise ( rb_eRuntimeError , "implicit argument passing of super from method defined by define_method() is not supported. Specify all arguments explicitly." ) ;
2007-06-24 09:05:51 -04:00
}
}
else {
2007-06-24 22:44:20 -04:00
klass = vm_search_super_klass ( ip -> klass , recv ) ;
2007-06-24 09:05:51 -04:00
}
flag = VM_CALL_SUPER_BIT | VM_CALL_FCALL_BIT ;
mn = rb_method_node ( klass , id ) ;
CALL_METHOD ( num , blockptr , flag , id , mn , recv , klass ) ;
2007-01-16 03:52:22 -05:00
}
/ * *
@ c method / iterator
@ e yield ( args ) # args . size = > num , flag shows expand argument or not
@ j yield ( args ) # args . size = > num
* /
DEFINE_INSN
invokeblock
2007-05-03 05:09:14 -04:00
( rb_num_t num , rb_num_t flag )
2007-01-16 03:52:22 -05:00
( .. . )
( VALUE val ) / / inc + = 1 - num ;
{
* blockinlining.c, compile.c, compile.h, error.c, eval.c,
eval_intern.h, eval_jump.h, eval_load.c, eval_method.h,
eval_safe.h, gc.c, insnhelper.h, insns.def, iseq.c, proc.c,
process.c, signal.c, thread.c, thread_pthread.ci, thread_win32.ci,
vm.c, vm.h, vm_dump.c, vm_evalbody.ci, vm_macro.def,
yarv.h, yarvcore.h, yarvcore.c: change type and macro names:
* yarv_*_t -> rb_*_t
* yarv_*_struct -> rb_*_struct
* yarv_tag -> rb_vm_tag
* YARV_* -> RUBY_VM_*
* proc.c, vm.c: move functions about env object creation
from proc.c to vm.c.
* proc.c, yarvcore.c: fix rb_cVM initialization place.
* inits.c: change Init_ISeq() order (after Init_VM).
* ruby.h, proc.c: change declaration place of rb_cEnv
from proc.c to ruby.c.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11651 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-02-06 14:00:03 -05:00
rb_block_t * block = GET_BLOCK_PTR ( ) ;
rb_iseq_t * iseq ;
2007-01-16 03:52:22 -05:00
int argc = num ;
if ( GET_ISEQ ( ) -> local_iseq -> type ! = ISEQ_TYPE_METHOD | | block == 0 ) {
* vm.c: some refactoring.
* rename th_* to vm_*.
* remove unused variables functions.
* add prototypes.
* blockinlining.c, compile.c, cont.c, eval.c, eval_intern.h,
eval_jump.h, eval_load.c, inits.c, insns.def, iseq.c, parse.y,
proc.c, process.c, signal.c, thread.c, vm.c, vm_dump.c,
vm_evalbody.ci, yarvcore.c, yarvcore.h: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12603 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-24 11:42:41 -04:00
vm_localjump_error ( "no block given (yield)" , Qnil , 0 ) ;
2007-01-16 03:52:22 -05:00
}
iseq = block -> iseq ;
if ( BUILTIN_TYPE ( iseq ) ! = T_NODE ) {
2007-06-25 12:05:17 -04:00
int opt_pc ;
argc = caller_setup_args ( th , GET_CFP ( ) , flag , argc , 0 , 0 ) ;
2007-06-24 14:40:13 -04:00
2007-06-24 04:55:17 -04:00
CHECK_STACK_OVERFLOW ( GET_CFP ( ) , iseq -> stack_max ) ;
2007-01-16 03:52:22 -05:00
2007-06-05 13:39:52 -04:00
DEC_SP ( argc ) ;
2007-06-25 12:05:17 -04:00
opt_pc = vm_yield_setup_args ( th , iseq , argc , GET_SP ( ) ,
block_proc_is_lambda ( block -> proc ) ) ;
argc = iseq -> arg_size ;
2007-01-16 03:52:22 -05:00
INC_SP ( argc ) ;
* vm.c: some refactoring.
* rename th_* to vm_*.
* remove unused variables functions.
* add prototypes.
* blockinlining.c, compile.c, cont.c, eval.c, eval_intern.h,
eval_jump.h, eval_load.c, inits.c, insns.def, iseq.c, parse.y,
proc.c, process.c, signal.c, thread.c, vm.c, vm_dump.c,
vm_evalbody.ci, yarvcore.c, yarvcore.h: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12603 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-24 11:42:41 -04:00
vm_push_frame ( th , iseq ,
FRAME_MAGIC_BLOCK , block -> self , ( VALUE ) block -> dfp ,
2007-06-25 12:05:17 -04:00
iseq -> iseq_encoded + opt_pc , GET_SP ( ) , block -> lfp ,
* vm.c: some refactoring.
* rename th_* to vm_*.
* remove unused variables functions.
* add prototypes.
* blockinlining.c, compile.c, cont.c, eval.c, eval_intern.h,
eval_jump.h, eval_load.c, inits.c, insns.def, iseq.c, parse.y,
proc.c, process.c, signal.c, thread.c, vm.c, vm_dump.c,
vm_evalbody.ci, yarvcore.c, yarvcore.h: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12603 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-24 11:42:41 -04:00
iseq -> local_size - argc ) ;
2007-01-16 03:52:22 -05:00
reg_cfp -> sp - = argc ;
RESTORE_REGS ( ) ;
NEXT_INSN ( ) ;
/* unreachable */
}
else {
* vm.c: some refactoring.
* rename th_* to vm_*.
* remove unused variables functions.
* add prototypes.
* blockinlining.c, compile.c, cont.c, eval.c, eval_intern.h,
eval_jump.h, eval_load.c, inits.c, insns.def, iseq.c, parse.y,
proc.c, process.c, signal.c, thread.c, vm.c, vm_dump.c,
vm_evalbody.ci, yarvcore.c, yarvcore.h: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12603 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-24 11:42:41 -04:00
val = vm_yield_with_cfunc ( th , block , block -> self ,
2007-02-26 17:51:33 -05:00
num , STACK_ADDR_FROM_TOP ( num ) ) ;
2007-01-16 03:52:22 -05:00
POPN ( num ) ;
}
}
/ * *
@ c method / iterator
@ e return from this scope .
@ j <EFBFBD> <EFBFBD> <EFBFBD> ̃ X <EFBFBD> R <EFBFBD> [ <EFBFBD> v <EFBFBD> <EFBFBD> <EFBFBD> 甲 <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> B
* /
DEFINE_INSN
leave
( )
( VALUE val )
( VALUE val )
{
if ( OPT_CHECKED_RUN ) {
if ( reg_cfp -> sp ! = reg_cfp -> bp ) {
2007-06-27 04:21:21 -04:00
rb_bug ( "Stack consistency error (sp: %d, bp: %d)" ,
VM_SP_CNT ( th , reg_cfp -> sp ) , VM_SP_CNT ( th , reg_cfp -> bp ) ) ;
2007-01-16 03:52:22 -05:00
}
}
* blockinlining.c, compile.c, compile.h, error.c, eval.c,
eval_intern.h, eval_jump.h, eval_load.c, eval_method.h,
eval_safe.h, gc.c, insnhelper.h, insns.def, iseq.c, proc.c,
process.c, signal.c, thread.c, thread_pthread.ci, thread_win32.ci,
vm.c, vm.h, vm_dump.c, vm_evalbody.ci, vm_macro.def,
yarv.h, yarvcore.h, yarvcore.c: change type and macro names:
* yarv_*_t -> rb_*_t
* yarv_*_struct -> rb_*_struct
* yarv_tag -> rb_vm_tag
* YARV_* -> RUBY_VM_*
* proc.c, vm.c: move functions about env object creation
from proc.c to vm.c.
* proc.c, yarvcore.c: fix rb_cVM initialization place.
* inits.c: change Init_ISeq() order (after Init_VM).
* ruby.h, proc.c: change declaration place of rb_cEnv
from proc.c to ruby.c.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11651 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-02-06 14:00:03 -05:00
RUBY_VM_CHECK_INTS ( ) ;
* vm.c: some refactoring.
* rename th_* to vm_*.
* remove unused variables functions.
* add prototypes.
* blockinlining.c, compile.c, cont.c, eval.c, eval_intern.h,
eval_jump.h, eval_load.c, inits.c, insns.def, iseq.c, parse.y,
proc.c, process.c, signal.c, thread.c, vm.c, vm_dump.c,
vm_evalbody.ci, yarvcore.c, yarvcore.h: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12603 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-24 11:42:41 -04:00
vm_pop_frame ( th ) ;
2007-01-16 03:52:22 -05:00
RESTORE_REGS ( ) ;
}
/ * *
@ c method / iterator
@ e return from this vm loop
@ j VM loop <EFBFBD> <EFBFBD> <EFBFBD> 甲 <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* /
DEFINE_INSN
finish
( )
( VALUE val )
( VALUE val )
{
2007-06-27 04:21:21 -04:00
# if OPT_CALL_THREADED_CODE
rb_bug ( "unused instruction on OPT_CALL_THREADED_CODE" ) ;
# else
2007-01-16 03:52:22 -05:00
th -> cfp ++ ;
return val ;
2007-06-27 04:21:21 -04:00
# endif
2007-01-16 03:52:22 -05:00
}
/**********************************************************/
/* deal with control flow 3: exception */
/**********************************************************/
/ * *
@ c exception
@ e longjump
@ j longjump
* /
DEFINE_INSN
throw
2007-05-03 05:09:14 -04:00
( rb_num_t throw_state )
2007-01-16 03:52:22 -05:00
( VALUE throwobj )
( VALUE val )
{
2007-05-03 05:09:14 -04:00
rb_num_t state = throw_state & 0 xff ;
rb_num_t flag = throw_state & 0x8000 ;
rb_num_t level = throw_state >> 16 ;
2007-01-16 03:52:22 -05:00
val = Qnil ; /* dummy */
if ( state ! = 0 ) {
VALUE * pt ;
int i ;
if ( flag ! = 0 ) {
if ( throw_state & 0x4000 ) {
pt = ( void * ) 1 ;
}
else {
pt = 0 ;
}
}
else {
if ( state == TAG_BREAK | | state == TAG_RETRY ) {
pt = GC_GUARDED_PTR_REF ( ( VALUE * ) * GET_DFP ( ) ) ;
for ( i = 0 ; i < level ; i ++ ) {
pt = GC_GUARDED_PTR_REF ( ( VALUE * ) * pt ) ;
}
}
else if ( state == TAG_RETURN ) {
* blockinlining.c, compile.c, compile.h, error.c, eval.c,
eval_intern.h, eval_jump.h, eval_load.c, eval_method.h,
eval_safe.h, gc.c, insnhelper.h, insns.def, iseq.c, proc.c,
process.c, signal.c, thread.c, thread_pthread.ci, thread_win32.ci,
vm.c, vm.h, vm_dump.c, vm_evalbody.ci, vm_macro.def,
yarv.h, yarvcore.h, yarvcore.c: change type and macro names:
* yarv_*_t -> rb_*_t
* yarv_*_struct -> rb_*_struct
* yarv_tag -> rb_vm_tag
* YARV_* -> RUBY_VM_*
* proc.c, vm.c: move functions about env object creation
from proc.c to vm.c.
* proc.c, yarvcore.c: fix rb_cVM initialization place.
* inits.c: change Init_ISeq() order (after Init_VM).
* ruby.h, proc.c: change declaration place of rb_cEnv
from proc.c to ruby.c.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11651 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-02-06 14:00:03 -05:00
rb_control_frame_t * cfp = GET_CFP ( ) ;
2007-01-16 03:52:22 -05:00
int is_orphan = 1 ;
VALUE * dfp = GET_DFP ( ) ;
/* check orphan */
while ( ( VALUE * ) cfp < th -> stack + th -> stack_size ) {
if ( GET_LFP ( ) == cfp -> lfp ) {
is_orphan = 0 ;
break ;
}
else if ( dfp == cfp -> dfp ) {
/* return from lambda{} */
if ( cfp -> magic == FRAME_MAGIC_LAMBDA ) {
is_orphan = 0 ;
break ;
}
dfp = GC_GUARDED_PTR_REF ( * cfp -> dfp ) ;
}
cfp ++ ;
}
if ( is_orphan ) {
* vm.c: some refactoring.
* rename th_* to vm_*.
* remove unused variables functions.
* add prototypes.
* blockinlining.c, compile.c, cont.c, eval.c, eval_intern.h,
eval_jump.h, eval_load.c, inits.c, insns.def, iseq.c, parse.y,
proc.c, process.c, signal.c, thread.c, vm.c, vm_dump.c,
vm_evalbody.ci, yarvcore.c, yarvcore.h: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12603 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-24 11:42:41 -04:00
vm_localjump_error ( "unexpected return" , throwobj ,
2007-01-16 03:52:22 -05:00
TAG_RETURN ) ;
}
/* set current lfp */
pt = GET_LFP ( ) ;
}
else {
2007-04-02 08:54:42 -04:00
rb_bug ( "isns(throw): unsupport throw type" ) ;
2007-01-16 03:52:22 -05:00
}
}
th -> state = state ;
2007-06-27 04:21:21 -04:00
THROW_EXCEPTION ( NEW_THROW_OBJECT ( throwobj , ( VALUE ) pt , state ) ) ;
2007-01-16 03:52:22 -05:00
}
else {
/* continue throw */
VALUE err = throwobj ;
if ( FIXNUM_P ( err ) ) {
th -> state = FIX2INT ( err ) ;
}
else if ( SYMBOL_P ( err ) ) {
th -> state = TAG_THROW ;
}
else if ( BUILTIN_TYPE ( err ) == T_NODE ) {
th -> state = GET_THROWOBJ_STATE ( err ) ;
}
else {
th -> state = FIX2INT ( rb_ivar_get ( err , idThrowState ) ) ;
}
2007-06-27 04:21:21 -04:00
THROW_EXCEPTION ( err ) ;
2007-01-16 03:52:22 -05:00
}
/* unreachable */
}
/**********************************************************/
/* deal with control flow 4: local jump */
/**********************************************************/
/ * *
@ c jump
@ e set PC to ( PC + dst ) .
@ j PC <EFBFBD> <EFBFBD> ( PC + dst ) <EFBFBD> ɂ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> B
* /
DEFINE_INSN
jump
( OFFSET dst )
( )
( )
{
* blockinlining.c, compile.c, compile.h, error.c, eval.c,
eval_intern.h, eval_jump.h, eval_load.c, eval_method.h,
eval_safe.h, gc.c, insnhelper.h, insns.def, iseq.c, proc.c,
process.c, signal.c, thread.c, thread_pthread.ci, thread_win32.ci,
vm.c, vm.h, vm_dump.c, vm_evalbody.ci, vm_macro.def,
yarv.h, yarvcore.h, yarvcore.c: change type and macro names:
* yarv_*_t -> rb_*_t
* yarv_*_struct -> rb_*_struct
* yarv_tag -> rb_vm_tag
* YARV_* -> RUBY_VM_*
* proc.c, vm.c: move functions about env object creation
from proc.c to vm.c.
* proc.c, yarvcore.c: fix rb_cVM initialization place.
* inits.c: change Init_ISeq() order (after Init_VM).
* ruby.h, proc.c: change declaration place of rb_cEnv
from proc.c to ruby.c.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11651 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-02-06 14:00:03 -05:00
RUBY_VM_CHECK_INTS ( ) ;
2007-01-16 03:52:22 -05:00
JUMP ( dst ) ;
}
/ * *
@ c jump
@ e if val is not false or nil , set PC to ( PC + dst ) .
@ j <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> val <EFBFBD> <EFBFBD> false <EFBFBD> <EFBFBD> nil <EFBFBD> ł Ȃ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> APC <EFBFBD> <EFBFBD> ( PC + dst ) <EFBFBD> ɂ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> B
* /
DEFINE_INSN
branchif
( OFFSET dst )
( VALUE val )
( )
{
if ( RTEST ( val ) ) {
* blockinlining.c, compile.c, compile.h, error.c, eval.c,
eval_intern.h, eval_jump.h, eval_load.c, eval_method.h,
eval_safe.h, gc.c, insnhelper.h, insns.def, iseq.c, proc.c,
process.c, signal.c, thread.c, thread_pthread.ci, thread_win32.ci,
vm.c, vm.h, vm_dump.c, vm_evalbody.ci, vm_macro.def,
yarv.h, yarvcore.h, yarvcore.c: change type and macro names:
* yarv_*_t -> rb_*_t
* yarv_*_struct -> rb_*_struct
* yarv_tag -> rb_vm_tag
* YARV_* -> RUBY_VM_*
* proc.c, vm.c: move functions about env object creation
from proc.c to vm.c.
* proc.c, yarvcore.c: fix rb_cVM initialization place.
* inits.c: change Init_ISeq() order (after Init_VM).
* ruby.h, proc.c: change declaration place of rb_cEnv
from proc.c to ruby.c.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11651 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-02-06 14:00:03 -05:00
RUBY_VM_CHECK_INTS ( ) ;
2007-01-16 03:52:22 -05:00
JUMP ( dst ) ;
}
}
/ * *
@ c jump
@ e if val is false or nil , set PC to ( PC + dst ) .
@ j <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> val <EFBFBD> <EFBFBD> false <EFBFBD> <EFBFBD> nil <EFBFBD> Ȃ <EFBFBD> <EFBFBD> APC <EFBFBD> <EFBFBD> ( PC + dst ) <EFBFBD> ɂ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> B
* /
DEFINE_INSN
branchunless
( OFFSET dst )
( VALUE val )
( )
{
if ( ! RTEST ( val ) ) {
* blockinlining.c, compile.c, compile.h, error.c, eval.c,
eval_intern.h, eval_jump.h, eval_load.c, eval_method.h,
eval_safe.h, gc.c, insnhelper.h, insns.def, iseq.c, proc.c,
process.c, signal.c, thread.c, thread_pthread.ci, thread_win32.ci,
vm.c, vm.h, vm_dump.c, vm_evalbody.ci, vm_macro.def,
yarv.h, yarvcore.h, yarvcore.c: change type and macro names:
* yarv_*_t -> rb_*_t
* yarv_*_struct -> rb_*_struct
* yarv_tag -> rb_vm_tag
* YARV_* -> RUBY_VM_*
* proc.c, vm.c: move functions about env object creation
from proc.c to vm.c.
* proc.c, yarvcore.c: fix rb_cVM initialization place.
* inits.c: change Init_ISeq() order (after Init_VM).
* ruby.h, proc.c: change declaration place of rb_cEnv
from proc.c to ruby.c.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11651 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-02-06 14:00:03 -05:00
RUBY_VM_CHECK_INTS ( ) ;
2007-01-16 03:52:22 -05:00
JUMP ( dst ) ;
}
}
/**********************************************************/
/* for optimize */
/**********************************************************/
/ * *
@ c optimize
@ e inline cache
@ j inline cache
* /
DEFINE_INSN
getinlinecache
( IC ic , OFFSET dst )
( )
( VALUE val )
{
if ( ic -> ic_vmstat == GET_VM_STATE_VERSION ( ) ) {
val = ic -> ic_value ;
JUMP ( dst ) ;
}
else {
/* none */
val = Qnil ;
}
}
/ * *
@ c optimize
@ e inline cache ( once )
@ j inline cache ( once )
* /
DEFINE_INSN
onceinlinecache
( IC ic , OFFSET dst )
( )
( VALUE val )
{
if ( ic -> ic_vmstat ) {
val = ic -> ic_value ;
JUMP ( dst ) ;
}
else {
/* none */
val = Qnil ;
}
}
/ * *
@ c optimize
@ e set inline cache
@ j set inline cahce
* /
DEFINE_INSN
setinlinecache
( OFFSET dst )
( VALUE val )
( VALUE val )
{
2007-07-01 14:16:02 -04:00
IC ic = GET_CONST_INLINE_CACHE ( dst ) ;
2007-01-16 03:52:22 -05:00
ic -> ic_value = val ;
ic -> ic_vmstat = GET_VM_STATE_VERSION ( ) ;
}
/ * *
@ c optimize
@ e case dispatcher
@ j case dispatcher
* /
DEFINE_INSN
opt_case_dispatch
( CDHASH hash , OFFSET else_offset )
( .. . , VALUE key )
( ) / / inc + = - 1 ;
{
if ( 0 ) {
/* if some === method is overrided */
}
else {
VALUE val ;
if ( st_lookup ( RHASH ( hash ) -> tbl , key , & val ) ) {
JUMP ( FIX2INT ( val ) ) ;
}
else {
JUMP ( else_offset ) ;
}
}
}
/ * *
@ c optimize
@ e check environment
@ j check environment
* /
DEFINE_INSN
opt_checkenv
( )
( )
( )
{
if ( GET_CFP ( ) -> bp ! = GET_DFP ( ) + 1 ) {
VALUE * new_dfp = GET_CFP ( ) -> bp - 1 ;
/* TODO: copy env and clean stack at creating env? */
* new_dfp = * GET_DFP ( ) ;
SET_DFP ( new_dfp ) ;
}
}
/** simple functions */
/ * *
@ c optimize
@ e optimized X + Y .
@ j <EFBFBD> œ K <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ꂽ X + Y <EFBFBD> B
* /
DEFINE_INSN
opt_plus
( )
( VALUE recv , VALUE obj )
( VALUE val )
{
if ( 0 ) {
}
# if 1
else if ( FIXNUM_2_P ( recv , obj ) & &
BASIC_OP_UNREDEFINED_P ( BOP_PLUS ) ) {
/* fixnum + fixnum */
2007-06-26 02:23:34 -04:00
# ifndef LONG_LONG_VALUE
2007-01-16 03:52:22 -05:00
val = ( recv + ( obj & ( ~ 1 ) ) ) ;
if ( ( ~ ( recv ^ obj ) & ( recv ^ val ) ) &
( ( VALUE ) 0x01 << ( ( sizeof ( VALUE ) * CHAR_BIT ) - 1 ) ) ) {
val = rb_big_plus ( rb_int2big ( FIX2INT ( recv ) ) ,
rb_int2big ( FIX2INT ( obj ) ) ) ;
}
2007-06-26 02:23:34 -04:00
# else
long a , b , c ;
a = FIX2LONG ( recv ) ;
b = FIX2LONG ( obj ) ;
c = a + b ;
if ( FIXABLE ( c ) ) {
val = LONG2FIX ( c ) ;
}
else {
val = rb_big_plus ( rb_int2big ( a ) , rb_int2big ( b ) ) ;
}
# endif
2007-01-16 03:52:22 -05:00
}
# endif
else if ( ! SPECIAL_CONST_P ( recv ) & & ! SPECIAL_CONST_P ( obj ) ) {
if ( 0 ) {
}
# if 1
else if ( HEAP_CLASS_OF ( recv ) == rb_cFloat & &
HEAP_CLASS_OF ( obj ) == rb_cFloat & &
BASIC_OP_UNREDEFINED_P ( BOP_PLUS ) ) {
val = rb_float_new ( RFLOAT ( recv ) -> value + RFLOAT ( obj ) -> value ) ;
}
# endif
# if 1
else if ( HEAP_CLASS_OF ( recv ) == rb_cString & &
HEAP_CLASS_OF ( obj ) == rb_cString & &
BASIC_OP_UNREDEFINED_P ( BOP_PLUS ) ) {
val = rb_str_plus ( recv , obj ) ;
}
# endif
# if 1
else if ( HEAP_CLASS_OF ( recv ) == rb_cArray & &
BASIC_OP_UNREDEFINED_P ( BOP_PLUS ) ) {
val = rb_ary_plus ( recv , obj ) ;
}
# endif
else {
goto INSN_LABEL ( normal_dispatch ) ;
}
}
else {
INSN_LABEL ( normal_dispatch ) :
PUSH ( recv ) ;
PUSH ( obj ) ;
2007-06-24 09:05:51 -04:00
CALL_SIMPLE_METHOD ( 1 , idPLUS , recv ) ;
2007-01-16 03:52:22 -05:00
}
}
/ * *
@ c optimize
@ e optimized X - Y .
@ j <EFBFBD> œ K <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ꂽ X - Y <EFBFBD> B
* /
DEFINE_INSN
opt_minus
( )
( VALUE recv , VALUE obj )
( VALUE val )
{
if ( FIXNUM_2_P ( recv , obj ) & &
BASIC_OP_UNREDEFINED_P ( BOP_MINUS ) ) {
long a , b , c ;
a = FIX2LONG ( recv ) ;
b = FIX2LONG ( obj ) ;
c = a - b ;
2007-06-26 02:23:34 -04:00
if ( FIXABLE ( c ) ) {
val = LONG2FIX ( c ) ;
}
else {
2007-01-16 03:52:22 -05:00
val = rb_big_minus ( rb_int2big ( a ) , rb_int2big ( b ) ) ;
}
}
else {
/* other */
PUSH ( recv ) ;
PUSH ( obj ) ;
2007-06-24 09:05:51 -04:00
CALL_SIMPLE_METHOD ( 1 , idMINUS , recv ) ;
2007-01-16 03:52:22 -05:00
}
}
/ * *
@ c optimize
@ e optimized X * Y .
@ j <EFBFBD> œ K <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ꂽ X * Y <EFBFBD> B
* /
DEFINE_INSN
opt_mult
( )
( VALUE recv , VALUE obj )
( VALUE val )
{
if ( FIXNUM_2_P ( recv , obj ) & &
BASIC_OP_UNREDEFINED_P ( BOP_MULT ) ) {
long a , b , c ;
a = FIX2LONG ( recv ) ;
if ( a == 0 ) {
val = recv ;
}
else {
b = FIX2LONG ( obj ) ;
c = a * b ;
2007-06-26 02:23:34 -04:00
if ( FIXABLE ( c ) & & c / a == b ) {
val = LONG2FIX ( c ) ;
}
else {
2007-01-16 03:52:22 -05:00
val = rb_big_mul ( rb_int2big ( a ) , rb_int2big ( b ) ) ;
}
}
}
else if ( ! SPECIAL_CONST_P ( recv ) & & ! SPECIAL_CONST_P ( obj ) ) {
if ( 0 ) {
}
# if 1
else if ( HEAP_CLASS_OF ( recv ) == rb_cFloat & &
HEAP_CLASS_OF ( obj ) == rb_cFloat & &
BASIC_OP_UNREDEFINED_P ( BOP_MULT ) ) {
val = rb_float_new ( RFLOAT ( recv ) -> value * RFLOAT ( obj ) -> value ) ;
}
# endif
else {
goto INSN_LABEL ( normal_dispatch ) ;
}
}
else {
INSN_LABEL ( normal_dispatch ) :
PUSH ( recv ) ;
PUSH ( obj ) ;
2007-06-24 09:05:51 -04:00
CALL_SIMPLE_METHOD ( 1 , idMULT , recv ) ;
2007-01-16 03:52:22 -05:00
}
}
/ * *
@ c optimize
@ e optimized X / Y .
@ j <EFBFBD> œ K <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ꂽ X / Y <EFBFBD> B
* /
DEFINE_INSN
opt_div
( )
( VALUE recv , VALUE obj )
( VALUE val )
{
if ( FIXNUM_2_P ( recv , obj ) & &
BASIC_OP_UNREDEFINED_P ( BOP_DIV ) ) {
long x , y , div ;
x = FIX2LONG ( recv ) ;
y = FIX2LONG ( obj ) ;
{
/* copied from numeric.c#fixdivmod */
long mod ;
if ( y == 0 )
rb_num_zerodiv ( ) ;
if ( y < 0 ) {
if ( x < 0 )
div = - x / - y ;
else
div = - ( x / - y ) ;
}
else {
if ( x < 0 )
div = - ( - x / y ) ;
else
div = x / y ;
}
mod = x - div * y ;
if ( ( mod < 0 & & y > 0 ) | | ( mod > 0 & & y < 0 ) ) {
mod + = y ;
div - = 1 ;
}
}
val = LONG2FIX ( div ) ;
}
else if ( ! SPECIAL_CONST_P ( recv ) & & ! SPECIAL_CONST_P ( obj ) ) {
if ( 0 ) {
}
# if 1
else if ( HEAP_CLASS_OF ( recv ) == rb_cFloat & &
HEAP_CLASS_OF ( obj ) == rb_cFloat & &
BASIC_OP_UNREDEFINED_P ( BOP_DIV ) ) {
val = rb_float_new ( RFLOAT ( recv ) -> value / RFLOAT ( obj ) -> value ) ;
}
# endif
else {
goto INSN_LABEL ( normal_dispatch ) ;
}
}
else {
INSN_LABEL ( normal_dispatch ) :
PUSH ( recv ) ;
PUSH ( obj ) ;
2007-06-24 09:05:51 -04:00
CALL_SIMPLE_METHOD ( 1 , idDIV , recv ) ;
2007-01-16 03:52:22 -05:00
}
}
/ * *
@ c optimize
@ e optimized X % Y .
@ j <EFBFBD> œ K <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ꂽ X % Y <EFBFBD> B
* /
DEFINE_INSN
opt_mod
( )
( VALUE recv , VALUE obj )
( VALUE val )
{
if ( FIXNUM_2_P ( recv , obj ) & &
BASIC_OP_UNREDEFINED_P ( BOP_MOD ) ) {
long x , y , mod ;
x = FIX2LONG ( recv ) ;
y = FIX2LONG ( obj ) ;
{
/* copied from numeric.c#fixdivmod */
long div ;
if ( y == 0 )
rb_num_zerodiv ( ) ;
if ( y < 0 ) {
if ( x < 0 )
div = - x / - y ;
else
div = - ( x / - y ) ;
}
else {
if ( x < 0 )
div = - ( - x / y ) ;
else
div = x / y ;
}
mod = x - div * y ;
if ( ( mod < 0 & & y > 0 ) | | ( mod > 0 & & y < 0 ) ) {
mod + = y ;
div - = 1 ;
}
}
val = LONG2FIX ( mod ) ;
}
else if ( ! SPECIAL_CONST_P ( recv ) & & ! SPECIAL_CONST_P ( obj ) ) {
if ( 0 ) {
}
else if ( HEAP_CLASS_OF ( recv ) == rb_cFloat & &
HEAP_CLASS_OF ( obj ) == rb_cFloat & &
BASIC_OP_UNREDEFINED_P ( BOP_MOD ) ) {
double x = RFLOAT ( recv ) -> value ;
double y = RFLOAT ( obj ) -> value ;
double div , mod ;
/* copied from numeric.c#flodivmod */
# if 0 & & defined ( HAVE_FMOD ) & & ! __x86_64__ /* temporary */
mod = fmod ( x , y ) ;
printf ( "-- %f %% %f = %f\n" , x , y , mod ) ;
# else
{
double z ;
modf ( x / y , & z ) ;
mod = x - z * y ;
}
# endif
div = ( x - mod ) / y ;
if ( y * mod < 0 ) {
mod + = y ;
div - = 1.0 ;
}
val = rb_float_new ( mod ) ;
}
else {
goto INSN_LABEL ( normal_dispatch ) ;
}
}
else {
INSN_LABEL ( normal_dispatch ) :
PUSH ( recv ) ;
PUSH ( obj ) ;
2007-06-24 09:05:51 -04:00
CALL_SIMPLE_METHOD ( 1 , idMOD , recv ) ;
2007-01-16 03:52:22 -05:00
}
}
/ * *
@ c optimize
@ e optimized X == Y .
@ j <EFBFBD> œ K <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ꂽ X == Y <EFBFBD> B
* /
DEFINE_INSN
opt_eq
( )
( VALUE recv , VALUE obj )
( VALUE val )
{
if ( FIXNUM_2_P ( recv , obj ) & &
BASIC_OP_UNREDEFINED_P ( BOP_EQ ) ) {
long a = FIX2LONG ( recv ) , b = FIX2LONG ( obj ) ;
if ( a == b ) {
val = Qtrue ;
}
else {
val = Qfalse ;
}
}
else if ( ! SPECIAL_CONST_P ( recv ) & & ! SPECIAL_CONST_P ( obj ) ) {
if ( 0 ) {
}
else if ( HEAP_CLASS_OF ( recv ) == rb_cFloat & &
HEAP_CLASS_OF ( obj ) == rb_cFloat & &
BASIC_OP_UNREDEFINED_P ( BOP_EQ ) ) {
double a = RFLOAT ( recv ) -> value ;
double b = RFLOAT ( obj ) -> value ;
if ( isnan ( a ) | | isnan ( b ) ) {
val = Qfalse ;
}
else if ( a == b ) {
val = Qtrue ;
}
else {
val = Qfalse ;
}
}
else if ( HEAP_CLASS_OF ( recv ) == rb_cString & &
HEAP_CLASS_OF ( obj ) == rb_cString & &
BASIC_OP_UNREDEFINED_P ( BOP_EQ ) ) {
VALUE str1 = recv ;
VALUE str2 = obj ;
if ( str1 == str2 ) {
val = Qtrue ;
}
else if ( RSTRING_LEN ( str1 ) == RSTRING_LEN ( str2 ) & &
rb_memcmp ( RSTRING_PTR ( str1 ) , RSTRING_PTR ( str2 ) ,
RSTRING_LEN ( str1 ) ) == 0 ) {
val = Qtrue ;
}
else {
val = Qfalse ;
}
}
else {
goto INSN_LABEL ( normal_dispatch ) ;
}
}
else {
INSN_LABEL ( normal_dispatch ) :
/* other */
PUSH ( recv ) ;
PUSH ( obj ) ;
2007-06-24 09:05:51 -04:00
CALL_SIMPLE_METHOD ( 1 , idEq , recv ) ;
2007-01-16 03:52:22 -05:00
}
}
/ * *
@ c optimize
@ e optimized X < Y .
@ j <EFBFBD> œ K <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ꂽ X < Y <EFBFBD> B
* /
DEFINE_INSN
opt_lt
( )
( VALUE recv , VALUE obj )
( VALUE val )
{
if ( FIXNUM_2_P ( recv , obj ) & &
BASIC_OP_UNREDEFINED_P ( BOP_LT ) ) {
long a = FIX2LONG ( recv ) , b = FIX2LONG ( obj ) ;
if ( a < b ) {
val = Qtrue ;
}
else {
val = Qfalse ;
}
}
else {
PUSH ( recv ) ;
PUSH ( obj ) ;
2007-06-24 09:05:51 -04:00
CALL_SIMPLE_METHOD ( 1 , idLT , recv ) ;
2007-01-16 03:52:22 -05:00
}
}
/ * *
@ c optimize
@ e optimized X <= Y .
@ j <EFBFBD> œ K <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ꂽ X <= Y <EFBFBD> B
* /
DEFINE_INSN
opt_le
( )
( VALUE recv , VALUE obj )
( VALUE val )
{
if ( FIXNUM_2_P ( recv , obj ) & &
BASIC_OP_UNREDEFINED_P ( BOP_LE ) ) {
long a = FIX2LONG ( recv ) , b = FIX2LONG ( obj ) ;
if ( a <= b ) {
val = Qtrue ;
}
else {
val = Qfalse ;
}
}
else {
/* other */
PUSH ( recv ) ;
PUSH ( obj ) ;
2007-06-24 09:05:51 -04:00
CALL_SIMPLE_METHOD ( 1 , idLE , recv ) ;
2007-01-16 03:52:22 -05:00
}
}
2007-05-21 00:46:51 -04:00
/ * *
@ c optimize
@ e optimized X > Y .
@ j <EFBFBD> œ K <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ꂽ X > Y <EFBFBD> B
* /
DEFINE_INSN
opt_gt
( )
( VALUE recv , VALUE obj )
( VALUE val )
{
if ( FIXNUM_2_P ( recv , obj ) & &
BASIC_OP_UNREDEFINED_P ( BOP_GT ) ) {
long a = FIX2LONG ( recv ) , b = FIX2LONG ( obj ) ;
if ( a > b ) {
val = Qtrue ;
}
else {
val = Qfalse ;
}
}
else {
PUSH ( recv ) ;
PUSH ( obj ) ;
2007-06-24 09:05:51 -04:00
CALL_SIMPLE_METHOD ( 1 , idGT , recv ) ;
2007-05-21 00:46:51 -04:00
}
}
/ * *
@ c optimize
@ e optimized X >= Y .
@ j <EFBFBD> œ K <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ꂽ X >= Y <EFBFBD> B
* /
DEFINE_INSN
opt_ge
( )
( VALUE recv , VALUE obj )
( VALUE val )
{
if ( FIXNUM_2_P ( recv , obj ) & &
BASIC_OP_UNREDEFINED_P ( BOP_GE ) ) {
long a = FIX2LONG ( recv ) , b = FIX2LONG ( obj ) ;
if ( a >= b ) {
val = Qtrue ;
}
else {
val = Qfalse ;
}
}
else {
PUSH ( recv ) ;
PUSH ( obj ) ;
2007-06-24 09:05:51 -04:00
CALL_SIMPLE_METHOD ( 1 , idGE , recv ) ;
2007-05-21 00:46:51 -04:00
}
}
2007-01-16 03:52:22 -05:00
/ * *
@ c optimize
@ e <<
@ j <<
* /
DEFINE_INSN
opt_ltlt
( )
( VALUE recv , VALUE obj )
( VALUE val )
{
if ( ! SPECIAL_CONST_P ( recv ) ) {
if ( 0 ) {
}
else if ( HEAP_CLASS_OF ( recv ) == rb_cString & &
BASIC_OP_UNREDEFINED_P ( BOP_LTLT ) ) {
val = rb_str_concat ( recv , obj ) ;
}
else if ( HEAP_CLASS_OF ( recv ) == rb_cArray & &
BASIC_OP_UNREDEFINED_P ( BOP_LTLT ) ) {
val = rb_ary_push ( recv , obj ) ;
}
else {
goto INSN_LABEL ( normal_dispatch ) ;
}
}
else {
INSN_LABEL ( normal_dispatch ) :
PUSH ( recv ) ;
PUSH ( obj ) ;
2007-06-24 09:05:51 -04:00
CALL_SIMPLE_METHOD ( 1 , idLTLT , recv ) ;
2007-01-16 03:52:22 -05:00
}
}
/ * *
@ c optimize
@ e [ ]
@ j [ ]
* /
DEFINE_INSN
opt_aref
( )
( VALUE recv , VALUE obj )
( VALUE val )
{
if ( ! SPECIAL_CONST_P ( recv ) & & BASIC_OP_UNREDEFINED_P ( BOP_AREF ) ) {
if ( HEAP_CLASS_OF ( recv ) == rb_cArray & & FIXNUM_P ( obj ) ) {
val = rb_ary_entry ( recv , FIX2LONG ( obj ) ) ;
}
else if ( HEAP_CLASS_OF ( recv ) == rb_cHash ) {
val = rb_hash_aref ( recv , obj ) ;
}
else {
goto INSN_LABEL ( normal_dispatch ) ;
}
}
else {
INSN_LABEL ( normal_dispatch ) :
PUSH ( recv ) ;
PUSH ( obj ) ;
2007-06-24 09:05:51 -04:00
CALL_SIMPLE_METHOD ( 1 , idAREF , recv ) ;
2007-01-16 03:52:22 -05:00
}
}
/ * *
@ c optimize
@ e recv [ obj ] = set
@ j recv [ obj ] = set
* /
DEFINE_INSN
opt_aset
( )
( VALUE recv , VALUE obj , VALUE set )
( VALUE val )
{
if ( ! SPECIAL_CONST_P ( recv ) & &
BASIC_OP_UNREDEFINED_P ( BOP_ASET ) ) {
if ( HEAP_CLASS_OF ( recv ) == rb_cArray & & FIXNUM_P ( obj ) ) {
rb_ary_store ( recv , FIX2LONG ( obj ) , set ) ;
val = set ;
}
else if ( HEAP_CLASS_OF ( recv ) == rb_cHash ) {
rb_hash_aset ( recv , obj , set ) ;
val = set ;
}
else {
goto INSN_LABEL ( normal_dispatch ) ;
}
}
else {
INSN_LABEL ( normal_dispatch ) :
PUSH ( recv ) ;
PUSH ( obj ) ;
PUSH ( set ) ;
2007-06-24 09:05:51 -04:00
CALL_SIMPLE_METHOD ( 2 , idASET , recv ) ;
2007-01-16 03:52:22 -05:00
}
}
/ * *
@ c optimize
@ e optimized length
@ j optimized length
* /
DEFINE_INSN
opt_length
( )
( VALUE recv )
( VALUE val )
{
if ( ! SPECIAL_CONST_P ( recv ) & &
BASIC_OP_UNREDEFINED_P ( BOP_LENGTH ) ) {
if ( HEAP_CLASS_OF ( recv ) == rb_cArray ) {
val = LONG2NUM ( RARRAY_LEN ( recv ) ) ;
}
else if ( HEAP_CLASS_OF ( recv ) == rb_cString ) {
val = LONG2NUM ( RSTRING_LEN ( recv ) ) ;
}
else if ( HEAP_CLASS_OF ( recv ) == rb_cHash ) {
val = INT2FIX ( RHASH ( recv ) -> tbl -> num_entries ) ;
}
else {
goto INSN_LABEL ( normal_dispatch ) ;
}
}
else {
INSN_LABEL ( normal_dispatch ) :
2007-06-24 09:05:51 -04:00
PUSH ( recv ) ;
CALL_SIMPLE_METHOD ( 0 , idLength , recv ) ;
2007-01-16 03:52:22 -05:00
}
}
/ * *
@ c optimize
@ e optimized succ
@ j optimized succ
* /
DEFINE_INSN
opt_succ
( )
( VALUE recv )
( VALUE val )
{
if ( SPECIAL_CONST_P ( recv ) ) {
if ( FIXNUM_P ( recv ) & &
BASIC_OP_UNREDEFINED_P ( BOP_SUCC ) ) {
const VALUE obj = INT2FIX ( 1 ) ;
/* fixnum + INT2FIX(1) */
val = ( recv + ( obj & ( ~ 1 ) ) ) ;
if ( ( ~ ( recv ^ obj ) & ( recv ^ val ) ) & 0x80000000 ) {
val = rb_big_plus ( rb_int2big ( INT2FIX ( recv ) ) ,
rb_int2big ( INT2FIX ( obj ) ) ) ;
}
}
else {
goto INSN_LABEL ( normal_dispatch ) ;
}
}
else {
if ( HEAP_CLASS_OF ( recv ) == rb_cString & &
BASIC_OP_UNREDEFINED_P ( BOP_SUCC ) ) {
val = rb_str_succ ( recv ) ;
}
else if ( HEAP_CLASS_OF ( recv ) == rb_cTime & &
BASIC_OP_UNREDEFINED_P ( BOP_SUCC ) ) {
val = rb_time_succ ( recv ) ;
}
else {
goto INSN_LABEL ( normal_dispatch ) ;
}
}
if ( 0 ) {
INSN_LABEL ( normal_dispatch ) :
2007-06-24 09:05:51 -04:00
PUSH ( recv ) ;
CALL_SIMPLE_METHOD ( 0 , idSucc , recv ) ;
2007-01-16 03:52:22 -05:00
}
}
/ * *
@ c optimize
@ e optimized regexp match
@ j <EFBFBD> œ K <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ꂽ <EFBFBD> <EFBFBD> <EFBFBD> K <EFBFBD> \ <EFBFBD> <EFBFBD> <EFBFBD> } <EFBFBD> b <EFBFBD> `
* /
DEFINE_INSN
opt_regexpmatch1
( VALUE r )
( VALUE obj )
( VALUE val )
{
val = rb_reg_match ( r , obj ) ;
}
/ * *
@ c optimize
@ e optimized regexp match 2
@ j <EFBFBD> œ K <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ꂽ <EFBFBD> <EFBFBD> <EFBFBD> K <EFBFBD> \ <EFBFBD> <EFBFBD> <EFBFBD> } <EFBFBD> b <EFBFBD> ` 2
* /
DEFINE_INSN
opt_regexpmatch2
( )
( VALUE obj2 , VALUE obj1 )
( VALUE val )
{
if ( TYPE ( obj2 ) == T_STRING ) {
val = rb_reg_match ( obj1 , obj2 ) ;
}
else {
val = rb_funcall ( obj2 , idEqTilde , 1 , obj1 ) ;
}
}
/ * *
@ c optimize
@ e call native compiled method
@ j <EFBFBD> l <EFBFBD> C <EFBFBD> e <EFBFBD> B <EFBFBD> u <EFBFBD> R <EFBFBD> <EFBFBD> <EFBFBD> p <EFBFBD> C <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> \ <EFBFBD> b <EFBFBD> h <EFBFBD> <EFBFBD> kick
* /
DEFINE_INSN
2007-06-30 14:02:24 -04:00
opt_call_c_function
( VALUE func )
2007-01-16 03:52:22 -05:00
( )
( )
{
2007-06-30 14:02:24 -04:00
rb_insn_func_t funcptr = ( rb_insn_func_t ) func ;
2007-07-02 08:49:35 -04:00
2007-06-30 14:02:24 -04:00
reg_cfp = ( funcptr ) ( th , reg_cfp ) ;
2007-01-16 03:52:22 -05:00
2007-06-30 14:02:24 -04:00
if ( reg_cfp == 0 ) {
VALUE err = th -> errinfo ;
th -> errinfo = Qnil ;
2007-07-01 22:59:37 -04:00
THROW_EXCEPTION ( err ) ;
2007-06-30 14:02:24 -04:00
}
2007-07-02 08:49:35 -04:00
RESTORE_REGS ( ) ;
2007-06-30 14:02:24 -04:00
NEXT_INSN ( ) ;
2007-01-16 03:52:22 -05:00
}
/ * *
@ c joke
@ e BLT
@ j BLT
* /
DEFINE_INSN
bitblt
( )
( )
( VALUE ret )
{
ret = rb_str_new2 ( "a bit of bacon, lettuce and tomato" ) ;
}
/ * *
@ c joke
@ e The Answer to Life , the Universe , and Everything
@ j <EFBFBD> l <EFBFBD> <EFBFBD> <EFBFBD> A <EFBFBD> F <EFBFBD> <EFBFBD> <EFBFBD> A <EFBFBD> <EFBFBD> <EFBFBD> ׂ Ă ̓ <EFBFBD> <EFBFBD> <EFBFBD>
* /
DEFINE_INSN
answer
( )
( )
( VALUE ret )
{
ret = INT2FIX ( 42 ) ;
}