summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Zaoui <daniel.zaoui@yahoo.com>2017-03-02 09:04:18 +0200
committerDaniel Zaoui <daniel.zaoui@yahoo.com>2017-03-02 09:04:18 +0200
commit47fb160084ecb425f11273735a10475c622cee22 (patch)
tree0c52be9ab19cb7d7d231f56f62bf2811e6c39c9f
parentdc0f1cdd8d2ef463ab2a1213b65e834ffcb0ca8b (diff)
Eolian: refactor all the ffi invocation
-rw-r--r--src/lib/Eolian_Debug.h5
-rw-r--r--src/lib/eolian_debug.c178
2 files changed, 108 insertions, 75 deletions
diff --git a/src/lib/Eolian_Debug.h b/src/lib/Eolian_Debug.h
index c115c06..fa16e40 100644
--- a/src/lib/Eolian_Debug.h
+++ b/src/lib/Eolian_Debug.h
@@ -41,7 +41,8 @@ typedef enum
41 EOLIAN_DEBUG_DOUBLE, 41 EOLIAN_DEBUG_DOUBLE,
42 EOLIAN_DEBUG_BOOLEAN, 42 EOLIAN_DEBUG_BOOLEAN,
43 EOLIAN_DEBUG_LONG, 43 EOLIAN_DEBUG_LONG,
44 EOLIAN_DEBUG_UINT 44 EOLIAN_DEBUG_UINT,
45 EOLIAN_DEBUG_VOID
45} Eolian_Debug_Basic_Type; 46} Eolian_Debug_Basic_Type;
46 47
47typedef struct 48typedef struct
@@ -56,7 +57,7 @@ typedef struct
56typedef struct 57typedef struct
57{ 58{
58 Eolian_Debug_Value value; 59 Eolian_Debug_Value value;
59 const Eolian_Function_Parameter *etype; 60 const Eolian_Function_Parameter *eparam;
60} Eolian_Debug_Parameter; 61} Eolian_Debug_Parameter;
61 62
62typedef struct 63typedef struct
diff --git a/src/lib/eolian_debug.c b/src/lib/eolian_debug.c
index e27bf26..0c7d21c 100644
--- a/src/lib/eolian_debug.c
+++ b/src/lib/eolian_debug.c
@@ -81,9 +81,11 @@ _eolian_type_resolve(const Eolian_Type *eo_type)
81 if (type == EOLIAN_TYPE_COMPLEX) 81 if (type == EOLIAN_TYPE_COMPLEX)
82 return EOLIAN_DEBUG_POINTER; 82 return EOLIAN_DEBUG_POINTER;
83 83
84#if 0
84 printf("Type %s not supported\n", 85 printf("Type %s not supported\n",
85 type_base != EOLIAN_TYPE_VOID ? eolian_type_full_name_get(eo_type) : 86 type_base != EOLIAN_TYPE_VOID ? eolian_type_full_name_get(eo_type) :
86 "void"); 87 "void");
88#endif
87 return EOLIAN_DEBUG_INVALID_TYPE; 89 return EOLIAN_DEBUG_INVALID_TYPE;
88 90
89} 91}
@@ -137,76 +139,116 @@ _function_find_by_name(const char *func_klname,
137} 139}
138#endif 140#endif
139 141
140static Eina_Bool 142static int
141_function_params_prepare(Eo *ptr, const Eolian_Function *foo, 143_function_invoke(Eo *ptr, const Eolian_Function *foo, Eolian_Function_Type foo_type,
142 Eolian_Debug_Parameter params[], Eolian_Debug_Return *ret_p, int *argnum) 144 Eolian_Debug_Parameter *params, Eolian_Debug_Return *ret)
143{ 145{
144 if (!foo) return EINA_FALSE; 146 /* The params table contains the keys and the values.
145 ffi_type *types[EOLIAN_DEBUG_MAXARGS]; 147 * This function doesn't allocate memory */
146 void *values[EOLIAN_DEBUG_MAXARGS]; 148 ffi_type *types[EOLIAN_DEBUG_MAXARGS]; /* FFI types */
147 void *pointers[EOLIAN_DEBUG_MAXARGS]; 149 void *values[EOLIAN_DEBUG_MAXARGS]; /* FFI Values */
150 void *pointers[EOLIAN_DEBUG_MAXARGS]; /* Used as values for out params, as we have to give a pointer to a pointer */
148 Eolian_Function_Parameter *eo_param; 151 Eolian_Function_Parameter *eo_param;
149 Eina_Iterator *itr = eolian_property_values_get(foo, EOLIAN_PROP_GET); 152 Eina_Iterator *itr;
150 Eina_Bool ret = EINA_FALSE; 153 Eolian_Debug_Basic_Type ed_type;
154 int argc, ffi_argc = 0;
155
156 if (!foo) return -1;
157 if (foo_type == EOLIAN_PROPERTY) return -1;
151 158
152 types[0] = &ffi_type_pointer; 159 /* Eo object storage */
153 values[0] = &ptr; 160 types[ffi_argc] = &ffi_type_pointer;
154 *argnum = 1; 161 values[ffi_argc] = &ptr;
162 ffi_argc++;
155 163
164 itr = eolian_property_keys_get(foo, foo_type);
165 argc = 0;
156 EINA_ITERATOR_FOREACH(itr, eo_param) 166 EINA_ITERATOR_FOREACH(itr, eo_param)
157 { 167 {
158 Eolian_Debug_Basic_Type type = _eolian_type_resolve(eolian_parameter_type_get(eo_param)); 168 /* Not verified */
159 169 ed_type = _eolian_type_resolve(eolian_parameter_type_get(eo_param));
160 if (type && *argnum < (EOLIAN_DEBUG_MAXARGS - 1)) 170 if (!ed_type) goto error;
161 { 171
162 params[*argnum].value.value.value = 0; 172 types[ffi_argc] = param_types[ed_type].ffi_type_p;
163 params[*argnum].value.type = type; 173 values[ffi_argc] = &(params[argc].value.value.value);
164 types[*argnum] = param_types[type].ffi_type_p; 174 ffi_argc++;
165 pointers[*argnum] = &(params[*argnum].value.value.value); 175 argc++;
166 values[*argnum] = &pointers[*argnum];
167 (*argnum)++;
168 }
169 else goto end;
170 } 176 }
171 if (*argnum == 1) 177
178 itr = foo_type == EOLIAN_METHOD ? eolian_function_parameters_get(foo) :
179 eolian_property_values_get(foo, foo_type);
180 EINA_ITERATOR_FOREACH(itr, eo_param)
172 { 181 {
173 const Eolian_Type *eo_type = eolian_function_return_type_get(foo, EOLIAN_PROP_GET); 182 ed_type = _eolian_type_resolve(eolian_parameter_type_get(eo_param));
174 Eolian_Debug_Basic_Type type = _eolian_type_resolve(eo_type); 183 if (!ed_type) goto error;
175 184
176 if (type) 185 if (foo_type == EOLIAN_PROP_GET ||
186 (foo_type == EOLIAN_METHOD && eolian_parameter_direction_get(eo_param) == EOLIAN_OUT_PARAM))
187 {
188 /* Out parameter */
189 params[argc].value.value.value = 0;
190 params[argc].value.type = ed_type;
191 types[ffi_argc] = &ffi_type_pointer;
192 pointers[ffi_argc] = &(params[argc].value.value.value);
193 values[ffi_argc] = &pointers[ffi_argc];
194 }
195 else
177 { 196 {
178 ret_p->value.value.value = 0; 197 /* In parameter */
179 ret_p->value.type = type; 198 types[ffi_argc] = param_types[ed_type].ffi_type_p;
199 values[ffi_argc] = &(params[argc].value.value.value);
180 } 200 }
181 else goto end; 201 ffi_argc++;
202 argc++;
182 } 203 }
183 204
184 // FIXME got to handle return type here (eolian_function_return_type_get) 205 const Eolian_Type *eo_type = eolian_function_return_type_get(foo, foo_type);
206 ffi_type *ffi_ret_type = &ffi_type_void;
207 if (eo_type)
208 {
209 ed_type = _eolian_type_resolve(eo_type);
210 if (!ed_type) goto error;
211
212 ffi_ret_type = param_types[ed_type].ffi_type_p;
213 }
214 else if (argc == 1 && foo_type == EOLIAN_PROP_GET)
215 {
216 /* If there is no return type but only one value is present, the value will
217 * be returned by the function.
218 * So we need FFI to not take it into account when invoking the function.
219 */
220 ffi_ret_type = param_types[params[0].value.type].ffi_type_p;
221 ffi_argc--;
222 }
185 223
186 const char *full_func_name = eolian_function_full_c_name_get(foo, EOLIAN_PROP_GET, EINA_FALSE); 224 const char *full_func_name = eolian_function_full_c_name_get(foo, EOLIAN_PROP_GET, EINA_FALSE);
187 printf("dlsym %s\n", full_func_name); 225 //printf("dlsym %s\n", full_func_name);
188 void *eo_func = dlsym(RTLD_DEFAULT, full_func_name); 226 void *eo_func = dlsym(RTLD_DEFAULT, full_func_name);
189 ffi_cif cif; 227 ffi_cif cif;
190#if 0 228 if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, ffi_argc,
191 ffi_type *ffi_type_p = &ffi_type_pointer; 229 ffi_ret_type, types) == FFI_OK)
192 if(*argnum == 1)
193 ffi_type_p = params[0].type->ffi_type_p;
194#endif
195 if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, *argnum, &ffi_type_pointer, types) == FFI_OK)
196 { 230 {
197 void *result; 231 void *result;
198 ffi_call(&cif, eo_func, &result, values); 232 ffi_call(&cif, eo_func, &result, values);
199 if(*argnum == 2) 233 if (ret) ret->value.type = EOLIAN_DEBUG_VOID;
234 if (eo_type)
235 {
236 if (ret)
237 {
238 ret->value.value.value = (uint64_t) result;
239 ret->value.type = ed_type;
240 }
241 }
242 else if (argc == 1 && foo_type == EOLIAN_PROP_GET)
200 params[0].value.value.value = (uint64_t) result; 243 params[0].value.value.value = (uint64_t) result;
201 if(*argnum == 1) 244 goto success;
202 ret_p->value.value.value = (uint64_t) result;
203
204 ret = EINA_TRUE;
205 } 245 }
206 246
207end: 247error:
248 argc = -1;
249success:
208 eina_iterator_free(itr); 250 eina_iterator_free(itr);
209 return ret; 251 return argc;
210} 252}
211 253
212static Eina_Bool 254static Eina_Bool
@@ -283,20 +325,18 @@ _class_buffer_fill(Eo *obj, const Eolian_Class *ekl, char *buf)
283 if (eolian_function_type_get(func) == EOLIAN_PROP_SET || 325 if (eolian_function_type_get(func) == EOLIAN_PROP_SET ||
284 !_eolian_function_is_implemented(func, EOLIAN_PROP_GET, ekl)) continue; 326 !_eolian_function_is_implemented(func, EOLIAN_PROP_GET, ekl)) continue;
285 Eina_Iterator *keys_itr = eolian_property_keys_get(func, EOLIAN_PROP_GET); 327 Eina_Iterator *keys_itr = eolian_property_keys_get(func, EOLIAN_PROP_GET);
286 if (keys_itr) 328 eina_iterator_free(keys_itr);
287 { 329 /* We dont support functions with key parameters */
288 eina_iterator_free(keys_itr); 330 if (keys_itr) continue;
289 continue; 331
290 }
291 Eolian_Debug_Parameter params[EOLIAN_DEBUG_MAXARGS]; 332 Eolian_Debug_Parameter params[EOLIAN_DEBUG_MAXARGS];
292 Eolian_Debug_Return ret; 333 Eolian_Debug_Return ret;
293 int argnum = 0; 334 int argnum = _function_invoke(obj, func, EOLIAN_PROP_GET, params, &ret);
294 Eina_Bool flag = _function_params_prepare(obj, func, params, &ret, &argnum);
295 335
296 if(!flag) continue; 336 if (argnum == -1) continue;
297 337
298 int len, i; 338 int len, i;
299 if(!size) // only if its the first func to succeed 339 if (!size) // only if its the first func to succeed
300 { 340 {
301 const char *class_name = eolian_class_full_name_get(ekl); 341 const char *class_name = eolian_class_full_name_get(ekl);
302 len = strlen(class_name) + 1; 342 len = strlen(class_name) + 1;
@@ -313,13 +353,9 @@ _class_buffer_fill(Eo *obj, const Eolian_Class *ekl, char *buf)
313 len = strlen(func_name) + 1; 353 len = strlen(func_name) + 1;
314 memcpy(buf + size, func_name, len); 354 memcpy(buf + size, func_name, len);
315 size += len; 355 size += len;
316 for(i = 1; i < argnum; i++) //print params 356 for (i = 0; i < argnum; i++) //print params
317 { 357 {
318 printf("%d result %s = ", i, param_types[params[i].value.type].print_format); 358 // if its a string we wont copy the pointer but the value
319 printf(param_types[params[i].value.type].print_format,
320 params[i].value.value.value);
321 printf("\n");
322 //if its a string we wont copy the pointer but the values
323 if (params[i].value.type == EOLIAN_DEBUG_STRING) 359 if (params[i].value.type == EOLIAN_DEBUG_STRING)
324 { 360 {
325 if((char *)params[i].value.value.value == NULL) 361 if((char *)params[i].value.value.value == NULL)
@@ -342,12 +378,8 @@ _class_buffer_fill(Eo *obj, const Eolian_Class *ekl, char *buf)
342 be in the function params iterator - hence argnum = 0. For that 378 be in the function params iterator - hence argnum = 0. For that
343 case we use Eolian_Debug_Return struct 379 case we use Eolian_Debug_Return struct
344 */ 380 */
345 if(argnum == 0) 381 if (ret.value.type != EOLIAN_DEBUG_VOID)
346 { 382 {
347 printf("%d result %s = ", i, param_types[ret.value.type].print_format);
348 printf(param_types[ret.value.type].print_format,
349 ret.value.value.value);
350 printf("\n");
351 //if its a string we wont copy the pointer but the values 383 //if its a string we wont copy the pointer but the values
352 if (ret.value.type == EOLIAN_DEBUG_STRING) 384 if (ret.value.type == EOLIAN_DEBUG_STRING)
353 { 385 {
@@ -376,16 +408,15 @@ _obj_info_req_cb(Eina_Debug_Session *session, int srcid, void *buffer, int size
376 uint64_t ptr64; 408 uint64_t ptr64;
377 memcpy(&ptr64, buffer, sizeof(ptr64)); 409 memcpy(&ptr64, buffer, sizeof(ptr64));
378 Eo *obj = (Eo *)ptr64; 410 Eo *obj = (Eo *)ptr64;
379 printf("%s - obj = %p\n", __FUNCTION__, obj);
380 411
381 const char *class_name = efl_class_name_get(obj); 412 const char *class_name = efl_class_name_get(obj);
382 const Eolian_Class *kl = _class_find_by_name(class_name); 413 const Eolian_Class *kl = _class_find_by_name(class_name);
383 char buf[100000]; 414 char *buf = alloca(100000);
384 unsigned int size_curr = 0; 415 unsigned int size_curr = 0;
385 if (!kl) 416 if (!kl)
386 { 417 {
387 printf("Class %s not found.\n", class_name); 418 printf("Class %s not found.\n", class_name);
388 return EINA_DEBUG_OK; 419 goto end;
389 } 420 }
390 memcpy(buf, &ptr64, sizeof(uint64_t)); 421 memcpy(buf, &ptr64, sizeof(uint64_t));
391 size_curr = sizeof(uint64_t); 422 size_curr = sizeof(uint64_t);
@@ -412,6 +443,7 @@ _obj_info_req_cb(Eina_Debug_Session *session, int srcid, void *buffer, int size
412 443
413 eina_debug_session_send(session, srcid, _obj_info_op, buf, size_curr); 444 eina_debug_session_send(session, srcid, _obj_info_op, buf, size_curr);
414 445
446end:
415 return EINA_DEBUG_OK; 447 return EINA_DEBUG_OK;
416} 448}
417 449
@@ -492,7 +524,7 @@ eolian_debug_object_information_decode(char *buffer, unsigned int size)
492 if (type) 524 if (type)
493 { 525 {
494 Eolian_Debug_Parameter *p = calloc(1, sizeof(*p)); 526 Eolian_Debug_Parameter *p = calloc(1, sizeof(*p));
495 p->etype = eo_param; 527 p->eparam = eo_param;
496 p->value.type = type; 528 p->value.type = type;
497 if (type == EOLIAN_DEBUG_STRING) 529 if (type == EOLIAN_DEBUG_STRING)
498 { 530 {
@@ -510,10 +542,10 @@ eolian_debug_object_information_decode(char *buffer, unsigned int size)
510 } 542 }
511 else goto error; 543 else goto error;
512 } 544 }
513 if(func->params == NULL) 545 func->ret.etype = eolian_function_return_type_get(
546 func->efunc, EOLIAN_PROP_GET);
547 if(func->ret.etype)
514 { 548 {
515 func->ret.etype = eolian_function_return_type_get(
516 func->efunc, EOLIAN_PROP_GET);
517 Eolian_Debug_Basic_Type type = _eolian_type_resolve(func->ret.etype); 549 Eolian_Debug_Basic_Type type = _eolian_type_resolve(func->ret.etype);
518 if (type) 550 if (type)
519 { 551 {