Started to fix some runtime bugs.

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

View File

@ -13,7 +13,7 @@
], ],
"windowsSdkVersion": "10.0.19041.0", "windowsSdkVersion": "10.0.19041.0",
"compilerPath": "C:/Users/Ed/scoop/apps/llvm/current/bin/clang++.exe", "compilerPath": "C:/Users/Ed/scoop/apps/llvm/current/bin/clang++.exe",
"intelliSenseMode": "windows-clang-x64" "intelliSenseMode": "windows-clang-x64",
} }
], ],
"version": 4 "version": 4

31
.vscode/gencpp.natvis vendored Normal file
View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<Type Name="String">
<DisplayString Condition="Data == nullptr">null</DisplayString>
<DisplayString>{Data,na}</DisplayString>
<Expand>
<!-- Define a synthetic child element for the Header -->
<Synthetic Name="Header">
<!-- Construct a Header object from the Data pointer -->
<DisplayString>{(Header*)((char*)Data - sizeof(Header))}</DisplayString>
<!-- Define the children of the synthetic element -->
<Expand>
<Item Name="Allocator">((Header*)((char*)Data - sizeof(Header)))->Allocator</Item>
<Item Name="Length">((Header*)((char*)Data - sizeof(Header)))->Length</Item>
<Item Name="Capacity">((Header*)((char*)Data - sizeof(Header)))->Capacity</Item>
</Expand>
</Synthetic>
</Expand>
</Type>
<Type Name="String::Header">
<DisplayString>Length: {Length}, Capacity: {Capacity}</DisplayString>
<Expand>
<Item Name="Allocator">Allocator</Item>
<Item Name="Length">Length</Item>
<Item Name="Capacity">Capacity</Item>
</Expand>
</Type>
</AutoVisualizer>

84
.vscode/gencpp_lldbvis.py vendored Normal file
View File

@ -0,0 +1,84 @@
import lldb
class String_SyntheticChildrenProvider:
def __init__(self, valobj, internal_dict):
self.valobj = valobj
def num_children(self):
return 3
def get_child_index(self, name):
if name == "Data":
return 0
if name == "Length":
return 1
if name == "Capacity":
return 2
return None
def get_child_at_index(self, index):
if index == 0:
return self.valobj.GetChildMemberWithName("Data")
data = self.valobj.GetChildMemberWithName("Data")
header_ptr = data.GetValueAsUnsigned() - 16
target = self.valobj.GetTarget()
header_type = target.FindFirstType("gen::String::Header")
header = self.valobj.CreateValueFromAddress("Header", header_ptr, header_type)
if index == 1:
return header.GetChildMemberWithName("Length")
if index == 2:
return header.GetChildMemberWithName("Capacity")
return None
def update(self):
pass
def list_synthetic_providers(debugger):
print("Listing synthetic providers (start)")
num_categories = debugger.GetNumCategories()
print("Debugger language categories count:", num_categories)
cpp_category = None
for i in range(num_categories):
print("WERE HERE")
print(debugger)
cat = debugger.GetCategoryAtIndex(i)
print("Category name: {}, language: {}".format(cat.GetName(), cat.GetLanguage()))
if cat.GetLanguage() == lldb.eLanguageTypeC_plus_plus:
cpp_category = cat
break
if not cpp_category:
print("Could not get C++ category")
return
synthetic_providers = cpp_category.GetSyntheticChildren()
if not synthetic_providers:
print("Could not get synthetic children")
return
num_providers = synthetic_providers.GetSize()
print("Number of synthetic providers:", num_providers)
for i in range(num_providers):
provider = synthetic_providers.GetSyntheticChildAtIndex(i)
print("Provider regex: {}, class name: {}".format(provider.GetRegex(), provider.GetDescription()))
print("Listing synthetic providers (finish)")
def __lldb_init_module(debugger, internal_dict):
print("Importing the String visualization")
debugger.HandleCommand("type synthetic add -x '^gen::String$' -l gencpp_libvis.String_SyntheticChildrenProvider")
print("Before list_synthetic_providers")
list_synthetic_providers(debugger)
lldb.debugger = None

28
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,28 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "lldb",
"request": "launch",
"name": "Debug gentime lldb",
"program": "${workspaceFolder}/test/gen/build/gencpp.exe",
"args": [],
"cwd": "${workspaceFolder}",
"postRunCommands": [
"command script import \"${workspaceFolder}/.vscode/gencpp_lldbvis.py\""
]
},
{
"type": "cppvsdbg",
"request": "launch",
"name": "Debug gentime vsdbg",
"program": "${workspaceFolder}/test/gen/build/gencpp.exe",
"args": [],
"cwd": "${workspaceFolder}",
"visualizerFile": "${workspaceFolder}/.vscode/gencpp.natvis"
}
]
}

View File

@ -18,5 +18,6 @@
"algorithm": "cpp", "algorithm": "cpp",
"limits": "cpp" "limits": "cpp"
}, },
"C_Cpp.intelliSenseEngineFallback": "disabled" "C_Cpp.intelliSenseEngineFallback": "disabled",
"mesonbuild.configureOnOpen": true
} }

View File

@ -76,17 +76,17 @@
<NMakePreprocessorDefinitions>WIN32;NDEBUG;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions> <NMakePreprocessorDefinitions>WIN32;NDEBUG;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<NMakeBuildCommandLine>$(ProjectDir)scripts\build.ps1</NMakeBuildCommandLine> <NMakeBuildCommandLine>powershell.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\build.ps1"</NMakeBuildCommandLine>
<NMakeReBuildCommandLine>$(ProjectDir)scripts\build.ps1</NMakeReBuildCommandLine> <NMakeReBuildCommandLine>powershell.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\build.ps1"</NMakeReBuildCommandLine>
<NMakeCleanCommandLine>$(ProjectDir)scripts\clean.ps1</NMakeCleanCommandLine> <NMakeCleanCommandLine>powershell.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\clean.ps1"</NMakeCleanCommandLine>
<NMakePreprocessorDefinitions>gen_time;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions> <NMakePreprocessorDefinitions>gen_time;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
<IncludePath>$(ProjectDir)thirdparty;$(ProjectDir)project;$(ProjectDir)test;$(IncludePath)</IncludePath> <IncludePath>$(ProjectDir)thirdparty;$(ProjectDir)project;$(ProjectDir)test;$(IncludePath)</IncludePath>
<SourcePath>$(ProjectDir)project;$(ProjectDir)test;$(SourcePath)</SourcePath> <SourcePath>$(ProjectDir)project;$(ProjectDir)test;$(SourcePath)</SourcePath>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<NMakeBuildCommandLine>$(ProjectDir)scripts\build.ps1</NMakeBuildCommandLine> <NMakeBuildCommandLine>powershell.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\build.ps1"</NMakeBuildCommandLine>
<NMakeReBuildCommandLine>$(ProjectDir)scripts\build.ps1</NMakeReBuildCommandLine> <NMakeReBuildCommandLine>powershell.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\build.ps1"</NMakeReBuildCommandLine>
<NMakeCleanCommandLine>$(ProjectDir)scripts\clean.ps1</NMakeCleanCommandLine> <NMakeCleanCommandLine>powershell.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\clean.ps1"</NMakeCleanCommandLine>
<NMakePreprocessorDefinitions>gen_time;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions> <NMakePreprocessorDefinitions>gen_time;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
<IncludePath>$(ProjectDir)thirdparty;$(ProjectDir)project;$(ProjectDir)test;$(IncludePath)</IncludePath> <IncludePath>$(ProjectDir)thirdparty;$(ProjectDir)project;$(ProjectDir)test;$(IncludePath)</IncludePath>
<SourcePath>$(ProjectDir)project;$(ProjectDir)test;$(SourcePath)</SourcePath> <SourcePath>$(ProjectDir)project;$(ProjectDir)test;$(SourcePath)</SourcePath>
@ -124,6 +124,9 @@
<ClCompile Include="test\gen\build\meson-private\sanitycheckcpp.cc" /> <ClCompile Include="test\gen\build\meson-private\sanitycheckcpp.cc" />
<ClCompile Include="test\test.cpp" /> <ClCompile Include="test\test.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Natvis Include=".vscode\gencpp.natvis" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
</ImportGroup> </ImportGroup>

View File

@ -14,4 +14,57 @@
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions> <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
</Filter> </Filter>
</ItemGroup> </ItemGroup>
<ItemGroup>
<ClCompile Include="project\Bloat.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="project\gen.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="project\gen.singleheader.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="test\gen\build\meson-private\sanitycheckc.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="test\gen\build\meson-private\sanitycheckcpp.cc">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="test\test.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="project\Bloat.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="project\Bloat.redef.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="project\Bloat.undef.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="project\gen.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="thirdparty\zpl.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include=".editorconfig" />
<None Include="Readme.md" />
<None Include="scripts\build.ci.ps1" />
<None Include="scripts\build.ps1" />
<None Include="scripts\clean.ps1" />
<None Include="scripts\get_sources.ps1" />
<None Include="scripts\meson.build" />
<None Include="singleheader\genc.refactor" />
<None Include="test\gen\meson.build" />
<None Include="test\meson.build" />
<None Include="test\Readme.md" />
</ItemGroup>
<ItemGroup>
<Natvis Include=".vscode\gencpp.natvis" />
</ItemGroup>
</Project> </Project>

View File

@ -3,4 +3,14 @@
<PropertyGroup> <PropertyGroup>
<ShowAllFiles>true</ShowAllFiles> <ShowAllFiles>true</ShowAllFiles>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LocalDebuggerAttach>false</LocalDebuggerAttach>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerCommand>C:\projects\gencpp\test\gen\build\gencpp.exe</LocalDebuggerCommand>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LocalDebuggerAttach>false</LocalDebuggerAttach>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerCommand>C:\projects\gencpp\test\gen\build\gencpp.exe</LocalDebuggerCommand>
</PropertyGroup>
</Project> </Project>

View File

@ -210,6 +210,9 @@ char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED";
}; };
// Dynamic String // 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 String
{ {
struct Header struct Header
@ -265,8 +268,11 @@ char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED";
if ( ! str ) if ( ! str )
mem_set( allocation, 0, alloc_size ); mem_set( allocation, 0, alloc_size );
Header header = { allocator, length, length }; Header&
String result = { rcast( char*, allocation) + header_size }; header = * rcast(Header*, allocation);
header = { allocator, length, length };
String result = { rcast( char*, allocation) + header_size };
if ( length && str ) if ( length && str )
mem_copy( result, str, length ); mem_copy( result, str, length );
@ -453,7 +459,7 @@ char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED";
Header& get_header() Header& get_header()
{ {
return pcast( Header, Data[ - sizeof( Header ) ] ); return *(Header*)(Data - sizeof(Header));
} }
sw length() const sw length() const
@ -551,6 +557,11 @@ char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED";
struct String_POD struct String_POD
{ {
char* Data; char* Data;
operator String()
{
return * rcast(String*, this);
}
}; };
static_assert( sizeof( String_POD ) == sizeof( String ), "String is not a POD" ); static_assert( sizeof( String_POD ) == sizeof( String ), "String is not a POD" );
#pragma endregion String #pragma endregion String

View File

@ -1213,13 +1213,11 @@ namespace gen
Code& Code&
t_void_write = ccast( Code, t_void ); t_void_write = ccast( Code, t_void );
t_void_write = def_type( name(void) ); t_void_write = def_type( name(void) );
t_void_write->Readonly = true;
# define def_constant_code_type( Type_ ) \ # define def_constant_code_type( Type_ ) \
Code& \ Code& \
t_##Type_##write = ccast( Code, type_ns(Type_) ); \ t_##Type_##_write = ccast( Code, type_ns(Type_) ); \
t_##Type_##write = def_type( name(Type_) ); \ t_##Type_##_write = def_type( name(Type_) ); \
t_##Type_##write->Readonly = true;
def_constant_code_type( int ); def_constant_code_type( int );
def_constant_code_type( bool ); def_constant_code_type( bool );
@ -1248,17 +1246,51 @@ namespace gen
spec_constexpr_write = ccast( Code, spec_constexpr ); spec_constexpr_write = ccast( Code, spec_constexpr );
spec_constexpr_write = def_specifiers( 1, ESpecifier::Constexpr ); spec_constexpr_write = def_specifiers( 1, ESpecifier::Constexpr );
# define def_constant_spec( Type_, ... ) \ # define def_constant_spec( Type_, ... ) \
Code& \ Code& \
spec_##Type_##write = ccast( Code, spec_##Type_); \ spec_##Type_##_write = ccast( Code, spec_##Type_); \
spec_##Type_##write = def_specifiers( macro_num_args(__VA_ARGS__), __VA_ARGS__); \ spec_##Type_##_write = def_specifiers( macro_num_args(__VA_ARGS__), __VA_ARGS__); \
spec_##Type_##write.lock()
def_constant_spec( const, ESpecifier::Const ); def_constant_spec( const, ESpecifier::Const );
def_constant_spec( inline, ESpecifier::Inline ); def_constant_spec( inline, ESpecifier::Inline );
# undef def_constant_spec # 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() void clear_code_memory()
{ {
using namespace StaticData; using namespace StaticData;
@ -1316,18 +1348,20 @@ namespace gen
// Will either make or retrive a code string. // Will either make or retrive a code string.
StringCached get_cached_string( StrC str ) StringCached get_cached_string( StrC str )
{ {
s32 hash_length = str.Len > kilobytes(1) ? kilobytes(1) : str.Len; s32 hash_length = str.Len > kilobytes(1) ? kilobytes(1) : str.Len;
u32 key = crc32( str.Ptr, hash_length ); u32 key = crc32( str.Ptr, hash_length );
String* result = str_tbl_get( & StaticData::StringMap, key ); {
String* result = str_tbl_get( & StaticData::StringMap, key );
if ( result ) if ( result )
return * 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 enum Type : u32
{ {
Invalid,
# define Entry( Specifier, Code ) Specifier, # define Entry( Specifier, Code ) Specifier,
Define_Specifiers Define_Specifiers
# undef Entry # undef Entry
Num_Specifiers, Num_Specifiers,
Invalid,
}; };
// Specifier to string // Specifier to string
@ -669,14 +669,8 @@ namespace gen
inline inline
Code& operator=( Code other ) Code& operator=( Code other )
{ {
if ( ast == nullptr )
{
log_failure("Attempt to set with a null AST!");
return *this;
}
#ifdef GEN_ENFORCE_READONLY_AST #ifdef GEN_ENFORCE_READONLY_AST
if ( ast->Readonly ) if ( ast && ast->Readonly )
{ {
log_failure("Attempted to set a readonly AST!"); log_failure("Attempted to set a readonly AST!");
return *this; return *this;
@ -738,6 +732,8 @@ namespace gen
// This currently just initializes the CodePool. // This currently just initializes the CodePool.
void init(); void init();
void deinit();
/* /*
Use this only if you know you generated the code you needed to a file. 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. And rather get rid of current code asts instead of growing the pool memory.

View File

@ -52,7 +52,7 @@ $path_scripts = Join-Path $path_root scripts
$gencpp = Join-Path $path_gen_build gencpp.exe $gencpp = Join-Path $path_gen_build gencpp.exe
Push-location $path_gen Push-location $path_gen
& $gencpp # & $gencpp
Pop-Location Pop-Location

View File

@ -14,11 +14,9 @@ int gen_main()
{ {
Memory::setup(); Memory::setup();
log_fmt("\nPress any key after attaching to process\n");
getchar();
gen::init(); gen::init();
gen::deinit();
Memory::cleanup(); Memory::cleanup();
return 0; return 0;
} }

7
x64/Debug/gencpp.log Normal file
View File

@ -0,0 +1,7 @@

Building Test
ninja: Entering directory `C:\projects\gencpp\test\gen\build'
[1/2] Compiling C++ object gencpp.exe.p/.._test.cpp.obj
[2/2] Linking target gencpp.exe