ruby-changes:67739
From: =E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3 <ko1@a...>
Date: Fri, 10 Sep 2021 20:01:19 +0900 (JST)
Subject: [ruby-changes:67739] fdae26a5a8 (master): include/ruby/internal/core/rtypeddata.h: add doxygen
https://git.ruby-lang.org/ruby.git/commit/?id=fdae26a5a8 From fdae26a5a8815e430661e5c6e7e90f167d5d1447 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3?= <shyouhei@r...> Date: Thu, 28 Jan 2021 15:10:40 +0900 Subject: include/ruby/internal/core/rtypeddata.h: add doxygen Must not be a bad idea to improve documents. [ci skip] --- include/ruby/internal/core/rtypeddata.h | 426 +++++++++++++++++++++++++++++++- 1 file changed, 422 insertions(+), 4 deletions(-) diff --git a/include/ruby/internal/core/rtypeddata.h b/include/ruby/internal/core/rtypeddata.h index 9d075c9..bbf2088 100644 --- a/include/ruby/internal/core/rtypeddata.h +++ b/include/ruby/internal/core/rtypeddata.h @@ -28,6 +28,8 @@ https://github.com/ruby/ruby/blob/trunk/include/ruby/internal/core/rtypeddata.h#L28 #include "ruby/internal/assume.h" #include "ruby/internal/attr/artificial.h" +#include "ruby/internal/attr/flag_enum.h" +#include "ruby/internal/attr/nonnull.h" #include "ruby/internal/attr/pure.h" #include "ruby/internal/cast.h" #include "ruby/internal/core/rbasic.h" @@ -38,13 +40,68 @@ https://github.com/ruby/ruby/blob/trunk/include/ruby/internal/core/rtypeddata.h#L40 #include "ruby/internal/stdbool.h" #include "ruby/internal/value_type.h" +/** + * @private + * + * @deprecated This macro once was a thing in the old days, but makes no sense + * any longer today. Exists here for backwards compatibility + * only. You can safely forget about it. + */ #define HAVE_TYPE_RB_DATA_TYPE_T 1 + +/** + * @private + * + * @deprecated This macro once was a thing in the old days, but makes no sense + * any longer today. Exists here for backwards compatibility + * only. You can safely forget about it. + */ #define HAVE_RB_DATA_TYPE_T_FUNCTION 1 + +/** + * @private + * + * @deprecated This macro once was a thing in the old days, but makes no sense + * any longer today. Exists here for backwards compatibility + * only. You can safely forget about it. + */ #define HAVE_RB_DATA_TYPE_T_PARENT 1 + +/** + * This is a value you can set to ::rb_data_type_struct::dfree. Setting this + * means the data was allocated using ::ruby_xmalloc() (or variants), and shall + * be freed using ::ruby_xfree(). + * + * @warning Do not use this if you want to use system malloc, because the + * system and Ruby might or might not share the same malloc + * implementation. + */ #define RUBY_TYPED_DEFAULT_FREE RUBY_DEFAULT_FREE + +/** + * This is a value you can set to ::rb_data_type_struct::dfree. Setting this + * means the data is managed by someone else, like, statically allocated. Of + * course you are on your own then. + */ #define RUBY_TYPED_NEVER_FREE RUBY_NEVER_FREE + +/** + * Convenient casting macro. + * + * @param obj An object, which is in fact an ::RTypedData. + * @return The passed object casted to ::RTypedData. + */ #define RTYPEDDATA(obj) RBIMPL_CAST((struct RTypedData *)(obj)) + +/** + * Convenient getter macro. + * + * @param v An object, which is in fact an ::RTypedData. + * @return The passed object's ::RTypedData::data field. + */ #define RTYPEDDATA_DATA(v) (RTYPEDDATA(v)->data) + +/** @old{rb_check_typeddata} */ #define Check_TypedStruct(v, t) \ rb_check_typeddata(RBIMPL_CAST((VALUE)(v)), (t)) @@ -57,55 +114,365 @@ https://github.com/ruby/ruby/blob/trunk/include/ruby/internal/core/rtypeddata.h#L114 #define RUBY_TYPED_PROMOTED1 RUBY_TYPED_PROMOTED1 /** @endcond */ -/* bits for rb_data_type_struct::flags */ -enum rbimpl_typeddata_flags { +/** + * @private + * + * Bits for rb_data_type_struct::flags. + */ +enum +RBIMPL_ATTR_FLAG_ENUM() +rbimpl_typeddata_flags { + /** + * This flag has something to do with Ruby's global interpreter lock. For + * maximum safety, Ruby locks the entire VM during GC. However your + * callback functions could unintentionally unlock it, for instance when + * they try to flush an IO buffer. Such operations are dangerous (threads + * then run alongside of GC). By default, to prevent those scenario, + * callbacks are deferred until the GC engine is 100% sure threads can run. + * This flag skips that; structs with it are deallocated during the sweep + * phase. + * + * Using this flag needs deep understanding of both GC and threads. You + * would better leave it unspecified. + */ RUBY_TYPED_FREE_IMMEDIATELY = 1, + + /** + * This flag has something to do with Ractor. Multiple Ractors run without + * protecting each other. Sharing an object among Ractors is basically + * dangerous, disabled by default. This flag is used to bypass that + * restriction. but setting it is not enough. In addition to do so, an + * object also has to be frozen, and be passed to + * rb_ractor_make_shareable() before being actually shareable. Of course, + * you have to manually prevent race conditions then. + * + * Using this flag needs deep understanding of multithreaded programming. + * You would better leave it unspecified. + */ RUBY_TYPED_FROZEN_SHAREABLE = RUBY_FL_SHAREABLE, + + /** + * This flag has something to do with our garbage collector. These days + * ruby objects are "generational". There are those who are young and + * those who are old. Young objects are prone to die; monitored relatively + * extensively by the garbage collector. OTOH old objects tend to live + * longer. They are relatively rarely considered. This basically works. + * But there is one tweak that has to be exercised. When an elder object + * has reference(s) to younger one(s), that referenced objects must not + * die. In order to detect additions of such references, old generations + * are protected by write barriers. It is a very difficult hack to + * appropriately insert write barriers everywhere. This mechanism is + * disabled by default for 3rd party extensions (they never get aged). By + * specifying this flag you can enable the generational feature to your + * data structure. Of course, you have to manually insert write barriers + * then. + * + * Using this flag needs deep understanding of GC internals, often at the + * level of source code. You would better leave it unspecified. + */ RUBY_TYPED_WB_PROTECTED = RUBY_FL_WB_PROTECTED, /* THIS FLAG DEPENDS ON Ruby version */ + + /** + * This flag is mysterious. It seems nobody is currently using it. The + * intention of this flag is also unclear. We need further investigations. + */ RUBY_TYPED_PROMOTED1 = RUBY_FL_PROMOTED1 /* THIS FLAG DEPENDS ON Ruby version */ }; +/** + * This is the struct that holds necessary info for a struct. It roughly + * resembles a Ruby level class; multiple objects can share a ::rb_data_type_t + * instance. + */ typedef struct rb_data_type_struct rb_data_type_t; +/** @copydoc rb_data_type_t */ struct rb_data_type_struct { + + /** + * Name of structs of this kind. This is used for diagnostic purposes. + * This has to be unique in the process, but doesn't has to be a valid + * C/Ruby identifier. + */ const char *wrap_struct_name; + + /** Function pointers. Resembles C++ `vtbl`.*/ struct { + + /** + * This function is called when the object is experiencing GC marks. + * If it contains references to other Ruby objects, you need to mark + * them also. Otherwise GC will smash your data. + * + * @see rb_gc_mark() + * @warning This is called during GC runs. Object allocations are + * impossible at that moment (that is why GC runs). + */ RUBY_DATA_FUNC dmark; + + /** + * This function is called when the object is no longer used. You need + * to do whatever necessary to avoid memory leaks. + * + * @warning This is called during GC runs. Object allocations are + * impossible at that moment (that is why GC runs). + */ RUBY_DATA_FUNC dfree; + + /** + * This function is to query the size of the underlying memory regions. + * + * @internal + * + * This function has only one usage, which is form inside of + * `ext/objspace`. + */ size_t (*dsize)(const void *); + + /** + * This function is called when the object is relocated. Like + * ::rb_data_type_struct::dmark, you need to update references to Ruby + * objects inside of your structs. + * + * @see rb_gc_location() + * @warning This is called during GC runs. Object allocations are + * impossible at that moment (that is why GC runs). + */ RUBY_DATA_FUNC dcompact; + + /** + * This field is reserved for future extension. For now, it must be + * filled with zeros. + */ void *reserved[1]; /* For future extension. This array *must* be filled with ZERO. */ } function; + + /** + * Parent of this class. Sometimes C structs have inheritance-like + * relationships. An example is `struct sockaddr` and its family. If you + * design such things, make ::rb_data_type_t for each of them and connect + * using this field. Ruby can then transparently cast your data back and + * forth when you call #TypedData_Get_Struct(). + * + * ```CXX + * struct parent { }; + * static inline const rb_data_type_t parent_type = { + * .wrap_struct_name = "parent", + (... truncated) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/