builtin,checker: add array.flags. Allow changing it in `unsafe {}` blocks
parent
612e742c1f
commit
579d5ae649
|
@ -5,19 +5,26 @@ module builtin
|
||||||
|
|
||||||
import strings
|
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 struct array {
|
||||||
pub:
|
pub:
|
||||||
element_size int // size in bytes of one element in the array.
|
element_size int // size in bytes of one element in the array.
|
||||||
pub mut:
|
pub mut:
|
||||||
data voidptr
|
data voidptr
|
||||||
offset int // in bytes (should be `usize`)
|
offset int // in bytes (should be `usize`)
|
||||||
len int // length of the array.
|
len int // length of the array in elements.
|
||||||
cap int // capacity of the array.
|
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`)
|
// Internal function, used by V (`nums := []int`)
|
||||||
fn __new_array(mylen int, cap int, elm_size int) array {
|
fn __new_array(mylen int, cap int, elm_size int) array {
|
||||||
cap_ := if cap < mylen { mylen } else { cap }
|
cap_ := if cap < mylen { mylen } else { cap }
|
||||||
|
@ -104,6 +111,11 @@ fn (mut a array) ensure_cap(required int) {
|
||||||
if a.data != voidptr(0) {
|
if a.data != voidptr(0) {
|
||||||
unsafe { vmemcpy(new_data, a.data, a.len * a.element_size) }
|
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?)
|
// 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.data = new_data
|
||||||
a.offset = 0
|
a.offset = 0
|
||||||
|
|
|
@ -510,7 +510,7 @@ pub fn memdup_noscan(src voidptr, sz int) voidptr {
|
||||||
return vcalloc_noscan(1)
|
return vcalloc_noscan(1)
|
||||||
}
|
}
|
||||||
unsafe {
|
unsafe {
|
||||||
mem := vcalloc_noscan(sz)
|
mem := malloc_noscan(sz)
|
||||||
return C.memcpy(mem, src, 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)
|
c.fail_if_immutable(expr.expr)
|
||||||
}
|
}
|
||||||
.array, .string {
|
.array, .string {
|
||||||
// This should only happen in `builtin`
|
// should only happen in `builtin` and unsafe blocks
|
||||||
if c.file.mod.name != 'builtin' {
|
inside_builtin := c.file.mod.name == 'builtin'
|
||||||
|
if !inside_builtin && !c.inside_unsafe {
|
||||||
c.error('`$typ_sym.kind` can not be modified', expr.pos)
|
c.error('`$typ_sym.kind` can not be modified', expr.pos)
|
||||||
return '', expr.pos
|
return '', expr.pos
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue