mri_sys/
ty.rs

1#![allow(non_snake_case)]
2
3use super::*;
4use std::mem;
5use libc;
6
7/// Gets the class of a `VALUE`.
8/// This is actually defined in the Ruby library, but it is inline.
9/// This is a port of it.
10pub unsafe fn rb_class_of(obj: VALUE) -> VALUE {
11    if IMMEDIATE_P(obj) {
12        if FIXNUM_P(obj) { return rb_cInteger; }
13        if FLONUM_P(obj) { return rb_cFloat; }
14        if obj == Qtrue { return rb_cTrueClass; }
15        if STATIC_SYM_P(obj) { return rb_cSymbol; }
16    } else if !RTEST(obj) {
17        if obj == Qnil   { return rb_cNilClass; }
18        if obj == Qfalse { return rb_cFalseClass; }
19    }
20    return (*RBasic::from_pointer(obj)).klass;
21}
22
23pub fn TYPE_P(obj: VALUE, ty: value_type) -> bool {
24    match ty {
25        value_type::T_FIXNUM => FIXNUM_P(obj),
26        value_type::T_TRUE => obj == Qtrue,
27        value_type::T_FALSE => obj == Qfalse,
28        value_type::T_NIL => obj == Qnil,
29        value_type::T_UNDEF => obj == Qundef,
30        value_type::T_SYMBOL => SYMBOL_P(obj),
31        value_type::T_FLOAT => FLOAT_TYPE_P(obj),
32        _ => !SPECIAL_CONST_P(obj) && BUILTIN_TYPE(obj) == ty
33    }
34}
35
36pub fn FLOAT_TYPE_P(obj: VALUE) -> bool {
37    FLONUM_P(obj) || (!SPECIAL_CONST_P(obj) &&
38                      BUILTIN_TYPE(obj) == T_FLOAT)
39}
40
41pub fn BUILTIN_TYPE(x: VALUE) -> value_type {
42    unsafe {
43        let basic: *const RBasic = mem::transmute(x);
44        let masked = (*basic).flags.0 & (T_MASK as libc::size_t);
45        mem::transmute(masked as u32)
46    }
47}
48
49#[cfg(not(mri_use_flonum))]
50pub fn FLONUM_P(_: VALUE) -> bool { false }
51
52#[cfg(mri_use_flonum)]
53pub fn FLONUM_P(x: VALUE) -> bool {
54    x & FLONUM_MASK == FLONUM_FLAG.0
55}
56
57pub fn FIXNUM_P(f: VALUE) -> bool {
58    (f & FIXNUM_FLAG) != 0
59}
60
61pub fn DYNAMIC_SYM_P(x: VALUE) -> bool {
62    !SPECIAL_CONST_P(x) && BUILTIN_TYPE(x) == T_SYMBOL
63}
64
65pub fn STATIC_SYM_P(x: VALUE) -> bool {
66    (x.0 & !((!0 as libc::uintptr_t) << SPECIAL_SHIFT)) == SYMBOL_FLAG.0
67}
68
69pub fn SYMBOL_P(x: VALUE) -> bool {
70    STATIC_SYM_P(x) || DYNAMIC_SYM_P(x)
71}
72
73pub fn SPECIAL_CONST_P(x: VALUE) -> bool {
74    IMMEDIATE_P(x) || !RTEST(x)
75}
76
77pub fn IMMEDIATE_P(x: VALUE) -> bool {
78    (x & IMMEDIATE_MASK) != 0
79}
80
81pub fn RTEST(v: VALUE) -> bool {
82    (v.0 & !Qnil.0) != 0
83}
84
85pub fn NIL_P(v: VALUE) -> bool {
86    v == Qnil
87}