4 ** See Copyright Notice in mruby.h
8 #include <mruby/string.h>
9 #include <mruby/data.h>
10 #include <mruby/class.h>
11 #include <mruby/numeric.h>
12 #include <mruby/internal.h>
15 mrb_data_object_alloc(mrb_state
*mrb
, struct RClass
*klass
, void *ptr
, const mrb_data_type
*type
)
17 struct RData
*data
= MRB_OBJ_ALLOC(mrb
, MRB_TT_CDATA
, klass
);
26 mrb_data_check_type(mrb_state
*mrb
, mrb_value obj
, const mrb_data_type
*type
)
28 if (!mrb_data_p(obj
)) {
29 mrb_check_type(mrb
, obj
, MRB_TT_CDATA
);
31 if (DATA_TYPE(obj
) != type
) {
32 const mrb_data_type
*t2
= DATA_TYPE(obj
);
35 mrb_raisef(mrb
, E_TYPE_ERROR
, "wrong argument type %s (expected %s)",
36 t2
->struct_name
, type
->struct_name
);
39 mrb_raisef(mrb
, E_TYPE_ERROR
, "uninitialized %t (expected %s)",
40 obj
, type
->struct_name
);
46 mrb_data_check_get_ptr(mrb_state
*mrb
, mrb_value obj
, const mrb_data_type
*type
)
48 if (!mrb_data_p(obj
)) {
51 if (DATA_TYPE(obj
) != type
) {
58 mrb_data_get_ptr(mrb_state
*mrb
, mrb_value obj
, const mrb_data_type
*type
)
60 mrb_data_check_type(mrb
, obj
, type
);
65 mrb_obj_to_sym(mrb_state
*mrb
, mrb_value name
)
67 if (mrb_symbol_p(name
)) return mrb_symbol(name
);
68 if (mrb_string_p(name
)) return mrb_intern_str(mrb
, name
);
69 mrb_raisef(mrb
, E_TYPE_ERROR
, "%!v is not a symbol nor a string", name
);
70 return 0; /* not reached */
73 #if !defined(MRB_NO_FLOAT) && !defined(MRB_NAN_BOXING)
75 mrb_float_id(mrb_float f
)
77 /* normalize -0.0 to 0.0 */
79 return (mrb_int
)mrb_byte_hash((uint8_t*)&f
, sizeof(f
));
84 mrb_obj_id(mrb_value obj
)
86 #if defined(MRB_NAN_BOXING)
91 return (mrb_int
)(u
>>32)^u
;
93 #elif defined(MRB_WORD_BOXING)
94 if (!mrb_immediate_p(obj
)) {
95 if (mrb_integer_p(obj
)) return mrb_integer(obj
);
97 if (mrb_float_p(obj
)) {
98 return mrb_float_id(mrb_float(obj
));
102 return (mrb_int
)obj
.w
;
103 #else /* MRB_NO_BOXING */
105 #define MakeID(p,t) (mrb_int)(((intptr_t)(p))^(t))
107 enum mrb_vtype tt
= mrb_type(obj
);
112 return MakeID(0, tt
); /* should not happen */
115 return MakeID(4, tt
);
117 return MakeID(0, tt
);
119 return MakeID(2, tt
);
121 return MakeID(mrb_symbol(obj
), tt
);
123 return MakeID(mrb_integer(obj
), tt
);
126 return MakeID(mrb_float_id(mrb_float(obj
)), tt
);
138 case MRB_TT_EXCEPTION
:
142 return MakeID(mrb_ptr(obj
), tt
);
147 #ifdef MRB_WORD_BOXING
150 mrb_word_boxing_float_value(mrb_state
*mrb
, mrb_float f
)
154 #ifdef MRB_WORDBOX_NO_FLOAT_TRUNCATE
155 v
.p
= mrb_obj_alloc(mrb
, MRB_TT_FLOAT
, mrb
->float_class
);
157 MRB_SET_FROZEN_FLAG(v
.bp
);
158 #elif defined(MRB_64BIT) && defined(MRB_USE_FLOAT32)
164 v
.w
= (v
.w
& ~3) | 2;
170 #ifndef MRB_WORDBOX_NO_FLOAT_TRUNCATE
172 mrb_word_boxing_value_float(mrb_value v
)
176 #if defined(MRB_64BIT) && defined(MRB_USE_FLOAT32)
184 #endif /* MRB_NO_FLOAT */
187 mrb_word_boxing_cptr_value(mrb_state
*mrb
, void *p
)
190 struct RCptr
*cptr
= MRB_OBJ_ALLOC(mrb
, MRB_TT_CPTR
, mrb
->object_class
);
192 SET_OBJ_VALUE(v
, cptr
);
196 #endif /* MRB_WORD_BOXING */
198 #if defined(MRB_WORD_BOXING) || (defined(MRB_NAN_BOXING) && defined(MRB_INT64))
200 mrb_boxing_int_value(mrb_state
*mrb
, mrb_int n
)
202 if (FIXABLE(n
)) return mrb_fixnum_value(n
);
205 struct RInteger
*p
= (struct RInteger
*)mrb_obj_alloc(mrb
, MRB_TT_INTEGER
, mrb
->integer_class
);
207 MRB_SET_FROZEN_FLAG((struct RBasic
*)p
);
214 #if defined _MSC_VER && _MSC_VER < 1900
218 mrb_msvc_va_copy(va_list *dest
, va_list src
)
222 #define va_copy(dest, src) mrb_msvc_va_copy(&(dest), src)
226 mrb_msvc_vsnprintf(char *s
, size_t n
, const char *format
, va_list arg
)
231 if (n
== 0 || (cnt
= _vsnprintf_s(s
, n
, _TRUNCATE
, format
, argcp
)) < 0) {
232 cnt
= _vscprintf(format
, arg
);
239 mrb_msvc_snprintf(char *s
, size_t n
, const char *format
, ...)
242 va_start(arg
, format
);
244 int ret
= mrb_msvc_vsnprintf(s
, n
, format
, arg
);
249 #endif /* defined _MSC_VER && _MSC_VER < 1900 */