commit e917cb8d8f46d04673436765fd31fe48dca8fbcd Author: Avril Date: Wed Mar 17 15:05:00 2021 +0000 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f74ce2b --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.o +sm-* +old-examples/ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..939551f --- /dev/null +++ b/Makefile @@ -0,0 +1 @@ +PROJECT=sm diff --git a/include/box.h b/include/box.h new file mode 100644 index 0000000..fc52a7f --- /dev/null +++ b/include/box.h @@ -0,0 +1,103 @@ +//! Deals with heap allocating (`boxing') types and values. +//! +//! Nameapace(s): +//! API functions/macros start with (or are) `box`. `unbox`, `BOX`, and `UNBOX`. +//! Internal impl. functions/macros start with (or are) `_box`, `_BOX`, `_unbox`, and `_UNBOX`. +//! +//! Provides macros for C and C++: +//! * BOX(T) - Allocate a properly aligned, uninitliased `T*` pointer on the heap. +//! * BOX_EX(T) - Allocate a properly aligned, zero-initialised `T*` pointer on the heap. +//! * BOX_WITH(T, val) - Allocate a properly aligned `T*` pointer on the heap with the value of `val`. +//! * UNBOX(val) - Free the memory of boxed pointer `val`, then return the value itself. +//! * UNBOX_EX(val) - Explicitly zero and then free the memory of boxed pointer `val`, then return the value itself. +//! +//! Provides templates for C++: +//! * T* box() - Same as `BOX(T)` +//! * T* box() - Same as `BOX_EX(T)` +//! * T* box(T value) - Same as `BOX_WITH(T, value)` +//! * T unbox(T* value) - Same as `UNBOX(value)` +//! * T unbox(T* value) - Same as `UNBOX_EX(value)` +//! +//! # Notes +//! `UNBOX_EX` and `unbox` use `explicit_bzero` to blank the memory before free. +//! Whereas `BOX_EX` and `box` just use `bzero`. +//! +//! This API is **not** designed to work with C++ classes, constructors, or destructors. It is designed for C types and structs. Constructors and destructors are not called or supported. Only use with C-like (so-called ``POD'') types without con/destructors. No default initialisation is done (besides zero-initialisation when requested). + +#ifndef _BOX_H +#define _BOX_H + +#ifdef __cplusplus + +#include +#include +//#include + +template +inline T* box() +{ + void* ptr = aligned_alloc(alignof(T), sizeof(T)); + if constexpr(Zero) bzero(ptr, sizeof(T)); + + return (T*)ptr; +} + +template +inline T* box(T val) +{ + T* ptr = box(); + *ptr = val; + return ptr; +} + +template +inline T unbox(T* boxed) +{ + T val = *boxed; + if constexpr(Zero) explicit_bzero((void*)boxed, sizeof(T)); + free((void*)boxed); + return val; +} + +template +inline static T _unbox_explicit(T* boxed) +{ + return unbox(boxed); +} + +#define BOX(T) box() +#define BOX_EX(T) box() +#define BOX_WITH(T, val) box(val) + +#define UNBOX_EX(val) _unbox_explicit(val) +#define UNBOX(val) unbox(val) + +#else + +#include +#include + +#define BOX(T) ({ void* _bx__ptr = aligned_alloc(_Alignof(T), sizeof(T)); \ + (T*)_bx__ptr; }) + +#define BOX_EX(T) ({ void* _bx__ptr = aligned_alloc(_Alignof(T), sizeof(T)); \ + bzero(_bx__ptr, sizeof(T)); \ + (T*)_bx__ptr; }) + +#define BOX_WITH(T, v) ({ T* _bx__ptr = aligned_alloc(_Alignof(T), sizeof(T)); \ + *_bx__ptr = (v); \ + _bx__ptr; }) + +#define UNBOX_EX(_val) ({ __auto_type _bx__ptr = (_val); \ + __auto_type _bx__val = *_bx__ptr; \ + explicit_bzero((void*)_bx__ptr, sizeof(_bx__val)); \ + free((void*)_bx__ptr); \ + _bx__val; }) + +#define UNBOX(val) ({ __auto_type _bx__val = *val; \ + free((void*)val); \ + _bx__val; }) + +#endif + +#endif /* _BOX_H */ diff --git a/include/frame.h b/include/frame.h new file mode 100644 index 0000000..c5051f9 --- /dev/null +++ b/include/frame.h @@ -0,0 +1,90 @@ +#pragma once + +#include "box.h" + +#include +#define _SM_STACK_SIZE 16 + +struct _sm_user { + bool set ;//: 1; No need for these to be bitfield packed, there's an alignment hole here anyway. + bool free ;//: 1; + + union { + uint8_t _8; + uint16_t _16; + uint32_t _32; + uint64_t _64; + + float _f32; + double _f64; + + void* _ptr; + }; +}; + +struct _sm_user_page { + _sm_user data[_SM_STACK_SIZE]; + + _sm_user_page* next; +}; + +struct _sm_frame { + _sm_user_page user; + + uint64_t pc; + _sm_frame* prev; +}; + +struct sm_state { + + + _sm_frame* current; +}; + +template +inline T* _sm_init(_sm_user* frame, T init) +{ + frame->free = true; + + T* ptr = box(); + *ptr = init; + return (T*) (frame->_ptr = (void*)ptr); +} + +template +inline T** _sm_init(_sm_user* frame, T* init) +{ + frame->free = false; + frame->_ptr = (void*)init; + + return (T**) &frame->_ptr; +} + +template +inline T* _sm_get(_sm_user* frame) +{ + return (T*) frame->_ptr; +} + +inline void _sm_free(_sm_user* frame) +{ + if (frame->free) + free(frame->_ptr); + frame->free = frame->set = false; +} + +#define _SM_DEF(T) template<> T* _sm_init(_sm_user* frame, T init); \ + template<> T* _sm_get(_sm_user* frame); + +_SM_DEF(char); +_SM_DEF(unsigned char); +_SM_DEF(short); +_SM_DEF(unsigned short); +_SM_DEF(int); +_SM_DEF(unsigned int); +_SM_DEF(long); +_SM_DEF(unsigned long); +_SM_DEF(float); +_SM_DEF(double); + +#undef _SM_DEF diff --git a/src/frame.cpp b/src/frame.cpp new file mode 100644 index 0000000..fcbde01 --- /dev/null +++ b/src/frame.cpp @@ -0,0 +1,29 @@ +#include + +#include + +#define BODY(T, U, nm) \ +template<> T* _sm_init(_sm_user* frame, T init) \ +{ \ + printf("hi\n"); \ + frame->free = false; \ + frame-> nm = (U)init; \ + return (T*)&frame-> nm; \ +} \ +template<> T* _sm_get(_sm_user* frame) \ +{ \ + return (T*)&frame-> nm; \ +} + +#define BODY_T(T, S) BODY(T, uint ## S ## _t, _ ## S) + +#define BODY_INT(T, S) BODY_T(T, S) \ + BODY_T(unsigned T, S) + +BODY_INT(char, 8) +BODY_INT(short, 16) +BODY_INT(int, 32) +BODY_INT(long, 64) + +BODY(float, float, _f32) +BODY(double, double, _f64) diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..c88510a --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,14 @@ +#include +#include + +struct _test { + int a, b; +}; + +int main() +{ + _test hi = { 0, 0 }; + auto _a = _sm_init(nullptr, hi); + + return 0; +}