mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
vweb fixes; ORM fixes; freeing strings
This commit is contained in:
parent
bac3c0a63e
commit
8d241cc164
@ -47,10 +47,8 @@ fn print_backtrace_skipping_top_frames_linux(skipframes int) bool {
|
||||
println('TODO: print_backtrace_skipping_top_frames_linux $skipframes with tcc fails tests with "stack smashing detected" .')
|
||||
return false
|
||||
}
|
||||
$if !android {
|
||||
$if !android { // backtrace is not available on Android.
|
||||
$if glibc {
|
||||
// backtrace is not available on Android.
|
||||
//if C.backtrace_symbols_fd != 0 {
|
||||
buffer := [100]byteptr
|
||||
nr_ptrs := C.backtrace(*voidptr(buffer), 100)
|
||||
nr_actual_frames := nr_ptrs-skipframes
|
||||
|
@ -174,8 +174,8 @@ fn (p mut Parser) comp_time() {
|
||||
p.is_vweb = false
|
||||
p.genln('/////////////////// tmpl end')
|
||||
receiver := p.cur_fn.args[0]
|
||||
dot := if receiver.is_mut { '->' } else { '.' }
|
||||
p.genln('vweb__Context_html($receiver.name $dot vweb, tmpl_res)')
|
||||
dot := if receiver.is_mut || receiver.ptr { '->' } else { '.' }
|
||||
p.genln('vweb__Context_html($receiver.name /*!*/$dot vweb, tmpl_res)')
|
||||
}
|
||||
else {
|
||||
p.error('bad comptime expr')
|
||||
@ -261,16 +261,23 @@ fn (p mut Parser) comptime_method_call(typ Type) {
|
||||
p.cgen.cur_line = ''
|
||||
p.check(.dollar)
|
||||
var := p.check_name()
|
||||
mut j := 0
|
||||
for i, method in typ.methods {
|
||||
if method.typ != 'void' {
|
||||
|
||||
continue
|
||||
}
|
||||
receiver := method.args[0]
|
||||
amp := if receiver.is_mut { '&' } else { '' }
|
||||
if i > 0 {
|
||||
if !p.expr_var.ptr {
|
||||
p.error('`$p.expr_var.name` needs to be a reference')
|
||||
}
|
||||
amp := if receiver.is_mut && !p.expr_var.ptr { '&' } else { '' }
|
||||
if j > 0 {
|
||||
p.gen(' else ')
|
||||
}
|
||||
p.gen('if ( string_eq($var, _STR("$method.name")) ) ${typ.name}_$method.name($amp $p.expr_var.name);')
|
||||
p.genln('if ( string_eq($var, _STR("$method.name")) ) ' +
|
||||
'${typ.name}_$method.name($amp $p.expr_var.name);')
|
||||
j++
|
||||
}
|
||||
p.check(.lpar)
|
||||
p.check(.rpar)
|
||||
|
@ -445,6 +445,7 @@ fn (p mut Parser) expression() string {
|
||||
is_num := typ.contains('*') || is_number_type(typ)
|
||||
p.check_space(p.tok)
|
||||
if is_str && tok_op == .plus && !p.is_js {
|
||||
p.is_alloc = true
|
||||
p.cgen.set_placeholder(ph, 'string_add(')
|
||||
p.gen(',')
|
||||
}
|
||||
|
@ -1000,7 +1000,8 @@ fn (p mut Parser) fn_call_args(f mut Fn) {
|
||||
}
|
||||
}
|
||||
p.expected_type = arg.typ
|
||||
clone := p.pref.autofree && arg.typ == 'string' && arg.is_moved && p.mod != 'builtin'
|
||||
clone := p.pref.autofree && p.mod != 'string' && arg.typ == 'string' &&
|
||||
!p.builtin_mod //&& arg.is_moved
|
||||
if clone {
|
||||
p.gen('/*YY f=$f.name arg=$arg.name is_moved=$arg.is_moved*/string_clone(')
|
||||
}
|
||||
|
@ -502,6 +502,7 @@ pub fn (v mut V) generate_main() {
|
||||
else if v.table.main_exists() {
|
||||
v.gen_main_start(true)
|
||||
cgen.genln(' main__main();')
|
||||
cgen.genln('free(g_str_buf);')
|
||||
v.gen_main_end('return 0')
|
||||
}
|
||||
}
|
||||
|
@ -1111,36 +1111,13 @@ fn (p mut Parser) close_scope() {
|
||||
mut i := p.var_idx - 1
|
||||
for ; i >= 0; i-- {
|
||||
v := p.local_vars[i]
|
||||
if v.scope_level != p.cur_fn.scope_level {
|
||||
break
|
||||
if p.pref.autofree && (v.is_alloc || (v.is_arg && v.typ == 'string')) { // && !p.pref.is_test {
|
||||
p.free_var(v)
|
||||
}
|
||||
// Clean up memory, only do this if -autofree was passed for now
|
||||
if p.pref.autofree && v.is_alloc { // && !p.pref.is_test {
|
||||
mut free_fn := 'free'
|
||||
if v.typ.starts_with('array_') {
|
||||
free_fn = 'v_array_free'
|
||||
} else if v.typ == 'string' {
|
||||
free_fn = 'v_string_free'
|
||||
//if p.fileis('str.v') {
|
||||
//println('freeing str $v.name')
|
||||
//}
|
||||
continue
|
||||
} else if v.ptr || v.typ.ends_with('*') {
|
||||
free_fn = 'v_ptr_free'
|
||||
//continue
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
if p.returns {
|
||||
// Don't free a variable that's being returned
|
||||
if !v.is_returned && v.typ != 'FILE*' { //!v.is_c {
|
||||
prev_line := p.cgen.lines[p.cgen.lines.len-2]
|
||||
p.cgen.lines[p.cgen.lines.len-2] =
|
||||
'$free_fn($v.name); /* :) close_scope free $v.typ */' + prev_line
|
||||
}
|
||||
} else {
|
||||
p.genln('$free_fn($v.name); // close_scope free')
|
||||
}
|
||||
//if p.fileis('mem.v') {
|
||||
//println(v.name + ' $v.is_arg scope=$v.scope_level cur=$p.cur_fn.scope_level')}
|
||||
if v.scope_level != p.cur_fn.scope_level {// && !v.is_arg {
|
||||
break
|
||||
}
|
||||
}
|
||||
if p.cur_fn.defer_text.last() != '' {
|
||||
@ -1153,6 +1130,37 @@ fn (p mut Parser) close_scope() {
|
||||
// println('close_scope new var_idx=$f.var_idx\n')
|
||||
}
|
||||
|
||||
fn (p mut Parser) free_var(v Var) {
|
||||
// Clean up memory, only do this if -autofree was passed for now
|
||||
//if p.fileis('mem.v') {println('free_var() $v.name')}
|
||||
mut free_fn := 'free'
|
||||
if v.typ.starts_with('array_') {
|
||||
free_fn = 'v_array_free'
|
||||
} else if v.typ == 'string' {
|
||||
free_fn = 'v_string_free'
|
||||
//if p.fileis('str.v') {
|
||||
//println('freeing str $v.name')
|
||||
//}
|
||||
//continue
|
||||
} else if v.ptr || v.typ.ends_with('*') {
|
||||
free_fn = 'v_ptr_free'
|
||||
//continue
|
||||
} else {
|
||||
return
|
||||
}
|
||||
if p.returns {
|
||||
// Don't free a variable that's being returned
|
||||
if !v.is_returned && v.typ != 'FILE*' { //!v.is_c {
|
||||
prev_line := p.cgen.lines[p.cgen.lines.len-2]
|
||||
p.cgen.lines[p.cgen.lines.len-2] =
|
||||
'$free_fn($v.name); /* :) close_scope free $v.typ */' + prev_line
|
||||
}
|
||||
} else {
|
||||
//if p.fileis('mem.v') {println(v.name)}
|
||||
p.genln('$free_fn($v.name); // close_scope free')
|
||||
}
|
||||
}
|
||||
|
||||
fn (p mut Parser) genln(s string) {
|
||||
p.cgen.genln(s)
|
||||
}
|
||||
@ -1567,11 +1575,13 @@ fn (p mut Parser) get_var_type(name string, is_ptr bool, deref_nr int) string {
|
||||
p.gen('*')
|
||||
}
|
||||
}
|
||||
/*
|
||||
if p.pref.autofree && v.typ == 'string' && v.is_arg &&
|
||||
p.assigned_type == 'string' {
|
||||
p.warn('setting moved ' + v.typ)
|
||||
p.mark_arg_moved(v)
|
||||
}
|
||||
*/
|
||||
mut typ := p.var_expr(v)
|
||||
// *var
|
||||
if deref_nr > 0 {
|
||||
@ -1691,12 +1701,14 @@ fn (p mut Parser) var_expr(v Var) string {
|
||||
p.next()
|
||||
return p.select_query(fn_ph)
|
||||
}
|
||||
if typ == 'pg__DB' && !p.fileis('pg.v') && p.peek() == .name &&
|
||||
!p.tokens[p.token_idx].lit.contains('exec')
|
||||
if typ == 'pg__DB' && !p.fileis('pg.v') && p.peek() == .name
|
||||
{
|
||||
p.next()
|
||||
p.insert_query(fn_ph)
|
||||
return 'void'
|
||||
name := p.tokens[p.token_idx].lit
|
||||
if !name.contains('exec') && !name.starts_with('q_') {
|
||||
p.next()
|
||||
p.insert_query(fn_ph)
|
||||
return 'void'
|
||||
}
|
||||
}
|
||||
// println('dot #$dc')
|
||||
typ = p.dot(typ, fn_ph)
|
||||
|
Loading…
Reference in New Issue
Block a user