aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/main.cpp4
-rw-r--r--src/parser.cpp47
-rw-r--r--src/qregisters.cpp3
-rw-r--r--src/qregisters.h11
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 = &macro_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 = &macro_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)
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)
{