Fixed some C/C++ compiler errors due to stricter checks.
[rubinius.git] / machine / capi / integer.cpp
blobb80a2227786975284153d17015bc848dfb4c148a
1 #include "class/string.hpp"
3 #include "capi/capi.hpp"
4 #include "capi/ruby.h"
6 using namespace rubinius;
7 using namespace rubinius::capi;
9 extern "C" {
10 /* This is a really wacky MRI API, which is actually marked internal
11 * despite being used in external code. The existing Fixnum#size and
12 * Bignum#size methods are sufficient for the 3-4 places it's used in MRI's
13 * code itself, where the 2nd argument isn't even used.
15 * We provide a "good enough" implementation.
17 size_t rb_absint_size(VALUE value, int* nlz_bits) {
18 NativeMethodEnvironment* env = NativeMethodEnvironment::get();
19 size_t size = 0;
21 if(RB_TYPE_P(value, T_FIXNUM)) {
22 if(value > 0) {
23 size = FIXNUM_MAX_WIDTH;
24 } else {
25 size = FIXNUM_MIN_WIDTH;
27 } else if(RB_TYPE_P(value, T_BIGNUM)) {
28 Bignum* big = MemoryHandle::object<Bignum>(value);
29 size = big->size(env->state())->to_native();
32 // Within bounds
33 if(nlz_bits) *nlz_bits = 0;
35 return size;
38 int rb_integer_pack(VALUE value, void *words, size_t numwords, size_t wordsize,
39 size_t nails, int flags)
41 if(nails != 0) {
42 rb_raise(rb_eNotImpError, "non-zero bit padding is unsupported");
45 if(((flags & INTEGER_PACK_MSWORD_FIRST) != 0 &&
46 (flags & INTEGER_PACK_LSBYTE_FIRST) != 0) ||
47 ((flags & INTEGER_PACK_LSWORD_FIRST) != 0 &&
48 (flags & INTEGER_PACK_MSBYTE_FIRST) != 0)) {
49 rb_raise(rb_eNotImpError, "mixed byte and word ordering is unsupported");
52 value = rb_to_int(value);
54 size_t numbytes = numwords * wordsize;
55 memset(words, 0, numbytes);
57 NativeMethodEnvironment* env = NativeMethodEnvironment::get();
59 if(Fixnum* f = MemoryHandle::try_as<Fixnum>(value)) {
60 intptr_t v = f->to_native();
62 if(v == 0) return 0;
64 if((numbytes >= FIXNUM_MIN_WIDTH / 8) &&
65 ((flags & INTEGER_PACK_NATIVE_BYTE_ORDER) ||
66 #ifdef RBX_LITTLE_ENDIAN
67 ((flags & INTEGER_PACK_LSWORD_FIRST) &&
68 (flags & INTEGER_PACK_LSBYTE_FIRST))
69 #else
70 ((flags & INTEGER_PACK_MSWORD_FIRST) &&
71 (flags & INTEGER_PACK_MSBYTE_FIRST))
72 #endif
75 memcpy(words, &v, numbytes);
76 return v < 0 ? -1 : 1;
80 String* bytes = String::create_pinned(env->state(), Fixnum::from(numbytes));
81 memset(bytes->byte_address(), 0, numbytes);
83 VALUE result = rb_funcall(rb_mCAPI, rb_intern("rb_integer_pack"), 6,
84 value, MemoryHandle::value(bytes), INT2FIX(numwords), INT2FIX(wordsize),
85 INT2FIX(nails), INT2FIX(flags));
87 memcpy(words, bytes->byte_address(), numbytes);
89 return FIX2INT(result);