commit
e917cb8d8f
@ -0,0 +1,3 @@
|
|||||||
|
*.o
|
||||||
|
sm-*
|
||||||
|
old-examples/
|
@ -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<T>() - Same as `BOX(T)`
|
||||||
|
//! * T* box<T, true>() - Same as `BOX_EX(T)`
|
||||||
|
//! * T* box<T>(T value) - Same as `BOX_WITH(T, value)`
|
||||||
|
//! * T unbox(T* value) - Same as `UNBOX(value)`
|
||||||
|
//! * T unbox<T, true>(T* value) - Same as `UNBOX_EX(value)`
|
||||||
|
//!
|
||||||
|
//! # Notes
|
||||||
|
//! `UNBOX_EX` and `unbox<T, true>` use `explicit_bzero` to blank the memory before free.
|
||||||
|
//! Whereas `BOX_EX` and `box<T, true>` 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 <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
//#include <strings.h>
|
||||||
|
|
||||||
|
template<typename T, bool Zero = false>
|
||||||
|
inline T* box()
|
||||||
|
{
|
||||||
|
void* ptr = aligned_alloc(alignof(T), sizeof(T));
|
||||||
|
if constexpr(Zero) bzero(ptr, sizeof(T));
|
||||||
|
|
||||||
|
return (T*)ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline T* box(T val)
|
||||||
|
{
|
||||||
|
T* ptr = box<T>();
|
||||||
|
*ptr = val;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, bool Zero = false>
|
||||||
|
inline T unbox(T* boxed)
|
||||||
|
{
|
||||||
|
T val = *boxed;
|
||||||
|
if constexpr(Zero) explicit_bzero((void*)boxed, sizeof(T));
|
||||||
|
free((void*)boxed);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline static T _unbox_explicit(T* boxed)
|
||||||
|
{
|
||||||
|
return unbox<T, true>(boxed);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BOX(T) box<T>()
|
||||||
|
#define BOX_EX(T) box<T, true>()
|
||||||
|
#define BOX_WITH(T, val) box<T>(val)
|
||||||
|
|
||||||
|
#define UNBOX_EX(val) _unbox_explicit(val)
|
||||||
|
#define UNBOX(val) unbox(val)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#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 */
|
@ -0,0 +1,90 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "box.h"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#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<typename T>
|
||||||
|
inline T* _sm_init(_sm_user* frame, T init)
|
||||||
|
{
|
||||||
|
frame->free = true;
|
||||||
|
|
||||||
|
T* ptr = box<T>();
|
||||||
|
*ptr = init;
|
||||||
|
return (T*) (frame->_ptr = (void*)ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline T** _sm_init(_sm_user* frame, T* init)
|
||||||
|
{
|
||||||
|
frame->free = false;
|
||||||
|
frame->_ptr = (void*)init;
|
||||||
|
|
||||||
|
return (T**) &frame->_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
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<T>(_sm_user* frame, T init); \
|
||||||
|
template<> T* _sm_get<T>(_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
|
@ -0,0 +1,29 @@
|
|||||||
|
#include <frame.h>
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
#define BODY(T, U, nm) \
|
||||||
|
template<> T* _sm_init<T>(_sm_user* frame, T init) \
|
||||||
|
{ \
|
||||||
|
printf("hi\n"); \
|
||||||
|
frame->free = false; \
|
||||||
|
frame-> nm = (U)init; \
|
||||||
|
return (T*)&frame-> nm; \
|
||||||
|
} \
|
||||||
|
template<> T* _sm_get<T>(_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)
|
@ -0,0 +1,14 @@
|
|||||||
|
#include <frame.h>
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
struct _test {
|
||||||
|
int a, b;
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
_test hi = { 0, 0 };
|
||||||
|
auto _a = _sm_init(nullptr, hi);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in new issue