summaryrefslogtreecommitdiff
path: root/src/pkg/runtime/slice.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/runtime/slice.c')
-rw-r--r--src/pkg/runtime/slice.c175
1 files changed, 175 insertions, 0 deletions
diff --git a/src/pkg/runtime/slice.c b/src/pkg/runtime/slice.c
new file mode 100644
index 000000000..d7a5a062f
--- /dev/null
+++ b/src/pkg/runtime/slice.c
@@ -0,0 +1,175 @@
+// Copyright 2009 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.
+
+#include "runtime.h"
+
+static int32 debug = 0;
+
+// makeslice(nel int, cap int, width int) (ary []any);
+void
+sys·makeslice(uint32 nel, uint32 cap, uint32 width, Slice ret)
+{
+ uint64 size;
+
+ if(cap < nel)
+ cap = nel;
+ size = cap*width;
+
+ ret.len = nel;
+ ret.cap = cap;
+ ret.array = mal(size);
+
+ FLUSH(&ret);
+
+ if(debug) {
+ prints("makeslice: nel=");
+ sys·printint(nel);
+ prints("; cap=");
+ sys·printint(cap);
+ prints("; width=");
+ sys·printint(width);
+ prints("; ret=");
+ sys·printslice(ret);
+ prints("\n");
+ }
+}
+
+static void
+throwslice(uint32 lb, uint32 hb, uint32 n)
+{
+ prints("slice[");
+ sys·printint(lb);
+ prints(":");
+ sys·printint(hb);
+ prints("] of [");
+ sys·printint(n);
+ prints("] array\n");
+ throw("array slice");
+}
+
+// sliceslice(old []any, lb int, hb int, width int) (ary []any);
+void
+sys·sliceslice(Slice old, uint32 lb, uint32 hb, uint32 width, Slice ret)
+{
+
+ if(hb > old.cap || lb > hb) {
+ if(debug) {
+ prints("sys·sliceslice: old=");
+ sys·printslice(old);
+ prints("; lb=");
+ sys·printint(lb);
+ prints("; hb=");
+ sys·printint(hb);
+ prints("; width=");
+ sys·printint(width);
+ prints("\n");
+
+ prints("oldarray: nel=");
+ sys·printint(old.len);
+ prints("; cap=");
+ sys·printint(old.cap);
+ prints("\n");
+ }
+ throwslice(lb, hb, old.cap);
+ }
+
+ // new array is inside old array
+ ret.len = hb-lb;
+ ret.cap = old.cap - lb;
+ ret.array = old.array + lb*width;
+
+ FLUSH(&ret);
+
+ if(debug) {
+ prints("sys·sliceslice: old=");
+ sys·printslice(old);
+ prints("; lb=");
+ sys·printint(lb);
+ prints("; hb=");
+ sys·printint(hb);
+ prints("; width=");
+ sys·printint(width);
+ prints("; ret=");
+ sys·printslice(ret);
+ prints("\n");
+ }
+}
+
+// slicearray(old *any, nel int, lb int, hb int, width int) (ary []any);
+void
+sys·slicearray(byte* old, uint32 nel, uint32 lb, uint32 hb, uint32 width, Slice ret)
+{
+
+ if(hb > nel || lb > hb) {
+ if(debug) {
+ prints("sys·slicearray: old=");
+ sys·printpointer(old);
+ prints("; nel=");
+ sys·printint(nel);
+ prints("; lb=");
+ sys·printint(lb);
+ prints("; hb=");
+ sys·printint(hb);
+ prints("; width=");
+ sys·printint(width);
+ prints("\n");
+ }
+ throwslice(lb, hb, nel);
+ }
+
+ // new array is inside old array
+ ret.len = hb-lb;
+ ret.cap = nel-lb;
+ ret.array = old + lb*width;
+
+ FLUSH(&ret);
+
+ if(debug) {
+ prints("sys·slicearray: old=");
+ sys·printpointer(old);
+ prints("; nel=");
+ sys·printint(nel);
+ prints("; lb=");
+ sys·printint(lb);
+ prints("; hb=");
+ sys·printint(hb);
+ prints("; width=");
+ sys·printint(width);
+ prints("; ret=");
+ sys·printslice(ret);
+ prints("\n");
+ }
+}
+
+// arraytoslice(old *any, nel int) (ary []any)
+void
+sys·arraytoslice(byte* old, uint32 nel, Slice ret)
+{
+
+ // new dope to old array
+ ret.len = nel;
+ ret.cap = nel;
+ ret.array = old;
+
+ FLUSH(&ret);
+
+ if(debug) {
+ prints("sys·slicearrayp: old=");
+ sys·printpointer(old);
+ prints("; ret=");
+ sys·printslice(ret);
+ prints("\n");
+ }
+}
+
+void
+sys·printslice(Slice a)
+{
+ prints("[");
+ sys·printint(a.len);
+ prints("/");
+ sys·printint(a.cap);
+ prints("]");
+ sys·printpointer(a.array);
+}