Files
CWasm/cwasm.h

194 lines
7.0 KiB
C

/*
File: cwasm.h
Author: Taylor Robbins
Date: 08\28\2025
Description:
** This header should be included before any other header and at the top of every compilation unit.
** It in turn includes any files that are needed for a CWasm-based application to function
*/
#ifndef _CWASM_H
#define _CWASM_H
// +--------------------------------------------------------------+
// | Check Compiler |
// +--------------------------------------------------------------+
#if !defined(__clang__)
#error CWasm is only tested to function with Clang as the compiler!
#endif
#if !defined(__clang_major__) || !defined(__clang_minor__) || !defined(__clang_patchlevel__)
#error Missing defines for __clang_major__, __clang_minor__, and __clang_patchlevel__!
#endif
#if !defined(__wasm32__)
#error CWasm only works when compiling for 32-bit WebAssembly!
#endif
#if defined(__EMSCRIPTEN__)
#error CWasm is not meant to be compiled with Emscripten. It functions as a standalone platform for C applications that only depend on a small subset of the C standard library
#endif
#ifndef __BYTE_ORDER__
#error Missing __BYTE_ORDER__ define!
#elif __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
#error This standard library implementation assumes little-endian byte order
#endif
// +--------------------------------------------------------------+
// | Check Configuration Macros |
// +--------------------------------------------------------------+
#ifndef CWASM_DEBUG
#define CWASM_DEBUG 0
#endif
#ifndef CWASM_ASSERTIONS_ENABLED
#define CWASM_ASSERTIONS_ENABLED CWASM_DEBUG
#endif
#ifndef CWASM_DEBUG_OUTPUT_LINE_BUFFER_SIZE
#define CWASM_DEBUG_OUTPUT_LINE_BUFFER_SIZE 1024 //chars
#endif
#ifndef CWASM_DEBUG_OUTPUT_PRINT_BUFFER_SIZE
#define CWASM_DEBUG_OUTPUT_PRINT_BUFFER_SIZE 1024 //chars
#endif
#ifndef CWASM_ENABLE_DBG_LEVEL_DEBUG
#define CWASM_ENABLE_DBG_LEVEL_DEBUG CWASM_DEBUG
#endif
#ifndef CWASM_ENABLE_DBG_LEVEL_INFO
#define CWASM_ENABLE_DBG_LEVEL_INFO 1
#endif
#ifndef CWASM_ENABLE_DBG_LEVEL_WARNING
#define CWASM_ENABLE_DBG_LEVEL_WARNING 1
#endif
#ifndef CWASM_ENABLE_DBG_LEVEL_ERROR
#define CWASM_ENABLE_DBG_LEVEL_ERROR 1
#endif
#ifndef CWASM_NO_STB_IMAGE
#define CWASM_NO_STB_IMAGE 0
#endif
// +--------------------------------------------------------------+
// | Macros |
// +--------------------------------------------------------------+
#ifdef __cplusplus
#define LANGUAGE_IS_C 0
#define LANGUAGE_IS_CPP 1
#else
#define LANGUAGE_IS_C 1
#define LANGUAGE_IS_CPP 0
#endif
#if LANGUAGE_IS_C
#define nullptr ((void*)0)
#endif
#define START_EXTERN_C extern "C" {
#define END_EXTERN_C }
#if LANGUAGE_IS_CPP
#define MAYBE_EXTERN_C EXTERN_C
#define MAYBE_START_EXTERN_C START_EXTERN_C
#define MAYBE_END_EXTERN_C END_EXTERN_C
#else
#define MAYBE_EXTERN_C //nothing
#define MAYBE_START_EXTERN_C //nothing
#define MAYBE_END_EXTERN_C //nothing
#endif
#define WASM_MEMORY_PAGE_SIZE (64*1024ULL) //64kB or 65,536b
#define WASM_MEMORY_MAX_NUM_PAGES (64*1024ULL) //65,536 pages * 64 kB/page = 4GB
#define WASM_MEMORY_MAX_SIZE ((u64)WASM_MEMORY_MAX_NUM_PAGES * (u64)WASM_MEMORY_PAGE_SIZE)
#define WASM_PROTECTED_SIZE 1024 //1kB at start of wasm memory should be unused and should never be written to
#define WASM_EXPORT(functionName) MAYBE_EXTERN_C __attribute__((export_name(#functionName)))
#if LANGUAGE_IS_C
#define ZEROED {0}
#else
#define ZEROED {}
#endif
#define ArrayCount(array) (sizeof(array) / sizeof((array)[0]))
#define IsAlignedTo(pntr, alignment) ((alignment) == 0 || (((size_t)(pntr)) % (alignment)) == 0)
#define AlignOffset(pntr, alignment) ((alignment) == 0 ? 0 : (((alignment) - (((size_t)(pntr)) % (alignment))) % alignment))
// Shorthand for writing things like (4 * 1024 * 1024) as Megabytes(4).
// Can be used for more than just memory sizes but these powers of 1024 are often
// used when partitioning memory because they relate to binary bit patterns
#define Kilo(value) ((value) * 1024ULL)
#define Mega(value) (Kilo(value) * 1024ULL)
#define Giga(value) (Mega(value) * 1024ULL)
#define Tera(value) (Giga(value) * 1024ULL)
#define Kilobytes(value) Kilo(value)
#define Megabytes(value) Mega(value)
#define Gigabytes(value) Giga(value)
#define Terabytes(value) Tera(value)
#define Thousand(value) ((value) * 1000ULL)
#define Million(value) ((value) * 1000000ULL)
#define Billion(value) ((value) * 1000000000ULL)
#define Trillion(value) ((value) * 1000000000000ULL)
#if CWASM_ASSERTIONS_ENABLED
#define Assert(condition) assert(condition)
#define AssertMsg(condition, message) assert_msg((condition), (message))
#else
#define Assert(condition) sizeof(condition) //do nothing, but make sure anything used in condition is not treated as "unused" when assertions are disabled
#define AssertMsg(condition, message) sizeof(condition)
#endif
#define NotNull(expression) Assert((expression) != nullptr)
#define Clamp(value, min, max) (((value) < (min)) ? (min) : (((value) > (max)) ? (max) : (value)))
//Actual Value of Pi: 3.1415926535897932384626433832795...
#define Pi64 3.14159265358979311599796346854 //accurate to 15 digits
#define Pi32 3.1415927410125732421875f //accurate to 6 digits
#define QuarterPi64 (Pi64/4.0)
#define ThirdPi64 (Pi64/3.0)
#define HalfPi64 (Pi64/2.0)
#define ThreeHalfsPi64 (Pi64*(3.0/2.0))
#define TwoPi64 (2*Pi64)
#define QuarterPi32 (Pi32/4.0f)
#define ThirdPi32 (Pi32/3.0f)
#define HalfPi32 (Pi32/2.0f)
#define ThreeHalfsPi32 (Pi32*(3.0f/2.0f))
#define TwoPi32 (2*Pi32)
//Actual Value of e: 2.7182818284590452353602874713526...
#define e64 2.71828182845904509079559829843 //accurate to 15 digits
#define e32 2.71828174591064453125f //accurate to 6 digits
// +--------------------------------------------------------------+
// | Standard Includes |
// +--------------------------------------------------------------+
// NOTE: These headers are all contained in CWasm's "std" folder, they are not "real" C standard library headers
#include <limits.h>
#include <stdint.h>
#include <uchar.h>
#include <float.h>
#include <stdbool.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>
#include <assert.h>
#include <math.h>
// +--------------------------------------------------------------+
// | Basic Type Names |
// +--------------------------------------------------------------+
// We use an "i" to indicate it can hold integer numbers
typedef int8_t i8;
typedef int16_t i16;
typedef int32_t i32;
typedef long long i64;
// We use a "u" to distinguish these as only holding unsigned numbers (they are still integers, but "i" is already taken)
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef unsigned long long u64;
// We use an "r" to indicate it can hold real numbers
typedef float r32;
typedef double r64;
#endif // _CWASM_H