RET
+TEXT runtime·write(SB),7,$24
+ // write only writes to stderr; ignore fd
+ MOVL $-12, 0(SP)
+ MOVL SP, BP
+ CALL *runtime·GetStdHandle(SB)
+ MOVL BP, SP
+
+ MOVL AX, 0(SP) // handle
+ MOVL buf+4(FP), DX // pointer
+ MOVL DX, 4(SP)
+ MOVL count+8(FP), DX // count
+ MOVL DX, 8(SP)
+ LEAL 20(SP), DX // written count
+ MOVL $0, 0(DX)
+ MOVL DX, 12(SP)
+ MOVL $0, 16(SP) // overlapped
+ CALL *runtime·WriteFile(SB)
+ MOVL BP, SI
+ RET
+
+TEXT runtime·badcallback(SB),7,$24
+ // write only writes to stderr; ignore fd
+ MOVL $-12, 0(SP)
+ MOVL SP, BP
+ CALL *runtime·GetStdHandle(SB)
+ MOVL BP, SP
+
+ MOVL AX, 0(SP) // handle
+ MOVL $runtime·badcallbackmsg(SB), DX // pointer
+ MOVL DX, 4(SP)
+ MOVL runtime·badcallbacklen(SB), DX // count
+ MOVL DX, 8(SP)
+ LEAL 20(SP), DX // written count
+ MOVL $0, 0(DX)
+ MOVL DX, 12(SP)
+ MOVL $0, 16(SP) // overlapped
+ CALL *runtime·WriteFile(SB)
+ MOVL BP, SI
+ RET
+
// faster get/set last error
TEXT runtime·getlasterror(SB),7,$0
MOVL 0x34(FS), AX
RET
+TEXT runtime·write(SB),7,$48
+ // write only ever writes to stderr; ignore fd
+ MOVQ $-12, CX // stderr
+ MOVQ CX, 0(SP)
+ MOVQ runtime·GetStdHandle(SB), AX
+ CALL AX
+
+ MOVQ AX, CX // handle
+ MOVQ CX, 0(SP)
+ MOVQ buf+8(FP), DX // pointer
+ MOVQ DX, 8(SP)
+ MOVL count+16(FP), R8 // count
+ MOVQ R8, 16(SP)
+ LEAQ 40(SP), R9 // written count
+ MOVQ $0, 0(R9)
+ MOVQ R9, 24(SP)
+ MOVQ $0, 32(SP) // overlapped
+ MOVQ runtime·WriteFile(SB), AX
+ CALL AX
+
+ RET
+
+TEXT runtime·badcallback(SB),7,$48
+ MOVQ $-12, CX // stderr
+ MOVQ CX, 0(SP)
+ MOVQ runtime·GetStdHandle(SB), AX
+ CALL AX
+
+ MOVQ AX, CX // handle
+ MOVQ CX, 0(SP)
+ MOVQ $runtime·badcallbackmsg(SB), DX // pointer
+ MOVQ DX, 8(SP)
+ MOVL $runtime·badcallbacklen(SB), R8 // count
+ MOVQ R8, 16(SP)
+ LEAQ 40(SP), R9 // written count
+ MOVQ $0, 0(R9)
+ MOVQ R9, 24(SP)
+ MOVQ $0, 32(SP) // overlapped
+ MOVQ runtime·WriteFile(SB), AX
+ CALL AX
+
+ RET
+
// faster get/set last error
TEXT runtime·getlasterror(SB),7,$0
MOVQ 0x30(GS), AX
MOVQ R14, 8(SP)
MOVQ R15, 0(SP)
+ // prepare call stack. use SUBQ to hide from stack frame checks
// cgocallback(void (*fn)(void*), void *frame, uintptr framesize)
- PUSHQ DX // uintptr framesize
- PUSHQ CX // void *frame
- PUSHQ AX // void (*fn)(void*)
+ SUBQ $24, SP
+ MOVQ DX, 16(SP) // uintptr framesize
+ MOVQ CX, 8(SP) // void *frame
+ MOVQ AX, 0(SP) // void (*fn)(void*)
CLD
CALL runtime·cgocallback(SB)
- POPQ AX
- POPQ CX
- POPQ DX
+ MOVQ 0(SP), AX
+ MOVQ 8(SP), CX
+ MOVQ 16(SP), DX
+ ADDQ $24, SP
// restore registers as required for windows callback
// 6l does not allow writing many POPs here issuing a warning "nosplit stack overflow"
runtime·stdcall(runtime·ExitProcess, 1, (uintptr)code);
}
-int32
-runtime·write(int32 fd, void *buf, int32 n)
-{
- void *handle;
- uint32 written;
-
- written = 0;
- switch(fd) {
- case 1:
- handle = runtime·stdcall(runtime·GetStdHandle, 1, (uintptr)-11);
- break;
- case 2:
- handle = runtime·stdcall(runtime·GetStdHandle, 1, (uintptr)-12);
- break;
- default:
- return -1;
- }
- runtime·stdcall(runtime·WriteFile, 5, handle, buf, (uintptr)n, &written, (uintptr)0);
- return written;
-}
-
void
runtime·osyield(void)
{
USED(on);
}
-static int8 badcallback[] = "runtime: cgo callback on thread not created by Go.\n";
-
-// This runs on a foreign stack, without an m or a g. No stack split.
-#pragma textflag 7
-void
-runtime·badcallback(void)
-{
- uint32 written;
-
- runtime·stdcall(
- runtime·WriteFile, 5,
- runtime·stdcall(runtime·GetStdHandle, 1, (uintptr)-12), // stderr
- badcallback,
- (uintptr)(sizeof badcallback - 1),
- &written,
- nil
- );
-}
+int8 runtime·badcallbackmsg[] = "runtime: cgo callback on thread not created by Go.\n";
+int32 runtime·badcallbacklen = sizeof runtime·badcallbackmsg - 1;