builtin,checker: add array.flags. Allow changing it in `unsafe {}` blocks
parent
612e742c1f
commit
579d5ae649
|
@ -5,19 +5,26 @@ module builtin
|
|||
|
||||
import strings
|
||||
|
||||
// array is a struct used for denoting array types in V
|
||||
// `array` is a struct, used for denoting all array types in V.
|
||||
// `.data` is a void pointer to the backing heap memory block,
|
||||
// which avoids using generics and thus without generating extra
|
||||
// code for every type.
|
||||
pub struct array {
|
||||
pub:
|
||||
element_size int // size in bytes of one element in the array.
|
||||
pub mut:
|
||||
data voidptr
|
||||
offset int // in bytes (should be `usize`)
|
||||
len int // length of the array.
|
||||
cap int // capacity of the array.
|
||||
len int // length of the array in elements.
|
||||
cap int // capacity of the array in elements.
|
||||
flags ArrayFlags
|
||||
}
|
||||
|
||||
[flag]
|
||||
pub enum ArrayFlags {
|
||||
noslices
|
||||
}
|
||||
|
||||
// array.data uses a void pointer, which allows implementing arrays without generics and without generating
|
||||
// extra code for every type.
|
||||
// Internal function, used by V (`nums := []int`)
|
||||
fn __new_array(mylen int, cap int, elm_size int) array {
|
||||
cap_ := if cap < mylen { mylen } else { cap }
|
||||
|
@ -104,6 +111,11 @@ fn (mut a array) ensure_cap(required int) {
|
|||
if a.data != voidptr(0) {
|
||||
unsafe { vmemcpy(new_data, a.data, a.len * a.element_size) }
|
||||
// TODO: the old data may be leaked when no GC is used (ref-counting?)
|
||||
if a.flags.has(.noslices) {
|
||||
unsafe {
|
||||
free(a.data)
|
||||
}
|
||||
}
|
||||
}
|
||||
a.data = new_data
|
||||
a.offset = 0
|
||||
|
|
|
@ -510,7 +510,7 @@ pub fn memdup_noscan(src voidptr, sz int) voidptr {
|
|||
return vcalloc_noscan(1)
|
||||
}
|
||||
unsafe {
|
||||
mem := vcalloc_noscan(sz)
|
||||
mem := malloc_noscan(sz)
|
||||
return C.memcpy(mem, src, sz)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1663,8 +1663,9 @@ fn (mut c Checker) fail_if_immutable(expr ast.Expr) (string, token.Position) {
|
|||
c.fail_if_immutable(expr.expr)
|
||||
}
|
||||
.array, .string {
|
||||
// This should only happen in `builtin`
|
||||
if c.file.mod.name != 'builtin' {
|
||||
// should only happen in `builtin` and unsafe blocks
|
||||
inside_builtin := c.file.mod.name == 'builtin'
|
||||
if !inside_builtin && !c.inside_unsafe {
|
||||
c.error('`$typ_sym.kind` can not be modified', expr.pos)
|
||||
return '', expr.pos
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue