Clean up reading of values of various types
This commit is contained in:
parent
c3701056c6
commit
ef3509cbcf
5 changed files with 77 additions and 93 deletions
|
@ -58,4 +58,35 @@ T1 _read_common(const unsigned char* source)
|
|||
#define read64ube(t) _read_common<uint64_t, uint64_t, 8, true>(reinterpret_cast<const unsigned char*>(t))
|
||||
#define read64ule(t) _read_common<uint64_t, uint64_t, 8, false>(reinterpret_cast<const unsigned char*>(t))
|
||||
|
||||
template<typename T> void swap_endian(T& value)
|
||||
{
|
||||
char* _value = reinterpret_cast<char*>(&value);
|
||||
for(size_t i = 0; i < sizeof(T)/2; i++)
|
||||
std::swap(_value[i], _value[sizeof(T)-i-1]);
|
||||
}
|
||||
|
||||
template<typename T> void swap_endian(T& value, int endian)
|
||||
{
|
||||
short _magic = 258;
|
||||
char magic = *reinterpret_cast<char*>(&_magic);
|
||||
bool do_swap = (endian == -1 && magic == 1) || (endian == 1 && magic == 2);
|
||||
if(do_swap)
|
||||
swap_endian(value);
|
||||
}
|
||||
|
||||
template<typename T> T read_of_endian(const void* value, int endian)
|
||||
{
|
||||
T val;
|
||||
memcpy(&val, value, sizeof(T));
|
||||
swap_endian(val, endian);
|
||||
return val;
|
||||
}
|
||||
|
||||
template<typename T> void write_of_endian(void* value, const T& val, int endian)
|
||||
{
|
||||
T val2;
|
||||
memcpy(value, &val, sizeof(T));
|
||||
swap_endian(*reinterpret_cast<T*>(value), endian);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "memorysearch.hpp"
|
||||
#include "minmax.hpp"
|
||||
#include "serialization.hpp"
|
||||
#include <iostream>
|
||||
|
||||
memory_search::memory_search(memory_space& space) throw(std::bad_alloc)
|
||||
|
@ -136,21 +137,8 @@ struct search_value_helper
|
|||
{
|
||||
if(left < sizeof(value_type))
|
||||
return false;
|
||||
value_type v1 = 0;
|
||||
value_type v2 = 0;
|
||||
if(!endian || (endian == memory_space::get_system_endian() && memory_space::can_read_unaligned())) {
|
||||
v1 = *reinterpret_cast<const value_type*>(oldv);
|
||||
v2 = *reinterpret_cast<const value_type*>(newv);
|
||||
} else if(endian < 0)
|
||||
for(size_t i = 0; i < sizeof(value_type); i++) {
|
||||
v1 |= static_cast<value_type>(oldv[i]) << (8 * i);
|
||||
v2 |= static_cast<value_type>(newv[i]) << (8 * i);
|
||||
}
|
||||
else if(endian > 0)
|
||||
for(size_t i = 0; i < sizeof(value_type); i++) {
|
||||
v1 |= static_cast<value_type>(oldv[i]) << (8 * (sizeof(T) - i - 1));
|
||||
v2 |= static_cast<value_type>(newv[i]) << (8 * (sizeof(T) - i - 1));
|
||||
}
|
||||
value_type v1 = read_of_endian<value_type>(oldv, endian);
|
||||
value_type v2 = read_of_endian<value_type>(newv, endian);
|
||||
return val(v1, v2);
|
||||
}
|
||||
const T& val;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "memoryspace.hpp"
|
||||
#include "minmax.hpp"
|
||||
#include "serialization.hpp"
|
||||
#include <algorithm>
|
||||
|
||||
namespace
|
||||
|
@ -14,27 +15,12 @@ namespace
|
|||
g = m.lookup(addr);
|
||||
if(!g.first || g.second + sizeof(T) > g.first->size)
|
||||
return 0;
|
||||
if((!g.first->endian || g.first->endian == system_endian) && memory_space::can_read_unaligned()) {
|
||||
//Native endian.
|
||||
if(g.first->direct_map)
|
||||
return read_of_endian<T>(g.first->direct_map + g.second, g.first->endian);
|
||||
else {
|
||||
T buf;
|
||||
if(g.first->direct_map)
|
||||
return *reinterpret_cast<T*>(g.first->direct_map + g.second);
|
||||
else
|
||||
g.first->read(g.second, &buf, sizeof(T));
|
||||
return buf;
|
||||
} else {
|
||||
//Can't read directly.
|
||||
unsigned char buf[sizeof(T)];
|
||||
if(g.first->direct_map)
|
||||
memcpy(buf, g.first->direct_map + g.second, sizeof(T));
|
||||
else
|
||||
g.first->read(g.second, buf, sizeof(T));
|
||||
if(g.first->endian && g.first->endian != system_endian) {
|
||||
//Needs byteswap.
|
||||
for(size_t i = 0; i < sizeof(T) / 2; i++)
|
||||
std::swap(buf[i], buf[sizeof(T) - i - 1]);
|
||||
}
|
||||
return *reinterpret_cast<T*>(buf);
|
||||
g.first->read(g.second, &buf, sizeof(T));
|
||||
return read_of_endian<T>(&buf, g.first->endian);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,26 +34,12 @@ namespace
|
|||
g = m.lookup(addr);
|
||||
if(!g.first || g.first->readonly || g.second + sizeof(T) > g.first->size)
|
||||
return false;
|
||||
if((!g.first->endian || g.first->endian == system_endian) && memory_space::can_read_unaligned()) {
|
||||
//Native endian.
|
||||
if(g.first->direct_map) {
|
||||
*reinterpret_cast<T*>(g.first->direct_map + g.second) = value;
|
||||
return true;
|
||||
} else
|
||||
g.first->write(g.second, &value, sizeof(T));
|
||||
} else {
|
||||
//The opposite endian (little).
|
||||
unsigned char buf[sizeof(T)];
|
||||
*reinterpret_cast<T*>(buf) = value;
|
||||
if(g.first->endian && g.first->endian != system_endian) {
|
||||
//Needs byteswap.
|
||||
for(size_t i = 0; i < sizeof(T) / 2; i++)
|
||||
std::swap(buf[i], buf[sizeof(T) - i - 1]);
|
||||
}
|
||||
if(g.first->direct_map)
|
||||
memcpy(g.first->direct_map + g.second, buf, sizeof(T));
|
||||
else
|
||||
return g.first->write(g.second, buf, sizeof(T));
|
||||
if(g.first->direct_map)
|
||||
write_of_endian(g.first->direct_map + g.second, value, g.first->endian);
|
||||
else {
|
||||
T buf;
|
||||
write_of_endian(&buf, value, g.first->endian);
|
||||
g.first->write(g.second, &buf, sizeof(T));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1,126 +1,121 @@
|
|||
#include "lua/internal.hpp"
|
||||
#include "core/moviedata.hpp"
|
||||
#include "library/serialization.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
template<typename U, typename S>
|
||||
template<typename S>
|
||||
int do_read(lua_state& L, const std::string& fname)
|
||||
{
|
||||
size_t address = L.get_numeric_argument<size_t>(1, fname.c_str());
|
||||
auto& h = get_host_memory();
|
||||
if(address + sizeof(U) > h.size()) {
|
||||
if(address + sizeof(S) > h.size()) {
|
||||
L.pushboolean(0);
|
||||
return 1;
|
||||
}
|
||||
U ret = 0;
|
||||
for(size_t i = 0; i < sizeof(U); i++)
|
||||
ret = 256 * ret + static_cast<uint8_t>(h[address + i]);
|
||||
L.pushnumber(static_cast<S>(ret));
|
||||
L.pushnumber(read_of_endian<S>(&h[address], 1));
|
||||
return 1;
|
||||
}
|
||||
|
||||
template<typename U, typename S>
|
||||
template<typename S>
|
||||
int do_write(lua_state& L, const std::string& fname)
|
||||
{
|
||||
size_t address = L.get_numeric_argument<size_t>(1, fname.c_str());
|
||||
U value = static_cast<U>(L.get_numeric_argument<S>(2, fname.c_str()));
|
||||
S value = static_cast<S>(L.get_numeric_argument<S>(2, fname.c_str()));
|
||||
auto& h = get_host_memory();
|
||||
if(address + sizeof(U) > h.size())
|
||||
h.resize(address + sizeof(U));
|
||||
for(size_t i = sizeof(U) - 1; i < sizeof(U); i--) {
|
||||
h[address + i] = value;
|
||||
value >>= 8;
|
||||
}
|
||||
if(address + sizeof(S) > h.size())
|
||||
h.resize(address + sizeof(S));
|
||||
write_of_endian<S>(&h[address], value, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
function_ptr_luafun hm_read(lua_func_misc, "hostmemory.read", [](lua_state& L,
|
||||
const std::string& fname) -> int {
|
||||
return do_read<uint8_t, uint8_t>(L, fname);
|
||||
return do_read<uint8_t>(L, fname);
|
||||
});
|
||||
|
||||
function_ptr_luafun hm_write(lua_func_misc, "hostmemory.write", [](lua_state& L,
|
||||
const std::string& fname) -> int {
|
||||
return do_write<uint8_t, uint8_t>(L, fname);
|
||||
return do_write<uint8_t>(L, fname);
|
||||
});
|
||||
|
||||
function_ptr_luafun hm_readb(lua_func_misc, "hostmemory.readbyte", [](lua_state& L,
|
||||
const std::string& fname) -> int {
|
||||
return do_read<uint8_t, uint8_t>(L, fname);
|
||||
return do_read<uint8_t>(L, fname);
|
||||
});
|
||||
|
||||
function_ptr_luafun hm_writeb(lua_func_misc, "hostmemory.writebyte", [](lua_state& L,
|
||||
const std::string& fname) -> int {
|
||||
return do_write<uint8_t, uint8_t>(L, fname);
|
||||
return do_write<uint8_t>(L, fname);
|
||||
});
|
||||
|
||||
function_ptr_luafun hm_readsb(lua_func_misc, "hostmemory.readsbyte", [](lua_state& L,
|
||||
const std::string& fname) -> int {
|
||||
return do_read<uint8_t, int8_t>(L, fname);
|
||||
return do_read<int8_t>(L, fname);
|
||||
});
|
||||
|
||||
function_ptr_luafun hm_writesb(lua_func_misc, "hostmemory.writesbyte", [](lua_state& L,
|
||||
const std::string& fname) -> int {
|
||||
return do_write<uint8_t, int8_t>(L, fname);
|
||||
return do_write<int8_t>(L, fname);
|
||||
});
|
||||
|
||||
function_ptr_luafun hm_readw(lua_func_misc, "hostmemory.readword", [](lua_state& L,
|
||||
const std::string& fname) -> int {
|
||||
return do_read<uint16_t, uint16_t>(L, fname);
|
||||
return do_read<uint16_t>(L, fname);
|
||||
});
|
||||
|
||||
function_ptr_luafun hm_writew(lua_func_misc, "hostmemory.writeword", [](lua_state& L,
|
||||
const std::string& fname) -> int {
|
||||
return do_write<uint16_t, uint16_t>(L, fname);
|
||||
return do_write<uint16_t>(L, fname);
|
||||
});
|
||||
|
||||
function_ptr_luafun hm_readsw(lua_func_misc, "hostmemory.readsword", [](lua_state& L,
|
||||
const std::string& fname) -> int {
|
||||
return do_read<uint16_t, int16_t>(L, fname);
|
||||
return do_read<int16_t>(L, fname);
|
||||
});
|
||||
|
||||
function_ptr_luafun hm_writesw(lua_func_misc, "hostmemory.writesword", [](lua_state& L,
|
||||
const std::string& fname) -> int {
|
||||
return do_write<uint16_t, int16_t>(L, fname);
|
||||
return do_write<int16_t>(L, fname);
|
||||
});
|
||||
|
||||
function_ptr_luafun hm_readd(lua_func_misc, "hostmemory.readdword", [](lua_state& L,
|
||||
const std::string& fname) -> int {
|
||||
return do_read<uint32_t, uint32_t>(L, fname);
|
||||
return do_read<uint32_t>(L, fname);
|
||||
});
|
||||
|
||||
function_ptr_luafun hm_writed(lua_func_misc, "hostmemory.writedword", [](lua_state& L,
|
||||
const std::string& fname) -> int {
|
||||
return do_write<uint32_t, uint32_t>(L, fname);
|
||||
return do_write<uint32_t>(L, fname);
|
||||
});
|
||||
|
||||
function_ptr_luafun hm_readsd(lua_func_misc, "hostmemory.readsdword", [](lua_state& L,
|
||||
const std::string& fname) -> int {
|
||||
return do_read<uint32_t, int32_t>(L, fname);
|
||||
return do_read<int32_t>(L, fname);
|
||||
});
|
||||
|
||||
function_ptr_luafun hm_writesd(lua_func_misc, "hostmemory.writesdword", [](lua_state& L,
|
||||
const std::string& fname) -> int {
|
||||
return do_write<uint32_t, int32_t>(L, fname);
|
||||
return do_write<int32_t>(L, fname);
|
||||
});
|
||||
|
||||
function_ptr_luafun hm_readq(lua_func_misc, "hostmemory.readqword", [](lua_state& L,
|
||||
const std::string& fname) -> int {
|
||||
return do_read<uint64_t, uint64_t>(L, fname);
|
||||
return do_read<uint64_t>(L, fname);
|
||||
});
|
||||
|
||||
function_ptr_luafun hm_writeq(lua_func_misc, "hostmemory.writeqword", [](lua_state& L,
|
||||
const std::string& fname) -> int {
|
||||
return do_write<uint64_t, uint64_t>(L, fname);
|
||||
return do_write<uint64_t>(L, fname);
|
||||
});
|
||||
|
||||
function_ptr_luafun hm_readsq(lua_func_misc, "hostmemory.readsqword", [](lua_state& L,
|
||||
const std::string& fname) -> int {
|
||||
return do_read<uint64_t, int64_t>(L, fname);
|
||||
return do_read<int64_t>(L, fname);
|
||||
});
|
||||
|
||||
function_ptr_luafun hm_writesq(lua_func_misc, "hostmemory.writesqword", [](lua_state& L,
|
||||
const std::string& fname) -> int {
|
||||
return do_write<uint64_t, int64_t>(L, fname);
|
||||
return do_write<int64_t>(L, fname);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "core/rom.hpp"
|
||||
#include "library/sha256.hpp"
|
||||
#include "library/string.hpp"
|
||||
#include "library/serialization.hpp"
|
||||
#include "library/minmax.hpp"
|
||||
|
||||
namespace
|
||||
|
@ -39,12 +40,9 @@ namespace
|
|||
|
||||
template<typename T> T bswap(T val)
|
||||
{
|
||||
char buf[sizeof(T)];
|
||||
memcpy(buf, &val, sizeof(T));
|
||||
for(size_t i = 0; i < sizeof(T) / 2; i++)
|
||||
std::swap(buf[i], buf[sizeof(T) - i - 1]);
|
||||
memcpy(&val, buf, sizeof(T));
|
||||
return val;
|
||||
T val2 = val;
|
||||
swap_endian(val2);
|
||||
return val2;
|
||||
}
|
||||
|
||||
class lua_vma
|
||||
|
|
Loading…
Add table
Reference in a new issue