Skip to content

Commit fe20a4f

Browse files
committed
Duplicated symbols working properly (except repeated symbols in global scope between loaders, it will call to the first in the set, this is a TODO).
1 parent af86097 commit fe20a4f

File tree

2 files changed

+124
-71
lines changed

2 files changed

+124
-71
lines changed

source/loader/source/loader_impl.c

Lines changed: 68 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ struct loader_handle_impl_type
6868
loader_naming_name name;
6969
loader_handle module;
7070
context ctx;
71+
int populated;
7172
};
7273

7374
struct loader_impl_metadata_cb_iterator_type
@@ -90,6 +91,10 @@ static int loader_impl_create_singleton(loader_impl impl, const char *path, cons
9091

9192
static loader_handle_impl loader_impl_load_handle(loader_impl impl, loader_handle module, const loader_naming_name name);
9293

94+
static int loader_impl_handle_init(loader_impl impl, char * name, loader_handle_impl handle_impl, void **handle_ptr, int populated);
95+
96+
static int loader_impl_handle_register(loader_impl impl, char * name, loader_handle_impl handle_impl, void **handle_ptr);
97+
9398
static int loader_impl_function_hook_call(context ctx, const char func_name[]);
9499

95100
static value loader_impl_metadata_handle_name(loader_handle_impl handle_impl);
@@ -100,7 +105,7 @@ static value loader_impl_metadata_handle(loader_handle_impl handle_impl);
100105

101106
static int loader_impl_metadata_cb_iterate(set s, set_key key, set_value val, set_cb_iterate_args args);
102107

103-
static void loader_impl_destroy_handle(loader_handle_impl handle_impl, int unlink);
108+
static void loader_impl_destroy_handle(loader_handle_impl handle_impl);
104109

105110
static int loader_impl_destroy_type_map_cb_iterate(set s, set_key key, set_value val, set_cb_iterate_args args);
106111

@@ -472,7 +477,7 @@ loader_handle_impl loader_impl_load_handle(loader_impl impl, loader_handle modul
472477
return NULL;
473478
}
474479

475-
void loader_impl_destroy_handle(loader_handle_impl handle_impl, int unlink)
480+
void loader_impl_destroy_handle(loader_handle_impl handle_impl)
476481
{
477482
if (handle_impl != NULL)
478483
{
@@ -493,7 +498,7 @@ void loader_impl_destroy_handle(loader_handle_impl handle_impl, int unlink)
493498
}
494499
}
495500

496-
if (unlink == 0)
501+
if (handle_impl->populated == 0)
497502
{
498503
context_remove(handle_impl->impl->ctx, handle_impl->ctx);
499504
}
@@ -581,6 +586,49 @@ int loader_impl_function_hook_call(context ctx, const char func_name[])
581586
return 0;
582587
}
583588

589+
int loader_impl_handle_init(loader_impl impl, char * name, loader_handle_impl handle_impl, void **handle_ptr, int populated)
590+
{
591+
static const char func_init_name[] = LOADER_IMPL_FUNCTION_INIT;
592+
593+
int result = loader_impl_function_hook_call(impl->ctx, func_init_name);
594+
595+
handle_impl->populated = populated;
596+
597+
if (result != 0)
598+
{
599+
log_write("metacall", LOG_LEVEL_ERROR, "Error when calling to init hook function (" LOADER_IMPL_FUNCTION_INIT ") of handle: %s", name);
600+
}
601+
602+
if (handle_ptr != NULL)
603+
{
604+
*handle_ptr = handle_impl;
605+
}
606+
607+
return result;
608+
}
609+
610+
int loader_impl_handle_register(loader_impl impl, char * name, loader_handle_impl handle_impl, void **handle_ptr)
611+
{
612+
if (handle_ptr == NULL)
613+
{
614+
if (context_contains(impl->ctx, handle_impl->ctx) == 0)
615+
{
616+
/* TODO: This still does not protect duplicated names between different loaders global scope */
617+
log_write("metacall", LOG_LEVEL_ERROR, "There are duplicated symbols already loaded in the global scope conflicting with handle: %s", name);
618+
}
619+
else if (context_append(impl->ctx, handle_impl->ctx) == 0)
620+
{
621+
return loader_impl_handle_init(impl, name, handle_impl, handle_ptr, 0);
622+
}
623+
}
624+
else
625+
{
626+
return loader_impl_handle_init(impl, name, handle_impl, handle_ptr, 1);
627+
}
628+
629+
return 1;
630+
}
631+
584632
int loader_impl_load_from_file(loader_impl impl, const loader_naming_path paths[], size_t size, void **handle_ptr)
585633
{
586634
if (impl != NULL)
@@ -625,32 +673,15 @@ int loader_impl_load_from_file(loader_impl impl, const loader_naming_path paths[
625673

626674
if (handle_impl != NULL)
627675
{
676+
handle_impl->populated = 1;
677+
628678
if (set_insert(impl->handle_impl_map, handle_impl->name, handle_impl) == 0)
629679
{
630680
if (interface_impl->discover(impl, handle_impl->module, handle_impl->ctx) == 0)
631681
{
632-
if (context_contains(impl->ctx, handle_impl->ctx) == 0)
633-
{
634-
/* TODO: This still does not protect duplicated names between different loaders global scope */
635-
log_write("metacall", LOG_LEVEL_ERROR, "There are duplicated symbols already loaded in the global scope conflicting with handle: %s", module_name);
636-
}
637-
else if (context_append(impl->ctx, handle_impl->ctx) == 0)
682+
if (loader_impl_handle_register(impl, module_name, handle_impl, handle_ptr) == 0)
638683
{
639-
static const char func_init_name[] = LOADER_IMPL_FUNCTION_INIT;
640-
641-
int result = loader_impl_function_hook_call(impl->ctx, func_init_name);
642-
643-
if (result != 0)
644-
{
645-
log_write("metacall", LOG_LEVEL_ERROR, "Error when calling to init hook function (" LOADER_IMPL_FUNCTION_INIT ") of handle: %s", module_name);
646-
}
647-
648-
if (handle_ptr != NULL)
649-
{
650-
*handle_ptr = handle_impl;
651-
}
652-
653-
return result;
684+
return 0;
654685
}
655686
}
656687

@@ -659,7 +690,7 @@ int loader_impl_load_from_file(loader_impl impl, const loader_naming_path paths[
659690

660691
log_write("metacall", LOG_LEVEL_ERROR, "Error when loading handle: %s", module_name);
661692

662-
loader_impl_destroy_handle(handle_impl, 1);
693+
loader_impl_destroy_handle(handle_impl);
663694
}
664695
}
665696
}
@@ -733,32 +764,15 @@ int loader_impl_load_from_memory(loader_impl impl, const char *buffer, size_t si
733764

734765
if (handle_impl != NULL)
735766
{
767+
handle_impl->populated = 1;
768+
736769
if (set_insert(impl->handle_impl_map, handle_impl->name, handle_impl) == 0)
737770
{
738771
if (interface_impl->discover(impl, handle_impl->module, handle_impl->ctx) == 0)
739772
{
740-
if (context_contains(impl->ctx, handle_impl->ctx) == 0)
741-
{
742-
/* TODO: This still does not protect duplicated names between different loaders global scope */
743-
log_write("metacall", LOG_LEVEL_ERROR, "There are duplicated symbols already loaded in the global scope conflicting with handle: %s", name);
744-
}
745-
else if (context_append(impl->ctx, handle_impl->ctx) == 0)
773+
if (loader_impl_handle_register(impl, name, handle_impl, handle_ptr) == 0)
746774
{
747-
static const char func_init_name[] = LOADER_IMPL_FUNCTION_INIT;
748-
749-
int result = loader_impl_function_hook_call(impl->ctx, func_init_name);
750-
751-
if (result != 0)
752-
{
753-
log_write("metacall", LOG_LEVEL_ERROR, "Error when calling to init hook function (" LOADER_IMPL_FUNCTION_INIT ") of handle: %s", name);
754-
}
755-
756-
if (handle_ptr != NULL)
757-
{
758-
*handle_ptr = handle_impl;
759-
}
760-
761-
return result;
775+
return 0;
762776
}
763777
}
764778

@@ -767,7 +781,7 @@ int loader_impl_load_from_memory(loader_impl impl, const char *buffer, size_t si
767781

768782
log_write("metacall", LOG_LEVEL_ERROR, "Error when loading handle: %s", name);
769783

770-
loader_impl_destroy_handle(handle_impl, 1);
784+
loader_impl_destroy_handle(handle_impl);
771785
}
772786
}
773787
}
@@ -810,32 +824,15 @@ int loader_impl_load_from_package(loader_impl impl, const loader_naming_path pat
810824

811825
if (handle_impl != NULL)
812826
{
827+
handle_impl->populated = 1;
828+
813829
if (set_insert(impl->handle_impl_map, handle_impl->name, handle_impl) == 0)
814830
{
815831
if (interface_impl->discover(impl, handle_impl->module, handle_impl->ctx) == 0)
816832
{
817-
if (context_contains(impl->ctx, handle_impl->ctx) == 0)
833+
if (loader_impl_handle_register(impl, package_name, handle_impl, handle_ptr) == 0)
818834
{
819-
/* TODO: This still does not protect duplicated names between different loaders global scope */
820-
log_write("metacall", LOG_LEVEL_ERROR, "There are duplicated symbols already loaded in the global scope conflicting with handle: %s", package_name);
821-
}
822-
else if (context_append(impl->ctx, handle_impl->ctx) == 0)
823-
{
824-
static const char func_init_name[] = LOADER_IMPL_FUNCTION_INIT;
825-
826-
int result = loader_impl_function_hook_call(impl->ctx, func_init_name);
827-
828-
if (result != 0)
829-
{
830-
log_write("metacall", LOG_LEVEL_ERROR, "Error when calling to init hook function (" LOADER_IMPL_FUNCTION_INIT ") of handle: %s", package_name);
831-
}
832-
833-
if (handle_ptr != NULL)
834-
{
835-
*handle_ptr = handle_impl;
836-
}
837-
838-
return result;
835+
return 0;
839836
}
840837
}
841838

@@ -844,7 +841,7 @@ int loader_impl_load_from_package(loader_impl impl, const loader_naming_path pat
844841

845842
log_write("metacall", LOG_LEVEL_ERROR, "Error when loading handle: %s", (void *)package_name);
846843

847-
loader_impl_destroy_handle(handle_impl, 1);
844+
loader_impl_destroy_handle(handle_impl);
848845
}
849846
}
850847
}
@@ -1048,7 +1045,7 @@ int loader_impl_clear(void *handle)
10481045

10491046
int result = !(set_remove(impl->handle_impl_map, (set_key)(handle_impl->name)) == handle_impl);
10501047

1051-
loader_impl_destroy_handle(handle_impl, 0);
1048+
loader_impl_destroy_handle(handle_impl);
10521049

10531050
return result;
10541051
}
@@ -1084,7 +1081,7 @@ int loader_impl_destroy_handle_map_cb_iterate(set s, set_key key, set_value val,
10841081
{
10851082
loader_handle_impl handle_impl = val;
10861083

1087-
loader_impl_destroy_handle(handle_impl, 0);
1084+
loader_impl_destroy_handle(handle_impl);
10881085

10891086
return 0;
10901087
}

source/tests/metacall_duplicated_symbols_test/source/metacall_duplicated_symbols_test.cpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,62 @@ TEST_F(metacall_duplicated_symbols_test, DefaultConstructor)
7373
EXPECT_EQ((int)0, (int)metacall_load_from_file("rb", rb_ducktype_scripts, sizeof(rb_ducktype_scripts) / sizeof(rb_ducktype_scripts[0]), NULL));
7474

7575
EXPECT_EQ((int)1, (int)metacall_load_from_file("rb", rb_second_scripts, sizeof(rb_second_scripts) / sizeof(rb_second_scripts[0]), NULL));
76+
77+
void *handleA = NULL;
78+
79+
static const char bufferA[] =
80+
"def get_second(first, second)\n"
81+
" puts('Second value is', second)\n"
82+
" return 4\n"
83+
"end\n";
84+
85+
void *handleB = NULL;
86+
87+
static const char bufferB[] =
88+
"def get_second(first, second)\n"
89+
" puts('Second value is', second)\n"
90+
" return 6\n"
91+
"end\n";
92+
93+
const enum metacall_value_id say_multiply_int_ids[] = {
94+
METACALL_INT, METACALL_INT
95+
};
96+
97+
/* Test global scope get_second which belongs to ducktype.rb */
98+
99+
void *ret = metacallt("get_second", say_multiply_int_ids, 5, 7);
100+
101+
EXPECT_EQ((int)7, (int)metacall_value_to_int(ret));
102+
103+
metacall_value_destroy(ret);
104+
105+
EXPECT_EQ((int)0, (int)metacall_load_from_memory("rb", bufferA, sizeof(bufferA), &handleA));
106+
107+
EXPECT_EQ((int)0, (int)metacall_load_from_memory("rb", bufferB, sizeof(bufferB), &handleB));
108+
109+
void *args[2] = {
110+
metacall_value_create_int(234),
111+
metacall_value_create_int(432)
112+
};
113+
114+
/* Test handleA get_second which belongs to bufferA */
115+
116+
ret = metacallhv_s(handleA, "get_second", args, 2);
117+
118+
EXPECT_EQ((int)4, (int)metacall_value_to_int(ret));
119+
120+
metacall_value_destroy(ret);
121+
122+
/* Test handleB get_second which belongs to bufferB */
123+
124+
ret = metacallhv_s(handleB, "get_second", args, 2);
125+
126+
EXPECT_EQ((int)6, (int)metacall_value_to_int(ret));
127+
128+
metacall_value_destroy(ret);
129+
130+
metacall_value_destroy(args[0]);
131+
metacall_value_destroy(args[1]);
76132
}
77133
#endif /* OPTION_BUILD_LOADERS_RB */
78134

0 commit comments

Comments
 (0)