diff options
Diffstat (limited to 'internal/string.h')
| -rw-r--r-- | internal/string.h | 95 |
1 files changed, 87 insertions, 8 deletions
diff --git a/internal/string.h b/internal/string.h index 8c481f979e..9212ce8986 100644 --- a/internal/string.h +++ b/internal/string.h @@ -14,15 +14,57 @@ #include "ruby/internal/stdbool.h" /* for bool */ #include "ruby/encoding.h" /* for rb_encoding */ #include "ruby/ruby.h" /* for VALUE */ +#include "encindex.h" -#define STR_NOEMBED FL_USER1 -#define STR_SHARED FL_USER2 /* = ELTS_SHARED */ +#define STR_SHARED FL_USER0 /* = ELTS_SHARED */ +#define STR_NOEMBED FL_USER1 +#define STR_CHILLED (FL_USER2 | FL_USER3) +#define STR_CHILLED_LITERAL FL_USER2 +#define STR_CHILLED_SYMBOL_TO_S FL_USER3 + +enum ruby_rstring_private_flags { + RSTRING_CHILLED = STR_CHILLED, +}; #ifdef rb_fstring_cstr # undef rb_fstring_cstr #endif +static inline bool +rb_str_encindex_fastpath(int encindex) +{ + // The overwhelming majority of strings are in one of these 3 encodings, + // which are all either ASCII or perfect ASCII supersets. + // Hence you can use fast, single byte algorithms on them, such as `memchr` etc, + // without all the overhead of fetching the rb_encoding and using functions such as + // rb_enc_mbminlen etc. + // Many other encodings could qualify, but they are expected to be rare occurences, + // so it's better to keep that list small. + switch (encindex) { + case ENCINDEX_ASCII_8BIT: + case ENCINDEX_UTF_8: + case ENCINDEX_US_ASCII: + return true; + default: + return false; + } +} + +static inline bool +rb_str_enc_fastpath(VALUE str) +{ + return rb_str_encindex_fastpath(ENCODING_GET_INLINED(str)); +} + +static inline rb_encoding * +rb_str_enc_get(VALUE str) +{ + RUBY_ASSERT(RB_TYPE_P(str, T_STRING)); + return rb_enc_from_index(ENCODING_GET(str)); +} + /* string.c */ +VALUE rb_str_dup_m(VALUE str); VALUE rb_fstring(VALUE); VALUE rb_fstring_cstr(const char *str); VALUE rb_fstring_enc_new(const char *ptr, long len, rb_encoding *enc); @@ -45,6 +87,21 @@ void rb_str_make_independent(VALUE str); int rb_enc_str_coderange_scan(VALUE str, rb_encoding *enc); int rb_ascii8bit_appendable_encoding_index(rb_encoding *enc, unsigned int code); VALUE rb_str_include(VALUE str, VALUE arg); +VALUE rb_str_byte_substr(VALUE str, VALUE beg, VALUE len); +VALUE rb_str_substr_two_fixnums(VALUE str, VALUE beg, VALUE len, int empty); +VALUE rb_str_tmp_frozen_no_embed_acquire(VALUE str); +void rb_str_make_embedded(VALUE); +VALUE rb_str_upto_each(VALUE, VALUE, int, int (*each)(VALUE, VALUE), VALUE); +size_t rb_str_size_as_embedded(VALUE); +bool rb_str_reembeddable_p(VALUE); +VALUE rb_str_upto_endless_each(VALUE, int (*each)(VALUE, VALUE), VALUE); +VALUE rb_str_with_debug_created_info(VALUE, VALUE, int); +VALUE rb_str_frozen_bare_string(VALUE); +const char *rb_str_null_check(VALUE); + +/* error.c */ +void rb_warn_unchilled_literal(VALUE str); +void rb_warn_unchilled_symbol_to_s(VALUE str); static inline bool STR_EMBED_P(VALUE str); static inline bool STR_SHARED_P(VALUE str); @@ -59,23 +116,22 @@ RUBY_SYMBOL_EXPORT_BEGIN VALUE rb_str_tmp_frozen_acquire(VALUE str); void rb_str_tmp_frozen_release(VALUE str, VALUE tmp); VALUE rb_setup_fake_str(struct RString *fake_str, const char *name, long len, rb_encoding *enc); -VALUE rb_str_upto_each(VALUE, VALUE, int, int (*each)(VALUE, VALUE), VALUE); -VALUE rb_str_upto_endless_each(VALUE, int (*each)(VALUE, VALUE), VALUE); -void rb_str_make_embedded(VALUE); -size_t rb_str_size_as_embedded(VALUE); -bool rb_str_reembeddable_p(VALUE); RUBY_SYMBOL_EXPORT_END VALUE rb_fstring_new(const char *ptr, long len); +void rb_gc_free_fstring(VALUE obj); +bool rb_obj_is_fstring_table(VALUE obj); +void Init_fstring_table(); VALUE rb_obj_as_string_result(VALUE str, VALUE obj); VALUE rb_str_opt_plus(VALUE x, VALUE y); VALUE rb_str_concat_literals(size_t num, const VALUE *strary); VALUE rb_str_eql(VALUE str1, VALUE str2); VALUE rb_id_quote_unprintable(ID); VALUE rb_sym_proc_call(ID mid, int argc, const VALUE *argv, int kw_splat, VALUE passed_proc); +VALUE rb_enc_literal_str(const char *ptr, long len, rb_encoding *enc); struct rb_execution_context_struct; -VALUE rb_ec_str_resurrect(struct rb_execution_context_struct *ec, VALUE str); +VALUE rb_ec_str_resurrect(struct rb_execution_context_struct *ec, VALUE str, bool chilled); #define rb_fstring_lit(str) rb_fstring_new((str), rb_strlen_lit(str)) #define rb_fstring_literal(str) rb_fstring_lit(str) @@ -107,6 +163,29 @@ STR_SHARED_P(VALUE str) } static inline bool +CHILLED_STRING_P(VALUE obj) +{ + return RB_TYPE_P(obj, T_STRING) && FL_TEST_RAW(obj, STR_CHILLED); +} + +static inline void +CHILLED_STRING_MUTATED(VALUE str) +{ + VALUE chilled_reason = RB_FL_TEST_RAW(str, STR_CHILLED); + FL_UNSET_RAW(str, STR_CHILLED); + switch (chilled_reason) { + case STR_CHILLED_SYMBOL_TO_S: + rb_warn_unchilled_symbol_to_s(str); + break; + case STR_CHILLED_LITERAL: + rb_warn_unchilled_literal(str); + break; + default: + rb_bug("RString was chilled for multiple reasons"); + } +} + +static inline bool is_ascii_string(VALUE str) { return rb_enc_str_coderange(str) == ENC_CODERANGE_7BIT; |
