From 39bccce4fdd1d5ebe312321c963e0325e4d696c5 Mon Sep 17 00:00:00 2001 From: Roland Reichwein Date: Sat, 21 Nov 2020 21:38:56 +0100 Subject: Bugfixing of stack (WIP) --- asm/intel64/add.cpp | 18 ++++++++++++------ asm/intel64/and.cpp | 12 ++++++++---- asm/intel64/bsf.cpp | 6 ++++-- asm/intel64/bsr.cpp | 6 ++++-- asm/intel64/codes.cpp | 2 +- asm/intel64/div.cpp | 9 ++++++--- asm/intel64/encode.cpp | 10 +++++----- asm/intel64/mov.cpp | 12 ++++++++---- asm/intel64/mul.cpp | 9 ++++++--- asm/intel64/or.cpp | 12 ++++++++---- 10 files changed, 62 insertions(+), 34 deletions(-) (limited to 'asm/intel64') diff --git a/asm/intel64/add.cpp b/asm/intel64/add.cpp index 07b14a1..12d1b94 100644 --- a/asm/intel64/add.cpp +++ b/asm/intel64/add.cpp @@ -38,23 +38,29 @@ Op_add::Op_add(const Asm::Args& args) machine_code = REX("W") + std::vector{ 0x01 } + ModRM(std::any_cast(args[1]).name(), std::any_cast(args[0]).name()); } else if (args[0].type() == typeid(Asm::Args::Register32) && args[1].type() == typeid(Asm::Args::Mem32Ptr64)) { // add reg32, [reg64] - machine_code = std::vector{ 0x03 } + ModRM(std::any_cast(args[0]).name(), std::any_cast(args[1]).reg()); + Asm::Args::Mem32Ptr64 ptr{std::any_cast(args[1])}; + machine_code = std::vector{ 0x03 } + ModRM(std::any_cast(args[0]).name(), ptr.reg(), ptr.offs()); } else if (args[0].type() == typeid(Asm::Args::Register64) && args[1].type() == typeid(Asm::Args::Mem64Ptr64)) { // add reg64, [reg64] - machine_code = REX("W") + std::vector{ 0x03 } + ModRM(std::any_cast(args[0]).name(), std::any_cast(args[1]).reg()); + Asm::Args::Mem64Ptr64 ptr{std::any_cast(args[1])}; + machine_code = REX("W") + std::vector{ 0x03 } + ModRM(std::any_cast(args[0]).name(), ptr.reg(), ptr.offs()); } else if (args[0].type() == typeid(Asm::Args::Mem8Ptr64) && args[1].type() == typeid(Asm::Args::Immediate8)) { // add [reg64], imm8 - machine_code = std::vector{ 0x80 } + ModRM("/0", std::any_cast(args[0]).reg()) + std::any_cast(args[1]).getCode(); + Asm::Args::Mem8Ptr64 ptr{std::any_cast(args[0])}; + machine_code = std::vector{ 0x80 } + ModRM("/0", ptr.reg(), ptr.offs()) + std::any_cast(args[1]).getCode(); } else if (args[0].type() == typeid(Asm::Args::Mem32Ptr64) && args[1].type() == typeid(Asm::Args::Immediate32)) { // add [reg64], imm32 - machine_code = std::vector{ 0x81 } + ModRM("/0", std::any_cast(args[0]).reg()) + std::any_cast(args[1]).getCode(); + Asm::Args::Mem32Ptr64 ptr{std::any_cast(args[0])}; + machine_code = std::vector{ 0x81 } + ModRM("/0", ptr.reg(), ptr.offs()) + std::any_cast(args[1]).getCode(); } else if (args[0].type() == typeid(Asm::Args::Mem64Ptr64) && args[1].type() == typeid(Asm::Args::Immediate32)) { // add qword ptr [reg64], imm32 (sign-extended) - machine_code = REX("W") + std::vector{ 0x81 } + ModRM("/0", std::any_cast(args[0]).reg()) + std::any_cast(args[1]).getCode(); + Asm::Args::Mem64Ptr64 ptr{std::any_cast(args[0])}; + machine_code = REX("W") + std::vector{ 0x81 } + ModRM("/0", ptr.reg(), ptr.offs()) + std::any_cast(args[1]).getCode(); } else if (args[0].type() == typeid(Asm::Args::Mem64Ptr64) && args[1].type() == typeid(Asm::Args::Immediate64)) { // add qword ptr [reg64], imm32 (sign-extended) - reduce imm64 to imm32! + Asm::Args::Mem64Ptr64 ptr{std::any_cast(args[0])}; Asm::Args::Immediate32 imm32{std::any_cast(args[1])}; - machine_code = REX("W") + std::vector{ 0x81 } + ModRM("/0", std::any_cast(args[0]).reg()) + imm32.getCode(); + machine_code = REX("W") + std::vector{ 0x81 } + ModRM("/0", ptr.reg(), ptr.offs()) + imm32.getCode(); } else { throw std::runtime_error("Unimplemented: add "s + args[0].type().name() + " "s + args[1].type().name()); diff --git a/asm/intel64/and.cpp b/asm/intel64/and.cpp index a2e110b..b87d408 100644 --- a/asm/intel64/and.cpp +++ b/asm/intel64/and.cpp @@ -30,16 +30,20 @@ Op_and::Op_and(const Asm::Args& args) machine_code = std::vector{ 0x81 } + ModRM("/4", std::any_cast(args[0]).name()) + std::any_cast(args[1]).getCode(); } else if (args[0].type() == typeid(Asm::Args::Register32) && args[1].type() == typeid(Asm::Args::Mem32Ptr64)) { // and reg32, [reg64] - machine_code = std::vector{ 0x23 } + ModRM(std::any_cast(args[0]).name(), std::any_cast(args[1]).reg()); + Asm::Args::Mem32Ptr64 ptr{std::any_cast(args[1])}; + machine_code = std::vector{ 0x23 } + ModRM(std::any_cast(args[0]).name(), ptr.reg(), ptr.offs()); } else if (args[0].type() == typeid(Asm::Args::Register64) && args[1].type() == typeid(Asm::Args::Mem64Ptr64)) { // and reg64, [reg64] - machine_code = REX("W") + std::vector{ 0x23 } + ModRM(std::any_cast(args[0]).name(), std::any_cast(args[1]).reg()); + Asm::Args::Mem64Ptr64 ptr{std::any_cast(args[1])}; + machine_code = REX("W") + std::vector{ 0x23 } + ModRM(std::any_cast(args[0]).name(), ptr.reg(), ptr.offs()); } else if (args[0].type() == typeid(Asm::Args::Mem32Ptr64) && args[1].type() == typeid(Asm::Args::Register32)) { // and [reg64], reg32 - machine_code = std::vector{ 0x21 } + ModRM(std::any_cast(args[1]).name(), std::any_cast(args[0]).reg()); + Asm::Args::Mem32Ptr64 ptr{std::any_cast(args[0])}; + machine_code = std::vector{ 0x21 } + ModRM(std::any_cast(args[1]).name(), ptr.reg(), ptr.offs()); } else if (args[0].type() == typeid(Asm::Args::Mem64Ptr64) && args[1].type() == typeid(Asm::Args::Register64)) { // and [reg64], reg64 - machine_code = REX("W") + std::vector{ 0x21 } + ModRM(std::any_cast(args[1]).name(), std::any_cast(args[0]).reg()); + Asm::Args::Mem64Ptr64 ptr{std::any_cast(args[0])}; + machine_code = REX("W") + std::vector{ 0x21 } + ModRM(std::any_cast(args[1]).name(), ptr.reg(), ptr.offs()); } else if (args[0].type() == typeid(Asm::Args::Register64) && args[1].type() == typeid(Asm::Args::Immediate32)) { // and reg64, imm32 (sign-extended) machine_code = REX("W") + std::vector{ 0x81 } + ModRM("/4", std::any_cast(args[0]).name()) + std::any_cast(args[1]).getCode(); diff --git a/asm/intel64/bsf.cpp b/asm/intel64/bsf.cpp index 974be43..24a0ae0 100644 --- a/asm/intel64/bsf.cpp +++ b/asm/intel64/bsf.cpp @@ -16,10 +16,12 @@ Op_bsf::Op_bsf(const Asm::Args& args) machine_code = REX("W") + std::vector{ 0x0F, 0xBC } + ModRM(std::any_cast(args[0]).name(), std::any_cast(args[1]).name()); } else if (args[0].type() == typeid(Asm::Args::Register32) && args[1].type() == typeid(Asm::Args::Mem32Ptr64)) { // bsf reg32, [reg64] - machine_code = std::vector{ 0x0F, 0xBC } + ModRM(std::any_cast(args[0]).name(), std::any_cast(args[1]).reg()); + Asm::Args::Mem32Ptr64 ptr{std::any_cast(args[1])}; + machine_code = std::vector{ 0x0F, 0xBC } + ModRM(std::any_cast(args[0]).name(), ptr.reg(), ptr.offs()); } else if (args[0].type() == typeid(Asm::Args::Register64) && args[1].type() == typeid(Asm::Args::Mem64Ptr64)) { // bsf reg64, [reg64] - machine_code = REX("W") + std::vector{ 0x0F, 0xBC } + ModRM(std::any_cast(args[0]).name(), std::any_cast(args[1]).reg()); + Asm::Args::Mem64Ptr64 ptr{std::any_cast(args[1])}; + machine_code = REX("W") + std::vector{ 0x0F, 0xBC } + ModRM(std::any_cast(args[0]).name(), ptr.reg(), ptr.offs()); } else { throw std::runtime_error("Unimplemented: bsf "s + args[0].type().name() + " "s + args[1].type().name()); diff --git a/asm/intel64/bsr.cpp b/asm/intel64/bsr.cpp index 099c7d2..5935402 100644 --- a/asm/intel64/bsr.cpp +++ b/asm/intel64/bsr.cpp @@ -16,10 +16,12 @@ Op_bsr::Op_bsr(const Asm::Args& args) machine_code = REX("W") + std::vector{ 0x0F, 0xBD } + ModRM(std::any_cast(args[0]).name(), std::any_cast(args[1]).name()); } else if (args[0].type() == typeid(Asm::Args::Register32) && args[1].type() == typeid(Asm::Args::Mem32Ptr64)) { // bsr reg32, [reg64] - machine_code = std::vector{ 0x0F, 0xBD } + ModRM(std::any_cast(args[0]).name(), std::any_cast(args[1]).reg()); + Asm::Args::Mem32Ptr64 ptr{std::any_cast(args[1])}; + machine_code = std::vector{ 0x0F, 0xBD } + ModRM(std::any_cast(args[0]).name(), ptr.reg(), ptr.offs()); } else if (args[0].type() == typeid(Asm::Args::Register64) && args[1].type() == typeid(Asm::Args::Mem64Ptr64)) { // bsr reg64, [reg64] - machine_code = REX("W") + std::vector{ 0x0F, 0xBD } + ModRM(std::any_cast(args[0]).name(), std::any_cast(args[1]).reg()); + Asm::Args::Mem64Ptr64 ptr{std::any_cast(args[1])}; + machine_code = REX("W") + std::vector{ 0x0F, 0xBD } + ModRM(std::any_cast(args[0]).name(), ptr.reg(), ptr.offs()); } else { throw std::runtime_error("Unimplemented: bsr "s + args[0].type().name() + " "s + args[1].type().name()); diff --git a/asm/intel64/codes.cpp b/asm/intel64/codes.cpp index 9f82d37..76108a1 100644 --- a/asm/intel64/codes.cpp +++ b/asm/intel64/codes.cpp @@ -78,7 +78,7 @@ std::vector ModRM(const std::string& reg, const std::string& rm, int32_ if (disp == 0 && rm_bits != 5) { // no displacement // ignore: keep MOD == 00, no displacement bytes if (rm_bits == 5) - throw std::runtime_error("ICE: [rbp] with now displacement is not supported"); // TODO: Support this, and SIB byte + throw std::runtime_error("ICE: [rbp] with no displacement is not supported"); // TODO: Support this, and SIB byte } else if (disp >= -128 && disp < 128) { result |= 0b01000000; // 8 bit displacement displacement_bytes.push_back(uint8_t(disp)); diff --git a/asm/intel64/div.cpp b/asm/intel64/div.cpp index 1e98b7b..cfe2503 100644 --- a/asm/intel64/div.cpp +++ b/asm/intel64/div.cpp @@ -21,14 +21,17 @@ Op_div::Op_div(const Asm::Args& args) machine_code = REX("W") + std::vector{ 0xF7 } + ModRM("/6", std::any_cast(args[0]).name()); } else if (args[0].type() == typeid(Asm::Args::Mem8Ptr64)) { // div byte ptr [reg64] (accu is al (remainder=ah) <- ah / x) + Asm::Args::Mem8Ptr64 ptr{std::any_cast(args[0])}; machine_code = std::vector{ 0xF6 } + - ModRM("/6", std::any_cast(args[0]).reg()); + ModRM("/6", ptr.reg(), ptr.offs()); } else if (args[0].type() == typeid(Asm::Args::Mem32Ptr64)) { // div dword ptr [reg64] (accu is eax (remainder=edx) <- edx:eax / x) + Asm::Args::Mem32Ptr64 ptr{std::any_cast(args[0])}; machine_code = std::vector{ 0xF7 } + - ModRM("/6", std::any_cast(args[0]).reg()); + ModRM("/6", ptr.reg(), ptr.offs()); } else if (args[0].type() == typeid(Asm::Args::Mem64Ptr64)) { // div qword ptr [reg64] (accu is rax (remainder=rdx) <- rdx:rax / x) + Asm::Args::Mem64Ptr64 ptr{std::any_cast(args[0])}; machine_code = REX("W") + std::vector{ 0xF7 } + - ModRM("/6", std::any_cast(args[0]).reg()); + ModRM("/6", ptr.reg(), ptr.offs()); } else { throw std::runtime_error("Unimplemented: div "s + args[0].type().name()); } diff --git a/asm/intel64/encode.cpp b/asm/intel64/encode.cpp index a2434fd..4e72933 100644 --- a/asm/intel64/encode.cpp +++ b/asm/intel64/encode.cpp @@ -33,7 +33,7 @@ std::shared_ptr makeLoadValue(const FlowGraph::Data& data, const FlowGraph:: //FlowGraph::TemporaryStorage& storage {dynamic_cast(data_storage)}; index_t index { graph.scope()->indexOfData(data)}; - return makeOp("mov", Asm::Args{{Asm::Args::Register32("eax"), Asm::Args::Mem32Ptr64("rbp", int32_t(index) * -4)}}); + return makeOp("mov", Asm::Args{{Asm::Args::Register32("eax"), Asm::Args::Mem32Ptr64("rbp", int32_t(index + 1) * -4)}}); } else throw std::runtime_error("ICE: Unsupported type for operand data at load: "s + demangle(typeid(data_storage))); } @@ -52,7 +52,7 @@ std::shared_ptr makeStoreValue(const FlowGraph::Data& data, const FlowGraph: //FlowGraph::TemporaryStorage& storage {dynamic_cast(data_storage)}; index_t index { graph.scope()->indexOfData(data)}; - return makeOp("mov", Asm::Args{{Asm::Args::Mem32Ptr64("rbp", int32_t(index) * -4), Asm::Args::Register32("eax")}}); + return makeOp("mov", Asm::Args{{Asm::Args::Mem32Ptr64("rbp", int32_t(index + 1) * -4), Asm::Args::Register32("eax")}}); } else throw std::runtime_error("ICE: Unsupported type for operand data at store: "s + demangle(typeid(data_storage))); } @@ -79,7 +79,7 @@ std::shared_ptr makeAddValue(const FlowGraph::Data& data, const FlowGraph::G //FlowGraph::TemporaryStorage& storage {dynamic_cast(data_storage)}; index_t index { graph.scope()->indexOfData(data)}; - return makeOp("add", Asm::Args{{Asm::Args::Register32("eax"), Asm::Args::Mem32Ptr64("rbp", int32_t(index) * -4)}}); + return makeOp("add", Asm::Args{{Asm::Args::Register32("eax"), Asm::Args::Mem32Ptr64("rbp", int32_t(index + 1) * -4)}}); } else throw std::runtime_error("ICE: Unsupported type for operand data at add: "s + demangle(typeid(data_storage))); } @@ -109,7 +109,7 @@ std::vector> makeMulValue(const FlowGraph::Data& data, co //FlowGraph::TemporaryStorage& storage {dynamic_cast(data_storage)}; index_t index { graph.scope()->indexOfData(data)}; - return {{makeOp("mul", Asm::Args{{Asm::Args::Mem32Ptr64("rbp", int32_t(index) * -4)}})}}; + return {{makeOp("mul", Asm::Args{{Asm::Args::Mem32Ptr64("rbp", int32_t(index + 1) * -4)}})}}; } else throw std::runtime_error("ICE: Unsupported type for operand data at mul: "s + demangle(typeid(data_storage))); } @@ -139,7 +139,7 @@ std::vector> makeDivValue(const FlowGraph::Data& data, co //FlowGraph::TemporaryStorage& storage {dynamic_cast(data_storage)}; index_t index { graph.scope()->indexOfData(data)}; - return {{makeOp("div", Asm::Args{{Asm::Args::Mem32Ptr64("rbp", int32_t(index) * -4)}})}}; + return {{makeOp("div", Asm::Args{{Asm::Args::Mem32Ptr64("rbp", int32_t(index + 1) * -4)}})}}; } else throw std::runtime_error("ICE: Unsupported type for operand data at div: "s + demangle(typeid(data_storage))); } diff --git a/asm/intel64/mov.cpp b/asm/intel64/mov.cpp index 5f09c82..5d09def 100644 --- a/asm/intel64/mov.cpp +++ b/asm/intel64/mov.cpp @@ -33,16 +33,20 @@ Op_mov::Op_mov(const Asm::Args& args) machine_code = std::vector{ REX("W") + static_cast(0xB8 + RegNo(std::any_cast(args[0]).name())) } + std::any_cast(args[1]).getCode(); } else if (args[0].type() == typeid(Asm::Args::Register32) && args[1].type() == typeid(Asm::Args::Mem32Ptr64)) { // mov reg32, [reg64] - machine_code = std::vector{ 0x8B } + ModRM(std::any_cast(args[0]).name(), std::any_cast(args[1]).reg()); + Asm::Args::Mem32Ptr64 ptr{std::any_cast(args[1])}; + machine_code = std::vector{ 0x8B } + ModRM(std::any_cast(args[0]).name(), ptr.reg(), ptr.offs()); } else if (args[0].type() == typeid(Asm::Args::Register64) && args[1].type() == typeid(Asm::Args::Mem64Ptr64)) { // mov reg64, [reg64] - machine_code = REX("W") + std::vector{ 0x8B } + ModRM(std::any_cast(args[0]).name(), std::any_cast(args[1]).reg()); + Asm::Args::Mem64Ptr64 ptr{std::any_cast(args[1])}; + machine_code = REX("W") + std::vector{ 0x8B } + ModRM(std::any_cast(args[0]).name(), ptr.reg(), ptr.offs()); } else if (args[0].type() == typeid(Asm::Args::Mem32Ptr64) && args[1].type() == typeid(Asm::Args::Register32)) { // mov [reg64], reg32 - machine_code = std::vector{ 0x89 } + ModRM(std::any_cast(args[1]).name(), std::any_cast(args[0]).reg()); + Asm::Args::Mem32Ptr64 ptr{std::any_cast(args[0])}; + machine_code = std::vector{ 0x89 } + ModRM(std::any_cast(args[1]).name(), ptr.reg(), ptr.offs()); } else if (args[0].type() == typeid(Asm::Args::Mem64Ptr64) && args[1].type() == typeid(Asm::Args::Register64)) { // mov [reg64], reg64 - machine_code = REX("W") + std::vector{ 0x89 } + ModRM(std::any_cast(args[1]).name(), std::any_cast(args[0]).reg()); + Asm::Args::Mem64Ptr64 ptr{std::any_cast(args[0])}; + machine_code = REX("W") + std::vector{ 0x89 } + ModRM(std::any_cast(args[1]).name(), ptr.reg(), ptr.offs()); } else if (args[0].type() == typeid(Asm::Args::Register64) && args[1].type() == typeid(Asm::Args::Immediate32)) { // mov reg64, imm32 (sign-extended) machine_code = REX("W") + std::vector{ 0xC7 } + ModRM("/0", std::any_cast(args[0]).name()) + std::any_cast(args[1]).getCode(); diff --git a/asm/intel64/mul.cpp b/asm/intel64/mul.cpp index 5825e2a..14810dc 100644 --- a/asm/intel64/mul.cpp +++ b/asm/intel64/mul.cpp @@ -21,14 +21,17 @@ Op_mul::Op_mul(const Asm::Args& args) machine_code = REX("W") + std::vector{ 0xF7 } + ModRM("/4", std::any_cast(args[0]).name()); } else if (args[0].type() == typeid(Asm::Args::Mem8Ptr64)) { // mul byte ptr [reg64] (accu is ax <- al) + Asm::Args::Mem8Ptr64 ptr{std::any_cast(args[0])}; machine_code = std::vector{ 0xF6 } + - ModRM("/4", std::any_cast(args[0]).reg()); + ModRM("/4", ptr.reg(), ptr.offs()); } else if (args[0].type() == typeid(Asm::Args::Mem32Ptr64)) { // mul dword ptr [reg64] (accu is edx:eax <- eax) + Asm::Args::Mem32Ptr64 ptr{std::any_cast(args[0])}; machine_code = std::vector{ 0xF7 } + - ModRM("/4", std::any_cast(args[0]).reg()); + ModRM("/4", ptr.reg(), ptr.offs()); } else if (args[0].type() == typeid(Asm::Args::Mem64Ptr64)) { // mul qword ptr [reg64] (accu is rdx:rax <- rax) + Asm::Args::Mem64Ptr64 ptr{std::any_cast(args[0])}; machine_code = REX("W") + std::vector{ 0xF7 } + - ModRM("/4", std::any_cast(args[0]).reg()); + ModRM("/4", ptr.reg(), ptr.offs()); } else { throw std::runtime_error("Unimplemented: mul "s + args[0].type().name()); } diff --git a/asm/intel64/or.cpp b/asm/intel64/or.cpp index c5be55c..27daf07 100644 --- a/asm/intel64/or.cpp +++ b/asm/intel64/or.cpp @@ -30,16 +30,20 @@ Op_or::Op_or(const Asm::Args& args) machine_code = std::vector{ 0x81 } + ModRM("/1", std::any_cast(args[0]).name()) + std::any_cast(args[1]).getCode(); } else if (args[0].type() == typeid(Asm::Args::Register32) && args[1].type() == typeid(Asm::Args::Mem32Ptr64)) { // or reg32, [reg64] - machine_code = std::vector{ 0x0B } + ModRM(std::any_cast(args[0]).name(), std::any_cast(args[1]).reg()); + Asm::Args::Mem32Ptr64 ptr{std::any_cast(args[1])}; + machine_code = std::vector{ 0x0B } + ModRM(std::any_cast(args[0]).name(), ptr.reg(), ptr.offs()); } else if (args[0].type() == typeid(Asm::Args::Register64) && args[1].type() == typeid(Asm::Args::Mem64Ptr64)) { // or reg64, [reg64] - machine_code = REX("W") + std::vector{ 0x0B } + ModRM(std::any_cast(args[0]).name(), std::any_cast(args[1]).reg()); + Asm::Args::Mem64Ptr64 ptr{std::any_cast(args[1])}; + machine_code = REX("W") + std::vector{ 0x0B } + ModRM(std::any_cast(args[0]).name(), ptr.reg(), ptr.offs()); } else if (args[0].type() == typeid(Asm::Args::Mem32Ptr64) && args[1].type() == typeid(Asm::Args::Register32)) { // or [reg64], reg32 - machine_code = std::vector{ 0x09 } + ModRM(std::any_cast(args[1]).name(), std::any_cast(args[0]).reg()); + Asm::Args::Mem32Ptr64 ptr{std::any_cast(args[0])}; + machine_code = std::vector{ 0x09 } + ModRM(std::any_cast(args[1]).name(), ptr.reg(), ptr.offs()); } else if (args[0].type() == typeid(Asm::Args::Mem64Ptr64) && args[1].type() == typeid(Asm::Args::Register64)) { // or [reg64], reg64 - machine_code = REX("W") + std::vector{ 0x09 } + ModRM(std::any_cast(args[1]).name(), std::any_cast(args[0]).reg()); + Asm::Args::Mem64Ptr64 ptr{std::any_cast(args[0])}; + machine_code = REX("W") + std::vector{ 0x09 } + ModRM(std::any_cast(args[1]).name(), ptr.reg(), ptr.offs()); } else if (args[0].type() == typeid(Asm::Args::Register64) && args[1].type() == typeid(Asm::Args::Immediate32)) { // or reg64, imm32 (sign-extended) machine_code = REX("W") + std::vector{ 0x81 } + ModRM("/1", std::any_cast(args[0]).name()) + std::any_cast(args[1]).getCode(); -- cgit v1.2.3