From d00de42969e2b9a67b586e0a696a77aff9ac12e2 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Mon, 8 May 2023 20:54:24 -0400 Subject: [PATCH] Started to fix some runtime bugs. --- .vscode/c_cpp_properties.json | 2 +- .vscode/gencpp.natvis | 31 +++++++++++++ .vscode/gencpp_lldbvis.py | 84 +++++++++++++++++++++++++++++++++++ .vscode/launch.json | 28 ++++++++++++ .vscode/settings.json | 3 +- gencpp.vcxproj | 15 ++++--- gencpp.vcxproj.filters | 53 ++++++++++++++++++++++ gencpp.vcxproj.user | 10 +++++ project/Bloat.hpp | 17 +++++-- project/gen.cpp | 72 ++++++++++++++++++++++-------- project/gen.hpp | 12 ++--- scripts/build.ci.ps1 | 2 +- test/test.cpp | 4 +- x64/Debug/gencpp.log | 7 +++ 14 files changed, 298 insertions(+), 42 deletions(-) create mode 100644 .vscode/gencpp.natvis create mode 100644 .vscode/gencpp_lldbvis.py create mode 100644 .vscode/launch.json create mode 100644 x64/Debug/gencpp.log diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 9de7779..d9b1de6 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -13,7 +13,7 @@ ], "windowsSdkVersion": "10.0.19041.0", "compilerPath": "C:/Users/Ed/scoop/apps/llvm/current/bin/clang++.exe", - "intelliSenseMode": "windows-clang-x64" + "intelliSenseMode": "windows-clang-x64", } ], "version": 4 diff --git a/.vscode/gencpp.natvis b/.vscode/gencpp.natvis new file mode 100644 index 0000000..dc4afb3 --- /dev/null +++ b/.vscode/gencpp.natvis @@ -0,0 +1,31 @@ + + + + + null + {Data,na} + + + + + {(Header*)((char*)Data - sizeof(Header))} + + + ((Header*)((char*)Data - sizeof(Header)))->Allocator + ((Header*)((char*)Data - sizeof(Header)))->Length + ((Header*)((char*)Data - sizeof(Header)))->Capacity + + + + + + + Length: {Length}, Capacity: {Capacity} + + Allocator + Length + Capacity + + + + diff --git a/.vscode/gencpp_lldbvis.py b/.vscode/gencpp_lldbvis.py new file mode 100644 index 0000000..872b854 --- /dev/null +++ b/.vscode/gencpp_lldbvis.py @@ -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 diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..c05ad50 --- /dev/null +++ b/.vscode/launch.json @@ -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" + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json index 02706d3..e1cdd77 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -18,5 +18,6 @@ "algorithm": "cpp", "limits": "cpp" }, - "C_Cpp.intelliSenseEngineFallback": "disabled" + "C_Cpp.intelliSenseEngineFallback": "disabled", + "mesonbuild.configureOnOpen": true } \ No newline at end of file diff --git a/gencpp.vcxproj b/gencpp.vcxproj index 29e3f11..e63b03f 100644 --- a/gencpp.vcxproj +++ b/gencpp.vcxproj @@ -76,17 +76,17 @@ WIN32;NDEBUG;$(NMakePreprocessorDefinitions) - $(ProjectDir)scripts\build.ps1 - $(ProjectDir)scripts\build.ps1 - $(ProjectDir)scripts\clean.ps1 + powershell.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\build.ps1" + powershell.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\build.ps1" + powershell.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\clean.ps1" gen_time;$(NMakePreprocessorDefinitions) $(ProjectDir)thirdparty;$(ProjectDir)project;$(ProjectDir)test;$(IncludePath) $(ProjectDir)project;$(ProjectDir)test;$(SourcePath) - $(ProjectDir)scripts\build.ps1 - $(ProjectDir)scripts\build.ps1 - $(ProjectDir)scripts\clean.ps1 + powershell.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\build.ps1" + powershell.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\build.ps1" + powershell.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\clean.ps1" gen_time;$(NMakePreprocessorDefinitions) $(ProjectDir)thirdparty;$(ProjectDir)project;$(ProjectDir)test;$(IncludePath) $(ProjectDir)project;$(ProjectDir)test;$(SourcePath) @@ -124,6 +124,9 @@ + + + diff --git a/gencpp.vcxproj.filters b/gencpp.vcxproj.filters index c04a89b..b8bee7a 100644 --- a/gencpp.vcxproj.filters +++ b/gencpp.vcxproj.filters @@ -14,4 +14,57 @@ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/gencpp.vcxproj.user b/gencpp.vcxproj.user index 966b4ff..568a826 100644 --- a/gencpp.vcxproj.user +++ b/gencpp.vcxproj.user @@ -3,4 +3,14 @@ true + + false + WindowsLocalDebugger + C:\projects\gencpp\test\gen\build\gencpp.exe + + + false + WindowsLocalDebugger + C:\projects\gencpp\test\gen\build\gencpp.exe + \ No newline at end of file diff --git a/project/Bloat.hpp b/project/Bloat.hpp index 201fdf9..2f011d0 100644 --- a/project/Bloat.hpp +++ b/project/Bloat.hpp @@ -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 diff --git a/project/gen.cpp b/project/gen.cpp index 05ffa9b..f43795b 100644 --- a/project/gen.cpp +++ b/project/gen.cpp @@ -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; } /* diff --git a/project/gen.hpp b/project/gen.hpp index c06b395..9e56de0 100644 --- a/project/gen.hpp +++ b/project/gen.hpp @@ -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. diff --git a/scripts/build.ci.ps1 b/scripts/build.ci.ps1 index bee5d18..0bf6e2d 100644 --- a/scripts/build.ci.ps1 +++ b/scripts/build.ci.ps1 @@ -52,7 +52,7 @@ $path_scripts = Join-Path $path_root scripts $gencpp = Join-Path $path_gen_build gencpp.exe Push-location $path_gen - & $gencpp + # & $gencpp Pop-Location diff --git a/test/test.cpp b/test/test.cpp index e5e4ab1..996394c 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -14,11 +14,9 @@ int gen_main() { Memory::setup(); - log_fmt("\nPress any key after attaching to process\n"); - getchar(); - gen::init(); + gen::deinit(); Memory::cleanup(); return 0; } diff --git a/x64/Debug/gencpp.log b/x64/Debug/gencpp.log new file mode 100644 index 0000000..6f97317 --- /dev/null +++ b/x64/Debug/gencpp.log @@ -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