Commit 1d77ff5b authored by Russ Cox's avatar Russ Cox

6g, 8g: handle slice by sub-word-sized index (uint8, int8, uint16, int16)

R=ken2
CC=golang-dev
https://golang.org/cl/1960042
parent 879b5a02
...@@ -1145,16 +1145,18 @@ cmpandthrow(Node *nl, Node *nr) ...@@ -1145,16 +1145,18 @@ cmpandthrow(Node *nl, Node *nr)
n1.op = OXXX; n1.op = OXXX;
t = types[TUINT32]; t = types[TUINT32];
if(is64(nl->type) || is64(nr->type)) { if(nl->type->width != t->width || nr->type->width != t->width) {
// two 64-bit is just a 64-bit compare, if((is64(nl->type) && nl->op != OLITERAL) || (is64(nr->type) && nr->op != OLITERAL))
// but one 32 and one 64 needs to copy t = types[TUINT64];
// the 32 into a register to get the full comparison.
t = types[TUINT64]; // Check if we need to use a temporary.
if(!is64(nl->type) && nl->op != OLITERAL) { // At least one of the arguments is 32 bits
// (the len or cap) so one temporary suffices.
if(nl->type->width != t->width && nl->op != OLITERAL) {
regalloc(&n1, t, nl); regalloc(&n1, t, nl);
gmove(nl, &n1); gmove(nl, &n1);
nl = &n1; nl = &n1;
} else if(!is64(nr->type) && nr->op != OLITERAL) { } else if(nr->type->width != t->width && nr->op != OLITERAL) {
regalloc(&n1, t, nr); regalloc(&n1, t, nr);
gmove(nr, &n1); gmove(nr, &n1);
nr = &n1; nr = &n1;
......
...@@ -857,7 +857,8 @@ cmpandthrow(Node *nl, Node *nr) ...@@ -857,7 +857,8 @@ cmpandthrow(Node *nl, Node *nr)
vlong cl; vlong cl;
Prog *p1; Prog *p1;
int op; int op;
Node *c; Node *c, n1;
Type *t;
op = OLE; op = OLE;
if(smallintconst(nl)) { if(smallintconst(nl)) {
...@@ -872,16 +873,34 @@ cmpandthrow(Node *nl, Node *nr) ...@@ -872,16 +873,34 @@ cmpandthrow(Node *nl, Node *nr)
nl = nr; nl = nr;
nr = c; nr = c;
} }
gins(optoas(OCMP, types[TUINT32]), nl, nr); // Arguments are known not to be 64-bit,
// but they might be smaller than 32 bits.
// Check if we need to use a temporary.
// At least one of the arguments is 32 bits
// (the len or cap) so one temporary suffices.
n1.op = OXXX;
t = types[TUINT32];
if(nl->type->width != t->width) {
regalloc(&n1, t, nl);
gmove(nl, &n1);
nl = &n1;
} else if(nr->type->width != t->width) {
regalloc(&n1, t, nr);
gmove(nr, &n1);
nr = &n1;
}
gins(optoas(OCMP, t), nl, nr);
if(n1.op != OXXX)
regfree(&n1);
if(throwpc == nil) { if(throwpc == nil) {
p1 = gbranch(optoas(op, types[TUINT32]), T); p1 = gbranch(optoas(op, t), T);
throwpc = pc; throwpc = pc;
ginscall(panicslice, 0); ginscall(panicslice, 0);
patch(p1, pc); patch(p1, pc);
} else { } else {
op = brcom(op); op = brcom(op);
p1 = gbranch(optoas(op, types[TUINT32]), T); p1 = gbranch(optoas(op, t), T);
patch(p1, throwpc); patch(p1, throwpc);
} }
} }
...@@ -1045,6 +1064,7 @@ sliceslice: ...@@ -1045,6 +1064,7 @@ sliceslice:
// if(lb[1] > old.nel[0]) goto throw; // if(lb[1] > old.nel[0]) goto throw;
n2 = nodes[0]; n2 = nodes[0];
n2.xoffset += Array_nel; n2.xoffset += Array_nel;
n2.type = types[TUINT32];
cmpandthrow(&nodes[1], &n2); cmpandthrow(&nodes[1], &n2);
// ret.nel = old.nel[0]-lb[1]; // ret.nel = old.nel[0]-lb[1];
...@@ -1064,6 +1084,7 @@ sliceslice: ...@@ -1064,6 +1084,7 @@ sliceslice:
// if(hb[2] > old.cap[0]) goto throw; // if(hb[2] > old.cap[0]) goto throw;
n2 = nodes[0]; n2 = nodes[0];
n2.xoffset += Array_cap; n2.xoffset += Array_cap;
n2.type = types[TUINT32];
cmpandthrow(&nodes[2], &n2); cmpandthrow(&nodes[2], &n2);
// if(lb[1] > hb[2]) goto throw; // if(lb[1] > hb[2]) goto throw;
......
...@@ -16,10 +16,7 @@ func readU16BE(r io.Reader, b []byte) (uint16, os.Error) { ...@@ -16,10 +16,7 @@ func readU16BE(r io.Reader, b []byte) (uint16, os.Error) {
if err != nil { if err != nil {
return 0, err return 0, err
} }
// TODO(nigeltao): remove the workaround when bug 1011 gets fixed. return uint16(b[0])<<8 + uint16(b[1]), nil
//return uint16(b[0])<<8 + uint16(b[1]), nil
ret := uint16(b[0])<<8 + uint16(b[1])
return ret, nil
} }
// readStr reads a length-prefixed string from r, using b as a scratch buffer. // readStr reads a length-prefixed string from r, using b as a scratch buffer.
......
// $G $D/$F.go && $L $F.$A && ./$A.out
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Issue 1011. Removing either #1 or #3 avoided the crash at #2.
package main
import (
"io"
"strings"
)
func readU16BE(b []byte) uint16 {
b[0] = 0
b[1] = 1
return uint16(b[0])<<8 + uint16(b[1]) // #1
n := uint16(b[0])<<8 + uint16(b[1])
return n
}
func readStr(r io.Reader, b []byte) string {
n := readU16BE(b)
if int(n) > len(b) {
return "err: n>b"
}
io.ReadFull(r, b[0:n]) // #2
return string(b[0:n]) // #3
return "ok"
}
func main() {
br := strings.NewReader("abcd")
readStr(br, make([]byte, 256))
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment