vendor tsgo
This commit is contained in:
185
tools/tsgo/internal/fswatch/fsevents_darwin_ffi_amd64.s
Normal file
185
tools/tsgo/internal/fswatch/fsevents_darwin_ffi_amd64.s
Normal file
@@ -0,0 +1,185 @@
|
||||
//go:build darwin && amd64
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// fsevents_darwin_ffi_amd64.s: amd64 assembly for the FSEvents backend
|
||||
//
|
||||
// Contains two functions:
|
||||
//
|
||||
// 1. FSEventStreamCreate trampoline: shuffles the float64 latency arg
|
||||
// from R9 (integer register, where syscall6 puts it) into X0 (xmm0,
|
||||
// where the System V AMD64 ABI expects the first float argument),
|
||||
// and hardcodes the flags argument to 0x11
|
||||
// (kFSEventStreamCreateFlagUseCFTypes |
|
||||
// kFSEventStreamCreateFlagFileEvents).
|
||||
//
|
||||
// 2. fsEventsCallbackASM: the C-convention callback invoked by FSEvents
|
||||
// on a GCD dispatch queue thread. Retains/copies callback data into a
|
||||
// payload, writes the payload pointer to eventPipe to wake the Go event-loop
|
||||
// goroutine, then returns. Never enters Go ABI; stays entirely in System V
|
||||
// AMD64 calling convention.
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// FSEventStreamCreate trampoline: shuffles the float64 latency argument.
|
||||
//
|
||||
// The runtime's syscall6 trampoline loads 6 args into registers:
|
||||
// DI=allocator SI=callback DX=ctx CX=paths
|
||||
// R8=sinceWhen R9=latency(bits)
|
||||
//
|
||||
// The C function expects latency in X0 (xmm0) and flags in R9.
|
||||
// flags is always 0x11 (kFSEventStreamCreateFlagUseCFTypes |
|
||||
// kFSEventStreamCreateFlagFileEvents), so we hardcode it.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
TEXT fse_FSEventStreamCreate_trampoline<>(SB), NOSPLIT, $0-0
|
||||
MOVQ R9, X0
|
||||
MOVQ $0x11, R9
|
||||
JMP fse_FSEventStreamCreate(SB)
|
||||
|
||||
GLOBL ·fse_FSEventStreamCreate_trampoline_addr(SB), RODATA, $8
|
||||
DATA ·fse_FSEventStreamCreate_trampoline_addr(SB)/8, $fse_FSEventStreamCreate_trampoline<>(SB)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// FSEvents callback: called from a GCD dispatch queue with C convention.
|
||||
// DI=streamRef SI=info DX=numEvents CX=paths R8=flags R9=ids
|
||||
//
|
||||
// `info` is a pointer to a streamCallback struct (see fsevents_darwin_ffi.go):
|
||||
// offset 0: eventPipeWrite fd (8 bytes)
|
||||
//
|
||||
// Stays entirely in C context (no cgocallback). Saves args to the per-stream
|
||||
// heap-allocated payload, writes its pointer to the stream's eventPipe to wake
|
||||
// its Go event loop goroutine, then returns immediately.
|
||||
//
|
||||
// NOFRAME: this function is entered from C, not Go. We manage the frame
|
||||
// ourselves following the System V AMD64 ABI.
|
||||
//
|
||||
// Frame layout (88 bytes, 16-byte aligned):
|
||||
// On entry from C, RSP ≡ 8 mod 16 (return address pushed by CALL).
|
||||
// SUB $88 → RSP ≡ 8-88 = 0 mod 16, aligned for CALL into libc.
|
||||
// RSP+ 0: payload pointer bytes written to eventPipe
|
||||
// RSP+ 8: saved info pointer
|
||||
// RSP+16: saved numEvents
|
||||
// RSP+24: saved original flags pointer
|
||||
// RSP+32: retained CFArray paths
|
||||
// RSP+40: copied flags pointer
|
||||
// RSP+48: saved original IDs pointer
|
||||
// RSP+56: copied IDs pointer
|
||||
// RSP+80: saved RBP ← BP points here (C frame chain)
|
||||
// RSP+88: return address (pushed by C's CALL)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
TEXT fsEventsCallbackASM<>(SB), NOSPLIT|NOFRAME, $0
|
||||
SUBQ $88, SP
|
||||
MOVQ BP, 80(SP)
|
||||
LEAQ 80(SP), BP
|
||||
|
||||
MOVQ SI, 8(SP) // info
|
||||
MOVQ DX, 16(SP) // numEvents
|
||||
MOVQ R8, 24(SP) // original flags
|
||||
MOVQ R9, 48(SP) // original IDs
|
||||
|
||||
// Retain the CFArray paths because FSEvents owns the callback argument.
|
||||
MOVQ CX, DI
|
||||
XORL AX, AX
|
||||
CALL fse_CFRetain(SB)
|
||||
TESTQ AX, AX
|
||||
JEQ done
|
||||
MOVQ AX, 32(SP)
|
||||
|
||||
// Copy the flags array into C heap memory owned by the Go event loop.
|
||||
MOVQ 16(SP), DI
|
||||
SHLQ $2, DI
|
||||
XORL AX, AX
|
||||
CALL fse_malloc(SB)
|
||||
TESTQ AX, AX
|
||||
JEQ releasePaths
|
||||
MOVQ AX, 40(SP)
|
||||
|
||||
MOVQ AX, DI
|
||||
MOVQ 24(SP), SI
|
||||
MOVQ 16(SP), DX
|
||||
SHLQ $2, DX
|
||||
XORL AX, AX
|
||||
CALL fse_memcpy(SB)
|
||||
|
||||
// Copy the event ID array into C heap memory owned by the Go event loop.
|
||||
MOVQ 16(SP), DI
|
||||
SHLQ $3, DI
|
||||
XORL AX, AX
|
||||
CALL fse_malloc(SB)
|
||||
TESTQ AX, AX
|
||||
JEQ freeFlags
|
||||
MOVQ AX, 56(SP)
|
||||
|
||||
MOVQ AX, DI
|
||||
MOVQ 48(SP), SI
|
||||
MOVQ 16(SP), DX
|
||||
SHLQ $3, DX
|
||||
XORL AX, AX
|
||||
CALL fse_memcpy(SB)
|
||||
|
||||
// Allocate and populate fsEventsCallbackPayload.
|
||||
MOVQ $32, DI
|
||||
XORL AX, AX
|
||||
CALL fse_malloc(SB)
|
||||
TESTQ AX, AX
|
||||
JEQ freeIDs
|
||||
MOVQ AX, 0(SP)
|
||||
|
||||
MOVQ 16(SP), CX
|
||||
MOVQ CX, (0*8)(AX)
|
||||
MOVQ 32(SP), CX
|
||||
MOVQ CX, (1*8)(AX)
|
||||
MOVQ 40(SP), CX
|
||||
MOVQ CX, (2*8)(AX)
|
||||
MOVQ 56(SP), CX
|
||||
MOVQ CX, (3*8)(AX)
|
||||
|
||||
// write(info->eventPipeWrite, &payload, sizeof(payload)).
|
||||
writeAgain:
|
||||
MOVQ 8(SP), AX // reload info
|
||||
MOVQ (0*8)(AX), DI // eventPipeWrite
|
||||
LEAQ 0(SP), SI // buf (payload pointer)
|
||||
MOVQ $8, DX // count
|
||||
XORL AX, AX // no float args
|
||||
CALL fse_write(SB)
|
||||
CMPQ AX, $8
|
||||
JEQ done
|
||||
CMPQ AX, $-1
|
||||
JNE freePayload
|
||||
XORL AX, AX // no float args
|
||||
CALL fse___error(SB)
|
||||
MOVL (AX), AX
|
||||
CMPL AX, $4 // EINTR
|
||||
JEQ writeAgain
|
||||
JMP freePayload
|
||||
|
||||
freePayload:
|
||||
MOVQ 0(SP), DI
|
||||
XORL AX, AX
|
||||
CALL fse_free(SB)
|
||||
|
||||
freeIDs:
|
||||
MOVQ 56(SP), DI
|
||||
XORL AX, AX
|
||||
CALL fse_free(SB)
|
||||
|
||||
freeFlags:
|
||||
MOVQ 40(SP), DI
|
||||
XORL AX, AX
|
||||
CALL fse_free(SB)
|
||||
|
||||
releasePaths:
|
||||
MOVQ 32(SP), DI
|
||||
XORL AX, AX
|
||||
CALL fse_CFRelease(SB)
|
||||
|
||||
// Return 0.
|
||||
done:
|
||||
XORL AX, AX
|
||||
MOVQ 80(SP), BP
|
||||
ADDQ $88, SP
|
||||
RET
|
||||
|
||||
GLOBL ·fsEventsCallbackAsmAddr(SB), RODATA, $8
|
||||
DATA ·fsEventsCallbackAsmAddr(SB)/8, $fsEventsCallbackASM<>(SB)
|
||||
Reference in New Issue
Block a user