Skip to content

Commit 78ceb5a

Browse files
committed
Fix endianness conversions for bigendian platforms
Signed-off-by: Matt Leon <mattleon@google.com>
1 parent 77fd0ea commit 78ceb5a

3 files changed

Lines changed: 27 additions & 6 deletions

File tree

include/proxy-wasm/word.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@ namespace proxy_wasm {
2424
// Use byteswap functions only when compiling for big-endian platforms.
2525
#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \
2626
__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
27-
#define htowasm(x, vm_uses_wasm_byte_order) ((vm_uses_wasm_byte_order) ? __builtin_bswap32(x) : (x))
28-
#define wasmtoh(x, vm_uses_wasm_byte_order) ((vm_uses_wasm_byte_order) ? __builtin_bswap32(x) : (x))
27+
static inline uint32_t bswap(uint32_t x) { return __builtin_bswap32(x); }
28+
static inline auto bswap(auto x) { return __builtin_bswap64(x); }
29+
#define htowasm(x, vm_uses_wasm_byte_order) ((vm_uses_wasm_byte_order) ? bswap(x) : (x))
30+
#define wasmtoh(x, vm_uses_wasm_byte_order) ((vm_uses_wasm_byte_order) ? bswap(x) : (x))
2931
#else
3032
#define htowasm(x, vm_uses_wasm_byte_order) (x)
3133
#define wasmtoh(x, vm_uses_wasm_byte_order) (x)

src/wasmtime/wasmtime.cc

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <variant>
2525

2626
#include "include/proxy-wasm/limits.h"
27+
#include "include/proxy-wasm/word.h"
2728

2829
#include "crates/c-api/include/wasmtime.hh" // IWYU pragma: keep
2930

@@ -72,6 +73,19 @@ template <typename Arg, typename... Args> std::string printValues(Arg arg, Args.
7273
return printValue(arg) + ((", " + printValue(args)) + ... + "");
7374
}
7475

76+
template <typename... Args> void InPlaceConvertWasmToHostEndianness(Args &...args) {
77+
(void(args = wasmtoh(convertWordToUint32(args), true)), ...);
78+
}
79+
proxy_wasm::Word ConvertWasmToHostEndianness(const proxy_wasm::Word &arg) {
80+
return proxy_wasm::Word(wasmtoh(convertWordToUint32(arg), true));
81+
}
82+
template <typename... Args> void InPlaceConvertHostToWasmEndianness(Args &...args) {
83+
(void(args = htowasm(convertWordToUint32(args), true)), ...);
84+
}
85+
template <typename... Args> auto ConvertHostToWasmEndianness(const Args &...args) {
86+
return std::make_tuple((htowasm(convertWordToUint32(args), true))...);
87+
}
88+
7589
} // namespace
7690

7791
class Wasmtime : public WasmVm {
@@ -283,6 +297,7 @@ void Wasmtime::registerHostFunctionImpl(std::string_view module_name,
283297
module_name, function_name,
284298
[this, function,
285299
function_name = std::string(module_name) + "." + std::string(function_name)](Args... args) {
300+
InPlaceConvertWasmToHostEndianness(args...);
286301
const bool log = cmpLogLevel(LogLevel::trace);
287302
if (log) {
288303
integration()->trace("[vm->host] " + function_name + "(" + printValues(args...) + ")");
@@ -304,6 +319,7 @@ void Wasmtime::registerHostFunctionImpl(std::string_view module_name,
304319
module_name, function_name,
305320
[this, function,
306321
function_name = std::string(module_name) + "." + std::string(function_name)](Args... args) {
322+
InPlaceConvertWasmToHostEndianness(args...);
307323
const bool log = cmpLogLevel(LogLevel::trace);
308324
if (log) {
309325
integration()->trace("[vm->host] " + function_name + "(" + printValues(args...) + ")");
@@ -312,7 +328,7 @@ void Wasmtime::registerHostFunctionImpl(std::string_view module_name,
312328
if (log) {
313329
integration()->trace("[vm<-host] " + function_name + " return: " + printValue(result));
314330
}
315-
return result;
331+
return ConvertHostToWasmEndianness(result);
316332
});
317333
if (!result) {
318334
fail(FailState::ConfigureFailed, "Failed to register host function: " + result.err().message());
@@ -340,6 +356,7 @@ void Wasmtime::getModuleFunctionImpl(std::string_view function_name,
340356
integration()->trace("[host->vm] " + std::string(function_name) + "(" + printValues(args...) +
341357
")");
342358
}
359+
InPlaceConvertHostToWasmEndianness(args...);
343360
TrapResult<std::monostate> result = func.call(store_->context(), {args...});
344361
if (!result) {
345362
fail(FailState::RuntimeError,
@@ -372,17 +389,19 @@ void Wasmtime::getModuleFunctionImpl(std::string_view function_name,
372389
integration()->trace("[host->vm] " + std::string(function_name) + "(" + printValues(args...) +
373390
")");
374391
}
392+
InPlaceConvertHostToWasmEndianness(args...);
375393
TrapResult<R> result = func.call(store_->context(), {args...});
376394
if (!result) {
377395
fail(FailState::RuntimeError,
378396
"Function: " + std::string(function_name) + " failed: " + result.err().message());
379397
return R{};
380398
}
399+
R result_host = ConvertWasmToHostEndianness(result.ok());
381400
if (log) {
382401
integration()->trace("[host<-vm] " + std::string(function_name) +
383-
" return: " + printValue(result.unwrap()));
402+
" return: " + printValue(result_host));
384403
}
385-
return result.ok();
404+
return result_host;
386405
};
387406
};
388407

test/wasm_vm_test.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ TEST_P(TestVm, Memory) {
8585
ASSERT_EQ(100, word.u64_);
8686

8787
uint32_t data[2] = {htowasm(static_cast<uint32_t>(-1), vm_->usesWasmByteOrder()),
88-
htowasm(200, vm_->usesWasmByteOrder())};
88+
htowasm(static_cast<uint32_t>(200), vm_->usesWasmByteOrder())};
8989
ASSERT_TRUE(vm_->setMemory(0x200, sizeof(int32_t) * 2, static_cast<void *>(data)));
9090
ASSERT_TRUE(vm_->getWord(0x200, &word));
9191
ASSERT_EQ(-1, static_cast<int32_t>(word.u64_));

0 commit comments

Comments
 (0)