summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--insns.def11
-rw-r--r--tool/ruby_vm/views/_insn_entry.erb14
-rw-r--r--vm_insnhelper.c4
-rw-r--r--vm_insnhelper.h16
4 files changed, 27 insertions, 18 deletions
diff --git a/insns.def b/insns.def
index cd57fbd6b8..69f1795814 100644
--- a/insns.def
+++ b/insns.def
@@ -366,7 +366,6 @@ concatstrings
// attr rb_snum_t sp_inc = 1 - num;
{
val = rb_str_concat_literals(num, STACK_ADDR_FROM_TOP(num));
- POPN(num);
}
/* push the result of to_s. */
@@ -403,7 +402,6 @@ toregexp
VALUE rb_reg_new_ary(VALUE ary, int options);
VALUE rb_ary_tmp_new_from_values(VALUE, long, const VALUE *);
const VALUE ary = rb_ary_tmp_new_from_values(0, cnt, STACK_ADDR_FROM_TOP(cnt));
- POPN(cnt);
val = rb_reg_new_ary(ary, (int)opt);
rb_ary_clear(ary);
}
@@ -427,7 +425,6 @@ newarray
// attr rb_snum_t sp_inc = 1 - num;
{
val = rb_ary_new4(num, STACK_ADDR_FROM_TOP(num));
- POPN(num);
}
/* dup array */
@@ -494,7 +491,6 @@ newhash
if (num) {
rb_hash_bulk_insert(num, STACK_ADDR_FROM_TOP(num), val);
}
- POPN(num);
}
/* put new Range object.(Range.new(low, high, flag)) */
@@ -545,6 +541,7 @@ dupn
INC_SP(n); /* alloca */
MEMCPY(dst, src, VALUE, n);
+ DEC_SP(n);
}
/* swap top 2 vals */
@@ -606,7 +603,7 @@ setn
(VALUE val)
// attr rb_snum_t sp_inc = 0;
{
- TOPN(n-1) = val;
+ TOPN(n) = val;
}
/* empty current stack */
@@ -617,7 +614,7 @@ adjuststack
(...)
// attr rb_snum_t sp_inc = -(rb_snum_t)n;
{
- DEC_SP(n);
+ /* none */
}
/**********************************************************/
@@ -757,7 +754,6 @@ opt_newarray_max
// attr rb_snum_t sp_inc = 1 - num;
{
val = vm_opt_newarray_max(num, STACK_ADDR_FROM_TOP(num));
- POPN(num);
}
DEFINE_INSN
@@ -768,7 +764,6 @@ opt_newarray_min
// attr rb_snum_t sp_inc = 1 - num;
{
val = vm_opt_newarray_min(num, STACK_ADDR_FROM_TOP(num));
- POPN(num);
}
/* Invoke method without block */
diff --git a/tool/ruby_vm/views/_insn_entry.erb b/tool/ruby_vm/views/_insn_entry.erb
index 708f637f83..2118dece86 100644
--- a/tool/ruby_vm/views/_insn_entry.erb
+++ b/tool/ruby_vm/views/_insn_entry.erb
@@ -21,7 +21,6 @@ INSN_ENTRY(<%= insn.name %>)
% insn.preamble.each do |konst|
<%= render_c_expr konst -%>
% end
-%
% insn.opes.each_with_index do |ope, i|
<%= ope[:name] %> = (<%= ope[:type] %>)GET_OPERAND(<%= i + 1 %>);
% end
@@ -32,8 +31,6 @@ INSN_ENTRY(<%= insn.name %>)
DEBUG_ENTER_INSN(INSN_ATTR(name));
% if insn.handles_frame?
ADD_PC(INSN_ATTR(width));
-% end
-% unless insn.pops.empty?
POPN(INSN_ATTR(popn));
% end
COLLECT_USAGE_INSN(INSN_ATTR(bin));
@@ -41,13 +38,16 @@ INSN_ENTRY(<%= insn.name %>)
COLLECT_USAGE_OPERAND(INSN_ATTR(bin), <%= i %>, <%= ope[:name] %>);
% end
<%= render_c_expr insn.expr -%>
-% unless insn.rets.empty?
CHECK_VM_STACK_OVERFLOW_FOR_INSN(VM_REG_CFP, INSN_ATTR(retn));
-% insn.rets.each_with_index do |ret, i|
+% if insn.handles_frame?
+% insn.rets.reverse_each do |ret|
PUSH(<%= insn.cast_to_VALUE ret %>);
% end
-% end
-% unless insn.handles_frame?
+% else
+ ADJ_SP(INSN_ATTR(sp_inc));
+% insn.rets.reverse_each.with_index do |ret, i|
+ TOPN(<%= i %>) = <%= insn.cast_to_VALUE ret %>;
+% end
ADD_PC(INSN_ATTR(width));
PREFETCH(GET_PC());
% end
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index 9903bcc176..acb7d7999d 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -1235,7 +1235,7 @@ vm_expandarray(rb_control_frame_t *cfp, VALUE ary, rb_num_t num, int flag)
{
int is_splat = flag & 0x01;
rb_num_t space_size = num + is_splat;
- VALUE *base = cfp->sp;
+ VALUE *base = cfp->sp - 1;
const VALUE *ptr;
rb_num_t len;
const VALUE obj = ary;
@@ -1250,8 +1250,6 @@ vm_expandarray(rb_control_frame_t *cfp, VALUE ary, rb_num_t num, int flag)
len = (rb_num_t)RARRAY_LEN(ary);
}
- cfp->sp += space_size;
-
if (flag & 0x02) {
/* post: ..., nil ,ary[-1], ..., ary[0..-num] # top */
rb_num_t i = 0, j;
diff --git a/vm_insnhelper.h b/vm_insnhelper.h
index 71ca408bf2..0fc31d2cea 100644
--- a/vm_insnhelper.h
+++ b/vm_insnhelper.h
@@ -101,6 +101,22 @@ enum vm_regan_acttype {
#define DEC_SP(x) (VM_REG_SP -= (COLLECT_USAGE_REGISTER_HELPER(SP, SET, (x))))
#define SET_SV(x) (*GET_SP() = (x))
/* set current stack value as x */
+#ifdef _MSC_VER
+/* Workaround needed for adding negative number to a pointer */
+#define ADJ_SP(x) do { \
+ rb_snum_t adj = (x); \
+ if (adj >= 0) { \
+ INC_SP(adj); \
+ } \
+ else { \
+ SIGNED_VALUE dec = -1; \
+ dec *= adj; \
+ DEC_SP(dec); \
+ } \
+} while (0)
+#else
+#define ADJ_SP(x) INC_SP(x)
+#endif
/* instruction sequence C struct */
#define GET_ISEQ() (GET_CFP()->iseq)