Website Summary Files Commits Branches @commit @diff @stats
diff options
context:
space:
mode:
Commit22b321bb4497543493010f57587c7a9dceb839b6 (patch)
Author
 dtrendafilov <trendafilov.dn@gmail.com>
2021-09-21 22:48:52 +0300
Committer
 GitHub <noreply@github.com>
2021-09-21 22:48:52 +0300
Files672d53f7d257df54d2222252bd2441f12b3be950
IPL-22b321bb4497543493010f57587c7a9dceb839b6.tar
IPL-22b321bb4497543493010f57587c7a9dceb839b6.tar.gz
IPL-22b321bb4497543493010f57587c7a9dceb839b6.zip
Parentf110794b0d57e47e335ae5eeffbb18a7a80580ad (diff)
Parent2f9dea35cff40a676b4603b8ffbd1f2669a4195a (diff)
Merge pull request #115 from SofiaCPP/feature/gctest
Add app to test GC implementations
51 files changed, 4735 insertions, 22 deletions
-rw-r--r--.gitignore2
-rw-r--r--JSImpl/solution/JSImpl.sln41
-rw-r--r--JSImpl/solution/Makefile20
-rw-r--r--JSImpl/solution/genie.lua3
-rw-r--r--compile_commands.json80
-rw-r--r--gctest/.clang-format148
-rw-r--r--gctest/README.md21
-rw-r--r--gctest/solution/Makefile48
-rw-r--r--gctest/solution/dummy_gc.make243
-rw-r--r--gctest/solution/dummy_gc.vcxproj245
-rw-r--r--gctest/solution/dummy_gc.vcxproj.filters13
-rw-r--r--gctest/solution/gctest.sln54
-rw-r--r--gctest/solution/genie.lua72
-rw-r--r--gctest/solution/leak_gc.make243
-rw-r--r--gctest/solution/leak_gc.vcxproj245
-rw-r--r--gctest/solution/leak_gc.vcxproj.filters13
-rw-r--r--gctest/solution/test_bench.make256
-rw-r--r--gctest/solution/test_bench.vcxproj238
-rw-r--r--gctest/solution/test_bench.vcxproj.filters16
-rw-r--r--gctest/src/cxxopts.hpp2114
-rw-r--r--gctest/src/flat_hash_map/bytell_hash_map.hpp (renamed from gctest/flat_hash_map/bytell_hash_map.hpp)0
-rw-r--r--gctest/src/flat_hash_map/flat_hash_map.hpp (renamed from gctest/flat_hash_map/flat_hash_map.hpp)0
-rw-r--r--gctest/src/flat_hash_map/unordered_map.hpp (renamed from gctest/flat_hash_map/unordered_map.hpp)0
-rw-r--r--gctest/src/gc.h60
-rw-r--r--gctest/src/gc_dummy.cpp71
-rw-r--r--gctest/src/gc_leak.cpp25
-rw-r--r--gctest/src/main.cpp392
-rw-r--r--gctest/src/minitrace.cpp1
-rw-r--r--gctest/src/minitrace/.gitignore (renamed from gctest/minitrace/.gitignore)0
-rw-r--r--gctest/src/minitrace/LICENSE (renamed from gctest/minitrace/LICENSE)0
-rw-r--r--gctest/src/minitrace/Makefile (renamed from gctest/minitrace/Makefile)0
-rw-r--r--gctest/src/minitrace/README.md (renamed from gctest/minitrace/README.md)0
-rw-r--r--gctest/src/minitrace/minitrace.c (renamed from gctest/minitrace/minitrace.c)4
-rw-r--r--gctest/src/minitrace/minitrace.h (renamed from gctest/minitrace/minitrace.h)0
-rw-r--r--gctest/src/minitrace/minitrace_test.cpp (renamed from gctest/minitrace/minitrace_test.cpp)0
-rw-r--r--gctest/src/minitrace/minitrace_test_mt.cpp (renamed from gctest/minitrace/minitrace_test_mt.cpp)0
-rw-r--r--gctest/src/minitrace/msvc/minitrace.sln (renamed from gctest/minitrace/msvc/minitrace.sln)0
-rw-r--r--gctest/src/minitrace/msvc/minitrace.vcxproj (renamed from gctest/minitrace/msvc/minitrace.vcxproj)0
-rw-r--r--gctest/src/minitrace/msvc/minitrace.vcxproj.filters (renamed from gctest/minitrace/msvc/minitrace.vcxproj.filters)0
-rw-r--r--gctest/src/weighted_action.h33
-rw-r--r--spasm/solution/spasm.vcxproj4
-rw-r--r--spasm/solution/spasm_lib.vcxproj16
-rw-r--r--spasm/solution/spasm_lib.vcxproj.filters12
-rw-r--r--spasm/solution/sprt.vcxproj4
-rw-r--r--spasm/solution/sprun.vcxproj4
-rw-r--r--spasm/src/asm/lexdump.cpp6
-rw-r--r--spasm/src/asm/lexdump3.cpp6
-rw-r--r--spasm/src/spasm.cpp1
-rw-r--r--spasm/src/spasm.hpp1
-rw-r--r--spasm/src/spasm_impl.hpp1
-rw-r--r--spasm/src/value.hpp1
diff --git a/.gitignore b/.gitignore
index 3c4efe2..e12e5ee 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,6 +21,8 @@ bld/
[Bb]in/
[Oo]bj/
[Ll]og/
+# clangd cache folder
+.cache/
# Visual Studio 2015 cache/options directory
.vs/
diff --git a/JSImpl/solution/JSImpl.sln b/JSImpl/solution/JSImpl.sln
index bb2638e..89a91b3 100644
--- a/JSImpl/solution/JSImpl.sln
+++ b/JSImpl/solution/JSImpl.sln
@@ -7,6 +7,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "gtest", "gtest", "{1BAF0A7D
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "JSImpl", "JSImpl", "{C30B5025-2FEB-CEC0-3803-5A97A4613522}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "gctest", "gctest", "{5EF0341D-CACF-B3B8-D3E7-3E8F3F461A1A}"
+EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sprun", "..\..\spasm\solution\sprun.vcxproj", "{FD605F10-6975-87C1-32F7-2A219ECA83F2}"
ProjectSection(ProjectDependencies) = postProject
{AE0A9E7C-9A41-9F0D-432E-85102F441B0F} = {AE0A9E7C-9A41-9F0D-432E-85102F441B0F}
@@ -44,6 +46,18 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "spasm", "..\..\spasm\soluti
{3F16CDE1-AB80-8158-F4BE-32FE60685FAD} = {3F16CDE1-AB80-8158-F4BE-32FE60685FAD}
EndProjectSection
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_bench", "..\..\gctest\solution\test_bench.vcxproj", "{A41847E7-90D0-8834-F9D7-6190E5AE2325}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "leak_gc", "..\..\gctest\solution\leak_gc.vcxproj", "{8BDD0170-F7BC-800B-00D5-0BE26C33E76C}"
+ ProjectSection(ProjectDependencies) = postProject
+ {A41847E7-90D0-8834-F9D7-6190E5AE2325} = {A41847E7-90D0-8834-F9D7-6190E5AE2325}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dummy_gc", "..\..\gctest\solution\dummy_gc.vcxproj", "{3AED02FA-26BA-5D05-4FD3-4BAD3BFF9293}"
+ ProjectSection(ProjectDependencies) = postProject
+ {A41847E7-90D0-8834-F9D7-6190E5AE2325} = {A41847E7-90D0-8834-F9D7-6190E5AE2325}
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@@ -132,6 +146,30 @@ Global
{69185F10-D52C-87C1-9EAE-2A210A8283F2}.Release|Win32.Build.0 = Release|Win32
{69185F10-D52C-87C1-9EAE-2A210A8283F2}.Release|x64.ActiveCfg = Release|x64
{69185F10-D52C-87C1-9EAE-2A210A8283F2}.Release|x64.Build.0 = Release|x64
+ {A41847E7-90D0-8834-F9D7-6190E5AE2325}.Debug|Win32.ActiveCfg = Debug|Win32
+ {A41847E7-90D0-8834-F9D7-6190E5AE2325}.Debug|Win32.Build.0 = Debug|Win32
+ {A41847E7-90D0-8834-F9D7-6190E5AE2325}.Debug|x64.ActiveCfg = Debug|x64
+ {A41847E7-90D0-8834-F9D7-6190E5AE2325}.Debug|x64.Build.0 = Debug|x64
+ {A41847E7-90D0-8834-F9D7-6190E5AE2325}.Release|Win32.ActiveCfg = Release|Win32
+ {A41847E7-90D0-8834-F9D7-6190E5AE2325}.Release|Win32.Build.0 = Release|Win32
+ {A41847E7-90D0-8834-F9D7-6190E5AE2325}.Release|x64.ActiveCfg = Release|x64
+ {A41847E7-90D0-8834-F9D7-6190E5AE2325}.Release|x64.Build.0 = Release|x64
+ {8BDD0170-F7BC-800B-00D5-0BE26C33E76C}.Debug|Win32.ActiveCfg = Debug|Win32
+ {8BDD0170-F7BC-800B-00D5-0BE26C33E76C}.Debug|Win32.Build.0 = Debug|Win32
+ {8BDD0170-F7BC-800B-00D5-0BE26C33E76C}.Debug|x64.ActiveCfg = Debug|x64
+ {8BDD0170-F7BC-800B-00D5-0BE26C33E76C}.Debug|x64.Build.0 = Debug|x64
+ {8BDD0170-F7BC-800B-00D5-0BE26C33E76C}.Release|Win32.ActiveCfg = Release|Win32
+ {8BDD0170-F7BC-800B-00D5-0BE26C33E76C}.Release|Win32.Build.0 = Release|Win32
+ {8BDD0170-F7BC-800B-00D5-0BE26C33E76C}.Release|x64.ActiveCfg = Release|x64
+ {8BDD0170-F7BC-800B-00D5-0BE26C33E76C}.Release|x64.Build.0 = Release|x64
+ {3AED02FA-26BA-5D05-4FD3-4BAD3BFF9293}.Debug|Win32.ActiveCfg = Debug|Win32
+ {3AED02FA-26BA-5D05-4FD3-4BAD3BFF9293}.Debug|Win32.Build.0 = Debug|Win32
+ {3AED02FA-26BA-5D05-4FD3-4BAD3BFF9293}.Debug|x64.ActiveCfg = Debug|x64
+ {3AED02FA-26BA-5D05-4FD3-4BAD3BFF9293}.Debug|x64.Build.0 = Debug|x64
+ {3AED02FA-26BA-5D05-4FD3-4BAD3BFF9293}.Release|Win32.ActiveCfg = Release|Win32
+ {3AED02FA-26BA-5D05-4FD3-4BAD3BFF9293}.Release|Win32.Build.0 = Release|Win32
+ {3AED02FA-26BA-5D05-4FD3-4BAD3BFF9293}.Release|x64.ActiveCfg = Release|x64
+ {3AED02FA-26BA-5D05-4FD3-4BAD3BFF9293}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -146,5 +184,8 @@ Global
{AE0A9E7C-9A41-9F0D-432E-85102F441B0F} = {9892E17D-8434-0C54-6DEF-1FA8593093A4}
{3F16CDE1-AB80-8158-F4BE-32FE60685FAD} = {9892E17D-8434-0C54-6DEF-1FA8593093A4}
{69185F10-D52C-87C1-9EAE-2A210A8283F2} = {9892E17D-8434-0C54-6DEF-1FA8593093A4}
+ {A41847E7-90D0-8834-F9D7-6190E5AE2325} = {5EF0341D-CACF-B3B8-D3E7-3E8F3F461A1A}
+ {8BDD0170-F7BC-800B-00D5-0BE26C33E76C} = {5EF0341D-CACF-B3B8-D3E7-3E8F3F461A1A}
+ {3AED02FA-26BA-5D05-4FD3-4BAD3BFF9293} = {5EF0341D-CACF-B3B8-D3E7-3E8F3F461A1A}
EndGlobalSection
EndGlobal
diff --git a/JSImpl/solution/Makefile b/JSImpl/solution/Makefile
index 45157d1..78a826a 100644
--- a/JSImpl/solution/Makefile
+++ b/JSImpl/solution/Makefile
@@ -6,7 +6,7 @@ ifndef config
endif
export config
-PROJECTS := JSImpl JSLib Test gmock gtest gtest_main spasm spasm_lib sprt sprun
+PROJECTS := JSImpl JSLib Test dummy_gc gmock gtest gtest_main leak_gc spasm spasm_lib sprt sprun test_bench
.PHONY: all clean help $(PROJECTS)
@@ -52,6 +52,18 @@ sprun: sprt
@echo "==== Building sprun ($(config)) ===="
@${MAKE} --no-print-directory -C ../../spasm/solution -f sprun.make
+test_bench:
+ @echo "==== Building test_bench ($(config)) ===="
+ @${MAKE} --no-print-directory -C ../../gctest/solution -f test_bench.make
+
+leak_gc: test_bench
+ @echo "==== Building leak_gc ($(config)) ===="
+ @${MAKE} --no-print-directory -C ../../gctest/solution -f leak_gc.make
+
+dummy_gc: test_bench
+ @echo "==== Building dummy_gc ($(config)) ===="
+ @${MAKE} --no-print-directory -C ../../gctest/solution -f dummy_gc.make
+
clean:
@${MAKE} --no-print-directory -C ../test -f Test.make clean
@${MAKE} --no-print-directory -C ../test -f gtest.make clean
@@ -63,6 +75,9 @@ clean:
@${MAKE} --no-print-directory -C ../../spasm/solution -f spasm_lib.make clean
@${MAKE} --no-print-directory -C ../../spasm/solution -f spasm.make clean
@${MAKE} --no-print-directory -C ../../spasm/solution -f sprun.make clean
+ @${MAKE} --no-print-directory -C ../../gctest/solution -f test_bench.make clean
+ @${MAKE} --no-print-directory -C ../../gctest/solution -f leak_gc.make clean
+ @${MAKE} --no-print-directory -C ../../gctest/solution -f dummy_gc.make clean
help:
@echo "Usage: make [config=name] [target]"
@@ -86,5 +101,8 @@ help:
@echo " spasm_lib"
@echo " spasm"
@echo " sprun"
+ @echo " test_bench"
+ @echo " leak_gc"
+ @echo " dummy_gc"
@echo ""
@echo "For more information, see https://github.com/bkaradzic/genie"
diff --git a/JSImpl/solution/genie.lua b/JSImpl/solution/genie.lua
index e3720a4..5d36fc8 100644
--- a/JSImpl/solution/genie.lua
+++ b/JSImpl/solution/genie.lua
@@ -49,3 +49,6 @@ solution 'JSImpl'
group 'Spasm'
include '../../spasm/solution/'
+
+ group 'gctest'
+ include '../../gctest/solution/'
diff --git a/compile_commands.json b/compile_commands.json
new file mode 100644
index 0000000..763a143
--- /dev/null
+++ b/compile_commands.json
@@ -0,0 +1,80 @@
+[
+ { "directory": "d:/repo/IPL/JSImpl/test",
+ "command": "g++ -MMD -MP -MP -D_SCL_SECURE_NO_WARNINGS -I\"googletest/googletest/include\" -I\"googletest/googlemock/include\" -I\"..\" -I\"../../spasm/src\" -I\"../../spasm/src/asm\" -Werror -Wall -Wextra -g -std=c++17 -o ../build/obj/Debug/Debug/Test/ASTInterpreterTests.o -c ASTInterpreterTests.cpp",
+ "file": "ASTInterpreterTests.cpp" },
+ { "directory": "d:/repo/IPL/JSImpl/test",
+ "command": "g++ -MMD -MP -MP -D_SCL_SECURE_NO_WARNINGS -I\"googletest/googletest/include\" -I\"googletest/googlemock/include\" -I\"..\" -I\"../../spasm/src\" -I\"../../spasm/src/asm\" -Werror -Wall -Wextra -g -std=c++17 -o ../build/obj/Debug/Debug/Test/CodeGenerationTests.o -c CodeGenerationTests.cpp",
+ "file": "CodeGenerationTests.cpp" },
+ { "directory": "d:/repo/IPL/JSImpl/test",
+ "command": "g++ -MMD -MP -MP -D_SCL_SECURE_NO_WARNINGS -I\"googletest/googletest/include\" -I\"googletest/googlemock/include\" -I\"..\" -I\"../../spasm/src\" -I\"../../spasm/src/asm\" -Werror -Wall -Wextra -g -std=c++17 -o ../build/obj/Debug/Debug/Test/LexerTests.o -c LexerTests.cpp",
+ "file": "LexerTests.cpp" },
+ { "directory": "d:/repo/IPL/JSImpl/test",
+ "command": "g++ -MMD -MP -MP -D_SCL_SECURE_NO_WARNINGS -I\"googletest/googletest/include\" -I\"googletest/googlemock/include\" -I\"..\" -I\"../../spasm/src\" -I\"../../spasm/src/asm\" -Werror -Wall -Wextra -g -std=c++17 -o ../build/obj/Debug/Debug/Test/ParserTests.o -c ParserTests.cpp",
+ "file": "ParserTests.cpp" },
+ { "directory": "d:/repo/IPL/JSImpl/test",
+ "command": "g++ -MMD -MP -MP -D_SCL_SECURE_NO_WARNINGS -I\"googletest/googletest/include\" -I\"googletest/googlemock/include\" -I\"..\" -I\"../../spasm/src\" -I\"../../spasm/src/asm\" -Werror -Wall -Wextra -g -std=c++17 -o ../build/obj/Debug/Debug/Test/empty.o -c empty.cpp",
+ "file": "empty.cpp" },
+ { "directory": "d:/repo/IPL/JSImpl/test",
+ "command": "g++ -MMD -MP -MP -D_SCL_SECURE_NO_WARNINGS -I\"googletest/googletest/include\" -I\"googletest/googlemock/include\" -I\"..\" -I\"../../spasm/src\" -I\"../../spasm/src/asm\" -Werror -Wall -Wextra -g -std=c++17 -o ../build/obj/Debug/Debug/Test/sprtTests.o -c sprtTests.cpp",
+ "file": "sprtTests.cpp" },
+ { "directory": "d:/repo/IPL/JSImpl/test",
+ "command": "g++ -MMD -MP -MP -D_SCL_SECURE_NO_WARNINGS -I\"googletest/googletest\" -I\"googletest/googletest/include\" -Werror -Wall -Wextra -g -std=c++17 -o ../build/obj/Debug/Debug/gtest/googletest/googletest/src/gtest-all.o -c googletest/googletest/src/gtest-all.cc",
+ "file": "googletest/googletest/src/gtest-all.cc" },
+ { "directory": "d:/repo/IPL/JSImpl/test",
+ "command": "g++ -MMD -MP -MP -D_SCL_SECURE_NO_WARNINGS -I\"googletest/googlemock\" -I\"googletest/googlemock/include\" -I\"googletest/googletest/include\" -Werror -Wall -Wextra -g -std=c++17 -o ../build/obj/Debug/Debug/gmock/googletest/googlemock/src/gmock-all.o -c googletest/googlemock/src/gmock-all.cc",
+ "file": "googletest/googlemock/src/gmock-all.cc" },
+ { "directory": "d:/repo/IPL/JSImpl/test",
+ "command": "g++ -MMD -MP -MP -D_SCL_SECURE_NO_WARNINGS -I\"googletest/googletest\" -I\"googletest/googletest/include\" -Werror -Wall -Wextra -g -std=c++17 -o ../build/obj/Debug/Debug/gtest_main/googletest/googletest/src/gtest_main.o -c googletest/googletest/src/gtest_main.cc",
+ "file": "googletest/googletest/src/gtest_main.cc" },
+ { "directory": "d:/repo/IPL/JSImpl/solution",
+ "command": "g++ -MMD -MP -MP -D_SCL_SECURE_NO_WARNINGS -Werror -Wall -Wextra -g -std=c++17 -o ../build/obj/Debug/Debug/JSLib/src/ASTInterpreter.o -c ../src/ASTInterpreter.cpp",
+ "file": "../src/ASTInterpreter.cpp" },
+ { "directory": "d:/repo/IPL/JSImpl/solution",
+ "command": "g++ -MMD -MP -MP -D_SCL_SECURE_NO_WARNINGS -Werror -Wall -Wextra -g -std=c++17 -o ../build/obj/Debug/Debug/JSLib/src/ASTPrinter.o -c ../src/ASTPrinter.cpp",
+ "file": "../src/ASTPrinter.cpp" },
+ { "directory": "d:/repo/IPL/JSImpl/solution",
+ "command": "g++ -MMD -MP -MP -D_SCL_SECURE_NO_WARNINGS -Werror -Wall -Wextra -g -std=c++17 -o ../build/obj/Debug/Debug/JSLib/src/ByteCodeGenerator.o -c ../src/ByteCodeGenerator.cpp",
+ "file": "../src/ByteCodeGenerator.cpp" },
+ { "directory": "d:/repo/IPL/JSImpl/solution",
+ "command": "g++ -MMD -MP -MP -D_SCL_SECURE_NO_WARNINGS -Werror -Wall -Wextra -g -std=c++17 -o ../build/obj/Debug/Debug/JSLib/src/Expression.o -c ../src/Expression.cpp",
+ "file": "../src/Expression.cpp" },
+ { "directory": "d:/repo/IPL/JSImpl/solution",
+ "command": "g++ -MMD -MP -MP -D_SCL_SECURE_NO_WARNINGS -Werror -Wall -Wextra -g -std=c++17 -o ../build/obj/Debug/Debug/JSLib/src/JSONParser.o -c ../src/JSONParser.cpp",
+ "file": "../src/JSONParser.cpp" },
+ { "directory": "d:/repo/IPL/JSImpl/solution",
+ "command": "g++ -MMD -MP -MP -D_SCL_SECURE_NO_WARNINGS -Werror -Wall -Wextra -g -std=c++17 -o ../build/obj/Debug/Debug/JSLib/src/Lexer.o -c ../src/Lexer.cpp",
+ "file": "../src/Lexer.cpp" },
+ { "directory": "d:/repo/IPL/JSImpl/solution",
+ "command": "g++ -MMD -MP -MP -D_SCL_SECURE_NO_WARNINGS -Werror -Wall -Wextra -g -std=c++17 -o ../build/obj/Debug/Debug/JSLib/src/Parser.o -c ../src/Parser.cpp",
+ "file": "../src/Parser.cpp" },
+ { "directory": "d:/repo/IPL/JSImpl/solution",
+ "command": "g++ -MMD -MP -MP -D_SCL_SECURE_NO_WARNINGS -Werror -Wall -Wextra -g -std=c++17 -o ../build/obj/Debug/Debug/JSImpl/src/main.o -c ../src/main.cpp",
+ "file": "../src/main.cpp" },
+ { "directory": "d:/repo/IPL/spasm/solution",
+ "command": "g++ -MMD -MP -MP -D_SCL_SECURE_NO_WARNINGS -Werror -Wall -Wextra -g -std=c++17 -o ../../JSImpl/build/obj/Debug/Debug/sprt/src/spasm.o -c ../src/spasm.cpp",
+ "file": "../src/spasm.cpp" },
+ { "directory": "d:/repo/IPL/spasm/solution",
+ "command": "g++ -MMD -MP -MP -D_SCL_SECURE_NO_WARNINGS -Werror -Wall -Wextra -g -std=c++17 -o ../../JSImpl/build/obj/Debug/Debug/spasm_lib/src/asm/assembler.o -c ../src/asm/assembler.cpp",
+ "file": "../src/asm/assembler.cpp" },
+ { "directory": "d:/repo/IPL/spasm/solution",
+ "command": "g++ -MMD -MP -MP -D_SCL_SECURE_NO_WARNINGS -Werror -Wall -Wextra -g -std=c++17 -o ../../JSImpl/build/obj/Debug/Debug/spasm_lib/src/asm/bytecode.o -c ../src/asm/bytecode.cpp",
+ "file": "../src/asm/bytecode.cpp" },
+ { "directory": "d:/repo/IPL/spasm/solution",
+ "command": "g++ -MMD -MP -MP -D_SCL_SECURE_NO_WARNINGS -Werror -Wall -Wextra -g -std=c++17 -o ../../JSImpl/build/obj/Debug/Debug/spasm_lib/src/asm/lexer.o -c ../src/asm/lexer.cpp",
+ "file": "../src/asm/lexer.cpp" },
+ { "directory": "d:/repo/IPL/spasm/solution",
+ "command": "g++ -MMD -MP -MP -D_SCL_SECURE_NO_WARNINGS -Werror -Wall -Wextra -g -std=c++17 -o ../../JSImpl/build/obj/Debug/Debug/spasm_lib/src/asm/symbol.o -c ../src/asm/symbol.cpp",
+ "file": "../src/asm/symbol.cpp" },
+ { "directory": "d:/repo/IPL/spasm/solution",
+ "command": "g++ -MMD -MP -MP -D_SCL_SECURE_NO_WARNINGS -Werror -Wall -Wextra -g -std=c++17 -o ../../JSImpl/build/obj/Debug/Debug/spasm_lib/src/asm/token.o -c ../src/asm/token.cpp",
+ "file": "../src/asm/token.cpp" },
+ { "directory": "d:/repo/IPL/spasm/solution",
+ "command": "g++ -MMD -MP -MP -D_SCL_SECURE_NO_WARNINGS -Werror -Wall -Wextra -g -std=c++17 -o ../../JSImpl/build/obj/Debug/Debug/spasm_lib/src/asm/tokenizer.o -c ../src/asm/tokenizer.cpp",
+ "file": "../src/asm/tokenizer.cpp" },
+ { "directory": "d:/repo/IPL/spasm/solution",
+ "command": "g++ -MMD -MP -MP -D_SCL_SECURE_NO_WARNINGS -Werror -Wall -Wextra -g -std=c++17 -o ../../JSImpl/build/obj/Debug/Debug/spasm/src/asm/main.o -c ../src/asm/main.cpp",
+ "file": "../src/asm/main.cpp" },
+ { "directory": "d:/repo/IPL/spasm/solution",
+ "command": "g++ -MMD -MP -MP -D_SCL_SECURE_NO_WARNINGS -Werror -Wall -Wextra -g -std=c++17 -o ../../JSImpl/build/obj/Debug/Debug/sprun/src/main.o -c ../src/main.cpp",
+ "file": "../src/main.cpp" }
+] \ No newline at end of file
diff --git a/gctest/.clang-format b/gctest/.clang-format
new file mode 100644
index 0000000..534d365
--- /dev/null
+++ b/gctest/.clang-format
@@ -0,0 +1,148 @@
+---
+Language: Cpp
+# BasedOnStyle: Chromium
+AccessModifierOffset: -4
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: false
+AlignConsecutiveDeclarations: false
+AlignEscapedNewlines: Left
+AlignOperands: true
+AlignTrailingComments: true
+AllowAllParametersOfDeclarationOnNextLine: false
+AllowShortBlocksOnASingleLine: false
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: Inline
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: true
+AlwaysBreakTemplateDeclarations: Yes
+BinPackArguments: true
+BinPackParameters: false
+BraceWrapping:
+ AfterClass: false
+ AfterControlStatement: false
+ AfterEnum: false
+ AfterFunction: false
+ AfterNamespace: false
+ AfterObjCDeclaration: false
+ AfterStruct: false
+ AfterUnion: false
+ AfterExternBlock: false
+ BeforeCatch: false
+ BeforeElse: false
+ IndentBraces: false
+ SplitEmptyFunction: true
+ SplitEmptyRecord: true
+ SplitEmptyNamespace: true
+BreakBeforeBinaryOperators: None
+BreakBeforeBraces: Allman
+BreakBeforeInheritanceComma: false
+BreakInheritanceList: BeforeColon
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializersBeforeComma: false
+BreakConstructorInitializers: BeforeColon
+BreakAfterJavaFieldAnnotations: false
+BreakStringLiterals: true
+ColumnLimit: 80
+CommentPragmas: '^ IWYU pragma:'
+CompactNamespaces: false
+ConstructorInitializerAllOnOneLineOrOnePerLine: true
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: true
+DerivePointerAlignment: false
+DisableFormat: false
+ExperimentalAutoDetectBinPacking: false
+FixNamespaceComments: true
+ForEachMacros:
+ - foreach
+ - Q_FOREACH
+ - BOOST_FOREACH
+IncludeBlocks: Preserve
+IncludeCategories:
+ - Regex: '^<ext/.*\.h>'
+ Priority: 2
+ - Regex: '^<.*\.h>'
+ Priority: 1
+ - Regex: '^<.*'
+ Priority: 2
+ - Regex: '.*'
+ Priority: 3
+IncludeIsMainRegex: '([-_](test|unittest))?$'
+IndentCaseLabels: true
+IndentPPDirectives: None
+IndentWidth: 4
+IndentWrappedFunctionNames: false
+JavaScriptQuotes: Leave
+JavaScriptWrapImports: true
+KeepEmptyLinesAtTheStartOfBlocks: false
+MacroBlockBegin: ''
+MacroBlockEnd: ''
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+ObjCBinPackProtocolList: Never
+ObjCBlockIndentWidth: 2
+ObjCSpaceAfterProperty: false
+ObjCSpaceBeforeProtocolList: true
+PenaltyBreakAssignment: 2
+PenaltyBreakBeforeFirstCallParameter: 1
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakString: 1000
+PenaltyBreakTemplateDeclaration: 10
+PenaltyExcessCharacter: 1000000
+PenaltyReturnTypeOnItsOwnLine: 200
+PointerAlignment: Left
+RawStringFormats:
+ - Language: Cpp
+ Delimiters:
+ - cc
+ - CC
+ - cpp
+ - Cpp
+ - CPP
+ - 'c++'
+ - 'C++'
+ CanonicalDelimiter: ''
+ BasedOnStyle: google
+ - Language: TextProto
+ Delimiters:
+ - pb
+ - PB
+ - proto
+ - PROTO
+ EnclosingFunctions:
+ - EqualsProto
+ - EquivToProto
+ - PARSE_PARTIAL_TEXT_PROTO
+ - PARSE_TEST_PROTO
+ - PARSE_TEXT_PROTO
+ - ParseTextOrDie
+ - ParseTextProtoOrDie
+ CanonicalDelimiter: ''
+ BasedOnStyle: google
+ReflowComments: true
+SortIncludes: true
+SortUsingDeclarations: true
+SpaceAfterCStyleCast: false
+SpaceAfterTemplateKeyword: true
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeCpp11BracedList: false
+SpaceBeforeCtorInitializerColon: true
+SpaceBeforeInheritanceColon: true
+SpaceBeforeParens: ControlStatements
+SpaceBeforeRangeBasedForLoopColon: true
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 2
+SpacesInAngles: false
+SpacesInContainerLiterals: true
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+Standard: Auto
+TabWidth: 8
+UseTab: Never
+...
+
diff --git a/gctest/README.md b/gctest/README.md
new file mode 100644
index 0000000..57528fb
--- /dev/null
+++ b/gctest/README.md
@@ -0,0 +1,21 @@
+# GC Test Bench
+
+A program to stress test garbage collector implementations.
+
+## Building
+
+The program is implemented as a static library, that has to be linked together
+with the garbage collector implementation to produce a test program.
+
+## Adding a new Garbage Collector implementation
+
+1. Implement the `GarbageCollector` interface from `gc.h` and the factory
+ function
+2. Add a new target in the `genie.lua` project
+
+## Running
+
+Running the program produces a `program.json` that can be open in
+`chrome://tracing` to allow analysis of the mutator vs garbage collector CPU
+usage and memory usage.
+
diff --git a/gctest/solution/Makefile b/gctest/solution/Makefile
new file mode 100644
index 0000000..fbc272e
--- /dev/null
+++ b/gctest/solution/Makefile
@@ -0,0 +1,48 @@
+# GNU Make solution makefile autogenerated by GENie
+# Type "make help" for usage help
+
+ifndef config
+ config=debug32
+endif
+export config
+
+PROJECTS := dummy_gc leak_gc test_bench
+
+.PHONY: all clean help $(PROJECTS)
+
+all: $(PROJECTS)
+
+test_bench:
+ @echo "==== Building test_bench ($(config)) ===="
+ @${MAKE} --no-print-directory -C . -f test_bench.make
+
+leak_gc: test_bench
+ @echo "==== Building leak_gc ($(config)) ===="
+ @${MAKE} --no-print-directory -C . -f leak_gc.make
+
+dummy_gc: test_bench
+ @echo "==== Building dummy_gc ($(config)) ===="
+ @${MAKE} --no-print-directory -C . -f dummy_gc.make
+
+clean:
+ @${MAKE} --no-print-directory -C . -f test_bench.make clean
+ @${MAKE} --no-print-directory -C . -f leak_gc.make clean
+ @${MAKE} --no-print-directory -C . -f dummy_gc.make clean
+
+help:
+ @echo "Usage: make [config=name] [target]"
+ @echo ""
+ @echo "CONFIGURATIONS:"
+ @echo " debug32"
+ @echo " release32"
+ @echo " debug64"
+ @echo " release64"
+ @echo ""
+ @echo "TARGETS:"
+ @echo " all (default)"
+ @echo " clean"
+ @echo " test_bench"
+ @echo " leak_gc"
+ @echo " dummy_gc"
+ @echo ""
+ @echo "For more information, see https://github.com/bkaradzic/genie"
diff --git a/gctest/solution/dummy_gc.make b/gctest/solution/dummy_gc.make
new file mode 100644
index 0000000..7b308c8
--- /dev/null
+++ b/gctest/solution/dummy_gc.make
@@ -0,0 +1,243 @@
+# GNU Make project makefile autogenerated by GENie
+ifndef config
+ config=debug32
+endif
+
+ifndef verbose
+ SILENT = @
+endif
+
+SHELLTYPE := msdos
+ifeq (,$(ComSpec)$(COMSPEC))
+ SHELLTYPE := posix
+endif
+ifeq (/bin,$(findstring /bin,$(SHELL)))
+ SHELLTYPE := posix
+endif
+ifeq (/bin,$(findstring /bin,$(MAKESHELL)))
+ SHELLTYPE := posix
+endif
+
+ifeq (posix,$(SHELLTYPE))
+ MKDIR = $(SILENT) mkdir -p "$(1)"
+ COPY = $(SILENT) cp -fR "$(1)" "$(2)"
+ RM = $(SILENT) rm -f "$(1)"
+else
+ MKDIR = $(SILENT) mkdir "$(subst /,\\,$(1))" 2> nul || exit 0
+ COPY = $(SILENT) copy /Y "$(subst /,\\,$(1))" "$(subst /,\\,$(2))"
+ RM = $(SILENT) del /F "$(subst /,\\,$(1))" 2> nul || exit 0
+endif
+
+CC = gcc
+CXX = g++
+AR = ar
+
+ifndef RESCOMP
+ ifdef WINDRES
+ RESCOMP = $(WINDRES)
+ else
+ RESCOMP = windres
+ endif
+endif
+
+MAKEFILE = dummy_gc.make
+
+ifeq ($(config),debug32)
+ OBJDIR = ../../JSImpl/build/obj/Debug/x32/Debug/dummy_gc
+ TARGETDIR = ../../JSImpl/build/bin/Debug
+ TARGET = $(TARGETDIR)/dummy_gc
+ DEFINES += -D_SCL_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS -DMTR_ENABLED
+ ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP -MP $(DEFINES) $(INCLUDES)
+ ALL_ASMFLAGS += $(ASMFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -m32
+ ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -m32
+ ALL_CXXFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -m32 -std=c++17
+ ALL_OBJCFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -m32
+ ALL_OBJCPPFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -m32 -std=c++17
+ ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES)
+ ALL_LDFLAGS += $(LDFLAGS) -L"../../JSImpl/build/bin/Debug" -m32
+ LIBDEPS += ../../JSImpl/build/bin/Debug/libtest_bench.a
+ LDDEPS += ../../JSImpl/build/bin/Debug/libtest_bench.a
+ LDRESP =
+ LIBS += $(LDDEPS)
+ EXTERNAL_LIBS +=
+ LINKOBJS = $(OBJECTS)
+ LINKCMD = $(CXX) -o $(TARGET) $(LINKOBJS) $(RESOURCES) $(ARCH) $(ALL_LDFLAGS) $(LIBS)
+ OBJRESP =
+ OBJECTS := \
+ $(OBJDIR)/src/gc_dummy.o \
+
+ define PREBUILDCMDS
+ endef
+ define PRELINKCMDS
+ endef
+ define POSTBUILDCMDS
+ endef
+endif
+
+ifeq ($(config),release32)
+ OBJDIR = ../../JSImpl/build/obj/Release/x32/Release/dummy_gc
+ TARGETDIR = ../../JSImpl/build/bin/Release
+ TARGET = $(TARGETDIR)/dummy_gc
+ DEFINES += -D_SCL_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS -DMTR_ENABLED
+ ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP -MP $(DEFINES) $(INCLUDES)
+ ALL_ASMFLAGS += $(ASMFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -O3 -m32
+ ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -O3 -m32
+ ALL_CXXFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -O3 -m32 -std=c++17
+ ALL_OBJCFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -O3 -m32
+ ALL_OBJCPPFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -O3 -m32 -std=c++17
+ ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES)
+ ALL_LDFLAGS += $(LDFLAGS) -L"../../JSImpl/build/bin/Release" -m32
+ LIBDEPS += ../../JSImpl/build/bin/Release/libtest_bench.a
+ LDDEPS += ../../JSImpl/build/bin/Release/libtest_bench.a
+ LDRESP =
+ LIBS += $(LDDEPS)
+ EXTERNAL_LIBS +=
+ LINKOBJS = $(OBJECTS)
+ LINKCMD = $(CXX) -o $(TARGET) $(LINKOBJS) $(RESOURCES) $(ARCH) $(ALL_LDFLAGS) $(LIBS)
+ OBJRESP =
+ OBJECTS := \
+ $(OBJDIR)/src/gc_dummy.o \
+
+ define PREBUILDCMDS
+ endef
+ define PRELINKCMDS
+ endef
+ define POSTBUILDCMDS
+ endef
+endif
+
+ifeq ($(config),debug64)
+ OBJDIR = ../../JSImpl/build/obj/Debug/x64/Debug/dummy_gc
+ TARGETDIR = ../../JSImpl/build/bin/Debug
+ TARGET = $(TARGETDIR)/dummy_gc
+ DEFINES += -D_SCL_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS -DMTR_ENABLED
+ ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP -MP $(DEFINES) $(INCLUDES)
+ ALL_ASMFLAGS += $(ASMFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -m64
+ ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -m64
+ ALL_CXXFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -m64 -std=c++17
+ ALL_OBJCFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -m64
+ ALL_OBJCPPFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -m64 -std=c++17
+ ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES)
+ ALL_LDFLAGS += $(LDFLAGS) -L"../../JSImpl/build/bin/Debug" -m64
+ LIBDEPS += ../../JSImpl/build/bin/Debug/libtest_bench.a
+ LDDEPS += ../../JSImpl/build/bin/Debug/libtest_bench.a
+ LDRESP =
+ LIBS += $(LDDEPS)
+ EXTERNAL_LIBS +=
+ LINKOBJS = $(OBJECTS)
+ LINKCMD = $(CXX) -o $(TARGET) $(LINKOBJS) $(RESOURCES) $(ARCH) $(ALL_LDFLAGS) $(LIBS)
+ OBJRESP =
+ OBJECTS := \
+ $(OBJDIR)/src/gc_dummy.o \
+
+ define PREBUILDCMDS
+ endef
+ define PRELINKCMDS
+ endef
+ define POSTBUILDCMDS
+ endef
+endif
+
+ifeq ($(config),release64)
+ OBJDIR = ../../JSImpl/build/obj/Release/x64/Release/dummy_gc
+ TARGETDIR = ../../JSImpl/build/bin/Release
+ TARGET = $(TARGETDIR)/dummy_gc
+ DEFINES += -D_SCL_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS -DMTR_ENABLED
+ ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP -MP $(DEFINES) $(INCLUDES)
+ ALL_ASMFLAGS += $(ASMFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -O3 -m64
+ ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -O3 -m64
+ ALL_CXXFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -O3 -m64 -std=c++17
+ ALL_OBJCFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -O3 -m64
+ ALL_OBJCPPFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -O3 -m64 -std=c++17
+ ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES)
+ ALL_LDFLAGS += $(LDFLAGS) -L"../../JSImpl/build/bin/Release" -m64
+ LIBDEPS += ../../JSImpl/build/bin/Release/libtest_bench.a
+ LDDEPS += ../../JSImpl/build/bin/Release/libtest_bench.a
+ LDRESP =
+ LIBS += $(LDDEPS)
+ EXTERNAL_LIBS +=
+ LINKOBJS = $(OBJECTS)
+ LINKCMD = $(CXX) -o $(TARGET) $(LINKOBJS) $(RESOURCES) $(ARCH) $(ALL_LDFLAGS) $(LIBS)
+ OBJRESP =
+ OBJECTS := \
+ $(OBJDIR)/src/gc_dummy.o \
+
+ define PREBUILDCMDS
+ endef
+ define PRELINKCMDS
+ endef
+ define POSTBUILDCMDS
+ endef
+endif
+
+OBJDIRS := \
+ $(OBJDIR) \
+ $(OBJDIR)/src \
+
+RESOURCES := \
+
+.PHONY: clean prebuild prelink
+
+all: $(OBJDIRS) $(TARGETDIR) prebuild prelink $(TARGET)
+ @:
+
+$(TARGET): $(GCH) $(OBJECTS) $(LIBDEPS) $(EXTERNAL_LIBS) $(RESOURCES) $(OBJRESP) $(LDRESP) | $(TARGETDIR) $(OBJDIRS)
+ @echo Linking dummy_gc
+ $(SILENT) $(LINKCMD)
+ $(POSTBUILDCMDS)
+
+$(TARGETDIR):
+ @echo Creating $(TARGETDIR)
+ -$(call MKDIR,$(TARGETDIR))
+
+$(OBJDIRS):
+ @echo Creating $(@)
+ -$(call MKDIR,$@)
+
+clean:
+ @echo Cleaning dummy_gc
+ifeq (posix,$(SHELLTYPE))
+ $(SILENT) rm -f $(TARGET)
+ $(SILENT) rm -rf $(OBJDIR)
+else
+ $(SILENT) if exist $(subst /,\\,$(TARGET)) del $(subst /,\\,$(TARGET))
+ $(SILENT) if exist $(subst /,\\,$(OBJDIR)) rmdir /s /q $(subst /,\\,$(OBJDIR))
+endif
+
+prebuild:
+ $(PREBUILDCMDS)
+
+prelink:
+ $(PRELINKCMDS)
+
+ifneq (,$(PCH))
+$(GCH): $(PCH) $(MAKEFILE) | $(OBJDIR)
+ @echo $(notdir $<)
+ $(SILENT) $(CXX) $(ALL_CXXFLAGS) -x c++-header $(DEFINES) $(INCLUDES) -o "$@" -c "$<"
+
+$(GCH_OBJC): $(PCH) $(MAKEFILE) | $(OBJDIR)
+ @echo $(notdir $<)
+ $(SILENT) $(CXX) $(ALL_OBJCPPFLAGS) -x objective-c++-header $(DEFINES) $(INCLUDES) -o "$@" -c "$<"
+endif
+
+ifneq (,$(OBJRESP))
+$(OBJRESP): $(OBJECTS) | $(TARGETDIR) $(OBJDIRS)
+ $(SILENT) echo $^
+ $(SILENT) echo $^ > $@
+endif
+
+ifneq (,$(LDRESP))
+$(LDRESP): $(LDDEPS) | $(TARGETDIR) $(OBJDIRS)
+ $(SILENT) echo $^
+ $(SILENT) echo $^ > $@
+endif
+
+$(OBJDIR)/src/gc_dummy.o: ../src/gc_dummy.cpp $(GCH) $(MAKEFILE) | $(OBJDIR)/src
+ @echo $(notdir $<)
+ $(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -c "$<"
+
+-include $(OBJECTS:%.o=%.d)
+ifneq (,$(PCH))
+ -include $(OBJDIR)/$(notdir $(PCH)).d
+ -include $(OBJDIR)/$(notdir $(PCH))_objc.d
+endif
diff --git a/gctest/solution/dummy_gc.vcxproj b/gctest/solution/dummy_gc.vcxproj
new file mode 100644
index 0000000..f10ece1
--- /dev/null
+++ b/gctest/solution/dummy_gc.vcxproj
@@ -0,0 +1,245 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="16.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{3AED02FA-26BA-5D05-4FD3-4BAD3BFF9293}</ProjectGuid>
+ <RootNamespace>dummy_gc</RootNamespace>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformMinVersion>10.0.10240.0</WindowsTargetPlatformMinVersion>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v142</PlatformToolset>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ <DebugSymbols>true</DebugSymbols>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v142</PlatformToolset>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ <DebugSymbols>true</DebugSymbols>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v142</PlatformToolset>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ <DebugSymbols>true</DebugSymbols>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v142</PlatformToolset>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ <DebugSymbols>true</DebugSymbols>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>..\..\JSImpl\build\bin\Debug\</OutDir>
+ <IntDir>..\..\JSImpl\build\obj\Debug\x32\Debug\dummy_gc\</IntDir>
+ <TargetName>dummy_gc</TargetName>
+ <TargetExt>.exe</TargetExt>
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <OutDir>..\..\JSImpl\build\bin\Debug\</OutDir>
+ <IntDir>..\..\JSImpl\build\obj\Debug\x64\Debug\dummy_gc\</IntDir>
+ <TargetName>dummy_gc</TargetName>
+ <TargetExt>.exe</TargetExt>
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>..\..\JSImpl\build\bin\Release\</OutDir>
+ <IntDir>..\..\JSImpl\build\obj\Release\x32\Release\dummy_gc\</IntDir>
+ <TargetName>dummy_gc</TargetName>
+ <TargetExt>.exe</TargetExt>
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <OutDir>..\..\JSImpl\build\bin\Release\</OutDir>
+ <IntDir>..\..\JSImpl\build\obj\Release\x64\Release\dummy_gc\</IntDir>
+ <TargetName>dummy_gc</TargetName>
+ <TargetExt>.exe</TargetExt>
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;MTR_ENABLED;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <PrecompiledHeader></PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <ProgramDataBaseFileName>$(IntDir)dummy_gc.compile.pdb</ProgramDataBaseFileName>
+ <DiagnosticsFormat>Caret</DiagnosticsFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;MTR_ENABLED;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)dummy_gc.pdb</ProgramDatabaseFile>
+ <AdditionalLibraryDirectories>;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <OutputFile>$(OutDir)dummy_gc.exe</OutputFile>
+ <EntryPointSymbol>mainCRTStartup</EntryPointSymbol>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;MTR_ENABLED;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <PrecompiledHeader></PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <ProgramDataBaseFileName>$(IntDir)dummy_gc.compile.pdb</ProgramDataBaseFileName>
+ <DiagnosticsFormat>Caret</DiagnosticsFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;MTR_ENABLED;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)dummy_gc.pdb</ProgramDatabaseFile>
+ <AdditionalLibraryDirectories>;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <OutputFile>$(OutDir)dummy_gc.exe</OutputFile>
+ <EntryPointSymbol>mainCRTStartup</EntryPointSymbol>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
+ <Optimization>MaxSpeed</Optimization>
+ <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;MTR_ENABLED;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <StringPooling>true</StringPooling>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <PrecompiledHeader></PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <ProgramDataBaseFileName>$(IntDir)dummy_gc.compile.pdb</ProgramDataBaseFileName>
+ <DiagnosticsFormat>Caret</DiagnosticsFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;MTR_ENABLED;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)dummy_gc.pdb</ProgramDatabaseFile>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <AdditionalLibraryDirectories>;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <OutputFile>$(OutDir)dummy_gc.exe</OutputFile>
+ <EntryPointSymbol>mainCRTStartup</EntryPointSymbol>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
+ <Optimization>MaxSpeed</Optimization>
+ <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;MTR_ENABLED;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <StringPooling>true</StringPooling>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <PrecompiledHeader></PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <ProgramDataBaseFileName>$(IntDir)dummy_gc.compile.pdb</ProgramDataBaseFileName>
+ <DiagnosticsFormat>Caret</DiagnosticsFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;MTR_ENABLED;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)dummy_gc.pdb</ProgramDatabaseFile>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <AdditionalLibraryDirectories>;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <OutputFile>$(OutDir)dummy_gc.exe</OutputFile>
+ <EntryPointSymbol>mainCRTStartup</EntryPointSymbol>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\src\gc_dummy.cpp">
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="test_bench.vcxproj">
+ <Project>{A41847E7-90D0-8834-F9D7-6190E5AE2325}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
diff --git a/gctest/solution/dummy_gc.vcxproj.filters b/gctest/solution/dummy_gc.vcxproj.filters
new file mode 100644
index 0000000..f8d3d44
--- /dev/null
+++ b/gctest/solution/dummy_gc.vcxproj.filters
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="16.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="src">
+ <UniqueIdentifier>{2DAB880B-99B4-887C-2230-9F7C8E38947C}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\src\gc_dummy.cpp">
+ <Filter>src</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project>
diff --git a/gctest/solution/gctest.sln b/gctest/solution/gctest.sln
new file mode 100644
index 0000000..c9b58c0
--- /dev/null
+++ b/gctest/solution/gctest.sln
@@ -0,0 +1,54 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_bench", "test_bench.vcxproj", "{A41847E7-90D0-8834-F9D7-6190E5AE2325}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "leak_gc", "leak_gc.vcxproj", "{8BDD0170-F7BC-800B-00D5-0BE26C33E76C}"
+ ProjectSection(ProjectDependencies) = postProject
+ {A41847E7-90D0-8834-F9D7-6190E5AE2325} = {A41847E7-90D0-8834-F9D7-6190E5AE2325}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dummy_gc", "dummy_gc.vcxproj", "{3AED02FA-26BA-5D05-4FD3-4BAD3BFF9293}"
+ ProjectSection(ProjectDependencies) = postProject
+ {A41847E7-90D0-8834-F9D7-6190E5AE2325} = {A41847E7-90D0-8834-F9D7-6190E5AE2325}
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
+ Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {A41847E7-90D0-8834-F9D7-6190E5AE2325}.Debug|Win32.ActiveCfg = Debug|Win32
+ {A41847E7-90D0-8834-F9D7-6190E5AE2325}.Debug|Win32.Build.0 = Debug|Win32
+ {A41847E7-90D0-8834-F9D7-6190E5AE2325}.Debug|x64.ActiveCfg = Debug|x64
+ {A41847E7-90D0-8834-F9D7-6190E5AE2325}.Debug|x64.Build.0 = Debug|x64
+ {A41847E7-90D0-8834-F9D7-6190E5AE2325}.Release|Win32.ActiveCfg = Release|Win32
+ {A41847E7-90D0-8834-F9D7-6190E5AE2325}.Release|Win32.Build.0 = Release|Win32
+ {A41847E7-90D0-8834-F9D7-6190E5AE2325}.Release|x64.ActiveCfg = Release|x64
+ {A41847E7-90D0-8834-F9D7-6190E5AE2325}.Release|x64.Build.0 = Release|x64
+ {8BDD0170-F7BC-800B-00D5-0BE26C33E76C}.Debug|Win32.ActiveCfg = Debug|Win32
+ {8BDD0170-F7BC-800B-00D5-0BE26C33E76C}.Debug|Win32.Build.0 = Debug|Win32
+ {8BDD0170-F7BC-800B-00D5-0BE26C33E76C}.Debug|x64.ActiveCfg = Debug|x64
+ {8BDD0170-F7BC-800B-00D5-0BE26C33E76C}.Debug|x64.Build.0 = Debug|x64
+ {8BDD0170-F7BC-800B-00D5-0BE26C33E76C}.Release|Win32.ActiveCfg = Release|Win32
+ {8BDD0170-F7BC-800B-00D5-0BE26C33E76C}.Release|Win32.Build.0 = Release|Win32
+ {8BDD0170-F7BC-800B-00D5-0BE26C33E76C}.Release|x64.ActiveCfg = Release|x64
+ {8BDD0170-F7BC-800B-00D5-0BE26C33E76C}.Release|x64.Build.0 = Release|x64
+ {3AED02FA-26BA-5D05-4FD3-4BAD3BFF9293}.Debug|Win32.ActiveCfg = Debug|Win32
+ {3AED02FA-26BA-5D05-4FD3-4BAD3BFF9293}.Debug|Win32.Build.0 = Debug|Win32
+ {3AED02FA-26BA-5D05-4FD3-4BAD3BFF9293}.Debug|x64.ActiveCfg = Debug|x64
+ {3AED02FA-26BA-5D05-4FD3-4BAD3BFF9293}.Debug|x64.Build.0 = Debug|x64
+ {3AED02FA-26BA-5D05-4FD3-4BAD3BFF9293}.Release|Win32.ActiveCfg = Release|Win32
+ {3AED02FA-26BA-5D05-4FD3-4BAD3BFF9293}.Release|Win32.Build.0 = Release|Win32
+ {3AED02FA-26BA-5D05-4FD3-4BAD3BFF9293}.Release|x64.ActiveCfg = Release|x64
+ {3AED02FA-26BA-5D05-4FD3-4BAD3BFF9293}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ EndGlobalSection
+EndGlobal
diff --git a/gctest/solution/genie.lua b/gctest/solution/genie.lua
new file mode 100644
index 0000000..8a1473a
--- /dev/null
+++ b/gctest/solution/genie.lua
@@ -0,0 +1,72 @@
+if not solution() then
+ solution 'gctest'
+ if _ACTION ~= 'jcdb' then
+ platforms { 'x32', 'x64' }
+ configurations {'Debug', 'Release'}
+ else
+ configurations {'Debug'}
+ platforms { 'x64' }
+ end
+ flags {
+ 'FatalWarnings',
+ 'ExtraWarnings',
+ 'Symbols',
+ }
+
+ defines {
+ '_SCL_SECURE_NO_WARNINGS',
+ }
+
+ local root = '../build/'
+
+ configuration 'Debug'
+ targetdir(root .. 'bin/Debug')
+ objdir(root .. 'obj/Debug')
+
+ configuration 'Release'
+ flags 'OptimizeSpeed'
+ targetdir(root .. 'bin/Release')
+ objdir(root .. 'obj/Release')
+ configuration '*'
+end
+
+function setup()
+ flags 'Cpp17'
+ defines {
+ '_SCL_SECURE_NO_WARNINGS',
+ '_CRT_SECURE_NO_WARNINGS',
+ '_CRT_NONSTDC_NO_WARNINGS', -- for strdup in minitrace.c
+ 'MTR_ENABLED',
+ }
+
+ -- GCC generates a warning for uninitialized data in
+ -- std::normal_distribution
+ configuration 'gcc'
+ removeflags 'ExtraWarnings'
+ configuration '*'
+end
+
+ project 'test_bench'
+ kind 'StaticLib'
+ language 'C++'
+ files {
+ '../src/main.cpp',
+ '../src/minitrace.cpp',
+ }
+ removeflags 'ExtraWarnings'
+ setup()
+
+ project 'leak_gc'
+ kind 'ConsoleApp'
+ language 'C++'
+ files '../src/gc_leak.cpp'
+ links 'test_bench'
+ setup()
+
+ project 'dummy_gc'
+ kind 'ConsoleApp'
+ language 'C++'
+ files '../src/gc_dummy.cpp'
+ links 'test_bench'
+ setup()
+
diff --git a/gctest/solution/leak_gc.make b/gctest/solution/leak_gc.make
new file mode 100644
index 0000000..4414edf
--- /dev/null
+++ b/gctest/solution/leak_gc.make
@@ -0,0 +1,243 @@
+# GNU Make project makefile autogenerated by GENie
+ifndef config
+ config=debug32
+endif
+
+ifndef verbose
+ SILENT = @
+endif
+
+SHELLTYPE := msdos
+ifeq (,$(ComSpec)$(COMSPEC))
+ SHELLTYPE := posix
+endif
+ifeq (/bin,$(findstring /bin,$(SHELL)))
+ SHELLTYPE := posix
+endif
+ifeq (/bin,$(findstring /bin,$(MAKESHELL)))
+ SHELLTYPE := posix
+endif
+
+ifeq (posix,$(SHELLTYPE))
+ MKDIR = $(SILENT) mkdir -p "$(1)"
+ COPY = $(SILENT) cp -fR "$(1)" "$(2)"
+ RM = $(SILENT) rm -f "$(1)"
+else
+ MKDIR = $(SILENT) mkdir "$(subst /,\\,$(1))" 2> nul || exit 0
+ COPY = $(SILENT) copy /Y "$(subst /,\\,$(1))" "$(subst /,\\,$(2))"
+ RM = $(SILENT) del /F "$(subst /,\\,$(1))" 2> nul || exit 0
+endif
+
+CC = gcc
+CXX = g++
+AR = ar
+
+ifndef RESCOMP
+ ifdef WINDRES
+ RESCOMP = $(WINDRES)
+ else
+ RESCOMP = windres
+ endif
+endif
+
+MAKEFILE = leak_gc.make
+
+ifeq ($(config),debug32)
+ OBJDIR = ../../JSImpl/build/obj/Debug/x32/Debug/leak_gc
+ TARGETDIR = ../../JSImpl/build/bin/Debug
+ TARGET = $(TARGETDIR)/leak_gc
+ DEFINES += -D_SCL_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS -DMTR_ENABLED
+ ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP -MP $(DEFINES) $(INCLUDES)
+ ALL_ASMFLAGS += $(ASMFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -m32
+ ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -m32
+ ALL_CXXFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -m32 -std=c++17
+ ALL_OBJCFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -m32
+ ALL_OBJCPPFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -m32 -std=c++17
+ ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES)
+ ALL_LDFLAGS += $(LDFLAGS) -L"../../JSImpl/build/bin/Debug" -m32
+ LIBDEPS += ../../JSImpl/build/bin/Debug/libtest_bench.a
+ LDDEPS += ../../JSImpl/build/bin/Debug/libtest_bench.a
+ LDRESP =
+ LIBS += $(LDDEPS)
+ EXTERNAL_LIBS +=
+ LINKOBJS = $(OBJECTS)
+ LINKCMD = $(CXX) -o $(TARGET) $(LINKOBJS) $(RESOURCES) $(ARCH) $(ALL_LDFLAGS) $(LIBS)
+ OBJRESP =
+ OBJECTS := \
+ $(OBJDIR)/src/gc_leak.o \
+
+ define PREBUILDCMDS
+ endef
+ define PRELINKCMDS
+ endef
+ define POSTBUILDCMDS
+ endef
+endif
+
+ifeq ($(config),release32)
+ OBJDIR = ../../JSImpl/build/obj/Release/x32/Release/leak_gc
+ TARGETDIR = ../../JSImpl/build/bin/Release
+ TARGET = $(TARGETDIR)/leak_gc
+ DEFINES += -D_SCL_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS -DMTR_ENABLED
+ ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP -MP $(DEFINES) $(INCLUDES)
+ ALL_ASMFLAGS += $(ASMFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -O3 -m32
+ ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -O3 -m32
+ ALL_CXXFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -O3 -m32 -std=c++17
+ ALL_OBJCFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -O3 -m32
+ ALL_OBJCPPFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -O3 -m32 -std=c++17
+ ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES)
+ ALL_LDFLAGS += $(LDFLAGS) -L"../../JSImpl/build/bin/Release" -m32
+ LIBDEPS += ../../JSImpl/build/bin/Release/libtest_bench.a
+ LDDEPS += ../../JSImpl/build/bin/Release/libtest_bench.a
+ LDRESP =
+ LIBS += $(LDDEPS)
+ EXTERNAL_LIBS +=
+ LINKOBJS = $(OBJECTS)
+ LINKCMD = $(CXX) -o $(TARGET) $(LINKOBJS) $(RESOURCES) $(ARCH) $(ALL_LDFLAGS) $(LIBS)
+ OBJRESP =
+ OBJECTS := \
+ $(OBJDIR)/src/gc_leak.o \
+
+ define PREBUILDCMDS
+ endef
+ define PRELINKCMDS
+ endef
+ define POSTBUILDCMDS
+ endef
+endif
+
+ifeq ($(config),debug64)
+ OBJDIR = ../../JSImpl/build/obj/Debug/x64/Debug/leak_gc
+ TARGETDIR = ../../JSImpl/build/bin/Debug
+ TARGET = $(TARGETDIR)/leak_gc
+ DEFINES += -D_SCL_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS -DMTR_ENABLED
+ ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP -MP $(DEFINES) $(INCLUDES)
+ ALL_ASMFLAGS += $(ASMFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -m64
+ ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -m64
+ ALL_CXXFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -m64 -std=c++17
+ ALL_OBJCFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -m64
+ ALL_OBJCPPFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -m64 -std=c++17
+ ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES)
+ ALL_LDFLAGS += $(LDFLAGS) -L"../../JSImpl/build/bin/Debug" -m64
+ LIBDEPS += ../../JSImpl/build/bin/Debug/libtest_bench.a
+ LDDEPS += ../../JSImpl/build/bin/Debug/libtest_bench.a
+ LDRESP =
+ LIBS += $(LDDEPS)
+ EXTERNAL_LIBS +=
+ LINKOBJS = $(OBJECTS)
+ LINKCMD = $(CXX) -o $(TARGET) $(LINKOBJS) $(RESOURCES) $(ARCH) $(ALL_LDFLAGS) $(LIBS)
+ OBJRESP =
+ OBJECTS := \
+ $(OBJDIR)/src/gc_leak.o \
+
+ define PREBUILDCMDS
+ endef
+ define PRELINKCMDS
+ endef
+ define POSTBUILDCMDS
+ endef
+endif
+
+ifeq ($(config),release64)
+ OBJDIR = ../../JSImpl/build/obj/Release/x64/Release/leak_gc
+ TARGETDIR = ../../JSImpl/build/bin/Release
+ TARGET = $(TARGETDIR)/leak_gc
+ DEFINES += -D_SCL_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS -DMTR_ENABLED
+ ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP -MP $(DEFINES) $(INCLUDES)
+ ALL_ASMFLAGS += $(ASMFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -O3 -m64
+ ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -O3 -m64
+ ALL_CXXFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -O3 -m64 -std=c++17
+ ALL_OBJCFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -O3 -m64
+ ALL_OBJCPPFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -O3 -m64 -std=c++17
+ ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES)
+ ALL_LDFLAGS += $(LDFLAGS) -L"../../JSImpl/build/bin/Release" -m64
+ LIBDEPS += ../../JSImpl/build/bin/Release/libtest_bench.a
+ LDDEPS += ../../JSImpl/build/bin/Release/libtest_bench.a
+ LDRESP =
+ LIBS += $(LDDEPS)
+ EXTERNAL_LIBS +=
+ LINKOBJS = $(OBJECTS)
+ LINKCMD = $(CXX) -o $(TARGET) $(LINKOBJS) $(RESOURCES) $(ARCH) $(ALL_LDFLAGS) $(LIBS)
+ OBJRESP =
+ OBJECTS := \
+ $(OBJDIR)/src/gc_leak.o \
+
+ define PREBUILDCMDS
+ endef
+ define PRELINKCMDS
+ endef
+ define POSTBUILDCMDS
+ endef
+endif
+
+OBJDIRS := \
+ $(OBJDIR) \
+ $(OBJDIR)/src \
+
+RESOURCES := \
+
+.PHONY: clean prebuild prelink
+
+all: $(OBJDIRS) $(TARGETDIR) prebuild prelink $(TARGET)
+ @:
+
+$(TARGET): $(GCH) $(OBJECTS) $(LIBDEPS) $(EXTERNAL_LIBS) $(RESOURCES) $(OBJRESP) $(LDRESP) | $(TARGETDIR) $(OBJDIRS)
+ @echo Linking leak_gc
+ $(SILENT) $(LINKCMD)
+ $(POSTBUILDCMDS)
+
+$(TARGETDIR):
+ @echo Creating $(TARGETDIR)
+ -$(call MKDIR,$(TARGETDIR))
+
+$(OBJDIRS):
+ @echo Creating $(@)
+ -$(call MKDIR,$@)
+
+clean:
+ @echo Cleaning leak_gc
+ifeq (posix,$(SHELLTYPE))
+ $(SILENT) rm -f $(TARGET)
+ $(SILENT) rm -rf $(OBJDIR)
+else
+ $(SILENT) if exist $(subst /,\\,$(TARGET)) del $(subst /,\\,$(TARGET))
+ $(SILENT) if exist $(subst /,\\,$(OBJDIR)) rmdir /s /q $(subst /,\\,$(OBJDIR))
+endif
+
+prebuild:
+ $(PREBUILDCMDS)
+
+prelink:
+ $(PRELINKCMDS)
+
+ifneq (,$(PCH))
+$(GCH): $(PCH) $(MAKEFILE) | $(OBJDIR)
+ @echo $(notdir $<)
+ $(SILENT) $(CXX) $(ALL_CXXFLAGS) -x c++-header $(DEFINES) $(INCLUDES) -o "$@" -c "$<"
+
+$(GCH_OBJC): $(PCH) $(MAKEFILE) | $(OBJDIR)
+ @echo $(notdir $<)
+ $(SILENT) $(CXX) $(ALL_OBJCPPFLAGS) -x objective-c++-header $(DEFINES) $(INCLUDES) -o "$@" -c "$<"
+endif
+
+ifneq (,$(OBJRESP))
+$(OBJRESP): $(OBJECTS) | $(TARGETDIR) $(OBJDIRS)
+ $(SILENT) echo $^
+ $(SILENT) echo $^ > $@
+endif
+
+ifneq (,$(LDRESP))
+$(LDRESP): $(LDDEPS) | $(TARGETDIR) $(OBJDIRS)
+ $(SILENT) echo $^
+ $(SILENT) echo $^ > $@
+endif
+
+$(OBJDIR)/src/gc_leak.o: ../src/gc_leak.cpp $(GCH) $(MAKEFILE) | $(OBJDIR)/src
+ @echo $(notdir $<)
+ $(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -c "$<"
+
+-include $(OBJECTS:%.o=%.d)
+ifneq (,$(PCH))
+ -include $(OBJDIR)/$(notdir $(PCH)).d
+ -include $(OBJDIR)/$(notdir $(PCH))_objc.d
+endif
diff --git a/gctest/solution/leak_gc.vcxproj b/gctest/solution/leak_gc.vcxproj
new file mode 100644
index 0000000..eeba8db
--- /dev/null
+++ b/gctest/solution/leak_gc.vcxproj
@@ -0,0 +1,245 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="16.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{8BDD0170-F7BC-800B-00D5-0BE26C33E76C}</ProjectGuid>
+ <RootNamespace>leak_gc</RootNamespace>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformMinVersion>10.0.10240.0</WindowsTargetPlatformMinVersion>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v142</PlatformToolset>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ <DebugSymbols>true</DebugSymbols>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v142</PlatformToolset>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ <DebugSymbols>true</DebugSymbols>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v142</PlatformToolset>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ <DebugSymbols>true</DebugSymbols>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v142</PlatformToolset>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ <DebugSymbols>true</DebugSymbols>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>..\..\JSImpl\build\bin\Debug\</OutDir>
+ <IntDir>..\..\JSImpl\build\obj\Debug\x32\Debug\leak_gc\</IntDir>
+ <TargetName>leak_gc</TargetName>
+ <TargetExt>.exe</TargetExt>
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <OutDir>..\..\JSImpl\build\bin\Debug\</OutDir>
+ <IntDir>..\..\JSImpl\build\obj\Debug\x64\Debug\leak_gc\</IntDir>
+ <TargetName>leak_gc</TargetName>
+ <TargetExt>.exe</TargetExt>
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>..\..\JSImpl\build\bin\Release\</OutDir>
+ <IntDir>..\..\JSImpl\build\obj\Release\x32\Release\leak_gc\</IntDir>
+ <TargetName>leak_gc</TargetName>
+ <TargetExt>.exe</TargetExt>
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <OutDir>..\..\JSImpl\build\bin\Release\</OutDir>
+ <IntDir>..\..\JSImpl\build\obj\Release\x64\Release\leak_gc\</IntDir>
+ <TargetName>leak_gc</TargetName>
+ <TargetExt>.exe</TargetExt>
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;MTR_ENABLED;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <PrecompiledHeader></PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <ProgramDataBaseFileName>$(IntDir)leak_gc.compile.pdb</ProgramDataBaseFileName>
+ <DiagnosticsFormat>Caret</DiagnosticsFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;MTR_ENABLED;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)leak_gc.pdb</ProgramDatabaseFile>
+ <AdditionalLibraryDirectories>;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <OutputFile>$(OutDir)leak_gc.exe</OutputFile>
+ <EntryPointSymbol>mainCRTStartup</EntryPointSymbol>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;MTR_ENABLED;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <PrecompiledHeader></PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <ProgramDataBaseFileName>$(IntDir)leak_gc.compile.pdb</ProgramDataBaseFileName>
+ <DiagnosticsFormat>Caret</DiagnosticsFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;MTR_ENABLED;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)leak_gc.pdb</ProgramDatabaseFile>
+ <AdditionalLibraryDirectories>;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <OutputFile>$(OutDir)leak_gc.exe</OutputFile>
+ <EntryPointSymbol>mainCRTStartup</EntryPointSymbol>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
+ <Optimization>MaxSpeed</Optimization>
+ <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;MTR_ENABLED;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <StringPooling>true</StringPooling>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <PrecompiledHeader></PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <ProgramDataBaseFileName>$(IntDir)leak_gc.compile.pdb</ProgramDataBaseFileName>
+ <DiagnosticsFormat>Caret</DiagnosticsFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;MTR_ENABLED;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)leak_gc.pdb</ProgramDatabaseFile>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <AdditionalLibraryDirectories>;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <OutputFile>$(OutDir)leak_gc.exe</OutputFile>
+ <EntryPointSymbol>mainCRTStartup</EntryPointSymbol>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
+ <Optimization>MaxSpeed</Optimization>
+ <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;MTR_ENABLED;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <StringPooling>true</StringPooling>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <PrecompiledHeader></PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <ProgramDataBaseFileName>$(IntDir)leak_gc.compile.pdb</ProgramDataBaseFileName>
+ <DiagnosticsFormat>Caret</DiagnosticsFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;MTR_ENABLED;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)leak_gc.pdb</ProgramDatabaseFile>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <AdditionalLibraryDirectories>;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <OutputFile>$(OutDir)leak_gc.exe</OutputFile>
+ <EntryPointSymbol>mainCRTStartup</EntryPointSymbol>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\src\gc_leak.cpp">
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="test_bench.vcxproj">
+ <Project>{A41847E7-90D0-8834-F9D7-6190E5AE2325}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
diff --git a/gctest/solution/leak_gc.vcxproj.filters b/gctest/solution/leak_gc.vcxproj.filters
new file mode 100644
index 0000000..8e2c3bc
--- /dev/null
+++ b/gctest/solution/leak_gc.vcxproj.filters
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="16.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="src">
+ <UniqueIdentifier>{2DAB880B-99B4-887C-2230-9F7C8E38947C}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\src\gc_leak.cpp">
+ <Filter>src</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project>
diff --git a/gctest/solution/test_bench.make b/gctest/solution/test_bench.make
new file mode 100644
index 0000000..f58b981
--- /dev/null
+++ b/gctest/solution/test_bench.make
@@ -0,0 +1,256 @@
+# GNU Make project makefile autogenerated by GENie
+ifndef config
+ config=debug32
+endif
+
+ifndef verbose
+ SILENT = @
+endif
+
+SHELLTYPE := msdos
+ifeq (,$(ComSpec)$(COMSPEC))
+ SHELLTYPE := posix
+endif
+ifeq (/bin,$(findstring /bin,$(SHELL)))
+ SHELLTYPE := posix
+endif
+ifeq (/bin,$(findstring /bin,$(MAKESHELL)))
+ SHELLTYPE := posix
+endif
+
+ifeq (posix,$(SHELLTYPE))
+ MKDIR = $(SILENT) mkdir -p "$(1)"
+ COPY = $(SILENT) cp -fR "$(1)" "$(2)"
+ RM = $(SILENT) rm -f "$(1)"
+else
+ MKDIR = $(SILENT) mkdir "$(subst /,\\,$(1))" 2> nul || exit 0
+ COPY = $(SILENT) copy /Y "$(subst /,\\,$(1))" "$(subst /,\\,$(2))"
+ RM = $(SILENT) del /F "$(subst /,\\,$(1))" 2> nul || exit 0
+endif
+
+CC = gcc
+CXX = g++
+AR = ar
+
+ifndef RESCOMP
+ ifdef WINDRES
+ RESCOMP = $(WINDRES)
+ else
+ RESCOMP = windres
+ endif
+endif
+
+MAKEFILE = test_bench.make
+
+ifeq ($(config),debug32)
+ OBJDIR = ../../JSImpl/build/obj/Debug/x32/Debug/test_bench
+ TARGETDIR = ../../JSImpl/build/bin/Debug
+ TARGET = $(TARGETDIR)/libtest_bench.a
+ DEFINES += -D_SCL_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS -DMTR_ENABLED
+ ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP -MP $(DEFINES) $(INCLUDES)
+ ALL_ASMFLAGS += $(ASMFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -m32
+ ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -m32
+ ALL_CXXFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -m32 -std=c++17
+ ALL_OBJCFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -m32
+ ALL_OBJCPPFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -m32 -std=c++17
+ ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES)
+ ALL_LDFLAGS += $(LDFLAGS) -m32
+ LIBDEPS +=
+ LDDEPS +=
+ LDRESP =
+ LIBS += $(LDDEPS)
+ EXTERNAL_LIBS +=
+ LINKOBJS = $(OBJECTS)
+ LINKCMD = $(AR) -rcs $(TARGET)
+ OBJRESP =
+ OBJECTS := \
+ $(OBJDIR)/src/main.o \
+ $(OBJDIR)/src/minitrace.o \
+
+ define PREBUILDCMDS
+ endef
+ define PRELINKCMDS
+ endef
+ define POSTBUILDCMDS
+ endef
+endif
+
+ifeq ($(config),release32)
+ OBJDIR = ../../JSImpl/build/obj/Release/x32/Release/test_bench
+ TARGETDIR = ../../JSImpl/build/bin/Release
+ TARGET = $(TARGETDIR)/libtest_bench.a
+ DEFINES += -D_SCL_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS -DMTR_ENABLED
+ ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP -MP $(DEFINES) $(INCLUDES)
+ ALL_ASMFLAGS += $(ASMFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -O3 -m32
+ ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -O3 -m32
+ ALL_CXXFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -O3 -m32 -std=c++17
+ ALL_OBJCFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -O3 -m32
+ ALL_OBJCPPFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -O3 -m32 -std=c++17
+ ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES)
+ ALL_LDFLAGS += $(LDFLAGS) -m32
+ LIBDEPS +=
+ LDDEPS +=
+ LDRESP =
+ LIBS += $(LDDEPS)
+ EXTERNAL_LIBS +=
+ LINKOBJS = $(OBJECTS)
+ LINKCMD = $(AR) -rcs $(TARGET)
+ OBJRESP =
+ OBJECTS := \
+ $(OBJDIR)/src/main.o \
+ $(OBJDIR)/src/minitrace.o \
+
+ define PREBUILDCMDS
+ endef
+ define PRELINKCMDS
+ endef
+ define POSTBUILDCMDS
+ endef
+endif
+
+ifeq ($(config),debug64)
+ OBJDIR = ../../JSImpl/build/obj/Debug/x64/Debug/test_bench
+ TARGETDIR = ../../JSImpl/build/bin/Debug
+ TARGET = $(TARGETDIR)/libtest_bench.a
+ DEFINES += -D_SCL_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS -DMTR_ENABLED
+ ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP -MP $(DEFINES) $(INCLUDES)
+ ALL_ASMFLAGS += $(ASMFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -m64
+ ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -m64
+ ALL_CXXFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -m64 -std=c++17
+ ALL_OBJCFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -m64
+ ALL_OBJCPPFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -m64 -std=c++17
+ ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES)
+ ALL_LDFLAGS += $(LDFLAGS) -m64
+ LIBDEPS +=
+ LDDEPS +=
+ LDRESP =
+ LIBS += $(LDDEPS)
+ EXTERNAL_LIBS +=
+ LINKOBJS = $(OBJECTS)
+ LINKCMD = $(AR) -rcs $(TARGET)
+ OBJRESP =
+ OBJECTS := \
+ $(OBJDIR)/src/main.o \
+ $(OBJDIR)/src/minitrace.o \
+
+ define PREBUILDCMDS
+ endef
+ define PRELINKCMDS
+ endef
+ define POSTBUILDCMDS
+ endef
+endif
+
+ifeq ($(config),release64)
+ OBJDIR = ../../JSImpl/build/obj/Release/x64/Release/test_bench
+ TARGETDIR = ../../JSImpl/build/bin/Release
+ TARGET = $(TARGETDIR)/libtest_bench.a
+ DEFINES += -D_SCL_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS -DMTR_ENABLED
+ ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP -MP $(DEFINES) $(INCLUDES)
+ ALL_ASMFLAGS += $(ASMFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -O3 -m64
+ ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -O3 -m64
+ ALL_CXXFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -O3 -m64 -std=c++17
+ ALL_OBJCFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -O3 -m64
+ ALL_OBJCPPFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -g -O3 -m64 -std=c++17
+ ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES)
+ ALL_LDFLAGS += $(LDFLAGS) -m64
+ LIBDEPS +=
+ LDDEPS +=
+ LDRESP =
+ LIBS += $(LDDEPS)
+ EXTERNAL_LIBS +=
+ LINKOBJS = $(OBJECTS)
+ LINKCMD = $(AR) -rcs $(TARGET)
+ OBJRESP =
+ OBJECTS := \
+ $(OBJDIR)/src/main.o \
+ $(OBJDIR)/src/minitrace.o \
+
+ define PREBUILDCMDS
+ endef
+ define PRELINKCMDS
+ endef
+ define POSTBUILDCMDS
+ endef
+endif
+
+OBJDIRS := \
+ $(OBJDIR) \
+ $(OBJDIR)/src \
+
+RESOURCES := \
+
+.PHONY: clean prebuild prelink
+
+all: $(OBJDIRS) $(TARGETDIR) prebuild prelink $(TARGET)
+ @:
+
+$(TARGET): $(GCH) $(OBJECTS) $(LIBDEPS) $(EXTERNAL_LIBS) $(RESOURCES) $(OBJRESP) $(LDRESP) | $(TARGETDIR) $(OBJDIRS)
+ @echo Archiving test_bench
+ifeq (posix,$(SHELLTYPE))
+ $(SILENT) rm -f $(TARGET)
+else
+ $(SILENT) if exist $(subst /,\\,$(TARGET)) del $(subst /,\\,$(TARGET))
+endif
+ $(SILENT) $(LINKCMD) $(LINKOBJS)
+ $(POSTBUILDCMDS)
+
+$(TARGETDIR):
+ @echo Creating $(TARGETDIR)
+ -$(call MKDIR,$(TARGETDIR))
+
+$(OBJDIRS):
+ @echo Creating $(@)
+ -$(call MKDIR,$@)
+
+clean:
+ @echo Cleaning test_bench
+ifeq (posix,$(SHELLTYPE))
+ $(SILENT) rm -f $(TARGET)
+ $(SILENT) rm -rf $(OBJDIR)
+else
+ $(SILENT) if exist $(subst /,\\,$(TARGET)) del $(subst /,\\,$(TARGET))
+ $(SILENT) if exist $(subst /,\\,$(OBJDIR)) rmdir /s /q $(subst /,\\,$(OBJDIR))
+endif
+
+prebuild:
+ $(PREBUILDCMDS)
+
+prelink:
+ $(PRELINKCMDS)
+
+ifneq (,$(PCH))
+$(GCH): $(PCH) $(MAKEFILE) | $(OBJDIR)
+ @echo $(notdir $<)
+ $(SILENT) $(CXX) $(ALL_CXXFLAGS) -x c++-header $(DEFINES) $(INCLUDES) -o "$@" -c "$<"
+
+$(GCH_OBJC): $(PCH) $(MAKEFILE) | $(OBJDIR)
+ @echo $(notdir $<)
+ $(SILENT) $(CXX) $(ALL_OBJCPPFLAGS) -x objective-c++-header $(DEFINES) $(INCLUDES) -o "$@" -c "$<"
+endif
+
+ifneq (,$(OBJRESP))
+$(OBJRESP): $(OBJECTS) | $(TARGETDIR) $(OBJDIRS)
+ $(SILENT) echo $^
+ $(SILENT) echo $^ > $@
+endif
+
+ifneq (,$(LDRESP))
+$(LDRESP): $(LDDEPS) | $(TARGETDIR) $(OBJDIRS)
+ $(SILENT) echo $^
+ $(SILENT) echo $^ > $@
+endif
+
+$(OBJDIR)/src/main.o: ../src/main.cpp $(GCH) $(MAKEFILE) | $(OBJDIR)/src
+ @echo $(notdir $<)
+ $(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -c "$<"
+
+$(OBJDIR)/src/minitrace.o: ../src/minitrace.cpp $(GCH) $(MAKEFILE) | $(OBJDIR)/src
+ @echo $(notdir $<)
+ $(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -c "$<"
+
+-include $(OBJECTS:%.o=%.d)
+ifneq (,$(PCH))
+ -include $(OBJDIR)/$(notdir $(PCH)).d
+ -include $(OBJDIR)/$(notdir $(PCH))_objc.d
+endif
diff --git a/gctest/solution/test_bench.vcxproj b/gctest/solution/test_bench.vcxproj
new file mode 100644
index 0000000..5625175
--- /dev/null
+++ b/gctest/solution/test_bench.vcxproj
@@ -0,0 +1,238 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="16.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{A41847E7-90D0-8834-F9D7-6190E5AE2325}</ProjectGuid>
+ <RootNamespace>test_bench</RootNamespace>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformMinVersion>10.0.10240.0</WindowsTargetPlatformMinVersion>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v142</PlatformToolset>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ <DebugSymbols>true</DebugSymbols>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v142</PlatformToolset>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ <DebugSymbols>true</DebugSymbols>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v142</PlatformToolset>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ <DebugSymbols>true</DebugSymbols>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v142</PlatformToolset>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ <DebugSymbols>true</DebugSymbols>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>..\..\JSImpl\build\bin\Debug\</OutDir>
+ <IntDir>..\..\JSImpl\build\obj\Debug\x32\Debug\test_bench\</IntDir>
+ <TargetName>test_bench</TargetName>
+ <TargetExt>.lib</TargetExt>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <OutDir>..\..\JSImpl\build\bin\Debug\</OutDir>
+ <IntDir>..\..\JSImpl\build\obj\Debug\x64\Debug\test_bench\</IntDir>
+ <TargetName>test_bench</TargetName>
+ <TargetExt>.lib</TargetExt>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>..\..\JSImpl\build\bin\Release\</OutDir>
+ <IntDir>..\..\JSImpl\build\obj\Release\x32\Release\test_bench\</IntDir>
+ <TargetName>test_bench</TargetName>
+ <TargetExt>.lib</TargetExt>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <OutDir>..\..\JSImpl\build\bin\Release\</OutDir>
+ <IntDir>..\..\JSImpl\build\obj\Release\x64\Release\test_bench\</IntDir>
+ <TargetName>test_bench</TargetName>
+ <TargetExt>.lib</TargetExt>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;MTR_ENABLED;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <PrecompiledHeader></PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <ProgramDataBaseFileName>$(OutDir)test_bench.pdb</ProgramDataBaseFileName>
+ <DiagnosticsFormat>Caret</DiagnosticsFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;MTR_ENABLED;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Lib>
+ <OutputFile>$(OutDir)test_bench.lib</OutputFile>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Lib>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)test_bench.pdb</ProgramDatabaseFile>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;MTR_ENABLED;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <PrecompiledHeader></PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <ProgramDataBaseFileName>$(OutDir)test_bench.pdb</ProgramDataBaseFileName>
+ <DiagnosticsFormat>Caret</DiagnosticsFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;MTR_ENABLED;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Lib>
+ <OutputFile>$(OutDir)test_bench.lib</OutputFile>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Lib>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)test_bench.pdb</ProgramDatabaseFile>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
+ <Optimization>MaxSpeed</Optimization>
+ <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;MTR_ENABLED;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <StringPooling>true</StringPooling>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <PrecompiledHeader></PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <ProgramDataBaseFileName>$(OutDir)test_bench.pdb</ProgramDataBaseFileName>
+ <DiagnosticsFormat>Caret</DiagnosticsFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;MTR_ENABLED;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Lib>
+ <OutputFile>$(OutDir)test_bench.lib</OutputFile>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Lib>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)test_bench.pdb</ProgramDatabaseFile>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
+ <Optimization>MaxSpeed</Optimization>
+ <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;MTR_ENABLED;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <StringPooling>true</StringPooling>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <PrecompiledHeader></PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <ProgramDataBaseFileName>$(OutDir)test_bench.pdb</ProgramDataBaseFileName>
+ <DiagnosticsFormat>Caret</DiagnosticsFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;MTR_ENABLED;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Lib>
+ <OutputFile>$(OutDir)test_bench.lib</OutputFile>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Lib>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)test_bench.pdb</ProgramDatabaseFile>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\src\main.cpp">
+ </ClCompile>
+ <ClCompile Include="..\src\minitrace.cpp">
+ </ClCompile>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
diff --git a/gctest/solution/test_bench.vcxproj.filters b/gctest/solution/test_bench.vcxproj.filters
new file mode 100644
index 0000000..5240a4d
--- /dev/null
+++ b/gctest/solution/test_bench.vcxproj.filters
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="16.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="src">
+ <UniqueIdentifier>{2DAB880B-99B4-887C-2230-9F7C8E38947C}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\src\main.cpp">
+ <Filter>src</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\minitrace.cpp">
+ <Filter>src</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project>
diff --git a/gctest/src/cxxopts.hpp b/gctest/src/cxxopts.hpp
new file mode 100644
index 0000000..6d230f0
--- /dev/null
+++ b/gctest/src/cxxopts.hpp
@@ -0,0 +1,2114 @@
+/*
+
+Copyright (c) 2014, 2015, 2016, 2017 Jarryd Beck
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+*/
+
+#ifndef CXXOPTS_HPP_INCLUDED
+#define CXXOPTS_HPP_INCLUDED
+
+#include <cstring>
+#include <cctype>
+#include <exception>
+#include <iostream>
+#include <limits>
+#include <map>
+#include <memory>
+#include <regex>
+#include <sstream>
+#include <string>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+
+#ifdef __cpp_lib_optional
+#include <optional>
+#define CXXOPTS_HAS_OPTIONAL
+#endif
+
+#ifndef CXXOPTS_VECTOR_DELIMITER
+#define CXXOPTS_VECTOR_DELIMITER ','
+#endif
+
+#define CXXOPTS__VERSION_MAJOR 2
+#define CXXOPTS__VERSION_MINOR 2
+#define CXXOPTS__VERSION_PATCH 0
+
+namespace cxxopts
+{
+ static constexpr struct {
+ uint8_t major, minor, patch;
+ } version = {
+ CXXOPTS__VERSION_MAJOR,
+ CXXOPTS__VERSION_MINOR,
+ CXXOPTS__VERSION_PATCH
+ };
+}
+
+//when we ask cxxopts to use Unicode, help strings are processed using ICU,
+//which results in the correct lengths being computed for strings when they
+//are formatted for the help output
+//it is necessary to make sure that <unicode/unistr.h> can be found by the
+//compiler, and that icu-uc is linked in to the binary.
+
+#ifdef CXXOPTS_USE_UNICODE
+#include <unicode/unistr.h>
+
+namespace cxxopts
+{
+ typedef icu::UnicodeString String;
+
+ inline
+ String
+ toLocalString(std::string s)
+ {
+ return icu::UnicodeString::fromUTF8(std::move(s));
+ }
+
+ class UnicodeStringIterator : public
+ std::iterator<std::forward_iterator_tag, int32_t>
+ {
+ public:
+
+ UnicodeStringIterator(const icu::UnicodeString* string, int32_t pos)
+ : s(string)
+ , i(pos)
+ {
+ }
+
+ value_type
+ operator*() const
+ {
+ return s->char32At(i);
+ }
+
+ bool
+ operator==(const UnicodeStringIterator& rhs) const
+ {
+ return s == rhs.s && i == rhs.i;
+ }
+
+ bool
+ operator!=(const UnicodeStringIterator& rhs) const
+ {
+ return !(*this == rhs);
+ }
+
+ UnicodeStringIterator&
+ operator++()
+ {
+ ++i;
+ return *this;
+ }
+
+ UnicodeStringIterator
+ operator+(int32_t v)
+ {
+ return UnicodeStringIterator(s, i + v);
+ }
+
+ private:
+ const icu::UnicodeString* s;
+ int32_t i;
+ };
+
+ inline
+ String&
+ stringAppend(String&s, String a)
+ {
+ return s.append(std::move(a));
+ }
+
+ inline
+ String&
+ stringAppend(String& s, int n, UChar32 c)
+ {
+ for (int i = 0; i != n; ++i)
+ {
+ s.append(c);
+ }
+
+ return s;
+ }
+
+ template <typename Iterator>
+ String&
+ stringAppend(String& s, Iterator begin, Iterator end)
+ {
+ while (begin != end)
+ {
+ s.append(*begin);
+ ++begin;
+ }
+
+ return s;
+ }
+
+ inline
+ size_t
+ stringLength(const String& s)
+ {
+ return s.length();
+ }
+
+ inline
+ std::string
+ toUTF8String(const String& s)
+ {
+ std::string result;
+ s.toUTF8String(result);
+
+ return result;
+ }
+
+ inline
+ bool
+ empty(const String& s)
+ {
+ return s.isEmpty();
+ }
+}
+
+namespace std
+{
+ inline
+ cxxopts::UnicodeStringIterator
+ begin(const icu::UnicodeString& s)
+ {
+ return cxxopts::UnicodeStringIterator(&s, 0);
+ }
+
+ inline
+ cxxopts::UnicodeStringIterator
+ end(const icu::UnicodeString& s)
+ {
+ return cxxopts::UnicodeStringIterator(&s, s.length());
+ }
+}
+
+//ifdef CXXOPTS_USE_UNICODE
+#else
+
+namespace cxxopts
+{
+ typedef std::string String;
+
+ template <typename T>
+ T
+ toLocalString(T&& t)
+ {
+ return std::forward<T>(t);
+ }
+
+ inline
+ size_t
+ stringLength(const String& s)
+ {
+ return s.length();
+ }
+
+ inline
+ String&
+ stringAppend(String&s, String a)
+ {
+ return s.append(std::move(a));
+ }
+
+ inline
+ String&
+ stringAppend(String& s, size_t n, char c)
+ {
+ return s.append(n, c);
+ }
+
+ template <typename Iterator>
+ String&
+ stringAppend(String& s, Iterator begin, Iterator end)
+ {
+ return s.append(begin, end);
+ }
+
+ template <typename T>
+ std::string
+ toUTF8String(T&& t)
+ {
+ return std::forward<T>(t);
+ }
+
+ inline
+ bool
+ empty(const std::string& s)
+ {
+ return s.empty();
+ }
+}
+
+//ifdef CXXOPTS_USE_UNICODE
+#endif
+
+namespace cxxopts
+{
+ namespace
+ {
+#ifdef _WIN32
+ const std::string LQUOTE("\'");
+ const std::string RQUOTE("\'");
+#else
+ const std::string LQUOTE("‘");
+ const std::string RQUOTE("’");
+#endif
+ }
+
+ class Value : public std::enable_shared_from_this<Value>
+ {
+ public:
+
+ virtual ~Value() = default;
+
+ virtual
+ std::shared_ptr<Value>
+ clone() const = 0;
+
+ virtual void
+ parse(const std::string& text) const = 0;
+
+ virtual void
+ parse() const = 0;
+
+ virtual bool
+ has_default() const = 0;
+
+ virtual bool
+ is_container() const = 0;
+
+ virtual bool
+ has_implicit() const = 0;
+
+ virtual std::string
+ get_default_value() const = 0;
+
+ virtual std::string
+ get_implicit_value() const = 0;
+
+ virtual std::shared_ptr<Value>
+ default_value(const std::string& value) = 0;
+
+ virtual std::shared_ptr<Value>
+ implicit_value(const std::string& value) = 0;
+
+ virtual std::shared_ptr<Value>
+ no_implicit_value() = 0;
+
+ virtual bool
+ is_boolean() const = 0;
+ };
+
+ class OptionException : public std::exception
+ {
+ public:
+ OptionException(const std::string& message)
+ : m_message(message)
+ {
+ }
+
+ virtual const char*
+ what() const noexcept
+ {
+ return m_message.c_str();
+ }
+
+ private:
+ std::string m_message;
+ };
+
+ class OptionSpecException : public OptionException
+ {
+ public:
+
+ OptionSpecException(const std::string& message)
+ : OptionException(message)
+ {
+ }
+ };
+
+ class OptionParseException : public OptionException
+ {
+ public:
+ OptionParseException(const std::string& message)
+ : OptionException(message)
+ {
+ }
+ };
+
+ class option_exists_error : public OptionSpecException
+ {
+ public:
+ option_exists_error(const std::string& option)
+ : OptionSpecException("Option " + LQUOTE + option + RQUOTE + " already exists")
+ {
+ }
+ };
+
+ class invalid_option_format_error : public OptionSpecException
+ {
+ public:
+ invalid_option_format_error(const std::string& format)
+ : OptionSpecException("Invalid option format " + LQUOTE + format + RQUOTE)
+ {
+ }
+ };
+
+ class option_syntax_exception : public OptionParseException {
+ public:
+ option_syntax_exception(const std::string& text)
+ : OptionParseException("Argument " + LQUOTE + text + RQUOTE +
+ " starts with a - but has incorrect syntax")
+ {
+ }
+ };
+
+ class option_not_exists_exception : public OptionParseException
+ {
+ public:
+ option_not_exists_exception(const std::string& option)
+ : OptionParseException("Option " + LQUOTE + option + RQUOTE + " does not exist")
+ {
+ }
+ };
+
+ class missing_argument_exception : public OptionParseException
+ {
+ public:
+ missing_argument_exception(const std::string& option)
+ : OptionParseException(
+ "Option " + LQUOTE + option + RQUOTE + " is missing an argument"
+ )
+ {
+ }
+ };
+
+ class option_requires_argument_exception : public OptionParseException
+ {
+ public:
+ option_requires_argument_exception(const std::string& option)
+ : OptionParseException(
+ "Option " + LQUOTE + option + RQUOTE + " requires an argument"
+ )
+ {
+ }
+ };
+
+ class option_not_has_argument_exception : public OptionParseException
+ {
+ public:
+ option_not_has_argument_exception
+ (
+ const std::string& option,
+ const std::string& arg
+ )
+ : OptionParseException(
+ "Option " + LQUOTE + option + RQUOTE +
+ " does not take an argument, but argument " +
+ LQUOTE + arg + RQUOTE + " given"
+ )
+ {
+ }
+ };
+
+ class option_not_present_exception : public OptionParseException
+ {
+ public:
+ option_not_present_exception(const std::string& option)
+ : OptionParseException("Option " + LQUOTE + option + RQUOTE + " not present")
+ {
+ }
+ };
+
+ class argument_incorrect_type : public OptionParseException
+ {
+ public:
+ argument_incorrect_type
+ (
+ const std::string& arg
+ )
+ : OptionParseException(
+ "Argument " + LQUOTE + arg + RQUOTE + " failed to parse"
+ )
+ {
+ }
+ };
+
+ class option_required_exception : public OptionParseException
+ {
+ public:
+ option_required_exception(const std::string& option)
+ : OptionParseException(
+ "Option " + LQUOTE + option + RQUOTE + " is required but not present"
+ )
+ {
+ }
+ };
+
+ namespace values
+ {
+ namespace
+ {
+ std::basic_regex<char> integer_pattern
+ ("(-)?(0x)?([0-9a-zA-Z]+)|((0x)?0)");
+ std::basic_regex<char> truthy_pattern
+ ("(t|T)(rue)?|1");
+ std::basic_regex<char> falsy_pattern
+ ("(f|F)(alse)?|0");
+ }
+
+ namespace detail
+ {
+ template <typename T, bool B>
+ struct SignedCheck;
+
+ template <typename T>
+ struct SignedCheck<T, true>
+ {
+ template <typename U>
+ void
+ operator()(bool negative, U u, const std::string& text)
+ {
+ if (negative)
+ {
+ if (u > static_cast<U>((std::numeric_limits<T>::min)()))
+ {
+ throw argument_incorrect_type(text);
+ }
+ }
+ else
+ {
+ if (u > static_cast<U>((std::numeric_limits<T>::max)()))
+ {
+ throw argument_incorrect_type(text);
+ }
+ }
+ }
+ };
+
+ template <typename T>
+ struct SignedCheck<T, false>
+ {
+ template <typename U>
+ void
+ operator()(bool, U, const std::string&) {}
+ };
+
+ template <typename T, typename U>
+ void
+ check_signed_range(bool negative, U value, const std::string& text)
+ {
+ SignedCheck<T, std::numeric_limits<T>::is_signed>()(negative, value, text);
+ }
+ }
+
+ template <typename R, typename T>
+ R
+ checked_negate(T&& t, const std::string&, std::true_type)
+ {
+ // if we got to here, then `t` is a positive number that fits into
+ // `R`. So to avoid MSVC C4146, we first cast it to `R`.
+ // See https://github.com/jarro2783/cxxopts/issues/62 for more details.
+ return -static_cast<R>(t-1)-1;
+ }
+
+ template <typename R, typename T>
+ T
+ checked_negate(T&&, const std::string& text, std::false_type)
+ {
+ throw argument_incorrect_type(text);
+ }
+
+ template <typename T>
+ void
+ integer_parser(const std::string& text, T& value)
+ {
+ std::smatch match;
+ std::regex_match(text, match, integer_pattern);
+
+ if (match.length() == 0)
+ {
+ throw argument_incorrect_type(text);
+ }
+
+ if (match.length(4) > 0)
+ {
+ value = 0;
+ return;
+ }
+
+ using US = typename std::make_unsigned<T>::type;
+
+ constexpr bool is_signed = std::numeric_limits<T>::is_signed;
+ const bool negative = match.length(1) > 0;
+ const uint8_t base = match.length(2) > 0 ? 16 : 10;
+
+ auto value_match = match[3];
+
+ US result = 0;
+
+ for (auto iter = value_match.first; iter != value_match.second; ++iter)
+ {
+ US digit = 0;
+
+ if (*iter >= '0' && *iter <= '9')
+ {
+ digit = static_cast<US>(*iter - '0');
+ }
+ else if (base == 16 && *iter >= 'a' && *iter <= 'f')
+ {
+ digit = static_cast<US>(*iter - 'a' + 10);
+ }
+ else if (base == 16 && *iter >= 'A' && *iter <= 'F')
+ {
+ digit = static_cast<US>(*iter - 'A' + 10);
+ }
+ else
+ {
+ throw argument_incorrect_type(text);
+ }
+
+ US next = result * base + digit;
+ if (result > next)
+ {
+ throw argument_incorrect_type(text);
+ }
+
+ result = next;
+ }
+
+ detail::check_signed_range<T>(negative, result, text);
+
+ if (negative)
+ {
+ value = checked_negate<T>(result,
+ text,
+ std::integral_constant<bool, is_signed>());
+ }
+ else
+ {
+ value = static_cast<T>(result);
+ }
+ }
+
+ template <typename T>
+ void stringstream_parser(const std::string& text, T& value)
+ {
+ std::stringstream in(text);
+ in >> value;
+ if (!in) {
+ throw argument_incorrect_type(text);
+ }
+ }
+
+ inline
+ void
+ parse_value(const std::string& text, uint8_t& value)
+ {
+ integer_parser(text, value);
+ }
+
+ inline
+ void
+ parse_value(const std::string& text, int8_t& value)
+ {
+ integer_parser(text, value);
+ }
+
+ inline
+ void
+ parse_value(const std::string& text, uint16_t& value)
+ {
+ integer_parser(text, value);
+ }
+
+ inline
+ void
+ parse_value(const std::string& text, int16_t& value)
+ {
+ integer_parser(text, value);
+ }
+
+ inline
+ void
+ parse_value(const std::string& text, uint32_t& value)
+ {
+ integer_parser(text, value);
+ }
+
+ inline
+ void
+ parse_value(const std::string& text, int32_t& value)
+ {
+ integer_parser(text, value);
+ }
+
+ inline
+ void
+ parse_value(const std::string& text, uint64_t& value)
+ {
+ integer_parser(text, value);
+ }
+
+ inline
+ void
+ parse_value(const std::string& text, int64_t& value)
+ {
+ integer_parser(text, value);
+ }
+
+ inline
+ void
+ parse_value(const std::string& text, bool& value)
+ {
+ std::smatch result;
+ std::regex_match(text, result, truthy_pattern);
+
+ if (!result.empty())
+ {
+ value = true;
+ return;
+ }
+
+ std::regex_match(text, result, falsy_pattern);
+ if (!result.empty())
+ {
+ value = false;
+ return;
+ }
+
+ throw argument_incorrect_type(text);
+ }
+
+ inline
+ void
+ parse_value(const std::string& text, std::string& value)
+ {
+ value = text;
+ }
+
+ // The fallback parser. It uses the stringstream parser to parse all types
+ // that have not been overloaded explicitly. It has to be placed in the
+ // source code before all other more specialized templates.
+ template <typename T>
+ void
+ parse_value(const std::string& text, T& value) {
+ stringstream_parser(text, value);
+ }
+
+ template <typename T>
+ void
+ parse_value(const std::string& text, std::vector<T>& value)
+ {
+ std::stringstream in(text);
+ std::string token;
+ while(in.eof() == false && std::getline(in, token, CXXOPTS_VECTOR_DELIMITER)) {
+ T v;
+ parse_value(token, v);
+ value.emplace_back(std::move(v));
+ }
+ }
+
+#ifdef CXXOPTS_HAS_OPTIONAL
+ template <typename T>
+ void
+ parse_value(const std::string& text, std::optional<T>& value)
+ {
+ T result;
+ parse_value(text, result);
+ value = std::move(result);
+ }
+#endif
+
+ template <typename T>
+ struct type_is_container
+ {
+ static constexpr bool value = false;
+ };
+
+ template <typename T>
+ struct type_is_container<std::vector<T>>
+ {
+ static constexpr bool value = true;
+ };
+
+ template <typename T>
+ class abstract_value : public Value
+ {
+ using Self = abstract_value<T>;
+
+ public:
+ abstract_value()
+ : m_result(std::make_shared<T>())
+ , m_store(m_result.get())
+ {
+ }
+
+ abstract_value(T* t)
+ : m_store(t)
+ {
+ }
+
+ virtual ~abstract_value() = default;
+
+ abstract_value(const abstract_value& rhs)
+ {
+ if (rhs.m_result)
+ {
+ m_result = std::make_shared<T>();
+ m_store = m_result.get();
+ }
+ else
+ {
+ m_store = rhs.m_store;
+ }
+
+ m_default = rhs.m_default;
+ m_implicit = rhs.m_implicit;
+ m_default_value = rhs.m_default_value;
+ m_implicit_value = rhs.m_implicit_value;
+ }
+
+ void
+ parse(const std::string& text) const
+ {
+ parse_value(text, *m_store);
+ }
+
+ bool
+ is_container() const
+ {
+ return type_is_container<T>::value;
+ }
+
+ void
+ parse() const
+ {
+ parse_value(m_default_value, *m_store);
+ }
+
+ bool
+ has_default() const
+ {
+ return m_default;
+ }
+
+ bool
+ has_implicit() const
+ {
+ return m_implicit;
+ }
+
+ std::shared_ptr<Value>
+ default_value(const std::string& value)
+ {
+ m_default = true;
+ m_default_value = value;
+ return shared_from_this();
+ }
+
+ std::shared_ptr<Value>
+ implicit_value(const std::string& value)
+ {
+ m_implicit = true;
+ m_implicit_value = value;
+ return shared_from_this();
+ }
+
+ std::shared_ptr<Value>
+ no_implicit_value()
+ {
+ m_implicit = false;
+ return shared_from_this();
+ }
+
+ std::string
+ get_default_value() const
+ {
+ return m_default_value;
+ }
+
+ std::string
+ get_implicit_value() const
+ {
+ return m_implicit_value;
+ }
+
+ bool
+ is_boolean() const
+ {
+ return std::is_same<T, bool>::value;
+ }
+
+ const T&
+ get() const
+ {
+ if (m_store == nullptr)
+ {
+ return *m_result;
+ }
+ else
+ {
+ return *m_store;
+ }
+ }
+
+ protected:
+ std::shared_ptr<T> m_result;
+ T* m_store;
+
+ bool m_default = false;
+ bool m_implicit = false;
+
+ std::string m_default_value;
+ std::string m_implicit_value;
+ };
+
+ template <typename T>
+ class standard_value : public abstract_value<T>
+ {
+ public:
+ using abstract_value<T>::abstract_value;
+
+ std::shared_ptr<Value>
+ clone() const
+ {
+ return std::make_shared<standard_value<T>>(*this);
+ }
+ };
+
+ template <>
+ class standard_value<bool> : public abstract_value<bool>
+ {
+ public:
+ ~standard_value() = default;
+
+ standard_value()
+ {
+ set_default_and_implicit();
+ }
+
+ standard_value(bool* b)
+ : abstract_value(b)
+ {
+ set_default_and_implicit();
+ }
+
+ std::shared_ptr<Value>
+ clone() const
+ {
+ return std::make_shared<standard_value<bool>>(*this);
+ }
+
+ private:
+
+ void
+ set_default_and_implicit()
+ {
+ m_default = true;
+ m_default_value = "false";
+ m_implicit = true;
+ m_implicit_value = "true";
+ }
+ };
+ }
+
+ template <typename T>
+ std::shared_ptr<Value>
+ value()
+ {
+ return std::make_shared<values::standard_value<T>>();
+ }
+
+ template <typename T>
+ std::shared_ptr<Value>
+ value(T& t)
+ {
+ return std::make_shared<values::standard_value<T>>(&t);
+ }
+
+ class OptionAdder;
+
+ class OptionDetails
+ {
+ public:
+ OptionDetails
+ (
+ const std::string& short_,
+ const std::string& long_,
+ const String& desc,
+ std::shared_ptr<const Value> val
+ )
+ : m_short(short_)
+ , m_long(long_)
+ , m_desc(desc)
+ , m_value(val)
+ , m_count(0)
+ {
+ }
+
+ OptionDetails(const OptionDetails& rhs)
+ : m_desc(rhs.m_desc)
+ , m_count(rhs.m_count)
+ {
+ m_value = rhs.m_value->clone();
+ }
+
+ OptionDetails(OptionDetails&& rhs) = default;
+
+ const String&
+ description() const
+ {
+ return m_desc;
+ }
+
+ const Value& value() const {
+ return *m_value;
+ }
+
+ std::shared_ptr<Value>
+ make_storage() const
+ {
+ return m_value->clone();
+ }
+
+ const std::string&
+ short_name() const
+ {
+ return m_short;
+ }
+
+ const std::string&
+ long_name() const
+ {
+ return m_long;
+ }
+
+ private:
+ std::string m_short;
+ std::string m_long;
+ String m_desc;
+ std::shared_ptr<const Value> m_value;
+ int m_count;
+ };
+
+ struct HelpOptionDetails
+ {
+ std::string s;
+ std::string l;
+ String desc;
+ bool has_default;
+ std::string default_value;
+ bool has_implicit;
+ std::string implicit_value;
+ std::string arg_help;
+ bool is_container;
+ bool is_boolean;
+ };
+
+ struct HelpGroupDetails
+ {
+ std::string name;
+ std::string description;
+ std::vector<HelpOptionDetails> options;
+ };
+
+ class OptionValue
+ {
+ public:
+ void
+ parse
+ (
+ std::shared_ptr<const OptionDetails> details,
+ const std::string& text
+ )
+ {
+ ensure_value(details);
+ ++m_count;
+ m_value->parse(text);
+ }
+
+ void
+ parse_default(std::shared_ptr<const OptionDetails> details)
+ {
+ ensure_value(details);
+ m_default = true;
+ m_value->parse();
+ }
+
+ size_t
+ count() const noexcept
+ {
+ return m_count;
+ }
+
+ // TODO: maybe default options should count towards the number of arguments
+ bool
+ has_default() const noexcept
+ {
+ return m_default;
+ }
+
+ template <typename T>
+ const T&
+ as() const
+ {
+ if (m_value == nullptr) {
+ throw std::domain_error("No value");
+ }
+
+#ifdef CXXOPTS_NO_RTTI
+ return static_cast<const values::standard_value<T>&>(*m_value).get();
+#else
+ return dynamic_cast<const values::standard_value<T>&>(*m_value).get();
+#endif
+ }
+
+ private:
+ void
+ ensure_value(std::shared_ptr<const OptionDetails> details)
+ {
+ if (m_value == nullptr)
+ {
+ m_value = details->make_storage();
+ }
+ }
+
+ std::shared_ptr<Value> m_value;
+ size_t m_count = 0;
+ bool m_default = false;
+ };
+
+ class KeyValue
+ {
+ public:
+ KeyValue(std::string key_, std::string value_)
+ : m_key(std::move(key_))
+ , m_value(std::move(value_))
+ {
+ }
+
+ const
+ std::string&
+ key() const
+ {
+ return m_key;
+ }
+
+ const
+ std::string&
+ value() const
+ {
+ return m_value;
+ }
+
+ template <typename T>
+ T
+ as() const
+ {
+ T result;
+ values::parse_value(m_value, result);
+ return result;
+ }
+
+ private:
+ std::string m_key;
+ std::string m_value;
+ };
+
+ class ParseResult
+ {
+ public:
+
+ ParseResult(
+ const std::shared_ptr<
+ std::unordered_map<std::string, std::shared_ptr<OptionDetails>>
+ >,
+ std::vector<std::string>,
+ bool allow_unrecognised,
+ int&, char**&);
+
+ size_t
+ count(const std::string& o) const
+ {
+ auto iter = m_options->find(o);
+ if (iter == m_options->end())
+ {
+ return 0;
+ }
+
+ auto riter = m_results.find(iter->second);
+
+ return riter->second.count();
+ }
+
+ const OptionValue&
+ operator[](const std::string& option) const
+ {
+ auto iter = m_options->find(option);
+
+ if (iter == m_options->end())
+ {
+ throw option_not_present_exception(option);
+ }
+
+ auto riter = m_results.find(iter->second);
+
+ return riter->second;
+ }
+
+ const std::vector<KeyValue>&
+ arguments() const
+ {
+ return m_sequential;
+ }
+
+ private:
+
+ void
+ parse(int& argc, char**& argv);
+
+ void
+ add_to_option(const std::string& option, const std::string& arg);
+
+ bool
+ consume_positional(std::string a);
+
+ void
+ parse_option
+ (
+ std::shared_ptr<OptionDetails> value,
+ const std::string& name,
+ const std::string& arg = ""
+ );
+
+ void
+ parse_default(std::shared_ptr<OptionDetails> details);
+
+ void
+ checked_parse_arg
+ (
+ int argc,
+ char* argv[],
+ int& current,
+ std::shared_ptr<OptionDetails> value,
+ const std::string& name
+ );
+
+ const std::shared_ptr<
+ std::unordered_map<std::string, std::shared_ptr<OptionDetails>>
+ > m_options;
+ std::vector<std::string> m_positional;
+ std::vector<std::string>::iterator m_next_positional;
+ std::unordered_set<std::string> m_positional_set;
+ std::unordered_map<std::shared_ptr<OptionDetails>, OptionValue> m_results;
+
+ bool m_allow_unrecognised;
+
+ std::vector<KeyValue> m_sequential;
+ };
+
+ class Options
+ {
+ typedef std::unordered_map<std::string, std::shared_ptr<OptionDetails>>
+ OptionMap;
+ public:
+
+ Options(std::string program, std::string help_string = "")
+ : m_program(std::move(program))
+ , m_help_string(toLocalString(std::move(help_string)))
+ , m_custom_help("[OPTION...]")
+ , m_positional_help("positional parameters")
+ , m_show_positional(false)
+ , m_allow_unrecognised(false)
+ , m_options(std::make_shared<OptionMap>())
+ , m_next_positional(m_positional.end())
+ {
+ }
+
+ Options&
+ positional_help(std::string help_text)
+ {
+ m_positional_help = std::move(help_text);
+ return *this;
+ }
+
+ Options&
+ custom_help(std::string help_text)
+ {
+ m_custom_help = std::move(help_text);
+ return *this;
+ }
+
+ Options&
+ show_positional_help()
+ {
+ m_show_positional = true;
+ return *this;
+ }
+
+ Options&
+ allow_unrecognised_options()
+ {
+ m_allow_unrecognised = true;
+ return *this;
+ }
+
+ ParseResult
+ parse(int& argc, char**& argv);
+
+ OptionAdder
+ add_options(std::string group = "");
+
+ void
+ add_option
+ (
+ const std::string& group,
+ const std::string& s,
+ const std::string& l,
+ std::string desc,
+ std::shared_ptr<const Value> value,
+ std::string arg_help
+ );
+
+ //parse positional arguments into the given option
+ void
+ parse_positional(std::string option);
+
+ void
+ parse_positional(std::vector<std::string> options);
+
+ void
+ parse_positional(std::initializer_list<std::string> options);
+
+ template <typename Iterator>
+ void
+ parse_positional(Iterator begin, Iterator end) {
+ parse_positional(std::vector<std::string>{begin, end});
+ }
+
+ std::string
+ help(const std::vector<std::string>& groups = {}) const;
+
+ const std::vector<std::string>
+ groups() const;
+
+ const HelpGroupDetails&
+ group_help(const std::string& group) const;
+
+ private:
+
+ void
+ add_one_option
+ (
+ const std::string& option,
+ std::shared_ptr<OptionDetails> details
+ );
+
+ String
+ help_one_group(const std::string& group) const;
+
+ void
+ generate_group_help
+ (
+ String& result,
+ const std::vector<std::string>& groups
+ ) const;
+
+ void
+ generate_all_groups_help(String& result) const;
+
+ std::string m_program;
+ String m_help_string;
+ std::string m_custom_help;
+ std::string m_positional_help;
+ bool m_show_positional;
+ bool m_allow_unrecognised;
+
+ std::shared_ptr<OptionMap> m_options;
+ std::vector<std::string> m_positional;
+ std::vector<std::string>::iterator m_next_positional;
+ std::unordered_set<std::string> m_positional_set;
+
+ //mapping from groups to help options
+ std::map<std::string, HelpGroupDetails> m_help;
+ };
+
+ class OptionAdder
+ {
+ public:
+
+ OptionAdder(Options& options, std::string group)
+ : m_options(options), m_group(std::move(group))
+ {
+ }
+
+ OptionAdder&
+ operator()
+ (
+ const std::string& opts,
+ const std::string& desc,
+ std::shared_ptr<const Value> value
+ = ::cxxopts::value<bool>(),
+ std::string arg_help = ""
+ );
+
+ private:
+ Options& m_options;
+ std::string m_group;
+ };
+
+ namespace
+ {
+ constexpr int OPTION_LONGEST = 30;
+ constexpr int OPTION_DESC_GAP = 2;
+
+ std::basic_regex<char> option_matcher
+ ("--([[:alnum:]][-_[:alnum:]]+)(=(.*))?|-([[:alnum:]]+)");
+
+ std::basic_regex<char> option_specifier
+ ("(([[:alnum:]]),)?[ ]*([[:alnum:]][-_[:alnum:]]*)?");
+
+ String
+ format_option
+ (
+ const HelpOptionDetails& o
+ )
+ {
+ auto& s = o.s;
+ auto& l = o.l;
+
+ String result = " ";
+
+ if (s.size() > 0)
+ {
+ result += "-" + toLocalString(s) + ",";
+ }
+ else
+ {
+ result += " ";
+ }
+
+ if (l.size() > 0)
+ {
+ result += " --" + toLocalString(l);
+ }
+
+ auto arg = o.arg_help.size() > 0 ? toLocalString(o.arg_help) : "arg";
+
+ if (!o.is_boolean)
+ {
+ if (o.has_implicit)
+ {
+ result += " [=" + arg + "(=" + toLocalString(o.implicit_value) + ")]";
+ }
+ else
+ {
+ result += " " + arg;
+ }
+ }
+
+ return result;
+ }
+
+ String
+ format_description
+ (
+ const HelpOptionDetails& o,
+ size_t start,
+ size_t width
+ )
+ {
+ auto desc = o.desc;
+
+ if (o.has_default && (!o.is_boolean || o.default_value != "false"))
+ {
+ desc += toLocalString(" (default: " + o.default_value + ")");
+ }
+
+ String result;
+
+ auto current = std::begin(desc);
+ auto startLine = current;
+ auto lastSpace = current;
+
+ auto size = size_t{};
+
+ while (current != std::end(desc))
+ {
+ if (*current == ' ')
+ {
+ lastSpace = current;
+ }
+
+ if (*current == '\n')
+ {
+ startLine = current + 1;
+ lastSpace = startLine;
+ }
+ else if (size > width)
+ {
+ if (lastSpace == startLine)
+ {
+ stringAppend(result, startLine, current + 1);
+ stringAppend(result, "\n");
+ stringAppend(result, start, ' ');
+ startLine = current + 1;
+ lastSpace = startLine;
+ }
+ else
+ {
+ stringAppend(result, startLine, lastSpace);
+ stringAppend(result, "\n");
+ stringAppend(result, start, ' ');
+ startLine = lastSpace + 1;
+ lastSpace = startLine;
+ }
+ size = 0;
+ }
+ else
+ {
+ ++size;
+ }
+
+ ++current;
+ }
+
+ //append whatever is left
+ stringAppend(result, startLine, current);
+
+ return result;
+ }
+ }
+
+inline
+ParseResult::ParseResult
+(
+ const std::shared_ptr<
+ std::unordered_map<std::string, std::shared_ptr<OptionDetails>>
+ > options,
+ std::vector<std::string> positional,
+ bool allow_unrecognised,
+ int& argc, char**& argv
+)
+: m_options(options)
+, m_positional(std::move(positional))
+, m_next_positional(m_positional.begin())
+, m_allow_unrecognised(allow_unrecognised)
+{
+ parse(argc, argv);
+}
+
+inline
+OptionAdder
+Options::add_options(std::string group)
+{
+ return OptionAdder(*this, std::move(group));
+}
+
+inline
+OptionAdder&
+OptionAdder::operator()
+(
+ const std::string& opts,
+ const std::string& desc,
+ std::shared_ptr<const Value> value,
+ std::string arg_help
+)
+{
+ std::match_results<const char*> result;
+ std::regex_match(opts.c_str(), result, option_specifier);
+
+ if (result.empty())
+ {
+ throw invalid_option_format_error(opts);
+ }
+
+ const auto& short_match = result[2];
+ const auto& long_match = result[3];
+
+ if (!short_match.length() && !long_match.length())
+ {
+ throw invalid_option_format_error(opts);
+ } else if (long_match.length() == 1 && short_match.length())
+ {
+ throw invalid_option_format_error(opts);
+ }
+
+ auto option_names = []
+ (
+ const std::sub_match<const char*>& short_,
+ const std::sub_match<const char*>& long_
+ )
+ {
+ if (long_.length() == 1)
+ {
+ return std::make_tuple(long_.str(), short_.str());
+ }
+ else
+ {
+ return std::make_tuple(short_.str(), long_.str());
+ }
+ }(short_match, long_match);
+
+ m_options.add_option
+ (
+ m_group,
+ std::get<0>(option_names),
+ std::get<1>(option_names),
+ desc,
+ value,
+ std::move(arg_help)
+ );
+
+ return *this;
+}
+
+inline
+void
+ParseResult::parse_default(std::shared_ptr<OptionDetails> details)
+{
+ m_results[details].parse_default(details);
+}
+
+inline
+void
+ParseResult::parse_option
+(
+ std::shared_ptr<OptionDetails> value,
+ const std::string& /*name*/,
+ const std::string& arg
+)
+{
+ auto& result = m_results[value];
+ result.parse(value, arg);
+
+ m_sequential.emplace_back(value->long_name(), arg);
+}
+
+inline
+void
+ParseResult::checked_parse_arg
+(
+ int argc,
+ char* argv[],
+ int& current,
+ std::shared_ptr<OptionDetails> value,
+ const std::string& name
+)
+{
+ if (current + 1 >= argc)
+ {
+ if (value->value().has_implicit())
+ {
+ parse_option(value, name, value->value().get_implicit_value());
+ }
+ else
+ {
+ throw missing_argument_exception(name);
+ }
+ }
+ else
+ {
+ if (value->value().has_implicit())
+ {
+ parse_option(value, name, value->value().get_implicit_value());
+ }
+ else
+ {
+ parse_option(value, name, argv[current + 1]);
+ ++current;
+ }
+ }
+}
+
+inline
+void
+ParseResult::add_to_option(const std::string& option, const std::string& arg)
+{
+ auto iter = m_options->find(option);
+
+ if (iter == m_options->end())
+ {
+ throw option_not_exists_exception(option);
+ }
+
+ parse_option(iter->second, option, arg);
+}
+
+inline
+bool
+ParseResult::consume_positional(std::string a)
+{
+ while (m_next_positional != m_positional.end())
+ {
+ auto iter = m_options->find(*m_next_positional);
+ if (iter != m_options->end())
+ {
+ auto& result = m_results[iter->second];
+ if (!iter->second->value().is_container())
+ {
+ if (result.count() == 0)
+ {
+ add_to_option(*m_next_positional, a);
+ ++m_next_positional;
+ return true;
+ }
+ else
+ {
+ ++m_next_positional;
+ continue;
+ }
+ }
+ else
+ {
+ add_to_option(*m_next_positional, a);
+ return true;
+ }
+ }
+ else
+ {
+ throw option_not_exists_exception(*m_next_positional);
+ }
+ }
+
+ return false;
+}
+
+inline
+void
+Options::parse_positional(std::string option)
+{
+ parse_positional(std::vector<std::string>{std::move(option)});
+}
+
+inline
+void
+Options::parse_positional(std::vector<std::string> options)
+{
+ m_positional = std::move(options);
+ m_next_positional = m_positional.begin();
+
+ m_positional_set.insert(m_positional.begin(), m_positional.end());
+}
+
+inline
+void
+Options::parse_positional(std::initializer_list<std::string> options)
+{
+ parse_positional(std::vector<std::string>(std::move(options)));
+}
+
+inline
+ParseResult
+Options::parse(int& argc, char**& argv)
+{
+ ParseResult result(m_options, m_positional, m_allow_unrecognised, argc, argv);
+ return result;
+}
+
+inline
+void
+ParseResult::parse(int& argc, char**& argv)
+{
+ int current = 1;
+
+ int nextKeep = 1;
+
+ bool consume_remaining = false;
+
+ while (current != argc)
+ {
+ if (strcmp(argv[current], "--") == 0)
+ {
+ consume_remaining = true;
+ ++current;
+ break;
+ }
+
+ std::match_results<const char*> result;
+ std::regex_match(argv[current], result, option_matcher);
+
+ if (result.empty())
+ {
+ //not a flag
+
+ // but if it starts with a `-`, then it's an error
+ if (argv[current][0] == '-' && argv[current][1] != '\0') {
+ if (!m_allow_unrecognised) {
+ throw option_syntax_exception(argv[current]);
+ }
+ }
+
+ //if true is returned here then it was consumed, otherwise it is
+ //ignored
+ if (consume_positional(argv[current]))
+ {
+ }
+ else
+ {
+ argv[nextKeep] = argv[current];
+ ++nextKeep;
+ }
+ //if we return from here then it was parsed successfully, so continue
+ }
+ else
+ {
+ //short or long option?
+ if (result[4].length() != 0)
+ {
+ const std::string& s = result[4];
+
+ for (std::size_t i = 0; i != s.size(); ++i)
+ {
+ std::string name(1, s[i]);
+ auto iter = m_options->find(name);
+
+ if (iter == m_options->end())
+ {
+ if (m_allow_unrecognised)
+ {
+ continue;
+ }
+ else
+ {
+ //error
+ throw option_not_exists_exception(name);
+ }
+ }
+
+ auto value = iter->second;
+
+ if (i + 1 == s.size())
+ {
+ //it must be the last argument
+ checked_parse_arg(argc, argv, current, value, name);
+ }
+ else if (value->value().has_implicit())
+ {
+ parse_option(value, name, value->value().get_implicit_value());
+ }
+ else
+ {
+ //error
+ throw option_requires_argument_exception(name);
+ }
+ }
+ }
+ else if (result[1].length() != 0)
+ {
+ const std::string& name = result[1];
+
+ auto iter = m_options->find(name);
+
+ if (iter == m_options->end())
+ {
+ if (m_allow_unrecognised)
+ {
+ // keep unrecognised options in argument list, skip to next argument
+ argv[nextKeep] = argv[current];
+ ++nextKeep;
+ ++current;
+ continue;
+ }
+ else
+ {
+ //error
+ throw option_not_exists_exception(name);
+ }
+ }
+
+ auto opt = iter->second;
+
+ //equals provided for long option?
+ if (result[2].length() != 0)
+ {
+ //parse the option given
+
+ parse_option(opt, name, result[3]);
+ }
+ else
+ {
+ //parse the next argument
+ checked_parse_arg(argc, argv, current, opt, name);
+ }
+ }
+
+ }
+
+ ++current;
+ }
+
+ for (auto& opt : *m_options)
+ {
+ auto& detail = opt.second;
+ auto& value = detail->value();
+
+ auto& store = m_results[detail];
+
+ if(value.has_default() && !store.count() && !store.has_default()){
+ parse_default(detail);
+ }
+ }
+
+ if (consume_remaining)
+ {
+ while (current < argc)
+ {
+ if (!consume_positional(argv[current])) {
+ break;
+ }
+ ++current;
+ }
+
+ //adjust argv for any that couldn't be swallowed
+ while (current != argc) {
+ argv[nextKeep] = argv[current];
+ ++nextKeep;
+ ++current;
+ }
+ }
+
+ argc = nextKeep;
+
+}
+
+inline
+void
+Options::add_option
+(
+ const std::string& group,
+ const std::string& s,
+ const std::string& l,
+ std::string desc,
+ std::shared_ptr<const Value> value,
+ std::string arg_help
+)
+{
+ auto stringDesc = toLocalString(std::move(desc));
+ auto option = std::make_shared<OptionDetails>(s, l, stringDesc, value);
+
+ if (s.size() > 0)
+ {
+ add_one_option(s, option);
+ }
+
+ if (l.size() > 0)
+ {
+ add_one_option(l, option);
+ }
+
+ //add the help details
+ auto& options = m_help[group];
+
+ options.options.emplace_back(HelpOptionDetails{s, l, stringDesc,
+ value->has_default(), value->get_default_value(),
+ value->has_implicit(), value->get_implicit_value(),
+ std::move(arg_help),
+ value->is_container(),
+ value->is_boolean()});
+}
+
+inline
+void
+Options::add_one_option
+(
+ const std::string& option,
+ std::shared_ptr<OptionDetails> details
+)
+{
+ auto in = m_options->emplace(option, details);
+
+ if (!in.second)
+ {
+ throw option_exists_error(option);
+ }
+}
+
+inline
+String
+Options::help_one_group(const std::string& g) const
+{
+ typedef std::vector<std::pair<String, String>> OptionHelp;
+
+ auto group = m_help.find(g);
+ if (group == m_help.end())
+ {
+ return "";
+ }
+
+ OptionHelp format;
+
+ size_t longest = 0;
+
+ String result;
+
+ if (!g.empty())
+ {
+ result += toLocalString(" " + g + " options:\n");
+ }
+
+ for (const auto& o : group->second.options)
+ {
+ if (m_positional_set.find(o.l) != m_positional_set.end() &&
+ !m_show_positional)
+ {
+ continue;
+ }
+
+ auto s = format_option(o);
+ longest = (std::max)(longest, stringLength(s));
+ format.push_back(std::make_pair(s, String()));
+ }
+
+ longest = (std::min)(longest, static_cast<size_t>(OPTION_LONGEST));
+
+ //widest allowed description
+ auto allowed = size_t{76} - longest - OPTION_DESC_GAP;
+
+ auto fiter = format.begin();
+ for (const auto& o : group->second.options)
+ {
+ if (m_positional_set.find(o.l) != m_positional_set.end() &&
+ !m_show_positional)
+ {
+ continue;
+ }
+
+ auto d = format_description(o, longest + OPTION_DESC_GAP, allowed);
+
+ result += fiter->first;
+ if (stringLength(fiter->first) > longest)
+ {
+ result += '\n';
+ result += toLocalString(std::string(longest + OPTION_DESC_GAP, ' '));
+ }
+ else
+ {
+ result += toLocalString(std::string(longest + OPTION_DESC_GAP -
+ stringLength(fiter->first),
+ ' '));
+ }
+ result += d;
+ result += '\n';
+
+ ++fiter;
+ }
+
+ return result;
+}
+
+inline
+void
+Options::generate_group_help
+(
+ String& result,
+ const std::vector<std::string>& print_groups
+) const
+{
+ for (size_t i = 0; i != print_groups.size(); ++i)
+ {
+ const String& group_help_text = help_one_group(print_groups[i]);
+ if (empty(group_help_text))
+ {
+ continue;
+ }
+ result += group_help_text;
+ if (i < print_groups.size() - 1)
+ {
+ result += '\n';
+ }
+ }
+}
+
+inline
+void
+Options::generate_all_groups_help(String& result) const
+{
+ std::vector<std::string> all_groups;
+ all_groups.reserve(m_help.size());
+
+ for (auto& group : m_help)
+ {
+ all_groups.push_back(group.first);
+ }
+
+ generate_group_help(result, all_groups);
+}
+
+inline
+std::string
+Options::help(const std::vector<std::string>& help_groups) const
+{
+ String result = m_help_string + "\nUsage:\n " +
+ toLocalString(m_program) + " " + toLocalString(m_custom_help);
+
+ if (m_positional.size() > 0 && m_positional_help.size() > 0) {
+ result += " " + toLocalString(m_positional_help);
+ }
+
+ result += "\n\n";
+
+ if (help_groups.size() == 0)
+ {
+ generate_all_groups_help(result);
+ }
+ else
+ {
+ generate_group_help(result, help_groups);
+ }
+
+ return toUTF8String(result);
+}
+
+inline
+const std::vector<std::string>
+Options::groups() const
+{
+ std::vector<std::string> g;
+
+ std::transform(
+ m_help.begin(),
+ m_help.end(),
+ std::back_inserter(g),
+ [] (const std::map<std::string, HelpGroupDetails>::value_type& pair)
+ {
+ return pair.first;
+ }
+ );
+
+ return g;
+}
+
+inline
+const HelpGroupDetails&
+Options::group_help(const std::string& group) const
+{
+ return m_help.at(group);
+}
+
+}
+
+#endif //CXXOPTS_HPP_INCLUDED
diff --git a/gctest/flat_hash_map/bytell_hash_map.hpp b/gctest/src/flat_hash_map/bytell_hash_map.hpp
index 9c9a246..9c9a246 100644
--- a/gctest/flat_hash_map/bytell_hash_map.hpp
+++ b/gctest/src/flat_hash_map/bytell_hash_map.hpp
diff --git a/gctest/flat_hash_map/flat_hash_map.hpp b/gctest/src/flat_hash_map/flat_hash_map.hpp
index a8723ee..a8723ee 100644
--- a/gctest/flat_hash_map/flat_hash_map.hpp
+++ b/gctest/src/flat_hash_map/flat_hash_map.hpp
diff --git a/gctest/flat_hash_map/unordered_map.hpp b/gctest/src/flat_hash_map/unordered_map.hpp
index 5e6e876..5e6e876 100644
--- a/gctest/flat_hash_map/unordered_map.hpp
+++ b/gctest/src/flat_hash_map/unordered_map.hpp
diff --git a/gctest/src/gc.h b/gctest/src/gc.h
new file mode 100644
index 0000000..e7a62a2
--- /dev/null
+++ b/gctest/src/gc.h
@@ -0,0 +1,60 @@
+#pragma once
+
+#include <cstddef>
+#include <unordered_set>
+
+class ObjectVisitor;
+
+class Object
+{
+public:
+ virtual ~Object() {}
+ virtual void VisitReferences(ObjectVisitor* visitor, void* state) = 0;
+};
+
+class ObjectVisitor
+{
+public:
+ virtual ~ObjectVisitor() {}
+
+ // Object** to allows the reference to be moved
+ virtual void VisitReference(Object* from, Object** to, void* state) = 0;
+};
+
+class GarbageCollector : public ObjectVisitor
+{
+public:
+ virtual void* Allocate(size_t size) = 0;
+
+ // Object** to allows the root to be moved
+ virtual void SetRoot(Object** root) = 0;
+
+ virtual void Shutdown() = 0;
+};
+
+class DestroyVisitor : public ObjectVisitor
+{
+public:
+ virtual void Destroy(Object* o)
+ {
+ auto insert_result = m_Visited.insert(o);
+ if (insert_result.second)
+ {
+ o->VisitReferences(this, nullptr);
+ o->~Object();
+ }
+ }
+
+ void VisitReference(Object*, Object** to, void*) override
+ {
+ if (*to)
+ {
+ Destroy(*to);
+ }
+ }
+ std::unordered_set<Object*> m_Visited;
+};
+
+std::unique_ptr<GarbageCollector> CreateGarbageCollector(int argc,
+ char* argv[]);
+
diff --git a/gctest/src/gc_dummy.cpp b/gctest/src/gc_dummy.cpp
new file mode 100644
index 0000000..68fc86d
--- /dev/null
+++ b/gctest/src/gc_dummy.cpp
@@ -0,0 +1,71 @@
+#include <memory>
+
+#include "gc.h"
+
+class DummyGC : public GarbageCollector
+{
+public:
+ DummyGC(unsigned gcInterval)
+ : m_GCInterval(gcInterval)
+ {}
+
+ void* Allocate(size_t size) override {
+ if (++m_AllocsSinceGC == m_GCInterval)
+ {
+ GC();
+ m_AllocsSinceGC = 0;
+ }
+ auto memory = ::operator new(size);
+ m_Allocated.insert(static_cast<Object*>(memory));
+ return memory;
+ }
+
+ void SetRoot(Object** root) override { m_Root = root; }
+
+ void VisitReference(Object*, Object** to, void*) override
+ {
+ auto insert = m_Visited.insert(*to);
+ if (insert.second)
+ {
+ (*to)->VisitReferences(this, nullptr);
+ }
+ }
+
+ void GC()
+ {
+ m_Visited.clear();
+ m_Visited.insert(*m_Root);
+ (*m_Root)->VisitReferences(this, nullptr);
+
+ for (auto object: m_Allocated)
+ {
+ if (m_Visited.find(object) == m_Visited.end())
+ {
+ object->~Object();
+ ::operator delete(object);
+ }
+ }
+ m_Allocated = m_Visited;
+ }
+
+ void Shutdown() override
+ {
+ for (auto object: m_Allocated)
+ {
+ object->~Object();
+ ::operator delete(object);
+ }
+
+ }
+
+ Object** m_Root;
+ std::unordered_set<Object*> m_Allocated;
+ std::unordered_set<Object*> m_Visited;
+ unsigned m_GCInterval;
+ unsigned m_AllocsSinceGC = 0;
+};
+
+std::unique_ptr<GarbageCollector> CreateGarbageCollector(int, char*[])
+{
+ return std::unique_ptr<GarbageCollector>(new DummyGC(1024));
+}
diff --git a/gctest/src/gc_leak.cpp b/gctest/src/gc_leak.cpp
new file mode 100644
index 0000000..dbb7ad3
--- /dev/null
+++ b/gctest/src/gc_leak.cpp
@@ -0,0 +1,25 @@
+#include <memory>
+
+#include "gc.h"
+
+class LeakGC : public GarbageCollector
+{
+ void* Allocate(size_t size) override { return ::operator new(size); }
+
+ void SetRoot(Object** root) override { m_Root = root; }
+
+ void VisitReference(Object*, Object**, void*) override {}
+
+ void Shutdown() override
+ {
+ DestroyVisitor dv;
+ dv.Destroy(*m_Root);
+ }
+
+ Object** m_Root;
+};
+
+std::unique_ptr<GarbageCollector> CreateGarbageCollector(int, char*[])
+{
+ return std::unique_ptr<GarbageCollector>(new LeakGC());
+}
diff --git a/gctest/src/main.cpp b/gctest/src/main.cpp
new file mode 100644
index 0000000..03e7ef8
--- /dev/null
+++ b/gctest/src/main.cpp
@@ -0,0 +1,392 @@
+#include <algorithm>
+#include <atomic>
+#include <cassert>
+#include <cstdio>
+#include <filesystem>
+#include <memory>
+#include <random>
+#include <string>
+#include "weighted_action.h"
+
+#include "minitrace/minitrace.h"
+
+#include "gc.h"
+
+#include "cxxopts.hpp"
+
+typedef std::mt19937 RandomGenerator;
+
+class RecycledObject : public Object
+{
+public:
+ RecycledObject() { ++Alive; }
+
+ ~RecycledObject() { --Alive; }
+ static std::atomic<size_t> Alive;
+ typedef Object** Location;
+
+ virtual Location GetLocation(RandomGenerator& random) = 0;
+ virtual size_t GetSize() const = 0;
+ unsigned m_Generation;
+};
+
+std::atomic<size_t> RecycledObject::Alive = 0;
+
+class LeafObject : public RecycledObject
+{
+public:
+ LeafObject(unsigned size) : m_Size(size)
+ {
+ std::fill(m_Extra, m_Extra + size, uint8_t(0xab));
+ }
+
+ ~LeafObject() {}
+
+ void VisitReferences(ObjectVisitor*, void*) override {}
+
+ RecycledObject::Location GetLocation(RandomGenerator&) override
+ {
+ return nullptr;
+ }
+
+ size_t GetSize() const override { return sizeof(*this) + m_Size; }
+
+private:
+ unsigned m_Size;
+ uint8_t m_Extra[1];
+};
+
+void* AllocateGCMemory(GarbageCollector* gc, size_t size)
+{
+ MTR_SCOPE_I("GC", "Allocate", "size", int(size));
+ return gc->Allocate(size);
+}
+
+Object* CreateLeaf(GarbageCollector* gc, unsigned extraSize)
+{
+ auto memory = AllocateGCMemory(gc, sizeof(LeafObject) + extraSize);
+ auto result = new (memory) LeafObject(extraSize);
+ return result;
+}
+
+class ScannedObject : public RecycledObject
+{
+public:
+ ScannedObject(unsigned children) : m_Size(children)
+ {
+ std::fill(m_Children, m_Children + m_Size, nullptr);
+ }
+ ~ScannedObject() {}
+
+ void VisitReferences(ObjectVisitor* visitor, void* state) override
+ {
+ auto end = m_Children + m_Size;
+ for (auto child = m_Children; child < end; ++child)
+ {
+ if (*child)
+ {
+ visitor->VisitReference(this, child, state);
+ }
+ }
+ }
+
+ RecycledObject::Location GetLocation(RandomGenerator& generator) override
+ {
+ std::uniform_int_distribution<unsigned> dist(0, m_Size - 1);
+ return m_Children + dist(generator);
+ }
+
+ size_t GetSize() const override
+ {
+ return sizeof(*this) + m_Size * sizeof(Object*);
+ }
+
+private:
+ unsigned m_Size;
+ Object* m_Children[1];
+};
+
+Object* CreateScanned(GarbageCollector* gc, unsigned children)
+{
+ auto extraSize = children * sizeof(Object*);
+ auto memory = AllocateGCMemory(gc, sizeof(ScannedObject) + extraSize);
+ auto result = new (memory) ScannedObject(children);
+ return result;
+}
+
+RecycledObject::Location GetRandomLocation(Object* root,
+ RandomGenerator& generator)
+{
+ auto result = static_cast<RecycledObject*>(root)->GetLocation(generator);
+ std::uniform_int_distribution<unsigned> dist(0, 99);
+ auto nonleaf = result;
+ while (result && *result)
+ {
+ if (dist(generator) < 5)
+ {
+ return result;
+ }
+ nonleaf = result;
+ result = static_cast<RecycledObject*>(*result)->GetLocation(generator);
+ }
+
+ return result ? result : nonleaf;
+}
+
+template <typename Factory, typename Dist>
+struct ObjectFactory
+{
+ ObjectFactory(Factory f,
+ Dist dist,
+ RandomGenerator* g,
+ GarbageCollector* gc)
+ : m_Factory(f), m_Dist(dist), m_Generator(g), m_GC(gc)
+ {
+ }
+
+ Object* operator()() const { return m_Factory(m_GC, m_Dist(*m_Generator)); }
+
+ Factory m_Factory;
+ Dist m_Dist;
+ RandomGenerator* m_Generator;
+ GarbageCollector* m_GC;
+};
+
+template <typename Factory, typename Dist>
+ObjectFactory<Factory, Dist> MakeFactory(Factory f,
+ Dist d,
+ RandomGenerator* g,
+ GarbageCollector* gc)
+{
+ return ObjectFactory<Factory, Dist>(f, d, g, gc);
+}
+
+template <typename Dist>
+struct SizeDistribution
+{
+ SizeDistribution(Dist dist, unsigned min, unsigned max)
+ : m_Dist(dist), m_Min(min), m_Max(max)
+ {
+ }
+
+ template <typename G>
+ unsigned operator()(G& g) const
+ {
+ auto r = unsigned(m_Dist(g));
+ return (m_Min < r) ? (r < m_Max ? r : m_Max) : m_Min;
+ }
+
+ mutable Dist m_Dist;
+ unsigned m_Min;
+ unsigned m_Max;
+};
+
+template <typename Dist>
+SizeDistribution<Dist> MakeSizeDist(Dist d, unsigned min, unsigned max)
+{
+ return SizeDistribution<Dist>(d, min, max);
+}
+
+typedef WeightedActionTable<Object*, RandomGenerator> CreateTable;
+typedef WeightedActionTable<void, RandomGenerator> OperationsTable;
+
+void NewObject(RecycledObject* root, CreateTable& create, RandomGenerator& rg)
+{
+ auto location = GetRandomLocation(root, rg);
+ *location = create.RunRandomAction();
+}
+
+void NewTempObject(CreateTable& create)
+{
+ create.RunRandomAction();
+}
+
+void DeleteObject(RecycledObject* root, RandomGenerator& rg)
+{
+ auto location = GetRandomLocation(root, rg);
+ *location = nullptr;
+}
+
+void CopyObject(RecycledObject* root, RandomGenerator& rg)
+{
+ auto from = GetRandomLocation(root, rg);
+ auto to = GetRandomLocation(root, rg);
+ *to = *from;
+}
+
+void MoveObject(RecycledObject* root, RandomGenerator& rg)
+{
+ auto from = GetRandomLocation(root, rg);
+ auto to = GetRandomLocation(root, rg);
+ *to = *from;
+ *from = nullptr;
+}
+
+void SwapObjects(RecycledObject* root, RandomGenerator& rg)
+{
+ auto a = GetRandomLocation(root, rg);
+ auto b = GetRandomLocation(root, rg);
+ std::swap(*a, *b);
+}
+
+struct HeapStatsVisitor : ObjectVisitor
+{
+ void ComputeStats(Object* root)
+ {
+ auto recycled = static_cast<RecycledObject*>(root);
+ m_CurrentGeneration = ++recycled->m_Generation;
+ m_Reachable = 1;
+ m_UsedMemory += recycled->GetSize();
+ m_Depth = 1;
+ unsigned depth = 1;
+ root->VisitReferences(this, &depth);
+ }
+ void VisitReference(Object*, Object** to, void* state) override
+ {
+ auto recycled = static_cast<RecycledObject*>(*to);
+ if (recycled->m_Generation < m_CurrentGeneration)
+ {
+ ++m_Reachable;
+ m_UsedMemory += recycled->GetSize();
+ recycled->m_Generation = m_CurrentGeneration;
+ auto depth = *static_cast<unsigned*>(state);
+ ++depth;
+ if (depth > m_Depth)
+ {
+ m_Depth = depth;
+ }
+ recycled->VisitReferences(this, &depth);
+ }
+ }
+ size_t m_Reachable = 0;
+ unsigned m_Depth = 0;
+ unsigned m_CurrentGeneration = 0;
+ size_t m_UsedMemory = 0;
+};
+
+// extern std::atomic<size_t> TotalMemory;
+
+CreateTable GetObjectFactory(RandomGenerator& rg, GarbageCollector* gc)
+{
+ CreateTable create(&rg);
+
+ std::normal_distribution<float> u_small(64, 16);
+ std::normal_distribution<float> u_medium(512, 128);
+ std::normal_distribution<float> u_large(4096, 1024);
+
+ auto size_small = MakeSizeDist(u_small, 16, 128);
+ auto size_medium = MakeSizeDist(u_medium, 128, 1024);
+ auto size_large = MakeSizeDist(u_large, 1024, 8192);
+
+ create.AddAction(MakeFactory(CreateLeaf, size_small, &rg, gc), 20);
+ create.AddAction(MakeFactory(CreateLeaf, size_medium, &rg, gc), 30);
+ create.AddAction(MakeFactory(CreateLeaf, size_large, &rg, gc), 20);
+
+ create.AddAction(MakeFactory(CreateScanned, size_small, &rg, gc), 20);
+ create.AddAction(MakeFactory(CreateScanned, size_medium, &rg, gc), 30);
+ create.AddAction(MakeFactory(CreateScanned, size_large, &rg, gc), 20);
+
+ return create;
+}
+
+int main(int argc, char* argv[])
+{
+ std::string process = argv[0];
+ {
+ std::filesystem::path p(process);
+ process = p.filename().string();
+ }
+ cxxopts::Options parser(process.c_str(),
+ "Test bench for garbage collectors");
+ parser.add_options()
+ ("s,seed", "Seed for the random generator", cxxopts::value<int>())
+ ("i,initial", "Number of initial objects", cxxopts::value<unsigned>()->default_value("20000"))
+ ("l,loops", "Number of loops to run", cxxopts::value<unsigned>()->default_value("2000"))
+ ("o,ops", "Number of operations per iteration", cxxopts::value<unsigned>()->default_value("250"))
+ ("h,help", "Print the help")
+ ;
+ parser.allow_unrecognised_options();
+
+ auto options = parser.parse(argc, argv);
+
+ if (options.count("help"))
+ {
+ std::printf("%s\n", parser.help().c_str());
+ return 0;
+ }
+
+ mtr_init((process + ".json").c_str());
+ MTR_META_PROCESS_NAME(process.c_str());
+ MTR_META_THREAD_NAME("Mutator thread");
+
+ RandomGenerator rg;
+ if (options.count("seed"))
+ {
+ rg.seed(options["seed"].as<int>());
+ }
+ auto gc = CreateGarbageCollector(argc, argv);
+
+ auto create = GetObjectFactory(rg, gc.get());
+
+ auto initial_count = options["initial"].as<unsigned>();
+ auto loops = options["loops"].as<unsigned>();
+ auto operations_count = options["ops"].as<unsigned>();
+
+ auto root = static_cast<RecycledObject*>(
+ CreateScanned(gc.get(), initial_count / 10));
+ gc->SetRoot(reinterpret_cast<Object**>(&root));
+
+ OperationsTable operations(&rg);
+
+ operations.AddAction(
+ [&create, &rg, &root]() { NewObject(root, create, rg); }, 30);
+
+ operations.AddAction([&create]() { NewTempObject(create); }, 40);
+
+ operations.AddAction([&root, &rg]() { DeleteObject(root, rg); }, 5);
+
+ operations.AddAction([&root, &rg]() { CopyObject(root, rg); }, 20);
+
+ operations.AddAction([&root, &rg]() { MoveObject(root, rg); }, 10);
+
+ operations.AddAction([&root, &rg]() { SwapObjects(root, rg); }, 20);
+
+ {
+ MTR_SCOPE("Mutator", "Initialize Heap");
+ for (auto i = 0u; i < initial_count; ++i)
+ {
+ auto location = GetRandomLocation(root, rg);
+ *location = create.RunRandomAction();
+ }
+ }
+
+ for (auto l = 0u; l < loops; ++l)
+ {
+ {
+ MTR_SCOPE_I("Mutator", "Step", "loop", l);
+ for (auto o = 0u; o < operations_count; ++o)
+ {
+ operations.RunRandomAction();
+ }
+ }
+ MTR_SCOPE_I("Mutator", "Walk Heap", "loop", l);
+ HeapStatsVisitor stats;
+ stats.ComputeStats(root);
+ MTR_COUNTER("Heap", "Reachable", int(stats.m_Reachable));
+ MTR_COUNTER("Heap", "Living", int(RecycledObject::Alive));
+ MTR_COUNTER("Heap", "Depth", int(stats.m_Depth));
+ // MTR_COUNTER("Heap", "Total KB", int(TotalMemory / 1024));
+ MTR_COUNTER("Heap", "Useful KB", int(stats.m_UsedMemory / 1024));
+ }
+
+ gc->Shutdown();
+
+ if (RecycledObject::Alive)
+ {
+ std::fprintf(stderr, "%zu objects leaked\n",
+ RecycledObject::Alive.load());
+ }
+
+ mtr_shutdown();
+ return 0;
+}
diff --git a/gctest/src/minitrace.cpp b/gctest/src/minitrace.cpp
new file mode 100644
index 0000000..4b96ae6
--- /dev/null
+++ b/gctest/src/minitrace.cpp
@@ -0,0 +1 @@
+#include "minitrace/minitrace.c"
diff --git a/gctest/minitrace/.gitignore b/gctest/src/minitrace/.gitignore
index 82fe1f4..82fe1f4 100644
--- a/gctest/minitrace/.gitignore
+++ b/gctest/src/minitrace/.gitignore
diff --git a/gctest/minitrace/LICENSE b/gctest/src/minitrace/LICENSE
index f746931..f746931 100644
--- a/gctest/minitrace/LICENSE
+++ b/gctest/src/minitrace/LICENSE
diff --git a/gctest/minitrace/Makefile b/gctest/src/minitrace/Makefile
index f6c2677..f6c2677 100644
--- a/gctest/minitrace/Makefile
+++ b/gctest/src/minitrace/Makefile
diff --git a/gctest/minitrace/README.md b/gctest/src/minitrace/README.md
index 75cdcbf..75cdcbf 100644
--- a/gctest/minitrace/README.md
+++ b/gctest/src/minitrace/README.md
diff --git a/gctest/minitrace/minitrace.c b/gctest/src/minitrace/minitrace.c
index 42c2634..3d8e7fd 100644
--- a/gctest/minitrace/minitrace.c
+++ b/gctest/src/minitrace/minitrace.c
@@ -10,10 +10,12 @@
#include <string.h>
#ifdef _WIN32
+#ifdef _MSVC
#pragma warning (disable:4996)
+#endif
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
-#define __thread __declspec(thread)
+#define __thread thread_local
#define pthread_mutex_t CRITICAL_SECTION
#define pthread_mutex_init(a, b) InitializeCriticalSection(a)
#define pthread_mutex_lock(a) EnterCriticalSection(a)
diff --git a/gctest/minitrace/minitrace.h b/gctest/src/minitrace/minitrace.h
index 2047eed..2047eed 100644
--- a/gctest/minitrace/minitrace.h
+++ b/gctest/src/minitrace/minitrace.h
diff --git a/gctest/minitrace/minitrace_test.cpp b/gctest/src/minitrace/minitrace_test.cpp
index 522ac8e..522ac8e 100644
--- a/gctest/minitrace/minitrace_test.cpp
+++ b/gctest/src/minitrace/minitrace_test.cpp
diff --git a/gctest/minitrace/minitrace_test_mt.cpp b/gctest/src/minitrace/minitrace_test_mt.cpp
index 899a193..899a193 100644
--- a/gctest/minitrace/minitrace_test_mt.cpp
+++ b/gctest/src/minitrace/minitrace_test_mt.cpp
diff --git a/gctest/minitrace/msvc/minitrace.sln b/gctest/src/minitrace/msvc/minitrace.sln
index 5a9925c..5a9925c 100644
--- a/gctest/minitrace/msvc/minitrace.sln
+++ b/gctest/src/minitrace/msvc/minitrace.sln
diff --git a/gctest/minitrace/msvc/minitrace.vcxproj b/gctest/src/minitrace/msvc/minitrace.vcxproj
index 362922f..362922f 100644
--- a/gctest/minitrace/msvc/minitrace.vcxproj
+++ b/gctest/src/minitrace/msvc/minitrace.vcxproj
diff --git a/gctest/minitrace/msvc/minitrace.vcxproj.filters b/gctest/src/minitrace/msvc/minitrace.vcxproj.filters
index daffed3..daffed3 100644
--- a/gctest/minitrace/msvc/minitrace.vcxproj.filters
+++ b/gctest/src/minitrace/msvc/minitrace.vcxproj.filters
diff --git a/gctest/src/weighted_action.h b/gctest/src/weighted_action.h
new file mode 100644
index 0000000..4bcdd6f
--- /dev/null
+++ b/gctest/src/weighted_action.h
@@ -0,0 +1,33 @@
+#pragma once
+#include <functional>
+#include <random>
+#include <vector>
+
+template <typename Result, typename Generator>
+class WeightedActionTable
+{
+public:
+ WeightedActionTable(Generator* generator) : m_Generator(generator) {}
+
+ typedef std::function<Result()> ActionCallback;
+
+ void AddAction(ActionCallback action, unsigned weight)
+ {
+ m_Actions.emplace_back(action);
+ m_Weights.emplace_back(weight);
+ m_Distribution =
+ std::discrete_distribution(m_Weights.begin(), m_Weights.end());
+ }
+
+ Result RunRandomAction()
+ {
+ auto random = m_Distribution(*m_Generator);
+ return m_Actions[random]();
+ }
+
+private:
+ std::vector<ActionCallback> m_Actions;
+ std::vector<unsigned> m_Weights;
+ Generator* m_Generator;
+ std::discrete_distribution<int> m_Distribution;
+};
diff --git a/spasm/solution/spasm.vcxproj b/spasm/solution/spasm.vcxproj
index c4d1cc3..e74771d 100644
--- a/spasm/solution/spasm.vcxproj
+++ b/spasm/solution/spasm.vcxproj
@@ -31,6 +31,7 @@
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
@@ -38,6 +39,7 @@
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
@@ -45,6 +47,7 @@
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
@@ -52,6 +55,7 @@
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
diff --git a/spasm/solution/spasm_lib.vcxproj b/spasm/solution/spasm_lib.vcxproj
index 72bd81e..bcb4ab9 100644
--- a/spasm/solution/spasm_lib.vcxproj
+++ b/spasm/solution/spasm_lib.vcxproj
@@ -31,6 +31,7 @@
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
@@ -38,6 +39,7 @@
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
@@ -45,6 +47,7 @@
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
@@ -52,6 +55,7 @@
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
@@ -223,18 +227,18 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
- <ClCompile Include="..\src\asm\bytecode.cpp">
- </ClCompile>
- <ClCompile Include="..\src\asm\symbol.cpp">
- </ClCompile>
- <ClCompile Include="..\src\asm\tokenizer.cpp">
- </ClCompile>
<ClCompile Include="..\src\asm\assembler.cpp">
</ClCompile>
+ <ClCompile Include="..\src\asm\bytecode.cpp">
+ </ClCompile>
<ClCompile Include="..\src\asm\lexer.cpp">
</ClCompile>
+ <ClCompile Include="..\src\asm\symbol.cpp">
+ </ClCompile>
<ClCompile Include="..\src\asm\token.cpp">
</ClCompile>
+ <ClCompile Include="..\src\asm\tokenizer.cpp">
+ </ClCompile>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
diff --git a/spasm/solution/spasm_lib.vcxproj.filters b/spasm/solution/spasm_lib.vcxproj.filters
index c82311e..82b5f56 100644
--- a/spasm/solution/spasm_lib.vcxproj.filters
+++ b/spasm/solution/spasm_lib.vcxproj.filters
@@ -9,22 +9,22 @@
</Filter>
</ItemGroup>
<ItemGroup>
- <ClCompile Include="..\src\asm\bytecode.cpp">
+ <ClCompile Include="..\src\asm\assembler.cpp">
<Filter>src\asm</Filter>
</ClCompile>
- <ClCompile Include="..\src\asm\symbol.cpp">
+ <ClCompile Include="..\src\asm\bytecode.cpp">
<Filter>src\asm</Filter>
</ClCompile>
- <ClCompile Include="..\src\asm\tokenizer.cpp">
+ <ClCompile Include="..\src\asm\lexer.cpp">
<Filter>src\asm</Filter>
</ClCompile>
- <ClCompile Include="..\src\asm\assembler.cpp">
+ <ClCompile Include="..\src\asm\symbol.cpp">
<Filter>src\asm</Filter>
</ClCompile>
- <ClCompile Include="..\src\asm\lexer.cpp">
+ <ClCompile Include="..\src\asm\token.cpp">
<Filter>src\asm</Filter>
</ClCompile>
- <ClCompile Include="..\src\asm\token.cpp">
+ <ClCompile Include="..\src\asm\tokenizer.cpp">
<Filter>src\asm</Filter>
</ClCompile>
</ItemGroup>
diff --git a/spasm/solution/sprt.vcxproj b/spasm/solution/sprt.vcxproj
index acc26ef..6e7737f 100644
--- a/spasm/solution/sprt.vcxproj
+++ b/spasm/solution/sprt.vcxproj
@@ -31,6 +31,7 @@
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
@@ -38,6 +39,7 @@
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
@@ -45,6 +47,7 @@
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
@@ -52,6 +55,7 @@
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
diff --git a/spasm/solution/sprun.vcxproj b/spasm/solution/sprun.vcxproj
index a86c487..15ab7f9 100644
--- a/spasm/solution/sprun.vcxproj
+++ b/spasm/solution/sprun.vcxproj
@@ -31,6 +31,7 @@
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
@@ -38,6 +39,7 @@
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
@@ -45,6 +47,7 @@
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
@@ -52,6 +55,7 @@
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
diff --git a/spasm/src/asm/lexdump.cpp b/spasm/src/asm/lexdump.cpp
index 440ff1e..b609124 100644
--- a/spasm/src/asm/lexdump.cpp
+++ b/spasm/src/asm/lexdump.cpp
@@ -42,12 +42,12 @@ class TokenDumper : public TokenStream
std::cout.width(8);
std::cout << token.lineno();
std::cout << ": " << token_name[ttype];
- if (ttype == Token::integer || ttype == Token::xinteger)
+ if (ttype == Token::Integer || ttype == Token::XInteger)
std::cout << '|' << token.value_int() << '|';
- else if (ttype == Token::ident)
+ else if (ttype == Token::Ident)
std::cout << '|' << token.value_str() << '|';
std::cout << std::endl;
- if (token.type() == Token::endinput)
+ if (token.type() == Token::EndInput)
end_reached = true;
}
diff --git a/spasm/src/asm/lexdump3.cpp b/spasm/src/asm/lexdump3.cpp
index 4e4ce9e..400058b 100644
--- a/spasm/src/asm/lexdump3.cpp
+++ b/spasm/src/asm/lexdump3.cpp
@@ -44,16 +44,16 @@ int main()
Token token;
token = td.next_token();
- while (token.type() != Token::endinput)
+ while (token.type() != Token::EndInput)
{
token = td.next_token();
Token::Token_type ttype = token.type();
std::cout.width(8);
std::cout << token.lineno();
std::cout << ": " << token_name[ttype];
- if (ttype == Token::integer || ttype == Token::xinteger)
+ if (ttype == Token::Integer || ttype == Token::XInteger)
std::cout << '|' << token.value_int() << '|';
- else if (ttype == Token::ident)
+ else if (ttype == Token::Ident)
std::cout << '|' << token.value_str() << '|';
std::cout << std::endl;
}
diff --git a/spasm/src/spasm.cpp b/spasm/src/spasm.cpp
index 94086a6..dab81b9 100644
--- a/spasm/src/spasm.cpp
+++ b/spasm/src/spasm.cpp
@@ -1,6 +1,5 @@
#include <algorithm>
#include <cassert>
-#include <iostream>
#include "spasm.hpp"
diff --git a/spasm/src/spasm.hpp b/spasm/src/spasm.hpp
index da3f44f..01015d3 100644
--- a/spasm/src/spasm.hpp
+++ b/spasm/src/spasm.hpp
@@ -2,7 +2,6 @@
#define SPASM_HPP
#include "spasm_impl.hpp"
-#include "value.hpp"
namespace Spasm
{
diff --git a/spasm/src/spasm_impl.hpp b/spasm/src/spasm_impl.hpp
index 04e809a..c568902 100644
--- a/spasm/src/spasm_impl.hpp
+++ b/spasm/src/spasm_impl.hpp
@@ -2,6 +2,7 @@
#define SPASM_IMPL_HPP
#include <iostream>
+#include <cstdint>
#include <unordered_set>
#include "types.hpp"
diff --git a/spasm/src/value.hpp b/spasm/src/value.hpp
index 725d48c..a4662f2 100644
--- a/spasm/src/value.hpp
+++ b/spasm/src/value.hpp
@@ -1,5 +1,6 @@
#pragma once
+#include <iostream>
#include <cassert>
#include "string.hpp"