Browse Source

Disable pointer arithmetic

gingerBill 7 years ago
parent
commit
de9a4b5164
6 changed files with 60 additions and 48 deletions
  1. 40 37
      core/_preload.odin
  2. 2 2
      core/hash.odin
  3. 15 5
      core/mem.odin
  4. 1 1
      core/os/windows.odin
  5. 1 1
      src/main.cpp
  6. 1 2
      src/types.cpp

+ 40 - 37
core/_preload.odin

@@ -4,6 +4,7 @@ import "core:os.odin"
 // import "core:fmt.odin" // TODO(bill): Remove the need for `fmt` here
 // import "core:fmt.odin" // TODO(bill): Remove the need for `fmt` here
 import "core:utf8.odin"
 import "core:utf8.odin"
 import "core:raw.odin"
 import "core:raw.odin"
+import "core:mem.odin"
 
 
 // Naming Conventions:
 // Naming Conventions:
 // In general, Ada_Case for types and snake_case for values
 // In general, Ada_Case for types and snake_case for values
@@ -347,10 +348,10 @@ append :: proc(array: ^$T/[dynamic]$E, args: ...E, loc := #caller_location) -> i
 	}
 	}
 	arg_len = min(cap(array)-len(array), arg_len);
 	arg_len = min(cap(array)-len(array), arg_len);
 	if arg_len > 0 {
 	if arg_len > 0 {
-		a := cast(^raw.Dynamic_Array)array;
-		data := cast(^E)a.data;
+		a := (^raw.Dynamic_Array)(array);
+		data := (^E)(a.data);
 		assert(data != nil);
 		assert(data != nil);
-		__mem_copy(data + a.len, &args[0], size_of(E) * arg_len);
+		__mem_copy(mem.ptr_offset(data, a.len), &args[0], size_of(E) * arg_len);
 		a.len += arg_len;
 		a.len += arg_len;
 	}
 	}
 	return len(array);
 	return len(array);
@@ -358,7 +359,7 @@ append :: proc(array: ^$T/[dynamic]$E, args: ...E, loc := #caller_location) -> i
 
 
 append_string :: proc(array: ^$T/[dynamic]$E/u8, args: ...string, loc := #caller_location) -> int {
 append_string :: proc(array: ^$T/[dynamic]$E/u8, args: ...string, loc := #caller_location) -> int {
 	for arg in args {
 	for arg in args {
-		append(array = array, args = cast([]E)arg, loc = loc);
+		append(array = array, args = ([]E)(arg), loc = loc);
 	}
 	}
 	return len(array);
 	return len(array);
 }
 }
@@ -372,13 +373,13 @@ pop :: proc "contextless" (array: ^$T/[dynamic]$E) -> E {
 }
 }
 
 
 clear_dynamic_array :: inline proc "contextless" (array: ^$T/[dynamic]$E) {
 clear_dynamic_array :: inline proc "contextless" (array: ^$T/[dynamic]$E) {
-	if array != nil do (cast(^raw.Dynamic_Array)array).len = 0;
+	if array != nil do (^raw.Dynamic_Array)(array).len = 0;
 }
 }
 clear_map :: inline proc "contextless" (m: ^$T/map[$K]$V) {
 clear_map :: inline proc "contextless" (m: ^$T/map[$K]$V) {
 	if m == nil do return;
 	if m == nil do return;
-	raw_map := cast(^raw.Map)m;
-	hashes  := cast(^raw.Dynamic_Array)&raw_map.hashes;
-	entries := cast(^raw.Dynamic_Array)&raw_map.entries;
+	raw_map := (^raw.Map)(m);
+	hashes  := (^raw.Dynamic_Array)(&raw_map.hashes);
+	entries := (^raw.Dynamic_Array)(&raw_map.entries);
 	hashes.len  = 0;
 	hashes.len  = 0;
 	entries.len = 0;
 	entries.len = 0;
 }
 }
@@ -387,7 +388,7 @@ clear :: proc[clear_dynamic_array, clear_map];
 
 
 reserve_dynamic_array :: proc(array: ^$T/[dynamic]$E, capacity: int, loc := #caller_location) -> bool {
 reserve_dynamic_array :: proc(array: ^$T/[dynamic]$E, capacity: int, loc := #caller_location) -> bool {
 	if array == nil do return false;
 	if array == nil do return false;
-	a := cast(^raw.Dynamic_Array)array;
+	a := (^raw.Dynamic_Array)(array);
 
 
 	if capacity <= a.cap do return true;
 	if capacity <= a.cap do return true;
 
 
@@ -413,7 +414,7 @@ reserve_dynamic_array :: proc(array: ^$T/[dynamic]$E, capacity: int, loc := #cal
 
 
 
 
 __get_map_header :: proc "contextless" (m: ^$T/map[$K]$V) -> __Map_Header {
 __get_map_header :: proc "contextless" (m: ^$T/map[$K]$V) -> __Map_Header {
-	header := __Map_Header{m = cast(^raw.Map)m};
+	header := __Map_Header{m = (^raw.Map)(m)};
 	Entry :: struct {
 	Entry :: struct {
 		key:   __Map_Key,
 		key:   __Map_Key,
 		next:  int,
 		next:  int,
@@ -442,7 +443,7 @@ __get_map_key :: proc "contextless" (key: $K) -> __Map_Key {
 		case: panic("Unhandled integer size");
 		case: panic("Unhandled integer size");
 		}
 		}
 	case Type_Info_Rune:
 	case Type_Info_Rune:
-		map_key.hash = u64((cast(^rune)&key)^);
+		map_key.hash = u64((^rune)(&key)^);
 	case Type_Info_Pointer:
 	case Type_Info_Pointer:
 		map_key.hash = u64(uintptr((^rawptr)(&key)^));
 		map_key.hash = u64(uintptr((^rawptr)(&key)^));
 	case Type_Info_Float:
 	case Type_Info_Float:
@@ -474,12 +475,12 @@ reserve :: proc[reserve_dynamic_array, reserve_map];
 
 
 
 
 new :: inline proc(T: type, loc := #caller_location) -> ^T {
 new :: inline proc(T: type, loc := #caller_location) -> ^T {
-	ptr := cast(^T)alloc(size_of(T), align_of(T), loc);
+	ptr := (^T)(alloc(size_of(T), align_of(T), loc));
 	ptr^ = T{};
 	ptr^ = T{};
 	return ptr;
 	return ptr;
 }
 }
 new_clone :: inline proc(data: $T, loc := #caller_location) -> ^T {
 new_clone :: inline proc(data: $T, loc := #caller_location) -> ^T {
-	ptr := cast(^T)alloc(size_of(T), align_of(T), loc);
+	ptr := (^T)(alloc(size_of(T), align_of(T), loc));
 	ptr^ = data;
 	ptr^ = data;
 	return ptr;
 	return ptr;
 }
 }
@@ -889,7 +890,7 @@ __string_ge :: inline proc "contextless" (a, b: string) -> bool { return __strin
 
 
 __cstring_len :: proc "contextless" (s: cstring) -> int {
 __cstring_len :: proc "contextless" (s: cstring) -> int {
 	n := 0;
 	n := 0;
-	for p := (^byte)(s); p != nil && p^ != 0; p += 1 {
+	for p := (^byte)(s); p != nil && p^ != 0; p = mem.ptr_offset(p, 1) {
 		n += 1;
 		n += 1;
 	}
 	}
 	return n;
 	return n;
@@ -1027,9 +1028,10 @@ __mem_copy_non_overlapping :: proc "contextless" (dst, src: rawptr, len: int) ->
 }
 }
 
 
 __mem_compare :: proc "contextless" (a, b: ^byte, n: int) -> int {
 __mem_compare :: proc "contextless" (a, b: ^byte, n: int) -> int {
+	pa :: mem.ptr_offset;
 	for i in 0..n do switch {
 	for i in 0..n do switch {
-	case (a+i)^ < (b+i)^: return -1;
-	case (a+i)^ > (b+i)^: return +1;
+	case pa(a, i)^ < pa(b, i)^: return -1;
+	case pa(a, i)^ > pa(b, i)^: return +1;
 	}
 	}
 	return 0;
 	return 0;
 }
 }
@@ -1102,7 +1104,7 @@ __abs_complex128 :: inline proc "contextless" (x: complex128) -> f64 {
 
 
 
 
 __dynamic_array_make :: proc(array_: rawptr, elem_size, elem_align: int, len, cap: int, loc := #caller_location) {
 __dynamic_array_make :: proc(array_: rawptr, elem_size, elem_align: int, len, cap: int, loc := #caller_location) {
-	array := cast(^raw.Dynamic_Array)array_;
+	array := (^raw.Dynamic_Array)(array_);
 	array.allocator = context.allocator;
 	array.allocator = context.allocator;
 	assert(array.allocator.procedure != nil);
 	assert(array.allocator.procedure != nil);
 
 
@@ -1113,7 +1115,7 @@ __dynamic_array_make :: proc(array_: rawptr, elem_size, elem_align: int, len, ca
 }
 }
 
 
 __dynamic_array_reserve :: proc(array_: rawptr, elem_size, elem_align: int, cap: int, loc := #caller_location) -> bool {
 __dynamic_array_reserve :: proc(array_: rawptr, elem_size, elem_align: int, cap: int, loc := #caller_location) -> bool {
-	array := cast(^raw.Dynamic_Array)array_;
+	array := (^raw.Dynamic_Array)(array_);
 
 
 	if cap <= array.cap do return true;
 	if cap <= array.cap do return true;
 
 
@@ -1135,7 +1137,7 @@ __dynamic_array_reserve :: proc(array_: rawptr, elem_size, elem_align: int, cap:
 }
 }
 
 
 __dynamic_array_resize :: proc(array_: rawptr, elem_size, elem_align: int, len: int, loc := #caller_location) -> bool {
 __dynamic_array_resize :: proc(array_: rawptr, elem_size, elem_align: int, len: int, loc := #caller_location) -> bool {
-	array := cast(^raw.Dynamic_Array)array_;
+	array := (^raw.Dynamic_Array)(array_);
 
 
 	ok := __dynamic_array_reserve(array_, elem_size, elem_align, len, loc);
 	ok := __dynamic_array_reserve(array_, elem_size, elem_align, len, loc);
 	if ok do array.len = len;
 	if ok do array.len = len;
@@ -1145,7 +1147,7 @@ __dynamic_array_resize :: proc(array_: rawptr, elem_size, elem_align: int, len:
 
 
 __dynamic_array_append :: proc(array_: rawptr, elem_size, elem_align: int,
 __dynamic_array_append :: proc(array_: rawptr, elem_size, elem_align: int,
                                items: rawptr, item_count: int, loc := #caller_location) -> int {
                                items: rawptr, item_count: int, loc := #caller_location) -> int {
-	array := cast(^raw.Dynamic_Array)array_;
+	array := (^raw.Dynamic_Array)(array_);
 
 
 	if items == nil    do return 0;
 	if items == nil    do return 0;
 	if item_count <= 0 do return 0;
 	if item_count <= 0 do return 0;
@@ -1159,15 +1161,16 @@ __dynamic_array_append :: proc(array_: rawptr, elem_size, elem_align: int,
 	// TODO(bill): Better error handling for failed reservation
 	// TODO(bill): Better error handling for failed reservation
 	if !ok do return array.len;
 	if !ok do return array.len;
 
 
-	data := cast(^byte)array.data;
-	assert(data != nil);
-	__mem_copy(data + (elem_size*array.len), items, elem_size * item_count);
+	assert(array.data != nil);
+	data := uintptr(array.data) + uintptr(elem_size*array.len);
+
+	__mem_copy(rawptr(data), items, elem_size * item_count);
 	array.len += item_count;
 	array.len += item_count;
 	return array.len;
 	return array.len;
 }
 }
 
 
 __dynamic_array_append_nothing :: proc(array_: rawptr, elem_size, elem_align: int, loc := #caller_location) -> int {
 __dynamic_array_append_nothing :: proc(array_: rawptr, elem_size, elem_align: int, loc := #caller_location) -> int {
-	array := cast(^raw.Dynamic_Array)array_;
+	array := (^raw.Dynamic_Array)(array_);
 
 
 	ok := true;
 	ok := true;
 	if array.cap <= array.len+1 {
 	if array.cap <= array.len+1 {
@@ -1177,9 +1180,9 @@ __dynamic_array_append_nothing :: proc(array_: rawptr, elem_size, elem_align: in
 	// TODO(bill): Better error handling for failed reservation
 	// TODO(bill): Better error handling for failed reservation
 	if !ok do return array.len;
 	if !ok do return array.len;
 
 
-	data := cast(^byte)array.data;
-	assert(data != nil);
-	__mem_zero(data + (elem_size*array.len), elem_size);
+	assert(array.data != nil);
+	data := uintptr(array.data) + uintptr(elem_size*array.len);
+	__mem_zero(rawptr(data), elem_size);
 	array.len += 1;
 	array.len += 1;
 	return array.len;
 	return array.len;
 }
 }
@@ -1196,7 +1199,7 @@ __default_hash :: proc(data: []byte) -> u64 {
 	}
 	}
 	return fnv64a(data);
 	return fnv64a(data);
 }
 }
-__default_hash_string :: proc(s: string) -> u64 do return __default_hash(cast([]byte)s);
+__default_hash_string :: proc(s: string) -> u64 do return __default_hash(([]byte)(s));
 
 
 __dynamic_map_reserve :: proc(using header: __Map_Header, cap: int, loc := #caller_location) {
 __dynamic_map_reserve :: proc(using header: __Map_Header, cap: int, loc := #caller_location) {
 	__dynamic_array_reserve(&m.hashes, size_of(int), align_of(int), cap, loc);
 	__dynamic_array_reserve(&m.hashes, size_of(int), align_of(int), cap, loc);
@@ -1207,8 +1210,8 @@ __dynamic_map_rehash :: proc(using header: __Map_Header, new_count: int, loc :=
 	nm: raw.Map;
 	nm: raw.Map;
 	new_header.m = &nm;
 	new_header.m = &nm;
 
 
-	header_hashes := cast(^raw.Dynamic_Array)&header.m.hashes;
-	nm_hashes     := cast(^raw.Dynamic_Array)&nm.hashes;
+	header_hashes := (^raw.Dynamic_Array)(&header.m.hashes);
+	nm_hashes     := (^raw.Dynamic_Array)(&nm.hashes);
 
 
 	__dynamic_array_resize(nm_hashes, size_of(int), align_of(int), new_count, loc);
 	__dynamic_array_resize(nm_hashes, size_of(int), align_of(int), new_count, loc);
 	__dynamic_array_reserve(&nm.entries, entry_size, entry_align, m.entries.len, loc);
 	__dynamic_array_reserve(&nm.entries, entry_size, entry_align, m.entries.len, loc);
@@ -1218,7 +1221,7 @@ __dynamic_map_rehash :: proc(using header: __Map_Header, new_count: int, loc :=
 		if len(nm.hashes) == 0 do __dynamic_map_grow(new_header, loc);
 		if len(nm.hashes) == 0 do __dynamic_map_grow(new_header, loc);
 
 
 		entry_header := __dynamic_map_get_entry(header, i);
 		entry_header := __dynamic_map_get_entry(header, i);
-		data := cast(^byte)entry_header;
+		data := uintptr(entry_header);
 
 
 		fr := __dynamic_map_find(new_header, entry_header.key);
 		fr := __dynamic_map_find(new_header, entry_header.key);
 		j := __dynamic_map_add_entry(new_header, entry_header.key, loc);
 		j := __dynamic_map_add_entry(new_header, entry_header.key, loc);
@@ -1231,8 +1234,8 @@ __dynamic_map_rehash :: proc(using header: __Map_Header, new_count: int, loc :=
 
 
 		e := __dynamic_map_get_entry(new_header, j);
 		e := __dynamic_map_get_entry(new_header, j);
 		e.next = fr.entry_index;
 		e.next = fr.entry_index;
-		ndata := cast(^byte)e;
-		__mem_copy(ndata+value_offset, data+value_offset, value_size);
+		ndata := uintptr(e);
+		__mem_copy(rawptr(ndata+value_offset), rawptr(data+value_offset), value_size);
 
 
 		if __dynamic_map_full(new_header) do __dynamic_map_grow(new_header, loc);
 		if __dynamic_map_full(new_header) do __dynamic_map_grow(new_header, loc);
 	}
 	}
@@ -1244,8 +1247,8 @@ __dynamic_map_rehash :: proc(using header: __Map_Header, new_count: int, loc :=
 __dynamic_map_get :: proc(h: __Map_Header, key: __Map_Key) -> rawptr {
 __dynamic_map_get :: proc(h: __Map_Header, key: __Map_Key) -> rawptr {
 	index := __dynamic_map_find(h, key).entry_index;
 	index := __dynamic_map_find(h, key).entry_index;
 	if index >= 0 {
 	if index >= 0 {
-		data := cast(^byte)__dynamic_map_get_entry(h, index);
-		return data + h.value_offset;
+		data := uintptr(__dynamic_map_get_entry(h, index));
+		return rawptr(data + h.value_offset);
 	}
 	}
 	return nil;
 	return nil;
 }
 }
@@ -1275,7 +1278,7 @@ __dynamic_map_set :: proc(h: __Map_Header, key: __Map_Key, value: rawptr, loc :=
 	{
 	{
 		e := __dynamic_map_get_entry(h, index);
 		e := __dynamic_map_get_entry(h, index);
 		e.key = key;
 		e.key = key;
-		val := cast(^byte)(uintptr(e) + h.value_offset);
+		val := (^byte)(uintptr(e) + h.value_offset);
 		__mem_copy(val, value, h.value_size);
 		__mem_copy(val, value, h.value_size);
 	}
 	}
 
 
@@ -1339,7 +1342,7 @@ __dynamic_map_delete :: proc(using h: __Map_Header, key: __Map_Key) {
 
 
 __dynamic_map_get_entry :: proc(using h: __Map_Header, index: int) -> ^__Map_Entry_Header {
 __dynamic_map_get_entry :: proc(using h: __Map_Header, index: int) -> ^__Map_Entry_Header {
 	assert(0 <= index && index < m.entries.len);
 	assert(0 <= index && index < m.entries.len);
-	return cast(^__Map_Entry_Header)(uintptr(m.entries.data) + uintptr(index*entry_size));
+	return (^__Map_Entry_Header)(uintptr(m.entries.data) + uintptr(index*entry_size));
 }
 }
 
 
 __dynamic_map_erase :: proc(using h: __Map_Header, fr: __Map_Find_Result) #no_bounds_check {
 __dynamic_map_erase :: proc(using h: __Map_Header, fr: __Map_Find_Result) #no_bounds_check {

+ 2 - 2
core/hash.odin

@@ -64,9 +64,9 @@ murmur32 :: proc(data: []byte) -> u32 {
 	h1: u32 = 0;
 	h1: u32 = 0;
 	nblocks := len(data)/4;
 	nblocks := len(data)/4;
 	p := &data[0];
 	p := &data[0];
-	p1 := p + 4*nblocks;
+	p1 := mem.ptr_offset(p, 4*nblocks);
 
 
-	for ; p < p1; p += 4 {
+	for ; p < p1; p = mem.ptr_offset(p, 4) {
 		k1 := (cast(^u32)p)^;
 		k1 := (cast(^u32)p)^;
 
 
 		k1 *= c1_32;
 		k1 *= c1_32;

+ 15 - 5
core/mem.odin

@@ -1,4 +1,5 @@
 import "core:raw.odin"
 import "core:raw.odin"
+import "core:mem.odin"
 
 
 foreign __llvm_core {
 foreign __llvm_core {
 	@(link_name = "llvm.bswap.i16") swap16 :: proc(b: u16) -> u16 ---;
 	@(link_name = "llvm.bswap.i16") swap16 :: proc(b: u16) -> u16 ---;
@@ -25,6 +26,15 @@ compare :: proc "contextless" (a, b: []byte) -> int {
 }
 }
 
 
 
 
+ptr_offset :: proc "contextless" (ptr: $P/^$T, n: int) -> P {
+	new := uintptr(ptr) + uintptr(size_of(T)*n);
+	return P(new);
+}
+
+ptr_sub :: proc "contextless" (a, b: $P/^$T) -> int {
+	return (int(uintptr(a)) - int(uintptr(b)))/size_of(T);
+}
+
 slice_ptr :: proc "contextless" (ptr: ^$T, len: int) -> []T {
 slice_ptr :: proc "contextless" (ptr: ^$T, len: int) -> []T {
 	assert(len >= 0);
 	assert(len >= 0);
 	slice := raw.Slice{data = ptr, len = len};
 	slice := raw.Slice{data = ptr, len = len};
@@ -75,18 +85,18 @@ AllocationHeader :: struct {size: int};
 
 
 allocation_header_fill :: proc(header: ^AllocationHeader, data: rawptr, size: int) {
 allocation_header_fill :: proc(header: ^AllocationHeader, data: rawptr, size: int) {
 	header.size = size;
 	header.size = size;
-	ptr := cast(^uint)(header+1);
-	n := cast(^uint)data - ptr;
+	ptr := cast(^uint)(mem.ptr_offset(header, 1));
+	n := mem.ptr_sub(cast(^uint)data, ptr);
 
 
 	for i in 0..n {
 	for i in 0..n {
-		(ptr+i)^ = ~uint(0);
+		mem.ptr_offset(ptr, i)^ = ~uint(0);
 	}
 	}
 }
 }
 allocation_header :: proc(data: rawptr) -> ^AllocationHeader {
 allocation_header :: proc(data: rawptr) -> ^AllocationHeader {
 	if data == nil do return nil;
 	if data == nil do return nil;
 	p := cast(^uint)data;
 	p := cast(^uint)data;
-	for (p-1)^ == ~uint(0) do p = (p-1);
-	return cast(^AllocationHeader)(p-1);
+	for ptr_offset(p, -1)^ == ~uint(0) do p = ptr_offset(p, -1);
+	return (^AllocationHeader)(ptr_offset(p, -1));
 }
 }
 
 
 
 

+ 1 - 1
core/os/windows.odin

@@ -265,7 +265,7 @@ _alloc_command_line_arguments :: proc() -> []string {
 	arg_list_ptr := win32.command_line_to_argv_w(win32.get_command_line_w(), &arg_count);
 	arg_list_ptr := win32.command_line_to_argv_w(win32.get_command_line_w(), &arg_count);
 	arg_list := make([]string, int(arg_count));
 	arg_list := make([]string, int(arg_count));
 	for _, i in arg_list {
 	for _, i in arg_list {
-		wc_str := (arg_list_ptr+i)^;
+		wc_str := mem.ptr_offset(arg_list_ptr, i)^;
 		olen := win32.wide_char_to_multi_byte(win32.CP_UTF8, 0, wc_str, -1,
 		olen := win32.wide_char_to_multi_byte(win32.CP_UTF8, 0, wc_str, -1,
 		                                      nil, 0, nil, nil);
 		                                      nil, 0, nil, nil);
 
 

+ 1 - 1
src/main.cpp

@@ -1,6 +1,6 @@
 #define USE_THREADED_PARSER 1
 #define USE_THREADED_PARSER 1
 // #define NO_ARRAY_BOUNDS_CHECK
 // #define NO_ARRAY_BOUNDS_CHECK
-// #define NO_POINTER_ARITHMETIC
+#define NO_POINTER_ARITHMETIC
 
 
 #include "common.cpp"
 #include "common.cpp"
 #include "timings.cpp"
 #include "timings.cpp"

+ 1 - 2
src/types.cpp

@@ -1785,8 +1785,7 @@ struct TypePath {
 
 
 
 
 void type_path_init(TypePath *tp) {
 void type_path_init(TypePath *tp) {
-	// TODO(bill): Use an allocator that uses a backing array if it can and then use alternative allocator when exhausted
-	array_init(&tp->path, heap_allocator());
+	tp->path.allocator = heap_allocator();
 }
 }
 
 
 void type_path_free(TypePath *tp) {
 void type_path_free(TypePath *tp) {