Coverage Report

Created: 2023-09-25 06:17

/src/mruby/src/etc.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
** etc.c
3
**
4
** See Copyright Notice in mruby.h
5
*/
6
7
#include <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>
13
14
MRB_API struct RData*
15
mrb_data_object_alloc(mrb_state *mrb, struct RClass *klass, void *ptr, const mrb_data_type *type)
16
5.13k
{
17
5.13k
  struct RData *data;
18
19
5.13k
  data = MRB_OBJ_ALLOC(mrb, MRB_TT_CDATA, klass);
20
5.13k
  data->data = ptr;
21
5.13k
  data->type = type;
22
23
5.13k
  return data;
24
5.13k
}
25
26
MRB_API void
27
mrb_data_check_type(mrb_state *mrb, mrb_value obj, const mrb_data_type *type)
28
0
{
29
0
  if (!mrb_data_p(obj)) {
30
0
    mrb_check_type(mrb, obj, MRB_TT_CDATA);
31
0
  }
32
0
  if (DATA_TYPE(obj) != type) {
33
0
    const mrb_data_type *t2 = DATA_TYPE(obj);
34
35
0
    if (t2) {
36
0
      mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %s (expected %s)",
37
0
                 t2->struct_name, type->struct_name);
38
0
    }
39
0
    else {
40
0
      mrb_raisef(mrb, E_TYPE_ERROR, "uninitialized %t (expected %s)",
41
0
                 obj, type->struct_name);
42
0
    }
43
0
  }
44
0
}
45
46
MRB_API void*
47
mrb_data_check_get_ptr(mrb_state *mrb, mrb_value obj, const mrb_data_type *type)
48
0
{
49
0
  if (!mrb_data_p(obj)) {
50
0
    return NULL;
51
0
  }
52
0
  if (DATA_TYPE(obj) != type) {
53
0
    return NULL;
54
0
  }
55
0
  return DATA_PTR(obj);
56
0
}
57
58
MRB_API void*
59
mrb_data_get_ptr(mrb_state *mrb, mrb_value obj, const mrb_data_type *type)
60
0
{
61
0
  mrb_data_check_type(mrb, obj, type);
62
0
  return DATA_PTR(obj);
63
0
}
64
65
MRB_API mrb_sym
66
mrb_obj_to_sym(mrb_state *mrb, mrb_value name)
67
19.5k
{
68
19.5k
  if (mrb_symbol_p(name)) return mrb_symbol(name);
69
0
  if (mrb_string_p(name)) return mrb_intern_str(mrb, name);
70
0
  mrb_raisef(mrb, E_TYPE_ERROR, "%!v is not a symbol nor a string", name);
71
0
  return 0;  /* not reached */
72
0
}
73
74
#if !defined(MRB_NO_FLOAT) && !defined(MRB_NAN_BOXING)
75
static mrb_int
76
mrb_float_id(mrb_float f)
77
0
{
78
  /* normalize -0.0 to 0.0 */
79
0
  if (f == 0) f = 0.0;
80
0
  return (mrb_int)mrb_byte_hash((uint8_t*)&f, sizeof(f));
81
0
}
82
#endif
83
84
MRB_API mrb_int
85
mrb_obj_id(mrb_value obj)
86
0
{
87
#if defined(MRB_NAN_BOXING)
88
#ifdef MRB_INT64
89
  return obj.u;
90
#else
91
  uint64_t u = obj.u;
92
  return (mrb_int)(u>>32)^u;
93
#endif
94
#elif defined(MRB_WORD_BOXING)
95
0
  if (!mrb_immediate_p(obj)) {
96
0
    if (mrb_integer_p(obj)) return mrb_integer(obj);
97
0
#ifndef MRB_NO_FLOAT
98
0
    if (mrb_float_p(obj)) {
99
0
      return mrb_float_id(mrb_float(obj));
100
0
    }
101
0
#endif
102
0
  }
103
0
  return (mrb_int)obj.w;
104
#else  /* MRB_NO_BOXING */
105
106
#define MakeID(p,t) (mrb_int)(((intptr_t)(p))^(t))
107
108
  enum mrb_vtype tt = mrb_type(obj);
109
110
  switch (tt) {
111
  case MRB_TT_FREE:
112
  case MRB_TT_UNDEF:
113
    return MakeID(0, tt); /* should not happen */
114
  case MRB_TT_FALSE:
115
    if (mrb_nil_p(obj))
116
      return MakeID(4, tt);
117
    else
118
      return MakeID(0, tt);
119
  case MRB_TT_TRUE:
120
    return MakeID(2, tt);
121
  case MRB_TT_SYMBOL:
122
    return MakeID(mrb_symbol(obj), tt);
123
  case MRB_TT_INTEGER:
124
    return MakeID(mrb_integer(obj), tt);
125
#ifndef MRB_NO_FLOAT
126
  case MRB_TT_FLOAT:
127
    return MakeID(mrb_float_id(mrb_float(obj)), tt);
128
#endif
129
  case MRB_TT_STRING:
130
  case MRB_TT_OBJECT:
131
  case MRB_TT_CLASS:
132
  case MRB_TT_MODULE:
133
  case MRB_TT_ICLASS:
134
  case MRB_TT_SCLASS:
135
  case MRB_TT_PROC:
136
  case MRB_TT_ARRAY:
137
  case MRB_TT_HASH:
138
  case MRB_TT_RANGE:
139
  case MRB_TT_EXCEPTION:
140
  case MRB_TT_CDATA:
141
  case MRB_TT_ISTRUCT:
142
  default:
143
    return MakeID(mrb_ptr(obj), tt);
144
  }
145
#endif
146
0
}
147
148
#ifdef MRB_WORD_BOXING
149
#ifndef MRB_NO_FLOAT
150
MRB_API mrb_value
151
mrb_word_boxing_float_value(mrb_state *mrb, mrb_float f)
152
18.5k
{
153
18.5k
  union mrb_value_ v;
154
155
#ifdef MRB_WORDBOX_NO_FLOAT_TRUNCATE
156
  v.p = mrb_obj_alloc(mrb, MRB_TT_FLOAT, mrb->float_class);
157
  v.fp->f = f;
158
  MRB_SET_FROZEN_FLAG(v.bp);
159
#elif defined(MRB_64BIT) && defined(MRB_USE_FLOAT32)
160
  v.w = 0;
161
  v.f = f;
162
  v.w = (v.w<<2) | 2;
163
#else
164
18.5k
  v.f = f;
165
18.5k
  v.w = (v.w & ~3) | 2;
166
18.5k
#endif
167
18.5k
  return v.value;
168
18.5k
}
169
170
171
#ifndef MRB_WORDBOX_NO_FLOAT_TRUNCATE
172
MRB_API mrb_float
173
mrb_word_boxing_value_float(mrb_value v)
174
18.2k
{
175
18.2k
  union mrb_value_ u;
176
18.2k
  u.value = v;
177
#if defined(MRB_64BIT) && defined(MRB_USE_FLOAT32)
178
  u.w >>= 2;
179
#else
180
18.2k
  u.w &= ~3;
181
18.2k
#endif
182
18.2k
  return u.f;
183
18.2k
}
184
#endif
185
#endif  /* MRB_NO_FLOAT */
186
187
MRB_API mrb_value
188
mrb_word_boxing_cptr_value(mrb_state *mrb, void *p)
189
0
{
190
0
  mrb_value v;
191
0
  struct RCptr *cptr = MRB_OBJ_ALLOC(mrb, MRB_TT_CPTR, mrb->object_class);
192
193
0
  SET_OBJ_VALUE(v, cptr);
194
0
  cptr->p = p;
195
0
  return v;
196
0
}
197
#endif  /* MRB_WORD_BOXING */
198
199
#if defined(MRB_WORD_BOXING) || (defined(MRB_NAN_BOXING) && defined(MRB_INT64))
200
MRB_API mrb_value
201
mrb_boxing_int_value(mrb_state *mrb, mrb_int n)
202
191k
{
203
191k
  if (FIXABLE(n)) return mrb_fixnum_value(n);
204
3.32k
  else {
205
3.32k
    mrb_value v;
206
3.32k
    struct RInteger *p;
207
208
3.32k
    p = (struct RInteger*)mrb_obj_alloc(mrb, MRB_TT_INTEGER, mrb->integer_class);
209
3.32k
    p->i = n;
210
3.32k
    MRB_SET_FROZEN_FLAG((struct RBasic*)p);
211
3.32k
    SET_OBJ_VALUE(v, p);
212
3.32k
    return v;
213
3.32k
  }
214
191k
}
215
#endif
216
217
#if defined _MSC_VER && _MSC_VER < 1900
218
219
#ifndef va_copy
220
static void
221
mrb_msvc_va_copy(va_list *dest, va_list src)
222
{
223
  *dest = src;
224
}
225
#define va_copy(dest, src) mrb_msvc_va_copy(&(dest), src)
226
#endif
227
228
MRB_API int
229
mrb_msvc_vsnprintf(char *s, size_t n, const char *format, va_list arg)
230
{
231
  int cnt;
232
  va_list argcp;
233
  va_copy(argcp, arg);
234
  if (n == 0 || (cnt = _vsnprintf_s(s, n, _TRUNCATE, format, argcp)) < 0) {
235
    cnt = _vscprintf(format, arg);
236
  }
237
  va_end(argcp);
238
  return cnt;
239
}
240
241
MRB_API int
242
mrb_msvc_snprintf(char *s, size_t n, const char *format, ...)
243
{
244
  va_list arg;
245
  int ret;
246
  va_start(arg, format);
247
  ret = mrb_msvc_vsnprintf(s, n, format, arg);
248
  va_end(arg);
249
  return ret;
250
}
251
252
#endif  /* defined _MSC_VER && _MSC_VER < 1900 */