summaryrefslogtreecommitdiff
path: root/shape.c
diff options
context:
space:
mode:
authorJean Boussier <jean.boussier@gmail.com>2025-06-11 14:32:35 +0200
committerJean Boussier <jean.boussier@gmail.com>2025-06-11 16:38:38 +0200
commit95201299fd7bf0918dfbd8c127ce2b5b33ffa537 (patch)
treeb6659cd0932fa3f0cb71c8cf8c2aba382d86cf6b /shape.c
parent4463ac264dc44979ea74bbca3de58ae72d5eea71 (diff)
Refactor the last references to `rb_shape_t`
The type isn't opaque because Ruby isn't often compiled with LTO, so for optimization purpose it's better to allow as much inlining as possible. However ideally only `shape.c` and `shape.h` should deal with the actual struct, and everything else should just deal with opaque `shape_id_t`.
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/13586
Diffstat (limited to 'shape.c')
-rw-r--r--shape.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/shape.c b/shape.c
index 20cbaf54a4..021ecb1a9e 100644
--- a/shape.c
+++ b/shape.c
@@ -1184,6 +1184,31 @@ rb_shape_memsize(shape_id_t shape_id)
return memsize;
}
+bool
+rb_shape_foreach_field(shape_id_t initial_shape_id, rb_shape_foreach_transition_callback func, void *data)
+{
+ RUBY_ASSERT(!rb_shape_too_complex_p(initial_shape_id));
+
+ rb_shape_t *shape = RSHAPE(initial_shape_id);
+ if (shape->type == SHAPE_ROOT) {
+ return true;
+ }
+
+ shape_id_t parent_id = shape_id(RSHAPE(shape->parent_id), initial_shape_id);
+ if (rb_shape_foreach_field(parent_id, func, data)) {
+ switch (func(shape_id(shape, initial_shape_id), data)) {
+ case ST_STOP:
+ return false;
+ case ST_CHECK:
+ case ST_CONTINUE:
+ break;
+ default:
+ rb_bug("unreachable");
+ }
+ }
+ return true;
+}
+
#if RUBY_DEBUG
bool
rb_shape_verify_consistency(VALUE obj, shape_id_t shape_id)