194 lines
7.0 KiB
C
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
|