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.