Ruby 3.0.5p211 (2022-11-24 revision ba5cf0f7c52d4d35cc6a173c89eda98ceffa2dcf)
rstring.h
Go to the documentation of this file.
1#ifndef RBIMPL_RSTRING_H /*-*-C++-*-vi:se ft=cpp:*/
2#define RBIMPL_RSTRING_H
27#include "ruby/internal/cast.h"
33#include "ruby/assert.h"
34
35#define RSTRING(obj) RBIMPL_CAST((struct RString *)(obj))
36#define RSTRING_NOEMBED RSTRING_NOEMBED
37#define RSTRING_EMBED_LEN_MASK RSTRING_EMBED_LEN_MASK
38#define RSTRING_EMBED_LEN_SHIFT RSTRING_EMBED_LEN_SHIFT
39#define RSTRING_EMBED_LEN_MAX RSTRING_EMBED_LEN_MAX
40#define RSTRING_FSTR RSTRING_FSTR
41
43#define RSTRING_EMBED_LEN RSTRING_EMBED_LEN
44#define RSTRING_LEN RSTRING_LEN
45#define RSTRING_LENINT RSTRING_LENINT
46#define RSTRING_PTR RSTRING_PTR
47#define RSTRING_END RSTRING_END
50#define StringValue(v) rb_string_value(&(v))
51#define StringValuePtr(v) rb_string_value_ptr(&(v))
52#define StringValueCStr(v) rb_string_value_cstr(&(v))
53#define SafeStringValue(v) StringValue(v)
54#define ExportStringValue(v) do { \
55 StringValue(v); \
56 (v) = rb_str_export(v); \
57} while (0)
58
60 RSTRING_NOEMBED = RUBY_FL_USER1,
61 RSTRING_EMBED_LEN_MASK = RUBY_FL_USER2 | RUBY_FL_USER3 | RUBY_FL_USER4 |
62 RUBY_FL_USER5 | RUBY_FL_USER6,
63 /* Actually, string encodings are also encoded into the flags, using
64 * remaining bits.*/
65 RSTRING_FSTR = RUBY_FL_USER17
66};
67
70 RSTRING_EMBED_LEN_MAX = RBIMPL_EMBED_LEN_MAX_OF(char) - 1
71};
72
73struct RString {
74 struct RBasic basic;
75 union {
76 struct {
77 long len;
78 char *ptr;
79 union {
80 long capa;
82 } aux;
83 } heap;
84 char ary[RSTRING_EMBED_LEN_MAX + 1];
85 } as;
86};
87
90VALUE rb_string_value(volatile VALUE*);
91char *rb_string_value_ptr(volatile VALUE*);
92char *rb_string_value_cstr(volatile VALUE*);
95
96RBIMPL_ATTR_ERROR(("rb_check_safe_str() and Check_SafeStr() are obsolete; use StringValue() instead"))
97void rb_check_safe_str(VALUE);
98#define Check_SafeStr(v) rb_check_safe_str(RBIMPL_CAST((VALUE)(v)))
100
103static inline long
104RSTRING_EMBED_LEN(VALUE str)
105{
106 RBIMPL_ASSERT_TYPE(str, RUBY_T_STRING);
108
109 VALUE f = RBASIC(str)->flags;
112 return RBIMPL_CAST((long)f);
113}
114
115RBIMPL_WARNING_PUSH()
116#if RBIMPL_COMPILER_IS(Intel)
117RBIMPL_WARNING_IGNORED(413)
118#endif
119
122static inline struct RString
123rbimpl_rstring_getmem(VALUE str)
124{
125 RBIMPL_ASSERT_TYPE(str, RUBY_T_STRING);
126
127 if (RB_FL_ANY_RAW(str, RSTRING_NOEMBED)) {
128 return *RSTRING(str);
129 }
130 else {
131 /* Expecting compilers to optimize this on-stack struct away. */
132 struct RString retval;
133 retval.as.heap.len = RSTRING_EMBED_LEN(str);
134 retval.as.heap.ptr = RSTRING(str)->as.ary;
135 return retval;
136 }
137}
138
139RBIMPL_WARNING_POP()
140
143static inline long
145{
146 return rbimpl_rstring_getmem(str).as.heap.len;
147}
148
150static inline char *
152{
153 char *ptr = rbimpl_rstring_getmem(str).as.heap.ptr;
154
155 if (RB_UNLIKELY(! ptr)) {
156 /* :BEWARE: @shyouhei thinks that currently, there are rooms for this
157 * function to return NULL. In the 20th century that was a pointless
158 * concern. However struct RString can hold fake strings nowadays. It
159 * seems no check against NULL are exercised around handling of them
160 * (one of such usages is located in marshal.c, which scares
161 * @shyouhei). Better check here for maximum safety.
162 *
163 * Also, this is not rb_warn() because RSTRING_PTR() can be called
164 * during GC (see what obj_info() does). rb_warn() needs to allocate
165 * Ruby objects. That is not possible at this moment. */
166 fprintf(stderr, "%s\n",
167 "RSTRING_PTR is returning NULL!! "
168 "SIGSEGV is highly expected to follow immediately. "
169 "If you could reproduce, attach your debugger here, "
170 "and look at the passed string."
171 );
172 }
173
174 return ptr;
175}
176
178static inline char *
179RSTRING_END(VALUE str)
180{
181 struct RString buf = rbimpl_rstring_getmem(str);
182
183 if (RB_UNLIKELY(! buf.as.heap.ptr)) {
184 /* Ditto. */
185 fprintf(stderr, "%s\n",
186 "RSTRING_END is returning NULL!! "
187 "SIGSEGV is highly expected to follow immediately. "
188 "If you could reproduce, attach your debugger here, "
189 "and look at the passed string."
190 );
191 }
192
193 return &buf.as.heap.ptr[buf.as.heap.len];
194}
195
197static inline int
198RSTRING_LENINT(VALUE str)
199{
200 return rb_long2int(RSTRING_LEN(str));
201}
202
203#ifdef HAVE_STMT_AND_DECL_IN_EXPR
204# define RSTRING_GETMEM(str, ptrvar, lenvar) \
205 __extension__ ({ \
206 struct RString rbimpl_str = rbimpl_rstring_getmem(str); \
207 (ptrvar) = rbimpl_str.as.heap.ptr; \
208 (lenvar) = rbimpl_str.as.heap.len; \
209 })
210#else
211# define RSTRING_GETMEM(str, ptrvar, lenvar) \
212 ((ptrvar) = RSTRING_PTR(str), \
213 (lenvar) = RSTRING_LEN(str))
214#endif /* HAVE_STMT_AND_DECL_IN_EXPR */
215#endif /* RBIMPL_RSTRING_H */
Defines RBIMPL_ATTR_ARTIFICIAL.
#define RBIMPL_ATTR_ARTIFICIAL()
Wraps (or simulates) __attribute__((artificial))
Definition: artificial.h:43
#define RBIMPL_ASSERT_OR_ASSUME(expr)
This is either RUBY_ASSERT or RBIMPL_ASSUME, depending on RUBY_DEBUG.
Definition: assert.h:229
#define RB_UNLIKELY(x)
Definition: assume.h:40
Defines RBIMPL_CAST.
struct RIMemo * ptr
Definition: debug.c:88
Tewaking visibility of C variables/functions.
#define RBIMPL_SYMBOL_EXPORT_END()
Counterpart of RBIMPL_SYMBOL_EXPORT_BEGIN.
Definition: dllexport.h:86
#define RBIMPL_SYMBOL_EXPORT_BEGIN()
Shortcut macro equivalent to RUBY_SYMBOL_EXPORT_BEGIN extern "C" {.
Definition: dllexport.h:77
char str[HTML_ESCAPE_MAX_LEN+1]
Definition: escape.c:18
#define RSTRING_LEN(string)
Definition: fbuffer.h:22
#define RSTRING_PTR(string)
Definition: fbuffer.h:19
Defines enum ruby_fl_type.
@ RUBY_FL_USHIFT
Definition: fl_type.h:150
#define RBIMPL_ATTR_ERROR(msg)
Wraps (or simulates) __attribute__((error))
Definition: error.h:29
Thin wrapper to ruby/config.h.
voidpf void * buf
Definition: ioapi.h:138
Arithmetic conversion between C's long and Ruby's.
#define rb_long2int
Definition: long.h:62
Defines RBIMPL_ATTR_PURE.
#define RBIMPL_ATTR_PURE_UNLESS_DEBUG()
Enables RBIMPL_ATTR_PURE iff.
Definition: pure.h:38
Defines struct RBasic.
#define RBASIC(obj)
Definition: rbasic.h:34
VALUE rb_str_to_str(VALUE)
Definition: string.c:1471
ruby_rstring_consts
Definition: rstring.h:68
#define StringValue(v)
Definition: rstring.h:50
#define RSTRING_NOEMBED
Definition: rstring.h:36
VALUE rb_str_export_locale(VALUE)
Definition: string.c:1199
char * rb_string_value_ptr(volatile VALUE *)
Definition: string.c:2334
VALUE rb_str_export(VALUE)
Definition: string.c:1193
#define RSTRING_EMBED_LEN_MAX
Definition: rstring.h:39
#define RSTRING_FSTR
Definition: rstring.h:40
#define RSTRING_EMBED_LEN_SHIFT
Definition: rstring.h:38
VALUE rb_string_value(volatile VALUE *)
Definition: string.c:2323
#define Check_SafeStr(v)
Definition: rstring.h:98
#define RSTRING(obj)
Definition: rstring.h:35
char * rb_string_value_cstr(volatile VALUE *)
Definition: string.c:2439
ruby_rstring_flags
Definition: rstring.h:59
#define RSTRING_EMBED_LEN_MASK
Definition: rstring.h:37
#define f
Definition: rbasic.h:47
struct RBasic basic
Definition: rstring.h:74
long capa
Definition: rstring.h:80
long len
Definition: rstring.h:77
VALUE shared
Definition: rstring.h:81
char * ptr
Definition: rstring.h:78
union RString::@100 as
struct RString::@100::@101 heap
unsigned long VALUE
Definition: value.h:38
Defines enum ruby_value_type.
@ RUBY_T_STRING
Definition: value_type.h:117
Defines RBIMPL_WARNING_PUSH.