defer 목록을 '스코프가 아직 갚아야 할 것' 목록으로 일반화했다. defer 블록과 소유 값 해제가 같은 목록에 쓰인 순서대로 들어가고, 모든 이탈 경로가 역순으로 갚는다. 해제에는 값 옆에 플래그를 둔다. 값이 저장될 때 세우고 넘겨줄 때 지운다. 값이 아직 여기 있는 경로에서만 해제되는데, 그건 코드의 모양만 봐서는 알 수 없는 것이다. 검사기가 소유권을 넘기는 사용을 이미 표시해두므로 그것을 읽는다. !void 함수의 빈 return 은 성공이다. 줄 값도 없고 오류도 없다는 뜻인데 프론트엔드가 타입 불일치로 거부하고 있었다. 런타임이 할당/해제 횟수를 센다. owndrop 프로그램이 그 둘이 일치함을 실행으로 증명한다 -- 이른 반환, 이미 넘긴 값, 스코프 끝 전부.
32 lines
1019 B
Plaintext
32 lines
1019 B
Plaintext
unit std.sys;
|
|
|
|
// The few things the language cannot say for itself. The runtime provides
|
|
// them; everything else in the standard library is written in Ferro.
|
|
extern "c" fn fe_rt_write(handle: i32, bytes: *u8, len: usize) -> i32;
|
|
extern "c" fn fe_rt_alloc(n: usize) -> *u8;
|
|
extern "c" fn fe_rt_free(p: *u8);
|
|
extern "c" fn fe_rt_exit(code: i32);
|
|
extern "c" fn fe_rt_allocs() -> i32;
|
|
extern "c" fn fe_rt_frees() -> i32;
|
|
|
|
pub fn exit(code: i32) -> void {
|
|
unsafe { fe_rt_exit(code); }
|
|
}
|
|
|
|
pub fn raw_write(handle: i32, bytes: *u8, len: usize) -> i32 {
|
|
unsafe { return fe_rt_write(handle, bytes, len); }
|
|
}
|
|
|
|
pub fn raw_alloc(n: usize) -> *u8 {
|
|
unsafe { return fe_rt_alloc(n); }
|
|
}
|
|
|
|
pub fn raw_free(p: *u8) -> void {
|
|
unsafe { fe_rt_free(p); }
|
|
}
|
|
|
|
// How many times the allocator was asked to hand out memory, and to take it
|
|
// back. A test can insist the two agree; nothing else should care.
|
|
pub fn allocs() -> i32 { unsafe { return fe_rt_allocs(); } }
|
|
pub fn frees() -> i32 { unsafe { return fe_rt_frees(); } }
|