initial commit

lib
Avril 3 years ago
commit e917cb8d8f
Signed by: flanchan
GPG Key ID: 284488987C31F630

3
.gitignore vendored

@ -0,0 +1,3 @@
*.o
sm-*
old-examples/

@ -0,0 +1 @@
PROJECT=sm

@ -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…
Cancel
Save