Add warnings
This commit is contained in:
parent
9c7f3d99a7
commit
5df281f4b6
@ -1,14 +1,17 @@
|
||||
#if 0
|
||||
#include <std/base.h>
|
||||
#include <std/project.h>
|
||||
#include <std/os.h>
|
||||
|
||||
#include <std/base.c>
|
||||
#include <std/os.c>
|
||||
|
||||
#if 0
|
||||
#include <std/project.h>
|
||||
#include <std/virtual_buffer.h>
|
||||
#include <std/windowing.h>
|
||||
#include <std/rendering.h>
|
||||
#include <std/ui_core.h>
|
||||
#include <std/ui_builder.h>
|
||||
|
||||
#include <std/base.c>
|
||||
#include <std/os.c>
|
||||
#include <std/virtual_buffer.c>
|
||||
#include <std/windowing.c>
|
||||
@ -274,8 +277,11 @@ int main()
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int main()
|
||||
int main(int argc, char** argv, char** envp)
|
||||
{
|
||||
unused(argc);
|
||||
unused(argv);
|
||||
unused(envp);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -2361,7 +2361,7 @@ fn Node* thread_node_get(Thread* thread, NodeIndex node_index)
|
||||
return node;
|
||||
}
|
||||
|
||||
may_be_unused fn String node_id_to_string(NodeId node_id)
|
||||
fn String node_id_to_string(NodeId node_id)
|
||||
{
|
||||
switch (node_id)
|
||||
{
|
||||
@ -3568,7 +3568,7 @@ global_variable const auto ip_interface_register_mask = (InternPoolInterface) {
|
||||
fn Hash32 lower ## _hash_index(Thread* thread, T ## Index item_index); \
|
||||
fn Hash32 lower ## _hash(Thread* thread, const T * const restrict item); \
|
||||
\
|
||||
may_be_unused fn T ## GetOrPut ip_ ## T ## _get_or_put(InternPool(T)* pool, Thread* thread, T ## Index item_index) \
|
||||
fn T ## GetOrPut ip_ ## T ## _get_or_put(InternPool(T)* pool, Thread* thread, T ## Index item_index) \
|
||||
{ \
|
||||
auto hash = lower ## _hash_index(thread, item_index); \
|
||||
auto* item = thread_ ## lower ## _get(thread, item_index); \
|
||||
@ -3581,7 +3581,7 @@ may_be_unused fn T ## GetOrPut ip_ ## T ## _get_or_put(InternPool(T)* pool, Thre
|
||||
.existing = result.existing,\
|
||||
};\
|
||||
}\
|
||||
may_be_unused fn T ## GetOrPut ip_ ## T ## _get_or_put_new(InternPool(T)* pool, Thread* thread, const T* item) \
|
||||
fn T ## GetOrPut ip_ ## T ## _get_or_put_new(InternPool(T)* pool, Thread* thread, const T* item) \
|
||||
{ \
|
||||
auto hash = lower ## _hash(thread, item); \
|
||||
auto result = ip_generic_get_or_put((GenericInternPool*)pool, thread, 0, (void*)item, sizeof(T), hash, &ip_interface_ ## lower); \
|
||||
@ -3591,7 +3591,7 @@ may_be_unused fn T ## GetOrPut ip_ ## T ## _get_or_put_new(InternPool(T)* pool,
|
||||
.existing = result.existing,\
|
||||
};\
|
||||
}\
|
||||
may_be_unused fn T ## Index ip_ ## T ## _remove(InternPool(T)* pool, Thread* thread, T ## Index item_index)\
|
||||
fn T ## Index ip_ ## T ## _remove(InternPool(T)* pool, Thread* thread, T ## Index item_index)\
|
||||
{\
|
||||
auto existing_capacity = pool->capacity;\
|
||||
auto* item = thread_ ## lower ## _get(thread, item_index);\
|
||||
@ -4778,7 +4778,7 @@ global_variable const NodeVirtualTable node_functions[NODE_COUNT] = {
|
||||
// },
|
||||
};
|
||||
|
||||
may_be_unused fn String type_id_to_string(Type* type)
|
||||
fn String type_id_to_string(Type* type)
|
||||
{
|
||||
switch (type->id)
|
||||
{
|
||||
@ -6791,7 +6791,7 @@ fn void analyze_file(Thread* thread, File* file)
|
||||
// }
|
||||
// }
|
||||
|
||||
// may_be_unused fn void print_function(Thread* thread, Function* function)
|
||||
// fn void print_function(Thread* thread, Function* function)
|
||||
// {
|
||||
// print("fn {s}\n====\n", function->name);
|
||||
// VirtualBuffer(NodeIndex) nodes = {};
|
||||
@ -7534,7 +7534,7 @@ fn void uleb128_encode(VirtualBuffer(u8)* buffer, u32 value)
|
||||
*vb_add(buffer, 1) = out;
|
||||
}
|
||||
|
||||
may_be_unused fn void dwarf_playground(Thread* thread)
|
||||
fn void dwarf_playground(Thread* thread)
|
||||
{
|
||||
auto file = file_read(thread->arena,
|
||||
#ifdef __APPLE__
|
||||
@ -7838,7 +7838,7 @@ STRUCT(FileBuffer)
|
||||
VirtualBuffer(u8) buffer;
|
||||
};
|
||||
|
||||
may_be_unused fn String write_elf(Thread* thread, ObjectOptions options)
|
||||
fn String write_elf(Thread* thread, ObjectOptions options)
|
||||
{
|
||||
ELFBuilder builder_stack = {};
|
||||
ELFBuilder* restrict builder = &builder_stack;
|
||||
@ -20654,7 +20654,7 @@ fn String pdb_build(Thread* thread)
|
||||
return (String) { pdb_file.pointer, pdb_file.length };
|
||||
}
|
||||
|
||||
may_be_unused fn String write_pe(Thread* thread, ObjectOptions options)
|
||||
fn String write_pe(Thread* thread, ObjectOptions options)
|
||||
{
|
||||
VirtualBuffer(u8) file = {};
|
||||
|
||||
@ -22056,7 +22056,7 @@ fn u8 can_remat(Thread* thread, NodeIndex node_index)
|
||||
}
|
||||
}
|
||||
|
||||
may_be_unused fn f32 get_spill_cost(Thread* thread, VirtualRegister* virtual_register)
|
||||
fn f32 get_spill_cost(Thread* thread, VirtualRegister* virtual_register)
|
||||
{
|
||||
auto spill_cost = virtual_register->spill_cost;
|
||||
if (__builtin_isnan(spill_cost))
|
||||
@ -23431,7 +23431,7 @@ STRUCT(MachOSection)
|
||||
};
|
||||
static_assert(sizeof(MachOSection) == 0x50);
|
||||
|
||||
may_be_unused fn String write_macho(Thread* restrict thread, ObjectOptions options)
|
||||
fn String write_macho(Thread* restrict thread, ObjectOptions options)
|
||||
{
|
||||
unused(thread);
|
||||
unused(options);
|
||||
|
@ -1,11 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#if _MSC_VER
|
||||
extern u64 _lzcnt_u64(u64);
|
||||
extern u64 _tzcnt_u64(u64);
|
||||
#endif
|
||||
|
||||
fn u8 log2_alignment(u64 alignment)
|
||||
{
|
||||
assert(alignment != 0);
|
||||
assert((alignment & (alignment - 1)) == 0);
|
||||
u64 left = (sizeof(alignment) * 8) - 1;
|
||||
#if _MSC_VER
|
||||
let_cast(u64, right, _lzcnt_u64(alignment));
|
||||
#else
|
||||
let_cast(u64, right, __builtin_clzll(alignment));
|
||||
#endif
|
||||
let_cast(u8, result, left - right);
|
||||
return result;
|
||||
}
|
||||
@ -32,7 +41,7 @@ fn u64 u64_from_u128(u128 n)
|
||||
fn u128 u128_shift_right(u128 value, u16 n)
|
||||
{
|
||||
#if defined (__TINYC__) || defined(_MSC_VER)
|
||||
u128 result = {0, 0};
|
||||
u128 result = {};
|
||||
|
||||
if (n < 128)
|
||||
{
|
||||
@ -59,7 +68,7 @@ fn u128 u128_shift_right(u128 value, u16 n)
|
||||
fn u128 u128_shift_left(u128 value, u16 n)
|
||||
{
|
||||
#if defined(__TINYC__) || defined(_MSC_VER)
|
||||
u128 result = {0, 0};
|
||||
u128 result = {};
|
||||
|
||||
if (n < 128)
|
||||
{
|
||||
@ -115,7 +124,7 @@ fn u128 u128_u64_add(u128 a, u64 b)
|
||||
fn u128 u128_u64_mul(u128 a, u64 b)
|
||||
{
|
||||
#if defined(__TINYC__) || defined(_MSC_VER)
|
||||
u128 result = {0, 0};
|
||||
u128 result = {};
|
||||
|
||||
// Compute low and high parts of the product
|
||||
u64 low_low = (a.low & 0xFFFFFFFF) * (b & 0xFFFFFFFF);
|
||||
@ -147,8 +156,8 @@ fn u64 u128_shift_right_by_64(u128 n)
|
||||
|
||||
// Lehmer's generator
|
||||
// https://lemire.me/blog/2019/03/19/the-fastest-conventional-random-number-generator-that-can-pass-big-crush/
|
||||
may_be_unused global_variable u128 rn_state;
|
||||
may_be_unused fn u64 generate_random_number()
|
||||
global_variable u128 rn_state;
|
||||
fn u64 generate_random_number()
|
||||
{
|
||||
rn_state = u128_u64_mul(rn_state, 0xda942042e4dd58b5);
|
||||
return u128_shift_right_by_64(rn_state);
|
||||
@ -167,7 +176,7 @@ fn u64 round_up_to_next_power_of_2(u64 n)
|
||||
return n;
|
||||
}
|
||||
|
||||
may_be_unused fn u64 absolute_int(s64 n)
|
||||
fn u64 absolute_int(s64 n)
|
||||
{
|
||||
return n < 0 ? cast_to(u64, -n) : cast_to(u64, n);
|
||||
}
|
||||
@ -230,7 +239,7 @@ fn u64 is_decimal_digit(u8 ch)
|
||||
|
||||
fn u64 is_hex_digit(u8 ch)
|
||||
{
|
||||
return (is_decimal_digit(ch) | ((ch == 'a' | ch == 'A') | (ch == 'b' | ch == 'B'))) | (((ch == 'c' | ch == 'C') | (ch == 'd' | ch == 'D')) | ((ch == 'e' | ch == 'E') | (ch == 'f' | ch == 'F')));
|
||||
return (is_decimal_digit(ch) | (((ch == 'a') | (ch == 'A')) | ((ch == 'b') | (ch == 'B')))) | ((((ch == 'c') | (ch == 'C')) | ((ch == 'd') | (ch == 'D'))) | (((ch == 'e') | (ch == 'E')) | ((ch == 'f') | (ch == 'F'))));
|
||||
}
|
||||
|
||||
fn u64 is_identifier_start(u8 ch)
|
||||
@ -293,14 +302,28 @@ fn u8 is_power_of_two(u64 value)
|
||||
|
||||
fn u8 first_bit_set_32(u32 value)
|
||||
{
|
||||
#if _MSC_VER
|
||||
DWORD result_dword;
|
||||
u8 result_u8 = _BitScanForward(&result_dword, value);
|
||||
unused(result_u8);
|
||||
let_cast(u8, result, result_dword);
|
||||
#else
|
||||
let(result, (u8)__builtin_ffs((s32)value));
|
||||
#endif
|
||||
result -= result != 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
fn u64 first_bit_set_64(u64 value)
|
||||
{
|
||||
#if _MSC_VER
|
||||
DWORD result_dword;
|
||||
u8 result_u8 = _BitScanForward64(&result_dword, value);
|
||||
unused(result_u8);
|
||||
let_cast(u8, result, result_dword);
|
||||
#else
|
||||
let(result, (u8) __builtin_ffs((s64)value));
|
||||
#endif
|
||||
result -= result != 0;
|
||||
return result;
|
||||
}
|
||||
|
@ -1,5 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#if _WIN32
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
#define LINK_LIBC 1
|
||||
|
||||
#ifdef NDEBUG
|
||||
@ -20,6 +24,7 @@
|
||||
#endif
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#define BB_SAFETY BB_DEBUG
|
||||
|
||||
@ -32,6 +37,33 @@
|
||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
#define CLAMP(a, x, b) (((a)>(x))?(a):((b)<(x))?(b):(x))
|
||||
|
||||
#ifdef __TINYC__
|
||||
#define declare_vector_type #error
|
||||
#else
|
||||
#ifdef __clang__
|
||||
#define declare_vector_type(T, count, name) typedef T name __attribute__((ext_vector_type(count)))
|
||||
#else
|
||||
#define declare_vector_type(T, count, name) typedef T name __attribute__((vector_size(count)))
|
||||
#endif
|
||||
#endif
|
||||
#define array_length(arr) sizeof(arr) / sizeof((arr)[0])
|
||||
#define KB(n) ((n) * 1024)
|
||||
#define MB(n) ((n) * 1024 * 1024)
|
||||
#define GB(n) ((u64)(n) * 1024 * 1024 * 1024)
|
||||
#define TB(n) ((u64)(n) * 1024 * 1024 * 1024 * 1024)
|
||||
#define unused(x) (void)(x)
|
||||
#if _MSC_VER
|
||||
#define BB_NORETURN __declspec(noreturn)
|
||||
#define BB_COLD __declspec(noinline)
|
||||
#elif defined(__TINYC__)
|
||||
#define BB_NORETURN __attribute__((noreturn))
|
||||
#define BB_COLD __attribute__((cold))
|
||||
#else
|
||||
#define BB_NORETURN [[noreturn]]
|
||||
#define BB_COLD [[gnu::cold]]
|
||||
#endif
|
||||
#define TRUNCATE(Destination, source) (Destination)(source)
|
||||
|
||||
#if _MSC_VER
|
||||
#define ENUM_START(EnumName, T) typedef T EnumName; typedef enum EnumName ## Flags
|
||||
#define ENUM_END(EnumName) EnumName ## Flags
|
||||
@ -76,7 +108,10 @@ typedef __int128_t s128;
|
||||
typedef size_t usize;
|
||||
|
||||
#if !defined(__TINYC__) && !defined(_MSC_VER)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wpedantic"
|
||||
typedef _Float16 f16;
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
typedef float f32;
|
||||
typedef double f64;
|
||||
@ -84,8 +119,34 @@ typedef double f64;
|
||||
typedef u32 Hash32;
|
||||
typedef u64 Hash64;
|
||||
|
||||
#define Slice(T) Slice_ ## T
|
||||
#define SliceP(T) SliceP_ ## T
|
||||
#define declare_slice_ex(T, StructName) STRUCT(StructName) \
|
||||
{\
|
||||
T* pointer;\
|
||||
u64 length;\
|
||||
}
|
||||
|
||||
#define declare_slice(T) declare_slice_ex(T, Slice(T))
|
||||
#define declare_slice_p(T) declare_slice_ex(T*, SliceP(T))
|
||||
|
||||
declare_slice(u8);
|
||||
declare_slice(u16);
|
||||
declare_slice(u32);
|
||||
declare_slice(u64);
|
||||
declare_slice(s8);
|
||||
declare_slice(s16);
|
||||
declare_slice(s32);
|
||||
declare_slice(s64);
|
||||
|
||||
declare_slice_p(char);
|
||||
declare_slice_p(void);
|
||||
|
||||
typedef Slice(u8) String;
|
||||
declare_slice(String);
|
||||
|
||||
#if BB_DEBUG
|
||||
#define assert(x) if (unlikely(!(x))) { my_panic("Assert failed: \"" # x "\" at {cstr}:{u32}\n", __FILE__, __LINE__); }
|
||||
#define assert(x) (unlikely(!(x)) ? panic("Assert failed: \"" # x "\" at {cstr}:{u32}\n", __FILE__, __LINE__) : unused(0))
|
||||
#else
|
||||
#define assert(x) unused(likely(x))
|
||||
#endif
|
||||
@ -101,18 +162,15 @@ typedef u64 Hash64;
|
||||
#undef unreachable
|
||||
#endif
|
||||
#if BB_DEBUG
|
||||
#define unreachable() my_panic("Unreachable triggered\n", __FILE__, __LINE__)
|
||||
#define unreachable() panic("Unreachable triggered\n", __FILE__, __LINE__)
|
||||
#else
|
||||
#define unreachable() unreachable_raw()
|
||||
#endif
|
||||
#ifdef __TINYC__
|
||||
#define fix_unreachable() unreachable_raw()
|
||||
#else
|
||||
#define fix_unreachable()
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef static_assert
|
||||
#define static_assert(x) _Static_assert((x), "Static assert failed!")
|
||||
#endif
|
||||
#define alignof(x) _Alignof(x)
|
||||
#else
|
||||
#define restrict __restrict
|
||||
@ -135,38 +193,30 @@ typedef u64 Hash64;
|
||||
#define likely(x) expect(x, 1)
|
||||
#define unlikely(x) expect(x, 0)
|
||||
#define breakpoint() __builtin_debugtrap()
|
||||
#define failed_execution() my_panic("Failed execution at {cstr}:{u32}\n", __FILE__, __LINE__)
|
||||
#define todo() my_panic("TODO at {cstr}:{u32}\n", __FILE__, __LINE__)
|
||||
#define failed_execution() panic("Failed execution at {cstr}:{u32}\n", __FILE__, __LINE__)
|
||||
#define todo() panic("TODO at {cstr}:{u32}\n", __FILE__, __LINE__); fix_unreachable()
|
||||
|
||||
fn void print(const char* format, ...);
|
||||
fn u8 os_is_being_debugged();
|
||||
fn void os_exit(u32 exit_code);
|
||||
|
||||
#define my_panic(...) do \
|
||||
{\
|
||||
print(__VA_ARGS__);\
|
||||
if (os_is_being_debugged())\
|
||||
{\
|
||||
trap();\
|
||||
fix_unreachable();\
|
||||
}\
|
||||
else\
|
||||
{\
|
||||
os_exit(1);\
|
||||
fix_unreachable();\
|
||||
}\
|
||||
} while (0)
|
||||
BB_NORETURN BB_COLD fn void os_exit(u32 exit_code);
|
||||
|
||||
#if _MSC_VER
|
||||
#define trap() __fastfail(1)
|
||||
#elif __has_builtin(__builtin_trap)
|
||||
#define trap() __builtin_trap()
|
||||
#else
|
||||
fn void trap()
|
||||
extern BB_NORETURN BB_COLD void abort(void);
|
||||
fn BB_NORETURN BB_COLD void trap_ext()
|
||||
{
|
||||
#ifdef __x86_64__
|
||||
asm volatile("ud2");
|
||||
}
|
||||
#else
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
#define trap() (trap_ext(), __builtin_unreachable())
|
||||
#endif
|
||||
|
||||
#define panic(format, ...) (print(format, __VA_ARGS__), os_exit(1))
|
||||
|
||||
#define let_pointer_cast(PointerChildType, var_name, value) PointerChildType* var_name = (PointerChildType*)(value)
|
||||
#if defined(__TINYC__) || defined(_MSC_VER)
|
||||
@ -174,92 +224,17 @@ fn void trap()
|
||||
#else
|
||||
#define let(name, value) __auto_type name = (value)
|
||||
#endif
|
||||
#define let_cast_unchecked(name, T, value) T name = (T)(value)
|
||||
#define let_cast(T, name, value) T name = cast_to(T, value)
|
||||
#define let_va_arg(T, name, args) T name = va_arg(args, T)
|
||||
#define assign_cast(to, from) to = cast_to(typeof(to), from)
|
||||
#define let_va_arg(T, name, args) T name = va_arg(args, T)
|
||||
#define transmute(D, source) *(D*)&source
|
||||
|
||||
UNION(SafeInteger)
|
||||
{
|
||||
s64 signed_value;
|
||||
u64 unsigned_value;
|
||||
};
|
||||
|
||||
fn SafeInteger safe_integer_cast(SafeInteger value, u64 to_size, u64 to_signedness, u64 from_size, u64 from_signedness)
|
||||
{
|
||||
SafeInteger result;
|
||||
let(shifter, to_size * 8 - to_signedness);
|
||||
let(to_max, (u64)(1 << shifter) - 1);
|
||||
// A fix for 64-bit wrapping
|
||||
to_max = to_max == 0 ? UINT64_MAX : to_max;
|
||||
let(to_signed_min, -((s64)1 << shifter));
|
||||
if (from_signedness == to_signedness)
|
||||
{
|
||||
if (to_size < from_size)
|
||||
{
|
||||
switch (to_signedness)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
if (value.unsigned_value > to_max)
|
||||
{
|
||||
todo();
|
||||
}
|
||||
} break;
|
||||
case 1:
|
||||
{
|
||||
if (value.signed_value < to_signed_min)
|
||||
{
|
||||
todo();
|
||||
}
|
||||
if (value.signed_value > (s64)to_max)
|
||||
{
|
||||
todo();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (from_signedness)
|
||||
{
|
||||
if (value.signed_value < 0)
|
||||
{
|
||||
todo();
|
||||
}
|
||||
else if (value.unsigned_value > to_max)
|
||||
{
|
||||
todo();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (value.unsigned_value > to_max)
|
||||
{
|
||||
todo();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result = value;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#define type_is_signed(T) ((T)(-1) < 0)
|
||||
#if BB_SAFETY
|
||||
#define safe_integer_cast_function(To, value) (To) ((value) < 0 ? (safe_integer_cast((SafeInteger) { .signed_value = (value) }, sizeof(To), type_is_signed(To), sizeof(typeof(value)), type_is_signed(typeof(value)))).signed_value : (safe_integer_cast((SafeInteger) { .signed_value = (value) }, sizeof(To), type_is_signed(To), sizeof(typeof(value)), type_is_signed(typeof(value)))).unsigned_value)
|
||||
#endif
|
||||
|
||||
#if BB_SAFETY
|
||||
#define cast_to(T, value) safe_integer_cast_function(T, value)
|
||||
#define cast_to(T, value) (assert((typeof(value)) (T) (value) == (value) && ((value) > 0) == ((T) (value) > 0)), (T) (value))
|
||||
#else
|
||||
#define cast_to(T, value) (T)(value)
|
||||
#endif
|
||||
|
||||
|
||||
typedef enum Corner
|
||||
{
|
||||
CORNER_00,
|
||||
@ -288,33 +263,6 @@ typedef enum Axis2
|
||||
#define NO_EXCEPT
|
||||
#endif
|
||||
|
||||
|
||||
#define Slice(T) Slice_ ## T
|
||||
#define SliceP(T) SliceP_ ## T
|
||||
#define declare_slice_ex(T, StructName) STRUCT(StructName) \
|
||||
{\
|
||||
T* pointer;\
|
||||
u64 length;\
|
||||
}
|
||||
|
||||
#define declare_slice(T) declare_slice_ex(T, Slice(T))
|
||||
#define declare_slice_p(T) declare_slice_ex(T*, SliceP(T))
|
||||
|
||||
declare_slice(u8);
|
||||
declare_slice(u16);
|
||||
declare_slice(u32);
|
||||
declare_slice(u64);
|
||||
declare_slice(s8);
|
||||
declare_slice(s16);
|
||||
declare_slice(s32);
|
||||
declare_slice(s64);
|
||||
|
||||
declare_slice_p(char);
|
||||
declare_slice_p(void);
|
||||
|
||||
typedef Slice(u8) String;
|
||||
declare_slice(String);
|
||||
|
||||
#define NamedEnumMemberEnum(e, enum_member) e ## _ ## enum_member
|
||||
#define NamedEnumMemberString(e, enum_member) strlit(#enum_member)
|
||||
|
||||
@ -338,38 +286,6 @@ for (typeof(bits) _bits_ = (bits), it = (start); _bits_; _bits_ >>= 1, ++it) if
|
||||
#define FOREACH_SET(it, set) \
|
||||
FOR_N(_i, 0, ((set)->arr.capacity + 63) / 64) FOR_BIT(it, _i*64, (set)->arr.pointer[_i])
|
||||
|
||||
|
||||
#ifdef __TINYC__
|
||||
#define declare_vector_type #error
|
||||
#else
|
||||
#ifdef __clang__
|
||||
#define declare_vector_type(T, count, name) typedef T name __attribute__((ext_vector_type(count)))
|
||||
#else
|
||||
#define declare_vector_type(T, count, name) typedef T name __attribute__((vector_size(count)))
|
||||
#endif
|
||||
#endif
|
||||
#define array_length(arr) sizeof(arr) / sizeof((arr)[0])
|
||||
#define KB(n) ((n) * 1024)
|
||||
#define MB(n) ((n) * 1024 * 1024)
|
||||
#define GB(n) ((u64)(n) * 1024 * 1024 * 1024)
|
||||
#define TB(n) ((u64)(n) * 1024 * 1024 * 1024 * 1024)
|
||||
#define unused(x) (void)(x)
|
||||
#ifdef __clang__
|
||||
#define may_be_unused __attribute__((unused))
|
||||
#else
|
||||
#define may_be_unused
|
||||
#endif
|
||||
#if _MSC_VER
|
||||
#define BB_NORETURN __declspec(noreturn)
|
||||
#define BB_COLD __declspec(noinline)
|
||||
#elif defined(__TINYC__)
|
||||
#define BB_NORETURN __attribute__((noreturn))
|
||||
#define BB_COLD __attribute__((cold))
|
||||
#else
|
||||
#define BB_NORETURN [[noreturn]]
|
||||
#define BB_COLD [[gnu::cold]]
|
||||
#endif
|
||||
#define TRUNCATE(Destination, source) (Destination)(source)
|
||||
#define size_until_end(T, field_name) (sizeof(T) - offsetof(T, field_name))
|
||||
#define SWAP(a, b) \
|
||||
do {\
|
||||
@ -393,21 +309,20 @@ FOR_N(_i, 0, ((set)->arr.capacity + 63) / 64) FOR_BIT(it, _i*64, (set)->arr.poin
|
||||
|
||||
#define case_to_name(prefix, e) case prefix ## e: return strlit(#e)
|
||||
|
||||
const may_be_unused global_variable u8 brace_open = '{';
|
||||
const may_be_unused global_variable u8 brace_close = '}';
|
||||
global_variable const u8 brace_open = '{';
|
||||
global_variable const u8 brace_close = '}';
|
||||
|
||||
const may_be_unused global_variable u8 parenthesis_open = '(';
|
||||
const may_be_unused global_variable u8 parenthesis_close = ')';
|
||||
global_variable const u8 parenthesis_open = '(';
|
||||
global_variable const u8 parenthesis_close = ')';
|
||||
|
||||
const may_be_unused global_variable u8 bracket_open = '[';
|
||||
const may_be_unused global_variable u8 bracket_close = ']';
|
||||
global_variable const u8 bracket_open = '[';
|
||||
global_variable const u8 bracket_close = ']';
|
||||
|
||||
#define s_get(s, i) (s).pointer[i]
|
||||
#define s_get_pointer(s, i) &((s).pointer[i])
|
||||
#define s_get_slice(T, s, start, end) (Slice(T)){ .pointer = ((s).pointer) + (start), .length = (end) - (start) }
|
||||
#define s_equal(a, b) ((a).length == (b).length && memcmp((a).pointer, (b).pointer, sizeof(*((a).pointer)) * (a).length) == 0)
|
||||
|
||||
|
||||
fn u64 align_forward(u64 value, u64 alignment);
|
||||
fn u64 align_backward(u64 value, u64 alignment);
|
||||
fn u8 log2_alignment(u64 alignment);
|
||||
@ -415,25 +330,6 @@ fn u8 is_power_of_two(u64 value);
|
||||
fn u8 first_bit_set_32(u32 value);
|
||||
fn u64 first_bit_set_64(u64 value);
|
||||
|
||||
fn u8 cast_u32_to_u8(u32 source, const char* name, int line);
|
||||
fn u16 cast_u32_to_u16(u32 source, const char* name, int line);
|
||||
fn s16 cast_u32_to_s16(u32 source, const char* name, int line);
|
||||
fn s32 cast_u32_to_s32(u32 source, const char* name, int line);
|
||||
fn u8 cast_u64_to_u8(u64 source, const char* name, int line);
|
||||
fn u16 cast_u64_to_u16(u64 source, const char* name, int line);
|
||||
fn u32 cast_u64_to_u32(u64 source, const char* name, int line);
|
||||
fn s32 cast_u64_to_s32(u64 source, const char* name, int line);
|
||||
fn s64 cast_u64_to_s64(u64 source, const char* name, int line);
|
||||
fn u8 cast_s32_to_u8(s32 source, const char* name, int line);
|
||||
fn u16 cast_s32_to_u16(s32 source, const char* name, int line);
|
||||
fn u32 cast_s32_to_u32(s32 source, const char* name, int line);
|
||||
fn u64 cast_s32_to_u64(s32 source, const char* name, int line);
|
||||
fn s16 cast_s32_to_s16(s32 source, const char* name, int line);
|
||||
fn u16 cast_s64_to_u16(s64 source, const char* name, int line);
|
||||
fn u32 cast_s64_to_u32(s64 source, const char* name, int line);
|
||||
fn u64 cast_s64_to_u64(s64 source, const char* name, int line);
|
||||
fn s32 cast_s64_to_s32(s64 source, const char* name, int line);
|
||||
|
||||
fn u32 format_decimal(String buffer, u64 decimal);
|
||||
fn u32 format_hexadecimal(String buffer, u64 hexadecimal);
|
||||
fn u64 format_float(String buffer, f64 value_double);
|
||||
|
@ -73,7 +73,7 @@ STRUCT(SmallIntResult)
|
||||
{
|
||||
u64 mantissa;
|
||||
s32 exponent;
|
||||
u8 is_small_int;
|
||||
u32 is_small_int:1;
|
||||
};
|
||||
|
||||
#define double_mantissa_bits 52
|
||||
@ -301,7 +301,7 @@ fn u64 mul_shift_64(const u64 m, const u64* const mul, const s32 j)
|
||||
{
|
||||
const u128 b0 = u128_u64_mul(u128_from_u64(m), mul[0]);
|
||||
const u128 b2 = u128_u64_mul(u128_from_u64(m), mul[1]);
|
||||
return u64_from_u128(u128_shift_right(u128_u64_add(b2, u128_shift_right_by_64(b0)), j - 64));
|
||||
return u64_from_u128(u128_shift_right(u128_u64_add(b2, u128_shift_right_by_64(b0)), cast_to(u16, j - 64)));
|
||||
// return (u64) (((b0 >> 64) + b2) >> (j - 64));
|
||||
}
|
||||
|
||||
@ -555,9 +555,10 @@ STRUCT(Double)
|
||||
{
|
||||
u64 mantissa;
|
||||
s32 exponent;
|
||||
u32 reserved;
|
||||
};
|
||||
|
||||
may_be_unused fn Double double_transform(u64 ieee_mantissa, u32 ieee_exponent)
|
||||
fn Double double_transform(u64 ieee_mantissa, u32 ieee_exponent)
|
||||
{
|
||||
u64 m2;
|
||||
s32 e2;
|
||||
@ -651,7 +652,7 @@ may_be_unused fn Double double_transform(u64 ieee_mantissa, u32 ieee_exponent)
|
||||
}
|
||||
|
||||
u32 vm_mod10 = ((u32)vm) - 10 * ((u32)vm_div10);
|
||||
u32 vr_div10 = div10(vr);
|
||||
u64 vr_div10 = div10(vr);
|
||||
u32 vr_mod10 = ((u32)vr) - 10 * ((u32)vr_div10);
|
||||
vm_is_trailing_zeroes &= vm_mod10 == 0;
|
||||
vr_is_trailing_zeroes &= last_removed_digit == 0;
|
||||
@ -740,7 +741,7 @@ may_be_unused fn Double double_transform(u64 ieee_mantissa, u32 ieee_exponent)
|
||||
};
|
||||
}
|
||||
|
||||
may_be_unused fn SmallIntResult small_int(u64 ieee_mantissa, u32 ieee_exponent)
|
||||
fn SmallIntResult small_int(u64 ieee_mantissa, u32 ieee_exponent)
|
||||
{
|
||||
SmallIntResult result = {};
|
||||
let(m2, ((u64)1 << double_mantissa_bits) | ieee_mantissa);
|
||||
@ -798,10 +799,11 @@ fn u32 decimalLength17(const u64 v) {
|
||||
// A floating decimal representing m * 10^e.
|
||||
STRUCT(floating_decimal_64)
|
||||
{
|
||||
uint64_t mantissa;
|
||||
u64 mantissa;
|
||||
// Decimal exponent's range is -324 to 308
|
||||
// inclusive, and can fit in a short if needed.
|
||||
int32_t exponent;
|
||||
s32 exponent;
|
||||
u32 reserved;
|
||||
};
|
||||
|
||||
fn u8* digits2(u64 value)
|
||||
@ -1065,6 +1067,14 @@ fn u64 format_float(String buffer, f64 value_double)
|
||||
return buffer_i;
|
||||
}
|
||||
|
||||
typedef enum IntegerFormat
|
||||
{
|
||||
INTEGER_FORMAT_HEXADECIMAL,
|
||||
INTEGER_FORMAT_DECIMAL,
|
||||
INTEGER_FORMAT_OCTAL,
|
||||
INTEGER_FORMAT_BINARY,
|
||||
} IntegerFormat;
|
||||
|
||||
fn String format_string_va(String buffer, const char* format, va_list args)
|
||||
{
|
||||
u8* it = (u8*)format;
|
||||
@ -1171,15 +1181,7 @@ fn String format_string_va(String buffer, const char* format, va_list args)
|
||||
u8* bit_count_end = it;
|
||||
u64 bit_count = parse_decimal(slice_from_pointer_range(u8, (u8*)bit_count_start, (u8*)bit_count_end));
|
||||
|
||||
typedef enum IntegerFormat
|
||||
{
|
||||
INTEGER_FORMAT_HEXADECIMAL,
|
||||
INTEGER_FORMAT_DECIMAL,
|
||||
INTEGER_FORMAT_OCTAL,
|
||||
INTEGER_FORMAT_BINARY,
|
||||
} IntegerFormat;
|
||||
|
||||
IntegerFormat format = INTEGER_FORMAT_DECIMAL;
|
||||
IntegerFormat integer_format = INTEGER_FORMAT_DECIMAL;
|
||||
|
||||
if (*it == ':')
|
||||
{
|
||||
@ -1187,16 +1189,16 @@ fn String format_string_va(String buffer, const char* format, va_list args)
|
||||
switch (*it)
|
||||
{
|
||||
case 'x':
|
||||
format = INTEGER_FORMAT_HEXADECIMAL;
|
||||
integer_format = INTEGER_FORMAT_HEXADECIMAL;
|
||||
break;
|
||||
case 'd':
|
||||
format = INTEGER_FORMAT_DECIMAL;
|
||||
integer_format = INTEGER_FORMAT_DECIMAL;
|
||||
break;
|
||||
case 'o':
|
||||
format = INTEGER_FORMAT_OCTAL;
|
||||
integer_format = INTEGER_FORMAT_OCTAL;
|
||||
break;
|
||||
case 'b':
|
||||
format = INTEGER_FORMAT_BINARY;
|
||||
integer_format = INTEGER_FORMAT_BINARY;
|
||||
break;
|
||||
default:
|
||||
unreachable();
|
||||
@ -1222,7 +1224,7 @@ fn String format_string_va(String buffer, const char* format, va_list args)
|
||||
|
||||
String buffer_slice = s_get_slice(u8, buffer, buffer_i, buffer.length);
|
||||
|
||||
switch (format)
|
||||
switch (integer_format)
|
||||
{
|
||||
case INTEGER_FORMAT_HEXADECIMAL:
|
||||
{
|
||||
@ -1287,7 +1289,7 @@ fn String format_string_va(String buffer, const char* format, va_list args)
|
||||
INTEGER_FORMAT_BINARY,
|
||||
} IntegerFormat;
|
||||
|
||||
IntegerFormat format = INTEGER_FORMAT_DECIMAL;
|
||||
IntegerFormat integer_format = INTEGER_FORMAT_DECIMAL;
|
||||
|
||||
if (*it == ':')
|
||||
{
|
||||
@ -1295,16 +1297,16 @@ fn String format_string_va(String buffer, const char* format, va_list args)
|
||||
switch (*it)
|
||||
{
|
||||
case 'x':
|
||||
format = INTEGER_FORMAT_HEXADECIMAL;
|
||||
integer_format = INTEGER_FORMAT_HEXADECIMAL;
|
||||
break;
|
||||
case 'd':
|
||||
format = INTEGER_FORMAT_DECIMAL;
|
||||
integer_format = INTEGER_FORMAT_DECIMAL;
|
||||
break;
|
||||
case 'o':
|
||||
format = INTEGER_FORMAT_OCTAL;
|
||||
integer_format = INTEGER_FORMAT_OCTAL;
|
||||
break;
|
||||
case 'b':
|
||||
format = INTEGER_FORMAT_BINARY;
|
||||
integer_format = INTEGER_FORMAT_BINARY;
|
||||
break;
|
||||
default:
|
||||
unreachable();
|
||||
@ -1330,7 +1332,7 @@ fn String format_string_va(String buffer, const char* format, va_list args)
|
||||
|
||||
let(buffer_slice, s_get_slice(u8, buffer, buffer_i, buffer.length));
|
||||
|
||||
switch (format)
|
||||
switch (integer_format)
|
||||
{
|
||||
case INTEGER_FORMAT_HEXADECIMAL:
|
||||
{
|
||||
|
@ -54,7 +54,7 @@ global_variable u8 md5_padding[] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
|
||||
may_be_unused fn MD5Context md5_init()
|
||||
fn MD5Context md5_init()
|
||||
{
|
||||
return (MD5Context) {
|
||||
.buffer = { MD5_A, MD5_B, MD5_C, MD5_D },
|
||||
@ -66,7 +66,7 @@ fn u32 rotate_left_u32(u32 x, u32 n)
|
||||
return (x << n) | (x >> (32 - n));
|
||||
}
|
||||
|
||||
may_be_unused fn void md5_step(u32* buffer, u32* input)
|
||||
fn void md5_step(u32* buffer, u32* input)
|
||||
{
|
||||
u32 aa = buffer[0];
|
||||
u32 bb = buffer[1];
|
||||
@ -114,7 +114,7 @@ may_be_unused fn void md5_step(u32* buffer, u32* input)
|
||||
buffer[3] += dd;
|
||||
}
|
||||
|
||||
may_be_unused fn void md5_update(MD5Context* context, String input_argument)
|
||||
fn void md5_update(MD5Context* context, String input_argument)
|
||||
{
|
||||
u32 input_local[16];
|
||||
auto offset = context->size % 64;
|
||||
@ -139,7 +139,7 @@ may_be_unused fn void md5_update(MD5Context* context, String input_argument)
|
||||
}
|
||||
}
|
||||
|
||||
may_be_unused fn MD5Result md5_end(MD5Context* context)
|
||||
fn MD5Result md5_end(MD5Context* context)
|
||||
{
|
||||
u32 input[16];
|
||||
auto offset = context->size % 64;
|
||||
|
@ -123,7 +123,7 @@ fn String path_base(String string)
|
||||
#if _WIN32
|
||||
if (!result.pointer)
|
||||
{
|
||||
let(index, string_last_ch(string, '\\'));
|
||||
index = string_last_ch(string, '\\');
|
||||
if (index != STRING_NO_MATCH)
|
||||
{
|
||||
result = s_get_slice(u8, string, index + 1, string.length);
|
||||
@ -148,21 +148,21 @@ fn String path_no_extension(String string)
|
||||
|
||||
#if LINK_LIBC == 0
|
||||
#ifdef __linux__
|
||||
may_be_unused fn forceinline long syscall0(long n)
|
||||
fn forceinline long syscall0(long n)
|
||||
{
|
||||
long ret;
|
||||
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n) : "rcx", "r11", "memory");
|
||||
return ret;
|
||||
}
|
||||
|
||||
may_be_unused fn forceinline long syscall1(long n, long a1)
|
||||
fn forceinline long syscall1(long n, long a1)
|
||||
{
|
||||
long ret;
|
||||
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1) : "rcx", "r11", "memory");
|
||||
return ret;
|
||||
}
|
||||
|
||||
may_be_unused fn forceinline long syscall2(long n, long a1, long a2)
|
||||
fn forceinline long syscall2(long n, long a1, long a2)
|
||||
{
|
||||
long ret;
|
||||
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2)
|
||||
@ -170,7 +170,7 @@ may_be_unused fn forceinline long syscall2(long n, long a1, long a2)
|
||||
return ret;
|
||||
}
|
||||
|
||||
may_be_unused fn forceinline long syscall3(long n, long a1, long a2, long a3)
|
||||
fn forceinline long syscall3(long n, long a1, long a2, long a3)
|
||||
{
|
||||
long ret;
|
||||
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2),
|
||||
@ -178,7 +178,7 @@ may_be_unused fn forceinline long syscall3(long n, long a1, long a2, long a3)
|
||||
return ret;
|
||||
}
|
||||
|
||||
may_be_unused fn forceinline long syscall4(long n, long a1, long a2, long a3, long a4)
|
||||
fn forceinline long syscall4(long n, long a1, long a2, long a3, long a4)
|
||||
{
|
||||
long ret;
|
||||
register long r10 __asm__("r10") = a4;
|
||||
@ -187,7 +187,7 @@ may_be_unused fn forceinline long syscall4(long n, long a1, long a2, long a3, lo
|
||||
return ret;
|
||||
}
|
||||
|
||||
may_be_unused fn forceinline long syscall5(long n, long a1, long a2, long a3, long a4, long a5)
|
||||
fn forceinline long syscall5(long n, long a1, long a2, long a3, long a4, long a5)
|
||||
{
|
||||
long ret;
|
||||
register long r10 __asm__("r10") = a4;
|
||||
@ -197,7 +197,7 @@ may_be_unused fn forceinline long syscall5(long n, long a1, long a2, long a3, lo
|
||||
return ret;
|
||||
}
|
||||
|
||||
may_be_unused fn forceinline long syscall6(long n, long a1, long a2, long a3, long a4, long a5, long a6)
|
||||
fn forceinline long syscall6(long n, long a1, long a2, long a3, long a4, long a5, long a6)
|
||||
{
|
||||
long ret;
|
||||
register long r10 __asm__("r10") = a4;
|
||||
@ -582,7 +582,7 @@ enum SyscallX86_64 : u64 {
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
may_be_unused fn void* posix_mmap(void* address, size_t length, int protection_flags, int map_flags, int fd, signed long offset)
|
||||
fn void* posix_mmap(void* address, size_t length, int protection_flags, int map_flags, int fd, signed long offset)
|
||||
{
|
||||
#if LINK_LIBC
|
||||
return mmap(address, length, protection_flags, map_flags, fd, offset);
|
||||
@ -595,7 +595,7 @@ may_be_unused fn void* posix_mmap(void* address, size_t length, int protection_f
|
||||
#endif
|
||||
}
|
||||
|
||||
may_be_unused fn int syscall_mprotect(void *address, size_t length, int protection_flags)
|
||||
fn int syscall_mprotect(void *address, size_t length, int protection_flags)
|
||||
{
|
||||
#if LINK_LIBC
|
||||
return mprotect(address, length, protection_flags);
|
||||
@ -608,7 +608,7 @@ may_be_unused fn int syscall_mprotect(void *address, size_t length, int protecti
|
||||
#endif
|
||||
}
|
||||
|
||||
may_be_unused fn int syscall_open(const char *file_path, int flags, int mode)
|
||||
fn int syscall_open(const char *file_path, int flags, int mode)
|
||||
{
|
||||
#if LINK_LIBC
|
||||
return open(file_path, flags, mode);
|
||||
@ -621,7 +621,7 @@ may_be_unused fn int syscall_open(const char *file_path, int flags, int mode)
|
||||
#endif
|
||||
}
|
||||
|
||||
may_be_unused fn int syscall_close(int fd)
|
||||
fn int syscall_close(int fd)
|
||||
{
|
||||
#if LINK_LIBC
|
||||
return close(fd);
|
||||
@ -647,7 +647,7 @@ fn int syscall_fstat(int fd, struct stat *buffer)
|
||||
#endif
|
||||
}
|
||||
|
||||
may_be_unused fn ssize_t syscall_read(int fd, void* buffer, size_t bytes)
|
||||
fn ssize_t syscall_read(int fd, void* buffer, size_t bytes)
|
||||
{
|
||||
#if LINK_LIBC
|
||||
return read(fd, buffer, bytes);
|
||||
@ -660,7 +660,7 @@ may_be_unused fn ssize_t syscall_read(int fd, void* buffer, size_t bytes)
|
||||
#endif
|
||||
}
|
||||
|
||||
may_be_unused fn ssize_t syscall_write(int fd, const void *buffer, size_t bytes)
|
||||
fn ssize_t syscall_write(int fd, const void *buffer, size_t bytes)
|
||||
{
|
||||
#if LINK_LIBC
|
||||
return write(fd, buffer, bytes);
|
||||
@ -673,7 +673,7 @@ may_be_unused fn ssize_t syscall_write(int fd, const void *buffer, size_t bytes)
|
||||
#endif
|
||||
}
|
||||
|
||||
may_be_unused fn int syscall_mkdir(String path, u32 mode)
|
||||
fn int syscall_mkdir(String path, u32 mode)
|
||||
{
|
||||
assert(path.pointer[path.length] == 0);
|
||||
#if LINK_LIBC
|
||||
@ -683,7 +683,7 @@ may_be_unused fn int syscall_mkdir(String path, u32 mode)
|
||||
#endif
|
||||
}
|
||||
|
||||
may_be_unused fn int syscall_rmdir(String path)
|
||||
fn int syscall_rmdir(String path)
|
||||
{
|
||||
assert(path.pointer[path.length] == 0);
|
||||
#if LINK_LIBC
|
||||
@ -693,7 +693,7 @@ may_be_unused fn int syscall_rmdir(String path)
|
||||
#endif
|
||||
}
|
||||
|
||||
may_be_unused fn int syscall_unlink(String path)
|
||||
fn int syscall_unlink(String path)
|
||||
{
|
||||
assert(path.pointer[path.length] == 0);
|
||||
#if LINK_LIBC
|
||||
@ -703,7 +703,7 @@ may_be_unused fn int syscall_unlink(String path)
|
||||
#endif
|
||||
}
|
||||
|
||||
may_be_unused fn pid_t syscall_fork()
|
||||
fn pid_t syscall_fork()
|
||||
{
|
||||
#if LINK_LIBC
|
||||
return fork();
|
||||
@ -713,7 +713,7 @@ may_be_unused fn pid_t syscall_fork()
|
||||
|
||||
}
|
||||
|
||||
may_be_unused fn signed long syscall_execve(const char* path, char *const argv[], char *const envp[])
|
||||
fn signed long syscall_execve(const char* path, char *const argv[], char *const envp[])
|
||||
{
|
||||
#if LINK_LIBC
|
||||
return execve(path, argv, envp);
|
||||
@ -722,7 +722,7 @@ may_be_unused fn signed long syscall_execve(const char* path, char *const argv[]
|
||||
#endif
|
||||
}
|
||||
|
||||
may_be_unused fn pid_t syscall_waitpid(pid_t pid, int* status, int options)
|
||||
fn pid_t syscall_waitpid(pid_t pid, int* status, int options)
|
||||
{
|
||||
#if LINK_LIBC
|
||||
return waitpid(pid, status, options);
|
||||
@ -731,7 +731,7 @@ may_be_unused fn pid_t syscall_waitpid(pid_t pid, int* status, int options)
|
||||
#endif
|
||||
}
|
||||
|
||||
may_be_unused fn int syscall_gettimeofday(struct timeval* tv, struct timezone* tz)
|
||||
fn int syscall_gettimeofday(struct timeval* tv, struct timezone* tz)
|
||||
{
|
||||
#if LINK_LIBC
|
||||
return gettimeofday(tv, tz);
|
||||
@ -740,7 +740,7 @@ may_be_unused fn int syscall_gettimeofday(struct timeval* tv, struct timezone* t
|
||||
#endif
|
||||
}
|
||||
|
||||
may_be_unused BB_NORETURN BB_COLD fn void syscall_exit(int status)
|
||||
BB_NORETURN BB_COLD fn void syscall_exit(int status)
|
||||
{
|
||||
#if LINK_LIBC
|
||||
_exit(status);
|
||||
@ -755,12 +755,12 @@ may_be_unused BB_NORETURN BB_COLD fn void syscall_exit(int status)
|
||||
}
|
||||
#endif
|
||||
|
||||
may_be_unused fn u64 os_timer_freq()
|
||||
fn u64 os_timer_freq()
|
||||
{
|
||||
return 1000 * 1000;
|
||||
}
|
||||
|
||||
may_be_unused fn u64 os_timer_get()
|
||||
fn u64 os_timer_get()
|
||||
{
|
||||
#if _WIN32
|
||||
LARGE_INTEGER large_integer;
|
||||
@ -787,6 +787,8 @@ fn FileDescriptor os_file_open(String path, OSFileOpenFlags flags, OSFilePermiss
|
||||
{
|
||||
assert(path.pointer[path.length] == 0);
|
||||
#if _WIN32
|
||||
unused(permissions);
|
||||
|
||||
DWORD dwDesiredAccess = 0;
|
||||
dwDesiredAccess |= flags.read * GENERIC_READ;
|
||||
dwDesiredAccess |= flags.write * GENERIC_WRITE;
|
||||
@ -854,7 +856,7 @@ fn void os_file_write(FileDescriptor fd, String content)
|
||||
#endif
|
||||
}
|
||||
|
||||
may_be_unused fn u64 os_file_read(FileDescriptor fd, String buffer, u64 byte_count)
|
||||
fn u64 os_file_read(FileDescriptor fd, String buffer, u64 byte_count)
|
||||
{
|
||||
assert(byte_count);
|
||||
assert(byte_count <= buffer.length);
|
||||
@ -966,22 +968,24 @@ BB_NORETURN BB_COLD fn void os_exit(u32 exit_code)
|
||||
exit(exit_code);
|
||||
}
|
||||
|
||||
fn void vprint(const char* format, va_list args)
|
||||
{
|
||||
u8 stack_buffer[16*1024];
|
||||
String buffer = { .pointer = stack_buffer, .length = array_length(stack_buffer) };
|
||||
String final_string = format_string_va(buffer, format, args);
|
||||
os_file_write(os_stdout_get(), final_string);
|
||||
}
|
||||
|
||||
fn void print(const char* format, ...)
|
||||
{
|
||||
#ifndef SILENT
|
||||
u8 stack_buffer[16*1024];
|
||||
String buffer = { .pointer = stack_buffer, .length = array_length(stack_buffer) };
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
String final_string = format_string_va(buffer, format, args);
|
||||
va_end(args);
|
||||
|
||||
os_file_write(os_stdout_get(), final_string);
|
||||
#endif
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vprint(format, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
static_assert(sizeof(Arena) == 64);
|
||||
const global_variable u64 minimum_position = sizeof(Arena);
|
||||
global_variable const u64 minimum_position = sizeof(Arena);
|
||||
|
||||
fn Arena* arena_initialize(u64 reserved_size, u64 granularity, u64 initial_size)
|
||||
{
|
||||
@ -1157,7 +1161,7 @@ fn void run_command(Arena* arena, CStringSlice arguments, char* envp[], RunComma
|
||||
{
|
||||
let(len, strlen(argument));
|
||||
memcpy(&bytes[byte_i], argument, len);
|
||||
byte_i += len;
|
||||
byte_i += cast_to(u32, len);
|
||||
bytes[byte_i] = ' ';
|
||||
byte_i += 1;
|
||||
}
|
||||
@ -1219,6 +1223,7 @@ fn void run_command(Arena* arena, CStringSlice arguments, char* envp[], RunComma
|
||||
0,
|
||||
NULL
|
||||
);
|
||||
unused(bufSize);
|
||||
print("CreateProcessA call failed: {cstr}\n", lpMsgBuf);
|
||||
todo();
|
||||
}
|
||||
@ -1242,8 +1247,9 @@ fn void run_command(Arena* arena, CStringSlice arguments, char* envp[], RunComma
|
||||
// close(pipes[0]);
|
||||
// fcntl(pipes[1], F_SETFD, FD_CLOEXEC);
|
||||
let(result, syscall_execve(arguments.pointer[0], arguments.pointer, envp));
|
||||
unused(result);
|
||||
#if LINK_LIBC
|
||||
my_panic("Execve failed! Error: {cstr}\n", strerror(errno));
|
||||
panic("Execve failed! Error: {cstr}\n", strerror(errno));
|
||||
#else
|
||||
todo();
|
||||
#endif
|
||||
@ -1322,7 +1328,7 @@ fn u8 os_is_being_debugged()
|
||||
{
|
||||
u8 result = 0;
|
||||
#if _WIN32
|
||||
result = IsDebuggerPresent();
|
||||
result = IsDebuggerPresent() != 0;
|
||||
#else
|
||||
#ifdef __APPLE__
|
||||
let(request, PT_TRACE_ME);
|
||||
@ -1366,6 +1372,7 @@ fn String os_get_environment_variable(const char* name)
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
fn u64 os_readlink(String path, String buffer)
|
||||
{
|
||||
u64 result = 0;
|
||||
@ -1396,7 +1403,6 @@ fn String os_readlink_allocate(Arena* arena, String path)
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
fn String os_realpath(String path, String buffer)
|
||||
{
|
||||
String result = {};
|
||||
@ -1434,7 +1440,7 @@ fn OSLibrary os_library_load(const char* library_name)
|
||||
|
||||
fn OSSymbol os_symbol_load(OSLibrary library, const char* symbol_name)
|
||||
{
|
||||
OSSymbol symbol = GetProcAddress(library.handle, symbol_name);
|
||||
OSSymbol symbol = (OSSymbol)GetProcAddress(library.handle, symbol_name);
|
||||
return symbol;
|
||||
}
|
||||
#else
|
||||
|
@ -1,7 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
@ -85,20 +83,21 @@ STRUCT(FileWriteOptions)
|
||||
{
|
||||
String path;
|
||||
String content;
|
||||
u8 executable;
|
||||
u64 executable:1;
|
||||
};
|
||||
|
||||
#if __APPLE__
|
||||
#define MY_PAGE_SIZE KB(16)
|
||||
#else
|
||||
#ifndef __APPLE__
|
||||
#define MY_PAGE_SIZE KB(4)
|
||||
#else
|
||||
#define MY_PAGE_SIZE KB(16)
|
||||
#endif
|
||||
const global_variable u64 page_size = MY_PAGE_SIZE;
|
||||
global_variable const u64 page_size = MY_PAGE_SIZE;
|
||||
|
||||
global_variable u64 minimum_granularity = MY_PAGE_SIZE;
|
||||
// global_variable u64 middle_granularity = MB(2);
|
||||
global_variable u64 default_size = GB(4);
|
||||
|
||||
fn void vprint(const char* format, va_list args);
|
||||
fn void print(const char* format, ...);
|
||||
fn void run_command(Arena* arena, CStringSlice arguments, char* envp[], RunCommandOptions options);
|
||||
fn String file_read(Arena* arena, String path);
|
||||
|
@ -124,6 +124,9 @@ u64 string_first_occurrence(String string, String substring)
|
||||
|
||||
fn u64 string_last_occurrence(String string, String substring)
|
||||
{
|
||||
unused(string);
|
||||
unused(substring);
|
||||
|
||||
todo();
|
||||
}
|
||||
|
||||
|
@ -263,7 +263,7 @@ BB_NORETURN BB_COLD fn void wrong_vulkan_result(VkResult result, String call_str
|
||||
unused(line);
|
||||
|
||||
String result_name = vulkan_result_to_string(result);
|
||||
my_panic("Wrong Vulkan result {s} at \"{s}\" {s}:{u32}\n", result_name, call_string, file, line);
|
||||
panic("Wrong Vulkan result {s} at \"{s}\" {s}:{u32}\n", result_name, call_string, file, line);
|
||||
}
|
||||
|
||||
fn void buffer_copy_to_local_command(VkCommandBuffer command_buffer, Slice(LocalBufferCopy) copies)
|
||||
|
11
build.bat
11
build.bat
@ -9,9 +9,18 @@ if not defined BB_BUILD_TYPE (
|
||||
set BB_BUILD_TYPE=debug
|
||||
)
|
||||
|
||||
if not defined BB_ERROR_ON_WARNINGS (
|
||||
set BB_ERROR_ON_WARNINGS=%BB_CI%
|
||||
)
|
||||
|
||||
if not defined BB_ERROR_LIMIT (
|
||||
set /a BB_ERROR_LIMIT=1-%BB_CI%
|
||||
)
|
||||
|
||||
set BUILD_DIR=cache
|
||||
mkdir %BUILD_DIR% > NUL 2>&1
|
||||
set BUILD_OUT=cache\build.exe
|
||||
set BB_ERROR_ON_WARNINGS=%BB_CI%
|
||||
|
||||
if "%BB_CI%" == "0" (
|
||||
%VK_SDK_PATH%\Bin\glslangValidator.exe -V bootstrap\std\shaders\rect.vert -o cache\rect.vert.spv --quiet || exit /b 1
|
||||
@ -19,5 +28,5 @@ if "%BB_CI%" == "0" (
|
||||
)
|
||||
|
||||
|
||||
cl /Zi /Y- /Gm- /std:clatest /diagnostics:caret -FC /nologo build.c /Fd%BUILD_DIR%\ /Fo%BUILD_DIR%\ /Fe%BUILD_OUT% -Ibootstrap -DBB_TIMETRACE=0 -DBB_BUILD_TYPE=\"%BB_BUILD_TYPE%\" -DBB_CI=%BB_CI% /link /INCREMENTAL:NO || exit /b 1
|
||||
cl /Zi /Y- /Gm- /std:clatest /diagnostics:caret -FC /nologo build.c /Fd%BUILD_DIR%\ /Fo%BUILD_DIR%\ /Fe%BUILD_OUT% -Ibootstrap -DBB_TIMETRACE=0 -DBB_BUILD_TYPE=\"%BB_BUILD_TYPE%\" -DBB_CI=%BB_CI% -DBB_ERROR_ON_WARNINGS=%BB_ERROR_ON_WARNINGS% -DBB_ERROR_LIMIT=%BB_ERROR_LIMIT% /link /INCREMENTAL:NO || exit /b 1
|
||||
%BUILD_OUT%
|
||||
|
63
build.c
63
build.c
@ -97,7 +97,7 @@ global_variable char* compiler_switches[COMPILER_ARGUMENT_STYLE_COUNT][COMPILER_
|
||||
},
|
||||
};
|
||||
|
||||
fn String file_find_in_path(Arena* arena, String file, String path_env)
|
||||
fn String file_find_in_path(Arena* arena, String file, String path_env, String extension)
|
||||
{
|
||||
String result = {};
|
||||
assert(path_env.pointer);
|
||||
@ -130,11 +130,11 @@ fn String file_find_in_path(Arena* arena, String file, String path_env)
|
||||
memcpy(&buffer[i], file.pointer, file.length);
|
||||
i += file.length;
|
||||
|
||||
#if _WIN32
|
||||
String exe_extension = strlit(".exe");
|
||||
memcpy(&buffer[i], exe_extension.pointer, exe_extension.length);
|
||||
i += exe_extension.length;
|
||||
#endif
|
||||
if (extension.length)
|
||||
{
|
||||
memcpy(&buffer[i], extension.pointer, extension.length);
|
||||
i += extension.length;
|
||||
}
|
||||
|
||||
buffer[i] = 0;
|
||||
i += 1;
|
||||
@ -239,6 +239,10 @@ fn String get_c_compiler_path(Arena* arena)
|
||||
String cc_path = {};
|
||||
String cc_env = os_get_environment_variable("CC");
|
||||
String path_env = os_get_environment_variable("PATH");
|
||||
String extension = {};
|
||||
#if _WIN32
|
||||
extension = strlit(".exe");
|
||||
#endif
|
||||
if (cc_env.pointer)
|
||||
{
|
||||
cc_path = cc_env;
|
||||
@ -246,14 +250,14 @@ fn String get_c_compiler_path(Arena* arena)
|
||||
#ifndef _WIN32
|
||||
else
|
||||
{
|
||||
cc_path = file_find_in_path(arena, strlit("cc"), path_env);
|
||||
cc_path = file_find_in_path(arena, strlit("cc"), path_env, extension);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!cc_path.pointer)
|
||||
{
|
||||
#if _WIN32
|
||||
cc_path = strlit("cl.exe");
|
||||
cc_path = strlit("cl");
|
||||
#elif defined(__APPLE__)
|
||||
cc_path = strlit("clang");
|
||||
#elif defined(__linux__)
|
||||
@ -269,7 +273,7 @@ fn String get_c_compiler_path(Arena* arena)
|
||||
#endif
|
||||
if (no_path_sep)
|
||||
{
|
||||
cc_path = file_find_in_path(arena, cc_path, path_env);
|
||||
cc_path = file_find_in_path(arena, cc_path, path_env, extension);
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
@ -296,7 +300,7 @@ fn String get_c_compiler_path(Arena* arena)
|
||||
|
||||
if (preferred_c_compiler != C_COMPILER_COUNT && c_compiler_is_supported_by_os(preferred_c_compiler))
|
||||
{
|
||||
String find_result = file_find_in_path(arena, c_compiler_to_string(preferred_c_compiler), path_env);
|
||||
String find_result = file_find_in_path(arena, c_compiler_to_string(preferred_c_compiler), path_env, extension);
|
||||
if (find_result.pointer)
|
||||
{
|
||||
cc_path = find_result;
|
||||
@ -448,6 +452,7 @@ fn void compile_program(Arena* arena, CompileOptions options)
|
||||
print("Could not find a valid compiler for CC: \"{cstr}\"\n", cc_env ? cc_env : "");
|
||||
print("PATH: {cstr}\n", getenv("PATH"));
|
||||
}
|
||||
|
||||
failed_execution();
|
||||
}
|
||||
|
||||
@ -474,6 +479,7 @@ fn void compile_program(Arena* arena, CompileOptions options)
|
||||
u64 arg_i = 0;
|
||||
#define add_arg(arg) args[arg_i++] = (arg)
|
||||
add_arg(string_to_c(options.compiler_path));
|
||||
|
||||
if (c_compiler == C_COMPILER_MSVC)
|
||||
{
|
||||
add_arg("/nologo");
|
||||
@ -541,6 +547,41 @@ fn void compile_program(Arena* arena, CompileOptions options)
|
||||
add_arg(optimization_switches[c_compiler == C_COMPILER_MSVC][options.build_type]);
|
||||
}
|
||||
|
||||
// Inmutable options
|
||||
switch (c_compiler)
|
||||
{
|
||||
case C_COMPILER_MSVC:
|
||||
{
|
||||
add_arg("/Wall");
|
||||
#if BB_ERROR_ON_WARNINGS
|
||||
add_arg("/WX");
|
||||
#endif
|
||||
add_arg("/wd4255");
|
||||
} break;
|
||||
default:
|
||||
{
|
||||
add_arg("-pedantic");
|
||||
add_arg("-Wall");
|
||||
add_arg("-Wextra");
|
||||
add_arg("-Wpedantic");
|
||||
add_arg("-Wno-unused-function");
|
||||
add_arg("-Wno-nested-anon-types");
|
||||
add_arg("-Wno-keyword-macro");
|
||||
add_arg("-Wno-gnu-auto-type");
|
||||
#ifndef __APPLE__
|
||||
add_arg("-Wno-auto-decl-extensions");
|
||||
#endif
|
||||
add_arg("-Wno-gnu-empty-initializer");
|
||||
add_arg("-Wno-fixed-enum-extension");
|
||||
#if BB_ERROR_ON_WARNINGS
|
||||
add_arg("-Werror");
|
||||
#endif
|
||||
|
||||
add_arg("-fno-strict-aliasing");
|
||||
add_arg("-fwrapv");
|
||||
} break;
|
||||
}
|
||||
|
||||
if (options.flags.colored_output && c_compiler_supports_colored_output(c_compiler))
|
||||
{
|
||||
add_arg("-fdiagnostics-color=auto");
|
||||
@ -715,7 +756,7 @@ int main(int argc, char* argv[], char** envp)
|
||||
.build_type = build_type_pick(),
|
||||
.flags = {
|
||||
.colored_output = 1,
|
||||
.error_limit = 1,
|
||||
.error_limit = BB_ERROR_LIMIT,
|
||||
.debug = 1,
|
||||
.time_trace = BB_TIMETRACE,
|
||||
},
|
||||
|
10
build.sh
10
build.sh
@ -9,6 +9,14 @@ if [[ -z "${BB_BUILD_TYPE-}" ]]; then
|
||||
BB_BUILD_TYPE=debug
|
||||
fi
|
||||
|
||||
if [[ -z "${BB_ERROR_ON_WARNINGS-}" ]]; then
|
||||
BB_ERROR_ON_WARNINGS=$BB_CI
|
||||
fi
|
||||
|
||||
if [[ -z "${BB_ERROR_LIMIT-}" ]]; then
|
||||
BB_ERROR_LIMIT=$((1 - BB_CI))
|
||||
fi
|
||||
|
||||
BUILD_DIR=cache
|
||||
mkdir -p $BUILD_DIR
|
||||
|
||||
@ -37,6 +45,6 @@ elif [[ $C_COMPILER == "gcc"* ]]; then
|
||||
GCC_ARGS=-fmax-errors=1
|
||||
fi
|
||||
|
||||
$C_COMPILER build.c -g -o $BUILD_OUT -Ibootstrap -std=gnu2x $CLANG_ARGS $GCC_ARGS -DBB_TIMETRACE=$BB_TIMETRACE -DBB_CI=$BB_CI -DBB_BUILD_TYPE=\"$BB_BUILD_TYPE\"
|
||||
$C_COMPILER build.c -g -o $BUILD_OUT -Ibootstrap -std=gnu2x $CLANG_ARGS $GCC_ARGS -DBB_TIMETRACE=$BB_TIMETRACE -DBB_CI=$BB_CI -DBB_BUILD_TYPE=\"$BB_BUILD_TYPE\" -DBB_ERROR_ON_WARNINGS=$BB_ERROR_ON_WARNINGS -DBB_ERROR_LIMIT=$BB_ERROR_LIMIT
|
||||
$BUILD_OUT $@
|
||||
exit 0
|
||||
|
Loading…
x
Reference in New Issue
Block a user