diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main.cpp | 4 | ||||
-rw-r--r-- | src/parser.cpp | 47 | ||||
-rw-r--r-- | src/qregisters.cpp | 3 | ||||
-rw-r--r-- | src/qregisters.h | 11 |
4 files changed, 42 insertions, 23 deletions
diff --git a/src/main.cpp b/src/main.cpp index bc82093..ce00c0a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -384,6 +384,8 @@ main(int argc, char **argv) */ QRegisters::view.initialize(); + /* the default registers (A-Z and 0-9) */ + QRegisters::globals.insert_defaults(); /* search string and status register */ QRegisters::globals.insert("_"); /* replacement string register */ @@ -395,6 +397,8 @@ main(int argc, char **argv) /* environment defaults and registers */ initialize_environment(argv[0]); + /* the default registers (A-Z and 0-9) */ + local_qregs.insert_defaults(); QRegisters::locals = &local_qregs; ring.edit((const gchar *)NULL); diff --git a/src/parser.cpp b/src/parser.cpp index 05694a2..de7184a 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -159,7 +159,23 @@ Execute::macro(const gchar *macro, bool locals) GotoTable *parent_goto_table = Goto::table; GotoTable macro_goto_table(false); - QRegisterTable *parent_locals = NULL; + QRegisterTable *parent_locals = QRegisters::locals; + /* + * NOTE: A local QReg table is not required + * for local macro calls (:M). + * However allocating it on the stack on-demand is + * tricky (VLAs are not in standard C++ and alloca() + * is buggy on MSCVRT), so we always reserve a + * local Q-Reg table. + * This is OK since the table object itself is very + * small and it's empty by default. + * Best would be to let Execute::macro() be a wrapper + * around something like Execute::local_macro() which + * cares about local Q-Reg allocation, but the special + * handling of currently-edited local Q-Regs below + * prevents this. + */ + QRegisterTable macro_locals(false); State *parent_state = States::current; gint parent_pc = macro_pc; @@ -177,17 +193,14 @@ Execute::macro(const gchar *macro, bool locals) loop_stack_fp = loop_stack.items(); Goto::table = ¯o_goto_table; + + /* + * Locals are only initialized when needed to + * improve the speed of local macro calls. + */ if (locals) { - /* - * Locals are only allocated when needed to save - * space on the call stack and to improve the speed - * of local macro calls. - * However since the QRegisterTable object is rather - * small we can allocate it using alloca() on the stack. - */ - parent_locals = QRegisters::locals; - QRegisters::locals = g_newa(QRegisterTable, 1); - new (QRegisters::locals) QRegisterTable(false); + macro_locals.insert_defaults(); + QRegisters::locals = ¯o_locals; } try { @@ -269,11 +282,7 @@ Execute::macro(const gchar *macro, bool locals) g_free(Goto::skip_label); Goto::skip_label = NULL; - if (locals) { - /* memory is reclaimed on return */ - QRegisters::locals->~QRegisterTable(); - QRegisters::locals = parent_locals; - } + QRegisters::locals = parent_locals; Goto::table = parent_goto_table; loop_stack_fp = parent_loop_fp; @@ -283,11 +292,7 @@ Execute::macro(const gchar *macro, bool locals) throw; /* forward */ } - if (locals) { - /* memory is reclaimed on return */ - QRegisters::locals->~QRegisterTable(); - QRegisters::locals = parent_locals; - } + QRegisters::locals = parent_locals; Goto::table = parent_goto_table; loop_stack_fp = parent_loop_fp; diff --git a/src/qregisters.cpp b/src/qregisters.cpp index 80675be..19590c9 100644 --- a/src/qregisters.cpp +++ b/src/qregisters.cpp @@ -696,7 +696,8 @@ QRegisterClipboard::undo_exchange_string(QRegisterData ®) reg.undo_set_string(); } -QRegisterTable::QRegisterTable(bool _undo) : must_undo(_undo) +void +QRegisterTable::insert_defaults(void) { /* general purpose registers */ for (gchar q = 'A'; q <= 'Z'; q++) diff --git a/src/qregisters.h b/src/qregisters.h index 4648149..fc7a624 100644 --- a/src/qregisters.h +++ b/src/qregisters.h @@ -286,6 +286,12 @@ public: class QRegisterTable : private RBTreeString, public Object { class UndoTokenRemove : public UndoToken { + /* + * NOTE: Storing the table here is only necessary since + * we may have to remove from a global or local Q-Reg + * table. This could be avoided using a separate + * subclass for local registers. + */ QRegisterTable *table; QRegister *reg; @@ -303,7 +309,8 @@ class QRegisterTable : private RBTreeString, public Object { bool must_undo; public: - QRegisterTable(bool _undo = true); + QRegisterTable(bool _must_undo = true) + : must_undo(_must_undo) {} ~QRegisterTable() { @@ -339,6 +346,8 @@ public: return insert(buf); } + void insert_defaults(void); + inline QRegister * find(const gchar *name) { |