diff --git a/vlib/builtin/bare/.checks/checks.v b/vlib/builtin/bare/.checks/checks.v index 8e9df4fc10..bb894b6074 100644 --- a/vlib/builtin/bare/.checks/checks.v +++ b/vlib/builtin/bare/.checks/checks.v @@ -12,12 +12,13 @@ fn passed (msg string) { fn vcheck(vfile string) { - run_check := "v -freestanding --enable-globals run " + run_check := "v -show_c_cmd -freestanding --enable-globals run " if 0 == os.system("$run_check $vfile/${vfile}.v") { passed(run_check) } else { failed(run_check) } + os.system("ls -lh $vfile/$vfile") os.system("rm -f $vfile/$vfile") } diff --git a/vlib/builtin/bare/.checks/linuxsys/linuxsys.v b/vlib/builtin/bare/.checks/linuxsys/linuxsys.v index 1e119df1c7..68f67c8ef0 100644 --- a/vlib/builtin/bare/.checks/linuxsys/linuxsys.v +++ b/vlib/builtin/bare/.checks/linuxsys/linuxsys.v @@ -165,7 +165,7 @@ fn check_mm_pages() { //pub fn mm_alloc(size u64) (voidptr, errno) fn check_mm_alloc() { - println ("checking check_mm_alloc") + println ("checking mm_alloc") for i in 1 .. 2000 { size := u64(i*1000) @@ -201,6 +201,107 @@ fn check_mm_alloc() { println ("mm_alloc passed") } +fn check_int_array_ro() { + println ("trying check_int_array_ro") + a := [100,110,120,130] + assert a.len == 4 + assert a[0] == 100 + assert a[1] == 110 + assert a[2] == 120 + assert a[3] == 130 + println ("check_int_array_ro passed") +} + +fn check_int_array_rw() { + println ("trying check_int_array_rw") + mut a := [-10,-11,-12,-13] + assert a.len == 4 + assert a[0] == -10 + assert a[1] == -11 + assert a[2] == -12 + assert a[3] == -13 + for i in 0..a.len { + b := -a[i] * 10 + a[i] = b + assert a[i] == b + } + assert a[3] == 130 + + println ("check_int_array_rw passed") +} + +fn check_int64_array_ro() { + println ("trying check_int64_array_ro") + a := [i64(1000),1100,1200,1300,1400] + assert a.len == 5 + assert a[0] == 1000 + assert a[1] == 1100 + assert a[2] == 1200 + assert a[3] == 1300 + assert a[4] == 1400 + println ("check_int64_array_ro passed") +} + +fn check_voidptr_array_ro() { + println ("trying check_voidptr_array_ro") + a := [ + voidptr(10000), + voidptr(11000), + voidptr(12000), + voidptr(13000), + voidptr(14000), + voidptr(15000) + ] + assert a.len == 6 + assert a[0] == voidptr(10000) + assert a[1] == voidptr(11000) + assert a[2] == voidptr(12000) + assert a[3] == voidptr(13000) + assert a[4] == voidptr(14000) + assert a[5] == voidptr(15000) + println ("check_voidptr_array_ro passed") +} + +fn check_voidptr_array_rw() { + println ("trying check_voidptr_array_rw") + mut a := [ + voidptr(-1), + voidptr(-1), + voidptr(-1), + voidptr(-1), + voidptr(-1), + voidptr(-1) + ] + assert a.len == 6 + + assert a[0] == voidptr(-1) + assert a[1] == voidptr(-1) + assert a[2] == voidptr(-1) + assert a[3] == voidptr(-1) + assert a[4] == voidptr(-1) + assert a[5] == voidptr(-1) + + a[0] = voidptr(100000) + assert a[0] == voidptr(100000) + + a[1] = voidptr(110000) + assert a[1] == voidptr(110000) + + a[2] = voidptr(120000) + assert a[2] == voidptr(120000) + + a[3] = voidptr(130000) + assert a[3] == voidptr(130000) + + a[4] = voidptr(140000) + assert a[4] == voidptr(140000) + + a[5] = voidptr(150000) + assert a[5] == voidptr(150000) + println ("check_voidptr_array_rw passed") +} + + fn main() { check_read_write_pipe() check_read_file() @@ -210,5 +311,10 @@ fn main() { check_mmap_one_page() check_mm_pages() check_mm_alloc() + check_int_array_ro() + check_int_array_rw() + check_int64_array_ro() + check_voidptr_array_ro() + check_voidptr_array_rw() sys_exit(0) } diff --git a/vlib/builtin/bare/array_bare.v b/vlib/builtin/bare/array_bare.v new file mode 100644 index 0000000000..eccf8b5ee5 --- /dev/null +++ b/vlib/builtin/bare/array_bare.v @@ -0,0 +1,36 @@ +module builtin + +pub struct array { +pub: + data voidptr + len int + cap int + element_size int +} + +// for now off the stack +fn new_array_from_c_array(len, cap, elm_size int, c_array voidptr) array { + arr := array { + len: len + cap: cap + element_size: elm_size + data: c_array + } + return arr +} + +// Private function. Used to implement array[] operator +fn (a array) get(i int) voidptr { + if i < 0 || i >= a.len { + panic('array.get: index out of range') // FIXME: (i == $i, a.len == $a.len)') + } + return a.data + i * a.element_size +} + +// Private function. Used to implement assigment to the array element. +fn (a mut array) set(i int, val voidptr) { + if i < 0 || i >= a.len { + panic('array.set: index out of range') //FIXME: (i == $i, a.len == $a.len)') + } + mem_copy(a.data + a.element_size * i, val, a.element_size) +} diff --git a/vlib/builtin/bare/linuxsys_bare.v b/vlib/builtin/bare/linuxsys_bare.v index ac707c3ff7..c4a6386954 100644 --- a/vlib/builtin/bare/linuxsys_bare.v +++ b/vlib/builtin/bare/linuxsys_bare.v @@ -17,12 +17,53 @@ pub enum wp_sys { } // First argument to waitid: -pub enum wi_sys { +pub enum wi_which { p_all = 0 p_pid = 1 p_pgid = 2 } +pub enum wi_si_code { + cld_exited = 1 // child has exited + cld_killed = 2 // child was killed + cld_dumped = 3 // child terminated abnormally + cld_trapped = 4 // traced child has trapped + cld_stopped = 5 // child has stopped + cld_continued = 6 // stopped child has continued +} + +/* Paraphrased from "man 2 waitid" on Linux + + Upon successful return, waitid() fills in the + following fields of the siginfo_t structure + pointed to by infop: + + si_pid, offset 0x10, int index 0x04: + The process ID of the child. + + si_uid: offset 0x14, int index 0x05 + The real user ID of the child. + + si_signo: offset 0x00, int index 0x00 + Always set to SIGCHLD. + + si_status: ofset 0x18, int index 0x06 + 1 the exit status of the child, as given to _exit(2) + (or exit(3)) (sc_sys.cld_exited) + 2 the signal that caused the child to terminate, stop, + or continue. + 3 The si_code field can be used to determine how to + interpret this field. + + si_code, set to one of (enum wi_si_code), offset 0x08, int index 0x02: + CLD_EXITED (child called _exit(2)); + CLD_KILLED (child killed by signal); + CLD_DUMPED (child killed by signal, and dumped core); + CLD_STOPPED (child stopped by signal); + CLD_TRAPPED (traced child has trapped); + CLD_CONTINUED (child continued by SIGCONT). +*/ + pub enum fcntl { fd_cloexec = 0x00000001 f_dupfd = 0x00000000 diff --git a/vlib/builtin/bare/mm_bare.v b/vlib/builtin/bare/mm_bare.v index 52d05e121d..29809f777b 100644 --- a/vlib/builtin/bare/mm_bare.v +++ b/vlib/builtin/bare/mm_bare.v @@ -1,7 +1,5 @@ module builtin -//__global buffer [128]byte - pub fn mm_pages(size u64) u32 { pages := (u64(size+u64(4))+u64(linux_mem.page_size))/u64(linux_mem.page_size) return u32(pages) @@ -14,16 +12,6 @@ pub fn mm_alloc(size u64) (byteptr, errno) { mem_prot := mm_prot(int(mm_prot.prot_read) | int(mm_prot.prot_write)) mem_flags := map_flags(int(map_flags.map_private) | int(map_flags.map_anonymous)) - //mps := i64_tos(buffer,80,i64(mem_prot),16) - //println(mps) - //mfs := i64_tos(buffer,80,i64(mem_flags),16) - //println(mfs) - - //print("pages in: ") - //ps := i64_tos(buffer,80,i64(pages),16) - //println(ps) - - a, e := sys_mmap(0, n_bytes, mem_prot, mem_flags, -1, 0) if e == .enoerror { mut ap := intptr(a) @@ -37,20 +25,14 @@ pub fn mm_free(addr byteptr) errno { ap := intptr(addr-4) size := u64(*ap) * u64(linux_mem.page_size) - //aps := i64_tos(buffer,80,i64(addr),16) - //println(aps) - - //ss := i64_tos(buffer,80,i64(size),16) - //print("size out: ") - //println(ss) - - //pas := i64_tos(buffer,80,i64(ap),16) - //println(pas) - - e := sys_munmap(ap, size) - - //es := i64_tos(buffer,80,i64(e),16) - //println(es) - - return e + return sys_munmap(ap, size) +} + +pub fn mem_copy(dest0 voidptr, src0 voidptr, n int) voidptr { + mut dest := byteptr(dest0) + src := byteptr(src0) + for i in 0..n { + dest[i] = src[i] + } + return dest0 } diff --git a/vlib/builtin/bare/syscallwrapper_test.v b/vlib/builtin/bare/syscallwrapper_test.v index 8496b2182d..f98797f104 100644 --- a/vlib/builtin/bare/syscallwrapper_test.v +++ b/vlib/builtin/bare/syscallwrapper_test.v @@ -1,20 +1,25 @@ import os fn test_syscallwrappers() { - if true {return} - vexe := os.getenv("VEXE") - vn := vexe.len - 1 - if vn > 1 { - dot_checks := vexe.substr(0,vn) + "vlib/builtin/bare/.checks" - assert os.dir_exists(dot_checks) - os.chdir(dot_checks) - checks_v := "checks.v" - assert os.file_exists(checks_v) - rc := os.exec("v run $checks_v") or { panic(err) } - assert !rc.output.contains("V panic: An assertion failed.") - assert !rc.output.contains("failed") - assert rc.exit_code == 0 - } else { - panic("Can't find v") + if true { return } + $if linux { + $if x64 { + exe := os.executable() + vdir := os.dir(exe) + if vdir.len > 1 { + dot_checks := vdir + "/.checks" + assert os.dir_exists(dot_checks) + + os.chdir(dot_checks) + checks_v := "checks.v" + assert os.file_exists(checks_v) + rc := os.exec("v run $checks_v") or { panic(err) } + assert !rc.output.contains("V panic: An assertion failed.") + assert !rc.output.contains("failed") + assert rc.exit_code == 0 + } else { + panic("Can't find test directory") + } + } } } diff --git a/vlib/compiler/cc.v b/vlib/compiler/cc.v index 779b2a8bba..19fbe2ba3b 100644 --- a/vlib/compiler/cc.v +++ b/vlib/compiler/cc.v @@ -126,7 +126,7 @@ fn (v mut V) cc() { v.out_name = v.out_name + '.so' } if v.pref.is_bare { - a << '-static -ffreestanding -nostdlib $vdir/vlib/os/bare/bare.S' + a << '-fno-stack-protector -static -ffreestanding -nostdlib $vdir/vlib/os/bare/bare.S' } if v.pref.build_mode == .build_module { // Create the modules & out directory if it's not there. @@ -263,7 +263,7 @@ fn (v mut V) cc() { a << libs // Without these libs compilation will fail on Linux // || os.user_os() == 'linux' - if v.pref.build_mode != .build_module && (v.os == .linux || v.os == .freebsd || v.os == .openbsd || + if !v.pref.is_bare && v.pref.build_mode != .build_module && (v.os == .linux || v.os == .freebsd || v.os == .openbsd || v.os == .netbsd || v.os == .dragonfly || v.os == .solaris) { a << '-lm -lpthread ' // -ldl is a Linux only thing. BSDs have it in libc. @@ -272,7 +272,7 @@ fn (v mut V) cc() { } } - if v.os == .js && os.user_os() == 'linux' { + if !v.pref.is_bare && v.os == .js && os.user_os() == 'linux' { a << '-lm' } diff --git a/vlib/compiler/cheaders.v b/vlib/compiler/cheaders.v index cf5f360c96..f0dcaa94cd 100644 --- a/vlib/compiler/cheaders.v +++ b/vlib/compiler/cheaders.v @@ -206,4 +206,17 @@ typedef map map_string; #define false 0 #endif ' + +bare_c_headers = ' + +#define EMPTY_ARRAY_OF_ELEMS(x,n) (x[]) +#define TCCSKIP(x) x + +#ifdef __TINYC__ +#undef EMPTY_ARRAY_OF_ELEMS +#define EMPTY_ARRAY_OF_ELEMS(x,n) (x[n]) +#undef TCCSKIP +#define TCCSKIP(x) +#endif +' ) diff --git a/vlib/compiler/main.v b/vlib/compiler/main.v index 1784dcbfa2..58de02e256 100644 --- a/vlib/compiler/main.v +++ b/vlib/compiler/main.v @@ -254,6 +254,8 @@ pub fn (v mut V) compile() { if !v.pref.is_bare { cgen.genln(c_headers) + } else { + cgen.genln(bare_c_headers) } } v.generate_hotcode_reloading_declarations()