2026-05-04 16:33:16 +01:00
|
|
|
#ifndef FX_REFLECTION_DARWIN_ARM64_CALLVM_H_
|
|
|
|
|
#define FX_REFLECTION_DARWIN_ARM64_CALLVM_H_
|
|
|
|
|
|
|
|
|
|
#include <fx/reflection/function.h>
|
|
|
|
|
#include <fx/value.h>
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
|
2026-05-17 17:11:02 +01:00
|
|
|
#define CALLVM_INVOKE_PROTOTYPE(suffix) \
|
|
|
|
|
fx_value callvm_invoke_##suffix( \
|
|
|
|
|
struct callvm *vm, \
|
|
|
|
|
fx_function_impl impl)
|
|
|
|
|
|
2026-05-04 16:33:16 +01:00
|
|
|
#define MAX_FIXED_ARGS ((unsigned int)-1)
|
|
|
|
|
#define MAX_DOUBLE_ARGS 8
|
|
|
|
|
#define MAX_INT_ARGS 8
|
|
|
|
|
|
|
|
|
|
/* dyn-dispatch.S depends on the layout of this struct */
|
|
|
|
|
struct callvm {
|
|
|
|
|
uint64_t vm_arg_int_count;
|
|
|
|
|
uint64_t vm_arg_double_count;
|
|
|
|
|
|
|
|
|
|
/* any args pushed after this limit is reached will be stored in the
|
|
|
|
|
* excess buffer. used for calling varargs functions */
|
|
|
|
|
uint64_t vm_arg_count, vm_arg_fixed;
|
|
|
|
|
|
|
|
|
|
uint64_t vm_arg_excess_count;
|
|
|
|
|
uint64_t vm_arg_excess_max;
|
|
|
|
|
|
|
|
|
|
uintptr_t vm_arg_int[MAX_INT_ARGS];
|
|
|
|
|
double vm_arg_double[MAX_DOUBLE_ARGS];
|
|
|
|
|
uintptr_t *vm_arg_excess;
|
|
|
|
|
};
|
|
|
|
|
|
2026-05-17 17:11:02 +01:00
|
|
|
typedef fx_value (*callvm_invoke_impl)(struct callvm *, fx_function_impl);
|
|
|
|
|
|
2026-05-04 16:33:16 +01:00
|
|
|
extern void callvm_reset(struct callvm *vm, unsigned int max_fixed_args);
|
|
|
|
|
extern void callvm_push(struct callvm *vm, const fx_value *value);
|
|
|
|
|
extern fx_value callvm_invoke(
|
|
|
|
|
struct callvm *vm,
|
|
|
|
|
fx_function_impl impl,
|
2026-05-17 17:11:02 +01:00
|
|
|
fx_type_id return_type);
|
2026-05-04 16:33:16 +01:00
|
|
|
|
|
|
|
|
#endif
|