Clean up reading of values of various types

This commit is contained in:
Ilari Liusvaara 2013-08-24 20:29:23 +03:00
parent c3701056c6
commit ef3509cbcf
5 changed files with 77 additions and 93 deletions

View file

@ -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 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)) #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 #endif

View file

@ -1,5 +1,6 @@
#include "memorysearch.hpp" #include "memorysearch.hpp"
#include "minmax.hpp" #include "minmax.hpp"
#include "serialization.hpp"
#include <iostream> #include <iostream>
memory_search::memory_search(memory_space& space) throw(std::bad_alloc) memory_search::memory_search(memory_space& space) throw(std::bad_alloc)
@ -136,21 +137,8 @@ struct search_value_helper
{ {
if(left < sizeof(value_type)) if(left < sizeof(value_type))
return false; return false;
value_type v1 = 0; value_type v1 = read_of_endian<value_type>(oldv, endian);
value_type v2 = 0; value_type v2 = read_of_endian<value_type>(newv, endian);
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));
}
return val(v1, v2); return val(v1, v2);
} }
const T& val; const T& val;

View file

@ -1,5 +1,6 @@
#include "memoryspace.hpp" #include "memoryspace.hpp"
#include "minmax.hpp" #include "minmax.hpp"
#include "serialization.hpp"
#include <algorithm> #include <algorithm>
namespace namespace
@ -14,27 +15,12 @@ namespace
g = m.lookup(addr); g = m.lookup(addr);
if(!g.first || g.second + sizeof(T) > g.first->size) if(!g.first || g.second + sizeof(T) > g.first->size)
return 0; return 0;
if((!g.first->endian || g.first->endian == system_endian) && memory_space::can_read_unaligned()) { if(g.first->direct_map)
//Native endian. return read_of_endian<T>(g.first->direct_map + g.second, g.first->endian);
else {
T buf; T buf;
if(g.first->direct_map) g.first->read(g.second, &buf, sizeof(T));
return *reinterpret_cast<T*>(g.first->direct_map + g.second); return read_of_endian<T>(&buf, g.first->endian);
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);
} }
} }
@ -48,26 +34,12 @@ namespace
g = m.lookup(addr); g = m.lookup(addr);
if(!g.first || g.first->readonly || g.second + sizeof(T) > g.first->size) if(!g.first || g.first->readonly || g.second + sizeof(T) > g.first->size)
return false; return false;
if((!g.first->endian || g.first->endian == system_endian) && memory_space::can_read_unaligned()) { if(g.first->direct_map)
//Native endian. write_of_endian(g.first->direct_map + g.second, value, g.first->endian);
if(g.first->direct_map) { else {
*reinterpret_cast<T*>(g.first->direct_map + g.second) = value; T buf;
return true; write_of_endian(&buf, value, g.first->endian);
} else g.first->write(g.second, &buf, sizeof(T));
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));
} }
return true; return true;
} }

View file

@ -1,126 +1,121 @@
#include "lua/internal.hpp" #include "lua/internal.hpp"
#include "core/moviedata.hpp" #include "core/moviedata.hpp"
#include "library/serialization.hpp"
namespace namespace
{ {
template<typename U, typename S> template<typename S>
int do_read(lua_state& L, const std::string& fname) int do_read(lua_state& L, const std::string& fname)
{ {
size_t address = L.get_numeric_argument<size_t>(1, fname.c_str()); size_t address = L.get_numeric_argument<size_t>(1, fname.c_str());
auto& h = get_host_memory(); auto& h = get_host_memory();
if(address + sizeof(U) > h.size()) { if(address + sizeof(S) > h.size()) {
L.pushboolean(0); L.pushboolean(0);
return 1; return 1;
} }
U ret = 0; L.pushnumber(read_of_endian<S>(&h[address], 1));
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));
return 1; return 1;
} }
template<typename U, typename S> template<typename S>
int do_write(lua_state& L, const std::string& fname) int do_write(lua_state& L, const std::string& fname)
{ {
size_t address = L.get_numeric_argument<size_t>(1, fname.c_str()); 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(); auto& h = get_host_memory();
if(address + sizeof(U) > h.size()) if(address + sizeof(S) > h.size())
h.resize(address + sizeof(U)); h.resize(address + sizeof(S));
for(size_t i = sizeof(U) - 1; i < sizeof(U); i--) { write_of_endian<S>(&h[address], value, 1);
h[address + i] = value;
value >>= 8;
}
return 0; return 0;
} }
function_ptr_luafun hm_read(lua_func_misc, "hostmemory.read", [](lua_state& L, function_ptr_luafun hm_read(lua_func_misc, "hostmemory.read", [](lua_state& L,
const std::string& fname) -> int { 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, function_ptr_luafun hm_write(lua_func_misc, "hostmemory.write", [](lua_state& L,
const std::string& fname) -> int { 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, function_ptr_luafun hm_readb(lua_func_misc, "hostmemory.readbyte", [](lua_state& L,
const std::string& fname) -> int { 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, function_ptr_luafun hm_writeb(lua_func_misc, "hostmemory.writebyte", [](lua_state& L,
const std::string& fname) -> int { 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, function_ptr_luafun hm_readsb(lua_func_misc, "hostmemory.readsbyte", [](lua_state& L,
const std::string& fname) -> int { 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, function_ptr_luafun hm_writesb(lua_func_misc, "hostmemory.writesbyte", [](lua_state& L,
const std::string& fname) -> int { 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, function_ptr_luafun hm_readw(lua_func_misc, "hostmemory.readword", [](lua_state& L,
const std::string& fname) -> int { 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, function_ptr_luafun hm_writew(lua_func_misc, "hostmemory.writeword", [](lua_state& L,
const std::string& fname) -> int { 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, function_ptr_luafun hm_readsw(lua_func_misc, "hostmemory.readsword", [](lua_state& L,
const std::string& fname) -> int { 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, function_ptr_luafun hm_writesw(lua_func_misc, "hostmemory.writesword", [](lua_state& L,
const std::string& fname) -> int { 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, function_ptr_luafun hm_readd(lua_func_misc, "hostmemory.readdword", [](lua_state& L,
const std::string& fname) -> int { 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, function_ptr_luafun hm_writed(lua_func_misc, "hostmemory.writedword", [](lua_state& L,
const std::string& fname) -> int { 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, function_ptr_luafun hm_readsd(lua_func_misc, "hostmemory.readsdword", [](lua_state& L,
const std::string& fname) -> int { 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, function_ptr_luafun hm_writesd(lua_func_misc, "hostmemory.writesdword", [](lua_state& L,
const std::string& fname) -> int { 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, function_ptr_luafun hm_readq(lua_func_misc, "hostmemory.readqword", [](lua_state& L,
const std::string& fname) -> int { 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, function_ptr_luafun hm_writeq(lua_func_misc, "hostmemory.writeqword", [](lua_state& L,
const std::string& fname) -> int { 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, function_ptr_luafun hm_readsq(lua_func_misc, "hostmemory.readsqword", [](lua_state& L,
const std::string& fname) -> int { 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, function_ptr_luafun hm_writesq(lua_func_misc, "hostmemory.writesqword", [](lua_state& L,
const std::string& fname) -> int { const std::string& fname) -> int {
return do_write<uint64_t, int64_t>(L, fname); return do_write<int64_t>(L, fname);
}); });
} }

View file

@ -6,6 +6,7 @@
#include "core/rom.hpp" #include "core/rom.hpp"
#include "library/sha256.hpp" #include "library/sha256.hpp"
#include "library/string.hpp" #include "library/string.hpp"
#include "library/serialization.hpp"
#include "library/minmax.hpp" #include "library/minmax.hpp"
namespace namespace
@ -39,12 +40,9 @@ namespace
template<typename T> T bswap(T val) template<typename T> T bswap(T val)
{ {
char buf[sizeof(T)]; T val2 = val;
memcpy(buf, &val, sizeof(T)); swap_endian(val2);
for(size_t i = 0; i < sizeof(T) / 2; i++) return val2;
std::swap(buf[i], buf[sizeof(T) - i - 1]);
memcpy(&val, buf, sizeof(T));
return val;
} }
class lua_vma class lua_vma