Skip to content

Commit a2df247

Browse files
committed
Introduce mrb_ssize type for buffer size on memory; ref mruby#4483
Previously, `mrb_int` was used as the type that represents the buffer size on memory, but the sizes of `RString` and `RArray` exceed 6 words when `MRB_INT64` is enabled on 32-bit CPU. I don't think it is necessary to be able to represent the buffer size on memory that exceeds the virtual address space. Therefore, for this purpose, introduce `mrb_ssize` which doesn't exceed the sizes of `mrb_int` and pointer. I think all `mrb_int` used for this purpose should be changed to `mrb_ssize`, but currently only the members of the structures (`RString`, `mrb_shared_string`, `RArray` and `mrb_shared_array`) are changed.
1 parent 79e73dd commit a2df247

4 files changed

Lines changed: 33 additions & 25 deletions

File tree

include/mruby/array.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ MRB_BEGIN_DECL
1717

1818
typedef struct mrb_shared_array {
1919
int refcnt;
20-
mrb_int len;
20+
mrb_ssize len;
2121
mrb_value *ptr;
2222
} mrb_shared_array;
2323

@@ -26,9 +26,9 @@ struct RArray {
2626
MRB_OBJECT_HEADER;
2727
union {
2828
struct {
29-
mrb_int len;
29+
mrb_ssize len;
3030
union {
31-
mrb_int capa;
31+
mrb_ssize capa;
3232
mrb_shared_array *shared;
3333
} aux;
3434
mrb_value *ptr;

include/mruby/string.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ struct RString {
2323
MRB_OBJECT_HEADER;
2424
union {
2525
struct {
26-
mrb_int len;
26+
mrb_ssize len;
2727
union {
28-
mrb_int capa;
28+
mrb_ssize capa;
2929
struct mrb_shared_string *shared;
3030
struct RString *fshared;
3131
} aux;
@@ -54,7 +54,7 @@ struct RStringEmbed {
5454
RSTR_SET_EMBED_LEN((s),(n));\
5555
}\
5656
else {\
57-
(s)->as.heap.len = (mrb_int)(n);\
57+
(s)->as.heap.len = (mrb_ssize)(n);\
5858
}\
5959
} while (0)
6060
#define RSTR_EMBED_PTR(s) (((struct RStringEmbed*)(s))->ary)

include/mruby/value.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,14 @@ typedef void mrb_value;
174174
#define MRB_SYMBOL_MAX UINT32_MAX
175175
#endif
176176

177+
#if INTPTR_MAX < MRB_INT_MAX
178+
typedef intptr_t mrb_ssize;
179+
# define MRB_SSIZE_MAX (INTPTR_MAX>>MRB_FIXNUM_SHIFT)
180+
#else
181+
typedef mrb_int mrb_ssize;
182+
# define MRB_SSIZE_MAX MRB_INT_MAX
183+
#endif
184+
177185
#ifndef mrb_immediate_p
178186
#define mrb_immediate_p(o) (mrb_type(o) < MRB_TT_FREE)
179187
#endif

src/string.c

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525
typedef struct mrb_shared_string {
2626
int refcnt;
27-
mrb_int capa;
27+
mrb_ssize capa;
2828
char *ptr;
2929
} mrb_shared_string;
3030

@@ -40,8 +40,8 @@ str_init_normal_capa(mrb_state *mrb, struct RString *s,
4040
if (p) memcpy(dst, p, len);
4141
dst[len] = '\0';
4242
s->as.heap.ptr = dst;
43-
s->as.heap.len = (mrb_int)len;
44-
s->as.heap.aux.capa = (mrb_int)capa;
43+
s->as.heap.len = (mrb_ssize)len;
44+
s->as.heap.aux.capa = (mrb_ssize)capa;
4545
RSTR_UNSET_TYPE_FLAG(s);
4646
return s;
4747
}
@@ -66,7 +66,7 @@ static struct RString*
6666
str_init_nofree(struct RString *s, const char *p, size_t len)
6767
{
6868
s->as.heap.ptr = (char *)p;
69-
s->as.heap.len = (mrb_int)len;
69+
s->as.heap.len = (mrb_ssize)len;
7070
s->as.heap.aux.capa = 0; /* nofree */
7171
RSTR_SET_TYPE_FLAG(s, NOFREE);
7272
return s;
@@ -118,7 +118,7 @@ str_new_static(mrb_state *mrb, const char *p, size_t len)
118118
if (RSTR_EMBEDDABLE_P(len)) {
119119
return str_init_embed(mrb_obj_alloc_string(mrb), p, len);
120120
}
121-
if (len >= MRB_INT_MAX) {
121+
if (len >= MRB_SSIZE_MAX) {
122122
mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big");
123123
}
124124
return str_init_nofree(mrb_obj_alloc_string(mrb), p, len);
@@ -130,7 +130,7 @@ str_new(mrb_state *mrb, const char *p, size_t len)
130130
if (RSTR_EMBEDDABLE_P(len)) {
131131
return str_init_embed(mrb_obj_alloc_string(mrb), p, len);
132132
}
133-
if (len >= MRB_INT_MAX) {
133+
if (len >= MRB_SSIZE_MAX) {
134134
mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big");
135135
}
136136
if (p && mrb_ro_data_p(p)) {
@@ -162,7 +162,7 @@ mrb_str_new_capa(mrb_state *mrb, size_t capa)
162162
if (RSTR_EMBEDDABLE_P(capa)) {
163163
s = str_init_embed(mrb_obj_alloc_string(mrb), NULL, 0);
164164
}
165-
else if (capa >= MRB_INT_MAX) {
165+
else if (capa >= MRB_SSIZE_MAX) {
166166
mrb_raise(mrb, E_ARGUMENT_ERROR, "string capacity size too big");
167167
/* not reached */
168168
s = NULL;
@@ -190,8 +190,8 @@ mrb_str_buf_new(mrb_state *mrb, size_t capa)
190190
static void
191191
resize_capa(mrb_state *mrb, struct RString *s, size_t capacity)
192192
{
193-
#if SIZE_MAX > MRB_INT_MAX
194-
mrb_assert(capacity < MRB_INT_MAX);
193+
#if SIZE_MAX > MRB_SSIZE_MAX
194+
mrb_assert(capacity < MRB_SSIZE_MAX);
195195
#endif
196196
if (RSTR_EMBED_P(s)) {
197197
if (!RSTR_EMBEDDABLE_P(capacity)) {
@@ -200,7 +200,7 @@ resize_capa(mrb_state *mrb, struct RString *s, size_t capacity)
200200
}
201201
else {
202202
s->as.heap.ptr = (char*)mrb_realloc(mrb, RSTR_PTR(s), capacity+1);
203-
s->as.heap.aux.capa = (mrb_int)capacity;
203+
s->as.heap.aux.capa = (mrb_ssize)capacity;
204204
}
205205
}
206206

@@ -568,7 +568,7 @@ str_share(mrb_state *mrb, struct RString *orig, struct RString *s)
568568
else {
569569
if (orig->as.heap.aux.capa > orig->as.heap.len) {
570570
orig->as.heap.ptr = (char *)mrb_realloc(mrb, orig->as.heap.ptr, len+1);
571-
orig->as.heap.aux.capa = len;
571+
orig->as.heap.aux.capa = (mrb_ssize)len;
572572
}
573573
str_init_shared(mrb, orig, s, NULL);
574574
str_init_shared(mrb, orig, orig, s->as.heap.aux.shared);
@@ -613,8 +613,8 @@ mrb_str_byte_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len)
613613
}
614614
else {
615615
str_share(mrb, orig, s);
616-
s->as.heap.ptr += beg;
617-
s->as.heap.len = len;
616+
s->as.heap.ptr += (mrb_ssize)beg;
617+
s->as.heap.len = (mrb_ssize)len;
618618
}
619619
RSTR_COPY_ASCII_FLAG(s, orig);
620620
return mrb_obj_value(s);
@@ -961,7 +961,7 @@ mrb_str_times(mrb_state *mrb, mrb_value self)
961961
if (times < 0) {
962962
mrb_raise(mrb, E_ARGUMENT_ERROR, "negative argument");
963963
}
964-
if (times && MRB_INT_MAX / times < RSTRING_LEN(self)) {
964+
if (times && MRB_SSIZE_MAX / times < RSTRING_LEN(self)) {
965965
mrb_raise(mrb, E_ARGUMENT_ERROR, "argument too big");
966966
}
967967

@@ -1302,7 +1302,7 @@ str_replace_partial(mrb_state *mrb, mrb_value src, mrb_int pos, mrb_int end, mrb
13021302
replen = (mrb_nil_p(rep) ? 0 : RSTRING_LEN(rep));
13031303
newlen = replen + len - (end - pos);
13041304

1305-
if (newlen >= MRB_INT_MAX || newlen < replen /* overflowed */) {
1305+
if (newlen >= MRB_SSIZE_MAX || newlen < replen /* overflowed */) {
13061306
mrb_raise(mrb, E_RUNTIME_ERROR, "string size too big");
13071307
}
13081308

@@ -2675,21 +2675,21 @@ mrb_str_cat(mrb_state *mrb, mrb_value str, const char *ptr, size_t len)
26752675

26762676
capa = RSTR_CAPA(s);
26772677
total = RSTR_LEN(s)+len;
2678-
if (total >= MRB_INT_MAX) {
2678+
if (total >= MRB_SSIZE_MAX) {
26792679
size_error:
26802680
mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big");
26812681
}
26822682
if (capa <= total) {
26832683
if (capa == 0) capa = 1;
26842684
while (capa <= total) {
2685-
if (capa <= MRB_INT_MAX / 2) {
2685+
if (capa <= MRB_SSIZE_MAX / 2) {
26862686
capa *= 2;
26872687
}
26882688
else {
26892689
capa = total+1;
26902690
}
26912691
}
2692-
if (capa <= total || capa > MRB_INT_MAX) {
2692+
if (capa <= total || capa > MRB_SSIZE_MAX) {
26932693
goto size_error;
26942694
}
26952695
resize_capa(mrb, s, capa);
@@ -2698,7 +2698,7 @@ mrb_str_cat(mrb_state *mrb, mrb_value str, const char *ptr, size_t len)
26982698
ptr = RSTR_PTR(s) + off;
26992699
}
27002700
memcpy(RSTR_PTR(s) + RSTR_LEN(s), ptr, len);
2701-
mrb_assert_int_fit(size_t, total, mrb_int, MRB_INT_MAX);
2701+
mrb_assert_int_fit(size_t, total, mrb_ssize, MRB_SSIZE_MAX);
27022702
RSTR_SET_LEN(s, total);
27032703
RSTR_PTR(s)[total] = '\0'; /* sentinel */
27042704
return str;

0 commit comments

Comments
 (0)