1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

freestanding: malloc/free with mm_alloc an mm_free

Added more array support that depends on malloc. Added string clone (that uses malloc). Added test for it. Eliminated stack allocated buffers from most of the unit checks.
This commit is contained in:
bogen85 2019-12-08 04:44:52 -06:00 committed by Alexander Medvednikov
parent 6ec626c5e9
commit 8178e1f7da
10 changed files with 96 additions and 56 deletions

View File

@ -12,8 +12,7 @@ fn passed (msg string) {
fn vcheck(vfile string) { fn vcheck(vfile string) {
//os.system("ln -s ../forkedtest $vfile/forkedtest") run_check := "v -user_mod_path . -freestanding run "
run_check := "v -user_mod_path . -freestanding --enable-globals run "
if 0 == os.system("$run_check $vfile/${vfile}.v") { if 0 == os.system("$run_check $vfile/${vfile}.v") {
passed(run_check) passed(run_check)
} else { } else {
@ -21,7 +20,6 @@ fn vcheck(vfile string) {
} }
os.system("ls -lh $vfile/$vfile") os.system("ls -lh $vfile/$vfile")
os.system("rm -f $vfile/$vfile") os.system("rm -f $vfile/$vfile")
//os.system("rm -f $vfile/forkedtest")
} }
fn main() { fn main() {

View File

@ -1,33 +1,25 @@
module forkedtest module forkedtest
__global buffer [128]byte
pub fn run (op fn(), label string, code wi_si_code, status int) int { pub fn run (op fn(), label string, code wi_si_code, status int) int {
child := sys_fork() child := sys_fork()
if child == 0 { if child == 0 {
op() op()
sys_exit(0) sys_exit(0)
} }
siginfo := [
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0]
e := sys_waitid(.p_pid, child, intptr(siginfo.data) , .wexited, 0) siginfo := [0].repeat(int(sig_index.si_size))
e := sys_waitid(.p_pid, child, intptr(&siginfo[0]), .wexited, 0)
assert e == .enoerror assert e == .enoerror
assert siginfo[sig_index.si_pid] == child assert siginfo[int(sig_index.si_pid)] == child
assert siginfo[sig_index.si_signo] == int(signo.sigchld) assert siginfo[int(sig_index.si_signo)] == int(signo.sigchld)
assert siginfo[sig_index.si_uid] == sys_getuid() assert siginfo[int(sig_index.si_uid)] == sys_getuid()
r_code := siginfo[sig_index.si_code] r_code := siginfo[sig_index.si_code]
r_status := siginfo[sig_index.si_status] r_status := siginfo[sig_index.si_status]
print("+++ ")
print(label) print(label)
if (int(code) == r_code) && (status == r_status) { if (int(code) == r_code) && (status == r_status) {
println(" PASSED") println(" PASSED")
@ -37,16 +29,16 @@ pub fn run (op fn(), label string, code wi_si_code, status int) int {
if int(code) != r_code { if int(code) != r_code {
print(">> Expecting si_code 0x") print(">> Expecting si_code 0x")
println(i64_tos(buffer,80,int(code),16)) println(i64_str(int(code),16))
print(">> Got 0x") print(">> Got 0x")
println(i64_tos(buffer,80,r_code,16)) println(i64_str(r_code,16))
} }
if status != r_status { if status != r_status {
print(">> Expecting status 0x") print(">> Expecting status 0x")
println(i64_tos(buffer,80,status,16)) println(i64_str(status,16))
print(">> Got 0x") print(">> Got 0x")
println(i64_tos(buffer,80,r_status,16)) println(i64_str(r_status,16))
} }
return 1 return 1

View File

@ -40,15 +40,15 @@ fn check_read_write_pipe() {
// sys_read // sys_read
// sys_close // sys_close
// //
buffer, e := mm_alloc(128) buffer0 := [byte(0)].repeat(128)
assert e == .enoerror buffer := byteptr(buffer0.data)
fd := [-1, -1] fd := [-1, -1]
assert fd[0] == -1 assert fd[0] == -1
assert fd[1] == -1 assert fd[1] == -1
a := sys_pipe(intptr(fd.data)) a := sys_pipe(intptr(&fd[0]))
assert a == .enoerror assert a == .enoerror
@ -62,7 +62,7 @@ fn check_read_write_pipe() {
assert e1 == .enoerror assert e1 == .enoerror
assert c1 == b assert c1 == b
c2, e2 := sys_read(fd[0], byteptr(buffer), u64(b)) c2, e2 := sys_read(fd[0], buffer, u64(b))
assert e2 == .enoerror assert e2 == .enoerror
assert c2 == b assert c2 == b
@ -77,8 +77,6 @@ fn check_read_write_pipe() {
assert sys_close(fd[1]) == .enoerror assert sys_close(fd[1]) == .enoerror
assert sys_close(-1) == .ebadf assert sys_close(-1) == .ebadf
assert mm_free(buffer) == .enoerror
} }
fn check_read_file() { fn check_read_file() {
@ -89,8 +87,8 @@ fn check_read_file() {
sys_close sys_close
sys_open sys_open
*/ */
buffer, mae := mm_alloc(128) buffer0 := [byte(0)].repeat(128)
assert mae == .enoerror buffer := byteptr(buffer0.data)
test_file := "sample_text1.txt" test_file := "sample_text1.txt"
sample_text := "Do not change this text.\n" sample_text := "Do not change this text.\n"
@ -105,7 +103,6 @@ fn check_read_file() {
assert sample_text[i] == buffer[i] assert sample_text[i] == buffer[i]
} }
assert sys_close(fd) == .enoerror assert sys_close(fd) == .enoerror
assert mm_free(buffer) == .enoerror
} }
fn check_open_file_fail() { fn check_open_file_fail() {

View File

@ -8,9 +8,8 @@ fn check_string_eq () {
} }
fn check_i64_tos() { fn check_i64_tos() {
buffer, e := mm_alloc(128) buffer0 := [byte(0)].repeat(128)
assert e == .enoerror buffer := byteptr(buffer0.data)
assert !isnil(buffer)
s0 := i64_tos(buffer, 70, 140, 10) s0 := i64_tos(buffer, 70, 140, 10)
assert s0 == "140" assert s0 == "140"
@ -23,14 +22,29 @@ fn check_i64_tos() {
s3 := i64_tos(buffer, 70, -160000, 10) s3 := i64_tos(buffer, 70, -160000, 10)
assert s3 == "-160000" assert s3 == "-160000"
}
assert mm_free(buffer) == .enoerror fn check_i64_str() {
assert "141" == i64_str(141, 10)
assert "-161" == i64_str(-161, 10)
assert "10002" == i64_str(65538, 16)
assert "-160001" == i64_str(-160001, 10)
}
fn check_str_clone() {
a := i64_str(1234,10)
b := a.clone()
assert a == b
c := i64_str(-6789,10).clone()
assert c == "-6789"
} }
fn main () { fn main () {
mut fails := 0 mut fails := 0
fails += forkedtest.normal_run(check_string_eq, "check_string_eq") fails += forkedtest.normal_run(check_string_eq, "check_string_eq")
fails += forkedtest.normal_run(check_i64_tos, "check_i64_tos") fails += forkedtest.normal_run(check_i64_tos, "check_i64_tos")
fails += forkedtest.normal_run(check_i64_str, "check_i64_str")
fails += forkedtest.normal_run(check_str_clone, "check_str_clone")
assert fails == 0 assert fails == 0
sys_exit(0) sys_exit(0)
} }

View File

@ -34,3 +34,21 @@ fn (a mut array) set(i int, val voidptr) {
} }
mem_copy(a.data + a.element_size * i, val, a.element_size) mem_copy(a.data + a.element_size * i, val, a.element_size)
} }
// array.repeat returns new array with the given array elements
// repeated `nr_repeat` times
pub fn (a array) repeat(nr_repeats int) array {
assert nr_repeats >= 0
arr := array {
len: nr_repeats * a.len
cap: nr_repeats * a.len
element_size: a.element_size
data: malloc(nr_repeats * a.len * a.element_size)
}
for i := 0; i < nr_repeats; i++ {
mem_copy(arr.data + i * a.len * a.element_size, a.data, a.len * a.element_size)
}
return arr
}

View File

@ -18,25 +18,25 @@ pub fn println(s string) {
} }
pub fn panic(s string) { pub fn panic(s string) {
print('V panic: ') eprint('V panic: ')
println(s) eprintln(s)
sys_exit(1) sys_exit(1)
} }
// replaces panic when -debug arg is passed // replaces panic when -debug arg is passed
fn panic_debug(line_no int, file, mod, fn_name, s string) { fn panic_debug(line_no int, file, mod, fn_name, s string) {
println('================ V panic ================') eprintln('================ V panic ================')
print(' module: ') eprint(' module: ')
println('mod') eprintln('mod')
print(' function: ') eprint(' function: ')
print(fn_name) eprint(fn_name)
println('()') eprintln('()')
println(' file: ') eprintln(' file: ')
println(file) eprintln(file)
//println(' line: ${line_no}') //println(' line: ${line_no}')
print(' message: ') eprint(' message: ')
println(s) eprintln(s)
println('=========================================') eprintln('=========================================')
sys_exit(1) sys_exit(1)
} }
pub fn eprint(s string) { pub fn eprint(s string) {

View File

@ -70,6 +70,7 @@ pub enum sig_index {
si_pid = 0x04 si_pid = 0x04
si_uid = 0x05 si_uid = 0x05
si_status = 0x06 si_status = 0x06
si_size = 0x80
} }
pub enum signo { pub enum signo {

View File

@ -39,3 +39,20 @@ pub fn mem_copy(dest0 voidptr, src0 voidptr, n int) voidptr {
} }
return dest0 return dest0
} }
[unsafe_fn]
pub fn malloc(n int) byteptr {
if n < 0 {
panic('malloc(<0)')
}
ptr, e := mm_alloc(u64(n))
assert e == .enoerror
assert !isnil(ptr)
return ptr
}
[unsafe_fn]
pub fn free(ptr voidptr) {
assert mm_free(ptr) == .enoerror
}

View File

@ -8,9 +8,9 @@ pub:
pub fn strlen(s byteptr) int { pub fn strlen(s byteptr) int {
mut i := 0 mut i := 0
for ; s[i] != 0; i++ {} for ; s[i] != 0; i++ {}
return i return i
} }
pub fn tos(s byteptr, len int) string { pub fn tos(s byteptr, len int) string {
if s == 0 { if s == 0 {
@ -95,18 +95,17 @@ pub fn i64_tos(buf byteptr, len int, n0 i64, base int) string {
return b return b
} }
pub fn i64_str(n0 i64, base int) string {
buf := malloc(80)
return i64_tos(buf, 79, n0, base)
}
/*
pub fn (a string) clone() string { pub fn (a string) clone() string {
mut b := string { mut b := string {
len: a.len len: a.len
str: malloc(a.len + 1) str: malloc(a.len + 1)
} }
for i := 0; i < a.len; i++ { mem_copy(b.str, a.str, a.len)
b[i] = a[i]
}
b[a.len] = `\0` b[a.len] = `\0`
return b return b
} }
*/

View File

@ -219,6 +219,10 @@ bare_c_headers = '
#define TCCSKIP(x) #define TCCSKIP(x)
#endif #endif
#ifndef EMPTY_STRUCT_INITIALIZATION
#define EMPTY_STRUCT_INITIALIZATION 0
#endif
#ifndef exit #ifndef exit
#define exit(rc) sys_exit(rc) #define exit(rc) sys_exit(rc)
void sys_exit (int); void sys_exit (int);