1 #include "core/command.hpp"
2 #include "lua/internal.hpp"
3 #include "core/debug.hpp"
4 #include "core/memorymanip.hpp"
5 #include "core/memorywatch.hpp"
6 #include "core/moviedata.hpp"
7 #include "core/moviefile.hpp"
8 #include "core/rom.hpp"
9 #include "library/sha256.hpp"
10 #include "library/string.hpp"
11 #include "library/minmax.hpp"
12 #include "library/int24.hpp"
16 uint64_t get_vmabase(lua_state
& L
, const std::string
& vma
)
18 for(auto i
: lsnes_memory
.get_regions())
21 throw std::runtime_error("No such VMA");
24 uint64_t get_read_address(lua_state
& L
, int& base
, const char* fn
)
27 if(L
.type(base
) == LUA_TSTRING
) {
28 vmabase
= get_vmabase(L
, L
.get_string(base
, fn
));
31 uint64_t addr
= L
.get_numeric_argument
<uint64_t>(base
++, fn
) + vmabase
;
35 template<typename T
, T (memory_space::*rfun
)(uint64_t addr
)>
36 class lua_read_memory
: public lua_function
39 lua_read_memory(const std::string
& name
) : lua_function(lua_func_misc
, name
) {}
40 int invoke(lua_state
& L
)
43 uint64_t addr
= get_read_address(L
, base
, "lua_read_memory");
44 L
.pushnumber(static_cast<T
>((lsnes_memory
.*rfun
)(addr
)));
49 template<typename T
, bool (memory_space::*wfun
)(uint64_t addr
, T value
)>
50 class lua_write_memory
: public lua_function
53 lua_write_memory(const std::string
& name
) : lua_function(lua_func_misc
, name
) {}
54 int invoke(lua_state
& L
)
57 uint64_t addr
= get_read_address(L
, base
, "lua_write_memory");
58 T value
= L
.get_numeric_argument
<T
>(base
+ 2, fname
.c_str());
59 (lsnes_memory
.*wfun
)(addr
, value
);
68 virtual void read(lua_state
& L
, uint64_t addr
) = 0;
69 virtual void write(lua_state
& L
, uint64_t addr
) = 0;
73 template<typename T
, T (memory_space::*rfun
)(uint64_t addr
), bool (memory_space::*wfun
)(uint64_t addr
,
75 class lua_mmap_memory_helper
: public mmap_base
78 ~lua_mmap_memory_helper() {}
79 void read(lua_state
& L
, uint64_t addr
)
81 L
.pushnumber(static_cast<T
>((lsnes_memory
.*rfun
)(addr
)));
84 void write(lua_state
& L
, uint64_t addr
)
86 T value
= L
.get_numeric_argument
<T
>(3, "aperture(write)");
87 (lsnes_memory
.*wfun
)(addr
, value
);
95 lua_mmap_struct(lua_state
& L
);
101 int index(lua_state
& L
, const std::string
& fname
)
103 const char* c
= L
.tostring(2);
109 if(!mappings
.count(c2
)) {
113 auto& x
= mappings
[c2
];
114 x
.first
->read(L
, x
.second
);
117 int newindex(lua_state
& L
, const std::string
& fname
)
119 const char* c
= L
.tostring(2);
123 if(!mappings
.count(c2
))
125 auto& x
= mappings
[c2
];
126 x
.first
->write(L
, x
.second
);
129 int map(lua_state
& L
, const std::string
& fname
);
132 size_t s
= mappings
.size();
133 return (stringfmt() << s
<< " " << ((s
!= 1) ? "mappings" : "mapping")).str();
136 std::map
<std::string
, std::pair
<mmap_base
*, uint64_t>> mappings
;
141 int aperture_read_fun(lua_State
* _L
)
143 lua_state
& L
= *reinterpret_cast<lua_state
*>(lua_touserdata(_L
, lua_upvalueindex(4)));
144 uint64_t base
= L
.tonumber(lua_upvalueindex(1));
145 uint64_t size
= 0xFFFFFFFFFFFFFFFFULL
;
146 if(L
.type(lua_upvalueindex(2)) == LUA_TNUMBER
)
147 size
= L
.tonumber(lua_upvalueindex(2));
148 mmap_base
* fn
= reinterpret_cast<mmap_base
*>(L
.touserdata(lua_upvalueindex(3)));
149 uint64_t addr
= L
.get_numeric_argument
<uint64_t>(2, "aperture(read)");
150 if(addr
> size
|| addr
+ base
< addr
) {
159 int aperture_write_fun(lua_State
* _L
)
161 lua_state
& L
= *reinterpret_cast<lua_state
*>(lua_touserdata(_L
, lua_upvalueindex(4)));
162 uint64_t base
= L
.tonumber(lua_upvalueindex(1));
163 uint64_t size
= 0xFFFFFFFFFFFFFFFFULL
;
164 if(L
.type(lua_upvalueindex(2)) == LUA_TNUMBER
)
165 size
= L
.tonumber(lua_upvalueindex(2));
166 mmap_base
* fn
= reinterpret_cast<mmap_base
*>(L
.touserdata(lua_upvalueindex(3)));
167 uint64_t addr
= L
.get_numeric_argument
<uint64_t>(2, "aperture(write)");
168 if(addr
> size
|| addr
+ base
< addr
)
175 void aperture_make_fun(lua_state
& L
, uint64_t base
, uint64_t size
, mmap_base
& type
)
179 L
.pushstring( "__index");
185 L
.pushlightuserdata(&type
);
186 L
.pushlightuserdata(&L
);
187 L
.pushcclosure(aperture_read_fun
, 4);
189 L
.pushstring("__newindex");
195 L
.pushlightuserdata(&type
);
196 L
.pushlightuserdata(&L
);
197 L
.pushcclosure(aperture_write_fun
, 4);
202 struct lua_debug_callback
209 static int dtor(lua_State
* L
)
211 lua_debug_callback
* D
= (lua_debug_callback
*)lua_touserdata(L
, 1);
214 int _dtor(lua_State
* L
);
216 std::map
<uint64_t, std::list
<lua_debug_callback
*>> cbs
;
218 int lua_debug_callback::_dtor(lua_State
* L
)
222 lua_pushlightuserdata(L
, &type
);
224 lua_rawset(L
, LUA_REGISTRYINDEX
);
225 debug_remove_callback(addr
, type
, h
);
226 for(auto j
= cbs
[addr
].begin(); j
!= cbs
[addr
].end(); j
++)
231 if(cbs
[addr
].empty())
236 void do_lua_error(lua_state
& L
, int ret
)
241 messages
<< "Error in Lua memory callback: " << L
.get_string(-1, "errhnd") << std::endl
;
245 messages
<< "Error in Lua memory callback (Out of memory)" << std::endl
;
248 messages
<< "Error in Lua memory callback (Double fault)" << std::endl
;
251 messages
<< "Error in Lua memory callback (\?\?\?)" << std::endl
;
256 template<debug_type type
, bool reg
> class lua_registerX
: public lua_function
259 lua_registerX(const std::string
& name
) : lua_function(lua_func_misc
, name
) {}
260 int invoke(lua_state
& L
)
264 if(L
.type(1) == LUA_TNIL
&& type
!= DEBUG_TRACE
) {
265 addr
= 0xFFFFFFFFFFFFFFFFULL
;
267 } else if(type
!= DEBUG_TRACE
)
268 addr
= get_read_address(L
, base
, fname
.c_str());
270 addr
= L
.get_numeric_argument
<uint64_t>(base
++, fname
.c_str());
271 if(L
.type(base
) != LUA_TFUNCTION
)
272 throw std::runtime_error("Expected last argument to " + fname
+ " to be function");
274 handle_registerX(L
, addr
, base
);
278 handle_unregisterX(L
, addr
, base
);
282 void handle_registerX(lua_state
& L
, uint64_t addr
, int lfn
)
284 auto& cbl
= cbs
[addr
];
286 //Put the context in userdata so it can be gc'd when Lua context is terminated.
287 lua_debug_callback
* D
= (lua_debug_callback
*)L
.newuserdata(sizeof(lua_debug_callback
));
289 L
.pushstring("__gc");
290 L
.pushcclosure(&lua_debug_callback::dtor
, 0);
293 L
.pushlightuserdata(&D
->addr
);
295 L
.rawset(LUA_REGISTRYINDEX
);
296 L
.pop(1); //Pop the copy of object.
303 D
->lua_fn
= L
.topointer(lfn
);
304 lua_state
* LL
= &L
.get_master();
306 if(type
!= DEBUG_TRACE
)
307 D
->h
= debug_add_callback(addr
, type
, [LL
, D2
](uint64_t addr
, uint64_t value
) {
308 LL
->pushlightuserdata(D2
);
309 LL
->rawget(LUA_REGISTRYINDEX
);
310 LL
->pushnumber(addr
);
311 LL
->pushnumber(value
);
312 do_lua_error(*LL
, LL
->pcall(2, 0, 0));
314 LL
->pushlightuserdata(&D
->addr
);
316 LL
->rawset(LUA_REGISTRYINDEX
);
317 D
->_dtor(LL
->handle());
320 D
->h
= debug_add_trace_callback(addr
, [LL
, D2
](uint64_t proc
, const char* str
) {
321 LL
->pushlightuserdata(D2
);
322 LL
->rawget(LUA_REGISTRYINDEX
);
323 LL
->pushnumber(proc
);
325 do_lua_error(*LL
, LL
->pcall(2, 0, 0));
327 LL
->pushlightuserdata(&D
->addr
);
329 LL
->rawset(LUA_REGISTRYINDEX
);
330 D
->_dtor(LL
->handle());
332 L
.pushlightuserdata(D2
);
334 L
.rawset(LUA_REGISTRYINDEX
);
336 void handle_unregisterX(lua_state
& L
, uint64_t addr
, int lfn
)
340 auto& cbl
= cbs
[addr
];
341 for(auto i
= cbl
.begin(); i
!= cbl
.end(); i
++) {
342 if((*i
)->type
!= type
) continue;
343 if(L
.topointer(lfn
) != (*i
)->lua_fn
) continue;
344 L
.pushlightuserdata(&(*i
)->type
);
346 L
.rawset(LUA_REGISTRYINDEX
);
347 (*i
)->_dtor(L
.handle());
348 //Lua will GC the object.
354 command::fnptr
<> callbacks_show_lua(lsnes_cmd
, "show-lua-callbacks", "", "",
355 []() throw(std::bad_alloc
, std::runtime_error
) {
357 for(auto& j
: i
.second
)
358 messages
<< "addr=" << j
->addr
<< " type=" << j
->type
<< " handle="
359 << j
->h
.handle
<< " dead=" << j
->dead
<< " lua_fn="
360 << j
->lua_fn
<< std::endl
;
363 class lua_mmap_memory
: public lua_function
366 lua_mmap_memory(const std::string
& name
, mmap_base
& _h
) : lua_function(lua_func_misc
, name
), h(_h
) {}
367 int invoke(lua_state
& L
)
369 if(L
.isnoneornil(1)) {
370 aperture_make_fun(L
, 0, 0xFFFFFFFFFFFFFFFFULL
, h
);
374 uint64_t addr
= get_read_address(L
, base
, "lua_mmap_memory");
375 uint64_t size
= L
.get_numeric_argument
<uint64_t>(base
, fname
.c_str());
377 throw std::runtime_error("Aperture with zero size is not valid");
378 aperture_make_fun(L
, addr
, size
- 1, h
);
384 function_ptr_luafun
vmacount(lua_func_misc
, "memory.vma_count", [](lua_state
& L
, const std::string
& fname
)
386 L
.pushnumber(lsnes_memory
.get_regions().size());
390 function_ptr_luafun
cheat(lua_func_misc
, "memory.cheat", [](lua_state
& L
, const std::string
& fname
)
393 uint64_t addr
= get_read_address(L
, base
, fname
.c_str());
394 if(L
.type(base
) == LUA_TNIL
|| L
.type(base
) == LUA_TNONE
) {
395 debug_clear_cheat(addr
);
397 uint64_t value
= L
.get_numeric_argument
<uint64_t>(base
, fname
.c_str());
398 debug_set_cheat(addr
, value
);
403 function_ptr_luafun
xmask(lua_func_misc
, "memory.setxmask", [](lua_state
& L
, const std::string
& fname
)
405 uint64_t value
= L
.get_numeric_argument
<uint64_t>(1, fname
.c_str());
406 debug_setxmask(value
);
410 int handle_push_vma(lua_state
& L
, memory_region
& r
)
413 L
.pushstring("region_name");
414 L
.pushlstring(r
.name
.c_str(), r
.name
.size());
416 L
.pushstring("baseaddr");
417 L
.pushnumber(r
.base
);
419 L
.pushstring("size");
420 L
.pushnumber(r
.size
);
422 L
.pushstring("lastaddr");
423 L
.pushnumber(r
.last_address());
425 L
.pushstring("readonly");
426 L
.pushboolean(r
.readonly
);
428 L
.pushstring("iospace");
429 L
.pushboolean(r
.special
);
431 L
.pushstring("native_endian");
432 L
.pushboolean(r
.endian
== 0);
434 L
.pushstring("endian");
435 L
.pushnumber(r
.endian
);
440 function_ptr_luafun
readvma(lua_func_misc
, "memory.read_vma", [](lua_state
& L
, const std::string
& fname
)
442 std::list
<memory_region
*> regions
= lsnes_memory
.get_regions();
443 uint32_t num
= L
.get_numeric_argument
<uint32_t>(1, fname
.c_str());
445 for(auto i
= regions
.begin(); i
!= regions
.end(); i
++, j
++)
447 return handle_push_vma(L
, **i
);
452 function_ptr_luafun
findvma(lua_func_misc
, "memory.find_vma", [](lua_state
& L
, const std::string
& fname
)
454 uint64_t addr
= L
.get_numeric_argument
<uint64_t>(1, fname
.c_str());
455 auto r
= lsnes_memory
.lookup(addr
);
457 return handle_push_vma(L
, *r
.first
);
462 const char* hexes
= "0123456789ABCDEF";
464 function_ptr_luafun
hashstate(lua_func_misc
, "memory.hash_state", [](lua_state
& L
, const std::string
& fname
)
467 auto x
= our_rom
.save_core_state();
468 size_t offset
= x
.size() - 32;
469 for(unsigned i
= 0; i
< 32; i
++) {
470 hash
[2 * i
+ 0] = hexes
[static_cast<unsigned char>(x
[offset
+ i
]) >> 4];
471 hash
[2 * i
+ 1] = hexes
[static_cast<unsigned char>(x
[offset
+ i
]) & 0xF];
473 L
.pushlstring(hash
, 64);
477 #define BLOCKSIZE 256
479 function_ptr_luafun
hashmemory(lua_func_misc
, "memory.hash_region", [](lua_state
& L
, const std::string
& fname
)
483 uint64_t addr
= get_read_address(L
, base
, fname
.c_str());
484 uint64_t size
= L
.get_numeric_argument
<uint64_t>(base
, fname
.c_str());
485 char buffer
[BLOCKSIZE
];
487 while(size
> BLOCKSIZE
) {
488 for(size_t i
= 0; i
< BLOCKSIZE
; i
++)
489 buffer
[i
] = lsnes_memory
.read
<uint8_t>(addr
+ i
);
490 h
.write(buffer
, BLOCKSIZE
);
494 for(size_t i
= 0; i
< size
; i
++)
495 buffer
[i
] = lsnes_memory
.read
<uint8_t>(addr
+ i
);
496 h
.write(buffer
, size
);
498 L
.pushlstring(hash
.c_str(), 64);
502 function_ptr_luafun
readmemoryr(lua_func_misc
, "memory.readregion", [](lua_state
& L
, const std::string
& fname
)
506 uint64_t addr
= get_read_address(L
, base
, fname
.c_str());
507 uint64_t size
= L
.get_numeric_argument
<uint64_t>(base
, fname
.c_str());
509 char buffer
[BLOCKSIZE
];
512 size_t rsize
= min(size
, static_cast<uint64_t>(BLOCKSIZE
));
513 lsnes_memory
.read_range(addr
, buffer
, rsize
);
514 for(size_t i
= 0; i
< rsize
; i
++) {
516 L
.pushnumber(static_cast<unsigned char>(buffer
[i
]));
525 function_ptr_luafun
writememoryr(lua_func_misc
, "memory.writeregion", [](lua_state
& L
,
526 const std::string
& fname
) -> int {
529 uint64_t addr
= get_read_address(L
, base
, fname
.c_str());
530 uint64_t size
= L
.get_numeric_argument
<uint64_t>(base
, fname
.c_str());
531 char buffer
[BLOCKSIZE
];
534 size_t rsize
= min(size
, static_cast<uint64_t>(BLOCKSIZE
));
535 for(size_t i
= 0; i
< rsize
; i
++) {
538 buffer
[i
] = L
.tointeger(-1);
541 lsnes_memory
.write_range(addr
, buffer
, rsize
);
548 function_ptr_luafun
gui_cbitmap(lua_func_misc
, "memory.map_structure", [](lua_state
& L
,
549 const std::string
& fname
) -> int {
550 lua_class
<lua_mmap_struct
>::create(L
);
554 function_ptr_luafun
memory_watchexpr(lua_func_misc
, "memory.read_expr", [](lua_state
& L
,
555 const std::string
& fname
) -> int {
556 std::string val
= evaluate_watch(L
.get_string(1, fname
.c_str()));
557 L
.pushstring(val
.c_str());
561 template<bool write
, bool sign
> int memory_scattergather(lua_state
& L
, const std::string
& fname
)
567 uint64_t vmabase
= 0;
569 val
= L
.get_numeric_argument
<uint64_t>(ptr
++, fname
.c_str());
570 while(L
.type(ptr
) != LUA_TNIL
&& L
.type(ptr
) != LUA_TNONE
) {
571 if(L
.type(ptr
) == LUA_TBOOLEAN
) {
572 if(L
.toboolean(ptr
++))
576 } else if(L
.type(ptr
) == LUA_TSTRING
) {
577 vmabase
= get_vmabase(L
, L
.get_string(ptr
++, fname
.c_str()));
580 addr
= L
.get_numeric_argument
<uint64_t>(ptr
++, fname
.c_str());
582 lsnes_memory
.write
<uint8_t>(addr
+ vmabase
, val
>> shift
);
584 val
= val
+ ((uint64_t)lsnes_memory
.read
<uint8_t>(addr
+ vmabase
) << shift
);
589 if(val
>= (1ULL << (shift
- 1))) sval
-= (1ULL << shift
);
590 if(sign
) L
.pushnumber(sval
); else L
.pushnumber(val
);
592 return write
? 0 : 1;
595 function_ptr_luafun
scattergather1(lua_func_misc
, "memory.read_sg", [](lua_state
& L
, const std::string
& fname
)
597 return memory_scattergather
<false, false>(L
, fname
);
600 function_ptr_luafun
scattergather2(lua_func_misc
, "memory.sread_sg", [](lua_state
& L
,
601 const std::string
& fname
) -> int {
602 return memory_scattergather
<false, true>(L
, fname
);
605 function_ptr_luafun
scattergather3(lua_func_misc
, "memory.write_sg", [](lua_state
& L
,
606 const std::string
& fname
) -> int {
607 return memory_scattergather
<true, false>(L
, fname
);
610 lua_read_memory
<uint8_t, &memory_space::read
<uint8_t>> rub("memory.readbyte");
611 lua_read_memory
<int8_t, &memory_space::read
<int8_t>> rsb("memory.readsbyte");
612 lua_read_memory
<uint16_t, &memory_space::read
<uint16_t>> ruw("memory.readword");
613 lua_read_memory
<int16_t, &memory_space::read
<int16_t>> rsw("memory.readsword");
614 lua_read_memory
<ss_uint24_t
, &memory_space::read
<ss_uint24_t
>> ruh("memory.readhword");
615 lua_read_memory
<ss_int24_t
, &memory_space::read
<ss_int24_t
>> rsh("memory.readshword");
616 lua_read_memory
<uint32_t, &memory_space::read
<uint32_t>> rud("memory.readdword");
617 lua_read_memory
<int32_t, &memory_space::read
<int32_t>> rsd("memory.readsdword");
618 lua_read_memory
<uint64_t, &memory_space::read
<uint64_t>> ruq("memory.readqword");
619 lua_read_memory
<int64_t, &memory_space::read
<int64_t>> rsq("memory.readsqword");
620 lua_read_memory
<float, &memory_space::read
<float>> rf4("memory.readfloat");
621 lua_read_memory
<double, &memory_space::read
<double>> rf8("memory.readdouble");
622 lua_write_memory
<uint8_t, &memory_space::write
<uint8_t>> wb("memory.writebyte");
623 lua_write_memory
<uint16_t, &memory_space::write
<uint16_t>> ww("memory.writeword");
624 lua_write_memory
<ss_uint24_t
, &memory_space::write
<ss_uint24_t
>> wh("memory.writehword");
625 lua_write_memory
<uint32_t, &memory_space::write
<uint32_t>> wd("memory.writedword");
626 lua_write_memory
<uint64_t, &memory_space::write
<uint64_t>> wq("memory.writeqword");
627 lua_write_memory
<float, &memory_space::write
<float>> wf4("memory.writefloat");
628 lua_write_memory
<double, &memory_space::write
<double>> wf8("memory.writedouble");
629 lua_mmap_memory_helper
<uint8_t, &memory_space::read
<uint8_t>, &memory_space::write
<uint8_t>> mhub
;
630 lua_mmap_memory_helper
<int8_t, &memory_space::read
<int8_t>, &memory_space::write
<int8_t>> mhsb
;
631 lua_mmap_memory_helper
<uint16_t, &memory_space::read
<uint16_t>, &memory_space::write
<uint16_t>> mhuw
;
632 lua_mmap_memory_helper
<int16_t, &memory_space::read
<int16_t>, &memory_space::write
<int16_t>> mhsw
;
633 lua_mmap_memory_helper
<ss_uint24_t
, &memory_space::read
<ss_uint24_t
>, &memory_space::write
<ss_uint24_t
>> mhuh
;
634 lua_mmap_memory_helper
<ss_int24_t
, &memory_space::read
<ss_int24_t
>, &memory_space::write
<ss_int24_t
>> mhsh
;
635 lua_mmap_memory_helper
<uint32_t, &memory_space::read
<uint32_t>, &memory_space::write
<uint32_t>> mhud
;
636 lua_mmap_memory_helper
<int32_t, &memory_space::read
<int32_t>, &memory_space::write
<int32_t>> mhsd
;
637 lua_mmap_memory_helper
<uint64_t, &memory_space::read
<uint64_t>, &memory_space::write
<uint64_t>> mhuq
;
638 lua_mmap_memory_helper
<int64_t, &memory_space::read
<int64_t>, &memory_space::write
<int64_t>> mhsq
;
639 lua_mmap_memory_helper
<float, &memory_space::read
<float>, &memory_space::write
<float>> mhf4
;
640 lua_mmap_memory_helper
<double, &memory_space::read
<double>, &memory_space::write
<double>> mhf8
;
641 lua_mmap_memory
mub("memory.mapbyte", mhub
);
642 lua_mmap_memory
msb("memory.mapsbyte", mhsb
);
643 lua_mmap_memory
muw("memory.mapword", mhuw
);
644 lua_mmap_memory
msw("memory.mapsword", mhsw
);
645 lua_mmap_memory
muh("memory.maphword", mhuh
);
646 lua_mmap_memory
msh("memory.mapshword", mhsh
);
647 lua_mmap_memory
mud("memory.mapdword", mhud
);
648 lua_mmap_memory
msd("memory.mapsdword", mhsd
);
649 lua_mmap_memory
muq("memory.mapqword", mhuq
);
650 lua_mmap_memory
msq("memory.mapsqword", mhsq
);
651 lua_mmap_memory
mf4("memory.mapfloat", mhf4
);
652 lua_mmap_memory
mf8("memory.mapdouble", mhf8
);
653 lua_registerX
<DEBUG_READ
, true> mrr("memory.registerread");
654 lua_registerX
<DEBUG_READ
, false> murr("memory.unregisterread");
655 lua_registerX
<DEBUG_WRITE
, true> mrw("memory.registerwrite");
656 lua_registerX
<DEBUG_WRITE
, false> murw("memory.unregisterwrite");
657 lua_registerX
<DEBUG_EXEC
, true> mrx("memory.registerexec");
658 lua_registerX
<DEBUG_EXEC
, false> murx("memory.unregisterexec");
659 lua_registerX
<DEBUG_TRACE
, true> mrt("memory.registertrace");
660 lua_registerX
<DEBUG_TRACE
, false> murt("memory.unregistertrace");
662 lua_class
<lua_mmap_struct
> class_mmap_struct("MMAP_STRUCT");
665 int lua_mmap_struct::map(lua_state
& L
, const std::string
& fname
)
667 const char* name
= L
.tostring(2);
669 uint64_t vmabase
= 0;
670 if(L
.type(3) == LUA_TSTRING
) {
671 vmabase
= get_vmabase(L
, L
.get_string(3, fname
.c_str()));
674 uint64_t addr
= L
.get_numeric_argument
<uint64_t>(base
+ 3, fname
.c_str());
675 const char* type
= L
.tostring(base
+ 4);
677 (stringfmt() << fname
<< ": Bad name").throwex();
679 (stringfmt() << fname
<< ": Bad type").throwex();
680 std::string
name2(name
);
681 std::string
type2(type
);
683 mappings
[name2
] = std::make_pair(&mhub
, addr
);
684 else if(type2
== "sbyte")
685 mappings
[name2
] = std::make_pair(&mhsb
, addr
);
686 else if(type2
== "word")
687 mappings
[name2
] = std::make_pair(&mhuw
, addr
);
688 else if(type2
== "sword")
689 mappings
[name2
] = std::make_pair(&mhsw
, addr
);
690 else if(type2
== "hword")
691 mappings
[name2
] = std::make_pair(&mhuh
, addr
);
692 else if(type2
== "shword")
693 mappings
[name2
] = std::make_pair(&mhsh
, addr
);
694 else if(type2
== "dword")
695 mappings
[name2
] = std::make_pair(&mhud
, addr
);
696 else if(type2
== "sdword")
697 mappings
[name2
] = std::make_pair(&mhsd
, addr
);
698 else if(type2
== "qword")
699 mappings
[name2
] = std::make_pair(&mhuq
, addr
);
700 else if(type2
== "sqword")
701 mappings
[name2
] = std::make_pair(&mhsq
, addr
);
702 else if(type2
== "float")
703 mappings
[name2
] = std::make_pair(&mhf4
, addr
);
704 else if(type2
== "double")
705 mappings
[name2
] = std::make_pair(&mhf8
, addr
);
707 (stringfmt() << fname
<< ": Bad type").throwex();
711 lua_mmap_struct::lua_mmap_struct(lua_state
& L
)
713 objclass
<lua_mmap_struct
>().bind_multi(L
, {
714 {"__index", &lua_mmap_struct::index
},
715 {"__newindex", &lua_mmap_struct::newindex
},
716 {"__call", &lua_mmap_struct::map
},