summaryrefslogtreecommitdiff
path: root/src/pkg/runtime/string.goc
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/runtime/string.goc')
-rw-r--r--src/pkg/runtime/string.goc102
1 files changed, 84 insertions, 18 deletions
diff --git a/src/pkg/runtime/string.goc b/src/pkg/runtime/string.goc
index b79acbe1c..97a69d07b 100644
--- a/src/pkg/runtime/string.goc
+++ b/src/pkg/runtime/string.goc
@@ -46,10 +46,8 @@ gostringsize(intgo l)
if(l == 0)
return runtime·emptystring;
- // leave room for NUL for C runtime (e.g., callers of getenv)
- s.str = runtime·mallocgc(l+1, 0, FlagNoScan|FlagNoZero);
+ s.str = runtime·mallocgc(l, 0, FlagNoScan|FlagNoZero);
s.len = l;
- s.str[l] = 0;
for(;;) {
ms = runtime·maxstring;
if((uintptr)l <= ms || runtime·casp((void**)&runtime·maxstring, (void*)ms, (void*)l))
@@ -80,6 +78,7 @@ runtime·gostringn(byte *str, intgo l)
return s;
}
+// used by cmd/cgo
Slice
runtime·gobytes(byte *p, intgo n)
{
@@ -102,11 +101,8 @@ runtime·gostringnocopy(byte *str)
return s;
}
-void
-runtime·cstringToGo(byte *str, String s)
-{
+func cstringToGo(str *byte) (s String) {
s = runtime·gostringnocopy(str);
- FLUSH(&s);
}
String
@@ -179,14 +175,35 @@ concatstring(intgo n, String *s)
return out;
}
-// NOTE: Cannot use func syntax, because we need the ...,
-// to signal to the garbage collector that this function does
-// not have a fixed size argument count.
#pragma textflag NOSPLIT
-void
-runtime·concatstring(intgo n, String s1, ...)
-{
- (&s1)[n] = concatstring(n, &s1);
+func concatstring2(s1 String, s2 String) (res String) {
+ USED(&s2);
+ res = concatstring(2, &s1);
+}
+#pragma textflag NOSPLIT
+func concatstring3(s1 String, s2 String, s3 String) (res String) {
+ USED(&s2);
+ USED(&s3);
+ res = concatstring(3, &s1);
+}
+#pragma textflag NOSPLIT
+func concatstring4(s1 String, s2 String, s3 String, s4 String) (res String) {
+ USED(&s2);
+ USED(&s3);
+ USED(&s4);
+ res = concatstring(4, &s1);
+}
+#pragma textflag NOSPLIT
+func concatstring5(s1 String, s2 String, s3 String, s4 String, s5 String) (res String) {
+ USED(&s2);
+ USED(&s3);
+ USED(&s4);
+ USED(&s5);
+ res = concatstring(5, &s1);
+}
+#pragma textflag NOSPLIT
+func concatstrings(s Slice) (res String) {
+ res = concatstring(s.len, (String*)s.array);
}
func eqstring(s1 String, s2 String) (v bool) {
@@ -219,6 +236,25 @@ runtime·strcmp(byte *s1, byte *s2)
}
}
+int32
+runtime·strncmp(byte *s1, byte *s2, uintptr n)
+{
+ uintptr i;
+ byte c1, c2;
+
+ for(i=0; i<n; i++) {
+ c1 = s1[i];
+ c2 = s2[i];
+ if(c1 < c2)
+ return -1;
+ if(c1 > c2)
+ return +1;
+ if(c1 == 0)
+ break;
+ }
+ return 0;
+}
+
byte*
runtime·strstr(byte *s1, byte *s2)
{
@@ -258,11 +294,35 @@ func slicebytetostring(b Slice) (s String) {
runtime·memmove(s.str, b.array, s.len);
}
+func slicebytetostringtmp(b Slice) (s String) {
+ void *pc;
+
+ if(raceenabled) {
+ pc = runtime·getcallerpc(&b);
+ runtime·racereadrangepc(b.array, b.len, pc, runtime·slicebytetostringtmp);
+ }
+
+ // Return a "string" referring to the actual []byte bytes.
+ // This is only for use by internal compiler optimizations
+ // that know that the string form will be discarded before
+ // the calling goroutine could possibly modify the original
+ // slice or synchronize with another goroutine.
+ // Today, the only such case is a m[string(k)] lookup where
+ // m is a string-keyed map and k is a []byte.
+ s.str = b.array;
+ s.len = b.len;
+}
+
func stringtoslicebyte(s String) (b Slice) {
- b.array = runtime·mallocgc(s.len, 0, FlagNoScan|FlagNoZero);
+ uintptr cap;
+
+ cap = runtime·roundupsize(s.len);
+ b.array = runtime·mallocgc(cap, 0, FlagNoScan|FlagNoZero);
b.len = s.len;
- b.cap = s.len;
+ b.cap = cap;
runtime·memmove(b.array, s.str, s.len);
+ if(cap != b.len)
+ runtime·memclr(b.array+b.len, cap-b.len);
}
func slicerunetostring(b Slice) (s String) {
@@ -297,6 +357,7 @@ func stringtoslicerune(s String) (b Slice) {
intgo n;
int32 dum, *r;
uint8 *p, *ep;
+ uintptr mem;
// two passes.
// unlike slicerunetostring, no race because strings are immutable.
@@ -308,13 +369,18 @@ func stringtoslicerune(s String) (b Slice) {
n++;
}
- b.array = runtime·mallocgc(n*sizeof(r[0]), 0, FlagNoScan|FlagNoZero);
+ if(n > MaxMem/sizeof(r[0]))
+ runtime·throw("out of memory");
+ mem = runtime·roundupsize(n*sizeof(r[0]));
+ b.array = runtime·mallocgc(mem, 0, FlagNoScan|FlagNoZero);
b.len = n;
- b.cap = n;
+ b.cap = mem/sizeof(r[0]);
p = s.str;
r = (int32*)b.array;
while(p < ep)
p += runtime·charntorune(r++, p, ep-p);
+ if(b.cap > b.len)
+ runtime·memclr(b.array+b.len*sizeof(r[0]), (b.cap-b.len)*sizeof(r[0]));
}
enum