alien>char/u16-string primitives now work correctly if the input is a byte array

slava 2006-11-03 05:37:51 +00:00
parent fada38fe0a
commit 726710a949
6 changed files with 39 additions and 9 deletions

View File

@ -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:

View File

@ -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

View File

@ -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()))

View File

@ -190,7 +190,7 @@ void primitive_fixnum_not(void)
}
#define INT_DEFBOX(name,type) \
void name (type integer) \
void name(type integer) \
{ \
dpush(tag_fixnum(integer)); \
}

View File

@ -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))

View File

@ -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++) \
{ \