Merge pull request #50 from birth-software/research-di
ELF linker prototype
This commit is contained in:
commit
b82f9d45ef
3
.github/workflows/ci.yml
vendored
3
.github/workflows/ci.yml
vendored
@ -24,6 +24,9 @@ jobs:
|
|||||||
# steps:
|
# steps:
|
||||||
# - name: Checkout
|
# - name: Checkout
|
||||||
# uses: actions/checkout@v4
|
# uses: actions/checkout@v4
|
||||||
|
# - name: Install LLVM
|
||||||
|
# run: |
|
||||||
|
# brew list llvm || brew install llvm
|
||||||
# - name: Build and test
|
# - name: Build and test
|
||||||
# run: |
|
# run: |
|
||||||
# ./project.sh test all
|
# ./project.sh test all
|
||||||
|
@ -33,7 +33,7 @@ typedef enum Linkage: u8
|
|||||||
} Linkage;
|
} Linkage;
|
||||||
declare_slice(Linkage);
|
declare_slice(Linkage);
|
||||||
|
|
||||||
struct CompileOptions
|
STRUCT(CompileOptions)
|
||||||
{
|
{
|
||||||
char* out_path;
|
char* out_path;
|
||||||
char* in_path;
|
char* in_path;
|
||||||
@ -43,7 +43,6 @@ struct CompileOptions
|
|||||||
Compiler compiler:1;
|
Compiler compiler:1;
|
||||||
Linkage linkage:1;
|
Linkage linkage:1;
|
||||||
};
|
};
|
||||||
typedef struct CompileOptions CompileOptions;
|
|
||||||
decl_vbp(char);
|
decl_vbp(char);
|
||||||
|
|
||||||
fn u8 is_debug(OptimizationMode optimization_mode, u8 debug_info)
|
fn u8 is_debug(OptimizationMode optimization_mode, u8 debug_info)
|
||||||
@ -63,20 +62,25 @@ fn void compile_c(const CompileOptions *const options, char** envp)
|
|||||||
compiler = "/usr/bin/gcc";
|
compiler = "/usr/bin/gcc";
|
||||||
break;
|
break;
|
||||||
case clang:
|
case clang:
|
||||||
|
#ifdef __APPLE__
|
||||||
|
compiler = "/opt/homebrew/opt/llvm/bin/clang";
|
||||||
|
#else
|
||||||
compiler = "/usr/bin/clang";
|
compiler = "/usr/bin/clang";
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
case COMPILER_COUNT:
|
case COMPILER_COUNT:
|
||||||
unreachable();
|
unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
*vb_add(args, 1) = compiler;
|
*vb_add(args, 1) = compiler;
|
||||||
|
// *vb_add(args, 1) = "-E";
|
||||||
*vb_add(args, 1) = options->in_path;
|
*vb_add(args, 1) = options->in_path;
|
||||||
*vb_add(args, 1) = "-o";
|
*vb_add(args, 1) = "-o";
|
||||||
*vb_add(args, 1) = options->out_path;
|
*vb_add(args, 1) = options->out_path;
|
||||||
|
|
||||||
if (options->debug_info)
|
if (options->debug_info)
|
||||||
{
|
{
|
||||||
*vb_add(args, 1) = "-g";
|
*vb_add(args, 1) = "-g3";
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (options->optimization_mode)
|
switch (options->optimization_mode)
|
||||||
@ -122,6 +126,7 @@ fn void compile_c(const CompileOptions *const options, char** envp)
|
|||||||
"-Wno-auto-decl-extensions",
|
"-Wno-auto-decl-extensions",
|
||||||
"-Wno-gnu-empty-initializer",
|
"-Wno-gnu-empty-initializer",
|
||||||
"-Wno-fixed-enum-extension",
|
"-Wno-fixed-enum-extension",
|
||||||
|
"-Wno-gnu-binary-literal",
|
||||||
"-pedantic",
|
"-pedantic",
|
||||||
"-fno-exceptions",
|
"-fno-exceptions",
|
||||||
"-fno-stack-protector",
|
"-fno-stack-protector",
|
||||||
@ -201,6 +206,8 @@ fn void compile_and_run(const CompileOptions* const options, char** envp, Compil
|
|||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
args = (CStringSlice) array_to_slice(((char*[]){
|
args = (CStringSlice) array_to_slice(((char*[]){
|
||||||
"/usr/bin/lldb",
|
"/usr/bin/lldb",
|
||||||
|
"-o",
|
||||||
|
"run",
|
||||||
"--",
|
"--",
|
||||||
common_compile_and_run_args
|
common_compile_and_run_args
|
||||||
}));
|
}));
|
||||||
@ -224,14 +231,13 @@ typedef enum Command : u8
|
|||||||
COMMAND_COUNT,
|
COMMAND_COUNT,
|
||||||
} Command;
|
} Command;
|
||||||
|
|
||||||
struct TestOptions
|
STRUCT(TestOptions)
|
||||||
{
|
{
|
||||||
Slice(Linkage) linkages;
|
Slice(Linkage) linkages;
|
||||||
Slice(OptimizationMode) optimization_modes;
|
Slice(OptimizationMode) optimization_modes;
|
||||||
Slice(String) test_paths;
|
Slice(String) test_paths;
|
||||||
Slice(CompilerBackend) compiler_backends;
|
Slice(CompilerBackend) compiler_backends;
|
||||||
};
|
};
|
||||||
typedef struct TestOptions TestOptions;
|
|
||||||
|
|
||||||
fn String linkage_name(Linkage linkage)
|
fn String linkage_name(Linkage linkage)
|
||||||
{
|
{
|
||||||
@ -475,7 +481,7 @@ int main(int argc, char* argv[], char** envp)
|
|||||||
case COMMAND_RUN_TESTS:
|
case COMMAND_RUN_TESTS:
|
||||||
{
|
{
|
||||||
Arena* arena = arena_init_default(KB(64));
|
Arena* arena = arena_init_default(KB(64));
|
||||||
Linkage all_linkages[] = { LINKAGE_STATIC, LINKAGE_DYNAMIC };
|
Linkage all_linkages[] = { LINKAGE_DYNAMIC, LINKAGE_STATIC };
|
||||||
static_assert(array_length(all_linkages) == LINKAGE_COUNT);
|
static_assert(array_length(all_linkages) == LINKAGE_COUNT);
|
||||||
OptimizationMode all_optimization_modes[] = {
|
OptimizationMode all_optimization_modes[] = {
|
||||||
O0,
|
O0,
|
||||||
|
177
bootstrap/lib.h
177
bootstrap/lib.h
@ -61,6 +61,10 @@ for (typeof(bits) _bits_ = (bits), it = (start); _bits_; _bits_ >>= 1, ++it) if
|
|||||||
#define FOREACH_SET(it, set) \
|
#define FOREACH_SET(it, set) \
|
||||||
FOR_N(_i, 0, ((set)->arr.capacity + 63) / 64) FOR_BIT(it, _i*64, (set)->arr.pointer[_i])
|
FOR_N(_i, 0, ((set)->arr.capacity + 63) / 64) FOR_BIT(it, _i*64, (set)->arr.pointer[_i])
|
||||||
|
|
||||||
|
#define STRUCT_FORWARD_DECL(S) typedef struct S S
|
||||||
|
#define STRUCT(S) STRUCT_FORWARD_DECL(S); struct S
|
||||||
|
#define UNION_FORWARD_DECL(U) typedef union U U
|
||||||
|
#define UNION(U) UNION_FORWARD_DECL(U); union U
|
||||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||||
|
|
||||||
@ -479,6 +483,25 @@ may_be_unused fn u64 absolute_int(s64 n)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if LINK_LIBC == 0
|
#if LINK_LIBC == 0
|
||||||
|
int strcmp(const char* s1, const char* s2)
|
||||||
|
{
|
||||||
|
auto diff = 0;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
auto ch1 = *s1;
|
||||||
|
auto ch2 = *s2;
|
||||||
|
diff = ch1 - ch2;
|
||||||
|
if (ch1 == 0 || ch2 == 0 || diff)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
s1 += 1;
|
||||||
|
s2 += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return diff;
|
||||||
|
}
|
||||||
void* memcpy(void* const restrict dst, const void* const restrict src, u64 size)
|
void* memcpy(void* const restrict dst, const void* const restrict src, u64 size)
|
||||||
{
|
{
|
||||||
auto* destination = (u8*)dst;
|
auto* destination = (u8*)dst;
|
||||||
@ -492,38 +515,37 @@ void* memcpy(void* const restrict dst, const void* const restrict src, u64 size)
|
|||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void* memmove(void* const dst, const void* const src, u64 n)
|
void* memmove(void* const dst, const void* const src, u64 n)
|
||||||
{
|
{
|
||||||
// Implementation
|
// Implementation
|
||||||
// https://opensource.apple.com/source/network_cmds/network_cmds-481.20.1/unbound/compat/memmove.c.auto.html
|
// https://opensource.apple.com/source/network_cmds/network_cmds-481.20.1/unbound/compat/memmove.c.auto.html
|
||||||
uint8_t* from = (uint8_t*) src;
|
uint8_t* from = (uint8_t*) src;
|
||||||
uint8_t* to = (uint8_t*) dst;
|
uint8_t* to = (uint8_t*) dst;
|
||||||
|
|
||||||
if (from == to || n == 0)
|
if (from == to || n == 0)
|
||||||
return dst;
|
return dst;
|
||||||
if (to > from && to-from < (s64)n) {
|
if (to > from && to-from < (s64)n) {
|
||||||
/* to overlaps with from */
|
/* to overlaps with from */
|
||||||
/* <from......> */
|
/* <from......> */
|
||||||
/* <to........> */
|
/* <to........> */
|
||||||
/* copy in reverse, to avoid overwriting from */
|
/* copy in reverse, to avoid overwriting from */
|
||||||
u64 i;
|
u64 i;
|
||||||
for(i=n-1; i>=0; i--)
|
for(i=n-1; i>=0; i--)
|
||||||
to[i] = from[i];
|
to[i] = from[i];
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
if (from > to && from-to < (int)n) {
|
if (from > to && from-to < (int)n) {
|
||||||
/* to overlaps with from */
|
/* to overlaps with from */
|
||||||
/* <from......> */
|
/* <from......> */
|
||||||
/* <to........> */
|
/* <to........> */
|
||||||
/* copy forwards, to avoid overwriting from */
|
/* copy forwards, to avoid overwriting from */
|
||||||
u64 i;
|
u64 i;
|
||||||
for(i=0; i<n; i++)
|
for(i=0; i<n; i++)
|
||||||
to[i] = from[i];
|
to[i] = from[i];
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
memcpy(dst, src, n);
|
memcpy(dst, src, n);
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* memset(void* dst, u8 n, u64 size)
|
void* memset(void* dst, u8 n, u64 size)
|
||||||
@ -537,11 +559,17 @@ void* memset(void* dst, u8 n, u64 size)
|
|||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn int memcmp(const void* left, const void* right, u64 n)
|
fn int memcmp(const void* a, const void* b, u64 n)
|
||||||
{
|
{
|
||||||
const u8 *l=(const u8*)left, *r=(const u8*)right;
|
auto *s1 = (u8*)a;
|
||||||
for (; n && *l == *r; n--, l++, r++);
|
auto *s2 = (u8*)b;
|
||||||
return n ? *l - *r : 0;
|
|
||||||
|
while (n-- > 0)
|
||||||
|
{
|
||||||
|
if (*s1++ != *s2++)
|
||||||
|
return s1[-1] < s2[-1] ? -1 : 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn u64 strlen (const char* c_string)
|
fn u64 strlen (const char* c_string)
|
||||||
@ -569,12 +597,11 @@ fn u64 strlen (const char* c_string)
|
|||||||
|
|
||||||
#define Slice(T) Slice_ ## T
|
#define Slice(T) Slice_ ## T
|
||||||
#define SliceP(T) SliceP_ ## T
|
#define SliceP(T) SliceP_ ## T
|
||||||
#define declare_slice_ex(T, StructName) struct StructName \
|
#define declare_slice_ex(T, StructName) STRUCT(StructName) \
|
||||||
{\
|
{\
|
||||||
T* pointer;\
|
T* pointer;\
|
||||||
u64 length;\
|
u64 length;\
|
||||||
};\
|
}
|
||||||
typedef struct StructName StructName
|
|
||||||
|
|
||||||
#define declare_slice(T) declare_slice_ex(T, Slice(T))
|
#define declare_slice(T) declare_slice_ex(T, Slice(T))
|
||||||
#define declare_slice_p(T) declare_slice_ex(T*, SliceP(T))
|
#define declare_slice_p(T) declare_slice_ex(T*, SliceP(T))
|
||||||
@ -582,7 +609,7 @@ typedef struct StructName StructName
|
|||||||
#define s_get(s, i) (s).pointer[i]
|
#define s_get(s, i) (s).pointer[i]
|
||||||
#define s_get_pointer(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_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))) == 0)
|
#define s_equal(a, b) ((a).length == (b).length && memcmp((a).pointer, (b).pointer, sizeof(*((a).pointer)) * (a).length) == 0)
|
||||||
|
|
||||||
declare_slice(u8);
|
declare_slice(u8);
|
||||||
declare_slice(s32);
|
declare_slice(s32);
|
||||||
@ -777,62 +804,62 @@ may_be_unused fn Hash32 hash64_to_hash32(Hash64 hash64)
|
|||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
may_be_unused fn forceinline long syscall0(long n)
|
may_be_unused fn forceinline long syscall0(long n)
|
||||||
{
|
{
|
||||||
long ret;
|
long ret;
|
||||||
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n) : "rcx", "r11", "memory");
|
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n) : "rcx", "r11", "memory");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
may_be_unused fn forceinline long syscall1(long n, long a1)
|
may_be_unused fn forceinline long syscall1(long n, long a1)
|
||||||
{
|
{
|
||||||
long ret;
|
long ret;
|
||||||
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1) : "rcx", "r11", "memory");
|
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1) : "rcx", "r11", "memory");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
may_be_unused fn forceinline long syscall2(long n, long a1, long a2)
|
may_be_unused fn forceinline long syscall2(long n, long a1, long a2)
|
||||||
{
|
{
|
||||||
long ret;
|
long ret;
|
||||||
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2)
|
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2)
|
||||||
: "rcx", "r11", "memory");
|
: "rcx", "r11", "memory");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
may_be_unused fn forceinline long syscall3(long n, long a1, long a2, long a3)
|
may_be_unused fn forceinline long syscall3(long n, long a1, long a2, long a3)
|
||||||
{
|
{
|
||||||
long ret;
|
long ret;
|
||||||
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2),
|
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2),
|
||||||
"d"(a3) : "rcx", "r11", "memory");
|
"d"(a3) : "rcx", "r11", "memory");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
may_be_unused fn forceinline long syscall4(long n, long a1, long a2, long a3, long a4)
|
may_be_unused fn forceinline long syscall4(long n, long a1, long a2, long a3, long a4)
|
||||||
{
|
{
|
||||||
long ret;
|
long ret;
|
||||||
register long r10 __asm__("r10") = a4;
|
register long r10 __asm__("r10") = a4;
|
||||||
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2),
|
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2),
|
||||||
"d"(a3), "r"(r10): "rcx", "r11", "memory");
|
"d"(a3), "r"(r10): "rcx", "r11", "memory");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
may_be_unused fn forceinline long syscall5(long n, long a1, long a2, long a3, long a4, long a5)
|
may_be_unused fn forceinline long syscall5(long n, long a1, long a2, long a3, long a4, long a5)
|
||||||
{
|
{
|
||||||
long ret;
|
long ret;
|
||||||
register long r10 __asm__("r10") = a4;
|
register long r10 __asm__("r10") = a4;
|
||||||
register long r8 __asm__("r8") = a5;
|
register long r8 __asm__("r8") = a5;
|
||||||
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2),
|
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2),
|
||||||
"d"(a3), "r"(r10), "r"(r8) : "rcx", "r11", "memory");
|
"d"(a3), "r"(r10), "r"(r8) : "rcx", "r11", "memory");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
may_be_unused fn forceinline long syscall6(long n, long a1, long a2, long a3, long a4, long a5, long a6)
|
may_be_unused fn forceinline long syscall6(long n, long a1, long a2, long a3, long a4, long a5, long a6)
|
||||||
{
|
{
|
||||||
long ret;
|
long ret;
|
||||||
register long r10 __asm__("r10") = a4;
|
register long r10 __asm__("r10") = a4;
|
||||||
register long r8 __asm__("r8") = a5;
|
register long r8 __asm__("r8") = a5;
|
||||||
register long r9 __asm__("r9") = a6;
|
register long r9 __asm__("r9") = a6;
|
||||||
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2),
|
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2),
|
||||||
"d"(a3), "r"(r10), "r"(r8), "r"(r9) : "rcx", "r11", "memory");
|
"d"(a3), "r"(r10), "r"(r8), "r"(r9) : "rcx", "r11", "memory");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum SyscallX86_64 : u64 {
|
enum SyscallX86_64 : u64 {
|
||||||
@ -1512,13 +1539,12 @@ fn u32 format_decimal(String buffer, u64 decimal)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define SILENT (0)
|
#define SILENT (0)
|
||||||
struct SmallIntResult
|
STRUCT(SmallIntResult)
|
||||||
{
|
{
|
||||||
u64 mantissa;
|
u64 mantissa;
|
||||||
s32 exponent;
|
s32 exponent;
|
||||||
u8 is_small_int;
|
u8 is_small_int;
|
||||||
};
|
};
|
||||||
typedef struct SmallIntResult SmallIntResult;
|
|
||||||
|
|
||||||
#define double_mantissa_bits 52
|
#define double_mantissa_bits 52
|
||||||
#define double_exponent_bits 11
|
#define double_exponent_bits 11
|
||||||
@ -1972,12 +1998,11 @@ static inline uint32_t mod1e9(const uint64_t x) {
|
|||||||
return (uint32_t) (x - 1000000000 * div1e9(x));
|
return (uint32_t) (x - 1000000000 * div1e9(x));
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Double
|
STRUCT(Double)
|
||||||
{
|
{
|
||||||
u64 mantissa;
|
u64 mantissa;
|
||||||
s32 exponent;
|
s32 exponent;
|
||||||
};
|
};
|
||||||
typedef struct Double Double;
|
|
||||||
|
|
||||||
may_be_unused fn Double double_transform(u64 ieee_mantissa, u32 ieee_exponent)
|
may_be_unused fn Double double_transform(u64 ieee_mantissa, u32 ieee_exponent)
|
||||||
{
|
{
|
||||||
@ -2145,12 +2170,13 @@ fn u32 decimalLength17(const u64 v) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// A floating decimal representing m * 10^e.
|
// A floating decimal representing m * 10^e.
|
||||||
typedef struct floating_decimal_64 {
|
STRUCT(floating_decimal_64)
|
||||||
|
{
|
||||||
uint64_t mantissa;
|
uint64_t mantissa;
|
||||||
// Decimal exponent's range is -324 to 308
|
// Decimal exponent's range is -324 to 308
|
||||||
// inclusive, and can fit in a short if needed.
|
// inclusive, and can fit in a short if needed.
|
||||||
int32_t exponent;
|
int32_t exponent;
|
||||||
} floating_decimal_64;
|
};
|
||||||
|
|
||||||
fn u8* digits2(u64 value)
|
fn u8* digits2(u64 value)
|
||||||
{
|
{
|
||||||
@ -2565,7 +2591,7 @@ global u64 minimum_granularity = page_size;
|
|||||||
// global u64 middle_granularity = MB(2);
|
// global u64 middle_granularity = MB(2);
|
||||||
global u64 default_size = GB(4);
|
global u64 default_size = GB(4);
|
||||||
|
|
||||||
struct Arena
|
STRUCT(Arena)
|
||||||
{
|
{
|
||||||
u64 reserved_size;
|
u64 reserved_size;
|
||||||
u64 committed;
|
u64 committed;
|
||||||
@ -2574,7 +2600,6 @@ struct Arena
|
|||||||
u8 reserved[4 * 8];
|
u8 reserved[4 * 8];
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct Arena Arena;
|
|
||||||
static_assert(sizeof(Arena) == 64);
|
static_assert(sizeof(Arena) == 64);
|
||||||
|
|
||||||
fn Arena* arena_init(u64 reserved_size, u64 granularity, u64 initial_size)
|
fn Arena* arena_init(u64 reserved_size, u64 granularity, u64 initial_size)
|
||||||
@ -2798,6 +2823,8 @@ may_be_unused fn u8* vb_append_bytes(VirtualBuffer(u8*) vb, Slice(u8) bytes)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define vb_add(a, count) (typeof((a)->pointer)) vb_generic_add((VirtualBuffer(u8)*)(a), sizeof(*((a)->pointer)), count)
|
#define vb_add(a, count) (typeof((a)->pointer)) vb_generic_add((VirtualBuffer(u8)*)(a), sizeof(*((a)->pointer)), count)
|
||||||
|
#define vb_add_struct(a, S) (S*) vb_generic_add(a, 1, sizeof(S))
|
||||||
|
#define vb_append_struct(a, T, s) *(vb_add_struct(a, T)) = s
|
||||||
#define vb_append_one(a, item) (typeof((a)->pointer)) vb_generic_append((VirtualBuffer(u8)*)(a), &(item), sizeof(*((a)->pointer)), 1)
|
#define vb_append_one(a, item) (typeof((a)->pointer)) vb_generic_append((VirtualBuffer(u8)*)(a), &(item), sizeof(*((a)->pointer)), 1)
|
||||||
#define vb_to_bytes(vb) (Slice(u8)) { .pointer = (u8*)((vb).pointer), .length = sizeof(*((vb).pointer)) * (vb).length, }
|
#define vb_to_bytes(vb) (Slice(u8)) { .pointer = (u8*)((vb).pointer), .length = sizeof(*((vb).pointer)) * (vb).length, }
|
||||||
#define vb_ensure_capacity(a, count) vb_generic_ensure_capacity((VirtualBuffer(u8)*)(a), sizeof(*((a)->pointer)), count)
|
#define vb_ensure_capacity(a, count) vb_generic_ensure_capacity((VirtualBuffer(u8)*)(a), sizeof(*((a)->pointer)), count)
|
||||||
|
4144
bootstrap/main.c
4144
bootstrap/main.c
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,10 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -e
|
set -ex
|
||||||
mkdir -p build
|
mkdir -p build
|
||||||
time clang -o build/build bootstrap/build.c -g -march=native -std=gnu2x -Wall -Wextra -Wpedantic -Wno-nested-anon-types -Wno-keyword-macro -Wno-gnu-auto-type -Wno-auto-decl-extensions -Wno-gnu-empty-initializer -Wno-fixed-enum-extension -pedantic -fno-exceptions -fno-stack-protector
|
case "$OSTYPE" in
|
||||||
|
linux*) CLANG_PATH="clang" ;;
|
||||||
|
darwin*) CLANG_PATH="/opt/homebrew/opt/llvm/bin/clang" ;;
|
||||||
|
*) exit 1 ;;
|
||||||
|
esac
|
||||||
|
time $CLANG_PATH -o build/build bootstrap/build.c -g -march=native -std=gnu2x -Wall -Wextra -Wpedantic -Wno-nested-anon-types -Wno-keyword-macro -Wno-gnu-auto-type -Wno-auto-decl-extensions -Wno-gnu-empty-initializer -Wno-fixed-enum-extension -pedantic -fno-exceptions -fno-stack-protector
|
||||||
build/build $@
|
build/build $@
|
||||||
|
Loading…
x
Reference in New Issue
Block a user