From 4e9f77ccf51271c9e917de7c2215cd30f8f31061 Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Wed, 21 Oct 2026 19:27:21 +0200 Subject: [PATCH 01/13] Move codegen source files to codegen directory --- src/engine/CMakeLists.txt | 6 +----- src/engine/compiler.cpp | 4 ++-- src/engine/compiler_p.cpp | 4 ++-- src/engine/internal/codegen/CMakeLists.txt | 9 +++++++++ .../internal/{ => codegen}/codebuilderfactory.cpp | 0 .../internal/{ => codegen}/codebuilderfactory.h | 0 src/engine/internal/{ => codegen}/icodebuilder.h | 0 .../internal/{ => codegen}/icodebuilderfactory.h | 0 .../internal/{ => codegen}/llvm/CMakeLists.txt | 0 .../{ => codegen}/llvm/instructions/CMakeLists.txt | 0 .../{ => codegen}/llvm/instructions/comparison.cpp | 0 .../{ => codegen}/llvm/instructions/comparison.h | 0 .../{ => codegen}/llvm/instructions/control.cpp | 0 .../{ => codegen}/llvm/instructions/control.h | 0 .../{ => codegen}/llvm/instructions/functions.cpp | 0 .../{ => codegen}/llvm/instructions/functions.h | 0 .../llvm/instructions/instructionbuilder.cpp | 0 .../llvm/instructions/instructionbuilder.h | 0 .../llvm/instructions/instructiongroup.cpp | 0 .../llvm/instructions/instructiongroup.h | 0 .../{ => codegen}/llvm/instructions/lists.cpp | 0 .../internal/{ => codegen}/llvm/instructions/lists.h | 0 .../{ => codegen}/llvm/instructions/logic.cpp | 0 .../internal/{ => codegen}/llvm/instructions/logic.h | 0 .../{ => codegen}/llvm/instructions/math.cpp | 0 .../internal/{ => codegen}/llvm/instructions/math.h | 0 .../{ => codegen}/llvm/instructions/procedures.cpp | 0 .../{ => codegen}/llvm/instructions/procedures.h | 0 .../{ => codegen}/llvm/instructions/processresult.h | 0 .../{ => codegen}/llvm/instructions/string.cpp | 0 .../{ => codegen}/llvm/instructions/string.h | 0 .../{ => codegen}/llvm/instructions/variables.cpp | 0 .../{ => codegen}/llvm/instructions/variables.h | 0 .../internal/{ => codegen}/llvm/llvmbuildutils.cpp | 0 .../internal/{ => codegen}/llvm/llvmbuildutils.h | 0 .../internal/{ => codegen}/llvm/llvmcodeanalyzer.cpp | 0 .../internal/{ => codegen}/llvm/llvmcodeanalyzer.h | 0 .../internal/{ => codegen}/llvm/llvmcodebuilder.cpp | 0 .../internal/{ => codegen}/llvm/llvmcodebuilder.h | 0 .../{ => codegen}/llvm/llvmcompilercontext.cpp | 0 .../{ => codegen}/llvm/llvmcompilercontext.h | 0 .../{ => codegen}/llvm/llvmconstantregister.h | 0 .../internal/{ => codegen}/llvm/llvmcoroutine.cpp | 0 .../internal/{ => codegen}/llvm/llvmcoroutine.h | 0 .../{ => codegen}/llvm/llvmexecutablecode.cpp | 0 .../internal/{ => codegen}/llvm/llvmexecutablecode.h | 0 .../{ => codegen}/llvm/llvmexecutioncontext.cpp | 0 .../{ => codegen}/llvm/llvmexecutioncontext.h | 0 .../internal/{ => codegen}/llvm/llvmfunctions.cpp | 0 .../internal/{ => codegen}/llvm/llvmfunctions.h | 0 .../internal/{ => codegen}/llvm/llvmifstatement.h | 0 .../internal/{ => codegen}/llvm/llvminstruction.h | 0 .../{ => codegen}/llvm/llvminstructionlist.cpp | 0 .../{ => codegen}/llvm/llvminstructionlist.h | 0 src/engine/internal/{ => codegen}/llvm/llvmlistptr.h | 0 .../{ => codegen}/llvm/llvmlocalvariableinfo.h | 0 src/engine/internal/{ => codegen}/llvm/llvmloop.h | 0 .../internal/{ => codegen}/llvm/llvmregister.h | 0 src/engine/internal/{ => codegen}/llvm/llvmtypes.cpp | 0 src/engine/internal/{ => codegen}/llvm/llvmtypes.h | 0 .../internal/{ => codegen}/llvm/llvmvariableptr.h | 0 test/codegen/codegentestutils.cpp | 2 +- test/codegen/codegentestutils.h | 2 +- test/llvm/code_analyzer/list_type_analysis.cpp | 12 ++++++------ test/llvm/code_analyzer/mixed_type_analysis.cpp | 12 ++++++------ test/llvm/code_analyzer/variable_type_analysis.cpp | 12 ++++++------ test/llvm/llvmexecutablecode_test.cpp | 8 ++++---- test/llvm/llvmexecutioncontext_test.cpp | 4 ++-- test/llvm/llvminstructionlist_test.cpp | 4 ++-- test/mocks/codebuilderfactorymock.h | 2 +- test/mocks/codebuildermock.h | 2 +- 71 files changed, 44 insertions(+), 39 deletions(-) create mode 100644 src/engine/internal/codegen/CMakeLists.txt rename src/engine/internal/{ => codegen}/codebuilderfactory.cpp (100%) rename src/engine/internal/{ => codegen}/codebuilderfactory.h (100%) rename src/engine/internal/{ => codegen}/icodebuilder.h (100%) rename src/engine/internal/{ => codegen}/icodebuilderfactory.h (100%) rename src/engine/internal/{ => codegen}/llvm/CMakeLists.txt (100%) rename src/engine/internal/{ => codegen}/llvm/instructions/CMakeLists.txt (100%) rename src/engine/internal/{ => codegen}/llvm/instructions/comparison.cpp (100%) rename src/engine/internal/{ => codegen}/llvm/instructions/comparison.h (100%) rename src/engine/internal/{ => codegen}/llvm/instructions/control.cpp (100%) rename src/engine/internal/{ => codegen}/llvm/instructions/control.h (100%) rename src/engine/internal/{ => codegen}/llvm/instructions/functions.cpp (100%) rename src/engine/internal/{ => codegen}/llvm/instructions/functions.h (100%) rename src/engine/internal/{ => codegen}/llvm/instructions/instructionbuilder.cpp (100%) rename src/engine/internal/{ => codegen}/llvm/instructions/instructionbuilder.h (100%) rename src/engine/internal/{ => codegen}/llvm/instructions/instructiongroup.cpp (100%) rename src/engine/internal/{ => codegen}/llvm/instructions/instructiongroup.h (100%) rename src/engine/internal/{ => codegen}/llvm/instructions/lists.cpp (100%) rename src/engine/internal/{ => codegen}/llvm/instructions/lists.h (100%) rename src/engine/internal/{ => codegen}/llvm/instructions/logic.cpp (100%) rename src/engine/internal/{ => codegen}/llvm/instructions/logic.h (100%) rename src/engine/internal/{ => codegen}/llvm/instructions/math.cpp (100%) rename src/engine/internal/{ => codegen}/llvm/instructions/math.h (100%) rename src/engine/internal/{ => codegen}/llvm/instructions/procedures.cpp (100%) rename src/engine/internal/{ => codegen}/llvm/instructions/procedures.h (100%) rename src/engine/internal/{ => codegen}/llvm/instructions/processresult.h (100%) rename src/engine/internal/{ => codegen}/llvm/instructions/string.cpp (100%) rename src/engine/internal/{ => codegen}/llvm/instructions/string.h (100%) rename src/engine/internal/{ => codegen}/llvm/instructions/variables.cpp (100%) rename src/engine/internal/{ => codegen}/llvm/instructions/variables.h (100%) rename src/engine/internal/{ => codegen}/llvm/llvmbuildutils.cpp (100%) rename src/engine/internal/{ => codegen}/llvm/llvmbuildutils.h (100%) rename src/engine/internal/{ => codegen}/llvm/llvmcodeanalyzer.cpp (100%) rename src/engine/internal/{ => codegen}/llvm/llvmcodeanalyzer.h (100%) rename src/engine/internal/{ => codegen}/llvm/llvmcodebuilder.cpp (100%) rename src/engine/internal/{ => codegen}/llvm/llvmcodebuilder.h (100%) rename src/engine/internal/{ => codegen}/llvm/llvmcompilercontext.cpp (100%) rename src/engine/internal/{ => codegen}/llvm/llvmcompilercontext.h (100%) rename src/engine/internal/{ => codegen}/llvm/llvmconstantregister.h (100%) rename src/engine/internal/{ => codegen}/llvm/llvmcoroutine.cpp (100%) rename src/engine/internal/{ => codegen}/llvm/llvmcoroutine.h (100%) rename src/engine/internal/{ => codegen}/llvm/llvmexecutablecode.cpp (100%) rename src/engine/internal/{ => codegen}/llvm/llvmexecutablecode.h (100%) rename src/engine/internal/{ => codegen}/llvm/llvmexecutioncontext.cpp (100%) rename src/engine/internal/{ => codegen}/llvm/llvmexecutioncontext.h (100%) rename src/engine/internal/{ => codegen}/llvm/llvmfunctions.cpp (100%) rename src/engine/internal/{ => codegen}/llvm/llvmfunctions.h (100%) rename src/engine/internal/{ => codegen}/llvm/llvmifstatement.h (100%) rename src/engine/internal/{ => codegen}/llvm/llvminstruction.h (100%) rename src/engine/internal/{ => codegen}/llvm/llvminstructionlist.cpp (100%) rename src/engine/internal/{ => codegen}/llvm/llvminstructionlist.h (100%) rename src/engine/internal/{ => codegen}/llvm/llvmlistptr.h (100%) rename src/engine/internal/{ => codegen}/llvm/llvmlocalvariableinfo.h (100%) rename src/engine/internal/{ => codegen}/llvm/llvmloop.h (100%) rename src/engine/internal/{ => codegen}/llvm/llvmregister.h (100%) rename src/engine/internal/{ => codegen}/llvm/llvmtypes.cpp (100%) rename src/engine/internal/{ => codegen}/llvm/llvmtypes.h (100%) rename src/engine/internal/{ => codegen}/llvm/llvmvariableptr.h (100%) diff --git a/src/engine/CMakeLists.txt b/src/engine/CMakeLists.txt index d4aa8ed52..b1a84308a 100644 --- a/src/engine/CMakeLists.txt +++ b/src/engine/CMakeLists.txt @@ -29,10 +29,6 @@ target_sources(scratchcpp thread_p.h internal/engine.cpp internal/engine.h - internal/icodebuilder.h - internal/icodebuilderfactory.h - internal/codebuilderfactory.cpp - internal/codebuilderfactory.h internal/clock.cpp internal/clock.h internal/iclock.h @@ -44,4 +40,4 @@ target_sources(scratchcpp internal/randomgenerator.cpp ) -add_subdirectory(internal/llvm) +add_subdirectory(internal/codegen) diff --git a/src/engine/compiler.cpp b/src/engine/compiler.cpp index fd4b41b72..05ca1a074 100644 --- a/src/engine/compiler.cpp +++ b/src/engine/compiler.cpp @@ -8,8 +8,8 @@ #include #include "compiler_p.h" -#include "internal/icodebuilderfactory.h" -#include "internal/icodebuilder.h" +#include "internal/codegen/icodebuilderfactory.h" +#include "internal/codegen/icodebuilder.h" using namespace libscratchcpp; diff --git a/src/engine/compiler_p.cpp b/src/engine/compiler_p.cpp index fce12ab7f..43bd5b57a 100644 --- a/src/engine/compiler_p.cpp +++ b/src/engine/compiler_p.cpp @@ -5,8 +5,8 @@ #include "compiler_p.h" -#include "internal/codebuilderfactory.h" -#include "internal/icodebuilder.h" +#include "internal/codegen/codebuilderfactory.h" +#include "internal/codegen/icodebuilder.h" using namespace libscratchcpp; diff --git a/src/engine/internal/codegen/CMakeLists.txt b/src/engine/internal/codegen/CMakeLists.txt new file mode 100644 index 000000000..7d7a4e582 --- /dev/null +++ b/src/engine/internal/codegen/CMakeLists.txt @@ -0,0 +1,9 @@ +target_sources(scratchcpp + PRIVATE + icodebuilder.h + icodebuilderfactory.h + codebuilderfactory.cpp + codebuilderfactory.h +) + +add_subdirectory(llvm) diff --git a/src/engine/internal/codebuilderfactory.cpp b/src/engine/internal/codegen/codebuilderfactory.cpp similarity index 100% rename from src/engine/internal/codebuilderfactory.cpp rename to src/engine/internal/codegen/codebuilderfactory.cpp diff --git a/src/engine/internal/codebuilderfactory.h b/src/engine/internal/codegen/codebuilderfactory.h similarity index 100% rename from src/engine/internal/codebuilderfactory.h rename to src/engine/internal/codegen/codebuilderfactory.h diff --git a/src/engine/internal/icodebuilder.h b/src/engine/internal/codegen/icodebuilder.h similarity index 100% rename from src/engine/internal/icodebuilder.h rename to src/engine/internal/codegen/icodebuilder.h diff --git a/src/engine/internal/icodebuilderfactory.h b/src/engine/internal/codegen/icodebuilderfactory.h similarity index 100% rename from src/engine/internal/icodebuilderfactory.h rename to src/engine/internal/codegen/icodebuilderfactory.h diff --git a/src/engine/internal/llvm/CMakeLists.txt b/src/engine/internal/codegen/llvm/CMakeLists.txt similarity index 100% rename from src/engine/internal/llvm/CMakeLists.txt rename to src/engine/internal/codegen/llvm/CMakeLists.txt diff --git a/src/engine/internal/llvm/instructions/CMakeLists.txt b/src/engine/internal/codegen/llvm/instructions/CMakeLists.txt similarity index 100% rename from src/engine/internal/llvm/instructions/CMakeLists.txt rename to src/engine/internal/codegen/llvm/instructions/CMakeLists.txt diff --git a/src/engine/internal/llvm/instructions/comparison.cpp b/src/engine/internal/codegen/llvm/instructions/comparison.cpp similarity index 100% rename from src/engine/internal/llvm/instructions/comparison.cpp rename to src/engine/internal/codegen/llvm/instructions/comparison.cpp diff --git a/src/engine/internal/llvm/instructions/comparison.h b/src/engine/internal/codegen/llvm/instructions/comparison.h similarity index 100% rename from src/engine/internal/llvm/instructions/comparison.h rename to src/engine/internal/codegen/llvm/instructions/comparison.h diff --git a/src/engine/internal/llvm/instructions/control.cpp b/src/engine/internal/codegen/llvm/instructions/control.cpp similarity index 100% rename from src/engine/internal/llvm/instructions/control.cpp rename to src/engine/internal/codegen/llvm/instructions/control.cpp diff --git a/src/engine/internal/llvm/instructions/control.h b/src/engine/internal/codegen/llvm/instructions/control.h similarity index 100% rename from src/engine/internal/llvm/instructions/control.h rename to src/engine/internal/codegen/llvm/instructions/control.h diff --git a/src/engine/internal/llvm/instructions/functions.cpp b/src/engine/internal/codegen/llvm/instructions/functions.cpp similarity index 100% rename from src/engine/internal/llvm/instructions/functions.cpp rename to src/engine/internal/codegen/llvm/instructions/functions.cpp diff --git a/src/engine/internal/llvm/instructions/functions.h b/src/engine/internal/codegen/llvm/instructions/functions.h similarity index 100% rename from src/engine/internal/llvm/instructions/functions.h rename to src/engine/internal/codegen/llvm/instructions/functions.h diff --git a/src/engine/internal/llvm/instructions/instructionbuilder.cpp b/src/engine/internal/codegen/llvm/instructions/instructionbuilder.cpp similarity index 100% rename from src/engine/internal/llvm/instructions/instructionbuilder.cpp rename to src/engine/internal/codegen/llvm/instructions/instructionbuilder.cpp diff --git a/src/engine/internal/llvm/instructions/instructionbuilder.h b/src/engine/internal/codegen/llvm/instructions/instructionbuilder.h similarity index 100% rename from src/engine/internal/llvm/instructions/instructionbuilder.h rename to src/engine/internal/codegen/llvm/instructions/instructionbuilder.h diff --git a/src/engine/internal/llvm/instructions/instructiongroup.cpp b/src/engine/internal/codegen/llvm/instructions/instructiongroup.cpp similarity index 100% rename from src/engine/internal/llvm/instructions/instructiongroup.cpp rename to src/engine/internal/codegen/llvm/instructions/instructiongroup.cpp diff --git a/src/engine/internal/llvm/instructions/instructiongroup.h b/src/engine/internal/codegen/llvm/instructions/instructiongroup.h similarity index 100% rename from src/engine/internal/llvm/instructions/instructiongroup.h rename to src/engine/internal/codegen/llvm/instructions/instructiongroup.h diff --git a/src/engine/internal/llvm/instructions/lists.cpp b/src/engine/internal/codegen/llvm/instructions/lists.cpp similarity index 100% rename from src/engine/internal/llvm/instructions/lists.cpp rename to src/engine/internal/codegen/llvm/instructions/lists.cpp diff --git a/src/engine/internal/llvm/instructions/lists.h b/src/engine/internal/codegen/llvm/instructions/lists.h similarity index 100% rename from src/engine/internal/llvm/instructions/lists.h rename to src/engine/internal/codegen/llvm/instructions/lists.h diff --git a/src/engine/internal/llvm/instructions/logic.cpp b/src/engine/internal/codegen/llvm/instructions/logic.cpp similarity index 100% rename from src/engine/internal/llvm/instructions/logic.cpp rename to src/engine/internal/codegen/llvm/instructions/logic.cpp diff --git a/src/engine/internal/llvm/instructions/logic.h b/src/engine/internal/codegen/llvm/instructions/logic.h similarity index 100% rename from src/engine/internal/llvm/instructions/logic.h rename to src/engine/internal/codegen/llvm/instructions/logic.h diff --git a/src/engine/internal/llvm/instructions/math.cpp b/src/engine/internal/codegen/llvm/instructions/math.cpp similarity index 100% rename from src/engine/internal/llvm/instructions/math.cpp rename to src/engine/internal/codegen/llvm/instructions/math.cpp diff --git a/src/engine/internal/llvm/instructions/math.h b/src/engine/internal/codegen/llvm/instructions/math.h similarity index 100% rename from src/engine/internal/llvm/instructions/math.h rename to src/engine/internal/codegen/llvm/instructions/math.h diff --git a/src/engine/internal/llvm/instructions/procedures.cpp b/src/engine/internal/codegen/llvm/instructions/procedures.cpp similarity index 100% rename from src/engine/internal/llvm/instructions/procedures.cpp rename to src/engine/internal/codegen/llvm/instructions/procedures.cpp diff --git a/src/engine/internal/llvm/instructions/procedures.h b/src/engine/internal/codegen/llvm/instructions/procedures.h similarity index 100% rename from src/engine/internal/llvm/instructions/procedures.h rename to src/engine/internal/codegen/llvm/instructions/procedures.h diff --git a/src/engine/internal/llvm/instructions/processresult.h b/src/engine/internal/codegen/llvm/instructions/processresult.h similarity index 100% rename from src/engine/internal/llvm/instructions/processresult.h rename to src/engine/internal/codegen/llvm/instructions/processresult.h diff --git a/src/engine/internal/llvm/instructions/string.cpp b/src/engine/internal/codegen/llvm/instructions/string.cpp similarity index 100% rename from src/engine/internal/llvm/instructions/string.cpp rename to src/engine/internal/codegen/llvm/instructions/string.cpp diff --git a/src/engine/internal/llvm/instructions/string.h b/src/engine/internal/codegen/llvm/instructions/string.h similarity index 100% rename from src/engine/internal/llvm/instructions/string.h rename to src/engine/internal/codegen/llvm/instructions/string.h diff --git a/src/engine/internal/llvm/instructions/variables.cpp b/src/engine/internal/codegen/llvm/instructions/variables.cpp similarity index 100% rename from src/engine/internal/llvm/instructions/variables.cpp rename to src/engine/internal/codegen/llvm/instructions/variables.cpp diff --git a/src/engine/internal/llvm/instructions/variables.h b/src/engine/internal/codegen/llvm/instructions/variables.h similarity index 100% rename from src/engine/internal/llvm/instructions/variables.h rename to src/engine/internal/codegen/llvm/instructions/variables.h diff --git a/src/engine/internal/llvm/llvmbuildutils.cpp b/src/engine/internal/codegen/llvm/llvmbuildutils.cpp similarity index 100% rename from src/engine/internal/llvm/llvmbuildutils.cpp rename to src/engine/internal/codegen/llvm/llvmbuildutils.cpp diff --git a/src/engine/internal/llvm/llvmbuildutils.h b/src/engine/internal/codegen/llvm/llvmbuildutils.h similarity index 100% rename from src/engine/internal/llvm/llvmbuildutils.h rename to src/engine/internal/codegen/llvm/llvmbuildutils.h diff --git a/src/engine/internal/llvm/llvmcodeanalyzer.cpp b/src/engine/internal/codegen/llvm/llvmcodeanalyzer.cpp similarity index 100% rename from src/engine/internal/llvm/llvmcodeanalyzer.cpp rename to src/engine/internal/codegen/llvm/llvmcodeanalyzer.cpp diff --git a/src/engine/internal/llvm/llvmcodeanalyzer.h b/src/engine/internal/codegen/llvm/llvmcodeanalyzer.h similarity index 100% rename from src/engine/internal/llvm/llvmcodeanalyzer.h rename to src/engine/internal/codegen/llvm/llvmcodeanalyzer.h diff --git a/src/engine/internal/llvm/llvmcodebuilder.cpp b/src/engine/internal/codegen/llvm/llvmcodebuilder.cpp similarity index 100% rename from src/engine/internal/llvm/llvmcodebuilder.cpp rename to src/engine/internal/codegen/llvm/llvmcodebuilder.cpp diff --git a/src/engine/internal/llvm/llvmcodebuilder.h b/src/engine/internal/codegen/llvm/llvmcodebuilder.h similarity index 100% rename from src/engine/internal/llvm/llvmcodebuilder.h rename to src/engine/internal/codegen/llvm/llvmcodebuilder.h diff --git a/src/engine/internal/llvm/llvmcompilercontext.cpp b/src/engine/internal/codegen/llvm/llvmcompilercontext.cpp similarity index 100% rename from src/engine/internal/llvm/llvmcompilercontext.cpp rename to src/engine/internal/codegen/llvm/llvmcompilercontext.cpp diff --git a/src/engine/internal/llvm/llvmcompilercontext.h b/src/engine/internal/codegen/llvm/llvmcompilercontext.h similarity index 100% rename from src/engine/internal/llvm/llvmcompilercontext.h rename to src/engine/internal/codegen/llvm/llvmcompilercontext.h diff --git a/src/engine/internal/llvm/llvmconstantregister.h b/src/engine/internal/codegen/llvm/llvmconstantregister.h similarity index 100% rename from src/engine/internal/llvm/llvmconstantregister.h rename to src/engine/internal/codegen/llvm/llvmconstantregister.h diff --git a/src/engine/internal/llvm/llvmcoroutine.cpp b/src/engine/internal/codegen/llvm/llvmcoroutine.cpp similarity index 100% rename from src/engine/internal/llvm/llvmcoroutine.cpp rename to src/engine/internal/codegen/llvm/llvmcoroutine.cpp diff --git a/src/engine/internal/llvm/llvmcoroutine.h b/src/engine/internal/codegen/llvm/llvmcoroutine.h similarity index 100% rename from src/engine/internal/llvm/llvmcoroutine.h rename to src/engine/internal/codegen/llvm/llvmcoroutine.h diff --git a/src/engine/internal/llvm/llvmexecutablecode.cpp b/src/engine/internal/codegen/llvm/llvmexecutablecode.cpp similarity index 100% rename from src/engine/internal/llvm/llvmexecutablecode.cpp rename to src/engine/internal/codegen/llvm/llvmexecutablecode.cpp diff --git a/src/engine/internal/llvm/llvmexecutablecode.h b/src/engine/internal/codegen/llvm/llvmexecutablecode.h similarity index 100% rename from src/engine/internal/llvm/llvmexecutablecode.h rename to src/engine/internal/codegen/llvm/llvmexecutablecode.h diff --git a/src/engine/internal/llvm/llvmexecutioncontext.cpp b/src/engine/internal/codegen/llvm/llvmexecutioncontext.cpp similarity index 100% rename from src/engine/internal/llvm/llvmexecutioncontext.cpp rename to src/engine/internal/codegen/llvm/llvmexecutioncontext.cpp diff --git a/src/engine/internal/llvm/llvmexecutioncontext.h b/src/engine/internal/codegen/llvm/llvmexecutioncontext.h similarity index 100% rename from src/engine/internal/llvm/llvmexecutioncontext.h rename to src/engine/internal/codegen/llvm/llvmexecutioncontext.h diff --git a/src/engine/internal/llvm/llvmfunctions.cpp b/src/engine/internal/codegen/llvm/llvmfunctions.cpp similarity index 100% rename from src/engine/internal/llvm/llvmfunctions.cpp rename to src/engine/internal/codegen/llvm/llvmfunctions.cpp diff --git a/src/engine/internal/llvm/llvmfunctions.h b/src/engine/internal/codegen/llvm/llvmfunctions.h similarity index 100% rename from src/engine/internal/llvm/llvmfunctions.h rename to src/engine/internal/codegen/llvm/llvmfunctions.h diff --git a/src/engine/internal/llvm/llvmifstatement.h b/src/engine/internal/codegen/llvm/llvmifstatement.h similarity index 100% rename from src/engine/internal/llvm/llvmifstatement.h rename to src/engine/internal/codegen/llvm/llvmifstatement.h diff --git a/src/engine/internal/llvm/llvminstruction.h b/src/engine/internal/codegen/llvm/llvminstruction.h similarity index 100% rename from src/engine/internal/llvm/llvminstruction.h rename to src/engine/internal/codegen/llvm/llvminstruction.h diff --git a/src/engine/internal/llvm/llvminstructionlist.cpp b/src/engine/internal/codegen/llvm/llvminstructionlist.cpp similarity index 100% rename from src/engine/internal/llvm/llvminstructionlist.cpp rename to src/engine/internal/codegen/llvm/llvminstructionlist.cpp diff --git a/src/engine/internal/llvm/llvminstructionlist.h b/src/engine/internal/codegen/llvm/llvminstructionlist.h similarity index 100% rename from src/engine/internal/llvm/llvminstructionlist.h rename to src/engine/internal/codegen/llvm/llvminstructionlist.h diff --git a/src/engine/internal/llvm/llvmlistptr.h b/src/engine/internal/codegen/llvm/llvmlistptr.h similarity index 100% rename from src/engine/internal/llvm/llvmlistptr.h rename to src/engine/internal/codegen/llvm/llvmlistptr.h diff --git a/src/engine/internal/llvm/llvmlocalvariableinfo.h b/src/engine/internal/codegen/llvm/llvmlocalvariableinfo.h similarity index 100% rename from src/engine/internal/llvm/llvmlocalvariableinfo.h rename to src/engine/internal/codegen/llvm/llvmlocalvariableinfo.h diff --git a/src/engine/internal/llvm/llvmloop.h b/src/engine/internal/codegen/llvm/llvmloop.h similarity index 100% rename from src/engine/internal/llvm/llvmloop.h rename to src/engine/internal/codegen/llvm/llvmloop.h diff --git a/src/engine/internal/llvm/llvmregister.h b/src/engine/internal/codegen/llvm/llvmregister.h similarity index 100% rename from src/engine/internal/llvm/llvmregister.h rename to src/engine/internal/codegen/llvm/llvmregister.h diff --git a/src/engine/internal/llvm/llvmtypes.cpp b/src/engine/internal/codegen/llvm/llvmtypes.cpp similarity index 100% rename from src/engine/internal/llvm/llvmtypes.cpp rename to src/engine/internal/codegen/llvm/llvmtypes.cpp diff --git a/src/engine/internal/llvm/llvmtypes.h b/src/engine/internal/codegen/llvm/llvmtypes.h similarity index 100% rename from src/engine/internal/llvm/llvmtypes.h rename to src/engine/internal/codegen/llvm/llvmtypes.h diff --git a/src/engine/internal/llvm/llvmvariableptr.h b/src/engine/internal/codegen/llvm/llvmvariableptr.h similarity index 100% rename from src/engine/internal/llvm/llvmvariableptr.h rename to src/engine/internal/codegen/llvm/llvmvariableptr.h diff --git a/test/codegen/codegentestutils.cpp b/test/codegen/codegentestutils.cpp index 6311f5fb1..b5f47c8ce 100644 --- a/test/codegen/codegentestutils.cpp +++ b/test/codegen/codegentestutils.cpp @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include "codegentestutils.h" #include "testfunctions.h" diff --git a/test/codegen/codegentestutils.h b/test/codegen/codegentestutils.h index 9fb9598a8..158f93f92 100644 --- a/test/codegen/codegentestutils.h +++ b/test/codegen/codegentestutils.h @@ -5,7 +5,7 @@ #include #include -#include +#include #define ASSERT_NUM_OP1(utils, type, rawArg, v) \ Value result = utils.getOpResult(type, rawArg, v); \ diff --git a/test/llvm/code_analyzer/list_type_analysis.cpp b/test/llvm/code_analyzer/list_type_analysis.cpp index 45d479fb3..da8251680 100644 --- a/test/llvm/code_analyzer/list_type_analysis.cpp +++ b/test/llvm/code_analyzer/list_type_analysis.cpp @@ -4,12 +4,12 @@ #include #include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #include #include diff --git a/test/llvm/code_analyzer/mixed_type_analysis.cpp b/test/llvm/code_analyzer/mixed_type_analysis.cpp index a082ee921..cfd2133f2 100644 --- a/test/llvm/code_analyzer/mixed_type_analysis.cpp +++ b/test/llvm/code_analyzer/mixed_type_analysis.cpp @@ -2,12 +2,12 @@ #include #include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #include #include diff --git a/test/llvm/code_analyzer/variable_type_analysis.cpp b/test/llvm/code_analyzer/variable_type_analysis.cpp index b910b154a..c62c57299 100644 --- a/test/llvm/code_analyzer/variable_type_analysis.cpp +++ b/test/llvm/code_analyzer/variable_type_analysis.cpp @@ -4,12 +4,12 @@ #include #include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #include #include diff --git a/test/llvm/llvmexecutablecode_test.cpp b/test/llvm/llvmexecutablecode_test.cpp index 1bb2fae01..6f14485b8 100644 --- a/test/llvm/llvmexecutablecode_test.cpp +++ b/test/llvm/llvmexecutablecode_test.cpp @@ -5,10 +5,10 @@ #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include #include #include diff --git a/test/llvm/llvmexecutioncontext_test.cpp b/test/llvm/llvmexecutioncontext_test.cpp index a26e88299..37939d036 100644 --- a/test/llvm/llvmexecutioncontext_test.cpp +++ b/test/llvm/llvmexecutioncontext_test.cpp @@ -1,6 +1,6 @@ #include -#include -#include +#include +#include #include using namespace libscratchcpp; diff --git a/test/llvm/llvminstructionlist_test.cpp b/test/llvm/llvminstructionlist_test.cpp index 02535da28..6d9741541 100644 --- a/test/llvm/llvminstructionlist_test.cpp +++ b/test/llvm/llvminstructionlist_test.cpp @@ -1,6 +1,6 @@ #include -#include -#include +#include +#include #include using namespace libscratchcpp; diff --git a/test/mocks/codebuilderfactorymock.h b/test/mocks/codebuilderfactorymock.h index d1d1d080c..1577a7149 100644 --- a/test/mocks/codebuilderfactorymock.h +++ b/test/mocks/codebuilderfactorymock.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include using namespace libscratchcpp; diff --git a/test/mocks/codebuildermock.h b/test/mocks/codebuildermock.h index 2eb3e0d87..9a41bd5e9 100644 --- a/test/mocks/codebuildermock.h +++ b/test/mocks/codebuildermock.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include using namespace libscratchcpp; From 6f74836c098dbb648f086a0604372e7e4e7932d9 Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Wed, 21 Oct 2026 20:33:39 +0200 Subject: [PATCH 02/13] Add a generic Instruction struct --- src/engine/internal/codegen/CMakeLists.txt | 1 + src/engine/internal/codegen/instruction.h | 110 ++++++++++++++++++ .../internal/codegen/llvm/llvminstruction.h | 99 +--------------- 3 files changed, 116 insertions(+), 94 deletions(-) create mode 100644 src/engine/internal/codegen/instruction.h diff --git a/src/engine/internal/codegen/CMakeLists.txt b/src/engine/internal/codegen/CMakeLists.txt index 7d7a4e582..96baf3c62 100644 --- a/src/engine/internal/codegen/CMakeLists.txt +++ b/src/engine/internal/codegen/CMakeLists.txt @@ -4,6 +4,7 @@ target_sources(scratchcpp icodebuilderfactory.h codebuilderfactory.cpp codebuilderfactory.h + instruction.h ) add_subdirectory(llvm) diff --git a/src/engine/internal/codegen/instruction.h b/src/engine/internal/codegen/instruction.h new file mode 100644 index 000000000..b674934d3 --- /dev/null +++ b/src/engine/internal/codegen/instruction.h @@ -0,0 +1,110 @@ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include + +namespace libscratchcpp +{ + +class BlockPrototype; + +template +struct Instruction +{ + enum class Type + { + FunctionCall, + Add, + Sub, + Mul, + Div, + Random, + RandomInt, + CmpEQ, + CmpGT, + CmpLT, + StrCmpEQCS, // case sensitive + StrCmpEQCI, // case insensitive + And, + Or, + Not, + Mod, + Round, + Abs, + Floor, + Ceil, + Sqrt, + Sin, + Cos, + Tan, + Asin, + Acos, + Atan, + Ln, + Log10, + Exp, + Exp10, + StringConcat, + StringChar, + StringLength, + Select, + CreateLocalVariable, + WriteLocalVariable, + ReadLocalVariable, + WriteVariable, + ReadVariable, + ClearList, + RemoveListItem, + AppendToList, + InsertToList, + ListReplace, + GetListContents, + GetListItem, + GetListSize, + GetListItemIndex, + ListContainsItem, + Yield, + BeginIf, + BeginElse, + EndIf, + BeginRepeatLoop, + LoopIndex, + BeginWhileLoop, + BeginRepeatUntilLoop, + BeginLoopCondition, + EndLoop, + Stop, + ThreadStop, + InvalidateTarget, + CallProcedure, + ProcedureArg, + Print + }; + + Instruction(Type type, bool loopCondition) : + type(type), + loopCondition(loopCondition) + { + } + + Type type; + std::string functionName; + std::vector> args; // target type, register + TRegister *functionReturnReg = nullptr; + bool functionTargetArg = false; // whether to add target ptr to function parameters + bool functionCtxArg = false; // whether to add execution context ptr to function parameters + Variable *targetVariable = nullptr; // for variables + List *targetList = nullptr; // for lists + Compiler::StaticType targetType = Compiler::StaticType::Unknown; // variable or list type (before read/write operation) + BlockPrototype *procedurePrototype = nullptr; + size_t procedureArgIndex = 0; + bool loopCondition = false; // whether the instruction is part of a loop condition + + // Linked list + TInstruction *previous = nullptr; + TInstruction *next = nullptr; + std::shared_ptr _next; // ensure items are not deleted +}; + +} // namespace libscratchcpp diff --git a/src/engine/internal/codegen/llvm/llvminstruction.h b/src/engine/internal/codegen/llvm/llvminstruction.h index 521f25afd..3a0bb65bc 100644 --- a/src/engine/internal/codegen/llvm/llvminstruction.h +++ b/src/engine/internal/codegen/llvm/llvminstruction.h @@ -4,6 +4,7 @@ #include +#include "../instruction.h" #include "llvmregister.h" namespace libscratchcpp @@ -12,102 +13,12 @@ namespace libscratchcpp class LLVMLocalVariableInfo; class BlockPrototype; -struct LLVMInstruction +struct LLVMInstruction : Instruction { - enum class Type - { - FunctionCall, - Add, - Sub, - Mul, - Div, - Random, - RandomInt, - CmpEQ, - CmpGT, - CmpLT, - StrCmpEQCS, // case sensitive - StrCmpEQCI, // case insensitive - And, - Or, - Not, - Mod, - Round, - Abs, - Floor, - Ceil, - Sqrt, - Sin, - Cos, - Tan, - Asin, - Acos, - Atan, - Ln, - Log10, - Exp, - Exp10, - StringConcat, - StringChar, - StringLength, - Select, - CreateLocalVariable, - WriteLocalVariable, - ReadLocalVariable, - WriteVariable, - ReadVariable, - ClearList, - RemoveListItem, - AppendToList, - InsertToList, - ListReplace, - GetListContents, - GetListItem, - GetListSize, - GetListItemIndex, - ListContainsItem, - Yield, - BeginIf, - BeginElse, - EndIf, - BeginRepeatLoop, - LoopIndex, - BeginWhileLoop, - BeginRepeatUntilLoop, - BeginLoopCondition, - EndLoop, - Stop, - ThreadStop, - InvalidateTarget, - CallProcedure, - ProcedureArg, - Print - }; + using Type = Instruction::Type; + using Instruction::Instruction; // inherit constructor - LLVMInstruction(Type type, bool loopCondition) : - type(type), - loopCondition(loopCondition) - { - } - - Type type; - std::string functionName; - std::vector> args; // target type, register - LLVMRegister *functionReturnReg = nullptr; - bool functionTargetArg = false; // whether to add target ptr to function parameters - bool functionCtxArg = false; // whether to add execution context ptr to function parameters - LLVMLocalVariableInfo *localVarInfo = nullptr; // for local variables - Variable *targetVariable = nullptr; // for variables - List *targetList = nullptr; // for lists - Compiler::StaticType targetType = Compiler::StaticType::Unknown; // variable or list type (before read/write operation) - BlockPrototype *procedurePrototype = nullptr; - size_t procedureArgIndex = 0; - bool loopCondition = false; // whether the instruction is part of a loop condition - - // Linked list - LLVMInstruction *previous = nullptr; - LLVMInstruction *next = nullptr; - std::shared_ptr _next; // ensure items are not deleted + LLVMLocalVariableInfo *localVarInfo = nullptr; // for local variables }; } // namespace libscratchcpp From 672ce414d0b9d25dc8be42420c6a3edac85bfd37 Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Wed, 21 Oct 2026 21:00:00 +0200 Subject: [PATCH 03/13] Add a generic InstructionList class --- src/engine/internal/codegen/CMakeLists.txt | 1 + src/engine/internal/codegen/instructionlist.h | 78 ++++ .../internal/codegen/llvm/CMakeLists.txt | 1 - .../internal/codegen/llvm/llvmcodeanalyzer.h | 2 +- .../codegen/llvm/llvminstructionlist.cpp | 65 --- .../codegen/llvm/llvminstructionlist.h | 26 +- test/codegen/CMakeLists.txt | 1 + test/codegen/instructionlist_test.cpp | 372 ++++++++++++++++++ test/llvm/CMakeLists.txt | 1 - test/llvm/llvminstructionlist_test.cpp | 366 ----------------- 10 files changed, 455 insertions(+), 458 deletions(-) create mode 100644 src/engine/internal/codegen/instructionlist.h delete mode 100644 src/engine/internal/codegen/llvm/llvminstructionlist.cpp create mode 100644 test/codegen/instructionlist_test.cpp delete mode 100644 test/llvm/llvminstructionlist_test.cpp diff --git a/src/engine/internal/codegen/CMakeLists.txt b/src/engine/internal/codegen/CMakeLists.txt index 96baf3c62..39b4b6caa 100644 --- a/src/engine/internal/codegen/CMakeLists.txt +++ b/src/engine/internal/codegen/CMakeLists.txt @@ -5,6 +5,7 @@ target_sources(scratchcpp codebuilderfactory.cpp codebuilderfactory.h instruction.h + instructionlist.h ) add_subdirectory(llvm) diff --git a/src/engine/internal/codegen/instructionlist.h b/src/engine/internal/codegen/instructionlist.h new file mode 100644 index 000000000..5f0e5eb9a --- /dev/null +++ b/src/engine/internal/codegen/instructionlist.h @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include +#include + +#include "test_export.h" + +namespace libscratchcpp +{ + +template +class LIBSCRATCHCPP_TEST_EXPORT InstructionList +{ + public: + InstructionList() = default; + InstructionList(const InstructionList &) = delete; + + inline TInstruction *first() const { return m_first.get(); } + + inline TInstruction *last() const { return m_last.get(); } + + inline bool empty() const { return !first(); } + + inline bool containsInstruction(TInstruction *ins) const + { + TInstruction *ptr = m_first.get(); + + while (ptr) { + if (ptr == ins) + return true; + + ptr = ptr->next; + } + + return false; + } + + inline bool containsInstruction(std::function func) const + { + TInstruction *ptr = m_first.get(); + + while (ptr) { + if (func(ptr)) + return true; + + ptr = ptr->next; + } + + return false; + } + + inline void addInstruction(std::shared_ptr ins) + { + if (!(m_first && m_last)) { + assert(!m_first && !m_last); + + m_first = ins; + m_last = ins; + + ins->previous = nullptr; + ins->next = nullptr; + ins->_next = nullptr; + } else { + m_last->next = ins.get(); + m_last->_next = ins; + ins->previous = m_last.get(); + m_last = ins; + } + } + + private: + std::shared_ptr m_first; + std::shared_ptr m_last; +}; + +} // namespace libscratchcpp diff --git a/src/engine/internal/codegen/llvm/CMakeLists.txt b/src/engine/internal/codegen/llvm/CMakeLists.txt index 818286c21..e2a8c1f8d 100644 --- a/src/engine/internal/codegen/llvm/CMakeLists.txt +++ b/src/engine/internal/codegen/llvm/CMakeLists.txt @@ -9,7 +9,6 @@ target_sources(scratchcpp llvmregister.h llvmconstantregister.h llvminstruction.h - llvminstructionlist.cpp llvminstructionlist.h llvmifstatement.h llvmloop.h diff --git a/src/engine/internal/codegen/llvm/llvmcodeanalyzer.h b/src/engine/internal/codegen/llvm/llvmcodeanalyzer.h index 87668c3b8..e8c320144 100644 --- a/src/engine/internal/codegen/llvm/llvmcodeanalyzer.h +++ b/src/engine/internal/codegen/llvm/llvmcodeanalyzer.h @@ -6,12 +6,12 @@ #include #include "test_export.h" +#include "llvminstructionlist.h" namespace libscratchcpp { class LLVMBuildUtils; -class LLVMInstructionList; class LLVMInstruction; class LIBSCRATCHCPP_TEST_EXPORT LLVMCodeAnalyzer diff --git a/src/engine/internal/codegen/llvm/llvminstructionlist.cpp b/src/engine/internal/codegen/llvm/llvminstructionlist.cpp deleted file mode 100644 index 61b8d6c38..000000000 --- a/src/engine/internal/codegen/llvm/llvminstructionlist.cpp +++ /dev/null @@ -1,65 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 - -#include - -#include "llvminstructionlist.h" -#include "llvminstruction.h" - -using namespace libscratchcpp; - -LLVMInstruction *LLVMInstructionList::first() const -{ - return m_first.get(); -} - -LLVMInstruction *LLVMInstructionList::last() const -{ - return m_last.get(); -} - -bool LLVMInstructionList::containsInstruction(LLVMInstruction *ins) const -{ - LLVMInstruction *ptr = m_first.get(); - - while (ptr) { - if (ptr == ins) - return true; - - ptr = ptr->next; - } - - return false; -} - -bool LLVMInstructionList::containsInstruction(std::function func) const -{ - LLVMInstruction *ptr = m_first.get(); - - while (ptr) { - if (func(ptr)) - return true; - - ptr = ptr->next; - } - - return false; -} - -void LLVMInstructionList::addInstruction(std::shared_ptr ins) -{ - if (!(m_first && m_last)) { - assert(!m_first && !m_last); - - m_first = ins; - m_last = ins; - - ins->previous = nullptr; - ins->next = nullptr; - ins->_next = nullptr; - } else { - m_last->next = ins.get(); - m_last->_next = ins; - ins->previous = m_last.get(); - m_last = ins; - } -} diff --git a/src/engine/internal/codegen/llvm/llvminstructionlist.h b/src/engine/internal/codegen/llvm/llvminstructionlist.h index 916ba81f5..cf988aaf9 100644 --- a/src/engine/internal/codegen/llvm/llvminstructionlist.h +++ b/src/engine/internal/codegen/llvm/llvminstructionlist.h @@ -2,35 +2,13 @@ #pragma once -#include -#include - -#include "test_export.h" +#include "../instructionlist.h" namespace libscratchcpp { struct LLVMInstruction; -class LIBSCRATCHCPP_TEST_EXPORT LLVMInstructionList -{ - public: - LLVMInstructionList() = default; - LLVMInstructionList(const LLVMInstructionList &) = delete; - - LLVMInstruction *first() const; - LLVMInstruction *last() const; - - bool empty() const { return !first(); } - - bool containsInstruction(LLVMInstruction *ins) const; - bool containsInstruction(std::function func) const; - - void addInstruction(std::shared_ptr ins); - - private: - std::shared_ptr m_first; - std::shared_ptr m_last; -}; +using LLVMInstructionList = InstructionList; } // namespace libscratchcpp diff --git a/test/codegen/CMakeLists.txt b/test/codegen/CMakeLists.txt index 0037124b2..cd67920ff 100644 --- a/test/codegen/CMakeLists.txt +++ b/test/codegen/CMakeLists.txt @@ -19,6 +19,7 @@ add_executable( codebuilder_test.cpp codegentestutils.cpp codegentestutils.h + instructionlist_test.cpp operators/equal_comparison_test.cpp operators/greater_than_test.cpp operators/less_than_test.cpp diff --git a/test/codegen/instructionlist_test.cpp b/test/codegen/instructionlist_test.cpp new file mode 100644 index 000000000..837bfcd3e --- /dev/null +++ b/test/codegen/instructionlist_test.cpp @@ -0,0 +1,372 @@ +#include +#include +#include +#include + +using namespace libscratchcpp; + +struct TInstruction : public Instruction +{ + using Type = Instruction::Type; + using Instruction::Instruction; // inherit constructor +}; + +TEST(InstructionListTest, EmptyList_First) +{ + InstructionList list; + ASSERT_EQ(list.first(), nullptr); +} + +TEST(InstructionListTest, EmptyList_Last) +{ + InstructionList list; + ASSERT_EQ(list.last(), nullptr); +} + +TEST(InstructionListTest, EmptyList_Empty) +{ + InstructionList list; + ASSERT_TRUE(list.empty()); +} + +TEST(InstructionListTest, EmptyList_ContainsNull) +{ + InstructionList list; + ASSERT_FALSE(list.containsInstruction(nullptr)); +} + +TEST(InstructionListTest, EmptyList_ContainsFunc) +{ + InstructionList list; + auto ins = std::make_shared(TInstruction::Type::FunctionCall, false); + ASSERT_FALSE(list.containsInstruction([](const TInstruction *) { return true; })); +} + +TEST(InstructionListTest, EmptyList_Contains) +{ + InstructionList list; + auto ins = std::make_shared(TInstruction::Type::FunctionCall, false); + ASSERT_FALSE(list.containsInstruction(ins.get())); +} + +TEST(InstructionListTest, SingleInstructionList_ContainsExistent) +{ + InstructionList list; + + auto ins1 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins1); + + ASSERT_TRUE(list.containsInstruction(ins1.get())); +} + +TEST(InstructionListTest, SingleInstructionList_ContainsNonExistent) +{ + InstructionList list; + + auto ins1 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins1); + + auto ins = std::make_shared(TInstruction::Type::FunctionCall, false); + ASSERT_FALSE(list.containsInstruction(ins.get())); +} + +TEST(InstructionListTest, SingleInstructionList_ContainsNull) +{ + InstructionList list; + + auto ins1 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins1); + + ASSERT_FALSE(list.containsInstruction(nullptr)); +} + +TEST(InstructionListTest, SingleInstructionList_ContainsFuncTrue) +{ + InstructionList list; + + auto ins1 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins1); + + ASSERT_TRUE(list.containsInstruction([](const TInstruction *) { return true; })); +} + +TEST(InstructionListTest, SingleInstructionList_ContainsFuncFalse) +{ + InstructionList list; + + auto ins1 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins1); + + auto ins = std::make_shared(TInstruction::Type::FunctionCall, false); + ASSERT_FALSE(list.containsInstruction([](const TInstruction *) { return false; })); +} + +TEST(InstructionListTest, MultipleInstructionList_ContainsExistent) +{ + InstructionList list; + + auto ins1 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins1); + + auto ins2 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins2); + + auto ins3 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins3); + + ASSERT_TRUE(list.containsInstruction(ins2.get())); +} + +TEST(InstructionListTest, MultipleInstructionList_ContainsNonExistent) +{ + InstructionList list; + + auto ins1 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins1); + + auto ins2 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins2); + + auto ins3 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins3); + + auto ins = std::make_shared(TInstruction::Type::FunctionCall, false); + ASSERT_FALSE(list.containsInstruction(ins.get())); +} + +TEST(InstructionListTest, MultipleInstructionList_ContainsNull) +{ + InstructionList list; + + auto ins1 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins1); + + auto ins2 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins2); + + auto ins3 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins3); + + ASSERT_FALSE(list.containsInstruction(nullptr)); +} + +TEST(InstructionListTest, MultipleInstructionList_ContainsExistentFunc) +{ + InstructionList list; + + auto ins1 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins1); + + auto ins2 = std::make_shared(TInstruction::Type::Stop, false); + list.addInstruction(ins2); + + auto ins3 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins3); + + ASSERT_TRUE(list.containsInstruction([](const TInstruction *ins) { return ins->type == TInstruction::Type::Stop; })); +} + +TEST(InstructionListTest, MultipleInstructionList_ContainsNonExistentFunc) +{ + InstructionList list; + + auto ins1 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins1); + + auto ins2 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins2); + + auto ins3 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins3); + + ASSERT_FALSE(list.containsInstruction([](const TInstruction *ins) { return ins->type == TInstruction::Type::Stop; })); +} + +TEST(InstructionListTest, AddSingleInstruction_First) +{ + InstructionList list; + auto ins = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins); + + ASSERT_EQ(list.first(), ins.get()); +} + +TEST(InstructionListTest, AddSingleInstruction_Last) +{ + InstructionList list; + auto ins = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins); + + ASSERT_EQ(list.last(), ins.get()); +} + +TEST(InstructionListTest, AddSingleInstruction_Empty) +{ + InstructionList list; + auto ins = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins); + + ASSERT_FALSE(list.empty()); +} + +TEST(InstructionListTest, AddSingleInstruction_Previous) +{ + InstructionList list; + auto ins = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins); + + ASSERT_EQ(ins->previous, nullptr); +} + +TEST(InstructionListTest, AddSingleInstruction_Next) +{ + InstructionList list; + auto ins = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins); + + ASSERT_EQ(ins->next, nullptr); +} + +TEST(InstructionListTest, AddMultipleInstructions_First) +{ + InstructionList list; + + auto ins1 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins1); + + auto ins2 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins2); + + auto ins3 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins3); + + ASSERT_EQ(list.first(), ins1.get()); +} + +TEST(InstructionListTest, AddMultipleInstructions_Last) +{ + InstructionList list; + + auto ins1 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins1); + + auto ins2 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins2); + + auto ins3 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins3); + + ASSERT_EQ(list.last(), ins3.get()); +} + +TEST(InstructionListTest, AddMultipleInstructions_Empty) +{ + InstructionList list; + + auto ins1 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins1); + + auto ins2 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins2); + + auto ins3 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins3); + + ASSERT_FALSE(list.empty()); +} + +TEST(InstructionListTest, AddMultipleInstructions_PreviousOfFirst) +{ + InstructionList list; + + auto ins1 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins1); + + auto ins2 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins2); + + auto ins3 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins3); + + ASSERT_EQ(ins1->previous, nullptr); +} + +TEST(InstructionListTest, AddMultipleInstructions_NextOfFirst) +{ + InstructionList list; + + auto ins1 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins1); + + auto ins2 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins2); + + auto ins3 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins3); + + ASSERT_EQ(ins1->next, ins2.get()); +} + +TEST(InstructionListTest, AddMultipleInstructions_PreviousOfMiddle) +{ + InstructionList list; + + auto ins1 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins1); + + auto ins2 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins2); + + auto ins3 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins3); + + ASSERT_EQ(ins2->previous, ins1.get()); +} + +TEST(InstructionListTest, AddMultipleInstructions_NextOfMiddle) +{ + InstructionList list; + + auto ins1 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins1); + + auto ins2 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins2); + + auto ins3 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins3); + + ASSERT_EQ(ins2->next, ins3.get()); +} + +TEST(InstructionListTest, AddMultipleInstructions_PreviousOfLast) +{ + InstructionList list; + + auto ins1 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins1); + + auto ins2 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins2); + + auto ins3 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins3); + + ASSERT_EQ(ins3->previous, ins2.get()); +} + +TEST(InstructionListTest, AddMultipleInstructions_NextOfLast) +{ + InstructionList list; + + auto ins1 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins1); + + auto ins2 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins2); + + auto ins3 = std::make_shared(TInstruction::Type::FunctionCall, false); + list.addInstruction(ins3); + + ASSERT_EQ(ins3->next, nullptr); +} diff --git a/test/llvm/CMakeLists.txt b/test/llvm/CMakeLists.txt index 96e8c6897..b435c092b 100644 --- a/test/llvm/CMakeLists.txt +++ b/test/llvm/CMakeLists.txt @@ -18,7 +18,6 @@ add_executable( main.cpp llvmexecutioncontext_test.cpp llvmexecutablecode_test.cpp - llvminstructionlist_test.cpp code_analyzer/variable_type_analysis.cpp code_analyzer/list_type_analysis.cpp code_analyzer/mixed_type_analysis.cpp diff --git a/test/llvm/llvminstructionlist_test.cpp b/test/llvm/llvminstructionlist_test.cpp deleted file mode 100644 index 6d9741541..000000000 --- a/test/llvm/llvminstructionlist_test.cpp +++ /dev/null @@ -1,366 +0,0 @@ -#include -#include -#include -#include - -using namespace libscratchcpp; - -TEST(LLVMInstructionListTest, EmptyList_First) -{ - LLVMInstructionList list; - ASSERT_EQ(list.first(), nullptr); -} - -TEST(LLVMInstructionListTest, EmptyList_Last) -{ - LLVMInstructionList list; - ASSERT_EQ(list.last(), nullptr); -} - -TEST(LLVMInstructionListTest, EmptyList_Empty) -{ - LLVMInstructionList list; - ASSERT_TRUE(list.empty()); -} - -TEST(LLVMInstructionListTest, EmptyList_ContainsNull) -{ - LLVMInstructionList list; - ASSERT_FALSE(list.containsInstruction(nullptr)); -} - -TEST(LLVMInstructionListTest, EmptyList_ContainsFunc) -{ - LLVMInstructionList list; - auto ins = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - ASSERT_FALSE(list.containsInstruction([](const LLVMInstruction *) { return true; })); -} - -TEST(LLVMInstructionListTest, EmptyList_Contains) -{ - LLVMInstructionList list; - auto ins = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - ASSERT_FALSE(list.containsInstruction(ins.get())); -} - -TEST(LLVMInstructionListTest, SingleInstructionList_ContainsExistent) -{ - LLVMInstructionList list; - - auto ins1 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins1); - - ASSERT_TRUE(list.containsInstruction(ins1.get())); -} - -TEST(LLVMInstructionListTest, SingleInstructionList_ContainsNonExistent) -{ - LLVMInstructionList list; - - auto ins1 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins1); - - auto ins = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - ASSERT_FALSE(list.containsInstruction(ins.get())); -} - -TEST(LLVMInstructionListTest, SingleInstructionList_ContainsNull) -{ - LLVMInstructionList list; - - auto ins1 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins1); - - ASSERT_FALSE(list.containsInstruction(nullptr)); -} - -TEST(LLVMInstructionListTest, SingleInstructionList_ContainsFuncTrue) -{ - LLVMInstructionList list; - - auto ins1 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins1); - - ASSERT_TRUE(list.containsInstruction([](const LLVMInstruction *) { return true; })); -} - -TEST(LLVMInstructionListTest, SingleInstructionList_ContainsFuncFalse) -{ - LLVMInstructionList list; - - auto ins1 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins1); - - auto ins = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - ASSERT_FALSE(list.containsInstruction([](const LLVMInstruction *) { return false; })); -} - -TEST(LLVMInstructionListTest, MultipleInstructionList_ContainsExistent) -{ - LLVMInstructionList list; - - auto ins1 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins1); - - auto ins2 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins2); - - auto ins3 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins3); - - ASSERT_TRUE(list.containsInstruction(ins2.get())); -} - -TEST(LLVMInstructionListTest, MultipleInstructionList_ContainsNonExistent) -{ - LLVMInstructionList list; - - auto ins1 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins1); - - auto ins2 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins2); - - auto ins3 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins3); - - auto ins = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - ASSERT_FALSE(list.containsInstruction(ins.get())); -} - -TEST(LLVMInstructionListTest, MultipleInstructionList_ContainsNull) -{ - LLVMInstructionList list; - - auto ins1 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins1); - - auto ins2 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins2); - - auto ins3 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins3); - - ASSERT_FALSE(list.containsInstruction(nullptr)); -} - -TEST(LLVMInstructionListTest, MultipleInstructionList_ContainsExistentFunc) -{ - LLVMInstructionList list; - - auto ins1 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins1); - - auto ins2 = std::make_shared(LLVMInstruction::Type::Stop, false); - list.addInstruction(ins2); - - auto ins3 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins3); - - ASSERT_TRUE(list.containsInstruction([](const LLVMInstruction *ins) { return ins->type == LLVMInstruction::Type::Stop; })); -} - -TEST(LLVMInstructionListTest, MultipleInstructionList_ContainsNonExistentFunc) -{ - LLVMInstructionList list; - - auto ins1 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins1); - - auto ins2 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins2); - - auto ins3 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins3); - - ASSERT_FALSE(list.containsInstruction([](const LLVMInstruction *ins) { return ins->type == LLVMInstruction::Type::Stop; })); -} - -TEST(LLVMInstructionListTest, AddSingleInstruction_First) -{ - LLVMInstructionList list; - auto ins = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins); - - ASSERT_EQ(list.first(), ins.get()); -} - -TEST(LLVMInstructionListTest, AddSingleInstruction_Last) -{ - LLVMInstructionList list; - auto ins = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins); - - ASSERT_EQ(list.last(), ins.get()); -} - -TEST(LLVMInstructionListTest, AddSingleInstruction_Empty) -{ - LLVMInstructionList list; - auto ins = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins); - - ASSERT_FALSE(list.empty()); -} - -TEST(LLVMInstructionListTest, AddSingleInstruction_Previous) -{ - LLVMInstructionList list; - auto ins = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins); - - ASSERT_EQ(ins->previous, nullptr); -} - -TEST(LLVMInstructionListTest, AddSingleInstruction_Next) -{ - LLVMInstructionList list; - auto ins = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins); - - ASSERT_EQ(ins->next, nullptr); -} - -TEST(LLVMInstructionListTest, AddMultipleInstructions_First) -{ - LLVMInstructionList list; - - auto ins1 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins1); - - auto ins2 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins2); - - auto ins3 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins3); - - ASSERT_EQ(list.first(), ins1.get()); -} - -TEST(LLVMInstructionListTest, AddMultipleInstructions_Last) -{ - LLVMInstructionList list; - - auto ins1 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins1); - - auto ins2 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins2); - - auto ins3 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins3); - - ASSERT_EQ(list.last(), ins3.get()); -} - -TEST(LLVMInstructionListTest, AddMultipleInstructions_Empty) -{ - LLVMInstructionList list; - - auto ins1 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins1); - - auto ins2 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins2); - - auto ins3 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins3); - - ASSERT_FALSE(list.empty()); -} - -TEST(LLVMInstructionListTest, AddMultipleInstructions_PreviousOfFirst) -{ - LLVMInstructionList list; - - auto ins1 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins1); - - auto ins2 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins2); - - auto ins3 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins3); - - ASSERT_EQ(ins1->previous, nullptr); -} - -TEST(LLVMInstructionListTest, AddMultipleInstructions_NextOfFirst) -{ - LLVMInstructionList list; - - auto ins1 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins1); - - auto ins2 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins2); - - auto ins3 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins3); - - ASSERT_EQ(ins1->next, ins2.get()); -} - -TEST(LLVMInstructionListTest, AddMultipleInstructions_PreviousOfMiddle) -{ - LLVMInstructionList list; - - auto ins1 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins1); - - auto ins2 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins2); - - auto ins3 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins3); - - ASSERT_EQ(ins2->previous, ins1.get()); -} - -TEST(LLVMInstructionListTest, AddMultipleInstructions_NextOfMiddle) -{ - LLVMInstructionList list; - - auto ins1 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins1); - - auto ins2 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins2); - - auto ins3 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins3); - - ASSERT_EQ(ins2->next, ins3.get()); -} - -TEST(LLVMInstructionListTest, AddMultipleInstructions_PreviousOfLast) -{ - LLVMInstructionList list; - - auto ins1 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins1); - - auto ins2 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins2); - - auto ins3 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins3); - - ASSERT_EQ(ins3->previous, ins2.get()); -} - -TEST(LLVMInstructionListTest, AddMultipleInstructions_NextOfLast) -{ - LLVMInstructionList list; - - auto ins1 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins1); - - auto ins2 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins2); - - auto ins3 = std::make_shared(LLVMInstruction::Type::FunctionCall, false); - list.addInstruction(ins3); - - ASSERT_EQ(ins3->next, nullptr); -} From 26a8a2ba5e606e080a6c973c907001234fc05739 Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Fri, 23 Oct 2026 09:37:43 +0200 Subject: [PATCH 04/13] Add base classes for generic codegen classes --- src/engine/internal/codegen/CMakeLists.txt | 3 + src/engine/internal/codegen/instruction.h | 100 ++-------------- src/engine/internal/codegen/instructionbase.h | 107 ++++++++++++++++++ src/engine/internal/codegen/instructionlist.h | 66 ++--------- .../internal/codegen/instructionlistbase.cpp | 50 ++++++++ .../internal/codegen/instructionlistbase.h | 37 ++++++ .../codegen/llvm/instructions/comparison.cpp | 10 +- .../codegen/llvm/instructions/control.cpp | 30 ++--- .../codegen/llvm/instructions/functions.cpp | 2 +- .../codegen/llvm/instructions/lists.cpp | 26 ++--- .../codegen/llvm/instructions/logic.cpp | 6 +- .../codegen/llvm/instructions/math.cpp | 44 +++---- .../codegen/llvm/instructions/procedures.cpp | 4 +- .../codegen/llvm/instructions/string.cpp | 6 +- .../codegen/llvm/instructions/variables.cpp | 10 +- .../codegen/llvm/llvmcodeanalyzer.cpp | 2 +- 16 files changed, 282 insertions(+), 221 deletions(-) create mode 100644 src/engine/internal/codegen/instructionbase.h create mode 100644 src/engine/internal/codegen/instructionlistbase.cpp create mode 100644 src/engine/internal/codegen/instructionlistbase.h diff --git a/src/engine/internal/codegen/CMakeLists.txt b/src/engine/internal/codegen/CMakeLists.txt index 39b4b6caa..d73063fc1 100644 --- a/src/engine/internal/codegen/CMakeLists.txt +++ b/src/engine/internal/codegen/CMakeLists.txt @@ -4,7 +4,10 @@ target_sources(scratchcpp icodebuilderfactory.h codebuilderfactory.cpp codebuilderfactory.h + instructionbase.h instruction.h + instructionlistbase.cpp + instructionlistbase.h instructionlist.h ) diff --git a/src/engine/internal/codegen/instruction.h b/src/engine/internal/codegen/instruction.h index b674934d3..382a996c5 100644 --- a/src/engine/internal/codegen/instruction.h +++ b/src/engine/internal/codegen/instruction.h @@ -2,109 +2,23 @@ #pragma once -#include +#include "instructionbase.h" namespace libscratchcpp { -class BlockPrototype; - template -struct Instruction +struct Instruction : public InstructionBase { - enum class Type - { - FunctionCall, - Add, - Sub, - Mul, - Div, - Random, - RandomInt, - CmpEQ, - CmpGT, - CmpLT, - StrCmpEQCS, // case sensitive - StrCmpEQCI, // case insensitive - And, - Or, - Not, - Mod, - Round, - Abs, - Floor, - Ceil, - Sqrt, - Sin, - Cos, - Tan, - Asin, - Acos, - Atan, - Ln, - Log10, - Exp, - Exp10, - StringConcat, - StringChar, - StringLength, - Select, - CreateLocalVariable, - WriteLocalVariable, - ReadLocalVariable, - WriteVariable, - ReadVariable, - ClearList, - RemoveListItem, - AppendToList, - InsertToList, - ListReplace, - GetListContents, - GetListItem, - GetListSize, - GetListItemIndex, - ListContainsItem, - Yield, - BeginIf, - BeginElse, - EndIf, - BeginRepeatLoop, - LoopIndex, - BeginWhileLoop, - BeginRepeatUntilLoop, - BeginLoopCondition, - EndLoop, - Stop, - ThreadStop, - InvalidateTarget, - CallProcedure, - ProcedureArg, - Print - }; + using Type = InstructionBase::Type; + using InstructionBase::InstructionBase; // inherit constructor + + inline TInstruction *getPrevious() { return static_cast(previous); } - Instruction(Type type, bool loopCondition) : - type(type), - loopCondition(loopCondition) - { - } + inline TInstruction *getNext() { return static_cast(next); } - Type type; - std::string functionName; std::vector> args; // target type, register TRegister *functionReturnReg = nullptr; - bool functionTargetArg = false; // whether to add target ptr to function parameters - bool functionCtxArg = false; // whether to add execution context ptr to function parameters - Variable *targetVariable = nullptr; // for variables - List *targetList = nullptr; // for lists - Compiler::StaticType targetType = Compiler::StaticType::Unknown; // variable or list type (before read/write operation) - BlockPrototype *procedurePrototype = nullptr; - size_t procedureArgIndex = 0; - bool loopCondition = false; // whether the instruction is part of a loop condition - - // Linked list - TInstruction *previous = nullptr; - TInstruction *next = nullptr; - std::shared_ptr _next; // ensure items are not deleted }; } // namespace libscratchcpp diff --git a/src/engine/internal/codegen/instructionbase.h b/src/engine/internal/codegen/instructionbase.h new file mode 100644 index 000000000..dfeb6aab1 --- /dev/null +++ b/src/engine/internal/codegen/instructionbase.h @@ -0,0 +1,107 @@ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include + +namespace libscratchcpp +{ + +class BlockPrototype; + +struct InstructionBase +{ + enum class Type + { + FunctionCall, + Add, + Sub, + Mul, + Div, + Random, + RandomInt, + CmpEQ, + CmpGT, + CmpLT, + StrCmpEQCS, // case sensitive + StrCmpEQCI, // case insensitive + And, + Or, + Not, + Mod, + Round, + Abs, + Floor, + Ceil, + Sqrt, + Sin, + Cos, + Tan, + Asin, + Acos, + Atan, + Ln, + Log10, + Exp, + Exp10, + StringConcat, + StringChar, + StringLength, + Select, + CreateLocalVariable, + WriteLocalVariable, + ReadLocalVariable, + WriteVariable, + ReadVariable, + ClearList, + RemoveListItem, + AppendToList, + InsertToList, + ListReplace, + GetListContents, + GetListItem, + GetListSize, + GetListItemIndex, + ListContainsItem, + Yield, + BeginIf, + BeginElse, + EndIf, + BeginRepeatLoop, + LoopIndex, + BeginWhileLoop, + BeginRepeatUntilLoop, + BeginLoopCondition, + EndLoop, + Stop, + ThreadStop, + InvalidateTarget, + CallProcedure, + ProcedureArg, + Print + }; + + InstructionBase(Type type, bool loopCondition) : + type(type), + loopCondition(loopCondition) + { + } + + Type type; + std::string functionName; + bool functionTargetArg = false; // whether to add target ptr to function parameters + bool functionCtxArg = false; // whether to add execution context ptr to function parameters + Variable *targetVariable = nullptr; // for variables + List *targetList = nullptr; // for lists + Compiler::StaticType targetType = Compiler::StaticType::Unknown; // variable or list type (before read/write operation) + BlockPrototype *procedurePrototype = nullptr; + size_t procedureArgIndex = 0; + bool loopCondition = false; // whether the instruction is part of a loop condition + + // Linked list + InstructionBase *previous = nullptr; + InstructionBase *next = nullptr; + std::shared_ptr _next; // ensure items are not deleted +}; + +} // namespace libscratchcpp diff --git a/src/engine/internal/codegen/instructionlist.h b/src/engine/internal/codegen/instructionlist.h index 5f0e5eb9a..d52beb37f 100644 --- a/src/engine/internal/codegen/instructionlist.h +++ b/src/engine/internal/codegen/instructionlist.h @@ -2,77 +2,27 @@ #pragma once -#include -#include - -#include "test_export.h" +#include "instructionlistbase.h" namespace libscratchcpp { template -class LIBSCRATCHCPP_TEST_EXPORT InstructionList +class InstructionList : public InstructionListBase { public: - InstructionList() = default; - InstructionList(const InstructionList &) = delete; - - inline TInstruction *first() const { return m_first.get(); } - - inline TInstruction *last() const { return m_last.get(); } - - inline bool empty() const { return !first(); } - - inline bool containsInstruction(TInstruction *ins) const - { - TInstruction *ptr = m_first.get(); - - while (ptr) { - if (ptr == ins) - return true; - - ptr = ptr->next; - } + inline TInstruction *first() const { return static_cast(InstructionListBase::first()); } - return false; - } - - inline bool containsInstruction(std::function func) const - { - TInstruction *ptr = m_first.get(); - - while (ptr) { - if (func(ptr)) - return true; + inline TInstruction *last() const { return static_cast(InstructionListBase::last()); } - ptr = ptr->next; - } + bool containsInstruction(InstructionBase *ins) const { return InstructionListBase::containsInstruction(ins); } - return false; - } - - inline void addInstruction(std::shared_ptr ins) + bool containsInstruction(std::function func) const { - if (!(m_first && m_last)) { - assert(!m_first && !m_last); - - m_first = ins; - m_last = ins; - - ins->previous = nullptr; - ins->next = nullptr; - ins->_next = nullptr; - } else { - m_last->next = ins.get(); - m_last->_next = ins; - ins->previous = m_last.get(); - m_last = ins; - } + return InstructionListBase::containsInstruction([&](const InstructionBase *i) { return func(static_cast(i)); }); } - private: - std::shared_ptr m_first; - std::shared_ptr m_last; + void addInstruction(std::shared_ptr ins) { return InstructionListBase::addInstruction(std::move(ins)); } }; } // namespace libscratchcpp diff --git a/src/engine/internal/codegen/instructionlistbase.cpp b/src/engine/internal/codegen/instructionlistbase.cpp new file mode 100644 index 000000000..3bc402bda --- /dev/null +++ b/src/engine/internal/codegen/instructionlistbase.cpp @@ -0,0 +1,50 @@ +#include "instructionlistbase.h" + +using namespace libscratchcpp; + +bool InstructionListBase::containsInstruction(InstructionBase *ins) const +{ + InstructionBase *ptr = m_first.get(); + + while (ptr) { + if (ptr == ins) + return true; + + ptr = ptr->next; + } + + return false; +} + +bool InstructionListBase::containsInstruction(std::function func) const +{ + InstructionBase *ptr = m_first.get(); + + while (ptr) { + if (func(ptr)) + return true; + + ptr = ptr->next; + } + + return false; +} + +void InstructionListBase::addInstruction(std::shared_ptr ins) +{ + if (!(m_first && m_last)) { + assert(!m_first && !m_last); + + m_first = ins; + m_last = ins; + + ins->previous = nullptr; + ins->next = nullptr; + ins->_next = nullptr; + } else { + m_last->next = ins.get(); + m_last->_next = ins; + ins->previous = m_last.get(); + m_last = ins; + } +} diff --git a/src/engine/internal/codegen/instructionlistbase.h b/src/engine/internal/codegen/instructionlistbase.h new file mode 100644 index 000000000..069582e67 --- /dev/null +++ b/src/engine/internal/codegen/instructionlistbase.h @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include +#include + +#include "test_export.h" +#include "instructionbase.h" + +namespace libscratchcpp +{ + +class LIBSCRATCHCPP_TEST_EXPORT InstructionListBase +{ + public: + InstructionListBase() = default; + InstructionListBase(const InstructionListBase &) = delete; + + inline InstructionBase *first() const { return m_first.get(); } + + inline InstructionBase *last() const { return m_last.get(); } + + inline bool empty() const { return !first(); } + + bool containsInstruction(InstructionBase *ins) const; + + bool containsInstruction(std::function func) const; + + void addInstruction(std::shared_ptr ins); + + private: + std::shared_ptr m_first; + std::shared_ptr m_last; +}; + +} // namespace libscratchcpp diff --git a/src/engine/internal/codegen/llvm/instructions/comparison.cpp b/src/engine/internal/codegen/llvm/instructions/comparison.cpp index 9a76ce24c..5f5353778 100644 --- a/src/engine/internal/codegen/llvm/instructions/comparison.cpp +++ b/src/engine/internal/codegen/llvm/instructions/comparison.cpp @@ -47,7 +47,7 @@ LLVMInstruction *Comparison::buildCmpEQ(LLVMInstruction *ins) const auto &arg2 = ins->args[1].second; ins->functionReturnReg->value = m_utils.createComparison(arg1, arg2, LLVMBuildUtils::Comparison::EQ); - return ins->next; + return ins->getNext(); } LLVMInstruction *Comparison::buildCmpGT(LLVMInstruction *ins) @@ -57,7 +57,7 @@ LLVMInstruction *Comparison::buildCmpGT(LLVMInstruction *ins) const auto &arg2 = ins->args[1].second; ins->functionReturnReg->value = m_utils.createComparison(arg1, arg2, LLVMBuildUtils::Comparison::GT); - return ins->next; + return ins->getNext(); } LLVMInstruction *Comparison::buildCmpLT(LLVMInstruction *ins) @@ -67,7 +67,7 @@ LLVMInstruction *Comparison::buildCmpLT(LLVMInstruction *ins) const auto &arg2 = ins->args[1].second; ins->functionReturnReg->value = m_utils.createComparison(arg1, arg2, LLVMBuildUtils::Comparison::LT); - return ins->next; + return ins->getNext(); } LLVMInstruction *Comparison::buildStrCmpEQCS(LLVMInstruction *ins) @@ -77,7 +77,7 @@ LLVMInstruction *Comparison::buildStrCmpEQCS(LLVMInstruction *ins) const auto &arg2 = ins->args[1].second; ins->functionReturnReg->value = m_utils.createStringComparison(arg1, arg2, true); - return ins->next; + return ins->getNext(); } LLVMInstruction *Comparison::buildStrCmpEQCI(LLVMInstruction *ins) @@ -87,5 +87,5 @@ LLVMInstruction *Comparison::buildStrCmpEQCI(LLVMInstruction *ins) const auto &arg2 = ins->args[1].second; ins->functionReturnReg->value = m_utils.createStringComparison(arg1, arg2, false); - return ins->next; + return ins->getNext(); } diff --git a/src/engine/internal/codegen/llvm/instructions/control.cpp b/src/engine/internal/codegen/llvm/instructions/control.cpp index 3c9207a55..b361a3618 100644 --- a/src/engine/internal/codegen/llvm/instructions/control.cpp +++ b/src/engine/internal/codegen/llvm/instructions/control.cpp @@ -102,13 +102,13 @@ LLVMInstruction *Control::buildSelect(LLVMInstruction *ins) ins->functionReturnReg->value = m_builder.CreateSelect(cond, trueValue, falseValue); ins->functionReturnReg->isInt = m_builder.CreateSelect(cond, arg2.second->isInt, arg3.second->isInt); ins->functionReturnReg->intValue = m_builder.CreateSelect(cond, arg2.second->intValue, arg3.second->intValue); - return ins->next; + return ins->getNext(); } LLVMInstruction *Control::buildYield(LLVMInstruction *ins) { m_utils.createSuspend(); - return ins->next; + return ins->getNext(); } LLVMInstruction *Control::buildBeginIf(LLVMInstruction *ins) @@ -128,7 +128,7 @@ LLVMInstruction *Control::buildBeginIf(LLVMInstruction *ins) m_utils.ifStatements().push_back(statement); - return ins->next; + return ins->getNext(); } LLVMInstruction *Control::buildBeginElse(LLVMInstruction *ins) @@ -155,7 +155,7 @@ LLVMInstruction *Control::buildBeginElse(LLVMInstruction *ins) // Switch to the else branch m_builder.SetInsertPoint(statement.elseBranch); - return ins->next; + return ins->getNext(); } LLVMInstruction *Control::buildEndIf(LLVMInstruction *ins) @@ -182,7 +182,7 @@ LLVMInstruction *Control::buildEndIf(LLVMInstruction *ins) ifStatements.pop_back(); - return ins->next; + return ins->getNext(); } LLVMInstruction *Control::buildBeginRepeatLoop(LLVMInstruction *ins) @@ -241,7 +241,7 @@ LLVMInstruction *Control::buildBeginRepeatLoop(LLVMInstruction *ins) m_utils.loops().push_back(loop); - return ins->next; + return ins->getNext(); } LLVMInstruction *Control::buildLoopIndex(LLVMInstruction *ins) @@ -253,7 +253,7 @@ LLVMInstruction *Control::buildLoopIndex(LLVMInstruction *ins) ins->functionReturnReg->intValue = index; ins->functionReturnReg->isInt = m_builder.getInt1(true); - return ins->next; + return ins->getNext(); } LLVMInstruction *Control::buildBeginWhileLoop(LLVMInstruction *ins) @@ -278,7 +278,7 @@ LLVMInstruction *Control::buildBeginWhileLoop(LLVMInstruction *ins) // Switch to body branch m_builder.SetInsertPoint(body); - return ins->next; + return ins->getNext(); } LLVMInstruction *Control::buildBeginRepeatUntilLoop(LLVMInstruction *ins) @@ -303,7 +303,7 @@ LLVMInstruction *Control::buildBeginRepeatUntilLoop(LLVMInstruction *ins) // Switch to body branch m_builder.SetInsertPoint(body); - return ins->next; + return ins->getNext(); } LLVMInstruction *Control::buildBeginLoopCondition(LLVMInstruction *ins) @@ -315,7 +315,7 @@ LLVMInstruction *Control::buildBeginLoopCondition(LLVMInstruction *ins) m_builder.SetInsertPoint(loop.conditionBranch); m_utils.loops().push_back(loop); - return ins->next; + return ins->getNext(); } LLVMInstruction *Control::buildEndLoop(LLVMInstruction *ins) @@ -339,7 +339,7 @@ LLVMInstruction *Control::buildEndLoop(LLVMInstruction *ins) loops.pop_back(); - return ins->next; + return ins->getNext(); } LLVMInstruction *Control::buildStop(LLVMInstruction *ins) @@ -350,7 +350,7 @@ LLVMInstruction *Control::buildStop(LLVMInstruction *ins) llvm::BasicBlock *nextBranch = llvm::BasicBlock::Create(m_utils.llvmCtx(), "", m_utils.function()); m_builder.SetInsertPoint(nextBranch); - return ins->next; + return ins->getNext(); } LLVMInstruction *Control::buildThreadStop(LLVMInstruction *ins) @@ -361,13 +361,13 @@ LLVMInstruction *Control::buildThreadStop(LLVMInstruction *ins) llvm::BasicBlock *nextBranch = llvm::BasicBlock::Create(m_utils.llvmCtx(), "", m_utils.function()); m_builder.SetInsertPoint(nextBranch); - return ins->next; + return ins->getNext(); } LLVMInstruction *Control::buildInvalidateTarget(LLVMInstruction *ins) { m_utils.invalidateTarget(); - return ins->next; + return ins->getNext(); } LLVMInstruction *Control::buildPrint(LLVMInstruction *ins) @@ -378,5 +378,5 @@ LLVMInstruction *Control::buildPrint(LLVMInstruction *ins) llvm::Value *str = m_utils.castValue(arg.second, arg.first); m_builder.CreateCall(m_utils.functions().resolve_llvm_print(), str); - return ins->next; + return ins->getNext(); } diff --git a/src/engine/internal/codegen/llvm/instructions/functions.cpp b/src/engine/internal/codegen/llvm/instructions/functions.cpp index 50a37550f..b73544db7 100644 --- a/src/engine/internal/codegen/llvm/instructions/functions.cpp +++ b/src/engine/internal/codegen/llvm/instructions/functions.cpp @@ -73,5 +73,5 @@ LLVMInstruction *Functions::buildFunctionCall(LLVMInstruction *ins) } } - return ins->next; + return ins->getNext(); } diff --git a/src/engine/internal/codegen/llvm/instructions/lists.cpp b/src/engine/internal/codegen/llvm/instructions/lists.cpp index 77efbee55..91386f8dd 100644 --- a/src/engine/internal/codegen/llvm/instructions/lists.cpp +++ b/src/engine/internal/codegen/llvm/instructions/lists.cpp @@ -82,14 +82,14 @@ LLVMInstruction *Lists::buildClearList(LLVMInstruction *ins) } } - return ins->next; + return ins->getNext(); } LLVMInstruction *Lists::buildRemoveListItem(LLVMInstruction *ins) { // No-op in empty lists if (ins->targetType == Compiler::StaticType::Void) - return ins->next; + return ins->getNext(); llvm::LLVMContext &llvmCtx = m_utils.llvmCtx(); llvm::Function *function = m_utils.function(); @@ -121,7 +121,7 @@ LLVMInstruction *Lists::buildRemoveListItem(LLVMInstruction *ins) m_builder.CreateBr(nextBlock); m_builder.SetInsertPoint(nextBlock); - return ins->next; + return ins->getNext(); } LLVMInstruction *Lists::buildAppendToList(LLVMInstruction *ins) @@ -170,7 +170,7 @@ LLVMInstruction *Lists::buildAppendToList(LLVMInstruction *ins) } createListTypeUpdate(listPtr, arg.second, type); - return ins->next; + return ins->getNext(); } LLVMInstruction *Lists::buildInsertToList(LLVMInstruction *ins) @@ -212,14 +212,14 @@ LLVMInstruction *Lists::buildInsertToList(LLVMInstruction *ins) m_builder.CreateBr(nextBlock); m_builder.SetInsertPoint(nextBlock); - return ins->next; + return ins->getNext(); } LLVMInstruction *Lists::buildListReplace(LLVMInstruction *ins) { // No-op in empty lists if (ins->targetType == Compiler::StaticType::Void) - return ins->next; + return ins->getNext(); llvm::LLVMContext &llvmCtx = m_utils.llvmCtx(); llvm::Function *function = m_utils.function(); @@ -263,7 +263,7 @@ LLVMInstruction *Lists::buildListReplace(LLVMInstruction *ins) m_builder.CreateBr(nextBlock); m_builder.SetInsertPoint(nextBlock); - return ins->next; + return ins->getNext(); } LLVMInstruction *Lists::buildGetListContents(LLVMInstruction *ins) @@ -274,7 +274,7 @@ LLVMInstruction *Lists::buildGetListContents(LLVMInstruction *ins) m_builder.CreateCall(m_utils.functions().resolve_list_to_string(), { listPtr.ptr, ptr }); ins->functionReturnReg->value = ptr; - return ins->next; + return ins->getNext(); } LLVMInstruction *Lists::buildGetListItem(LLVMInstruction *ins) @@ -286,7 +286,7 @@ LLVMInstruction *Lists::buildGetListItem(LLVMInstruction *ins) if (ins->targetType == Compiler::StaticType::Void) { LLVMConstantRegister nullReg(Compiler::StaticType::String, ""); ins->functionReturnReg->value = m_utils.createValue(static_cast(&nullReg)); - return ins->next; + return ins->getNext(); } assert(ins->args.size() == 1); @@ -331,7 +331,7 @@ LLVMInstruction *Lists::buildGetListItem(LLVMInstruction *ins) ins->functionReturnReg->typeVar = typeVar; createListTypeAssumption(listPtr, typeVar, ins->targetType, inRange); - return ins->next; + return ins->getNext(); } LLVMInstruction *Lists::buildGetListSize(LLVMInstruction *ins) @@ -343,7 +343,7 @@ LLVMInstruction *Lists::buildGetListSize(LLVMInstruction *ins) ins->functionReturnReg->isInt = m_builder.getInt1(true); ins->functionReturnReg->intValue = size; - return ins->next; + return ins->getNext(); } LLVMInstruction *Lists::buildGetListItemIndex(LLVMInstruction *ins) @@ -355,7 +355,7 @@ LLVMInstruction *Lists::buildGetListItemIndex(LLVMInstruction *ins) Compiler::StaticType listType = ins->targetType; ins->functionReturnReg->value = m_builder.CreateSIToFP(m_utils.getListItemIndex(listPtr, listType, arg.second), m_builder.getDoubleTy()); - return ins->next; + return ins->getNext(); } LLVMInstruction *Lists::buildListContainsItem(LLVMInstruction *ins) @@ -369,7 +369,7 @@ LLVMInstruction *Lists::buildListContainsItem(LLVMInstruction *ins) llvm::Value *index = m_utils.getListItemIndex(listPtr, listType, arg.second); ins->functionReturnReg->value = m_builder.CreateICmpSGT(index, llvm::ConstantInt::get(m_builder.getInt64Ty(), -1, true)); - return ins->next; + return ins->getNext(); } llvm::Value *Lists::createIndexRangeCheck(const LLVMListPtr &listPtr, llvm::Value *index, const std::string &name, bool includeSize) diff --git a/src/engine/internal/codegen/llvm/instructions/logic.cpp b/src/engine/internal/codegen/llvm/instructions/logic.cpp index e4410286b..9c4f3e7b4 100644 --- a/src/engine/internal/codegen/llvm/instructions/logic.cpp +++ b/src/engine/internal/codegen/llvm/instructions/logic.cpp @@ -42,7 +42,7 @@ LLVMInstruction *Logic::buildAnd(LLVMInstruction *ins) llvm::Value *bool2 = m_utils.castValue(arg2.second, arg2.first); ins->functionReturnReg->value = m_builder.CreateAnd(bool1, bool2); - return ins->next; + return ins->getNext(); } LLVMInstruction *Logic::buildOr(LLVMInstruction *ins) @@ -54,7 +54,7 @@ LLVMInstruction *Logic::buildOr(LLVMInstruction *ins) llvm::Value *bool2 = m_utils.castValue(arg2.second, arg2.first); ins->functionReturnReg->value = m_builder.CreateOr(bool1, bool2); - return ins->next; + return ins->getNext(); } LLVMInstruction *Logic::buildNot(LLVMInstruction *ins) @@ -64,5 +64,5 @@ LLVMInstruction *Logic::buildNot(LLVMInstruction *ins) llvm::Value *value = m_utils.castValue(arg.second, arg.first); ins->functionReturnReg->value = m_builder.CreateNot(value); - return ins->next; + return ins->getNext(); } diff --git a/src/engine/internal/codegen/llvm/instructions/math.cpp b/src/engine/internal/codegen/llvm/instructions/math.cpp index aeb95cc3f..86812a018 100644 --- a/src/engine/internal/codegen/llvm/instructions/math.cpp +++ b/src/engine/internal/codegen/llvm/instructions/math.cpp @@ -123,7 +123,7 @@ LLVMInstruction *Math::buildAdd(LLVMInstruction *ins) ins->functionReturnReg->isInt = m_builder.CreateAnd(arg1.second->isInt, arg2.second->isInt); ins->functionReturnReg->intValue = m_builder.CreateAdd(int1, int2); - return ins->next; + return ins->getNext(); } LLVMInstruction *Math::buildSub(LLVMInstruction *ins) @@ -141,7 +141,7 @@ LLVMInstruction *Math::buildSub(LLVMInstruction *ins) ins->functionReturnReg->isInt = m_builder.CreateAnd(arg1.second->isInt, arg2.second->isInt); ins->functionReturnReg->intValue = m_builder.CreateSub(int1, int2); - return ins->next; + return ins->getNext(); } LLVMInstruction *Math::buildMul(LLVMInstruction *ins) @@ -159,7 +159,7 @@ LLVMInstruction *Math::buildMul(LLVMInstruction *ins) ins->functionReturnReg->isInt = m_builder.CreateAnd(arg1.second->isInt, arg2.second->isInt); ins->functionReturnReg->intValue = m_builder.CreateMul(int1, int2); - return ins->next; + return ins->getNext(); } LLVMInstruction *Math::buildDiv(LLVMInstruction *ins) @@ -171,7 +171,7 @@ LLVMInstruction *Math::buildDiv(LLVMInstruction *ins) llvm::Value *num2 = m_utils.removeNaN(m_utils.castValue(arg2.second, arg2.first)); ins->functionReturnReg->value = m_builder.CreateFDiv(num1, num2); - return ins->next; + return ins->getNext(); } LLVMInstruction *Math::buildRandom(LLVMInstruction *ins) @@ -205,7 +205,7 @@ LLVMInstruction *Math::buildRandom(LLVMInstruction *ins) } } - return ins->next; + return ins->getNext(); } LLVMInstruction *Math::buildRandomInt(LLVMInstruction *ins) @@ -220,7 +220,7 @@ LLVMInstruction *Math::buildRandomInt(LLVMInstruction *ins) ins->functionReturnReg->intValue = intValue; ins->functionReturnReg->isInt = m_builder.getInt1(true); - return ins->next; + return ins->getNext(); } LLVMInstruction *Math::buildMod(LLVMInstruction *ins) @@ -272,7 +272,7 @@ LLVMInstruction *Math::buildMod(LLVMInstruction *ins) ins->functionReturnReg->intValue = resultPhi; ins->functionReturnReg->isInt = isIntPhi; - return ins->next; + return ins->getNext(); } LLVMInstruction *Math::buildRound(LLVMInstruction *ins) @@ -305,7 +305,7 @@ LLVMInstruction *Math::buildRound(LLVMInstruction *ins) ins->functionReturnReg->isInt = isNotInf; ins->functionReturnReg->intValue = m_builder.CreateSelect(isInt, intValue, cast); - return ins->next; + return ins->getNext(); } LLVMInstruction *Math::buildAbs(LLVMInstruction *ins) @@ -322,7 +322,7 @@ LLVMInstruction *Math::buildAbs(LLVMInstruction *ins) ins->functionReturnReg->isInt = arg.second->isInt; ins->functionReturnReg->intValue = m_builder.CreateCall(absFunc, { intValue, m_builder.getInt1(false) }); - return ins->next; + return ins->getNext(); } LLVMInstruction *Math::buildFloor(LLVMInstruction *ins) @@ -345,7 +345,7 @@ LLVMInstruction *Math::buildFloor(LLVMInstruction *ins) ins->functionReturnReg->isInt = isNotInf; ins->functionReturnReg->intValue = m_builder.CreateSelect(isInt, intValue, cast); - return ins->next; + return ins->getNext(); } LLVMInstruction *Math::buildCeil(LLVMInstruction *ins) @@ -368,7 +368,7 @@ LLVMInstruction *Math::buildCeil(LLVMInstruction *ins) ins->functionReturnReg->isInt = isNotInf; ins->functionReturnReg->intValue = m_builder.CreateSelect(isInt, intValue, cast); - return ins->next; + return ins->getNext(); } LLVMInstruction *Math::buildSqrt(LLVMInstruction *ins) @@ -382,7 +382,7 @@ LLVMInstruction *Math::buildSqrt(LLVMInstruction *ins) llvm::Value *num = m_utils.removeNaN(m_utils.castValue(arg.second, arg.first)); ins->functionReturnReg->value = m_builder.CreateFAdd(m_builder.CreateCall(sqrtFunc, num), zero); - return ins->next; + return ins->getNext(); } LLVMInstruction *Math::buildSin(LLVMInstruction *ins) @@ -405,7 +405,7 @@ LLVMInstruction *Math::buildSin(LLVMInstruction *ins) llvm::Value *rounded = m_builder.CreateCall(roundFunc, m_builder.CreateFMul(sinResult, factor)); // round(sin(x * 180) * 1e10) ins->functionReturnReg->value = m_builder.CreateFAdd(m_builder.CreateFDiv(rounded, factor), zero); - return ins->next; + return ins->getNext(); } LLVMInstruction *Math::buildCos(LLVMInstruction *ins) @@ -426,7 +426,7 @@ LLVMInstruction *Math::buildCos(LLVMInstruction *ins) llvm::Value *rounded = m_builder.CreateCall(roundFunc, m_builder.CreateFMul(cosResult, factor)); // round(cos(x * 180) * 1e10) ins->functionReturnReg->value = m_builder.CreateFDiv(rounded, factor); - return ins->next; + return ins->getNext(); } LLVMInstruction *Math::buildTan(LLVMInstruction *ins) @@ -463,7 +463,7 @@ LLVMInstruction *Math::buildTan(LLVMInstruction *ins) llvm::Value *inner = m_builder.CreateSelect(m_builder.CreateOr(isUndefined3, isUndefined4), negInf, result); ins->functionReturnReg->value = m_builder.CreateSelect(m_builder.CreateOr(isUndefined1, isUndefined2), posInf, inner); - return ins->next; + return ins->getNext(); } LLVMInstruction *Math::buildAsin(LLVMInstruction *ins) @@ -481,7 +481,7 @@ LLVMInstruction *Math::buildAsin(LLVMInstruction *ins) llvm::Value *num = m_utils.removeNaN(m_utils.castValue(arg.second, arg.first)); ins->functionReturnReg->value = m_builder.CreateFAdd(m_builder.CreateFDiv(m_builder.CreateFMul(m_builder.CreateCall(asinFunc, num), piDeg), pi), zero); - return ins->next; + return ins->getNext(); } LLVMInstruction *Math::buildAcos(LLVMInstruction *ins) @@ -497,7 +497,7 @@ LLVMInstruction *Math::buildAcos(LLVMInstruction *ins) llvm::Value *num = m_utils.removeNaN(m_utils.castValue(arg.second, arg.first)); ins->functionReturnReg->value = m_builder.CreateFDiv(m_builder.CreateFMul(m_builder.CreateCall(acosFunc, num), piDeg), pi); - return ins->next; + return ins->getNext(); } LLVMInstruction *Math::buildAtan(LLVMInstruction *ins) @@ -513,7 +513,7 @@ LLVMInstruction *Math::buildAtan(LLVMInstruction *ins) llvm::Value *num = m_utils.removeNaN(m_utils.castValue(arg.second, arg.first)); ins->functionReturnReg->value = m_builder.CreateFDiv(m_builder.CreateFMul(m_builder.CreateCall(atanFunc, num), piDeg), pi); - return ins->next; + return ins->getNext(); } LLVMInstruction *Math::buildLn(LLVMInstruction *ins) @@ -525,7 +525,7 @@ LLVMInstruction *Math::buildLn(LLVMInstruction *ins) llvm::Value *num = m_utils.removeNaN(m_utils.castValue(arg.second, arg.first)); ins->functionReturnReg->value = m_builder.CreateCall(logFunc, num); - return ins->next; + return ins->getNext(); } LLVMInstruction *Math::buildLog10(LLVMInstruction *ins) @@ -537,7 +537,7 @@ LLVMInstruction *Math::buildLog10(LLVMInstruction *ins) llvm::Value *num = m_utils.removeNaN(m_utils.castValue(arg.second, arg.first)); ins->functionReturnReg->value = m_builder.CreateCall(log10Func, num); - return ins->next; + return ins->getNext(); } LLVMInstruction *Math::buildExp(LLVMInstruction *ins) @@ -549,7 +549,7 @@ LLVMInstruction *Math::buildExp(LLVMInstruction *ins) llvm::Value *num = m_utils.removeNaN(m_utils.castValue(arg.second, arg.first)); ins->functionReturnReg->value = m_builder.CreateCall(expFunc, num); - return ins->next; + return ins->getNext(); } LLVMInstruction *Math::buildExp10(LLVMInstruction *ins) @@ -561,5 +561,5 @@ LLVMInstruction *Math::buildExp10(LLVMInstruction *ins) llvm::Value *num = m_utils.removeNaN(m_utils.castValue(arg.second, arg.first)); ins->functionReturnReg->value = m_builder.CreateCall(expFunc, num); - return ins->next; + return ins->getNext(); } diff --git a/src/engine/internal/codegen/llvm/instructions/procedures.cpp b/src/engine/internal/codegen/llvm/instructions/procedures.cpp index cac59650a..ed80f7faf 100644 --- a/src/engine/internal/codegen/llvm/instructions/procedures.cpp +++ b/src/engine/internal/codegen/llvm/instructions/procedures.cpp @@ -98,7 +98,7 @@ LLVMInstruction *Procedures::buildCallProcedure(LLVMInstruction *ins) m_utils.reloadVariables(); m_utils.reloadLists(); - return ins->next; + return ins->getNext(); } LLVMInstruction *Procedures::buildProcedureArg(LLVMInstruction *ins) @@ -109,5 +109,5 @@ LLVMInstruction *Procedures::buildProcedureArg(LLVMInstruction *ins) llvm::Value *arg = m_utils.function()->getArg(passArgCount + 1 + ins->procedureArgIndex); // omit warp arg ins->functionReturnReg->value = arg; - return ins->next; + return ins->getNext(); } diff --git a/src/engine/internal/codegen/llvm/instructions/string.cpp b/src/engine/internal/codegen/llvm/instructions/string.cpp index 77120976a..ba8cc331c 100644 --- a/src/engine/internal/codegen/llvm/instructions/string.cpp +++ b/src/engine/internal/codegen/llvm/instructions/string.cpp @@ -75,7 +75,7 @@ LLVMInstruction *String::buildStringConcat(LLVMInstruction *ins) ins->functionReturnReg->value = result; - return ins->next; + return ins->getNext(); } LLVMInstruction *String::buildStringChar(LLVMInstruction *ins) @@ -116,7 +116,7 @@ LLVMInstruction *String::buildStringChar(LLVMInstruction *ins) ins->functionReturnReg->value = result; - return ins->next; + return ins->getNext(); } LLVMInstruction *String::buildStringLength(LLVMInstruction *ins) @@ -132,5 +132,5 @@ LLVMInstruction *String::buildStringLength(LLVMInstruction *ins) ins->functionReturnReg->intValue = size; ins->functionReturnReg->isInt = m_builder.getInt1(true); - return ins->next; + return ins->getNext(); } diff --git a/src/engine/internal/codegen/llvm/instructions/variables.cpp b/src/engine/internal/codegen/llvm/instructions/variables.cpp index 6eec5cf7c..0d6ce25a5 100644 --- a/src/engine/internal/codegen/llvm/instructions/variables.cpp +++ b/src/engine/internal/codegen/llvm/instructions/variables.cpp @@ -53,7 +53,7 @@ LLVMInstruction *Variables::buildCreateLocalVariable(LLVMInstruction *ins) LLVMConstantRegister null(ins->functionReturnReg->type(), Value()); ins->functionReturnReg->value = m_utils.createValue(&null); - return ins->next; + return ins->getNext(); } LLVMInstruction *Variables::buildWriteLocalVariable(LLVMInstruction *ins) @@ -66,7 +66,7 @@ LLVMInstruction *Variables::buildWriteLocalVariable(LLVMInstruction *ins) m_builder.CreateStore(m_builder.getInt32(static_cast(m_utils.mapType(arg2.first))), typeVar); m_utils.createValueStore(arg1.second->value, typeVar, info->isInt, info->intValue, arg2.second, arg2.first, arg2.first); - return ins->next; + return ins->getNext(); } LLVMInstruction *Variables::buildReadLocalVariable(LLVMInstruction *ins) @@ -77,7 +77,7 @@ LLVMInstruction *Variables::buildReadLocalVariable(LLVMInstruction *ins) ins->functionReturnReg->value = m_utils.castValue(arg.second, ins->functionReturnReg->type()); ins->functionReturnReg->isInt = m_builder.CreateLoad(m_builder.getInt1Ty(), info->isInt); ins->functionReturnReg->intValue = m_builder.CreateLoad(m_builder.getInt64Ty(), info->intValue); - return ins->next; + return ins->getNext(); } LLVMInstruction *Variables::buildWriteVariable(LLVMInstruction *ins) @@ -89,7 +89,7 @@ LLVMInstruction *Variables::buildWriteVariable(LLVMInstruction *ins) m_utils.createValueStore(varPtr.stackPtr, m_utils.getValueTypePtr(varPtr.stackPtr), varPtr.isInt, varPtr.intValue, arg.second, ins->targetType, argType); m_builder.CreateStore(m_builder.getInt1(true), varPtr.changed); - return ins->next; + return ins->getNext(); } LLVMInstruction *Variables::buildReadVariable(LLVMInstruction *ins) @@ -100,5 +100,5 @@ LLVMInstruction *Variables::buildReadVariable(LLVMInstruction *ins) ins->functionReturnReg->value = varPtr.stackPtr; ins->functionReturnReg->isInt = m_builder.CreateLoad(m_builder.getInt1Ty(), varPtr.isInt); ins->functionReturnReg->intValue = m_builder.CreateLoad(m_builder.getInt64Ty(), varPtr.intValue); - return ins->next; + return ins->getNext(); } diff --git a/src/engine/internal/codegen/llvm/llvmcodeanalyzer.cpp b/src/engine/internal/codegen/llvm/llvmcodeanalyzer.cpp index 1e594d75d..c917e1165 100644 --- a/src/engine/internal/codegen/llvm/llvmcodeanalyzer.cpp +++ b/src/engine/internal/codegen/llvm/llvmcodeanalyzer.cpp @@ -148,7 +148,7 @@ void LLVMCodeAnalyzer::analyzeScript(const LLVMInstructionList &script) const typeAssignedInstructions.insert(ins); } - ins = ins->next; + ins = ins->getNext(); } assert(branches.size() == 1); From 553b3097b67e3c6a701a883aa83fc056bd146e87 Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Fri, 23 Oct 2026 11:25:46 +0200 Subject: [PATCH 05/13] Add unsafeConstants parameter to CompileContext --- include/scratchcpp/compilercontext.h | 4 +++- src/engine/compilercontext.cpp | 4 ++-- src/engine/compilercontext_p.cpp | 5 +++-- src/engine/compilercontext_p.h | 6 +++++- src/engine/internal/codegen/codebuilderfactory.cpp | 4 ++-- src/engine/internal/codegen/codebuilderfactory.h | 2 +- src/engine/internal/codegen/icodebuilderfactory.h | 2 +- src/engine/internal/codegen/llvm/llvmcompilercontext.cpp | 4 ++-- src/engine/internal/codegen/llvm/llvmcompilercontext.h | 2 +- test/compiler/compiler_test.cpp | 4 ++-- test/mocks/codebuilderfactorymock.h | 2 +- 11 files changed, 23 insertions(+), 16 deletions(-) diff --git a/include/scratchcpp/compilercontext.h b/include/scratchcpp/compilercontext.h index 1b3351995..aed59175b 100644 --- a/include/scratchcpp/compilercontext.h +++ b/include/scratchcpp/compilercontext.h @@ -2,6 +2,8 @@ #pragma once +#include + #include "global.h" #include "spimpl.h" @@ -16,7 +18,7 @@ class CompilerContextPrivate; class LIBSCRATCHCPP_EXPORT CompilerContext { public: - CompilerContext(IEngine *engine, Target *target); + CompilerContext(IEngine *engine, Target *target, const std::unordered_set &unsafeConstants = {}); CompilerContext(const CompilerContext &) = delete; virtual ~CompilerContext() { } diff --git a/src/engine/compilercontext.cpp b/src/engine/compilercontext.cpp index fa78ad57a..ee96b26a7 100644 --- a/src/engine/compilercontext.cpp +++ b/src/engine/compilercontext.cpp @@ -7,8 +7,8 @@ using namespace libscratchcpp; /*! Constructs CompilerContext. */ -CompilerContext::CompilerContext(IEngine *engine, Target *target) : - impl(spimpl::make_unique_impl(engine, target)) +CompilerContext::CompilerContext(IEngine *engine, Target *target, const std::unordered_set &unsafeConstants) : + impl(spimpl::make_unique_impl(engine, target, unsafeConstants)) { } diff --git a/src/engine/compilercontext_p.cpp b/src/engine/compilercontext_p.cpp index 5f4c42f25..181470d59 100644 --- a/src/engine/compilercontext_p.cpp +++ b/src/engine/compilercontext_p.cpp @@ -4,8 +4,9 @@ using namespace libscratchcpp; -CompilerContextPrivate::CompilerContextPrivate(IEngine *engine, Target *target) : +CompilerContextPrivate::CompilerContextPrivate(IEngine *engine, Target *target, const std::unordered_set &unsafeConstants) : engine(engine), - target(target) + target(target), + unsafeConstants(unsafeConstants) { } diff --git a/src/engine/compilercontext_p.h b/src/engine/compilercontext_p.h index 5a97a56a1..a12c73f09 100644 --- a/src/engine/compilercontext_p.h +++ b/src/engine/compilercontext_p.h @@ -2,6 +2,9 @@ #pragma once +#include +#include + namespace libscratchcpp { @@ -10,10 +13,11 @@ class Target; struct CompilerContextPrivate { - CompilerContextPrivate(IEngine *engine, Target *target); + CompilerContextPrivate(IEngine *engine, Target *target, const std::unordered_set &unsafeConstants); IEngine *engine = nullptr; Target *target = nullptr; + const std::unordered_set unsafeConstants; }; } // namespace libscratchcpp diff --git a/src/engine/internal/codegen/codebuilderfactory.cpp b/src/engine/internal/codegen/codebuilderfactory.cpp index 853f283cd..fc2985de5 100644 --- a/src/engine/internal/codegen/codebuilderfactory.cpp +++ b/src/engine/internal/codegen/codebuilderfactory.cpp @@ -19,8 +19,8 @@ std::shared_ptr CodeBuilderFactory::create(CompilerContext *ctx, B return std::make_shared(static_cast(ctx), procedurePrototype, codeType); } -std::shared_ptr CodeBuilderFactory::createCtx(IEngine *engine, Target *target) const +std::shared_ptr CodeBuilderFactory::createCtx(IEngine *engine, Target *target, const std::unordered_set &unsafeConstants) const { - auto ptr = std::make_shared(engine, target); + auto ptr = std::make_shared(engine, target, unsafeConstants); return ptr; } diff --git a/src/engine/internal/codegen/codebuilderfactory.h b/src/engine/internal/codegen/codebuilderfactory.h index 8218f3bc2..955e5fe5e 100644 --- a/src/engine/internal/codegen/codebuilderfactory.h +++ b/src/engine/internal/codegen/codebuilderfactory.h @@ -13,7 +13,7 @@ class LIBSCRATCHCPP_TEST_EXPORT CodeBuilderFactory : public ICodeBuilderFactory public: static std::shared_ptr instance(); std::shared_ptr create(CompilerContext *ctx, BlockPrototype *procedurePrototype, Compiler::CodeType codeType) const override; - std::shared_ptr createCtx(IEngine *engine, Target *target) const override; + std::shared_ptr createCtx(IEngine *engine, Target *target, const std::unordered_set &unsafeConstants = {}) const override; private: static std::shared_ptr m_instance; diff --git a/src/engine/internal/codegen/icodebuilderfactory.h b/src/engine/internal/codegen/icodebuilderfactory.h index de0b7b8df..419cf50e9 100644 --- a/src/engine/internal/codegen/icodebuilderfactory.h +++ b/src/engine/internal/codegen/icodebuilderfactory.h @@ -16,7 +16,7 @@ class ICodeBuilderFactory virtual ~ICodeBuilderFactory() { } virtual std::shared_ptr create(CompilerContext *ctx, BlockPrototype *procedurePrototype = nullptr, Compiler::CodeType codeType = Compiler::CodeType::Script) const = 0; - virtual std::shared_ptr createCtx(IEngine *engine, Target *target) const = 0; + virtual std::shared_ptr createCtx(IEngine *engine, Target *target, const std::unordered_set &unsafeConstants = {}) const = 0; }; } // namespace libscratchcpp diff --git a/src/engine/internal/codegen/llvm/llvmcompilercontext.cpp b/src/engine/internal/codegen/llvm/llvmcompilercontext.cpp index 3e65c9d39..ea319c7aa 100644 --- a/src/engine/internal/codegen/llvm/llvmcompilercontext.cpp +++ b/src/engine/internal/codegen/llvm/llvmcompilercontext.cpp @@ -17,8 +17,8 @@ using namespace libscratchcpp; -LLVMCompilerContext::LLVMCompilerContext(IEngine *engine, Target *target) : - CompilerContext(engine, target), +LLVMCompilerContext::LLVMCompilerContext(IEngine *engine, Target *target, const std::unordered_set &unsafeConstants) : + CompilerContext(engine, target, unsafeConstants), m_llvmCtx(std::make_unique()), m_module(std::make_unique(target ? target->name() : "", *m_llvmCtx)), m_llvmCtxPtr(m_llvmCtx.get()), diff --git a/src/engine/internal/codegen/llvm/llvmcompilercontext.h b/src/engine/internal/codegen/llvm/llvmcompilercontext.h index 9cc8462b7..19de9fbf9 100644 --- a/src/engine/internal/codegen/llvm/llvmcompilercontext.h +++ b/src/engine/internal/codegen/llvm/llvmcompilercontext.h @@ -28,7 +28,7 @@ using function_id_t = unsigned int; class LIBSCRATCHCPP_TEST_EXPORT LLVMCompilerContext : public CompilerContext { public: - LLVMCompilerContext(IEngine *engine, Target *target); + LLVMCompilerContext(IEngine *engine, Target *target, const std::unordered_set &unsafeConstants = {}); void preoptimize() override; diff --git a/test/compiler/compiler_test.cpp b/test/compiler/compiler_test.cpp index 0869357db..c3cfa4b8a 100644 --- a/test/compiler/compiler_test.cpp +++ b/test/compiler/compiler_test.cpp @@ -31,7 +31,7 @@ class CompilerTest : public testing::Test m_ctx = std::make_shared(&m_engine, &m_target); CompilerPrivate::setBuilderFactory(&m_builderFactory); - EXPECT_CALL(m_builderFactory, createCtx(&m_engine, &m_target)).WillOnce(Return(m_ctx)); + EXPECT_CALL(m_builderFactory, createCtx(&m_engine, &m_target, _)).WillOnce(Return(m_ctx)); m_compiler = std::make_unique(&m_engine, &m_target); m_builder = std::make_shared(); @@ -1873,7 +1873,7 @@ TEST_F(CompilerTest, Preoptimize) { auto ctx = std::make_shared(&m_engine, &m_target); - EXPECT_CALL(m_builderFactory, createCtx(&m_engine, &m_target)).WillOnce(Return(ctx)); + EXPECT_CALL(m_builderFactory, createCtx(&m_engine, &m_target, _)).WillOnce(Return(ctx)); Compiler compiler(&m_engine, &m_target); EXPECT_CALL(*ctx, preoptimize()); diff --git a/test/mocks/codebuilderfactorymock.h b/test/mocks/codebuilderfactorymock.h index 1577a7149..4913525f0 100644 --- a/test/mocks/codebuilderfactorymock.h +++ b/test/mocks/codebuilderfactorymock.h @@ -9,5 +9,5 @@ class CodeBuilderFactoryMock : public ICodeBuilderFactory { public: MOCK_METHOD(std::shared_ptr, create, (CompilerContext *, BlockPrototype *, Compiler::CodeType), (const, override)); - MOCK_METHOD(std::shared_ptr, createCtx, (IEngine *, Target *), (const, override)); + MOCK_METHOD(std::shared_ptr, createCtx, (IEngine *, Target *, const std::unordered_set &), (const, override)); }; From 4d3f9795cb40b304af3d7b9bb26d5fa82477aba1 Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Fri, 23 Oct 2026 11:26:29 +0200 Subject: [PATCH 06/13] Pass unsafe constants to CompilerContext --- include/scratchcpp/compiler.h | 2 +- src/engine/compiler.cpp | 4 ++-- src/engine/compiler_p.cpp | 2 +- src/engine/internal/engine.cpp | 36 ++++++++++++++++++++++++++++++++-- src/engine/internal/engine.h | 3 ++- 5 files changed, 40 insertions(+), 7 deletions(-) diff --git a/include/scratchcpp/compiler.h b/include/scratchcpp/compiler.h index 1d7b22b61..633de3670 100644 --- a/include/scratchcpp/compiler.h +++ b/include/scratchcpp/compiler.h @@ -164,7 +164,7 @@ class LIBSCRATCHCPP_EXPORT Compiler const std::unordered_set &unsupportedBlocks() const; - static std::shared_ptr createContext(IEngine *engine, Target *target); + static std::shared_ptr createContext(IEngine *engine, Target *target, const std::unordered_set &unsafeConstants); private: spimpl::unique_impl_ptr impl; diff --git a/src/engine/compiler.cpp b/src/engine/compiler.cpp index 05ca1a074..d0aeb1a07 100644 --- a/src/engine/compiler.cpp +++ b/src/engine/compiler.cpp @@ -751,8 +751,8 @@ const std::unordered_set &Compiler::unsupportedBlocks() const } /*! Creates a compiler context for the given target. */ -std::shared_ptr Compiler::createContext(IEngine *engine, Target *target) +std::shared_ptr Compiler::createContext(IEngine *engine, Target *target, const std::unordered_set &unsafeConstants) { CompilerPrivate::initBuilderFactory(); - return CompilerPrivate::builderFactory()->createCtx(engine, target); + return CompilerPrivate::builderFactory()->createCtx(engine, target, unsafeConstants); } diff --git a/src/engine/compiler_p.cpp b/src/engine/compiler_p.cpp index 43bd5b57a..983ce4c34 100644 --- a/src/engine/compiler_p.cpp +++ b/src/engine/compiler_p.cpp @@ -18,7 +18,7 @@ CompilerPrivate::CompilerPrivate(CompilerContext *ctx) : } CompilerPrivate::CompilerPrivate(IEngine *engine, Target *target) : - ctxPtr(Compiler::createContext(engine, target)), + ctxPtr(Compiler::createContext(engine, target, {})), // NOTE: This constructor is only used in tests, so we can leave unsafe constants empty ctx(ctxPtr.get()) { initBuilderFactory(); diff --git a/src/engine/internal/engine.cpp b/src/engine/internal/engine.cpp index 170013de1..547d9104c 100644 --- a/src/engine/internal/engine.cpp +++ b/src/engine/internal/engine.cpp @@ -85,6 +85,7 @@ void Engine::clear() m_broadcastMap.clear(); m_broadcastSenders.clear(); m_sortedDrawables.clear(); + m_unsafeConstants.clear(); m_threads.clear(); m_threadsToStop.clear(); m_scripts.clear(); @@ -245,10 +246,41 @@ void Engine::compile() // Resolve entities by ID resolveIds(); + // Find unsafe constants (string numerals) in costume and sound names + m_unsafeConstants.clear(); + + for (auto target : m_targets) { + IEngine *engine = target->engine(); + + if (engine) { + auto checkConstant = [this](const std::string &str) { + Value stringValue(str); + Value numberValue(stringValue.toDouble()); + + if (stringValue.isValidNumber() && str == numberValue.toString()) + m_unsafeConstants.insert(str); + }; + + const auto &targets = engine->targets(); + bool found = false; + + for (const auto &target : targets) { + const auto &costumes = target->costumes(); + const auto &sounds = target->sounds(); + + for (const auto &costume : costumes) + checkConstant(costume->name()); + + for (const auto &sound : sounds) + checkConstant(sound->name()); + } + } + } + // Compile scripts for (auto target : m_targets) { std::cout << "Compiling scripts in target " << target->name() << "..." << std::endl; - auto ctx = Compiler::createContext(this, target.get()); + auto ctx = Compiler::createContext(this, target.get(), m_unsafeConstants); m_compilerContexts[target.get()] = ctx; Compiler compiler(ctx.get()); const auto &blocks = target->blocks(); @@ -1789,7 +1821,7 @@ void Engine::compileMonitor(std::shared_ptr monitor) auto ext = blockExtension(block->opcode()); if (ext) { - auto ctx = Compiler::createContext(this, target); + auto ctx = Compiler::createContext(this, target, m_unsafeConstants); Compiler compiler(ctx.get()); MonitorNameFunc nameFunc = resolveMonitorNameFunc(ext, block->opcode()); diff --git a/src/engine/internal/engine.h b/src/engine/internal/engine.h index 2508a4677..8d10ba7a4 100644 --- a/src/engine/internal/engine.h +++ b/src/engine/internal/engine.h @@ -241,7 +241,8 @@ class LIBSCRATCHCPP_TEST_EXPORT Engine : public IEngine std::unordered_map m_broadcastSenders; // used for resolving broadcast promises std::vector> m_monitors; std::vector m_extensions; - std::vector m_sortedDrawables; // sorted by layer (reverse order of execution) + std::vector m_sortedDrawables; // sorted by layer (reverse order of execution) + std::unordered_set m_unsafeConstants; // string numerals which shouldn't be optimized std::vector> m_threads; std::vector> m_threadsToStop; std::shared_ptr m_activeThread; From b2eb2d2496017f89c93a7a156fc626c0770e331d Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Fri, 23 Oct 2026 11:46:43 +0200 Subject: [PATCH 07/13] Add unsafe constants getter to CompilerContext --- include/scratchcpp/compilercontext.h | 2 ++ src/engine/compilercontext.cpp | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/include/scratchcpp/compilercontext.h b/include/scratchcpp/compilercontext.h index aed59175b..ed8376617 100644 --- a/include/scratchcpp/compilercontext.h +++ b/include/scratchcpp/compilercontext.h @@ -25,6 +25,8 @@ class LIBSCRATCHCPP_EXPORT CompilerContext IEngine *engine() const; Target *target() const; + const std::unordered_set &unsafeConstants() const; + /*! * Optimizes compiled scripts ahead of time. * \see Compiler#preoptimize() diff --git a/src/engine/compilercontext.cpp b/src/engine/compilercontext.cpp index ee96b26a7..8d16a44dc 100644 --- a/src/engine/compilercontext.cpp +++ b/src/engine/compilercontext.cpp @@ -23,3 +23,9 @@ Target *CompilerContext::target() const { return impl->target; } + +/*! Returns the list of unsafe constants (used internally during optimization). */ +const std::unordered_set &CompilerContext::unsafeConstants() const +{ + return impl->unsafeConstants; +} From 45567c7199db807f3ccae275d76354ca92bec220 Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Fri, 23 Oct 2026 11:47:09 +0200 Subject: [PATCH 08/13] Use unsafe constants from CompilerContext --- .../internal/codegen/llvm/llvmbuildutils.cpp | 33 ++----------------- .../internal/codegen/llvm/llvmbuildutils.h | 2 -- .../llvm/code_analyzer/list_type_analysis.cpp | 16 +++------ .../code_analyzer/variable_type_analysis.cpp | 17 +++------- 4 files changed, 11 insertions(+), 57 deletions(-) diff --git a/src/engine/internal/codegen/llvm/llvmbuildutils.cpp b/src/engine/internal/codegen/llvm/llvmbuildutils.cpp index 8dc05aaff..037fdeb63 100644 --- a/src/engine/internal/codegen/llvm/llvmbuildutils.cpp +++ b/src/engine/internal/codegen/llvm/llvmbuildutils.cpp @@ -42,35 +42,6 @@ LLVMBuildUtils::LLVMBuildUtils(LLVMCompilerContext *ctx, llvm::IRBuilder<> &buil initTypes(); createVariableMap(); createListMap(); - - // Find unsafe numeric string constants in costume and sound names - if (m_target) { - IEngine *engine = m_target->engine(); - - if (engine) { - auto checkConstant = [this](const std::string &str) { - Value stringValue(str); - Value numberValue(stringValue.toDouble()); - - if (stringValue.isValidNumber() && str == numberValue.toString()) - m_unsafeConstants.insert(str); - }; - - const auto &targets = engine->targets(); - bool found = false; - - for (const auto &target : targets) { - const auto &costumes = target->costumes(); - const auto &sounds = target->sounds(); - - for (const auto &costume : costumes) - checkConstant(costume->name()); - - for (const auto &sound : sounds) - checkConstant(sound->name()); - } - } - } } void LLVMBuildUtils::init(llvm::Function *function, BlockPrototype *procedurePrototype, bool warp, const std::vector> ®s) @@ -522,7 +493,9 @@ Compiler::StaticType LLVMBuildUtils::optimizeRegisterType(const LLVMRegister *re std::string str = value.toString(); // Apply this optimization only if the number matches the string and the constant is safe - if (value.isValidNumber() && numberValue.toString() == str && m_unsafeConstants.find(str) == m_unsafeConstants.cend()) + const auto &unsafeConstants = m_ctx->unsafeConstants(); + + if (value.isValidNumber() && numberValue.toString() == str && unsafeConstants.find(str) == unsafeConstants.cend()) ret = Compiler::StaticType::Number; } diff --git a/src/engine/internal/codegen/llvm/llvmbuildutils.h b/src/engine/internal/codegen/llvm/llvmbuildutils.h index 2a7938081..892fdf664 100644 --- a/src/engine/internal/codegen/llvm/llvmbuildutils.h +++ b/src/engine/internal/codegen/llvm/llvmbuildutils.h @@ -180,8 +180,6 @@ class LIBSCRATCHCPP_TEST_EXPORT LLVMBuildUtils bool m_warp = false; Compiler::CodeType m_codeType = Compiler::CodeType::Script; - std::unordered_set m_unsafeConstants; - llvm::Value *m_executionContextPtr = nullptr; llvm::Value *m_targetPtr = nullptr; llvm::Value *m_targetVariables = nullptr; diff --git a/test/llvm/code_analyzer/list_type_analysis.cpp b/test/llvm/code_analyzer/list_type_analysis.cpp index da8251680..e252a00f9 100644 --- a/test/llvm/code_analyzer/list_type_analysis.cpp +++ b/test/llvm/code_analyzer/list_type_analysis.cpp @@ -1,7 +1,5 @@ #include -#include -#include -#include +#include #include #include #include @@ -22,17 +20,11 @@ class LLVMCodeAnalyzer_ListTypeAnalysis : public testing::Test { auto engine = m_project.engine(); m_target = std::make_shared(); - m_spriteWithUnsafeConstants = std::make_shared(); - auto costume = std::make_shared(m_unsafeCostumeNumConstant, "", ""); - m_spriteWithUnsafeConstants->addCostume(costume); + engine->setTargets({ m_target }); - auto sound = std::make_shared(m_unsafeSoundNumConstant, "", ""); - m_spriteWithUnsafeConstants->addSound(sound); - - engine->setTargets({ m_target, m_spriteWithUnsafeConstants }); - - m_ctx = std::make_unique(engine.get(), m_target.get()); + const std::unordered_set unsafeConstants = { m_unsafeCostumeNumConstant, m_unsafeSoundNumConstant }; + m_ctx = std::make_unique(engine.get(), m_target.get(), unsafeConstants); m_builder = std::make_unique>(*m_ctx->llvmCtx()); m_utils = std::make_unique(m_ctx.get(), *m_builder, Compiler::CodeType::Script); m_analyzer = std::make_unique(*m_utils); diff --git a/test/llvm/code_analyzer/variable_type_analysis.cpp b/test/llvm/code_analyzer/variable_type_analysis.cpp index c62c57299..10361a201 100644 --- a/test/llvm/code_analyzer/variable_type_analysis.cpp +++ b/test/llvm/code_analyzer/variable_type_analysis.cpp @@ -1,7 +1,5 @@ #include -#include -#include -#include +#include #include #include #include @@ -22,17 +20,11 @@ class LLVMCodeAnalyzer_VariableTypeAnalysis : public testing::Test { auto engine = m_project.engine(); m_target = std::make_shared(); - m_spriteWithUnsafeConstants = std::make_shared(); - auto costume = std::make_shared(m_unsafeCostumeNumConstant, "", ""); - m_spriteWithUnsafeConstants->addCostume(costume); + engine->setTargets({ m_target }); - auto sound = std::make_shared(m_unsafeSoundNumConstant, "", ""); - m_spriteWithUnsafeConstants->addSound(sound); - - engine->setTargets({ m_target, m_spriteWithUnsafeConstants }); - - m_ctx = std::make_unique(engine.get(), m_target.get()); + const std::unordered_set unsafeConstants = { m_unsafeCostumeNumConstant, m_unsafeSoundNumConstant }; + m_ctx = std::make_unique(engine.get(), m_target.get(), unsafeConstants); m_builder = std::make_unique>(*m_ctx->llvmCtx()); m_utils = std::make_unique(m_ctx.get(), *m_builder, Compiler::CodeType::Script); m_analyzer = std::make_unique(*m_utils); @@ -47,7 +39,6 @@ class LLVMCodeAnalyzer_VariableTypeAnalysis : public testing::Test private: Project m_project; std::shared_ptr m_target; - std::shared_ptr m_spriteWithUnsafeConstants; std::unique_ptr m_ctx; std::unique_ptr> m_builder; std::unique_ptr m_utils; From a1940fc838cd7ec3b86d9a39b822fcecdcc36ec0 Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Sun, 25 Oct 2026 00:06:29 +0200 Subject: [PATCH 09/13] Add missing license identifier to InstructionListBase --- src/engine/internal/codegen/instructionlistbase.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/engine/internal/codegen/instructionlistbase.cpp b/src/engine/internal/codegen/instructionlistbase.cpp index 3bc402bda..304b78a55 100644 --- a/src/engine/internal/codegen/instructionlistbase.cpp +++ b/src/engine/internal/codegen/instructionlistbase.cpp @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 + #include "instructionlistbase.h" using namespace libscratchcpp; From d356a80743b66a830053f19679f718fda0ce9794 Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Sun, 25 Oct 2026 00:11:39 +0200 Subject: [PATCH 10/13] Move value-related fields to InstructionBase --- src/engine/internal/codegen/instruction.h | 20 +- src/engine/internal/codegen/instructionbase.h | 3 + .../codegen/llvm/instructions/comparison.cpp | 35 ++-- .../codegen/llvm/instructions/control.cpp | 34 ++-- .../codegen/llvm/instructions/functions.cpp | 22 ++- .../llvm/instructions/instructionbuilder.cpp | 4 +- .../codegen/llvm/instructions/lists.cpp | 50 +++-- .../codegen/llvm/instructions/logic.cpp | 19 +- .../codegen/llvm/instructions/math.cpp | 182 +++++++++++------- .../codegen/llvm/instructions/procedures.cpp | 6 +- .../codegen/llvm/instructions/string.cpp | 23 ++- .../codegen/llvm/instructions/variables.cpp | 30 +-- .../internal/codegen/llvm/llvmbuildutils.cpp | 4 +- .../internal/codegen/llvm/llvmcodebuilder.cpp | 10 +- 14 files changed, 262 insertions(+), 180 deletions(-) diff --git a/src/engine/internal/codegen/instruction.h b/src/engine/internal/codegen/instruction.h index 382a996c5..6820945a7 100644 --- a/src/engine/internal/codegen/instruction.h +++ b/src/engine/internal/codegen/instruction.h @@ -13,12 +13,24 @@ struct Instruction : public InstructionBase using Type = InstructionBase::Type; using InstructionBase::InstructionBase; // inherit constructor - inline TInstruction *getPrevious() { return static_cast(previous); } + inline TInstruction *getPrevious() const { return static_cast(previous); } - inline TInstruction *getNext() { return static_cast(next); } + inline TInstruction *getNext() const { return static_cast(next); } - std::vector> args; // target type, register - TRegister *functionReturnReg = nullptr; + inline std::vector> getArgs() const + { + // TODO: Replace this with getArg(index) and argCount() methods + std::vector> out; + out.reserve(args.size()); + + for (auto &a : args) + out.emplace_back(a.first, dynamic_cast(a.second)); + + return out; + } + + inline TRegister *getFunctionReturnReg() const { return dynamic_cast(functionReturnReg); } + inline void setFunctionReturnReg(TRegister *reg) { functionReturnReg = reg; } }; } // namespace libscratchcpp diff --git a/src/engine/internal/codegen/instructionbase.h b/src/engine/internal/codegen/instructionbase.h index dfeb6aab1..f83bcfe30 100644 --- a/src/engine/internal/codegen/instructionbase.h +++ b/src/engine/internal/codegen/instructionbase.h @@ -98,6 +98,9 @@ struct InstructionBase size_t procedureArgIndex = 0; bool loopCondition = false; // whether the instruction is part of a loop condition + std::vector> args; // target type, register + CompilerValue *functionReturnReg = nullptr; + // Linked list InstructionBase *previous = nullptr; InstructionBase *next = nullptr; diff --git a/src/engine/internal/codegen/llvm/instructions/comparison.cpp b/src/engine/internal/codegen/llvm/instructions/comparison.cpp index 5f5353778..c504ba7f6 100644 --- a/src/engine/internal/codegen/llvm/instructions/comparison.cpp +++ b/src/engine/internal/codegen/llvm/instructions/comparison.cpp @@ -43,9 +43,10 @@ ProcessResult Comparison::process(LLVMInstruction *ins) LLVMInstruction *Comparison::buildCmpEQ(LLVMInstruction *ins) { assert(ins->args.size() == 2); - const auto &arg1 = ins->args[0].second; - const auto &arg2 = ins->args[1].second; - ins->functionReturnReg->value = m_utils.createComparison(arg1, arg2, LLVMBuildUtils::Comparison::EQ); + const auto &args = ins->getArgs(); + const auto &arg1 = args[0].second; + const auto &arg2 = args[1].second; + ins->getFunctionReturnReg()->value = m_utils.createComparison(arg1, arg2, LLVMBuildUtils::Comparison::EQ); return ins->getNext(); } @@ -53,9 +54,10 @@ LLVMInstruction *Comparison::buildCmpEQ(LLVMInstruction *ins) LLVMInstruction *Comparison::buildCmpGT(LLVMInstruction *ins) { assert(ins->args.size() == 2); - const auto &arg1 = ins->args[0].second; - const auto &arg2 = ins->args[1].second; - ins->functionReturnReg->value = m_utils.createComparison(arg1, arg2, LLVMBuildUtils::Comparison::GT); + const auto &args = ins->getArgs(); + const auto &arg1 = args[0].second; + const auto &arg2 = args[1].second; + ins->getFunctionReturnReg()->value = m_utils.createComparison(arg1, arg2, LLVMBuildUtils::Comparison::GT); return ins->getNext(); } @@ -63,9 +65,10 @@ LLVMInstruction *Comparison::buildCmpGT(LLVMInstruction *ins) LLVMInstruction *Comparison::buildCmpLT(LLVMInstruction *ins) { assert(ins->args.size() == 2); - const auto &arg1 = ins->args[0].second; - const auto &arg2 = ins->args[1].second; - ins->functionReturnReg->value = m_utils.createComparison(arg1, arg2, LLVMBuildUtils::Comparison::LT); + const auto &args = ins->getArgs(); + const auto &arg1 = args[0].second; + const auto &arg2 = args[1].second; + ins->getFunctionReturnReg()->value = m_utils.createComparison(arg1, arg2, LLVMBuildUtils::Comparison::LT); return ins->getNext(); } @@ -73,9 +76,10 @@ LLVMInstruction *Comparison::buildCmpLT(LLVMInstruction *ins) LLVMInstruction *Comparison::buildStrCmpEQCS(LLVMInstruction *ins) { assert(ins->args.size() == 2); - const auto &arg1 = ins->args[0].second; - const auto &arg2 = ins->args[1].second; - ins->functionReturnReg->value = m_utils.createStringComparison(arg1, arg2, true); + const auto &args = ins->getArgs(); + const auto &arg1 = args[0].second; + const auto &arg2 = args[1].second; + ins->getFunctionReturnReg()->value = m_utils.createStringComparison(arg1, arg2, true); return ins->getNext(); } @@ -83,9 +87,10 @@ LLVMInstruction *Comparison::buildStrCmpEQCS(LLVMInstruction *ins) LLVMInstruction *Comparison::buildStrCmpEQCI(LLVMInstruction *ins) { assert(ins->args.size() == 2); - const auto &arg1 = ins->args[0].second; - const auto &arg2 = ins->args[1].second; - ins->functionReturnReg->value = m_utils.createStringComparison(arg1, arg2, false); + const auto &args = ins->getArgs(); + const auto &arg1 = args[0].second; + const auto &arg2 = args[1].second; + ins->getFunctionReturnReg()->value = m_utils.createStringComparison(arg1, arg2, false); return ins->getNext(); } diff --git a/src/engine/internal/codegen/llvm/instructions/control.cpp b/src/engine/internal/codegen/llvm/instructions/control.cpp index b361a3618..100f1875e 100644 --- a/src/engine/internal/codegen/llvm/instructions/control.cpp +++ b/src/engine/internal/codegen/llvm/instructions/control.cpp @@ -83,9 +83,10 @@ ProcessResult Control::process(LLVMInstruction *ins) LLVMInstruction *Control::buildSelect(LLVMInstruction *ins) { assert(ins->args.size() == 3); - const auto &arg1 = ins->args[0]; - const auto &arg2 = ins->args[1]; - const auto &arg3 = ins->args[2]; + const auto &args = ins->getArgs(); + const auto &arg1 = args[0]; + const auto &arg2 = args[1]; + const auto &arg3 = args[2]; auto type = arg2.first; llvm::Value *cond = m_utils.castValue(arg1.second, arg1.first); llvm::Value *trueValue; @@ -99,9 +100,9 @@ LLVMInstruction *Control::buildSelect(LLVMInstruction *ins) falseValue = m_utils.createValue(arg3.second); } - ins->functionReturnReg->value = m_builder.CreateSelect(cond, trueValue, falseValue); - ins->functionReturnReg->isInt = m_builder.CreateSelect(cond, arg2.second->isInt, arg3.second->isInt); - ins->functionReturnReg->intValue = m_builder.CreateSelect(cond, arg2.second->intValue, arg3.second->intValue); + ins->getFunctionReturnReg()->value = m_builder.CreateSelect(cond, trueValue, falseValue); + ins->getFunctionReturnReg()->isInt = m_builder.CreateSelect(cond, arg2.second->isInt, arg3.second->isInt); + ins->getFunctionReturnReg()->intValue = m_builder.CreateSelect(cond, arg2.second->intValue, arg3.second->intValue); return ins->getNext(); } @@ -119,7 +120,8 @@ LLVMInstruction *Control::buildBeginIf(LLVMInstruction *ins) // Use last reg assert(ins->args.size() == 1); - const auto ® = ins->args[0]; + const auto &args = ins->getArgs(); + const auto ® = args[0]; assert(reg.first == Compiler::StaticType::Bool); statement.condition = m_utils.castValue(reg.second, reg.first); @@ -205,7 +207,8 @@ LLVMInstruction *Control::buildBeginRepeatLoop(LLVMInstruction *ins) // Use last reg for count assert(ins->args.size() == 1); - const auto ® = ins->args[0]; + const auto &args = ins->getArgs(); + const auto ® = args[0]; assert(reg.first == Compiler::StaticType::Number); llvm::Value *count = m_utils.castValue(reg.second, reg.first); llvm::Value *isInf = m_builder.CreateFCmpOEQ(count, llvm::ConstantFP::getInfinity(m_builder.getDoubleTy(), false)); @@ -249,9 +252,9 @@ LLVMInstruction *Control::buildLoopIndex(LLVMInstruction *ins) assert(!m_utils.loops().empty()); LLVMLoop &loop = m_utils.loops().back(); llvm::Value *index = m_builder.CreateLoad(m_builder.getInt64Ty(), loop.index); - ins->functionReturnReg->value = m_builder.CreateUIToFP(index, m_builder.getDoubleTy()); - ins->functionReturnReg->intValue = index; - ins->functionReturnReg->isInt = m_builder.getInt1(true); + ins->getFunctionReturnReg()->value = m_builder.CreateUIToFP(index, m_builder.getDoubleTy()); + ins->getFunctionReturnReg()->intValue = index; + ins->getFunctionReturnReg()->isInt = m_builder.getInt1(true); return ins->getNext(); } @@ -270,7 +273,8 @@ LLVMInstruction *Control::buildBeginWhileLoop(LLVMInstruction *ins) // Use last reg assert(ins->args.size() == 1); - const auto ® = ins->args[0]; + const auto &args = ins->getArgs(); + const auto ® = args[0]; assert(reg.first == Compiler::StaticType::Bool); llvm::Value *condition = m_utils.castValue(reg.second, reg.first); m_builder.CreateCondBr(condition, body, loop.afterLoop); @@ -295,7 +299,8 @@ LLVMInstruction *Control::buildBeginRepeatUntilLoop(LLVMInstruction *ins) // Use last reg assert(ins->args.size() == 1); - const auto ® = ins->args[0]; + const auto &args = ins->getArgs(); + const auto ® = args[0]; assert(reg.first == Compiler::StaticType::Bool); llvm::Value *condition = m_utils.castValue(reg.second, reg.first); m_builder.CreateCondBr(condition, loop.afterLoop, body); @@ -374,7 +379,8 @@ LLVMInstruction *Control::buildPrint(LLVMInstruction *ins) { assert(ins->args.size() == 1); - const auto &arg = ins->args[0]; + const auto &args = ins->getArgs(); + const auto &arg = args[0]; llvm::Value *str = m_utils.castValue(arg.second, arg.first); m_builder.CreateCall(m_utils.functions().resolve_llvm_print(), str); diff --git a/src/engine/internal/codegen/llvm/instructions/functions.cpp b/src/engine/internal/codegen/llvm/instructions/functions.cpp index b73544db7..b05623430 100644 --- a/src/engine/internal/codegen/llvm/instructions/functions.cpp +++ b/src/engine/internal/codegen/llvm/instructions/functions.cpp @@ -35,7 +35,7 @@ LLVMInstruction *Functions::buildFunctionCall(LLVMInstruction *ins) // Strings are returned through an output parameter llvm::Value *stringRet = nullptr; - if (ins->functionReturnReg && ins->functionReturnReg->type() == Compiler::StaticType::String) { + if (ins->getFunctionReturnReg() && ins->getFunctionReturnReg()->type() == Compiler::StaticType::String) { stringRet = m_utils.addStringAlloca(); types.push_back(m_utils.getType(Compiler::StaticType::String, false)); args.push_back(stringRet); @@ -54,22 +54,24 @@ LLVMInstruction *Functions::buildFunctionCall(LLVMInstruction *ins) } // Args - for (auto &arg : ins->args) { + const auto &insArgs = ins->getArgs(); + + for (auto &arg : insArgs) { types.push_back(m_utils.getType(arg.first, false)); args.push_back(m_utils.castValue(arg.second, arg.first)); } - llvm::Type *retType = m_utils.getType(ins->functionReturnReg ? ins->functionReturnReg->type() : Compiler::StaticType::Void, true); + llvm::Type *retType = m_utils.getType(ins->getFunctionReturnReg() ? ins->getFunctionReturnReg()->type() : Compiler::StaticType::Void, true); llvm::Value *ret = m_builder.CreateCall(m_utils.functions().resolveFunction(ins->functionName, llvm::FunctionType::get(retType, types, false)), args); - if (ins->functionReturnReg) { - if (ins->functionReturnReg->type() == Compiler::StaticType::String) - ins->functionReturnReg->value = stringRet; - else if (m_utils.isSingleType(ins->functionReturnReg->type())) - ins->functionReturnReg->value = ret; + if (ins->getFunctionReturnReg()) { + if (ins->getFunctionReturnReg()->type() == Compiler::StaticType::String) + ins->getFunctionReturnReg()->value = stringRet; + else if (m_utils.isSingleType(ins->getFunctionReturnReg()->type())) + ins->getFunctionReturnReg()->value = ret; else { - ins->functionReturnReg->value = m_utils.addAlloca(retType); - m_builder.CreateStore(ret, ins->functionReturnReg->value); + ins->getFunctionReturnReg()->value = m_utils.addAlloca(retType); + m_builder.CreateStore(ret, ins->getFunctionReturnReg()->value); } } diff --git a/src/engine/internal/codegen/llvm/instructions/instructionbuilder.cpp b/src/engine/internal/codegen/llvm/instructions/instructionbuilder.cpp index 87977e327..402118860 100644 --- a/src/engine/internal/codegen/llvm/instructions/instructionbuilder.cpp +++ b/src/engine/internal/codegen/llvm/instructions/instructionbuilder.cpp @@ -39,8 +39,8 @@ LLVMInstruction *InstructionBuilder::process(LLVMInstruction *ins) if (result.match) { #ifndef LLVM_INTEGER_SUPPORT - if (ins->functionReturnReg) - ins->functionReturnReg->isInt = m_utils.builder().getInt1(false); + if (ins->getFunctionReturnReg()) + ins->getFunctionReturnReg()->isInt = m_utils.builder().getInt1(false); #endif return result.next; diff --git a/src/engine/internal/codegen/llvm/instructions/lists.cpp b/src/engine/internal/codegen/llvm/instructions/lists.cpp index 91386f8dd..e7ad0cf92 100644 --- a/src/engine/internal/codegen/llvm/instructions/lists.cpp +++ b/src/engine/internal/codegen/llvm/instructions/lists.cpp @@ -5,6 +5,7 @@ #include "../llvmbuildutils.h" #include "../llvmconstantregister.h" #include "../llvmcompilercontext.h" +#include "../../optimizationutils.h" using namespace libscratchcpp; using namespace libscratchcpp::llvmins; @@ -95,7 +96,8 @@ LLVMInstruction *Lists::buildRemoveListItem(LLVMInstruction *ins) llvm::Function *function = m_utils.function(); assert(ins->args.size() == 1); - const auto &arg = ins->args[0]; + const auto &args = ins->getArgs(); + const auto &arg = args[0]; LLVMListPtr &listPtr = m_utils.listPtr(ins->targetList); @@ -130,8 +132,9 @@ LLVMInstruction *Lists::buildAppendToList(LLVMInstruction *ins) llvm::Function *function = m_utils.function(); assert(ins->args.size() == 1); - const auto &arg = ins->args[0]; - Compiler::StaticType type = m_utils.optimizeRegisterType(arg.second); + const auto &args = ins->getArgs(); + const auto &arg = args[0]; + Compiler::StaticType type = OptimizationUtils::optimizeValueType(m_utils.compilerCtx(), arg.second); LLVMListPtr &listPtr = m_utils.listPtr(ins->targetList); // Check if enough space is allocated @@ -179,9 +182,10 @@ LLVMInstruction *Lists::buildInsertToList(LLVMInstruction *ins) llvm::Function *function = m_utils.function(); assert(ins->args.size() == 2); - const auto &indexArg = ins->args[0]; - const auto &valueArg = ins->args[1]; - Compiler::StaticType type = m_utils.optimizeRegisterType(valueArg.second); + const auto &args = ins->getArgs(); + const auto &indexArg = args[0]; + const auto &valueArg = args[1]; + Compiler::StaticType type = OptimizationUtils::optimizeValueType(m_utils.compilerCtx(), valueArg.second); LLVMListPtr &listPtr = m_utils.listPtr(ins->targetList); // Range check @@ -225,9 +229,10 @@ LLVMInstruction *Lists::buildListReplace(LLVMInstruction *ins) llvm::Function *function = m_utils.function(); assert(ins->args.size() == 2); - const auto &indexArg = ins->args[0]; - const auto &valueArg = ins->args[1]; - Compiler::StaticType type = m_utils.optimizeRegisterType(valueArg.second); + const auto &args = ins->getArgs(); + const auto &indexArg = args[0]; + const auto &valueArg = args[1]; + Compiler::StaticType type = OptimizationUtils::optimizeValueType(m_utils.compilerCtx(), valueArg.second); LLVMListPtr &listPtr = m_utils.listPtr(ins->targetList); Compiler::StaticType listType = ins->targetType; @@ -272,7 +277,7 @@ LLVMInstruction *Lists::buildGetListContents(LLVMInstruction *ins) const LLVMListPtr &listPtr = m_utils.listPtr(ins->targetList); llvm::Value *ptr = m_utils.addStringAlloca(); m_builder.CreateCall(m_utils.functions().resolve_list_to_string(), { listPtr.ptr, ptr }); - ins->functionReturnReg->value = ptr; + ins->getFunctionReturnReg()->value = ptr; return ins->getNext(); } @@ -285,12 +290,13 @@ LLVMInstruction *Lists::buildGetListItem(LLVMInstruction *ins) // Return empty string for empty lists if (ins->targetType == Compiler::StaticType::Void) { LLVMConstantRegister nullReg(Compiler::StaticType::String, ""); - ins->functionReturnReg->value = m_utils.createValue(static_cast(&nullReg)); + ins->getFunctionReturnReg()->value = m_utils.createValue(static_cast(&nullReg)); return ins->getNext(); } assert(ins->args.size() == 1); - const auto &arg = ins->args[0]; + const auto &args = ins->getArgs(); + const auto &arg = args[0]; LLVMListPtr &listPtr = m_utils.listPtr(ins->targetList); // Range check @@ -327,8 +333,8 @@ LLVMInstruction *Lists::buildGetListItem(LLVMInstruction *ins) itemTypeResult->addIncoming(stringType, outOfRangeBlock); llvm::Value *typeVar = createListTypeVar(listPtr, itemTypeResult); - ins->functionReturnReg->value = result; - ins->functionReturnReg->typeVar = typeVar; + ins->getFunctionReturnReg()->value = result; + ins->getFunctionReturnReg()->typeVar = typeVar; createListTypeAssumption(listPtr, typeVar, ins->targetType, inRange); return ins->getNext(); @@ -339,9 +345,9 @@ LLVMInstruction *Lists::buildGetListSize(LLVMInstruction *ins) assert(ins->args.size() == 0); const LLVMListPtr &listPtr = m_utils.listPtr(ins->targetList); llvm::Value *size = m_utils.getListSize(listPtr); - ins->functionReturnReg->value = m_builder.CreateUIToFP(size, m_builder.getDoubleTy()); - ins->functionReturnReg->isInt = m_builder.getInt1(true); - ins->functionReturnReg->intValue = size; + ins->getFunctionReturnReg()->value = m_builder.CreateUIToFP(size, m_builder.getDoubleTy()); + ins->getFunctionReturnReg()->isInt = m_builder.getInt1(true); + ins->getFunctionReturnReg()->intValue = size; return ins->getNext(); } @@ -349,25 +355,27 @@ LLVMInstruction *Lists::buildGetListSize(LLVMInstruction *ins) LLVMInstruction *Lists::buildGetListItemIndex(LLVMInstruction *ins) { assert(ins->args.size() == 1); - const auto &arg = ins->args[0]; + const auto &args = ins->getArgs(); + const auto &arg = args[0]; LLVMListPtr &listPtr = m_utils.listPtr(ins->targetList); Compiler::StaticType listType = ins->targetType; - ins->functionReturnReg->value = m_builder.CreateSIToFP(m_utils.getListItemIndex(listPtr, listType, arg.second), m_builder.getDoubleTy()); + ins->getFunctionReturnReg()->value = m_builder.CreateSIToFP(m_utils.getListItemIndex(listPtr, listType, arg.second), m_builder.getDoubleTy()); return ins->getNext(); } LLVMInstruction *Lists::buildListContainsItem(LLVMInstruction *ins) { assert(ins->args.size() == 1); - const auto &arg = ins->args[0]; + const auto &args = ins->getArgs(); + const auto &arg = args[0]; LLVMListPtr &listPtr = m_utils.listPtr(ins->targetList); Compiler::StaticType listType = ins->targetType; llvm::Value *index = m_utils.getListItemIndex(listPtr, listType, arg.second); - ins->functionReturnReg->value = m_builder.CreateICmpSGT(index, llvm::ConstantInt::get(m_builder.getInt64Ty(), -1, true)); + ins->getFunctionReturnReg()->value = m_builder.CreateICmpSGT(index, llvm::ConstantInt::get(m_builder.getInt64Ty(), -1, true)); return ins->getNext(); } diff --git a/src/engine/internal/codegen/llvm/instructions/logic.cpp b/src/engine/internal/codegen/llvm/instructions/logic.cpp index 9c4f3e7b4..920ac043d 100644 --- a/src/engine/internal/codegen/llvm/instructions/logic.cpp +++ b/src/engine/internal/codegen/llvm/instructions/logic.cpp @@ -36,11 +36,12 @@ ProcessResult Logic::process(LLVMInstruction *ins) LLVMInstruction *Logic::buildAnd(LLVMInstruction *ins) { assert(ins->args.size() == 2); - const auto &arg1 = ins->args[0]; - const auto &arg2 = ins->args[1]; + const auto &args = ins->getArgs(); + const auto &arg1 = args[0]; + const auto &arg2 = args[1]; llvm::Value *bool1 = m_utils.castValue(arg1.second, arg1.first); llvm::Value *bool2 = m_utils.castValue(arg2.second, arg2.first); - ins->functionReturnReg->value = m_builder.CreateAnd(bool1, bool2); + ins->getFunctionReturnReg()->value = m_builder.CreateAnd(bool1, bool2); return ins->getNext(); } @@ -48,11 +49,12 @@ LLVMInstruction *Logic::buildAnd(LLVMInstruction *ins) LLVMInstruction *Logic::buildOr(LLVMInstruction *ins) { assert(ins->args.size() == 2); - const auto &arg1 = ins->args[0]; - const auto &arg2 = ins->args[1]; + const auto &args = ins->getArgs(); + const auto &arg1 = args[0]; + const auto &arg2 = args[1]; llvm::Value *bool1 = m_utils.castValue(arg1.second, arg1.first); llvm::Value *bool2 = m_utils.castValue(arg2.second, arg2.first); - ins->functionReturnReg->value = m_builder.CreateOr(bool1, bool2); + ins->getFunctionReturnReg()->value = m_builder.CreateOr(bool1, bool2); return ins->getNext(); } @@ -60,9 +62,10 @@ LLVMInstruction *Logic::buildOr(LLVMInstruction *ins) LLVMInstruction *Logic::buildNot(LLVMInstruction *ins) { assert(ins->args.size() == 1); - const auto &arg = ins->args[0]; + const auto &args = ins->getArgs(); + const auto &arg = args[0]; llvm::Value *value = m_utils.castValue(arg.second, arg.first); - ins->functionReturnReg->value = m_builder.CreateNot(value); + ins->getFunctionReturnReg()->value = m_builder.CreateNot(value); return ins->getNext(); } diff --git a/src/engine/internal/codegen/llvm/instructions/math.cpp b/src/engine/internal/codegen/llvm/instructions/math.cpp index 86812a018..eb605abaa 100644 --- a/src/engine/internal/codegen/llvm/instructions/math.cpp +++ b/src/engine/internal/codegen/llvm/instructions/math.cpp @@ -111,17 +111,18 @@ ProcessResult Math::process(LLVMInstruction *ins) LLVMInstruction *Math::buildAdd(LLVMInstruction *ins) { assert(ins->args.size() == 2); - const auto &arg1 = ins->args[0]; - const auto &arg2 = ins->args[1]; + const auto &args = ins->getArgs(); + const auto &arg1 = args[0]; + const auto &arg2 = args[1]; llvm::Value *double1 = m_utils.removeNaN(m_utils.castValue(arg1.second, arg1.first, LLVMBuildUtils::NumberType::Double)); llvm::Value *double2 = m_utils.removeNaN(m_utils.castValue(arg2.second, arg2.first, LLVMBuildUtils::NumberType::Double)); - ins->functionReturnReg->value = m_builder.CreateFAdd(double1, double2); + ins->getFunctionReturnReg()->value = m_builder.CreateFAdd(double1, double2); llvm::Value *int1 = m_utils.castValue(arg1.second, arg1.first, LLVMBuildUtils::NumberType::Int); llvm::Value *int2 = m_utils.castValue(arg2.second, arg2.first, LLVMBuildUtils::NumberType::Int); - ins->functionReturnReg->isInt = m_builder.CreateAnd(arg1.second->isInt, arg2.second->isInt); - ins->functionReturnReg->intValue = m_builder.CreateAdd(int1, int2); + ins->getFunctionReturnReg()->isInt = m_builder.CreateAnd(arg1.second->isInt, arg2.second->isInt); + ins->getFunctionReturnReg()->intValue = m_builder.CreateAdd(int1, int2); return ins->getNext(); } @@ -129,17 +130,18 @@ LLVMInstruction *Math::buildAdd(LLVMInstruction *ins) LLVMInstruction *Math::buildSub(LLVMInstruction *ins) { assert(ins->args.size() == 2); - const auto &arg1 = ins->args[0]; - const auto &arg2 = ins->args[1]; + const auto &args = ins->getArgs(); + const auto &arg1 = args[0]; + const auto &arg2 = args[1]; llvm::Value *double1 = m_utils.removeNaN(m_utils.castValue(arg1.second, arg1.first, LLVMBuildUtils::NumberType::Double)); llvm::Value *double2 = m_utils.removeNaN(m_utils.castValue(arg2.second, arg2.first, LLVMBuildUtils::NumberType::Double)); - ins->functionReturnReg->value = m_builder.CreateFSub(double1, double2); + ins->getFunctionReturnReg()->value = m_builder.CreateFSub(double1, double2); llvm::Value *int1 = m_utils.castValue(arg1.second, arg1.first, LLVMBuildUtils::NumberType::Int); llvm::Value *int2 = m_utils.castValue(arg2.second, arg2.first, LLVMBuildUtils::NumberType::Int); - ins->functionReturnReg->isInt = m_builder.CreateAnd(arg1.second->isInt, arg2.second->isInt); - ins->functionReturnReg->intValue = m_builder.CreateSub(int1, int2); + ins->getFunctionReturnReg()->isInt = m_builder.CreateAnd(arg1.second->isInt, arg2.second->isInt); + ins->getFunctionReturnReg()->intValue = m_builder.CreateSub(int1, int2); return ins->getNext(); } @@ -147,17 +149,18 @@ LLVMInstruction *Math::buildSub(LLVMInstruction *ins) LLVMInstruction *Math::buildMul(LLVMInstruction *ins) { assert(ins->args.size() == 2); - const auto &arg1 = ins->args[0]; - const auto &arg2 = ins->args[1]; + const auto &args = ins->getArgs(); + const auto &arg1 = args[0]; + const auto &arg2 = args[1]; llvm::Value *double1 = m_utils.removeNaN(m_utils.castValue(arg1.second, arg1.first, LLVMBuildUtils::NumberType::Double)); llvm::Value *double2 = m_utils.removeNaN(m_utils.castValue(arg2.second, arg2.first, LLVMBuildUtils::NumberType::Double)); - ins->functionReturnReg->value = m_builder.CreateFMul(double1, double2); + ins->getFunctionReturnReg()->value = m_builder.CreateFMul(double1, double2); llvm::Value *int1 = m_utils.castValue(arg1.second, arg1.first, LLVMBuildUtils::NumberType::Int); llvm::Value *int2 = m_utils.castValue(arg2.second, arg2.first, LLVMBuildUtils::NumberType::Int); - ins->functionReturnReg->isInt = m_builder.CreateAnd(arg1.second->isInt, arg2.second->isInt); - ins->functionReturnReg->intValue = m_builder.CreateMul(int1, int2); + ins->getFunctionReturnReg()->isInt = m_builder.CreateAnd(arg1.second->isInt, arg2.second->isInt); + ins->getFunctionReturnReg()->intValue = m_builder.CreateMul(int1, int2); return ins->getNext(); } @@ -165,11 +168,12 @@ LLVMInstruction *Math::buildMul(LLVMInstruction *ins) LLVMInstruction *Math::buildDiv(LLVMInstruction *ins) { assert(ins->args.size() == 2); - const auto &arg1 = ins->args[0]; - const auto &arg2 = ins->args[1]; + const auto &args = ins->getArgs(); + const auto &arg1 = args[0]; + const auto &arg2 = args[1]; llvm::Value *num1 = m_utils.removeNaN(m_utils.castValue(arg1.second, arg1.first)); llvm::Value *num2 = m_utils.removeNaN(m_utils.castValue(arg2.second, arg2.first)); - ins->functionReturnReg->value = m_builder.CreateFDiv(num1, num2); + ins->getFunctionReturnReg()->value = m_builder.CreateFDiv(num1, num2); return ins->getNext(); } @@ -177,15 +181,16 @@ LLVMInstruction *Math::buildDiv(LLVMInstruction *ins) LLVMInstruction *Math::buildRandom(LLVMInstruction *ins) { assert(ins->args.size() == 2); - const auto &arg1 = ins->args[0]; - const auto &arg2 = ins->args[1]; + const auto &args = ins->getArgs(); + const auto &arg1 = args[0]; + const auto &arg2 = args[1]; LLVMRegister *reg1 = arg1.second; LLVMRegister *reg2 = arg2.second; if (reg1->type() == Compiler::StaticType::Bool && reg2->type() == Compiler::StaticType::Bool) { llvm::Value *bool1 = m_utils.castValue(arg1.second, Compiler::StaticType::Bool); llvm::Value *bool2 = m_utils.castValue(arg2.second, Compiler::StaticType::Bool); - ins->functionReturnReg->value = m_builder.CreateCall(m_utils.functions().resolve_llvm_random_bool(), { m_utils.executionContextPtr(), bool1, bool2 }); + ins->getFunctionReturnReg()->value = m_builder.CreateCall(m_utils.functions().resolve_llvm_random_bool(), { m_utils.executionContextPtr(), bool1, bool2 }); } else { llvm::Constant *inf = llvm::ConstantFP::getInfinity(m_builder.getDoubleTy(), false); llvm::Value *num1 = m_utils.removeNaN(m_utils.castValue(arg1.second, Compiler::StaticType::Number)); @@ -196,12 +201,13 @@ LLVMInstruction *Math::buildRandom(LLVMInstruction *ins) // NOTE: The random function will be called even in edge cases where it isn't needed, but they're rare, so it shouldn't be an issue if (reg1->type() == Compiler::StaticType::Number && reg2->type() == Compiler::StaticType::Number) - ins->functionReturnReg->value = + ins->getFunctionReturnReg()->value = m_builder.CreateSelect(isInfOrNaN, sum, m_builder.CreateCall(m_utils.functions().resolve_llvm_random_double(), { m_utils.executionContextPtr(), num1, num2 })); else { llvm::Value *value1 = m_utils.createValue(reg1); llvm::Value *value2 = m_utils.createValue(reg2); - ins->functionReturnReg->value = m_builder.CreateSelect(isInfOrNaN, sum, m_builder.CreateCall(m_utils.functions().resolve_llvm_random(), { m_utils.executionContextPtr(), value1, value2 })); + ins->getFunctionReturnReg()->value = + m_builder.CreateSelect(isInfOrNaN, sum, m_builder.CreateCall(m_utils.functions().resolve_llvm_random(), { m_utils.executionContextPtr(), value1, value2 })); } } @@ -211,14 +217,15 @@ LLVMInstruction *Math::buildRandom(LLVMInstruction *ins) LLVMInstruction *Math::buildRandomInt(LLVMInstruction *ins) { assert(ins->args.size() == 2); - const auto &arg1 = ins->args[0]; - const auto &arg2 = ins->args[1]; + const auto &args = ins->getArgs(); + const auto &arg1 = args[0]; + const auto &arg2 = args[1]; llvm::Value *from = m_builder.CreateFPToSI(m_utils.castValue(arg1.second, arg1.first), m_builder.getInt64Ty()); llvm::Value *to = m_builder.CreateFPToSI(m_utils.castValue(arg2.second, arg2.first), m_builder.getInt64Ty()); llvm::Value *intValue = m_builder.CreateCall(m_utils.functions().resolve_llvm_random_int64(), { m_utils.executionContextPtr(), from, to }); - ins->functionReturnReg->value = m_builder.CreateSIToFP(intValue, m_builder.getDoubleTy()); - ins->functionReturnReg->intValue = intValue; - ins->functionReturnReg->isInt = m_builder.getInt1(true); + ins->getFunctionReturnReg()->value = m_builder.CreateSIToFP(intValue, m_builder.getDoubleTy()); + ins->getFunctionReturnReg()->intValue = intValue; + ins->getFunctionReturnReg()->isInt = m_builder.getInt1(true); return ins->getNext(); } @@ -226,8 +233,9 @@ LLVMInstruction *Math::buildRandomInt(LLVMInstruction *ins) LLVMInstruction *Math::buildMod(LLVMInstruction *ins) { assert(ins->args.size() == 2); - const auto &arg1 = ins->args[0]; - const auto &arg2 = ins->args[1]; + const auto &args = ins->getArgs(); + const auto &arg1 = args[0]; + const auto &arg2 = args[1]; // double: rem(a, b) / b < 0.0 ? rem(a, b) + b : rem(a, b) llvm::Constant *doubleZero = llvm::ConstantFP::get(m_utils.llvmCtx(), llvm::APFloat(0.0)); @@ -235,7 +243,7 @@ LLVMInstruction *Math::buildMod(LLVMInstruction *ins) llvm::Value *double2 = m_utils.removeNaN(m_utils.castValue(arg2.second, arg2.first)); llvm::Value *doubleRem = m_builder.CreateFRem(double1, double2); // rem(a, b) llvm::Value *doubleCond = m_builder.CreateFCmpOLT(m_builder.CreateFDiv(doubleRem, double2), doubleZero); // rem(a, b) / b < 0.0 - ins->functionReturnReg->value = m_builder.CreateSelect(doubleCond, m_builder.CreateFAdd(doubleRem, double2), doubleRem); + ins->getFunctionReturnReg()->value = m_builder.CreateSelect(doubleCond, m_builder.CreateFAdd(doubleRem, double2), doubleRem); // int: b == 0 ? 0 (double fallback) : ((rem(a, b) < 0) != (b < 0) ? rem(a, b) + b : rem(a, b)) llvm::Constant *intZero = llvm::ConstantInt::get(m_builder.getInt64Ty(), 0, true); @@ -269,8 +277,8 @@ LLVMInstruction *Math::buildMod(LLVMInstruction *ins) isIntPhi->addIncoming(noInt, nanBlock); isIntPhi->addIncoming(isInt, intBlock); - ins->functionReturnReg->intValue = resultPhi; - ins->functionReturnReg->isInt = isIntPhi; + ins->getFunctionReturnReg()->intValue = resultPhi; + ins->getFunctionReturnReg()->isInt = isIntPhi; return ins->getNext(); } @@ -281,7 +289,8 @@ LLVMInstruction *Math::buildRound(LLVMInstruction *ins) llvm::Module *module = m_utils.module(); assert(ins->args.size() == 1); - const auto &arg = ins->args[0]; + const auto &args = ins->getArgs(); + const auto &arg = args[0]; // double: x >= 0.0 ? round(x) : (x >= -0.5 ? -0.0 : floor(x + 0.5)) llvm::Constant *zero = llvm::ConstantFP::get(llvmCtx, llvm::APFloat(0.0)); @@ -293,7 +302,7 @@ LLVMInstruction *Math::buildRound(LLVMInstruction *ins) llvm::Value *roundNum = m_builder.CreateCall(roundFunc, doubleValue); // round(num) llvm::Value *negativeCond = m_builder.CreateFCmpOGE(doubleValue, llvm::ConstantFP::get(llvmCtx, llvm::APFloat(-0.5))); // num >= -0.5 llvm::Value *negativeRound = m_builder.CreateCall(floorFunc, m_builder.CreateFAdd(doubleValue, llvm::ConstantFP::get(llvmCtx, llvm::APFloat(0.5)))); // floor(x + 0.5) - ins->functionReturnReg->value = m_builder.CreateSelect(notNegative, roundNum, m_builder.CreateSelect(negativeCond, negativeZero, negativeRound)); + ins->getFunctionReturnReg()->value = m_builder.CreateSelect(notNegative, roundNum, m_builder.CreateSelect(negativeCond, negativeZero, negativeRound)); // int: doubleX == inf || doubleX == -inf ? doubleX : intX llvm::Constant *posInf = llvm::ConstantFP::getInfinity(m_builder.getDoubleTy(), false); @@ -301,9 +310,9 @@ LLVMInstruction *Math::buildRound(LLVMInstruction *ins) llvm::Value *isInt = arg.second->isInt; llvm::Value *intValue = arg.second->intValue; llvm::Value *isNotInf = m_builder.CreateAnd(m_builder.CreateFCmpONE(doubleValue, posInf), m_builder.CreateFCmpONE(doubleValue, negInf)); - llvm::Value *cast = m_builder.CreateFPToSI(ins->functionReturnReg->value, m_builder.getInt64Ty()); - ins->functionReturnReg->isInt = isNotInf; - ins->functionReturnReg->intValue = m_builder.CreateSelect(isInt, intValue, cast); + llvm::Value *cast = m_builder.CreateFPToSI(ins->getFunctionReturnReg()->value, m_builder.getInt64Ty()); + ins->getFunctionReturnReg()->isInt = isNotInf; + ins->getFunctionReturnReg()->intValue = m_builder.CreateSelect(isInt, intValue, cast); return ins->getNext(); } @@ -311,16 +320,17 @@ LLVMInstruction *Math::buildRound(LLVMInstruction *ins) LLVMInstruction *Math::buildAbs(LLVMInstruction *ins) { assert(ins->args.size() == 1); - const auto &arg = ins->args[0]; + const auto &args = ins->getArgs(); + const auto &arg = args[0]; llvm::Function *fabsFunc = llvm::Intrinsic::getDeclaration(m_utils.module(), llvm::Intrinsic::fabs, m_builder.getDoubleTy()); llvm::Value *doubleValue = m_utils.removeNaN(m_utils.castValue(arg.second, arg.first)); - ins->functionReturnReg->value = m_builder.CreateCall(fabsFunc, doubleValue); + ins->getFunctionReturnReg()->value = m_builder.CreateCall(fabsFunc, doubleValue); llvm::Function *absFunc = llvm::Intrinsic::getDeclaration(m_utils.module(), llvm::Intrinsic::abs, m_builder.getInt64Ty()); llvm::Value *intValue = arg.second->intValue; - ins->functionReturnReg->isInt = arg.second->isInt; - ins->functionReturnReg->intValue = m_builder.CreateCall(absFunc, { intValue, m_builder.getInt1(false) }); + ins->getFunctionReturnReg()->isInt = arg.second->isInt; + ins->getFunctionReturnReg()->intValue = m_builder.CreateCall(absFunc, { intValue, m_builder.getInt1(false) }); return ins->getNext(); } @@ -328,12 +338,13 @@ LLVMInstruction *Math::buildAbs(LLVMInstruction *ins) LLVMInstruction *Math::buildFloor(LLVMInstruction *ins) { assert(ins->args.size() == 1); - const auto &arg = ins->args[0]; + const auto &args = ins->getArgs(); + const auto &arg = args[0]; // double: floor(doubleX) llvm::Function *floorFunc = llvm::Intrinsic::getDeclaration(m_utils.module(), llvm::Intrinsic::floor, m_builder.getDoubleTy()); llvm::Value *doubleValue = m_utils.removeNaN(m_utils.castValue(arg.second, arg.first)); - ins->functionReturnReg->value = m_builder.CreateCall(floorFunc, doubleValue); + ins->getFunctionReturnReg()->value = m_builder.CreateCall(floorFunc, doubleValue); // int: doubleX == inf || doubleX == -inf ? doubleX : intX llvm::Constant *posInf = llvm::ConstantFP::getInfinity(m_builder.getDoubleTy(), false); @@ -341,9 +352,9 @@ LLVMInstruction *Math::buildFloor(LLVMInstruction *ins) llvm::Value *isInt = arg.second->isInt; llvm::Value *intValue = arg.second->intValue; llvm::Value *isNotInf = m_builder.CreateAnd(m_builder.CreateFCmpONE(doubleValue, posInf), m_builder.CreateFCmpONE(doubleValue, negInf)); - llvm::Value *cast = m_builder.CreateFPToSI(ins->functionReturnReg->value, m_builder.getInt64Ty()); - ins->functionReturnReg->isInt = isNotInf; - ins->functionReturnReg->intValue = m_builder.CreateSelect(isInt, intValue, cast); + llvm::Value *cast = m_builder.CreateFPToSI(ins->getFunctionReturnReg()->value, m_builder.getInt64Ty()); + ins->getFunctionReturnReg()->isInt = isNotInf; + ins->getFunctionReturnReg()->intValue = m_builder.CreateSelect(isInt, intValue, cast); return ins->getNext(); } @@ -351,12 +362,13 @@ LLVMInstruction *Math::buildFloor(LLVMInstruction *ins) LLVMInstruction *Math::buildCeil(LLVMInstruction *ins) { assert(ins->args.size() == 1); - const auto &arg = ins->args[0]; + const auto &args = ins->getArgs(); + const auto &arg = args[0]; // double: ceil(doubleX) llvm::Function *ceilFunc = llvm::Intrinsic::getDeclaration(m_utils.module(), llvm::Intrinsic::ceil, m_builder.getDoubleTy()); llvm::Value *doubleValue = m_utils.removeNaN(m_utils.castValue(arg.second, arg.first)); - ins->functionReturnReg->value = m_builder.CreateCall(ceilFunc, doubleValue); + ins->getFunctionReturnReg()->value = m_builder.CreateCall(ceilFunc, doubleValue); // int: doubleX == inf || doubleX == -inf ? doubleX : intX llvm::Constant *posInf = llvm::ConstantFP::getInfinity(m_builder.getDoubleTy(), false); @@ -364,9 +376,9 @@ LLVMInstruction *Math::buildCeil(LLVMInstruction *ins) llvm::Value *isInt = arg.second->isInt; llvm::Value *intValue = arg.second->intValue; llvm::Value *isNotInf = m_builder.CreateAnd(m_builder.CreateFCmpONE(doubleValue, posInf), m_builder.CreateFCmpONE(doubleValue, negInf)); - llvm::Value *cast = m_builder.CreateFPToSI(ins->functionReturnReg->value, m_builder.getInt64Ty()); - ins->functionReturnReg->isInt = isNotInf; - ins->functionReturnReg->intValue = m_builder.CreateSelect(isInt, intValue, cast); + llvm::Value *cast = m_builder.CreateFPToSI(ins->getFunctionReturnReg()->value, m_builder.getInt64Ty()); + ins->getFunctionReturnReg()->isInt = isNotInf; + ins->getFunctionReturnReg()->intValue = m_builder.CreateSelect(isInt, intValue, cast); return ins->getNext(); } @@ -374,13 +386,15 @@ LLVMInstruction *Math::buildCeil(LLVMInstruction *ins) LLVMInstruction *Math::buildSqrt(LLVMInstruction *ins) { assert(ins->args.size() == 1); - const auto &arg = ins->args[0]; + const auto &args = ins->getArgs(); + const auto &arg = args[0]; + // sqrt(x) + 0.0 // This avoids negative zero llvm::Constant *zero = llvm::ConstantFP::get(m_utils.llvmCtx(), llvm::APFloat(0.0)); llvm::Function *sqrtFunc = llvm::Intrinsic::getDeclaration(m_utils.module(), llvm::Intrinsic::sqrt, m_builder.getDoubleTy()); llvm::Value *num = m_utils.removeNaN(m_utils.castValue(arg.second, arg.first)); - ins->functionReturnReg->value = m_builder.CreateFAdd(m_builder.CreateCall(sqrtFunc, num), zero); + ins->getFunctionReturnReg()->value = m_builder.CreateFAdd(m_builder.CreateCall(sqrtFunc, num), zero); return ins->getNext(); } @@ -391,7 +405,9 @@ LLVMInstruction *Math::buildSin(LLVMInstruction *ins) llvm::Module *module = m_utils.module(); assert(ins->args.size() == 1); - const auto &arg = ins->args[0]; + const auto &args = ins->getArgs(); + const auto &arg = args[0]; + // round(sin(x * pi / 180.0) * 1e10) / 1e10 + 0.0 // +0.0 to avoid -0.0 llvm::Constant *zero = llvm::ConstantFP::get(llvmCtx, llvm::APFloat(0.0)); @@ -403,7 +419,7 @@ LLVMInstruction *Math::buildSin(LLVMInstruction *ins) llvm::Value *num = m_utils.removeNaN(m_utils.castValue(arg.second, arg.first)); llvm::Value *sinResult = m_builder.CreateCall(sinFunc, m_builder.CreateFDiv(m_builder.CreateFMul(num, pi), piDeg)); // sin(x * pi / 180) llvm::Value *rounded = m_builder.CreateCall(roundFunc, m_builder.CreateFMul(sinResult, factor)); // round(sin(x * 180) * 1e10) - ins->functionReturnReg->value = m_builder.CreateFAdd(m_builder.CreateFDiv(rounded, factor), zero); + ins->getFunctionReturnReg()->value = m_builder.CreateFAdd(m_builder.CreateFDiv(rounded, factor), zero); return ins->getNext(); } @@ -414,7 +430,9 @@ LLVMInstruction *Math::buildCos(LLVMInstruction *ins) llvm::Module *module = m_utils.module(); assert(ins->args.size() == 1); - const auto &arg = ins->args[0]; + const auto &args = ins->getArgs(); + const auto &arg = args[0]; + // round(cos(x * pi / 180.0) * 1e10) / 1e10 llvm::Constant *pi = llvm::ConstantFP::get(llvmCtx, llvm::APFloat(std::acos(-1.0))); llvm::Constant *piDeg = llvm::ConstantFP::get(llvmCtx, llvm::APFloat(180.0)); @@ -424,7 +442,7 @@ LLVMInstruction *Math::buildCos(LLVMInstruction *ins) llvm::Value *num = m_utils.removeNaN(m_utils.castValue(arg.second, arg.first)); llvm::Value *cosResult = m_builder.CreateCall(cosFunc, m_builder.CreateFDiv(m_builder.CreateFMul(num, pi), piDeg)); // cos(x * pi / 180) llvm::Value *rounded = m_builder.CreateCall(roundFunc, m_builder.CreateFMul(cosResult, factor)); // round(cos(x * 180) * 1e10) - ins->functionReturnReg->value = m_builder.CreateFDiv(rounded, factor); + ins->getFunctionReturnReg()->value = m_builder.CreateFDiv(rounded, factor); return ins->getNext(); } @@ -435,7 +453,9 @@ LLVMInstruction *Math::buildTan(LLVMInstruction *ins) llvm::Module *module = m_utils.module(); assert(ins->args.size() == 1); - const auto &arg = ins->args[0]; + const auto &args = ins->getArgs(); + const auto &arg = args[0]; + // ((mod = rem(x, 360.0)) == -270.0 || mod == 90.0) ? inf : ((mod == -90.0 || mod == 270.0) ? -inf : round(tan(x * pi / 180.0) * 1e10) / 1e10 + 0.0) // +0.0 to avoid -0.0 llvm::Constant *zero = llvm::ConstantFP::get(llvmCtx, llvm::APFloat(0.0)); @@ -461,7 +481,7 @@ LLVMInstruction *Math::buildTan(LLVMInstruction *ins) llvm::Value *rounded = m_builder.CreateCall(roundFunc, m_builder.CreateFMul(tanResult, factor)); // round(tan(x * 180) * 1e10) llvm::Value *result = m_builder.CreateFAdd(m_builder.CreateFDiv(rounded, factor), zero); // round(tan(x * pi / 180.0) * 1e10) / 1e10 + 0.0 llvm::Value *inner = m_builder.CreateSelect(m_builder.CreateOr(isUndefined3, isUndefined4), negInf, result); - ins->functionReturnReg->value = m_builder.CreateSelect(m_builder.CreateOr(isUndefined1, isUndefined2), posInf, inner); + ins->getFunctionReturnReg()->value = m_builder.CreateSelect(m_builder.CreateOr(isUndefined1, isUndefined2), posInf, inner); return ins->getNext(); } @@ -471,7 +491,9 @@ LLVMInstruction *Math::buildAsin(LLVMInstruction *ins) llvm::LLVMContext &llvmCtx = m_utils.llvmCtx(); assert(ins->args.size() == 1); - const auto &arg = ins->args[0]; + const auto &args = ins->getArgs(); + const auto &arg = args[0]; + // asin(x) * 180.0 / pi + 0.0 // +0.0 to avoid -0.0 llvm::Constant *zero = llvm::ConstantFP::get(llvmCtx, llvm::APFloat(0.0)); @@ -479,7 +501,7 @@ LLVMInstruction *Math::buildAsin(LLVMInstruction *ins) llvm::Constant *piDeg = llvm::ConstantFP::get(llvmCtx, llvm::APFloat(180.0)); llvm::Function *asinFunc = llvm::Intrinsic::getDeclaration(m_utils.module(), llvm::Intrinsic::asin, m_builder.getDoubleTy()); llvm::Value *num = m_utils.removeNaN(m_utils.castValue(arg.second, arg.first)); - ins->functionReturnReg->value = m_builder.CreateFAdd(m_builder.CreateFDiv(m_builder.CreateFMul(m_builder.CreateCall(asinFunc, num), piDeg), pi), zero); + ins->getFunctionReturnReg()->value = m_builder.CreateFAdd(m_builder.CreateFDiv(m_builder.CreateFMul(m_builder.CreateCall(asinFunc, num), piDeg), pi), zero); return ins->getNext(); } @@ -489,13 +511,15 @@ LLVMInstruction *Math::buildAcos(LLVMInstruction *ins) llvm::LLVMContext &llvmCtx = m_utils.llvmCtx(); assert(ins->args.size() == 1); - const auto &arg = ins->args[0]; + const auto &args = ins->getArgs(); + const auto &arg = args[0]; + // acos(x) * 180.0 / pi llvm::Constant *pi = llvm::ConstantFP::get(llvmCtx, llvm::APFloat(std::acos(-1.0))); llvm::Constant *piDeg = llvm::ConstantFP::get(llvmCtx, llvm::APFloat(180.0)); llvm::Function *acosFunc = llvm::Intrinsic::getDeclaration(m_utils.module(), llvm::Intrinsic::acos, m_builder.getDoubleTy()); llvm::Value *num = m_utils.removeNaN(m_utils.castValue(arg.second, arg.first)); - ins->functionReturnReg->value = m_builder.CreateFDiv(m_builder.CreateFMul(m_builder.CreateCall(acosFunc, num), piDeg), pi); + ins->getFunctionReturnReg()->value = m_builder.CreateFDiv(m_builder.CreateFMul(m_builder.CreateCall(acosFunc, num), piDeg), pi); return ins->getNext(); } @@ -505,13 +529,15 @@ LLVMInstruction *Math::buildAtan(LLVMInstruction *ins) llvm::LLVMContext &llvmCtx = m_utils.llvmCtx(); assert(ins->args.size() == 1); - const auto &arg = ins->args[0]; + const auto &args = ins->getArgs(); + const auto &arg = args[0]; + // atan(x) * 180.0 / pi llvm::Constant *pi = llvm::ConstantFP::get(llvmCtx, llvm::APFloat(std::acos(-1.0))); llvm::Constant *piDeg = llvm::ConstantFP::get(llvmCtx, llvm::APFloat(180.0)); llvm::Function *atanFunc = llvm::Intrinsic::getDeclaration(m_utils.module(), llvm::Intrinsic::atan, m_builder.getDoubleTy()); llvm::Value *num = m_utils.removeNaN(m_utils.castValue(arg.second, arg.first)); - ins->functionReturnReg->value = m_builder.CreateFDiv(m_builder.CreateFMul(m_builder.CreateCall(atanFunc, num), piDeg), pi); + ins->getFunctionReturnReg()->value = m_builder.CreateFDiv(m_builder.CreateFMul(m_builder.CreateCall(atanFunc, num), piDeg), pi); return ins->getNext(); } @@ -519,11 +545,13 @@ LLVMInstruction *Math::buildAtan(LLVMInstruction *ins) LLVMInstruction *Math::buildLn(LLVMInstruction *ins) { assert(ins->args.size() == 1); - const auto &arg = ins->args[0]; + const auto &args = ins->getArgs(); + const auto &arg = args[0]; + // log(x) llvm::Function *logFunc = llvm::Intrinsic::getDeclaration(m_utils.module(), llvm::Intrinsic::log, m_builder.getDoubleTy()); llvm::Value *num = m_utils.removeNaN(m_utils.castValue(arg.second, arg.first)); - ins->functionReturnReg->value = m_builder.CreateCall(logFunc, num); + ins->getFunctionReturnReg()->value = m_builder.CreateCall(logFunc, num); return ins->getNext(); } @@ -531,11 +559,13 @@ LLVMInstruction *Math::buildLn(LLVMInstruction *ins) LLVMInstruction *Math::buildLog10(LLVMInstruction *ins) { assert(ins->args.size() == 1); - const auto &arg = ins->args[0]; + const auto &args = ins->getArgs(); + const auto &arg = args[0]; + // log10(x) llvm::Function *log10Func = llvm::Intrinsic::getDeclaration(m_utils.module(), llvm::Intrinsic::log10, m_builder.getDoubleTy()); llvm::Value *num = m_utils.removeNaN(m_utils.castValue(arg.second, arg.first)); - ins->functionReturnReg->value = m_builder.CreateCall(log10Func, num); + ins->getFunctionReturnReg()->value = m_builder.CreateCall(log10Func, num); return ins->getNext(); } @@ -543,11 +573,13 @@ LLVMInstruction *Math::buildLog10(LLVMInstruction *ins) LLVMInstruction *Math::buildExp(LLVMInstruction *ins) { assert(ins->args.size() == 1); - const auto &arg = ins->args[0]; + const auto &args = ins->getArgs(); + const auto &arg = args[0]; + // exp(x) llvm::Function *expFunc = llvm::Intrinsic::getDeclaration(m_utils.module(), llvm::Intrinsic::exp, m_builder.getDoubleTy()); llvm::Value *num = m_utils.removeNaN(m_utils.castValue(arg.second, arg.first)); - ins->functionReturnReg->value = m_builder.CreateCall(expFunc, num); + ins->getFunctionReturnReg()->value = m_builder.CreateCall(expFunc, num); return ins->getNext(); } @@ -555,11 +587,13 @@ LLVMInstruction *Math::buildExp(LLVMInstruction *ins) LLVMInstruction *Math::buildExp10(LLVMInstruction *ins) { assert(ins->args.size() == 1); - const auto &arg = ins->args[0]; + const auto &args = ins->getArgs(); + const auto &arg = args[0]; + // exp10(x) llvm::Function *expFunc = llvm::Intrinsic::getDeclaration(m_utils.module(), llvm::Intrinsic::exp10, m_builder.getDoubleTy()); llvm::Value *num = m_utils.removeNaN(m_utils.castValue(arg.second, arg.first)); - ins->functionReturnReg->value = m_builder.CreateCall(expFunc, num); + ins->getFunctionReturnReg()->value = m_builder.CreateCall(expFunc, num); return ins->getNext(); } diff --git a/src/engine/internal/codegen/llvm/instructions/procedures.cpp b/src/engine/internal/codegen/llvm/instructions/procedures.cpp index ed80f7faf..d6d522834 100644 --- a/src/engine/internal/codegen/llvm/instructions/procedures.cpp +++ b/src/engine/internal/codegen/llvm/instructions/procedures.cpp @@ -59,7 +59,9 @@ LLVMInstruction *Procedures::buildCallProcedure(LLVMInstruction *ins) args.push_back(m_utils.procedurePrototype() ? m_utils.warpArg() : m_builder.getInt1(false)); // Add procedure args - for (const auto &arg : ins->args) { + const auto &insArgs = ins->getArgs(); + + for (const auto &arg : insArgs) { if (m_utils.isSingleType(arg.first)) args.push_back(m_utils.castValue(arg.second, arg.first)); else @@ -107,7 +109,7 @@ LLVMInstruction *Procedures::buildProcedureArg(LLVMInstruction *ins) llvm::FunctionType *funcType = m_utils.scriptFunctionType(nullptr); int passArgCount = funcType->getNumParams(); llvm::Value *arg = m_utils.function()->getArg(passArgCount + 1 + ins->procedureArgIndex); // omit warp arg - ins->functionReturnReg->value = arg; + ins->getFunctionReturnReg()->value = arg; return ins->getNext(); } diff --git a/src/engine/internal/codegen/llvm/instructions/string.cpp b/src/engine/internal/codegen/llvm/instructions/string.cpp index ba8cc331c..277b6468f 100644 --- a/src/engine/internal/codegen/llvm/instructions/string.cpp +++ b/src/engine/internal/codegen/llvm/instructions/string.cpp @@ -36,8 +36,9 @@ ProcessResult String::process(LLVMInstruction *ins) LLVMInstruction *String::buildStringConcat(LLVMInstruction *ins) { assert(ins->args.size() == 2); - const auto &arg1 = ins->args[0]; - const auto &arg2 = ins->args[1]; + const auto &args = ins->getArgs(); + const auto &arg1 = args[0]; + const auto &arg2 = args[1]; llvm::Value *str1 = m_utils.castValue(arg1.second, arg1.first); llvm::Value *str2 = m_utils.castValue(arg2.second, arg2.first); llvm::PointerType *charPointerType = m_builder.getInt16Ty()->getPointerTo(); @@ -73,7 +74,7 @@ LLVMInstruction *String::buildStringConcat(LLVMInstruction *ins) writePtr = m_builder.CreateGEP(m_builder.getInt16Ty(), writePtr, size1); m_builder.CreateCall(memcpyFunc, { writePtr, data2, m_builder.CreateMul(m_builder.CreateAdd(size2, m_builder.getInt64(1)), m_builder.getInt64(2)), m_builder.getInt1(false) }); - ins->functionReturnReg->value = result; + ins->getFunctionReturnReg()->value = result; return ins->getNext(); } @@ -81,8 +82,9 @@ LLVMInstruction *String::buildStringConcat(LLVMInstruction *ins) LLVMInstruction *String::buildStringChar(LLVMInstruction *ins) { assert(ins->args.size() == 2); - const auto &arg1 = ins->args[0]; - const auto &arg2 = ins->args[1]; + const auto &args = ins->getArgs(); + const auto &arg1 = args[0]; + const auto &arg2 = args[1]; llvm::Value *str = m_utils.castValue(arg1.second, arg1.first); llvm::Value *index = m_utils.castValue(arg2.second, arg2.first, LLVMBuildUtils::NumberType::Int); llvm::PointerType *charPointerType = m_builder.getInt16Ty()->getPointerTo(); @@ -114,7 +116,7 @@ LLVMInstruction *String::buildStringChar(LLVMInstruction *ins) m_builder.CreateStore(m_builder.getInt16(0), char2); m_builder.CreateStore(m_builder.CreateSelect(inRange, m_builder.getInt64(1), m_builder.getInt64(0)), sizeField); - ins->functionReturnReg->value = result; + ins->getFunctionReturnReg()->value = result; return ins->getNext(); } @@ -124,13 +126,14 @@ LLVMInstruction *String::buildStringLength(LLVMInstruction *ins) llvm::StructType *stringPtrType = m_utils.compilerCtx()->stringPtrType(); assert(ins->args.size() == 1); - const auto &arg = ins->args[0]; + const auto &args = ins->getArgs(); + const auto &arg = args[0]; llvm::Value *str = m_utils.castValue(arg.second, arg.first); llvm::Value *sizeField = m_builder.CreateStructGEP(stringPtrType, str, 1); llvm::Value *size = m_builder.CreateLoad(m_builder.getInt64Ty(), sizeField); - ins->functionReturnReg->value = m_builder.CreateSIToFP(size, m_builder.getDoubleTy()); - ins->functionReturnReg->intValue = size; - ins->functionReturnReg->isInt = m_builder.getInt1(true); + ins->getFunctionReturnReg()->value = m_builder.CreateSIToFP(size, m_builder.getDoubleTy()); + ins->getFunctionReturnReg()->intValue = size; + ins->getFunctionReturnReg()->isInt = m_builder.getInt1(true); return ins->getNext(); } diff --git a/src/engine/internal/codegen/llvm/instructions/variables.cpp b/src/engine/internal/codegen/llvm/instructions/variables.cpp index 0d6ce25a5..04382ac3b 100644 --- a/src/engine/internal/codegen/llvm/instructions/variables.cpp +++ b/src/engine/internal/codegen/llvm/instructions/variables.cpp @@ -4,6 +4,7 @@ #include "../llvminstruction.h" #include "../llvmbuildutils.h" #include "../llvmconstantregister.h" +#include "../../optimizationutils.h" using namespace libscratchcpp; using namespace libscratchcpp::llvmins; @@ -51,16 +52,17 @@ LLVMInstruction *Variables::buildCreateLocalVariable(LLVMInstruction *ins) m_builder.CreateStore(m_builder.getInt1(false), info->isInt); m_builder.CreateStore(llvm::ConstantInt::get(m_builder.getInt64Ty(), 0, true), info->isInt); - LLVMConstantRegister null(ins->functionReturnReg->type(), Value()); - ins->functionReturnReg->value = m_utils.createValue(&null); + LLVMConstantRegister null(ins->getFunctionReturnReg()->type(), Value()); + ins->getFunctionReturnReg()->value = m_utils.createValue(&null); return ins->getNext(); } LLVMInstruction *Variables::buildWriteLocalVariable(LLVMInstruction *ins) { assert(ins->args.size() == 2); - const auto &arg1 = ins->args[0]; - const auto &arg2 = ins->args[1]; + const auto &args = ins->getArgs(); + const auto &arg1 = args[0]; + const auto &arg2 = args[1]; LLVMLocalVariableInfo *info = ins->localVarInfo; llvm::Value *typeVar = m_utils.addAlloca(m_builder.getInt32Ty()); m_builder.CreateStore(m_builder.getInt32(static_cast(m_utils.mapType(arg2.first))), typeVar); @@ -72,19 +74,21 @@ LLVMInstruction *Variables::buildWriteLocalVariable(LLVMInstruction *ins) LLVMInstruction *Variables::buildReadLocalVariable(LLVMInstruction *ins) { assert(ins->args.size() == 1); - const auto &arg = ins->args[0]; + const auto &args = ins->getArgs(); + const auto &arg = args[0]; LLVMLocalVariableInfo *info = ins->localVarInfo; - ins->functionReturnReg->value = m_utils.castValue(arg.second, ins->functionReturnReg->type()); - ins->functionReturnReg->isInt = m_builder.CreateLoad(m_builder.getInt1Ty(), info->isInt); - ins->functionReturnReg->intValue = m_builder.CreateLoad(m_builder.getInt64Ty(), info->intValue); + ins->getFunctionReturnReg()->value = m_utils.castValue(arg.second, ins->getFunctionReturnReg()->type()); + ins->getFunctionReturnReg()->isInt = m_builder.CreateLoad(m_builder.getInt1Ty(), info->isInt); + ins->getFunctionReturnReg()->intValue = m_builder.CreateLoad(m_builder.getInt64Ty(), info->intValue); return ins->getNext(); } LLVMInstruction *Variables::buildWriteVariable(LLVMInstruction *ins) { assert(ins->args.size() == 1); - const auto &arg = ins->args[0]; - Compiler::StaticType argType = m_utils.optimizeRegisterType(arg.second); + const auto &args = ins->getArgs(); + const auto &arg = args[0]; + Compiler::StaticType argType = OptimizationUtils::optimizeValueType(m_utils.compilerCtx(), arg.second); LLVMVariablePtr &varPtr = m_utils.variablePtr(ins->targetVariable); m_utils.createValueStore(varPtr.stackPtr, m_utils.getValueTypePtr(varPtr.stackPtr), varPtr.isInt, varPtr.intValue, arg.second, ins->targetType, argType); @@ -97,8 +101,8 @@ LLVMInstruction *Variables::buildReadVariable(LLVMInstruction *ins) assert(ins->args.size() == 0); LLVMVariablePtr &varPtr = m_utils.variablePtr(ins->targetVariable); - ins->functionReturnReg->value = varPtr.stackPtr; - ins->functionReturnReg->isInt = m_builder.CreateLoad(m_builder.getInt1Ty(), varPtr.isInt); - ins->functionReturnReg->intValue = m_builder.CreateLoad(m_builder.getInt64Ty(), varPtr.intValue); + ins->getFunctionReturnReg()->value = varPtr.stackPtr; + ins->getFunctionReturnReg()->isInt = m_builder.CreateLoad(m_builder.getInt1Ty(), varPtr.isInt); + ins->getFunctionReturnReg()->intValue = m_builder.CreateLoad(m_builder.getInt64Ty(), varPtr.intValue); return ins->getNext(); } diff --git a/src/engine/internal/codegen/llvm/llvmbuildutils.cpp b/src/engine/internal/codegen/llvm/llvmbuildutils.cpp index 037fdeb63..804c03905 100644 --- a/src/engine/internal/codegen/llvm/llvmbuildutils.cpp +++ b/src/engine/internal/codegen/llvm/llvmbuildutils.cpp @@ -176,7 +176,7 @@ void LLVMBuildUtils::end(LLVMInstruction *lastInstruction, LLVMRegister *lastCon case Compiler::CodeType::Reporter: { // Use last instruction return value (or last constant) and create a ValueData instance assert(lastInstruction || lastConstant); - LLVMRegister *ret = lastInstruction ? lastInstruction->functionReturnReg : lastConstant; + LLVMRegister *ret = lastInstruction ? lastInstruction->getFunctionReturnReg() : lastConstant; llvm::Value *copy = createNewValue(ret); m_builder.CreateRet(m_builder.CreateLoad(m_valueDataType, copy)); break; @@ -187,7 +187,7 @@ void LLVMBuildUtils::end(LLVMInstruction *lastInstruction, LLVMRegister *lastCon assert(lastInstruction || lastConstant); if (lastInstruction) - m_builder.CreateRet(castValue(lastInstruction->functionReturnReg, Compiler::StaticType::Bool)); + m_builder.CreateRet(castValue(lastInstruction->getFunctionReturnReg(), Compiler::StaticType::Bool)); else m_builder.CreateRet(castValue(lastConstant, Compiler::StaticType::Bool)); break; diff --git a/src/engine/internal/codegen/llvm/llvmcodebuilder.cpp b/src/engine/internal/codegen/llvm/llvmcodebuilder.cpp index 7621e1e0d..39018f548 100644 --- a/src/engine/internal/codegen/llvm/llvmcodebuilder.cpp +++ b/src/engine/internal/codegen/llvm/llvmcodebuilder.cpp @@ -114,7 +114,7 @@ CompilerValue *LLVMCodeBuilder::addFunctionCall(const std::string &functionName, if (m_utils.isSingleType(returnType)) reg->isRawValue = true; - ins->functionReturnReg = reg.get(); + ins->setFunctionReturnReg(reg.get()); return addReg(reg, ins); } @@ -167,7 +167,7 @@ CompilerValue *LLVMCodeBuilder::addLocalVariableValue(CompilerLocalVariable *var auto ret = std::make_shared(variable->type()); ret->isRawValue = false; - ins->functionReturnReg = ret.get(); + ins->setFunctionReturnReg(ret.get()); m_instructions.addInstruction(ins); return addReg(ret, ins); @@ -181,7 +181,7 @@ CompilerValue *LLVMCodeBuilder::addVariableValue(Variable *variable) auto ret = std::make_shared(Compiler::StaticType::Unknown); ret->isRawValue = false; - ins->functionReturnReg = ret.get(); + ins->setFunctionReturnReg(ret.get()); m_instructions.addInstruction(ins); return addReg(ret, ins); @@ -206,7 +206,7 @@ CompilerValue *LLVMCodeBuilder::addListItem(List *list, CompilerValue *index) auto ret = std::make_shared(Compiler::StaticType::Unknown); ret->isRawValue = false; - ins->functionReturnReg = ret.get(); + ins->setFunctionReturnReg(ret.get()); m_instructions.addInstruction(ins); return addReg(ret, ins); @@ -259,7 +259,7 @@ CompilerValue *LLVMCodeBuilder::addProcedureArgument(const std::string &name) auto ins = std::make_shared(LLVMInstruction::Type::ProcedureArg, m_loopCondition); auto ret = std::make_shared(type); ret->isRawValue = (type != Compiler::StaticType::Unknown); - ins->functionReturnReg = ret.get(); + ins->setFunctionReturnReg(ret.get()); ins->procedureArgIndex = index; m_instructions.addInstruction(ins); From 8d82978f3616bde9dc21675fa4e31e0424833113 Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Sun, 25 Oct 2026 00:12:12 +0200 Subject: [PATCH 11/13] Move code analyzer out from llvm --- src/engine/internal/codegen/CMakeLists.txt | 4 + .../llvmcodeanalyzer.cpp => codeanalyzer.cpp} | 82 +- src/engine/internal/codegen/codeanalyzer.h | 64 ++ .../internal/codegen/llvm/CMakeLists.txt | 2 - .../internal/codegen/llvm/llvmbuildutils.cpp | 24 +- .../internal/codegen/llvm/llvmbuildutils.h | 2 - .../internal/codegen/llvm/llvmcodeanalyzer.h | 64 -- .../internal/codegen/llvm/llvmcodebuilder.cpp | 2 +- .../internal/codegen/llvm/llvmcodebuilder.h | 4 +- .../internal/codegen/optimizationutils.cpp | 29 + .../internal/codegen/optimizationutils.h | 16 + .../llvm/code_analyzer/list_type_analysis.cpp | 840 +++++++++--------- .../code_analyzer/mixed_type_analysis.cpp | 257 +++--- .../code_analyzer/variable_type_analysis.cpp | 776 ++++++++-------- 14 files changed, 1054 insertions(+), 1112 deletions(-) rename src/engine/internal/codegen/{llvm/llvmcodeanalyzer.cpp => codeanalyzer.cpp} (75%) create mode 100644 src/engine/internal/codegen/codeanalyzer.h delete mode 100644 src/engine/internal/codegen/llvm/llvmcodeanalyzer.h create mode 100644 src/engine/internal/codegen/optimizationutils.cpp create mode 100644 src/engine/internal/codegen/optimizationutils.h diff --git a/src/engine/internal/codegen/CMakeLists.txt b/src/engine/internal/codegen/CMakeLists.txt index d73063fc1..bb278efb3 100644 --- a/src/engine/internal/codegen/CMakeLists.txt +++ b/src/engine/internal/codegen/CMakeLists.txt @@ -9,6 +9,10 @@ target_sources(scratchcpp instructionlistbase.cpp instructionlistbase.h instructionlist.h + codeanalyzer.cpp + codeanalyzer.h + optimizationutils.cpp + optimizationutils.h ) add_subdirectory(llvm) diff --git a/src/engine/internal/codegen/llvm/llvmcodeanalyzer.cpp b/src/engine/internal/codegen/codeanalyzer.cpp similarity index 75% rename from src/engine/internal/codegen/llvm/llvmcodeanalyzer.cpp rename to src/engine/internal/codegen/codeanalyzer.cpp index c917e1165..fdb26b02c 100644 --- a/src/engine/internal/codegen/llvm/llvmcodeanalyzer.cpp +++ b/src/engine/internal/codegen/codeanalyzer.cpp @@ -1,27 +1,29 @@ // SPDX-License-Identifier: Apache-2.0 -#include "llvmcodeanalyzer.h" -#include "llvminstructionlist.h" -#include "llvminstruction.h" -#include "llvmbuildutils.h" +#include + +#include "codeanalyzer.h" +#include "instructionlistbase.h" +#include "instructionbase.h" +#include "optimizationutils.h" using namespace libscratchcpp; // NOTE: The loop condition in repeat until and while loops is considered a part of the loop body -static const std::unordered_set BEGIN_LOOP_INSTRUCTIONS = { LLVMInstruction::Type::BeginRepeatLoop, LLVMInstruction::Type::BeginLoopCondition }; +static const std::unordered_set BEGIN_LOOP_INSTRUCTIONS = { InstructionBase::Type::BeginRepeatLoop, InstructionBase::Type::BeginLoopCondition }; -static const std::unordered_set LIST_WRITE_INSTRUCTIONS = { LLVMInstruction::Type::AppendToList, LLVMInstruction::Type::InsertToList, LLVMInstruction::Type::ListReplace }; +static const std::unordered_set LIST_WRITE_INSTRUCTIONS = { InstructionBase::Type::AppendToList, InstructionBase::Type::InsertToList, InstructionBase::Type::ListReplace }; -LLVMCodeAnalyzer::LLVMCodeAnalyzer(const LLVMBuildUtils &utils) : - m_utils(utils) +CodeAnalyzer::CodeAnalyzer(CompilerContext *ctx) : + m_ctx(ctx) { } -void LLVMCodeAnalyzer::analyzeScript(const LLVMInstructionList &script) const +void CodeAnalyzer::analyzeScript(const InstructionListBase &script) const { - std::unordered_set typeAssignedInstructions; + std::unordered_set typeAssignedInstructions; std::vector> branches; - LLVMInstruction *ins = script.first(); + InstructionBase *ins = script.first(); auto topBranch = std::make_unique(); topBranch->start = ins; @@ -148,14 +150,14 @@ void LLVMCodeAnalyzer::analyzeScript(const LLVMInstructionList &script) const typeAssignedInstructions.insert(ins); } - ins = ins->getNext(); + ins = ins->next; } assert(branches.size() == 1); assert(branches.back().get() == topBranchPtr); } -void LLVMCodeAnalyzer::updateVariableType(Branch *branch, LLVMInstruction *ins, std::unordered_set &typeAssignedInstructions, bool isWrite) const +void CodeAnalyzer::updateVariableType(Branch *branch, InstructionBase *ins, std::unordered_set &typeAssignedInstructions, bool isWrite) const { auto it = branch->variableTypes.find(ins->targetVariable); @@ -182,7 +184,7 @@ void LLVMCodeAnalyzer::updateVariableType(Branch *branch, LLVMInstruction *ins, } } -void LLVMCodeAnalyzer::updateListType(Branch *branch, LLVMInstruction *ins, std::unordered_set &typeAssignedInstructions, bool isWrite) const +void CodeAnalyzer::updateListType(Branch *branch, InstructionBase *ins, std::unordered_set &typeAssignedInstructions, bool isWrite) const { auto it = branch->listTypes.find(ins->targetList); @@ -211,7 +213,7 @@ void LLVMCodeAnalyzer::updateListType(Branch *branch, LLVMInstruction *ins, std: } } -void LLVMCodeAnalyzer::mergeVariableTypes(Branch *branch, Branch *previousBranch) const +void CodeAnalyzer::mergeVariableTypes(Branch *branch, Branch *previousBranch) const { for (const auto &[var, type] : branch->variableTypes) { auto it = previousBranch->variableTypes.find(var); @@ -223,13 +225,13 @@ void LLVMCodeAnalyzer::mergeVariableTypes(Branch *branch, Branch *previousBranch } } -void LLVMCodeAnalyzer::overrideVariableTypes(Branch *branch, Branch *previousBranch) const +void CodeAnalyzer::overrideVariableTypes(Branch *branch, Branch *previousBranch) const { for (const auto &[var, type] : branch->variableTypes) previousBranch->variableTypes[var] = type; } -void LLVMCodeAnalyzer::mergeListTypes(Branch *branch, Branch *previousBranch, bool firstUnknown) const +void CodeAnalyzer::mergeListTypes(Branch *branch, Branch *previousBranch, bool firstUnknown) const { for (const auto &[list, type] : branch->listTypes) { auto it = previousBranch->listTypes.find(list); @@ -241,69 +243,69 @@ void LLVMCodeAnalyzer::mergeListTypes(Branch *branch, Branch *previousBranch, bo } } -bool LLVMCodeAnalyzer::isLoopStart(const LLVMInstruction *ins) const +bool CodeAnalyzer::isLoopStart(const InstructionBase *ins) const { return (BEGIN_LOOP_INSTRUCTIONS.find(ins->type) != BEGIN_LOOP_INSTRUCTIONS.cend()); } -bool LLVMCodeAnalyzer::isLoopEnd(const LLVMInstruction *ins) const +bool CodeAnalyzer::isLoopEnd(const InstructionBase *ins) const { - return (ins->type == LLVMInstruction::Type::EndLoop); + return (ins->type == InstructionBase::Type::EndLoop); } -bool LLVMCodeAnalyzer::isIfStart(const LLVMInstruction *ins) const +bool CodeAnalyzer::isIfStart(const InstructionBase *ins) const { - return (ins->type == LLVMInstruction::Type::BeginIf); + return (ins->type == InstructionBase::Type::BeginIf); } -bool LLVMCodeAnalyzer::isElse(const LLVMInstruction *ins) const +bool CodeAnalyzer::isElse(const InstructionBase *ins) const { - return (ins->type == LLVMInstruction::Type::BeginElse); + return (ins->type == InstructionBase::Type::BeginElse); } -bool LLVMCodeAnalyzer::isIfEnd(const LLVMInstruction *ins) const +bool CodeAnalyzer::isIfEnd(const InstructionBase *ins) const { - return (ins->type == LLVMInstruction::Type::EndIf); + return (ins->type == InstructionBase::Type::EndIf); } -bool LLVMCodeAnalyzer::isVariableRead(const LLVMInstruction *ins) const +bool CodeAnalyzer::isVariableRead(const InstructionBase *ins) const { - return (ins->type == LLVMInstruction::Type::ReadVariable); + return (ins->type == InstructionBase::Type::ReadVariable); } -bool LLVMCodeAnalyzer::isVariableWrite(const LLVMInstruction *ins) const +bool CodeAnalyzer::isVariableWrite(const InstructionBase *ins) const { - return (ins->type == LLVMInstruction::Type::WriteVariable); + return (ins->type == InstructionBase::Type::WriteVariable); } -bool LLVMCodeAnalyzer::isListRead(const LLVMInstruction *ins) const +bool CodeAnalyzer::isListRead(const InstructionBase *ins) const { - return (ins->type == LLVMInstruction::Type::GetListItem); + return (ins->type == InstructionBase::Type::GetListItem); } -bool LLVMCodeAnalyzer::isListWrite(const LLVMInstruction *ins) const +bool CodeAnalyzer::isListWrite(const InstructionBase *ins) const { return (LIST_WRITE_INSTRUCTIONS.find(ins->type) != LIST_WRITE_INSTRUCTIONS.cend()); } -bool LLVMCodeAnalyzer::isListClear(const LLVMInstruction *ins) const +bool CodeAnalyzer::isListClear(const InstructionBase *ins) const { - return (ins->type == LLVMInstruction::Type::ClearList); + return (ins->type == InstructionBase::Type::ClearList); } -bool LLVMCodeAnalyzer::isProcedureCall(const LLVMInstruction *ins) const +bool CodeAnalyzer::isProcedureCall(const InstructionBase *ins) const { - return (ins->type == LLVMInstruction::Type::CallProcedure); + return (ins->type == InstructionBase::Type::CallProcedure); } -Compiler::StaticType LLVMCodeAnalyzer::writeType(LLVMInstruction *ins) const +Compiler::StaticType CodeAnalyzer::writeType(InstructionBase *ins) const { assert(ins); assert(!ins->args.empty()); auto &arg = ins->args.back(); // value is always the last argument in variable/list write instructions - const LLVMRegister *argReg = arg.second; + const CompilerValue *argValue = arg.second; - Compiler::StaticType ret = m_utils.optimizeRegisterType(argReg); + Compiler::StaticType ret = OptimizationUtils::optimizeValueType(m_ctx, argValue); arg.first = ret; // store the return type in the value argument return ret; } diff --git a/src/engine/internal/codegen/codeanalyzer.h b/src/engine/internal/codegen/codeanalyzer.h new file mode 100644 index 000000000..9e6f19397 --- /dev/null +++ b/src/engine/internal/codegen/codeanalyzer.h @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include +#include + +#include "test_export.h" + +namespace libscratchcpp +{ + +class InstructionListBase; +class InstructionBase; + +class LIBSCRATCHCPP_TEST_EXPORT CodeAnalyzer +{ + public: + CodeAnalyzer(CompilerContext *ctx); + CodeAnalyzer(const CodeAnalyzer &) = delete; + + void analyzeScript(const InstructionListBase &script) const; + + private: + struct Branch + { + InstructionBase *start = nullptr; + bool typeChanges = false; + std::unordered_map variableTypes; + std::unordered_map listTypes; + + std::unique_ptr elseBranch; + bool isAtElse = false; // whether we're currently processing the else branch + }; + + void updateVariableType(Branch *branch, InstructionBase *ins, std::unordered_set &typeAssignedInstructions, bool isWrite) const; + void updateListType(Branch *branch, InstructionBase *ins, std::unordered_set &typeAssignedInstructions, bool isWrite) const; + + void mergeVariableTypes(Branch *branch, Branch *previousBranch) const; + void overrideVariableTypes(Branch *branch, Branch *previousBranch) const; + void mergeListTypes(Branch *branch, Branch *previousBranch, bool firstUnknown) const; + + bool isLoopStart(const InstructionBase *ins) const; + bool isLoopEnd(const InstructionBase *ins) const; + bool isIfStart(const InstructionBase *ins) const; + bool isElse(const InstructionBase *ins) const; + bool isIfEnd(const InstructionBase *ins) const; + + bool isVariableRead(const InstructionBase *ins) const; + bool isVariableWrite(const InstructionBase *ins) const; + + bool isListRead(const InstructionBase *ins) const; + bool isListWrite(const InstructionBase *ins) const; + bool isListClear(const InstructionBase *ins) const; + + bool isProcedureCall(const InstructionBase *ins) const; + + Compiler::StaticType writeType(InstructionBase *ins) const; + + private: + CompilerContext *m_ctx; +}; + +} // namespace libscratchcpp diff --git a/src/engine/internal/codegen/llvm/CMakeLists.txt b/src/engine/internal/codegen/llvm/CMakeLists.txt index e2a8c1f8d..706fb1eae 100644 --- a/src/engine/internal/codegen/llvm/CMakeLists.txt +++ b/src/engine/internal/codegen/llvm/CMakeLists.txt @@ -2,8 +2,6 @@ target_sources(scratchcpp PRIVATE llvmbuildutils.cpp llvmbuildutils.h - llvmcodeanalyzer.cpp - llvmcodeanalyzer.h llvmcodebuilder.cpp llvmcodebuilder.h llvmregister.h diff --git a/src/engine/internal/codegen/llvm/llvmbuildutils.cpp b/src/engine/internal/codegen/llvm/llvmbuildutils.cpp index 804c03905..64a63b734 100644 --- a/src/engine/internal/codegen/llvm/llvmbuildutils.cpp +++ b/src/engine/internal/codegen/llvm/llvmbuildutils.cpp @@ -13,6 +13,7 @@ #include "llvmcompilercontext.h" #include "llvmregister.h" #include "llvminstruction.h" +#include "../optimizationutils.h" using namespace libscratchcpp; @@ -68,7 +69,8 @@ void LLVMBuildUtils::init(llvm::Function *function, BlockPrototype *procedurePro // Init registers for (auto reg : regs) { #ifdef LLVM_INTEGER_SUPPORT - bool isIntConst = (reg->isConst() && optimizeRegisterType(reg.get()) == Compiler::StaticType::Number && reg->constValue().toDouble() == std::floor(reg->constValue().toDouble())); + bool isIntConst = + (reg->isConst() && OptimizationUtils::optimizeValueType(m_ctx, reg.get()) == Compiler::StaticType::Number && reg->constValue().toDouble() == std::floor(reg->constValue().toDouble())); reg->isInt = m_builder.getInt1(isIntConst); #else reg->isInt = m_builder.getInt1(false); @@ -482,26 +484,6 @@ std::vector &LLVMBuildUtils::loops() return m_loops; } -Compiler::StaticType LLVMBuildUtils::optimizeRegisterType(const LLVMRegister *reg) const -{ - Compiler::StaticType ret = reg->type(); - - // Optimize string constants that represent numbers - if (reg->isConst() && reg->type() == Compiler::StaticType::String) { - const Value &value = reg->constValue(); - Value numberValue(value.toDouble()); - std::string str = value.toString(); - - // Apply this optimization only if the number matches the string and the constant is safe - const auto &unsafeConstants = m_ctx->unsafeConstants(); - - if (value.isValidNumber() && numberValue.toString() == str && unsafeConstants.find(str) == unsafeConstants.cend()) - ret = Compiler::StaticType::Number; - } - - return ret; -} - Compiler::StaticType LLVMBuildUtils::mapType(ValueType type) { assert(TYPE_MAP.find(type) != TYPE_MAP.cend()); diff --git a/src/engine/internal/codegen/llvm/llvmbuildutils.h b/src/engine/internal/codegen/llvm/llvmbuildutils.h index 892fdf664..2b2546cee 100644 --- a/src/engine/internal/codegen/llvm/llvmbuildutils.h +++ b/src/engine/internal/codegen/llvm/llvmbuildutils.h @@ -87,8 +87,6 @@ class LIBSCRATCHCPP_TEST_EXPORT LLVMBuildUtils std::vector &ifStatements(); std::vector &loops(); - Compiler::StaticType optimizeRegisterType(const LLVMRegister *reg) const; - static Compiler::StaticType mapType(ValueType type); static ValueType mapType(Compiler::StaticType type); static bool isSingleType(Compiler::StaticType type); diff --git a/src/engine/internal/codegen/llvm/llvmcodeanalyzer.h b/src/engine/internal/codegen/llvm/llvmcodeanalyzer.h deleted file mode 100644 index e8c320144..000000000 --- a/src/engine/internal/codegen/llvm/llvmcodeanalyzer.h +++ /dev/null @@ -1,64 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include -#include - -#include "test_export.h" -#include "llvminstructionlist.h" - -namespace libscratchcpp -{ - -class LLVMBuildUtils; -class LLVMInstruction; - -class LIBSCRATCHCPP_TEST_EXPORT LLVMCodeAnalyzer -{ - public: - LLVMCodeAnalyzer(const LLVMBuildUtils &utils); - LLVMCodeAnalyzer(const LLVMCodeAnalyzer &) = delete; - - void analyzeScript(const LLVMInstructionList &script) const; - - private: - struct Branch - { - LLVMInstruction *start = nullptr; - bool typeChanges = false; - std::unordered_map variableTypes; - std::unordered_map listTypes; - - std::unique_ptr elseBranch; - bool isAtElse = false; // whether we're currently processing the else branch - }; - - void updateVariableType(Branch *branch, LLVMInstruction *ins, std::unordered_set &typeAssignedInstructions, bool isWrite) const; - void updateListType(Branch *branch, LLVMInstruction *ins, std::unordered_set &typeAssignedInstructions, bool isWrite) const; - - void mergeVariableTypes(Branch *branch, Branch *previousBranch) const; - void overrideVariableTypes(Branch *branch, Branch *previousBranch) const; - void mergeListTypes(Branch *branch, Branch *previousBranch, bool firstUnknown) const; - - bool isLoopStart(const LLVMInstruction *ins) const; - bool isLoopEnd(const LLVMInstruction *ins) const; - bool isIfStart(const LLVMInstruction *ins) const; - bool isElse(const LLVMInstruction *ins) const; - bool isIfEnd(const LLVMInstruction *ins) const; - - bool isVariableRead(const LLVMInstruction *ins) const; - bool isVariableWrite(const LLVMInstruction *ins) const; - - bool isListRead(const LLVMInstruction *ins) const; - bool isListWrite(const LLVMInstruction *ins) const; - bool isListClear(const LLVMInstruction *ins) const; - - bool isProcedureCall(const LLVMInstruction *ins) const; - - Compiler::StaticType writeType(LLVMInstruction *ins) const; - - const LLVMBuildUtils &m_utils; -}; - -} // namespace libscratchcpp diff --git a/src/engine/internal/codegen/llvm/llvmcodebuilder.cpp b/src/engine/internal/codegen/llvm/llvmcodebuilder.cpp index 39018f548..3570020e6 100644 --- a/src/engine/internal/codegen/llvm/llvmcodebuilder.cpp +++ b/src/engine/internal/codegen/llvm/llvmcodebuilder.cpp @@ -28,7 +28,7 @@ LLVMCodeBuilder::LLVMCodeBuilder(LLVMCompilerContext *ctx, BlockPrototype *proce m_module(ctx->module()), m_builder(m_llvmCtx), m_utils(ctx, m_builder, codeType), - m_codeAnalyzer(m_utils), + m_codeAnalyzer(ctx), m_procedurePrototype(procedurePrototype), m_defaultWarp(procedurePrototype ? procedurePrototype->warp() : false), m_warp(m_defaultWarp), diff --git a/src/engine/internal/codegen/llvm/llvmcodebuilder.h b/src/engine/internal/codegen/llvm/llvmcodebuilder.h index 188fc3dc5..123eefd6f 100644 --- a/src/engine/internal/codegen/llvm/llvmcodebuilder.h +++ b/src/engine/internal/codegen/llvm/llvmcodebuilder.h @@ -12,7 +12,6 @@ #include "../icodebuilder.h" #include "test_export.h" #include "llvmbuildutils.h" -#include "llvmcodeanalyzer.h" #include "llvminstruction.h" #include "llvminstructionlist.h" #include "llvmcoroutine.h" @@ -20,6 +19,7 @@ #include "llvmlistptr.h" #include "llvmfunctions.h" #include "instructions/instructionbuilder.h" +#include "../codeanalyzer.h" namespace libscratchcpp { @@ -144,7 +144,7 @@ class LIBSCRATCHCPP_TEST_EXPORT LLVMCodeBuilder : public ICodeBuilder llvm::IRBuilder<> m_builder; llvm::Function *m_function = nullptr; LLVMBuildUtils m_utils; - LLVMCodeAnalyzer m_codeAnalyzer; + CodeAnalyzer m_codeAnalyzer; llvm::StructType *m_valueDataType = nullptr; llvm::StructType *m_stringPtrType = nullptr; diff --git a/src/engine/internal/codegen/optimizationutils.cpp b/src/engine/internal/codegen/optimizationutils.cpp new file mode 100644 index 000000000..64ccf7077 --- /dev/null +++ b/src/engine/internal/codegen/optimizationutils.cpp @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: Apache-2.0 + +#include +#include +#include + +#include "optimizationutils.h" + +using namespace libscratchcpp; + +Compiler::StaticType OptimizationUtils::optimizeValueType(CompilerContext *ctx, const CompilerValue *value) +{ + Compiler::StaticType ret = value->type(); + + // Optimize string constants that represent numbers + if (value->isConst() && value->type() == Compiler::StaticType::String) { + const Value &constValue = dynamic_cast(value)->value(); + Value numberValue(constValue.toDouble()); + std::string str = constValue.toString(); + + // Apply this optimization only if the number matches the string and the constant is safe + const auto &unsafeConstants = ctx->unsafeConstants(); + + if (constValue.isValidNumber() && numberValue.toString() == str && unsafeConstants.find(str) == unsafeConstants.cend()) + ret = Compiler::StaticType::Number; + } + + return ret; +} diff --git a/src/engine/internal/codegen/optimizationutils.h b/src/engine/internal/codegen/optimizationutils.h new file mode 100644 index 000000000..ec0755033 --- /dev/null +++ b/src/engine/internal/codegen/optimizationutils.h @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include + +namespace libscratchcpp +{ + +class OptimizationUtils +{ + public: + static Compiler::StaticType optimizeValueType(CompilerContext *ctx, const CompilerValue *value); +}; + +} // namespace libscratchcpp diff --git a/test/llvm/code_analyzer/list_type_analysis.cpp b/test/llvm/code_analyzer/list_type_analysis.cpp index e252a00f9..55c9e0651 100644 --- a/test/llvm/code_analyzer/list_type_analysis.cpp +++ b/test/llvm/code_analyzer/list_type_analysis.cpp @@ -2,18 +2,16 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include using namespace libscratchcpp; -class LLVMCodeAnalyzer_ListTypeAnalysis : public testing::Test +class CodeAnalyzer_ListTypeAnalysis : public testing::Test { public: void SetUp() override @@ -24,13 +22,11 @@ class LLVMCodeAnalyzer_ListTypeAnalysis : public testing::Test engine->setTargets({ m_target }); const std::unordered_set unsafeConstants = { m_unsafeCostumeNumConstant, m_unsafeSoundNumConstant }; - m_ctx = std::make_unique(engine.get(), m_target.get(), unsafeConstants); - m_builder = std::make_unique>(*m_ctx->llvmCtx()); - m_utils = std::make_unique(m_ctx.get(), *m_builder, Compiler::CodeType::Script); - m_analyzer = std::make_unique(*m_utils); + m_ctx = std::make_unique(engine.get(), m_target.get(), unsafeConstants); + m_analyzer = std::make_unique(m_ctx.get()); } - std::unique_ptr m_analyzer; + std::unique_ptr m_analyzer; const std::string m_safeNumConstant = "3.14"; const std::string m_unsafeCostumeNumConstant = "12"; @@ -40,18 +36,16 @@ class LLVMCodeAnalyzer_ListTypeAnalysis : public testing::Test Project m_project; std::shared_ptr m_target; std::shared_ptr m_spriteWithUnsafeConstants; - std::unique_ptr m_ctx; - std::unique_ptr> m_builder; - std::unique_ptr m_utils; + std::unique_ptr m_ctx; }; -TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, FirstListWrite) +TEST_F(CodeAnalyzer_ListTypeAnalysis, FirstListWrite) { - LLVMInstructionList list; + InstructionListBase list; List targetList("", ""); - auto appendList = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value(Compiler::StaticType::Number, 42.0); + auto appendList = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value(Compiler::StaticType::Number, 42.0); appendList->targetList = &targetList; appendList->args.push_back({ Compiler::StaticType::Unknown, &value }); list.addInstruction(appendList); @@ -62,19 +56,19 @@ TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, FirstListWrite) ASSERT_EQ(appendList->targetType, Compiler::StaticType::Unknown); } -TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, SecondListWrite) +TEST_F(CodeAnalyzer_ListTypeAnalysis, SecondListWrite) { - LLVMInstructionList list; + InstructionListBase list; List targetList("", ""); - auto appendList1 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 42); + auto appendList1 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value1(Compiler::StaticType::Number, 42); appendList1->targetList = &targetList; appendList1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(appendList1); - auto appendList2 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value2(Compiler::StaticType::String, "hello"); + auto appendList2 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value2(Compiler::StaticType::String, "hello"); appendList2->targetList = &targetList; appendList2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(appendList2); @@ -88,29 +82,29 @@ TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, SecondListWrite) ASSERT_EQ(appendList2->targetType, Compiler::StaticType::Unknown); } -TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, MultipleWritesSameType_AfterClear) +TEST_F(CodeAnalyzer_ListTypeAnalysis, MultipleWritesSameType_AfterClear) { - LLVMInstructionList list; + InstructionListBase list; List targetList("", ""); - auto clearList = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearList = std::make_shared(InstructionBase::Type::ClearList, false); clearList->targetList = &targetList; list.addInstruction(clearList); - auto appendList1 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value1(Compiler::StaticType::String, "first"); + auto appendList1 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value1(Compiler::StaticType::String, "first"); appendList1->targetList = &targetList; appendList1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(appendList1); - auto appendList2 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value2(Compiler::StaticType::String, "second"); + auto appendList2 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value2(Compiler::StaticType::String, "second"); appendList2->targetList = &targetList; appendList2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(appendList2); - auto appendList3 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value3(Compiler::StaticType::String, "third"); + auto appendList3 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value3(Compiler::StaticType::String, "third"); appendList3->targetList = &targetList; appendList3->args.push_back({ Compiler::StaticType::Unknown, &value3 }); list.addInstruction(appendList3); @@ -122,29 +116,29 @@ TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, MultipleWritesSameType_AfterClear) ASSERT_EQ(appendList3->targetType, Compiler::StaticType::String); } -TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, MultipleWritesDifferentTypes_AfterClear) +TEST_F(CodeAnalyzer_ListTypeAnalysis, MultipleWritesDifferentTypes_AfterClear) { - LLVMInstructionList list; + InstructionListBase list; List targetList("", ""); - auto clearList = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearList = std::make_shared(InstructionBase::Type::ClearList, false); clearList->targetList = &targetList; list.addInstruction(clearList); - auto appendList1 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 42); + auto appendList1 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value1(Compiler::StaticType::Number, 42); appendList1->targetList = &targetList; appendList1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(appendList1); - auto appendList2 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value2(Compiler::StaticType::String, "hello"); + auto appendList2 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value2(Compiler::StaticType::String, "hello"); appendList2->targetList = &targetList; appendList2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(appendList2); - auto appendList3 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value3(Compiler::StaticType::Bool, true); + auto appendList3 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value3(Compiler::StaticType::Bool, true); appendList3->targetList = &targetList; appendList3->args.push_back({ Compiler::StaticType::Unknown, &value3 }); list.addInstruction(appendList3); @@ -156,23 +150,23 @@ TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, MultipleWritesDifferentTypes_AfterClea ASSERT_EQ(appendList3->targetType, Compiler::StaticType::Number | Compiler::StaticType::String); } -TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, StringOptimization_AfterClear) +TEST_F(CodeAnalyzer_ListTypeAnalysis, StringOptimization_AfterClear) { - LLVMInstructionList list; + InstructionListBase list; List targetList("", ""); - auto clearList = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearList = std::make_shared(InstructionBase::Type::ClearList, false); clearList->targetList = &targetList; list.addInstruction(clearList); - auto appendList1 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value1(Compiler::StaticType::String, m_safeNumConstant); + auto appendList1 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value1(Compiler::StaticType::String, m_safeNumConstant); appendList1->targetList = &targetList; appendList1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(appendList1); - auto appendList2 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value2(Compiler::StaticType::Bool, true); + auto appendList2 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value2(Compiler::StaticType::Bool, true); appendList2->targetList = &targetList; appendList2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(appendList2); @@ -185,23 +179,23 @@ TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, StringOptimization_AfterClear) ASSERT_EQ(appendList2->targetType, Compiler::StaticType::Number); } -TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, StringOptimization_AfterClear_DifferentString) +TEST_F(CodeAnalyzer_ListTypeAnalysis, StringOptimization_AfterClear_DifferentString) { - LLVMInstructionList list; + InstructionListBase list; List targetList("", ""); - auto clearList = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearList = std::make_shared(InstructionBase::Type::ClearList, false); clearList->targetList = &targetList; list.addInstruction(clearList); - auto appendList1 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value1(Compiler::StaticType::String, "1.0"); + auto appendList1 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value1(Compiler::StaticType::String, "1.0"); appendList1->targetList = &targetList; appendList1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(appendList1); - auto appendList2 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value2(Compiler::StaticType::Bool, true); + auto appendList2 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value2(Compiler::StaticType::Bool, true); appendList2->targetList = &targetList; appendList2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(appendList2); @@ -214,23 +208,23 @@ TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, StringOptimization_AfterClear_Differen ASSERT_EQ(appendList2->targetType, Compiler::StaticType::String); } -TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, StringOptimization_AfterClear_UnsafeCostumeConstant) +TEST_F(CodeAnalyzer_ListTypeAnalysis, StringOptimization_AfterClear_UnsafeCostumeConstant) { - LLVMInstructionList list; + InstructionListBase list; List targetList("", ""); - auto clearList = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearList = std::make_shared(InstructionBase::Type::ClearList, false); clearList->targetList = &targetList; list.addInstruction(clearList); - auto appendList1 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value1(Compiler::StaticType::String, m_unsafeCostumeNumConstant); + auto appendList1 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value1(Compiler::StaticType::String, m_unsafeCostumeNumConstant); appendList1->targetList = &targetList; appendList1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(appendList1); - auto appendList2 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value2(Compiler::StaticType::Bool, true); + auto appendList2 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value2(Compiler::StaticType::Bool, true); appendList2->targetList = &targetList; appendList2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(appendList2); @@ -243,23 +237,23 @@ TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, StringOptimization_AfterClear_UnsafeCo ASSERT_EQ(appendList2->targetType, Compiler::StaticType::String); } -TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, StringOptimization_AfterClear_UnsafeSoundConstant) +TEST_F(CodeAnalyzer_ListTypeAnalysis, StringOptimization_AfterClear_UnsafeSoundConstant) { - LLVMInstructionList list; + InstructionListBase list; List targetList("", ""); - auto clearList = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearList = std::make_shared(InstructionBase::Type::ClearList, false); clearList->targetList = &targetList; list.addInstruction(clearList); - auto appendList1 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value1(Compiler::StaticType::String, m_unsafeSoundNumConstant); + auto appendList1 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value1(Compiler::StaticType::String, m_unsafeSoundNumConstant); appendList1->targetList = &targetList; appendList1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(appendList1); - auto appendList2 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value2(Compiler::StaticType::Bool, true); + auto appendList2 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value2(Compiler::StaticType::Bool, true); appendList2->targetList = &targetList; appendList2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(appendList2); @@ -272,23 +266,23 @@ TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, StringOptimization_AfterClear_UnsafeSo ASSERT_EQ(appendList2->targetType, Compiler::StaticType::String); } -TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, ClearListOperation) +TEST_F(CodeAnalyzer_ListTypeAnalysis, ClearListOperation) { - LLVMInstructionList list; + InstructionListBase list; List targetList("", ""); - auto appendList1 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 42); + auto appendList1 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value1(Compiler::StaticType::Number, 42); appendList1->targetList = &targetList; appendList1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(appendList1); - auto clearList = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearList = std::make_shared(InstructionBase::Type::ClearList, false); clearList->targetList = &targetList; list.addInstruction(clearList); - auto appendList2 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value2(Compiler::StaticType::String, "hello"); + auto appendList2 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value2(Compiler::StaticType::String, "hello"); appendList2->targetList = &targetList; appendList2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(appendList2); @@ -301,26 +295,26 @@ TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, ClearListOperation) ASSERT_EQ(appendList2->targetType, Compiler::StaticType::Void); } -TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, ProcedureCall) +TEST_F(CodeAnalyzer_ListTypeAnalysis, ProcedureCall) { - LLVMInstructionList list; + InstructionListBase list; List targetList("", ""); - auto clearList = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearList = std::make_shared(InstructionBase::Type::ClearList, false); clearList->targetList = &targetList; list.addInstruction(clearList); - auto appendList1 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value1(Compiler::StaticType::String, "hello"); + auto appendList1 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value1(Compiler::StaticType::String, "hello"); appendList1->targetList = &targetList; appendList1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(appendList1); - auto procCall = std::make_shared(LLVMInstruction::Type::CallProcedure, false); + auto procCall = std::make_shared(InstructionBase::Type::CallProcedure, false); list.addInstruction(procCall); - auto appendList2 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value2(Compiler::StaticType::Number, 5.2); + auto appendList2 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value2(Compiler::StaticType::Number, 5.2); appendList2->targetList = &targetList; appendList2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(appendList2); @@ -333,32 +327,32 @@ TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, ProcedureCall) ASSERT_EQ(appendList2->targetType, Compiler::StaticType::Unknown); } -TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, MixedWriteOperationsSameType_AfterClear) +TEST_F(CodeAnalyzer_ListTypeAnalysis, MixedWriteOperationsSameType_AfterClear) { - LLVMInstructionList list; + InstructionListBase list; List targetList("", ""); - auto clearList = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearList = std::make_shared(InstructionBase::Type::ClearList, false); clearList->targetList = &targetList; list.addInstruction(clearList); - auto appendList = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value1(Compiler::StaticType::String, "hello"); + auto appendList = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value1(Compiler::StaticType::String, "hello"); appendList->targetList = &targetList; appendList->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(appendList); - auto insertList = std::make_shared(LLVMInstruction::Type::InsertToList, false); - LLVMConstantRegister index(Compiler::StaticType::Number, 0); - LLVMConstantRegister value2(Compiler::StaticType::String, "world"); + auto insertList = std::make_shared(InstructionBase::Type::InsertToList, false); + CompilerConstant index(Compiler::StaticType::Number, 0); + CompilerConstant value2(Compiler::StaticType::String, "world"); insertList->targetList = &targetList; insertList->args.push_back({ Compiler::StaticType::Number, &index }); insertList->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(insertList); - auto replaceList = std::make_shared(LLVMInstruction::Type::ListReplace, false); - LLVMConstantRegister index2(Compiler::StaticType::Number, 1); - LLVMConstantRegister value3(Compiler::StaticType::String, "test"); + auto replaceList = std::make_shared(InstructionBase::Type::ListReplace, false); + CompilerConstant index2(Compiler::StaticType::Number, 1); + CompilerConstant value3(Compiler::StaticType::String, "test"); replaceList->targetList = &targetList; replaceList->args.push_back({ Compiler::StaticType::Number, &index2 }); replaceList->args.push_back({ Compiler::StaticType::Unknown, &value3 }); @@ -371,39 +365,39 @@ TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, MixedWriteOperationsSameType_AfterClea ASSERT_EQ(replaceList->targetType, Compiler::StaticType::String); } -TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, MixedWriteOperationsDifferentTypes_AfterClear) +TEST_F(CodeAnalyzer_ListTypeAnalysis, MixedWriteOperationsDifferentTypes_AfterClear) { - LLVMInstructionList list; + InstructionListBase list; List targetList("", ""); - auto clearList = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearList = std::make_shared(InstructionBase::Type::ClearList, false); clearList->targetList = &targetList; list.addInstruction(clearList); - auto appendList = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value1(Compiler::StaticType::String, "hello"); + auto appendList = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value1(Compiler::StaticType::String, "hello"); appendList->targetList = &targetList; appendList->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(appendList); - auto insertList = std::make_shared(LLVMInstruction::Type::InsertToList, false); - LLVMConstantRegister index(Compiler::StaticType::Number, 0); - LLVMConstantRegister value2(Compiler::StaticType::Bool, false); + auto insertList = std::make_shared(InstructionBase::Type::InsertToList, false); + CompilerConstant index(Compiler::StaticType::Number, 0); + CompilerConstant value2(Compiler::StaticType::Bool, false); insertList->targetList = &targetList; insertList->args.push_back({ Compiler::StaticType::Number, &index }); insertList->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(insertList); - auto replaceList = std::make_shared(LLVMInstruction::Type::ListReplace, false); - LLVMConstantRegister index2(Compiler::StaticType::Number, 1); - LLVMConstantRegister value3(Compiler::StaticType::Number, 5.2); + auto replaceList = std::make_shared(InstructionBase::Type::ListReplace, false); + CompilerConstant index2(Compiler::StaticType::Number, 1); + CompilerConstant value3(Compiler::StaticType::Number, 5.2); replaceList->targetList = &targetList; replaceList->args.push_back({ Compiler::StaticType::Number, &index2 }); replaceList->args.push_back({ Compiler::StaticType::Unknown, &value3 }); list.addInstruction(replaceList); - auto appendList2 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value4(Compiler::StaticType::String, "world"); + auto appendList2 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value4(Compiler::StaticType::String, "world"); appendList2->targetList = &targetList; appendList2->args.push_back({ Compiler::StaticType::Unknown, &value4 }); list.addInstruction(appendList2); @@ -416,21 +410,21 @@ TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, MixedWriteOperationsDifferentTypes_Aft ASSERT_EQ(appendList2->targetType, Compiler::StaticType::Unknown); } -TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, LoopSingleWrite) +TEST_F(CodeAnalyzer_ListTypeAnalysis, LoopSingleWrite) { - LLVMInstructionList list; + InstructionListBase list; List targetList("", ""); - auto loopStart = std::make_shared(LLVMInstruction::Type::BeginRepeatLoop, false); + auto loopStart = std::make_shared(InstructionBase::Type::BeginRepeatLoop, false); list.addInstruction(loopStart); - auto appendList = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value(Compiler::StaticType::Number, 1.25); + auto appendList = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value(Compiler::StaticType::Number, 1.25); appendList->targetList = &targetList; appendList->args.push_back({ Compiler::StaticType::Unknown, &value }); list.addInstruction(appendList); - auto loopEnd = std::make_shared(LLVMInstruction::Type::EndLoop, false); + auto loopEnd = std::make_shared(InstructionBase::Type::EndLoop, false); list.addInstruction(loopEnd); m_analyzer->analyzeScript(list); @@ -439,25 +433,25 @@ TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, LoopSingleWrite) ASSERT_EQ(appendList->targetType, Compiler::StaticType::Unknown); } -TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, LoopSingleWrite_AfterClear) +TEST_F(CodeAnalyzer_ListTypeAnalysis, LoopSingleWrite_AfterClear) { - LLVMInstructionList list; + InstructionListBase list; List targetList("", ""); - auto clearList = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearList = std::make_shared(InstructionBase::Type::ClearList, false); clearList->targetList = &targetList; list.addInstruction(clearList); - auto loopStart = std::make_shared(LLVMInstruction::Type::BeginRepeatLoop, false); + auto loopStart = std::make_shared(InstructionBase::Type::BeginRepeatLoop, false); list.addInstruction(loopStart); - auto appendList = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value(Compiler::StaticType::Number, 1.25); + auto appendList = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value(Compiler::StaticType::Number, 1.25); appendList->targetList = &targetList; appendList->args.push_back({ Compiler::StaticType::Unknown, &value }); list.addInstruction(appendList); - auto loopEnd = std::make_shared(LLVMInstruction::Type::EndLoop, false); + auto loopEnd = std::make_shared(InstructionBase::Type::EndLoop, false); list.addInstruction(loopEnd); m_analyzer->analyzeScript(list); @@ -465,29 +459,29 @@ TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, LoopSingleWrite_AfterClear) ASSERT_EQ(appendList->targetType, Compiler::StaticType::Number); } -TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, ClearAndWriteInIfStatement_IfBranch) +TEST_F(CodeAnalyzer_ListTypeAnalysis, ClearAndWriteInIfStatement_IfBranch) { - LLVMInstructionList list; + InstructionListBase list; List targetList("", ""); - auto ifStart = std::make_shared(LLVMInstruction::Type::BeginIf, false); + auto ifStart = std::make_shared(InstructionBase::Type::BeginIf, false); list.addInstruction(ifStart); - auto clearList = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearList = std::make_shared(InstructionBase::Type::ClearList, false); clearList->targetList = &targetList; list.addInstruction(clearList); - auto appendList1 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 1.25); + auto appendList1 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value1(Compiler::StaticType::Number, 1.25); appendList1->targetList = &targetList; appendList1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(appendList1); - auto ifEnd = std::make_shared(LLVMInstruction::Type::EndIf, false); + auto ifEnd = std::make_shared(InstructionBase::Type::EndIf, false); list.addInstruction(ifEnd); - auto appendList2 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value2(Compiler::StaticType::Bool, true); + auto appendList2 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value2(Compiler::StaticType::Bool, true); appendList2->targetList = &targetList; appendList2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(appendList2); @@ -500,32 +494,32 @@ TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, ClearAndWriteInIfStatement_IfBranch) ASSERT_EQ(appendList2->targetType, Compiler::StaticType::Unknown); } -TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, ClearAndWriteInIfStatement_ElseBranch) +TEST_F(CodeAnalyzer_ListTypeAnalysis, ClearAndWriteInIfStatement_ElseBranch) { - LLVMInstructionList list; + InstructionListBase list; List targetList("", ""); - auto ifStart = std::make_shared(LLVMInstruction::Type::BeginIf, false); + auto ifStart = std::make_shared(InstructionBase::Type::BeginIf, false); list.addInstruction(ifStart); - auto elseStart = std::make_shared(LLVMInstruction::Type::BeginElse, false); + auto elseStart = std::make_shared(InstructionBase::Type::BeginElse, false); list.addInstruction(elseStart); - auto clearList = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearList = std::make_shared(InstructionBase::Type::ClearList, false); clearList->targetList = &targetList; list.addInstruction(clearList); - auto appendList1 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 1.25); + auto appendList1 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value1(Compiler::StaticType::Number, 1.25); appendList1->targetList = &targetList; appendList1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(appendList1); - auto ifEnd = std::make_shared(LLVMInstruction::Type::EndIf, false); + auto ifEnd = std::make_shared(InstructionBase::Type::EndIf, false); list.addInstruction(ifEnd); - auto appendList2 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value2(Compiler::StaticType::Bool, true); + auto appendList2 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value2(Compiler::StaticType::Bool, true); appendList2->targetList = &targetList; appendList2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(appendList2); @@ -538,42 +532,42 @@ TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, ClearAndWriteInIfStatement_ElseBranch) ASSERT_EQ(appendList2->targetType, Compiler::StaticType::Unknown); } -TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, ClearAndWriteInIfElse) +TEST_F(CodeAnalyzer_ListTypeAnalysis, ClearAndWriteInIfElse) { - LLVMInstructionList list; + InstructionListBase list; List targetList("", ""); - auto ifStart = std::make_shared(LLVMInstruction::Type::BeginIf, false); + auto ifStart = std::make_shared(InstructionBase::Type::BeginIf, false); list.addInstruction(ifStart); - auto clearList1 = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearList1 = std::make_shared(InstructionBase::Type::ClearList, false); clearList1->targetList = &targetList; list.addInstruction(clearList1); - auto appendList1 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 1.25); + auto appendList1 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value1(Compiler::StaticType::Number, 1.25); appendList1->targetList = &targetList; appendList1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(appendList1); - auto elseStart = std::make_shared(LLVMInstruction::Type::BeginElse, false); + auto elseStart = std::make_shared(InstructionBase::Type::BeginElse, false); list.addInstruction(elseStart); - auto clearList2 = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearList2 = std::make_shared(InstructionBase::Type::ClearList, false); clearList2->targetList = &targetList; list.addInstruction(clearList2); - auto appendList2 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value2(Compiler::StaticType::String, "hello"); + auto appendList2 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value2(Compiler::StaticType::String, "hello"); appendList2->targetList = &targetList; appendList2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(appendList2); - auto ifEnd = std::make_shared(LLVMInstruction::Type::EndIf, false); + auto ifEnd = std::make_shared(InstructionBase::Type::EndIf, false); list.addInstruction(ifEnd); - auto appendList3 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value3(Compiler::StaticType::Bool, true); + auto appendList3 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value3(Compiler::StaticType::Bool, true); appendList3->targetList = &targetList; appendList3->args.push_back({ Compiler::StaticType::Unknown, &value3 }); list.addInstruction(appendList3); @@ -587,29 +581,29 @@ TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, ClearAndWriteInIfElse) ASSERT_EQ(appendList3->targetType, Compiler::StaticType::Number | Compiler::StaticType::String); } -TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, ClearAndWriteInLoop) +TEST_F(CodeAnalyzer_ListTypeAnalysis, ClearAndWriteInLoop) { - LLVMInstructionList list; + InstructionListBase list; List targetList("", ""); - auto loopStart = std::make_shared(LLVMInstruction::Type::BeginRepeatLoop, false); + auto loopStart = std::make_shared(InstructionBase::Type::BeginRepeatLoop, false); list.addInstruction(loopStart); - auto clearList = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearList = std::make_shared(InstructionBase::Type::ClearList, false); clearList->targetList = &targetList; list.addInstruction(clearList); - auto appendList1 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 1.25); + auto appendList1 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value1(Compiler::StaticType::Number, 1.25); appendList1->targetList = &targetList; appendList1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(appendList1); - auto loopEnd = std::make_shared(LLVMInstruction::Type::EndLoop, false); + auto loopEnd = std::make_shared(InstructionBase::Type::EndLoop, false); list.addInstruction(loopEnd); - auto appendList2 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value2(Compiler::StaticType::Bool, true); + auto appendList2 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value2(Compiler::StaticType::Bool, true); appendList2->targetList = &targetList; appendList2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(appendList2); @@ -622,36 +616,36 @@ TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, ClearAndWriteInLoop) ASSERT_EQ(appendList2->targetType, Compiler::StaticType::Unknown); } -TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, ClearAfterWriteInLoop) +TEST_F(CodeAnalyzer_ListTypeAnalysis, ClearAfterWriteInLoop) { - LLVMInstructionList list; + InstructionListBase list; List targetList("", ""); // Establish bool type before loop - auto clearList1 = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearList1 = std::make_shared(InstructionBase::Type::ClearList, false); clearList1->targetList = &targetList; list.addInstruction(clearList1); - auto appendList = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value(Compiler::StaticType::Bool, true); + auto appendList = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value(Compiler::StaticType::Bool, true); appendList->targetList = &targetList; appendList->args.push_back({ Compiler::StaticType::Unknown, &value }); list.addInstruction(appendList); - auto loopStart = std::make_shared(LLVMInstruction::Type::BeginRepeatLoop, false); + auto loopStart = std::make_shared(InstructionBase::Type::BeginRepeatLoop, false); list.addInstruction(loopStart); - auto appendList1 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 5); + auto appendList1 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value1(Compiler::StaticType::Number, 5); appendList1->targetList = &targetList; appendList1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(appendList1); - auto clearList2 = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearList2 = std::make_shared(InstructionBase::Type::ClearList, false); clearList2->targetList = &targetList; list.addInstruction(clearList2); - auto loopEnd = std::make_shared(LLVMInstruction::Type::EndLoop, false); + auto loopEnd = std::make_shared(InstructionBase::Type::EndLoop, false); list.addInstruction(loopEnd); m_analyzer->analyzeScript(list); @@ -659,48 +653,46 @@ TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, ClearAfterWriteInLoop) ASSERT_EQ(appendList1->targetType, Compiler::StaticType::Bool); } -TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, WhileLoop) +TEST_F(CodeAnalyzer_ListTypeAnalysis, WhileLoop) { - LLVMInstructionList list; + InstructionListBase list; List targetList("", ""); // Establish bool type before loop - auto clearList1 = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearList1 = std::make_shared(InstructionBase::Type::ClearList, false); clearList1->targetList = &targetList; list.addInstruction(clearList1); - auto appendList = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value(Compiler::StaticType::Bool, true); + auto appendList = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value(Compiler::StaticType::Bool, true); appendList->targetList = &targetList; appendList->args.push_back({ Compiler::StaticType::Unknown, &value }); list.addInstruction(appendList); - auto loopCond = std::make_shared(LLVMInstruction::Type::BeginLoopCondition, false); + auto loopCond = std::make_shared(InstructionBase::Type::BeginLoopCondition, false); list.addInstruction(loopCond); // Read an item in loop condition - auto getItem = std::make_shared(LLVMInstruction::Type::GetListItem, false); - LLVMConstantRegister index(Compiler::StaticType::Number, 0); + auto getItem = std::make_shared(InstructionBase::Type::GetListItem, false); + CompilerConstant index(Compiler::StaticType::Number, 0); getItem->targetList = &targetList; getItem->args.push_back({ Compiler::StaticType::Number, &index }); list.addInstruction(getItem); - LLVMRegister sourceValue(Compiler::StaticType::Unknown); - sourceValue.isRawValue = false; - sourceValue.instruction = getItem; + CompilerValue sourceValue(Compiler::StaticType::Unknown); getItem->functionReturnReg = &sourceValue; - auto loopStart = std::make_shared(LLVMInstruction::Type::BeginWhileLoop, false); + auto loopStart = std::make_shared(InstructionBase::Type::BeginWhileLoop, false); list.addInstruction(loopStart); // Change the type in the loop - auto appendList1 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 5); + auto appendList1 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value1(Compiler::StaticType::Number, 5); appendList1->targetList = &targetList; appendList1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(appendList1); - auto loopEnd = std::make_shared(LLVMInstruction::Type::EndLoop, false); + auto loopEnd = std::make_shared(InstructionBase::Type::EndLoop, false); list.addInstruction(loopEnd); m_analyzer->analyzeScript(list); @@ -709,48 +701,46 @@ TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, WhileLoop) ASSERT_EQ(appendList1->targetType, Compiler::StaticType::Number | Compiler::StaticType::Bool); } -TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, RepeatUntilLoop) +TEST_F(CodeAnalyzer_ListTypeAnalysis, RepeatUntilLoop) { - LLVMInstructionList list; + InstructionListBase list; List targetList("", ""); // Establish bool type before loop - auto clearList1 = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearList1 = std::make_shared(InstructionBase::Type::ClearList, false); clearList1->targetList = &targetList; list.addInstruction(clearList1); - auto appendList = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value(Compiler::StaticType::Bool, true); + auto appendList = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value(Compiler::StaticType::Bool, true); appendList->targetList = &targetList; appendList->args.push_back({ Compiler::StaticType::Unknown, &value }); list.addInstruction(appendList); - auto loopCond = std::make_shared(LLVMInstruction::Type::BeginLoopCondition, false); + auto loopCond = std::make_shared(InstructionBase::Type::BeginLoopCondition, false); list.addInstruction(loopCond); // Read an item in loop condition - auto getItem = std::make_shared(LLVMInstruction::Type::GetListItem, false); - LLVMConstantRegister index(Compiler::StaticType::Number, 0); + auto getItem = std::make_shared(InstructionBase::Type::GetListItem, false); + CompilerConstant index(Compiler::StaticType::Number, 0); getItem->targetList = &targetList; getItem->args.push_back({ Compiler::StaticType::Number, &index }); list.addInstruction(getItem); - LLVMRegister sourceValue(Compiler::StaticType::Unknown); - sourceValue.isRawValue = false; - sourceValue.instruction = getItem; + CompilerValue sourceValue(Compiler::StaticType::Unknown); getItem->functionReturnReg = &sourceValue; - auto loopStart = std::make_shared(LLVMInstruction::Type::BeginRepeatUntilLoop, false); + auto loopStart = std::make_shared(InstructionBase::Type::BeginRepeatUntilLoop, false); list.addInstruction(loopStart); // Change the type in the loop - auto appendList1 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 5); + auto appendList1 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value1(Compiler::StaticType::Number, 5); appendList1->targetList = &targetList; appendList1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(appendList1); - auto loopEnd = std::make_shared(LLVMInstruction::Type::EndLoop, false); + auto loopEnd = std::make_shared(InstructionBase::Type::EndLoop, false); list.addInstruction(loopEnd); m_analyzer->analyzeScript(list); @@ -759,27 +749,27 @@ TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, RepeatUntilLoop) ASSERT_EQ(appendList1->targetType, Compiler::StaticType::Number | Compiler::StaticType::Bool); } -TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, LoopMultipleWrites_UnknownType) +TEST_F(CodeAnalyzer_ListTypeAnalysis, LoopMultipleWrites_UnknownType) { - LLVMInstructionList list; + InstructionListBase list; List targetList("", ""); - auto loopStart = std::make_shared(LLVMInstruction::Type::BeginRepeatLoop, false); + auto loopStart = std::make_shared(InstructionBase::Type::BeginRepeatLoop, false); list.addInstruction(loopStart); - auto appendList1 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 5); + auto appendList1 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value1(Compiler::StaticType::Number, 5); appendList1->targetList = &targetList; appendList1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(appendList1); - auto appendList2 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value2(Compiler::StaticType::String, "test"); + auto appendList2 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value2(Compiler::StaticType::String, "test"); appendList2->targetList = &targetList; appendList2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(appendList2); - auto loopEnd = std::make_shared(LLVMInstruction::Type::EndLoop, false); + auto loopEnd = std::make_shared(InstructionBase::Type::EndLoop, false); list.addInstruction(loopEnd); m_analyzer->analyzeScript(list); @@ -791,32 +781,32 @@ TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, LoopMultipleWrites_UnknownType) ASSERT_EQ(appendList2->targetType, Compiler::StaticType::Unknown); } -TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, LoopMultipleWrites_AfterClear) +TEST_F(CodeAnalyzer_ListTypeAnalysis, LoopMultipleWrites_AfterClear) { - LLVMInstructionList list; + InstructionListBase list; List targetList("", ""); // Establish bool type before loop - auto clearList = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearList = std::make_shared(InstructionBase::Type::ClearList, false); clearList->targetList = &targetList; list.addInstruction(clearList); - auto loopStart = std::make_shared(LLVMInstruction::Type::BeginRepeatLoop, false); + auto loopStart = std::make_shared(InstructionBase::Type::BeginRepeatLoop, false); list.addInstruction(loopStart); - auto appendList1 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 5); + auto appendList1 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value1(Compiler::StaticType::Number, 5); appendList1->targetList = &targetList; appendList1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(appendList1); - auto appendList2 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value2(Compiler::StaticType::String, "test"); + auto appendList2 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value2(Compiler::StaticType::String, "test"); appendList2->targetList = &targetList; appendList2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(appendList2); - auto loopEnd = std::make_shared(LLVMInstruction::Type::EndLoop, false); + auto loopEnd = std::make_shared(InstructionBase::Type::EndLoop, false); list.addInstruction(loopEnd); m_analyzer->analyzeScript(list); @@ -826,34 +816,34 @@ TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, LoopMultipleWrites_AfterClear) ASSERT_EQ(appendList2->targetType, Compiler::StaticType::Number | Compiler::StaticType::String); } -TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, IfElseStatementDifferentTypes) +TEST_F(CodeAnalyzer_ListTypeAnalysis, IfElseStatementDifferentTypes) { - LLVMInstructionList list; + InstructionListBase list; List targetList("", ""); - auto ifStart = std::make_shared(LLVMInstruction::Type::BeginIf, false); + auto ifStart = std::make_shared(InstructionBase::Type::BeginIf, false); list.addInstruction(ifStart); - auto appendList1 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 42); + auto appendList1 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value1(Compiler::StaticType::Number, 42); appendList1->targetList = &targetList; appendList1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(appendList1); - auto elseStart = std::make_shared(LLVMInstruction::Type::BeginElse, false); + auto elseStart = std::make_shared(InstructionBase::Type::BeginElse, false); list.addInstruction(elseStart); - auto appendList2 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value2(Compiler::StaticType::String, "test"); + auto appendList2 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value2(Compiler::StaticType::String, "test"); appendList2->targetList = &targetList; appendList2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(appendList2); - auto ifEnd = std::make_shared(LLVMInstruction::Type::EndIf, false); + auto ifEnd = std::make_shared(InstructionBase::Type::EndIf, false); list.addInstruction(ifEnd); - auto appendList3 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value3(Compiler::StaticType::Bool, true); + auto appendList3 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value3(Compiler::StaticType::Bool, true); appendList3->targetList = &targetList; appendList3->args.push_back({ Compiler::StaticType::Unknown, &value3 }); list.addInstruction(appendList3); @@ -868,38 +858,38 @@ TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, IfElseStatementDifferentTypes) ASSERT_EQ(appendList3->targetType, Compiler::StaticType::Unknown); } -TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, IfElseStatementDifferentTypes_AfterClear) +TEST_F(CodeAnalyzer_ListTypeAnalysis, IfElseStatementDifferentTypes_AfterClear) { - LLVMInstructionList list; + InstructionListBase list; List targetList("", ""); - auto clearList = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearList = std::make_shared(InstructionBase::Type::ClearList, false); clearList->targetList = &targetList; list.addInstruction(clearList); - auto ifStart = std::make_shared(LLVMInstruction::Type::BeginIf, false); + auto ifStart = std::make_shared(InstructionBase::Type::BeginIf, false); list.addInstruction(ifStart); - auto appendList1 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 42); + auto appendList1 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value1(Compiler::StaticType::Number, 42); appendList1->targetList = &targetList; appendList1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(appendList1); - auto elseStart = std::make_shared(LLVMInstruction::Type::BeginElse, false); + auto elseStart = std::make_shared(InstructionBase::Type::BeginElse, false); list.addInstruction(elseStart); - auto appendList2 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value2(Compiler::StaticType::String, "test"); + auto appendList2 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value2(Compiler::StaticType::String, "test"); appendList2->targetList = &targetList; appendList2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(appendList2); - auto ifEnd = std::make_shared(LLVMInstruction::Type::EndIf, false); + auto ifEnd = std::make_shared(InstructionBase::Type::EndIf, false); list.addInstruction(ifEnd); - auto appendList3 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value3(Compiler::StaticType::Bool, true); + auto appendList3 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value3(Compiler::StaticType::Bool, true); appendList3->targetList = &targetList; appendList3->args.push_back({ Compiler::StaticType::Unknown, &value3 }); list.addInstruction(appendList3); @@ -914,35 +904,35 @@ TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, IfElseStatementDifferentTypes_AfterCle ASSERT_EQ(appendList3->targetType, Compiler::StaticType::Number | Compiler::StaticType::String); } -TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, IfElseStatementDifferentType_IfBranch_AfterClear) +TEST_F(CodeAnalyzer_ListTypeAnalysis, IfElseStatementDifferentType_IfBranch_AfterClear) { - LLVMInstructionList list; + InstructionListBase list; List targetList("", ""); - auto clearList = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearList = std::make_shared(InstructionBase::Type::ClearList, false); clearList->targetList = &targetList; list.addInstruction(clearList); - auto appendList1 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 42); + auto appendList1 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value1(Compiler::StaticType::Number, 42); appendList1->targetList = &targetList; appendList1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(appendList1); - auto ifStart = std::make_shared(LLVMInstruction::Type::BeginIf, false); + auto ifStart = std::make_shared(InstructionBase::Type::BeginIf, false); list.addInstruction(ifStart); - auto appendList2 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value2(Compiler::StaticType::String, "test"); + auto appendList2 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value2(Compiler::StaticType::String, "test"); appendList2->targetList = &targetList; appendList2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(appendList2); - auto ifEnd = std::make_shared(LLVMInstruction::Type::EndIf, false); + auto ifEnd = std::make_shared(InstructionBase::Type::EndIf, false); list.addInstruction(ifEnd); - auto appendList3 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value3(Compiler::StaticType::Bool, true); + auto appendList3 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value3(Compiler::StaticType::Bool, true); appendList3->targetList = &targetList; appendList3->args.push_back({ Compiler::StaticType::Unknown, &value3 }); list.addInstruction(appendList3); @@ -956,38 +946,38 @@ TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, IfElseStatementDifferentType_IfBranch_ ASSERT_EQ(appendList3->targetType, Compiler::StaticType::Number | Compiler::StaticType::String); } -TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, IfElseStatementDifferentType_ElseBranch_AfterClear) +TEST_F(CodeAnalyzer_ListTypeAnalysis, IfElseStatementDifferentType_ElseBranch_AfterClear) { - LLVMInstructionList list; + InstructionListBase list; List targetList("", ""); - auto clearList = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearList = std::make_shared(InstructionBase::Type::ClearList, false); clearList->targetList = &targetList; list.addInstruction(clearList); - auto appendList1 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 42); + auto appendList1 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value1(Compiler::StaticType::Number, 42); appendList1->targetList = &targetList; appendList1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(appendList1); - auto ifStart = std::make_shared(LLVMInstruction::Type::BeginIf, false); + auto ifStart = std::make_shared(InstructionBase::Type::BeginIf, false); list.addInstruction(ifStart); - auto elseStart = std::make_shared(LLVMInstruction::Type::BeginElse, false); + auto elseStart = std::make_shared(InstructionBase::Type::BeginElse, false); list.addInstruction(elseStart); - auto appendList2 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value2(Compiler::StaticType::String, "test"); + auto appendList2 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value2(Compiler::StaticType::String, "test"); appendList2->targetList = &targetList; appendList2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(appendList2); - auto ifEnd = std::make_shared(LLVMInstruction::Type::EndIf, false); + auto ifEnd = std::make_shared(InstructionBase::Type::EndIf, false); list.addInstruction(ifEnd); - auto appendList3 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value3(Compiler::StaticType::Bool, true); + auto appendList3 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value3(Compiler::StaticType::Bool, true); appendList3->targetList = &targetList; appendList3->args.push_back({ Compiler::StaticType::Unknown, &value3 }); list.addInstruction(appendList3); @@ -1001,35 +991,35 @@ TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, IfElseStatementDifferentType_ElseBranc ASSERT_EQ(appendList3->targetType, Compiler::StaticType::Number | Compiler::StaticType::String); } -TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, WriteBeforeLoop_AfterClear) +TEST_F(CodeAnalyzer_ListTypeAnalysis, WriteBeforeLoop_AfterClear) { - LLVMInstructionList list; + InstructionListBase list; List targetList("", ""); - auto clearList = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearList = std::make_shared(InstructionBase::Type::ClearList, false); clearList->targetList = &targetList; list.addInstruction(clearList); - auto appendListBefore = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister valueBefore(Compiler::StaticType::String, "initial"); + auto appendListBefore = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant valueBefore(Compiler::StaticType::String, "initial"); appendListBefore->targetList = &targetList; appendListBefore->args.push_back({ Compiler::StaticType::Unknown, &valueBefore }); list.addInstruction(appendListBefore); - auto loopStart = std::make_shared(LLVMInstruction::Type::BeginRepeatLoop, false); + auto loopStart = std::make_shared(InstructionBase::Type::BeginRepeatLoop, false); list.addInstruction(loopStart); - auto appendListInLoop = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister valueInLoop(Compiler::StaticType::Number, 42); + auto appendListInLoop = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant valueInLoop(Compiler::StaticType::Number, 42); appendListInLoop->targetList = &targetList; appendListInLoop->args.push_back({ Compiler::StaticType::Unknown, &valueInLoop }); list.addInstruction(appendListInLoop); - auto loopEnd = std::make_shared(LLVMInstruction::Type::EndLoop, false); + auto loopEnd = std::make_shared(InstructionBase::Type::EndLoop, false); list.addInstruction(loopEnd); - auto appendList = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value(Compiler::StaticType::Bool, false); + auto appendList = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value(Compiler::StaticType::Bool, false); appendList->targetList = &targetList; appendList->args.push_back({ Compiler::StaticType::Unknown, &value }); list.addInstruction(appendList); @@ -1039,35 +1029,35 @@ TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, WriteBeforeLoop_AfterClear) ASSERT_EQ(appendList->targetType, Compiler::StaticType::String | Compiler::StaticType::Number); } -TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, WriteBeforeIfStatement_IfBranch_AfterClear) +TEST_F(CodeAnalyzer_ListTypeAnalysis, WriteBeforeIfStatement_IfBranch_AfterClear) { - LLVMInstructionList list; + InstructionListBase list; List targetList("", ""); - auto clearList = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearList = std::make_shared(InstructionBase::Type::ClearList, false); clearList->targetList = &targetList; list.addInstruction(clearList); - auto appendListBefore = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister valueBefore(Compiler::StaticType::String, "initial"); + auto appendListBefore = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant valueBefore(Compiler::StaticType::String, "initial"); appendListBefore->targetList = &targetList; appendListBefore->args.push_back({ Compiler::StaticType::Unknown, &valueBefore }); list.addInstruction(appendListBefore); - auto ifStart = std::make_shared(LLVMInstruction::Type::BeginIf, false); + auto ifStart = std::make_shared(InstructionBase::Type::BeginIf, false); list.addInstruction(ifStart); - auto appendListInIfStatement = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister valueInIfStatement(Compiler::StaticType::Number, 42); + auto appendListInIfStatement = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant valueInIfStatement(Compiler::StaticType::Number, 42); appendListInIfStatement->targetList = &targetList; appendListInIfStatement->args.push_back({ Compiler::StaticType::Unknown, &valueInIfStatement }); list.addInstruction(appendListInIfStatement); - auto ifEnd = std::make_shared(LLVMInstruction::Type::EndIf, false); + auto ifEnd = std::make_shared(InstructionBase::Type::EndIf, false); list.addInstruction(ifEnd); - auto appendList = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value(Compiler::StaticType::Bool, false); + auto appendList = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value(Compiler::StaticType::Bool, false); appendList->targetList = &targetList; appendList->args.push_back({ Compiler::StaticType::Unknown, &value }); list.addInstruction(appendList); @@ -1077,38 +1067,38 @@ TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, WriteBeforeIfStatement_IfBranch_AfterC ASSERT_EQ(appendList->targetType, Compiler::StaticType::String | Compiler::StaticType::Number); } -TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, WriteBeforeIfStatement_ElseBranch_AfterClear) +TEST_F(CodeAnalyzer_ListTypeAnalysis, WriteBeforeIfStatement_ElseBranch_AfterClear) { - LLVMInstructionList list; + InstructionListBase list; List targetList("", ""); - auto clearList = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearList = std::make_shared(InstructionBase::Type::ClearList, false); clearList->targetList = &targetList; list.addInstruction(clearList); - auto appendListBefore = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister valueBefore(Compiler::StaticType::String, "initial"); + auto appendListBefore = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant valueBefore(Compiler::StaticType::String, "initial"); appendListBefore->targetList = &targetList; appendListBefore->args.push_back({ Compiler::StaticType::Unknown, &valueBefore }); list.addInstruction(appendListBefore); - auto ifStart = std::make_shared(LLVMInstruction::Type::BeginIf, false); + auto ifStart = std::make_shared(InstructionBase::Type::BeginIf, false); list.addInstruction(ifStart); - auto elseStart = std::make_shared(LLVMInstruction::Type::BeginElse, false); + auto elseStart = std::make_shared(InstructionBase::Type::BeginElse, false); list.addInstruction(elseStart); - auto appendListInIfStatement = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister valueInIfStatement(Compiler::StaticType::Number, 42); + auto appendListInIfStatement = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant valueInIfStatement(Compiler::StaticType::Number, 42); appendListInIfStatement->targetList = &targetList; appendListInIfStatement->args.push_back({ Compiler::StaticType::Unknown, &valueInIfStatement }); list.addInstruction(appendListInIfStatement); - auto ifEnd = std::make_shared(LLVMInstruction::Type::EndIf, false); + auto ifEnd = std::make_shared(InstructionBase::Type::EndIf, false); list.addInstruction(ifEnd); - auto appendList = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value(Compiler::StaticType::Bool, false); + auto appendList = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value(Compiler::StaticType::Bool, false); appendList->targetList = &targetList; appendList->args.push_back({ Compiler::StaticType::Unknown, &value }); list.addInstruction(appendList); @@ -1118,44 +1108,44 @@ TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, WriteBeforeIfStatement_ElseBranch_Afte ASSERT_EQ(appendList->targetType, Compiler::StaticType::String | Compiler::StaticType::Number); } -TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, WriteBeforeIfElse_AfterClear) +TEST_F(CodeAnalyzer_ListTypeAnalysis, WriteBeforeIfElse_AfterClear) { - LLVMInstructionList list; + InstructionListBase list; List targetList("", ""); - auto clearList = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearList = std::make_shared(InstructionBase::Type::ClearList, false); clearList->targetList = &targetList; list.addInstruction(clearList); - auto appendListBefore = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister valueBefore(Compiler::StaticType::Bool, true); + auto appendListBefore = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant valueBefore(Compiler::StaticType::Bool, true); appendListBefore->targetList = &targetList; appendListBefore->args.push_back({ Compiler::StaticType::Unknown, &valueBefore }); list.addInstruction(appendListBefore); - auto ifStart = std::make_shared(LLVMInstruction::Type::BeginIf, false); + auto ifStart = std::make_shared(InstructionBase::Type::BeginIf, false); list.addInstruction(ifStart); - auto appendList1 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 42); + auto appendList1 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value1(Compiler::StaticType::Number, 42); appendList1->targetList = &targetList; appendList1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(appendList1); - auto elseStart = std::make_shared(LLVMInstruction::Type::BeginElse, false); + auto elseStart = std::make_shared(InstructionBase::Type::BeginElse, false); list.addInstruction(elseStart); - auto appendList2 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value2(Compiler::StaticType::String, "test"); + auto appendList2 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value2(Compiler::StaticType::String, "test"); appendList2->targetList = &targetList; appendList2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(appendList2); - auto ifEnd = std::make_shared(LLVMInstruction::Type::EndIf, false); + auto ifEnd = std::make_shared(InstructionBase::Type::EndIf, false); list.addInstruction(ifEnd); - auto appendList3 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value3(Compiler::StaticType::Bool, true); + auto appendList3 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value3(Compiler::StaticType::Bool, true); appendList3->targetList = &targetList; appendList3->args.push_back({ Compiler::StaticType::Unknown, &value3 }); list.addInstruction(appendList3); @@ -1173,56 +1163,56 @@ TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, WriteBeforeIfElse_AfterClear) ASSERT_EQ(appendList3->targetType, Compiler::StaticType::Unknown); } -TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, ComplexNestedControlFlow_AfterClear) +TEST_F(CodeAnalyzer_ListTypeAnalysis, ComplexNestedControlFlow_AfterClear) { - LLVMInstructionList list; + InstructionListBase list; List targetList("", ""); - auto clearList = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearList = std::make_shared(InstructionBase::Type::ClearList, false); clearList->targetList = &targetList; list.addInstruction(clearList); - auto outerLoop = std::make_shared(LLVMInstruction::Type::BeginRepeatLoop, false); + auto outerLoop = std::make_shared(InstructionBase::Type::BeginRepeatLoop, false); list.addInstruction(outerLoop); - auto appendList1 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 1); + auto appendList1 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value1(Compiler::StaticType::Number, 1); appendList1->targetList = &targetList; appendList1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(appendList1); - auto ifStart = std::make_shared(LLVMInstruction::Type::BeginIf, false); + auto ifStart = std::make_shared(InstructionBase::Type::BeginIf, false); list.addInstruction(ifStart); - auto innerLoop = std::make_shared(LLVMInstruction::Type::BeginRepeatLoop, false); + auto innerLoop = std::make_shared(InstructionBase::Type::BeginRepeatLoop, false); list.addInstruction(innerLoop); - auto appendList2 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value2(Compiler::StaticType::String, "nested"); + auto appendList2 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value2(Compiler::StaticType::String, "nested"); appendList2->targetList = &targetList; appendList2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(appendList2); - auto innerLoopEnd = std::make_shared(LLVMInstruction::Type::EndLoop, false); + auto innerLoopEnd = std::make_shared(InstructionBase::Type::EndLoop, false); list.addInstruction(innerLoopEnd); - auto elseStart = std::make_shared(LLVMInstruction::Type::BeginElse, false); + auto elseStart = std::make_shared(InstructionBase::Type::BeginElse, false); list.addInstruction(elseStart); - auto appendList3 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value3(Compiler::StaticType::Bool, true); + auto appendList3 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value3(Compiler::StaticType::Bool, true); appendList3->targetList = &targetList; appendList3->args.push_back({ Compiler::StaticType::Unknown, &value3 }); list.addInstruction(appendList3); - auto ifEnd = std::make_shared(LLVMInstruction::Type::EndIf, false); + auto ifEnd = std::make_shared(InstructionBase::Type::EndIf, false); list.addInstruction(ifEnd); - auto outerLoopEnd = std::make_shared(LLVMInstruction::Type::EndLoop, false); + auto outerLoopEnd = std::make_shared(InstructionBase::Type::EndLoop, false); list.addInstruction(outerLoopEnd); - auto appendList4 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value4(Compiler::StaticType::Bool, true); + auto appendList4 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value4(Compiler::StaticType::Bool, true); appendList4->targetList = &targetList; appendList4->args.push_back({ Compiler::StaticType::Unknown, &value4 }); list.addInstruction(appendList4); @@ -1236,23 +1226,23 @@ TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, ComplexNestedControlFlow_AfterClear) ASSERT_EQ(appendList4->targetType, Compiler::StaticType::Unknown); } -TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, MultipleListsSeparateAnalysis) +TEST_F(CodeAnalyzer_ListTypeAnalysis, MultipleListsSeparateAnalysis) { - LLVMInstructionList list; + InstructionListBase list; List targetList1("", ""), targetList2("", ""); - auto clearList1 = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearList1 = std::make_shared(InstructionBase::Type::ClearList, false); clearList1->targetList = &targetList1; list.addInstruction(clearList1); - auto appendList1 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 42); + auto appendList1 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value1(Compiler::StaticType::Number, 42); appendList1->targetList = &targetList1; appendList1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(appendList1); - auto appendList2 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value2(Compiler::StaticType::String, "test"); + auto appendList2 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value2(Compiler::StaticType::String, "test"); appendList2->targetList = &targetList2; appendList2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(appendList2); @@ -1264,43 +1254,41 @@ TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, MultipleListsSeparateAnalysis) ASSERT_EQ(appendList2->targetType, Compiler::StaticType::Unknown); } -TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, CrossListDependency_SingleType) +TEST_F(CodeAnalyzer_ListTypeAnalysis, CrossListDependency_SingleType) { - LLVMInstructionList list; + InstructionListBase list; List sourceList("", ""), targetList("", ""); - auto clearSource = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearSource = std::make_shared(InstructionBase::Type::ClearList, false); clearSource->targetList = &sourceList; list.addInstruction(clearSource); - auto clearTarget = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearTarget = std::make_shared(InstructionBase::Type::ClearList, false); clearTarget->targetList = &targetList; list.addInstruction(clearTarget); - auto appendList2 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 3.14); + auto appendList2 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value1(Compiler::StaticType::Number, 3.14); appendList2->targetList = &sourceList; appendList2->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(appendList2); - auto getItem = std::make_shared(LLVMInstruction::Type::GetListItem, false); - LLVMConstantRegister index(Compiler::StaticType::Number, 0); + auto getItem = std::make_shared(InstructionBase::Type::GetListItem, false); + CompilerConstant index(Compiler::StaticType::Number, 0); getItem->targetList = &sourceList; getItem->args.push_back({ Compiler::StaticType::Number, &index }); list.addInstruction(getItem); - LLVMRegister sourceValue(Compiler::StaticType::Unknown); - sourceValue.isRawValue = false; - sourceValue.instruction = getItem; + CompilerValue sourceValue(Compiler::StaticType::Unknown); getItem->functionReturnReg = &sourceValue; - auto appendList1_1 = std::make_shared(LLVMInstruction::Type::AppendToList, false); + auto appendList1_1 = std::make_shared(InstructionBase::Type::AppendToList, false); appendList1_1->targetList = &targetList; appendList1_1->args.push_back({ Compiler::StaticType::Unknown, &sourceValue }); list.addInstruction(appendList1_1); - auto appendList1_2 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value2(Compiler::StaticType::String, "test"); + auto appendList1_2 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value2(Compiler::StaticType::String, "test"); appendList1_2->targetList = &targetList; appendList1_2->args.push_back({ Compiler::StaticType::Unknown, &sourceValue }); list.addInstruction(appendList1_2); @@ -1320,50 +1308,48 @@ TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, CrossListDependency_SingleType) ASSERT_EQ(appendList1_2->targetType, Compiler::StaticType::Number | Compiler::StaticType::String); } -TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, CrossListDependency_MultipleTypes) +TEST_F(CodeAnalyzer_ListTypeAnalysis, CrossListDependency_MultipleTypes) { - LLVMInstructionList list; + InstructionListBase list; List sourceList("", ""), targetList("", ""); - auto clearSource = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearSource = std::make_shared(InstructionBase::Type::ClearList, false); clearSource->targetList = &sourceList; list.addInstruction(clearSource); - auto clearTarget = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearTarget = std::make_shared(InstructionBase::Type::ClearList, false); clearTarget->targetList = &targetList; list.addInstruction(clearTarget); // Establish Number | Bool types - auto appendList1 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 42); + auto appendList1 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value1(Compiler::StaticType::Number, 42); appendList1->targetList = &sourceList; appendList1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(appendList1); - auto appendList2 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value2(Compiler::StaticType::Bool, true); + auto appendList2 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value2(Compiler::StaticType::Bool, true); appendList2->targetList = &sourceList; appendList2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(appendList2); - auto getItem = std::make_shared(LLVMInstruction::Type::GetListItem, false); - LLVMConstantRegister index(Compiler::StaticType::Number, 0); + auto getItem = std::make_shared(InstructionBase::Type::GetListItem, false); + CompilerConstant index(Compiler::StaticType::Number, 0); getItem->targetList = &sourceList; getItem->args.push_back({ Compiler::StaticType::Number, &index }); list.addInstruction(getItem); - LLVMRegister sourceValue(Compiler::StaticType::Unknown); - sourceValue.isRawValue = false; - sourceValue.instruction = getItem; + CompilerValue sourceValue(Compiler::StaticType::Unknown); getItem->functionReturnReg = &sourceValue; - auto appendList3 = std::make_shared(LLVMInstruction::Type::AppendToList, false); + auto appendList3 = std::make_shared(InstructionBase::Type::AppendToList, false); appendList3->targetList = &targetList; appendList3->args.push_back({ Compiler::StaticType::Unknown, &sourceValue }); list.addInstruction(appendList3); - auto appendList4 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value4(Compiler::StaticType::String, "test"); + auto appendList4 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value4(Compiler::StaticType::String, "test"); appendList4->targetList = &targetList; appendList4->args.push_back({ Compiler::StaticType::Unknown, &sourceValue }); list.addInstruction(appendList4); @@ -1380,126 +1366,120 @@ TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, CrossListDependency_MultipleTypes) ASSERT_EQ(appendList4->targetType, Compiler::StaticType::Unknown); } -TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, ChainedAssignmentsInLoop) +TEST_F(CodeAnalyzer_ListTypeAnalysis, ChainedAssignmentsInLoop) { - LLVMInstructionList list; + InstructionListBase list; List listA("a", ""), listB("b", ""), listC("c", ""); - auto clearA = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearA = std::make_shared(InstructionBase::Type::ClearList, false); clearA->targetList = &listA; list.addInstruction(clearA); - auto clearB = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearB = std::make_shared(InstructionBase::Type::ClearList, false); clearB->targetList = &listB; list.addInstruction(clearB); - auto clearC = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearC = std::make_shared(InstructionBase::Type::ClearList, false); clearC->targetList = &listC; list.addInstruction(clearC); // a += 5 - auto appendA1 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister valueA1(Compiler::StaticType::Number, 5); + auto appendA1 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant valueA1(Compiler::StaticType::Number, 5); appendA1->targetList = &listA; appendA1->args.push_back({ Compiler::StaticType::Unknown, &valueA1 }); list.addInstruction(appendA1); // b += 3 - auto appendB1 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister valueB1(Compiler::StaticType::Number, 3); + auto appendB1 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant valueB1(Compiler::StaticType::Number, 3); appendB1->targetList = &listB; appendB1->args.push_back({ Compiler::StaticType::Unknown, &valueB1 }); list.addInstruction(appendB1); // c += 8 - auto appendC1 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister valueC1(Compiler::StaticType::Number, 8); + auto appendC1 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant valueC1(Compiler::StaticType::Number, 8); appendC1->targetList = &listC; appendC1->args.push_back({ Compiler::StaticType::Unknown, &valueC1 }); list.addInstruction(appendC1); // loop start - auto loopStart = std::make_shared(LLVMInstruction::Type::BeginRepeatLoop, false); + auto loopStart = std::make_shared(InstructionBase::Type::BeginRepeatLoop, false); list.addInstruction(loopStart); // clear a - clearA = std::make_shared(LLVMInstruction::Type::ClearList, false); + clearA = std::make_shared(InstructionBase::Type::ClearList, false); clearA->targetList = &listA; list.addInstruction(clearA); // a += b[0] - auto getB = std::make_shared(LLVMInstruction::Type::GetListItem, false); - LLVMConstantRegister indexB(Compiler::StaticType::Number, 0); + auto getB = std::make_shared(InstructionBase::Type::GetListItem, false); + CompilerConstant indexB(Compiler::StaticType::Number, 0); getB->targetList = &listB; getB->args.push_back({ Compiler::StaticType::Number, &indexB }); list.addInstruction(getB); - LLVMRegister bValue(Compiler::StaticType::Unknown); - bValue.isRawValue = false; - bValue.instruction = getB; + CompilerValue bValue(Compiler::StaticType::Unknown); getB->functionReturnReg = &bValue; - auto appendA2 = std::make_shared(LLVMInstruction::Type::AppendToList, false); + auto appendA2 = std::make_shared(InstructionBase::Type::AppendToList, false); appendA2->targetList = &listA; appendA2->args.push_back({ Compiler::StaticType::Unknown, &bValue }); list.addInstruction(appendA2); // clear b - clearB = std::make_shared(LLVMInstruction::Type::ClearList, false); + clearB = std::make_shared(InstructionBase::Type::ClearList, false); clearB->targetList = &listB; list.addInstruction(clearB); // b += c[0] - auto getC1 = std::make_shared(LLVMInstruction::Type::GetListItem, false); - LLVMConstantRegister indexC1(Compiler::StaticType::Number, 0); + auto getC1 = std::make_shared(InstructionBase::Type::GetListItem, false); + CompilerConstant indexC1(Compiler::StaticType::Number, 0); getC1->targetList = &listC; getC1->args.push_back({ Compiler::StaticType::Number, &indexC1 }); list.addInstruction(getC1); - LLVMRegister cValue1(Compiler::StaticType::Unknown); - cValue1.isRawValue = false; - cValue1.instruction = getC1; + CompilerValue cValue1(Compiler::StaticType::Unknown); getC1->functionReturnReg = &cValue1; - auto appendB2 = std::make_shared(LLVMInstruction::Type::AppendToList, false); + auto appendB2 = std::make_shared(InstructionBase::Type::AppendToList, false); appendB2->targetList = &listB; appendB2->args.push_back({ Compiler::StaticType::Unknown, &cValue1 }); list.addInstruction(appendB2); // clear c - clearC = std::make_shared(LLVMInstruction::Type::ClearList, false); + clearC = std::make_shared(InstructionBase::Type::ClearList, false); clearC->targetList = &listC; list.addInstruction(clearC); // c += "test" - auto appendC2 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister valueC2(Compiler::StaticType::String, "test"); + auto appendC2 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant valueC2(Compiler::StaticType::String, "test"); appendC2->targetList = &listC; appendC2->args.push_back({ Compiler::StaticType::Unknown, &valueC2 }); list.addInstruction(appendC2); // loop end - auto loopEnd = std::make_shared(LLVMInstruction::Type::EndLoop, false); + auto loopEnd = std::make_shared(InstructionBase::Type::EndLoop, false); list.addInstruction(loopEnd); // clear a (final assignment we want to test) - auto clearAFinal = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearAFinal = std::make_shared(InstructionBase::Type::ClearList, false); clearAFinal->targetList = &listA; list.addInstruction(clearAFinal); // a += c[0] - auto getC2 = std::make_shared(LLVMInstruction::Type::GetListItem, false); - LLVMConstantRegister indexC2(Compiler::StaticType::Number, 0); + auto getC2 = std::make_shared(InstructionBase::Type::GetListItem, false); + CompilerConstant indexC2(Compiler::StaticType::Number, 0); getC2->targetList = &listC; getC2->args.push_back({ Compiler::StaticType::Number, &indexC2 }); list.addInstruction(getC2); - LLVMRegister cValue2(Compiler::StaticType::Unknown); - cValue2.isRawValue = false; - cValue2.instruction = getC2; + CompilerValue cValue2(Compiler::StaticType::Unknown); getC2->functionReturnReg = &cValue2; - auto appendA3 = std::make_shared(LLVMInstruction::Type::AppendToList, false); + auto appendA3 = std::make_shared(InstructionBase::Type::AppendToList, false); appendA3->targetList = &listA; appendA3->args.push_back({ Compiler::StaticType::Unknown, &cValue2 }); list.addInstruction(appendA3); @@ -1517,37 +1497,35 @@ TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, ChainedAssignmentsInLoop) ASSERT_EQ(getC2->targetType, expectedCType); } -TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, ListReadReturnRegType) +TEST_F(CodeAnalyzer_ListTypeAnalysis, ListReadReturnRegType) { - LLVMInstructionList list; + InstructionListBase list; List sourceList("", ""), targetList("", ""); - auto clearSource = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearSource = std::make_shared(InstructionBase::Type::ClearList, false); clearSource->targetList = &sourceList; list.addInstruction(clearSource); - auto clearTarget = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearTarget = std::make_shared(InstructionBase::Type::ClearList, false); clearTarget->targetList = &targetList; list.addInstruction(clearTarget); - auto appendList2 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 3.14); + auto appendList2 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value1(Compiler::StaticType::Number, 3.14); appendList2->targetList = &sourceList; appendList2->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(appendList2); - auto getItem = std::make_shared(LLVMInstruction::Type::GetListItem, false); - LLVMConstantRegister index(Compiler::StaticType::Number, 0); + auto getItem = std::make_shared(InstructionBase::Type::GetListItem, false); + CompilerConstant index(Compiler::StaticType::Number, 0); getItem->targetList = &sourceList; getItem->args.push_back({ Compiler::StaticType::Number, &index }); list.addInstruction(getItem); - LLVMRegister sourceValue(Compiler::StaticType::Unknown); - sourceValue.isRawValue = false; - sourceValue.instruction = getItem; + CompilerValue sourceValue(Compiler::StaticType::Unknown); getItem->functionReturnReg = &sourceValue; - auto appendList1_1 = std::make_shared(LLVMInstruction::Type::AppendToList, false); + auto appendList1_1 = std::make_shared(InstructionBase::Type::AppendToList, false); appendList1_1->targetList = &targetList; appendList1_1->args.push_back({ Compiler::StaticType::Unknown, &sourceValue }); list.addInstruction(appendList1_1); @@ -1558,37 +1536,35 @@ TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, ListReadReturnRegType) ASSERT_EQ(sourceValue.type(), Compiler::StaticType::Number | Compiler::StaticType::String); } -TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, CrossListWriteArgType) +TEST_F(CodeAnalyzer_ListTypeAnalysis, CrossListWriteArgType) { - LLVMInstructionList list; + InstructionListBase list; List sourceList("", ""), targetList("", ""); - auto clearSource = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearSource = std::make_shared(InstructionBase::Type::ClearList, false); clearSource->targetList = &sourceList; list.addInstruction(clearSource); - auto clearTarget = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearTarget = std::make_shared(InstructionBase::Type::ClearList, false); clearTarget->targetList = &targetList; list.addInstruction(clearTarget); - auto appendList2 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 3.14); + auto appendList2 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant value1(Compiler::StaticType::Number, 3.14); appendList2->targetList = &sourceList; appendList2->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(appendList2); - auto getItem = std::make_shared(LLVMInstruction::Type::GetListItem, false); - LLVMConstantRegister index(Compiler::StaticType::Number, 0); + auto getItem = std::make_shared(InstructionBase::Type::GetListItem, false); + CompilerConstant index(Compiler::StaticType::Number, 0); getItem->targetList = &sourceList; getItem->args.push_back({ Compiler::StaticType::Number, &index }); list.addInstruction(getItem); - LLVMRegister sourceValue(Compiler::StaticType::Unknown); - sourceValue.isRawValue = false; - sourceValue.instruction = getItem; + CompilerValue sourceValue(Compiler::StaticType::Unknown); getItem->functionReturnReg = &sourceValue; - auto appendList1_1 = std::make_shared(LLVMInstruction::Type::AppendToList, false); + auto appendList1_1 = std::make_shared(InstructionBase::Type::AppendToList, false); appendList1_1->targetList = &targetList; appendList1_1->args.push_back({ Compiler::StaticType::Unknown, &sourceValue }); list.addInstruction(appendList1_1); diff --git a/test/llvm/code_analyzer/mixed_type_analysis.cpp b/test/llvm/code_analyzer/mixed_type_analysis.cpp index cfd2133f2..d5bc4c28a 100644 --- a/test/llvm/code_analyzer/mixed_type_analysis.cpp +++ b/test/llvm/code_analyzer/mixed_type_analysis.cpp @@ -2,84 +2,77 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include using namespace libscratchcpp; -class LLVMCodeAnalyzer_MixedTypeAnalysis : public testing::Test +class CodeAnalyzer_MixedTypeAnalysis : public testing::Test { public: void SetUp() override { auto engine = m_project.engine(); - m_ctx = std::make_unique(engine.get(), &m_target); - m_builder = std::make_unique>(*m_ctx->llvmCtx()); - m_utils = std::make_unique(m_ctx.get(), *m_builder, Compiler::CodeType::Script); - m_analyzer = std::make_unique(*m_utils); + const std::unordered_set unsafeConstants = {}; + m_ctx = std::make_unique(engine.get(), &m_target, unsafeConstants); + m_analyzer = std::make_unique(m_ctx.get()); } - std::unique_ptr m_analyzer; + std::unique_ptr m_analyzer; private: Project m_project; Target m_target; - std::unique_ptr m_ctx; - std::unique_ptr> m_builder; - std::unique_ptr m_utils; + std::unique_ptr m_ctx; }; -TEST_F(LLVMCodeAnalyzer_MixedTypeAnalysis, EmptyScript) +TEST_F(CodeAnalyzer_MixedTypeAnalysis, EmptyScript) { - LLVMInstructionList list; + InstructionListBase list; m_analyzer->analyzeScript(list); } -TEST_F(LLVMCodeAnalyzer_MixedTypeAnalysis, NoOperations) +TEST_F(CodeAnalyzer_MixedTypeAnalysis, NoOperations) { - LLVMInstructionList list; + InstructionListBase list; - auto funcCall = std::make_shared(LLVMInstruction::Type::FunctionCall, false); + auto funcCall = std::make_shared(InstructionBase::Type::FunctionCall, false); list.addInstruction(funcCall); m_analyzer->analyzeScript(list); } -TEST_F(LLVMCodeAnalyzer_MixedTypeAnalysis, VariableToList_SimpleTransfer) +TEST_F(CodeAnalyzer_MixedTypeAnalysis, VariableToList_SimpleTransfer) { - LLVMInstructionList list; + InstructionListBase list; Variable sourceVar("sourceVar", ""); List targetList("targetList", ""); - auto clearList = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearList = std::make_shared(InstructionBase::Type::ClearList, false); clearList->targetList = &targetList; list.addInstruction(clearList); // Write to variable - auto writeVar = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister varValue(Compiler::StaticType::String, "hello"); + auto writeVar = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant varValue(Compiler::StaticType::String, "hello"); writeVar->targetVariable = &sourceVar; writeVar->args.push_back({ Compiler::StaticType::Unknown, &varValue }); list.addInstruction(writeVar); // Read from variable and write to list - auto readVar = std::make_shared(LLVMInstruction::Type::ReadVariable, false); + auto readVar = std::make_shared(InstructionBase::Type::ReadVariable, false); readVar->targetVariable = &sourceVar; list.addInstruction(readVar); - LLVMRegister readVarReg(Compiler::StaticType::Unknown); - readVarReg.isRawValue = false; - readVarReg.instruction = readVar; + CompilerValue readVarReg(Compiler::StaticType::Unknown); readVar->functionReturnReg = &readVarReg; - auto appendList = std::make_shared(LLVMInstruction::Type::AppendToList, false); + auto appendList = std::make_shared(InstructionBase::Type::AppendToList, false); appendList->targetList = &targetList; appendList->args.push_back({ Compiler::StaticType::Unknown, &readVarReg }); list.addInstruction(appendList); @@ -99,36 +92,34 @@ TEST_F(LLVMCodeAnalyzer_MixedTypeAnalysis, VariableToList_SimpleTransfer) ASSERT_EQ(readVarReg.type(), Compiler::StaticType::String); } -TEST_F(LLVMCodeAnalyzer_MixedTypeAnalysis, ListToVariable_SimpleTransfer) +TEST_F(CodeAnalyzer_MixedTypeAnalysis, ListToVariable_SimpleTransfer) { - LLVMInstructionList list; + InstructionListBase list; List sourceList("sourceList", ""); Variable targetVar("targetVar", ""); - auto clearList = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearList = std::make_shared(InstructionBase::Type::ClearList, false); clearList->targetList = &sourceList; list.addInstruction(clearList); // Write to list - auto appendList = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister listValue(Compiler::StaticType::Bool, true); + auto appendList = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant listValue(Compiler::StaticType::Bool, true); appendList->targetList = &sourceList; appendList->args.push_back({ Compiler::StaticType::Unknown, &listValue }); list.addInstruction(appendList); // Read from list and write to variable - auto getListItem = std::make_shared(LLVMInstruction::Type::GetListItem, false); - LLVMConstantRegister index(Compiler::StaticType::Number, 0); + auto getListItem = std::make_shared(InstructionBase::Type::GetListItem, false); + CompilerConstant index(Compiler::StaticType::Number, 0); getListItem->targetList = &sourceList; getListItem->args.push_back({ Compiler::StaticType::Number, &index }); list.addInstruction(getListItem); - LLVMRegister readListReg(Compiler::StaticType::Unknown); - readListReg.isRawValue = false; - readListReg.instruction = getListItem; + CompilerValue readListReg(Compiler::StaticType::Unknown); getListItem->functionReturnReg = &readListReg; - auto writeVar = std::make_shared(LLVMInstruction::Type::WriteVariable, false); + auto writeVar = std::make_shared(InstructionBase::Type::WriteVariable, false); writeVar->targetVariable = &targetVar; writeVar->args.push_back({ Compiler::StaticType::Unknown, &readListReg }); list.addInstruction(writeVar); @@ -148,52 +139,48 @@ TEST_F(LLVMCodeAnalyzer_MixedTypeAnalysis, ListToVariable_SimpleTransfer) ASSERT_EQ(readListReg.type(), Compiler::StaticType::Bool | Compiler::StaticType::String); } -TEST_F(LLVMCodeAnalyzer_MixedTypeAnalysis, CircularVarListDependency) +TEST_F(CodeAnalyzer_MixedTypeAnalysis, CircularVarListDependency) { - LLVMInstructionList list; + InstructionListBase list; Variable var("var", ""); List targetList("list", ""); // Initialize variable with number - auto writeVar1 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 42); + auto writeVar1 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value1(Compiler::StaticType::Number, 42); writeVar1->targetVariable = &var; writeVar1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(writeVar1); // Clear list - auto clearList = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearList = std::make_shared(InstructionBase::Type::ClearList, false); clearList->targetList = &targetList; list.addInstruction(clearList); // Read from variable and write to list - auto readVar = std::make_shared(LLVMInstruction::Type::ReadVariable, false); + auto readVar = std::make_shared(InstructionBase::Type::ReadVariable, false); readVar->targetVariable = &var; list.addInstruction(readVar); - LLVMRegister readVarReg(Compiler::StaticType::Unknown); - readVarReg.isRawValue = false; - readVarReg.instruction = readVar; + CompilerValue readVarReg(Compiler::StaticType::Unknown); readVar->functionReturnReg = &readVarReg; - auto appendList = std::make_shared(LLVMInstruction::Type::AppendToList, false); + auto appendList = std::make_shared(InstructionBase::Type::AppendToList, false); appendList->targetList = &targetList; appendList->args.push_back({ Compiler::StaticType::Unknown, &readVarReg }); list.addInstruction(appendList); // Read from list and write back to variable (circular dependency) - auto getListItem = std::make_shared(LLVMInstruction::Type::GetListItem, false); - LLVMConstantRegister index(Compiler::StaticType::Number, 0); + auto getListItem = std::make_shared(InstructionBase::Type::GetListItem, false); + CompilerConstant index(Compiler::StaticType::Number, 0); getListItem->targetList = &targetList; getListItem->args.push_back({ Compiler::StaticType::Number, &index }); list.addInstruction(getListItem); - LLVMRegister readListReg(Compiler::StaticType::Unknown); - readListReg.isRawValue = false; - readListReg.instruction = getListItem; + CompilerValue readListReg(Compiler::StaticType::Unknown); getListItem->functionReturnReg = &readListReg; - auto writeVar2 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); + auto writeVar2 = std::make_shared(InstructionBase::Type::WriteVariable, false); writeVar2->targetVariable = &var; writeVar2->args.push_back({ Compiler::StaticType::Unknown, &readListReg }); list.addInstruction(writeVar2); @@ -208,49 +195,47 @@ TEST_F(LLVMCodeAnalyzer_MixedTypeAnalysis, CircularVarListDependency) ASSERT_EQ(writeVar2->targetType, Compiler::StaticType::Number); } -TEST_F(LLVMCodeAnalyzer_MixedTypeAnalysis, LoopWithVarListInteraction_TypeConflict) +TEST_F(CodeAnalyzer_MixedTypeAnalysis, LoopWithVarListInteraction_TypeConflict) { - LLVMInstructionList list; + InstructionListBase list; Variable var("var", ""); List targetList("list", ""); - auto clearList = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearList = std::make_shared(InstructionBase::Type::ClearList, false); clearList->targetList = &targetList; list.addInstruction(clearList); // First iteration: write string to variable - auto writeVar1 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value1(Compiler::StaticType::String, "text"); + auto writeVar1 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value1(Compiler::StaticType::String, "text"); writeVar1->targetVariable = &var; writeVar1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(writeVar1); - auto loopStart = std::make_shared(LLVMInstruction::Type::BeginRepeatLoop, false); + auto loopStart = std::make_shared(InstructionBase::Type::BeginRepeatLoop, false); list.addInstruction(loopStart); // Read from variable and write to list - auto readVar = std::make_shared(LLVMInstruction::Type::ReadVariable, false); + auto readVar = std::make_shared(InstructionBase::Type::ReadVariable, false); readVar->targetVariable = &var; list.addInstruction(readVar); - LLVMRegister readVarReg(Compiler::StaticType::Unknown); - readVarReg.isRawValue = false; - readVarReg.instruction = readVar; + CompilerValue readVarReg(Compiler::StaticType::Unknown); readVar->functionReturnReg = &readVarReg; - auto appendList = std::make_shared(LLVMInstruction::Type::AppendToList, false); + auto appendList = std::make_shared(InstructionBase::Type::AppendToList, false); appendList->targetList = &targetList; appendList->args.push_back({ Compiler::StaticType::Unknown, &readVarReg }); list.addInstruction(appendList); // Second iteration: write number to variable (creates type conflict) - auto writeVar2 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value2(Compiler::StaticType::Number, 42); + auto writeVar2 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value2(Compiler::StaticType::Number, 42); writeVar2->targetVariable = &var; writeVar2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(writeVar2); - auto loopEnd = std::make_shared(LLVMInstruction::Type::EndLoop, false); + auto loopEnd = std::make_shared(InstructionBase::Type::EndLoop, false); list.addInstruction(loopEnd); m_analyzer->analyzeScript(list); @@ -262,65 +247,61 @@ TEST_F(LLVMCodeAnalyzer_MixedTypeAnalysis, LoopWithVarListInteraction_TypeConfli ASSERT_EQ(writeVar2->targetType, Compiler::StaticType::String | Compiler::StaticType::Number); } -TEST_F(LLVMCodeAnalyzer_MixedTypeAnalysis, ConditionalVarListTransfer_TypeConflict) +TEST_F(CodeAnalyzer_MixedTypeAnalysis, ConditionalVarListTransfer_TypeConflict) { - LLVMInstructionList list; + InstructionListBase list; Variable var("var", ""); List targetList("list", ""); - auto clearList = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearList = std::make_shared(InstructionBase::Type::ClearList, false); clearList->targetList = &targetList; list.addInstruction(clearList); - auto ifStart = std::make_shared(LLVMInstruction::Type::BeginIf, false); + auto ifStart = std::make_shared(InstructionBase::Type::BeginIf, false); list.addInstruction(ifStart); // If branch: write number to variable, transfer to list - auto writeVar1 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 123); + auto writeVar1 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value1(Compiler::StaticType::Number, 123); writeVar1->targetVariable = &var; writeVar1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(writeVar1); - auto readVar1 = std::make_shared(LLVMInstruction::Type::ReadVariable, false); + auto readVar1 = std::make_shared(InstructionBase::Type::ReadVariable, false); readVar1->targetVariable = &var; list.addInstruction(readVar1); - LLVMRegister readVar1Reg(Compiler::StaticType::Unknown); - readVar1Reg.isRawValue = false; - readVar1Reg.instruction = readVar1; + CompilerValue readVar1Reg(Compiler::StaticType::Unknown); readVar1->functionReturnReg = &readVar1Reg; - auto appendList1 = std::make_shared(LLVMInstruction::Type::AppendToList, false); + auto appendList1 = std::make_shared(InstructionBase::Type::AppendToList, false); appendList1->targetList = &targetList; appendList1->args.push_back({ Compiler::StaticType::Unknown, &readVar1Reg }); list.addInstruction(appendList1); - auto elseStart = std::make_shared(LLVMInstruction::Type::BeginElse, false); + auto elseStart = std::make_shared(InstructionBase::Type::BeginElse, false); list.addInstruction(elseStart); // Else branch: write string to variable, transfer to list - auto writeVar2 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value2(Compiler::StaticType::String, "hello"); + auto writeVar2 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value2(Compiler::StaticType::String, "hello"); writeVar2->targetVariable = &var; writeVar2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(writeVar2); - auto readVar2 = std::make_shared(LLVMInstruction::Type::ReadVariable, false); + auto readVar2 = std::make_shared(InstructionBase::Type::ReadVariable, false); readVar2->targetVariable = &var; list.addInstruction(readVar2); - LLVMRegister readVar2Reg(Compiler::StaticType::Unknown); - readVar2Reg.isRawValue = false; - readVar2Reg.instruction = readVar2; + CompilerValue readVar2Reg(Compiler::StaticType::Unknown); readVar2->functionReturnReg = &readVar2Reg; - auto appendList2 = std::make_shared(LLVMInstruction::Type::AppendToList, false); + auto appendList2 = std::make_shared(InstructionBase::Type::AppendToList, false); appendList2->targetList = &targetList; appendList2->args.push_back({ Compiler::StaticType::Unknown, &readVar2Reg }); list.addInstruction(appendList2); - auto ifEnd = std::make_shared(LLVMInstruction::Type::EndIf, false); + auto ifEnd = std::make_shared(InstructionBase::Type::EndIf, false); list.addInstruction(ifEnd); m_analyzer->analyzeScript(list); @@ -332,57 +313,53 @@ TEST_F(LLVMCodeAnalyzer_MixedTypeAnalysis, ConditionalVarListTransfer_TypeConfli ASSERT_EQ(appendList2->targetType, Compiler::StaticType::Void); } -TEST_F(LLVMCodeAnalyzer_MixedTypeAnalysis, MultipleVarsToSingleList_TypePropagation) +TEST_F(CodeAnalyzer_MixedTypeAnalysis, MultipleVarsToSingleList_TypePropagation) { - LLVMInstructionList list; + InstructionListBase list; Variable var1("var1", ""); Variable var2("var2", ""); List targetList("list", ""); - auto clearList = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearList = std::make_shared(InstructionBase::Type::ClearList, false); clearList->targetList = &targetList; list.addInstruction(clearList); // Initialize first variable with boolean - auto writeVar1 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value1(Compiler::StaticType::Bool, true); + auto writeVar1 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value1(Compiler::StaticType::Bool, true); writeVar1->targetVariable = &var1; writeVar1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(writeVar1); // Initialize second variable with same type - auto writeVar2 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value2(Compiler::StaticType::Bool, false); + auto writeVar2 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value2(Compiler::StaticType::Bool, false); writeVar2->targetVariable = &var2; writeVar2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(writeVar2); // Read from first variable and write to list - auto readVar1 = std::make_shared(LLVMInstruction::Type::ReadVariable, false); + auto readVar1 = std::make_shared(InstructionBase::Type::ReadVariable, false); readVar1->targetVariable = &var1; list.addInstruction(readVar1); - LLVMRegister readVar1Reg(Compiler::StaticType::Unknown); - readVar1Reg.isRawValue = false; - readVar1Reg.instruction = readVar1; + CompilerValue readVar1Reg(Compiler::StaticType::Unknown); readVar1->functionReturnReg = &readVar1Reg; - auto appendList1 = std::make_shared(LLVMInstruction::Type::AppendToList, false); + auto appendList1 = std::make_shared(InstructionBase::Type::AppendToList, false); appendList1->targetList = &targetList; appendList1->args.push_back({ Compiler::StaticType::Unknown, &readVar1Reg }); list.addInstruction(appendList1); // Read from second variable and write to list - auto readVar2 = std::make_shared(LLVMInstruction::Type::ReadVariable, false); + auto readVar2 = std::make_shared(InstructionBase::Type::ReadVariable, false); readVar2->targetVariable = &var2; list.addInstruction(readVar2); - LLVMRegister readVar2Reg(Compiler::StaticType::Unknown); - readVar2Reg.isRawValue = false; - readVar2Reg.instruction = readVar2; + CompilerValue readVar2Reg(Compiler::StaticType::Unknown); readVar2->functionReturnReg = &readVar2Reg; - auto appendList2 = std::make_shared(LLVMInstruction::Type::AppendToList, false); + auto appendList2 = std::make_shared(InstructionBase::Type::AppendToList, false); appendList2->targetList = &targetList; appendList2->args.push_back({ Compiler::StaticType::Unknown, &readVar2Reg }); list.addInstruction(appendList2); @@ -394,60 +371,56 @@ TEST_F(LLVMCodeAnalyzer_MixedTypeAnalysis, MultipleVarsToSingleList_TypePropagat ASSERT_EQ(appendList2->targetType, Compiler::StaticType::Bool); } -TEST_F(LLVMCodeAnalyzer_MixedTypeAnalysis, SingleListToMultipleVars_TypePropagation) +TEST_F(CodeAnalyzer_MixedTypeAnalysis, SingleListToMultipleVars_TypePropagation) { - LLVMInstructionList list; + InstructionListBase list; List sourceList("sourceList", ""); Variable var1("var1", ""); Variable var2("var2", ""); - auto clearList = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearList = std::make_shared(InstructionBase::Type::ClearList, false); clearList->targetList = &sourceList; list.addInstruction(clearList); // Initialize list with string values - auto appendList1 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister listValue1(Compiler::StaticType::String, "first"); + auto appendList1 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant listValue1(Compiler::StaticType::String, "first"); appendList1->targetList = &sourceList; appendList1->args.push_back({ Compiler::StaticType::Unknown, &listValue1 }); list.addInstruction(appendList1); - auto appendList2 = std::make_shared(LLVMInstruction::Type::AppendToList, false); - LLVMConstantRegister listValue2(Compiler::StaticType::String, "second"); + auto appendList2 = std::make_shared(InstructionBase::Type::AppendToList, false); + CompilerConstant listValue2(Compiler::StaticType::String, "second"); appendList2->targetList = &sourceList; appendList2->args.push_back({ Compiler::StaticType::Unknown, &listValue2 }); list.addInstruction(appendList2); // Read first item and write to first variable - auto readList1 = std::make_shared(LLVMInstruction::Type::GetListItem, false); - LLVMConstantRegister index1(Compiler::StaticType::Number, 0); + auto readList1 = std::make_shared(InstructionBase::Type::GetListItem, false); + CompilerConstant index1(Compiler::StaticType::Number, 0); readList1->targetList = &sourceList; readList1->args.push_back({ Compiler::StaticType::Number, &index1 }); list.addInstruction(readList1); - LLVMRegister readList1Reg(Compiler::StaticType::Unknown); - readList1Reg.isRawValue = false; - readList1Reg.instruction = readList1; + CompilerValue readList1Reg(Compiler::StaticType::Unknown); readList1->functionReturnReg = &readList1Reg; - auto writeVar1 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); + auto writeVar1 = std::make_shared(InstructionBase::Type::WriteVariable, false); writeVar1->targetVariable = &var1; writeVar1->args.push_back({ Compiler::StaticType::Unknown, &readList1Reg }); list.addInstruction(writeVar1); // Read second item and write to second variable - auto readList2 = std::make_shared(LLVMInstruction::Type::GetListItem, false); - LLVMConstantRegister index2(Compiler::StaticType::Number, 1); + auto readList2 = std::make_shared(InstructionBase::Type::GetListItem, false); + CompilerConstant index2(Compiler::StaticType::Number, 1); readList2->targetList = &sourceList; readList2->args.push_back({ Compiler::StaticType::Number, &index2 }); list.addInstruction(readList2); - LLVMRegister readList2Reg(Compiler::StaticType::Unknown); - readList2Reg.isRawValue = false; - readList2Reg.instruction = readList2; + CompilerValue readList2Reg(Compiler::StaticType::Unknown); readList2->functionReturnReg = &readList2Reg; - auto writeVar2 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); + auto writeVar2 = std::make_shared(InstructionBase::Type::WriteVariable, false); writeVar2->targetVariable = &var2; writeVar2->args.push_back({ Compiler::StaticType::Unknown, &readList2Reg }); list.addInstruction(writeVar2); @@ -461,52 +434,48 @@ TEST_F(LLVMCodeAnalyzer_MixedTypeAnalysis, SingleListToMultipleVars_TypePropagat ASSERT_EQ(readList2Reg.type(), Compiler::StaticType::String); } -TEST_F(LLVMCodeAnalyzer_MixedTypeAnalysis, ComplexChain_VarToListToVar_TypePropagation) +TEST_F(CodeAnalyzer_MixedTypeAnalysis, ComplexChain_VarToListToVar_TypePropagation) { - LLVMInstructionList list; + InstructionListBase list; Variable sourceVar("sourceVar", ""); List intermediateList("intermediateList", ""); Variable targetVar("targetVar", ""); - auto clearList = std::make_shared(LLVMInstruction::Type::ClearList, false); + auto clearList = std::make_shared(InstructionBase::Type::ClearList, false); clearList->targetList = &intermediateList; list.addInstruction(clearList); // Initialize source variable - auto writeSourceVar = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister sourceValue(Compiler::StaticType::Number, 3.14159); + auto writeSourceVar = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant sourceValue(Compiler::StaticType::Number, 3.14159); writeSourceVar->targetVariable = &sourceVar; writeSourceVar->args.push_back({ Compiler::StaticType::Unknown, &sourceValue }); list.addInstruction(writeSourceVar); // Read from source variable and write to intermediate list - auto readSourceVar = std::make_shared(LLVMInstruction::Type::ReadVariable, false); + auto readSourceVar = std::make_shared(InstructionBase::Type::ReadVariable, false); readSourceVar->targetVariable = &sourceVar; list.addInstruction(readSourceVar); - LLVMRegister readSourceVarReg(Compiler::StaticType::Unknown); - readSourceVarReg.isRawValue = false; - readSourceVarReg.instruction = readSourceVar; + CompilerValue readSourceVarReg(Compiler::StaticType::Unknown); readSourceVar->functionReturnReg = &readSourceVarReg; - auto appendList = std::make_shared(LLVMInstruction::Type::AppendToList, false); + auto appendList = std::make_shared(InstructionBase::Type::AppendToList, false); appendList->targetList = &intermediateList; appendList->args.push_back({ Compiler::StaticType::Unknown, &readSourceVarReg }); list.addInstruction(appendList); // Read from intermediate list and write to target variable - auto readList = std::make_shared(LLVMInstruction::Type::GetListItem, false); - LLVMConstantRegister index(Compiler::StaticType::Number, 0); + auto readList = std::make_shared(InstructionBase::Type::GetListItem, false); + CompilerConstant index(Compiler::StaticType::Number, 0); readList->targetList = &intermediateList; readList->args.push_back({ Compiler::StaticType::Number, &index }); list.addInstruction(readList); - LLVMRegister readListReg(Compiler::StaticType::Unknown); - readListReg.isRawValue = false; - readListReg.instruction = readList; + CompilerValue readListReg(Compiler::StaticType::Unknown); readList->functionReturnReg = &readListReg; - auto writeTargetVar = std::make_shared(LLVMInstruction::Type::WriteVariable, false); + auto writeTargetVar = std::make_shared(InstructionBase::Type::WriteVariable, false); writeTargetVar->targetVariable = &targetVar; writeTargetVar->args.push_back({ Compiler::StaticType::Unknown, &readListReg }); list.addInstruction(writeTargetVar); diff --git a/test/llvm/code_analyzer/variable_type_analysis.cpp b/test/llvm/code_analyzer/variable_type_analysis.cpp index 10361a201..ce46efd9d 100644 --- a/test/llvm/code_analyzer/variable_type_analysis.cpp +++ b/test/llvm/code_analyzer/variable_type_analysis.cpp @@ -2,18 +2,16 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include using namespace libscratchcpp; -class LLVMCodeAnalyzer_VariableTypeAnalysis : public testing::Test +class CodeAnalyzer_VariableTypeAnalysis : public testing::Test { public: void SetUp() override @@ -24,13 +22,11 @@ class LLVMCodeAnalyzer_VariableTypeAnalysis : public testing::Test engine->setTargets({ m_target }); const std::unordered_set unsafeConstants = { m_unsafeCostumeNumConstant, m_unsafeSoundNumConstant }; - m_ctx = std::make_unique(engine.get(), m_target.get(), unsafeConstants); - m_builder = std::make_unique>(*m_ctx->llvmCtx()); - m_utils = std::make_unique(m_ctx.get(), *m_builder, Compiler::CodeType::Script); - m_analyzer = std::make_unique(*m_utils); + m_ctx = std::make_unique(engine.get(), m_target.get(), unsafeConstants); + m_analyzer = std::make_unique(m_ctx.get()); } - std::unique_ptr m_analyzer; + std::unique_ptr m_analyzer; const std::string m_safeNumConstant = "3.14"; const std::string m_unsafeCostumeNumConstant = "12"; @@ -39,18 +35,16 @@ class LLVMCodeAnalyzer_VariableTypeAnalysis : public testing::Test private: Project m_project; std::shared_ptr m_target; - std::unique_ptr m_ctx; - std::unique_ptr> m_builder; - std::unique_ptr m_utils; + std::unique_ptr m_ctx; }; -TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, FirstVariableWrite) +TEST_F(CodeAnalyzer_VariableTypeAnalysis, FirstVariableWrite) { - LLVMInstructionList list; + InstructionListBase list; Variable var("", ""); - auto setVar = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value(Compiler::StaticType::Number, 42.0); + auto setVar = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value(Compiler::StaticType::Number, 42.0); setVar->targetVariable = &var; setVar->args.push_back({ Compiler::StaticType::Unknown, &value }); list.addInstruction(setVar); @@ -61,13 +55,13 @@ TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, FirstVariableWrite) ASSERT_EQ(setVar->targetType, Compiler::StaticType::Unknown); } -TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, FirstVariableWrite_ArgType) +TEST_F(CodeAnalyzer_VariableTypeAnalysis, FirstVariableWrite_ArgType) { - LLVMInstructionList list; + InstructionListBase list; Variable var("", ""); - auto setVar = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value(Compiler::StaticType::String, "test"); + auto setVar = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value(Compiler::StaticType::String, "test"); setVar->targetVariable = &var; setVar->args.push_back({ Compiler::StaticType::Unknown, &value }); list.addInstruction(setVar); @@ -78,19 +72,19 @@ TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, FirstVariableWrite_ArgType) ASSERT_EQ(setVar->args.back().first, Compiler::StaticType::String); } -TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, SecondVariableWrite) +TEST_F(CodeAnalyzer_VariableTypeAnalysis, SecondVariableWrite) { - LLVMInstructionList list; + InstructionListBase list; Variable var("", ""); - auto setVar1 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 42); + auto setVar1 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value1(Compiler::StaticType::Number, 42); setVar1->targetVariable = &var; setVar1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(setVar1); - auto setVar2 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value2(Compiler::StaticType::String, "hello"); + auto setVar2 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value2(Compiler::StaticType::String, "hello"); setVar2->targetVariable = &var; setVar2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(setVar2); @@ -103,26 +97,24 @@ TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, SecondVariableWrite) ASSERT_EQ(setVar2->targetType, Compiler::StaticType::Number); } -TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, InstructionReturnTypePropagation) +TEST_F(CodeAnalyzer_VariableTypeAnalysis, InstructionReturnTypePropagation) { - LLVMInstructionList list; + InstructionListBase list; Variable var("", ""); - auto ins = std::make_shared(LLVMInstruction::Type::Add, true); + auto ins = std::make_shared(InstructionBase::Type::Add, true); list.addInstruction(ins); - LLVMRegister ret(Compiler::StaticType::Number); - ret.isRawValue = false; - ret.instruction = ins; + CompilerValue ret(Compiler::StaticType::Number); ins->functionReturnReg = &ret; - auto setVar1 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); + auto setVar1 = std::make_shared(InstructionBase::Type::WriteVariable, false); setVar1->targetVariable = &var; setVar1->args.push_back({ Compiler::StaticType::Unknown, &ret }); list.addInstruction(setVar1); - auto setVar2 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value2(Compiler::StaticType::String, "hello"); + auto setVar2 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value2(Compiler::StaticType::String, "hello"); setVar2->targetVariable = &var; setVar2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(setVar2); @@ -135,20 +127,18 @@ TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, InstructionReturnTypePropagation) ASSERT_EQ(setVar2->targetType, Compiler::StaticType::Number); } -TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, InstructionReturnTypePropagation_ArgType) +TEST_F(CodeAnalyzer_VariableTypeAnalysis, InstructionReturnTypePropagation_ArgType) { - LLVMInstructionList list; + InstructionListBase list; Variable var("", ""); - auto ins = std::make_shared(LLVMInstruction::Type::Add, true); + auto ins = std::make_shared(InstructionBase::Type::Add, true); list.addInstruction(ins); - LLVMRegister ret(Compiler::StaticType::Number); - ret.isRawValue = false; - ret.instruction = ins; + CompilerValue ret(Compiler::StaticType::Number); ins->functionReturnReg = &ret; - auto setVar1 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); + auto setVar1 = std::make_shared(InstructionBase::Type::WriteVariable, false); setVar1->targetVariable = &var; setVar1->args.push_back({ Compiler::StaticType::Unknown, &ret }); list.addInstruction(setVar1); @@ -159,25 +149,25 @@ TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, InstructionReturnTypePropagation_A ASSERT_EQ(setVar1->args.back().first, Compiler::StaticType::Number); } -TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, MultipleWritesSameType) +TEST_F(CodeAnalyzer_VariableTypeAnalysis, MultipleWritesSameType) { - LLVMInstructionList list; + InstructionListBase list; Variable var("", ""); - auto setVar1 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value1(Compiler::StaticType::String, "first"); + auto setVar1 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value1(Compiler::StaticType::String, "first"); setVar1->targetVariable = &var; setVar1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(setVar1); - auto setVar2 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value2(Compiler::StaticType::String, "second"); + auto setVar2 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value2(Compiler::StaticType::String, "second"); setVar2->targetVariable = &var; setVar2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(setVar2); - auto setVar3 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value3(Compiler::StaticType::String, "third"); + auto setVar3 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value3(Compiler::StaticType::String, "third"); setVar3->targetVariable = &var; setVar3->args.push_back({ Compiler::StaticType::Unknown, &value3 }); list.addInstruction(setVar3); @@ -189,19 +179,19 @@ TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, MultipleWritesSameType) ASSERT_EQ(setVar3->targetType, Compiler::StaticType::String); } -TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, StringOptimization) +TEST_F(CodeAnalyzer_VariableTypeAnalysis, StringOptimization) { - LLVMInstructionList list; + InstructionListBase list; Variable var("", ""); - auto setVar1 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value1(Compiler::StaticType::String, m_safeNumConstant); + auto setVar1 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value1(Compiler::StaticType::String, m_safeNumConstant); setVar1->targetVariable = &var; setVar1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(setVar1); - auto setVar2 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value2(Compiler::StaticType::Bool, true); + auto setVar2 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value2(Compiler::StaticType::Bool, true); setVar2->targetVariable = &var; setVar2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(setVar2); @@ -213,19 +203,19 @@ TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, StringOptimization) ASSERT_EQ(setVar2->targetType, Compiler::StaticType::Number); } -TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, StringOptimization_DifferentString) +TEST_F(CodeAnalyzer_VariableTypeAnalysis, StringOptimization_DifferentString) { - LLVMInstructionList list; + InstructionListBase list; Variable var("", ""); - auto setVar1 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value1(Compiler::StaticType::String, "1.0"); + auto setVar1 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value1(Compiler::StaticType::String, "1.0"); setVar1->targetVariable = &var; setVar1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(setVar1); - auto setVar2 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value2(Compiler::StaticType::Bool, true); + auto setVar2 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value2(Compiler::StaticType::Bool, true); setVar2->targetVariable = &var; setVar2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(setVar2); @@ -237,19 +227,19 @@ TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, StringOptimization_DifferentString ASSERT_EQ(setVar2->targetType, Compiler::StaticType::String); } -TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, StringOptimization_UnsafeCostumeConstant) +TEST_F(CodeAnalyzer_VariableTypeAnalysis, StringOptimization_UnsafeCostumeConstant) { - LLVMInstructionList list; + InstructionListBase list; Variable var("", ""); - auto setVar1 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value1(Compiler::StaticType::String, m_unsafeCostumeNumConstant); + auto setVar1 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value1(Compiler::StaticType::String, m_unsafeCostumeNumConstant); setVar1->targetVariable = &var; setVar1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(setVar1); - auto setVar2 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value2(Compiler::StaticType::Bool, true); + auto setVar2 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value2(Compiler::StaticType::Bool, true); setVar2->targetVariable = &var; setVar2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(setVar2); @@ -261,19 +251,19 @@ TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, StringOptimization_UnsafeCostumeCo ASSERT_EQ(setVar2->targetType, Compiler::StaticType::String); } -TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, StringOptimization_UnsafeSoundConstant) +TEST_F(CodeAnalyzer_VariableTypeAnalysis, StringOptimization_UnsafeSoundConstant) { - LLVMInstructionList list; + InstructionListBase list; Variable var("", ""); - auto setVar1 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value1(Compiler::StaticType::String, m_unsafeSoundNumConstant); + auto setVar1 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value1(Compiler::StaticType::String, m_unsafeSoundNumConstant); setVar1->targetVariable = &var; setVar1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(setVar1); - auto setVar2 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value2(Compiler::StaticType::Bool, true); + auto setVar2 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value2(Compiler::StaticType::Bool, true); setVar2->targetVariable = &var; setVar2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(setVar2); @@ -285,13 +275,13 @@ TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, StringOptimization_UnsafeSoundCons ASSERT_EQ(setVar2->targetType, Compiler::StaticType::String); } -TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, ArgTypeStringOptimization) +TEST_F(CodeAnalyzer_VariableTypeAnalysis, ArgTypeStringOptimization) { - LLVMInstructionList list; + InstructionListBase list; Variable var("", ""); - auto setVar1 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value1(Compiler::StaticType::String, m_safeNumConstant); + auto setVar1 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value1(Compiler::StaticType::String, m_safeNumConstant); setVar1->targetVariable = &var; setVar1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(setVar1); @@ -301,21 +291,21 @@ TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, ArgTypeStringOptimization) ASSERT_EQ(setVar1->args.back().first, Compiler::StaticType::Number); } -TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, LoopSingleWrite) +TEST_F(CodeAnalyzer_VariableTypeAnalysis, LoopSingleWrite) { - LLVMInstructionList list; + InstructionListBase list; Variable var("", ""); - auto loopStart = std::make_shared(LLVMInstruction::Type::BeginRepeatLoop, false); + auto loopStart = std::make_shared(InstructionBase::Type::BeginRepeatLoop, false); list.addInstruction(loopStart); - auto setVar = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value(Compiler::StaticType::Number, 1.25); + auto setVar = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value(Compiler::StaticType::Number, 1.25); setVar->targetVariable = &var; setVar->args.push_back({ Compiler::StaticType::Unknown, &value }); list.addInstruction(setVar); - auto loopEnd = std::make_shared(LLVMInstruction::Type::EndLoop, false); + auto loopEnd = std::make_shared(InstructionBase::Type::EndLoop, false); list.addInstruction(loopEnd); m_analyzer->analyzeScript(list); @@ -324,42 +314,40 @@ TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, LoopSingleWrite) ASSERT_EQ(setVar->targetType, Compiler::StaticType::Unknown); } -TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, WhileLoop) +TEST_F(CodeAnalyzer_VariableTypeAnalysis, WhileLoop) { - LLVMInstructionList list; + InstructionListBase list; Variable var("", ""); // Establish bool type before loop - auto setVar = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value(Compiler::StaticType::Bool, true); + auto setVar = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value(Compiler::StaticType::Bool, true); setVar->targetVariable = &var; setVar->args.push_back({ Compiler::StaticType::Unknown, &value }); list.addInstruction(setVar); - auto loopCond = std::make_shared(LLVMInstruction::Type::BeginLoopCondition, false); + auto loopCond = std::make_shared(InstructionBase::Type::BeginLoopCondition, false); list.addInstruction(loopCond); // Read the variable in loop condition - auto readVar = std::make_shared(LLVMInstruction::Type::ReadVariable, true); + auto readVar = std::make_shared(InstructionBase::Type::ReadVariable, true); readVar->targetVariable = &var; list.addInstruction(readVar); - LLVMRegister varValue(Compiler::StaticType::Unknown); - varValue.isRawValue = false; - varValue.instruction = readVar; + CompilerValue varValue(Compiler::StaticType::Unknown); readVar->functionReturnReg = &varValue; - auto loopStart = std::make_shared(LLVMInstruction::Type::BeginWhileLoop, false); + auto loopStart = std::make_shared(InstructionBase::Type::BeginWhileLoop, false); list.addInstruction(loopStart); // Change the type in the loop - auto setVar1 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 5); + auto setVar1 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value1(Compiler::StaticType::Number, 5); setVar1->targetVariable = &var; setVar1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(setVar1); - auto loopEnd = std::make_shared(LLVMInstruction::Type::EndLoop, false); + auto loopEnd = std::make_shared(InstructionBase::Type::EndLoop, false); list.addInstruction(loopEnd); m_analyzer->analyzeScript(list); @@ -368,42 +356,40 @@ TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, WhileLoop) ASSERT_EQ(setVar1->targetType, Compiler::StaticType::Number | Compiler::StaticType::Bool); } -TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, RepeatUntilLoop) +TEST_F(CodeAnalyzer_VariableTypeAnalysis, RepeatUntilLoop) { - LLVMInstructionList list; + InstructionListBase list; Variable var("", ""); // Establish bool type before loop - auto setVar = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value(Compiler::StaticType::Bool, true); + auto setVar = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value(Compiler::StaticType::Bool, true); setVar->targetVariable = &var; setVar->args.push_back({ Compiler::StaticType::Unknown, &value }); list.addInstruction(setVar); - auto loopCond = std::make_shared(LLVMInstruction::Type::BeginLoopCondition, false); + auto loopCond = std::make_shared(InstructionBase::Type::BeginLoopCondition, false); list.addInstruction(loopCond); // Read the variable in loop condition - auto readVar = std::make_shared(LLVMInstruction::Type::ReadVariable, true); + auto readVar = std::make_shared(InstructionBase::Type::ReadVariable, true); readVar->targetVariable = &var; list.addInstruction(readVar); - LLVMRegister varValue(Compiler::StaticType::Unknown); - varValue.isRawValue = false; - varValue.instruction = readVar; + CompilerValue varValue(Compiler::StaticType::Unknown); readVar->functionReturnReg = &varValue; - auto loopStart = std::make_shared(LLVMInstruction::Type::BeginRepeatUntilLoop, false); + auto loopStart = std::make_shared(InstructionBase::Type::BeginRepeatUntilLoop, false); list.addInstruction(loopStart); // Change the type in the loop - auto setVar1 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 5); + auto setVar1 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value1(Compiler::StaticType::Number, 5); setVar1->targetVariable = &var; setVar1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(setVar1); - auto loopEnd = std::make_shared(LLVMInstruction::Type::EndLoop, false); + auto loopEnd = std::make_shared(InstructionBase::Type::EndLoop, false); list.addInstruction(loopEnd); m_analyzer->analyzeScript(list); @@ -412,30 +398,30 @@ TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, RepeatUntilLoop) ASSERT_EQ(setVar1->targetType, Compiler::StaticType::Number | Compiler::StaticType::Bool); } -TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, ProcedureCallInLoop) +TEST_F(CodeAnalyzer_VariableTypeAnalysis, ProcedureCallInLoop) { - LLVMInstructionList list; + InstructionListBase list; Variable var("", ""); - auto setVar1 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 1.25); + auto setVar1 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value1(Compiler::StaticType::Number, 1.25); setVar1->targetVariable = &var; setVar1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(setVar1); - auto loopStart = std::make_shared(LLVMInstruction::Type::BeginRepeatLoop, false); + auto loopStart = std::make_shared(InstructionBase::Type::BeginRepeatLoop, false); list.addInstruction(loopStart); - auto setVar2 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value2(Compiler::StaticType::Number, 5); + auto setVar2 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value2(Compiler::StaticType::Number, 5); setVar2->targetVariable = &var; setVar2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(setVar2); - auto procCall = std::make_shared(LLVMInstruction::Type::CallProcedure, false); + auto procCall = std::make_shared(InstructionBase::Type::CallProcedure, false); list.addInstruction(procCall); - auto loopEnd = std::make_shared(LLVMInstruction::Type::EndLoop, false); + auto loopEnd = std::make_shared(InstructionBase::Type::EndLoop, false); list.addInstruction(loopEnd); m_analyzer->analyzeScript(list); @@ -446,27 +432,27 @@ TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, ProcedureCallInLoop) ASSERT_EQ(setVar2->targetType, Compiler::StaticType::Unknown); } -TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, LoopMultipleWrites_UnknownType) +TEST_F(CodeAnalyzer_VariableTypeAnalysis, LoopMultipleWrites_UnknownType) { - LLVMInstructionList list; + InstructionListBase list; Variable var("", ""); - auto loopStart = std::make_shared(LLVMInstruction::Type::BeginRepeatLoop, false); + auto loopStart = std::make_shared(InstructionBase::Type::BeginRepeatLoop, false); list.addInstruction(loopStart); - auto setVar1 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 5); + auto setVar1 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value1(Compiler::StaticType::Number, 5); setVar1->targetVariable = &var; setVar1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(setVar1); - auto setVar2 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value2(Compiler::StaticType::String, "test"); + auto setVar2 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value2(Compiler::StaticType::String, "test"); setVar2->targetVariable = &var; setVar2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(setVar2); - auto loopEnd = std::make_shared(LLVMInstruction::Type::EndLoop, false); + auto loopEnd = std::make_shared(InstructionBase::Type::EndLoop, false); list.addInstruction(loopEnd); m_analyzer->analyzeScript(list); @@ -478,34 +464,34 @@ TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, LoopMultipleWrites_UnknownType) ASSERT_EQ(setVar2->targetType, Compiler::StaticType::Number); } -TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, LoopMultipleWrites_KnownType) +TEST_F(CodeAnalyzer_VariableTypeAnalysis, LoopMultipleWrites_KnownType) { - LLVMInstructionList list; + InstructionListBase list; Variable var("", ""); // Establish bool type before loop - auto setVar = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value(Compiler::StaticType::Bool, true); + auto setVar = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value(Compiler::StaticType::Bool, true); setVar->targetVariable = &var; setVar->args.push_back({ Compiler::StaticType::Unknown, &value }); list.addInstruction(setVar); - auto loopStart = std::make_shared(LLVMInstruction::Type::BeginRepeatLoop, false); + auto loopStart = std::make_shared(InstructionBase::Type::BeginRepeatLoop, false); list.addInstruction(loopStart); - auto setVar1 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 5); + auto setVar1 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value1(Compiler::StaticType::Number, 5); setVar1->targetVariable = &var; setVar1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(setVar1); - auto setVar2 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value2(Compiler::StaticType::String, "test"); + auto setVar2 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value2(Compiler::StaticType::String, "test"); setVar2->targetVariable = &var; setVar2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(setVar2); - auto loopEnd = std::make_shared(LLVMInstruction::Type::EndLoop, false); + auto loopEnd = std::make_shared(InstructionBase::Type::EndLoop, false); list.addInstruction(loopEnd); m_analyzer->analyzeScript(list); @@ -517,50 +503,50 @@ TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, LoopMultipleWrites_KnownType) ASSERT_EQ(setVar2->targetType, Compiler::StaticType::Number); } -TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, LoopWithIfElseWrites) +TEST_F(CodeAnalyzer_VariableTypeAnalysis, LoopWithIfElseWrites) { - LLVMInstructionList list; + InstructionListBase list; Variable var("", ""); // var = "string" - auto setVarBefore = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister valueBefore(Compiler::StaticType::String, "string"); + auto setVarBefore = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant valueBefore(Compiler::StaticType::String, "string"); setVarBefore->targetVariable = &var; setVarBefore->args.push_back({ Compiler::StaticType::Unknown, &valueBefore }); list.addInstruction(setVarBefore); // repeat - auto loopStart = std::make_shared(LLVMInstruction::Type::BeginRepeatLoop, false); + auto loopStart = std::make_shared(InstructionBase::Type::BeginRepeatLoop, false); list.addInstruction(loopStart); // if - auto ifStart = std::make_shared(LLVMInstruction::Type::BeginIf, false); + auto ifStart = std::make_shared(InstructionBase::Type::BeginIf, false); list.addInstruction(ifStart); // var = 1 - auto setVar1 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 1); + auto setVar1 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value1(Compiler::StaticType::Number, 1); setVar1->targetVariable = &var; setVar1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(setVar1); // else - auto elseStart = std::make_shared(LLVMInstruction::Type::BeginElse, false); + auto elseStart = std::make_shared(InstructionBase::Type::BeginElse, false); list.addInstruction(elseStart); // var = 2 - auto setVar2 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value2(Compiler::StaticType::Number, 2); + auto setVar2 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value2(Compiler::StaticType::Number, 2); setVar2->targetVariable = &var; setVar2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(setVar2); // end if - auto ifEnd = std::make_shared(LLVMInstruction::Type::EndIf, false); + auto ifEnd = std::make_shared(InstructionBase::Type::EndIf, false); list.addInstruction(ifEnd); // end loop - auto loopEnd = std::make_shared(LLVMInstruction::Type::EndLoop, false); + auto loopEnd = std::make_shared(InstructionBase::Type::EndLoop, false); list.addInstruction(loopEnd); m_analyzer->analyzeScript(list); @@ -572,34 +558,34 @@ TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, LoopWithIfElseWrites) ASSERT_EQ(setVar2->targetType, Compiler::StaticType::String | Compiler::StaticType::Number); } -TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, IfElseStatementSameTypes) +TEST_F(CodeAnalyzer_VariableTypeAnalysis, IfElseStatementSameTypes) { - LLVMInstructionList list; + InstructionListBase list; Variable var("", ""); - auto ifStart = std::make_shared(LLVMInstruction::Type::BeginIf, false); + auto ifStart = std::make_shared(InstructionBase::Type::BeginIf, false); list.addInstruction(ifStart); - auto setVar1 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 42); + auto setVar1 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value1(Compiler::StaticType::Number, 42); setVar1->targetVariable = &var; setVar1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(setVar1); - auto elseStart = std::make_shared(LLVMInstruction::Type::BeginElse, false); + auto elseStart = std::make_shared(InstructionBase::Type::BeginElse, false); list.addInstruction(elseStart); - auto setVar2 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value2(Compiler::StaticType::Number, 1.25); + auto setVar2 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value2(Compiler::StaticType::Number, 1.25); setVar2->targetVariable = &var; setVar2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(setVar2); - auto ifEnd = std::make_shared(LLVMInstruction::Type::EndIf, false); + auto ifEnd = std::make_shared(InstructionBase::Type::EndIf, false); list.addInstruction(ifEnd); - auto setVar3 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value3(Compiler::StaticType::String, "test"); + auto setVar3 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value3(Compiler::StaticType::String, "test"); setVar3->targetVariable = &var; setVar3->args.push_back({ Compiler::StaticType::Unknown, &value3 }); list.addInstruction(setVar3); @@ -614,34 +600,34 @@ TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, IfElseStatementSameTypes) ASSERT_EQ(setVar3->targetType, Compiler::StaticType::Number); } -TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, IfElseStatementDifferentTypes) +TEST_F(CodeAnalyzer_VariableTypeAnalysis, IfElseStatementDifferentTypes) { - LLVMInstructionList list; + InstructionListBase list; Variable var("", ""); - auto ifStart = std::make_shared(LLVMInstruction::Type::BeginIf, false); + auto ifStart = std::make_shared(InstructionBase::Type::BeginIf, false); list.addInstruction(ifStart); - auto setVar1 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 42); + auto setVar1 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value1(Compiler::StaticType::Number, 42); setVar1->targetVariable = &var; setVar1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(setVar1); - auto elseStart = std::make_shared(LLVMInstruction::Type::BeginElse, false); + auto elseStart = std::make_shared(InstructionBase::Type::BeginElse, false); list.addInstruction(elseStart); - auto setVar2 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value2(Compiler::StaticType::String, "test"); + auto setVar2 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value2(Compiler::StaticType::String, "test"); setVar2->targetVariable = &var; setVar2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(setVar2); - auto ifEnd = std::make_shared(LLVMInstruction::Type::EndIf, false); + auto ifEnd = std::make_shared(InstructionBase::Type::EndIf, false); list.addInstruction(ifEnd); - auto setVar3 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value3(Compiler::StaticType::Bool, true); + auto setVar3 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value3(Compiler::StaticType::Bool, true); setVar3->targetVariable = &var; setVar3->args.push_back({ Compiler::StaticType::Unknown, &value3 }); list.addInstruction(setVar3); @@ -656,31 +642,31 @@ TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, IfElseStatementDifferentTypes) ASSERT_EQ(setVar3->targetType, Compiler::StaticType::Number | Compiler::StaticType::String); } -TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, IfElseStatementDifferentType_IfBranch) +TEST_F(CodeAnalyzer_VariableTypeAnalysis, IfElseStatementDifferentType_IfBranch) { - LLVMInstructionList list; + InstructionListBase list; Variable var("", ""); - auto setVar1 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 42); + auto setVar1 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value1(Compiler::StaticType::Number, 42); setVar1->targetVariable = &var; setVar1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(setVar1); - auto ifStart = std::make_shared(LLVMInstruction::Type::BeginIf, false); + auto ifStart = std::make_shared(InstructionBase::Type::BeginIf, false); list.addInstruction(ifStart); - auto setVar2 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value2(Compiler::StaticType::String, "test"); + auto setVar2 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value2(Compiler::StaticType::String, "test"); setVar2->targetVariable = &var; setVar2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(setVar2); - auto ifEnd = std::make_shared(LLVMInstruction::Type::EndIf, false); + auto ifEnd = std::make_shared(InstructionBase::Type::EndIf, false); list.addInstruction(ifEnd); - auto setVar3 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value3(Compiler::StaticType::Bool, true); + auto setVar3 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value3(Compiler::StaticType::Bool, true); setVar3->targetVariable = &var; setVar3->args.push_back({ Compiler::StaticType::Unknown, &value3 }); list.addInstruction(setVar3); @@ -694,34 +680,34 @@ TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, IfElseStatementDifferentType_IfBra ASSERT_EQ(setVar3->targetType, Compiler::StaticType::Number | Compiler::StaticType::String); } -TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, IfElseStatementDifferentType_ElseBranch) +TEST_F(CodeAnalyzer_VariableTypeAnalysis, IfElseStatementDifferentType_ElseBranch) { - LLVMInstructionList list; + InstructionListBase list; Variable var("", ""); - auto setVar1 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 42); + auto setVar1 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value1(Compiler::StaticType::Number, 42); setVar1->targetVariable = &var; setVar1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(setVar1); - auto ifStart = std::make_shared(LLVMInstruction::Type::BeginIf, false); + auto ifStart = std::make_shared(InstructionBase::Type::BeginIf, false); list.addInstruction(ifStart); - auto elseStart = std::make_shared(LLVMInstruction::Type::BeginElse, false); + auto elseStart = std::make_shared(InstructionBase::Type::BeginElse, false); list.addInstruction(elseStart); - auto setVar2 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value2(Compiler::StaticType::String, "test"); + auto setVar2 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value2(Compiler::StaticType::String, "test"); setVar2->targetVariable = &var; setVar2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(setVar2); - auto ifEnd = std::make_shared(LLVMInstruction::Type::EndIf, false); + auto ifEnd = std::make_shared(InstructionBase::Type::EndIf, false); list.addInstruction(ifEnd); - auto setVar3 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value3(Compiler::StaticType::Bool, true); + auto setVar3 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value3(Compiler::StaticType::Bool, true); setVar3->targetVariable = &var; setVar3->args.push_back({ Compiler::StaticType::Unknown, &value3 }); list.addInstruction(setVar3); @@ -735,31 +721,31 @@ TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, IfElseStatementDifferentType_ElseB ASSERT_EQ(setVar3->targetType, Compiler::StaticType::Number | Compiler::StaticType::String); } -TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, WriteBeforeLoop) +TEST_F(CodeAnalyzer_VariableTypeAnalysis, WriteBeforeLoop) { - LLVMInstructionList list; + InstructionListBase list; Variable var("", ""); - auto setVarBefore = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister valueBefore(Compiler::StaticType::String, "initial"); + auto setVarBefore = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant valueBefore(Compiler::StaticType::String, "initial"); setVarBefore->targetVariable = &var; setVarBefore->args.push_back({ Compiler::StaticType::Unknown, &valueBefore }); list.addInstruction(setVarBefore); - auto loopStart = std::make_shared(LLVMInstruction::Type::BeginRepeatLoop, false); + auto loopStart = std::make_shared(InstructionBase::Type::BeginRepeatLoop, false); list.addInstruction(loopStart); - auto setVarInLoop = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister valueInLoop(Compiler::StaticType::Number, 42); + auto setVarInLoop = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant valueInLoop(Compiler::StaticType::Number, 42); setVarInLoop->targetVariable = &var; setVarInLoop->args.push_back({ Compiler::StaticType::Unknown, &valueInLoop }); list.addInstruction(setVarInLoop); - auto loopEnd = std::make_shared(LLVMInstruction::Type::EndLoop, false); + auto loopEnd = std::make_shared(InstructionBase::Type::EndLoop, false); list.addInstruction(loopEnd); - auto setVar = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value(Compiler::StaticType::Bool, false); + auto setVar = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value(Compiler::StaticType::Bool, false); setVar->targetVariable = &var; setVar->args.push_back({ Compiler::StaticType::Unknown, &value }); list.addInstruction(setVar); @@ -770,31 +756,31 @@ TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, WriteBeforeLoop) ASSERT_EQ(setVar->targetType, Compiler::StaticType::String | Compiler::StaticType::Number); } -TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, WriteBeforeIfStatement_IfBranch) +TEST_F(CodeAnalyzer_VariableTypeAnalysis, WriteBeforeIfStatement_IfBranch) { - LLVMInstructionList list; + InstructionListBase list; Variable var("", ""); - auto setVarBefore = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister valueBefore(Compiler::StaticType::String, "initial"); + auto setVarBefore = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant valueBefore(Compiler::StaticType::String, "initial"); setVarBefore->targetVariable = &var; setVarBefore->args.push_back({ Compiler::StaticType::Unknown, &valueBefore }); list.addInstruction(setVarBefore); - auto ifStart = std::make_shared(LLVMInstruction::Type::BeginIf, false); + auto ifStart = std::make_shared(InstructionBase::Type::BeginIf, false); list.addInstruction(ifStart); - auto setVarInIfStatement = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister valueInIfStatement(Compiler::StaticType::Number, 42); + auto setVarInIfStatement = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant valueInIfStatement(Compiler::StaticType::Number, 42); setVarInIfStatement->targetVariable = &var; setVarInIfStatement->args.push_back({ Compiler::StaticType::Unknown, &valueInIfStatement }); list.addInstruction(setVarInIfStatement); - auto ifEnd = std::make_shared(LLVMInstruction::Type::EndIf, false); + auto ifEnd = std::make_shared(InstructionBase::Type::EndIf, false); list.addInstruction(ifEnd); - auto setVar = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value(Compiler::StaticType::Bool, false); + auto setVar = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value(Compiler::StaticType::Bool, false); setVar->targetVariable = &var; setVar->args.push_back({ Compiler::StaticType::Unknown, &value }); list.addInstruction(setVar); @@ -805,34 +791,34 @@ TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, WriteBeforeIfStatement_IfBranch) ASSERT_EQ(setVar->targetType, Compiler::StaticType::String | Compiler::StaticType::Number); } -TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, WriteBeforeIfStatement_ElseBranch) +TEST_F(CodeAnalyzer_VariableTypeAnalysis, WriteBeforeIfStatement_ElseBranch) { - LLVMInstructionList list; + InstructionListBase list; Variable var("", ""); - auto setVarBefore = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister valueBefore(Compiler::StaticType::String, "initial"); + auto setVarBefore = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant valueBefore(Compiler::StaticType::String, "initial"); setVarBefore->targetVariable = &var; setVarBefore->args.push_back({ Compiler::StaticType::Unknown, &valueBefore }); list.addInstruction(setVarBefore); - auto ifStart = std::make_shared(LLVMInstruction::Type::BeginIf, false); + auto ifStart = std::make_shared(InstructionBase::Type::BeginIf, false); list.addInstruction(ifStart); - auto elseStart = std::make_shared(LLVMInstruction::Type::BeginElse, false); + auto elseStart = std::make_shared(InstructionBase::Type::BeginElse, false); list.addInstruction(elseStart); - auto setVarInIfStatement = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister valueInIfStatement(Compiler::StaticType::Number, 42); + auto setVarInIfStatement = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant valueInIfStatement(Compiler::StaticType::Number, 42); setVarInIfStatement->targetVariable = &var; setVarInIfStatement->args.push_back({ Compiler::StaticType::Unknown, &valueInIfStatement }); list.addInstruction(setVarInIfStatement); - auto ifEnd = std::make_shared(LLVMInstruction::Type::EndIf, false); + auto ifEnd = std::make_shared(InstructionBase::Type::EndIf, false); list.addInstruction(ifEnd); - auto setVar = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value(Compiler::StaticType::Bool, false); + auto setVar = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value(Compiler::StaticType::Bool, false); setVar->targetVariable = &var; setVar->args.push_back({ Compiler::StaticType::Unknown, &value }); list.addInstruction(setVar); @@ -843,40 +829,40 @@ TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, WriteBeforeIfStatement_ElseBranch) ASSERT_EQ(setVar->targetType, Compiler::StaticType::String | Compiler::StaticType::Number); } -TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, WriteBeforeIfElse) +TEST_F(CodeAnalyzer_VariableTypeAnalysis, WriteBeforeIfElse) { - LLVMInstructionList list; + InstructionListBase list; Variable var("", ""); - auto setVarBefore = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister valueBefore(Compiler::StaticType::Bool, true); + auto setVarBefore = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant valueBefore(Compiler::StaticType::Bool, true); setVarBefore->targetVariable = &var; setVarBefore->args.push_back({ Compiler::StaticType::Unknown, &valueBefore }); list.addInstruction(setVarBefore); - auto ifStart = std::make_shared(LLVMInstruction::Type::BeginIf, false); + auto ifStart = std::make_shared(InstructionBase::Type::BeginIf, false); list.addInstruction(ifStart); - auto setVar1 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 42); + auto setVar1 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value1(Compiler::StaticType::Number, 42); setVar1->targetVariable = &var; setVar1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(setVar1); - auto elseStart = std::make_shared(LLVMInstruction::Type::BeginElse, false); + auto elseStart = std::make_shared(InstructionBase::Type::BeginElse, false); list.addInstruction(elseStart); - auto setVar2 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value2(Compiler::StaticType::String, "test"); + auto setVar2 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value2(Compiler::StaticType::String, "test"); setVar2->targetVariable = &var; setVar2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(setVar2); - auto ifEnd = std::make_shared(LLVMInstruction::Type::EndIf, false); + auto ifEnd = std::make_shared(InstructionBase::Type::EndIf, false); list.addInstruction(ifEnd); - auto setVar3 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value3(Compiler::StaticType::Bool, true); + auto setVar3 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value3(Compiler::StaticType::Bool, true); setVar3->targetVariable = &var; setVar3->args.push_back({ Compiler::StaticType::Unknown, &value3 }); list.addInstruction(setVar3); @@ -894,25 +880,25 @@ TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, WriteBeforeIfElse) ASSERT_EQ(setVar3->targetType, Compiler::StaticType::Number | Compiler::StaticType::String); } -TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, WriteInIfStatement_IfBranch) +TEST_F(CodeAnalyzer_VariableTypeAnalysis, WriteInIfStatement_IfBranch) { - LLVMInstructionList list; + InstructionListBase list; Variable var("", ""); - auto ifStart = std::make_shared(LLVMInstruction::Type::BeginIf, false); + auto ifStart = std::make_shared(InstructionBase::Type::BeginIf, false); list.addInstruction(ifStart); - auto setVarInIfStatement = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister valueInIfStatement(Compiler::StaticType::Number, 42); + auto setVarInIfStatement = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant valueInIfStatement(Compiler::StaticType::Number, 42); setVarInIfStatement->targetVariable = &var; setVarInIfStatement->args.push_back({ Compiler::StaticType::Unknown, &valueInIfStatement }); list.addInstruction(setVarInIfStatement); - auto ifEnd = std::make_shared(LLVMInstruction::Type::EndIf, false); + auto ifEnd = std::make_shared(InstructionBase::Type::EndIf, false); list.addInstruction(ifEnd); - auto setVar = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value(Compiler::StaticType::Bool, false); + auto setVar = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value(Compiler::StaticType::Bool, false); setVar->targetVariable = &var; setVar->args.push_back({ Compiler::StaticType::Unknown, &value }); list.addInstruction(setVar); @@ -925,28 +911,28 @@ TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, WriteInIfStatement_IfBranch) ASSERT_EQ(setVar->targetType, Compiler::StaticType::Unknown); } -TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, WriteInIfStatement_ElseBranch) +TEST_F(CodeAnalyzer_VariableTypeAnalysis, WriteInIfStatement_ElseBranch) { - LLVMInstructionList list; + InstructionListBase list; Variable var("", ""); - auto ifStart = std::make_shared(LLVMInstruction::Type::BeginIf, false); + auto ifStart = std::make_shared(InstructionBase::Type::BeginIf, false); list.addInstruction(ifStart); - auto elseStart = std::make_shared(LLVMInstruction::Type::BeginElse, false); + auto elseStart = std::make_shared(InstructionBase::Type::BeginElse, false); list.addInstruction(elseStart); - auto setVarInIfStatement = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister valueInIfStatement(Compiler::StaticType::Number, 42); + auto setVarInIfStatement = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant valueInIfStatement(Compiler::StaticType::Number, 42); setVarInIfStatement->targetVariable = &var; setVarInIfStatement->args.push_back({ Compiler::StaticType::Unknown, &valueInIfStatement }); list.addInstruction(setVarInIfStatement); - auto ifEnd = std::make_shared(LLVMInstruction::Type::EndIf, false); + auto ifEnd = std::make_shared(InstructionBase::Type::EndIf, false); list.addInstruction(ifEnd); - auto setVar = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value(Compiler::StaticType::Bool, false); + auto setVar = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value(Compiler::StaticType::Bool, false); setVar->targetVariable = &var; setVar->args.push_back({ Compiler::StaticType::Unknown, &value }); list.addInstruction(setVar); @@ -959,34 +945,34 @@ TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, WriteInIfStatement_ElseBranch) ASSERT_EQ(setVar->targetType, Compiler::StaticType::Unknown); } -TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, WriteInIfElse) +TEST_F(CodeAnalyzer_VariableTypeAnalysis, WriteInIfElse) { - LLVMInstructionList list; + InstructionListBase list; Variable var("", ""); - auto ifStart = std::make_shared(LLVMInstruction::Type::BeginIf, false); + auto ifStart = std::make_shared(InstructionBase::Type::BeginIf, false); list.addInstruction(ifStart); - auto setVar1 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 42); + auto setVar1 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value1(Compiler::StaticType::Number, 42); setVar1->targetVariable = &var; setVar1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(setVar1); - auto elseStart = std::make_shared(LLVMInstruction::Type::BeginElse, false); + auto elseStart = std::make_shared(InstructionBase::Type::BeginElse, false); list.addInstruction(elseStart); - auto setVar2 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value2(Compiler::StaticType::String, "test"); + auto setVar2 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value2(Compiler::StaticType::String, "test"); setVar2->targetVariable = &var; setVar2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(setVar2); - auto ifEnd = std::make_shared(LLVMInstruction::Type::EndIf, false); + auto ifEnd = std::make_shared(InstructionBase::Type::EndIf, false); list.addInstruction(ifEnd); - auto setVar3 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value3(Compiler::StaticType::Bool, true); + auto setVar3 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value3(Compiler::StaticType::Bool, true); setVar3->targetVariable = &var; setVar3->args.push_back({ Compiler::StaticType::Unknown, &value3 }); list.addInstruction(setVar3); @@ -1000,25 +986,25 @@ TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, WriteInIfElse) ASSERT_EQ(setVar3->targetType, Compiler::StaticType::Number | Compiler::StaticType::String); } -TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, WriteInLoop) +TEST_F(CodeAnalyzer_VariableTypeAnalysis, WriteInLoop) { - LLVMInstructionList list; + InstructionListBase list; Variable var("", ""); - auto loopStart = std::make_shared(LLVMInstruction::Type::BeginRepeatLoop, false); + auto loopStart = std::make_shared(InstructionBase::Type::BeginRepeatLoop, false); list.addInstruction(loopStart); - auto setVarInLoop = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister valueInLoop(Compiler::StaticType::Number, 42); + auto setVarInLoop = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant valueInLoop(Compiler::StaticType::Number, 42); setVarInLoop->targetVariable = &var; setVarInLoop->args.push_back({ Compiler::StaticType::Unknown, &valueInLoop }); list.addInstruction(setVarInLoop); - auto loopEnd = std::make_shared(LLVMInstruction::Type::EndLoop, false); + auto loopEnd = std::make_shared(InstructionBase::Type::EndLoop, false); list.addInstruction(loopEnd); - auto setVar = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value(Compiler::StaticType::Bool, false); + auto setVar = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value(Compiler::StaticType::Bool, false); setVar->targetVariable = &var; setVar->args.push_back({ Compiler::StaticType::Unknown, &value }); list.addInstruction(setVar); @@ -1031,39 +1017,39 @@ TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, WriteInLoop) ASSERT_EQ(setVar->targetType, Compiler::StaticType::Unknown); } -TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, NestedIfStatements) +TEST_F(CodeAnalyzer_VariableTypeAnalysis, NestedIfStatements) { - LLVMInstructionList list; + InstructionListBase list; Variable var("", ""); - auto outerIf = std::make_shared(LLVMInstruction::Type::BeginIf, false); + auto outerIf = std::make_shared(InstructionBase::Type::BeginIf, false); list.addInstruction(outerIf); - auto setVar1 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 1); + auto setVar1 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value1(Compiler::StaticType::Number, 1); setVar1->targetVariable = &var; setVar1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(setVar1); - auto outerElse = std::make_shared(LLVMInstruction::Type::BeginElse, false); + auto outerElse = std::make_shared(InstructionBase::Type::BeginElse, false); list.addInstruction(outerElse); - auto innerIf = std::make_shared(LLVMInstruction::Type::BeginIf, false); + auto innerIf = std::make_shared(InstructionBase::Type::BeginIf, false); list.addInstruction(innerIf); - auto innerElse = std::make_shared(LLVMInstruction::Type::BeginElse, false); + auto innerElse = std::make_shared(InstructionBase::Type::BeginElse, false); list.addInstruction(innerElse); - auto innerIfEnd = std::make_shared(LLVMInstruction::Type::EndIf, false); + auto innerIfEnd = std::make_shared(InstructionBase::Type::EndIf, false); list.addInstruction(innerIfEnd); - auto setVar2 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value2(Compiler::StaticType::String, "test"); + auto setVar2 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value2(Compiler::StaticType::String, "test"); setVar2->targetVariable = &var; setVar2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(setVar2); - auto outerIfEnd = std::make_shared(LLVMInstruction::Type::EndIf, false); + auto outerIfEnd = std::make_shared(InstructionBase::Type::EndIf, false); list.addInstruction(outerIfEnd); m_analyzer->analyzeScript(list); @@ -1072,52 +1058,52 @@ TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, NestedIfStatements) ASSERT_EQ(setVar2->targetType, Compiler::StaticType::Unknown); } -TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, ComplexNestedControlFlow) +TEST_F(CodeAnalyzer_VariableTypeAnalysis, ComplexNestedControlFlow) { - LLVMInstructionList list; + InstructionListBase list; Variable var("", ""); - auto outerLoop = std::make_shared(LLVMInstruction::Type::BeginRepeatLoop, false); + auto outerLoop = std::make_shared(InstructionBase::Type::BeginRepeatLoop, false); list.addInstruction(outerLoop); - auto setVar1 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 1); + auto setVar1 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value1(Compiler::StaticType::Number, 1); setVar1->targetVariable = &var; setVar1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(setVar1); - auto ifStart = std::make_shared(LLVMInstruction::Type::BeginIf, false); + auto ifStart = std::make_shared(InstructionBase::Type::BeginIf, false); list.addInstruction(ifStart); - auto innerLoop = std::make_shared(LLVMInstruction::Type::BeginRepeatLoop, false); + auto innerLoop = std::make_shared(InstructionBase::Type::BeginRepeatLoop, false); list.addInstruction(innerLoop); - auto setVar2 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value2(Compiler::StaticType::String, "nested"); + auto setVar2 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value2(Compiler::StaticType::String, "nested"); setVar2->targetVariable = &var; setVar2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(setVar2); - auto innerLoopEnd = std::make_shared(LLVMInstruction::Type::EndLoop, false); + auto innerLoopEnd = std::make_shared(InstructionBase::Type::EndLoop, false); list.addInstruction(innerLoopEnd); - auto elseStart = std::make_shared(LLVMInstruction::Type::BeginElse, false); + auto elseStart = std::make_shared(InstructionBase::Type::BeginElse, false); list.addInstruction(elseStart); - auto setVar3 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value3(Compiler::StaticType::Bool, true); + auto setVar3 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value3(Compiler::StaticType::Bool, true); setVar3->targetVariable = &var; setVar3->args.push_back({ Compiler::StaticType::Unknown, &value3 }); list.addInstruction(setVar3); - auto ifEnd = std::make_shared(LLVMInstruction::Type::EndIf, false); + auto ifEnd = std::make_shared(InstructionBase::Type::EndIf, false); list.addInstruction(ifEnd); - auto outerLoopEnd = std::make_shared(LLVMInstruction::Type::EndLoop, false); + auto outerLoopEnd = std::make_shared(InstructionBase::Type::EndLoop, false); list.addInstruction(outerLoopEnd); - auto setVar4 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value4(Compiler::StaticType::Bool, true); + auto setVar4 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value4(Compiler::StaticType::Bool, true); setVar4->targetVariable = &var; setVar4->args.push_back({ Compiler::StaticType::Unknown, &value4 }); list.addInstruction(setVar4); @@ -1131,19 +1117,19 @@ TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, ComplexNestedControlFlow) ASSERT_EQ(setVar4->targetType, Compiler::StaticType::Unknown); } -TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, MultipleVariablesSeparateAnalysis) +TEST_F(CodeAnalyzer_VariableTypeAnalysis, MultipleVariablesSeparateAnalysis) { - LLVMInstructionList list; + InstructionListBase list; Variable var1("", ""), var2("", ""); - auto setVar1 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 42); + auto setVar1 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value1(Compiler::StaticType::Number, 42); setVar1->targetVariable = &var1; setVar1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(setVar1); - auto setVar2 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value2(Compiler::StaticType::String, "test"); + auto setVar2 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value2(Compiler::StaticType::String, "test"); setVar2->targetVariable = &var2; setVar2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(setVar2); @@ -1155,33 +1141,31 @@ TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, MultipleVariablesSeparateAnalysis) ASSERT_EQ(setVar2->targetType, Compiler::StaticType::Unknown); } -TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, CrossVariableDependency_SingleType) +TEST_F(CodeAnalyzer_VariableTypeAnalysis, CrossVariableDependency_SingleType) { - LLVMInstructionList list; + InstructionListBase list; Variable var1("", ""), var2("", ""); - auto setVar2 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 3.14); + auto setVar2 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value1(Compiler::StaticType::Number, 3.14); setVar2->targetVariable = &var2; setVar2->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(setVar2); - auto readVar2 = std::make_shared(LLVMInstruction::Type::ReadVariable, false); + auto readVar2 = std::make_shared(InstructionBase::Type::ReadVariable, false); readVar2->targetVariable = &var2; list.addInstruction(readVar2); - LLVMRegister var2Value(Compiler::StaticType::Unknown); - var2Value.isRawValue = false; - var2Value.instruction = readVar2; + CompilerValue var2Value(Compiler::StaticType::Unknown); readVar2->functionReturnReg = &var2Value; - auto setVar1_1 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); + auto setVar1_1 = std::make_shared(InstructionBase::Type::WriteVariable, false); setVar1_1->targetVariable = &var1; setVar1_1->args.push_back({ Compiler::StaticType::Unknown, &var2Value }); list.addInstruction(setVar1_1); - auto setVar1_2 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value2(Compiler::StaticType::String, "test"); + auto setVar1_2 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value2(Compiler::StaticType::String, "test"); setVar1_2->targetVariable = &var1; setVar1_2->args.push_back({ Compiler::StaticType::Unknown, &var2Value }); list.addInstruction(setVar1_2); @@ -1201,49 +1185,47 @@ TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, CrossVariableDependency_SingleType ASSERT_EQ(setVar1_2->targetType, Compiler::StaticType::Number); } -TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, CrossVariableDependency_MultipleTypes) +TEST_F(CodeAnalyzer_VariableTypeAnalysis, CrossVariableDependency_MultipleTypes) { - LLVMInstructionList list; + InstructionListBase list; Variable var1("", ""), var2("", ""); // Establish Number | Bool types - auto ifStart = std::make_shared(LLVMInstruction::Type::BeginIf, false); + auto ifStart = std::make_shared(InstructionBase::Type::BeginIf, false); list.addInstruction(ifStart); - auto setVar1 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 42); + auto setVar1 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value1(Compiler::StaticType::Number, 42); setVar1->targetVariable = &var2; setVar1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(setVar1); - auto elseStart = std::make_shared(LLVMInstruction::Type::BeginElse, false); + auto elseStart = std::make_shared(InstructionBase::Type::BeginElse, false); list.addInstruction(elseStart); - auto setVar2 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value2(Compiler::StaticType::Bool, true); + auto setVar2 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value2(Compiler::StaticType::Bool, true); setVar2->targetVariable = &var2; setVar2->args.push_back({ Compiler::StaticType::Unknown, &value2 }); list.addInstruction(setVar2); - auto ifEnd = std::make_shared(LLVMInstruction::Type::EndIf, false); + auto ifEnd = std::make_shared(InstructionBase::Type::EndIf, false); list.addInstruction(ifEnd); - auto readVar2 = std::make_shared(LLVMInstruction::Type::ReadVariable, false); + auto readVar2 = std::make_shared(InstructionBase::Type::ReadVariable, false); readVar2->targetVariable = &var2; list.addInstruction(readVar2); - LLVMRegister var2Value(Compiler::StaticType::Unknown); - var2Value.isRawValue = false; - var2Value.instruction = readVar2; + CompilerValue var2Value(Compiler::StaticType::Unknown); readVar2->functionReturnReg = &var2Value; - auto setVar3 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); + auto setVar3 = std::make_shared(InstructionBase::Type::WriteVariable, false); setVar3->targetVariable = &var1; setVar3->args.push_back({ Compiler::StaticType::Unknown, &var2Value }); list.addInstruction(setVar3); - auto setVar4 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value4(Compiler::StaticType::String, "test"); + auto setVar4 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value4(Compiler::StaticType::String, "test"); setVar4->targetVariable = &var1; setVar4->args.push_back({ Compiler::StaticType::Unknown, &var2Value }); list.addInstruction(setVar4); @@ -1260,88 +1242,82 @@ TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, CrossVariableDependency_MultipleTy ASSERT_EQ(setVar4->targetType, Compiler::StaticType::Number | Compiler::StaticType::Bool); } -TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, ChainedAssignmentsInLoop) +TEST_F(CodeAnalyzer_VariableTypeAnalysis, ChainedAssignmentsInLoop) { - LLVMInstructionList list; + InstructionListBase list; Variable varA("a", ""), varB("b", ""), varC("c", ""); // a = 5 - auto setA1 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister valueA1(Compiler::StaticType::Number, 5); + auto setA1 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant valueA1(Compiler::StaticType::Number, 5); setA1->targetVariable = &varA; setA1->args.push_back({ Compiler::StaticType::Unknown, &valueA1 }); list.addInstruction(setA1); // b = 3 - auto setB1 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister valueB1(Compiler::StaticType::Number, 3); + auto setB1 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant valueB1(Compiler::StaticType::Number, 3); setB1->targetVariable = &varB; setB1->args.push_back({ Compiler::StaticType::Unknown, &valueB1 }); list.addInstruction(setB1); // c = 8 - auto setC1 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister valueC1(Compiler::StaticType::Number, 8); + auto setC1 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant valueC1(Compiler::StaticType::Number, 8); setC1->targetVariable = &varC; setC1->args.push_back({ Compiler::StaticType::Unknown, &valueC1 }); list.addInstruction(setC1); // loop start - auto loopStart = std::make_shared(LLVMInstruction::Type::BeginRepeatLoop, false); + auto loopStart = std::make_shared(InstructionBase::Type::BeginRepeatLoop, false); list.addInstruction(loopStart); // a = b - auto readB = std::make_shared(LLVMInstruction::Type::ReadVariable, false); + auto readB = std::make_shared(InstructionBase::Type::ReadVariable, false); readB->targetVariable = &varB; list.addInstruction(readB); - LLVMRegister bValue(Compiler::StaticType::Unknown); - bValue.isRawValue = false; - bValue.instruction = readB; + CompilerValue bValue(Compiler::StaticType::Unknown); readB->functionReturnReg = &bValue; - auto setA2 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); + auto setA2 = std::make_shared(InstructionBase::Type::WriteVariable, false); setA2->targetVariable = &varA; setA2->args.push_back({ Compiler::StaticType::Unknown, &bValue }); list.addInstruction(setA2); // b = c - auto readC1 = std::make_shared(LLVMInstruction::Type::ReadVariable, false); + auto readC1 = std::make_shared(InstructionBase::Type::ReadVariable, false); readC1->targetVariable = &varC; list.addInstruction(readC1); - LLVMRegister cValue1(Compiler::StaticType::Unknown); - cValue1.isRawValue = false; - cValue1.instruction = readC1; + CompilerValue cValue1(Compiler::StaticType::Unknown); readC1->functionReturnReg = &cValue1; - auto setB2 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); + auto setB2 = std::make_shared(InstructionBase::Type::WriteVariable, false); setB2->targetVariable = &varB; setB2->args.push_back({ Compiler::StaticType::Unknown, &cValue1 }); list.addInstruction(setB2); // c = "test" - auto setC2 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister valueC2(Compiler::StaticType::String, "test"); + auto setC2 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant valueC2(Compiler::StaticType::String, "test"); setC2->targetVariable = &varC; setC2->args.push_back({ Compiler::StaticType::Unknown, &valueC2 }); list.addInstruction(setC2); // loop end - auto loopEnd = std::make_shared(LLVMInstruction::Type::EndLoop, false); + auto loopEnd = std::make_shared(InstructionBase::Type::EndLoop, false); list.addInstruction(loopEnd); // a = c (final assignment we want to test) - auto readC2 = std::make_shared(LLVMInstruction::Type::ReadVariable, false); + auto readC2 = std::make_shared(InstructionBase::Type::ReadVariable, false); readC2->targetVariable = &varC; list.addInstruction(readC2); - LLVMRegister cValue2(Compiler::StaticType::Unknown); - cValue2.isRawValue = false; - cValue2.instruction = readC2; + CompilerValue cValue2(Compiler::StaticType::Unknown); readC2->functionReturnReg = &cValue2; - auto setA3 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); + auto setA3 = std::make_shared(InstructionBase::Type::WriteVariable, false); setA3->targetVariable = &varA; setA3->args.push_back({ Compiler::StaticType::Unknown, &cValue2 }); list.addInstruction(setA3); @@ -1361,36 +1337,34 @@ TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, ChainedAssignmentsInLoop) ASSERT_EQ(readC2->targetType, expectedCType); } -TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, SelfAssignment) +TEST_F(CodeAnalyzer_VariableTypeAnalysis, SelfAssignment) { - LLVMInstructionList list; + InstructionListBase list; Variable var("", ""); // First establish a type for the variable - auto setVar1 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 42); + auto setVar1 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value1(Compiler::StaticType::Number, 42); setVar1->targetVariable = &var; setVar1->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(setVar1); // Self-assignment: var = var - auto readVar = std::make_shared(LLVMInstruction::Type::ReadVariable, false); + auto readVar = std::make_shared(InstructionBase::Type::ReadVariable, false); readVar->targetVariable = &var; list.addInstruction(readVar); - LLVMRegister varValue(Compiler::StaticType::Unknown); - varValue.isRawValue = false; - varValue.instruction = readVar; + CompilerValue varValue(Compiler::StaticType::Unknown); readVar->functionReturnReg = &varValue; - auto setVar2 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); + auto setVar2 = std::make_shared(InstructionBase::Type::WriteVariable, false); setVar2->targetVariable = &var; setVar2->args.push_back({ Compiler::StaticType::Unknown, &varValue }); list.addInstruction(setVar2); // Should still be Number - auto setVar3 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value3(Compiler::StaticType::String, "test"); + auto setVar3 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value3(Compiler::StaticType::String, "test"); setVar3->targetVariable = &var; setVar3->args.push_back({ Compiler::StaticType::Unknown, &value3 }); list.addInstruction(setVar3); @@ -1407,30 +1381,28 @@ TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, SelfAssignment) ASSERT_EQ(setVar3->targetType, Compiler::StaticType::Number); } -TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, SelfAssignmentInLoop) +TEST_F(CodeAnalyzer_VariableTypeAnalysis, SelfAssignmentInLoop) { - LLVMInstructionList list; + InstructionListBase list; Variable var("", ""); - auto loopStart = std::make_shared(LLVMInstruction::Type::BeginRepeatLoop, false); + auto loopStart = std::make_shared(InstructionBase::Type::BeginRepeatLoop, false); list.addInstruction(loopStart); // Self-assignment inside loop: var = var - auto readVar = std::make_shared(LLVMInstruction::Type::ReadVariable, false); + auto readVar = std::make_shared(InstructionBase::Type::ReadVariable, false); readVar->targetVariable = &var; list.addInstruction(readVar); - LLVMRegister varValue(Compiler::StaticType::Unknown); - varValue.isRawValue = false; - varValue.instruction = readVar; + CompilerValue varValue(Compiler::StaticType::Unknown); readVar->functionReturnReg = &varValue; - auto setVar = std::make_shared(LLVMInstruction::Type::WriteVariable, false); + auto setVar = std::make_shared(InstructionBase::Type::WriteVariable, false); setVar->targetVariable = &var; setVar->args.push_back({ Compiler::StaticType::Unknown, &varValue }); list.addInstruction(setVar); - auto loopEnd = std::make_shared(LLVMInstruction::Type::EndLoop, false); + auto loopEnd = std::make_shared(InstructionBase::Type::EndLoop, false); list.addInstruction(loopEnd); m_analyzer->analyzeScript(list); @@ -1440,27 +1412,25 @@ TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, SelfAssignmentInLoop) ASSERT_EQ(setVar->targetType, Compiler::StaticType::Unknown); } -TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, VariableReadReturnRegType) +TEST_F(CodeAnalyzer_VariableTypeAnalysis, VariableReadReturnRegType) { - LLVMInstructionList list; + InstructionListBase list; Variable var1("", ""), var2("", ""); - auto setVar2 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 3.14); + auto setVar2 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value1(Compiler::StaticType::Number, 3.14); setVar2->targetVariable = &var2; setVar2->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(setVar2); - auto readVar2 = std::make_shared(LLVMInstruction::Type::ReadVariable, false); + auto readVar2 = std::make_shared(InstructionBase::Type::ReadVariable, false); readVar2->targetVariable = &var2; list.addInstruction(readVar2); - LLVMRegister var2Value(Compiler::StaticType::Unknown); - var2Value.isRawValue = false; - var2Value.instruction = readVar2; + CompilerValue var2Value(Compiler::StaticType::Unknown); readVar2->functionReturnReg = &var2Value; - auto setVar1_1 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); + auto setVar1_1 = std::make_shared(InstructionBase::Type::WriteVariable, false); setVar1_1->targetVariable = &var1; setVar1_1->args.push_back({ Compiler::StaticType::Unknown, &var2Value }); list.addInstruction(setVar1_1); @@ -1471,27 +1441,25 @@ TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, VariableReadReturnRegType) ASSERT_EQ(var2Value.type(), Compiler::StaticType::Number); } -TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, CrossVariableWriteArgType) +TEST_F(CodeAnalyzer_VariableTypeAnalysis, CrossVariableWriteArgType) { - LLVMInstructionList list; + InstructionListBase list; Variable var1("", ""), var2("", ""); - auto setVar2 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); - LLVMConstantRegister value1(Compiler::StaticType::Number, 3.14); + auto setVar2 = std::make_shared(InstructionBase::Type::WriteVariable, false); + CompilerConstant value1(Compiler::StaticType::Number, 3.14); setVar2->targetVariable = &var2; setVar2->args.push_back({ Compiler::StaticType::Unknown, &value1 }); list.addInstruction(setVar2); - auto readVar2 = std::make_shared(LLVMInstruction::Type::ReadVariable, false); + auto readVar2 = std::make_shared(InstructionBase::Type::ReadVariable, false); readVar2->targetVariable = &var2; list.addInstruction(readVar2); - LLVMRegister var2Value(Compiler::StaticType::Unknown); - var2Value.isRawValue = false; - var2Value.instruction = readVar2; + CompilerValue var2Value(Compiler::StaticType::Unknown); readVar2->functionReturnReg = &var2Value; - auto setVar1_1 = std::make_shared(LLVMInstruction::Type::WriteVariable, false); + auto setVar1_1 = std::make_shared(InstructionBase::Type::WriteVariable, false); setVar1_1->targetVariable = &var1; setVar1_1->args.push_back({ Compiler::StaticType::Unknown, &var2Value }); list.addInstruction(setVar1_1); From 44f1371cb6ac98e092a91218bdb27d111229e124 Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Sun, 25 Oct 2026 00:24:46 +0200 Subject: [PATCH 12/13] Remove outer loop from unsafe constant check --- src/engine/internal/engine.cpp | 35 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/src/engine/internal/engine.cpp b/src/engine/internal/engine.cpp index 547d9104c..9ec5a0ddb 100644 --- a/src/engine/internal/engine.cpp +++ b/src/engine/internal/engine.cpp @@ -249,32 +249,25 @@ void Engine::compile() // Find unsafe constants (string numerals) in costume and sound names m_unsafeConstants.clear(); - for (auto target : m_targets) { - IEngine *engine = target->engine(); - - if (engine) { - auto checkConstant = [this](const std::string &str) { - Value stringValue(str); - Value numberValue(stringValue.toDouble()); + auto checkConstant = [this](const std::string &str) { + Value stringValue(str); + Value numberValue(stringValue.toDouble()); - if (stringValue.isValidNumber() && str == numberValue.toString()) - m_unsafeConstants.insert(str); - }; + if (stringValue.isValidNumber() && str == numberValue.toString()) + m_unsafeConstants.insert(str); + }; - const auto &targets = engine->targets(); - bool found = false; + bool found = false; - for (const auto &target : targets) { - const auto &costumes = target->costumes(); - const auto &sounds = target->sounds(); + for (const auto &target : m_targets) { + const auto &costumes = target->costumes(); + const auto &sounds = target->sounds(); - for (const auto &costume : costumes) - checkConstant(costume->name()); + for (const auto &costume : costumes) + checkConstant(costume->name()); - for (const auto &sound : sounds) - checkConstant(sound->name()); - } - } + for (const auto &sound : sounds) + checkConstant(sound->name()); } // Compile scripts From c14fecaea50a9af6ce734a45a8042fa1b3716e67 Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Sun, 25 Oct 2026 00:34:37 +0200 Subject: [PATCH 13/13] Add unsafeConstants parameter to Compiler constructor --- include/scratchcpp/compiler.h | 2 +- src/engine/compiler.cpp | 4 ++-- src/engine/compiler_p.cpp | 4 ++-- src/engine/compiler_p.h | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/scratchcpp/compiler.h b/include/scratchcpp/compiler.h index 633de3670..626635528 100644 --- a/include/scratchcpp/compiler.h +++ b/include/scratchcpp/compiler.h @@ -53,7 +53,7 @@ class LIBSCRATCHCPP_EXPORT Compiler using Args = std::vector; Compiler(CompilerContext *ctx); - Compiler(IEngine *engine, Target *target); + Compiler(IEngine *engine, Target *target, const std::unordered_set &unsafeConstants = {}); Compiler(const Compiler &) = delete; IEngine *engine() const; diff --git a/src/engine/compiler.cpp b/src/engine/compiler.cpp index d0aeb1a07..799c0ae14 100644 --- a/src/engine/compiler.cpp +++ b/src/engine/compiler.cpp @@ -20,8 +20,8 @@ Compiler::Compiler(CompilerContext *ctx) : } /*! Constructs Compiler using a new context for the given target. */ -Compiler::Compiler(IEngine *engine, Target *target) : - impl(spimpl::make_unique_impl(engine, target)) +Compiler::Compiler(IEngine *engine, Target *target, const std::unordered_set &unsafeConstants) : + impl(spimpl::make_unique_impl(engine, target, unsafeConstants)) { } diff --git a/src/engine/compiler_p.cpp b/src/engine/compiler_p.cpp index 983ce4c34..a6b4c8b51 100644 --- a/src/engine/compiler_p.cpp +++ b/src/engine/compiler_p.cpp @@ -17,8 +17,8 @@ CompilerPrivate::CompilerPrivate(CompilerContext *ctx) : initBuilderFactory(); } -CompilerPrivate::CompilerPrivate(IEngine *engine, Target *target) : - ctxPtr(Compiler::createContext(engine, target, {})), // NOTE: This constructor is only used in tests, so we can leave unsafe constants empty +CompilerPrivate::CompilerPrivate(IEngine *engine, Target *target, const std::unordered_set &unsafeConstants) : + ctxPtr(Compiler::createContext(engine, target, unsafeConstants)), ctx(ctxPtr.get()) { initBuilderFactory(); diff --git a/src/engine/compiler_p.h b/src/engine/compiler_p.h index c0d076606..a366d82ca 100644 --- a/src/engine/compiler_p.h +++ b/src/engine/compiler_p.h @@ -29,7 +29,7 @@ class LIBSCRATCHCPP_TEST_EXPORT CompilerPrivate }; CompilerPrivate(CompilerContext *ctx); - CompilerPrivate(IEngine *engine, Target *target); + CompilerPrivate(IEngine *engine, Target *target, const std::unordered_set &unsafeConstants); static void initBuilderFactory();