Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion include/proxy-wasm/wasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,8 @@ inline bool WasmBase::copyToPointerSize(std::string_view s, uint64_t ptr_ptr, ui
}

template <typename T> inline bool WasmBase::setDatatype(uint64_t ptr, const T &t) {
return wasm_vm_->setMemory(ptr, sizeof(T), &t);
T value = htowasm(t, wasm_vm_->usesWasmByteOrder());
return wasm_vm_->setMemory(ptr, sizeof(T), &value);
}

} // namespace proxy_wasm
11 changes: 11 additions & 0 deletions test/endianness_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ class EndiannessContext : public TestContext {
// opposed to output parameter.
return static_cast<WasmResult>(3333333333U);
}
uint32_t getLogLevel() override {
// Asymmetric byte pattern to catch host-endian writes via setDatatype.
return 0x02000001U;
}
};

class EndiannessWasm : public TestWasm {
Expand Down Expand Up @@ -149,6 +153,13 @@ TEST_P(EndiannessTest, WasmCallReadsBufferPassedByHost) {
ASSERT_TRUE(test_buffer_from_host(context_)) << context_->getLog();
}

TEST_P(EndiannessTest, HostCallSetDatatype) {
WasmCallWord<0> test_host_set_datatype;
wasm_->wasm_vm()->getFunction("test_host_set_datatype", &test_host_set_datatype);

EXPECT_TRUE(test_host_set_datatype(context_)) << context_->getLog();
}

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EndiannessTest);

} // namespace
Expand Down
22 changes: 21 additions & 1 deletion test/test_data/endianness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub extern "C" fn _initialize() {
}

#[no_mangle]
pub extern "C" fn proxy_abi_version_0_2_0() {}
pub extern "C" fn proxy_abi_version_0_2_1() {}

#[no_mangle]
pub extern "C" fn proxy_on_memory_allocate(size: usize) -> *mut u8 {
Expand Down Expand Up @@ -177,3 +177,23 @@ pub extern "C" fn test_buffer_from_host() -> bool {
}
}
}

extern "C" {
// proxy_get_log_level writes the host log level to Wasm memory via setDatatype.
fn proxy_get_log_level(return_level: *mut u32) -> u32;
}

#[no_mangle]
pub extern "C" fn test_host_set_datatype() -> u32 {
let mut level: u32 = 0;
unsafe {
let status = proxy_get_log_level(&mut level);
if status != 0 {
panic!("unexpected status: {}", status);
}
if level != 0x02000001 {
panic!("unexpected level: {}", level);
}
}
return 1;
}
25 changes: 25 additions & 0 deletions test/wasm_vm_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,31 @@ TEST_P(TestVm, Memory) {
ASSERT_EQ(200, static_cast<int32_t>(word.u64_));
}

TEST_P(TestVm, SetDatatypeWritesLittleEndian) {
if (engine_ == "null") {
// NullVm stores host-endian values in memory.
return;
}
auto source = readTestWasmFile("abi_export.wasm");
ASSERT_FALSE(source.empty());
auto local_vm = makeVm(engine_);
TestWasm wasm(std::move(local_vm));
ASSERT_TRUE(wasm.load(source, false));
ASSERT_TRUE(wasm.initialize());

const uint64_t ptr = 0x1000;
const uint32_t value = 0x02000001U;

ASSERT_TRUE(wasm.setDatatype(ptr, value));

auto mem = wasm.wasm_vm()->getMemory(ptr, sizeof(uint32_t));
ASSERT_TRUE(mem.has_value());
EXPECT_EQ(static_cast<uint8_t>(mem->data()[0]), 0x01U);
EXPECT_EQ(static_cast<uint8_t>(mem->data()[1]), 0x00U);
EXPECT_EQ(static_cast<uint8_t>(mem->data()[2]), 0x00U);
EXPECT_EQ(static_cast<uint8_t>(mem->data()[3]), 0x02U);
}

TEST_P(TestVm, Clone) {
if (vm_->cloneable() == proxy_wasm::Cloneable::NotCloneable) {
return;
Expand Down
Loading