Skip to content

Commit 11e8b79

Browse files
committed
C ffi with ints works
1 parent c1eff3e commit 11e8b79

3 files changed

Lines changed: 147 additions & 25 deletions

File tree

lib/libprint.cpp

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,62 @@
55
extern "C" {
66
void print();
77
int mul(int a, int b);
8+
void test_v();
9+
int test_ii_i(int a, int b);
10+
int test_iii_i(int a, int b, int c);
11+
int test_iiii_i(int a, int b, int c, int d);
12+
int test_iiiii_i(int a, int b, int c, int d, int e);
13+
int test_iiiiii_i(int a, int b, int c, int d, int e, int f);
14+
bool test_ii_b(int a, int b);
15+
bool test_bb_b(bool a, bool b);
816
}
917

1018
void print() { printf("It's working!\n"); }
1119

12-
int mul(int a, int b) {
13-
printf("Multiplying %d and %d\n", a, b);
14-
int result = a * b;
15-
printf("Multiplication result: %d\n", result);
16-
return result;
20+
void test_v() {
21+
printf("Test: void()\n");
22+
}
23+
24+
int test_ii_i(int a, int b) {
25+
int r = a + b;
26+
printf("Test (%d, %d)\n", a, b);
27+
return r;
28+
}
29+
30+
31+
int test_iii_i(int a, int b, int c) {
32+
int r = a + b + c;
33+
printf("Test (%d, %d, %d)\n", a, b, c);
34+
return r;
35+
}
36+
37+
38+
int test_iiii_i(int a, int b, int c, int d) {
39+
int r = a + b + c + d;
40+
printf("Test (%d, %d, %d, %d)\n", a, b, c, d);
41+
return r;
42+
}
43+
44+
int test_iiiii_i(int a, int b, int c, int d, int e) {
45+
int r = a + b + c + d + e;
46+
printf("Test (%d, %d, %d, %d, %d)\n", a, b, c, d, e);
47+
return r;
48+
}
49+
50+
int test_iiiiii_i(int a, int b, int c, int d, int e, int f) {
51+
int r = a + b + c + d + e + f;
52+
printf("Test (%d, %d, %d, %d, %d, %d)\n", a, b, c, d, e, f);
53+
return r;
54+
}
55+
56+
bool test_ii_b(int a, int b) {
57+
bool r = a == b;
58+
printf("Test (%d, %d) -> %s\n", a, b, r ? "true" : "false");
59+
return r;
60+
}
61+
62+
bool test_bb_b(bool a, bool b) {
63+
bool r = a == b;
64+
printf("Test (%s, %s) -> %s\n", a ? "true" : "false", b ? "true" : "false", r ? "true" : "false");
65+
return r;
1766
}

src/executer/ExternalFunctions.cpp

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33

44
namespace ffi {
55

6-
Arguments::Arguments() : size{0}, buffer() {}
6+
Arguments::Arguments() : size{0}, buffer() {
7+
clear();
8+
}
79

810
void Arguments::addWord(word_t value) {
911
ASSURE(size < capacity, "Too many arguments added to the buffer");
@@ -97,34 +99,54 @@ qword_t ExternalFunctions::call(size_t id, const Arguments& args) {
9799
qword_t result;
98100

99101
__asm__ volatile (
100-
"movq %[args_tag], %%R10\n" // Bring arg pointer into R10
101102

102-
// ---
103+
"movq %[args_tag], %%R10\n" // Bring arg pointer into R10
103104

104-
"get_next_value_into_rax:\n"
105+
"call bring_next_value_into_rax\n"
106+
"movq %%rax, %%rdi\n" // Move the first argument into rdi
105107

106108
"cmpq $0, (%%R10)\n" // Check if type is None (0)
107109
"je label_do_call\n" // End of args
108110

109-
"add $8, %%R10\n" // Bring the pointer to the argument value
110-
"movq (%%R10), %%rdi\n" // Put into target register
111+
"call bring_next_value_into_rax\n"
112+
"movq %%rax, %%rsi\n" // Move the first argument into rsi
113+
114+
"cmpq $0, (%%R10)\n" // Check if type is None (0)
115+
"je label_do_call\n" // End of args
111116

112-
"add $8, %%R10\n" // Move to next argument
117+
"call bring_next_value_into_rax\n"
118+
"movq %%rax, %%rdx\n" // Move the first argument into rdx
113119

114-
// ---
115-
// "movq %%rax, %%rdi\n" // Move the first argument into rdi
116-
// "jump get_next_value_into_rdi\n"
120+
"cmpq $0, (%%R10)\n" // Check if type is None (0)
121+
"je label_do_call\n" // End of args
117122

123+
"call bring_next_value_into_rax\n"
124+
"movq %%rax, %%rcx\n" // Move the first argument into rcx
118125

119126
"cmpq $0, (%%R10)\n" // Check if type is None (0)
120127
"je label_do_call\n" // End of args
121128

122-
"add $8, %%R10\n" // Bring the pointer to the argument value
123-
"movq (%%R10), %%rsi\n" // Put into target register (rsi)
129+
"call bring_next_value_into_rax\n"
130+
"movq %%rax, %%r8\n" // Move the first argument into r8
124131

125-
"add $8, %%R10\n" // Move to next argument
132+
"cmpq $0, (%%R10)\n" // Check if type is None (0)
133+
"je label_do_call\n" // End of args
126134

127-
// ---
135+
"call bring_next_value_into_rax\n"
136+
"movq %%rax, %%r9\n" // Move the first argument into r9
137+
138+
"jmp label_do_call\n" // Skip the function and call the method
139+
140+
// Function bring_next_value_into_rax
141+
"bring_next_value_into_rax:\n"
142+
// These chacks would be nice to have here, but the call somehow segfaults then
143+
// " cmpq $0, (%%R10)\n" // Check if type is None (0)
144+
// " je label_do_call\n" // End of args
145+
" add $8, %%R10\n" // Bring the pointer to the argument value
146+
" movq (%%R10), %%rax\n" // Put into target register
147+
" add $8, %%R10\n" // Move to next argument
148+
" ret\n"
149+
// End of bring_next_value_into_rax
128150

129151
"label_do_call:"
130152
"call *%[fn_tag]\n"

src/mains/Tests.cpp

Lines changed: 57 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -123,14 +123,65 @@ void testFile(std::string path){
123123

124124
void testLibrary(){
125125
std::cout << "Testing library..." << std::endl;
126+
126127
ffi::ExternalFunctions externalFunctions;
127-
auto id = externalFunctions.add("print", "mul");
128128

129-
ffi::Arguments args;
130-
args.addDWord(5);
131-
args.addDWord(10);
132-
auto r = externalFunctions.call(id, args); // TODO: Args are not used yet
133-
EXPECT_EQ(50, r);
129+
auto test_ii_i = externalFunctions.add("print", "test_ii_i");
130+
{
131+
ffi::Arguments args;
132+
args.addDWord(5);
133+
args.addDWord(10);
134+
auto r = externalFunctions.call(test_ii_i, args);
135+
EXPECT_EQ(15, r);
136+
}
137+
138+
auto test_iii_i = externalFunctions.add("print", "test_iii_i");
139+
{
140+
ffi::Arguments args;
141+
args.addDWord(5);
142+
args.addDWord(10);
143+
args.addDWord(15);
144+
auto r = externalFunctions.call(test_iii_i, args);
145+
EXPECT_EQ(30, r);
146+
}
147+
148+
auto test_iiii_i = externalFunctions.add("print", "test_iiii_i");
149+
{
150+
ffi::Arguments args;
151+
args.addDWord(5);
152+
args.addDWord(10);
153+
args.addDWord(15);
154+
args.addDWord(20);
155+
auto r = externalFunctions.call(test_iiii_i, args);
156+
EXPECT_EQ(50, r);
157+
}
158+
159+
160+
auto test_iiiii_i = externalFunctions.add("print", "test_iiiii_i");
161+
{
162+
ffi::Arguments args;
163+
args.addDWord(5);
164+
args.addDWord(10);
165+
args.addDWord(15);
166+
args.addDWord(20);
167+
args.addDWord(25);
168+
auto r = externalFunctions.call(test_iiiii_i, args);
169+
EXPECT_EQ(75, r);
170+
}
171+
172+
auto test_iiiiii_i = externalFunctions.add("print", "test_iiiiii_i");
173+
{
174+
ffi::Arguments args;
175+
args.addDWord(5);
176+
args.addDWord(10);
177+
args.addDWord(15);
178+
args.addDWord(20);
179+
args.addDWord(25);
180+
args.addDWord(30);
181+
auto r = externalFunctions.call(test_iiiiii_i, args);
182+
EXPECT_EQ(105, r);
183+
}
184+
134185
std::cout << "[ OK ] Library test passed." << std::endl;
135186
}
136187

0 commit comments

Comments
 (0)