fx.reflection: fix linux compilation

This commit is contained in:
2026-05-29 20:20:19 +01:00
parent 34a8ccff95
commit 2d396ee071
2 changed files with 199 additions and 68 deletions
+198 -67
View File
@@ -1,3 +1,5 @@
#include <fx/type.h>
#include <fx/value-type.h>
#include <platform/callvm.h> #include <platform/callvm.h>
#include <stdlib.h> #include <stdlib.h>
@@ -11,100 +13,229 @@
} }
#endif #endif
void callvm_reset(struct callvm* vm, unsigned int max_fixed_args) void callvm_reset(struct callvm *vm, unsigned int max_fixed_args)
{ {
vm->vm_arg_int_count = 0; vm->vm_arg_int_count = 0;
vm->vm_arg_double_count = 0; vm->vm_arg_double_count = 0;
vm->vm_arg_fixed = max_fixed_args; vm->vm_arg_fixed = max_fixed_args;
vm->vm_arg_excess_count = 0; vm->vm_arg_excess_count = 0;
vm->vm_double_excess_count = 0; vm->vm_double_excess_count = 0;
} }
static void expand_excess(struct callvm* vm) static void expand_excess(struct callvm *vm)
{ {
size_t new_capacity = vm->vm_arg_excess_max * 2; size_t new_capacity = vm->vm_arg_excess_max * 2;
if (!new_capacity) { if (!new_capacity) {
new_capacity = 4; new_capacity = 4;
} }
void* buf = realloc( void *buf = realloc(
vm->vm_arg_excess, vm->vm_arg_excess,
new_capacity * sizeof *vm->vm_arg_excess); new_capacity * sizeof *vm->vm_arg_excess);
if (!buf) { if (!buf) {
return; return;
} }
vm->vm_arg_excess = buf; vm->vm_arg_excess = buf;
vm->vm_arg_excess_max = new_capacity; vm->vm_arg_excess_max = new_capacity;
} }
static void push_excess(struct callvm* vm, uintptr_t value) static void push_excess(struct callvm *vm, uintptr_t value)
{ {
if (vm->vm_arg_excess_count + 1 > vm->vm_arg_excess_max) { if (vm->vm_arg_excess_count + 1 > vm->vm_arg_excess_max) {
expand_excess(vm); expand_excess(vm);
} }
vm->vm_arg_excess[vm->vm_arg_excess_count++] = value; vm->vm_arg_excess[vm->vm_arg_excess_count++] = value;
vm->vm_arg_count++; vm->vm_arg_count++;
} }
static void push_int(struct callvm* vm, uintptr_t value) static void push_int(struct callvm *vm, uintptr_t value)
{ {
if (vm->vm_arg_int_count >= MAX_INT_ARGS) { if (vm->vm_arg_int_count >= MAX_INT_ARGS) {
push_excess(vm, value); push_excess(vm, value);
return; return;
} }
vm->vm_arg_int[vm->vm_arg_int_count++] = value; vm->vm_arg_int[vm->vm_arg_int_count++] = value;
vm->vm_arg_count++; vm->vm_arg_count++;
} }
static void push_double(struct callvm* vm, double value) static void push_double(struct callvm *vm, double value)
{ {
if (vm->vm_arg_double_count >= MAX_DOUBLE_ARGS) { if (vm->vm_arg_double_count >= MAX_DOUBLE_ARGS) {
push_excess(vm, *(uintptr_t*)&value); push_excess(vm, *(uintptr_t *)&value);
return; return;
} }
vm->vm_arg_double[vm->vm_arg_double_count++] = value; vm->vm_arg_double[vm->vm_arg_double_count++] = value;
vm->vm_arg_count++; vm->vm_arg_count++;
if (vm->vm_arg_count > vm->vm_arg_fixed) { if (vm->vm_arg_count > vm->vm_arg_fixed) {
vm->vm_double_excess_count++; vm->vm_double_excess_count++;
} }
} }
void callvm_push(struct callvm* vm, const fx_value* value) void callvm_push(struct callvm *vm, const fx_value *value)
{ {
switch (value->v_type.t_primitive) { if (!fx_type_is_value_type(value->v_type)) {
case FX_VALUE_TYPE_DOUBLE: push_int(vm, (uintptr_t)value->v_object);
push_double(vm, value->v_double); return;
break; }
default:
push_int(vm, (uintptr_t)value->v_pointer); unsigned int value_type = __fx_type_get_value_type(value->v_type);
break;
} switch (value_type) {
case __FX_VALUE_TYPE_BOOL:
push_int(vm, value->v_bool);
break;
case __FX_VALUE_TYPE_I16:
push_int(vm, value->v_i16);
break;
case __FX_VALUE_TYPE_U16:
push_int(vm, value->v_u16);
break;
case __FX_VALUE_TYPE_I32:
push_int(vm, value->v_i32);
break;
case __FX_VALUE_TYPE_U32:
push_int(vm, value->v_u32);
break;
case __FX_VALUE_TYPE_I64:
push_int(vm, value->v_i64);
break;
case __FX_VALUE_TYPE_U64:
push_int(vm, value->v_u64);
break;
case __FX_VALUE_TYPE_IPTR:
push_int(vm, value->v_iptr);
break;
case __FX_VALUE_TYPE_UPTR:
push_int(vm, value->v_uptr);
break;
case __FX_VALUE_TYPE_SBYTE:
push_int(vm, value->v_sbyte);
break;
case __FX_VALUE_TYPE_BYTE:
push_int(vm, value->v_byte);
break;
case __FX_VALUE_TYPE_SHORT:
push_int(vm, value->v_short);
break;
case __FX_VALUE_TYPE_USHORT:
push_int(vm, value->v_ushort);
break;
case __FX_VALUE_TYPE_INT:
push_int(vm, value->v_int);
break;
case __FX_VALUE_TYPE_UINT:
push_int(vm, value->v_uint);
break;
case __FX_VALUE_TYPE_LONG:
push_int(vm, value->v_long);
break;
case __FX_VALUE_TYPE_ULONG:
push_int(vm, value->v_ulong);
break;
case __FX_VALUE_TYPE_LONGLONG:
push_int(vm, value->v_longlong);
break;
case __FX_VALUE_TYPE_ULONGLONG:
push_int(vm, value->v_ulonglong);
break;
case __FX_VALUE_TYPE_SIZE:
push_int(vm, value->v_size);
break;
case __FX_VALUE_TYPE_FLOAT:
push_double(vm, value->v_float);
break;
case __FX_VALUE_TYPE_DOUBLE:
push_double(vm, value->v_double);
break;
case __FX_VALUE_TYPE_CSTR:
push_int(vm, (uintptr_t)value->v_cstr);
break;
case __FX_VALUE_TYPE_POINTER:
push_int(vm, (uintptr_t)value->v_pointer);
break;
default:
break;
}
} }
extern uintptr_t callvm_invoke_i(fx_function_impl impl, struct callvm* vm); extern uintptr_t callvm_invoke_i(fx_function_impl impl, struct callvm *vm);
extern double callvm_invoke_d(fx_function_impl impl, struct callvm* vm); extern double callvm_invoke_d(fx_function_impl impl, struct callvm *vm);
extern void callvm_invoke_v(fx_function_impl impl, struct callvm* vm); extern void callvm_invoke_v(fx_function_impl impl, struct callvm *vm);
fx_value callvm_invoke( fx_value callvm_invoke(
struct callvm* vm, struct callvm *vm,
fx_function_impl impl, fx_function_impl impl,
fx_value_type return_type) fx_type_id return_type)
{ {
switch (return_type) { if (!fx_type_is_value_type(return_type)) {
case FX_VALUE_TYPE_NONE: uintptr_t v = callvm_invoke_i(impl, vm);
callvm_invoke_v(impl, vm); fx_value result = {
break; .v_type = return_type,
case FX_VALUE_TYPE_DOUBLE: .v_object = (fx_object *)v,
return FX_VALUE_DOUBLE(callvm_invoke_d(impl, vm)); };
default: return result;
return FX_VALUE_INT(callvm_invoke_i(impl, vm)); }
}
return FX_VALUE_EMPTY; unsigned int value_type = __fx_type_get_value_type(return_type);
switch (value_type) {
case __FX_VALUE_TYPE_BOOL:
return FX_BOOL(callvm_invoke_i(impl, vm));
case __FX_VALUE_TYPE_I16:
return FX_I16(callvm_invoke_i(impl, vm));
case __FX_VALUE_TYPE_U16:
return FX_U16(callvm_invoke_i(impl, vm));
case __FX_VALUE_TYPE_I32:
return FX_I32(callvm_invoke_i(impl, vm));
case __FX_VALUE_TYPE_U32:
return FX_U32(callvm_invoke_i(impl, vm));
case __FX_VALUE_TYPE_I64:
return FX_I64(callvm_invoke_i(impl, vm));
case __FX_VALUE_TYPE_U64:
return FX_U64(callvm_invoke_i(impl, vm));
case __FX_VALUE_TYPE_IPTR:
return FX_IPTR(callvm_invoke_i(impl, vm));
case __FX_VALUE_TYPE_UPTR:
return FX_UPTR(callvm_invoke_i(impl, vm));
case __FX_VALUE_TYPE_SBYTE:
return FX_SBYTE(callvm_invoke_i(impl, vm));
case __FX_VALUE_TYPE_BYTE:
return FX_BYTE(callvm_invoke_i(impl, vm));
case __FX_VALUE_TYPE_SHORT:
return FX_SHORT(callvm_invoke_i(impl, vm));
case __FX_VALUE_TYPE_USHORT:
return FX_USHORT(callvm_invoke_i(impl, vm));
case __FX_VALUE_TYPE_INT:
return FX_INT(callvm_invoke_i(impl, vm));
case __FX_VALUE_TYPE_UINT:
return FX_UINT(callvm_invoke_i(impl, vm));
case __FX_VALUE_TYPE_LONG:
return FX_LONG(callvm_invoke_i(impl, vm));
case __FX_VALUE_TYPE_ULONG:
return FX_ULONG(callvm_invoke_i(impl, vm));
case __FX_VALUE_TYPE_LONGLONG:
return FX_LONGLONG(callvm_invoke_i(impl, vm));
case __FX_VALUE_TYPE_ULONGLONG:
return FX_ULONGLONG(callvm_invoke_i(impl, vm));
case __FX_VALUE_TYPE_SIZE:
return FX_SIZE(callvm_invoke_i(impl, vm));
case __FX_VALUE_TYPE_FLOAT:
return FX_FLOAT(callvm_invoke_d(impl, vm));
case __FX_VALUE_TYPE_DOUBLE:
return FX_DOUBLE(callvm_invoke_d(impl, vm));
case __FX_VALUE_TYPE_CSTR:
return FX_CSTR((const char *)callvm_invoke_i(impl, vm));
case __FX_VALUE_TYPE_POINTER:
return FX_POINTER((void *)callvm_invoke_i(impl, vm));
default:
return FX_VALUE_EMPTY;
}
return FX_VALUE_EMPTY;
} }
@@ -32,6 +32,6 @@ extern void callvm_push(struct callvm *vm, const fx_value *value);
extern fx_value callvm_invoke( extern fx_value callvm_invoke(
struct callvm *vm, struct callvm *vm,
fx_function_impl impl, fx_function_impl impl,
fx_value_type return_type); fx_type_id return_type);
#endif #endif