Skip to content

Commit

Permalink
Optimize dyn_function's arguments handling.
Browse files Browse the repository at this point in the history
1. Removed unused argName.
2. Add dynFunction_arguments.
3. Avoid list iteration in dynFunction_nrOfArguments.
  • Loading branch information
PengZheng committed Jan 22, 2024
1 parent 6fffb96 commit 1220311
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 39 deletions.
4 changes: 4 additions & 0 deletions libs/dfi/gtest/src/dyn_example_functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,7 @@ void example5Func(const char *s1, char *s2) {
assert(strncmp("s1", s1, 5) == 0);
assert(strncmp("s2", s2, 5) == 0);
}

int32_t example6Func() {
return 1234;
}
2 changes: 2 additions & 0 deletions libs/dfi/gtest/src/dyn_example_functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ void example4Func(struct tst_seq seq);
#define EXAMPLE5_DESCRIPTOR "example(#const=true;tt)V"
void example5Func(const char *s1, char *s2);

#define EXAMPLE6_DESCRIPTOR "example()I"
int32_t example6Func();


#ifdef __cplusplus
Expand Down
7 changes: 0 additions & 7 deletions libs/dfi/gtest/src/dyn_function_ei_tests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,6 @@ TEST_F(DynFunctionErrorInjectionTestSuite, ParseError) {
result += strerror(ENOMEM);
EXPECT_STREQ(result.c_str(), celix_err_popLastError());

celix_ei_expect_asprintf((void*) dynFunction_parse, 1, -1, 3);
rc = dynFunction_parseWithStr(EXAMPLE1_DESCRIPTOR, nullptr, &dynFunc);
EXPECT_NE(0, rc);
EXPECT_STREQ("Error parsing descriptor", celix_err_popLastError());
EXPECT_STREQ("Error allocating argument name", celix_err_popLastError());


celix_ei_expect_calloc((void*)dynFunction_parse, 1, nullptr, 3);
rc = dynFunction_parseWithStr(EXAMPLE1_DESCRIPTOR, nullptr, &dynFunc);
EXPECT_NE(0, rc);
Expand Down
27 changes: 27 additions & 0 deletions libs/dfi/gtest/src/dyn_function_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,13 @@ TEST_F(DynFunctionTests, DynFuncTest1) {
rc = dynFunction_parseWithStr(EXAMPLE1_DESCRIPTOR, nullptr, &dynFunc);
ASSERT_EQ(0, rc);
EXPECT_TRUE(dynFunction_hasReturn(dynFunc));
EXPECT_EQ(3, dynFunction_nrOfArguments(dynFunc));
auto args = dynFunction_arguments(dynFunc);
dyn_function_argument_type* arg = NULL;
TAILQ_FOREACH(arg, args, entries) {
EXPECT_EQ(DYN_FUNCTION_ARGUMENT_META__STD, arg->argumentMeta);
EXPECT_EQ('I', dynType_descriptorType(arg->type));
}

ffi_sarg rVal = 0;
int32_t a = 2;
Expand Down Expand Up @@ -190,6 +197,7 @@ TEST_F(DynFunctionTests, DynFuncTest4) {
rc = dynFunction_parseWithStr(EXAMPLE4_DESCRIPTOR, nullptr, &dynFunc);
ASSERT_EQ(0, rc);
EXPECT_FALSE(dynFunction_hasReturn(dynFunc));
EXPECT_EQ(1, dynFunction_nrOfArguments(dynFunc));

double buf[4];
buf[0] = 1.1;
Expand Down Expand Up @@ -237,6 +245,25 @@ TEST_F(DynFunctionTests, DynFuncTest5) {
EXPECT_TRUE(func_test5());
}

TEST_F(DynFunctionTests, DynFuncTest6) {
dyn_function_type *dynFunc = nullptr;
void (*fp)(void) = (void(*)(void)) example6Func;
int rc;

rc = dynFunction_parseWithStr(EXAMPLE6_DESCRIPTOR, nullptr, &dynFunc);
ASSERT_EQ(0, rc);
EXPECT_TRUE(dynFunction_hasReturn(dynFunc));
EXPECT_EQ(0, dynFunction_nrOfArguments(dynFunc));
auto args = dynFunction_arguments(dynFunc);
EXPECT_TRUE(TAILQ_EMPTY(args));

ffi_sarg rVal = 0;
rc = dynFunction_call(dynFunc, fp, &rVal, nullptr);
dynFunction_destroy(dynFunc);
EXPECT_EQ(0, rc);
EXPECT_EQ(1234, rVal);
}

TEST_F(DynFunctionTests, InvalidDynFuncTest) {

dyn_function_type *dynFunc = nullptr;
Expand Down
15 changes: 15 additions & 0 deletions libs/dfi/include/dyn_function.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@ enum dyn_function_argument_meta {
DYN_FUNCTION_ARGUMENT_META__OUTPUT = 3
};

typedef struct _dyn_function_argument_type dyn_function_argument_type;
TAILQ_HEAD(dyn_function_arguments_head,_dyn_function_argument_type);
struct _dyn_function_argument_type {
int index;
enum dyn_function_argument_meta argumentMeta;
dyn_type* type;
TAILQ_ENTRY(_dyn_function_argument_type) entries;
};

/**
* @brief Creates a dyn_function_type according to the given function descriptor stream.
*
Expand Down Expand Up @@ -107,6 +116,12 @@ CELIX_DFI_EXPORT const dyn_type* dynFunction_argumentTypeForIndex(const dyn_func
*/
CELIX_DFI_EXPORT enum dyn_function_argument_meta dynFunction_argumentMetaForIndex(const dyn_function_type* dynFunc, int argumentNr);

/**
* @brief Returns the argument list for the given dynamic function type instance.
* @note It always returns valid list.
*/
CELIX_DFI_EXPORT const struct dyn_function_arguments_head* dynFunction_arguments(const dyn_function_type* dynFunc);

/**
* @brief Returns the return value type for the given dynamic function type instance.
* @param[in] dynFunc The dynamic type instance for function.
Expand Down
21 changes: 5 additions & 16 deletions libs/dfi/src/dyn_function.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,26 +107,19 @@ static int dynFunction_parseDescriptor(dyn_function_type* dynFunc, FILE* descrip
ungetc(nextChar, descriptor);

celix_autoptr(dyn_type) type = NULL;
celix_autofree char* argName = NULL;
dyn_function_argument_type* arg = NULL;

if ((status = dynType_parse(descriptor, NULL, dynFunc->refTypes, &type)) != OK) {
return status;
}

if (asprintf(&argName, "arg%04i", index) == -1) {
celix_err_pushf("Error allocating argument name");
return MEM_ERROR;
}

arg = calloc(1, sizeof(*arg));
if (arg == NULL) {
celix_err_pushf("Error allocating arg");
return MEM_ERROR;
}
arg->index = index++;
arg->type = celix_steal_ptr(type);
arg->name = celix_steal_ptr(argName);

TAILQ_INSERT_TAIL(&dynFunc->arguments, arg, entries);

Expand Down Expand Up @@ -154,6 +147,9 @@ enum dyn_function_argument_meta dynFunction_argumentMetaForIndex(const dyn_funct
return result;
}

const struct dyn_function_arguments_head* dynFunction_arguments(const dyn_function_type* dynFunc) {
return &dynFunc->arguments;
}

static int dynFunction_initCif(dyn_function_type* dynFunc) {
unsigned int nargs = 0;
Expand Down Expand Up @@ -200,9 +196,6 @@ void dynFunction_destroy(dyn_function_type* dynFunc) {
dyn_function_argument_type* tmp = NULL;
entry = TAILQ_FIRST(&dynFunc->arguments);
while (entry != NULL) {
if (entry->name != NULL) {
free(entry->name);
}
dynType_destroy(entry->type);
tmp = entry;
entry = TAILQ_NEXT(entry, entries);
Expand Down Expand Up @@ -256,12 +249,8 @@ int dynFunction_getFnPointer(const dyn_function_type* dynFunc, void (**fn)(void)
}

int dynFunction_nrOfArguments(const dyn_function_type* dynFunc) {
int count = 0;
dyn_function_argument_type *entry = NULL;
TAILQ_FOREACH(entry, &dynFunc->arguments, entries) {
count += 1;
}
return count;
dyn_function_argument_type* last = TAILQ_LAST(&dynFunc->arguments, dyn_function_arguments_head);
return last == NULL ? 0 : (last->index+1);
}

const dyn_type* dynFunction_argumentTypeForIndex(const dyn_function_type* dynFunc, int argumentNr) {
Expand Down
23 changes: 7 additions & 16 deletions libs/dfi/src/dyn_function_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,27 +33,18 @@ extern "C" {
#endif

struct _dyn_function_type {
char *name;
struct types_head *refTypes; //NOTE not owned
TAILQ_HEAD(,_dyn_function_argument_type) arguments;
ffi_type **ffiArguments;
dyn_type *funcReturn;
char* name;
struct types_head* refTypes; //NOTE not owned
struct dyn_function_arguments_head arguments;
ffi_type** ffiArguments;
dyn_type* funcReturn;
ffi_cif cif;

//closure part
ffi_closure *ffiClosure;
ffi_closure* ffiClosure;
void (*fn)(void);
void *userData;
void (*bind)(void *userData, void *args[], void *ret);
};

typedef struct _dyn_function_argument_type dyn_function_argument_type;
struct _dyn_function_argument_type {
int index;
char *name;
enum dyn_function_argument_meta argumentMeta;
dyn_type *type;
TAILQ_ENTRY(_dyn_function_argument_type) entries;
void (*bind)(void* userData, void* args[], void* ret);
};

#ifdef __cplusplus
Expand Down

0 comments on commit 1220311

Please sign in to comment.