Slide 9
Slide 9 text
Maintainable?
static void intern_rec(value *dest)
{
unsigned int code;
tag_t tag;
mlsize_t size, len, ofs_ind;
value v, clos;
asize_t ofs;
header_t header;
char cksum[16];
struct custom_operations * ops;
tailcall:
code = read8u();
if (code >= PREFIX_SMALL_INT) {
if (code >= PREFIX_SMALL_BLOCK) {
/* Small block */
tag = code & 0xF;
size = (code >> 4) & 0x7;
read_block:
if (size == 0) {
v = Atom(tag);
} else {
v = Val_hp(intern_dest);
*dest = v;
if (intern_obj_table != NULL) intern_obj_table[obj_counter++] = v;
dest = (value *) (intern_dest + 1);
*intern_dest = Make_header(size, tag, intern_color);
intern_dest += 1 + size;
for(/*nothing*/; size > 1; size--, dest++)
intern_rec(dest);
goto tailcall;
}
} else {
/* Small integer */
v = Val_int(code & 0x3F);
}
} else {
if (code >= PREFIX_SMALL_STRING) {
/* Small string */
len = (code & 0x1F);
read_string:
size = (len + sizeof(value)) / sizeof(value);
v = Val_hp(intern_dest);
if (intern_obj_table != NULL) intern_obj_table[obj_counter++] = v;
*intern_dest = Make_header(size, String_tag, intern_color);
intern_dest += 1 + size;
Field(v, size - 1) = 0;
ofs_ind = Bsize_wsize(size) - 1;
Byte(v, ofs_ind) = ofs_ind - len;
readblock(String_val(v), len);
} else {
switch(code) {
case CODE_INT8:
v = Val_long(read8s());
break;
case CODE_INT16:
v = Val_long(read16s());
break;
case CODE_INT32:
v = Val_long(read32s());
break;
case CODE_INT64:
#ifdef ARCH_SIXTYFOUR
v = Val_long(read64s());
break;
#else
intern_cleanup();
failwith("input_value: integer too large");
break;
#endif
case CODE_SHARED8:
ofs = read8u();
read_shared:
Assert (ofs > 0);
Assert (ofs <= obj_counter);
Assert (intern_obj_table != NULL);
v = intern_obj_table[obj_counter - ofs];
break;
case CODE_SHARED16:
ofs = read16u();
goto read_shared;
case CODE_SHARED32:
ofs = read32u();
goto read_shared;
case CODE_BLOCK32:
header = (header_t) read32u();
tag = Tag_hd(header);
size = Wosize_hd(header);
goto read_block;
case CODE_STRING8:
len = read8u();
goto read_string;
case CODE_STRING32:
len = read32u();
goto read_string;
case CODE_DOUBLE_LITTLE:
case CODE_DOUBLE_BIG:
if (sizeof(double) != 8) {
intern_cleanup();
invalid_argument("input_value: non-standard floats");
}
v = Val_hp(intern_dest);
if (intern_obj_table != NULL) intern_obj_table[obj_counter++] = v;
*intern_dest = Make_header(Double_wosize, Double_tag, intern_color);
intern_dest += 1 + Double_wosize;
readblock((char *) v, 8);
#if ARCH_FLOAT_ENDIANNESS == 0x76543210
if (code != CODE_DOUBLE_BIG) Reverse_64(v, v);
#elif ARCH_FLOAT_ENDIANNESS == 0x01234567
if (code != CODE_DOUBLE_LITTLE) Reverse_64(v, v);
#else
if (code == CODE_DOUBLE_LITTLE)
Permute_64(v, ARCH_FLOAT_ENDIANNESS, v, 0x01234567)
else
Permute_64(v, ARCH_FLOAT_ENDIANNESS, v, 0x76543210);
#endif
break;
case CODE_DOUBLE_ARRAY8_LITTLE:
case CODE_DOUBLE_ARRAY8_BIG:
len = read8u();
read_double_array:
if (sizeof(double) != 8) {
intern_cleanup();
invalid_argument("input_value: non-standard floats");
}
size = len * Double_wosize;
v = Val_hp(intern_dest);
if (intern_obj_table != NULL) intern_obj_table[obj_counter++] = v;
*intern_dest = Make_header(size, Double_array_tag, intern_color);
intern_dest += 1 + size;
readblock((char *) v, len * 8
#if ARCH_FLOAT_ENDIANNESS == 0x76543
if (code != CODE_DOUBLE_ARRAY8
code != CODE_DOUBLE_ARRAY3
mlsize_t i;
for (i = 0; i < len; i++) Rev
}
#elif ARCH_FLOAT_ENDIANNESS == 0x012345
if (code != CODE_DOUBLE_ARRAY8_L
code != CODE_DOUBLE_ARRAY32_
mlsize_t i;
for (i = 0; i < len; i++) Rever
}
#else
if (code == CODE_DOUBLE_ARRAY8_LIT
code == CODE_DOUBLE_ARRAY32_LI
mlsize_t i;
for (i = 0; i < len; i++)
Permute_64((value)((double *)v
(value)((double *)v +
} else {
mlsize_t i;
for (i = 0; i < len; i++)
Permute_64((value)((double *)v +
(value)((double *)v +
}
#endif
break;
case CODE_DOUBLE_ARRAY32_LITTLE:
case CODE_DOUBLE_ARRAY32_BIG:
len = read32u();
goto read_double_array;
case CODE_CODEPOINTER:
ofs = read32u();
readblock(cksum, 16);
if (memcmp(cksum, code_checksum(), 16) !=
intern_cleanup();
failwith("input_value: code mismatch");
}
v = (value) (code_area_start + ofs);
break;
case CODE_INFIXPOINTER:
ofs = read32u();
intern_rec(&clos);
v = clos + ofs;
break;
case CODE_CUSTOM:
ops = find_custom_operations((char *) intern
if (ops == NULL) {
intern_cleanup();
failwith("input_value: unknown custom block
}
while (*intern_src++ != 0) /*nothing*/; /*ski
size = ops->deserialize((void *) (intern_dest
size = 1 + (size + sizeof(value) - 1) / sizeof
v = Val_hp(intern_dest);
if (intern_obj_table != NULL) intern_obj_table[
*intern_dest = Make_header(size, Custom_tag, in
Custom_ops_val(v) = ops;
intern_dest += 1 + size;
break;
default:
intern_clean
Few dependencies are not enough to
make code maintainable.