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/hex.hpp"
13 #include "library/int24.hpp"
17 uint64_t get_vmabase(lua::state
& L
, const std::string
& vma
)
19 for(auto i
: lsnes_memory
.get_regions())
22 throw std::runtime_error("No such VMA");
25 uint64_t get_read_address(lua::state
& L
, int& base
, const char* fn
)
28 if(L
.type(base
) == LUA_TSTRING
) {
29 vmabase
= get_vmabase(L
, L
.get_string(base
, fn
));
32 uint64_t addr
= L
.get_numeric_argument
<uint64_t>(base
++, fn
) + vmabase
;
36 template<typename T
, T (memory_space::*rfun
)(uint64_t addr
)>
37 class lua_read_memory
: public lua::function
40 lua_read_memory(const std::string
& name
) : lua::function(lua_func_misc
, name
) {}
41 int invoke(lua::state
& L
)
44 uint64_t addr
= get_read_address(L
, base
, "lua_read_memory");
45 L
.pushnumber(static_cast<T
>((lsnes_memory
.*rfun
)(addr
)));
50 template<typename T
, bool (memory_space::*wfun
)(uint64_t addr
, T value
)>
51 class lua_write_memory
: public lua::function
54 lua_write_memory(const std::string
& name
) : lua::function(lua_func_misc
, name
) {}
55 int invoke(lua::state
& L
)
58 uint64_t addr
= get_read_address(L
, base
, "lua_write_memory");
59 T value
= L
.get_numeric_argument
<T
>(base
+ 2, fname
.c_str());
60 (lsnes_memory
.*wfun
)(addr
, value
);
69 virtual void read(lua::state
& L
, uint64_t addr
) = 0;
70 virtual void write(lua::state
& L
, uint64_t addr
) = 0;
74 template<typename T
, T (memory_space::*rfun
)(uint64_t addr
), bool (memory_space::*wfun
)(uint64_t addr
,
76 class lua_mmap_memory_helper
: public mmap_base
79 ~lua_mmap_memory_helper() {}
80 void read(lua::state
& L
, uint64_t addr
)
82 L
.pushnumber(static_cast<T
>((lsnes_memory
.*rfun
)(addr
)));
85 void write(lua::state
& L
, uint64_t addr
)
87 T value
= L
.get_numeric_argument
<T
>(3, "aperture(write)");
88 (lsnes_memory
.*wfun
)(addr
, value
);
96 lua_mmap_struct(lua::state
& L
);
102 int index(lua::state
& L
, const std::string
& fname
)
104 const char* c
= L
.tostring(2);
110 if(!mappings
.count(c2
)) {
114 auto& x
= mappings
[c2
];
115 x
.first
->read(L
, x
.second
);
118 int newindex(lua::state
& L
, const std::string
& fname
)
120 const char* c
= L
.tostring(2);
124 if(!mappings
.count(c2
))
126 auto& x
= mappings
[c2
];
127 x
.first
->write(L
, x
.second
);
130 static int create(lua::state
& L
, lua::parameters
& P
)
132 lua::_class
<lua_mmap_struct
>::create(L
);
135 int map(lua::state
& L
, const std::string
& fname
);
138 size_t s
= mappings
.size();
139 return (stringfmt() << s
<< " " << ((s
!= 1) ? "mappings" : "mapping")).str();
142 std::map
<std::string
, std::pair
<mmap_base
*, uint64_t>> mappings
;
147 int aperture_read_fun(lua_State
* _L
)
149 lua::state
& L
= *reinterpret_cast<lua::state
*>(lua_touserdata(_L
, lua_upvalueindex(4)));
150 uint64_t base
= L
.tonumber(lua_upvalueindex(1));
151 uint64_t size
= 0xFFFFFFFFFFFFFFFFULL
;
152 if(L
.type(lua_upvalueindex(2)) == LUA_TNUMBER
)
153 size
= L
.tonumber(lua_upvalueindex(2));
154 mmap_base
* fn
= reinterpret_cast<mmap_base
*>(L
.touserdata(lua_upvalueindex(3)));
155 uint64_t addr
= L
.get_numeric_argument
<uint64_t>(2, "aperture(read)");
156 if(addr
> size
|| addr
+ base
< addr
) {
165 int aperture_write_fun(lua_State
* _L
)
167 lua::state
& L
= *reinterpret_cast<lua::state
*>(lua_touserdata(_L
, lua_upvalueindex(4)));
168 uint64_t base
= L
.tonumber(lua_upvalueindex(1));
169 uint64_t size
= 0xFFFFFFFFFFFFFFFFULL
;
170 if(L
.type(lua_upvalueindex(2)) == LUA_TNUMBER
)
171 size
= L
.tonumber(lua_upvalueindex(2));
172 mmap_base
* fn
= reinterpret_cast<mmap_base
*>(L
.touserdata(lua_upvalueindex(3)));
173 uint64_t addr
= L
.get_numeric_argument
<uint64_t>(2, "aperture(write)");
174 if(addr
> size
|| addr
+ base
< addr
)
181 void aperture_make_fun(lua::state
& L
, uint64_t base
, uint64_t size
, mmap_base
& type
)
185 L
.pushstring( "__index");
191 L
.pushlightuserdata(&type
);
192 L
.pushlightuserdata(&L
);
193 L
.pushcclosure(aperture_read_fun
, 4);
195 L
.pushstring("__newindex");
201 L
.pushlightuserdata(&type
);
202 L
.pushlightuserdata(&L
);
203 L
.pushcclosure(aperture_write_fun
, 4);
208 struct lua_debug_callback
215 static int dtor(lua_State
* L
)
217 lua_debug_callback
* D
= (lua_debug_callback
*)lua_touserdata(L
, 1);
220 int _dtor(lua_State
* L
);
222 std::map
<uint64_t, std::list
<lua_debug_callback
*>> cbs
;
224 int lua_debug_callback::_dtor(lua_State
* L
)
228 lua_pushlightuserdata(L
, &type
);
230 lua_rawset(L
, LUA_REGISTRYINDEX
);
231 debug_remove_callback(addr
, type
, h
);
232 for(auto j
= cbs
[addr
].begin(); j
!= cbs
[addr
].end(); j
++)
237 if(cbs
[addr
].empty())
242 void do_lua_error(lua::state
& L
, int ret
)
247 messages
<< "Error in Lua memory callback: " << L
.get_string(-1, "errhnd") << std::endl
;
251 messages
<< "Error in Lua memory callback (Out of memory)" << std::endl
;
254 messages
<< "Error in Lua memory callback (Double fault)" << std::endl
;
257 messages
<< "Error in Lua memory callback (\?\?\?)" << std::endl
;
262 template<debug_type type
, bool reg
> class lua_registerX
: public lua::function
265 lua_registerX(const std::string
& name
) : lua::function(lua_func_misc
, name
) {}
266 int invoke(lua::state
& L
)
270 if(L
.type(1) == LUA_TNIL
&& type
!= DEBUG_TRACE
) {
271 addr
= 0xFFFFFFFFFFFFFFFFULL
;
273 } else if(type
!= DEBUG_TRACE
)
274 addr
= get_read_address(L
, base
, fname
.c_str());
276 addr
= L
.get_numeric_argument
<uint64_t>(base
++, fname
.c_str());
277 if(L
.type(base
) != LUA_TFUNCTION
)
278 throw std::runtime_error("Expected last argument to " + fname
+ " to be function");
280 handle_registerX(L
, addr
, base
);
284 handle_unregisterX(L
, addr
, base
);
288 void handle_registerX(lua::state
& L
, uint64_t addr
, int lfn
)
290 auto& cbl
= cbs
[addr
];
292 //Put the context in userdata so it can be gc'd when Lua context is terminated.
293 lua_debug_callback
* D
= (lua_debug_callback
*)L
.newuserdata(sizeof(lua_debug_callback
));
295 L
.pushstring("__gc");
296 L
.pushcclosure(&lua_debug_callback::dtor
, 0);
299 L
.pushlightuserdata(&D
->addr
);
301 L
.rawset(LUA_REGISTRYINDEX
);
302 L
.pop(1); //Pop the copy of object.
309 D
->lua_fn
= L
.topointer(lfn
);
310 lua::state
* LL
= &L
.get_master();
312 if(type
!= DEBUG_TRACE
)
313 D
->h
= debug_add_callback(addr
, type
, [LL
, D2
](uint64_t addr
, uint64_t value
) {
314 LL
->pushlightuserdata(D2
);
315 LL
->rawget(LUA_REGISTRYINDEX
);
316 LL
->pushnumber(addr
);
317 LL
->pushnumber(value
);
318 do_lua_error(*LL
, LL
->pcall(2, 0, 0));
320 LL
->pushlightuserdata(&D
->addr
);
322 LL
->rawset(LUA_REGISTRYINDEX
);
323 D
->_dtor(LL
->handle());
326 D
->h
= debug_add_trace_callback(addr
, [LL
, D2
](uint64_t proc
, const char* str
) {
327 LL
->pushlightuserdata(D2
);
328 LL
->rawget(LUA_REGISTRYINDEX
);
329 LL
->pushnumber(proc
);
331 do_lua_error(*LL
, LL
->pcall(2, 0, 0));
333 LL
->pushlightuserdata(&D
->addr
);
335 LL
->rawset(LUA_REGISTRYINDEX
);
336 D
->_dtor(LL
->handle());
338 L
.pushlightuserdata(D2
);
340 L
.rawset(LUA_REGISTRYINDEX
);
342 void handle_unregisterX(lua::state
& L
, uint64_t addr
, int lfn
)
346 auto& cbl
= cbs
[addr
];
347 for(auto i
= cbl
.begin(); i
!= cbl
.end(); i
++) {
348 if((*i
)->type
!= type
) continue;
349 if(L
.topointer(lfn
) != (*i
)->lua_fn
) continue;
350 L
.pushlightuserdata(&(*i
)->type
);
352 L
.rawset(LUA_REGISTRYINDEX
);
353 (*i
)->_dtor(L
.handle());
354 //Lua will GC the object.
360 command::fnptr
<> callbacks_show_lua(lsnes_cmd
, "show-lua-callbacks", "", "",
361 []() throw(std::bad_alloc
, std::runtime_error
) {
363 for(auto& j
: i
.second
)
364 messages
<< "addr=" << j
->addr
<< " type=" << j
->type
<< " handle="
365 << j
->h
.handle
<< " dead=" << j
->dead
<< " lua_fn="
366 << j
->lua_fn
<< std::endl
;
369 class lua_mmap_memory
: public lua::function
372 lua_mmap_memory(const std::string
& name
, mmap_base
& _h
) : lua::function(lua_func_misc
, name
), h(_h
) {}
373 int invoke(lua::state
& L
)
375 if(L
.isnoneornil(1)) {
376 aperture_make_fun(L
, 0, 0xFFFFFFFFFFFFFFFFULL
, h
);
380 uint64_t addr
= get_read_address(L
, base
, "lua_mmap_memory");
381 uint64_t size
= L
.get_numeric_argument
<uint64_t>(base
, fname
.c_str());
383 throw std::runtime_error("Aperture with zero size is not valid");
384 aperture_make_fun(L
, addr
, size
- 1, h
);
390 lua::fnptr
vmacount(lua_func_misc
, "memory.vma_count", [](lua::state
& L
, const std::string
& fname
)
392 L
.pushnumber(lsnes_memory
.get_regions().size());
396 lua::fnptr
cheat(lua_func_misc
, "memory.cheat", [](lua::state
& L
, const std::string
& fname
)
399 uint64_t addr
= get_read_address(L
, base
, fname
.c_str());
400 if(L
.type(base
) == LUA_TNIL
|| L
.type(base
) == LUA_TNONE
) {
401 debug_clear_cheat(addr
);
403 uint64_t value
= L
.get_numeric_argument
<uint64_t>(base
, fname
.c_str());
404 debug_set_cheat(addr
, value
);
409 lua::fnptr
xmask(lua_func_misc
, "memory.setxmask", [](lua::state
& L
, const std::string
& fname
)
411 uint64_t value
= L
.get_numeric_argument
<uint64_t>(1, fname
.c_str());
412 debug_setxmask(value
);
416 int handle_push_vma(lua::state
& L
, memory_region
& r
)
419 L
.pushstring("region_name");
420 L
.pushlstring(r
.name
.c_str(), r
.name
.size());
422 L
.pushstring("baseaddr");
423 L
.pushnumber(r
.base
);
425 L
.pushstring("size");
426 L
.pushnumber(r
.size
);
428 L
.pushstring("lastaddr");
429 L
.pushnumber(r
.last_address());
431 L
.pushstring("readonly");
432 L
.pushboolean(r
.readonly
);
434 L
.pushstring("iospace");
435 L
.pushboolean(r
.special
);
437 L
.pushstring("native_endian");
438 L
.pushboolean(r
.endian
== 0);
440 L
.pushstring("endian");
441 L
.pushnumber(r
.endian
);
446 lua::fnptr
readvma(lua_func_misc
, "memory.read_vma", [](lua::state
& L
, const std::string
& fname
)
448 std::list
<memory_region
*> regions
= lsnes_memory
.get_regions();
449 uint32_t num
= L
.get_numeric_argument
<uint32_t>(1, fname
.c_str());
451 for(auto i
= regions
.begin(); i
!= regions
.end(); i
++, j
++)
453 return handle_push_vma(L
, **i
);
458 lua::fnptr
findvma(lua_func_misc
, "memory.find_vma", [](lua::state
& L
, const std::string
& fname
)
460 uint64_t addr
= L
.get_numeric_argument
<uint64_t>(1, fname
.c_str());
461 auto r
= lsnes_memory
.lookup(addr
);
463 return handle_push_vma(L
, *r
.first
);
468 const char* hexes
= "0123456789ABCDEF";
470 lua::fnptr
hashstate(lua_func_misc
, "memory.hash_state", [](lua::state
& L
, const std::string
& fname
)
473 auto x
= our_rom
.save_core_state();
474 size_t offset
= x
.size() - 32;
475 L
.pushlstring(hex::b_to((uint8_t*)&x
[offset
], 32));
479 #define BLOCKSIZE 256
481 lua::fnptr
hashmemory(lua_func_misc
, "memory.hash_region", [](lua::state
& L
, const std::string
& fname
)
485 uint64_t addr
= get_read_address(L
, base
, fname
.c_str());
486 uint64_t size
= L
.get_numeric_argument
<uint64_t>(base
, fname
.c_str());
487 char buffer
[BLOCKSIZE
];
489 while(size
> BLOCKSIZE
) {
490 for(size_t i
= 0; i
< BLOCKSIZE
; i
++)
491 buffer
[i
] = lsnes_memory
.read
<uint8_t>(addr
+ i
);
492 h
.write(buffer
, BLOCKSIZE
);
496 for(size_t i
= 0; i
< size
; i
++)
497 buffer
[i
] = lsnes_memory
.read
<uint8_t>(addr
+ i
);
498 h
.write(buffer
, size
);
500 L
.pushlstring(hash
.c_str(), 64);
504 lua::fnptr
readmemoryr(lua_func_misc
, "memory.readregion", [](lua::state
& L
, const std::string
& fname
)
508 uint64_t addr
= get_read_address(L
, base
, fname
.c_str());
509 uint64_t size
= L
.get_numeric_argument
<uint64_t>(base
, fname
.c_str());
511 char buffer
[BLOCKSIZE
];
514 size_t rsize
= min(size
, static_cast<uint64_t>(BLOCKSIZE
));
515 lsnes_memory
.read_range(addr
, buffer
, rsize
);
516 for(size_t i
= 0; i
< rsize
; i
++) {
518 L
.pushnumber(static_cast<unsigned char>(buffer
[i
]));
527 lua::fnptr
writememoryr(lua_func_misc
, "memory.writeregion", [](lua::state
& L
,
528 const std::string
& fname
) -> int {
531 uint64_t addr
= get_read_address(L
, base
, fname
.c_str());
532 uint64_t size
= L
.get_numeric_argument
<uint64_t>(base
, fname
.c_str());
533 char buffer
[BLOCKSIZE
];
536 size_t rsize
= min(size
, static_cast<uint64_t>(BLOCKSIZE
));
537 for(size_t i
= 0; i
< rsize
; i
++) {
540 buffer
[i
] = L
.tointeger(-1);
543 lsnes_memory
.write_range(addr
, buffer
, rsize
);
550 template<bool write
, bool sign
> int memory_scattergather(lua::state
& L
, const std::string
& fname
)
556 uint64_t vmabase
= 0;
558 val
= L
.get_numeric_argument
<uint64_t>(ptr
++, fname
.c_str());
559 while(L
.type(ptr
) != LUA_TNIL
&& L
.type(ptr
) != LUA_TNONE
) {
560 if(L
.type(ptr
) == LUA_TBOOLEAN
) {
561 if(L
.toboolean(ptr
++))
565 } else if(L
.type(ptr
) == LUA_TSTRING
) {
566 vmabase
= get_vmabase(L
, L
.get_string(ptr
++, fname
.c_str()));
569 addr
= L
.get_numeric_argument
<uint64_t>(ptr
++, fname
.c_str());
571 lsnes_memory
.write
<uint8_t>(addr
+ vmabase
, val
>> shift
);
573 val
= val
+ ((uint64_t)lsnes_memory
.read
<uint8_t>(addr
+ vmabase
) << shift
);
578 if(val
>= (1ULL << (shift
- 1))) sval
-= (1ULL << shift
);
579 if(sign
) L
.pushnumber(sval
); else L
.pushnumber(val
);
581 return write
? 0 : 1;
584 lua::fnptr
scattergather1(lua_func_misc
, "memory.read_sg", [](lua::state
& L
, const std::string
& fname
)
586 return memory_scattergather
<false, false>(L
, fname
);
589 lua::fnptr
scattergather2(lua_func_misc
, "memory.sread_sg", [](lua::state
& L
,
590 const std::string
& fname
) -> int {
591 return memory_scattergather
<false, true>(L
, fname
);
594 lua::fnptr
scattergather3(lua_func_misc
, "memory.write_sg", [](lua::state
& L
,
595 const std::string
& fname
) -> int {
596 return memory_scattergather
<true, false>(L
, fname
);
599 lua_read_memory
<uint8_t, &memory_space::read
<uint8_t>> rub("memory.readbyte");
600 lua_read_memory
<int8_t, &memory_space::read
<int8_t>> rsb("memory.readsbyte");
601 lua_read_memory
<uint16_t, &memory_space::read
<uint16_t>> ruw("memory.readword");
602 lua_read_memory
<int16_t, &memory_space::read
<int16_t>> rsw("memory.readsword");
603 lua_read_memory
<ss_uint24_t
, &memory_space::read
<ss_uint24_t
>> ruh("memory.readhword");
604 lua_read_memory
<ss_int24_t
, &memory_space::read
<ss_int24_t
>> rsh("memory.readshword");
605 lua_read_memory
<uint32_t, &memory_space::read
<uint32_t>> rud("memory.readdword");
606 lua_read_memory
<int32_t, &memory_space::read
<int32_t>> rsd("memory.readsdword");
607 lua_read_memory
<uint64_t, &memory_space::read
<uint64_t>> ruq("memory.readqword");
608 lua_read_memory
<int64_t, &memory_space::read
<int64_t>> rsq("memory.readsqword");
609 lua_read_memory
<float, &memory_space::read
<float>> rf4("memory.readfloat");
610 lua_read_memory
<double, &memory_space::read
<double>> rf8("memory.readdouble");
611 lua_write_memory
<uint8_t, &memory_space::write
<uint8_t>> wb("memory.writebyte");
612 lua_write_memory
<uint16_t, &memory_space::write
<uint16_t>> ww("memory.writeword");
613 lua_write_memory
<ss_uint24_t
, &memory_space::write
<ss_uint24_t
>> wh("memory.writehword");
614 lua_write_memory
<uint32_t, &memory_space::write
<uint32_t>> wd("memory.writedword");
615 lua_write_memory
<uint64_t, &memory_space::write
<uint64_t>> wq("memory.writeqword");
616 lua_write_memory
<float, &memory_space::write
<float>> wf4("memory.writefloat");
617 lua_write_memory
<double, &memory_space::write
<double>> wf8("memory.writedouble");
618 lua_mmap_memory_helper
<uint8_t, &memory_space::read
<uint8_t>, &memory_space::write
<uint8_t>> mhub
;
619 lua_mmap_memory_helper
<int8_t, &memory_space::read
<int8_t>, &memory_space::write
<int8_t>> mhsb
;
620 lua_mmap_memory_helper
<uint16_t, &memory_space::read
<uint16_t>, &memory_space::write
<uint16_t>> mhuw
;
621 lua_mmap_memory_helper
<int16_t, &memory_space::read
<int16_t>, &memory_space::write
<int16_t>> mhsw
;
622 lua_mmap_memory_helper
<ss_uint24_t
, &memory_space::read
<ss_uint24_t
>, &memory_space::write
<ss_uint24_t
>> mhuh
;
623 lua_mmap_memory_helper
<ss_int24_t
, &memory_space::read
<ss_int24_t
>, &memory_space::write
<ss_int24_t
>> mhsh
;
624 lua_mmap_memory_helper
<uint32_t, &memory_space::read
<uint32_t>, &memory_space::write
<uint32_t>> mhud
;
625 lua_mmap_memory_helper
<int32_t, &memory_space::read
<int32_t>, &memory_space::write
<int32_t>> mhsd
;
626 lua_mmap_memory_helper
<uint64_t, &memory_space::read
<uint64_t>, &memory_space::write
<uint64_t>> mhuq
;
627 lua_mmap_memory_helper
<int64_t, &memory_space::read
<int64_t>, &memory_space::write
<int64_t>> mhsq
;
628 lua_mmap_memory_helper
<float, &memory_space::read
<float>, &memory_space::write
<float>> mhf4
;
629 lua_mmap_memory_helper
<double, &memory_space::read
<double>, &memory_space::write
<double>> mhf8
;
630 lua_mmap_memory
mub("memory.mapbyte", mhub
);
631 lua_mmap_memory
msb("memory.mapsbyte", mhsb
);
632 lua_mmap_memory
muw("memory.mapword", mhuw
);
633 lua_mmap_memory
msw("memory.mapsword", mhsw
);
634 lua_mmap_memory
muh("memory.maphword", mhuh
);
635 lua_mmap_memory
msh("memory.mapshword", mhsh
);
636 lua_mmap_memory
mud("memory.mapdword", mhud
);
637 lua_mmap_memory
msd("memory.mapsdword", mhsd
);
638 lua_mmap_memory
muq("memory.mapqword", mhuq
);
639 lua_mmap_memory
msq("memory.mapsqword", mhsq
);
640 lua_mmap_memory
mf4("memory.mapfloat", mhf4
);
641 lua_mmap_memory
mf8("memory.mapdouble", mhf8
);
642 lua_registerX
<DEBUG_READ
, true> mrr("memory.registerread");
643 lua_registerX
<DEBUG_READ
, false> murr("memory.unregisterread");
644 lua_registerX
<DEBUG_WRITE
, true> mrw("memory.registerwrite");
645 lua_registerX
<DEBUG_WRITE
, false> murw("memory.unregisterwrite");
646 lua_registerX
<DEBUG_EXEC
, true> mrx("memory.registerexec");
647 lua_registerX
<DEBUG_EXEC
, false> murx("memory.unregisterexec");
648 lua_registerX
<DEBUG_TRACE
, true> mrt("memory.registertrace");
649 lua_registerX
<DEBUG_TRACE
, false> murt("memory.unregistertrace");
651 lua::_class
<lua_mmap_struct
> class_mmap_struct(lua_class_memory
, "MMAP_STRUCT", {
652 {"new", &lua_mmap_struct::create
},
654 {"__index", &lua_mmap_struct::index
},
655 {"__newindex", &lua_mmap_struct::newindex
},
656 {"__call", &lua_mmap_struct::map
},
660 int lua_mmap_struct::map(lua::state
& L
, const std::string
& fname
)
662 const char* name
= L
.tostring(2);
664 uint64_t vmabase
= 0;
665 if(L
.type(3) == LUA_TSTRING
) {
666 vmabase
= get_vmabase(L
, L
.get_string(3, fname
.c_str()));
669 uint64_t addr
= L
.get_numeric_argument
<uint64_t>(base
+ 3, fname
.c_str());
670 const char* type
= L
.tostring(base
+ 4);
672 (stringfmt() << fname
<< ": Bad name").throwex();
674 (stringfmt() << fname
<< ": Bad type").throwex();
675 std::string
name2(name
);
676 std::string
type2(type
);
678 mappings
[name2
] = std::make_pair(&mhub
, addr
);
679 else if(type2
== "sbyte")
680 mappings
[name2
] = std::make_pair(&mhsb
, addr
);
681 else if(type2
== "word")
682 mappings
[name2
] = std::make_pair(&mhuw
, addr
);
683 else if(type2
== "sword")
684 mappings
[name2
] = std::make_pair(&mhsw
, addr
);
685 else if(type2
== "hword")
686 mappings
[name2
] = std::make_pair(&mhuh
, addr
);
687 else if(type2
== "shword")
688 mappings
[name2
] = std::make_pair(&mhsh
, addr
);
689 else if(type2
== "dword")
690 mappings
[name2
] = std::make_pair(&mhud
, addr
);
691 else if(type2
== "sdword")
692 mappings
[name2
] = std::make_pair(&mhsd
, addr
);
693 else if(type2
== "qword")
694 mappings
[name2
] = std::make_pair(&mhuq
, addr
);
695 else if(type2
== "sqword")
696 mappings
[name2
] = std::make_pair(&mhsq
, addr
);
697 else if(type2
== "float")
698 mappings
[name2
] = std::make_pair(&mhf4
, addr
);
699 else if(type2
== "double")
700 mappings
[name2
] = std::make_pair(&mhf8
, addr
);
702 (stringfmt() << fname
<< ": Bad type").throwex();
706 lua_mmap_struct::lua_mmap_struct(lua::state
& L
)