v/checker.v: disallow pointer arithmetic for InfixExpr outside unsafe {} (#5640)
parent
a2395ff3e8
commit
0b49e4db1c
|
@ -29,7 +29,7 @@ fn __new_array(mylen int, cap int, elm_size int) array {
|
||||||
|
|
||||||
fn __new_array_with_default(mylen int, cap int, elm_size int, val voidptr) array {
|
fn __new_array_with_default(mylen int, cap int, elm_size int, val voidptr) array {
|
||||||
cap_ := if cap < mylen { mylen } else { cap }
|
cap_ := if cap < mylen { mylen } else { cap }
|
||||||
arr := array{
|
mut arr := array{
|
||||||
element_size: elm_size
|
element_size: elm_size
|
||||||
data: vcalloc(cap_ * elm_size)
|
data: vcalloc(cap_ * elm_size)
|
||||||
len: mylen
|
len: mylen
|
||||||
|
@ -37,7 +37,9 @@ fn __new_array_with_default(mylen int, cap int, elm_size int, val voidptr) array
|
||||||
}
|
}
|
||||||
if val != 0 {
|
if val != 0 {
|
||||||
for i in 0..arr.len {
|
for i in 0..arr.len {
|
||||||
C.memcpy(charptr(arr.data) + i*elm_size, val, elm_size)
|
unsafe {
|
||||||
|
arr.set_unsafe(i, val)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return arr
|
return arr
|
||||||
|
@ -45,7 +47,7 @@ fn __new_array_with_default(mylen int, cap int, elm_size int, val voidptr) array
|
||||||
|
|
||||||
fn __new_array_with_array_default(mylen int, cap int, elm_size int, val array) array {
|
fn __new_array_with_array_default(mylen int, cap int, elm_size int, val array) array {
|
||||||
cap_ := if cap < mylen { mylen } else { cap }
|
cap_ := if cap < mylen { mylen } else { cap }
|
||||||
arr := array{
|
mut arr := array{
|
||||||
element_size: elm_size
|
element_size: elm_size
|
||||||
data: vcalloc(cap_ * elm_size)
|
data: vcalloc(cap_ * elm_size)
|
||||||
len: mylen
|
len: mylen
|
||||||
|
@ -53,7 +55,9 @@ fn __new_array_with_array_default(mylen int, cap int, elm_size int, val array) a
|
||||||
}
|
}
|
||||||
for i in 0..arr.len {
|
for i in 0..arr.len {
|
||||||
val_clone := val.clone()
|
val_clone := val.clone()
|
||||||
C.memcpy(charptr(arr.data) + i*elm_size, &val_clone, elm_size)
|
unsafe {
|
||||||
|
arr.set_unsafe(i, &val_clone)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return arr
|
return arr
|
||||||
}
|
}
|
||||||
|
@ -123,9 +127,13 @@ pub fn (a array) repeat(count int) array {
|
||||||
ary := array{}
|
ary := array{}
|
||||||
C.memcpy(&ary, a.data, sizeof(array))
|
C.memcpy(&ary, a.data, sizeof(array))
|
||||||
ary_clone := ary.clone()
|
ary_clone := ary.clone()
|
||||||
C.memcpy(byteptr(arr.data) + i * a.len * a.element_size, &ary_clone, a.len * a.element_size)
|
unsafe {
|
||||||
|
C.memcpy(arr.get_unsafe(i * a.len), &ary_clone, a.len * a.element_size)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
C.memcpy(byteptr(arr.data) + i * a.len * a.element_size, byteptr(a.data), a.len * a.element_size)
|
unsafe {
|
||||||
|
C.memcpy(arr.get_unsafe(i * a.len), byteptr(a.data), a.len * a.element_size)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return arr
|
return arr
|
||||||
|
@ -144,9 +152,10 @@ pub fn (mut a array) insert(i int, val voidptr) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
a.ensure_cap(a.len + 1)
|
a.ensure_cap(a.len + 1)
|
||||||
size := a.element_size
|
unsafe {
|
||||||
C.memmove(byteptr(a.data) + (i + 1) * size, byteptr(a.data) + i * size, (a.len - i) * size)
|
C.memmove(a.get_unsafe(i + 1), a.get_unsafe(i), (a.len - i) * a.element_size)
|
||||||
C.memcpy(byteptr(a.data) + i * size, val, size)
|
a.set_unsafe(i, val)
|
||||||
|
}
|
||||||
a.len++
|
a.len++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,8 +168,11 @@ pub fn (mut a array) insert_many(i int, val voidptr, size int) {
|
||||||
}
|
}
|
||||||
a.ensure_cap(a.len + size)
|
a.ensure_cap(a.len + size)
|
||||||
elem_size := a.element_size
|
elem_size := a.element_size
|
||||||
C.memmove(byteptr(a.data) + (i + size) * elem_size, byteptr(a.data) + i * elem_size, (a.len - i) * elem_size)
|
unsafe {
|
||||||
C.memcpy(byteptr(a.data) + i * elem_size, val, size * elem_size)
|
iptr := a.get_unsafe(i)
|
||||||
|
C.memmove(a.get_unsafe(i + size), iptr, (a.len - i) * elem_size)
|
||||||
|
C.memcpy(iptr, val, size * elem_size)
|
||||||
|
}
|
||||||
a.len += size
|
a.len += size
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,10 +193,11 @@ pub fn (mut a array) delete(i int) {
|
||||||
panic('array.delete: index out of range (i == $i, a.len == $a.len)')
|
panic('array.delete: index out of range (i == $i, a.len == $a.len)')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
size := a.element_size
|
|
||||||
// NB: if a is [12,34], a.len = 2, a.delete(0)
|
// NB: if a is [12,34], a.len = 2, a.delete(0)
|
||||||
// should move (2-0-1) elements = 1 element (the 34) forward
|
// should move (2-0-1) elements = 1 element (the 34) forward
|
||||||
C.memmove(byteptr(a.data) + i * size, byteptr(a.data) + (i + 1) * size, (a.len - i - 1) * size)
|
unsafe {
|
||||||
|
C.memmove(a.get_unsafe(i), a.get_unsafe(i + 1), (a.len - i - 1) * a.element_size)
|
||||||
|
}
|
||||||
a.len--
|
a.len--
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,6 +214,14 @@ pub fn (mut a array) trim(index int) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// we manually inline this for single operations for performance without -prod
|
||||||
|
[inline] [unsafe_fn]
|
||||||
|
fn (a array) get_unsafe(i int) voidptr {
|
||||||
|
unsafe {
|
||||||
|
return byteptr(a.data) + i * a.element_size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Private function. Used to implement array[] operator
|
// Private function. Used to implement array[] operator
|
||||||
fn (a array) get(i int) voidptr {
|
fn (a array) get(i int) voidptr {
|
||||||
$if !no_bounds_checking? {
|
$if !no_bounds_checking? {
|
||||||
|
@ -208,7 +229,9 @@ fn (a array) get(i int) voidptr {
|
||||||
panic('array.get: index out of range (i == $i, a.len == $a.len)')
|
panic('array.get: index out of range (i == $i, a.len == $a.len)')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
unsafe {
|
||||||
return byteptr(a.data) + i * a.element_size
|
return byteptr(a.data) + i * a.element_size
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// array.first returns the first element of the array
|
// array.first returns the first element of the array
|
||||||
|
@ -228,7 +251,9 @@ pub fn (a array) last() voidptr {
|
||||||
panic('array.last: array is empty')
|
panic('array.last: array is empty')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
unsafe {
|
||||||
return byteptr(a.data) + (a.len - 1) * a.element_size
|
return byteptr(a.data) + (a.len - 1) * a.element_size
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// array.slice returns an array using the same buffer as original array
|
// array.slice returns an array using the same buffer as original array
|
||||||
|
@ -248,10 +273,14 @@ fn (a array) slice(start, _end int) array {
|
||||||
panic('array.slice: slice bounds out of range ($start < 0)')
|
panic('array.slice: slice bounds out of range ($start < 0)')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mut data := byteptr(0)
|
||||||
|
unsafe {
|
||||||
|
data = byteptr(a.data) + start * a.element_size
|
||||||
|
}
|
||||||
l := end - start
|
l := end - start
|
||||||
res := array{
|
res := array{
|
||||||
element_size: a.element_size
|
element_size: a.element_size
|
||||||
data: byteptr(a.data) + start * a.element_size
|
data: data
|
||||||
len: l
|
len: l
|
||||||
cap: l
|
cap: l
|
||||||
}
|
}
|
||||||
|
@ -276,7 +305,7 @@ pub fn (a &array) clone() array {
|
||||||
if size == 0 {
|
if size == 0 {
|
||||||
size++
|
size++
|
||||||
}
|
}
|
||||||
arr := array{
|
mut arr := array{
|
||||||
element_size: a.element_size
|
element_size: a.element_size
|
||||||
data: vcalloc(size)
|
data: vcalloc(size)
|
||||||
len: a.len
|
len: a.len
|
||||||
|
@ -286,9 +315,9 @@ pub fn (a &array) clone() array {
|
||||||
if a.element_size == sizeof(array) {
|
if a.element_size == sizeof(array) {
|
||||||
for i in 0..a.len {
|
for i in 0..a.len {
|
||||||
ar := array{}
|
ar := array{}
|
||||||
C.memcpy(&ar, byteptr(a.data) + i * a.element_size, sizeof(array))
|
C.memcpy(&ar, a.get_unsafe(i), sizeof(array))
|
||||||
ar_clone := ar.clone()
|
ar_clone := ar.clone()
|
||||||
C.memcpy(byteptr(arr.data) + i * a.element_size, &ar_clone, a.element_size)
|
arr.set_unsafe(i, &ar_clone)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
C.memcpy(byteptr(arr.data), a.data, a.cap * a.element_size)
|
C.memcpy(byteptr(arr.data), a.data, a.cap * a.element_size)
|
||||||
|
@ -309,16 +338,28 @@ fn (a &array) slice_clone(start, _end int) array {
|
||||||
panic('array.slice: slice bounds out of range ($start < 0)')
|
panic('array.slice: slice bounds out of range ($start < 0)')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mut data := byteptr(0)
|
||||||
|
unsafe {
|
||||||
|
data = byteptr(a.data) + start * a.element_size
|
||||||
|
}
|
||||||
l := end - start
|
l := end - start
|
||||||
res := array{
|
res := array{
|
||||||
element_size: a.element_size
|
element_size: a.element_size
|
||||||
data: byteptr(a.data) + start * a.element_size
|
data: data
|
||||||
len: l
|
len: l
|
||||||
cap: l
|
cap: l
|
||||||
}
|
}
|
||||||
return res.clone()
|
return res.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// we manually inline this for single operations for performance without -prod
|
||||||
|
[inline] [unsafe_fn]
|
||||||
|
fn (mut a array) set_unsafe(i int, val voidptr) {
|
||||||
|
unsafe {
|
||||||
|
C.memcpy(byteptr(a.data) + a.element_size * i, val, a.element_size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Private function. Used to implement assigment to the array element.
|
// Private function. Used to implement assigment to the array element.
|
||||||
fn (mut a array) set(i int, val voidptr) {
|
fn (mut a array) set(i int, val voidptr) {
|
||||||
$if !no_bounds_checking? {
|
$if !no_bounds_checking? {
|
||||||
|
@ -326,12 +367,16 @@ fn (mut a array) set(i int, val voidptr) {
|
||||||
panic('array.set: index out of range (i == $i, a.len == $a.len)')
|
panic('array.set: index out of range (i == $i, a.len == $a.len)')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
unsafe {
|
||||||
C.memcpy(byteptr(a.data) + a.element_size * i, val, a.element_size)
|
C.memcpy(byteptr(a.data) + a.element_size * i, val, a.element_size)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut a array) push(val voidptr) {
|
fn (mut a array) push(val voidptr) {
|
||||||
a.ensure_cap(a.len + 1)
|
a.ensure_cap(a.len + 1)
|
||||||
|
unsafe {
|
||||||
C.memcpy(byteptr(a.data) + a.element_size * a.len, val, a.element_size)
|
C.memcpy(byteptr(a.data) + a.element_size * a.len, val, a.element_size)
|
||||||
|
}
|
||||||
a.len++
|
a.len++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,11 +387,15 @@ pub fn (mut a3 array) push_many(val voidptr, size int) {
|
||||||
// handle `arr << arr`
|
// handle `arr << arr`
|
||||||
copy := a3.clone()
|
copy := a3.clone()
|
||||||
a3.ensure_cap(a3.len + size)
|
a3.ensure_cap(a3.len + size)
|
||||||
|
unsafe {
|
||||||
//C.memcpy(a.data, copy.data, copy.element_size * copy.len)
|
//C.memcpy(a.data, copy.data, copy.element_size * copy.len)
|
||||||
C.memcpy(byteptr(a3.data) + a3.element_size * a3.len, copy.data, a3.element_size * size)
|
C.memcpy(a3.get_unsafe(a3.len), copy.data, a3.element_size * size)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
a3.ensure_cap(a3.len + size)
|
a3.ensure_cap(a3.len + size)
|
||||||
C.memcpy(byteptr(a3.data) + a3.element_size * a3.len, val, a3.element_size * size)
|
unsafe {
|
||||||
|
C.memcpy(a3.get_unsafe(a3.len), val, a3.element_size * size)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
a3.len += size
|
a3.len += size
|
||||||
}
|
}
|
||||||
|
@ -357,15 +406,16 @@ pub fn (a array) reverse() array {
|
||||||
if a.len < 2 {
|
if a.len < 2 {
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
arr := array{
|
mut arr := array{
|
||||||
element_size: a.element_size
|
element_size: a.element_size
|
||||||
data: vcalloc(a.cap * a.element_size)
|
data: vcalloc(a.cap * a.element_size)
|
||||||
len: a.len
|
len: a.len
|
||||||
cap: a.cap
|
cap: a.cap
|
||||||
}
|
}
|
||||||
for i in 0..a.len {
|
for i in 0..a.len {
|
||||||
//C.memcpy(arr.data + i * arr.element_size, &a[a.len - 1 - i], arr.element_size)
|
unsafe {
|
||||||
C.memcpy(byteptr(arr.data) + i * arr.element_size, byteptr(a.data) + (a.len - 1 - i) * arr.element_size, arr.element_size)
|
arr.set_unsafe(i, a.get_unsafe(a.len - 1 - i))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return arr
|
return arr
|
||||||
}
|
}
|
||||||
|
@ -591,7 +641,7 @@ pub fn compare_f32(a, b &f32) int {
|
||||||
pub fn (a array) pointers() []voidptr {
|
pub fn (a array) pointers() []voidptr {
|
||||||
mut res := []voidptr{}
|
mut res := []voidptr{}
|
||||||
for i in 0..a.len {
|
for i in 0..a.len {
|
||||||
res << byteptr(a.data) + i * a.element_size
|
res << a.get_unsafe(i)
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,7 +93,9 @@ pub fn (nn int) str_l(max int) string {
|
||||||
buf[index] = `-`
|
buf[index] = `-`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
C.memmove(buf,buf+index, (max-index)+1 )
|
C.memmove(buf,buf+index, (max-index)+1 )
|
||||||
|
}
|
||||||
return tos(buf, (max-index))
|
return tos(buf, (max-index))
|
||||||
//return tos(buf + index, (max-index))
|
//return tos(buf + index, (max-index))
|
||||||
}
|
}
|
||||||
|
@ -139,7 +141,9 @@ pub fn (nn u32) str() string {
|
||||||
index++
|
index++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
C.memmove(buf,buf+index, (max-index)+1 )
|
C.memmove(buf,buf+index, (max-index)+1 )
|
||||||
|
}
|
||||||
return tos(buf, (max-index))
|
return tos(buf, (max-index))
|
||||||
//return tos(buf + index, (max-index))
|
//return tos(buf + index, (max-index))
|
||||||
}
|
}
|
||||||
|
@ -186,7 +190,9 @@ pub fn (nn i64) str() string {
|
||||||
buf[index] = `-`
|
buf[index] = `-`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
C.memmove(buf,buf+index, (max-index)+1 )
|
C.memmove(buf,buf+index, (max-index)+1 )
|
||||||
|
}
|
||||||
return tos(buf, (max-index))
|
return tos(buf, (max-index))
|
||||||
//return tos(buf + index, (max-index))
|
//return tos(buf + index, (max-index))
|
||||||
}
|
}
|
||||||
|
@ -216,7 +222,9 @@ pub fn (nn u64) str() string {
|
||||||
index++
|
index++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
C.memmove(buf,buf+index, (max-index)+1 )
|
C.memmove(buf,buf+index, (max-index)+1 )
|
||||||
|
}
|
||||||
return tos(buf, (max-index))
|
return tos(buf, (max-index))
|
||||||
//return tos(buf + index, (max-index))
|
//return tos(buf + index, (max-index))
|
||||||
}
|
}
|
||||||
|
@ -260,7 +268,9 @@ pub fn (nn byte) hex() string {
|
||||||
//buf[index] = `0`
|
//buf[index] = `0`
|
||||||
index++
|
index++
|
||||||
|
|
||||||
|
unsafe {
|
||||||
return tos(buf + index, (max - index))
|
return tos(buf + index, (max - index))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (nn i8) hex() string {
|
pub fn (nn i8) hex() string {
|
||||||
|
@ -287,7 +297,9 @@ pub fn (nn u16) hex() string {
|
||||||
//buf[index] = `0`
|
//buf[index] = `0`
|
||||||
index++
|
index++
|
||||||
|
|
||||||
|
unsafe {
|
||||||
return tos(buf + index, (max - index))
|
return tos(buf + index, (max - index))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (nn i16) hex() string {
|
pub fn (nn i16) hex() string {
|
||||||
|
@ -314,7 +326,9 @@ pub fn (nn u32) hex() string {
|
||||||
//buf[index] = `0`
|
//buf[index] = `0`
|
||||||
index++
|
index++
|
||||||
|
|
||||||
|
unsafe {
|
||||||
return tos(buf + index, (max - index))
|
return tos(buf + index, (max - index))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (nn int) hex() string {
|
pub fn (nn int) hex() string {
|
||||||
|
@ -345,7 +359,9 @@ pub fn (nn u64) hex() string {
|
||||||
//buf[index] = `0`
|
//buf[index] = `0`
|
||||||
index++
|
index++
|
||||||
|
|
||||||
|
unsafe {
|
||||||
C.memmove(buf,buf+index, (max-index)+1 )
|
C.memmove(buf,buf+index, (max-index)+1 )
|
||||||
|
}
|
||||||
return tos(buf, (max-index))
|
return tos(buf, (max-index))
|
||||||
//return tos(buf + index, (max-index))
|
//return tos(buf + index, (max-index))
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,7 +127,9 @@ fn (mut d DenseArray) push(key string, value voidptr) u32 {
|
||||||
}
|
}
|
||||||
push_index := d.len
|
push_index := d.len
|
||||||
d.keys[push_index] = key
|
d.keys[push_index] = key
|
||||||
|
unsafe {
|
||||||
C.memcpy(d.values + push_index * u32(d.value_bytes), value, d.value_bytes)
|
C.memcpy(d.values + push_index * u32(d.value_bytes), value, d.value_bytes)
|
||||||
|
}
|
||||||
d.len++
|
d.len++
|
||||||
return push_index
|
return push_index
|
||||||
}
|
}
|
||||||
|
@ -138,7 +140,9 @@ fn (d DenseArray) get(i int) voidptr {
|
||||||
panic('DenseArray.get: index out of range (i == $i, d.len == $d.len)')
|
panic('DenseArray.get: index out of range (i == $i, d.len == $d.len)')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
unsafe {
|
||||||
return byteptr(d.keys) + i * int(sizeof(string))
|
return byteptr(d.keys) + i * int(sizeof(string))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move all zeros to the end of the array and resize array
|
// Move all zeros to the end of the array and resize array
|
||||||
|
@ -152,9 +156,11 @@ fn (mut d DenseArray) zeros_to_end() {
|
||||||
d.keys[count] = d.keys[i]
|
d.keys[count] = d.keys[i]
|
||||||
d.keys[i] = tmp_key
|
d.keys[i] = tmp_key
|
||||||
// swap values (TODO: optimize)
|
// swap values (TODO: optimize)
|
||||||
|
unsafe {
|
||||||
C.memcpy(tmp_value, d.values + count * u32(d.value_bytes), d.value_bytes)
|
C.memcpy(tmp_value, d.values + count * u32(d.value_bytes), d.value_bytes)
|
||||||
C.memcpy(d.values + count * u32(d.value_bytes), d.values + i * d.value_bytes, d.value_bytes)
|
C.memcpy(d.values + count * u32(d.value_bytes), d.values + i * d.value_bytes, d.value_bytes)
|
||||||
C.memcpy(d.values + i * d.value_bytes, tmp_value, d.value_bytes)
|
C.memcpy(d.values + i * d.value_bytes, tmp_value, d.value_bytes)
|
||||||
|
}
|
||||||
count++
|
count++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -206,8 +212,10 @@ fn new_map_1(value_bytes int) map {
|
||||||
fn new_map_init(n, value_bytes int, keys &string, values voidptr) map {
|
fn new_map_init(n, value_bytes int, keys &string, values voidptr) map {
|
||||||
mut out := new_map_1(value_bytes)
|
mut out := new_map_1(value_bytes)
|
||||||
for i in 0 .. n {
|
for i in 0 .. n {
|
||||||
|
unsafe {
|
||||||
out.set(keys[i], byteptr(values) + i * value_bytes)
|
out.set(keys[i], byteptr(values) + i * value_bytes)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,8 +266,10 @@ fn (mut m map) ensure_extra_metas(probe_count u32) {
|
||||||
if (probe_count << 1) == m.extra_metas {
|
if (probe_count << 1) == m.extra_metas {
|
||||||
m.extra_metas += extra_metas_inc
|
m.extra_metas += extra_metas_inc
|
||||||
mem_size := (m.cap + 2 + m.extra_metas)
|
mem_size := (m.cap + 2 + m.extra_metas)
|
||||||
|
unsafe {
|
||||||
m.metas = &u32(C.realloc(m.metas, sizeof(u32) * mem_size))
|
m.metas = &u32(C.realloc(m.metas, sizeof(u32) * mem_size))
|
||||||
C.memset(m.metas + mem_size - extra_metas_inc, 0, sizeof(u32) * extra_metas_inc)
|
C.memset(m.metas + mem_size - extra_metas_inc, 0, sizeof(u32) * extra_metas_inc)
|
||||||
|
}
|
||||||
// Should almost never happen
|
// Should almost never happen
|
||||||
if probe_count == 252 {
|
if probe_count == 252 {
|
||||||
panic('Probe overflow')
|
panic('Probe overflow')
|
||||||
|
@ -282,7 +292,9 @@ fn (mut m map) set(k string, value voidptr) {
|
||||||
for meta == m.metas[index] {
|
for meta == m.metas[index] {
|
||||||
kv_index := m.metas[index + 1]
|
kv_index := m.metas[index + 1]
|
||||||
if fast_string_eq(key, m.key_values.keys[kv_index]) {
|
if fast_string_eq(key, m.key_values.keys[kv_index]) {
|
||||||
|
unsafe {
|
||||||
C.memcpy(m.key_values.values + kv_index * u32(m.value_bytes), value, m.value_bytes)
|
C.memcpy(m.key_values.values + kv_index * u32(m.value_bytes), value, m.value_bytes)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
index += 2
|
index += 2
|
||||||
|
@ -362,9 +374,11 @@ fn (mut m map) get_and_set(key string, zero voidptr) voidptr {
|
||||||
if meta == m.metas[index] {
|
if meta == m.metas[index] {
|
||||||
kv_index := m.metas[index + 1]
|
kv_index := m.metas[index + 1]
|
||||||
if fast_string_eq(key, m.key_values.keys[kv_index]) {
|
if fast_string_eq(key, m.key_values.keys[kv_index]) {
|
||||||
|
unsafe {
|
||||||
return voidptr(m.key_values.values + kv_index * u32(m.value_bytes))
|
return voidptr(m.key_values.values + kv_index * u32(m.value_bytes))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
index += 2
|
index += 2
|
||||||
meta += probe_inc
|
meta += probe_inc
|
||||||
if meta > m.metas[index] { break }
|
if meta > m.metas[index] { break }
|
||||||
|
@ -383,9 +397,11 @@ fn (m map) get(key string, zero voidptr) voidptr {
|
||||||
if meta == m.metas[index] {
|
if meta == m.metas[index] {
|
||||||
kv_index := m.metas[index + 1]
|
kv_index := m.metas[index + 1]
|
||||||
if fast_string_eq(key, m.key_values.keys[kv_index]) {
|
if fast_string_eq(key, m.key_values.keys[kv_index]) {
|
||||||
|
unsafe {
|
||||||
return voidptr(m.key_values.values + kv_index * u32(m.value_bytes))
|
return voidptr(m.key_values.values + kv_index * u32(m.value_bytes))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
index += 2
|
index += 2
|
||||||
meta += probe_inc
|
meta += probe_inc
|
||||||
if meta > m.metas[index] { break }
|
if meta > m.metas[index] { break }
|
||||||
|
|
|
@ -39,10 +39,10 @@ fn opt_ok2(data voidptr, mut option &OptionBase, size int) {
|
||||||
*option = OptionBase {
|
*option = OptionBase {
|
||||||
ok: true
|
ok: true
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// use ecode to get the end of OptionBase and then memcpy into it
|
// use ecode to get the end of OptionBase and then memcpy into it
|
||||||
C.memcpy(byteptr(&option.ecode) + sizeof(int), data, size)
|
C.memcpy(byteptr(&option.ecode) + sizeof(int), data, size)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Old option type used for bootstrapping
|
// Old option type used for bootstrapping
|
||||||
|
|
|
@ -48,8 +48,10 @@ fn new_sorted_map(n, value_bytes int) SortedMap { // TODO: Remove `n`
|
||||||
fn new_sorted_map_init(n, value_bytes int, keys &string, values voidptr) SortedMap {
|
fn new_sorted_map_init(n, value_bytes int, keys &string, values voidptr) SortedMap {
|
||||||
mut out := new_sorted_map(n, value_bytes)
|
mut out := new_sorted_map(n, value_bytes)
|
||||||
for i in 0 .. n {
|
for i in 0 .. n {
|
||||||
|
unsafe {
|
||||||
out.set(keys[i], byteptr(values) + i * value_bytes)
|
out.set(keys[i], byteptr(values) + i * value_bytes)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -118,8 +118,10 @@ pub fn (_str string) to_wide() &u16 {
|
||||||
mut wstr := &u16(malloc((num_chars + 1) * 2)) // sizeof(wchar_t)
|
mut wstr := &u16(malloc((num_chars + 1) * 2)) // sizeof(wchar_t)
|
||||||
if wstr != 0 {
|
if wstr != 0 {
|
||||||
C.MultiByteToWideChar(cp_utf8, 0, _str.str, _str.len, wstr, num_chars)
|
C.MultiByteToWideChar(cp_utf8, 0, _str.str, _str.len, wstr, num_chars)
|
||||||
|
unsafe {
|
||||||
C.memset(&byte(wstr) + num_chars * 2, 0, 2)
|
C.memset(&byte(wstr) + num_chars * 2, 0, 2)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return wstr
|
return wstr
|
||||||
} $else {
|
} $else {
|
||||||
return 0
|
return 0
|
||||||
|
@ -141,8 +143,10 @@ pub fn string_from_wide2(_wstr &u16, len int) string {
|
||||||
mut str_to := malloc(num_chars + 1)
|
mut str_to := malloc(num_chars + 1)
|
||||||
if str_to != 0 {
|
if str_to != 0 {
|
||||||
C.WideCharToMultiByte(cp_utf8, 0, _wstr, len, str_to, num_chars, 0, 0)
|
C.WideCharToMultiByte(cp_utf8, 0, _wstr, len, str_to, num_chars, 0, 0)
|
||||||
|
unsafe {
|
||||||
C.memset(str_to + num_chars, 0, 1)
|
C.memset(str_to + num_chars, 0, 1)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return tos2(str_to)
|
return tos2(str_to)
|
||||||
} $else {
|
} $else {
|
||||||
return ''
|
return ''
|
||||||
|
|
|
@ -51,6 +51,7 @@ fn wyhash64(key byteptr, len, seed_ u64) u64 {
|
||||||
mut p := &key[0]
|
mut p := &key[0]
|
||||||
mut seed := seed_
|
mut seed := seed_
|
||||||
mut i := len & 63
|
mut i := len & 63
|
||||||
|
unsafe {
|
||||||
if i < 4 {
|
if i < 4 {
|
||||||
seed = wymum(wyr3(p, i) ^ seed ^ wyp0, seed ^ wyp1)
|
seed = wymum(wyr3(p, i) ^ seed ^ wyp0, seed ^ wyp1)
|
||||||
}
|
}
|
||||||
|
@ -69,12 +70,14 @@ fn wyhash64(key byteptr, len, seed_ u64) u64 {
|
||||||
else {
|
else {
|
||||||
seed = wymum(wyr8(p) ^ seed ^ wyp0, wyr8(p + 8) ^ seed ^ wyp1) ^ wymum(wyr8(p + 16) ^ seed ^ wyp2, wyr8(p + 24) ^ seed ^ wyp3) ^ wymum(wyr8(p + i - 32) ^ seed ^ wyp1, wyr8(p + i - 24) ^ seed ^ wyp2) ^ wymum(wyr8(p + i - 16) ^ seed ^ wyp3, wyr8(p + i - 8) ^ seed ^ wyp0)
|
seed = wymum(wyr8(p) ^ seed ^ wyp0, wyr8(p + 8) ^ seed ^ wyp1) ^ wymum(wyr8(p + 16) ^ seed ^ wyp2, wyr8(p + 24) ^ seed ^ wyp3) ^ wymum(wyr8(p + i - 32) ^ seed ^ wyp1, wyr8(p + i - 24) ^ seed ^ wyp2) ^ wymum(wyr8(p + i - 16) ^ seed ^ wyp3, wyr8(p + i - 8) ^ seed ^ wyp0)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if i == len {
|
if i == len {
|
||||||
return wymum(seed, len ^ wyp4)
|
return wymum(seed, len ^ wyp4)
|
||||||
}
|
}
|
||||||
mut see1 := seed
|
mut see1 := seed
|
||||||
mut see2 := seed
|
mut see2 := seed
|
||||||
mut see3 := seed
|
mut see3 := seed
|
||||||
|
unsafe {
|
||||||
p = p + i
|
p = p + i
|
||||||
for i = len - i; i >= 64; i -= 64 {
|
for i = len - i; i >= 64; i -= 64 {
|
||||||
seed = wymum(wyr8(p) ^ seed ^ wyp0, wyr8(p + 8) ^ seed ^ wyp1)
|
seed = wymum(wyr8(p) ^ seed ^ wyp0, wyr8(p + 8) ^ seed ^ wyp1)
|
||||||
|
@ -83,6 +86,7 @@ fn wyhash64(key byteptr, len, seed_ u64) u64 {
|
||||||
see3 = wymum(wyr8(p + 48) ^ see3 ^ wyp3, wyr8(p + 56) ^ see3 ^ wyp0)
|
see3 = wymum(wyr8(p + 48) ^ see3 ^ wyp3, wyr8(p + 56) ^ see3 ^ wyp0)
|
||||||
p = p + 64
|
p = p + 64
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return wymum(seed ^ see1 ^ see2, see3 ^ len ^ wyp4)
|
return wymum(seed ^ see1 ^ see2, see3 ^ len ^ wyp4)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,10 @@ fn (mut ws Client) read_handshake(seckey string) {
|
||||||
buffer_size := 1
|
buffer_size := 1
|
||||||
mut buffer := malloc(max_buffer)
|
mut buffer := malloc(max_buffer)
|
||||||
for bytes_read <= max_buffer {
|
for bytes_read <= max_buffer {
|
||||||
res := ws.read_from_server(buffer + bytes_read, buffer_size)
|
mut res := 0
|
||||||
|
unsafe {
|
||||||
|
res = ws.read_from_server(buffer + bytes_read, buffer_size)
|
||||||
|
}
|
||||||
if res == 0 || res == -1 {
|
if res == 0 || res == -1 {
|
||||||
l.f('read_handshake: Failed to read handshake.')
|
l.f('read_handshake: Failed to read handshake.')
|
||||||
}
|
}
|
||||||
|
|
|
@ -257,7 +257,9 @@ pub fn (mut ws Client) write(payload byteptr, payload_len int, code OPCode) int
|
||||||
} else if payload_len > 125 && payload_len <= 0xffff {
|
} else if payload_len > 125 && payload_len <= 0xffff {
|
||||||
len16 := C.htons(payload_len)
|
len16 := C.htons(payload_len)
|
||||||
header[1] = (126 | 0x80)
|
header[1] = (126 | 0x80)
|
||||||
|
unsafe {
|
||||||
C.memcpy(header.data + 2, &len16, 2)
|
C.memcpy(header.data + 2, &len16, 2)
|
||||||
|
}
|
||||||
header[4] = masking_key[0]
|
header[4] = masking_key[0]
|
||||||
header[5] = masking_key[1]
|
header[5] = masking_key[1]
|
||||||
header[6] = masking_key[2]
|
header[6] = masking_key[2]
|
||||||
|
@ -265,7 +267,9 @@ pub fn (mut ws Client) write(payload byteptr, payload_len int, code OPCode) int
|
||||||
} else if payload_len > 0xffff && payload_len <= 0xffffffffffffffff { // 65535 && 18446744073709551615
|
} else if payload_len > 0xffff && payload_len <= 0xffffffffffffffff { // 65535 && 18446744073709551615
|
||||||
len64 := htonl64(u64(payload_len))
|
len64 := htonl64(u64(payload_len))
|
||||||
header[1] = (127 | 0x80)
|
header[1] = (127 | 0x80)
|
||||||
|
unsafe {
|
||||||
C.memcpy(header.data + 2, len64, 8)
|
C.memcpy(header.data + 2, len64, 8)
|
||||||
|
}
|
||||||
header[10] = masking_key[0]
|
header[10] = masking_key[0]
|
||||||
header[11] = masking_key[1]
|
header[11] = masking_key[1]
|
||||||
header[12] = masking_key[2]
|
header[12] = masking_key[2]
|
||||||
|
@ -276,8 +280,11 @@ pub fn (mut ws Client) write(payload byteptr, payload_len int, code OPCode) int
|
||||||
goto free_data
|
goto free_data
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
C.memcpy(fbdata, header.data, header_len)
|
C.memcpy(fbdata, header.data, header_len)
|
||||||
C.memcpy(fbdata + header_len, payload, payload_len)
|
C.memcpy(fbdata + header_len, payload, payload_len)
|
||||||
|
}
|
||||||
for i in 0 .. payload_len {
|
for i in 0 .. payload_len {
|
||||||
frame_buf[header_len + i] ^= masking_key[i % 4] & 0xff
|
frame_buf[header_len + i] ^= masking_key[i % 4] & 0xff
|
||||||
}
|
}
|
||||||
|
@ -320,7 +327,10 @@ pub fn (mut ws Client) read() int {
|
||||||
mut frame := Frame{}
|
mut frame := Frame{}
|
||||||
mut frame_size := u64(header_len)
|
mut frame_size := u64(header_len)
|
||||||
for bytes_read < frame_size && ws.state == .open {
|
for bytes_read < frame_size && ws.state == .open {
|
||||||
byt := ws.read_from_server(data + int(bytes_read), 1)
|
mut byt := 0
|
||||||
|
unsafe {
|
||||||
|
byt = ws.read_from_server(data + int(bytes_read), 1)
|
||||||
|
}
|
||||||
match byt {
|
match byt {
|
||||||
0 {
|
0 {
|
||||||
error := 'server closed the connection.'
|
error := 'server closed the connection.'
|
||||||
|
@ -442,7 +452,9 @@ pub fn (mut ws Client) read() int {
|
||||||
}
|
}
|
||||||
mut by := 0
|
mut by := 0
|
||||||
for f in frags {
|
for f in frags {
|
||||||
|
unsafe {
|
||||||
C.memcpy(pl + by, f.data, f.len)
|
C.memcpy(pl + by, f.data, f.len)
|
||||||
|
}
|
||||||
by += int(f.len)
|
by += int(f.len)
|
||||||
unsafe {
|
unsafe {
|
||||||
free(f.data)
|
free(f.data)
|
||||||
|
|
|
@ -58,12 +58,16 @@ pub fn environ() map[string]string {
|
||||||
$if windows {
|
$if windows {
|
||||||
mut estrings := C.GetEnvironmentStringsW()
|
mut estrings := C.GetEnvironmentStringsW()
|
||||||
mut eline := ''
|
mut eline := ''
|
||||||
for c := estrings; *c != 0; c = c + eline.len + 1 {
|
for c := estrings; *c != 0; {
|
||||||
eline = string_from_wide(c)
|
eline = string_from_wide(c)
|
||||||
eq_index := eline.index_byte(`=`)
|
eq_index := eline.index_byte(`=`)
|
||||||
if eq_index > 0 {
|
if eq_index > 0 {
|
||||||
res[eline[0..eq_index]] = eline[eq_index + 1..]
|
res[eline[0..eq_index]] = eline[eq_index + 1..]
|
||||||
}
|
}
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
c = c + eline.len + 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
C.FreeEnvironmentStringsW(estrings)
|
C.FreeEnvironmentStringsW(estrings)
|
||||||
} $else {
|
} $else {
|
||||||
|
|
|
@ -106,12 +106,16 @@ fn close_conn(loop &C.picoev_loop, fd int) {
|
||||||
|
|
||||||
[inline]
|
[inline]
|
||||||
fn myread(fd int, b byteptr, max_len, idx int) int {
|
fn myread(fd int, b byteptr, max_len, idx int) int {
|
||||||
|
unsafe {
|
||||||
return C.read(fd, b + idx, max_len - idx)
|
return C.read(fd, b + idx, max_len - idx)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[inline]
|
[inline]
|
||||||
fn mysubstr(s byteptr, from, len int) string {
|
fn mysubstr(s byteptr, from, len int) string {
|
||||||
|
unsafe {
|
||||||
return tos(s + from, len)
|
return tos(s + from, len)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rw_callback(loop &C.picoev_loop, fd, events int, cb_arg voidptr) {
|
fn rw_callback(loop &C.picoev_loop, fd, events int, cb_arg voidptr) {
|
||||||
|
@ -123,7 +127,10 @@ fn rw_callback(loop &C.picoev_loop, fd, events int, cb_arg voidptr) {
|
||||||
}
|
}
|
||||||
else if (events & C.PICOEV_READ) != 0 {
|
else if (events & C.PICOEV_READ) != 0 {
|
||||||
C.picoev_set_timeout(loop, fd, timeout_secs)
|
C.picoev_set_timeout(loop, fd, timeout_secs)
|
||||||
buf := (p.buf + fd * max_read)
|
mut buf := p.buf
|
||||||
|
unsafe {
|
||||||
|
buf += fd * max_read
|
||||||
|
}
|
||||||
idx := p.idx[fd]
|
idx := p.idx[fd]
|
||||||
mut r := myread(fd, buf, max_read, idx)
|
mut r := myread(fd, buf, max_read, idx)
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
|
@ -141,12 +148,18 @@ fn rw_callback(loop &C.picoev_loop, fd, events int, cb_arg voidptr) {
|
||||||
} else {
|
} else {
|
||||||
r += idx
|
r += idx
|
||||||
mut s := tos(buf, r)
|
mut s := tos(buf, r)
|
||||||
out := (p.out + fd * max_write)
|
mut out := p.out
|
||||||
|
unsafe {
|
||||||
|
out += fd * max_write
|
||||||
|
}
|
||||||
mut res := picohttpparser.Response{
|
mut res := picohttpparser.Response{
|
||||||
fd: fd
|
fd: fd
|
||||||
date: p.date
|
date: p.date
|
||||||
buf_start: out
|
buf_start: out
|
||||||
buf: out + p.oidx[fd]
|
buf: out
|
||||||
|
}
|
||||||
|
unsafe {
|
||||||
|
res.buf += p.oidx[fd]
|
||||||
}
|
}
|
||||||
mut req := picohttpparser.Request{}
|
mut req := picohttpparser.Request{}
|
||||||
for {
|
for {
|
||||||
|
|
|
@ -477,6 +477,10 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) table.Type {
|
||||||
left_default := c.table.get_type_symbol(c.table.mktyp(left_type))
|
left_default := c.table.get_type_symbol(c.table.mktyp(left_type))
|
||||||
left_pos := infix_expr.left.position()
|
left_pos := infix_expr.left.position()
|
||||||
right_pos := infix_expr.right.position()
|
right_pos := infix_expr.right.position()
|
||||||
|
if (left_type.is_ptr() || left.is_pointer()) &&
|
||||||
|
infix_expr.op in [.plus, .minus] && !c.inside_unsafe {
|
||||||
|
c.error('pointer arithmetic is only allowed in `unsafe` blocks', left_pos)
|
||||||
|
}
|
||||||
mut return_type := left_type
|
mut return_type := left_type
|
||||||
// Single side check
|
// Single side check
|
||||||
// Place these branches according to ops' usage frequency to accelerate.
|
// Place these branches according to ops' usage frequency to accelerate.
|
||||||
|
|
|
@ -4,13 +4,13 @@ fn test_ptr_arithmetic(){
|
||||||
unsafe {
|
unsafe {
|
||||||
p++
|
p++
|
||||||
p += 2
|
p += 2
|
||||||
|
p = p - 1
|
||||||
}
|
}
|
||||||
p = p - 1 // not caught yet
|
|
||||||
|
|
||||||
// byteptr, voidptr, charptr are handled differently
|
// byteptr, voidptr, charptr are handled differently
|
||||||
mut q := byteptr(1)
|
mut q := byteptr(1)
|
||||||
unsafe {
|
unsafe {
|
||||||
q -= 2
|
q -= 2
|
||||||
|
q = q + 1
|
||||||
}
|
}
|
||||||
q = q + 1 // not caught yet
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue