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.pull/3011/head
parent
6ec626c5e9
commit
8178e1f7da
|
@ -12,8 +12,7 @@ fn passed (msg string) {
|
|||
|
||||
|
||||
fn vcheck(vfile string) {
|
||||
//os.system("ln -s ../forkedtest $vfile/forkedtest")
|
||||
run_check := "v -user_mod_path . -freestanding --enable-globals run "
|
||||
run_check := "v -user_mod_path . -freestanding run "
|
||||
if 0 == os.system("$run_check $vfile/${vfile}.v") {
|
||||
passed(run_check)
|
||||
} else {
|
||||
|
@ -21,7 +20,6 @@ fn vcheck(vfile string) {
|
|||
}
|
||||
os.system("ls -lh $vfile/$vfile")
|
||||
os.system("rm -f $vfile/$vfile")
|
||||
//os.system("rm -f $vfile/forkedtest")
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
|
|
@ -1,33 +1,25 @@
|
|||
module forkedtest
|
||||
|
||||
__global buffer [128]byte
|
||||
|
||||
pub fn run (op fn(), label string, code wi_si_code, status int) int {
|
||||
child := sys_fork()
|
||||
if child == 0 {
|
||||
op()
|
||||
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 siginfo[sig_index.si_pid] == child
|
||||
assert siginfo[sig_index.si_signo] == int(signo.sigchld)
|
||||
assert siginfo[sig_index.si_uid] == sys_getuid()
|
||||
assert siginfo[int(sig_index.si_pid)] == child
|
||||
assert siginfo[int(sig_index.si_signo)] == int(signo.sigchld)
|
||||
assert siginfo[int(sig_index.si_uid)] == sys_getuid()
|
||||
|
||||
r_code := siginfo[sig_index.si_code]
|
||||
r_status := siginfo[sig_index.si_status]
|
||||
|
||||
print("+++ ")
|
||||
print(label)
|
||||
if (int(code) == r_code) && (status == r_status) {
|
||||
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 {
|
||||
print(">> Expecting si_code 0x")
|
||||
println(i64_tos(buffer,80,int(code),16))
|
||||
println(i64_str(int(code),16))
|
||||
print(">> Got 0x")
|
||||
println(i64_tos(buffer,80,r_code,16))
|
||||
println(i64_str(r_code,16))
|
||||
}
|
||||
|
||||
if status != r_status {
|
||||
print(">> Expecting status 0x")
|
||||
println(i64_tos(buffer,80,status,16))
|
||||
println(i64_str(status,16))
|
||||
print(">> Got 0x")
|
||||
println(i64_tos(buffer,80,r_status,16))
|
||||
println(i64_str(r_status,16))
|
||||
}
|
||||
|
||||
return 1
|
||||
|
|
|
@ -40,15 +40,15 @@ fn check_read_write_pipe() {
|
|||
// sys_read
|
||||
// sys_close
|
||||
//
|
||||
buffer, e := mm_alloc(128)
|
||||
assert e == .enoerror
|
||||
buffer0 := [byte(0)].repeat(128)
|
||||
buffer := byteptr(buffer0.data)
|
||||
|
||||
fd := [-1, -1]
|
||||
|
||||
assert fd[0] == -1
|
||||
assert fd[1] == -1
|
||||
|
||||
a := sys_pipe(intptr(fd.data))
|
||||
a := sys_pipe(intptr(&fd[0]))
|
||||
|
||||
assert a == .enoerror
|
||||
|
||||
|
@ -62,7 +62,7 @@ fn check_read_write_pipe() {
|
|||
assert e1 == .enoerror
|
||||
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 c2 == b
|
||||
|
@ -77,8 +77,6 @@ fn check_read_write_pipe() {
|
|||
assert sys_close(fd[1]) == .enoerror
|
||||
|
||||
assert sys_close(-1) == .ebadf
|
||||
|
||||
assert mm_free(buffer) == .enoerror
|
||||
}
|
||||
|
||||
fn check_read_file() {
|
||||
|
@ -89,8 +87,8 @@ fn check_read_file() {
|
|||
sys_close
|
||||
sys_open
|
||||
*/
|
||||
buffer, mae := mm_alloc(128)
|
||||
assert mae == .enoerror
|
||||
buffer0 := [byte(0)].repeat(128)
|
||||
buffer := byteptr(buffer0.data)
|
||||
|
||||
test_file := "sample_text1.txt"
|
||||
sample_text := "Do not change this text.\n"
|
||||
|
@ -105,7 +103,6 @@ fn check_read_file() {
|
|||
assert sample_text[i] == buffer[i]
|
||||
}
|
||||
assert sys_close(fd) == .enoerror
|
||||
assert mm_free(buffer) == .enoerror
|
||||
}
|
||||
|
||||
fn check_open_file_fail() {
|
||||
|
|
|
@ -8,9 +8,8 @@ fn check_string_eq () {
|
|||
}
|
||||
|
||||
fn check_i64_tos() {
|
||||
buffer, e := mm_alloc(128)
|
||||
assert e == .enoerror
|
||||
assert !isnil(buffer)
|
||||
buffer0 := [byte(0)].repeat(128)
|
||||
buffer := byteptr(buffer0.data)
|
||||
|
||||
s0 := i64_tos(buffer, 70, 140, 10)
|
||||
assert s0 == "140"
|
||||
|
@ -23,14 +22,29 @@ fn check_i64_tos() {
|
|||
|
||||
s3 := i64_tos(buffer, 70, -160000, 10)
|
||||
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 () {
|
||||
mut fails := 0
|
||||
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_str, "check_i64_str")
|
||||
fails += forkedtest.normal_run(check_str_clone, "check_str_clone")
|
||||
assert fails == 0
|
||||
sys_exit(0)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
||||
// 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
|
||||
}
|
||||
|
|
|
@ -18,25 +18,25 @@ pub fn println(s string) {
|
|||
}
|
||||
|
||||
pub fn panic(s string) {
|
||||
print('V panic: ')
|
||||
println(s)
|
||||
eprint('V panic: ')
|
||||
eprintln(s)
|
||||
sys_exit(1)
|
||||
}
|
||||
|
||||
// replaces panic when -debug arg is passed
|
||||
fn panic_debug(line_no int, file, mod, fn_name, s string) {
|
||||
println('================ V panic ================')
|
||||
print(' module: ')
|
||||
println('mod')
|
||||
print(' function: ')
|
||||
print(fn_name)
|
||||
println('()')
|
||||
println(' file: ')
|
||||
println(file)
|
||||
eprintln('================ V panic ================')
|
||||
eprint(' module: ')
|
||||
eprintln('mod')
|
||||
eprint(' function: ')
|
||||
eprint(fn_name)
|
||||
eprintln('()')
|
||||
eprintln(' file: ')
|
||||
eprintln(file)
|
||||
//println(' line: ${line_no}')
|
||||
print(' message: ')
|
||||
println(s)
|
||||
println('=========================================')
|
||||
eprint(' message: ')
|
||||
eprintln(s)
|
||||
eprintln('=========================================')
|
||||
sys_exit(1)
|
||||
}
|
||||
pub fn eprint(s string) {
|
||||
|
|
|
@ -70,6 +70,7 @@ pub enum sig_index {
|
|||
si_pid = 0x04
|
||||
si_uid = 0x05
|
||||
si_status = 0x06
|
||||
si_size = 0x80
|
||||
}
|
||||
|
||||
pub enum signo {
|
||||
|
|
|
@ -39,3 +39,20 @@ pub fn mem_copy(dest0 voidptr, src0 voidptr, n int) voidptr {
|
|||
}
|
||||
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
|
||||
}
|
||||
|
|
|
@ -95,18 +95,17 @@ pub fn i64_tos(buf byteptr, len int, n0 i64, base int) string {
|
|||
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 {
|
||||
mut b := string {
|
||||
len: a.len
|
||||
str: malloc(a.len + 1)
|
||||
}
|
||||
for i := 0; i < a.len; i++ {
|
||||
b[i] = a[i]
|
||||
}
|
||||
mem_copy(b.str, a.str, a.len)
|
||||
b[a.len] = `\0`
|
||||
return b
|
||||
}
|
||||
*/
|
||||
|
|
|
@ -219,6 +219,10 @@ bare_c_headers = '
|
|||
#define TCCSKIP(x)
|
||||
#endif
|
||||
|
||||
#ifndef EMPTY_STRUCT_INITIALIZATION
|
||||
#define EMPTY_STRUCT_INITIALIZATION 0
|
||||
#endif
|
||||
|
||||
#ifndef exit
|
||||
#define exit(rc) sys_exit(rc)
|
||||
void sys_exit (int);
|
||||
|
|
Loading…
Reference in New Issue