fx: support for registering callable functions with types

This commit is contained in:
2026-05-05 21:16:31 +01:00
parent 703155affe
commit f3062222cb
16 changed files with 182 additions and 25 deletions
+2 -2
View File
@@ -1,7 +1,7 @@
#include <fx/macros.h>
#include <fx/reflection/assembly.h>
FX_ASSEMBLY_BEGIN()
FX_ASSEMBLY_BEGIN(fx_cmdline)
FX_ASSEMBLY_NAME("fx.cmdline");
FX_ASSEMBLY_VERSION(1, 0, 0, 0);
FX_ASSEMBLY_END()
FX_ASSEMBLY_END(fx_cmdline)
+2 -2
View File
@@ -1,7 +1,7 @@
#include <fx/macros.h>
#include <fx/reflection/assembly.h>
FX_ASSEMBLY_BEGIN()
FX_ASSEMBLY_BEGIN(fx_compression)
FX_ASSEMBLY_NAME("fx.compression");
FX_ASSEMBLY_VERSION(1, 0, 0, 0);
FX_ASSEMBLY_END()
FX_ASSEMBLY_END(fx_compression)
+4 -4
View File
@@ -1,7 +1,7 @@
#include <fx/macros.h>
#include <fx/reflection/assembly.h>
FX_ASSEMBLY_BEGIN()
FX_ASSEMBLY_NAME("fx.io");
FX_ASSEMBLY_VERSION(1, 0, 0, 0);
FX_ASSEMBLY_END()
FX_ASSEMBLY_BEGIN(fx_io)
FX_ASSEMBLY_NAME("fx.io");
FX_ASSEMBLY_VERSION(1, 0, 0, 0);
FX_ASSEMBLY_END(fx_io)
+2 -2
View File
@@ -1,7 +1,7 @@
#include <fx/macros.h>
#include <fx/reflection/assembly.h>
FX_ASSEMBLY_BEGIN()
FX_ASSEMBLY_BEGIN(fx_runtime)
FX_ASSEMBLY_NAME("fx.runtime");
FX_ASSEMBLY_VERSION(1, 0, 0, 0);
FX_ASSEMBLY_EXPORT_TYPE("fx", "stream", fx_stream);
@@ -9,4 +9,4 @@ FX_ASSEMBLY_BEGIN()
FX_ASSEMBLY_EXPORT_TYPE("fx", "stringstream", fx_stringstream);
FX_ASSEMBLY_EXPORT_TYPE("fx", "iterator", fx_iterator);
FX_ASSEMBLY_EXPORT_TYPE("fx.reflection", "assembly", fx_assembly);
FX_ASSEMBLY_END()
FX_ASSEMBLY_END(fx_runtime)
+2 -2
View File
@@ -1,7 +1,7 @@
#include <fx/macros.h>
#include <fx/reflection/assembly.h>
FX_ASSEMBLY_BEGIN()
FX_ASSEMBLY_BEGIN(fx_serial)
FX_ASSEMBLY_NAME("fx.serial");
FX_ASSEMBLY_VERSION(1, 0, 0, 0);
FX_ASSEMBLY_END()
FX_ASSEMBLY_END(fx_serial)
+2 -2
View File
@@ -1,7 +1,7 @@
#include <fx/macros.h>
#include <fx/reflection/assembly.h>
FX_ASSEMBLY_BEGIN()
FX_ASSEMBLY_BEGIN(fx_term)
FX_ASSEMBLY_NAME("fx.term");
FX_ASSEMBLY_VERSION(1, 0, 0, 0);
FX_ASSEMBLY_END()
FX_ASSEMBLY_END(fx_term)
+19 -3
View File
@@ -22,6 +22,11 @@ struct fx_function_p {
/*** PRIVATE FUNCTIONS ********************************************************/
static const char *function_get_name(const struct fx_function_p *func)
{
return func->func_name;
}
static fx_status function_bind(
struct fx_function_p *func,
fx_value *args,
@@ -98,10 +103,9 @@ static fx_status function_invoke(
return FX_SUCCESS;
}
/*** PUBLIC FUNCTIONS
* *********************************************************/
/*** PUBLIC FUNCTIONS *********************************************************/
FX_API fx_function *fx_function_create(
fx_function *fx_function_create(
const char *name,
fx_function_flags flags,
fx_function_impl impl,
@@ -118,6 +122,10 @@ FX_API fx_function *fx_function_create(
func,
FX_REFLECTION_TYPE_FUNCTION);
if (nr_args == 1 && args[0] == FX_VALUE_TYPE_NONE) {
nr_args = 0;
}
p->func_name = fx_strdup(name);
p->func_flags = flags;
p->func_impl = impl;
@@ -131,6 +139,14 @@ FX_API fx_function *fx_function_create(
return func;
}
const char *fx_function_get_name(const fx_function *func)
{
FX_CLASS_DISPATCH_STATIC_0(
FX_REFLECTION_TYPE_FUNCTION,
function_get_name,
func);
}
fx_status fx_function_bind(fx_function *func, fx_value *args, size_t nr_args)
{
FX_CLASS_DISPATCH_STATIC(
@@ -14,6 +14,7 @@ typedef enum fx_function_flags {
FX_FUNCTION_F_STATIC = 0x01u,
FX_FUNCTION_F_VIRTUAL = 0x02u,
FX_FUNCTION_F_VARARG = 0x04u,
FX_FUNCTION_F_CONSTRUCTOR = 0x08u,
} fx_function_flags;
typedef void (*fx_function_impl)();
@@ -25,6 +26,8 @@ FX_TYPE_CLASS_DECLARATION_END(fx_function)
FX_API fx_type_id fx_function_get_type();
FX_API const char *fx_function_get_name(const fx_function *func);
FX_API fx_function *fx_function_create(
const char *name,
fx_function_flags flags,
@@ -2,6 +2,7 @@
#define FX_REFLECTION_TYPE_H_
#include <fx/macros.h>
#include <fx/reflection/function.h>
FX_DECLS_BEGIN;
@@ -17,6 +18,9 @@ FX_TYPE_CLASS_DECLARATION_END(fx_type)
FX_API fx_type_id fx_type_get_type();
FX_API const char *fx_type_get_name(const fx_type *ty);
FX_API const fx_function *fx_type_get_function(
const fx_type *ty,
const char *name);
FX_API const fx_type *fx_type_get_by_id(fx_type_id id);
FX_API const fx_type *fx_type_get_by_name(const char *name);
+19
View File
@@ -12,12 +12,22 @@ struct fx_type_p {
extern struct fx_type_info *fx_type_info_get_by_id(const union fx_type_id *key);
extern struct fx_type_info *fx_type_info_get_by_name(const char *name);
extern fx_function *fx_type_info_get_function_by_name(
const struct fx_type_info *ty,
const char *name);
static const char *type_get_name(const struct fx_type_p *ty)
{
return ty->ty_info->ty_name;
}
const fx_function *type_get_function(
const struct fx_type_p *ty,
const char *name)
{
return fx_type_info_get_function_by_name(ty->ty_info, name);
}
/*** PUBLIC FUNCTIONS *********************************************************/
fx_type *__fx_type_create(struct fx_type_info *type_info)
@@ -40,6 +50,15 @@ const char *fx_type_get_name(const fx_type *ty)
FX_CLASS_DISPATCH_STATIC_0(FX_REFLECTION_TYPE_TYPE, type_get_name, ty);
}
const fx_function *fx_type_get_function(const fx_type *ty, const char *name)
{
FX_CLASS_DISPATCH_STATIC(
FX_REFLECTION_TYPE_TYPE,
type_get_function,
ty,
name);
}
const fx_type *fx_type_get_by_id(fx_type_id id)
{
struct fx_type_info *ty = fx_type_info_get_by_id(id);
+8 -1
View File
@@ -73,9 +73,16 @@ fx_result fx_class_instantiate(
c_entry);
const struct fx_type_info *class_info = comp->c_type;
void *class_data = (char *)out + comp->c_class_data_offset;
struct fx_type_info *main_class_param = NULL;
if (class_info == type) {
main_class_param = type;
}
if (class_info->ty_class_init) {
class_info->ty_class_init(out, class_data);
class_info->ty_class_init(
out,
main_class_param,
class_data);
}
entry = fx_queue_next(entry);
+49 -5
View File
@@ -5,6 +5,7 @@
#include <fx/object.h>
#include <fx/thread.h>
#include <fx/type.h>
#include <fx/value.h>
#include <stdlib.h>
#define __FX_IFACE_I0(p, x) p##x
@@ -13,7 +14,10 @@
/* Type definitions macros (for use in .c source file) */
#define FX_TYPE_CLASS_BEGIN(type_name) \
static void type_name##_class_init(fx_class *p, void *d) \
static void type_name##_class_init( \
fx_class *p, \
fx_type_info *ty, \
void *d) \
{
#define FX_TYPE_CLASS_END(type_name) }
@@ -21,9 +25,49 @@
static void type_name##_type_functionality_init(void *opaque) \
{
#define FX_TYPE_FUNCTIONALITY_END(type_name) }
#define FX_TYPE_CONSTRUCTOR(name, impl, ...)
#define FX_TYPE_METHOD(return_type, name, impl, ...)
#define FX_TYPE_FUNCTION(return_type, name, impl, ...)
#define FX_TYPE_CONSTRUCTOR(name, impl, flags, ...) \
do { \
if (ty) { \
fx_value_type args[] = {__VA_ARGS__}; \
fx_function *func = fx_function_create( \
name, \
FX_FUNCTION_F_CONSTRUCTOR \
| FX_FUNCTION_F_STATIC | (flags), \
(fx_function_impl)impl, \
args, \
sizeof args / sizeof args[0], \
FX_VALUE_TYPE_POINTER); \
fx_type_add_function(ty, func); \
} \
} while (0)
#define FX_TYPE_METHOD(return_type, name, impl, flags, ...) \
do { \
if (ty) { \
fx_value_type args[] = {__VA_ARGS__}; \
fx_function *func = fx_function_create( \
name, \
(flags), \
(fx_function_impl)impl, \
args, \
sizeof args / sizeof args[0], \
return_type); \
fx_type_add_function(ty, func); \
} \
} while (0)
#define FX_TYPE_FUNCTION(return_type, name, impl, ...) \
do { \
if (ty) { \
fx_value_type args[] = {__VA_ARGS__}; \
fx_function *func = fx_function_create( \
name, \
FX_FUNCTION_F_STATIC | (flags), \
(fx_function_impl)impl, \
args, \
sizeof args / sizeof args[0], \
return_type); \
fx_type_add_function(ty, func); \
} \
} while (0)
#define FX_TYPE_VTABLE_INTERFACE_BEGIN(interface_name, interface_id) \
interface_name##_class *__FX_IFACE_I1(iface, __LINE__) \
@@ -43,7 +87,7 @@
#define FX_TYPE_DEFINITION_BEGIN(name) \
static fx_type_info name##_type_info = {0}; \
static void name##_class_init(fx_class *, void *); \
static void name##_class_init(fx_class *, fx_type_info *, void *); \
static void name##_type_init(void) \
{ \
fx_type_info *type_info = &name##_type_info; \
+7 -1
View File
@@ -14,8 +14,12 @@
struct _fx_class;
struct _fx_object;
struct fx_type_info;
typedef void (*fx_class_init_function)(struct _fx_class *, void *);
typedef void (*fx_class_init_function)(
struct _fx_class *,
struct fx_type_info *,
void *);
typedef void (*fx_instance_init_function)(struct _fx_object *, void *);
typedef void (*fx_instance_fini_function)(struct _fx_object *, void *);
@@ -86,5 +90,7 @@ static inline int fx_type_id_compare(fx_type_id a, fx_type_id b)
}
FX_API fx_result fx_type_register(fx_type_info *info);
FX_API fx_result
fx_type_add_function(fx_type_info *info, struct _fx_object *func);
#endif
+14
View File
@@ -1,4 +1,5 @@
#include <ctype.h>
#include <fx/reflection/function.h>
#include <fx/stream.h>
#include <fx/string.h>
#include <fx/stringstream.h>
@@ -1716,6 +1717,19 @@ FX_TYPE_CLASS_BEGIN(fx_string)
FX_INTERFACE_ENTRY(it_begin) = iterator_begin;
FX_INTERFACE_ENTRY(it_cbegin) = iterator_cbegin;
FX_TYPE_VTABLE_INTERFACE_END(fx_iterable, FX_TYPE_ITERABLE)
FX_TYPE_CONSTRUCTOR("create", fx_string_create, 0, FX_VALUE_TYPE_NONE);
FX_TYPE_CONSTRUCTOR(
"create_from_cstr",
fx_string_create_from_cstr,
1,
FX_VALUE_TYPE_CSTR);
FX_TYPE_METHOD(
FX_VALUE_TYPE_CSTR,
"get_cstr",
fx_string_get_cstr,
0,
FX_VALUE_TYPE_POINTER);
FX_TYPE_CLASS_END(fx_string)
FX_TYPE_DEFINITION_BEGIN(fx_string)
+40
View File
@@ -6,6 +6,7 @@
#include <fx/bst.h>
#include <fx/endian.h>
#include <fx/object.h>
#include <fx/reflection/function.h>
#include <fx/type.h>
#include <stdio.h>
#include <stdlib.h>
@@ -343,6 +344,29 @@ fx_result fx_type_register(struct fx_type_info *info)
return FX_RESULT_SUCCESS;
}
fx_result fx_type_add_function(fx_type_info *info, struct _fx_object *func)
{
const char *name = fx_function_get_name(func);
struct fx_namemap_entry *entry = fx_namemap_get(
&info->ty_functions,
name);
if (entry) {
return FX_RESULT_ERR(NAME_EXISTS);
}
struct fx_type_function *ty_func = malloc(sizeof *ty_func);
if (!ty_func) {
return FX_RESULT_ERR(NO_MEMORY);
}
memset(ty_func, 0x0, sizeof *ty_func);
ty_func->f_func = func;
fx_namemap_put(&info->ty_functions, name, &ty_func->f_entry);
return FX_RESULT_SUCCESS;
}
struct fx_type_info *fx_type_info_get_by_id(const union fx_type_id *key)
{
return get_type(&type_idmap, key);
@@ -357,3 +381,19 @@ struct fx_type_info *fx_type_info_get_by_name(const char *name)
return fx_unbox(struct fx_type_info, entry, ty_namemap_entry);
}
fx_function *fx_type_info_get_function_by_name(
const struct fx_type_info *ty,
const char *name)
{
fx_namemap_entry *entry = fx_namemap_get(&ty->ty_functions, name);
if (!entry) {
return NULL;
}
struct fx_type_function *func = fx_unbox(
struct fx_type_function,
entry,
f_entry);
return func->f_func;
}
+5 -1
View File
@@ -4,6 +4,7 @@
#include <fx/bst.h>
#include <fx/namemap.h>
#include <fx/queue.h>
#include <fx/reflection/function.h>
#include <fx/reflection/type.h>
#include <fx/type.h>
#include <stddef.h>
@@ -20,7 +21,7 @@ struct fx_type_component {
struct fx_type_function {
struct fx_namemap_entry f_entry;
struct fx_function *f_func;
fx_function *f_func;
};
extern struct fx_type_registration *fx_type_get_registration(fx_type_id id);
@@ -29,5 +30,8 @@ extern struct fx_type_component *fx_type_get_component(
const union fx_type_id *key);
extern struct fx_type_info *fx_type_info_get_by_id(const union fx_type_id *key);
extern struct fx_type_info *fx_type_info_get_by_name(const char *name);
extern fx_function *fx_type_info_get_function_by_name(
const struct fx_type_info *ty,
const char *name);
#endif