@@ -483,22 +483,6 @@ VAL MKBUFFERc(VM* vm, Buffer* buf) {
483483 return cl;
484484}
485485
486−static VAL make_buf_offset(VM* vm, BufOffset* off, int outerlock) {
487− Closure* cl = allocate(vm, sizeof(Closure) + sizeof *off, outerlock);
488− SETTY(cl, BUFOFFSET);
489− cl->info.buf_offset = (BufOffset*)((void*)cl + sizeof(Closure));
490− memmove(cl->info.buf_offset, off, sizeof *off);
491− return cl;
492−}
493−
494−static VAL MKBUFOFFSET(VM* vm, BufOffset* off) {
495− return make_buf_offset(vm, off, 0);
496−}
497−
498−VAL MKBUFOFFSETc(VM* vm, BufOffset* off) {
499− return make_buf_offset(vm, off, 1);
500−}
501−
502486static VAL internal_allocate(VM *vm, size_t hint) {
503487 size_t size = hint + sizeof(Closure) + sizeof(Buffer);
504488
@@ -523,17 +507,6 @@ VAL idris_allocate(VM* vm, VAL hint) {
523507 return cl;
524508}
525509
526−VAL idris_copy(VM* vm, VAL len, VAL src) {
527− size_t length = len->info.bits64;
528− Closure* cl = internal_allocate(vm, length);
529− memmove(cl->info.buf->store, (GETTY(src) == BUFOFFSET ?
530− src->info.buf_offset->buf->info.buf->store + src->info.buf_offset->offset :
531− src->info.buf->store
532− ), length);
533− cl->info.buf->fill = length;
534− return cl;
535−}
536−
537510static void internal_memset(void *dest, const void *src, size_t size, size_t num) {
538511 while (num--) {
539512 memmove(dest, src, size);
@@ -541,95 +514,49 @@ static void internal_memset(void *dest, const void *src, size_t size, size_t num
541514 }
542515}
543516
544−static void internal_prepare_append(VM* vm, VAL buf, size_t bufLen, size_t appLen, void** storePtr, Closure** valPtr) {
517+static VAL internal_prepare_append(VM* vm, VAL buf, size_t bufLen, size_t appLen) {
545518 size_t totalLen = bufLen + appLen;
546− // Might be able to get rid of some duplication here...
547− if (GETTY(buf) == BUFOFFSET) {
548− if (buf->info.buf_offset->offset + bufLen !=
549− buf->info.buf_offset->buf->info.buf->fill ||
550− buf->info.buf_offset->offset + totalLen >
551− buf->info.buf_offset->buf->info.buf->cap) {
552− // We're not at the fill or are over cap, so need a new buffer
553− *valPtr = internal_allocate(vm, totalLen);
554− memmove((*valPtr)->info.buf->store,
555− buf->info.buf_offset->buf->info.buf->store + buf->info.buf_offset->offset,
556− bufLen);
557− (*valPtr)->info.buf->fill = totalLen;
558− *storePtr = (*valPtr)->info.buf->store + bufLen;
559− } else {
560− // Hooray, can just bump the fill
561− *valPtr = buf;
562− buf->info.buf_offset->buf->info.buf->fill += appLen;
563− *storePtr = buf->info.buf_offset->buf->info.buf->store + buf->info.buf_offset->offset + bufLen;
564− }
519+ Closure* cl;
520+ if (bufLen != buf->info.buf->fill ||
521+ totalLen > buf->info.buf->cap) {
522+ // We're not at the fill or are over cap, so need a new buffer
523+ cl = internal_allocate(vm, totalLen);
524+ memmove(cl->info.buf->store,
525+ buf->info.buf->store,
526+ bufLen);
527+ cl->info.buf->fill = totalLen;
565528 } else {
566− Buffer* newBuf;
567− if (bufLen != buf->info.buf->fill ||
568− totalLen > buf->info.buf->cap) {
569− // We're not at the fill or are over cap, so need a new buffer
570− *valPtr = internal_allocate(vm, totalLen);
571− newBuf = (*valPtr)->info.buf;
572− memmove(newBuf->store,
573− buf->info.buf->store,
574− bufLen);
575− newBuf->fill = totalLen;
576− } else {
577− // Hooray, can just bump the fill
578− *valPtr = buf;
579− newBuf = buf->info.buf;
580− newBuf->fill += appLen;
581− }
582− *storePtr = newBuf->store + bufLen;
529+ // Hooray, can just bump the fill
530+ cl = buf;
531+ cl->info.buf->fill += appLen;
583532 }
533+ return cl;
584534}
585535
586−VAL idris_appendBuffer(VM* vm, VAL fst, VAL fstLen, VAL cnt, VAL sndLen, VAL snd) {
536+VAL idris_appendBuffer(VM* vm, VAL fst, VAL fstLen, VAL cnt, VAL sndLen, VAL sndOff, VAL snd) {
587537 size_t firstLength = fstLen->info.bits64;
588538 size_t secondLength = sndLen->info.bits64;
589539 size_t count = cnt->info.bits64;
590− void* store;
591− Closure *cl;
592− internal_prepare_append(vm, fst, firstLength, count * secondLength, &store, &cl);
593− internal_memset(store, GETTY(snd) == BUFOFFSET ?
594− snd->info.buf_offset->buf->info.buf->store + snd->info.buf_offset->offset :
595− snd->info.buf->store
596− , secondLength, count);
540+ size_t offset = sndOff->info.bits64;
541+ Closure* cl = internal_prepare_append(vm, fst, firstLength, count * secondLength);
542+ internal_memset(cl->info.buf->store + firstLength, snd->info.buf->store + offset, secondLength, count);
597543 return cl;
598544}
599545
600−VAL idris_peekBuffer(VM* vm, VAL src, VAL off) {
601− size_t offset = off->info.bits64;
602− if (offset == 0)
603− return src;
604− BufOffset b;
605− if (GETTY(src) == BUFOFFSET) {
606− b.buf = src->info.buf_offset->buf;
607− b.offset = src->info.buf_offset->offset + offset;
608− } else {
609− b.buf = src;
610− b.offset = offset;
611− }
612− return MKBUFOFFSET(vm, &b);
613−}
614−
615546// Special cased because we can use memset
616547VAL idris_appendB8Native(VM* vm, VAL buf, VAL len, VAL cnt, VAL val) {
617548 size_t bufLen = len->info.bits64;
618549 size_t count = cnt->info.bits64;
619− void* store;
620− Closure* cl;
621− internal_prepare_append(vm, buf, bufLen, count, &store, &cl);
622− memset(store, val->info.bits8, count);
550+ Closure* cl = internal_prepare_append(vm, buf, bufLen, count);
551+ memset(cl->info.buf->store + bufLen, val->info.bits8, count);
623552 return cl;
624553}
625554
626555static VAL internal_append_bits(VM* vm, VAL buf, VAL bufLen, VAL cnt, const void* val, size_t val_len) {
627556 size_t len = bufLen->info.bits64;
628557 size_t count = cnt->info.bits64;
629− void* store;
630− Closure* cl;
631− internal_prepare_append(vm, buf, len, count * val_len, &store, &cl);
632− internal_memset(store, val, val_len, count);
558+ Closure* cl = internal_prepare_append(vm, buf, len, count * val_len);
559+ internal_memset(cl->info.buf->store + len, val, val_len, count);
633560 return cl;
634561}
635562
@@ -708,104 +635,78 @@ VAL idris_appendB64BE(VM* vm, VAL buf, VAL len, VAL cnt, VAL val) {
708635
709636VAL idris_peekB8Native(VM* vm, VAL buf, VAL off) {
710637 size_t offset = off->info.bits64;
711− uint8_t* val = GETTY(buf) == BUFOFFSET ?
712− buf->info.buf_offset->buf->info.buf->store + buf->info.buf_offset->offset + offset :
713− buf->info.buf->store + offset;
638+ uint8_t *val = buf->info.buf->store + offset;
714639 return MKB8(vm, *val);
715640}
716641
717642VAL idris_peekB16Native(VM* vm, VAL buf, VAL off) {
718643 size_t offset = off->info.bits64;
719− uint16_t* val = (uint16_t *) ((GETTY(buf) == BUFOFFSET) ?
720− buf->info.buf_offset->buf->info.buf->store + buf->info.buf_offset->offset + offset :
721− buf->info.buf->store + offset);
644+ uint16_t *val = (uint16_t *) (buf->info.buf->store + offset);
722645 return MKB16(vm, *val);
723646}
724647
725648VAL idris_peekB16LE(VM* vm, VAL buf, VAL off) {
726649 size_t offset = off->info.bits64;
727− unsigned char* val = (GETTY(buf) == BUFOFFSET) ?
728− buf->info.buf_offset->buf->info.buf->store + buf->info.buf_offset->offset + offset :
729− buf->info.buf->store + offset;
730− return MKB16(vm, ((uint16_t) val[0]) +
731− (((uint16_t) val[1]) << 8));
650+ return MKB16(vm, ((uint16_t) buf->info.buf->store[offset]) +
651+ (((uint16_t) buf->info.buf->store[offset + 1]) << 8));
732652}
733653
734654VAL idris_peekB16BE(VM* vm, VAL buf, VAL off) {
735655 size_t offset = off->info.bits64;
736− unsigned char* val = (GETTY(buf) == BUFOFFSET) ?
737− buf->info.buf_offset->buf->info.buf->store + buf->info.buf_offset->offset + offset :
738− buf->info.buf->store + offset;
739− return MKB16(vm, ((uint16_t) val[1]) +
740− (((uint16_t) val[0]) << 8));
656+ return MKB16(vm, ((uint16_t) buf->info.buf->store[offset + 1]) +
657+ (((uint16_t) buf->info.buf->store[offset]) << 8));
741658}
742659
743660VAL idris_peekB32Native(VM* vm, VAL buf, VAL off) {
744661 size_t offset = off->info.bits64;
745− uint32_t* val = (uint32_t *) ((GETTY(buf) == BUFOFFSET) ?
746− buf->info.buf_offset->buf->info.buf->store + buf->info.buf_offset->offset + offset :
747− buf->info.buf->store + offset);
662+ uint32_t *val = (uint32_t *) (buf->info.buf->store + offset);
748663 return MKB32(vm, *val);
749664}
750665
751666VAL idris_peekB32LE(VM* vm, VAL buf, VAL off) {
752667 size_t offset = off->info.bits64;
753− unsigned char* val = (GETTY(buf) == BUFOFFSET) ?
754− buf->info.buf_offset->buf->info.buf->store + buf->info.buf_offset->offset + offset :
755− buf->info.buf->store + offset;
756− return MKB32(vm, ((uint32_t) val[0]) +
757− (((uint32_t) val[1]) << 8) +
758− (((uint32_t) val[2]) << 16) +
759− (((uint32_t) val[3]) << 24));
668+ return MKB32(vm, ((uint32_t) buf->info.buf->store[offset]) +
669+ (((uint32_t) buf->info.buf->store[offset + 1]) << 8) +
670+ (((uint32_t) buf->info.buf->store[offset + 2]) << 16) +
671+ (((uint32_t) buf->info.buf->store[offset + 3]) << 24));
760672}
761673
762674VAL idris_peekB32BE(VM* vm, VAL buf, VAL off) {
763675 size_t offset = off->info.bits64;
764− unsigned char* val = (GETTY(buf) == BUFOFFSET) ?
765− buf->info.buf_offset->buf->info.buf->store + buf->info.buf_offset->offset + offset :
766− buf->info.buf->store + offset;
767− return MKB32(vm, ((uint32_t) val[3]) +
768− (((uint32_t) val[2]) << 8) +
769− (((uint32_t) val[1]) << 16) +
770− (((uint32_t) val[0]) << 24));
676+ return MKB32(vm, ((uint32_t) buf->info.buf->store[offset + 3]) +
677+ (((uint32_t) buf->info.buf->store[offset + 2]) << 8) +
678+ (((uint32_t) buf->info.buf->store[offset + 1]) << 16) +
679+ (((uint32_t) buf->info.buf->store[offset]) << 24));
771680}
772681
773682VAL idris_peekB64Native(VM* vm, VAL buf, VAL off) {
774683 size_t offset = off->info.bits64;
775− uint64_t* val = (uint64_t *) ((GETTY(buf) == BUFOFFSET) ?
776− buf->info.buf_offset->buf->info.buf->store + buf->info.buf_offset->offset + offset :
777− buf->info.buf->store + offset);
684+ uint64_t *val = (uint64_t *) (buf->info.buf->store + offset);
778685 return MKB64(vm, *val);
779686}
780687
781688VAL idris_peekB64LE(VM* vm, VAL buf, VAL off) {
782689 size_t offset = off->info.bits64;
783− unsigned char* val = (GETTY(buf) == BUFOFFSET) ?
784− buf->info.buf_offset->buf->info.buf->store + buf->info.buf_offset->offset + offset :
785− buf->info.buf->store + offset;
786− return MKB64(vm, ((uint64_t) val[0]) +
787− (((uint64_t) val[1]) << 8) +
788− (((uint64_t) val[2]) << 16) +
789− (((uint64_t) val[3]) << 24) +
790− (((uint64_t) val[4]) << 32) +
791− (((uint64_t) val[5]) << 40) +
792− (((uint64_t) val[6]) << 48) +
793− (((uint64_t) val[7]) << 56));
690+ return MKB64(vm, ((uint64_t) buf->info.buf->store[offset]) +
691+ (((uint64_t) buf->info.buf->store[offset + 1]) << 8) +
692+ (((uint64_t) buf->info.buf->store[offset + 2]) << 16) +
693+ (((uint64_t) buf->info.buf->store[offset + 3]) << 24) +
694+ (((uint64_t) buf->info.buf->store[offset + 4]) << 32) +
695+ (((uint64_t) buf->info.buf->store[offset + 5]) << 40) +
696+ (((uint64_t) buf->info.buf->store[offset + 6]) << 48) +
697+ (((uint64_t) buf->info.buf->store[offset + 7]) << 56));
794698}
795699
796700VAL idris_peekB64BE(VM* vm, VAL buf, VAL off) {
797701 size_t offset = off->info.bits64;
798− unsigned char* val = (GETTY(buf) == BUFOFFSET) ?
799− buf->info.buf_offset->buf->info.buf->store + buf->info.buf_offset->offset + offset :
800− buf->info.buf->store + offset;
801− return MKB64(vm, ((uint64_t) val[7]) +
802− (((uint64_t) val[6]) << 8) +
803− (((uint64_t) val[5]) << 16) +
804− (((uint64_t) val[4]) << 24) +
805− (((uint64_t) val[3]) << 32) +
806− (((uint64_t) val[2]) << 40) +
807− (((uint64_t) val[1]) << 48) +
808− (((uint64_t) val[0]) << 56));
702+ return MKB64(vm, ((uint64_t) buf->info.buf->store[offset + 7]) +
703+ (((uint64_t) buf->info.buf->store[offset + 6]) << 8) +
704+ (((uint64_t) buf->info.buf->store[offset + 5]) << 16) +
705+ (((uint64_t) buf->info.buf->store[offset + 4]) << 24) +
706+ (((uint64_t) buf->info.buf->store[offset + 3]) << 32) +
707+ (((uint64_t) buf->info.buf->store[offset + 2]) << 40) +
708+ (((uint64_t) buf->info.buf->store[offset + 1]) << 48) +
709+ (((uint64_t) buf->info.buf->store[offset]) << 56));
809710}
810711
811712typedef struct {
@@ -888,18 +789,6 @@ VAL copyTo(VM* vm, VAL x) {
888789 case BUFFER:
889790 cl = MKBUFFERc(vm, x->info.buf);
890791 break;
891− case BUFOFFSET:
892− // The underlying Buffer might already exist in the new heap
893− // but we can't do anything reasonable about it
894− if (x->info.buf_offset->offset == 0)
895− cl = MKBUFFERc(vm, x->info.buf_offset->buf->info.buf);
896− else {
897− // Could theoretically make this a bit more efficient
898− // by allocating the BufOffset and Buffer together
899− cl = MKBUFOFFSETc(vm, x->info.buf_offset);
900− cl->info.buf_offset->buf = MKBUFFERc(vm, x->info.buf_offset->buf->info.buf);
901− }
902− break;
903792 case BIGINT:
904793 cl = MKBIGMc(vm, x->info.ptr);
905794 break;