Skip to content

Commit

Permalink
Scope incoming objects and allow calling on them
Browse files Browse the repository at this point in the history
  • Loading branch information
fwsGonzo committed Aug 15, 2024
1 parent 8ce62c0 commit 93b9b06
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 22 deletions.
12 changes: 2 additions & 10 deletions src/gvar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,16 +165,8 @@ void GuestVariant::set(Sandbox &emu, const Variant &value) {

case Variant::OBJECT: { // Objects are represented as uintptr_t
godot::Object *obj = value.operator godot::Object *();
// XXX: Information leak, we are exposing the object address to the guest
// TODO: Use a hash table to map object addresses to guest object IDs
godot::Node *node = godot::Object::cast_to<godot::Node>(obj);
if (!node) {
ERR_PRINT("SetVariant(): Object is not a Node (unsupported!)");
this->v.i = 0;
break;
}
emu.add_scoped_object(node);
this->v.i = (uintptr_t)node;
emu.add_scoped_object(obj);
this->v.i = (uintptr_t)obj;
break;
}
case Variant::NODE_PATH: { // Node paths are represented as strings
Expand Down
42 changes: 30 additions & 12 deletions src/syscalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,26 +34,44 @@ APICALL(api_vcall) {

auto &emu = riscv::emu(machine);

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

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];
}

GDExtensionCallError error;

auto *vcall = vp->toVariantPtr(emu);
Variant ret;
vcall->callp("call", argptrs.data(), args_size, ret, error);
vret->set(emu, ret);
if (vp->type == Variant::CALLABLE) {
std::array<Variant, 8> vargs;
std::array<const Variant *, 8> argptrs;
for (size_t i = 0; i < args_size; i++) {
vargs[i] = args[i].toVariant(emu);
argptrs[i] = &vargs[i];
}

auto *vcall = vp->toVariantPtr(emu);
Variant ret;
vcall->callp(String::utf8(method.data(), method.size()), argptrs.data(), args_size, ret, error);
vret->set(emu, ret);
} else if (vp->type == Variant::OBJECT) {
auto *obj = reinterpret_cast<godot::Object *>(uintptr_t(vp->v.i));
if (!emu.is_scoped_object(obj)) {
ERR_PRINT("Object is not scoped");
throw std::runtime_error("Object is not scoped");
}

Array vargs;
vargs.resize(args_size);
for (unsigned i = 0; i < args_size; i++) {
vargs[i] = args[i].toVariant(emu);
}
Variant ret = obj->callv(String::utf8(method.data(), method.size()), vargs);
vret->set(emu, ret);
} else {
ERR_PRINT("Invalid Variant type for Object::call");
}
}

APICALL(api_veval) {
Expand Down

0 comments on commit 93b9b06

Please sign in to comment.