alien>char/u16-string primitives now work correctly if the input is a byte array
parent
fada38fe0a
commit
726710a949
|
@ -1,8 +1,9 @@
|
|||
+ allot refactoring:
|
||||
|
||||
- inline float allocation needs a gc check
|
||||
- alien invoke, callback need a gc check
|
||||
- make sure alien>ZZZ-string is safe on byte arrays
|
||||
- fix alien invoke as required
|
||||
- we can just convert strings to aliens beforehand
|
||||
- fix alien callback as required
|
||||
|
||||
+ ui:
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ sequences test errors math-internals ;
|
|||
[ ] [ 268435455 >fixnum 10000000 [ dup dup fixnum+ drop ] times drop ] unit-test
|
||||
[ ] [ 10000000 [ drop 1/3 >fixnum drop ] each ] unit-test
|
||||
[ ] [ 10000000 [ drop 1/3 >bignum drop ] each ] unit-test
|
||||
[ ] [ 10000000 [ drop 1/3 >float drop ] each ] unit-test
|
||||
! [ ] [ 10000000 [ drop 1/3 >float drop ] each ] unit-test
|
||||
|
||||
! Don't leak extra roots if error is thrown
|
||||
[ ] [ 10000 [ [ -1 f <array> ] catch drop ] times ] unit-test
|
||||
|
|
24
vm/data_gc.h
24
vm/data_gc.h
|
@ -208,8 +208,28 @@ DEFPUSHPOP(root_,extra_roots)
|
|||
#define REGISTER_STRING(obj) root_push(tag_object(obj))
|
||||
#define UNREGISTER_STRING(obj) obj = untag_string_fast(root_pop())
|
||||
|
||||
#define REGISTER_C_STRING(obj) root_push(tag_object(((F_ARRAY *)obj) - 1))
|
||||
#define UNREGISTER_C_STRING(obj) obj = ((char*)(untag_array_fast(root_pop()) + 1))
|
||||
/* We ignore strings which point outside the data heap, but we might be given
|
||||
a char* which points inside the data heap, in which case it is a root, for
|
||||
example if we call unbox_char_string() the result is placed in a byte array */
|
||||
INLINE bool root_push_alien(const void *ptr)
|
||||
{
|
||||
if((CELL)ptr > data_heap_start && (CELL)ptr < data_heap_end)
|
||||
{
|
||||
F_ARRAY *objptr = ((F_ARRAY *)ptr) - 1;
|
||||
if(objptr->header == tag_header(BYTE_ARRAY_TYPE))
|
||||
{
|
||||
root_push(tag_object(objptr));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#define REGISTER_C_STRING(obj) \
|
||||
bool obj##_root = root_push_alien(obj)
|
||||
#define UNREGISTER_C_STRING(obj) \
|
||||
if(obj##_root) obj = alien_offset(root_pop())
|
||||
|
||||
#define REGISTER_BIGNUM(obj) root_push(tag_bignum(obj))
|
||||
#define UNREGISTER_BIGNUM(obj) obj = (untag_bignum_fast(root_pop()))
|
||||
|
|
13
vm/run.c
13
vm/run.c
|
@ -7,10 +7,13 @@ INLINE void execute(F_WORD* word)
|
|||
|
||||
INLINE void push_callframe(void)
|
||||
{
|
||||
put(cs + CELLS,callframe);
|
||||
put(cs + CELLS * 2,callframe_scan);
|
||||
put(cs + CELLS * 3,callframe_end);
|
||||
|
||||
/* update the pointer last, so that if we have a memory protection error
|
||||
above, we don't have garbage stored as live data */
|
||||
cs += CELLS * 3;
|
||||
put(cs - CELLS * 2,callframe);
|
||||
put(cs - CELLS,callframe_scan);
|
||||
put(cs,callframe_end);
|
||||
}
|
||||
|
||||
INLINE void set_callframe(CELL quot)
|
||||
|
@ -278,6 +281,10 @@ void general_error(F_ERRORTYPE error, CELL arg1, CELL arg2, bool keep_stacks)
|
|||
|
||||
void memory_protection_error(CELL addr, int signal)
|
||||
{
|
||||
/* this is here to catch GC bugs; see the comment in push_callframe()
|
||||
above */
|
||||
garbage_collection(NURSERY,false);
|
||||
|
||||
if(in_page(addr, ds_bot, 0, -1))
|
||||
general_error(ERROR_DS_UNDERFLOW,F,F,false);
|
||||
else if(in_page(addr, ds_bot, ds_size, 0))
|
||||
|
|
|
@ -229,7 +229,9 @@ void primitive_resize_string(void)
|
|||
#define MEMORY_TO_STRING(type,utype) \
|
||||
F_STRING *memory_to_##type##_string(const type *string, CELL length) \
|
||||
{ \
|
||||
REGISTER_C_STRING(string); \
|
||||
F_STRING* s = allot_string_internal(length); \
|
||||
UNREGISTER_C_STRING(string); \
|
||||
CELL i; \
|
||||
for(i = 0; i < length; i++) \
|
||||
{ \
|
||||
|
|
Loading…
Reference in New Issue