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  }