mirror of
				https://github.com/janet-lang/janet
				synced 2025-10-31 15:43:01 +00:00 
			
		
		
		
	Add JANET_MARSH_UNSAFE flag.
This allows unmarshal to optional marshal raw pointers and cfunctions and send them across threads. This flag is only exposed in the C API as it is very easy to misuse and cause segfaults.
This commit is contained in:
		| @@ -61,7 +61,9 @@ enum { | ||||
|     LB_ABSTRACT, /* 217 */ | ||||
|     LB_REFERENCE, /* 218 */ | ||||
|     LB_FUNCENV_REF, /* 219 */ | ||||
|     LB_FUNCDEF_REF /* 220 */ | ||||
|     LB_FUNCDEF_REF, /* 220 */ | ||||
|     LB_UNSAFE_CFUNCTION, /* 221 */ | ||||
|     LB_UNSAFE_POINTER /* 222 */ | ||||
| } LeadBytes; | ||||
|  | ||||
| /* Helper to look inside an entry in an environment */ | ||||
| @@ -563,9 +565,25 @@ static void marshal_one(MarshalState *st, Janet x, int flags) { | ||||
|             marshal_one_fiber(st, janet_unwrap_fiber(x), flags + 1); | ||||
|             return; | ||||
|         } | ||||
|         case JANET_CFUNCTION: { | ||||
|             if (!(flags & JANET_MARSHAL_UNSAFE)) goto no_registry; | ||||
|             MARK_SEEN(); | ||||
|             pushbyte(st, LB_UNSAFE_CFUNCTION); | ||||
|             JanetCFunction cfn = janet_unwrap_cfunction(x); | ||||
|             pushbytes(st, (uint8_t *) &cfn, sizeof(JanetCFunction)); | ||||
|             return; | ||||
|         } | ||||
|         case JANET_POINTER: { | ||||
|             if (!(flags & JANET_MARSHAL_UNSAFE)) goto no_registry; | ||||
|             MARK_SEEN(); | ||||
|             pushbyte(st, LB_UNSAFE_POINTER); | ||||
|             void *ptr = janet_unwrap_pointer(x); | ||||
|             pushbytes(st, (uint8_t *) &ptr, sizeof(void *)); | ||||
|             return; | ||||
|         } | ||||
|     no_registry: | ||||
|         default: { | ||||
|             janet_panicf("no registry value and cannot marshal %p", x); | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
| #undef MARK_SEEN | ||||
| @@ -1293,6 +1311,42 @@ static const uint8_t *unmarshal_one( | ||||
|             } | ||||
|             return data; | ||||
|         } | ||||
|         case LB_UNSAFE_POINTER: { | ||||
|             MARSH_EOS(st, data + sizeof(void *)); | ||||
|             data++; | ||||
|             if (!(flags & JANET_MARSHAL_UNSAFE)) { | ||||
|                 janet_panicf("unsafe flag not given, " | ||||
|                              "will not unmarshal raw pointer at index %d", | ||||
|                              (int)(data - st->start)); | ||||
|             } | ||||
|             union { | ||||
|                 void *ptr; | ||||
|                 uint8_t bytes[sizeof(void *)]; | ||||
|             } u; | ||||
|             memcpy(u.bytes, data, sizeof(void *)); | ||||
|             data += sizeof(void *); | ||||
|             *out = janet_wrap_pointer(u.ptr); | ||||
|             janet_v_push(st->lookup, *out); | ||||
|             return data; | ||||
|         } | ||||
|         case LB_UNSAFE_CFUNCTION: { | ||||
|             MARSH_EOS(st, data + sizeof(JanetCFunction)); | ||||
|             data++; | ||||
|             if (!(flags & JANET_MARSHAL_UNSAFE)) { | ||||
|                 janet_panicf("unsafe flag not given, " | ||||
|                              "will not unmarshal function pointer at index %d", | ||||
|                              (int)(data - st->start)); | ||||
|             } | ||||
|             union { | ||||
|                 JanetCFunction ptr; | ||||
|                 uint8_t bytes[sizeof(JanetCFunction)]; | ||||
|             } u; | ||||
|             memcpy(u.bytes, data, sizeof(JanetCFunction)); | ||||
|             data += sizeof(JanetCFunction); | ||||
|             *out = janet_wrap_cfunction(u.ptr); | ||||
|             janet_v_push(st->lookup, *out); | ||||
|             return data; | ||||
|         } | ||||
|         default: { | ||||
|             janet_panicf("unknown byte %x at index %d", | ||||
|                          *data, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Calvin Rose
					Calvin Rose