Skip to content

Commit ea38ddd

Browse files
committed
Add support for pointers in c loader.
1 parent 2cf32ca commit ea38ddd

File tree

5 files changed

+87
-10
lines changed

5 files changed

+87
-10
lines changed

source/loaders/c_loader/source/c_loader_impl.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -720,7 +720,7 @@ function_return function_c_interface_invoke(function func, function_impl impl, f
720720
ret = value_create_null();
721721
result_ptr = NULL;
722722
}
723-
else if (ret_id != TYPE_STRING)
723+
else if (ret_id != TYPE_STRING && ret_id != TYPE_PTR)
724724
{
725725
result = ret = value_type_create(NULL, ret_size, ret_id);
726726
}
@@ -732,6 +732,10 @@ function_return function_c_interface_invoke(function func, function_impl impl, f
732732
char *str = (char *)result;
733733
ret = value_create_string(str, strlen(str));
734734
}
735+
else if (ret_id == TYPE_PTR)
736+
{
737+
ret = value_create_ptr(result);
738+
}
735739
}
736740

737741
for (size_t args_count = 0; args_count < args_size; ++args_count)
@@ -836,6 +840,7 @@ int c_loader_impl_initialize_types(loader_impl impl)
836840
{ TYPE_BOOL, "bool" },
837841

838842
{ TYPE_CHAR, "char" },
843+
{ TYPE_CHAR, "unsigned char" },
839844
{ TYPE_CHAR, "int8_t" },
840845
{ TYPE_CHAR, "uint8_t" },
841846
{ TYPE_CHAR, "int_least8_t" },
@@ -844,6 +849,7 @@ int c_loader_impl_initialize_types(loader_impl impl)
844849
{ TYPE_CHAR, "uint_fast8_t" },
845850

846851
{ TYPE_SHORT, "short" },
852+
{ TYPE_SHORT, "unsigned short" },
847853
{ TYPE_SHORT, "int16_t" },
848854
{ TYPE_SHORT, "uint16_t" },
849855
{ TYPE_SHORT, "int_least16_t" },
@@ -852,6 +858,7 @@ int c_loader_impl_initialize_types(loader_impl impl)
852858
{ TYPE_SHORT, "uint_fast16_t" },
853859

854860
{ TYPE_INT, "int" },
861+
{ TYPE_INT, "unsigned int" },
855862
{ TYPE_INT, "uint32_t" },
856863
{ TYPE_INT, "int32_t" },
857864
{ TYPE_INT, "int_least32_t" },
@@ -860,7 +867,9 @@ int c_loader_impl_initialize_types(loader_impl impl)
860867
{ TYPE_INT, "uint_fast32_t" },
861868

862869
{ TYPE_LONG, "long" },
870+
{ TYPE_LONG, "unsigned long" },
863871
{ TYPE_LONG, "long long" },
872+
{ TYPE_LONG, "unsigned long long" },
864873
{ TYPE_LONG, "uint64_t" },
865874
{ TYPE_LONG, "int64_t" },
866875
{ TYPE_LONG, "int_least64_t" },
@@ -1005,7 +1014,12 @@ static type_id c_loader_impl_clang_type(loader_impl impl, CXCursor cursor, CXTyp
10051014
case CXType_Bool:
10061015
return TYPE_BOOL;
10071016

1017+
case CXType_Short:
1018+
case CXType_UShort:
1019+
return TYPE_SHORT;
1020+
10081021
case CXType_Int:
1022+
case CXType_UInt:
10091023
return TYPE_INT;
10101024

10111025
case CXType_Void:

source/loaders/node_loader/source/node_loader_impl.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1442,14 +1442,13 @@ value node_loader_impl_napi_to_value(loader_impl_node node_impl, napi_env env, n
14421442
}
14431443
else if (valuetype == napi_external)
14441444
{
1445-
/* Returns the previously allocated copy */
14461445
void *c = nullptr;
14471446

14481447
status = napi_get_value_external(env, v, &c);
14491448

14501449
node_loader_impl_exception(env, status);
14511450

1452-
return c;
1451+
return value_create_ptr(c);
14531452
}
14541453

14551454
return ret;
@@ -1635,10 +1634,7 @@ napi_value node_loader_impl_value_to_napi(loader_impl_node node_impl, napi_env e
16351634
}
16361635
else if (id == TYPE_PTR)
16371636
{
1638-
/* Copy value and set the ownership, the old value will be deleted after the call */
1639-
void *c = value_copy(arg_value);
1640-
1641-
value_move(arg_value, c);
1637+
void *c = value_to_ptr(arg_value);
16421638

16431639
status = napi_create_external(env, c, nullptr, nullptr, &v);
16441640

source/metacall/source/metacall.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1119,8 +1119,15 @@ void *metacallfv_s(void *func, void *args[], size_t size)
11191119
{
11201120
if (value_validate(args[iterator]) != 0)
11211121
{
1122+
const char *name = function_name(f);
1123+
1124+
if (name == NULL)
1125+
{
1126+
name = "anonymous";
1127+
}
1128+
11221129
// TODO: Implement type error return a value
1123-
log_write("metacall", LOG_LEVEL_ERROR, "Invalid argument at position %" PRIuS " when calling to metacallfv_s", iterator);
1130+
log_write("metacall", LOG_LEVEL_ERROR, "Invalid argument at position %" PRIuS " when calling to metacallfv_s with function <%s> and value <%p>", iterator, name, args[iterator]);
11241131
return NULL;
11251132
}
11261133

@@ -2120,8 +2127,15 @@ void *metacallv_method(void *target, const char *name, method_invoke_ptr call, v
21202127
{
21212128
if (value_validate(args[iterator]) != 0)
21222129
{
2130+
const char *name = method_name(m);
2131+
2132+
if (name == NULL)
2133+
{
2134+
name = "anonymous";
2135+
}
2136+
21232137
// TODO: Implement type error return a value
2124-
log_write("metacall", LOG_LEVEL_ERROR, "Invalid argument at position %" PRIuS " when calling to metacallv_method", iterator);
2138+
log_write("metacall", LOG_LEVEL_ERROR, "Invalid argument at position %" PRIuS " when calling to metacallv_method with method <%s> and value <%p>", iterator, name, args[iterator]);
21252139
vector_destroy(v);
21262140
return NULL;
21272141
}

source/scripts/c/compiled/source/compiled.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include <assert.h>
22
#include <stdio.h>
3+
#include <stdlib.h>
34
#include <string.h>
45

56
void compiled_print(int a, double b)
@@ -23,3 +24,47 @@ void process_text(char *input)
2324
printf("inside of compiled script '%s'\n", input);
2425
assert(strcmp(input, "test_test") == 0);
2526
}
27+
28+
typedef struct data_t
29+
{
30+
int value;
31+
} *data_ptr_t;
32+
33+
data_ptr_t alloc_data(void)
34+
{
35+
data_ptr_t ptr = malloc(sizeof(struct data_t));
36+
37+
ptr->value = 0;
38+
39+
printf("alloc_data %p\n", ptr);
40+
41+
return ptr;
42+
}
43+
44+
void alloc_data_args(data_ptr_t *ptr)
45+
{
46+
*ptr = malloc(sizeof(struct data_t));
47+
48+
(*ptr)->value = 0;
49+
50+
printf("alloc_data_args %p\n", *ptr);
51+
printf("alloc_data_args ref %p\n", ptr);
52+
}
53+
54+
void set_data_value(data_ptr_t ptr, int value)
55+
{
56+
printf("set_data_value %p\n", ptr);
57+
ptr->value = value;
58+
}
59+
60+
int get_data_value(data_ptr_t ptr)
61+
{
62+
printf("get_data_value %p\n", ptr);
63+
return ptr->value;
64+
}
65+
66+
void free_data(data_ptr_t ptr)
67+
{
68+
printf("free_data %p\n", ptr);
69+
free(ptr);
70+
}

source/tests/metacall_node_port_c_test/source/metacall_node_port_c_test.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,20 @@ TEST_F(metacall_node_port_c_test, DefaultConstructor)
3838
static const char buffer[] =
3939
"const assert = require('assert');\n"
4040
"const { metacall_load_from_file_export } = require('" METACALL_NODE_PORT_PATH "');\n"
41-
"const { return_text, process_text } = metacall_load_from_file_export('c', ['compiled.c']);\n"
41+
"const { return_text, process_text, alloc_data, alloc_data_args, set_data_value, get_data_value, free_data } = metacall_load_from_file_export('c', ['compiled.c']);\n"
42+
// Test strings
4243
"const result = return_text();\n"
4344
"console.log(`'${result}'`);\n"
4445
"assert(result == 'hello');\n"
4546
"console.log(result);\n"
4647
"process_text('test_test');\n"
48+
// Test return pointers
49+
"data_ptr = alloc_data();\n"
50+
"console.log(data_ptr);\n"
51+
"set_data_value(data_ptr, 12);\n"
52+
"assert(get_data_value(data_ptr) == 12);\n"
53+
"free_data(data_ptr);\n"
54+
// TODO: Implement passing reference by arguments (alloc_data_args)
4755
"\n";
4856

4957
ASSERT_EQ((int)0, (int)metacall_load_from_memory("node", buffer, sizeof(buffer), NULL));

0 commit comments

Comments
 (0)