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
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) {
//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() {

View File

@ -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

View File

@ -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() {

View File

@ -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)
}

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)
}
// 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) {
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) {

View File

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

View File

@ -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
}

View File

@ -8,9 +8,9 @@ pub:
pub fn strlen(s byteptr) int {
mut i := 0
for ; s[i] != 0; i++ {}
for ; s[i] != 0; i++ {}
return i
}
}
pub fn tos(s byteptr, len int) string {
if s == 0 {
@ -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
}
*/

View File

@ -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);