mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
free arrays when they are out of scope
main.v: update help
This commit is contained in:
parent
385f1c856e
commit
40c31f701f
@ -46,23 +46,6 @@ fn (f mut Fn) open_scope() {
|
||||
f.scope_level++
|
||||
}
|
||||
|
||||
fn (f mut Fn) close_scope() {
|
||||
// println('close_scope level=$f.scope_level var_idx=$f.var_idx')
|
||||
// Move back `var_idx` (pointer to the end of the array) till we reach the previous scope level.
|
||||
// This effectivly deletes (closes) current scope.
|
||||
mut i := f.var_idx - 1
|
||||
for; i >= 0; i-- {
|
||||
v := f.local_vars[i]
|
||||
if v.scope_level != f.scope_level {
|
||||
// println('breaking. "$v.name" v.scope_level=$v.scope_level')
|
||||
break
|
||||
}
|
||||
}
|
||||
f.var_idx = i + 1
|
||||
// println('close_scope new var_idx=$f.var_idx\n')
|
||||
f.scope_level--
|
||||
}
|
||||
|
||||
fn (f &Fn) mark_var_used(v Var) {
|
||||
for i, vv in f.local_vars {
|
||||
if vv.name == v.name {
|
||||
@ -432,19 +415,11 @@ fn (p mut Parser) check_unused_variables() {
|
||||
p.scanner.line_nr = var.line_nr - 1
|
||||
p.error('`$var.name` declared and not used')
|
||||
}
|
||||
// Very basic automatic memory management at the end of the function.
|
||||
// This is inserted right before the final `}`, so if the object is being returned,
|
||||
// the free method will not be called.
|
||||
if p.pref.is_test && var.typ.contains('array_') {
|
||||
// p.genln('v_${var.typ}_free($var.name); // !!!! XAXA')
|
||||
// p.genln('free(${var.name}.data); // !!!! XAXA')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Important function with 5 args.
|
||||
// user.say_hi() => "User_say_hi(user)"
|
||||
// method_ph - where to insert "user_say_hi("
|
||||
// user.register() => "User_register(user)"
|
||||
// method_ph - where to insert "user_register("
|
||||
// receiver_var - "user" (needed for pthreads)
|
||||
// receiver_type - "User"
|
||||
fn (p mut Parser) async_fn_call(f Fn, method_ph int, receiver_var, receiver_type string) {
|
||||
|
@ -977,7 +977,7 @@ fn new_v(args[]string) *V {
|
||||
if os.dir_exists(vroot) && os.dir_exists(vroot + '/vlib/builtin') {
|
||||
|
||||
} else {
|
||||
println('vlib not found. It should be next to V executable. ')
|
||||
println('vlib not found. It should be next to the V executable. ')
|
||||
println('Go to https://vlang.io to install V.')
|
||||
exit(1)
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ mut:
|
||||
is_global bool // __global (translated from C only)
|
||||
is_used bool
|
||||
scope_level int
|
||||
is_alloc bool
|
||||
}
|
||||
|
||||
struct Parser {
|
||||
@ -69,6 +70,7 @@ mut:
|
||||
attr string
|
||||
v_script bool // "V bash", import all os functions into global space
|
||||
var_decl_name string // To allow declaring the variable so that it can be used in the struct initialization
|
||||
building_v bool
|
||||
}
|
||||
|
||||
const (
|
||||
@ -96,6 +98,9 @@ fn (c mut V) new_parser(path string, run Pass) Parser {
|
||||
os: c.os
|
||||
run: run
|
||||
vroot: c.vroot
|
||||
building_v: !c.pref.is_repl && (path.contains('compiler/') ||
|
||||
path.contains('v/vlib'))
|
||||
|
||||
}
|
||||
p.next()
|
||||
// p.scanner.debug_tokens()
|
||||
@ -214,8 +219,9 @@ fn (p mut Parser) parse() {
|
||||
// $if, $else
|
||||
p.comp_time()
|
||||
case Token.key_global:
|
||||
if !p.pref.translated && !p.pref.is_live && !p.builtin_pkg && !p.building_v() {
|
||||
//p.error('__global is only allowed in translated code')
|
||||
if !p.pref.translated && !p.pref.is_live &&
|
||||
!p.builtin_pkg && !p.building_v {
|
||||
p.error('__global is only allowed in translated code')
|
||||
}
|
||||
p.next()
|
||||
name := p.check_name()
|
||||
@ -988,10 +994,35 @@ fn (p mut Parser) statements_no_curly_end() string {
|
||||
}
|
||||
//p.fmt_dec()
|
||||
// println('close scope line=$p.scanner.line_nr')
|
||||
p.cur_fn.close_scope()
|
||||
p.close_scope()
|
||||
return last_st_typ
|
||||
}
|
||||
|
||||
fn (p mut Parser) close_scope() {
|
||||
// println('close_scope level=$f.scope_level var_idx=$f.var_idx')
|
||||
// Move back `var_idx` (pointer to the end of the array) till we reach the previous scope level.
|
||||
// This effectivly deletes (closes) current scope.
|
||||
mut i := p.cur_fn.var_idx - 1
|
||||
for; i >= 0; i-- {
|
||||
v := p.cur_fn.local_vars[i]
|
||||
if v.scope_level != p.cur_fn.scope_level {
|
||||
// println('breaking. "$v.name" v.scope_level=$v.scope_level')
|
||||
break
|
||||
}
|
||||
if !p.building_v && !v.is_mut && v.is_alloc {
|
||||
if v.typ.starts_with('array_') {
|
||||
p.genln('v_array_free($v.name); // close_scope free')
|
||||
}
|
||||
else {
|
||||
p.genln('free($v.name); // close_scope free')
|
||||
}
|
||||
}
|
||||
}
|
||||
p.cur_fn.var_idx = i + 1
|
||||
// println('close_scope new var_idx=$f.var_idx\n')
|
||||
p.cur_fn.scope_level--
|
||||
}
|
||||
|
||||
fn (p mut Parser) genln(s string) {
|
||||
p.cgen.genln(s)
|
||||
}
|
||||
@ -1221,6 +1252,7 @@ fn (p mut Parser) var_decl() {
|
||||
name: name
|
||||
typ: typ
|
||||
is_mut: is_mut
|
||||
is_alloc: typ.starts_with('array_')
|
||||
})
|
||||
mut cgen_typ := typ
|
||||
if !or_else {
|
||||
@ -3115,7 +3147,7 @@ fn (p mut Parser) for_st() {
|
||||
p.check(.lcbr)
|
||||
p.genln('')
|
||||
p.statements()
|
||||
p.cur_fn.close_scope()
|
||||
p.close_scope()
|
||||
p.for_expr_cnt--
|
||||
}
|
||||
|
||||
@ -3228,7 +3260,7 @@ fn (p mut Parser) return_st() {
|
||||
else {
|
||||
ret := p.cgen.cur_line.right(ph)
|
||||
p.cgen(p.cur_fn.defer_text)
|
||||
if expr_type == 'void*' {
|
||||
if p.cur_fn.defer_text == '' || expr_type == 'void*' {
|
||||
p.cgen.resetln('return $ret')
|
||||
} else {
|
||||
tmp := p.get_tmp()
|
||||
@ -3369,10 +3401,12 @@ fn is_compile_time_const(s string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
/*
|
||||
fn (p &Parser) building_v() bool {
|
||||
cur_dir := os.getwd()
|
||||
return p.file_path.contains('v/compiler') || cur_dir.contains('v/compiler')
|
||||
}
|
||||
*/
|
||||
|
||||
fn (p mut Parser) attribute() {
|
||||
p.check(.lsbr)
|
||||
|
@ -5,13 +5,15 @@
|
||||
module builtin
|
||||
|
||||
struct array {
|
||||
is_slice bool
|
||||
pub:
|
||||
// Using a void pointer allows to implement arrays without generics and without generating
|
||||
// extra code for every type.
|
||||
pub:
|
||||
data voidptr
|
||||
len int
|
||||
cap int
|
||||
element_size int
|
||||
|
||||
}
|
||||
|
||||
// Private function, used by V (`nums := []int`)
|
||||
@ -144,6 +146,7 @@ pub fn (s array) slice(start, _end int) array {
|
||||
data: s.data + start * s.element_size
|
||||
len: l
|
||||
cap: l
|
||||
is_slice: true
|
||||
}
|
||||
return res
|
||||
}
|
||||
@ -215,7 +218,11 @@ pub fn (a []int) str() string {
|
||||
return res
|
||||
}
|
||||
|
||||
pub fn (a []int) free() {
|
||||
//pub fn (a []int) free() {
|
||||
pub fn (a array) free() {
|
||||
if a.is_slice {
|
||||
return
|
||||
}
|
||||
C.free(a.data)
|
||||
}
|
||||
|
||||
|
@ -716,12 +716,14 @@ pub fn (s string) free() {
|
||||
C.free(s.str)
|
||||
}
|
||||
|
||||
/*
|
||||
fn (arr []string) free() {
|
||||
for s in arr {
|
||||
s.free()
|
||||
}
|
||||
C.free(arr.data)
|
||||
}
|
||||
*/
|
||||
|
||||
// all_before('23:34:45.234', '.') == '23:34:45'
|
||||
pub fn (s string) all_before(dot string) string {
|
||||
|
Loading…
Reference in New Issue
Block a user