Skip to content

Commit cd52e41

Browse files
committed
Add dyncall integration (WIP)
1 parent d36003e commit cd52e41

6 files changed

Lines changed: 153 additions & 6 deletions

File tree

codegen/metac_codegen.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1078,7 +1078,17 @@ static void MetaCCodegen_doExpr(metac_bytecode_ctx_t* ctx,
10781078

10791079
if (op == expr_signed_integer)
10801080
{
1081-
(*result) = imm32_(cast(int32_t)exp->ValueI64, true);
1081+
int32_t typeIndexIndex = TYPE_INDEX_INDEX(exp->TypeIndex);
1082+
bool isSigned = TypeIndex_isSigned(exp->TypeIndex);
1083+
if (typeIndexIndex == type_long_long
1084+
|| typeIndexIndex == type_unsigned_long_long)
1085+
{
1086+
(*result) = imm64_(exp->ValueI64, isSigned);
1087+
}
1088+
else
1089+
{
1090+
(*result) = imm32_(cast(int32_t)exp->ValueI64, isSigned);
1091+
}
10821092
goto Lret;
10831093
}
10841094
else if (op == expr_char)

libinterpret/bc_common.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@
2828
#endif
2929

3030
static const uint32_t skipFn = UINT32_MAX;
31-
static const uint32_t nodeFromName = UINT32_MAX - 1;
32-
static const uint32_t currentScope = UINT32_MAX - 2;
3331

3432
#define CONSTEXPR
3533

libinterpret/bc_dyncall.c

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
#include <dyncall.h>
2+
3+
#include "bc_common.h"
4+
// ============================================================
5+
// BCValue → libdyncall Argument
6+
// ============================================================
7+
static void PushArg(DCCallVM* vm, const BCValue* arg)
8+
{
9+
switch (arg->type.type)
10+
{
11+
case BCTypeEnum_i8:
12+
case BCTypeEnum_i16:
13+
case BCTypeEnum_i32:
14+
dcArgInt(vm, arg->imm32.imm32);
15+
break;
16+
17+
case BCTypeEnum_u8:
18+
case BCTypeEnum_u16:
19+
case BCTypeEnum_u32:
20+
dcArgInt(vm, (int32_t)arg->imm32.imm32);
21+
break;
22+
23+
case BCTypeEnum_i64:
24+
dcArgLongLong(vm, arg->imm64.imm64);
25+
break;
26+
27+
case BCTypeEnum_u64:
28+
dcArgLongLong(vm, (long long)arg->imm64.imm64);
29+
break;
30+
31+
case BCTypeEnum_f23:
32+
dcArgFloat(vm, *(float*)&arg->imm32.imm32);
33+
break;
34+
35+
case BCTypeEnum_f52:
36+
dcArgDouble(vm, *(double*)&arg->imm64.imm64);
37+
break;
38+
39+
case BCTypeEnum_Ptr:
40+
case BCTypeEnum_Function:
41+
dcArgPointer(vm, (void*)(uintptr_t)arg->imm64.imm64);
42+
break;
43+
44+
default:
45+
assert(!"Unsupported arg type for external call");
46+
}
47+
}
48+
49+
void DynCallExternal(void* funcPtr, BCType returnType, BCValue* args,
50+
uint32_t argCount, BCValue* result)
51+
{
52+
DCCallVM* vm = dcNewCallVM(4096);
53+
dcMode(vm, DC_CALL_C_DEFAULT);
54+
55+
for (uint32_t i = 0; i < argCount; i++)
56+
{
57+
PushArg(vm, &args[i]);
58+
}
59+
60+
switch (returnType.type)
61+
{
62+
case BCTypeEnum_Void:
63+
dcCallVoid(vm, funcPtr);
64+
memset(result, 0, sizeof(*result));
65+
break;
66+
case BCTypeEnum_i8:
67+
case BCTypeEnum_i16:
68+
case BCTypeEnum_i32:
69+
result->imm32.imm32 = (dcCallInt(vm, funcPtr), true); break;
70+
case BCTypeEnum_u8:
71+
case BCTypeEnum_u16:
72+
case BCTypeEnum_u32:
73+
result->imm32.imm32 = (dcCallInt(vm, funcPtr)); break;
74+
case BCTypeEnum_i64:
75+
result->imm64.imm64 = (dcCallLongLong(vm, funcPtr), true); break;
76+
case BCTypeEnum_u64:
77+
result->imm64.imm64 = ((uint64_t)dcCallLongLong(vm, funcPtr)); break;
78+
case BCTypeEnum_f23:
79+
result->imm32.imm32 = (*(uint32_t*)&(float){dcCallFloat(vm, funcPtr)}); break;
80+
case BCTypeEnum_f52:
81+
result->imm64.imm64 = (*(uint64_t*)&(double){dcCallDouble(vm, funcPtr)}); break;
82+
case BCTypeEnum_Ptr:
83+
case BCTypeEnum_Function:
84+
result->imm64.imm64 = ((uint64_t)(uintptr_t)dcCallPointer(vm, funcPtr)); break;
85+
default:
86+
assert(!"Unsupported return type");
87+
}
88+
89+
dcFree(vm);
90+
}
91+
92+
93+
94+
/*
95+
static void PushArg(DCCallVM* vm, const BCValue* arg)
96+
{
97+
switch (arg->type.type)
98+
{
99+
case BCTypeEnum_i8: dcArgChar(vm, (char)arg->imm32.imm32); break;
100+
case BCTypeEnum_u8: dcArgChar(vm, (char)arg->imm32.imm32); break;
101+
case BCTypeEnum_i16: dcArgShort(vm, (short)arg->imm32.imm32); break;
102+
case BCTypeEnum_u16: dcArgShort(vm, (short)arg->imm32.imm32); break;
103+
case BCTypeEnum_i32: dcArgInt(vm, arg->imm32.imm32); break;
104+
case BCTypeEnum_u32: dcArgInt(vm, (int)arg->imm32.imm32); break;
105+
case BCTypeEnum_i64: dcArgLongLong(vm, arg->imm64.imm64); break;
106+
case BCTypeEnum_u64: dcArgLongLong(vm, (long long)arg->imm64.imm64); break;
107+
case BCTypeEnum_f23: dcArgFloat(vm, arg->imm32.f32); break;
108+
case BCTypeEnum_f52: dcArgDouble(vm, arg->imm64.f64); break;
109+
case BCTypeEnum_Ptr:
110+
case BCTypeEnum_Function:
111+
dcArgPointer(vm, (void*)(uintptr_t)arg->imm64.imm64);
112+
break;
113+
default:
114+
assert(!"Unsupported arg type");
115+
}
116+
}
117+
118+
}
119+
*/

libinterpret/make_dyncall.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/bin/sh
2+
CC=cc
3+
$CC -o bc_dyncall.o bc_dyncall.c -I../3rdparty/libdyncall-1.4/ -ldyncall_s -L../3rdparty/libdyncall/1.4/libdyncall -c

printer/metac_printer.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2070,6 +2070,7 @@ static inline void PrintSemaExpr(metac_printer_t* self,
20702070
}
20712071
else if (semaExpr->Kind == expr_signed_integer)
20722072
{
2073+
//TODO sign extend ...
20732074
PrintI64(self, semaExpr->ValueI64);
20742075
}
20752076
else if (semaExpr->Kind == expr_float)

semantic/metac_type.c

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,33 @@
11
#include "metac_type.h"
22

3-
const char* type_index_kind_toChars(metac_type_index_kind_t Kind)
3+
const char* type_index_kind_toChars(metac_type_index_kind_t kind)
44
{
55
const char* result = 0;
66

77
#define CASE(KIND, VALUE) \
88
case KIND: result = #KIND; break;
99

10-
switch(Kind)
10+
switch(kind)
1111
{
1212
FOREACH_TYPE_INDEX_KIND(CASE)
1313
}
1414

1515
return result;
1616
#undef CASE
17-
}
17+
}
18+
19+
bool TypeIndex_isSigned(metac_type_index_t typeIndex)
20+
{
21+
assert(TYPE_INDEX_KIND(typeIndex) == type_index_basic);
22+
switch(TYPE_INDEX_INDEX(typeIndex))
23+
{
24+
case type_char:
25+
case type_short:
26+
case type_int:
27+
case type_long:
28+
case type_long_long:
29+
return true;
30+
}
31+
32+
return false;
33+
}

0 commit comments

Comments
 (0)