From 54707ff81d53e21619be690c1fc2622ed91d7acb Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Mon, 16 Dec 2019 22:22:04 +0300 Subject: [PATCH] do not allow calloc(0) --- tools/fast/fast.v | 14 +++++++++----- tools/fast/header.html | 2 +- vlib/builtin/array.v | 18 ++++++++++++++---- vlib/builtin/builtin.v | 6 +++--- vlib/builtin/option.v | 10 ++++++++++ vlib/compiler/fn.v | 1 + 6 files changed, 38 insertions(+), 13 deletions(-) diff --git a/tools/fast/fast.v b/tools/fast/fast.v index 2c7b426f7d..04e9642b99 100644 --- a/tools/fast/fast.v +++ b/tools/fast/fast.v @@ -11,22 +11,26 @@ fn main() { vdir := os.dir(os.dir(dir)) if !os.exists('$vdir/v') && !os.is_dir('$vdir/vlib') { println('fast.html generator needs to be located in `v/tools/fast/`') - } + } println('fast.html generator\n') // Fetch the last commit's hash println('Fetching updates...') - exec('git pull --rebase') + ret := os.system('git pull --rebase') + if ret != 0 { + println('failed to git pull') + return + } mut commit_hash := exec('git rev-parse HEAD') commit_hash = commit_hash[..7] if !os.exists('table.html') { os.create('table.html') or { panic(err) } - } + } mut table := os.read_file('table.html') or { panic(err) } // Do nothing if it's already been processed. if table.contains(commit_hash) { println('Commit $commit_hash has already been processed') return - } + } // Build an optimized V println('Building vprod...') exec('v -o $vdir/vprod -prod $vdir/v.v') @@ -74,7 +78,7 @@ fn measure(cmd string) int { println('Warming up...') for i in 0..3 { exec(cmd) - } + } println('Building...') ticks := time.ticks() exec(cmd) diff --git a/tools/fast/header.html b/tools/fast/header.html index 700b65408d..e3e1fc8f86 100644 --- a/tools/fast/header.html +++ b/tools/fast/header.html @@ -38,7 +38,7 @@ td {

Is V still fast?

Monitoring compilation speed for each commit.

-Running on a $3.5 instance.

+Running on a 2014 MacBook Pro.

Source code: fast.v

diff --git a/vlib/builtin/array.v b/vlib/builtin/array.v index 997497dca7..35aa5b15ee 100644 --- a/vlib/builtin/array.v +++ b/vlib/builtin/array.v @@ -18,11 +18,12 @@ pub: // Private function, used by V (`nums := []int`) fn new_array(mylen, cap, elm_size int) array { + cap_ := if cap == 0 { 1 } else { cap } arr := array { len: mylen cap: cap element_size: elm_size - data: calloc(cap * elm_size) + data: calloc(cap_ * elm_size) } return arr } @@ -36,11 +37,12 @@ pub fn make(len, cap, elm_size int) array { // Private function, used by V (`nums := [1, 2, 3]`) fn new_array_from_c_array(len, cap, elm_size int, c_array voidptr) array { + cap_ := if cap == 0 { 1 } else { cap } arr := array { len: len cap: cap element_size: elm_size - data: calloc(cap * elm_size) + data: calloc(cap_ * elm_size) } // TODO Write all memory functions (like memcpy) in V C.memcpy(arr.data, c_array, len * elm_size) @@ -96,11 +98,15 @@ pub fn (a array) repeat(nr_repeats int) array { if nr_repeats < 0 { panic('array.repeat: count is negative (count == $nr_repeats)') } + mut size := nr_repeats * a.len * a.element_size + if size == 0 { + size = a.element_size + } arr := array { len: nr_repeats * a.len cap: nr_repeats * a.len element_size: a.element_size - data: calloc(nr_repeats * a.len * a.element_size) + data: calloc(size) } for i := 0; i < nr_repeats; i++ { C.memcpy(arr.data + i * a.len * a.element_size, a.data, a.len * a.element_size) @@ -267,11 +273,15 @@ pub fn (a array) reverse() array { // array.clone returns an independent copy of a given array pub fn (a array) clone() array { + mut size := a.cap * a.element_size + if size == 0 { + size++ + } arr := array { len: a.len cap: a.cap element_size: a.element_size - data: calloc(a.cap * a.element_size) + data: calloc(size) } C.memcpy(arr.data, a.data, a.cap * a.element_size) return arr diff --git a/vlib/builtin/builtin.v b/vlib/builtin/builtin.v index 8bc049bcf8..e1f6f2268c 100644 --- a/vlib/builtin/builtin.v +++ b/vlib/builtin/builtin.v @@ -106,7 +106,7 @@ __global nr_mallocs int = 0 [unsafe_fn] pub fn malloc(n int) byteptr { if n <= 0 { - panic('malloc(<0)') + panic('malloc(<=0)') } $if prealloc { res := g_m2_ptr @@ -136,8 +136,8 @@ TODO } pub fn calloc(n int) byteptr { - if n < 0 { - panic('calloc(<0)') + if n <= 0 { + panic('calloc(<=0)') } return C.calloc(n, 1) } diff --git a/vlib/builtin/option.v b/vlib/builtin/option.v index 104e761089..91137c8fac 100644 --- a/vlib/builtin/option.v +++ b/vlib/builtin/option.v @@ -4,6 +4,16 @@ module builtin +/* +struct Option2 { + data T + error string + ecode int + ok bool + is_none bool +} +*/ + struct Option { data [300]byte error string diff --git a/vlib/compiler/fn.v b/vlib/compiler/fn.v index ed11982173..eed86f6416 100644 --- a/vlib/compiler/fn.v +++ b/vlib/compiler/fn.v @@ -403,6 +403,7 @@ fn (p mut Parser) fn_decl() { // Register ?option type for return value and args if typ.starts_with('Option_') { p.cgen.typedefs << 'typedef Option $typ;' + //p.cgen.typedefs << 'typedef struct Option_$typ Option_$typ' } for arg in f.args { if arg.typ.starts_with('Option_') {