diff --git a/include/ruby/internal/core/rregexp.h b/include/ruby/internal/core/rregexp.h index 3c33f12860..cf54a399f1 100644 --- a/include/ruby/internal/core/rregexp.h +++ b/include/ruby/internal/core/rregexp.h @@ -28,7 +28,20 @@ #include "ruby/internal/value.h" #include "ruby/internal/value_type.h" +/** + * Convenient casting macro. + * + * @param obj An object, which is in fact an ::RRegexp. + * @return The passed object casted to ::RRegexp. + */ #define RREGEXP(obj) RBIMPL_CAST((struct RRegexp *)(obj)) + +/** + * Convenient accessor macro. + * + * @param obj An object, which is in fact an ::RRegexp. + * @return The passed object's pattern buffer. + */ #define RREGEXP_PTR(obj) (RREGEXP(obj)->ptr) /** @cond INTERNAL_MACRO */ #define RREGEXP_SRC RREGEXP_SRC @@ -37,17 +50,55 @@ #define RREGEXP_SRC_END RREGEXP_SRC_END /** @endcond */ -struct re_patter_buffer; /* a.k.a. OnigRegexType, defined in onigmo.h */ +struct re_patter_buffer; /* a.k.a. OnigRegexType, defined in onigmo.h */ +/** + * Ruby's regular expression. A regexp is compiled into its own intermediate + * representation. This one holds that info. Regexp "match" operation then + * executes that IR. + */ struct RRegexp { + + /** Basic part, including flags and class. */ struct RBasic basic; + + /** + * The pattern buffer. This is a quasi-opaque struct that holds compiled + * intermediate representation of the regular expression. + * + * @note Compilation of a regexp could be delayed until actual match. + */ struct re_pattern_buffer *ptr; + + /** Source code of this expression. */ const VALUE src; + + /** + * Reference count. A regexp match can take extraordinarily long time to + * run. Ruby's regular expression is heavily extended and not a regular + * language any longer; runs in NP-time in practice. Now, Ruby also has + * threads and GVL. In order to prevent long GVL lockup, our regexp engine + * can release it on occasions. This means that multiple threads can touch + * a regular expressions at once. That itself is okay. But their cleanup + * phase shall wait for all the concurrent runs, to prevent use-after-free + * situation. This field is used to count such threads that are executing + * this particular pattern buffer. + * + * @warning Of course, touching this field from extension libraries causes + * catastrophic effects. Just leave it. + */ unsigned long usecnt; }; RBIMPL_ATTR_PURE_UNLESS_DEBUG() RBIMPL_ATTR_ARTIFICIAL() +/** + * Convenient getter function. + * + * @param[in] rexp The regular expression in question. + * @return The source code of the regular expression. + * @pre `rexp` must be of ::RRegexp. + */ static inline VALUE RREGEXP_SRC(VALUE rexp) { @@ -59,6 +110,17 @@ RREGEXP_SRC(VALUE rexp) RBIMPL_ATTR_PURE_UNLESS_DEBUG() RBIMPL_ATTR_ARTIFICIAL() +/** + * Convenient getter function. + * + * @param[in] rexp The regular expression in question. + * @return The source code of the regular expression, in C's string. + * @pre `rexp` must be of ::RRegexp. + * + * @internal + * + * It seems nobody uses this function in the wild. Subject to hide? + */ static inline char * RREGEXP_SRC_PTR(VALUE rexp) { @@ -67,6 +129,17 @@ RREGEXP_SRC_PTR(VALUE rexp) RBIMPL_ATTR_PURE_UNLESS_DEBUG() RBIMPL_ATTR_ARTIFICIAL() +/** + * Convenient getter function. + * + * @param[in] rexp The regular expression in question. + * @return The length of the source code of the regular expression. + * @pre `rexp` must be of ::RRegexp. + * + * @internal + * + * It seems nobody uses this function in the wild. Subject to hide? + */ static inline long RREGEXP_SRC_LEN(VALUE rexp) { @@ -75,6 +148,17 @@ RREGEXP_SRC_LEN(VALUE rexp) RBIMPL_ATTR_PURE_UNLESS_DEBUG() RBIMPL_ATTR_ARTIFICIAL() +/** + * Convenient getter function. + * + * @param[in] rexp The regular expression in question. + * @return The end of the source code of the regular expression. + * @pre `rexp` must be of ::RRegexp. + * + * @internal + * + * It seems nobody uses this function in the wild. Subject to hide? + */ static inline char * RREGEXP_SRC_END(VALUE rexp) {