Project

General

Profile

Feature #12005 ยป unify-fixnum-and-bignum.patch

akr (Akira Tanaka), 05/03/2016 10:18 AM

View differences:

bignum.c (working copy)
#define BIGNUM_SET_NEGATIVE_SIGN(b) BIGNUM_SET_SIGN(b, 0)
#define BIGNUM_SET_POSITIVE_SIGN(b) BIGNUM_SET_SIGN(b, 1)
#define bignew(len,sign) bignew_1(rb_cBignum,(len),(sign))
#define bignew(len,sign) bignew_1(rb_cInteger,(len),(sign))
#define BDIGITS_ZERO(ptr, n) do { \
BDIGIT *bdigitz_zero_ptr = (ptr); \
......
*/
static VALUE
rb_big_coerce(VALUE x, VALUE y)
rb_int_coerce(VALUE x, VALUE y)
{
if (FIXNUM_P(y)) {
y = rb_int2big(FIX2LONG(y));
if (FIXNUM_P(y) || RB_BIGNUM_TYPE_P(y)) {
return rb_assoc_new(y, x);
}
else if (!RB_BIGNUM_TYPE_P(y)) {
rb_raise(rb_eTypeError, "can't coerce %"PRIsVALUE" to Bignum",
rb_obj_class(y));
else {
x = rb_Float(x);
y = rb_Float(y);
return rb_assoc_new(y, x);
}
return rb_assoc_new(y, x);
}
VALUE
......
void
Init_Bignum(void)
{
rb_cBignum = rb_define_class("Bignum", rb_cInteger);
rb_define_method(rb_cBignum, "coerce", rb_big_coerce, 1);
rb_cBignum = rb_cInteger;
rb_define_const(rb_cObject, "Bignum", rb_cInteger);
rb_define_method(rb_cBignum, "===", rb_big_eq, 1);
rb_define_method(rb_cInteger, "coerce", rb_int_coerce, 1);
#ifdef USE_GMP
/* The version of loaded GMP. */
rb_define_const(rb_cBignum, "GMP_VERSION", rb_sprintf("GMP %s", gmp_version));
rb_define_const(rb_cInteger, "GMP_VERSION", rb_sprintf("GMP %s", gmp_version));
#endif
bootstraptest/test_literal.rb (working copy)
assert_equal ':sym', ':sym.inspect'
assert_equal 'Symbol', ':sym.class'
assert_equal '1234', '1234'
assert_equal 'Fixnum', '1234.class'
assert_equal 'Integer', '1234.class'
assert_equal '1234', '1_2_3_4'
assert_equal 'Fixnum', '1_2_3_4.class'
assert_equal 'Integer', '1_2_3_4.class'
assert_equal '18', '0x12'
assert_equal 'Fixnum', '0x12.class'
assert_equal 'Integer', '0x12.class'
assert_equal '15', '0o17'
assert_equal 'Fixnum', '0o17.class'
assert_equal 'Integer', '0o17.class'
assert_equal '5', '0b101'
assert_equal 'Fixnum', '0b101.class'
assert_equal 'Integer', '0b101.class'
assert_equal '123456789012345678901234567890', '123456789012345678901234567890'
assert_equal 'Bignum', '123456789012345678901234567890.class'
assert_equal 'Integer', '123456789012345678901234567890.class'
assert_equal '2.0', '2.0'
assert_equal 'Float', '1.3.class'
......
assert_equal 'c', 'r = ("a".."c"); r.end'
assert_equal 'String', '__FILE__.class'
assert_equal 'Fixnum', '__LINE__.class'
assert_equal 'Integer', '__LINE__.class'
###
error.c (working copy)
etype = "nil";
}
else if (FIXNUM_P(x)) {
etype = "Fixnum";
etype = "Integer";
}
else if (SYMBOL_P(x)) {
etype = "Symbol";
ext/-test-/testutil/extconf.rb (working copy)
# frozen_string_literal: false
$INCFLAGS << " -I$(topdir) -I$(top_srcdir)"
$srcs = Dir[File.join($srcdir, "*.{#{SRC_EXT.join(%q{,})}}")]
inits = $srcs.map {|s| File.basename(s, ".*")}
inits.delete("init")
inits.map! {|s|"X(#{s})"}
$defs << "-DTEST_INIT_FUNCS(X)=\"#{inits.join(' ')}\""
create_makefile("-test-/testutil")
ext/-test-/testutil/init.c (working copy)
#include "ruby.h"
#define init(n) {void Init_##n(VALUE klass); Init_##n(klass);}
void
Init_testutil(void)
{
VALUE mBug = rb_define_module("Bug");
VALUE klass = rb_define_class_under(mBug, "TestUtil", rb_cObject);
TEST_INIT_FUNCS(init);
}
ext/-test-/testutil/integer.c (working copy)
#include "internal.h"
static VALUE
int_bignum_p(VALUE self)
{
return RB_TYPE_P(self, T_BIGNUM) ? Qtrue : Qfalse;
}
static VALUE
int_fixnum_p(VALUE self)
{
return FIXNUM_P(self) ? Qtrue : Qfalse;
}
static VALUE
rb_int_to_bignum(VALUE x)
{
if (FIXNUM_P(x))
x = rb_int2big(FIX2LONG(x));
return x;
}
void
Init_integer(VALUE klass)
{
rb_define_method(rb_cInteger, "bignum?", int_bignum_p, 0);
rb_define_method(rb_cInteger, "fixnum?", int_fixnum_p, 0);
rb_define_method(rb_cInteger, "to_bignum", rb_int_to_bignum, 0);
}
ext/json/generator/generator.c (working copy)
#endif
static VALUE mJSON, mExt, mGenerator, cState, mGeneratorMethods, mObject,
mHash, mArray, mFixnum, mBignum, mFloat, mString, mString_Extend,
mHash, mArray, mInteger, mFixnum, mBignum, mFloat, mString, mString_Extend,
mTrueClass, mFalseClass, mNilClass, eGeneratorError,
eNestingError, CRegexp_MULTILINE, CJSON_SAFE_STATE_PROTOTYPE,
i_SAFE_STATE_PROTOTYPE;
......
*
* Returns a JSON string representation for this Integer number.
*/
static VALUE mInteger_to_json(int argc, VALUE *argv, VALUE self)
{
GENERATE_JSON(integer);
}
/*
* call-seq: to_json(*)
*
* Returns a JSON string representation for this Integer number.
*/
static VALUE mFixnum_to_json(int argc, VALUE *argv, VALUE self)
{
GENERATE_JSON(fixnum);
......
fbuffer_append_str(buffer, tmp);
}
static void generate_json_integer(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
{
if (FIXNUM_P(obj))
generate_json_fixnum(buffer, Vstate, state, obj);
else
generate_json_bignum(buffer, Vstate, state, obj);
}
static void generate_json_float(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
{
double value = RFLOAT_VALUE(obj);
......
generate_json_false(buffer, Vstate, state, obj);
} else if (obj == Qtrue) {
generate_json_true(buffer, Vstate, state, obj);
} else if (klass == rb_cFixnum) {
} else if (FIXNUM_P(obj)) {
generate_json_fixnum(buffer, Vstate, state, obj);
} else if (klass == rb_cBignum) {
} else if (RB_TYPE_P(obj, T_BIGNUM)) {
generate_json_bignum(buffer, Vstate, state, obj);
} else if (klass == rb_cFloat) {
generate_json_float(buffer, Vstate, state, obj);
......
rb_define_method(mHash, "to_json", mHash_to_json, -1);
mArray = rb_define_module_under(mGeneratorMethods, "Array");
rb_define_method(mArray, "to_json", mArray_to_json, -1);
mFixnum = rb_define_module_under(mGeneratorMethods, "Fixnum");
rb_define_method(mFixnum, "to_json", mFixnum_to_json, -1);
mBignum = rb_define_module_under(mGeneratorMethods, "Bignum");
rb_define_method(mBignum, "to_json", mBignum_to_json, -1);
if (rb_cInteger == rb_cFixnum) {
mInteger = rb_define_module_under(mGeneratorMethods, "Integer");
rb_define_method(mInteger, "to_json", mInteger_to_json, -1);
}
else {
mFixnum = rb_define_module_under(mGeneratorMethods, "Fixnum");
rb_define_method(mFixnum, "to_json", mFixnum_to_json, -1);
mBignum = rb_define_module_under(mGeneratorMethods, "Bignum");
rb_define_method(mBignum, "to_json", mBignum_to_json, -1);
}
mFloat = rb_define_module_under(mGeneratorMethods, "Float");
rb_define_method(mFloat, "to_json", mFloat_to_json, -1);
mString = rb_define_module_under(mGeneratorMethods, "String");
ext/json/generator/generator.h (working copy)
static void generate_json_null(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj);
static void generate_json_false(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj);
static void generate_json_true(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj);
static void generate_json_integer(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj);
static void generate_json_fixnum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj);
static void generate_json_bignum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj);
static void generate_json_float(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj);
include/ruby/ruby.h (working copy)
rb_class_of(VALUE obj)
{
if (RB_IMMEDIATE_P(obj)) {
if (RB_FIXNUM_P(obj)) return rb_cFixnum;
if (RB_FIXNUM_P(obj)) return rb_cInteger;
if (RB_FLONUM_P(obj)) return rb_cFloat;
if (obj == RUBY_Qtrue) return rb_cTrueClass;
if (RB_STATIC_SYM_P(obj)) return rb_cSymbol;
insns.def (working copy)
case T_STRING:
if (BASIC_OP_UNREDEFINED_P(BOP_EQQ,
SYMBOL_REDEFINED_OP_FLAG |
FIXNUM_REDEFINED_OP_FLAG |
INTEGER_REDEFINED_OP_FLAG |
FLOAT_REDEFINED_OP_FLAG |
BIGNUM_REDEFINED_OP_FLAG |
NIL_REDEFINED_OP_FLAG |
TRUE_REDEFINED_OP_FLAG |
FALSE_REDEFINED_OP_FLAG |
......
(VALUE val)
{
if (FIXNUM_2_P(recv, obj) &&
BASIC_OP_UNREDEFINED_P(BOP_PLUS,FIXNUM_REDEFINED_OP_FLAG)) {
BASIC_OP_UNREDEFINED_P(BOP_PLUS,INTEGER_REDEFINED_OP_FLAG)) {
/* fixnum + fixnum */
#ifndef LONG_LONG_VALUE
val = (recv + (obj & (~1)));
......
(VALUE val)
{
if (FIXNUM_2_P(recv, obj) &&
BASIC_OP_UNREDEFINED_P(BOP_MINUS, FIXNUM_REDEFINED_OP_FLAG)) {
BASIC_OP_UNREDEFINED_P(BOP_MINUS, INTEGER_REDEFINED_OP_FLAG)) {
long a, b, c;
a = FIX2LONG(recv);
......
(VALUE val)
{
if (FIXNUM_2_P(recv, obj) &&
BASIC_OP_UNREDEFINED_P(BOP_MULT, FIXNUM_REDEFINED_OP_FLAG)) {
BASIC_OP_UNREDEFINED_P(BOP_MULT, INTEGER_REDEFINED_OP_FLAG)) {
val = rb_fix_mul_fix(recv, obj);
}
else if (FLONUM_2_P(recv, obj) &&
......
(VALUE val)
{
if (FIXNUM_2_P(recv, obj) &&
BASIC_OP_UNREDEFINED_P(BOP_DIV, FIXNUM_REDEFINED_OP_FLAG)) {
BASIC_OP_UNREDEFINED_P(BOP_DIV, INTEGER_REDEFINED_OP_FLAG)) {
if (FIX2LONG(obj) == 0) goto INSN_LABEL(normal_dispatch);
val = rb_fix_div_fix(recv, obj);
}
......
(VALUE val)
{
if (FIXNUM_2_P(recv, obj) &&
BASIC_OP_UNREDEFINED_P(BOP_MOD, FIXNUM_REDEFINED_OP_FLAG )) {
BASIC_OP_UNREDEFINED_P(BOP_MOD, INTEGER_REDEFINED_OP_FLAG )) {
if (FIX2LONG(obj) == 0) goto INSN_LABEL(normal_dispatch);
val = rb_fix_mod_fix(recv, obj);
}
......
(VALUE val)
{
if (FIXNUM_2_P(recv, obj) &&
BASIC_OP_UNREDEFINED_P(BOP_LT, FIXNUM_REDEFINED_OP_FLAG)) {
BASIC_OP_UNREDEFINED_P(BOP_LT, INTEGER_REDEFINED_OP_FLAG)) {
SIGNED_VALUE a = recv, b = obj;
if (a < b) {
......
(VALUE val)
{
if (FIXNUM_2_P(recv, obj) &&
BASIC_OP_UNREDEFINED_P(BOP_LE, FIXNUM_REDEFINED_OP_FLAG)) {
BASIC_OP_UNREDEFINED_P(BOP_LE, INTEGER_REDEFINED_OP_FLAG)) {
SIGNED_VALUE a = recv, b = obj;
if (a <= b) {
......
(VALUE val)
{
if (FIXNUM_2_P(recv, obj) &&
BASIC_OP_UNREDEFINED_P(BOP_GT, FIXNUM_REDEFINED_OP_FLAG)) {
BASIC_OP_UNREDEFINED_P(BOP_GT, INTEGER_REDEFINED_OP_FLAG)) {
SIGNED_VALUE a = recv, b = obj;
if (a > b) {
......
(VALUE val)
{
if (FIXNUM_2_P(recv, obj) &&
BASIC_OP_UNREDEFINED_P(BOP_GE, FIXNUM_REDEFINED_OP_FLAG)) {
BASIC_OP_UNREDEFINED_P(BOP_GE, INTEGER_REDEFINED_OP_FLAG)) {
SIGNED_VALUE a = recv, b = obj;
if (a >= b) {
......
{
if (SPECIAL_CONST_P(recv)) {
if (FIXNUM_P(recv) &&
BASIC_OP_UNREDEFINED_P(BOP_SUCC, FIXNUM_REDEFINED_OP_FLAG)) {
BASIC_OP_UNREDEFINED_P(BOP_SUCC, INTEGER_REDEFINED_OP_FLAG)) {
const VALUE obj = INT2FIX(1);
/* fixnum + INT2FIX(1) */
val = (recv + (obj & (~1)));
lib/mathn.rb (working copy)
end
##
# When mathn is required, Fixnum's division is enhanced to
# When mathn is required, Integer's division is enhanced to
# return more precise values from mathematical expressions.
#
# 2/3*3 # => 0
# require 'mathn'
# 2/3*3 # => 2
class Fixnum
remove_method :/
##
# +/+ defines the Rational division for Fixnum.
#
# 1/3 # => (1/3)
alias / quo
end
##
# When mathn is required Bignum's division is enhanced to
# return more precise values from mathematical expressions.
#
# (2**72) / ((2**70) * 3) # => 4/3
numeric.c (working copy)
* (-1).succ #=> 0
*/
static VALUE
fix_succ(VALUE num)
{
long i = FIX2LONG(num) + 1;
return LONG2NUM(i);
}
VALUE
rb_int_succ(VALUE num)
{
......
rb_define_method(rb_cInteger, "abs", int_abs, 0);
rb_define_method(rb_cInteger, "magnitude", int_abs, 0);
rb_define_method(rb_cInteger, "===", int_equal, 1);
rb_define_method(rb_cInteger, "==", int_equal, 1);
rb_define_method(rb_cInteger, ">", int_gt, 1);
rb_define_method(rb_cInteger, ">=", int_ge, 1);
......
rb_define_method(rb_cInteger, "size", int_size, 0);
rb_define_method(rb_cInteger, "bit_length", rb_int_bit_length, 0);
rb_cFixnum = rb_define_class("Fixnum", rb_cInteger);
rb_define_method(rb_cFixnum, "+", fix_plus, 1);
rb_define_method(rb_cFixnum, "-", fix_minus, 1);
rb_define_method(rb_cFixnum, "*", fix_mul, 1);
rb_define_method(rb_cFixnum, "/", fix_div, 1);
rb_define_method(rb_cFixnum, "%", fix_mod, 1);
rb_define_method(rb_cFixnum, "==", fix_equal, 1);
rb_define_method(rb_cFixnum, "===", fix_equal, 1);
rb_define_method(rb_cFixnum, ">", fix_gt, 1);
rb_define_method(rb_cFixnum, ">=", fix_ge, 1);
rb_define_method(rb_cFixnum, "<", fix_lt, 1);
rb_define_method(rb_cFixnum, "<=", fix_le, 1);
rb_define_method(rb_cFixnum, "succ", fix_succ, 0);
rb_cFixnum = rb_cInteger;
rb_define_const(rb_cObject, "Fixnum", rb_cInteger);
rb_cFloat = rb_define_class("Float", rb_cNumeric);
sprintf.c (working copy)
if (value == rb_cNilClass) {
return LITERAL("nil");
}
else if (value == rb_cFixnum) {
return LITERAL("Fixnum");
else if (value == rb_cInteger) {
return LITERAL("Integer");
}
else if (value == rb_cSymbol) {
return LITERAL("Symbol");
test/-ext-/num2int/test_num2int.rb (working copy)
end
def assert_fix2i_success(type, num, result=num)
return if !num.kind_of?(Fixnum)
return if !num.fixnum?
func = "FIX2#{type}".upcase
assert_fix2i_success_internal(result.to_s, func, num)
end
......
end
def assert_fix2i_error(type, num)
return if !num.kind_of?(Fixnum)
return if !num.fixnum?
func = "FIX2#{type}".upcase
assert_num2i_error_internal(func, num)
end
test/-ext-/typeddata/test_typeddata.rb (working copy)
assert_raise_with_message(TypeError, "wrong argument type Symbol (expected typed_data)") {Bug::TypedData.check(:e)}
assert_raise_with_message(TypeError, "wrong argument type Fixnum (expected typed_data)") {Bug::TypedData.check(0)}
assert_raise_with_message(TypeError, "wrong argument type Integer (expected typed_data)") {Bug::TypedData.check(0)}
assert_raise_with_message(TypeError, "wrong argument type String (expected typed_data)") {Bug::TypedData.check("a")}
test/lib/test/unit/assertions.rb (working copy)
end
def assert_fixnum(v, msg=nil)
assert_instance_of(Fixnum, v, msg)
assert_instance_of(Integer, v, msg)
assert_predicate(v, :fixnum?, msg)
end
def assert_bignum(v, msg=nil)
assert_instance_of(Bignum, v, msg)
assert_instance_of(Integer, v, msg)
assert_predicate(v, :bignum?, msg)
end
class << (AssertFile = Struct.new(:failure_message).new)
test/lib/test/unit.rb (working copy)
require_relative '../envutil'
require 'test/unit/testcase'
require 'optparse'
require '-test-/testutil'
# See Test::Unit
module Test
test/ruby/test_bignum.rb (working copy)
end
BIGNUM_MIN_BITS = n
T_ZERO = b.coerce(0).first
T_ONE = b.coerce(1).first
T_MONE = b.coerce(-1).first
T31 = b.coerce(2**31).first # 2147483648
T31P = b.coerce(T31 - 1).first # 2147483647
T32 = b.coerce(2**32).first # 4294967296
T32P = b.coerce(T32 - 1).first # 4294967295
T64 = b.coerce(2**64).first # 18446744073709551616
T64P = b.coerce(T64 - 1).first # 18446744073709551615
T1024 = b.coerce(2**1024).first
T1024P = b.coerce(T1024 - 1).first
T_ZERO = 0.to_bignum
T_ONE = 1.to_bignum
T_MONE = (-1).to_bignum
T31 = (2**31).to_bignum # 2147483648
T31P = (T31 - 1).to_bignum # 2147483647
T32 = (2**32).to_bignum # 4294967296
T32P = (T32 - 1).to_bignum # 4294967295
T64 = (2**64).to_bignum # 18446744073709551616
T64P = (T64 - 1).to_bignum # 18446744073709551615
T1024 = (2**1024).to_bignum
T1024P = (T1024 - 1).to_bignum
def setup
@verbose = $VERBOSE
......
end
def test_too_big_to_s
if (big = 2**31-1).is_a?(Fixnum)
if (big = 2**31-1).fixnum?
return
end
assert_raise_with_message(RangeError, /too big to convert/) {(1 << big).to_s}
test/ruby/test_hash.rb (working copy)
def test_create
assert_equal({1=>2, 3=>4}, @cls[[[1,2],[3,4]]])
assert_raise(ArgumentError) { Hash[0, 1, 2] }
assert_warning(/wrong element type Fixnum at 1 /) {@cls[[[1, 2], 3]]}
assert_warning(/wrong element type Integer at 1 /) {@cls[[[1, 2], 3]]}
bug5406 = '[ruby-core:39945]'
assert_raise(ArgumentError, bug5406) { @cls[[[1, 2], [3, 4, 5]]] }
assert_equal({1=>2, 3=>4}, @cls[1,2,3,4])
test/ruby/test_integer.rb (working copy)
def test_succ
assert_equal(2, 1.send(:succ))
Fixnum.class_eval do
alias succ_bak succ
remove_method :succ
end
assert_equal(2, 1.succ)
assert_equal(4294967297, 4294967296.succ)
ensure
Fixnum.class_eval do
alias succ succ_bak
remove_method :succ_bak
end
end
def test_chr
test/ruby/test_numeric.rb (working copy)
assert_raise_with_message(TypeError, /:"\\u3042"/) {1^:"\u{3042}"}
bug10711 = '[ruby-core:67405] [Bug #10711]'
exp = "1.2 can't be coerced into Fixnum"
exp = "1.2 can't be coerced into Integer"
assert_raise_with_message(TypeError, exp, bug10711) { 1 & 1.2 }
end
test/ruby/test_optimization.rb (working copy)
assert_bignum FIXNUM_MAX + 1
assert_equal 21, 10 + 11
assert_redefine_method('Fixnum', '+', 'assert_equal 11, 10 + 11')
assert_redefine_method('Integer', '+', 'assert_equal 11, 10 + 11')
end
def test_fixnum_minus
......
assert_bignum FIXNUM_MIN - 1
assert_equal 5, 8 - 3
assert_redefine_method('Fixnum', '-', 'assert_equal 3, 8 - 3')
assert_redefine_method('Integer', '-', 'assert_equal 3, 8 - 3')
end
def test_fixnum_mul
assert_equal 15, 3 * 5
assert_redefine_method('Fixnum', '*', 'assert_equal 5, 3 * 5')
assert_redefine_method('Integer', '*', 'assert_equal 5, 3 * 5')
end
def test_fixnum_div
assert_equal 3, 15 / 5
assert_redefine_method('Fixnum', '/', 'assert_equal 5, 15 / 5')
assert_redefine_method('Integer', '/', 'assert_equal 5, 15 / 5')
end
def test_fixnum_mod
assert_equal 1, 8 % 7
assert_redefine_method('Fixnum', '%', 'assert_equal 7, 8 % 7')
assert_redefine_method('Integer', '%', 'assert_equal 7, 8 % 7')
end
def test_float_plus
test/ruby/test_regexp.rb (working copy)
def test_error_message_on_failed_conversion
bug7539 = '[ruby-core:50733]'
assert_equal false, /x/=== 42
assert_raise_with_message(TypeError, 'no implicit conversion of Fixnum into String', bug7539) {
assert_raise_with_message(TypeError, 'no implicit conversion of Integer into String', bug7539) {
Regexp.quote(42)
}
end
test/ruby/test_settracefunc.rb (working copy)
events.shift)
assert_equal(["line", 4, __method__, self.class],
events.shift)
assert_equal(["c-call", 4, :+, Fixnum],
assert_equal(["c-call", 4, :+, Integer],
events.shift)
assert_equal(["c-return", 4, :+, Fixnum],
assert_equal(["c-return", 4, :+, Integer],
events.shift)
assert_equal(["line", 5, __method__, self.class],
events.shift)
......
events.shift)
assert_equal(["line", 5, :add, self.class],
events.shift)
assert_equal(["c-call", 5, :+, Fixnum],
assert_equal(["c-call", 5, :+, Integer],
events.shift)
assert_equal(["c-return", 5, :+, Fixnum],
assert_equal(["c-return", 5, :+, Integer],
events.shift)
assert_equal(["return", 6, :add, self.class],
events.shift)
......
["c-return", 8, :new, Class],
["call", 4, :foo, ThreadTraceInnerClass],
["line", 5, :foo, ThreadTraceInnerClass],
["c-call", 5, :+, Fixnum],
["c-return", 5, :+, Fixnum],
["c-call", 5, :+, Integer],
["c-return", 5, :+, Integer],
["return", 6, :foo, ThreadTraceInnerClass],
["line", 9, __method__, self.class],
["c-call", 9, :set_trace_func, Thread]].each do |e|
......
# pp events
# expected_events =
[[:b_call, :test_tracepoint_block, TestSetTraceFunc, TestSetTraceFunc, nil],
[:c_call, :times, Integer, Fixnum, nil],
[:c_call, :times, Integer, Integer, nil],
[:b_call, :test_tracepoint_block, TestSetTraceFunc, TestSetTraceFunc, nil],
[:b_return, :test_tracepoint_block, TestSetTraceFunc, TestSetTraceFunc, 3],
[:c_return, :times, Integer, Fixnum, 1],
[:c_return, :times, Integer, Integer, 1],
[:call, :method_for_test_tracepoint_block, TestSetTraceFunc, TestSetTraceFunc, nil],
[:b_call, :test_tracepoint_block, TestSetTraceFunc, TestSetTraceFunc, nil],
[:b_return, :test_tracepoint_block, TestSetTraceFunc, TestSetTraceFunc, 4],
vm.c (working copy)
static int
vm_redefinition_check_flag(VALUE klass)
{
if (klass == rb_cFixnum) return FIXNUM_REDEFINED_OP_FLAG;
if (klass == rb_cInteger) return INTEGER_REDEFINED_OP_FLAG;
if (klass == rb_cFloat) return FLOAT_REDEFINED_OP_FLAG;
if (klass == rb_cString) return STRING_REDEFINED_OP_FLAG;
if (klass == rb_cArray) return ARRAY_REDEFINED_OP_FLAG;
if (klass == rb_cHash) return HASH_REDEFINED_OP_FLAG;
if (klass == rb_cBignum) return BIGNUM_REDEFINED_OP_FLAG;
if (klass == rb_cSymbol) return SYMBOL_REDEFINED_OP_FLAG;
if (klass == rb_cTime) return TIME_REDEFINED_OP_FLAG;
if (klass == rb_cRegexp) return REGEXP_REDEFINED_OP_FLAG;
......
#define OP(mid_, bop_) (mid = id##mid_, bop = BOP_##bop_, ruby_vm_redefined_flag[bop] = 0)
#define C(k) add_opt_method(rb_c##k, mid, bop)
OP(PLUS, PLUS), (C(Fixnum), C(Float), C(String), C(Array));
OP(MINUS, MINUS), (C(Fixnum), C(Float));
OP(MULT, MULT), (C(Fixnum), C(Float));
OP(DIV, DIV), (C(Fixnum), C(Float));
OP(MOD, MOD), (C(Fixnum), C(Float));
OP(Eq, EQ), (C(Fixnum), C(Float), C(String));
OP(Eqq, EQQ), (C(Fixnum), C(Bignum), C(Float), C(Symbol), C(String),
OP(PLUS, PLUS), (C(Integer), C(Float), C(String), C(Array));
OP(MINUS, MINUS), (C(Integer), C(Float));
OP(MULT, MULT), (C(Integer), C(Float));
OP(DIV, DIV), (C(Integer), C(Float));
OP(MOD, MOD), (C(Integer), C(Float));
OP(Eq, EQ), (C(Integer), C(Float), C(String));
OP(Eqq, EQQ), (C(Integer), C(Float), C(Symbol), C(String),
C(NilClass), C(TrueClass), C(FalseClass));
OP(LT, LT), (C(Fixnum), C(Float));
OP(LE, LE), (C(Fixnum), C(Float));
OP(GT, GT), (C(Fixnum), C(Float));
OP(GE, GE), (C(Fixnum), C(Float));
OP(LT, LT), (C(Integer), C(Float));
OP(LE, LE), (C(Integer), C(Float));
OP(GT, GT), (C(Integer), C(Float));
OP(GE, GE), (C(Integer), C(Float));
OP(LTLT, LTLT), (C(String), C(Array));
OP(AREF, AREF), (C(Array), C(Hash));
OP(ASET, ASET), (C(Array), C(Hash));
OP(Length, LENGTH), (C(Array), C(String), C(Hash));
OP(Size, SIZE), (C(Array), C(String), C(Hash));
OP(EmptyP, EMPTY_P), (C(Array), C(String), C(Hash));
OP(Succ, SUCC), (C(Fixnum), C(String), C(Time));
OP(Succ, SUCC), (C(Integer), C(String), C(Time));
OP(EqTilde, MATCH), (C(Regexp), C(String));
OP(Freeze, FREEZE), (C(String));
OP(Max, MAX), (C(Array));
vm_core.h (working copy)
#define RUBY_VM_FIBER_MACHINE_STACK_SIZE_MIN ( 16 * 1024 * sizeof(VALUE)) /* 64 KB or 128 KB */
/* optimize insn */
#define FIXNUM_REDEFINED_OP_FLAG (1 << 0)
#define INTEGER_REDEFINED_OP_FLAG (1 << 0)
#define FLOAT_REDEFINED_OP_FLAG (1 << 1)
#define STRING_REDEFINED_OP_FLAG (1 << 2)
#define ARRAY_REDEFINED_OP_FLAG (1 << 3)
#define HASH_REDEFINED_OP_FLAG (1 << 4)
#define BIGNUM_REDEFINED_OP_FLAG (1 << 5)
/* #define BIGNUM_REDEFINED_OP_FLAG (1 << 5) */
#define SYMBOL_REDEFINED_OP_FLAG (1 << 6)
#define TIME_REDEFINED_OP_FLAG (1 << 7)
#define REGEXP_REDEFINED_OP_FLAG (1 << 8)
vm_insnhelper.c (working copy)
opt_eq_func(VALUE recv, VALUE obj, CALL_INFO ci, CALL_CACHE cc)
{
if (FIXNUM_2_P(recv, obj) &&
BASIC_OP_UNREDEFINED_P(BOP_EQ, FIXNUM_REDEFINED_OP_FLAG)) {
BASIC_OP_UNREDEFINED_P(BOP_EQ, INTEGER_REDEFINED_OP_FLAG)) {
return (recv == obj) ? Qtrue : Qfalse;
}
else if (FLONUM_2_P(recv, obj) &&
    (1-1/1)