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 {
|
||||
cap_ := if cap < mylen { mylen } else { cap }
|
||||
arr := array{
|
||||
mut arr := array{
|
||||
element_size: elm_size
|
||||
data: vcalloc(cap_ * elm_size)
|
||||
len: mylen
|
||||
|
@ -37,7 +37,9 @@ fn __new_array_with_default(mylen int, cap int, elm_size int, val voidptr) array
|
|||
}
|
||||
if val != 0 {
|
||||
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
|
||||
|
@ -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 {
|
||||
cap_ := if cap < mylen { mylen } else { cap }
|
||||
arr := array{
|
||||
mut arr := array{
|
||||
element_size: elm_size
|
||||
data: vcalloc(cap_ * elm_size)
|
||||
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 {
|
||||
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
|
||||
}
|
||||
|
@ -123,9 +127,13 @@ pub fn (a array) repeat(count int) array {
|
|||
ary := array{}
|
||||
C.memcpy(&ary, a.data, sizeof(array))
|
||||
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 {
|
||||
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
|
||||
|
@ -144,9 +152,10 @@ pub fn (mut a array) insert(i int, val voidptr) {
|
|||
}
|
||||
}
|
||||
a.ensure_cap(a.len + 1)
|
||||
size := a.element_size
|
||||
C.memmove(byteptr(a.data) + (i + 1) * size, byteptr(a.data) + i * size, (a.len - i) * size)
|
||||
C.memcpy(byteptr(a.data) + i * size, val, size)
|
||||
unsafe {
|
||||
C.memmove(a.get_unsafe(i + 1), a.get_unsafe(i), (a.len - i) * a.element_size)
|
||||
a.set_unsafe(i, val)
|
||||
}
|
||||
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)
|
||||
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)
|
||||
C.memcpy(byteptr(a.data) + i * elem_size, val, size * elem_size)
|
||||
unsafe {
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -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)')
|
||||
}
|
||||
}
|
||||
size := a.element_size
|
||||
// NB: if a is [12,34], a.len = 2, a.delete(0)
|
||||
// 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--
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
fn (a array) get(i int) voidptr {
|
||||
$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)')
|
||||
}
|
||||
}
|
||||
return byteptr(a.data) + i * a.element_size
|
||||
unsafe {
|
||||
return byteptr(a.data) + i * a.element_size
|
||||
}
|
||||
}
|
||||
|
||||
// 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')
|
||||
}
|
||||
}
|
||||
return byteptr(a.data) + (a.len - 1) * a.element_size
|
||||
unsafe {
|
||||
return byteptr(a.data) + (a.len - 1) * a.element_size
|
||||
}
|
||||
}
|
||||
|
||||
// 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)')
|
||||
}
|
||||
}
|
||||
mut data := byteptr(0)
|
||||
unsafe {
|
||||
data = byteptr(a.data) + start * a.element_size
|
||||
}
|
||||
l := end - start
|
||||
res := array{
|
||||
element_size: a.element_size
|
||||
data: byteptr(a.data) + start * a.element_size
|
||||
data: data
|
||||
len: l
|
||||
cap: l
|
||||
}
|
||||
|
@ -276,7 +305,7 @@ pub fn (a &array) clone() array {
|
|||
if size == 0 {
|
||||
size++
|
||||
}
|
||||
arr := array{
|
||||
mut arr := array{
|
||||
element_size: a.element_size
|
||||
data: vcalloc(size)
|
||||
len: a.len
|
||||
|
@ -286,9 +315,9 @@ pub fn (a &array) clone() array {
|
|||
if a.element_size == sizeof(array) {
|
||||
for i in 0..a.len {
|
||||
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()
|
||||
C.memcpy(byteptr(arr.data) + i * a.element_size, &ar_clone, a.element_size)
|
||||
arr.set_unsafe(i, &ar_clone)
|
||||
}
|
||||
} else {
|
||||
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)')
|
||||
}
|
||||
}
|
||||
mut data := byteptr(0)
|
||||
unsafe {
|
||||
data = byteptr(a.data) + start * a.element_size
|
||||
}
|
||||
l := end - start
|
||||
res := array{
|
||||
element_size: a.element_size
|
||||
data: byteptr(a.data) + start * a.element_size
|
||||
data: data
|
||||
len: l
|
||||
cap: l
|
||||
}
|
||||
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.
|
||||
fn (mut a array) set(i int, val voidptr) {
|
||||
$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)')
|
||||
}
|
||||
}
|
||||
C.memcpy(byteptr(a.data) + a.element_size * i, val, a.element_size)
|
||||
unsafe {
|
||||
C.memcpy(byteptr(a.data) + a.element_size * i, val, a.element_size)
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut a array) push(val voidptr) {
|
||||
a.ensure_cap(a.len + 1)
|
||||
C.memcpy(byteptr(a.data) + a.element_size * a.len, val, a.element_size)
|
||||
unsafe {
|
||||
C.memcpy(byteptr(a.data) + a.element_size * a.len, val, a.element_size)
|
||||
}
|
||||
a.len++
|
||||
}
|
||||
|
||||
|
@ -342,11 +387,15 @@ pub fn (mut a3 array) push_many(val voidptr, size int) {
|
|||
// handle `arr << arr`
|
||||
copy := a3.clone()
|
||||
a3.ensure_cap(a3.len + size)
|
||||
//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)
|
||||
unsafe {
|
||||
//C.memcpy(a.data, copy.data, copy.element_size * copy.len)
|
||||
C.memcpy(a3.get_unsafe(a3.len), copy.data, a3.element_size * size)
|
||||
}
|
||||
} else {
|
||||
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
|
||||
}
|
||||
|
@ -357,15 +406,16 @@ pub fn (a array) reverse() array {
|
|||
if a.len < 2 {
|
||||
return a
|
||||
}
|
||||
arr := array{
|
||||
mut arr := array{
|
||||
element_size: a.element_size
|
||||
data: vcalloc(a.cap * a.element_size)
|
||||
len: a.len
|
||||
cap: a.cap
|
||||
}
|
||||
for i in 0..a.len {
|
||||
//C.memcpy(arr.data + i * arr.element_size, &a[a.len - 1 - i], arr.element_size)
|
||||
C.memcpy(byteptr(arr.data) + i * arr.element_size, byteptr(a.data) + (a.len - 1 - i) * arr.element_size, arr.element_size)
|
||||
unsafe {
|
||||
arr.set_unsafe(i, a.get_unsafe(a.len - 1 - i))
|
||||
}
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
@ -591,7 +641,7 @@ pub fn compare_f32(a, b &f32) int {
|
|||
pub fn (a array) pointers() []voidptr {
|
||||
mut res := []voidptr{}
|
||||
for i in 0..a.len {
|
||||
res << byteptr(a.data) + i * a.element_size
|
||||
res << a.get_unsafe(i)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
|
|
@ -93,7 +93,9 @@ pub fn (nn int) str_l(max int) string {
|
|||
buf[index] = `-`
|
||||
}
|
||||
|
||||
C.memmove(buf,buf+index, (max-index)+1 )
|
||||
unsafe {
|
||||
C.memmove(buf,buf+index, (max-index)+1 )
|
||||
}
|
||||
return tos(buf, (max-index))
|
||||
//return tos(buf + index, (max-index))
|
||||
}
|
||||
|
@ -139,7 +141,9 @@ pub fn (nn u32) str() string {
|
|||
index++
|
||||
}
|
||||
|
||||
C.memmove(buf,buf+index, (max-index)+1 )
|
||||
unsafe {
|
||||
C.memmove(buf,buf+index, (max-index)+1 )
|
||||
}
|
||||
return tos(buf, (max-index))
|
||||
//return tos(buf + index, (max-index))
|
||||
}
|
||||
|
@ -186,7 +190,9 @@ pub fn (nn i64) str() string {
|
|||
buf[index] = `-`
|
||||
}
|
||||
|
||||
C.memmove(buf,buf+index, (max-index)+1 )
|
||||
unsafe {
|
||||
C.memmove(buf,buf+index, (max-index)+1 )
|
||||
}
|
||||
return tos(buf, (max-index))
|
||||
//return tos(buf + index, (max-index))
|
||||
}
|
||||
|
@ -216,7 +222,9 @@ pub fn (nn u64) str() string {
|
|||
index++
|
||||
}
|
||||
|
||||
C.memmove(buf,buf+index, (max-index)+1 )
|
||||
unsafe {
|
||||
C.memmove(buf,buf+index, (max-index)+1 )
|
||||
}
|
||||
return tos(buf, (max-index))
|
||||
//return tos(buf + index, (max-index))
|
||||
}
|
||||
|
@ -260,7 +268,9 @@ pub fn (nn byte) hex() string {
|
|||
//buf[index] = `0`
|
||||
index++
|
||||
|
||||
return tos(buf + index, (max - index))
|
||||
unsafe {
|
||||
return tos(buf + index, (max - index))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (nn i8) hex() string {
|
||||
|
@ -287,7 +297,9 @@ pub fn (nn u16) hex() string {
|
|||
//buf[index] = `0`
|
||||
index++
|
||||
|
||||
return tos(buf + index, (max - index))
|
||||
unsafe {
|
||||
return tos(buf + index, (max - index))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (nn i16) hex() string {
|
||||
|
@ -314,7 +326,9 @@ pub fn (nn u32) hex() string {
|
|||
//buf[index] = `0`
|
||||
index++
|
||||
|
||||
return tos(buf + index, (max - index))
|
||||
unsafe {
|
||||
return tos(buf + index, (max - index))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (nn int) hex() string {
|
||||
|
@ -345,7 +359,9 @@ pub fn (nn u64) hex() string {
|
|||
//buf[index] = `0`
|
||||
index++
|
||||
|
||||
C.memmove(buf,buf+index, (max-index)+1 )
|
||||
unsafe {
|
||||
C.memmove(buf,buf+index, (max-index)+1 )
|
||||
}
|
||||
return tos(buf, (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
|
||||
d.keys[push_index] = key
|
||||
C.memcpy(d.values + push_index * u32(d.value_bytes), value, d.value_bytes)
|
||||
unsafe {
|
||||
C.memcpy(d.values + push_index * u32(d.value_bytes), value, d.value_bytes)
|
||||
}
|
||||
d.len++
|
||||
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)')
|
||||
}
|
||||
}
|
||||
return byteptr(d.keys) + i * int(sizeof(string))
|
||||
unsafe {
|
||||
return byteptr(d.keys) + i * int(sizeof(string))
|
||||
}
|
||||
}
|
||||
|
||||
// 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[i] = tmp_key
|
||||
// swap values (TODO: optimize)
|
||||
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 + i * d.value_bytes, tmp_value, d.value_bytes)
|
||||
unsafe {
|
||||
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 + i * d.value_bytes, tmp_value, d.value_bytes)
|
||||
}
|
||||
count++
|
||||
}
|
||||
}
|
||||
|
@ -206,7 +212,9 @@ fn new_map_1(value_bytes int) map {
|
|||
fn new_map_init(n, value_bytes int, keys &string, values voidptr) map {
|
||||
mut out := new_map_1(value_bytes)
|
||||
for i in 0 .. n {
|
||||
out.set(keys[i], byteptr(values) + i * value_bytes)
|
||||
unsafe {
|
||||
out.set(keys[i], byteptr(values) + i * value_bytes)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
@ -258,8 +266,10 @@ fn (mut m map) ensure_extra_metas(probe_count u32) {
|
|||
if (probe_count << 1) == m.extra_metas {
|
||||
m.extra_metas += extra_metas_inc
|
||||
mem_size := (m.cap + 2 + m.extra_metas)
|
||||
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)
|
||||
unsafe {
|
||||
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)
|
||||
}
|
||||
// Should almost never happen
|
||||
if probe_count == 252 {
|
||||
panic('Probe overflow')
|
||||
|
@ -282,7 +292,9 @@ fn (mut m map) set(k string, value voidptr) {
|
|||
for meta == m.metas[index] {
|
||||
kv_index := m.metas[index + 1]
|
||||
if fast_string_eq(key, m.key_values.keys[kv_index]) {
|
||||
C.memcpy(m.key_values.values + kv_index * u32(m.value_bytes), value, m.value_bytes)
|
||||
unsafe {
|
||||
C.memcpy(m.key_values.values + kv_index * u32(m.value_bytes), value, m.value_bytes)
|
||||
}
|
||||
return
|
||||
}
|
||||
index += 2
|
||||
|
@ -362,7 +374,9 @@ fn (mut m map) get_and_set(key string, zero voidptr) voidptr {
|
|||
if meta == m.metas[index] {
|
||||
kv_index := m.metas[index + 1]
|
||||
if fast_string_eq(key, m.key_values.keys[kv_index]) {
|
||||
return voidptr(m.key_values.values + kv_index * u32(m.value_bytes))
|
||||
unsafe {
|
||||
return voidptr(m.key_values.values + kv_index * u32(m.value_bytes))
|
||||
}
|
||||
}
|
||||
}
|
||||
index += 2
|
||||
|
@ -383,7 +397,9 @@ fn (m map) get(key string, zero voidptr) voidptr {
|
|||
if meta == m.metas[index] {
|
||||
kv_index := m.metas[index + 1]
|
||||
if fast_string_eq(key, m.key_values.keys[kv_index]) {
|
||||
return voidptr(m.key_values.values + kv_index * u32(m.value_bytes))
|
||||
unsafe {
|
||||
return voidptr(m.key_values.values + kv_index * u32(m.value_bytes))
|
||||
}
|
||||
}
|
||||
}
|
||||
index += 2
|
||||
|
|
|
@ -39,10 +39,10 @@ fn opt_ok2(data voidptr, mut option &OptionBase, size int) {
|
|||
*option = OptionBase {
|
||||
ok: true
|
||||
}
|
||||
}
|
||||
|
||||
// use ecode to get the end of OptionBase and then memcpy into it
|
||||
C.memcpy(byteptr(&option.ecode) + sizeof(int), data, size)
|
||||
// use ecode to get the end of OptionBase and then memcpy into it
|
||||
C.memcpy(byteptr(&option.ecode) + sizeof(int), data, size)
|
||||
}
|
||||
}
|
||||
|
||||
// Old option type used for bootstrapping
|
||||
|
|
|
@ -48,7 +48,9 @@ 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 {
|
||||
mut out := new_sorted_map(n, value_bytes)
|
||||
for i in 0 .. n {
|
||||
out.set(keys[i], byteptr(values) + i * value_bytes)
|
||||
unsafe {
|
||||
out.set(keys[i], byteptr(values) + i * value_bytes)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
|
|
@ -118,7 +118,9 @@ pub fn (_str string) to_wide() &u16 {
|
|||
mut wstr := &u16(malloc((num_chars + 1) * 2)) // sizeof(wchar_t)
|
||||
if wstr != 0 {
|
||||
C.MultiByteToWideChar(cp_utf8, 0, _str.str, _str.len, wstr, num_chars)
|
||||
C.memset(&byte(wstr) + num_chars * 2, 0, 2)
|
||||
unsafe {
|
||||
C.memset(&byte(wstr) + num_chars * 2, 0, 2)
|
||||
}
|
||||
}
|
||||
return wstr
|
||||
} $else {
|
||||
|
@ -141,7 +143,9 @@ pub fn string_from_wide2(_wstr &u16, len int) string {
|
|||
mut str_to := malloc(num_chars + 1)
|
||||
if str_to != 0 {
|
||||
C.WideCharToMultiByte(cp_utf8, 0, _wstr, len, str_to, num_chars, 0, 0)
|
||||
C.memset(str_to + num_chars, 0, 1)
|
||||
unsafe {
|
||||
C.memset(str_to + num_chars, 0, 1)
|
||||
}
|
||||
}
|
||||
return tos2(str_to)
|
||||
} $else {
|
||||
|
|
|
@ -51,23 +51,25 @@ fn wyhash64(key byteptr, len, seed_ u64) u64 {
|
|||
mut p := &key[0]
|
||||
mut seed := seed_
|
||||
mut i := len & 63
|
||||
if i < 4 {
|
||||
seed = wymum(wyr3(p, i) ^ seed ^ wyp0, seed ^ wyp1)
|
||||
}
|
||||
else if i <= 8 {
|
||||
seed = wymum(wyr4(p) ^ seed ^ wyp0, wyr4(p + i - 4) ^ seed ^ wyp1)
|
||||
}
|
||||
else if i <= 16 {
|
||||
seed = wymum(wyr8(p) ^ seed ^ wyp0, wyr8(p + i - 8) ^ seed ^ wyp1)
|
||||
}
|
||||
else if i <= 24 {
|
||||
seed = wymum(wyr8(p) ^ seed ^ wyp0, wyr8(p + 8) ^ seed ^ wyp1) ^ wymum(wyr8(p + i - 8) ^ seed ^ wyp2, seed ^ wyp3)
|
||||
}
|
||||
else if i <= 32 {
|
||||
seed = wymum(wyr8(p) ^ seed ^ wyp0, wyr8(p + 8) ^ seed ^ wyp1) ^ wymum(wyr8(p + 16) ^ seed ^ wyp2, wyr8(p + i - 8) ^ seed ^ wyp3)
|
||||
}
|
||||
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)
|
||||
unsafe {
|
||||
if i < 4 {
|
||||
seed = wymum(wyr3(p, i) ^ seed ^ wyp0, seed ^ wyp1)
|
||||
}
|
||||
else if i <= 8 {
|
||||
seed = wymum(wyr4(p) ^ seed ^ wyp0, wyr4(p + i - 4) ^ seed ^ wyp1)
|
||||
}
|
||||
else if i <= 16 {
|
||||
seed = wymum(wyr8(p) ^ seed ^ wyp0, wyr8(p + i - 8) ^ seed ^ wyp1)
|
||||
}
|
||||
else if i <= 24 {
|
||||
seed = wymum(wyr8(p) ^ seed ^ wyp0, wyr8(p + 8) ^ seed ^ wyp1) ^ wymum(wyr8(p + i - 8) ^ seed ^ wyp2, seed ^ wyp3)
|
||||
}
|
||||
else if i <= 32 {
|
||||
seed = wymum(wyr8(p) ^ seed ^ wyp0, wyr8(p + 8) ^ seed ^ wyp1) ^ wymum(wyr8(p + 16) ^ seed ^ wyp2, wyr8(p + i - 8) ^ seed ^ wyp3)
|
||||
}
|
||||
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)
|
||||
}
|
||||
}
|
||||
if i == len {
|
||||
return wymum(seed, len ^ wyp4)
|
||||
|
@ -75,13 +77,15 @@ fn wyhash64(key byteptr, len, seed_ u64) u64 {
|
|||
mut see1 := seed
|
||||
mut see2 := seed
|
||||
mut see3 := seed
|
||||
p = p + i
|
||||
for i = len - i; i >= 64; i -= 64 {
|
||||
seed = wymum(wyr8(p) ^ seed ^ wyp0, wyr8(p + 8) ^ seed ^ wyp1)
|
||||
see1 = wymum(wyr8(p + 16) ^ see1 ^ wyp2, wyr8(p + 24) ^ see1 ^ wyp3)
|
||||
see2 = wymum(wyr8(p + 32) ^ see2 ^ wyp1, wyr8(p + 40) ^ see2 ^ wyp2)
|
||||
see3 = wymum(wyr8(p + 48) ^ see3 ^ wyp3, wyr8(p + 56) ^ see3 ^ wyp0)
|
||||
p = p + 64
|
||||
unsafe {
|
||||
p = p + i
|
||||
for i = len - i; i >= 64; i -= 64 {
|
||||
seed = wymum(wyr8(p) ^ seed ^ wyp0, wyr8(p + 8) ^ seed ^ wyp1)
|
||||
see1 = wymum(wyr8(p + 16) ^ see1 ^ wyp2, wyr8(p + 24) ^ see1 ^ wyp3)
|
||||
see2 = wymum(wyr8(p + 32) ^ see2 ^ wyp1, wyr8(p + 40) ^ see2 ^ wyp2)
|
||||
see3 = wymum(wyr8(p + 48) ^ see3 ^ wyp3, wyr8(p + 56) ^ see3 ^ wyp0)
|
||||
p = p + 64
|
||||
}
|
||||
}
|
||||
return wymum(seed ^ see1 ^ see2, see3 ^ len ^ wyp4)
|
||||
}
|
||||
|
|
|
@ -7,7 +7,10 @@ fn (mut ws Client) read_handshake(seckey string) {
|
|||
buffer_size := 1
|
||||
mut buffer := malloc(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 {
|
||||
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 {
|
||||
len16 := C.htons(payload_len)
|
||||
header[1] = (126 | 0x80)
|
||||
C.memcpy(header.data + 2, &len16, 2)
|
||||
unsafe {
|
||||
C.memcpy(header.data + 2, &len16, 2)
|
||||
}
|
||||
header[4] = masking_key[0]
|
||||
header[5] = masking_key[1]
|
||||
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
|
||||
len64 := htonl64(u64(payload_len))
|
||||
header[1] = (127 | 0x80)
|
||||
C.memcpy(header.data + 2, len64, 8)
|
||||
unsafe {
|
||||
C.memcpy(header.data + 2, len64, 8)
|
||||
}
|
||||
header[10] = masking_key[0]
|
||||
header[11] = masking_key[1]
|
||||
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
|
||||
return -1
|
||||
}
|
||||
C.memcpy(fbdata, header.data, header_len)
|
||||
C.memcpy(fbdata + header_len, payload, payload_len)
|
||||
unsafe
|
||||
{
|
||||
C.memcpy(fbdata, header.data, header_len)
|
||||
C.memcpy(fbdata + header_len, payload, payload_len)
|
||||
}
|
||||
for i in 0 .. payload_len {
|
||||
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_size := u64(header_len)
|
||||
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 {
|
||||
0 {
|
||||
error := 'server closed the connection.'
|
||||
|
@ -442,7 +452,9 @@ pub fn (mut ws Client) read() int {
|
|||
}
|
||||
mut by := 0
|
||||
for f in frags {
|
||||
C.memcpy(pl + by, f.data, f.len)
|
||||
unsafe {
|
||||
C.memcpy(pl + by, f.data, f.len)
|
||||
}
|
||||
by += int(f.len)
|
||||
unsafe {
|
||||
free(f.data)
|
||||
|
|
|
@ -58,12 +58,16 @@ pub fn environ() map[string]string {
|
|||
$if windows {
|
||||
mut estrings := C.GetEnvironmentStringsW()
|
||||
mut eline := ''
|
||||
for c := estrings; *c != 0; c = c + eline.len + 1 {
|
||||
for c := estrings; *c != 0; {
|
||||
eline = string_from_wide(c)
|
||||
eq_index := eline.index_byte(`=`)
|
||||
if eq_index > 0 {
|
||||
res[eline[0..eq_index]] = eline[eq_index + 1..]
|
||||
}
|
||||
unsafe
|
||||
{
|
||||
c = c + eline.len + 1
|
||||
}
|
||||
}
|
||||
C.FreeEnvironmentStringsW(estrings)
|
||||
} $else {
|
||||
|
|
|
@ -106,12 +106,16 @@ fn close_conn(loop &C.picoev_loop, fd int) {
|
|||
|
||||
[inline]
|
||||
fn myread(fd int, b byteptr, max_len, idx int) int {
|
||||
return C.read(fd, b + idx, max_len - idx)
|
||||
unsafe {
|
||||
return C.read(fd, b + idx, max_len - idx)
|
||||
}
|
||||
}
|
||||
|
||||
[inline]
|
||||
fn mysubstr(s byteptr, from, len int) string {
|
||||
return tos(s + from, len)
|
||||
unsafe {
|
||||
return tos(s + from, len)
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
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]
|
||||
mut r := myread(fd, buf, max_read, idx)
|
||||
if r == 0 {
|
||||
|
@ -141,12 +148,18 @@ fn rw_callback(loop &C.picoev_loop, fd, events int, cb_arg voidptr) {
|
|||
} else {
|
||||
r += idx
|
||||
mut s := tos(buf, r)
|
||||
out := (p.out + fd * max_write)
|
||||
mut out := p.out
|
||||
unsafe {
|
||||
out += fd * max_write
|
||||
}
|
||||
mut res := picohttpparser.Response{
|
||||
fd: fd
|
||||
date: p.date
|
||||
buf_start: out
|
||||
buf: out + p.oidx[fd]
|
||||
buf: out
|
||||
}
|
||||
unsafe {
|
||||
res.buf += p.oidx[fd]
|
||||
}
|
||||
mut req := picohttpparser.Request{}
|
||||
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_pos := infix_expr.left.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
|
||||
// Single side check
|
||||
// Place these branches according to ops' usage frequency to accelerate.
|
||||
|
|
|
@ -4,13 +4,13 @@ fn test_ptr_arithmetic(){
|
|||
unsafe {
|
||||
p++
|
||||
p += 2
|
||||
p = p - 1
|
||||
}
|
||||
p = p - 1 // not caught yet
|
||||
|
||||
// byteptr, voidptr, charptr are handled differently
|
||||
mut q := byteptr(1)
|
||||
unsafe {
|
||||
q -= 2
|
||||
q = q + 1
|
||||
}
|
||||
q = q + 1 // not caught yet
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue