Skip to content

Commit 3beb6ac

Browse files
committed
Implement support for array in arguments for python.
1 parent 8d3084c commit 3beb6ac

File tree

2 files changed

+107
-87
lines changed

2 files changed

+107
-87
lines changed

source/loaders/node_loader/source/node_loader_impl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -710,7 +710,7 @@ napi_value node_loader_impl_value_to_napi(loader_impl_node node_impl, napi_env e
710710
for (iterator = 0; iterator < array_size; ++iterator)
711711
{
712712
/* TODO: Review recursion overflow */
713-
napi_value element_v =node_loader_impl_value_to_napi(node_impl, env, static_cast<value>(array_value[iterator]));
713+
napi_value element_v = node_loader_impl_value_to_napi(node_impl, env, static_cast<value>(array_value[iterator]));
714714

715715
status = napi_set_element(env, v, iterator, element_v);
716716

source/loaders/py_loader/source/py_loader_impl.c

Lines changed: 106 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -409,128 +409,148 @@ value py_loader_impl_return(PyObject * result, type_id id)
409409
return v;
410410
}
411411

412-
function_return function_py_interface_invoke(function func, function_impl impl, function_args args)
412+
PyObject * py_loader_impl_value_to_capi(type_id id, value v)
413413
{
414-
loader_impl_py_function py_func = (loader_impl_py_function)impl;
414+
if (id == TYPE_BOOL)
415+
{
416+
boolean b = value_to_bool(v);
415417

416-
signature s = function_signature(func);
418+
long l = (b == 0) ? 0L : 1L;
417419

418-
const size_t args_size = signature_count(s);
420+
return PyBool_FromLong(l);
421+
}
422+
else if (id == TYPE_INT)
423+
{
424+
int i = value_to_int(v);
419425

420-
type ret_type = signature_get_return(s);
426+
#if PY_MAJOR_VERSION == 2
427+
return PyInt_FromLong(i);
428+
#elif PY_MAJOR_VERSION == 3
429+
long l = (long)i;
421430

422-
PyObject * tuple_args = PyTuple_New(args_size);
431+
return PyLong_FromLong(l);
432+
#endif
433+
}
434+
else if (id == TYPE_LONG)
435+
{
436+
long l = value_to_long(v);
423437

424-
PyObject * result = NULL;
438+
return PyLong_FromLong(l);
439+
}
440+
else if (id == TYPE_FLOAT)
441+
{
442+
float f = value_to_float(v);
425443

426-
size_t args_count;
444+
return PyFloat_FromDouble((double)f);
445+
}
446+
else if (id == TYPE_DOUBLE)
447+
{
448+
double d = value_to_double(v);
427449

428-
PyGILState_STATE gstate = PyGILState_Ensure();
450+
return PyFloat_FromDouble(d);
451+
}
452+
else if (id == TYPE_STRING)
453+
{
454+
const char * str = value_to_string(v);
429455

430-
for (args_count = 0; args_count < args_size; ++args_count)
456+
#if PY_MAJOR_VERSION == 2
457+
return PyString_FromString(str);
458+
#elif PY_MAJOR_VERSION == 3
459+
return PyUnicode_FromString(str);
460+
#endif
461+
}
462+
else if (id == TYPE_BUFFER)
431463
{
432-
type t = signature_get_type(s, args_count);
464+
/* This forces that you wont never be able to pass a buffer as a pointer to metacall without be wrapped into a value type */
465+
/* If a pointer is passed this will produce a garbage read from outside of the memory range of the parameter */
466+
size_t size = value_type_size(v);
433467

434-
type_id id = TYPE_INVALID;
468+
const char * buffer = value_to_buffer(v);
435469

436-
if (t == NULL)
437-
{
438-
id = value_type_id((value)args[args_count]);
439-
}
440-
else
470+
#if PY_MAJOR_VERSION == 2
471+
472+
/* TODO */
473+
474+
#elif PY_MAJOR_VERSION == 3
475+
return PyBytes_FromStringAndSize(buffer, (Py_ssize_t)size);
476+
#endif
477+
}
478+
else if (id == TYPE_ARRAY)
479+
{
480+
value * array_value = value_to_array(v);
481+
482+
Py_ssize_t iterator, array_size = (Py_ssize_t)value_type_count(v);
483+
484+
PyObject * list = PyList_New(array_size);
485+
486+
for (iterator = 0; iterator < array_size; ++iterator)
441487
{
442-
id = type_index(t);
488+
PyObject * item = py_loader_impl_value_to_capi(value_type_id((value)array_value[iterator]), (value)array_value[iterator]);
489+
490+
if (PyList_SetItem(list, iterator, item) != 0)
491+
{
492+
/* TODO: Report error */
493+
}
443494
}
444495

445-
log_write("metacall", LOG_LEVEL_DEBUG, "Type (%p): %d", (void *)t, id);
496+
return list;
497+
}
498+
else if (id == TYPE_MAP)
499+
{
500+
/* TODO */
501+
}
502+
else if (id == TYPE_PTR)
503+
{
504+
void * ptr = value_to_ptr(v);
446505

447-
if (id == TYPE_BOOL)
448-
{
449-
boolean * value_ptr = (boolean *)(args[args_count]);
506+
#if PY_MAJOR_VERSION == 2
450507

451-
long l = (*value_ptr == 0) ? 0L : 1L;
508+
/* TODO */
452509

453-
py_func->values[args_count] = PyBool_FromLong(l);
454-
}
455-
else if (id == TYPE_INT)
456-
{
457-
int * value_ptr = (int *)(args[args_count]);
510+
#elif PY_MAJOR_VERSION == 3
511+
return PyCapsule_New(ptr, NULL, NULL);
512+
#endif
513+
}
458514

459-
#if PY_MAJOR_VERSION == 2
460-
py_func->values[args_count] = PyInt_FromLong(*value_ptr);
461-
#elif PY_MAJOR_VERSION == 3
462-
long l = (long)(*value_ptr);
515+
return NULL;
516+
}
463517

464-
py_func->values[args_count] = PyLong_FromLong(l);
465-
#endif
466-
}
467-
else if (id == TYPE_LONG)
468-
{
469-
long * value_ptr = (long *)(args[args_count]);
518+
function_return function_py_interface_invoke(function func, function_impl impl, function_args args)
519+
{
520+
loader_impl_py_function py_func = (loader_impl_py_function)impl;
470521

471-
py_func->values[args_count] = PyLong_FromLong(*value_ptr);
472-
}
473-
else if (id == TYPE_FLOAT)
474-
{
475-
float * value_ptr = (float *)(args[args_count]);
522+
signature s = function_signature(func);
476523

477-
py_func->values[args_count] = PyFloat_FromDouble((double)*value_ptr);
478-
}
479-
else if (id == TYPE_DOUBLE)
480-
{
481-
double * value_ptr = (double *)(args[args_count]);
524+
const size_t args_size = signature_count(s);
482525

483-
py_func->values[args_count] = PyFloat_FromDouble(*value_ptr);
484-
}
485-
else if (id == TYPE_STRING)
486-
{
487-
const char * value_ptr = (const char *)(args[args_count]);
526+
type ret_type = signature_get_return(s);
488527

489-
#if PY_MAJOR_VERSION == 2
490-
py_func->values[args_count] = PyString_FromString(value_ptr);
491-
#elif PY_MAJOR_VERSION == 3
492-
py_func->values[args_count] = PyUnicode_FromString(value_ptr);
493-
#endif
528+
PyObject * tuple_args = PyTuple_New(args_size);
494529

495-
}
496-
else if (id == TYPE_BUFFER)
497-
{
498-
/* This forces that you wont never be able to pass a buffer as a pointer to metacall without be wrapped into a value type */
499-
/* If a pointer is passed this will produce a garbage read from outside of the memory range of the parameter */
500-
value * v = (value)args[args_count];
530+
PyObject * result = NULL;
501531

502-
size_t size = value_type_size(v);
532+
size_t args_count;
503533

504-
const char * buffer = value_to_buffer(v);
534+
PyGILState_STATE gstate = PyGILState_Ensure();
505535

506-
#if PY_MAJOR_VERSION == 2
536+
for (args_count = 0; args_count < args_size; ++args_count)
537+
{
538+
type t = signature_get_type(s, args_count);
507539

508-
/* TODO */
540+
type_id id = TYPE_INVALID;
509541

510-
#elif PY_MAJOR_VERSION == 3
511-
py_func->values[args_count] = PyBytes_FromStringAndSize(buffer, (Py_ssize_t) size);
512-
#endif
513-
}
514-
else if (id == TYPE_ARRAY)
542+
if (t == NULL)
515543
{
516-
/* TODO */
544+
id = value_type_id((value)args[args_count]);
517545
}
518-
else if (id == TYPE_MAP)
546+
else
519547
{
520-
/* TODO */
548+
id = type_index(t);
521549
}
522-
else if (id == TYPE_PTR)
523-
{
524-
void * value_ptr = *((void **)(args[args_count]));
525-
526-
#if PY_MAJOR_VERSION == 2
527550

528-
/* TODO */
551+
log_write("metacall", LOG_LEVEL_DEBUG, "Type (%p): %d", (void *)t, id);
529552

530-
#elif PY_MAJOR_VERSION == 3
531-
py_func->values[args_count] = PyCapsule_New(value_ptr, NULL, NULL);
532-
#endif
533-
}
553+
py_func->values[args_count] = py_loader_impl_value_to_capi(id, args[args_count]);
534554

535555
if (py_func->values[args_count] != NULL)
536556
{

0 commit comments

Comments
 (0)