diff options
Diffstat (limited to 'src/frontend/mame/luaengine_debug.cpp')
-rw-r--r-- | src/frontend/mame/luaengine_debug.cpp | 256 |
1 files changed, 175 insertions, 81 deletions
diff --git a/src/frontend/mame/luaengine_debug.cpp b/src/frontend/mame/luaengine_debug.cpp index 699c303f44f..749d4c34aa0 100644 --- a/src/frontend/mame/luaengine_debug.cpp +++ b/src/frontend/mame/luaengine_debug.cpp @@ -30,6 +30,78 @@ struct wrap_textbuf }; +class symbol_table_wrapper +{ +public: + symbol_table_wrapper(symbol_table_wrapper const &) = delete; + + symbol_table_wrapper(running_machine &machine, std::shared_ptr<symbol_table_wrapper> const &parent, device_t *device) + : m_table(machine, parent ? &parent->table() : nullptr, device) + , m_parent(parent) + { + } + + symbol_table &table() { return m_table; } + symbol_table const &table() const { return m_table; } + std::shared_ptr<symbol_table_wrapper> const &parent() { return m_parent; } + + symbol_entry &add(char const *name) { return m_table.add(name, symbol_table::READ_WRITE); } + symbol_entry &add(char const *name, u64 value) { return m_table.add(name, value); } + symbol_entry *find(char const *name) const { return m_table.find(name); } + symbol_entry *find_deep(char const *name) { return m_table.find_deep(name); } + + u64 value(const char *symbol) { return m_table.value(symbol); } + void set_value(const char *symbol, u64 value) { m_table.set_value(symbol, value); } + +private: + symbol_table m_table; + std::shared_ptr<symbol_table_wrapper> const m_parent; +}; + + +class expression_wrapper +{ +public: + expression_wrapper(expression_wrapper const &) = delete; + expression_wrapper &operator=(expression_wrapper const &) = delete; + + expression_wrapper(std::shared_ptr<symbol_table_wrapper> const &symtable) + : m_expression(symtable->table()) + , m_symbols(symtable) + { + } + + expression_wrapper(std::shared_ptr<symbol_table_wrapper> const &symtable, char const *expression, int default_base) + : m_expression(symtable->table(), expression, default_base) + , m_symbols(symtable) + { + } + + expression_wrapper(std::shared_ptr<symbol_table_wrapper> const &symtable, char const *expression) + : m_expression(symtable->table(), expression) + , m_symbols(symtable) + { + } + + void set_default_base(int base) { m_expression.set_default_base(base); } + void parse(char const *string) { m_expression.parse(string); } + u64 execute() { return m_expression.execute(); } + bool is_empty() const { return m_expression.is_empty(); } + char const *original_string() const { return m_expression.original_string(); } + std::shared_ptr<symbol_table_wrapper> const &symbols() { return m_symbols; } + + void set_symbols(std::shared_ptr<symbol_table_wrapper> const &symtable) + { + m_expression.set_symbols(symtable->table()); + m_symbols = symtable; + } + +private: + parsed_expression m_expression; + std::shared_ptr<symbol_table_wrapper> m_symbols; +}; + + template <bool Enable> sol::object do_breakpoint_enable(device_debug &dev, sol::this_state s, sol::object index) { @@ -106,12 +178,12 @@ void lua_engine::initialize_debug(sol::table &emu) { "m", EXPSPACE_REGION } }; - auto const do_add_symbol = [this] (symbol_table &st, char const *name, sol::protected_function getter, std::optional<sol::protected_function> setter, std::optional<char const *> format) + auto const do_add_symbol = [this] (symbol_table_wrapper &st, char const *name, sol::protected_function getter, std::optional<sol::protected_function> setter, std::optional<char const *> format) -> symbol_entry & { symbol_table::setter_func setfun; if (setter) setfun = [this, cbfunc = std::move(*setter)] (u64 value) { invoke(cbfunc, value); }; - st.add( + return st.table().add( name, [this, cbfunc = std::move(getter)] () -> u64 { @@ -130,46 +202,50 @@ void lua_engine::initialize_debug(sol::table &emu) (format && *format) ? *format : ""); }; - auto symbol_table_type = emu.new_usertype<symbol_table>( + auto symbol_table_type = emu.new_usertype<symbol_table_wrapper>( "symbol_table", sol::call_constructor, sol::factories( - [] (running_machine &machine, symbol_table *parent, device_t *device) { return std::make_unique<symbol_table>(machine, parent, device); }, - [] (running_machine &machine, symbol_table *parent) { return std::make_unique<symbol_table>(machine, parent); }, - [] (running_machine &machine, device_t &device) { return std::make_unique<symbol_table>(machine, nullptr, &device); }, - [] (running_machine &machine) { return std::make_unique<symbol_table>(machine); })); + [] (running_machine &machine) + { return std::make_shared<symbol_table_wrapper>(machine, nullptr, nullptr); }, + [] (std::shared_ptr<symbol_table_wrapper> const &parent, device_t *device) + { return std::make_shared<symbol_table_wrapper>(parent->table().machine(), parent, device); }, + [] (std::shared_ptr<symbol_table_wrapper> const &parent) + { return std::make_shared<symbol_table_wrapper>(parent->table().machine(), parent, nullptr); }, + [] (device_t &device) + { return std::make_shared<symbol_table_wrapper>(device.machine(), nullptr, &device); })); symbol_table_type["set_memory_modified_func"] = - [this] (symbol_table &st, sol::object cb) + [this] (symbol_table_wrapper &st, sol::object cb) { if (cb == sol::lua_nil) - st.set_memory_modified_func(nullptr); + st.table().set_memory_modified_func(nullptr); else if (cb.is<sol::protected_function>()) - st.set_memory_modified_func([this, cbfunc = cb.as<sol::protected_function>()] () { invoke(cbfunc); }); + st.table().set_memory_modified_func([this, cbfunc = cb.as<sol::protected_function>()] () { invoke(cbfunc); }); else osd_printf_error("[LUA ERROR] must call set_memory_modified_func with function or nil\n"); }; symbol_table_type["add"] = sol::overload( - [] (symbol_table &st, char const *name) { st.add(name, symbol_table::READ_WRITE); }, - static_cast<void (symbol_table::*)(char const *, u64)>(&symbol_table::add), + static_cast<symbol_entry &(symbol_table_wrapper::*)(char const *)>(&symbol_table_wrapper::add), + static_cast<symbol_entry &(symbol_table_wrapper::*)(char const *, u64)>(&symbol_table_wrapper::add), do_add_symbol, - [do_add_symbol] (symbol_table &st, char const *name, sol::protected_function getter, sol::lua_nil_t, char const *format) + [do_add_symbol] (symbol_table_wrapper &st, char const *name, sol::protected_function getter, sol::lua_nil_t, char const *format) -> symbol_entry & { - do_add_symbol(st, name, getter, std::nullopt, format); + return do_add_symbol(st, name, getter, std::nullopt, format); }, - [do_add_symbol] (symbol_table &st, char const *name, sol::protected_function getter, std::optional<sol::protected_function> setter) + [do_add_symbol] (symbol_table_wrapper &st, char const *name, sol::protected_function getter, std::optional<sol::protected_function> setter) -> symbol_entry & { - do_add_symbol(st, name, getter, setter, nullptr); + return do_add_symbol(st, name, getter, setter, nullptr); }, - [do_add_symbol] (symbol_table &st, char const *name, sol::protected_function getter, char const *format) + [do_add_symbol] (symbol_table_wrapper &st, char const *name, sol::protected_function getter, char const *format) -> symbol_entry & { - do_add_symbol(st, name, getter, std::nullopt, format); + return do_add_symbol(st, name, getter, std::nullopt, format); }, - [do_add_symbol] (symbol_table &st, char const *name, sol::protected_function getter) + [do_add_symbol] (symbol_table_wrapper &st, char const *name, sol::protected_function getter) -> symbol_entry & { - do_add_symbol(st, name, getter, std::nullopt, nullptr); + return do_add_symbol(st, name, getter, std::nullopt, nullptr); }, - [this] (symbol_table &st, char const *name, int minparams, int maxparams, sol::protected_function execute) + [this] (symbol_table_wrapper &st, char const *name, int minparams, int maxparams, sol::protected_function execute) -> symbol_entry & { - st.add( + return st.table().add( name, minparams, maxparams, @@ -185,41 +261,40 @@ void lua_engine::initialize_debug(sol::table &emu) return result ? *result : 0; }); }); - symbol_table_type["find"] = &symbol_table::find; - symbol_table_type["find_deep"] = &symbol_table::find_deep; - symbol_table_type["value"] = &symbol_table::value; - symbol_table_type["set_value"] = &symbol_table::set_value; + symbol_table_type["find"] = &symbol_table_wrapper::find; + symbol_table_type["find_deep"] = &symbol_table_wrapper::find_deep; + symbol_table_type["value"] = &symbol_table_wrapper::value; + symbol_table_type["set_value"] = &symbol_table_wrapper::set_value; symbol_table_type["memory_value"] = - [] (symbol_table &st, char const *name, char const *space, u32 offset, int size, bool disable_se) + [] (symbol_table_wrapper &st, char const *name, char const *space, u32 offset, int size, bool disable_se) { expression_space const es = s_expression_space_parser(space); - return st.memory_value(name, es, offset, size, disable_se); + return st.table().memory_value(name, es, offset, size, disable_se); }; symbol_table_type["set_memory_value"] = - [] (symbol_table &st, char const *name, char const *space, u32 offset, int size, u64 value, bool disable_se) + [] (symbol_table_wrapper &st, char const *name, char const *space, u32 offset, int size, u64 value, bool disable_se) { expression_space const es = s_expression_space_parser(space); - st.set_memory_value(name, es, offset, size, value, disable_se); + st.table().set_memory_value(name, es, offset, size, value, disable_se); }; //symbol_table_type["read_memory"] = &symbol_table::read_memory; crashes if you try to use it, need to work out why //symbol_table_type["write_memory"] = &symbol_table::write_memory; crashes if you try to use it, need to work out why - symbol_table_type["entries"] = sol::property([] (symbol_table const &st) { return standard_tag_object_ptr_map<symbol_entry>(st.entries()); }); - symbol_table_type["parent"] = sol::property(&symbol_table::parent); + symbol_table_type["entries"] = sol::property([] (symbol_table_wrapper const &st) { return standard_tag_object_ptr_map<symbol_entry>(st.table().entries()); }); + symbol_table_type["parent"] = sol::property(&symbol_table_wrapper::parent); - auto parsed_expression_type = emu.new_usertype<parsed_expression>( + auto parsed_expression_type = emu.new_usertype<expression_wrapper>( "parsed_expression", - sol::call_constructor, sol::factories( - [] (symbol_table &symtable) { return std::make_unique<parsed_expression>(symtable); }, - [] (symbol_table &symtable, char const *expression, int default_base) { return std::make_unique<parsed_expression>(symtable, expression, default_base); }, - [] (symbol_table &symtable, char const *expression) { return std::make_unique<parsed_expression>(symtable, expression); }, - [] (parsed_expression const &src) { return std::make_unique<parsed_expression>(src); })); - parsed_expression_type["set_default_base"] = &parsed_expression::set_default_base; - parsed_expression_type["parse"] = [] (parsed_expression &e, char const *string) { e.parse(string); }; - parsed_expression_type["execute"] = &parsed_expression::execute; - parsed_expression_type["is_empty"] = sol::property(&parsed_expression::is_empty); - parsed_expression_type["original_string"] = sol::property(&parsed_expression::original_string); - parsed_expression_type["symbols"] = sol::property(&parsed_expression::symbols, &parsed_expression::set_symbols); + sol::call_constructor, sol::constructors< + expression_wrapper(std::shared_ptr<symbol_table_wrapper> const &), + expression_wrapper(std::shared_ptr<symbol_table_wrapper> const &, char const *, int), + expression_wrapper(std::shared_ptr<symbol_table_wrapper> const &, char const *)>()); + parsed_expression_type["set_default_base"] = &expression_wrapper::set_default_base; + parsed_expression_type["parse"] = &expression_wrapper::parse; + parsed_expression_type["execute"] = &expression_wrapper::execute; + parsed_expression_type["is_empty"] = sol::property(&expression_wrapper::is_empty); + parsed_expression_type["original_string"] = sol::property(&expression_wrapper::original_string); + parsed_expression_type["symbols"] = sol::property(&expression_wrapper::symbols, &expression_wrapper::set_symbols); auto symbol_entry_type = sol().registry().new_usertype<symbol_entry>("symbol_entry", sol::no_constructor); @@ -266,22 +341,22 @@ void lua_engine::initialize_debug(sol::table &emu) auto device_debug_type = sol().registry().new_usertype<device_debug>("device_debug", sol::no_constructor); device_debug_type["step"] = - [] (device_debug &dev, sol::object num) - { - int steps = 1; - if (num.is<int>()) - steps = num.as<int>(); - dev.single_step(steps); - }; + [] (device_debug &dev, sol::object num) + { + int steps = 1; + if (num.is<int>()) + steps = num.as<int>(); + dev.single_step(steps); + }; device_debug_type["go"] = &device_debug::go; device_debug_type["bpset"] = - [] (device_debug &dev, offs_t address, char const *cond, char const *act) - { - int result(dev.breakpoint_set(address, cond, act)); - dev.device().machine().debug_view().update_all(DVT_DISASSEMBLY); - dev.device().machine().debug_view().update_all(DVT_BREAK_POINTS); - return result; - }; + [] (device_debug &dev, offs_t address, char const *cond, char const *act) + { + int result(dev.breakpoint_set(address, cond, act)); + dev.device().machine().debug_view().update_all(DVT_DISASSEMBLY); + dev.device().machine().debug_view().update_all(DVT_BREAK_POINTS); + return result; + }; device_debug_type["bpclear"] = sol::overload( [] (device_debug &dev, int index) { @@ -302,21 +377,21 @@ void lua_engine::initialize_debug(sol::table &emu) device_debug_type["bpenable"] = &do_breakpoint_enable<true>; device_debug_type["bpdisable"] = &do_breakpoint_enable<false>; device_debug_type["bplist"] = - [this] (device_debug &dev) - { - sol::table table = sol().create_table(); - for (auto const &bpp : dev.breakpoint_list()) - table[bpp.second->index()] = sol::make_reference(sol(), *bpp.second); - return table; - }; + [this] (device_debug &dev) + { + sol::table table = sol().create_table(); + for (auto const &bpp : dev.breakpoint_list()) + table[bpp.second->index()] = sol::make_reference(sol(), bpp.second.get()); + return table; + }; device_debug_type["wpset"] = - [] (device_debug &dev, addr_space &sp, std::string const &type, offs_t addr, offs_t len, char const *cond, char const *act) - { - read_or_write const wptype = s_read_or_write_parser(type); - int result(dev.watchpoint_set(sp.space, wptype, addr, len, cond, act)); - dev.device().machine().debug_view().update_all(DVT_WATCH_POINTS); - return result; - }; + [] (device_debug &dev, addr_space &sp, std::string const &type, offs_t addr, offs_t len, char const *cond, char const *act) + { + read_or_write const wptype = s_read_or_write_parser(type); + int result(dev.watchpoint_set(sp.space, wptype, addr, len, cond, act)); + dev.device().machine().debug_view().update_all(DVT_WATCH_POINTS); + return result; + }; device_debug_type["wpclear"] = sol::overload( [] (device_debug &dev, int index) { @@ -333,18 +408,28 @@ void lua_engine::initialize_debug(sol::table &emu) device_debug_type["wpenable"] = &do_watchpoint_enable<true>; device_debug_type["wpdisable"] = &do_watchpoint_enable<false>; device_debug_type["wplist"] = - [this] (device_debug &dev, addr_space &sp) - { - sol::table table = sol().create_table(); - for (auto &wpp : dev.watchpoint_vector(sp.space.spacenum())) - table[wpp->index()] = sol::make_reference(sol(), *wpp); - return table; - }; + [this] (device_debug &dev, addr_space &sp) + { + sol::table table = sol().create_table(); + for (auto &wpp : dev.watchpoint_vector(sp.space.spacenum())) + table[wpp->index()] = sol::make_reference(sol(), wpp.get()); + return table; + }; auto breakpoint_type = sol().registry().new_usertype<debug_breakpoint>("breakpoint", sol::no_constructor); breakpoint_type["index"] = sol::property(&debug_breakpoint::index); - breakpoint_type["enabled"] = sol::property(&debug_breakpoint::enabled); + breakpoint_type["enabled"] = sol::property( + &debug_breakpoint::enabled, + [] (debug_breakpoint &bp, bool val) + { + if (bp.enabled() != val) + { + bp.setEnabled(val); + bp.debugInterface()->device().machine().debug_view().update_all(DVT_DISASSEMBLY); + bp.debugInterface()->device().machine().debug_view().update_all(DVT_BREAK_POINTS); + } + }); breakpoint_type["address"] = sol::property(&debug_breakpoint::address); breakpoint_type["condition"] = sol::property(&debug_breakpoint::condition); breakpoint_type["action"] = sol::property(&debug_breakpoint::action); @@ -352,7 +437,16 @@ void lua_engine::initialize_debug(sol::table &emu) auto watchpoint_type = sol().registry().new_usertype<debug_watchpoint>("watchpoint", sol::no_constructor); watchpoint_type["index"] = sol::property(&debug_watchpoint::index); - watchpoint_type["enabled"] = sol::property(&debug_watchpoint::enabled); + watchpoint_type["enabled"] = sol::property( + &debug_watchpoint::enabled, + [] (debug_watchpoint &wp, bool val) + { + if (wp.enabled() != val) + { + wp.setEnabled(val); + wp.debugInterface()->device().machine().debug_view().update_all(DVT_WATCH_POINTS); + } + }); watchpoint_type["type"] = sol::property( [] (debug_watchpoint &wp) -> char const * { |