From 5681be1fd8f2790167276a8799e5f240e661bd8a Mon Sep 17 00:00:00 2001 From: Sylvie <35663410+Rangi42@users.noreply.github.com> Date: Sat, 9 Mar 2024 11:12:34 -0500 Subject: [PATCH] Use automatic allocation and `std::move` for RPN bytes (#1336) --- include/asm/rpn.hpp | 31 +++++++++------ src/asm/output.cpp | 2 +- src/asm/parser.y | 92 +++++++++++++++++++++++---------------------- src/asm/rpn.cpp | 57 ++++++++++++---------------- 4 files changed, 92 insertions(+), 90 deletions(-) diff --git a/include/asm/rpn.hpp b/include/asm/rpn.hpp index ea0c30ec..5a803f08 100644 --- a/include/asm/rpn.hpp +++ b/include/asm/rpn.hpp @@ -16,23 +16,32 @@ struct Expression { std::string reason; // Why the expression is not known, if it isn't bool isKnown; // Whether the expression's value is known at assembly time bool isSymbol; // Whether the expression represents a symbol suitable for const diffing - std::vector *rpn; // Bytes serializing the RPN expression - uint32_t rpnPatchSize; // Size the expression will take in the object file + std::vector rpn; // Bytes serializing the RPN expression + uint32_t rpnPatchSize; // Size the expression will take in the object file int32_t getConstVal() const; Symbol const *symbolOf() const; bool isDiffConstant(Symbol const *symName) const; + + Expression() = default; + Expression(Expression &&) = default; +#ifdef _MSC_VER + // MSVC and WinFlexBison won't build without this... + Expression(const Expression &) = default; +#endif + + Expression &operator=(Expression &&) = default; }; void rpn_Number(Expression &expr, uint32_t val); void rpn_Symbol(Expression &expr, char const *symName); -void rpn_LOGNOT(Expression &expr, const Expression &src); -void rpn_BinaryOp(RPNCommand op, Expression &expr, const Expression &src1, const Expression &src2); -void rpn_HIGH(Expression &expr, const Expression &src); -void rpn_LOW(Expression &expr, const Expression &src); +void rpn_LOGNOT(Expression &expr, Expression &&src); +void rpn_BinaryOp(RPNCommand op, Expression &expr, Expression &&src1, const Expression &src2); +void rpn_HIGH(Expression &expr, Expression &&src); +void rpn_LOW(Expression &expr, Expression &&src); void rpn_ISCONST(Expression &expr, const Expression &src); -void rpn_NEG(Expression &expr, const Expression &src); -void rpn_NOT(Expression &expr, const Expression &src); +void rpn_NEG(Expression &expr, Expression &&src); +void rpn_NOT(Expression &expr, Expression &&src); void rpn_BankSymbol(Expression &expr, char const *symName); void rpn_BankSection(Expression &expr, char const *sectionName); void rpn_BankSelf(Expression &expr); @@ -43,8 +52,8 @@ void rpn_StartOfSectionType(Expression &expr, SectionType type); void rpn_Free(Expression &expr); -void rpn_CheckHRAM(Expression &expr, const Expression &src); -void rpn_CheckRST(Expression &expr, const Expression &src); -void rpn_CheckNBit(Expression const &expr, uint8_t n); +void rpn_CheckHRAM(Expression &expr); +void rpn_CheckRST(Expression &expr); +void rpn_CheckNBit(const Expression &expr, uint8_t n); #endif // RGBDS_ASM_RPN_H diff --git a/src/asm/output.cpp b/src/asm/output.cpp index 195b25ca..f6262abb 100644 --- a/src/asm/output.cpp +++ b/src/asm/output.cpp @@ -276,7 +276,7 @@ static void initpatch(Patch &patch, uint32_t type, Expression const &expr, uint3 patch.rpn[4] = (uint32_t)expr.val >> 24; } else { patch.rpn.resize(expr.rpnPatchSize); - writerpn(patch.rpn, *expr.rpn); + writerpn(patch.rpn, expr.rpn); } } diff --git a/src/asm/parser.y b/src/asm/parser.y index 9ce3af9c..535176c1 100644 --- a/src/asm/parser.y +++ b/src/asm/parser.y @@ -968,11 +968,11 @@ ds: ds_args: reloc_8bit { - $$.push_back($1); + $$.push_back(std::move($1)); } | ds_args COMMA reloc_8bit { - $1.push_back($3); - $$ = $1; + $1.push_back(std::move($3)); + $$ = std::move($1); } ; @@ -1243,24 +1243,24 @@ constlist_32bit_entry: reloc_8bit: relocexpr { rpn_CheckNBit($1, 8); - $$ = $1; + $$ = std::move($1); } ; reloc_8bit_no_str: relocexpr_no_str { rpn_CheckNBit($1, 8); - $$ = $1; + $$ = std::move($1); } ; reloc_8bit_offset: OP_ADD relocexpr { rpn_CheckNBit($2, 8); - $$ = $2; + $$ = std::move($2); } | OP_SUB relocexpr { - rpn_NEG($$, $2); + rpn_NEG($$, std::move($2)); rpn_CheckNBit($$, 8); } ; @@ -1268,19 +1268,21 @@ reloc_8bit_offset: reloc_16bit: relocexpr { rpn_CheckNBit($1, 16); - $$ = $1; + $$ = std::move($1); } ; reloc_16bit_no_str: relocexpr_no_str { rpn_CheckNBit($1, 16); - $$ = $1; + $$ = std::move($1); } ; relocexpr: - relocexpr_no_str + relocexpr_no_str { + $$ = std::move($1); + } | string { std::vector output; @@ -1297,82 +1299,82 @@ relocexpr_no_str: rpn_Number($$, $1); } | OP_LOGICNOT relocexpr %prec NEG { - rpn_LOGNOT($$, $2); + rpn_LOGNOT($$, std::move($2)); } | relocexpr OP_LOGICOR relocexpr { - rpn_BinaryOp(RPN_LOGOR, $$, $1, $3); + rpn_BinaryOp(RPN_LOGOR, $$, std::move($1), $3); } | relocexpr OP_LOGICAND relocexpr { - rpn_BinaryOp(RPN_LOGAND, $$, $1, $3); + rpn_BinaryOp(RPN_LOGAND, $$, std::move($1), $3); } | relocexpr OP_LOGICEQU relocexpr { - rpn_BinaryOp(RPN_LOGEQ, $$, $1, $3); + rpn_BinaryOp(RPN_LOGEQ, $$, std::move($1), $3); } | relocexpr OP_LOGICGT relocexpr { - rpn_BinaryOp(RPN_LOGGT, $$, $1, $3); + rpn_BinaryOp(RPN_LOGGT, $$, std::move($1), $3); } | relocexpr OP_LOGICLT relocexpr { - rpn_BinaryOp(RPN_LOGLT, $$, $1, $3); + rpn_BinaryOp(RPN_LOGLT, $$, std::move($1), $3); } | relocexpr OP_LOGICGE relocexpr { - rpn_BinaryOp(RPN_LOGGE, $$, $1, $3); + rpn_BinaryOp(RPN_LOGGE, $$, std::move($1), $3); } | relocexpr OP_LOGICLE relocexpr { - rpn_BinaryOp(RPN_LOGLE, $$, $1, $3); + rpn_BinaryOp(RPN_LOGLE, $$, std::move($1), $3); } | relocexpr OP_LOGICNE relocexpr { - rpn_BinaryOp(RPN_LOGNE, $$, $1, $3); + rpn_BinaryOp(RPN_LOGNE, $$, std::move($1), $3); } | relocexpr OP_ADD relocexpr { - rpn_BinaryOp(RPN_ADD, $$, $1, $3); + rpn_BinaryOp(RPN_ADD, $$, std::move($1), $3); } | relocexpr OP_SUB relocexpr { - rpn_BinaryOp(RPN_SUB, $$, $1, $3); + rpn_BinaryOp(RPN_SUB, $$, std::move($1), $3); } | relocexpr OP_XOR relocexpr { - rpn_BinaryOp(RPN_XOR, $$, $1, $3); + rpn_BinaryOp(RPN_XOR, $$, std::move($1), $3); } | relocexpr OP_OR relocexpr { - rpn_BinaryOp(RPN_OR, $$, $1, $3); + rpn_BinaryOp(RPN_OR, $$, std::move($1), $3); } | relocexpr OP_AND relocexpr { - rpn_BinaryOp(RPN_AND, $$, $1, $3); + rpn_BinaryOp(RPN_AND, $$, std::move($1), $3); } | relocexpr OP_SHL relocexpr { - rpn_BinaryOp(RPN_SHL, $$, $1, $3); + rpn_BinaryOp(RPN_SHL, $$, std::move($1), $3); } | relocexpr OP_SHR relocexpr { - rpn_BinaryOp(RPN_SHR, $$, $1, $3); + rpn_BinaryOp(RPN_SHR, $$, std::move($1), $3); } | relocexpr OP_USHR relocexpr { - rpn_BinaryOp(RPN_USHR, $$, $1, $3); + rpn_BinaryOp(RPN_USHR, $$, std::move($1), $3); } | relocexpr OP_MUL relocexpr { - rpn_BinaryOp(RPN_MUL, $$, $1, $3); + rpn_BinaryOp(RPN_MUL, $$, std::move($1), $3); } | relocexpr OP_DIV relocexpr { - rpn_BinaryOp(RPN_DIV, $$, $1, $3); + rpn_BinaryOp(RPN_DIV, $$, std::move($1), $3); } | relocexpr OP_MOD relocexpr { - rpn_BinaryOp(RPN_MOD, $$, $1, $3); + rpn_BinaryOp(RPN_MOD, $$, std::move($1), $3); } | relocexpr OP_EXP relocexpr { - rpn_BinaryOp(RPN_EXP, $$, $1, $3); + rpn_BinaryOp(RPN_EXP, $$, std::move($1), $3); } | OP_ADD relocexpr %prec NEG { - $$ = $2; + $$ = std::move($2); } | OP_SUB relocexpr %prec NEG { - rpn_NEG($$, $2); + rpn_NEG($$, std::move($2)); } | OP_NOT relocexpr %prec NEG { - rpn_NOT($$, $2); + rpn_NOT($$, std::move($2)); } | OP_HIGH LPAREN relocexpr RPAREN { - rpn_HIGH($$, $3); + rpn_HIGH($$, std::move($3)); } | OP_LOW LPAREN relocexpr RPAREN { - rpn_LOW($$, $3); + rpn_LOW($$, std::move($3)); } | OP_ISCONST LPAREN relocexpr RPAREN { rpn_ISCONST($$, $3); @@ -1470,7 +1472,7 @@ relocexpr_no_str: rpn_Number($$, charmap_HasChar($3.string)); } | LPAREN relocexpr RPAREN { - $$ = $2; + $$ = std::move($2); } ; @@ -1904,13 +1906,13 @@ z80_ldd: z80_ldio: Z80_LDH MODE_A COMMA op_mem_ind { - rpn_CheckHRAM($4, $4); + rpn_CheckHRAM($4); sect_AbsByte(0xF0); sect_RelByte($4, 1); } | Z80_LDH op_mem_ind COMMA MODE_A { - rpn_CheckHRAM($2, $2); + rpn_CheckHRAM($2); sect_AbsByte(0xE0); sect_RelByte($2, 1); @@ -2166,7 +2168,7 @@ z80_rrca: z80_rst: Z80_RST reloc_8bit { - rpn_CheckRST($2, $2); + rpn_CheckRST($2); if (!$2.isKnown) sect_RelByte($2, 0); else @@ -2261,7 +2263,7 @@ z80_xor: op_mem_ind: LBRACK reloc_16bit RBRACK { - $$ = $2; + $$ = std::move($2); } ; @@ -2273,9 +2275,11 @@ op_a_r: ; op_a_n: - reloc_8bit + reloc_8bit { + $$ = std::move($1); + } | MODE_A COMMA reloc_8bit { - $$ = $3; + $$ = std::move($3); } ; @@ -2729,7 +2733,7 @@ static void compoundAssignment(const char *symName, RPNCommand op, int32_t const rpn_Symbol(oldExpr, symName); rpn_Number(constExpr, constValue); - rpn_BinaryOp(op, newExpr, oldExpr, constExpr); + rpn_BinaryOp(op, newExpr, std::move(oldExpr), constExpr); newValue = newExpr.getConstVal(); sym_AddVar(symName, newValue); } diff --git a/src/asm/rpn.cpp b/src/asm/rpn.cpp index 98e74d4d..0e1e07df 100644 --- a/src/asm/rpn.cpp +++ b/src/asm/rpn.cpp @@ -29,7 +29,7 @@ static void initExpression(Expression &expr) { expr.reason.clear(); expr.isKnown = true; expr.isSymbol = false; - expr.rpn = nullptr; + expr.rpn.clear(); expr.rpnPatchSize = 0; } @@ -42,21 +42,14 @@ static void makeUnknown(Expression &expr, Ts... parts) { } static uint8_t *reserveSpace(Expression &expr, uint32_t size) { - if (!expr.rpn) { - expr.rpn = new (std::nothrow) std::vector(); - if (!expr.rpn) - fatalerror("Failed to allocate RPN expression: %s\n", strerror(errno)); - } + size_t curSize = expr.rpn.size(); - size_t curSize = expr.rpn->size(); - - expr.rpn->resize(curSize + size); - return &(*expr.rpn)[curSize]; + expr.rpn.resize(curSize + size); + return &expr.rpn[curSize]; } // Free the RPN expression void rpn_Free(Expression &expr) { - delete expr.rpn; initExpression(expr); } @@ -220,8 +213,7 @@ void rpn_StartOfSectionType(Expression &expr, SectionType type) { *ptr++ = type; } -void rpn_CheckHRAM(Expression &expr, const Expression &src) { - expr = src; +void rpn_CheckHRAM(Expression &expr) { expr.isSymbol = false; if (!expr.isKnown) { @@ -235,9 +227,7 @@ void rpn_CheckHRAM(Expression &expr, const Expression &src) { } } -void rpn_CheckRST(Expression &expr, const Expression &src) { - expr = src; - +void rpn_CheckRST(Expression &expr) { if (expr.isKnown) { // A valid RST address must be masked with 0x38 if (expr.val & ~0x38) @@ -251,7 +241,7 @@ void rpn_CheckRST(Expression &expr, const Expression &src) { } // Checks that an RPN expression's value fits within N bits (signed or unsigned) -void rpn_CheckNBit(Expression const &expr, uint8_t n) { +void rpn_CheckNBit(const Expression &expr, uint8_t n) { assert(n != 0); // That doesn't make sense assert(n < CHAR_BIT * sizeof(int)); // Otherwise `1 << n` is UB @@ -273,8 +263,8 @@ int32_t Expression::getConstVal() const { return val; } -void rpn_LOGNOT(Expression &expr, const Expression &src) { - expr = src; +void rpn_LOGNOT(Expression &expr, Expression &&src) { + expr = std::move(src); expr.isSymbol = false; if (expr.isKnown) { @@ -288,7 +278,7 @@ void rpn_LOGNOT(Expression &expr, const Expression &src) { Symbol const *Expression::symbolOf() const { if (!isSymbol) return nullptr; - return sym_FindScopedSymbol((char const *)&(*rpn)[1]); + return sym_FindScopedSymbol((char const *)&rpn[1]); } bool Expression::isDiffConstant(Symbol const *sym) const { @@ -343,7 +333,7 @@ static int32_t tryConstMask(Expression const &lhs, Expression const &rhs) { return (symbolOfs + sect.alignOfs) & ~unknownBits; } -void rpn_BinaryOp(RPNCommand op, Expression &expr, const Expression &src1, const Expression &src2) { +void rpn_BinaryOp(RPNCommand op, Expression &expr, Expression &&src1, const Expression &src2) { initExpression(expr); expr.isSymbol = false; int32_t constMaskVal; @@ -515,7 +505,7 @@ void rpn_BinaryOp(RPNCommand op, Expression &expr, const Expression &src1, const (uint8_t)(lval >> 24), }; expr.rpnPatchSize = sizeof(bytes); - expr.rpn = nullptr; + expr.rpn.clear(); memcpy(reserveSpace(expr, sizeof(bytes)), bytes, sizeof(bytes)); // Use the other expression's un-const reason @@ -523,7 +513,7 @@ void rpn_BinaryOp(RPNCommand op, Expression &expr, const Expression &src1, const } else { // Otherwise just reuse its RPN buffer expr.rpnPatchSize = src1.rpnPatchSize; - expr.rpn = src1.rpn; + std::swap(expr.rpn, src1.rpn); expr.reason = src1.reason; } @@ -546,8 +536,8 @@ void rpn_BinaryOp(RPNCommand op, Expression &expr, const Expression &src1, const len = sizeof(bytes); patchSize = sizeof(bytes); } else { - ptr = src2.rpn->data(); // Pointer to the right RPN - len = src2.rpn->size(); // Size of the right RPN + ptr = src2.rpn.data(); // Pointer to the right RPN + len = src2.rpn.size(); // Size of the right RPN patchSize = src2.rpnPatchSize; } // Copy the right RPN and append the operator @@ -558,13 +548,12 @@ void rpn_BinaryOp(RPNCommand op, Expression &expr, const Expression &src1, const memcpy(buf, ptr, len); buf[len] = op; - delete src2.rpn; // If there was none, this is `delete nullptr` expr.rpnPatchSize += patchSize + 1; } } -void rpn_HIGH(Expression &expr, const Expression &src) { - expr = src; +void rpn_HIGH(Expression &expr, Expression &&src) { + expr = std::move(src); expr.isSymbol = false; if (expr.isKnown) { @@ -576,8 +565,8 @@ void rpn_HIGH(Expression &expr, const Expression &src) { } } -void rpn_LOW(Expression &expr, const Expression &src) { - expr = src; +void rpn_LOW(Expression &expr, Expression &&src) { + expr = std::move(src); expr.isSymbol = false; if (expr.isKnown) { @@ -597,8 +586,8 @@ void rpn_ISCONST(Expression &expr, const Expression &src) { expr.isSymbol = false; } -void rpn_NEG(Expression &expr, const Expression &src) { - expr = src; +void rpn_NEG(Expression &expr, Expression &&src) { + expr = std::move(src); expr.isSymbol = false; if (expr.isKnown) { @@ -609,8 +598,8 @@ void rpn_NEG(Expression &expr, const Expression &src) { } } -void rpn_NOT(Expression &expr, const Expression &src) { - expr = src; +void rpn_NOT(Expression &expr, Expression &&src) { + expr = std::move(src); expr.isSymbol = false; if (expr.isKnown) {