@@ -466,11 +466,11 @@ int rb_object_interface_create(object obj, object_impl impl)
466466 return 0 ;
467467}
468468
469- value rb_object_interface_get (object obj , object_impl impl , union accessor_type * accessor )
469+ value rb_object_interface_get (object obj , object_impl impl , struct accessor_type * accessor )
470470{
471471 loader_impl_rb_object rb_object = (loader_impl_rb_object )impl ;
472472 VALUE rb_val_object = rb_object -> object ;
473- const char * key = accessor -> key ;
473+ const char * key = accessor -> id == ACCESSOR_TYPE_DYNAMIC ? accessor -> data . key : attribute_name ( accessor -> data . attr ) ;
474474 VALUE got = rb_iv_get (rb_val_object , key );
475475 VALUE exception = rb_errinfo ();
476476
@@ -491,11 +491,11 @@ value rb_object_interface_get(object obj, object_impl impl, union accessor_type
491491 return result ;
492492}
493493
494- int rb_object_interface_set (object obj , object_impl impl , union accessor_type * accessor , value v )
494+ int rb_object_interface_set (object obj , object_impl impl , struct accessor_type * accessor , value v )
495495{
496496 loader_impl_rb_object rb_object = (loader_impl_rb_object )impl ;
497497 VALUE rb_val_object = rb_object -> object ;
498- const char * key = accessor -> key ;
498+ const char * key = accessor -> id == ACCESSOR_TYPE_DYNAMIC ? accessor -> data . key : attribute_name ( accessor -> data . attr ) ;
499499 rb_iv_set (rb_val_object , key , rb_type_serialize (v ));
500500 VALUE exception = rb_errinfo ();
501501
@@ -637,10 +637,10 @@ object rb_class_interface_constructor(klass cls, class_impl impl, const char *na
637637 return obj ;
638638}
639639
640- value rb_class_interface_static_get (klass cls , class_impl impl , union accessor_type * accessor )
640+ value rb_class_interface_static_get (klass cls , class_impl impl , struct accessor_type * accessor )
641641{
642642 loader_impl_rb_class rb_class = (loader_impl_rb_class )impl ;
643- const char * attr_name = accessor -> key ;
643+ const char * attr_name = accessor -> id == ACCESSOR_TYPE_DYNAMIC ? accessor -> data . key : attribute_name ( accessor -> data . attr ) ;
644644 VALUE rb_val_class = rb_class -> class ;
645645 VALUE got = rb_cv_get (rb_val_class , attr_name );
646646 VALUE exception = rb_errinfo ();
@@ -662,10 +662,10 @@ value rb_class_interface_static_get(klass cls, class_impl impl, union accessor_t
662662 return result ;
663663}
664664
665- int rb_class_interface_static_set (klass cls , class_impl impl , union accessor_type * accessor , value v )
665+ int rb_class_interface_static_set (klass cls , class_impl impl , struct accessor_type * accessor , value v )
666666{
667667 loader_impl_rb_class rb_class = (loader_impl_rb_class )impl ;
668- const char * attr_name = accessor -> key ;
668+ const char * attr_name = accessor -> id == ACCESSOR_TYPE_DYNAMIC ? accessor -> data . key : attribute_name ( accessor -> data . attr ) ;
669669 VALUE rb_val_class = rb_class -> class ;
670670
671671 (void )cls ;
@@ -1398,7 +1398,29 @@ void rb_loader_impl_discover_methods(klass c, VALUE cls, const char *class_name_
13981398
13991399 if (register_method (c , m ) != 0 )
14001400 {
1401- log_write ("metacall" , LOG_LEVEL_ERROR , "Ruby failed to register method '%s'" , method_name_str );
1401+ log_write ("metacall" , LOG_LEVEL_ERROR , "Ruby failed to register method '%s' in class '%s'" , method_name_str , class_name_str );
1402+ }
1403+ }
1404+ }
1405+
1406+ void rb_loader_impl_discover_attributes (klass c , const char * class_name_str , VALUE attributes , int (* register_attr )(klass , attribute ))
1407+ {
1408+ size_t attributes_index , attributes_size = RARRAY_LEN (attributes );
1409+
1410+ for (attributes_index = 0 ; attributes_index < attributes_size ; ++ attributes_index )
1411+ {
1412+ VALUE rb_attr = rb_ary_entry (attributes , attributes_index );
1413+ VALUE name = rb_funcall (rb_attr , rb_intern ("id2name" ), 0 );
1414+ const char * attr_name_str = RSTRING_PTR (name );
1415+
1416+ log_write ("metacall" , LOG_LEVEL_DEBUG , "Attribute '%s' inside '%s'" , attr_name_str , class_name_str );
1417+
1418+ /* TODO: Visibility? */
1419+ attribute attr = attribute_create (c , attr_name_str , NULL , (attribute_impl )rb_attr , VISIBILITY_PUBLIC , NULL );
1420+
1421+ if (register_attr (c , attr ) != 0 )
1422+ {
1423+ log_write ("metacall" , LOG_LEVEL_ERROR , "Ruby failed to register attribute '%s' in class '%s'" , attr_name_str , class_name_str );
14021424 }
14031425 }
14041426}
@@ -1485,6 +1507,7 @@ int rb_loader_impl_discover_module(loader_impl impl, loader_impl_rb_module rb_mo
14851507 rb_cls -> class = cls ;
14861508 rb_cls -> impl = impl ;
14871509
1510+ /* Discover methods */
14881511 VALUE argv [1 ] = { Qtrue }; /* include_superclasses ? Qtrue : Qfalse; */
14891512 VALUE methods = rb_class_public_instance_methods (1 , argv , cls ); /* argc, argv, cls */
14901513 rb_loader_impl_discover_methods (c , cls , class_name_str , VISIBILITY_PUBLIC , "instance_method" , methods , & class_register_method );
@@ -1508,7 +1531,13 @@ int rb_loader_impl_discover_module(loader_impl impl, loader_impl_rb_module rb_mo
15081531 methods = rb_obj_singleton_methods (1 , argv , cls );
15091532 rb_loader_impl_discover_methods (c , cls , class_name_str , VISIBILITY_PUBLIC , "singleton_method" , methods , & class_register_static_method );
15101533#endif
1511- /* TODO: Implement attributes */
1534+
1535+ /* Discover attributes */
1536+ VALUE static_attributes = rb_mod_class_variables (1 , argv , cls );
1537+ rb_loader_impl_discover_attributes (c , class_name_str , static_attributes , & class_register_static_attribute );
1538+
1539+ VALUE instance_attributes = rb_obj_instance_variables (cls );
1540+ rb_loader_impl_discover_attributes (c , class_name_str , instance_attributes , & class_register_attribute );
15121541
15131542 /* Define default constructor. Ruby only supports one constructor, a
15141543 * method called 'initialize'. It can have arguments but when inspected via
0 commit comments