Skip to content

Commit 7567336

Browse files
committed
Implemented attributes for static and dynamic languages, make ruby attributes work properly.
1 parent c9f699d commit 7567336

File tree

11 files changed

+99
-57
lines changed

11 files changed

+99
-57
lines changed

source/loaders/java_loader/source/java_loader_impl.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -433,11 +433,11 @@ int java_object_interface_create(object obj, object_impl impl)
433433
return 0;
434434
}
435435

436-
value java_object_interface_get(object obj, object_impl impl, union accessor_type *accessor)
436+
value java_object_interface_get(object obj, object_impl impl, struct accessor_type *accessor)
437437
{
438438
(void)obj;
439439

440-
attribute attr = accessor->attr;
440+
attribute attr = accessor->data.attr;
441441
const char *key = (const char *)attribute_name(attr);
442442
type fieldType = (type)attribute_type(attr);
443443

@@ -629,11 +629,11 @@ value java_object_interface_get(object obj, object_impl impl, union accessor_typ
629629
return NULL;
630630
}
631631

632-
int java_object_interface_set(object obj, object_impl impl, union accessor_type *accessor, value v)
632+
int java_object_interface_set(object obj, object_impl impl, struct accessor_type *accessor, value v)
633633
{
634634
(void)obj;
635635

636-
attribute attr = accessor->attr;
636+
attribute attr = accessor->data.attr;
637637
const char *key = (const char *)attribute_name(attr);
638638
type fieldType = (type)attribute_type(attr);
639639

@@ -1010,11 +1010,11 @@ object java_class_interface_constructor(klass cls, class_impl impl, const char *
10101010
return obj;
10111011
}
10121012

1013-
value java_class_interface_static_get(klass cls, class_impl impl, union accessor_type *accessor)
1013+
value java_class_interface_static_get(klass cls, class_impl impl, struct accessor_type *accessor)
10141014
{
10151015
(void)cls;
10161016

1017-
attribute attr = accessor->attr;
1017+
attribute attr = accessor->data.attr;
10181018
const char *key = (const char *)attribute_name(attr);
10191019
type fieldType = (type)attribute_type(attr);
10201020
loader_impl_java_class java_cls = static_cast<loader_impl_java_class>(impl);
@@ -1263,11 +1263,11 @@ value java_class_interface_static_get(klass cls, class_impl impl, union accessor
12631263
return NULL;
12641264
}
12651265

1266-
int java_class_interface_static_set(klass cls, class_impl impl, union accessor_type *accessor, value v)
1266+
int java_class_interface_static_set(klass cls, class_impl impl, struct accessor_type *accessor, value v)
12671267
{
12681268
(void)cls;
12691269

1270-
attribute attr = accessor->attr;
1270+
attribute attr = accessor->data.attr;
12711271
const char *key = (const char *)attribute_name(attr);
12721272
type fieldType = (type)attribute_type(attr);
12731273
loader_impl_java_class java_cls = static_cast<loader_impl_java_class>(impl);

source/loaders/rb_loader/source/rb_loader_impl.c

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -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

source/reflect/include/reflect/reflect_accessor.h

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,21 @@ enum accessor_type_id
4141
ACCESSOR_TYPE_DYNAMIC = 1
4242
};
4343

44-
/*
45-
* Apart from attribute, there is constructor and method
46-
* also included for future uses
47-
*/
48-
union accessor_type
44+
struct accessor_type
4945
{
50-
const char *key;
51-
constructor ctor;
52-
attribute attr;
53-
method m;
46+
enum accessor_type_id id;
47+
48+
/*
49+
* In addition to attribute, there is constructor and method
50+
* also included for future uses
51+
*/
52+
union
53+
{
54+
const char *key;
55+
constructor ctor;
56+
attribute attr;
57+
method m;
58+
} data;
5459
};
5560

5661
#ifdef __cplusplus

source/reflect/include/reflect/reflect_class.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@ typedef int (*class_impl_interface_create)(klass, class_impl);
4747

4848
typedef object (*class_impl_interface_constructor)(klass, class_impl, const char *, constructor, class_args, size_t);
4949

50-
typedef value (*class_impl_interface_static_get)(klass, class_impl, union accessor_type *);
50+
typedef value (*class_impl_interface_static_get)(klass, class_impl, struct accessor_type *);
5151

52-
typedef int (*class_impl_interface_static_set)(klass, class_impl, union accessor_type *, value);
52+
typedef int (*class_impl_interface_static_set)(klass, class_impl, struct accessor_type *, value);
5353

5454
typedef value (*class_impl_interface_static_invoke)(klass, class_impl, method, class_args, size_t);
5555

source/reflect/include/reflect/reflect_object.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@ typedef value (*object_reject_callback)(value, void *);
4747

4848
typedef int (*object_impl_interface_create)(object, object_impl);
4949

50-
typedef value (*object_impl_interface_get)(object, object_impl, union accessor_type *);
50+
typedef value (*object_impl_interface_get)(object, object_impl, struct accessor_type *);
5151

52-
typedef int (*object_impl_interface_set)(object, object_impl, union accessor_type *, value);
52+
typedef int (*object_impl_interface_set)(object, object_impl, struct accessor_type *, value);
5353

5454
typedef value (*object_impl_interface_method_invoke)(object, object_impl, method, object_args, size_t);
5555

source/reflect/source/reflect_class.c

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,7 @@ value class_static_get(klass cls, const char *key)
496496
{
497497
if (cls != NULL && cls->interface != NULL && cls->interface->static_get != NULL && key != NULL)
498498
{
499-
union accessor_type accessor;
499+
struct accessor_type accessor;
500500
attribute attr = set_get(cls->static_attributes, (set_key)key);
501501

502502
if (attr == NULL)
@@ -509,13 +509,16 @@ value class_static_get(klass cls, const char *key)
509509
}
510510

511511
case ACCESSOR_TYPE_DYNAMIC: {
512-
accessor.key = key;
512+
accessor.data.key = key;
513513
}
514514
}
515+
516+
accessor.id = ACCESSOR_TYPE_DYNAMIC;
515517
}
516518
else
517519
{
518-
accessor.attr = attr;
520+
accessor.data.attr = attr;
521+
accessor.id = ACCESSOR_TYPE_STATIC;
519522
}
520523

521524
value v = cls->interface->static_get(cls, cls->impl, &accessor);
@@ -535,7 +538,7 @@ int class_static_set(klass cls, const char *key, value v)
535538
{
536539
if (cls != NULL && cls->interface != NULL && cls->interface->static_set != NULL && key != NULL && v != NULL)
537540
{
538-
union accessor_type accessor;
541+
struct accessor_type accessor;
539542
attribute attr = set_get(cls->static_attributes, (set_key)key);
540543

541544
if (attr == NULL)
@@ -548,13 +551,16 @@ int class_static_set(klass cls, const char *key, value v)
548551
}
549552

550553
case ACCESSOR_TYPE_DYNAMIC: {
551-
accessor.key = key;
554+
accessor.data.key = key;
552555
}
553556
}
557+
558+
accessor.id = ACCESSOR_TYPE_DYNAMIC;
554559
}
555560
else
556561
{
557-
accessor.attr = attr;
562+
accessor.data.attr = attr;
563+
accessor.id = ACCESSOR_TYPE_STATIC;
558564
}
559565

560566
if (cls->interface->static_set(cls, cls->impl, &accessor, v) != 0)
@@ -642,9 +648,6 @@ vector class_methods(klass cls, const char *key)
642648
return NULL;
643649
}
644650

645-
/// TODO: DELETE
646-
log_write("metacall", LOG_LEVEL_DEBUG, "The class %s.%s has %" PRIuS " methods: %p", cls->name, key, map_size(cls->methods), map_get(cls->methods, (map_key)key));
647-
648651
return map_get(cls->methods, (map_key)key);
649652
}
650653

source/reflect/source/reflect_object.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ value object_get(object obj, const char *key)
248248
{
249249
if (obj != NULL && obj->interface != NULL && obj->interface->get != NULL)
250250
{
251-
union accessor_type accessor;
251+
struct accessor_type accessor;
252252
attribute attr = class_attribute(obj->cls, key);
253253

254254
if (attr == NULL)
@@ -261,13 +261,16 @@ value object_get(object obj, const char *key)
261261
}
262262

263263
case ACCESSOR_TYPE_DYNAMIC: {
264-
accessor.key = key;
264+
accessor.data.key = key;
265265
}
266266
}
267+
268+
accessor.id = ACCESSOR_TYPE_DYNAMIC;
267269
}
268270
else
269271
{
270-
accessor.attr = attr;
272+
accessor.data.attr = attr;
273+
accessor.id = ACCESSOR_TYPE_STATIC;
271274
}
272275

273276
value v = obj->interface->get(obj, obj->impl, &accessor);
@@ -287,7 +290,7 @@ int object_set(object obj, const char *key, value v)
287290
{
288291
if (obj != NULL && obj->interface != NULL && obj->interface->set != NULL)
289292
{
290-
union accessor_type accessor;
293+
struct accessor_type accessor;
291294
attribute attr = class_attribute(obj->cls, key);
292295

293296
if (attr == NULL)
@@ -300,13 +303,16 @@ int object_set(object obj, const char *key, value v)
300303
}
301304

302305
case ACCESSOR_TYPE_DYNAMIC: {
303-
accessor.key = key;
306+
accessor.data.key = key;
304307
}
305308
}
309+
310+
accessor.id = ACCESSOR_TYPE_DYNAMIC;
306311
}
307312
else
308313
{
309-
accessor.attr = attr;
314+
accessor.data.attr = attr;
315+
accessor.id = ACCESSOR_TYPE_STATIC;
310316
}
311317

312318
if (obj->interface->set(obj, obj->impl, &accessor, v) != 0)

source/reflect/source/reflect_signature.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ value signature_metadata_args_map_name(const char *name)
365365
return NULL;
366366
}
367367

368-
v_array[1] = value_create_string(name, strlen(name));
368+
v_array[1] = name ? value_create_string(name, strlen(name)) : value_create_string("", 0);
369369

370370
if (v_array[1] == NULL)
371371
{

source/scripts/ruby/klass/source/klass.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
class MyClass
44

55
@@class_hierarchy_var = 555
6+
@yeet = 3
67

78
def initialize(param1, param2)
89
# Instance variables

source/tests/metacall_ruby_object_class_test/source/metacall_ruby_object_class_test.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,6 @@ TEST_F(metacall_ruby_object_class_test, DefaultConstructor)
130130
}
131131
#endif /* OPTION_BUILD_LOADERS_RB */
132132

133-
#if 0 /* TODO: Delete this for showing a heap after free error */
134133
/* Print inspect information */
135134
{
136135
size_t size = 0;
@@ -151,7 +150,6 @@ TEST_F(metacall_ruby_object_class_test, DefaultConstructor)
151150

152151
metacall_allocator_destroy(allocator);
153152
}
154-
#endif
155153

156154
EXPECT_EQ((int)0, (int)metacall_destroy());
157155
}

0 commit comments

Comments
 (0)