Clean up Ruby Shape API
Make printing shapes better, use a struct instead of specific methods for each field on a shape. Co-Authored-By: Aaron Patterson <tenderlove@ruby-lang.org>
This commit is contained in:
parent
2ccf6e5394
commit
297df92407
Notes:
git
2022-12-16 18:28:13 +00:00
129
shape.c
129
shape.c
@ -551,56 +551,15 @@ rb_shape_memsize(rb_shape_t *shape)
|
||||
}
|
||||
|
||||
#if SHAPE_DEBUG
|
||||
VALUE rb_cShape;
|
||||
|
||||
static size_t
|
||||
shape_memsize(const void *shape_ptr)
|
||||
{
|
||||
return rb_shape_memsize((rb_shape_t *)shape_ptr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Exposing Shape to Ruby via RubyVM.debug_shape
|
||||
*/
|
||||
static const rb_data_type_t shape_data_type = {
|
||||
.wrap_struct_name = "Shape",
|
||||
.function = {
|
||||
.dmark = NULL,
|
||||
.dfree = NULL,
|
||||
.dsize = shape_memsize,
|
||||
},
|
||||
.flags = RUBY_TYPED_FREE_IMMEDIATELY|RUBY_TYPED_WB_PROTECTED
|
||||
};
|
||||
|
||||
static VALUE
|
||||
rb_wrapped_shape_id(VALUE self)
|
||||
{
|
||||
rb_shape_t * shape;
|
||||
TypedData_Get_Struct(self, rb_shape_t, &shape_data_type, shape);
|
||||
return INT2NUM(rb_shape_id(shape));
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_shape_type(VALUE self)
|
||||
{
|
||||
rb_shape_t * shape;
|
||||
TypedData_Get_Struct(self, rb_shape_t, &shape_data_type, shape);
|
||||
return INT2NUM(shape->type);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_shape_capacity(VALUE self)
|
||||
{
|
||||
rb_shape_t * shape;
|
||||
TypedData_Get_Struct(self, rb_shape_t, &shape_data_type, shape);
|
||||
return INT2NUM(shape->capacity);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_shape_too_complex(VALUE self)
|
||||
{
|
||||
rb_shape_t * shape;
|
||||
TypedData_Get_Struct(self, rb_shape_t, &shape_data_type, shape);
|
||||
shape = rb_shape_get_shape_by_id(NUM2INT(rb_struct_getmember(self, rb_intern("id"))));
|
||||
if (rb_shape_id(shape) == OBJ_TOO_COMPLEX_SHAPE_ID) {
|
||||
return Qtrue;
|
||||
}
|
||||
@ -609,19 +568,6 @@ rb_shape_too_complex(VALUE self)
|
||||
}
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_shape_parent_id(VALUE self)
|
||||
{
|
||||
rb_shape_t * shape;
|
||||
TypedData_Get_Struct(self, rb_shape_t, &shape_data_type, shape);
|
||||
if (shape->parent_id != INVALID_SHAPE_ID) {
|
||||
return INT2NUM(shape->parent_id);
|
||||
}
|
||||
else {
|
||||
return Qnil;
|
||||
}
|
||||
}
|
||||
|
||||
static VALUE
|
||||
parse_key(ID key)
|
||||
{
|
||||
@ -631,15 +577,23 @@ parse_key(ID key)
|
||||
return LONG2NUM(key);
|
||||
}
|
||||
|
||||
static VALUE rb_shape_edge_name(rb_shape_t * shape);
|
||||
|
||||
static VALUE
|
||||
rb_shape_t_to_rb_cShape(rb_shape_t *shape)
|
||||
{
|
||||
union { const rb_shape_t *in; void *out; } deconst;
|
||||
VALUE res;
|
||||
deconst.in = shape;
|
||||
res = TypedData_Wrap_Struct(rb_cShape, &shape_data_type, deconst.out);
|
||||
VALUE rb_cShape = rb_const_get(rb_cRubyVM, rb_intern("Shape"));
|
||||
|
||||
return res;
|
||||
VALUE obj = rb_struct_new(rb_cShape,
|
||||
INT2NUM(rb_shape_id(shape)),
|
||||
INT2NUM(shape->parent_id),
|
||||
rb_shape_edge_name(shape),
|
||||
INT2NUM(shape->next_iv_index),
|
||||
INT2NUM(shape->size_pool_index),
|
||||
INT2NUM(shape->type),
|
||||
INT2NUM(shape->capacity));
|
||||
rb_obj_freeze(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
static enum rb_id_table_iterator_result
|
||||
@ -653,7 +607,8 @@ static VALUE
|
||||
rb_shape_edges(VALUE self)
|
||||
{
|
||||
rb_shape_t* shape;
|
||||
TypedData_Get_Struct(self, rb_shape_t, &shape_data_type, shape);
|
||||
|
||||
shape = rb_shape_get_shape_by_id(NUM2INT(rb_struct_getmember(self, rb_intern("id"))));
|
||||
|
||||
VALUE hash = rb_hash_new();
|
||||
|
||||
@ -665,11 +620,8 @@ rb_shape_edges(VALUE self)
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_shape_edge_name(VALUE self)
|
||||
rb_shape_edge_name(rb_shape_t * shape)
|
||||
{
|
||||
rb_shape_t* shape;
|
||||
TypedData_Get_Struct(self, rb_shape_t, &shape_data_type, shape);
|
||||
|
||||
if (shape->edge_name) {
|
||||
if (is_instance_id(shape->edge_name)) {
|
||||
return ID2SYM(shape->edge_name);
|
||||
@ -679,29 +631,11 @@ rb_shape_edge_name(VALUE self)
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_shape_next_iv_index(VALUE self)
|
||||
{
|
||||
rb_shape_t* shape;
|
||||
TypedData_Get_Struct(self, rb_shape_t, &shape_data_type, shape);
|
||||
|
||||
return INT2NUM(shape->next_iv_index);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_shape_size_pool_index(VALUE self)
|
||||
{
|
||||
rb_shape_t * shape;
|
||||
TypedData_Get_Struct(self, rb_shape_t, &shape_data_type, shape);
|
||||
|
||||
return INT2NUM(shape->size_pool_index);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_shape_export_depth(VALUE self)
|
||||
{
|
||||
rb_shape_t* shape;
|
||||
TypedData_Get_Struct(self, rb_shape_t, &shape_data_type, shape);
|
||||
shape = rb_shape_get_shape_by_id(NUM2INT(rb_struct_getmember(self, rb_intern("id"))));
|
||||
return SIZET2NUM(rb_shape_depth(shape));
|
||||
}
|
||||
|
||||
@ -709,7 +643,7 @@ static VALUE
|
||||
rb_shape_parent(VALUE self)
|
||||
{
|
||||
rb_shape_t * shape;
|
||||
TypedData_Get_Struct(self, rb_shape_t, &shape_data_type, shape);
|
||||
shape = rb_shape_get_shape_by_id(NUM2INT(rb_struct_getmember(self, rb_intern("id"))));
|
||||
if (shape->parent_id != INVALID_SHAPE_ID) {
|
||||
return rb_shape_t_to_rb_cShape(rb_shape_get_parent(shape));
|
||||
}
|
||||
@ -771,12 +705,6 @@ shape_transition_tree(VALUE self)
|
||||
return rb_obj_shape(rb_shape_get_root_shape());
|
||||
}
|
||||
|
||||
static VALUE
|
||||
next_shape_id(VALUE self)
|
||||
{
|
||||
return INT2NUM(GET_VM()->next_shape_id);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_shape_find_by_id(VALUE mod, VALUE id)
|
||||
{
|
||||
@ -847,19 +775,19 @@ void
|
||||
Init_shape(void)
|
||||
{
|
||||
#if SHAPE_DEBUG
|
||||
rb_cShape = rb_define_class_under(rb_cRubyVM, "Shape", rb_cObject);
|
||||
rb_undef_alloc_func(rb_cShape);
|
||||
VALUE rb_cShape = rb_struct_define_under(rb_cRubyVM, "Shape",
|
||||
"id",
|
||||
"parent_id",
|
||||
"edge_name",
|
||||
"next_iv_index",
|
||||
"size_pool_index",
|
||||
"type",
|
||||
"capacity",
|
||||
NULL);
|
||||
|
||||
rb_define_method(rb_cShape, "parent_id", rb_shape_parent_id, 0);
|
||||
rb_define_method(rb_cShape, "parent", rb_shape_parent, 0);
|
||||
rb_define_method(rb_cShape, "edges", rb_shape_edges, 0);
|
||||
rb_define_method(rb_cShape, "edge_name", rb_shape_edge_name, 0);
|
||||
rb_define_method(rb_cShape, "next_iv_index", rb_shape_next_iv_index, 0);
|
||||
rb_define_method(rb_cShape, "size_pool_index", rb_shape_size_pool_index, 0);
|
||||
rb_define_method(rb_cShape, "depth", rb_shape_export_depth, 0);
|
||||
rb_define_method(rb_cShape, "id", rb_wrapped_shape_id, 0);
|
||||
rb_define_method(rb_cShape, "type", rb_shape_type, 0);
|
||||
rb_define_method(rb_cShape, "capacity", rb_shape_capacity, 0);
|
||||
rb_define_method(rb_cShape, "too_complex?", rb_shape_too_complex, 0);
|
||||
rb_define_const(rb_cShape, "SHAPE_ROOT", INT2NUM(SHAPE_ROOT));
|
||||
rb_define_const(rb_cShape, "SHAPE_IVAR", INT2NUM(SHAPE_IVAR));
|
||||
@ -873,7 +801,6 @@ Init_shape(void)
|
||||
|
||||
rb_define_singleton_method(rb_cShape, "transition_tree", shape_transition_tree, 0);
|
||||
rb_define_singleton_method(rb_cShape, "find_by_id", rb_shape_find_by_id, 1);
|
||||
rb_define_singleton_method(rb_cShape, "next_shape_id", next_shape_id, 0);
|
||||
rb_define_singleton_method(rb_cShape, "of", rb_shape_debug_shape, 1);
|
||||
rb_define_singleton_method(rb_cShape, "root_shape", rb_shape_root_shape, 0);
|
||||
#endif
|
||||
|
@ -391,7 +391,7 @@ class TestShapes < Test::Unit::TestCase
|
||||
|
||||
def test_out_of_bounds_shape
|
||||
assert_raise ArgumentError do
|
||||
RubyVM::Shape.find_by_id(RubyVM::Shape.next_shape_id)
|
||||
RubyVM::Shape.find_by_id(RubyVM.stat[:next_shape_id])
|
||||
end
|
||||
assert_raise ArgumentError do
|
||||
RubyVM::Shape.find_by_id(-1)
|
||||
|
Loading…
x
Reference in New Issue
Block a user