github.com/primecitizens/pcz/std@v0.2.1/core/reflect/call.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright 2023 The Prime Citizens 3 // 4 // Copyright 2014 The Go Authors. All rights reserved. 5 // Use of this source code is governed by a BSD-style 6 // license that can be found in the LICENSE file. 7 8 package reflect 9 10 import ( 11 "unsafe" 12 13 "github.com/primecitizens/pcz/std/core/abi" 14 "github.com/primecitizens/pcz/std/core/assert" 15 "github.com/primecitizens/pcz/std/core/mem" 16 ) 17 18 // Call calls fn with arguments described by stackArgs, stackArgsSize, 19 // frameSize, and regArgs. 20 // 21 // Arguments passed on the stack and space for return values passed on the stack 22 // must be laid out at the space pointed to by stackArgs (with total length 23 // stackArgsSize) according to the ABI. 24 // 25 // stackRetOffset must be some value <= stackArgsSize that indicates the 26 // offset within stackArgs where the return value space begins. 27 // 28 // frameSize is the total size of the argument frame at stackArgs and must 29 // therefore be >= stackArgsSize. It must include additional space for spilling 30 // register arguments for stack growth and preemption. 31 // 32 // TODO(mknyszek): Once we don't need the additional spill space, remove frameSize, 33 // since frameSize will be redundant with stackArgsSize. 34 // 35 // Arguments passed in registers must be laid out in regArgs according to the ABI. 36 // regArgs will hold any return values passed in registers after the call. 37 // 38 // Call copies stack arguments from stackArgs to the goroutine stack, and 39 // then copies back stackArgsSize-stackRetOffset bytes back to the return space 40 // in stackArgs once fn has completed. It also "unspills" argument registers from 41 // regArgs before calling fn, and spills them back into regArgs immediately 42 // following the call to fn. If there are results being returned on the stack, 43 // the caller should pass the argument frame type as stackArgsType so that 44 // reflectcall can execute appropriate write barriers during the copy. 45 // 46 // Call expects regArgs.ReturnIsPtr to be populated indicating which 47 // registers on the return path will contain Go pointers. It will then store 48 // these pointers in regArgs.Ptrs such that they are visible to the GC. 49 // 50 // Arguments passed through to reflectcall do not escape. The type is used 51 // only in a very limited callee of reflectcall, the stackArgs are copied, and 52 // regArgs is only used in the reflectcall frame. 53 // 54 //go:noescape 55 func Call(stackArgsType *abi.Type, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs) 56 57 // in asm_*.s 58 // not called directly; definitions here supply type information for traceback. 59 // These must have the same signature (arg pointer map) as reflectcall. 60 61 func call16(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs) 62 func call32(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs) 63 func call64(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs) 64 func call128(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs) 65 func call256(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs) 66 func call512(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs) 67 func call1024(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs) 68 func call2048(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs) 69 func call4096(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs) 70 func call8192(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs) 71 func call16384(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs) 72 func call32768(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs) 73 func call65536(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs) 74 func call131072(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs) 75 func call262144(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs) 76 func call524288(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs) 77 func call1048576(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs) 78 func call2097152(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs) 79 func call4194304(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs) 80 func call8388608(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs) 81 func call16777216(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs) 82 func call33554432(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs) 83 func call67108864(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs) 84 func call134217728(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs) 85 func call268435456(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs) 86 func call536870912(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs) 87 func call1073741824(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs) 88 89 func badreflectcall() { 90 assert.Throw("arg", "size", "to", "reflect.call", "more", "than", "1GB") 91 } 92 93 // reflectcallmove is invoked by reflectcall to copy the return values 94 // out of the stack and into the heap, invoking the necessary write 95 // barriers. dst, src, and size describe the return value area to 96 // copy. typ describes the entire frame (not just the return values). 97 // typ may be nil, which indicates write barriers are not needed. 98 // 99 // It must be nosplit and must only call nosplit functions because the 100 // stack map of reflectcall is wrong. 101 // 102 //go:nosplit 103 func reflectcallmove(typ *abi.Type, dst, src unsafe.Pointer, size uintptr, regs *abi.RegArgs) { 104 // if writeBarrier.needed && typ != nil && typ.ptrdata != 0 && size >= goarch.PtrSize { 105 // bulkBarrierPreWrite(uintptr(dst), uintptr(src), size) 106 // } 107 108 mem.Move(dst, src, size) 109 110 // Move pointers returned in registers to a place where the GC can see them. 111 for i := range regs.Ints { 112 if regs.ReturnIsPtr.Get(i) { 113 regs.Ptrs[i] = unsafe.Pointer(regs.Ints[i]) 114 } 115 } 116 }