Skip to content

Commit dbd6f65

Browse files
committed
FEAT: improved support for dealing with HANDLE types in extensions
Originally, HANDLE was just pointer, but I enhanced it recently to also being able define its type, so one can on native side test, type of provided handle and not just blindly throw some pointers as an arguments. In this commit it is reflected also when dealing with native extensions.
1 parent 6749aa1 commit dbd6f65

File tree

6 files changed

+95
-31
lines changed

6 files changed

+95
-31
lines changed

src/boot/types-ext.r

+3-3
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ REBOL [
1717
end 0 0
1818
unset * null
1919
none * null
20-
handle * ptr
20+
handle * handle
2121

2222
logic 4 32
2323
integer * 64
@@ -57,6 +57,6 @@ image * image
5757

5858
gob 47 ser
5959

60-
object 48 ptr
61-
module * ptr
60+
object 48 object
61+
module * object
6262

src/core/f-extension.c

+27-4
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,14 @@
3737
// Extension evaluation categories:
3838
enum {
3939
RXE_NULL, // unset
40-
RXE_PTR, // any pointer
40+
RXE_HANDLE, // handle
4141
RXE_32, // logic
4242
RXE_64, // integer, decimal, etc.
4343
RXE_SYM, // word
4444
RXE_SER, // string
4545
RXE_IMAGE, // image
4646
RXE_DATE, // from upper section
47+
RXE_OBJECT, // any object
4748
RXE_MAX
4849
};
4950

@@ -88,8 +89,12 @@ x*/ RXIARG Value_To_RXI(REBVAL *val)
8889
arg.series = VAL_SERIES(val);
8990
arg.index = VAL_INDEX(val);
9091
break;
91-
case RXE_PTR:
92+
case RXE_OBJECT:
93+
arg.addr = VAL_OBJ_FRAME(val);
94+
break;
95+
case RXE_HANDLE:
9296
arg.addr = VAL_HANDLE(val);
97+
arg.handle.type = VAL_HANDLE_TYPE(val);
9398
break;
9499
case RXE_32:
95100
arg.int32a = VAL_I32(val);
@@ -105,7 +110,7 @@ x*/ RXIARG Value_To_RXI(REBVAL *val)
105110
break;
106111
case RXE_IMAGE:
107112
arg.series = VAL_SERIES(val);
108-
arg.width = VAL_IMAGE_WIDE(val);
113+
arg.width = VAL_IMAGE_WIDE(val);
109114
arg.height = VAL_IMAGE_HIGH(val);
110115
break;
111116
case RXE_NULL:
@@ -131,8 +136,12 @@ x*/ void RXI_To_Value(REBVAL *val, RXIARG arg, REBCNT type)
131136
VAL_SERIES(val) = arg.series;
132137
VAL_INDEX(val) = arg.index;
133138
break;
134-
case RXE_PTR:
139+
case RXE_OBJECT:
140+
VAL_OBJ_FRAME(val) = arg.addr;
141+
break;
142+
case RXE_HANDLE:
135143
VAL_HANDLE(val) = arg.addr;
144+
VAL_HANDLE_TYPE(val) = arg.handle.type;
136145
break;
137146
case RXE_32:
138147
VAL_I32(val) = arg.int32a;
@@ -324,6 +333,7 @@ x*/ int Do_Callback(REBSER *obj, u32 name, RXIARG *args, RXIARG *result)
324333

325334
// Try to load the DLL file:
326335
if (!(dll = OS_OPEN_LIBRARY(name, &error))) {
336+
printf("error: %i\n", error);
327337
Trap1(RE_NO_EXTENSION, val);
328338
}
329339

@@ -476,6 +486,19 @@ x*/ int Do_Callback(REBSER *obj, u32 name, RXIARG *args, RXIARG *result)
476486
SET_FALSE(val);
477487
break;
478488
case RXR_ERROR:
489+
{
490+
const char* errmsg = frm.args[1].series;
491+
if(errmsg != NULL) {
492+
int len = strlen(errmsg);
493+
VAL_SET(val, REB_STRING);
494+
VAL_SERIES(val) = Make_Binary(len);
495+
VAL_INDEX(val) = 0;
496+
VAL_TAIL(val) = len;
497+
memcpy(VAL_BIN_HEAD(val), errmsg, len);
498+
}
499+
Trap1(RE_COMMAND_FAIL, val);
500+
}
501+
break;
479502
default:
480503
SET_UNSET(val);
481504
}

src/include/reb-defs.h

+35-1
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,21 @@
3232
#define REB_DEFS_H
3333

3434
#ifndef REB_DEF
35-
typedef void *REBSER;
35+
typedef void(*ANYFUNC)(void *);
36+
typedef struct RL_Reb_Series {
37+
void *data;
38+
u32 tail;
39+
} REBSER;
3640
typedef void *REBOBJ;
41+
typedef struct Reb_Handle {
42+
REBCNT sym; // Index of the word's symbol. Used as a handle's type!
43+
REBFLG flags; // Handle_Flags
44+
union {
45+
ANYFUNC code;
46+
REBSER *data;
47+
REBINT index;
48+
};
49+
} REBHAN;
3750
#endif
3851

3952
/* These used for access-os native function */
@@ -82,6 +95,27 @@ typedef struct rebol_met {
8295
typedef int cmp_t(const void *, const void *);
8396
void reb_qsort(void *a, size_t n, size_t es, cmp_t *cmp);
8497

98+
// Encoding_opts was originally in sys-core.h, but I moved it here so it can
99+
// be used also while makking external extensions. (oldes)
100+
101+
// Encoding options:
102+
enum encoding_opts {
103+
ENC_OPT_BIG, // big endian (not little)
104+
ENC_OPT_UTF8, // UTF-8
105+
ENC_OPT_UTF16, // UTF-16
106+
ENC_OPT_UTF32, // UTF-32
107+
ENC_OPT_BOM, // byte order marker
108+
ENC_OPT_CRLF, // CR line termination
109+
ENC_OPT_NO_COPY, // do not copy if ASCII
110+
};
111+
112+
#define ENCF_NO_COPY (1<<ENC_OPT_NO_COPY)
113+
#if OS_CRLF
114+
#define ENCF_OS_CRLF (1<<ENC_OPT_CRLF)
115+
#else
116+
#define ENCF_OS_CRLF 0
117+
#endif
118+
85119
#pragma pack()
86120

87121
#endif

src/include/reb-ext.h

+6-2
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
4141
*/
4242

43-
4443
// Value structure (for passing args to and from):
4544
#pragma pack(4)
4645
typedef union rxi_arg_val {
@@ -66,6 +65,10 @@ typedef union rxi_arg_val {
6665
int width:16;
6766
int height:16;
6867
};
68+
struct {
69+
void *ptr;
70+
REBCNT type;
71+
} handle;
6972
} RXIARG;
7073

7174
// For direct access to arg array:
@@ -107,7 +110,8 @@ typedef int (*RXICAL)(int cmd, RXIFRM *args, REBCEC *ctx);
107110
#define RXA_INDEX(f,n) (RXA_ARG(f,n).index)
108111
#define RXA_OBJECT(f,n) (RXA_ARG(f,n).addr)
109112
#define RXA_MODULE(f,n) (RXA_ARG(f,n).addr)
110-
#define RXA_HANDLE(f,n) (RXA_ARG(f,n).addr)
113+
#define RXA_HANDLE(f,n) (RXA_ARG(f,n).handle.ptr)
114+
#define RXA_HANDLE_TYPE(f,n) (RXA_ARG(f,n).handle.type)
111115
#define RXA_IMAGE(f,n) (RXA_ARG(f,n).image)
112116
#define RXA_IMAGE_BITS(f,n) ((REBYTE *)RL_SERIES((RXA_ARG(f,n).image), RXI_SER_DATA))
113117
#define RXA_IMAGE_WIDTH(f,n) (RXA_ARG(f,n).width)

src/include/sys-core.h

-18
Original file line numberDiff line numberDiff line change
@@ -268,24 +268,6 @@ enum {
268268
POL_EXEC,
269269
};
270270

271-
// Encoding options:
272-
enum encoding_opts {
273-
ENC_OPT_BIG, // big endian (not little)
274-
ENC_OPT_UTF8, // UTF-8
275-
ENC_OPT_UTF16, // UTF-16
276-
ENC_OPT_UTF32, // UTF-32
277-
ENC_OPT_BOM, // byte order marker
278-
ENC_OPT_CRLF, // CR line termination
279-
ENC_OPT_NO_COPY, // do not copy if ASCII
280-
};
281-
282-
#define ENCF_NO_COPY (1<<ENC_OPT_NO_COPY)
283-
#if OS_CRLF
284-
#define ENCF_OS_CRLF (1<<ENC_OPT_CRLF)
285-
#else
286-
#define ENCF_OS_CRLF 0
287-
#endif
288-
289271
/***********************************************************************
290272
**
291273
** Macros

src/os/host-ext-test.c

+24-3
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,15 @@ char *RX_Spec =
6868
"img0: command [{return 10x20 image}]\n"
6969
"cec0: command [{test command context struct} blk [block!]]\n"
7070
"cec1: command [{returns cec.index value or -1 if no cec}]\n"
71+
"hndl1: command [{creates a handle}]\n"
72+
"hndl2: command [{return handle's internal value as integer} hnd [handle!]]\n"
73+
"hndl3: command [{null handle's internal value} hnd [handle!]]\n"
7174

72-
"a: b: c: none\n"
75+
"a: b: c: h: none\n"
7376
"xtest: does [\n"
7477
"foreach blk [\n"
78+
"[h: hndl1]\n"
79+
"[hndl2 h]\n"
7580
"[xarg0]\n"
7681
"[xarg1 111]\n"
7782
"[xarg1 1.1]\n"
@@ -83,6 +88,7 @@ char *RX_Spec =
8388
"[xword1 {system}]\n"
8489
"[xobj1 system 'version]\n"
8590

91+
8692
// We just use this context as example. Normally, it would be
8793
// your own object that has your special functions within it.
8894
"[calls lib 'negate]\n"
@@ -97,7 +103,7 @@ char *RX_Spec =
97103
//"replace {x} {x} {y}\n"
98104
"probe do blk\n"
99105
"]\n"
100-
"prin {^/^[[7mAsync call result should be printed:^[[0m }"
106+
"prin {^/^[[7mAsync call result (should be printed 1234):^[[0m }"
101107
"wait 0.1 ; let async events happen\n"
102108
"exit\n"
103109
"]\n"
@@ -228,7 +234,22 @@ RXIEXT int RX_Call(int cmd, RXIFRM *frm, void *ctx) {
228234
RXA_INT64(frm, 1) = (i64)(cec ? cec->index : -1);
229235
RXA_TYPE(frm, 1) = RXT_INTEGER;
230236
}
231-
237+
break;
238+
239+
case 11: //command [{creates a handle}]"
240+
{
241+
RXA_HANDLE(frm, 1) = (void*)42;
242+
RXA_HANDLE_TYPE(frm, 1) = RL_MAP_WORD("xtest");
243+
RXA_TYPE(frm, 1) = RXT_HANDLE;
244+
}
245+
break;
246+
247+
case 12: //command [{return handle's internal value as integer} hnd [handle!]]"
248+
{
249+
i64 i = (i64)RXA_HANDLE(frm, 1);
250+
RXA_INT64(frm, 1) = i;
251+
RXA_TYPE(frm, 1) = RXT_INTEGER;
252+
}
232253
break;
233254

234255
default:

0 commit comments

Comments
 (0)