Don't use MRI internals in the Ruby extension

Using internals of MRI by using RARRAY_PTR makes it necessary for other
implementations such as Rubinius to continuously copy the structure
returned by RARRAY_PTR back and forth since in Rubinius objects are
layed out differently internally.

Extensions should not depend and use these internal MRI structures if
this is not necessary and when there are API methods that can provide
the same functionality. This makes sure other implementations can also
use the extension without any big problems.

For this reason I also removed the FIXME comment, since that change
would also heavily depend on the internal memory layout of objects on
MRI.
This commit is contained in:
Dirkjan Bussink 2012-03-17 11:28:19 +01:00
parent 8786a8e6e0
commit 65c360a2ca
2 changed files with 7 additions and 6 deletions

View File

@ -219,11 +219,12 @@ static VALUE MessagePack_Array_to_msgpack(int argc, VALUE *argv, VALUE self)
{ {
ARG_BUFFER(out, argc, argv); ARG_BUFFER(out, argc, argv);
// FIXME check sizeof(long) > sizeof(unsigned int) && RARRAY_LEN(self) > UINT_MAX // FIXME check sizeof(long) > sizeof(unsigned int) && RARRAY_LEN(self) > UINT_MAX
msgpack_pack_array(out, (unsigned int)RARRAY_LEN(self)); unsigned int ary_length = (unsigned int)RARRAY_LEN(self);
VALUE* p = RARRAY_PTR(self); unsigned int i = 0;
VALUE* const pend = p + RARRAY_LEN(self); msgpack_pack_array(out, ary_length);
for(;p != pend; ++p) { for(; i < ary_length; ++i) {
rb_funcall(*p, s_to_msgpack, 1, out); VALUE p = rb_ary_entry(self, i);
rb_funcall(p, s_to_msgpack, 1, out);
} }
return out; return out;
} }

View File

@ -112,7 +112,7 @@ static inline int template_callback_array(unpack_user* u, unsigned int n, VALUE*
{ *o = rb_ary_new2(n); return 0; } { *o = rb_ary_new2(n); return 0; }
static inline int template_callback_array_item(unpack_user* u, VALUE* c, VALUE o) static inline int template_callback_array_item(unpack_user* u, VALUE* c, VALUE o)
{ rb_ary_push(*c, o); return 0; } // FIXME set value directry RARRAY_PTR(obj)[RARRAY_LEN(obj)++] { rb_ary_push(*c, o); return 0; }
static inline int template_callback_map(unpack_user* u, unsigned int n, VALUE* o) static inline int template_callback_map(unpack_user* u, unsigned int n, VALUE* o)
{ *o = rb_hash_new(); return 0; } { *o = rb_hash_new(); return 0; }