v2 / vlib / builtin / linux_bare / libc_impl.v
174 lines · 150 sloc · 3.33 KB · 28bfd02af512f572aaa1255332ca95bf363da05e
Raw
1module builtin
2
3import dlmalloc
4
5__global global_allocator dlmalloc.Dlmalloc
6
7@[export: 'memcpy']
8@[unsafe]
9pub fn memcpy(dest voidptr, const_src voidptr, n usize) voidptr {
10 dest_ := unsafe { &u8(dest) }
11 src_ := unsafe { &u8(const_src) }
12 unsafe {
13 for i in 0 .. int(n) {
14 dest_[i] = src_[i]
15 }
16 }
17 return unsafe { dest }
18}
19
20@[export: 'malloc']
21@[unsafe]
22fn __malloc(n usize) voidptr {
23 return unsafe { global_allocator.malloc(n) }
24}
25
26@[export: 'strlen']
27@[unsafe]
28fn strlen(const_s voidptr) usize {
29 s := unsafe { &u8(const_s) }
30 mut i := 0
31 for ; unsafe { s[i] } != 0; i++ {}
32 return usize(i)
33}
34
35@[export: 'realloc']
36@[unsafe]
37fn realloc(old_area voidptr, new_size usize) voidptr {
38 if old_area == 0 {
39 return unsafe { malloc(int(new_size)) }
40 }
41 if new_size == usize(0) {
42 unsafe { free(old_area) }
43 return 0
44 }
45 old_size := unsafe { *(&u64(&u64(old_area) - sizeof(u64))) }
46 if u64(new_size) <= old_size {
47 return unsafe { old_area }
48 } else {
49 new_area := unsafe { malloc(int(new_size)) }
50 unsafe { memmove(new_area, old_area, usize(old_size)) }
51 unsafe { free(old_area) }
52 return new_area
53 }
54}
55
56@[export: 'memset']
57@[unsafe]
58fn memset(s voidptr, c int, n usize) voidptr {
59 mut s_ := unsafe { &char(s) }
60 for i in 0 .. int(n) {
61 unsafe {
62 s_[i] = char(c)
63 }
64 }
65 return unsafe { s }
66}
67
68@[export: 'memmove']
69@[unsafe]
70fn memmove(dest voidptr, const_src voidptr, n usize) voidptr {
71 dest_ := unsafe { &u8(dest) }
72 src_ := unsafe { &u8(const_src) }
73 mut temp_buf := unsafe { malloc(int(n)) }
74 for i in 0 .. int(n) {
75 unsafe {
76 temp_buf[i] = src_[i]
77 }
78 }
79
80 for i in 0 .. int(n) {
81 unsafe {
82 dest_[i] = temp_buf[i]
83 }
84 }
85 unsafe { free(temp_buf) }
86 return unsafe { dest }
87}
88
89@[export: 'calloc']
90@[unsafe]
91fn __calloc(nmemb usize, size usize) voidptr {
92 new_area := unsafe { malloc(int(nmemb) * int(size)) }
93 unsafe { memset(new_area, 0, nmemb * size) }
94 return new_area
95}
96
97fn getchar() int {
98 x := u8(0)
99 sys_read(0, &x, 1)
100 return int(x)
101}
102
103@[export: 'memcmp']
104fn memcmp(const_a voidptr, const_b voidptr, n usize) int {
105 a_ := unsafe { &u8(const_a) }
106 b_ := unsafe { &u8(const_b) }
107 for i in 0 .. int(n) {
108 if unsafe { a_[i] != b_[i] } {
109 unsafe {
110 return a_[i] - b_[i]
111 }
112 }
113 }
114 return 0
115}
116
117@[export: 'free']
118@[unsafe]
119fn __free(ptr voidptr) {
120 unsafe {
121 global_allocator.free_(ptr)
122 }
123}
124
125fn vsprintf(str &char, format &char, ap &u8) int {
126 panic('vsprintf(): string interpolation is not supported in `-freestanding`')
127}
128
129fn vsnprintf(str &char, size usize, format &char, ap &u8) int {
130 panic('vsnprintf(): string interpolation is not supported in `-freestanding`')
131}
132
133// not really needed
134fn bare_read(buf &u8, count u64) (i64, Errno) {
135 return sys_read(0, buf, count)
136}
137
138pub fn bare_print(buf &u8, len u64) {
139 sys_write(1, buf, len)
140}
141
142fn bare_eprint(buf &u8, len u64) {
143 sys_write(2, buf, len)
144}
145
146pub fn write(fd i64, buf &u8, count u64) i64 {
147 x, _ := sys_write(fd, buf, count)
148 return x
149}
150
151@[noreturn]
152fn bare_panic(msg string) {
153 println('V panic' + msg)
154 exit(1)
155}
156
157fn bare_backtrace() string {
158 return 'backtraces are not available with `-freestanding`'
159}
160
161@[export: 'exit']
162@[noreturn]
163fn __exit(code int) {
164 sys_exit(code)
165}
166
167@[export: 'qsort']
168fn __qsort(base voidptr, nmemb usize, size usize, sort_cb FnSortCB) {
169 panic('qsort() is not yet implemented in `-freestanding`')
170}
171
172fn init_global_allocator() {
173 global_allocator = dlmalloc.new(get_linux_allocator())
174}
175