Skip to content

Commit

Permalink
Use arrays to view guest memory instead of std::span
Browse files Browse the repository at this point in the history
  • Loading branch information
fwsGonzo committed Jul 29, 2024
1 parent 2f0b665 commit 1a9cd8d
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 18 deletions.
2 changes: 1 addition & 1 deletion libriscv
8 changes: 4 additions & 4 deletions src/gvar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ Variant GuestVariant::toVariant(const Sandbox &emu) const {
case Variant::FLOAT:
return v.f;
case Variant::STRING: {
auto s = emu.machine().memory.rvspan<GuestStdString>(v.s, 1);
return s[0].to_godot_string(emu.machine());
auto *s = emu.machine().memory.memarray<GuestStdString, 1>(v.s);
return (*s)[0].to_godot_string(emu.machine());
}

case Variant::VECTOR2:
Expand Down Expand Up @@ -87,8 +87,8 @@ void GuestVariant::set(Sandbox &emu, const Variant &value) {
// TODO: Improve this by allocating string + contents + null terminator in one go
auto &machine = emu.machine();
auto ptr = machine.arena().malloc(sizeof(GuestStdString));
auto gstr = machine.memory.rvspan<GuestStdString>(ptr, 1);
gstr[0].set_string(machine, ptr, str.get_data(), str.length());
auto gstr = machine.memory.memarray<GuestStdString, 1>(ptr);
(*gstr)[0].set_string(machine, ptr, str.get_data(), str.length());
this->v.s = ptr;
break;
}
Expand Down
12 changes: 6 additions & 6 deletions src/riscv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ struct GuestStdString
else if (size > max_len)
throw std::runtime_error("Guest std::string too large (size > 16MB)");
// Copy the string from guest memory
const auto view = machine.memory.rvspan<char> (ptr, size);
const auto view = machine.memory.rvview(ptr, size);
return std::string(view.data(), view.size());
}
String to_godot_string(const machine_t& machine, std::size_t max_len = 16UL << 20) const
Expand All @@ -109,9 +109,9 @@ struct GuestStdString
this->ptr = machine.arena().malloc(len + 1);
this->size = len;
// Copy the string to guest memory
auto view = machine.memory.rvspan<char>(ptr, len);
std::memcpy(view.data(), data, len);
view[len] = '\0';
char *guest_ptr = machine.memory.memarray<char>(this->ptr, len + 1);
std::memcpy(guest_ptr, data, len);
guest_ptr[len] = '\0';
this->capacity = len;
}
}
Expand All @@ -129,8 +129,8 @@ struct GuestStdVector
if (size > capacity)
throw std::runtime_error("Guest std::vector has size > capacity");
// Copy the vector from guest memory
const auto view = machine.memory.rvspan<T>(ptr, size);
return std::vector<T>(view.begin(), view.end());
const auto *elements = machine.memory.memarray<T>(ptr, size);
return std::vector<T>(elements, size);
}
};

Expand Down
2 changes: 1 addition & 1 deletion src/shmain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ void Sandbox::setup_arguments(const Variant **args, int argc) {
const auto spanDataPtr = sp;
const auto spanElements = argc;

auto v = m_machine->memory.rvspan<GuestVariant>(spanDataPtr, spanElements);
auto *v = m_machine->memory.memarray<GuestVariant>(spanDataPtr, spanElements);

for (size_t i = 0; i < argc; i++) {
//printf("args[%zu] = type %d\n", i, int(args[i]->get_type()));
Expand Down
17 changes: 11 additions & 6 deletions src/syscalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,30 +11,35 @@ inline Sandbox &emu(machine_t &m) {
#define APICALL(func) static void func(machine_t &machine [[maybe_unused]])

APICALL(api_print) {
auto [view] = machine.sysargs<std::span<GuestVariant>>();
auto [array, len] = machine.sysargs<gaddr_t, gaddr_t>();
auto &emu = riscv::emu(machine);

const GuestVariant *array_ptr = emu.machine().memory.memarray<GuestVariant>(array, len);

// We really want print_internal to be a public function.
for (const auto &var : view) {
for (gaddr_t i = 0; i < len; i++) {
auto &var = array_ptr[i];
UtilityFunctions::print(var.toVariant(emu));
}
}

APICALL(api_vcall) {
auto [vp, method, mlen, args, vret] = machine.sysargs<GuestVariant *, std::string, unsigned, std::span<GuestVariant>, GuestVariant *>();
auto [vp, method, mlen, args_ptr, args_size, vret] = machine.sysargs<GuestVariant *, std::string, unsigned, gaddr_t, gaddr_t, GuestVariant *>();
(void)mlen;

auto &emu = riscv::emu(machine);
emu.print("Calling method: " + std::string(method));

std::array<Variant, 64> vargs;
std::array<const Variant *, 64> argptrs;
if (args.size() > vargs.size()) {
if (args_size > vargs.size()) {
emu.print("Too many arguments.");
return;
}

for (size_t i = 0; i < args.size(); i++) {
const GuestVariant *args = emu.machine().memory.memarray<GuestVariant>(args_ptr, args_size);

for (size_t i = 0; i < args_size; i++) {
vargs[i] = args[i].toVariant(emu);
argptrs[i] = &vargs[i];
}
Expand All @@ -43,7 +48,7 @@ APICALL(api_vcall) {

auto *vcall = vp->toVariantPtr(emu);
Variant ret;
vcall->callp("call", argptrs.data(), args.size(), ret, error);
vcall->callp("call", argptrs.data(), args_size, ret, error);
vret->set(emu, ret);
}

Expand Down

0 comments on commit 1a9cd8d

Please sign in to comment.