Skip to content

Commit 9249a36

Browse files
committed
FEAT: exporting new library functions for registering, creation and releasing handles (so these may be also used from external native modules.
1 parent 77e026c commit 9249a36

File tree

3 files changed

+62
-3
lines changed

3 files changed

+62
-3
lines changed

src/core/a-lib.c

+54
Original file line numberDiff line numberDiff line change
@@ -1121,6 +1121,60 @@ RL_API REBSER* RL_Decode_UTF_String(REBYTE *src, REBCNT len, REBINT utf, REBFLG
11211121
return Decode_UTF_String(src, len, utf, ccr, uni);
11221122
}
11231123

1124+
/***********************************************************************
1125+
**
1126+
*/ RL_API REBCNT RL_Register_Handle(REBYTE *name, REBCNT size, void* free_func)
1127+
/*
1128+
** Stores handle's specification (required data size and optional free callback.
1129+
**
1130+
** Returns:
1131+
** table index for the word (whether found or new)
1132+
** or NOT_FOUND if handle with give ID is already registered.
1133+
** Arguments:
1134+
** name - handle's name as a c-string (length is being detected)
1135+
** size - size of needed memory to handle
1136+
** free_func - custom function to be called when handle is released
1137+
**
1138+
***********************************************************************/
1139+
{
1140+
REBCNT sym;
1141+
REBCNT len;
1142+
// Convert C-string to Rebol word
1143+
len = strlen(cs_cast(name));
1144+
sym = Scan_Word(name, len);
1145+
if (!sym) return NOT_FOUND; //TODO: use different value if word is invalid?
1146+
return Register_Handle(sym, size, (REB_HANDLE_FREE_FUNC)free_func);
1147+
}
1148+
1149+
RL_API REBHOB* RL_Make_Handle_Context(REBCNT sym)
1150+
/*
1151+
** Allocates memory large enough to hold given handle's id
1152+
**
1153+
** Returns:
1154+
** A pointer to a Rebol's handle value.
1155+
** Arguments:
1156+
** sym - handle's word id
1157+
**
1158+
***********************************************************************/
1159+
{
1160+
return Make_Handle_Context(sym);
1161+
}
1162+
1163+
RL_API void RL_Free_Handle_Context(REBHOB *hob)
1164+
/*
1165+
** Frees memory of given handle's context
1166+
**
1167+
** Returns:
1168+
** nothing
1169+
** Arguments:
1170+
** hob - handle's context
1171+
**
1172+
***********************************************************************/
1173+
{
1174+
Free_Hob(hob);
1175+
}
1176+
1177+
11241178

11251179

11261180
#include "reb-lib-lib.h"

src/include/reb-ext.h

+6-2
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,9 @@ typedef union rxi_arg_val {
6868
};
6969
struct {
7070
void *ptr;
71-
REBCNT type;
71+
REBCNT type; // Handle's name (symbol)
72+
REBFLG flags:16; // Handle_Flags
73+
REBCNT index:16; // Index into Reb_Handle_Spec value
7274
} handle;
7375
} RXIARG;
7476

@@ -113,7 +115,9 @@ typedef int (*RXICAL)(int cmd, RXIFRM *args, REBCEC *ctx);
113115
#define RXA_MODULE(f,n) (RXA_ARG(f,n).addr)
114116
#define RXA_HANDLE(f,n) (RXA_ARG(f,n).handle.ptr)
115117
#define RXA_HANDLE_TYPE(f,n) (RXA_ARG(f,n).handle.type)
116-
#define RXA_IMAGE(f,n) (RXA_ARG(f,n).image)
118+
#define RXA_HANDLE_FLAGS(f,n) (RXA_ARG(f,n).handle.flags)
119+
#define RXA_HANDLE_INDEX(f,n) (RXA_ARG(f,n).handle.index)
120+
#define RXA_IMAGE(f,n) (RXA_ARG(f,n).image)
117121
#define RXA_IMAGE_BITS(f,n) ((REBYTE *)RL_SERIES((RXA_ARG(f,n).image), RXI_SER_DATA))
118122
#define RXA_IMAGE_WIDTH(f,n) (RXA_ARG(f,n).width)
119123
#define RXA_IMAGE_HEIGHT(f,n) (RXA_ARG(f,n).height)

src/include/sys-value.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -1075,6 +1075,7 @@ enum Handle_Flags {
10751075
HANDLE_CONTEXT = 1 << 2,
10761076
HANDLE_CONTEXT_MARKED = 1 << 3, // used in handle's context (HOB)
10771077
HANDLE_CONTEXT_USED = 1 << 4, // --//--
1078+
HANDLE_CONTEXT_LOCKED = 1 << 5, // so Rebol will not GC the handle if C side still depends on it
10781079
};
10791080

10801081
typedef struct Reb_Handle_Spec {
@@ -1131,7 +1132,7 @@ typedef struct Reb_Handle {
11311132
#define IS_USED_HOB(h) ((h)->flags & HANDLE_CONTEXT_USED) // used to detect if handle's context is still valid
11321133
#define USE_HOB(h) ((h)->flags |= HANDLE_CONTEXT_USED)
11331134
#define UNUSE_HOB(h) ((h)->flags &= ~HANDLE_CONTEXT_USED)
1134-
#define IS_MARK_HOB(h) ((h)->flags & HANDLE_CONTEXT_MARKED) // GC marks still used handles, so these are not released
1135+
#define IS_MARK_HOB(h) ((h)->flags & (HANDLE_CONTEXT_MARKED | HANDLE_CONTEXT_LOCKED)) // GC marks still used handles, so these are not released
11351136
#define MARK_HOB(h) ((h)->flags |= HANDLE_CONTEXT_MARKED)
11361137
#define UNMARK_HOB(h) ((h)->flags &= ~HANDLE_CONTEXT_MARKED)
11371138
#define MARK_HANDLE_CONTEXT(v) (MARK_HOB(VAL_HANDLE_CTX(v)))

0 commit comments

Comments
 (0)