std: 프로그램이 바깥 세상과 이야기한다 -- 파일과 명령줄
런타임에 open/read/close 와 명령줄을 넣었다. std.io 가 그 위에 파일 열기, 읽기, 쓰기, 그리고 명령줄을 조각으로 나누는 것을 얹는다. 인용부호 처리는 런타임이 알 일이 아니라 라이브러리가 할 일이다. 길에서 고친 것들: - *T 가 타입 시스템에 실체가 없어서 덩어리로 취급됐다. 이제 진짜 종류다 -- 주소일 뿐이고 추적할 대여도 실행할 drop 도 없는 Copy 타입. 그 결과 &u8 이 *u8 에 자동으로 맞지 않게 됐는데, 그게 맞다: R9 는 그 변환을 unsafe 안의 @ptr_cast 로만 허용한다. - raw 포인터에 정수를 더하면 더 뒤의 주소다. 소유자나 대여에는 허용하지 않는다 -- 자기 자리가 있는 것에서 걸어나가는 것이 *T 의 용도다. - @volatile_load / @volatile_store / @ptr_cast 를 내린다. - undefined 가 선언된 타입을 따른다. 없으면 손으로 타이핑할 수 있는 것보다 큰 버퍼를 선언할 방법이 아예 없었다. R8 이 정확히 동작하는 것도 확인했다: 참조성 파라미터가 둘인 함수는 슬라이스를 반환할 수 없다. 어디서 파생됐는지 시그니처가 말하지 않기 때문이다. exec.py 24/24.
This commit is contained in:
@@ -131,6 +131,10 @@ fe_trap endp
|
||||
extern _GetProcessHeap@0 : near
|
||||
extern _HeapAlloc@12 : near
|
||||
extern _HeapFree@12 : near
|
||||
extern _CreateFileA@28 : near
|
||||
extern _ReadFile@20 : near
|
||||
extern _CloseHandle@4 : near
|
||||
extern _GetCommandLineA@0 : near
|
||||
|
||||
; fe_rt_write(handle, ptr, len) -> bytes written
|
||||
public fe_rt_write
|
||||
@@ -298,6 +302,78 @@ hex_digit:
|
||||
ret
|
||||
fe_rt_write_hex endp
|
||||
|
||||
; fe_rt_open(path, write) -> handle, or -1
|
||||
; `path` is a NUL-terminated byte string. Reading opens what is there; writing
|
||||
; creates or truncates.
|
||||
public fe_rt_open
|
||||
fe_rt_open proc near
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
push 0 ; hTemplateFile
|
||||
push 128 ; FILE_ATTRIBUTE_NORMAL
|
||||
cmp dword ptr [ebp+12], 0
|
||||
jne open_write
|
||||
push 3 ; OPEN_EXISTING
|
||||
push 0
|
||||
push 1 ; FILE_SHARE_READ
|
||||
push 80000000h ; GENERIC_READ
|
||||
jmp open_call
|
||||
open_write:
|
||||
push 2 ; CREATE_ALWAYS
|
||||
push 0
|
||||
push 0
|
||||
push 40000000h ; GENERIC_WRITE
|
||||
open_call:
|
||||
push dword ptr [ebp+8]
|
||||
call _CreateFileA@28
|
||||
mov esp, ebp
|
||||
pop ebp
|
||||
ret
|
||||
fe_rt_open endp
|
||||
|
||||
; fe_rt_read(handle, buf, len) -> bytes read, or -1
|
||||
public fe_rt_read
|
||||
fe_rt_read proc near
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
push 0
|
||||
push offset written
|
||||
push dword ptr [ebp+16]
|
||||
push dword ptr [ebp+12]
|
||||
push dword ptr [ebp+8]
|
||||
call _ReadFile@20
|
||||
test eax, eax
|
||||
jne read_ok
|
||||
mov eax, -1
|
||||
jmp read_done
|
||||
read_ok:
|
||||
mov eax, [written]
|
||||
read_done:
|
||||
mov esp, ebp
|
||||
pop ebp
|
||||
ret
|
||||
fe_rt_read endp
|
||||
|
||||
; fe_rt_close(handle)
|
||||
public fe_rt_close
|
||||
fe_rt_close proc near
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
push dword ptr [ebp+8]
|
||||
call _CloseHandle@4
|
||||
mov esp, ebp
|
||||
pop ebp
|
||||
ret
|
||||
fe_rt_close endp
|
||||
|
||||
; fe_rt_cmdline() -> pointer to the whole command line, NUL terminated.
|
||||
; Splitting it is the standard library's job, not the runtime's.
|
||||
public fe_rt_cmdline
|
||||
fe_rt_cmdline proc near
|
||||
call _GetCommandLineA@0
|
||||
ret
|
||||
fe_rt_cmdline endp
|
||||
|
||||
; fe_rt_exit(code) -- never returns
|
||||
public fe_rt_exit
|
||||
fe_rt_exit proc near
|
||||
|
||||
Reference in New Issue
Block a user