2011-09-05 16:02:30 +04:00
|
|
|
|
/** ##skip -*- mode:c; style:ruby; coding: utf-8 -*-
|
2007-01-16 11:52:22 +03:00
|
|
|
|
insns.def - YARV instruction definitions
|
|
|
|
|
|
|
|
|
|
$Author: $
|
|
|
|
|
created at: 04/01/01 01:17:55 JST
|
|
|
|
|
|
* blockinlining.c, compile.c, compile.h, debug.c, debug.h,
id.c, insnhelper.h, insns.def, thread.c, thread_pthread.ci,
thread_pthread.h, thread_win32.ci, thread_win32.h, vm.h,
vm_dump.c, vm_evalbody.ci, vm_opts.h: fix comments and
copyright year.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13920 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-11-14 01:13:04 +03:00
|
|
|
|
Copyright (C) 2004-2007 Koichi Sasada
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/** ##skip
|
|
|
|
|
instruction comment
|
|
|
|
|
@c: category
|
|
|
|
|
@e: english description
|
|
|
|
|
@j: japanese description
|
|
|
|
|
|
|
|
|
|
instruction form:
|
|
|
|
|
DEFINE_INSN
|
2010-08-02 19:53:48 +04:00
|
|
|
|
instruction_name
|
2007-01-16 11:52:22 +03:00
|
|
|
|
(instruction_operands, ..)
|
|
|
|
|
(pop_values, ..)
|
|
|
|
|
(return value)
|
|
|
|
|
{
|
|
|
|
|
.. // insn body
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c nop
|
|
|
|
|
@e nop
|
|
|
|
|
@j nop
|
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
nop
|
|
|
|
|
()
|
|
|
|
|
()
|
|
|
|
|
()
|
|
|
|
|
{
|
|
|
|
|
/* none */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**********************************************************/
|
|
|
|
|
/* deal with variables */
|
|
|
|
|
/**********************************************************/
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c variable
|
2012-10-04 17:52:20 +04:00
|
|
|
|
@e Get local variable (pointed by `idx' and `level').
|
|
|
|
|
'level' indicates the nesting depth from the current block.
|
|
|
|
|
@j level, idx で指定されたローカル変数の値をスタックに置く。
|
|
|
|
|
level はブロックのネストレベルで、何段上かを示す。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
getlocal
|
2012-10-04 17:52:20 +04:00
|
|
|
|
(lindex_t idx, rb_num_t level)
|
2007-01-16 11:52:22 +03:00
|
|
|
|
()
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
2012-12-04 08:57:50 +04:00
|
|
|
|
int i, lev = (int)level;
|
2012-10-04 17:52:20 +04:00
|
|
|
|
VALUE *ep = GET_EP();
|
2012-12-04 08:57:50 +04:00
|
|
|
|
|
2014-10-23 05:50:45 +04:00
|
|
|
|
/* optimized insns generated for level == (0|1) in defs/opt_operand.def */
|
2012-12-04 08:57:50 +04:00
|
|
|
|
for (i = 0; i < lev; i++) {
|
2013-01-08 09:57:42 +04:00
|
|
|
|
ep = GET_PREV_EP(ep);
|
2012-10-04 17:52:20 +04:00
|
|
|
|
}
|
|
|
|
|
val = *(ep - idx);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c variable
|
2012-10-04 17:52:20 +04:00
|
|
|
|
@e Set a local variable (pointed to by 'idx') as val.
|
|
|
|
|
'level' indicates the nesting depth from the current block.
|
|
|
|
|
@j level, idx で指定されたローカル変数の値を val にする。
|
|
|
|
|
level はブロックのネストレベルで、何段上かを示す。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
setlocal
|
2012-10-04 17:52:20 +04:00
|
|
|
|
(lindex_t idx, rb_num_t level)
|
2007-01-16 11:52:22 +03:00
|
|
|
|
(VALUE val)
|
|
|
|
|
()
|
|
|
|
|
{
|
2012-12-04 08:57:50 +04:00
|
|
|
|
int i, lev = (int)level;
|
2012-10-04 17:52:20 +04:00
|
|
|
|
VALUE *ep = GET_EP();
|
2012-12-04 08:57:50 +04:00
|
|
|
|
|
2014-10-23 05:50:45 +04:00
|
|
|
|
/* optimized insns generated for level == (0|1) in defs/opt_operand.def */
|
2012-12-04 08:57:50 +04:00
|
|
|
|
for (i = 0; i < lev; i++) {
|
2012-10-04 17:52:20 +04:00
|
|
|
|
ep = GET_PREV_EP(ep);
|
|
|
|
|
}
|
|
|
|
|
*(ep - idx) = val;
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c variable
|
2011-11-05 15:30:51 +04:00
|
|
|
|
@e Get value of special local variable ($~, $_, ..).
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j 特殊なローカル変数($~, $_, ...)の値を得る。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
getspecial
|
2012-12-10 10:11:16 +04:00
|
|
|
|
(rb_num_t key, rb_num_t type)
|
2007-01-16 11:52:22 +03:00
|
|
|
|
()
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
2012-06-11 07:14:59 +04:00
|
|
|
|
val = vm_getspecial(th, GET_LEP(), key, type);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c variable
|
2011-11-05 15:30:51 +04:00
|
|
|
|
@e Set value of special local variable ($~, $_, ...) to obj.
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j 特別なローカル変数($~, $_, ...)の値を設定する。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
setspecial
|
2012-12-10 10:11:16 +04:00
|
|
|
|
(rb_num_t key)
|
2007-01-16 11:52:22 +03:00
|
|
|
|
(VALUE obj)
|
|
|
|
|
()
|
|
|
|
|
{
|
2012-06-11 07:14:59 +04:00
|
|
|
|
lep_svar_set(th, GET_LEP(), key, obj);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c variable
|
2011-11-05 15:30:51 +04:00
|
|
|
|
@e Get value of instance variable id of self.
|
|
|
|
|
If is_local is not 0, get value of class local variable.
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j self のインスタンス変数 id の値を得る。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
getinstancevariable
|
2009-07-13 08:44:20 +04:00
|
|
|
|
(ID id, IC ic)
|
2007-01-16 11:52:22 +03:00
|
|
|
|
()
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
2012-10-16 21:07:23 +04:00
|
|
|
|
val = vm_getinstancevariable(GET_SELF(), id, ic);
|
2007-02-04 22:17:33 +03:00
|
|
|
|
}
|
|
|
|
|
|
2007-01-16 11:52:22 +03:00
|
|
|
|
/**
|
|
|
|
|
@c variable
|
2011-11-05 15:30:51 +04:00
|
|
|
|
@e Set value of instance variable id of self to val.
|
|
|
|
|
If is_local is not 0, set value of class local variable.
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j self のインスタンス変数 id を val にする。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
setinstancevariable
|
2009-09-06 11:40:24 +04:00
|
|
|
|
(ID id, IC ic)
|
2007-01-16 11:52:22 +03:00
|
|
|
|
(VALUE val)
|
|
|
|
|
()
|
|
|
|
|
{
|
2012-10-16 21:07:23 +04:00
|
|
|
|
vm_setinstancevariable(GET_SELF(), id, val, ic);
|
2007-02-04 22:17:33 +03:00
|
|
|
|
}
|
|
|
|
|
|
2007-01-16 11:52:22 +03:00
|
|
|
|
/**
|
|
|
|
|
@c variable
|
2011-11-05 15:30:51 +04:00
|
|
|
|
@e Get value of class variable id of klass as val.
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j 現在のスコープのクラス変数 id の値を得る。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
getclassvariable
|
|
|
|
|
(ID id)
|
|
|
|
|
()
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
2015-03-09 00:22:43 +03:00
|
|
|
|
val = rb_cvar_get(vm_get_cvar_base(rb_vm_get_cref(GET_EP()), GET_CFP()), id);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c variable
|
2011-11-05 15:30:51 +04:00
|
|
|
|
@e Set value of class variable id of klass as val.
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j klass のクラス変数 id を val にする。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
setclassvariable
|
2007-02-04 22:15:38 +03:00
|
|
|
|
(ID id)
|
2007-01-16 11:52:22 +03:00
|
|
|
|
(VALUE val)
|
|
|
|
|
()
|
|
|
|
|
{
|
2015-03-09 00:22:43 +03:00
|
|
|
|
rb_cvar_set(vm_get_cvar_base(rb_vm_get_cref(GET_EP()), GET_CFP()), id, val);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c variable
|
|
|
|
|
@e
|
2011-11-05 15:30:51 +04:00
|
|
|
|
Get constant variable id. If klass is Qnil, constants
|
|
|
|
|
are searched in the current scope. If klass is Qfalse, constants
|
|
|
|
|
are searched as top level constants. Otherwise, get constant under klass
|
2007-01-16 11:52:22 +03:00
|
|
|
|
class or module.
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j 定数 id の値を得る。
|
|
|
|
|
klass が Qnil なら、そのスコープで得られる定数の値を得る。
|
|
|
|
|
Qfalse なら、トップレベルスコープを得る。
|
|
|
|
|
それ以外なら、klass クラスの下の定数を得る。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
getconstant
|
|
|
|
|
(ID id)
|
|
|
|
|
(VALUE klass)
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
* fix namespace issue on singleton class expressions. [Bug #10943]
* vm_core.h, method.h: remove rb_iseq_t::cref_stack. CREF is stored
to rb_method_definition_t::body.iseq_body.cref.
* vm_insnhelper.c: modify SVAR usage.
When calling ISEQ type method, push CREF information onto method
frame, SVAR located place. Before this fix, SVAR is simply nil.
After this patch, CREF (or NULL == Qfalse for not iseq methods)
is stored at the method invocation.
When SVAR is requierd, then put NODE_IF onto SVAR location,
and NDOE_IF::nd_reserved points CREF itself.
* vm.c (vm_cref_new, vm_cref_dump, vm_cref_new_toplevel): added.
* vm_insnhelper.c (vm_push_frame): accept CREF.
* method.h, vm_method.c (rb_add_method_iseq): added. This function
accepts iseq and CREF.
* class.c (clone_method): use rb_add_method_iseq().
* gc.c (mark_method_entry): mark method_entry::body.iseq_body.cref.
* iseq.c: remove CREF related codes.
* insns.def (getinlinecache/setinlinecache): CREF should be cache key
because a different CREF has a different namespace.
* node.c (rb_gc_mark_node): mark NODE_IF::nd_reserved for SVAR.
* proc.c: catch up changes.
* struct.c: ditto.
* insns.def: ditto.
* vm_args.c (raise_argument_error): ditto.
* vm_eval.c: ditto.
* test/ruby/test_class.rb: add a test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49874 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-03-06 15:24:58 +03:00
|
|
|
|
val = vm_get_ev_const(th, klass, id, 0);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c variable
|
|
|
|
|
@e
|
2011-11-05 15:30:51 +04:00
|
|
|
|
Set constant variable id. If klass is Qfalse, constant
|
2007-01-16 11:52:22 +03:00
|
|
|
|
is able to access in this scope. if klass is Qnil, set
|
|
|
|
|
top level constant. otherwise, set constant under klass
|
|
|
|
|
class or module.
|
|
|
|
|
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j 定数 id の値を val にする。
|
|
|
|
|
klass が Qfalse なら、そのスコープで得られる定数 id の値を設定する。
|
|
|
|
|
Qnil なら、トップレベルスコープの値を設定する。
|
|
|
|
|
それ以外なら、klass クラスの下の定数を設定する。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
setconstant
|
|
|
|
|
(ID id)
|
2008-05-14 06:31:28 +04:00
|
|
|
|
(VALUE val, VALUE cbase)
|
2007-01-16 11:52:22 +03:00
|
|
|
|
()
|
|
|
|
|
{
|
2008-05-14 06:31:28 +04:00
|
|
|
|
vm_check_if_namespace(cbase);
|
|
|
|
|
rb_const_set(cbase, id, val);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c variable
|
|
|
|
|
@e get global variable id.
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j グローバル変数 id の値を得る。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
getglobal
|
|
|
|
|
(GENTRY entry)
|
|
|
|
|
()
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
2010-10-12 18:35:40 +04:00
|
|
|
|
val = GET_GLOBAL((VALUE)entry);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c variable
|
|
|
|
|
@e set global variable id as val.
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j グローバル変数 id の値を設定する。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
setglobal
|
|
|
|
|
(GENTRY entry)
|
|
|
|
|
(VALUE val)
|
|
|
|
|
()
|
|
|
|
|
{
|
2010-10-12 18:35:40 +04:00
|
|
|
|
SET_GLOBAL((VALUE)entry, val);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**********************************************************/
|
|
|
|
|
/* deal with values */
|
|
|
|
|
/**********************************************************/
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c put
|
* blockinlining.c, compile.c, compile.h, debug.c, debug.h,
id.c, insnhelper.h, insns.def, thread.c, thread_pthread.ci,
thread_pthread.h, thread_win32.ci, thread_win32.h, vm.h,
vm_dump.c, vm_evalbody.ci, vm_opts.h: fix comments and
copyright year.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13920 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-11-14 01:13:04 +03:00
|
|
|
|
@e put nil to stack.
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j スタックに nil をプッシュする。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
putnil
|
|
|
|
|
()
|
|
|
|
|
()
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
|
|
|
|
val = Qnil;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c put
|
|
|
|
|
@e put self.
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j スタックに self をプッシュする。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
putself
|
|
|
|
|
()
|
|
|
|
|
()
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
|
|
|
|
val = GET_SELF();
|
|
|
|
|
}
|
|
|
|
|
|
2008-05-14 06:31:28 +04:00
|
|
|
|
/**
|
|
|
|
|
@c put
|
2008-07-01 07:05:58 +04:00
|
|
|
|
@e put some object.
|
|
|
|
|
i.e. Fixnum, true, false, nil, and so on.
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j オブジェクト val をスタックにプッシュする。
|
2008-07-01 07:05:58 +04:00
|
|
|
|
i.e. Fixnum, true, false, nil, and so on.
|
2008-05-14 06:31:28 +04:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
2008-07-01 07:05:58 +04:00
|
|
|
|
putobject
|
|
|
|
|
(VALUE val)
|
2008-05-14 06:31:28 +04:00
|
|
|
|
()
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
2008-07-01 07:05:58 +04:00
|
|
|
|
/* */
|
2008-05-14 06:31:28 +04:00
|
|
|
|
}
|
|
|
|
|
|
2007-01-16 11:52:22 +03:00
|
|
|
|
/**
|
|
|
|
|
@c put
|
2008-07-01 07:05:58 +04:00
|
|
|
|
@e put special object. "value_type" is for expansion.
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j 特別なオブジェクト val をスタックにプッシュする。
|
|
|
|
|
オブジェクトの種類は value_type による.
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
2008-07-01 07:05:58 +04:00
|
|
|
|
putspecialobject
|
|
|
|
|
(rb_num_t value_type)
|
2007-01-16 11:52:22 +03:00
|
|
|
|
()
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
2010-10-31 16:11:02 +03:00
|
|
|
|
enum vm_special_object_type type = (enum vm_special_object_type)value_type;
|
2010-10-31 04:42:54 +03:00
|
|
|
|
|
|
|
|
|
switch (type) {
|
2008-07-01 07:05:58 +04:00
|
|
|
|
case VM_SPECIAL_OBJECT_VMCORE:
|
|
|
|
|
val = rb_mRubyVMFrozenCore;
|
|
|
|
|
break;
|
|
|
|
|
case VM_SPECIAL_OBJECT_CBASE:
|
* fix namespace issue on singleton class expressions. [Bug #10943]
* vm_core.h, method.h: remove rb_iseq_t::cref_stack. CREF is stored
to rb_method_definition_t::body.iseq_body.cref.
* vm_insnhelper.c: modify SVAR usage.
When calling ISEQ type method, push CREF information onto method
frame, SVAR located place. Before this fix, SVAR is simply nil.
After this patch, CREF (or NULL == Qfalse for not iseq methods)
is stored at the method invocation.
When SVAR is requierd, then put NODE_IF onto SVAR location,
and NDOE_IF::nd_reserved points CREF itself.
* vm.c (vm_cref_new, vm_cref_dump, vm_cref_new_toplevel): added.
* vm_insnhelper.c (vm_push_frame): accept CREF.
* method.h, vm_method.c (rb_add_method_iseq): added. This function
accepts iseq and CREF.
* class.c (clone_method): use rb_add_method_iseq().
* gc.c (mark_method_entry): mark method_entry::body.iseq_body.cref.
* iseq.c: remove CREF related codes.
* insns.def (getinlinecache/setinlinecache): CREF should be cache key
because a different CREF has a different namespace.
* node.c (rb_gc_mark_node): mark NODE_IF::nd_reserved for SVAR.
* proc.c: catch up changes.
* struct.c: ditto.
* insns.def: ditto.
* vm_args.c (raise_argument_error): ditto.
* vm_eval.c: ditto.
* test/ruby/test_class.rb: add a test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49874 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-03-06 15:24:58 +03:00
|
|
|
|
val = vm_get_cbase(GET_EP());
|
2008-07-01 07:05:58 +04:00
|
|
|
|
break;
|
2009-12-03 21:25:57 +03:00
|
|
|
|
case VM_SPECIAL_OBJECT_CONST_BASE:
|
* fix namespace issue on singleton class expressions. [Bug #10943]
* vm_core.h, method.h: remove rb_iseq_t::cref_stack. CREF is stored
to rb_method_definition_t::body.iseq_body.cref.
* vm_insnhelper.c: modify SVAR usage.
When calling ISEQ type method, push CREF information onto method
frame, SVAR located place. Before this fix, SVAR is simply nil.
After this patch, CREF (or NULL == Qfalse for not iseq methods)
is stored at the method invocation.
When SVAR is requierd, then put NODE_IF onto SVAR location,
and NDOE_IF::nd_reserved points CREF itself.
* vm.c (vm_cref_new, vm_cref_dump, vm_cref_new_toplevel): added.
* vm_insnhelper.c (vm_push_frame): accept CREF.
* method.h, vm_method.c (rb_add_method_iseq): added. This function
accepts iseq and CREF.
* class.c (clone_method): use rb_add_method_iseq().
* gc.c (mark_method_entry): mark method_entry::body.iseq_body.cref.
* iseq.c: remove CREF related codes.
* insns.def (getinlinecache/setinlinecache): CREF should be cache key
because a different CREF has a different namespace.
* node.c (rb_gc_mark_node): mark NODE_IF::nd_reserved for SVAR.
* proc.c: catch up changes.
* struct.c: ditto.
* insns.def: ditto.
* vm_args.c (raise_argument_error): ditto.
* vm_eval.c: ditto.
* test/ruby/test_class.rb: add a test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49874 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-03-06 15:24:58 +03:00
|
|
|
|
val = vm_get_const_base(GET_EP());
|
2009-12-03 21:25:57 +03:00
|
|
|
|
break;
|
2008-07-01 07:05:58 +04:00
|
|
|
|
default:
|
|
|
|
|
rb_bug("putspecialobject insn: unknown value_type");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c put
|
|
|
|
|
@e put iseq value.
|
|
|
|
|
@j put iseq value.
|
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
putiseq
|
|
|
|
|
(ISEQ iseq)
|
|
|
|
|
()
|
|
|
|
|
(VALUE ret)
|
|
|
|
|
{
|
2015-07-22 01:52:59 +03:00
|
|
|
|
ret = (VALUE)iseq;
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c put
|
|
|
|
|
@e put string val. string will be copied.
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j 文字列をコピーしてスタックにプッシュする。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
putstring
|
2007-07-02 16:49:35 +04:00
|
|
|
|
(VALUE str)
|
2007-01-16 11:52:22 +03:00
|
|
|
|
()
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
2009-02-18 08:33:36 +03:00
|
|
|
|
val = rb_str_resurrect(str);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c put
|
|
|
|
|
@e put concatenate strings
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j スタックトップの文字列を n 個連結し,結果をスタックにプッシュする。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
concatstrings
|
2007-05-03 13:09:14 +04:00
|
|
|
|
(rb_num_t num)
|
2007-01-16 11:52:22 +03:00
|
|
|
|
(...)
|
|
|
|
|
(VALUE val) // inc += 1 - num;
|
|
|
|
|
{
|
2011-08-01 07:10:02 +04:00
|
|
|
|
rb_num_t i = num - 1;
|
2007-01-16 11:52:22 +03:00
|
|
|
|
|
2011-08-01 07:10:02 +04:00
|
|
|
|
val = rb_str_resurrect(TOPN(i));
|
2009-06-30 11:46:44 +04:00
|
|
|
|
while (i-- > 0) {
|
2008-05-21 19:18:15 +04:00
|
|
|
|
const VALUE v = TOPN(i);
|
2015-09-29 10:37:40 +03:00
|
|
|
|
rb_str_append_literal(val, v);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
POPN(num);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c put
|
|
|
|
|
@e to_str
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j to_str の結果をスタックにプッシュする。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
tostring
|
|
|
|
|
()
|
|
|
|
|
(VALUE val)
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
|
|
|
|
val = rb_obj_as_string(val);
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-21 02:49:31 +03:00
|
|
|
|
/**
|
|
|
|
|
@c put
|
|
|
|
|
@e Freeze (dynamically) created strings.
|
|
|
|
|
@j (埋め込み)文字列を freeze する。もし、debug_info が与えられていれば、それを設定する。
|
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
freezestring
|
|
|
|
|
(VALUE debug_info)
|
|
|
|
|
(VALUE str)
|
|
|
|
|
(VALUE str)
|
|
|
|
|
{
|
|
|
|
|
if (!NIL_P(debug_info)) {
|
|
|
|
|
rb_ivar_set(str, id_debug_created_info, debug_info);
|
|
|
|
|
}
|
|
|
|
|
rb_str_freeze(str);
|
|
|
|
|
}
|
|
|
|
|
|
2007-01-16 11:52:22 +03:00
|
|
|
|
/**
|
|
|
|
|
@c put
|
|
|
|
|
@e to Regexp
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j 文字列 str を正規表現にコンパイルしてスタックにプッシュする。
|
|
|
|
|
コンパイル時,opt を正規表現のオプションとする。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
toregexp
|
2008-01-29 11:03:51 +03:00
|
|
|
|
(rb_num_t opt, rb_num_t cnt)
|
|
|
|
|
(...)
|
|
|
|
|
(VALUE val) // inc += 1 - cnt;
|
2007-01-16 11:52:22 +03:00
|
|
|
|
{
|
2008-01-29 11:03:51 +03:00
|
|
|
|
VALUE rb_reg_new_ary(VALUE ary, int options);
|
2009-06-30 11:46:44 +04:00
|
|
|
|
rb_num_t i;
|
2009-02-11 08:46:17 +03:00
|
|
|
|
const VALUE ary = rb_ary_tmp_new(cnt);
|
2008-01-29 11:03:51 +03:00
|
|
|
|
for (i = 0; i < cnt; i++) {
|
|
|
|
|
rb_ary_store(ary, cnt-i-1, TOPN(i));
|
|
|
|
|
}
|
|
|
|
|
POPN(cnt);
|
2009-06-30 11:46:44 +04:00
|
|
|
|
val = rb_reg_new_ary(ary, (int)opt);
|
2009-02-11 08:46:17 +03:00
|
|
|
|
rb_ary_clear(ary);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c put
|
|
|
|
|
@e put new array.
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j 新しい配列をスタック上の num 個の値で初期化して生成しプッシュする。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
newarray
|
2007-05-03 13:09:14 +04:00
|
|
|
|
(rb_num_t num)
|
2007-01-16 11:52:22 +03:00
|
|
|
|
(...)
|
|
|
|
|
(VALUE val) // inc += 1 - num;
|
|
|
|
|
{
|
|
|
|
|
val = rb_ary_new4((long)num, STACK_ADDR_FROM_TOP(num));
|
|
|
|
|
POPN(num);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c put
|
|
|
|
|
@e dup array
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j 配列 ary を dup してスタックにプッシュする。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
duparray
|
|
|
|
|
(VALUE ary)
|
|
|
|
|
()
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
2009-02-18 08:33:36 +03:00
|
|
|
|
val = rb_ary_resurrect(ary);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c put
|
|
|
|
|
@e expand array to num objects.
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j スタックトップのオブジェクトが配列であれば、それを展開する。
|
|
|
|
|
配列オブジェクトの要素数が num以下ならば、代わりに nil を積む。num以上なら、
|
|
|
|
|
num以上の要素は切り捨てる。
|
|
|
|
|
配列オブジェクトでなければ、num - 1 個の nil を積む。
|
|
|
|
|
もし flag が真なら、残り要素の配列を積む
|
|
|
|
|
flag: 0x01 - 最後を配列に
|
|
|
|
|
flag: 0x02 - postarg 用
|
2007-08-23 11:10:56 +04:00
|
|
|
|
flag: 0x04 - reverse?
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
expandarray
|
2007-05-03 13:09:14 +04:00
|
|
|
|
(rb_num_t num, rb_num_t flag)
|
2007-01-16 11:52:22 +03:00
|
|
|
|
(..., VALUE ary)
|
2008-01-23 20:17:23 +03:00
|
|
|
|
(...) // inc += num - 1 + (flag & 1 ? 1 : 0);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
{
|
2009-06-30 11:46:44 +04:00
|
|
|
|
vm_expandarray(GET_CFP(), ary, num, (int)flag);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c put
|
|
|
|
|
@e concat two arrays
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j 二つの配列 ary1, ary2 を連結しスタックへプッシュする。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
concatarray
|
|
|
|
|
()
|
|
|
|
|
(VALUE ary1, VALUE ary2st)
|
|
|
|
|
(VALUE ary)
|
|
|
|
|
{
|
2008-05-21 19:18:15 +04:00
|
|
|
|
const VALUE ary2 = ary2st;
|
2007-12-01 08:20:06 +03:00
|
|
|
|
VALUE tmp1 = rb_check_convert_type(ary1, T_ARRAY, "Array", "to_a");
|
|
|
|
|
VALUE tmp2 = rb_check_convert_type(ary2, T_ARRAY, "Array", "to_a");
|
2007-01-16 11:52:22 +03:00
|
|
|
|
|
2007-07-05 21:11:45 +04:00
|
|
|
|
if (NIL_P(tmp1)) {
|
|
|
|
|
tmp1 = rb_ary_new3(1, ary1);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
|
2007-07-05 21:11:45 +04:00
|
|
|
|
if (NIL_P(tmp2)) {
|
|
|
|
|
tmp2 = rb_ary_new3(1, ary2);
|
|
|
|
|
}
|
2007-01-16 11:52:22 +03:00
|
|
|
|
|
2007-07-05 21:11:45 +04:00
|
|
|
|
if (tmp1 == ary1) {
|
|
|
|
|
tmp1 = rb_ary_dup(ary1);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
2007-07-05 21:11:45 +04:00
|
|
|
|
ary = rb_ary_concat(tmp1, tmp2);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c put
|
|
|
|
|
@e splat array
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j 配列 ary に対して to_a を呼び出す。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
splatarray
|
|
|
|
|
(VALUE flag)
|
|
|
|
|
(VALUE ary)
|
|
|
|
|
(VALUE obj)
|
|
|
|
|
{
|
2007-12-01 08:20:06 +03:00
|
|
|
|
VALUE tmp = rb_check_convert_type(ary, T_ARRAY, "Array", "to_a");
|
2007-01-16 11:52:22 +03:00
|
|
|
|
if (NIL_P(tmp)) {
|
|
|
|
|
tmp = rb_ary_new3(1, ary);
|
|
|
|
|
}
|
2012-02-16 00:41:38 +04:00
|
|
|
|
else if (RTEST(flag)) {
|
|
|
|
|
tmp = rb_ary_dup(tmp);
|
|
|
|
|
}
|
2007-01-16 11:52:22 +03:00
|
|
|
|
obj = tmp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c put
|
|
|
|
|
@e put new Hash.
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j 新しいハッシュをスタックトップの n 個を初期値として生成する。
|
|
|
|
|
n はキーと値のペアなので 2 の倍数でなければならない。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
newhash
|
2007-05-03 13:09:14 +04:00
|
|
|
|
(rb_num_t num)
|
2007-01-16 11:52:22 +03:00
|
|
|
|
(...)
|
|
|
|
|
(VALUE val) // inc += 1 - num;
|
|
|
|
|
{
|
* compile.c, cont.c, gc.c, insns.def, iseq.c, iseq.h, process.c,
thread.c, vm.c, vm_core.h, vm_dump.c, vm_eval.c,
vm_insnhelper.c, vm_method.c, template/insns_info.inc.tmpl,
tool/instruction.rb: fixed types.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@25030 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2009-09-22 00:58:26 +04:00
|
|
|
|
rb_num_t i;
|
* probes.d: add DTrace probe declarations. [ruby-core:27448]
* array.c (empty_ary_alloc, ary_new): added array create DTrace probe.
* compile.c (rb_insns_name): allowing DTrace probes to access
instruction sequence name.
* Makefile.in: translate probes.d file to appropriate header file.
* common.mk: declare dependencies on the DTrace header.
* configure.in: add a test for existence of DTrace.
* eval.c (setup_exception): add a probe for when an exception is
raised.
* gc.c: Add DTrace probes for mark begin and end, and sweep begin and
end.
* hash.c (empty_hash_alloc): Add a probe for hash allocation.
* insns.def: Add probes for function entry and return.
* internal.h: function declaration for compile.c change.
* load.c (rb_f_load): add probes for `load` entry and exit, require
entry and exit, and wrapping search_required for load path search.
* object.c (rb_obj_alloc): added a probe for general object creation.
* parse.y (yycompile0): added a probe around parse and compile phase.
* string.c (empty_str_alloc, str_new): DTrace probes for string
allocation.
* test/dtrace/*: tests for DTrace probes.
* vm.c (vm_invoke_proc): add probes for function return on exception
raise, hash create, and instruction sequence execution.
* vm_core.h: add probe declarations for function entry and exit.
* vm_dump.c: add probes header file.
* vm_eval.c (vm_call0_cfunc, vm_call0_cfunc_with_frame): add probe on
function entry and return.
* vm_exec.c: expose instruction number to instruction name function.
* vm_insnshelper.c: add function entry and exit probes for cfunc
methods.
* vm_insnhelper.h: vm usage information is always collected, so
uncomment the functions.
12 19:14:50 2012 Akinori MUSHA <knu@iDaemons.org>
* configure.in (isinf, isnan): isinf() and isnan() are macros on
DragonFly which cannot be found by AC_REPLACE_FUNCS(). This
workaround enforces the fact that they exist on DragonFly.
12 15:59:38 2012 Shugo Maeda <shugo@ruby-lang.org>
* vm_core.h (rb_call_info_t::refinements), compile.c (new_callinfo),
vm_insnhelper.c (vm_search_method): revert r37616 because it's too
slow. [ruby-dev:46477]
* test/ruby/test_refinement.rb (test_inline_method_cache): skip
the test until the bug is fixed efficiently.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37631 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-11-13 01:52:12 +04:00
|
|
|
|
|
2015-10-29 08:32:57 +03:00
|
|
|
|
RUBY_DTRACE_CREATE_HOOK(HASH, num);
|
* probes.d: add DTrace probe declarations. [ruby-core:27448]
* array.c (empty_ary_alloc, ary_new): added array create DTrace probe.
* compile.c (rb_insns_name): allowing DTrace probes to access
instruction sequence name.
* Makefile.in: translate probes.d file to appropriate header file.
* common.mk: declare dependencies on the DTrace header.
* configure.in: add a test for existence of DTrace.
* eval.c (setup_exception): add a probe for when an exception is
raised.
* gc.c: Add DTrace probes for mark begin and end, and sweep begin and
end.
* hash.c (empty_hash_alloc): Add a probe for hash allocation.
* insns.def: Add probes for function entry and return.
* internal.h: function declaration for compile.c change.
* load.c (rb_f_load): add probes for `load` entry and exit, require
entry and exit, and wrapping search_required for load path search.
* object.c (rb_obj_alloc): added a probe for general object creation.
* parse.y (yycompile0): added a probe around parse and compile phase.
* string.c (empty_str_alloc, str_new): DTrace probes for string
allocation.
* test/dtrace/*: tests for DTrace probes.
* vm.c (vm_invoke_proc): add probes for function return on exception
raise, hash create, and instruction sequence execution.
* vm_core.h: add probe declarations for function entry and exit.
* vm_dump.c: add probes header file.
* vm_eval.c (vm_call0_cfunc, vm_call0_cfunc_with_frame): add probe on
function entry and return.
* vm_exec.c: expose instruction number to instruction name function.
* vm_insnshelper.c: add function entry and exit probes for cfunc
methods.
* vm_insnhelper.h: vm usage information is always collected, so
uncomment the functions.
12 19:14:50 2012 Akinori MUSHA <knu@iDaemons.org>
* configure.in (isinf, isnan): isinf() and isnan() are macros on
DragonFly which cannot be found by AC_REPLACE_FUNCS(). This
workaround enforces the fact that they exist on DragonFly.
12 15:59:38 2012 Shugo Maeda <shugo@ruby-lang.org>
* vm_core.h (rb_call_info_t::refinements), compile.c (new_callinfo),
vm_insnhelper.c (vm_search_method): revert r37616 because it's too
slow. [ruby-dev:46477]
* test/ruby/test_refinement.rb (test_inline_method_cache): skip
the test until the bug is fixed efficiently.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37631 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-11-13 01:52:12 +04:00
|
|
|
|
|
2007-01-16 11:52:22 +03:00
|
|
|
|
val = rb_hash_new();
|
|
|
|
|
|
|
|
|
|
for (i = num; i > 0; i -= 2) {
|
2008-05-21 19:18:15 +04:00
|
|
|
|
const VALUE v = TOPN(i - 2);
|
2008-05-22 07:52:22 +04:00
|
|
|
|
const VALUE k = TOPN(i - 1);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
rb_hash_aset(val, k, v);
|
|
|
|
|
}
|
|
|
|
|
POPN(num);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c put
|
|
|
|
|
@e put new Range object.(Range.new(low, high, flag))
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j Range.new(low, high, flag) のようなオブジェクトを生成しスタックにプッシュする。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
newrange
|
2007-05-03 13:09:14 +04:00
|
|
|
|
(rb_num_t flag)
|
2007-01-16 11:52:22 +03:00
|
|
|
|
(VALUE low, VALUE high)
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
2009-06-30 11:46:44 +04:00
|
|
|
|
val = rb_range_new(low, high, (int)flag);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**********************************************************/
|
|
|
|
|
/* deal with stack operation */
|
|
|
|
|
/**********************************************************/
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c stack
|
|
|
|
|
@e pop from stack.
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j スタックから一つポップする。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
pop
|
|
|
|
|
()
|
|
|
|
|
(VALUE val)
|
|
|
|
|
()
|
|
|
|
|
{
|
2011-11-27 12:24:19 +04:00
|
|
|
|
(void)val;
|
2007-01-16 11:52:22 +03:00
|
|
|
|
/* none */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c stack
|
|
|
|
|
@e duplicate stack top.
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j スタックトップをコピーしてスタックにプッシュする。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
dup
|
|
|
|
|
()
|
|
|
|
|
(VALUE val)
|
|
|
|
|
(VALUE val1, VALUE val2)
|
|
|
|
|
{
|
|
|
|
|
val1 = val2 = val;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c stack
|
|
|
|
|
@e duplicate stack top n elements
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j スタックトップの n 個をコピーしてスタックにプッシュする。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
dupn
|
2007-05-03 13:09:14 +04:00
|
|
|
|
(rb_num_t n)
|
2007-01-16 11:52:22 +03:00
|
|
|
|
(...)
|
|
|
|
|
(...) // inc += n;
|
|
|
|
|
{
|
2009-06-30 11:46:44 +04:00
|
|
|
|
rb_num_t i;
|
2007-01-16 11:52:22 +03:00
|
|
|
|
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
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j スタックトップの 2 つの値を交換する。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
swap
|
|
|
|
|
()
|
|
|
|
|
(VALUE val, VALUE obj)
|
|
|
|
|
(VALUE obj, VALUE val)
|
|
|
|
|
{
|
|
|
|
|
/* none */
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-25 03:20:39 +03:00
|
|
|
|
/**
|
|
|
|
|
@c stack
|
|
|
|
|
@e reverse stack top N order.
|
|
|
|
|
@j スタックトップの n 個の値を逆転する。
|
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
reverse
|
|
|
|
|
(rb_num_t n)
|
|
|
|
|
(...)
|
|
|
|
|
(...) // inc += 0;
|
|
|
|
|
{
|
|
|
|
|
rb_num_t i;
|
|
|
|
|
VALUE *sp = STACK_ADDR_FROM_TOP(n);
|
|
|
|
|
|
|
|
|
|
for (i=0; i<n/2; i++) {
|
|
|
|
|
VALUE v0 = sp[i];
|
|
|
|
|
VALUE v1 = TOPN(i);
|
|
|
|
|
sp[i] = v1;
|
|
|
|
|
TOPN(i) = v0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-01-16 11:52:22 +03:00
|
|
|
|
/**
|
|
|
|
|
@c stack
|
* blockinlining.c, compile.c, compile.h, debug.c, debug.h,
id.c, insnhelper.h, insns.def, thread.c, thread_pthread.ci,
thread_pthread.h, thread_win32.ci, thread_win32.h, vm.h,
vm_dump.c, vm_evalbody.ci, vm_opts.h: fix comments and
copyright year.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13920 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-11-14 01:13:04 +03:00
|
|
|
|
@e for stack caching.
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j スタックキャッシングの状態を調整するために必要な命令。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
reput
|
|
|
|
|
()
|
|
|
|
|
(..., VALUE val)
|
|
|
|
|
(VALUE val) // inc += 0;
|
|
|
|
|
{
|
|
|
|
|
/* none */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c stack
|
|
|
|
|
@e get nth stack value from stack top
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j スタックトップから n 個目をスタックにプッシュする。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
topn
|
2007-05-03 13:09:14 +04:00
|
|
|
|
(rb_num_t n)
|
2007-01-16 11:52:22 +03:00
|
|
|
|
(...)
|
|
|
|
|
(VALUE val) // inc += 1;
|
|
|
|
|
{
|
|
|
|
|
val = TOPN(n);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c stack
|
|
|
|
|
@e set Nth stack entry to stack top
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j スタックトップの値を n 個目のスタックにコピー
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
setn
|
2007-05-03 13:09:14 +04:00
|
|
|
|
(rb_num_t n)
|
2007-01-16 11:52:22 +03:00
|
|
|
|
(..., VALUE val)
|
|
|
|
|
(VALUE val) // inc += 0
|
|
|
|
|
{
|
2007-06-01 08:05:46 +04:00
|
|
|
|
TOPN(n-1) = val;
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c stack
|
2015-02-16 17:44:01 +03:00
|
|
|
|
@e empty current stack
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j current stack を空にする。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
2008-01-25 21:02:01 +03:00
|
|
|
|
adjuststack
|
|
|
|
|
(rb_num_t n)
|
2007-01-16 11:52:22 +03:00
|
|
|
|
(...)
|
2008-01-25 21:02:01 +03:00
|
|
|
|
(...) // inc -= n
|
2007-01-16 11:52:22 +03:00
|
|
|
|
{
|
2008-02-05 18:54:33 +03:00
|
|
|
|
DEC_SP(n);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**********************************************************/
|
|
|
|
|
/* deal with setting */
|
|
|
|
|
/**********************************************************/
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c setting
|
|
|
|
|
@e defined?
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j defined? を行う。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
defined
|
2010-10-31 04:42:54 +03:00
|
|
|
|
(rb_num_t op_type, VALUE obj, VALUE needstr)
|
2007-01-16 11:52:22 +03:00
|
|
|
|
(VALUE v)
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
2015-06-02 22:15:29 +03:00
|
|
|
|
val = vm_defined(th, GET_CFP(), op_type, obj, needstr, v);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
|
2012-08-08 11:52:19 +04:00
|
|
|
|
/**
|
|
|
|
|
@c setting
|
|
|
|
|
@e check `target' matches `pattern'.
|
|
|
|
|
`flag & VM_CHECKMATCH_TYPE_MASK' describe how to check pattern.
|
|
|
|
|
VM_CHECKMATCH_TYPE_WHEN: ignore target and check pattern is truthy.
|
|
|
|
|
VM_CHECKMATCH_TYPE_CASE: check `patten === target'.
|
|
|
|
|
VM_CHECKMATCH_TYPE_RESCUE: check `pattern.kind_op?(Module) && pattern == target'.
|
|
|
|
|
if `flag & VM_CHECKMATCH_ARRAY' is not 0, then `patten' is array of patterns.
|
|
|
|
|
@j see above comments.
|
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
checkmatch
|
|
|
|
|
(rb_num_t flag)
|
|
|
|
|
(VALUE target, VALUE pattern)
|
|
|
|
|
(VALUE result)
|
|
|
|
|
{
|
2012-08-28 18:05:52 +04:00
|
|
|
|
enum vm_check_match_type checkmatch_type =
|
|
|
|
|
(enum vm_check_match_type)(flag & VM_CHECKMATCH_TYPE_MASK);
|
2012-08-08 11:52:19 +04:00
|
|
|
|
result = Qfalse;
|
|
|
|
|
|
|
|
|
|
if (flag & VM_CHECKMATCH_ARRAY) {
|
|
|
|
|
int i;
|
|
|
|
|
for (i = 0; i < RARRAY_LEN(pattern); i++) {
|
2013-05-13 13:56:22 +04:00
|
|
|
|
if (RTEST(check_match(RARRAY_AREF(pattern, i), target, checkmatch_type))) {
|
2012-08-08 11:52:19 +04:00
|
|
|
|
result = Qtrue;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
2012-08-28 18:05:52 +04:00
|
|
|
|
if (RTEST(check_match(pattern, target, checkmatch_type))) {
|
2012-08-08 11:52:19 +04:00
|
|
|
|
result = Qtrue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
* rewrite method/block parameter fitting logic to optimize
keyword arguments/parameters and a splat argument.
[Feature #10440] (Details are described in this ticket)
Most of complex part is moved to vm_args.c.
Now, ISeq#to_a does not catch up new instruction format.
* vm_core.h: change iseq data structures.
* introduce rb_call_info_kw_arg_t to represent keyword arguments.
* add rb_call_info_t::kw_arg.
* rename rb_iseq_t::arg_post_len to rb_iseq_t::arg_post_num.
* rename rb_iseq_t::arg_keywords to arg_keyword_num.
* rename rb_iseq_t::arg_keyword to rb_iseq_t::arg_keyword_bits.
to represent keyword bitmap parameter index.
This bitmap parameter shows that which keyword parameters are given
or not given (0 for given).
It is refered by `checkkeyword' instruction described bellow.
* rename rb_iseq_t::arg_keyword_check to rb_iseq_t::arg_keyword_rest
to represent keyword rest parameter index.
* add rb_iseq_t::arg_keyword_default_values to represent default
keyword values.
* rename VM_CALL_ARGS_SKIP_SETUP to VM_CALL_ARGS_SIMPLE
to represent
(ci->flag & (SPLAT|BLOCKARG)) &&
ci->blockiseq == NULL &&
ci->kw_arg == NULL.
* vm_insnhelper.c, vm_args.c: rewrite with refactoring.
* rewrite splat argument code.
* rewrite keyword arguments/parameters code.
* merge method and block parameter fitting code into one code base.
* vm.c, vm_eval.c: catch up these changes.
* compile.c (new_callinfo): callinfo requires kw_arg parameter.
* compile.c (compile_array_): check the last argument Hash object or
not. If Hash object and all keys are Symbol literals, they are
compiled to keyword arguments.
* insns.def (checkkeyword): add new instruction.
This instruction check the availability of corresponding keyword.
For example, a method "def foo k1: 'v1'; end" is cimpiled to the
following instructions.
0000 checkkeyword 2, 0 # check k1 is given.
0003 branchif 9 # if given, jump to address #9
0005 putstring "v1"
0007 setlocal_OP__WC__0 3 # k1 = 'v1'
0009 trace 8
0011 putnil
0012 trace 16
0014 leave
* insns.def (opt_send_simple): removed and add new instruction
"opt_send_without_block".
* parse.y (new_args_tail_gen): reorder variables.
Before this patch, a method "def foo(k1: 1, kr1:, k2: 2, **krest, &b)"
has parameter variables "k1, kr1, k2, &b, internal_id, krest",
but this patch reorders to "kr1, k1, k2, internal_id, krest, &b".
(locate a block variable at last)
* parse.y (vtable_pop): added.
This function remove latest `n' variables from vtable.
* iseq.c: catch up iseq data changes.
* proc.c: ditto.
* class.c (keyword_error): export as rb_keyword_error().
* common.mk: depend vm_args.c for vm.o.
* hash.c (rb_hash_has_key): export.
* internal.h: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48239 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2014-11-02 21:02:55 +03:00
|
|
|
|
/**
|
|
|
|
|
@c setting
|
|
|
|
|
@e check keywords are specified or not.
|
|
|
|
|
@j キーワードが指定されているかどうかチェックする
|
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
checkkeyword
|
|
|
|
|
(lindex_t kw_bits_index, rb_num_t keyword_index)
|
|
|
|
|
()
|
|
|
|
|
(VALUE ret)
|
|
|
|
|
{
|
|
|
|
|
const VALUE *ep = GET_EP();
|
|
|
|
|
const VALUE kw_bits = *(ep - kw_bits_index);
|
|
|
|
|
|
|
|
|
|
if (FIXNUM_P(kw_bits)) {
|
|
|
|
|
int bits = FIX2INT(kw_bits);
|
|
|
|
|
ret = (bits & (0x01 << keyword_index)) ? Qfalse : Qtrue;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
assert(RB_TYPE_P(kw_bits, T_HASH));
|
|
|
|
|
ret = rb_hash_has_key(kw_bits, INT2FIX(keyword_index)) ? Qfalse : Qtrue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-01-16 11:52:22 +03:00
|
|
|
|
/**
|
|
|
|
|
@c setting
|
|
|
|
|
@e trace
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j trace 用の命令。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
trace
|
2008-07-01 22:13:22 +04:00
|
|
|
|
(rb_num_t nf)
|
2007-01-16 11:52:22 +03:00
|
|
|
|
()
|
|
|
|
|
()
|
|
|
|
|
{
|
2009-06-30 11:46:44 +04:00
|
|
|
|
rb_event_flag_t flag = (rb_event_flag_t)nf;
|
2008-07-01 22:13:22 +04:00
|
|
|
|
|
2012-12-01 06:13:06 +04:00
|
|
|
|
if (RUBY_DTRACE_METHOD_ENTRY_ENABLED() ||
|
|
|
|
|
RUBY_DTRACE_METHOD_RETURN_ENABLED() ||
|
|
|
|
|
RUBY_DTRACE_CMETHOD_ENTRY_ENABLED() ||
|
|
|
|
|
RUBY_DTRACE_CMETHOD_RETURN_ENABLED()) {
|
|
|
|
|
|
2015-10-29 08:32:57 +03:00
|
|
|
|
switch (flag) {
|
2012-12-01 06:13:06 +04:00
|
|
|
|
case RUBY_EVENT_CALL:
|
|
|
|
|
RUBY_DTRACE_METHOD_ENTRY_HOOK(th, 0, 0);
|
|
|
|
|
break;
|
|
|
|
|
case RUBY_EVENT_C_CALL:
|
|
|
|
|
RUBY_DTRACE_CMETHOD_ENTRY_HOOK(th, 0, 0);
|
|
|
|
|
break;
|
|
|
|
|
case RUBY_EVENT_RETURN:
|
|
|
|
|
RUBY_DTRACE_METHOD_RETURN_HOOK(th, 0, 0);
|
|
|
|
|
break;
|
|
|
|
|
case RUBY_EVENT_C_RETURN:
|
|
|
|
|
RUBY_DTRACE_CMETHOD_RETURN_HOOK(th, 0, 0);
|
|
|
|
|
break;
|
* probes.d: add DTrace probe declarations. [ruby-core:27448]
* array.c (empty_ary_alloc, ary_new): added array create DTrace probe.
* compile.c (rb_insns_name): allowing DTrace probes to access
instruction sequence name.
* Makefile.in: translate probes.d file to appropriate header file.
* common.mk: declare dependencies on the DTrace header.
* configure.in: add a test for existence of DTrace.
* eval.c (setup_exception): add a probe for when an exception is
raised.
* gc.c: Add DTrace probes for mark begin and end, and sweep begin and
end.
* hash.c (empty_hash_alloc): Add a probe for hash allocation.
* insns.def: Add probes for function entry and return.
* internal.h: function declaration for compile.c change.
* load.c (rb_f_load): add probes for `load` entry and exit, require
entry and exit, and wrapping search_required for load path search.
* object.c (rb_obj_alloc): added a probe for general object creation.
* parse.y (yycompile0): added a probe around parse and compile phase.
* string.c (empty_str_alloc, str_new): DTrace probes for string
allocation.
* test/dtrace/*: tests for DTrace probes.
* vm.c (vm_invoke_proc): add probes for function return on exception
raise, hash create, and instruction sequence execution.
* vm_core.h: add probe declarations for function entry and exit.
* vm_dump.c: add probes header file.
* vm_eval.c (vm_call0_cfunc, vm_call0_cfunc_with_frame): add probe on
function entry and return.
* vm_exec.c: expose instruction number to instruction name function.
* vm_insnshelper.c: add function entry and exit probes for cfunc
methods.
* vm_insnhelper.h: vm usage information is always collected, so
uncomment the functions.
12 19:14:50 2012 Akinori MUSHA <knu@iDaemons.org>
* configure.in (isinf, isnan): isinf() and isnan() are macros on
DragonFly which cannot be found by AC_REPLACE_FUNCS(). This
workaround enforces the fact that they exist on DragonFly.
12 15:59:38 2012 Shugo Maeda <shugo@ruby-lang.org>
* vm_core.h (rb_call_info_t::refinements), compile.c (new_callinfo),
vm_insnhelper.c (vm_search_method): revert r37616 because it's too
slow. [ruby-dev:46477]
* test/ruby/test_refinement.rb (test_inline_method_cache): skip
the test until the bug is fixed efficiently.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37631 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-11-13 01:52:12 +04:00
|
|
|
|
}
|
|
|
|
|
}
|
2012-11-30 02:28:16 +04:00
|
|
|
|
|
2012-11-20 13:48:24 +04:00
|
|
|
|
EXEC_EVENT_HOOK(th, flag, GET_SELF(), 0, 0 /* id and klass are resolved at callee */,
|
2013-03-12 12:02:17 +04:00
|
|
|
|
(flag & (RUBY_EVENT_RETURN | RUBY_EVENT_B_RETURN)) ? TOPN(0) : Qundef);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**********************************************************/
|
|
|
|
|
/* deal with control flow 1: class/module */
|
|
|
|
|
/**********************************************************/
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c class/module
|
|
|
|
|
@e
|
2014-05-26 19:00:23 +04:00
|
|
|
|
enter class definition scope. if super is Qfalse, and class
|
2007-01-16 11:52:22 +03:00
|
|
|
|
"klass" is defined, it's redefine. otherwise, define "klass" class.
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j クラス定義スコープへ移行する。
|
|
|
|
|
もし super が Qfalse で klassクラスが定義されていれば再定義である。
|
|
|
|
|
そうでなければ、klass クラスを定義する。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
defineclass
|
2012-12-20 12:13:53 +04:00
|
|
|
|
(ID id, ISEQ class_iseq, rb_num_t flags)
|
2007-01-16 11:52:22 +03:00
|
|
|
|
(VALUE cbase, VALUE super)
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
|
|
|
|
VALUE klass;
|
2012-12-20 12:13:53 +04:00
|
|
|
|
rb_vm_defineclass_type_t type = VM_DEFINECLASS_TYPE(flags);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
|
2012-12-20 12:13:53 +04:00
|
|
|
|
switch (type) {
|
|
|
|
|
case VM_DEFINECLASS_TYPE_CLASS:
|
2007-01-16 11:52:22 +03:00
|
|
|
|
/* val is dummy. classdef returns class scope value */
|
|
|
|
|
|
2012-12-20 12:13:53 +04:00
|
|
|
|
if (VM_DEFINECLASS_HAS_SUPERCLASS_P(flags) &&
|
|
|
|
|
!RB_TYPE_P(super, T_CLASS)) {
|
2015-06-29 11:38:04 +03:00
|
|
|
|
rb_raise(rb_eTypeError, "superclass must be a Class (%"PRIsVALUE" given)",
|
2015-06-28 20:10:00 +03:00
|
|
|
|
rb_obj_class(super));
|
2012-12-20 12:13:53 +04:00
|
|
|
|
}
|
|
|
|
|
|
2007-01-16 11:52:22 +03:00
|
|
|
|
if (super == Qnil) {
|
|
|
|
|
super = rb_cObject;
|
|
|
|
|
}
|
2007-02-25 19:29:26 +03:00
|
|
|
|
|
2008-04-03 14:59:44 +04:00
|
|
|
|
vm_check_if_namespace(cbase);
|
|
|
|
|
|
2007-01-16 11:52:22 +03:00
|
|
|
|
/* find klass */
|
2009-02-12 18:48:44 +03:00
|
|
|
|
rb_autoload_load(cbase, id);
|
2011-09-02 09:36:49 +04:00
|
|
|
|
if ((klass = vm_search_const_defined_class(cbase, id)) != 0) {
|
2007-01-16 11:52:22 +03:00
|
|
|
|
/* already exist */
|
2012-12-20 12:13:53 +04:00
|
|
|
|
klass = VM_DEFINECLASS_SCOPED_P(flags) ?
|
|
|
|
|
rb_public_const_get_at(klass, id) : rb_const_get_at(klass, id);
|
2012-07-28 06:15:48 +04:00
|
|
|
|
if (!RB_TYPE_P(klass, T_CLASS)) {
|
2015-06-29 11:38:04 +03:00
|
|
|
|
rb_raise(rb_eTypeError, "%"PRIsVALUE" is not a class", rb_id2str(id));
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (super != rb_cObject) {
|
|
|
|
|
VALUE tmp;
|
2007-09-28 10:21:46 +04:00
|
|
|
|
tmp = rb_class_real(RCLASS_SUPER(klass));
|
2007-01-16 11:52:22 +03:00
|
|
|
|
|
|
|
|
|
if (tmp != super) {
|
2015-06-29 11:38:04 +03:00
|
|
|
|
rb_raise(rb_eTypeError, "superclass mismatch for class %"PRIsVALUE"",
|
2015-06-28 20:10:26 +03:00
|
|
|
|
rb_id2str(id));
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* new class declaration */
|
|
|
|
|
klass = rb_define_class_id(id, super);
|
2009-07-30 11:45:42 +04:00
|
|
|
|
rb_set_class_path_string(klass, cbase, rb_id2str(id));
|
2007-01-16 11:52:22 +03:00
|
|
|
|
rb_const_set(cbase, id, klass);
|
|
|
|
|
rb_class_inherited(super, klass);
|
|
|
|
|
}
|
2007-07-02 06:59:37 +04:00
|
|
|
|
break;
|
2012-12-20 12:13:53 +04:00
|
|
|
|
case VM_DEFINECLASS_TYPE_SINGLETON_CLASS:
|
2007-01-16 11:52:22 +03:00
|
|
|
|
/* val is dummy. classdef returns class scope value */
|
|
|
|
|
/* super is dummy */
|
|
|
|
|
klass = rb_singleton_class(cbase);
|
2007-07-02 06:59:37 +04:00
|
|
|
|
break;
|
2012-12-20 12:13:53 +04:00
|
|
|
|
case VM_DEFINECLASS_TYPE_MODULE:
|
2007-01-16 11:52:22 +03:00
|
|
|
|
/* val is dummy. classdef returns class scope value */
|
|
|
|
|
/* super is dummy */
|
|
|
|
|
|
2008-04-03 14:59:44 +04:00
|
|
|
|
vm_check_if_namespace(cbase);
|
|
|
|
|
|
2007-01-16 11:52:22 +03:00
|
|
|
|
/* find klass */
|
2011-09-02 09:36:49 +04:00
|
|
|
|
if ((klass = vm_search_const_defined_class(cbase, id)) != 0) {
|
2012-12-20 12:13:53 +04:00
|
|
|
|
klass = VM_DEFINECLASS_SCOPED_P(flags) ?
|
2013-01-11 04:58:08 +04:00
|
|
|
|
rb_public_const_get_at(klass, id) : rb_const_get_at(klass, id);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
/* already exist */
|
2012-07-28 06:15:48 +04:00
|
|
|
|
if (!RB_TYPE_P(klass, T_MODULE)) {
|
2015-06-29 11:38:04 +03:00
|
|
|
|
rb_raise(rb_eTypeError, "%"PRIsVALUE" is not a module", rb_id2str(id));
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* new module declaration */
|
|
|
|
|
klass = rb_define_module_id(id);
|
2009-07-30 11:45:42 +04:00
|
|
|
|
rb_set_class_path_string(klass, cbase, rb_id2str(id));
|
2007-01-16 11:52:22 +03:00
|
|
|
|
rb_const_set(cbase, id, klass);
|
|
|
|
|
}
|
2007-07-02 06:59:37 +04:00
|
|
|
|
break;
|
|
|
|
|
default:
|
2012-12-20 12:13:53 +04:00
|
|
|
|
rb_bug("unknown defineclass type: %d", (int)type);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
2007-08-12 23:09:15 +04:00
|
|
|
|
|
2007-01-16 11:52:22 +03:00
|
|
|
|
/* enter scope */
|
* method.h: introduce rb_callable_method_entry_t to remove
rb_control_frame_t::klass.
[Bug #11278], [Bug #11279]
rb_method_entry_t data belong to modules/classes.
rb_method_entry_t::owner points defined module or class.
module M
def foo; end
end
In this case, owner is M.
rb_callable_method_entry_t data belong to only classes.
For modules, MRI creates corresponding T_ICLASS internally.
rb_callable_method_entry_t can also belong to T_ICLASS.
rb_callable_method_entry_t::defined_class points T_CLASS or
T_ICLASS.
rb_method_entry_t data for classes (not for modules) are also
rb_callable_method_entry_t data because it is completely same data.
In this case, rb_method_entry_t::owner == rb_method_entry_t::defined_class.
For example, there are classes C and D, and incldues M,
class C; include M; end
class D; include M; end
then, two T_ICLASS objects for C's super class and D's super class
will be created.
When C.new.foo is called, then M#foo is searcheed and
rb_callable_method_t data is used by VM to invoke M#foo.
rb_method_entry_t data is only one for M#foo.
However, rb_callable_method_entry_t data are two (and can be more).
It is proportional to the number of including (and prepending)
classes (the number of T_ICLASS which point to the module).
Now, created rb_callable_method_entry_t are collected when
the original module M was modified. We can think it is a cache.
We need to select what kind of method entry data is needed.
To operate definition, then you need to use rb_method_entry_t.
You can access them by the following functions.
* rb_method_entry(VALUE klass, ID id);
* rb_method_entry_with_refinements(VALUE klass, ID id);
* rb_method_entry_without_refinements(VALUE klass, ID id);
* rb_resolve_refined_method(VALUE refinements, const rb_method_entry_t *me);
To invoke methods, then you need to use rb_callable_method_entry_t
which you can get by the following APIs corresponding to the
above listed functions.
* rb_callable_method_entry(VALUE klass, ID id);
* rb_callable_method_entry_with_refinements(VALUE klass, ID id);
* rb_callable_method_entry_without_refinements(VALUE klass, ID id);
* rb_resolve_refined_method_callable(VALUE refinements, const rb_callable_method_entry_t *me);
VM pushes rb_callable_method_entry_t, so that rb_vm_frame_method_entry()
returns rb_callable_method_entry_t.
You can check a super class of current method by
rb_callable_method_entry_t::defined_class.
* method.h: renamed from rb_method_entry_t::klass to
rb_method_entry_t::owner.
* internal.h: add rb_classext_struct::callable_m_tbl to cache
rb_callable_method_entry_t data.
We need to consider abotu this field again because it is only
active for T_ICLASS.
* class.c (method_entry_i): ditto.
* class.c (rb_define_attr): rb_method_entry() does not takes
defiend_class_ptr.
* gc.c (mark_method_entry): mark RCLASS_CALLABLE_M_TBL() for T_ICLASS.
* cont.c (fiber_init): rb_control_frame_t::klass is removed.
* proc.c: fix `struct METHOD' data structure because
rb_callable_method_t has all information.
* vm_core.h: remove several fields.
* rb_control_frame_t::klass.
* rb_block_t::klass.
And catch up changes.
* eval.c: catch up changes.
* gc.c: ditto.
* insns.def: ditto.
* vm.c: ditto.
* vm_args.c: ditto.
* vm_backtrace.c: ditto.
* vm_dump.c: ditto.
* vm_eval.c: ditto.
* vm_insnhelper.c: ditto.
* vm_method.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-07-03 14:24:50 +03:00
|
|
|
|
vm_push_frame(th, class_iseq, VM_FRAME_MAGIC_CLASS, klass,
|
* fix namespace issue on singleton class expressions. [Bug #10943]
* vm_core.h, method.h: remove rb_iseq_t::cref_stack. CREF is stored
to rb_method_definition_t::body.iseq_body.cref.
* vm_insnhelper.c: modify SVAR usage.
When calling ISEQ type method, push CREF information onto method
frame, SVAR located place. Before this fix, SVAR is simply nil.
After this patch, CREF (or NULL == Qfalse for not iseq methods)
is stored at the method invocation.
When SVAR is requierd, then put NODE_IF onto SVAR location,
and NDOE_IF::nd_reserved points CREF itself.
* vm.c (vm_cref_new, vm_cref_dump, vm_cref_new_toplevel): added.
* vm_insnhelper.c (vm_push_frame): accept CREF.
* method.h, vm_method.c (rb_add_method_iseq): added. This function
accepts iseq and CREF.
* class.c (clone_method): use rb_add_method_iseq().
* gc.c (mark_method_entry): mark method_entry::body.iseq_body.cref.
* iseq.c: remove CREF related codes.
* insns.def (getinlinecache/setinlinecache): CREF should be cache key
because a different CREF has a different namespace.
* node.c (rb_gc_mark_node): mark NODE_IF::nd_reserved for SVAR.
* proc.c: catch up changes.
* struct.c: ditto.
* insns.def: ditto.
* vm_args.c (raise_argument_error): ditto.
* vm_eval.c: ditto.
* test/ruby/test_class.rb: add a test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49874 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-03-06 15:24:58 +03:00
|
|
|
|
VM_ENVVAL_BLOCK_PTR(GET_BLOCK_PTR()),
|
2015-11-13 23:02:19 +03:00
|
|
|
|
(VALUE)vm_cref_push(th, klass, NULL, FALSE),
|
2015-07-22 01:52:59 +03:00
|
|
|
|
class_iseq->body->iseq_encoded, GET_SP(),
|
|
|
|
|
class_iseq->body->local_size, class_iseq->body->stack_max);
|
* fix namespace issue on singleton class expressions. [Bug #10943]
* vm_core.h, method.h: remove rb_iseq_t::cref_stack. CREF is stored
to rb_method_definition_t::body.iseq_body.cref.
* vm_insnhelper.c: modify SVAR usage.
When calling ISEQ type method, push CREF information onto method
frame, SVAR located place. Before this fix, SVAR is simply nil.
After this patch, CREF (or NULL == Qfalse for not iseq methods)
is stored at the method invocation.
When SVAR is requierd, then put NODE_IF onto SVAR location,
and NDOE_IF::nd_reserved points CREF itself.
* vm.c (vm_cref_new, vm_cref_dump, vm_cref_new_toplevel): added.
* vm_insnhelper.c (vm_push_frame): accept CREF.
* method.h, vm_method.c (rb_add_method_iseq): added. This function
accepts iseq and CREF.
* class.c (clone_method): use rb_add_method_iseq().
* gc.c (mark_method_entry): mark method_entry::body.iseq_body.cref.
* iseq.c: remove CREF related codes.
* insns.def (getinlinecache/setinlinecache): CREF should be cache key
because a different CREF has a different namespace.
* node.c (rb_gc_mark_node): mark NODE_IF::nd_reserved for SVAR.
* proc.c: catch up changes.
* struct.c: ditto.
* insns.def: ditto.
* vm_args.c (raise_argument_error): ditto.
* vm_eval.c: ditto.
* test/ruby/test_class.rb: add a test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49874 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-03-06 15:24:58 +03:00
|
|
|
|
|
2007-01-16 11:52:22 +03:00
|
|
|
|
RESTORE_REGS();
|
|
|
|
|
NEXT_INSN();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**********************************************************/
|
|
|
|
|
/* deal with control flow 2: method/iterator */
|
|
|
|
|
/**********************************************************/
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c method/iterator
|
* insns.def (send, invokesuper, invokeblock, opt_*), vm_core.h:
use only a `ci' (rb_call_info_t) parameter instead of using
parameters such as `op_id', 'op_argc', `blockiseq' and flag.
These information are stored in rb_call_info_t at the compile
time.
This technique simplifies parameter passings at related
function calls (~10% speedups for simple mehtod invocation at
my machine).
`rb_call_info_t' also has new function pointer variable `call'.
This `call' variable enables to customize method (block)
invocation process for each place. However, it always call
`vm_call_general()' at this changes.
`rb_call_info_t' also has temporary variables for method
(block) invocation.
* vm_core.h, compile.c, insns.def: introduce VM_CALL_ARGS_SKIP_SETUP
VM_CALL macro. This flag indicates that this call can skip
caller_setup (block arg and splat arg).
* compile.c: catch up above changes.
* iseq.c: catch up above changes (especially for TS_CALLINFO).
* tool/instruction.rb: catch up above chagnes.
* vm_insnhelper.c, vm_insnhelper.h: ditto. Macros and functions
parameters are changed.
* vm_eval.c (vm_call0): ditto (it will be rewriten soon).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37180 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-10-14 20:59:05 +04:00
|
|
|
|
@e invoke method.
|
|
|
|
|
@j メソッド呼び出しを行う。ci に必要な情報が格納されている。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
send
|
2015-09-19 20:59:58 +03:00
|
|
|
|
(CALL_INFO ci, CALL_CACHE cc, ISEQ blockiseq)
|
2007-01-16 11:52:22 +03:00
|
|
|
|
(...)
|
2012-10-15 21:22:57 +04:00
|
|
|
|
(VALUE val) // inc += - (int)(ci->orig_argc + ((ci->flag & VM_CALL_ARGS_BLOCKARG) ? 1 : 0));
|
2007-01-16 11:52:22 +03:00
|
|
|
|
{
|
2015-09-19 20:59:58 +03:00
|
|
|
|
struct rb_calling_info calling;
|
2015-10-01 13:50:49 +03:00
|
|
|
|
|
|
|
|
|
vm_caller_setup_arg_block(th, reg_cfp, &calling, ci, blockiseq, FALSE);
|
2015-09-19 20:59:58 +03:00
|
|
|
|
vm_search_method(ci, cc, calling.recv = TOPN(calling.argc = ci->orig_argc));
|
|
|
|
|
CALL_METHOD(&calling, ci, cc);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
|
2013-11-10 01:17:06 +04:00
|
|
|
|
DEFINE_INSN
|
|
|
|
|
opt_str_freeze
|
|
|
|
|
(VALUE str)
|
|
|
|
|
()
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
|
|
|
|
if (BASIC_OP_UNREDEFINED_P(BOP_FREEZE, STRING_REDEFINED_OP_FLAG)) {
|
|
|
|
|
val = str;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
val = rb_funcall(rb_str_resurrect(str), idFreeze, 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-10-18 13:44:19 +04:00
|
|
|
|
/**
|
|
|
|
|
@c optimize
|
* rewrite method/block parameter fitting logic to optimize
keyword arguments/parameters and a splat argument.
[Feature #10440] (Details are described in this ticket)
Most of complex part is moved to vm_args.c.
Now, ISeq#to_a does not catch up new instruction format.
* vm_core.h: change iseq data structures.
* introduce rb_call_info_kw_arg_t to represent keyword arguments.
* add rb_call_info_t::kw_arg.
* rename rb_iseq_t::arg_post_len to rb_iseq_t::arg_post_num.
* rename rb_iseq_t::arg_keywords to arg_keyword_num.
* rename rb_iseq_t::arg_keyword to rb_iseq_t::arg_keyword_bits.
to represent keyword bitmap parameter index.
This bitmap parameter shows that which keyword parameters are given
or not given (0 for given).
It is refered by `checkkeyword' instruction described bellow.
* rename rb_iseq_t::arg_keyword_check to rb_iseq_t::arg_keyword_rest
to represent keyword rest parameter index.
* add rb_iseq_t::arg_keyword_default_values to represent default
keyword values.
* rename VM_CALL_ARGS_SKIP_SETUP to VM_CALL_ARGS_SIMPLE
to represent
(ci->flag & (SPLAT|BLOCKARG)) &&
ci->blockiseq == NULL &&
ci->kw_arg == NULL.
* vm_insnhelper.c, vm_args.c: rewrite with refactoring.
* rewrite splat argument code.
* rewrite keyword arguments/parameters code.
* merge method and block parameter fitting code into one code base.
* vm.c, vm_eval.c: catch up these changes.
* compile.c (new_callinfo): callinfo requires kw_arg parameter.
* compile.c (compile_array_): check the last argument Hash object or
not. If Hash object and all keys are Symbol literals, they are
compiled to keyword arguments.
* insns.def (checkkeyword): add new instruction.
This instruction check the availability of corresponding keyword.
For example, a method "def foo k1: 'v1'; end" is cimpiled to the
following instructions.
0000 checkkeyword 2, 0 # check k1 is given.
0003 branchif 9 # if given, jump to address #9
0005 putstring "v1"
0007 setlocal_OP__WC__0 3 # k1 = 'v1'
0009 trace 8
0011 putnil
0012 trace 16
0014 leave
* insns.def (opt_send_simple): removed and add new instruction
"opt_send_without_block".
* parse.y (new_args_tail_gen): reorder variables.
Before this patch, a method "def foo(k1: 1, kr1:, k2: 2, **krest, &b)"
has parameter variables "k1, kr1, k2, &b, internal_id, krest",
but this patch reorders to "kr1, k1, k2, internal_id, krest, &b".
(locate a block variable at last)
* parse.y (vtable_pop): added.
This function remove latest `n' variables from vtable.
* iseq.c: catch up iseq data changes.
* proc.c: ditto.
* class.c (keyword_error): export as rb_keyword_error().
* common.mk: depend vm_args.c for vm.o.
* hash.c (rb_hash_has_key): export.
* internal.h: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48239 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2014-11-02 21:02:55 +03:00
|
|
|
|
@e Invoke method without block
|
|
|
|
|
@j Invoke method without block
|
2012-10-18 13:44:19 +04:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
* rewrite method/block parameter fitting logic to optimize
keyword arguments/parameters and a splat argument.
[Feature #10440] (Details are described in this ticket)
Most of complex part is moved to vm_args.c.
Now, ISeq#to_a does not catch up new instruction format.
* vm_core.h: change iseq data structures.
* introduce rb_call_info_kw_arg_t to represent keyword arguments.
* add rb_call_info_t::kw_arg.
* rename rb_iseq_t::arg_post_len to rb_iseq_t::arg_post_num.
* rename rb_iseq_t::arg_keywords to arg_keyword_num.
* rename rb_iseq_t::arg_keyword to rb_iseq_t::arg_keyword_bits.
to represent keyword bitmap parameter index.
This bitmap parameter shows that which keyword parameters are given
or not given (0 for given).
It is refered by `checkkeyword' instruction described bellow.
* rename rb_iseq_t::arg_keyword_check to rb_iseq_t::arg_keyword_rest
to represent keyword rest parameter index.
* add rb_iseq_t::arg_keyword_default_values to represent default
keyword values.
* rename VM_CALL_ARGS_SKIP_SETUP to VM_CALL_ARGS_SIMPLE
to represent
(ci->flag & (SPLAT|BLOCKARG)) &&
ci->blockiseq == NULL &&
ci->kw_arg == NULL.
* vm_insnhelper.c, vm_args.c: rewrite with refactoring.
* rewrite splat argument code.
* rewrite keyword arguments/parameters code.
* merge method and block parameter fitting code into one code base.
* vm.c, vm_eval.c: catch up these changes.
* compile.c (new_callinfo): callinfo requires kw_arg parameter.
* compile.c (compile_array_): check the last argument Hash object or
not. If Hash object and all keys are Symbol literals, they are
compiled to keyword arguments.
* insns.def (checkkeyword): add new instruction.
This instruction check the availability of corresponding keyword.
For example, a method "def foo k1: 'v1'; end" is cimpiled to the
following instructions.
0000 checkkeyword 2, 0 # check k1 is given.
0003 branchif 9 # if given, jump to address #9
0005 putstring "v1"
0007 setlocal_OP__WC__0 3 # k1 = 'v1'
0009 trace 8
0011 putnil
0012 trace 16
0014 leave
* insns.def (opt_send_simple): removed and add new instruction
"opt_send_without_block".
* parse.y (new_args_tail_gen): reorder variables.
Before this patch, a method "def foo(k1: 1, kr1:, k2: 2, **krest, &b)"
has parameter variables "k1, kr1, k2, &b, internal_id, krest",
but this patch reorders to "kr1, k1, k2, internal_id, krest, &b".
(locate a block variable at last)
* parse.y (vtable_pop): added.
This function remove latest `n' variables from vtable.
* iseq.c: catch up iseq data changes.
* proc.c: ditto.
* class.c (keyword_error): export as rb_keyword_error().
* common.mk: depend vm_args.c for vm.o.
* hash.c (rb_hash_has_key): export.
* internal.h: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48239 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2014-11-02 21:02:55 +03:00
|
|
|
|
opt_send_without_block
|
2015-09-19 20:59:58 +03:00
|
|
|
|
(CALL_INFO ci, CALL_CACHE cc)
|
2012-10-18 13:44:19 +04:00
|
|
|
|
(...)
|
|
|
|
|
(VALUE val) // inc += -ci->orig_argc;
|
|
|
|
|
{
|
2015-09-19 20:59:58 +03:00
|
|
|
|
struct rb_calling_info calling;
|
|
|
|
|
calling.blockptr = NULL;
|
|
|
|
|
vm_search_method(ci, cc, calling.recv = TOPN(calling.argc = ci->orig_argc));
|
|
|
|
|
CALL_METHOD(&calling, ci, cc);
|
2012-10-18 13:44:19 +04:00
|
|
|
|
}
|
|
|
|
|
|
2007-01-16 11:52:22 +03:00
|
|
|
|
/**
|
|
|
|
|
@c method/iterator
|
|
|
|
|
@e super(args) # args.size => num
|
* insns.def (send, invokesuper, invokeblock, opt_*), vm_core.h:
use only a `ci' (rb_call_info_t) parameter instead of using
parameters such as `op_id', 'op_argc', `blockiseq' and flag.
These information are stored in rb_call_info_t at the compile
time.
This technique simplifies parameter passings at related
function calls (~10% speedups for simple mehtod invocation at
my machine).
`rb_call_info_t' also has new function pointer variable `call'.
This `call' variable enables to customize method (block)
invocation process for each place. However, it always call
`vm_call_general()' at this changes.
`rb_call_info_t' also has temporary variables for method
(block) invocation.
* vm_core.h, compile.c, insns.def: introduce VM_CALL_ARGS_SKIP_SETUP
VM_CALL macro. This flag indicates that this call can skip
caller_setup (block arg and splat arg).
* compile.c: catch up above changes.
* iseq.c: catch up above changes (especially for TS_CALLINFO).
* tool/instruction.rb: catch up above chagnes.
* vm_insnhelper.c, vm_insnhelper.h: ditto. Macros and functions
parameters are changed.
* vm_eval.c (vm_call0): ditto (it will be rewriten soon).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37180 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-10-14 20:59:05 +04:00
|
|
|
|
@j super を実行する。ci に必要な情報が格納されている。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
invokesuper
|
2015-09-19 20:59:58 +03:00
|
|
|
|
(CALL_INFO ci, CALL_CACHE cc, ISEQ blockiseq)
|
2007-01-16 11:52:22 +03:00
|
|
|
|
(...)
|
2012-10-15 21:22:57 +04:00
|
|
|
|
(VALUE val) // inc += - (int)(ci->orig_argc + ((ci->flag & VM_CALL_ARGS_BLOCKARG) ? 1 : 0));
|
2007-01-16 11:52:22 +03:00
|
|
|
|
{
|
2015-09-19 20:59:58 +03:00
|
|
|
|
struct rb_calling_info calling;
|
|
|
|
|
calling.argc = ci->orig_argc;
|
|
|
|
|
|
2015-10-01 13:50:49 +03:00
|
|
|
|
vm_caller_setup_arg_block(th, reg_cfp, &calling, ci, blockiseq, TRUE);
|
2015-09-19 20:59:58 +03:00
|
|
|
|
calling.recv = GET_SELF();
|
|
|
|
|
vm_search_super_method(th, GET_CFP(), &calling, ci, cc);
|
|
|
|
|
CALL_METHOD(&calling, ci, cc);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c method/iterator
|
* insns.def (send, invokesuper, invokeblock, opt_*), vm_core.h:
use only a `ci' (rb_call_info_t) parameter instead of using
parameters such as `op_id', 'op_argc', `blockiseq' and flag.
These information are stored in rb_call_info_t at the compile
time.
This technique simplifies parameter passings at related
function calls (~10% speedups for simple mehtod invocation at
my machine).
`rb_call_info_t' also has new function pointer variable `call'.
This `call' variable enables to customize method (block)
invocation process for each place. However, it always call
`vm_call_general()' at this changes.
`rb_call_info_t' also has temporary variables for method
(block) invocation.
* vm_core.h, compile.c, insns.def: introduce VM_CALL_ARGS_SKIP_SETUP
VM_CALL macro. This flag indicates that this call can skip
caller_setup (block arg and splat arg).
* compile.c: catch up above changes.
* iseq.c: catch up above changes (especially for TS_CALLINFO).
* tool/instruction.rb: catch up above chagnes.
* vm_insnhelper.c, vm_insnhelper.h: ditto. Macros and functions
parameters are changed.
* vm_eval.c (vm_call0): ditto (it will be rewriten soon).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37180 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-10-14 20:59:05 +04:00
|
|
|
|
@e yield(args)
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j yield を実行する。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
invokeblock
|
* insns.def (send, invokesuper, invokeblock, opt_*), vm_core.h:
use only a `ci' (rb_call_info_t) parameter instead of using
parameters such as `op_id', 'op_argc', `blockiseq' and flag.
These information are stored in rb_call_info_t at the compile
time.
This technique simplifies parameter passings at related
function calls (~10% speedups for simple mehtod invocation at
my machine).
`rb_call_info_t' also has new function pointer variable `call'.
This `call' variable enables to customize method (block)
invocation process for each place. However, it always call
`vm_call_general()' at this changes.
`rb_call_info_t' also has temporary variables for method
(block) invocation.
* vm_core.h, compile.c, insns.def: introduce VM_CALL_ARGS_SKIP_SETUP
VM_CALL macro. This flag indicates that this call can skip
caller_setup (block arg and splat arg).
* compile.c: catch up above changes.
* iseq.c: catch up above changes (especially for TS_CALLINFO).
* tool/instruction.rb: catch up above chagnes.
* vm_insnhelper.c, vm_insnhelper.h: ditto. Macros and functions
parameters are changed.
* vm_eval.c (vm_call0): ditto (it will be rewriten soon).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37180 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-10-14 20:59:05 +04:00
|
|
|
|
(CALL_INFO ci)
|
2007-01-16 11:52:22 +03:00
|
|
|
|
(...)
|
* insns.def (send, invokesuper, invokeblock, opt_*), vm_core.h:
use only a `ci' (rb_call_info_t) parameter instead of using
parameters such as `op_id', 'op_argc', `blockiseq' and flag.
These information are stored in rb_call_info_t at the compile
time.
This technique simplifies parameter passings at related
function calls (~10% speedups for simple mehtod invocation at
my machine).
`rb_call_info_t' also has new function pointer variable `call'.
This `call' variable enables to customize method (block)
invocation process for each place. However, it always call
`vm_call_general()' at this changes.
`rb_call_info_t' also has temporary variables for method
(block) invocation.
* vm_core.h, compile.c, insns.def: introduce VM_CALL_ARGS_SKIP_SETUP
VM_CALL macro. This flag indicates that this call can skip
caller_setup (block arg and splat arg).
* compile.c: catch up above changes.
* iseq.c: catch up above changes (especially for TS_CALLINFO).
* tool/instruction.rb: catch up above chagnes.
* vm_insnhelper.c, vm_insnhelper.h: ditto. Macros and functions
parameters are changed.
* vm_eval.c (vm_call0): ditto (it will be rewriten soon).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37180 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-10-14 20:59:05 +04:00
|
|
|
|
(VALUE val) // inc += 1 - ci->orig_argc;
|
2007-01-16 11:52:22 +03:00
|
|
|
|
{
|
2015-09-19 20:59:58 +03:00
|
|
|
|
struct rb_calling_info calling;
|
|
|
|
|
calling.argc = ci->orig_argc;
|
|
|
|
|
calling.blockptr = NULL;
|
|
|
|
|
calling.recv = GET_SELF();
|
|
|
|
|
|
|
|
|
|
val = vm_invoke_block(th, GET_CFP(), &calling, ci);
|
2007-08-06 15:36:30 +04:00
|
|
|
|
if (val == Qundef) {
|
2007-01-16 11:52:22 +03:00
|
|
|
|
RESTORE_REGS();
|
|
|
|
|
NEXT_INSN();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c method/iterator
|
|
|
|
|
@e return from this scope.
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j このスコープから抜ける。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
leave
|
|
|
|
|
()
|
|
|
|
|
(VALUE val)
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
|
|
|
|
if (OPT_CHECKED_RUN) {
|
2015-08-05 08:43:58 +03:00
|
|
|
|
const VALUE *const bp = vm_base_ptr(reg_cfp);
|
|
|
|
|
if (reg_cfp->sp != bp) {
|
2008-07-12 17:17:29 +04:00
|
|
|
|
rb_bug("Stack consistency error (sp: %"PRIdPTRDIFF", bp: %"PRIdPTRDIFF")",
|
2015-08-05 08:43:58 +03:00
|
|
|
|
VM_SP_CNT(th, reg_cfp->sp), VM_SP_CNT(th, bp));
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-07-19 18:19:40 +04:00
|
|
|
|
RUBY_VM_CHECK_INTS(th);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
|
* vm_core.h: remove VM_FRAME_MAGIC_FINISH (finish frame type).
Before this commit:
`finish frame' was place holder which indicates that VM loop
needs to return function.
If a C method calls a Ruby methods (a method written by Ruby),
then VM loop will be (re-)invoked. When the Ruby method returns,
then also VM loop should be escaped. `finish frame' has only
one instruction `finish', which returns VM loop function.
VM loop function executes `finish' instruction, then VM loop
function returns itself.
With such mechanism, `leave' instruction (which returns one
frame from current scope) doesn't need to check that this `leave'
should also return from VM loop function.
Strictly, one branch can be removed from `leave' instructon.
Consideration:
However, pushing the `finish frame' needs costs because
it needs several memory accesses. The number of pushing
`finish frame' is greater than I had assumed. Of course,
pushing `finish frame' consumes additional control frame.
Moreover, recent processors has good branch prediction,
with which we can ignore such trivial checking.
After this commit:
Finally, I decide to remove `finish frame' and `finish'
instruction. Some parts of VM depend on `finish frame',
so the new frame flag VM_FRAME_FLAG_FINISH is introduced.
If this frame should escape from VM function loop, then
the result of VM_FRAME_TYPE_FINISH_P(cfp) is true.
`leave' instruction checks this flag every time.
I measured performance on it. However on my environments,
it improves some benchmarks and slows some benchmarks down.
Maybe it is because of C compiler optimization parameters.
I'll re-visit here if this cause problems.
* insns.def (leave, finish): remove finish instruction.
* vm.c, vm_eval.c, vm_exec.c, vm_backtrace.c, vm_dump.c:
apply above changes.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36099 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-06-15 14:22:34 +04:00
|
|
|
|
if (UNLIKELY(VM_FRAME_TYPE_FINISH_P(GET_CFP()))) {
|
2012-08-07 15:13:57 +04:00
|
|
|
|
vm_pop_frame(th);
|
|
|
|
|
|
2007-06-27 12:21:21 +04:00
|
|
|
|
#if OPT_CALL_THREADED_CODE
|
2012-08-07 15:13:57 +04:00
|
|
|
|
th->retval = val;
|
|
|
|
|
return 0;
|
2007-06-27 12:21:21 +04:00
|
|
|
|
#else
|
* vm_core.h: remove VM_FRAME_MAGIC_FINISH (finish frame type).
Before this commit:
`finish frame' was place holder which indicates that VM loop
needs to return function.
If a C method calls a Ruby methods (a method written by Ruby),
then VM loop will be (re-)invoked. When the Ruby method returns,
then also VM loop should be escaped. `finish frame' has only
one instruction `finish', which returns VM loop function.
VM loop function executes `finish' instruction, then VM loop
function returns itself.
With such mechanism, `leave' instruction (which returns one
frame from current scope) doesn't need to check that this `leave'
should also return from VM loop function.
Strictly, one branch can be removed from `leave' instructon.
Consideration:
However, pushing the `finish frame' needs costs because
it needs several memory accesses. The number of pushing
`finish frame' is greater than I had assumed. Of course,
pushing `finish frame' consumes additional control frame.
Moreover, recent processors has good branch prediction,
with which we can ignore such trivial checking.
After this commit:
Finally, I decide to remove `finish frame' and `finish'
instruction. Some parts of VM depend on `finish frame',
so the new frame flag VM_FRAME_FLAG_FINISH is introduced.
If this frame should escape from VM function loop, then
the result of VM_FRAME_TYPE_FINISH_P(cfp) is true.
`leave' instruction checks this flag every time.
I measured performance on it. However on my environments,
it improves some benchmarks and slows some benchmarks down.
Maybe it is because of C compiler optimization parameters.
I'll re-visit here if this cause problems.
* insns.def (leave, finish): remove finish instruction.
* vm.c, vm_eval.c, vm_exec.c, vm_backtrace.c, vm_dump.c:
apply above changes.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36099 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-06-15 14:22:34 +04:00
|
|
|
|
return val;
|
2007-06-27 12:21:21 +04:00
|
|
|
|
#endif
|
* vm_core.h: remove VM_FRAME_MAGIC_FINISH (finish frame type).
Before this commit:
`finish frame' was place holder which indicates that VM loop
needs to return function.
If a C method calls a Ruby methods (a method written by Ruby),
then VM loop will be (re-)invoked. When the Ruby method returns,
then also VM loop should be escaped. `finish frame' has only
one instruction `finish', which returns VM loop function.
VM loop function executes `finish' instruction, then VM loop
function returns itself.
With such mechanism, `leave' instruction (which returns one
frame from current scope) doesn't need to check that this `leave'
should also return from VM loop function.
Strictly, one branch can be removed from `leave' instructon.
Consideration:
However, pushing the `finish frame' needs costs because
it needs several memory accesses. The number of pushing
`finish frame' is greater than I had assumed. Of course,
pushing `finish frame' consumes additional control frame.
Moreover, recent processors has good branch prediction,
with which we can ignore such trivial checking.
After this commit:
Finally, I decide to remove `finish frame' and `finish'
instruction. Some parts of VM depend on `finish frame',
so the new frame flag VM_FRAME_FLAG_FINISH is introduced.
If this frame should escape from VM function loop, then
the result of VM_FRAME_TYPE_FINISH_P(cfp) is true.
`leave' instruction checks this flag every time.
I measured performance on it. However on my environments,
it improves some benchmarks and slows some benchmarks down.
Maybe it is because of C compiler optimization parameters.
I'll re-visit here if this cause problems.
* insns.def (leave, finish): remove finish instruction.
* vm.c, vm_eval.c, vm_exec.c, vm_backtrace.c, vm_dump.c:
apply above changes.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36099 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-06-15 14:22:34 +04:00
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
vm_pop_frame(th);
|
|
|
|
|
RESTORE_REGS();
|
|
|
|
|
}
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**********************************************************/
|
|
|
|
|
/* deal with control flow 3: exception */
|
|
|
|
|
/**********************************************************/
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c exception
|
|
|
|
|
@e longjump
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j 大域ジャンプを行う。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
throw
|
2007-05-03 13:09:14 +04:00
|
|
|
|
(rb_num_t throw_state)
|
2007-01-16 11:52:22 +03:00
|
|
|
|
(VALUE throwobj)
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
2012-07-19 18:19:40 +04:00
|
|
|
|
RUBY_VM_CHECK_INTS(th);
|
2007-08-06 15:36:30 +04:00
|
|
|
|
val = vm_throw(th, GET_CFP(), throw_state, throwobj);
|
|
|
|
|
THROW_EXCEPTION(val);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
/* unreachable */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**********************************************************/
|
|
|
|
|
/* deal with control flow 4: local jump */
|
|
|
|
|
/**********************************************************/
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c jump
|
|
|
|
|
@e set PC to (PC + dst).
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j PC を (PC + dst) にする。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
jump
|
|
|
|
|
(OFFSET dst)
|
|
|
|
|
()
|
|
|
|
|
()
|
|
|
|
|
{
|
2012-07-19 18:19:40 +04:00
|
|
|
|
RUBY_VM_CHECK_INTS(th);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
JUMP(dst);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c jump
|
|
|
|
|
@e if val is not false or nil, set PC to (PC + dst).
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j もし val が false か nil でなければ、PC を (PC + dst) にする。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
branchif
|
|
|
|
|
(OFFSET dst)
|
|
|
|
|
(VALUE val)
|
|
|
|
|
()
|
|
|
|
|
{
|
|
|
|
|
if (RTEST(val)) {
|
2012-07-19 18:19:40 +04:00
|
|
|
|
RUBY_VM_CHECK_INTS(th);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
JUMP(dst);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c jump
|
|
|
|
|
@e if val is false or nil, set PC to (PC + dst).
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j もし val が false か nil ならば、PC を (PC + dst) にする。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
branchunless
|
|
|
|
|
(OFFSET dst)
|
|
|
|
|
(VALUE val)
|
|
|
|
|
()
|
|
|
|
|
{
|
|
|
|
|
if (!RTEST(val)) {
|
2012-07-19 18:19:40 +04:00
|
|
|
|
RUBY_VM_CHECK_INTS(th);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
JUMP(dst);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-22 09:30:12 +03:00
|
|
|
|
/**
|
|
|
|
|
@c jump
|
|
|
|
|
@e if val is nil, set PC to (PC + dst).
|
|
|
|
|
@j もし val が nil ならば、PC を (PC + dst) にする。
|
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
branchnil
|
|
|
|
|
(OFFSET dst)
|
|
|
|
|
(VALUE val)
|
|
|
|
|
()
|
|
|
|
|
{
|
|
|
|
|
if (NIL_P(val)) {
|
|
|
|
|
RUBY_VM_CHECK_INTS(th);
|
|
|
|
|
JUMP(dst);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-01-16 11:52:22 +03:00
|
|
|
|
|
|
|
|
|
/**********************************************************/
|
|
|
|
|
/* for optimize */
|
|
|
|
|
/**********************************************************/
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c optimize
|
2013-08-21 10:51:51 +04:00
|
|
|
|
@e push inline-cached value and go to dst if it is valid
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j インラインキャッシュが有効なら、値をスタックにプッシュして dst へジャンプする。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
getinlinecache
|
2009-07-13 08:44:20 +04:00
|
|
|
|
(OFFSET dst, IC ic)
|
2007-01-16 11:52:22 +03:00
|
|
|
|
()
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
* fix namespace issue on singleton class expressions. [Bug #10943]
* vm_core.h, method.h: remove rb_iseq_t::cref_stack. CREF is stored
to rb_method_definition_t::body.iseq_body.cref.
* vm_insnhelper.c: modify SVAR usage.
When calling ISEQ type method, push CREF information onto method
frame, SVAR located place. Before this fix, SVAR is simply nil.
After this patch, CREF (or NULL == Qfalse for not iseq methods)
is stored at the method invocation.
When SVAR is requierd, then put NODE_IF onto SVAR location,
and NDOE_IF::nd_reserved points CREF itself.
* vm.c (vm_cref_new, vm_cref_dump, vm_cref_new_toplevel): added.
* vm_insnhelper.c (vm_push_frame): accept CREF.
* method.h, vm_method.c (rb_add_method_iseq): added. This function
accepts iseq and CREF.
* class.c (clone_method): use rb_add_method_iseq().
* gc.c (mark_method_entry): mark method_entry::body.iseq_body.cref.
* iseq.c: remove CREF related codes.
* insns.def (getinlinecache/setinlinecache): CREF should be cache key
because a different CREF has a different namespace.
* node.c (rb_gc_mark_node): mark NODE_IF::nd_reserved for SVAR.
* proc.c: catch up changes.
* struct.c: ditto.
* insns.def: ditto.
* vm_args.c (raise_argument_error): ditto.
* vm_eval.c: ditto.
* test/ruby/test_class.rb: add a test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49874 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-03-06 15:24:58 +03:00
|
|
|
|
if (ic->ic_serial == GET_GLOBAL_CONSTANT_STATE() &&
|
2015-10-30 01:43:45 +03:00
|
|
|
|
(ic->ic_cref == NULL || ic->ic_cref == rb_vm_get_cref(GET_EP()))) {
|
2009-09-12 21:16:27 +04:00
|
|
|
|
val = ic->ic_value.value;
|
2007-01-16 11:52:22 +03:00
|
|
|
|
JUMP(dst);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* none */
|
|
|
|
|
val = Qnil;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c optimize
|
|
|
|
|
@e set inline cache
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j インラインキャッシュの値を設定する。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
setinlinecache
|
2010-02-24 20:06:15 +03:00
|
|
|
|
(IC ic)
|
2007-01-16 11:52:22 +03:00
|
|
|
|
(VALUE val)
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
2015-10-30 00:21:13 +03:00
|
|
|
|
VM_ASSERT(ic->ic_value.value != Qundef);
|
2009-09-12 21:16:27 +04:00
|
|
|
|
ic->ic_value.value = val;
|
2013-12-09 14:51:02 +04:00
|
|
|
|
ic->ic_serial = GET_GLOBAL_CONSTANT_STATE() - ruby_vm_const_missing_count;
|
2015-10-30 01:43:45 +03:00
|
|
|
|
ic->ic_cref = vm_get_const_key_cref(GET_EP());
|
2009-01-15 18:31:43 +03:00
|
|
|
|
ruby_vm_const_missing_count = 0;
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
|
2013-08-20 21:41:13 +04:00
|
|
|
|
/**
|
|
|
|
|
@c optimize
|
2013-08-21 10:51:51 +04:00
|
|
|
|
@e run iseq only once
|
2013-08-20 21:41:13 +04:00
|
|
|
|
@j once を実現する。
|
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
once
|
|
|
|
|
(ISEQ iseq, IC ic)
|
|
|
|
|
()
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
|
|
|
|
union iseq_inline_storage_entry *is = (union iseq_inline_storage_entry *)ic;
|
|
|
|
|
|
iseq_inline_storage_entry: 24=>16 bytes on 64-bit
We may tag the running_thread pointer to avoid making the "once" struct
bigger than "struct iseq_inline_cache_entry".
This only saves a small amount with "valgrind ruby -e exit"
before:
total heap usage: 48,122 allocs, 19,248 frees, 8,110,149 bytes allocated
after:
total heap usage: 48,122 allocs, 19,253 frees, 8,099,197 bytes allocated
* insns.def (once): define and use fake RUNNING_THREAD_ONCE_DONE
pointer to indicate is->once.running_thread is done.
* vm_core.h (iseq_inline_storage_entry): remove done field,
allowing the union to be reduced from 24=>16 bytes on 64-bit
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47542 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2014-09-11 23:25:32 +04:00
|
|
|
|
#define RUNNING_THREAD_ONCE_DONE ((rb_thread_t *)(0x1))
|
2013-08-20 21:41:13 +04:00
|
|
|
|
retry:
|
iseq_inline_storage_entry: 24=>16 bytes on 64-bit
We may tag the running_thread pointer to avoid making the "once" struct
bigger than "struct iseq_inline_cache_entry".
This only saves a small amount with "valgrind ruby -e exit"
before:
total heap usage: 48,122 allocs, 19,248 frees, 8,110,149 bytes allocated
after:
total heap usage: 48,122 allocs, 19,253 frees, 8,099,197 bytes allocated
* insns.def (once): define and use fake RUNNING_THREAD_ONCE_DONE
pointer to indicate is->once.running_thread is done.
* vm_core.h (iseq_inline_storage_entry): remove done field,
allowing the union to be reduced from 24=>16 bytes on 64-bit
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47542 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2014-09-11 23:25:32 +04:00
|
|
|
|
if (is->once.running_thread == RUNNING_THREAD_ONCE_DONE) {
|
|
|
|
|
val = is->once.value;
|
|
|
|
|
}
|
|
|
|
|
else if (is->once.running_thread == NULL) {
|
|
|
|
|
is->once.running_thread = th;
|
|
|
|
|
val = is->once.value = rb_ensure(vm_once_exec, (VALUE)iseq, vm_once_clear, (VALUE)is);
|
|
|
|
|
/* is->once.running_thread is cleared by vm_once_clear() */
|
|
|
|
|
is->once.running_thread = RUNNING_THREAD_ONCE_DONE; /* success */
|
|
|
|
|
rb_iseq_add_mark_object(GET_ISEQ(), val);
|
|
|
|
|
}
|
|
|
|
|
else if (is->once.running_thread == th) {
|
|
|
|
|
/* recursive once */
|
|
|
|
|
val = vm_once_exec((VALUE)iseq);
|
2013-08-20 21:41:13 +04:00
|
|
|
|
}
|
|
|
|
|
else {
|
iseq_inline_storage_entry: 24=>16 bytes on 64-bit
We may tag the running_thread pointer to avoid making the "once" struct
bigger than "struct iseq_inline_cache_entry".
This only saves a small amount with "valgrind ruby -e exit"
before:
total heap usage: 48,122 allocs, 19,248 frees, 8,110,149 bytes allocated
after:
total heap usage: 48,122 allocs, 19,253 frees, 8,099,197 bytes allocated
* insns.def (once): define and use fake RUNNING_THREAD_ONCE_DONE
pointer to indicate is->once.running_thread is done.
* vm_core.h (iseq_inline_storage_entry): remove done field,
allowing the union to be reduced from 24=>16 bytes on 64-bit
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47542 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2014-09-11 23:25:32 +04:00
|
|
|
|
/* waiting for finish */
|
|
|
|
|
RUBY_VM_CHECK_INTS(th);
|
|
|
|
|
rb_thread_schedule();
|
|
|
|
|
goto retry;
|
2013-08-20 21:41:13 +04:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-01-16 11:52:22 +03:00
|
|
|
|
/**
|
|
|
|
|
@c optimize
|
2013-08-21 10:51:51 +04:00
|
|
|
|
@e case dispatcher, jump by table if possible
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j case 文で、可能なら表引きでジャンプする。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
opt_case_dispatch
|
|
|
|
|
(CDHASH hash, OFFSET else_offset)
|
|
|
|
|
(..., VALUE key)
|
|
|
|
|
() // inc += -1;
|
|
|
|
|
{
|
2010-09-09 17:40:14 +04:00
|
|
|
|
switch(TYPE(key)) {
|
|
|
|
|
case T_FLOAT: {
|
|
|
|
|
double ival;
|
|
|
|
|
if (modf(RFLOAT_VALUE(key), &ival) == 0.0) {
|
|
|
|
|
key = FIXABLE(ival) ? LONG2FIX((long)ival) : rb_dbl2big(ival);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
2010-09-09 17:40:14 +04:00
|
|
|
|
}
|
|
|
|
|
case T_SYMBOL: /* fall through */
|
|
|
|
|
case T_FIXNUM:
|
|
|
|
|
case T_BIGNUM:
|
|
|
|
|
case T_STRING:
|
2011-08-25 02:02:03 +04:00
|
|
|
|
if (BASIC_OP_UNREDEFINED_P(BOP_EQQ,
|
|
|
|
|
SYMBOL_REDEFINED_OP_FLAG |
|
|
|
|
|
FIXNUM_REDEFINED_OP_FLAG |
|
2015-12-08 02:56:57 +03:00
|
|
|
|
FLOAT_REDEFINED_OP_FLAG |
|
2011-08-25 02:02:03 +04:00
|
|
|
|
BIGNUM_REDEFINED_OP_FLAG |
|
|
|
|
|
STRING_REDEFINED_OP_FLAG)) {
|
2010-10-13 17:51:20 +04:00
|
|
|
|
st_data_t val;
|
2013-05-26 20:19:04 +04:00
|
|
|
|
if (st_lookup(RHASH_TBL_RAW(hash), key, &val)) {
|
2010-10-13 17:51:20 +04:00
|
|
|
|
JUMP(FIX2INT((VALUE)val));
|
2010-09-09 17:40:14 +04:00
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
JUMP(else_offset);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
2010-09-27 18:47:30 +04:00
|
|
|
|
default:
|
|
|
|
|
break;
|
2009-08-12 09:55:06 +04:00
|
|
|
|
}
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** simple functions */
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c optimize
|
|
|
|
|
@e optimized X+Y.
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j 最適化された X+Y。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
opt_plus
|
2015-09-19 20:59:58 +03:00
|
|
|
|
(CALL_INFO ci, CALL_CACHE cc)
|
2007-01-16 11:52:22 +03:00
|
|
|
|
(VALUE recv, VALUE obj)
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
2012-08-23 11:22:40 +04:00
|
|
|
|
if (FIXNUM_2_P(recv, obj) &&
|
|
|
|
|
BASIC_OP_UNREDEFINED_P(BOP_PLUS,FIXNUM_REDEFINED_OP_FLAG)) {
|
2007-01-16 11:52:22 +03:00
|
|
|
|
/* fixnum + fixnum */
|
2007-06-26 10:23:34 +04:00
|
|
|
|
#ifndef LONG_LONG_VALUE
|
2007-01-16 11:52:22 +03:00
|
|
|
|
val = (recv + (obj & (~1)));
|
|
|
|
|
if ((~(recv ^ obj) & (recv ^ val)) &
|
|
|
|
|
((VALUE)0x01 << ((sizeof(VALUE) * CHAR_BIT) - 1))) {
|
2007-07-12 13:52:48 +04:00
|
|
|
|
val = rb_big_plus(rb_int2big(FIX2LONG(recv)),
|
|
|
|
|
rb_int2big(FIX2LONG(obj)));
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
2007-06-26 10: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 11:52:22 +03:00
|
|
|
|
}
|
2012-08-23 11:22:40 +04:00
|
|
|
|
else if (FLONUM_2_P(recv, obj) &&
|
|
|
|
|
BASIC_OP_UNREDEFINED_P(BOP_PLUS, FLOAT_REDEFINED_OP_FLAG)) {
|
|
|
|
|
val = DBL2NUM(RFLOAT_VALUE(recv) + RFLOAT_VALUE(obj));
|
|
|
|
|
}
|
2007-01-16 11:52:22 +03:00
|
|
|
|
else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
|
vm_insnhelper.h: RBASIC_CLASS
* vm_insnhelper.c (opt_eq_func): use RBASIC_CLASS() instead of HEAP_CLASS_OF().
* insns.def (opt_plus, opt_minus, opt_mult, opt_div, opt_mod, opt_lt),
(opt_gt, opt_ltlt, opt_aref, opt_aset, opt_length, opt_size),
(opt_empty_p, opt_succ): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42702 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-08-27 11:11:10 +04:00
|
|
|
|
if (RBASIC_CLASS(recv) == rb_cFloat && RBASIC_CLASS(obj) == rb_cFloat &&
|
2012-08-23 11:22:40 +04:00
|
|
|
|
BASIC_OP_UNREDEFINED_P(BOP_PLUS, FLOAT_REDEFINED_OP_FLAG)) {
|
2008-09-05 22:24:21 +04:00
|
|
|
|
val = DBL2NUM(RFLOAT_VALUE(recv) + RFLOAT_VALUE(obj));
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
vm_insnhelper.h: RBASIC_CLASS
* vm_insnhelper.c (opt_eq_func): use RBASIC_CLASS() instead of HEAP_CLASS_OF().
* insns.def (opt_plus, opt_minus, opt_mult, opt_div, opt_mod, opt_lt),
(opt_gt, opt_ltlt, opt_aref, opt_aset, opt_length, opt_size),
(opt_empty_p, opt_succ): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42702 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-08-27 11:11:10 +04:00
|
|
|
|
else if (RBASIC_CLASS(recv) == rb_cString && RBASIC_CLASS(obj) == rb_cString &&
|
2011-08-25 02:02:03 +04:00
|
|
|
|
BASIC_OP_UNREDEFINED_P(BOP_PLUS, STRING_REDEFINED_OP_FLAG)) {
|
2007-01-16 11:52:22 +03:00
|
|
|
|
val = rb_str_plus(recv, obj);
|
|
|
|
|
}
|
vm_insnhelper.h: RBASIC_CLASS
* vm_insnhelper.c (opt_eq_func): use RBASIC_CLASS() instead of HEAP_CLASS_OF().
* insns.def (opt_plus, opt_minus, opt_mult, opt_div, opt_mod, opt_lt),
(opt_gt, opt_ltlt, opt_aref, opt_aset, opt_length, opt_size),
(opt_empty_p, opt_succ): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42702 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-08-27 11:11:10 +04:00
|
|
|
|
else if (RBASIC_CLASS(recv) == rb_cArray &&
|
2011-08-25 02:02:03 +04:00
|
|
|
|
BASIC_OP_UNREDEFINED_P(BOP_PLUS, ARRAY_REDEFINED_OP_FLAG)) {
|
2007-01-16 11:52:22 +03:00
|
|
|
|
val = rb_ary_plus(recv, obj);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
goto INSN_LABEL(normal_dispatch);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
2012-08-23 11:22:40 +04:00
|
|
|
|
INSN_LABEL(normal_dispatch):
|
2007-01-16 11:52:22 +03:00
|
|
|
|
PUSH(recv);
|
|
|
|
|
PUSH(obj);
|
* insns.def (send, invokesuper, invokeblock, opt_*), vm_core.h:
use only a `ci' (rb_call_info_t) parameter instead of using
parameters such as `op_id', 'op_argc', `blockiseq' and flag.
These information are stored in rb_call_info_t at the compile
time.
This technique simplifies parameter passings at related
function calls (~10% speedups for simple mehtod invocation at
my machine).
`rb_call_info_t' also has new function pointer variable `call'.
This `call' variable enables to customize method (block)
invocation process for each place. However, it always call
`vm_call_general()' at this changes.
`rb_call_info_t' also has temporary variables for method
(block) invocation.
* vm_core.h, compile.c, insns.def: introduce VM_CALL_ARGS_SKIP_SETUP
VM_CALL macro. This flag indicates that this call can skip
caller_setup (block arg and splat arg).
* compile.c: catch up above changes.
* iseq.c: catch up above changes (especially for TS_CALLINFO).
* tool/instruction.rb: catch up above chagnes.
* vm_insnhelper.c, vm_insnhelper.h: ditto. Macros and functions
parameters are changed.
* vm_eval.c (vm_call0): ditto (it will be rewriten soon).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37180 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-10-14 20:59:05 +04:00
|
|
|
|
CALL_SIMPLE_METHOD(recv);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c optimize
|
|
|
|
|
@e optimized X-Y.
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j 最適化された X-Y。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
opt_minus
|
2015-09-19 20:59:58 +03:00
|
|
|
|
(CALL_INFO ci, CALL_CACHE cc)
|
2007-01-16 11:52:22 +03:00
|
|
|
|
(VALUE recv, VALUE obj)
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
|
|
|
|
if (FIXNUM_2_P(recv, obj) &&
|
2011-08-25 02:02:03 +04:00
|
|
|
|
BASIC_OP_UNREDEFINED_P(BOP_MINUS, FIXNUM_REDEFINED_OP_FLAG)) {
|
2007-01-16 11:52:22 +03:00
|
|
|
|
long a, b, c;
|
|
|
|
|
|
|
|
|
|
a = FIX2LONG(recv);
|
|
|
|
|
b = FIX2LONG(obj);
|
|
|
|
|
c = a - b;
|
|
|
|
|
|
2007-06-26 10:23:34 +04:00
|
|
|
|
if (FIXABLE(c)) {
|
|
|
|
|
val = LONG2FIX(c);
|
|
|
|
|
}
|
|
|
|
|
else {
|
2007-01-16 11:52:22 +03:00
|
|
|
|
val = rb_big_minus(rb_int2big(a), rb_int2big(b));
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-08-23 11:22:40 +04:00
|
|
|
|
else if (FLONUM_2_P(recv, obj) &&
|
|
|
|
|
BASIC_OP_UNREDEFINED_P(BOP_MINUS, FLOAT_REDEFINED_OP_FLAG)) {
|
|
|
|
|
val = DBL2NUM(RFLOAT_VALUE(recv) - RFLOAT_VALUE(obj));
|
|
|
|
|
}
|
2009-02-23 19:12:38 +03:00
|
|
|
|
else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
|
vm_insnhelper.h: RBASIC_CLASS
* vm_insnhelper.c (opt_eq_func): use RBASIC_CLASS() instead of HEAP_CLASS_OF().
* insns.def (opt_plus, opt_minus, opt_mult, opt_div, opt_mod, opt_lt),
(opt_gt, opt_ltlt, opt_aref, opt_aset, opt_length, opt_size),
(opt_empty_p, opt_succ): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42702 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-08-27 11:11:10 +04:00
|
|
|
|
if (RBASIC_CLASS(recv) == rb_cFloat && RBASIC_CLASS(obj) == rb_cFloat &&
|
2012-08-23 11:22:40 +04:00
|
|
|
|
BASIC_OP_UNREDEFINED_P(BOP_MINUS, FLOAT_REDEFINED_OP_FLAG)) {
|
2009-02-23 19:12:38 +03:00
|
|
|
|
val = DBL2NUM(RFLOAT_VALUE(recv) - RFLOAT_VALUE(obj));
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
goto INSN_LABEL(normal_dispatch);
|
|
|
|
|
}
|
|
|
|
|
}
|
2007-01-16 11:52:22 +03:00
|
|
|
|
else {
|
|
|
|
|
/* other */
|
2009-02-23 19:12:38 +03:00
|
|
|
|
INSN_LABEL(normal_dispatch):
|
2007-01-16 11:52:22 +03:00
|
|
|
|
PUSH(recv);
|
|
|
|
|
PUSH(obj);
|
* insns.def (send, invokesuper, invokeblock, opt_*), vm_core.h:
use only a `ci' (rb_call_info_t) parameter instead of using
parameters such as `op_id', 'op_argc', `blockiseq' and flag.
These information are stored in rb_call_info_t at the compile
time.
This technique simplifies parameter passings at related
function calls (~10% speedups for simple mehtod invocation at
my machine).
`rb_call_info_t' also has new function pointer variable `call'.
This `call' variable enables to customize method (block)
invocation process for each place. However, it always call
`vm_call_general()' at this changes.
`rb_call_info_t' also has temporary variables for method
(block) invocation.
* vm_core.h, compile.c, insns.def: introduce VM_CALL_ARGS_SKIP_SETUP
VM_CALL macro. This flag indicates that this call can skip
caller_setup (block arg and splat arg).
* compile.c: catch up above changes.
* iseq.c: catch up above changes (especially for TS_CALLINFO).
* tool/instruction.rb: catch up above chagnes.
* vm_insnhelper.c, vm_insnhelper.h: ditto. Macros and functions
parameters are changed.
* vm_eval.c (vm_call0): ditto (it will be rewriten soon).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37180 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-10-14 20:59:05 +04:00
|
|
|
|
CALL_SIMPLE_METHOD(recv);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c optimize
|
|
|
|
|
@e optimized X*Y.
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j 最適化された X*Y。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
opt_mult
|
2015-09-19 20:59:58 +03:00
|
|
|
|
(CALL_INFO ci, CALL_CACHE cc)
|
2007-01-16 11:52:22 +03:00
|
|
|
|
(VALUE recv, VALUE obj)
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
|
|
|
|
if (FIXNUM_2_P(recv, obj) &&
|
2011-08-25 02:02:03 +04:00
|
|
|
|
BASIC_OP_UNREDEFINED_P(BOP_MULT, FIXNUM_REDEFINED_OP_FLAG)) {
|
2011-05-30 10:53:21 +04:00
|
|
|
|
long a, b;
|
2007-01-16 11:52:22 +03:00
|
|
|
|
|
|
|
|
|
a = FIX2LONG(recv);
|
|
|
|
|
if (a == 0) {
|
|
|
|
|
val = recv;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
b = FIX2LONG(obj);
|
2013-04-09 15:39:53 +04:00
|
|
|
|
if (MUL_OVERFLOW_FIXNUM_P(a, b)) {
|
2007-01-16 11:52:22 +03:00
|
|
|
|
val = rb_big_mul(rb_int2big(a), rb_int2big(b));
|
2013-04-09 15:39:53 +04:00
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
val = LONG2FIX(a * b);
|
|
|
|
|
}
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
2012-08-23 11:22:40 +04:00
|
|
|
|
else if (FLONUM_2_P(recv, obj) &&
|
|
|
|
|
BASIC_OP_UNREDEFINED_P(BOP_MULT, FLOAT_REDEFINED_OP_FLAG)) {
|
|
|
|
|
val = DBL2NUM(RFLOAT_VALUE(recv) * RFLOAT_VALUE(obj));
|
|
|
|
|
}
|
2007-01-16 11:52:22 +03:00
|
|
|
|
else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
|
vm_insnhelper.h: RBASIC_CLASS
* vm_insnhelper.c (opt_eq_func): use RBASIC_CLASS() instead of HEAP_CLASS_OF().
* insns.def (opt_plus, opt_minus, opt_mult, opt_div, opt_mod, opt_lt),
(opt_gt, opt_ltlt, opt_aref, opt_aset, opt_length, opt_size),
(opt_empty_p, opt_succ): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42702 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-08-27 11:11:10 +04:00
|
|
|
|
if (RBASIC_CLASS(recv) == rb_cFloat && RBASIC_CLASS(obj) == rb_cFloat &&
|
2012-08-23 11:22:40 +04:00
|
|
|
|
BASIC_OP_UNREDEFINED_P(BOP_MULT, FLOAT_REDEFINED_OP_FLAG)) {
|
2008-09-05 22:24:21 +04:00
|
|
|
|
val = DBL2NUM(RFLOAT_VALUE(recv) * RFLOAT_VALUE(obj));
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
goto INSN_LABEL(normal_dispatch);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
INSN_LABEL(normal_dispatch):
|
|
|
|
|
PUSH(recv);
|
|
|
|
|
PUSH(obj);
|
* insns.def (send, invokesuper, invokeblock, opt_*), vm_core.h:
use only a `ci' (rb_call_info_t) parameter instead of using
parameters such as `op_id', 'op_argc', `blockiseq' and flag.
These information are stored in rb_call_info_t at the compile
time.
This technique simplifies parameter passings at related
function calls (~10% speedups for simple mehtod invocation at
my machine).
`rb_call_info_t' also has new function pointer variable `call'.
This `call' variable enables to customize method (block)
invocation process for each place. However, it always call
`vm_call_general()' at this changes.
`rb_call_info_t' also has temporary variables for method
(block) invocation.
* vm_core.h, compile.c, insns.def: introduce VM_CALL_ARGS_SKIP_SETUP
VM_CALL macro. This flag indicates that this call can skip
caller_setup (block arg and splat arg).
* compile.c: catch up above changes.
* iseq.c: catch up above changes (especially for TS_CALLINFO).
* tool/instruction.rb: catch up above chagnes.
* vm_insnhelper.c, vm_insnhelper.h: ditto. Macros and functions
parameters are changed.
* vm_eval.c (vm_call0): ditto (it will be rewriten soon).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37180 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-10-14 20:59:05 +04:00
|
|
|
|
CALL_SIMPLE_METHOD(recv);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c optimize
|
|
|
|
|
@e optimized X/Y.
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j 最適化された X/Y。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
opt_div
|
2015-09-19 20:59:58 +03:00
|
|
|
|
(CALL_INFO ci, CALL_CACHE cc)
|
2007-01-16 11:52:22 +03:00
|
|
|
|
(VALUE recv, VALUE obj)
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
|
|
|
|
if (FIXNUM_2_P(recv, obj) &&
|
2011-08-25 02:02:03 +04:00
|
|
|
|
BASIC_OP_UNREDEFINED_P(BOP_DIV, FIXNUM_REDEFINED_OP_FLAG)) {
|
2007-01-16 11:52:22 +03:00
|
|
|
|
long x, y, div;
|
|
|
|
|
|
|
|
|
|
x = FIX2LONG(recv);
|
|
|
|
|
y = FIX2LONG(obj);
|
|
|
|
|
{
|
|
|
|
|
/* copied from numeric.c#fixdivmod */
|
|
|
|
|
long mod;
|
|
|
|
|
if (y == 0)
|
2008-02-19 05:14:14 +03:00
|
|
|
|
goto INSN_LABEL(normal_dispatch);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
2007-07-13 21:08:12 +04:00
|
|
|
|
val = LONG2NUM(div);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
2012-08-23 11:22:40 +04:00
|
|
|
|
else if (FLONUM_2_P(recv, obj) &&
|
2013-12-10 22:18:31 +04:00
|
|
|
|
BASIC_OP_UNREDEFINED_P(BOP_DIV, FLOAT_REDEFINED_OP_FLAG)) {
|
2012-08-23 11:22:40 +04:00
|
|
|
|
val = DBL2NUM(RFLOAT_VALUE(recv) / RFLOAT_VALUE(obj));
|
|
|
|
|
}
|
2007-01-16 11:52:22 +03:00
|
|
|
|
else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
|
vm_insnhelper.h: RBASIC_CLASS
* vm_insnhelper.c (opt_eq_func): use RBASIC_CLASS() instead of HEAP_CLASS_OF().
* insns.def (opt_plus, opt_minus, opt_mult, opt_div, opt_mod, opt_lt),
(opt_gt, opt_ltlt, opt_aref, opt_aset, opt_length, opt_size),
(opt_empty_p, opt_succ): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42702 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-08-27 11:11:10 +04:00
|
|
|
|
if (RBASIC_CLASS(recv) == rb_cFloat && RBASIC_CLASS(obj) == rb_cFloat &&
|
2012-08-23 11:22:40 +04:00
|
|
|
|
BASIC_OP_UNREDEFINED_P(BOP_DIV, FLOAT_REDEFINED_OP_FLAG)) {
|
2008-09-05 22:24:21 +04:00
|
|
|
|
val = DBL2NUM(RFLOAT_VALUE(recv) / RFLOAT_VALUE(obj));
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
goto INSN_LABEL(normal_dispatch);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
INSN_LABEL(normal_dispatch):
|
|
|
|
|
PUSH(recv);
|
|
|
|
|
PUSH(obj);
|
* insns.def (send, invokesuper, invokeblock, opt_*), vm_core.h:
use only a `ci' (rb_call_info_t) parameter instead of using
parameters such as `op_id', 'op_argc', `blockiseq' and flag.
These information are stored in rb_call_info_t at the compile
time.
This technique simplifies parameter passings at related
function calls (~10% speedups for simple mehtod invocation at
my machine).
`rb_call_info_t' also has new function pointer variable `call'.
This `call' variable enables to customize method (block)
invocation process for each place. However, it always call
`vm_call_general()' at this changes.
`rb_call_info_t' also has temporary variables for method
(block) invocation.
* vm_core.h, compile.c, insns.def: introduce VM_CALL_ARGS_SKIP_SETUP
VM_CALL macro. This flag indicates that this call can skip
caller_setup (block arg and splat arg).
* compile.c: catch up above changes.
* iseq.c: catch up above changes (especially for TS_CALLINFO).
* tool/instruction.rb: catch up above chagnes.
* vm_insnhelper.c, vm_insnhelper.h: ditto. Macros and functions
parameters are changed.
* vm_eval.c (vm_call0): ditto (it will be rewriten soon).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37180 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-10-14 20:59:05 +04:00
|
|
|
|
CALL_SIMPLE_METHOD(recv);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c optimize
|
|
|
|
|
@e optimized X%Y.
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j 最適化された X%Y。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
opt_mod
|
2015-09-19 20:59:58 +03:00
|
|
|
|
(CALL_INFO ci, CALL_CACHE cc)
|
2007-01-16 11:52:22 +03:00
|
|
|
|
(VALUE recv, VALUE obj)
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
|
|
|
|
if (FIXNUM_2_P(recv, obj) &&
|
2011-08-25 02:02:03 +04:00
|
|
|
|
BASIC_OP_UNREDEFINED_P(BOP_MOD, FIXNUM_REDEFINED_OP_FLAG )) {
|
2013-04-22 17:57:21 +04:00
|
|
|
|
long x, y;
|
2007-01-16 11:52:22 +03:00
|
|
|
|
|
|
|
|
|
x = FIX2LONG(recv);
|
|
|
|
|
y = FIX2LONG(obj);
|
2013-04-22 17:57:21 +04:00
|
|
|
|
if (x > 0 && y > 0) {
|
|
|
|
|
val = LONG2FIX(x % y);
|
2014-01-25 07:15:30 +04:00
|
|
|
|
}
|
|
|
|
|
else {
|
2007-01-16 11:52:22 +03:00
|
|
|
|
/* copied from numeric.c#fixdivmod */
|
2013-04-22 17:57:21 +04:00
|
|
|
|
long div, mod;
|
2007-01-16 11:52:22 +03:00
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
2013-04-22 17:57:21 +04:00
|
|
|
|
val = LONG2FIX(mod);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
2012-08-23 11:22:40 +04:00
|
|
|
|
else if (FLONUM_2_P(recv, obj) &&
|
|
|
|
|
BASIC_OP_UNREDEFINED_P(BOP_MOD, FLOAT_REDEFINED_OP_FLAG)) {
|
|
|
|
|
val = DBL2NUM(ruby_float_mod(RFLOAT_VALUE(recv), RFLOAT_VALUE(obj)));
|
|
|
|
|
}
|
2007-01-16 11:52:22 +03:00
|
|
|
|
else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
|
vm_insnhelper.h: RBASIC_CLASS
* vm_insnhelper.c (opt_eq_func): use RBASIC_CLASS() instead of HEAP_CLASS_OF().
* insns.def (opt_plus, opt_minus, opt_mult, opt_div, opt_mod, opt_lt),
(opt_gt, opt_ltlt, opt_aref, opt_aset, opt_length, opt_size),
(opt_empty_p, opt_succ): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42702 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-08-27 11:11:10 +04:00
|
|
|
|
if (RBASIC_CLASS(recv) == rb_cFloat && RBASIC_CLASS(obj) == rb_cFloat &&
|
2012-08-23 11:22:40 +04:00
|
|
|
|
BASIC_OP_UNREDEFINED_P(BOP_MOD, FLOAT_REDEFINED_OP_FLAG)) {
|
2012-03-14 10:10:01 +04:00
|
|
|
|
val = DBL2NUM(ruby_float_mod(RFLOAT_VALUE(recv), RFLOAT_VALUE(obj)));
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
goto INSN_LABEL(normal_dispatch);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
INSN_LABEL(normal_dispatch):
|
|
|
|
|
PUSH(recv);
|
|
|
|
|
PUSH(obj);
|
* insns.def (send, invokesuper, invokeblock, opt_*), vm_core.h:
use only a `ci' (rb_call_info_t) parameter instead of using
parameters such as `op_id', 'op_argc', `blockiseq' and flag.
These information are stored in rb_call_info_t at the compile
time.
This technique simplifies parameter passings at related
function calls (~10% speedups for simple mehtod invocation at
my machine).
`rb_call_info_t' also has new function pointer variable `call'.
This `call' variable enables to customize method (block)
invocation process for each place. However, it always call
`vm_call_general()' at this changes.
`rb_call_info_t' also has temporary variables for method
(block) invocation.
* vm_core.h, compile.c, insns.def: introduce VM_CALL_ARGS_SKIP_SETUP
VM_CALL macro. This flag indicates that this call can skip
caller_setup (block arg and splat arg).
* compile.c: catch up above changes.
* iseq.c: catch up above changes (especially for TS_CALLINFO).
* tool/instruction.rb: catch up above chagnes.
* vm_insnhelper.c, vm_insnhelper.h: ditto. Macros and functions
parameters are changed.
* vm_eval.c (vm_call0): ditto (it will be rewriten soon).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37180 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-10-14 20:59:05 +04:00
|
|
|
|
CALL_SIMPLE_METHOD(recv);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c optimize
|
|
|
|
|
@e optimized X==Y.
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j 最適化された X==Y。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
opt_eq
|
2015-09-19 20:59:58 +03:00
|
|
|
|
(CALL_INFO ci, CALL_CACHE cc)
|
2007-01-16 11:52:22 +03:00
|
|
|
|
(VALUE recv, VALUE obj)
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
2015-09-19 20:59:58 +03:00
|
|
|
|
val = opt_eq_func(recv, obj, ci, cc);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
|
2007-12-18 15:07:51 +03:00
|
|
|
|
if (val == Qundef) {
|
|
|
|
|
/* other */
|
|
|
|
|
PUSH(recv);
|
|
|
|
|
PUSH(obj);
|
* insns.def (send, invokesuper, invokeblock, opt_*), vm_core.h:
use only a `ci' (rb_call_info_t) parameter instead of using
parameters such as `op_id', 'op_argc', `blockiseq' and flag.
These information are stored in rb_call_info_t at the compile
time.
This technique simplifies parameter passings at related
function calls (~10% speedups for simple mehtod invocation at
my machine).
`rb_call_info_t' also has new function pointer variable `call'.
This `call' variable enables to customize method (block)
invocation process for each place. However, it always call
`vm_call_general()' at this changes.
`rb_call_info_t' also has temporary variables for method
(block) invocation.
* vm_core.h, compile.c, insns.def: introduce VM_CALL_ARGS_SKIP_SETUP
VM_CALL macro. This flag indicates that this call can skip
caller_setup (block arg and splat arg).
* compile.c: catch up above changes.
* iseq.c: catch up above changes (especially for TS_CALLINFO).
* tool/instruction.rb: catch up above chagnes.
* vm_insnhelper.c, vm_insnhelper.h: ditto. Macros and functions
parameters are changed.
* vm_eval.c (vm_call0): ditto (it will be rewriten soon).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37180 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-10-14 20:59:05 +04:00
|
|
|
|
CALL_SIMPLE_METHOD(recv);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
2007-12-18 15:07:51 +03:00
|
|
|
|
}
|
2007-01-16 11:52:22 +03:00
|
|
|
|
|
2007-12-18 15:07:51 +03:00
|
|
|
|
/**
|
|
|
|
|
@c optimize
|
|
|
|
|
@e optimized X!=Y.
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j 最適化された X!=Y。
|
2007-12-18 15:07:51 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
opt_neq
|
2015-09-19 20:59:58 +03:00
|
|
|
|
(CALL_INFO ci, CALL_CACHE cc, CALL_INFO ci_eq, CALL_CACHE cc_eq)
|
2007-12-18 15:07:51 +03:00
|
|
|
|
(VALUE recv, VALUE obj)
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
|
|
|
|
extern VALUE rb_obj_not_equal(VALUE obj1, VALUE obj2);
|
2015-09-19 20:59:58 +03:00
|
|
|
|
vm_search_method(ci, cc, recv);
|
|
|
|
|
|
2007-12-18 15:07:51 +03:00
|
|
|
|
val = Qundef;
|
|
|
|
|
|
2015-09-19 20:59:58 +03:00
|
|
|
|
if (check_cfunc(cc->me, rb_obj_not_equal)) {
|
|
|
|
|
val = opt_eq_func(recv, obj, ci_eq, cc_eq);
|
2007-12-18 15:07:51 +03:00
|
|
|
|
|
|
|
|
|
if (val != Qundef) {
|
|
|
|
|
val = RTEST(val) ? Qfalse : Qtrue;
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
2007-12-18 15:07:51 +03:00
|
|
|
|
|
|
|
|
|
if (val == Qundef) {
|
2007-01-16 11:52:22 +03:00
|
|
|
|
/* other */
|
|
|
|
|
PUSH(recv);
|
|
|
|
|
PUSH(obj);
|
* insns.def (send, invokesuper, invokeblock, opt_*), vm_core.h:
use only a `ci' (rb_call_info_t) parameter instead of using
parameters such as `op_id', 'op_argc', `blockiseq' and flag.
These information are stored in rb_call_info_t at the compile
time.
This technique simplifies parameter passings at related
function calls (~10% speedups for simple mehtod invocation at
my machine).
`rb_call_info_t' also has new function pointer variable `call'.
This `call' variable enables to customize method (block)
invocation process for each place. However, it always call
`vm_call_general()' at this changes.
`rb_call_info_t' also has temporary variables for method
(block) invocation.
* vm_core.h, compile.c, insns.def: introduce VM_CALL_ARGS_SKIP_SETUP
VM_CALL macro. This flag indicates that this call can skip
caller_setup (block arg and splat arg).
* compile.c: catch up above changes.
* iseq.c: catch up above changes (especially for TS_CALLINFO).
* tool/instruction.rb: catch up above chagnes.
* vm_insnhelper.c, vm_insnhelper.h: ditto. Macros and functions
parameters are changed.
* vm_eval.c (vm_call0): ditto (it will be rewriten soon).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37180 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-10-14 20:59:05 +04:00
|
|
|
|
CALL_SIMPLE_METHOD(recv);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c optimize
|
|
|
|
|
@e optimized X<Y.
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j 最適化された X<Y。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
opt_lt
|
2015-09-19 20:59:58 +03:00
|
|
|
|
(CALL_INFO ci, CALL_CACHE cc)
|
2007-01-16 11:52:22 +03:00
|
|
|
|
(VALUE recv, VALUE obj)
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
|
|
|
|
if (FIXNUM_2_P(recv, obj) &&
|
2011-08-25 02:02:03 +04:00
|
|
|
|
BASIC_OP_UNREDEFINED_P(BOP_LT, FIXNUM_REDEFINED_OP_FLAG)) {
|
2008-05-22 21:31:15 +04:00
|
|
|
|
SIGNED_VALUE a = recv, b = obj;
|
2007-01-16 11:52:22 +03:00
|
|
|
|
|
|
|
|
|
if (a < b) {
|
|
|
|
|
val = Qtrue;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
val = Qfalse;
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-08-23 11:22:40 +04:00
|
|
|
|
else if (FLONUM_2_P(recv, obj) &&
|
|
|
|
|
BASIC_OP_UNREDEFINED_P(BOP_LT, FLOAT_REDEFINED_OP_FLAG)) {
|
|
|
|
|
/* flonum is not NaN */
|
|
|
|
|
val = RFLOAT_VALUE(recv) < RFLOAT_VALUE(obj) ? Qtrue : Qfalse;
|
|
|
|
|
}
|
2009-02-23 19:12:38 +03:00
|
|
|
|
else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
|
vm_insnhelper.h: RBASIC_CLASS
* vm_insnhelper.c (opt_eq_func): use RBASIC_CLASS() instead of HEAP_CLASS_OF().
* insns.def (opt_plus, opt_minus, opt_mult, opt_div, opt_mod, opt_lt),
(opt_gt, opt_ltlt, opt_aref, opt_aset, opt_length, opt_size),
(opt_empty_p, opt_succ): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42702 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-08-27 11:11:10 +04:00
|
|
|
|
if (RBASIC_CLASS(recv) == rb_cFloat && RBASIC_CLASS(obj) == rb_cFloat &&
|
2012-08-23 11:22:40 +04:00
|
|
|
|
BASIC_OP_UNREDEFINED_P(BOP_LT, FLOAT_REDEFINED_OP_FLAG)) {
|
|
|
|
|
val = double_cmp_lt(RFLOAT_VALUE(recv), RFLOAT_VALUE(obj));
|
2009-02-23 19:12:38 +03:00
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
goto INSN_LABEL(normal_dispatch);
|
|
|
|
|
}
|
|
|
|
|
}
|
2007-01-16 11:52:22 +03:00
|
|
|
|
else {
|
2009-02-23 19:12:38 +03:00
|
|
|
|
INSN_LABEL(normal_dispatch):
|
2007-01-16 11:52:22 +03:00
|
|
|
|
PUSH(recv);
|
|
|
|
|
PUSH(obj);
|
* insns.def (send, invokesuper, invokeblock, opt_*), vm_core.h:
use only a `ci' (rb_call_info_t) parameter instead of using
parameters such as `op_id', 'op_argc', `blockiseq' and flag.
These information are stored in rb_call_info_t at the compile
time.
This technique simplifies parameter passings at related
function calls (~10% speedups for simple mehtod invocation at
my machine).
`rb_call_info_t' also has new function pointer variable `call'.
This `call' variable enables to customize method (block)
invocation process for each place. However, it always call
`vm_call_general()' at this changes.
`rb_call_info_t' also has temporary variables for method
(block) invocation.
* vm_core.h, compile.c, insns.def: introduce VM_CALL_ARGS_SKIP_SETUP
VM_CALL macro. This flag indicates that this call can skip
caller_setup (block arg and splat arg).
* compile.c: catch up above changes.
* iseq.c: catch up above changes (especially for TS_CALLINFO).
* tool/instruction.rb: catch up above chagnes.
* vm_insnhelper.c, vm_insnhelper.h: ditto. Macros and functions
parameters are changed.
* vm_eval.c (vm_call0): ditto (it will be rewriten soon).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37180 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-10-14 20:59:05 +04:00
|
|
|
|
CALL_SIMPLE_METHOD(recv);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c optimize
|
|
|
|
|
@e optimized X<=Y.
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j 最適化された X<=Y。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
opt_le
|
2015-09-19 20:59:58 +03:00
|
|
|
|
(CALL_INFO ci, CALL_CACHE cc)
|
2007-01-16 11:52:22 +03:00
|
|
|
|
(VALUE recv, VALUE obj)
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
|
|
|
|
if (FIXNUM_2_P(recv, obj) &&
|
2011-08-25 02:02:03 +04:00
|
|
|
|
BASIC_OP_UNREDEFINED_P(BOP_LE, FIXNUM_REDEFINED_OP_FLAG)) {
|
2008-05-22 21:31:15 +04:00
|
|
|
|
SIGNED_VALUE a = recv, b = obj;
|
2007-01-16 11:52:22 +03:00
|
|
|
|
|
|
|
|
|
if (a <= b) {
|
|
|
|
|
val = Qtrue;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
val = Qfalse;
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-08-23 11:22:40 +04:00
|
|
|
|
else if (FLONUM_2_P(recv, obj) &&
|
|
|
|
|
BASIC_OP_UNREDEFINED_P(BOP_LE, FLOAT_REDEFINED_OP_FLAG)) {
|
|
|
|
|
/* flonum is not NaN */
|
|
|
|
|
val = RFLOAT_VALUE(recv) <= RFLOAT_VALUE(obj) ? Qtrue : Qfalse;
|
|
|
|
|
}
|
2007-01-16 11:52:22 +03:00
|
|
|
|
else {
|
|
|
|
|
/* other */
|
|
|
|
|
PUSH(recv);
|
|
|
|
|
PUSH(obj);
|
* insns.def (send, invokesuper, invokeblock, opt_*), vm_core.h:
use only a `ci' (rb_call_info_t) parameter instead of using
parameters such as `op_id', 'op_argc', `blockiseq' and flag.
These information are stored in rb_call_info_t at the compile
time.
This technique simplifies parameter passings at related
function calls (~10% speedups for simple mehtod invocation at
my machine).
`rb_call_info_t' also has new function pointer variable `call'.
This `call' variable enables to customize method (block)
invocation process for each place. However, it always call
`vm_call_general()' at this changes.
`rb_call_info_t' also has temporary variables for method
(block) invocation.
* vm_core.h, compile.c, insns.def: introduce VM_CALL_ARGS_SKIP_SETUP
VM_CALL macro. This flag indicates that this call can skip
caller_setup (block arg and splat arg).
* compile.c: catch up above changes.
* iseq.c: catch up above changes (especially for TS_CALLINFO).
* tool/instruction.rb: catch up above chagnes.
* vm_insnhelper.c, vm_insnhelper.h: ditto. Macros and functions
parameters are changed.
* vm_eval.c (vm_call0): ditto (it will be rewriten soon).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37180 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-10-14 20:59:05 +04:00
|
|
|
|
CALL_SIMPLE_METHOD(recv);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-05-21 08:46:51 +04:00
|
|
|
|
/**
|
|
|
|
|
@c optimize
|
|
|
|
|
@e optimized X>Y.
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j 最適化された X>Y。
|
2007-05-21 08:46:51 +04:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
opt_gt
|
2015-09-19 20:59:58 +03:00
|
|
|
|
(CALL_INFO ci, CALL_CACHE cc)
|
2007-05-21 08:46:51 +04:00
|
|
|
|
(VALUE recv, VALUE obj)
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
|
|
|
|
if (FIXNUM_2_P(recv, obj) &&
|
2011-08-25 02:02:03 +04:00
|
|
|
|
BASIC_OP_UNREDEFINED_P(BOP_GT, FIXNUM_REDEFINED_OP_FLAG)) {
|
2008-05-22 21:31:15 +04:00
|
|
|
|
SIGNED_VALUE a = recv, b = obj;
|
2007-05-21 08:46:51 +04:00
|
|
|
|
|
|
|
|
|
if (a > b) {
|
|
|
|
|
val = Qtrue;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
val = Qfalse;
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-08-23 11:22:40 +04:00
|
|
|
|
else if (FLONUM_2_P(recv, obj) &&
|
|
|
|
|
BASIC_OP_UNREDEFINED_P(BOP_GT, FLOAT_REDEFINED_OP_FLAG)) {
|
|
|
|
|
/* flonum is not NaN */
|
|
|
|
|
val = RFLOAT_VALUE(recv) > RFLOAT_VALUE(obj) ? Qtrue : Qfalse;
|
|
|
|
|
}
|
2009-02-23 19:12:38 +03:00
|
|
|
|
else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
|
vm_insnhelper.h: RBASIC_CLASS
* vm_insnhelper.c (opt_eq_func): use RBASIC_CLASS() instead of HEAP_CLASS_OF().
* insns.def (opt_plus, opt_minus, opt_mult, opt_div, opt_mod, opt_lt),
(opt_gt, opt_ltlt, opt_aref, opt_aset, opt_length, opt_size),
(opt_empty_p, opt_succ): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42702 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-08-27 11:11:10 +04:00
|
|
|
|
if (RBASIC_CLASS(recv) == rb_cFloat && RBASIC_CLASS(obj) == rb_cFloat &&
|
2012-08-23 11:22:40 +04:00
|
|
|
|
BASIC_OP_UNREDEFINED_P(BOP_GT, FLOAT_REDEFINED_OP_FLAG)) {
|
|
|
|
|
val = double_cmp_gt(RFLOAT_VALUE(recv), RFLOAT_VALUE(obj));
|
2009-02-23 19:12:38 +03:00
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
goto INSN_LABEL(normal_dispatch);
|
|
|
|
|
}
|
|
|
|
|
}
|
2007-05-21 08:46:51 +04:00
|
|
|
|
else {
|
2009-02-23 19:12:38 +03:00
|
|
|
|
INSN_LABEL(normal_dispatch):
|
2007-05-21 08:46:51 +04:00
|
|
|
|
PUSH(recv);
|
|
|
|
|
PUSH(obj);
|
* insns.def (send, invokesuper, invokeblock, opt_*), vm_core.h:
use only a `ci' (rb_call_info_t) parameter instead of using
parameters such as `op_id', 'op_argc', `blockiseq' and flag.
These information are stored in rb_call_info_t at the compile
time.
This technique simplifies parameter passings at related
function calls (~10% speedups for simple mehtod invocation at
my machine).
`rb_call_info_t' also has new function pointer variable `call'.
This `call' variable enables to customize method (block)
invocation process for each place. However, it always call
`vm_call_general()' at this changes.
`rb_call_info_t' also has temporary variables for method
(block) invocation.
* vm_core.h, compile.c, insns.def: introduce VM_CALL_ARGS_SKIP_SETUP
VM_CALL macro. This flag indicates that this call can skip
caller_setup (block arg and splat arg).
* compile.c: catch up above changes.
* iseq.c: catch up above changes (especially for TS_CALLINFO).
* tool/instruction.rb: catch up above chagnes.
* vm_insnhelper.c, vm_insnhelper.h: ditto. Macros and functions
parameters are changed.
* vm_eval.c (vm_call0): ditto (it will be rewriten soon).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37180 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-10-14 20:59:05 +04:00
|
|
|
|
CALL_SIMPLE_METHOD(recv);
|
2007-05-21 08:46:51 +04:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c optimize
|
|
|
|
|
@e optimized X>=Y.
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j 最適化された X>=Y。
|
2007-05-21 08:46:51 +04:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
opt_ge
|
2015-09-19 20:59:58 +03:00
|
|
|
|
(CALL_INFO ci, CALL_CACHE cc)
|
2007-05-21 08:46:51 +04:00
|
|
|
|
(VALUE recv, VALUE obj)
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
|
|
|
|
if (FIXNUM_2_P(recv, obj) &&
|
2011-08-25 02:02:03 +04:00
|
|
|
|
BASIC_OP_UNREDEFINED_P(BOP_GE, FIXNUM_REDEFINED_OP_FLAG)) {
|
2008-05-22 21:31:15 +04:00
|
|
|
|
SIGNED_VALUE a = recv, b = obj;
|
2007-05-21 08:46:51 +04:00
|
|
|
|
|
|
|
|
|
if (a >= b) {
|
|
|
|
|
val = Qtrue;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
val = Qfalse;
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-08-23 11:22:40 +04:00
|
|
|
|
else if (FLONUM_2_P(recv, obj) &&
|
|
|
|
|
BASIC_OP_UNREDEFINED_P(BOP_GE, FLOAT_REDEFINED_OP_FLAG)) {
|
|
|
|
|
/* flonum is not NaN */
|
|
|
|
|
val = RFLOAT_VALUE(recv) >= RFLOAT_VALUE(obj) ? Qtrue : Qfalse;
|
|
|
|
|
}
|
2007-05-21 08:46:51 +04:00
|
|
|
|
else {
|
|
|
|
|
PUSH(recv);
|
|
|
|
|
PUSH(obj);
|
* insns.def (send, invokesuper, invokeblock, opt_*), vm_core.h:
use only a `ci' (rb_call_info_t) parameter instead of using
parameters such as `op_id', 'op_argc', `blockiseq' and flag.
These information are stored in rb_call_info_t at the compile
time.
This technique simplifies parameter passings at related
function calls (~10% speedups for simple mehtod invocation at
my machine).
`rb_call_info_t' also has new function pointer variable `call'.
This `call' variable enables to customize method (block)
invocation process for each place. However, it always call
`vm_call_general()' at this changes.
`rb_call_info_t' also has temporary variables for method
(block) invocation.
* vm_core.h, compile.c, insns.def: introduce VM_CALL_ARGS_SKIP_SETUP
VM_CALL macro. This flag indicates that this call can skip
caller_setup (block arg and splat arg).
* compile.c: catch up above changes.
* iseq.c: catch up above changes (especially for TS_CALLINFO).
* tool/instruction.rb: catch up above chagnes.
* vm_insnhelper.c, vm_insnhelper.h: ditto. Macros and functions
parameters are changed.
* vm_eval.c (vm_call0): ditto (it will be rewriten soon).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37180 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-10-14 20:59:05 +04:00
|
|
|
|
CALL_SIMPLE_METHOD(recv);
|
2007-05-21 08:46:51 +04:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-01-16 11:52:22 +03:00
|
|
|
|
/**
|
|
|
|
|
@c optimize
|
|
|
|
|
@e <<
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j 最適化された X<<Y。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
opt_ltlt
|
2015-09-19 20:59:58 +03:00
|
|
|
|
(CALL_INFO ci, CALL_CACHE cc)
|
2007-01-16 11:52:22 +03:00
|
|
|
|
(VALUE recv, VALUE obj)
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
|
|
|
|
if (!SPECIAL_CONST_P(recv)) {
|
vm_insnhelper.h: RBASIC_CLASS
* vm_insnhelper.c (opt_eq_func): use RBASIC_CLASS() instead of HEAP_CLASS_OF().
* insns.def (opt_plus, opt_minus, opt_mult, opt_div, opt_mod, opt_lt),
(opt_gt, opt_ltlt, opt_aref, opt_aset, opt_length, opt_size),
(opt_empty_p, opt_succ): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42702 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-08-27 11:11:10 +04:00
|
|
|
|
if (RBASIC_CLASS(recv) == rb_cString &&
|
2012-08-23 11:22:40 +04:00
|
|
|
|
BASIC_OP_UNREDEFINED_P(BOP_LTLT, STRING_REDEFINED_OP_FLAG)) {
|
2007-01-16 11:52:22 +03:00
|
|
|
|
val = rb_str_concat(recv, obj);
|
|
|
|
|
}
|
vm_insnhelper.h: RBASIC_CLASS
* vm_insnhelper.c (opt_eq_func): use RBASIC_CLASS() instead of HEAP_CLASS_OF().
* insns.def (opt_plus, opt_minus, opt_mult, opt_div, opt_mod, opt_lt),
(opt_gt, opt_ltlt, opt_aref, opt_aset, opt_length, opt_size),
(opt_empty_p, opt_succ): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42702 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-08-27 11:11:10 +04:00
|
|
|
|
else if (RBASIC_CLASS(recv) == rb_cArray &&
|
2011-08-25 02:02:03 +04:00
|
|
|
|
BASIC_OP_UNREDEFINED_P(BOP_LTLT, ARRAY_REDEFINED_OP_FLAG)) {
|
2007-01-16 11:52:22 +03:00
|
|
|
|
val = rb_ary_push(recv, obj);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
goto INSN_LABEL(normal_dispatch);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
INSN_LABEL(normal_dispatch):
|
|
|
|
|
PUSH(recv);
|
|
|
|
|
PUSH(obj);
|
* insns.def (send, invokesuper, invokeblock, opt_*), vm_core.h:
use only a `ci' (rb_call_info_t) parameter instead of using
parameters such as `op_id', 'op_argc', `blockiseq' and flag.
These information are stored in rb_call_info_t at the compile
time.
This technique simplifies parameter passings at related
function calls (~10% speedups for simple mehtod invocation at
my machine).
`rb_call_info_t' also has new function pointer variable `call'.
This `call' variable enables to customize method (block)
invocation process for each place. However, it always call
`vm_call_general()' at this changes.
`rb_call_info_t' also has temporary variables for method
(block) invocation.
* vm_core.h, compile.c, insns.def: introduce VM_CALL_ARGS_SKIP_SETUP
VM_CALL macro. This flag indicates that this call can skip
caller_setup (block arg and splat arg).
* compile.c: catch up above changes.
* iseq.c: catch up above changes (especially for TS_CALLINFO).
* tool/instruction.rb: catch up above chagnes.
* vm_insnhelper.c, vm_insnhelper.h: ditto. Macros and functions
parameters are changed.
* vm_eval.c (vm_call0): ditto (it will be rewriten soon).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37180 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-10-14 20:59:05 +04:00
|
|
|
|
CALL_SIMPLE_METHOD(recv);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c optimize
|
|
|
|
|
@e []
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j 最適化された recv[obj]。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
opt_aref
|
2015-09-19 20:59:58 +03:00
|
|
|
|
(CALL_INFO ci, CALL_CACHE cc)
|
2007-01-16 11:52:22 +03:00
|
|
|
|
(VALUE recv, VALUE obj)
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
2011-08-25 02:02:03 +04:00
|
|
|
|
if (!SPECIAL_CONST_P(recv)) {
|
vm_insnhelper.h: RBASIC_CLASS
* vm_insnhelper.c (opt_eq_func): use RBASIC_CLASS() instead of HEAP_CLASS_OF().
* insns.def (opt_plus, opt_minus, opt_mult, opt_div, opt_mod, opt_lt),
(opt_gt, opt_ltlt, opt_aref, opt_aset, opt_length, opt_size),
(opt_empty_p, opt_succ): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42702 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-08-27 11:11:10 +04:00
|
|
|
|
if (RBASIC_CLASS(recv) == rb_cArray && BASIC_OP_UNREDEFINED_P(BOP_AREF, ARRAY_REDEFINED_OP_FLAG) && FIXNUM_P(obj)) {
|
2007-01-16 11:52:22 +03:00
|
|
|
|
val = rb_ary_entry(recv, FIX2LONG(obj));
|
|
|
|
|
}
|
vm_insnhelper.h: RBASIC_CLASS
* vm_insnhelper.c (opt_eq_func): use RBASIC_CLASS() instead of HEAP_CLASS_OF().
* insns.def (opt_plus, opt_minus, opt_mult, opt_div, opt_mod, opt_lt),
(opt_gt, opt_ltlt, opt_aref, opt_aset, opt_length, opt_size),
(opt_empty_p, opt_succ): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42702 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-08-27 11:11:10 +04:00
|
|
|
|
else if (RBASIC_CLASS(recv) == rb_cHash && BASIC_OP_UNREDEFINED_P(BOP_AREF, HASH_REDEFINED_OP_FLAG)) {
|
2007-01-16 11:52:22 +03:00
|
|
|
|
val = rb_hash_aref(recv, obj);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
goto INSN_LABEL(normal_dispatch);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
INSN_LABEL(normal_dispatch):
|
|
|
|
|
PUSH(recv);
|
|
|
|
|
PUSH(obj);
|
* insns.def (send, invokesuper, invokeblock, opt_*), vm_core.h:
use only a `ci' (rb_call_info_t) parameter instead of using
parameters such as `op_id', 'op_argc', `blockiseq' and flag.
These information are stored in rb_call_info_t at the compile
time.
This technique simplifies parameter passings at related
function calls (~10% speedups for simple mehtod invocation at
my machine).
`rb_call_info_t' also has new function pointer variable `call'.
This `call' variable enables to customize method (block)
invocation process for each place. However, it always call
`vm_call_general()' at this changes.
`rb_call_info_t' also has temporary variables for method
(block) invocation.
* vm_core.h, compile.c, insns.def: introduce VM_CALL_ARGS_SKIP_SETUP
VM_CALL macro. This flag indicates that this call can skip
caller_setup (block arg and splat arg).
* compile.c: catch up above changes.
* iseq.c: catch up above changes (especially for TS_CALLINFO).
* tool/instruction.rb: catch up above chagnes.
* vm_insnhelper.c, vm_insnhelper.h: ditto. Macros and functions
parameters are changed.
* vm_eval.c (vm_call0): ditto (it will be rewriten soon).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37180 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-10-14 20:59:05 +04:00
|
|
|
|
CALL_SIMPLE_METHOD(recv);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c optimize
|
|
|
|
|
@e recv[obj] = set
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j 最適化された recv[obj] = set。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
opt_aset
|
2015-09-19 20:59:58 +03:00
|
|
|
|
(CALL_INFO ci, CALL_CACHE cc)
|
2007-01-16 11:52:22 +03:00
|
|
|
|
(VALUE recv, VALUE obj, VALUE set)
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
2011-08-25 02:02:03 +04:00
|
|
|
|
if (!SPECIAL_CONST_P(recv)) {
|
vm_insnhelper.h: RBASIC_CLASS
* vm_insnhelper.c (opt_eq_func): use RBASIC_CLASS() instead of HEAP_CLASS_OF().
* insns.def (opt_plus, opt_minus, opt_mult, opt_div, opt_mod, opt_lt),
(opt_gt, opt_ltlt, opt_aref, opt_aset, opt_length, opt_size),
(opt_empty_p, opt_succ): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42702 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-08-27 11:11:10 +04:00
|
|
|
|
if (RBASIC_CLASS(recv) == rb_cArray && BASIC_OP_UNREDEFINED_P(BOP_ASET, ARRAY_REDEFINED_OP_FLAG) && FIXNUM_P(obj)) {
|
2007-01-16 11:52:22 +03:00
|
|
|
|
rb_ary_store(recv, FIX2LONG(obj), set);
|
|
|
|
|
val = set;
|
|
|
|
|
}
|
vm_insnhelper.h: RBASIC_CLASS
* vm_insnhelper.c (opt_eq_func): use RBASIC_CLASS() instead of HEAP_CLASS_OF().
* insns.def (opt_plus, opt_minus, opt_mult, opt_div, opt_mod, opt_lt),
(opt_gt, opt_ltlt, opt_aref, opt_aset, opt_length, opt_size),
(opt_empty_p, opt_succ): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42702 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-08-27 11:11:10 +04:00
|
|
|
|
else if (RBASIC_CLASS(recv) == rb_cHash && BASIC_OP_UNREDEFINED_P(BOP_ASET, HASH_REDEFINED_OP_FLAG)) {
|
2007-01-16 11:52:22 +03:00
|
|
|
|
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);
|
* insns.def (send, invokesuper, invokeblock, opt_*), vm_core.h:
use only a `ci' (rb_call_info_t) parameter instead of using
parameters such as `op_id', 'op_argc', `blockiseq' and flag.
These information are stored in rb_call_info_t at the compile
time.
This technique simplifies parameter passings at related
function calls (~10% speedups for simple mehtod invocation at
my machine).
`rb_call_info_t' also has new function pointer variable `call'.
This `call' variable enables to customize method (block)
invocation process for each place. However, it always call
`vm_call_general()' at this changes.
`rb_call_info_t' also has temporary variables for method
(block) invocation.
* vm_core.h, compile.c, insns.def: introduce VM_CALL_ARGS_SKIP_SETUP
VM_CALL macro. This flag indicates that this call can skip
caller_setup (block arg and splat arg).
* compile.c: catch up above changes.
* iseq.c: catch up above changes (especially for TS_CALLINFO).
* tool/instruction.rb: catch up above chagnes.
* vm_insnhelper.c, vm_insnhelper.h: ditto. Macros and functions
parameters are changed.
* vm_eval.c (vm_call0): ditto (it will be rewriten soon).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37180 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-10-14 20:59:05 +04:00
|
|
|
|
CALL_SIMPLE_METHOD(recv);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-10 08:54:08 +04:00
|
|
|
|
/**
|
|
|
|
|
@c optimize
|
|
|
|
|
@e recv[str] = set
|
|
|
|
|
@j 最適化された recv[str] = set。
|
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
opt_aset_with
|
2015-09-19 20:59:58 +03:00
|
|
|
|
(CALL_INFO ci, CALL_CACHE cc, VALUE key)
|
2014-01-10 08:54:08 +04:00
|
|
|
|
(VALUE recv, VALUE val)
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
|
|
|
|
if (!SPECIAL_CONST_P(recv) && RBASIC_CLASS(recv) == rb_cHash && BASIC_OP_UNREDEFINED_P(BOP_ASET, HASH_REDEFINED_OP_FLAG)) {
|
|
|
|
|
rb_hash_aset(recv, key, val);
|
2014-01-25 07:15:30 +04:00
|
|
|
|
}
|
|
|
|
|
else {
|
2014-01-10 08:54:08 +04:00
|
|
|
|
PUSH(recv);
|
|
|
|
|
PUSH(rb_str_resurrect(key));
|
|
|
|
|
PUSH(val);
|
|
|
|
|
CALL_SIMPLE_METHOD(recv);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c optimize
|
|
|
|
|
@e recv[str]
|
|
|
|
|
@j 最適化された recv[str]。
|
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
opt_aref_with
|
2015-09-19 20:59:58 +03:00
|
|
|
|
(CALL_INFO ci, CALL_CACHE cc, VALUE key)
|
2014-01-10 08:54:08 +04:00
|
|
|
|
(VALUE recv)
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
|
|
|
|
if (!SPECIAL_CONST_P(recv) && RBASIC_CLASS(recv) == rb_cHash && BASIC_OP_UNREDEFINED_P(BOP_AREF, HASH_REDEFINED_OP_FLAG)) {
|
|
|
|
|
val = rb_hash_aref(recv, key);
|
2014-01-25 07:15:30 +04:00
|
|
|
|
}
|
|
|
|
|
else {
|
2014-01-10 08:54:08 +04:00
|
|
|
|
PUSH(recv);
|
|
|
|
|
PUSH(rb_str_resurrect(key));
|
|
|
|
|
CALL_SIMPLE_METHOD(recv);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-01-16 11:52:22 +03:00
|
|
|
|
/**
|
|
|
|
|
@c optimize
|
|
|
|
|
@e optimized length
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j 最適化された recv.length()。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
opt_length
|
2015-09-19 20:59:58 +03:00
|
|
|
|
(CALL_INFO ci, CALL_CACHE cc)
|
2007-01-16 11:52:22 +03:00
|
|
|
|
(VALUE recv)
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
2011-08-25 02:02:03 +04:00
|
|
|
|
if (!SPECIAL_CONST_P(recv)) {
|
vm_insnhelper.h: RBASIC_CLASS
* vm_insnhelper.c (opt_eq_func): use RBASIC_CLASS() instead of HEAP_CLASS_OF().
* insns.def (opt_plus, opt_minus, opt_mult, opt_div, opt_mod, opt_lt),
(opt_gt, opt_ltlt, opt_aref, opt_aset, opt_length, opt_size),
(opt_empty_p, opt_succ): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42702 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-08-27 11:11:10 +04:00
|
|
|
|
if (RBASIC_CLASS(recv) == rb_cString &&
|
2011-08-25 02:02:03 +04:00
|
|
|
|
BASIC_OP_UNREDEFINED_P(BOP_LENGTH, STRING_REDEFINED_OP_FLAG)) {
|
2007-08-25 12:54:29 +04:00
|
|
|
|
val = rb_str_length(recv);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
vm_insnhelper.h: RBASIC_CLASS
* vm_insnhelper.c (opt_eq_func): use RBASIC_CLASS() instead of HEAP_CLASS_OF().
* insns.def (opt_plus, opt_minus, opt_mult, opt_div, opt_mod, opt_lt),
(opt_gt, opt_ltlt, opt_aref, opt_aset, opt_length, opt_size),
(opt_empty_p, opt_succ): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42702 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-08-27 11:11:10 +04:00
|
|
|
|
else if (RBASIC_CLASS(recv) == rb_cArray &&
|
2011-08-25 02:02:03 +04:00
|
|
|
|
BASIC_OP_UNREDEFINED_P(BOP_LENGTH, ARRAY_REDEFINED_OP_FLAG)) {
|
2007-08-25 12:54:29 +04:00
|
|
|
|
val = LONG2NUM(RARRAY_LEN(recv));
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
vm_insnhelper.h: RBASIC_CLASS
* vm_insnhelper.c (opt_eq_func): use RBASIC_CLASS() instead of HEAP_CLASS_OF().
* insns.def (opt_plus, opt_minus, opt_mult, opt_div, opt_mod, opt_lt),
(opt_gt, opt_ltlt, opt_aref, opt_aset, opt_length, opt_size),
(opt_empty_p, opt_succ): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42702 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-08-27 11:11:10 +04:00
|
|
|
|
else if (RBASIC_CLASS(recv) == rb_cHash &&
|
2011-08-25 02:02:03 +04:00
|
|
|
|
BASIC_OP_UNREDEFINED_P(BOP_LENGTH, HASH_REDEFINED_OP_FLAG)) {
|
2007-08-30 03:12:21 +04:00
|
|
|
|
val = INT2FIX(RHASH_SIZE(recv));
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
goto INSN_LABEL(normal_dispatch);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
INSN_LABEL(normal_dispatch):
|
2007-06-24 17:05:51 +04:00
|
|
|
|
PUSH(recv);
|
* insns.def (send, invokesuper, invokeblock, opt_*), vm_core.h:
use only a `ci' (rb_call_info_t) parameter instead of using
parameters such as `op_id', 'op_argc', `blockiseq' and flag.
These information are stored in rb_call_info_t at the compile
time.
This technique simplifies parameter passings at related
function calls (~10% speedups for simple mehtod invocation at
my machine).
`rb_call_info_t' also has new function pointer variable `call'.
This `call' variable enables to customize method (block)
invocation process for each place. However, it always call
`vm_call_general()' at this changes.
`rb_call_info_t' also has temporary variables for method
(block) invocation.
* vm_core.h, compile.c, insns.def: introduce VM_CALL_ARGS_SKIP_SETUP
VM_CALL macro. This flag indicates that this call can skip
caller_setup (block arg and splat arg).
* compile.c: catch up above changes.
* iseq.c: catch up above changes (especially for TS_CALLINFO).
* tool/instruction.rb: catch up above chagnes.
* vm_insnhelper.c, vm_insnhelper.h: ditto. Macros and functions
parameters are changed.
* vm_eval.c (vm_call0): ditto (it will be rewriten soon).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37180 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-10-14 20:59:05 +04:00
|
|
|
|
CALL_SIMPLE_METHOD(recv);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-09-06 12:39:57 +04:00
|
|
|
|
/**
|
|
|
|
|
@c optimize
|
|
|
|
|
@e optimized size
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j 最適化された recv.size()。
|
2009-09-06 12:39:57 +04:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
opt_size
|
2015-09-19 20:59:58 +03:00
|
|
|
|
(CALL_INFO ci, CALL_CACHE cc)
|
2009-09-06 12:39:57 +04:00
|
|
|
|
(VALUE recv)
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
2011-08-25 02:02:03 +04:00
|
|
|
|
if (!SPECIAL_CONST_P(recv)) {
|
vm_insnhelper.h: RBASIC_CLASS
* vm_insnhelper.c (opt_eq_func): use RBASIC_CLASS() instead of HEAP_CLASS_OF().
* insns.def (opt_plus, opt_minus, opt_mult, opt_div, opt_mod, opt_lt),
(opt_gt, opt_ltlt, opt_aref, opt_aset, opt_length, opt_size),
(opt_empty_p, opt_succ): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42702 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-08-27 11:11:10 +04:00
|
|
|
|
if (RBASIC_CLASS(recv) == rb_cString &&
|
2011-08-25 02:02:03 +04:00
|
|
|
|
BASIC_OP_UNREDEFINED_P(BOP_SIZE, STRING_REDEFINED_OP_FLAG)) {
|
2009-09-06 12:39:57 +04:00
|
|
|
|
val = rb_str_length(recv);
|
|
|
|
|
}
|
vm_insnhelper.h: RBASIC_CLASS
* vm_insnhelper.c (opt_eq_func): use RBASIC_CLASS() instead of HEAP_CLASS_OF().
* insns.def (opt_plus, opt_minus, opt_mult, opt_div, opt_mod, opt_lt),
(opt_gt, opt_ltlt, opt_aref, opt_aset, opt_length, opt_size),
(opt_empty_p, opt_succ): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42702 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-08-27 11:11:10 +04:00
|
|
|
|
else if (RBASIC_CLASS(recv) == rb_cArray &&
|
2011-08-25 02:02:03 +04:00
|
|
|
|
BASIC_OP_UNREDEFINED_P(BOP_SIZE, ARRAY_REDEFINED_OP_FLAG)) {
|
2009-09-06 12:39:57 +04:00
|
|
|
|
val = LONG2NUM(RARRAY_LEN(recv));
|
|
|
|
|
}
|
vm_insnhelper.h: RBASIC_CLASS
* vm_insnhelper.c (opt_eq_func): use RBASIC_CLASS() instead of HEAP_CLASS_OF().
* insns.def (opt_plus, opt_minus, opt_mult, opt_div, opt_mod, opt_lt),
(opt_gt, opt_ltlt, opt_aref, opt_aset, opt_length, opt_size),
(opt_empty_p, opt_succ): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42702 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-08-27 11:11:10 +04:00
|
|
|
|
else if (RBASIC_CLASS(recv) == rb_cHash &&
|
2011-08-25 02:02:03 +04:00
|
|
|
|
BASIC_OP_UNREDEFINED_P(BOP_SIZE, HASH_REDEFINED_OP_FLAG)) {
|
2009-09-06 12:39:57 +04:00
|
|
|
|
val = INT2FIX(RHASH_SIZE(recv));
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
goto INSN_LABEL(normal_dispatch);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
INSN_LABEL(normal_dispatch):
|
|
|
|
|
PUSH(recv);
|
* insns.def (send, invokesuper, invokeblock, opt_*), vm_core.h:
use only a `ci' (rb_call_info_t) parameter instead of using
parameters such as `op_id', 'op_argc', `blockiseq' and flag.
These information are stored in rb_call_info_t at the compile
time.
This technique simplifies parameter passings at related
function calls (~10% speedups for simple mehtod invocation at
my machine).
`rb_call_info_t' also has new function pointer variable `call'.
This `call' variable enables to customize method (block)
invocation process for each place. However, it always call
`vm_call_general()' at this changes.
`rb_call_info_t' also has temporary variables for method
(block) invocation.
* vm_core.h, compile.c, insns.def: introduce VM_CALL_ARGS_SKIP_SETUP
VM_CALL macro. This flag indicates that this call can skip
caller_setup (block arg and splat arg).
* compile.c: catch up above changes.
* iseq.c: catch up above changes (especially for TS_CALLINFO).
* tool/instruction.rb: catch up above chagnes.
* vm_insnhelper.c, vm_insnhelper.h: ditto. Macros and functions
parameters are changed.
* vm_eval.c (vm_call0): ditto (it will be rewriten soon).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37180 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-10-14 20:59:05 +04:00
|
|
|
|
CALL_SIMPLE_METHOD(recv);
|
2009-09-06 12:39:57 +04:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-26 13:34:46 +04:00
|
|
|
|
/**
|
|
|
|
|
@c optimize
|
|
|
|
|
@e optimized empty?
|
|
|
|
|
@j 最適化された recv.empty?()。
|
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
opt_empty_p
|
2015-09-19 20:59:58 +03:00
|
|
|
|
(CALL_INFO ci, CALL_CACHE cc)
|
2012-09-26 13:34:46 +04:00
|
|
|
|
(VALUE recv)
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
|
|
|
|
if (!SPECIAL_CONST_P(recv)) {
|
vm_insnhelper.h: RBASIC_CLASS
* vm_insnhelper.c (opt_eq_func): use RBASIC_CLASS() instead of HEAP_CLASS_OF().
* insns.def (opt_plus, opt_minus, opt_mult, opt_div, opt_mod, opt_lt),
(opt_gt, opt_ltlt, opt_aref, opt_aset, opt_length, opt_size),
(opt_empty_p, opt_succ): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42702 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-08-27 11:11:10 +04:00
|
|
|
|
if (RBASIC_CLASS(recv) == rb_cString &&
|
2012-09-26 13:34:46 +04:00
|
|
|
|
BASIC_OP_UNREDEFINED_P(BOP_EMPTY_P, STRING_REDEFINED_OP_FLAG)) {
|
|
|
|
|
if (RSTRING_LEN(recv) == 0) val = Qtrue;
|
|
|
|
|
else val = Qfalse;
|
|
|
|
|
}
|
vm_insnhelper.h: RBASIC_CLASS
* vm_insnhelper.c (opt_eq_func): use RBASIC_CLASS() instead of HEAP_CLASS_OF().
* insns.def (opt_plus, opt_minus, opt_mult, opt_div, opt_mod, opt_lt),
(opt_gt, opt_ltlt, opt_aref, opt_aset, opt_length, opt_size),
(opt_empty_p, opt_succ): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42702 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-08-27 11:11:10 +04:00
|
|
|
|
else if (RBASIC_CLASS(recv) == rb_cArray &&
|
2012-09-26 13:34:46 +04:00
|
|
|
|
BASIC_OP_UNREDEFINED_P(BOP_EMPTY_P, ARRAY_REDEFINED_OP_FLAG)) {
|
|
|
|
|
if (RARRAY_LEN(recv) == 0) val = Qtrue;
|
|
|
|
|
else val = Qfalse;
|
|
|
|
|
}
|
vm_insnhelper.h: RBASIC_CLASS
* vm_insnhelper.c (opt_eq_func): use RBASIC_CLASS() instead of HEAP_CLASS_OF().
* insns.def (opt_plus, opt_minus, opt_mult, opt_div, opt_mod, opt_lt),
(opt_gt, opt_ltlt, opt_aref, opt_aset, opt_length, opt_size),
(opt_empty_p, opt_succ): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42702 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-08-27 11:11:10 +04:00
|
|
|
|
else if (RBASIC_CLASS(recv) == rb_cHash &&
|
2012-09-26 13:34:46 +04:00
|
|
|
|
BASIC_OP_UNREDEFINED_P(BOP_EMPTY_P, HASH_REDEFINED_OP_FLAG)) {
|
|
|
|
|
if (RHASH_EMPTY_P(recv)) val = Qtrue;
|
|
|
|
|
else val = Qfalse;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
goto INSN_LABEL(normal_dispatch);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
INSN_LABEL(normal_dispatch):
|
|
|
|
|
PUSH(recv);
|
* insns.def (send, invokesuper, invokeblock, opt_*), vm_core.h:
use only a `ci' (rb_call_info_t) parameter instead of using
parameters such as `op_id', 'op_argc', `blockiseq' and flag.
These information are stored in rb_call_info_t at the compile
time.
This technique simplifies parameter passings at related
function calls (~10% speedups for simple mehtod invocation at
my machine).
`rb_call_info_t' also has new function pointer variable `call'.
This `call' variable enables to customize method (block)
invocation process for each place. However, it always call
`vm_call_general()' at this changes.
`rb_call_info_t' also has temporary variables for method
(block) invocation.
* vm_core.h, compile.c, insns.def: introduce VM_CALL_ARGS_SKIP_SETUP
VM_CALL macro. This flag indicates that this call can skip
caller_setup (block arg and splat arg).
* compile.c: catch up above changes.
* iseq.c: catch up above changes (especially for TS_CALLINFO).
* tool/instruction.rb: catch up above chagnes.
* vm_insnhelper.c, vm_insnhelper.h: ditto. Macros and functions
parameters are changed.
* vm_eval.c (vm_call0): ditto (it will be rewriten soon).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37180 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-10-14 20:59:05 +04:00
|
|
|
|
CALL_SIMPLE_METHOD(recv);
|
2012-09-26 13:34:46 +04:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-01-16 11:52:22 +03:00
|
|
|
|
/**
|
|
|
|
|
@c optimize
|
|
|
|
|
@e optimized succ
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j 最適化された recv.succ()。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
opt_succ
|
2015-09-19 20:59:58 +03:00
|
|
|
|
(CALL_INFO ci, CALL_CACHE cc)
|
2007-01-16 11:52:22 +03:00
|
|
|
|
(VALUE recv)
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
|
|
|
|
if (SPECIAL_CONST_P(recv)) {
|
|
|
|
|
if (FIXNUM_P(recv) &&
|
2011-08-25 02:02:03 +04:00
|
|
|
|
BASIC_OP_UNREDEFINED_P(BOP_SUCC, FIXNUM_REDEFINED_OP_FLAG)) {
|
2007-01-16 11:52:22 +03:00
|
|
|
|
const VALUE obj = INT2FIX(1);
|
|
|
|
|
/* fixnum + INT2FIX(1) */
|
|
|
|
|
val = (recv + (obj & (~1)));
|
2007-07-13 12:42:27 +04:00
|
|
|
|
if ((~(recv ^ obj) & (recv ^ val)) & ((unsigned long)LONG_MAX + 1)) {
|
2007-07-12 13:52:48 +04:00
|
|
|
|
val = rb_big_plus(rb_int2big(FIX2LONG(recv)),
|
|
|
|
|
rb_int2big(FIX2LONG(obj)));
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
goto INSN_LABEL(normal_dispatch);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
vm_insnhelper.h: RBASIC_CLASS
* vm_insnhelper.c (opt_eq_func): use RBASIC_CLASS() instead of HEAP_CLASS_OF().
* insns.def (opt_plus, opt_minus, opt_mult, opt_div, opt_mod, opt_lt),
(opt_gt, opt_ltlt, opt_aref, opt_aset, opt_length, opt_size),
(opt_empty_p, opt_succ): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42702 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-08-27 11:11:10 +04:00
|
|
|
|
if (RBASIC_CLASS(recv) == rb_cString &&
|
2011-08-25 02:02:03 +04:00
|
|
|
|
BASIC_OP_UNREDEFINED_P(BOP_SUCC, STRING_REDEFINED_OP_FLAG)) {
|
2007-01-16 11:52:22 +03:00
|
|
|
|
val = rb_str_succ(recv);
|
|
|
|
|
}
|
2007-12-18 15:07:51 +03:00
|
|
|
|
else
|
|
|
|
|
{
|
2007-01-16 11:52:22 +03:00
|
|
|
|
goto INSN_LABEL(normal_dispatch);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (0) {
|
|
|
|
|
INSN_LABEL(normal_dispatch):
|
2007-06-24 17:05:51 +04:00
|
|
|
|
PUSH(recv);
|
* insns.def (send, invokesuper, invokeblock, opt_*), vm_core.h:
use only a `ci' (rb_call_info_t) parameter instead of using
parameters such as `op_id', 'op_argc', `blockiseq' and flag.
These information are stored in rb_call_info_t at the compile
time.
This technique simplifies parameter passings at related
function calls (~10% speedups for simple mehtod invocation at
my machine).
`rb_call_info_t' also has new function pointer variable `call'.
This `call' variable enables to customize method (block)
invocation process for each place. However, it always call
`vm_call_general()' at this changes.
`rb_call_info_t' also has temporary variables for method
(block) invocation.
* vm_core.h, compile.c, insns.def: introduce VM_CALL_ARGS_SKIP_SETUP
VM_CALL macro. This flag indicates that this call can skip
caller_setup (block arg and splat arg).
* compile.c: catch up above changes.
* iseq.c: catch up above changes (especially for TS_CALLINFO).
* tool/instruction.rb: catch up above chagnes.
* vm_insnhelper.c, vm_insnhelper.h: ditto. Macros and functions
parameters are changed.
* vm_eval.c (vm_call0): ditto (it will be rewriten soon).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37180 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-10-14 20:59:05 +04:00
|
|
|
|
CALL_SIMPLE_METHOD(recv);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-12-18 15:07:51 +03:00
|
|
|
|
/**
|
|
|
|
|
@c optimize
|
|
|
|
|
@e optimized not
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j 最適化された recv.!()。
|
2007-12-18 15:07:51 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
opt_not
|
2015-09-19 20:59:58 +03:00
|
|
|
|
(CALL_INFO ci, CALL_CACHE cc)
|
2007-12-18 15:07:51 +03:00
|
|
|
|
(VALUE recv)
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
|
|
|
|
extern VALUE rb_obj_not(VALUE obj);
|
|
|
|
|
|
2015-09-19 20:59:58 +03:00
|
|
|
|
vm_search_method(ci, cc, recv);
|
|
|
|
|
|
|
|
|
|
if (check_cfunc(cc->me, rb_obj_not)) {
|
2007-12-18 15:07:51 +03:00
|
|
|
|
val = RTEST(recv) ? Qfalse : Qtrue;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
PUSH(recv);
|
* insns.def (send, invokesuper, invokeblock, opt_*), vm_core.h:
use only a `ci' (rb_call_info_t) parameter instead of using
parameters such as `op_id', 'op_argc', `blockiseq' and flag.
These information are stored in rb_call_info_t at the compile
time.
This technique simplifies parameter passings at related
function calls (~10% speedups for simple mehtod invocation at
my machine).
`rb_call_info_t' also has new function pointer variable `call'.
This `call' variable enables to customize method (block)
invocation process for each place. However, it always call
`vm_call_general()' at this changes.
`rb_call_info_t' also has temporary variables for method
(block) invocation.
* vm_core.h, compile.c, insns.def: introduce VM_CALL_ARGS_SKIP_SETUP
VM_CALL macro. This flag indicates that this call can skip
caller_setup (block arg and splat arg).
* compile.c: catch up above changes.
* iseq.c: catch up above changes (especially for TS_CALLINFO).
* tool/instruction.rb: catch up above chagnes.
* vm_insnhelper.c, vm_insnhelper.h: ditto. Macros and functions
parameters are changed.
* vm_eval.c (vm_call0): ditto (it will be rewriten soon).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37180 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-10-14 20:59:05 +04:00
|
|
|
|
CALL_SIMPLE_METHOD(recv);
|
2007-12-18 15:07:51 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-01-16 11:52:22 +03:00
|
|
|
|
/**
|
|
|
|
|
@c optimize
|
|
|
|
|
@e optimized regexp match
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j 最適化された正規表現マッチ。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
opt_regexpmatch1
|
|
|
|
|
(VALUE r)
|
|
|
|
|
(VALUE obj)
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
2013-09-26 11:39:48 +04:00
|
|
|
|
if (BASIC_OP_UNREDEFINED_P(BOP_MATCH, REGEXP_REDEFINED_OP_FLAG)) {
|
|
|
|
|
val = rb_reg_match(r, obj);
|
2014-01-25 07:15:30 +04:00
|
|
|
|
}
|
|
|
|
|
else {
|
2013-09-26 11:39:48 +04:00
|
|
|
|
val = rb_funcall(r, idEqTilde, 1, obj);
|
|
|
|
|
}
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c optimize
|
|
|
|
|
@e optimized regexp match 2
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j 最適化された正規表現マッチ 2
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
opt_regexpmatch2
|
2015-09-19 20:59:58 +03:00
|
|
|
|
(CALL_INFO ci, CALL_CACHE cc)
|
2007-01-16 11:52:22 +03:00
|
|
|
|
(VALUE obj2, VALUE obj1)
|
|
|
|
|
(VALUE val)
|
|
|
|
|
{
|
2014-03-12 02:28:33 +04:00
|
|
|
|
if (CLASS_OF(obj2) == rb_cString &&
|
2013-09-26 11:58:28 +04:00
|
|
|
|
BASIC_OP_UNREDEFINED_P(BOP_MATCH, STRING_REDEFINED_OP_FLAG)) {
|
2007-01-16 11:52:22 +03:00
|
|
|
|
val = rb_reg_match(obj1, obj2);
|
|
|
|
|
}
|
|
|
|
|
else {
|
2013-08-31 10:07:21 +04:00
|
|
|
|
PUSH(obj2);
|
|
|
|
|
PUSH(obj1);
|
|
|
|
|
CALL_SIMPLE_METHOD(obj2);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@c optimize
|
|
|
|
|
@e call native compiled method
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j ネイティブコンパイルしたメソッドを起動。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
2007-06-30 22:02:24 +04:00
|
|
|
|
opt_call_c_function
|
2007-08-12 23:09:15 +04:00
|
|
|
|
(rb_insn_func_t funcptr)
|
2007-01-16 11:52:22 +03:00
|
|
|
|
()
|
|
|
|
|
()
|
|
|
|
|
{
|
2007-06-30 22:02:24 +04:00
|
|
|
|
reg_cfp = (funcptr)(th, reg_cfp);
|
2007-01-16 11:52:22 +03:00
|
|
|
|
|
2007-06-30 22:02:24 +04:00
|
|
|
|
if (reg_cfp == 0) {
|
|
|
|
|
VALUE err = th->errinfo;
|
|
|
|
|
th->errinfo = Qnil;
|
2007-07-02 06:59:37 +04:00
|
|
|
|
THROW_EXCEPTION(err);
|
2007-06-30 22:02:24 +04:00
|
|
|
|
}
|
|
|
|
|
|
2007-07-02 16:49:35 +04:00
|
|
|
|
RESTORE_REGS();
|
2007-06-30 22:02:24 +04:00
|
|
|
|
NEXT_INSN();
|
2007-01-16 11:52:22 +03: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
|
2011-09-04 16:22:46 +04:00
|
|
|
|
@j 人生、宇宙、すべての答え。
|
2007-01-16 11:52:22 +03:00
|
|
|
|
*/
|
|
|
|
|
DEFINE_INSN
|
|
|
|
|
answer
|
|
|
|
|
()
|
|
|
|
|
()
|
|
|
|
|
(VALUE ret)
|
|
|
|
|
{
|
|
|
|
|
ret = INT2FIX(42);
|
|
|
|
|
}
|
|
|
|
|
|