c-scripting/src/base.h

253 lines
4.9 KiB
C

////////////////////////////////
// Context Cracking
// untangle compiler, os, & architecture
#if defined(__clang__)
# define COMPILER_CLANG 1
# if defined(_WIN32)
# define OS_WINDOWS 1
# elif defined(__gnu_linux__)
# define OS_LINUX 1
# elif defined(__APPLE__) && defined(__MACH__)
# define OS_MAC 1
# else
# error missing OS detection
# endif
# if defined(__amd64__)
# define ARCH_X64 1
// TODO(allen): verify this works on clang
# elif defined(__i386__)
# define ARCH_X86 1
// TODO(allen): verify this works on clang
# elif defined(__arm__)
# define ARCH_ARM 1
// TODO(allen): verify this works on clang
# elif defined(__aarch64__)
# define ARCH_ARM64 1
# else
# error missing ARCH detection
# endif
#elif defined(_MSC_VER)
# define COMPILER_CL 1
# if defined(_WIN32)
# define OS_WINDOWS 1
# else
# error missing OS detection
# endif
# if defined(_M_AMD64)
# define ARCH_X64 1
# elif defined(_M_I86)
# define ARCH_X86 1
# elif defined(_M_ARM)
# define ARCH_ARM 1
// TODO(allen): ARM64?
# else
# error missing ARCH detection
# endif
#elif defined(__GNUC__)
# define COMPILER_GCC 1
# if defined(_WIN32)
# define OS_WINDOWS 1
# elif defined(__gnu_linux__)
# define OS_LINUX 1
# elif defined(__APPLE__) && defined(__MACH__)
# define OS_MAC 1
# else
# error missing OS detection
# endif
# if defined(__amd64__)
# define ARCH_X64 1
# elif defined(__i386__)
# define ARCH_X86 1
# elif defined(__arm__)
# define ARCH_ARM 1
# elif defined(__aarch64__)
# define ARCH_ARM64 1
# else
# error missing ARCH detection
# endif
#else
# error no context cracking for this compiler
#endif
#if !defined(COMPILER_CL)
# define COMPILER_CL 0
#endif
#if !defined(COMPILER_CLANG)
# define COMPILER_CLANG 0
#endif
#if !defined(COMPILER_GCC)
# define COMPILER_GCC 0
#endif
#if !defined(OS_WINDOWS)
# define OS_WINDOWS 0
#endif
#if !defined(OS_LINUX)
# define OS_LINUX 0
#endif
#if !defined(OS_MAC)
# define OS_MAC 0
#endif
#if !defined(ARCH_X64)
# define ARCH_X64 0
#endif
#if !defined(ARCH_X86)
# define ARCH_X86 0
#endif
#if !defined(ARCH_ARM)
# define ARCH_ARM 0
#endif
#if !defined(ARCH_ARM64)
# define ARCH_ARM64 0
#endif
// language
#if defined(__cplusplus)
# define LANG_CXX 1
#else
# define LANG_C 1
#endif
#if !defined(LANG_CXX)
# define LANG_CXX 0
#endif
#if !defined(LANG_C)
# define LANG_C 0
#endif
////////////////////////////////
// GLUE(a,b) STRIFY(s)
#define GLUE__(a,b) a##b
#define GLUE_(a,b) GLUE__(a,b)
#define GLUE(a,b) GLUE_(a,b)
#define STRIFY__(s) #s
#define STRIFY_(s) STRIFY__(s)
#define STRIFY(s) STRIFY_(s)
////////////////////////////////
// SECTION(<section-name>) <Decl>
#if COMPILER_CLANG || COMPILER_GCC
# define SECTION(N) __attribute__((__section__(N)))
#elif COMPILER_CL
# define SECTION(N) __declspec(allocate(N))
#else
# error SECTION not defined for this compiler
#endif
// for CL users: #pragma section(<section>,read,write)
////////////////////////////////
// BEFORE_MAIN(){ <...> }
#if OS_WINDOWS
# pragma section(".CRT$XCU", read)
# if LANG_CXX
# define BEFORE_MAIN_NAMED(n) \
static void n(void); \
__declspec(allocate(".CRT$XCU")) \
__pragma(comment(linker,"/include:" #n "__")) \
extern "C" void (*n##__)(void); \
void (*n##__)(void) = n; \
static void n(void)
# else
# define BEFORE_MAIN_NAMED(n) \
static void n(void); \
__declspec(allocate(".CRT$XCU")) \
__pragma(comment(linker,"/include:" #n "__")) \
void (*n##__)(void) = n; \
static void n(void)
# endif
#elif OS_LINUX
# define BEFORE_MAIN_NAMED(n) \
__attribute__((constructor)) static void n(void)
#else
# error BEFORE_MAIN missing for this OS
#endif
#define BEFORE_MAIN_(n) BEFORE_MAIN_NAMED(n)
#define BEFORE_MAIN() BEFORE_MAIN_(GLUE(beforemain,__COUNTER__))
////////////////////////////////
// DO_NOT_ELIMINATE
#if OS_WINDOWS
# define DO_NOT_ELIMINATE__S0(N) __pragma(comment(linker,"/include:" #N))
# define DO_NOT_ELIMINATE__S1(N) DO_NOT_ELIMINATE__S0(N)
# define DO_NOT_ELIMINATE(N) DO_NOT_ELIMINATE__S1(N)
#else
# define DO_NOT_ELIMINATE(N)
#endif
////////////////////////////////
// Types
#include <stdint.h>
typedef int8_t S8;
typedef int16_t S16;
typedef int32_t S32;
typedef int64_t S64;
typedef uint8_t U8;
typedef uint16_t U16;
typedef uint32_t U32;
typedef uint64_t U64;
typedef S8 B8;
typedef S16 B16;
typedef S32 B32;
typedef S64 B64;
typedef float F32;
typedef double F64;
typedef struct RangePtr{
U8 *first;
U8 *opl;
} RangePtr;
typedef struct String8{
U8 *str;
U64 size;
} String8;
#define str8_lit(str) str8((U8*)(str), sizeof(str) - 1)
#define str8_lit_const(str) { (U8*)(str), sizeof(str) - 1 }
#define str8_expand(s) ((int)((s).size)), ((s).str)
////////////////////////////////
// Functions
static String8 str8(U8 *str, U64 size);
static B32 str8_match(String8 a, String8 b, U32 flags);
static void* os_this_image(void);
static RangePtr self_img_get_section(void *image, String8 name);