Ensure that the closure_map is big enough when deserializing.
Also document more invariants about the closure representation, and avoid some code duplication. Fixes #1108 (caught by fuzz testing).
This commit is contained in:
parent
9d909d6834
commit
1d3fe10d3d
|
@ -792,7 +792,7 @@ static Scheme_Object *write_compiled_closure(Scheme_Object *obj)
|
|||
|
||||
svec_size = data->closure_size;
|
||||
if (SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_HAS_TYPED_ARGS) {
|
||||
svec_size += ((CLOS_TYPE_BITS_PER_ARG * (data->num_params + data->closure_size)) + BITS_PER_MZSHORT - 1) / BITS_PER_MZSHORT;
|
||||
svec_size += boxmap_size(data->num_params + data->closure_size);
|
||||
{
|
||||
int k, mv;
|
||||
for (k = data->num_params + data->closure_size; --k; ) {
|
||||
|
@ -1014,6 +1014,11 @@ static Scheme_Object *read_compiled_closure(Scheme_Object *obj)
|
|||
|
||||
if (!(SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_HAS_TYPED_ARGS))
|
||||
data->closure_size = SCHEME_SVEC_LEN(v);
|
||||
|
||||
if ((SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_HAS_TYPED_ARGS))
|
||||
if (data->closure_size + boxmap_size(data->closure_size + data->num_params) != SCHEME_SVEC_LEN(v))
|
||||
return NULL;
|
||||
|
||||
data->closure_map = SCHEME_SVEC_VEC(v);
|
||||
|
||||
/* If the closure is empty, create the closure now */
|
||||
|
|
|
@ -1683,7 +1683,7 @@ scheme_resolve_lets(Scheme_Object *form, Resolve_Info *info)
|
|||
/* closures */
|
||||
/*========================================================================*/
|
||||
|
||||
XFORM_NONGCING static int boxmap_size(int n)
|
||||
XFORM_NONGCING int boxmap_size(int n)
|
||||
{
|
||||
return ((CLOS_TYPE_BITS_PER_ARG * n) + (BITS_PER_MZSHORT - 1)) / BITS_PER_MZSHORT;
|
||||
}
|
||||
|
|
|
@ -2709,9 +2709,14 @@ typedef struct Scheme_Closure_Data
|
|||
Scheme_Inclhash_Object iso; /* keyex used for flags */
|
||||
mzshort num_params; /* includes collecting arg if has_rest */
|
||||
mzshort max_let_depth;
|
||||
mzshort closure_size;
|
||||
mzshort *closure_map; /* actually a Closure_Info* until resolved; if CLOS_HAS_TYPED_ARGS,
|
||||
followed by bit array with CLOS_TYPE_BITS_PER_ARG bits per args then per closed-over */
|
||||
mzshort closure_size; /* the number of closed-over variables */
|
||||
mzshort *closure_map; /* actually a Closure_Info* until resolved;
|
||||
contains closure_size elements mapping closed-over var to stack positions.
|
||||
|
||||
If CLOS_HAS_TYPED_ARGS, that array is followed by bit array with
|
||||
CLOS_TYPE_BITS_PER_ARG bits per args then per closed-over
|
||||
|
||||
total size = closure_size + (closure_size + num_params) * CLOS_TYPE_BITS_PER_ARG */
|
||||
Scheme_Object *code;
|
||||
Scheme_Object *name; /* name or (vector name src line col pos span generated?) */
|
||||
void *tl_map; /* fixnum or bit array (as array of `int's) indicating which globals+lifts in prefix are used */
|
||||
|
@ -2732,6 +2737,7 @@ typedef struct Scheme_Closure_Data
|
|||
|
||||
XFORM_NONGCING void scheme_boxmap_set(mzshort *boxmap, int j, int bit, int delta);
|
||||
XFORM_NONGCING int scheme_boxmap_get(mzshort *boxmap, int j, int delta);
|
||||
XFORM_NONGCING int boxmap_size(int n);
|
||||
|
||||
int scheme_has_method_property(Scheme_Object *code);
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user