Uh oh!
There was an error while loading. Please reload this page.
@ccallable: Emit a header file with given name - #1861
Conversation
Uh oh!
There was an error while loading. Please reload this page.
certik
commented
May 26, 2023
Let's add a test for this? |
certik
left a comment
There was a problem hiding this comment.
I think this looks great.
We should add a test that calls this from C and includes the header file, to ensure that everything actually works. We can do that in a next PR.
Smit-create
commented
May 28, 2023
Thanks @certik. The test is added and it works. |
| @ccallable(header="_test_bindc_03_my_header.h") | ||
| def test_emit_header_ccallable() -> i32: | ||
| i: i32 = 5 | ||
| assert i == 5 | ||
| i = i*5 | ||
| return i + 10 |
There was a problem hiding this comment.
See this test. The header file will be created and will be used in the original file.
There was a problem hiding this comment.
Ah, the generated file contains the header file?
I think we still need a handwritten file that includes it, to be sure that all the arguments are compatible.
There was a problem hiding this comment.
% lpython --show-c integration_tests/bindc_03.py > b.c
Will generate two file.
- main file:
#include<complex.h>
#include<inttypes.h>
#include"_test_bindc_03_my_header.h"
#include"bindc_03b.h"
#include<stdlib.h>
#include<stdbool.h>
#include<stdio.h>
#include<string.h>
#include<lfortran_intrinsics.h>structdimension_descriptor
{
int32_t lower_bound, length;
};
structArrayWrapped {
void* array;
};
structi32
{
int32_t *data;
structdimension_descriptor dims[32];
int32_t n_dims;
bool is_allocated;
};
inlinevoidstruct_deepcopy_ArrayWrapped(structArrayWrapped* src, structArrayWrapped* dest);
// Implementationsint32_t__lpython_overloaded_4___lpython_floordiv(int32_t a, int32_t b)
{
int32_t _lpython_return_variable;
double r;
int32_t result;
r = (double)(a)/(double)(b);
result = (int32_t)(r);
if (r >= 0.00000000000000000e+00 || (double)(result) == r) {
_lpython_return_variable = result;
return _lpython_return_variable;
}
_lpython_return_variable = result - 1;
return _lpython_return_variable;
}
int32_t__lpython_overloaded_2___mod(int32_t a, int32_t b)
{
int32_t _lpython_return_variable;
_lpython_return_variable = a - __lpython_overloaded_4___lpython_floordiv(a, b)*b;
return _lpython_return_variable;
}
float_lfortran_caimag(floatcomplex x);
double_lfortran_zaimag(doublecomplex x);
voidgpy(void* a, int32_t value, bool offset_value)
{
g(a, value, offset_value);
}
voidf(void* q_void)
{
int32_t el;
int32_t i;
structi32 q_value;
structi32* q = &q_value;
q->n_dims = 1;
q->dims[0].lower_bound = 0;
q->dims[0].length = 0;
q->data = (int32_t*) q_void;
for (i=0; i<=10 - 1; i++) {
{
void* q2;
q2 = (void*) &q->data[(i - q->dims[0].lower_bound)];
gpy(q2, i*i, (bool)(__lpython_overloaded_2___mod(i, 2)));
el = q->data[(i - q->dims[0].lower_bound)];
printf("%d\n", el);
ASSERT(el == i*i + __lpython_overloaded_2___mod(i, 2));
}
}
}
voidh(void* q_void)
{
int32_t el;
int32_t i;
structi32 q_value;
structi32* q = &q_value;
q->n_dims = 1;
q->dims[0].lower_bound = 0;
q->dims[0].length = 0;
q->data = (int32_t*) q_void;
for (i=0; i<=10 - 1; i++) {
{
el = q->data[(i - q->dims[0].lower_bound)];
printf("%d\n", el);
ASSERT(el == i*i + __lpython_overloaded_2___mod(i, 2));
}
}
}
voidrun()
{
void* a;
structArrayWrapped array_wrapped_value;
structArrayWrapped* array_wrapped = &array_wrapped_value;
structArrayWrapped array_wrapped1_value;
structArrayWrapped* array_wrapped1 = &array_wrapped1_value;
uint64_t q;
int32_t size;
void* x;
array_wrapped->array = a;
size = 10;
a = get_array(size);
ASSERT(a != NULL);
array_wrapped->array = a;
f(array_wrapped->array);
q = (uint64_t)(a);
x = (void*)(q);
array_wrapped->array = x;
f(array_wrapped->array);
struct_deepcopy_ArrayWrapped(array_wrapped, array_wrapped1);
h(array_wrapped1->array);
ASSERT(test_emit_header_ccallable() == 35);
}
void_lpython_main_program()
{
run();
}
intmain(int argc, char* argv[])
{
_lpython_set_argv(argc, argv);
_lpython_main_program();
return0;
}
voidstruct_deepcopy_ArrayWrapped(structArrayWrapped* src, structArrayWrapped* dest) {
dest->array = src->array;
}- header file:
#ifndef _TEST_BINDC_03_MY_HEADER_H
#define_TEST_BINDC_03_MY_HEADER_H
#include<complex.h>
#include<inttypes.h>
#include<stdlib.h>
#include<stdbool.h>
#include<stdio.h>
#include<string.h>
#include<lfortran_intrinsics.h>int32_ttest_emit_header_ccallable()
{
int32_t _lpython_return_variable;
int32_t i;
i = 5;
ASSERT(i == 5);
i = i*5;
_lpython_return_variable = i + 10;
return _lpython_return_variable;
}
#endifThere was a problem hiding this comment.
I think we still need a handwritten file that includes it, to be sure that all the arguments are compatible.
Yeah, you're right. ccallable needs to be updated in the LLVM backend so that it can call from C.
There was a problem hiding this comment.
The test_emit_header_ccallable must be in a C file, not a header file, otherwise the function will be generated twice by the C compiler and you will get linking errors.
Fixes#1797