Rewrite Ruby's GC_VALUE without use of macros for easier debugging

This commit is contained in:
William S Fulton 2013-04-06 02:20:56 +01:00
commit bb3fe8c906

View file

@ -185,104 +185,95 @@ namespace swig {
return rb_funcall(args->src, args->id, args->nargs, args->target); return rb_funcall(args->src, args->id, args->nargs, args->target);
} }
bool relational_equal_op(const GC_VALUE& other, const ID& op_id, bool (*op_func)(const VALUE& a, const VALUE& b)) const
%#define GC_VALUE_CMP( op_id, op, cmp, cmpval ) \ {
bool op( const GC_VALUE& other ) const \ if (FIXNUM_P(_obj) && FIXNUM_P(other._obj)) {
{ \ return op_func(_obj, other._obj);
if ( FIXNUM_P(_obj) && FIXNUM_P(other._obj) ) \ }
{ \ bool res = false;
return _obj cmp other._obj; \ VALUE ret = Qnil;
} \ SWIG_RUBY_THREAD_BEGIN_BLOCK;
bool res = false; \ if (rb_respond_to(_obj, op_id)) {
VALUE ret = Qnil; \ OpArgs args;
SWIG_RUBY_THREAD_BEGIN_BLOCK; \ args.src = _obj;
if ( rb_respond_to( _obj, op_id ) ) \ args.id = op_id;
{ \ args.nargs = 1;
OpArgs args; \ args.target = VALUE(other);
args.src = _obj; \ ret = rb_rescue(RUBY_METHOD_FUNC(swig_rescue_funcall), VALUE(&args),
args.id = op_id; \ (RUBY_METHOD_FUNC(swig_rescue_swallow)), Qnil);
args.nargs = 1; \ }
args.target = VALUE(other); \ if (ret == Qnil) {
ret = rb_rescue(RUBY_METHOD_FUNC(swig_rescue_funcall), VALUE(&args), \ VALUE a = rb_funcall( _obj, hash_id, 0 );
(RUBY_METHOD_FUNC(swig_rescue_swallow)), Qnil); \ VALUE b = rb_funcall( VALUE(other), hash_id, 0 );
} \ res = op_func(a, b);
if ( ret == Qnil ) { \ } else {
VALUE a = rb_funcall( _obj, hash_id, 0 ); \ res = RTEST(ret);
VALUE b = rb_funcall( VALUE(other), hash_id, 0 ); \ }
res = a cmp b; \ SWIG_RUBY_THREAD_END_BLOCK;
} \ return res;
else \
{ \
res = RTEST( ret ); \
} \
SWIG_RUBY_THREAD_END_BLOCK; \
return res; \
} }
static bool operator_eq(const VALUE& a, const VALUE& b) { return a == b; }
static bool operator_lt(const VALUE& a, const VALUE& b) { return a < b; }
static bool operator_le(const VALUE& a, const VALUE& b) { return a <= b; }
static bool operator_gt(const VALUE& a, const VALUE& b) { return a > b; }
static bool operator_ge(const VALUE& a, const VALUE& b) { return a >= b; }
GC_VALUE_CMP( eq_id, operator==, ==, == 0 ) bool operator==(const GC_VALUE& other) const { return relational_equal_op(other, eq_id, operator_eq); }
GC_VALUE_CMP( lt_id, operator<, < , < 0 ) bool operator<(const GC_VALUE& other) const { return relational_equal_op(other, lt_id, operator_lt); }
GC_VALUE_CMP( le_id, operator<=, <=, <= 0 ) bool operator<=(const GC_VALUE& other) const { return relational_equal_op(other, le_id, operator_le); }
GC_VALUE_CMP( gt_id, operator>, > , > 0 ) bool operator>(const GC_VALUE& other) const { return relational_equal_op(other, gt_id, operator_gt); }
GC_VALUE_CMP( ge_id, operator>=, >=, >= 0 ) bool operator>=(const GC_VALUE& other) const { return relational_equal_op(other, ge_id, operator_ge); }
%#undef GC_VALUE_CMP
bool operator!=( const GC_VALUE& other ) bool operator!=(const GC_VALUE& other) const
{ {
return !(this->operator==(other)); return !(this->operator==(other));
} }
%#define GC_VALUE_UNARY( proc_id, op ) \ GC_VALUE unary_op(const ID& op_id) const
GC_VALUE op() const \ {
{ \ VALUE ret = Qnil;
VALUE ret = Qnil; \ SWIG_RUBY_THREAD_BEGIN_BLOCK;
SWIG_RUBY_THREAD_BEGIN_BLOCK; \ OpArgs args;
OpArgs args; \ args.src = _obj;
args.src = _obj; \ args.id = op_id;
args.id = proc_id; \ args.nargs = 0;
args.nargs = 0; \ args.target = Qnil;
args.target = Qnil; \ ret = rb_rescue(RUBY_METHOD_FUNC(swig_rescue_funcall), VALUE(&args),
ret = rb_rescue(RUBY_METHOD_FUNC(swig_rescue_funcall), VALUE(&args), \ (RUBY_METHOD_FUNC(swig_rescue_swallow)), Qnil);
(RUBY_METHOD_FUNC(swig_rescue_swallow)), Qnil); \ SWIG_RUBY_THREAD_END_BLOCK;
SWIG_RUBY_THREAD_END_BLOCK; \ return ret;
return ret; \
} }
GC_VALUE_UNARY( pos_id, operator+ ) GC_VALUE operator+() const { return unary_op(pos_id); }
GC_VALUE_UNARY( neg_id, operator- ) GC_VALUE operator-() const { return unary_op(neg_id); }
GC_VALUE_UNARY( inv_id, operator~ ) GC_VALUE operator~() const { return unary_op(inv_id); }
%#undef GC_VALUE_BINARY
%#define GC_VALUE_BINARY( proc_id, op ) \ GC_VALUE binary_op(const GC_VALUE& other, const ID& op_id) const
GC_VALUE op( const GC_VALUE& other ) const \ {
{ \ VALUE ret = Qnil;
VALUE ret = Qnil; \ SWIG_RUBY_THREAD_BEGIN_BLOCK;
SWIG_RUBY_THREAD_BEGIN_BLOCK; \ OpArgs args;
OpArgs args; \ args.src = _obj;
args.src = _obj; \ args.id = op_id;
args.id = proc_id; \ args.nargs = 1;
args.nargs = 1; \ args.target = VALUE(other);
args.target = VALUE(other); \ ret = rb_rescue(RUBY_METHOD_FUNC(swig_rescue_funcall), VALUE(&args),
ret = rb_rescue(RUBY_METHOD_FUNC(swig_rescue_funcall), VALUE(&args), \ (RUBY_METHOD_FUNC(swig_rescue_swallow)), Qnil);
(RUBY_METHOD_FUNC(swig_rescue_swallow)), Qnil); \ SWIG_RUBY_THREAD_END_BLOCK;
SWIG_RUBY_THREAD_END_BLOCK; \ return GC_VALUE(ret);
return GC_VALUE(ret); \
} }
GC_VALUE_BINARY( add_id, operator+ ); GC_VALUE operator+(const GC_VALUE& other) const { return binary_op(other, add_id); }
GC_VALUE_BINARY( sub_id, operator- ); GC_VALUE operator-(const GC_VALUE& other) const { return binary_op(other, sub_id); }
GC_VALUE_BINARY( mul_id, operator* ); GC_VALUE operator*(const GC_VALUE& other) const { return binary_op(other, mul_id); }
GC_VALUE_BINARY( div_id, operator/ ); GC_VALUE operator/(const GC_VALUE& other) const { return binary_op(other, div_id); }
GC_VALUE_BINARY( mod_id, operator% ); GC_VALUE operator%(const GC_VALUE& other) const { return binary_op(other, mod_id); }
GC_VALUE operator&(const GC_VALUE& other) const { return binary_op(other, and_id); }
GC_VALUE_BINARY( and_id, operator& ); GC_VALUE operator^(const GC_VALUE& other) const { return binary_op(other, xor_id); }
GC_VALUE_BINARY( xor_id, operator^ ); GC_VALUE operator|(const GC_VALUE& other) const { return binary_op(other, or_id); }
GC_VALUE_BINARY( or_id, operator| ); GC_VALUE operator<<(const GC_VALUE& other) const { return binary_op(other, lshift_id); }
GC_VALUE operator>>(const GC_VALUE& other) const { return binary_op(other, rshift_id); }
GC_VALUE_BINARY( lshift_id, operator<< );
GC_VALUE_BINARY( rshift_id, operator>> );
%#undef GC_VALUE_BINARY
}; };
ID GC_VALUE::hash_id = rb_intern("hash"); ID GC_VALUE::hash_id = rb_intern("hash");