// slicecopy(to any, fr any, wid uint32) int void runtime·slicecopy(Slice to, Slice fm, uintptr width, int32 ret) { if(fm.len == 0 || to.len == 0 || width == 0) { ret = 0; goto out; } ret = fm.len; if(to.len < ret) ret = to.len; if(ret == 1 && width == 1) { // common case worth about 2x to do here *to.array = *fm.array; // known to be a byte pointer } else { runtime·memmove(to.array, fm.array, ret*width); } out: FLUSH(&ret); if(debug) { runtime·prints("main·copy: to="); runtime·printslice(to); runtime·prints("; fm="); runtime·printslice(fm); runtime·prints("; width="); runtime·printint(width); runtime·prints("; ret="); runtime·printint(ret); runtime·prints("\n"); } }
void runtime·growslice(SliceType* t, Slice old, int64 n, Slice ret) { ret.array = 0; ret.len = 0; ret.cap = 0; FLUSH(&ret); #line 59 "/home/14/ren/source/golang/go/src/pkg/runtime/slice.goc" int64 cap; void *pc; if(n < 1) runtime·panicstring("growslice: invalid n"); cap = old.cap + n; if((intgo)cap != cap || cap < (int64)old.cap || (t->elem->size > 0 && cap > MaxMem/t->elem->size)) runtime·panicstring("growslice: cap out of range"); if(raceenabled) { pc = runtime·getcallerpc(&t); runtime·racereadrangepc(old.array, old.len*t->elem->size, pc, runtime·growslice); } growslice1(t, old, cap, &ret); if(debug) { runtime·printf("growslice(%S,", *t->string); runtime·printslice(old); runtime·printf(", new cap=%D) =", cap); runtime·printslice(ret); } FLUSH(&ret); }
void runtime·growslice(SliceType* t, Slice old, int64 n, Slice ret) { ret.array = 0; ret.len = 0; ret.cap = 0; FLUSH(&ret); #line 59 "C:\Users\ADMINI~1\AppData\Local\Temp\2\makerelease686069423\go\src\pkg\runtime\slice.goc" int64 cap; void *pc; if(n < 1) runtime·panicstring("growslice: invalid n"); cap = old.cap + n; if((intgo)cap != cap || cap < (int64)old.cap || (t->elem->size > 0 && cap > MaxMem/t->elem->size)) runtime·panicstring("growslice: cap out of range"); if(raceenabled) { pc = runtime·getcallerpc(&t); runtime·racereadrangepc(old.array, old.len*t->elem->size, pc, runtime·growslice); } growslice1(t, old, cap, &ret); if(debug) { runtime·printf("growslice(%S,", *t->string); runtime·printslice(old); runtime·printf(", new cap=%D) =", cap); runtime·printslice(ret); } FLUSH(&ret); }
// growslice(type *Type, x, []T, n int64) []T void runtime·growslice(SliceType *t, Slice old, int64 n, Slice ret) { int64 cap; void *pc; if(n < 1) runtime·panicstring("growslice: invalid n"); cap = old.cap + n; if((intgo)cap != cap || cap < old.cap || (t->elem->size > 0 && cap > MaxMem/t->elem->size)) runtime·panicstring("growslice: cap out of range"); if(raceenabled) { pc = runtime·getcallerpc(&t); runtime·racereadrangepc(old.array, old.len*t->elem->size, t->elem->size, pc, runtime·growslice); } growslice1(t, old, cap, &ret); FLUSH(&ret); if(debug) { runtime·printf("growslice(%S,", *t->string); runtime·printslice(old); runtime·printf(", new cap=%D) =", cap); runtime·printslice(ret); } }
// makeslice(nel int, cap int, width int) (ary []any); void runtime·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="); runtime·printint(nel); prints("; cap="); runtime·printint(cap); prints("; width="); runtime·printint(width); prints("; ret="); runtime·printslice(ret); prints("\n"); } }
void runtime·makeslice(SliceType* t, int64 len, int64 cap, Slice ret) { #line 24 "/home/pi/go_build/hg/go/src/pkg/runtime/slice.goc" // NOTE: The len > MaxMem/elemsize check here is not strictly necessary, // but it produces a 'len out of range' error instead of a 'cap out of range' error // when someone does make([]T, bignumber). 'cap out of range' is true too, // but since the cap is only being supplied implicitly, saying len is clearer. // See issue 4085. if(len < 0 || (intgo)len != len || t->elem->size > 0 && len > MaxMem / t->elem->size) runtime·panicstring("makeslice: len out of range"); if(cap < len || (intgo)cap != cap || t->elem->size > 0 && cap > MaxMem / t->elem->size) runtime·panicstring("makeslice: cap out of range"); makeslice1(t, len, cap, &ret); if(debug) { runtime·printf("makeslice(%S, %D, %D); ret=", *t->string, len, cap); runtime·printslice(ret); } FLUSH(&ret); }
void runtime·makeslice(SliceType* t, int64 len, int64 cap, Slice ret) { ret.array = 0; ret.len = 0; ret.cap = 0; FLUSH(&ret); #line 24 "C:\Users\ADMINI~1\AppData\Local\Temp\2\makerelease686069423\go\src\pkg\runtime\slice.goc" // NOTE: The len > MaxMem/elemsize check here is not strictly necessary, // but it produces a 'len out of range' error instead of a 'cap out of range' error // when someone does make([]T, bignumber). 'cap out of range' is true too, // but since the cap is only being supplied implicitly, saying len is clearer. // See issue 4085. if(len < 0 || (intgo)len != len || t->elem->size > 0 && len > MaxMem / t->elem->size) runtime·panicstring("makeslice: len out of range"); if(cap < len || (intgo)cap != cap || t->elem->size > 0 && cap > MaxMem / t->elem->size) runtime·panicstring("makeslice: cap out of range"); makeslice1(t, len, cap, &ret); if(debug) { runtime·printf("makeslice(%S, %D, %D); ret=", *t->string, len, cap); runtime·printslice(ret); } FLUSH(&ret); }
// arraytoslice(old *any, nel int) (ary []any) void runtime·arraytoslice(byte* old, uint32 nel, Slice ret) { if(nel > 0 && old == nil) { // crash if old == nil. // could give a better message // but this is consistent with all the in-line checks // that the compiler inserts for other uses. *old = 0; } // new dope to old array ret.len = nel; ret.cap = nel; ret.array = old; FLUSH(&ret); if(debug) { prints("runtime·slicearrayp: old="); runtime·printpointer(old); prints("; ret="); runtime·printslice(ret); prints("\n"); } }
// sliceslice(old []any, lb int, hb int, width int) (ary []any); void runtime·sliceslice(Slice old, uint32 lb, uint32 hb, uint32 width, Slice ret) { if(hb > old.cap || lb > hb) { if(debug) { prints("runtime·sliceslice: old="); runtime·printslice(old); prints("; lb="); runtime·printint(lb); prints("; hb="); runtime·printint(hb); prints("; width="); runtime·printint(width); prints("\n"); prints("oldarray: nel="); runtime·printint(old.len); prints("; cap="); runtime·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("runtime·sliceslice: old="); runtime·printslice(old); prints("; lb="); runtime·printint(lb); prints("; hb="); runtime·printint(hb); prints("; width="); runtime·printint(width); prints("; ret="); runtime·printslice(ret); prints("\n"); } }
void runtime·copy(Slice to, Slice fm, uintptr width, intgo ret) { ret = 0; FLUSH(&ret); #line 135 "C:\Users\ADMINI~1\AppData\Local\Temp\2\makerelease686069423\go\src\pkg\runtime\slice.goc" void *pc; if(fm.len == 0 || to.len == 0 || width == 0) { ret = 0; goto out; } ret = fm.len; if(to.len < ret) ret = to.len; if(raceenabled) { pc = runtime·getcallerpc(&to); runtime·racewriterangepc(to.array, ret*width, pc, runtime·copy); runtime·racereadrangepc(fm.array, ret*width, pc, runtime·copy); } if(ret == 1 && width == 1) { // common case worth about 2x to do here *to.array = *fm.array; // known to be a byte pointer } else { runtime·memmove(to.array, fm.array, ret*width); } out: if(debug) { runtime·prints("main·copy: to="); runtime·printslice(to); runtime·prints("; fm="); runtime·printslice(fm); runtime·prints("; width="); runtime·printint(width); runtime·prints("; ret="); runtime·printint(ret); runtime·prints("\n"); } FLUSH(&ret); }
void runtime·copy(Slice to, Slice fm, uintptr width, intgo ret) { ret = 0; FLUSH(&ret); #line 139 "/home/14/ren/source/golang/go/src/pkg/runtime/slice.goc" void *pc; if(fm.len == 0 || to.len == 0 || width == 0) { ret = 0; goto out; } ret = fm.len; if(to.len < ret) ret = to.len; if(raceenabled) { pc = runtime·getcallerpc(&to); runtime·racewriterangepc(to.array, ret*width, pc, runtime·copy); runtime·racereadrangepc(fm.array, ret*width, pc, runtime·copy); } if(ret == 1 && width == 1) { // common case worth about 2x to do here *to.array = *fm.array; // known to be a byte pointer } else { runtime·memmove(to.array, fm.array, ret*width); } out: if(debug) { runtime·prints("main·copy: to="); runtime·printslice(to); runtime·prints("; fm="); runtime·printslice(fm); runtime·prints("; width="); runtime·printint(width); runtime·prints("; ret="); runtime·printint(ret); runtime·prints("\n"); } FLUSH(&ret); }
// sliceslice1(old []any, lb uint64, width uint64) (ary []any); void runtime·sliceslice1(Slice old, uint64 lb, uint64 width, Slice ret) { if(lb > old.len) { if(debug) { runtime·prints("runtime.sliceslice: old="); runtime·printslice(old); runtime·prints("; lb="); runtime·printint(lb); runtime·prints("; width="); runtime·printint(width); runtime·prints("\n"); runtime·prints("oldarray: nel="); runtime·printint(old.len); runtime·prints("; cap="); runtime·printint(old.cap); runtime·prints("\n"); } runtime·panicslice(); } // new array is inside old array ret.len = old.len - lb; ret.cap = old.cap - lb; ret.array = old.array + lb*width; FLUSH(&ret); if(debug) { runtime·prints("runtime.sliceslice: old="); runtime·printslice(old); runtime·prints("; lb="); runtime·printint(lb); runtime·prints("; width="); runtime·printint(width); runtime·prints("; ret="); runtime·printslice(ret); runtime·prints("\n"); } }
// slicearray(old *any, nel int, lb int, hb int, width int) (ary []any); void runtime·slicearray(byte* old, uint32 nel, uint32 lb, uint32 hb, uint32 width, Slice ret) { if(nel > 0 && old == nil) { // crash if old == nil. // could give a better message // but this is consistent with all the in-line checks // that the compiler inserts for other uses. *old = 0; } if(hb > nel || lb > hb) { if(debug) { prints("runtime·slicearray: old="); runtime·printpointer(old); prints("; nel="); runtime·printint(nel); prints("; lb="); runtime·printint(lb); prints("; hb="); runtime·printint(hb); prints("; width="); runtime·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("runtime·slicearray: old="); runtime·printpointer(old); prints("; nel="); runtime·printint(nel); prints("; lb="); runtime·printint(lb); prints("; hb="); runtime·printint(hb); prints("; width="); runtime·printint(width); prints("; ret="); runtime·printslice(ret); prints("\n"); } }
// growslice(type *Type, x, []T, n int64) []T void runtime·growslice(SliceType *t, Slice old, int64 n, Slice ret) { int64 cap; if(n < 1) runtime·panicstring("growslice: invalid n"); cap = old.cap + n; if((int32)cap != cap || cap > ((uintptr)-1) / t->elem->size) runtime·panicstring("growslice: cap out of range"); growslice1(t, old, cap, &ret); FLUSH(&ret); if(debug) { runtime·printf("growslice(%S,", *t->string); runtime·printslice(old); runtime·printf(", new cap=%D) =", cap); runtime·printslice(ret); } }
// see also unsafe·NewArray // makeslice(typ *Type, len, cap int64) (ary []any); void runtime·makeslice(SliceType *t, int64 len, int64 cap, Slice ret) { if(len < 0 || (int32)len != len) runtime·panicstring("makeslice: len out of range"); if(cap < len || (int32)cap != cap || cap > ((uintptr)-1) / t->elem->size) runtime·panicstring("makeslice: cap out of range"); makeslice1(t, len, cap, &ret); if(debug) { runtime·printf("makeslice(%S, %D, %D); ret=", *t->string, len, cap); runtime·printslice(ret); } }
// make([]T, len, cap)会调用到这个函数来。注意这里的ret是整个结构体传进来的。所以按go的函数调用协议,返回值在栈中的布局其实是一个结构体而不是结构体指针。 // see also unsafe·NewArray // makeslice(typ *Type, len, cap int64) (ary []any); void runtime·makeslice(SliceType *t, int64 len, int64 cap, Slice ret) { // NOTE: The len > MaxMem/elemsize check here is not strictly necessary, // but it produces a 'len out of range' error instead of a 'cap out of range' error // when someone does make([]T, bignumber). 'cap out of range' is true too, // but since the cap is only being supplied implicitly, saying len is clearer. // See issue 4085. //(intgo)len != len是将len强制转换为go的int(依赖于机器位数,32或64),这就说明make([]T, len, cap)上面支持的len其实是int类型的 //也就意味着,在32位机器上,传一个很大的数,超过32位能表示的范围是会出错的。64位机器上没什么感觉。 if(len < 0 || (intgo)len != len || t->elem->size > 0 && len > MaxMem / t->elem->size) runtime·panicstring("makeslice: len out of range"); if(cap < len || (intgo)cap != cap || t->elem->size > 0 && cap > MaxMem / t->elem->size) runtime·panicstring("makeslice: cap out of range"); makeslice1(t, len, cap, &ret); if(debug) { runtime·printf("makeslice(%S, %D, %D); ret=", *t->string, len, cap); runtime·printslice(ret); } }
// Very simple printf. Only for debugging prints. // Do not add to this without checking with Rob. static void vprintf(int8 *s, byte *arg) { int8 *p, *lp; byte *narg; // lock(&debuglock); lp = p = s; for(; *p; p++) { if(*p != '%') continue; if(p > lp) write(fd, lp, p-lp); p++; narg = nil; switch(*p) { case 't': narg = arg + 1; break; case 'd': // 32-bit case 'x': arg = vrnd(arg, 4); narg = arg + 4; break; case 'D': // 64-bit case 'U': case 'X': case 'f': arg = vrnd(arg, sizeof(uintptr)); narg = arg + 8; break; case 'p': // pointer-sized case 's': arg = vrnd(arg, sizeof(uintptr)); narg = arg + sizeof(uintptr); break; case 'S': // pointer-aligned but bigger arg = vrnd(arg, sizeof(uintptr)); narg = arg + sizeof(String); break; case 'a': // pointer-aligned but bigger arg = vrnd(arg, sizeof(uintptr)); narg = arg + sizeof(Slice); break; case 'i': // pointer-aligned but bigger case 'e': arg = vrnd(arg, sizeof(uintptr)); narg = arg + sizeof(Eface); break; } switch(*p) { case 'a': ·printslice(*(Slice*)arg); break; case 'd': ·printint(*(int32*)arg); break; case 'D': ·printint(*(int64*)arg); break; case 'e': ·printeface(*(Eface*)arg); break; case 'f': ·printfloat(*(float64*)arg); break; case 'i': ·printiface(*(Iface*)arg); break; case 'p': ·printpointer(*(void**)arg); break; case 's': prints(*(int8**)arg); break; case 'S': ·printstring(*(String*)arg); break; case 't': ·printbool(*(bool*)arg); break; case 'U': ·printuint(*(uint64*)arg); break; case 'x': ·printhex(*(uint32*)arg); break; case 'X': ·printhex(*(uint64*)arg); break; case '!': ·panicl(-1); } arg = narg; lp = p+1; } if(p > lp) write(fd, lp, p-lp); // unlock(&debuglock); }
// Very simple printf. Only for debugging prints. // Do not add to this without checking with Rob. static void vprintf(int8 *s, byte *base) { int8 *p, *lp; uintptr arg, narg; byte *v; // lock(&debuglock); lp = p = s; arg = 0; for(; *p; p++) { if(*p != '%') continue; if(p > lp) runtime·write(2, lp, p-lp); p++; narg = 0; switch(*p) { case 't': narg = arg + 1; break; case 'd': // 32-bit case 'x': arg = runtime·rnd(arg, 4); narg = arg + 4; break; case 'D': // 64-bit case 'U': case 'X': case 'f': arg = runtime·rnd(arg, sizeof(uintptr)); narg = arg + 8; break; case 'C': arg = runtime·rnd(arg, sizeof(uintptr)); narg = arg + 16; break; case 'p': // pointer-sized case 's': arg = runtime·rnd(arg, sizeof(uintptr)); narg = arg + sizeof(uintptr); break; case 'S': // pointer-aligned but bigger arg = runtime·rnd(arg, sizeof(uintptr)); narg = arg + sizeof(String); break; case 'a': // pointer-aligned but bigger arg = runtime·rnd(arg, sizeof(uintptr)); narg = arg + sizeof(Slice); break; case 'i': // pointer-aligned but bigger case 'e': arg = runtime·rnd(arg, sizeof(uintptr)); narg = arg + sizeof(Eface); break; } v = base+arg; switch(*p) { case 'a': runtime·printslice(*(Slice*)v); break; case 'd': runtime·printint(*(int32*)v); break; case 'D': runtime·printint(*(int64*)v); break; case 'e': runtime·printeface(*(Eface*)v); break; case 'f': runtime·printfloat(*(float64*)v); break; case 'C': runtime·printcomplex(*(Complex128*)v); break; case 'i': runtime·printiface(*(Iface*)v); break; case 'p': runtime·printpointer(*(void**)v); break; case 's': runtime·prints(*(int8**)v); break; case 'S': runtime·printstring(*(String*)v); break; case 't': runtime·printbool(*(bool*)v); break; case 'U': runtime·printuint(*(uint64*)v); break; case 'x': runtime·printhex(*(uint32*)v); break; case 'X': runtime·printhex(*(uint64*)v); break; } arg = narg; lp = p+1; } if(p > lp) runtime·write(2, lp, p-lp); // unlock(&debuglock); }