Started to fix some runtime bugs.

This commit is contained in:
2023-05-08 20:54:24 -04:00
parent 59042a162c
commit d00de42969
14 changed files with 298 additions and 42 deletions

View File

@ -210,6 +210,9 @@ char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED";
};
// Dynamic String
// This is directly based off the ZPL string api.
// They used a header pattern
// I kept it for simplicty of porting but its not necessary to keep it that way.
struct String
{
struct Header
@ -265,8 +268,11 @@ char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED";
if ( ! str )
mem_set( allocation, 0, alloc_size );
Header header = { allocator, length, length };
String result = { rcast( char*, allocation) + header_size };
Header&
header = * rcast(Header*, allocation);
header = { allocator, length, length };
String result = { rcast( char*, allocation) + header_size };
if ( length && str )
mem_copy( result, str, length );
@ -453,7 +459,7 @@ char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED";
Header& get_header()
{
return pcast( Header, Data[ - sizeof( Header ) ] );
return *(Header*)(Data - sizeof(Header));
}
sw length() const
@ -551,6 +557,11 @@ char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED";
struct String_POD
{
char* Data;
operator String()
{
return * rcast(String*, this);
}
};
static_assert( sizeof( String_POD ) == sizeof( String ), "String is not a POD" );
#pragma endregion String

View File

@ -1213,13 +1213,11 @@ namespace gen
Code&
t_void_write = ccast( Code, t_void );
t_void_write = def_type( name(void) );
t_void_write->Readonly = true;
# define def_constant_code_type( Type_ ) \
Code& \
t_##Type_##write = ccast( Code, type_ns(Type_) ); \
t_##Type_##write = def_type( name(Type_) ); \
t_##Type_##write->Readonly = true;
# define def_constant_code_type( Type_ ) \
Code& \
t_##Type_##_write = ccast( Code, type_ns(Type_) ); \
t_##Type_##_write = def_type( name(Type_) ); \
def_constant_code_type( int );
def_constant_code_type( bool );
@ -1248,17 +1246,51 @@ namespace gen
spec_constexpr_write = ccast( Code, spec_constexpr );
spec_constexpr_write = def_specifiers( 1, ESpecifier::Constexpr );
# define def_constant_spec( Type_, ... ) \
Code& \
spec_##Type_##write = ccast( Code, spec_##Type_); \
spec_##Type_##write = def_specifiers( macro_num_args(__VA_ARGS__), __VA_ARGS__); \
spec_##Type_##write.lock()
# define def_constant_spec( Type_, ... ) \
Code& \
spec_##Type_##_write = ccast( Code, spec_##Type_); \
spec_##Type_##_write = def_specifiers( macro_num_args(__VA_ARGS__), __VA_ARGS__); \
def_constant_spec( const, ESpecifier::Const );
def_constant_spec( inline, ESpecifier::Inline );
# undef def_constant_spec
}
void deinit()
{
using namespace StaticData;
s32 left = array_count( CodePools );
do
{
Pool* code_pool = & CodePools[left];
pool_free( code_pool );
}
while ( left--, left );
left = array_count( CodeEntriesArenas );
do
{
Arena* code_entries_arena = & CodeEntriesArenas[left];
arena_free( code_entries_arena );
}
while ( left--, left );
left = array_count( StringArenas );
do
{
Arena* string_arena = & StringArenas[left];
arena_free( string_arena );
}
while ( left--, left );
str_tbl_destroy( & StringMap );
type_tbl_destroy( & TypeMap );
array_free( CodePools );
array_free( CodeEntriesArenas );
}
void clear_code_memory()
{
using namespace StaticData;
@ -1316,18 +1348,20 @@ namespace gen
// Will either make or retrive a code string.
StringCached get_cached_string( StrC str )
{
s32 hash_length = str.Len > kilobytes(1) ? kilobytes(1) : str.Len;
u32 key = crc32( str.Ptr, hash_length );
String* result = str_tbl_get( & StaticData::StringMap, key );
s32 hash_length = str.Len > kilobytes(1) ? kilobytes(1) : str.Len;
u32 key = crc32( str.Ptr, hash_length );
{
String* result = str_tbl_get( & StaticData::StringMap, key );
if ( result )
return * result;
if ( result )
return * result;
}
* result = String::make( get_string_allocator( str.Len ), str.Ptr );
String result = String::make( get_string_allocator( str.Len ), str.Ptr );
str_tbl_set( & StaticData::StringMap, key, * result );
str_tbl_set( & StaticData::StringMap, key, result );
return * result;
return result;
}
/*

View File

@ -235,12 +235,12 @@ namespace gen
enum Type : u32
{
Invalid,
# define Entry( Specifier, Code ) Specifier,
Define_Specifiers
# undef Entry
Num_Specifiers,
Invalid,
};
// Specifier to string
@ -669,14 +669,8 @@ namespace gen
inline
Code& operator=( Code other )
{
if ( ast == nullptr )
{
log_failure("Attempt to set with a null AST!");
return *this;
}
#ifdef GEN_ENFORCE_READONLY_AST
if ( ast->Readonly )
if ( ast && ast->Readonly )
{
log_failure("Attempted to set a readonly AST!");
return *this;
@ -738,6 +732,8 @@ namespace gen
// This currently just initializes the CodePool.
void init();
void deinit();
/*
Use this only if you know you generated the code you needed to a file.
And rather get rid of current code asts instead of growing the pool memory.