Ruby: include/ruby/internal/core/rstring.h Source File

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
23#include "ruby/internal/config.h"
24#include "ruby/internal/arithmetic/long.h"
25#include "ruby/internal/attr/artificial.h"
26#include "ruby/internal/attr/pure.h"
27#include "ruby/internal/cast.h"
28#include "ruby/internal/core/rbasic.h"
29#include "ruby/internal/dllexport.h"
30#include "ruby/internal/fl_type.h"
31#include "ruby/internal/value_type.h"
32#include "ruby/internal/warning_push.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
59 enum ruby_rstring_flags {
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
68 enum ruby_rstring_consts {
69 RSTRING_EMBED_LEN_SHIFT = RUBY_FL_USHIFT + 2,
70 RSTRING_EMBED_LEN_MAX = RBIMPL_EMBED_LEN_MAX_OF(char) - 1
71};
72
73 struct RString {
74 struct RBasic basic;
75 union {
76 struct {
77 long len;
78 char *ptr;
79 union {
80 long capa;
81 VALUE shared;
82 } aux;
83 } heap;
84 char ary[RSTRING_EMBED_LEN_MAX + 1];
85 } as;
86};
87
88 RBIMPL_SYMBOL_EXPORT_BEGIN()
89 VALUE rb_str_to_str(VALUE);
90 VALUE rb_string_value(volatile VALUE*);
91char *rb_string_value_ptr(volatile VALUE*);
92char *rb_string_value_cstr(volatile VALUE*);
93 VALUE rb_str_export(VALUE);
94 VALUE rb_str_export_locale(VALUE);
95
96 RBIMPL_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)))
99 RBIMPL_SYMBOL_EXPORT_END()
100
101 RBIMPL_ATTR_PURE_UNLESS_DEBUG()
102 RBIMPL_ATTR_ARTIFICIAL()
103static inline long
104RSTRING_EMBED_LEN(VALUE str)
105{
106 RBIMPL_ASSERT_TYPE(str, RUBY_T_STRING);
107 RBIMPL_ASSERT_OR_ASSUME(! RB_FL_ANY_RAW(str, RSTRING_NOEMBED));
108
109 VALUE f = RBASIC(str)->flags;
110 f &= RSTRING_EMBED_LEN_MASK;
111 f >>= RSTRING_EMBED_LEN_SHIFT;
112 return RBIMPL_CAST((long)f);
113}
114
115RBIMPL_WARNING_PUSH()
116#if RBIMPL_COMPILER_IS(Intel)
117RBIMPL_WARNING_IGNORED(413)
118#endif
119
120 RBIMPL_ATTR_PURE_UNLESS_DEBUG()
121 RBIMPL_ATTR_ARTIFICIAL()
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
141 RBIMPL_ATTR_PURE_UNLESS_DEBUG()
142 RBIMPL_ATTR_ARTIFICIAL()
143static inline long
144 RSTRING_LEN(VALUE str)
145{
146 return rbimpl_rstring_getmem(str).as.heap.len;
147}
148
149 RBIMPL_ATTR_ARTIFICIAL()
150static inline char *
151 RSTRING_PTR(VALUE str)
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
177 RBIMPL_ATTR_ARTIFICIAL()
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
196 RBIMPL_ATTR_ARTIFICIAL()
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 */
artificial.h
Defines RBIMPL_ATTR_ARTIFICIAL.
RBIMPL_ATTR_ARTIFICIAL
#define RBIMPL_ATTR_ARTIFICIAL()
Wraps (or simulates) __attribute__((artificial))
Definition: artificial.h:43
assert.h
RBIMPL_ASSERT_OR_ASSUME
#define RBIMPL_ASSERT_OR_ASSUME(expr)
This is either RUBY_ASSERT or RBIMPL_ASSUME, depending on RUBY_DEBUG.
Definition: assert.h:229
RB_UNLIKELY
#define RB_UNLIKELY(x)
Definition: assume.h:40
cast.h
Defines RBIMPL_CAST.
ptr
struct RIMemo * ptr
Definition: debug.c:88
dllexport.h
Tewaking visibility of C variables/functions.
RBIMPL_SYMBOL_EXPORT_END
#define RBIMPL_SYMBOL_EXPORT_END()
Counterpart of RBIMPL_SYMBOL_EXPORT_BEGIN.
Definition: dllexport.h:86
RBIMPL_SYMBOL_EXPORT_BEGIN
#define RBIMPL_SYMBOL_EXPORT_BEGIN()
Shortcut macro equivalent to RUBY_SYMBOL_EXPORT_BEGIN extern "C" {.
Definition: dllexport.h:77
str
char str[HTML_ESCAPE_MAX_LEN+1]
Definition: escape.c:18
RSTRING_LEN
#define RSTRING_LEN(string)
Definition: fbuffer.h:22
RSTRING_PTR
#define RSTRING_PTR(string)
Definition: fbuffer.h:19
fl_type.h
Defines enum ruby_fl_type.
RUBY_FL_USHIFT
@ RUBY_FL_USHIFT
Definition: fl_type.h:150
RBIMPL_ATTR_ERROR
#define RBIMPL_ATTR_ERROR(msg)
Wraps (or simulates) __attribute__((error))
Definition: error.h:29
config.h
Thin wrapper to ruby/config.h.
buf
voidpf void * buf
Definition: ioapi.h:138
long.h
Arithmetic conversion between C's long and Ruby's.
rb_long2int
#define rb_long2int
Definition: long.h:62
pure.h
Defines RBIMPL_ATTR_PURE.
RBIMPL_ATTR_PURE_UNLESS_DEBUG
#define RBIMPL_ATTR_PURE_UNLESS_DEBUG()
Enables RBIMPL_ATTR_PURE iff.
Definition: pure.h:38
rbasic.h
Defines struct RBasic.
RBASIC
#define RBASIC(obj)
Definition: rbasic.h:34
rb_str_to_str
VALUE rb_str_to_str(VALUE)
Definition: string.c:1471
ruby_rstring_consts
ruby_rstring_consts
Definition: rstring.h:68
StringValue
#define StringValue(v)
Definition: rstring.h:50
RSTRING_NOEMBED
#define RSTRING_NOEMBED
Definition: rstring.h:36
rb_str_export_locale
VALUE rb_str_export_locale(VALUE)
Definition: string.c:1199
rb_string_value_ptr
char * rb_string_value_ptr(volatile VALUE *)
Definition: string.c:2334
rb_str_export
VALUE rb_str_export(VALUE)
Definition: string.c:1193
RSTRING_EMBED_LEN_MAX
#define RSTRING_EMBED_LEN_MAX
Definition: rstring.h:39
RSTRING_FSTR
#define RSTRING_FSTR
Definition: rstring.h:40
RSTRING_EMBED_LEN_SHIFT
#define RSTRING_EMBED_LEN_SHIFT
Definition: rstring.h:38
rb_string_value
VALUE rb_string_value(volatile VALUE *)
Definition: string.c:2323
Check_SafeStr
#define Check_SafeStr(v)
Definition: rstring.h:98
RSTRING
#define RSTRING(obj)
Definition: rstring.h:35
rb_string_value_cstr
char * rb_string_value_cstr(volatile VALUE *)
Definition: string.c:2439
ruby_rstring_flags
ruby_rstring_flags
Definition: rstring.h:59
RSTRING_EMBED_LEN_MASK
#define RSTRING_EMBED_LEN_MASK
Definition: rstring.h:37
f
#define f
RBasic
Definition: rbasic.h:47
RString
Definition: rstring.h:73
RString::basic
struct RBasic basic
Definition: rstring.h:74
RString::capa
long capa
Definition: rstring.h:80
RString::len
long len
Definition: rstring.h:77
RString::shared
VALUE shared
Definition: rstring.h:81
RString::ptr
char * ptr
Definition: rstring.h:78
RString::as
union RString::@100 as
RString::heap
struct RString::@100::@101 heap
VALUE
unsigned long VALUE
Definition: value.h:38
value_type.h
Defines enum ruby_value_type.
RUBY_T_STRING
@ RUBY_T_STRING
Definition: value_type.h:117
warning_push.h
Defines RBIMPL_WARNING_PUSH.