Skip to content

Commit

Permalink
Implement String copy to guest std::string, fix Dictionary string bug
Browse files Browse the repository at this point in the history
  • Loading branch information
fwsGonzo committed Sep 5, 2024
1 parent 123ceb1 commit 8ffc9de
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 1 deletion.
6 changes: 6 additions & 0 deletions program/cpp/api/string.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,9 @@ String &String::operator=(String &&other) {
m_idx = other.m_idx;
return *this;
}

String::operator std::string() const {
std::string str;
sys_string_ops(String_Op::TO_STD_STRING, m_idx, 0, (Variant *)&str);
return str;
}
8 changes: 8 additions & 0 deletions program/cpp/api/string.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ struct String {
String operator[](int idx) const;
String at(int idx) const { return (*this)[idx]; }

operator std::string() const;

// String size
int size() const;

Expand All @@ -48,10 +50,16 @@ inline Variant::Variant(const String &s) {
}

inline Variant::operator String() const {
if (m_type != STRING) {
api_throw("std::bad_cast", "Failed to cast Variant to String", this);
}
return String::from_variant_index(v.i);
}

inline String Variant::as_string() const {
if (m_type != STRING) {
api_throw("std::bad_cast", "Failed to cast Variant to String", this);
}
return String::from_variant_index(v.i);
}

Expand Down
1 change: 1 addition & 0 deletions program/cpp/api/syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,4 +146,5 @@ enum class String_Op {
INSERT,
FIND,
ERASE,
TO_STD_STRING,
};
14 changes: 13 additions & 1 deletion src/syscalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,16 @@ APICALL(api_print) {
auto [array, len] = machine.sysargs<gaddr_t, gaddr_t>();
auto &emu = riscv::emu(machine);

if (len >= 64) {
ERR_PRINT("print(): Too many Variants to print");
throw std::runtime_error("print(): Too many Variants to print");
}
const GuestVariant *array_ptr = emu.machine().memory.memarray<GuestVariant>(array, len);

// We really want print_internal to be a public function.
for (gaddr_t i = 0; i < len; i++) {
auto &var = array_ptr[i];
//printf("Variant[%lu]: type=%d\n", i, var.type);
UtilityFunctions::print(var.toVariant(emu));
}
}
Expand Down Expand Up @@ -793,7 +798,7 @@ APICALL(api_dict_ops) {
auto *vp = emu.machine().memory.memarray<GuestVariant>(vaddr, 1);
// TODO: Check if the value is already scoped?
auto v = dict[key->toVariant(emu)];
vp->set(emu, v, true); // Implicit trust, as we are returning engine-provided result.
vp->create(emu, std::move(v));
break;
}
case Dictionary_Op::SET: {
Expand Down Expand Up @@ -859,6 +864,13 @@ APICALL(api_string_ops) {
case String_Op::GET_LENGTH:
machine.set_result(str.length());
break;
case String_Op::TO_STD_STRING: {
// Get the string as a std::string.
auto utf8 = str.utf8();
auto *gstr = emu.machine().memory.memarray<GuestStdString>(vaddr, 1);
gstr->set_string(emu.machine(), vaddr, utf8.ptr(), utf8.length());
break;
}
default:
ERR_PRINT("Invalid String operation");
throw std::runtime_error("Invalid String operation");
Expand Down

0 comments on commit 8ffc9de

Please sign in to comment.