From 8178e1f7da902598732f941ef42d62b3621e7146 Mon Sep 17 00:00:00 2001 From: bogen85 <52499484+bogen85@users.noreply.github.com> Date: Sun, 8 Dec 2019 04:44:52 -0600 Subject: [PATCH] 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. --- vlib/builtin/bare/.checks/checks.v | 4 +-- .../bare/.checks/forkedtest/forkedtest.v | 30 +++++++------------ vlib/builtin/bare/.checks/linuxsys/linuxsys.v | 15 ++++------ vlib/builtin/bare/.checks/string/string.v | 22 +++++++++++--- vlib/builtin/bare/array_bare.v | 18 +++++++++++ vlib/builtin/bare/builtin_bare.v | 26 ++++++++-------- vlib/builtin/bare/linuxsys_bare.v | 1 + vlib/builtin/bare/mm_bare.v | 17 +++++++++++ vlib/builtin/bare/string_bare.v | 15 +++++----- vlib/compiler/cheaders.v | 4 +++ 10 files changed, 96 insertions(+), 56 deletions(-) diff --git a/vlib/builtin/bare/.checks/checks.v b/vlib/builtin/bare/.checks/checks.v index 25c7618259..0868cf73e5 100644 --- a/vlib/builtin/bare/.checks/checks.v +++ b/vlib/builtin/bare/.checks/checks.v @@ -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() { diff --git a/vlib/builtin/bare/.checks/forkedtest/forkedtest.v b/vlib/builtin/bare/.checks/forkedtest/forkedtest.v index 9d1d27d895..bb2200a586 100644 --- a/vlib/builtin/bare/.checks/forkedtest/forkedtest.v +++ b/vlib/builtin/bare/.checks/forkedtest/forkedtest.v @@ -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 diff --git a/vlib/builtin/bare/.checks/linuxsys/linuxsys.v b/vlib/builtin/bare/.checks/linuxsys/linuxsys.v index dd72c6268d..903bbd8e31 100644 --- a/vlib/builtin/bare/.checks/linuxsys/linuxsys.v +++ b/vlib/builtin/bare/.checks/linuxsys/linuxsys.v @@ -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() { diff --git a/vlib/builtin/bare/.checks/string/string.v b/vlib/builtin/bare/.checks/string/string.v index 5da867c6c6..01d4426cf4 100644 --- a/vlib/builtin/bare/.checks/string/string.v +++ b/vlib/builtin/bare/.checks/string/string.v @@ -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) } diff --git a/vlib/builtin/bare/array_bare.v b/vlib/builtin/bare/array_bare.v index eccf8b5ee5..e2fc075066 100644 --- a/vlib/builtin/bare/array_bare.v +++ b/vlib/builtin/bare/array_bare.v @@ -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 +} diff --git a/vlib/builtin/bare/builtin_bare.v b/vlib/builtin/bare/builtin_bare.v index 05096b908e..d47e53ecf4 100644 --- a/vlib/builtin/bare/builtin_bare.v +++ b/vlib/builtin/bare/builtin_bare.v @@ -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) { diff --git a/vlib/builtin/bare/linuxsys_bare.v b/vlib/builtin/bare/linuxsys_bare.v index 29670e38dc..e3511d1883 100644 --- a/vlib/builtin/bare/linuxsys_bare.v +++ b/vlib/builtin/bare/linuxsys_bare.v @@ -70,6 +70,7 @@ pub enum sig_index { si_pid = 0x04 si_uid = 0x05 si_status = 0x06 + si_size = 0x80 } pub enum signo { diff --git a/vlib/builtin/bare/mm_bare.v b/vlib/builtin/bare/mm_bare.v index a97607916d..8248231a49 100644 --- a/vlib/builtin/bare/mm_bare.v +++ b/vlib/builtin/bare/mm_bare.v @@ -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 +} diff --git a/vlib/builtin/bare/string_bare.v b/vlib/builtin/bare/string_bare.v index f15247990c..1dbd286b0d 100644 --- a/vlib/builtin/bare/string_bare.v +++ b/vlib/builtin/bare/string_bare.v @@ -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 } -*/ diff --git a/vlib/compiler/cheaders.v b/vlib/compiler/cheaders.v index 0146781cc5..aeac952f6b 100644 --- a/vlib/compiler/cheaders.v +++ b/vlib/compiler/cheaders.v @@ -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);