Commit dc4af29c authored by nagayama15's avatar nagayama15

🚧 Change the return value of the visitor

parent d428484f
...@@ -45,175 +45,232 @@ namespace kyut::watermarker { ...@@ -45,175 +45,232 @@ namespace kyut::watermarker {
EXPR_TYPE(MemoryCopy) \ EXPR_TYPE(MemoryCopy) \
EXPR_TYPE(MemoryFill) EXPR_TYPE(MemoryFill)
enum class SideEffect : std::uint32_t {
none = 0,
readOnly = 1,
write = 2,
};
// Watermark embedder // Watermark embedder
std::size_t embedExpression(wasm::Expression *expr, CircularBitStreamReader &stream); SideEffect embedExpression(wasm::Expression *expr, CircularBitStreamReader &stream);
std::size_t embedExpressionList(const wasm::ExpressionList &exprs, CircularBitStreamReader &stream) { SideEffect embedExpressionList(const wasm::ExpressionList &exprs, CircularBitStreamReader &stream) {
std::size_t numBits = 0; auto effect = SideEffect::none;
for (const auto expr : exprs) { for (const auto expr : exprs) {
numBits += embedExpression(expr, stream); effect = (std::max)(embedExpression(expr, stream), effect);
} }
return numBits; return effect;
} }
std::size_t embedBlock(wasm::Block &expr, CircularBitStreamReader &stream) { SideEffect embedBlock(wasm::Block &expr, CircularBitStreamReader &stream) {
return embedExpressionList(expr.list, stream); return embedExpressionList(expr.list, stream);
} }
std::size_t embedIf(wasm::If &expr, CircularBitStreamReader &stream) { SideEffect embedIf(wasm::If &expr, CircularBitStreamReader &stream) {
return embedExpression(expr.condition, stream) + embedExpression(expr.ifTrue, stream) + return (std::max)({
embedExpression(expr.ifFalse, stream); embedExpression(expr.condition, stream),
embedExpression(expr.ifTrue, stream),
embedExpression(expr.ifFalse, stream),
});
} }
std::size_t embedLoop(wasm::Loop &expr, CircularBitStreamReader &stream) { SideEffect embedLoop(wasm::Loop &expr, CircularBitStreamReader &stream) {
return embedExpression(expr.body, stream); return embedExpression(expr.body, stream);
} }
std::size_t embedBreak(wasm::Break &expr, CircularBitStreamReader &stream) { SideEffect embedBreak(wasm::Break &expr, CircularBitStreamReader &stream) {
return embedExpression(expr.value, stream) + embedExpression(expr.condition, stream); embedExpression(expr.value, stream);
embedExpression(expr.condition, stream);
return SideEffect::write;
} }
std::size_t embedSwitch(wasm::Switch &expr, CircularBitStreamReader &stream) { SideEffect embedSwitch(wasm::Switch &expr, CircularBitStreamReader &stream) {
return embedExpression(expr.condition, stream) + embedExpression(expr.value, stream); return (std::max)(embedExpression(expr.condition, stream), embedExpression(expr.value, stream));
} }
std::size_t embedCall(wasm::Call &expr, CircularBitStreamReader &stream) { SideEffect embedCall(wasm::Call &expr, CircularBitStreamReader &stream) {
return embedExpressionList(expr.operands, stream); embedExpressionList(expr.operands, stream);
// It is difficult to estimate the side effects of the function calls
return SideEffect::write;
} }
std::size_t embedCallIndirect(wasm::CallIndirect &expr, CircularBitStreamReader &stream) { SideEffect embedCallIndirect(wasm::CallIndirect &expr, CircularBitStreamReader &stream) {
return embedExpression(expr.target, stream) + embedExpressionList(expr.operands, stream); embedExpression(expr.target, stream);
embedExpressionList(expr.operands, stream);
// It is difficult to estimate the side effects of the function calls
return SideEffect::write;
} }
std::size_t embedGetLocal([[maybe_unused]] wasm::GetLocal &expr, SideEffect embedGetLocal([[maybe_unused]] wasm::GetLocal &expr,
[[maybe_unused]] CircularBitStreamReader &stream) { [[maybe_unused]] CircularBitStreamReader &stream) {
return 0; return SideEffect::readOnly;
} }
std::size_t embedSetLocal(wasm::SetLocal &expr, CircularBitStreamReader &stream) { SideEffect embedSetLocal(wasm::SetLocal &expr, CircularBitStreamReader &stream) {
return embedExpression(expr.value, stream); embedExpression(expr.value, stream);
return SideEffect::write;
} }
std::size_t embedGetGlobal([[maybe_unused]] wasm::GetGlobal &expr, SideEffect embedGetGlobal([[maybe_unused]] wasm::GetGlobal &expr,
[[maybe_unused]] CircularBitStreamReader &stream) { [[maybe_unused]] CircularBitStreamReader &stream) {
return 0; return SideEffect::readOnly;
} }
std::size_t embedSetGlobal(wasm::SetGlobal &expr, CircularBitStreamReader &stream) { SideEffect embedSetGlobal(wasm::SetGlobal &expr, CircularBitStreamReader &stream) {
return embedExpression(expr.value, stream); embedExpression(expr.value, stream);
return SideEffect::write;
} }
std::size_t embedLoad(wasm::Load &expr, CircularBitStreamReader &stream) { SideEffect embedLoad(wasm::Load &expr, CircularBitStreamReader &stream) {
return embedExpression(expr.ptr, stream); return (std::max)(embedExpression(expr.ptr, stream), SideEffect::readOnly);
} }
std::size_t embedStore(wasm::Store &expr, CircularBitStreamReader &stream) { SideEffect embedStore(wasm::Store &expr, CircularBitStreamReader &stream) {
return embedExpression(expr.ptr, stream) + embedExpression(expr.value, stream); embedExpression(expr.ptr, stream);
embedExpression(expr.value, stream);
return SideEffect::write;
} }
std::size_t embedConst([[maybe_unused]] wasm::Const &expr, [[maybe_unused]] CircularBitStreamReader &stream) { SideEffect embedConst([[maybe_unused]] wasm::Const &expr, [[maybe_unused]] CircularBitStreamReader &stream) {
return 0; return SideEffect::none;
} }
std::size_t embedUnary(wasm::Unary &expr, CircularBitStreamReader &stream) { SideEffect embedUnary(wasm::Unary &expr, CircularBitStreamReader &stream) {
return embedExpression(expr.value, stream); return embedExpression(expr.value, stream);
} }
std::size_t embedBinary(wasm::Binary &expr, CircularBitStreamReader &stream) { SideEffect embedBinary(wasm::Binary &expr, CircularBitStreamReader &stream) {
// TODO: implement watermarking // TODO: implement watermarking
return embedExpression(expr.left, stream) + embedExpression(expr.right, stream); return (std::max)(embedExpression(expr.left, stream), embedExpression(expr.right, stream));
} }
std::size_t embedSelect(wasm::Select &expr, CircularBitStreamReader &stream) { SideEffect embedSelect(wasm::Select &expr, CircularBitStreamReader &stream) {
return embedExpression(expr.condition, stream) + embedExpression(expr.ifTrue, stream) + return (std::max)({
embedExpression(expr.ifFalse, stream); embedExpression(expr.condition, stream),
embedExpression(expr.ifTrue, stream),
embedExpression(expr.ifFalse, stream),
});
} }
std::size_t embedDrop(wasm::Drop &expr, CircularBitStreamReader &stream) { SideEffect embedDrop(wasm::Drop &expr, CircularBitStreamReader &stream) {
return embedExpression(expr.value, stream); return embedExpression(expr.value, stream);
} }
std::size_t embedReturn(wasm::Return &expr, CircularBitStreamReader &stream) { SideEffect embedReturn(wasm::Return &expr, CircularBitStreamReader &stream) {
return embedExpression(expr.value, stream); embedExpression(expr.value, stream);
return SideEffect::write;
} }
std::size_t embedHost(wasm::Host &expr, CircularBitStreamReader &stream) { SideEffect embedHost(wasm::Host &expr, CircularBitStreamReader &stream) {
return embedExpressionList(expr.operands, stream); embedExpressionList(expr.operands, stream);
return SideEffect::write;
} }
std::size_t embedNop([[maybe_unused]] wasm::Nop &expr, [[maybe_unused]] CircularBitStreamReader &stream) { SideEffect embedNop([[maybe_unused]] wasm::Nop &expr, [[maybe_unused]] CircularBitStreamReader &stream) {
return 0; return SideEffect::none;
} }
std::size_t embedUnreachable([[maybe_unused]] wasm::Unreachable &expr, SideEffect embedUnreachable([[maybe_unused]] wasm::Unreachable &expr,
[[maybe_unused]] CircularBitStreamReader &stream) { [[maybe_unused]] CircularBitStreamReader &stream) {
return 0; return SideEffect::write;
} }
std::size_t embedAtomicRMW(wasm::AtomicRMW &expr, CircularBitStreamReader &stream) { SideEffect embedAtomicRMW(wasm::AtomicRMW &expr, CircularBitStreamReader &stream) {
return embedExpression(expr.ptr, stream) + embedExpression(expr.value, stream); embedExpression(expr.ptr, stream);
embedExpression(expr.value, stream);
return SideEffect::write;
} }
std::size_t embedAtomicCmpxchg(wasm::AtomicCmpxchg &expr, CircularBitStreamReader &stream) { SideEffect embedAtomicCmpxchg(wasm::AtomicCmpxchg &expr, CircularBitStreamReader &stream) {
return embedExpression(expr.ptr, stream) + embedExpression(expr.expected, stream) + embedExpression(expr.ptr, stream);
embedExpression(expr.expected, stream);
embedExpression(expr.replacement, stream); embedExpression(expr.replacement, stream);
return SideEffect::write;
} }
std::size_t embedAtomicWait(wasm::AtomicWait &expr, CircularBitStreamReader &stream) { SideEffect embedAtomicWait(wasm::AtomicWait &expr, CircularBitStreamReader &stream) {
return embedExpression(expr.ptr, stream) + embedExpression(expr.expected, stream) + embedExpression(expr.ptr, stream);
embedExpression(expr.expected, stream);
embedExpression(expr.timeout, stream); embedExpression(expr.timeout, stream);
return SideEffect::write;
} }
std::size_t embedAtomicNotify(wasm::AtomicNotify &expr, CircularBitStreamReader &stream) { SideEffect embedAtomicNotify(wasm::AtomicNotify &expr, CircularBitStreamReader &stream) {
return embedExpression(expr.ptr, stream) + embedExpression(expr.notifyCount, stream); embedExpression(expr.ptr, stream);
embedExpression(expr.notifyCount, stream);
return SideEffect::write;
} }
std::size_t embedSIMDExtract(wasm::SIMDExtract &expr, CircularBitStreamReader &stream) { SideEffect embedSIMDExtract(wasm::SIMDExtract &expr, CircularBitStreamReader &stream) {
return embedExpression(expr.vec, stream); return embedExpression(expr.vec, stream);
} }
std::size_t embedSIMDReplace(wasm::SIMDReplace &expr, CircularBitStreamReader &stream) { SideEffect embedSIMDReplace(wasm::SIMDReplace &expr, CircularBitStreamReader &stream) {
return embedExpression(expr.vec, stream) + embedExpression(expr.value, stream); return (std::max)(embedExpression(expr.vec, stream), embedExpression(expr.value, stream));
} }
std::size_t embedSIMDShuffle(wasm::SIMDShuffle &expr, CircularBitStreamReader &stream) { SideEffect embedSIMDShuffle(wasm::SIMDShuffle &expr, CircularBitStreamReader &stream) {
return embedExpression(expr.left, stream) + embedExpression(expr.right, stream); return (std::max)(embedExpression(expr.left, stream), embedExpression(expr.right, stream));
} }
std::size_t embedSIMDBitselect(wasm::SIMDBitselect &expr, CircularBitStreamReader &stream) { SideEffect embedSIMDBitselect(wasm::SIMDBitselect &expr, CircularBitStreamReader &stream) {
return embedExpression(expr.cond, stream) + embedExpression(expr.left, stream) + return (std::max)({
embedExpression(expr.right, stream); embedExpression(expr.cond, stream),
embedExpression(expr.left, stream),
embedExpression(expr.right, stream),
});
} }
std::size_t embedSIMDShift(wasm::SIMDShift &expr, CircularBitStreamReader &stream) { SideEffect embedSIMDShift(wasm::SIMDShift &expr, CircularBitStreamReader &stream) {
return embedExpression(expr.vec, stream) + embedExpression(expr.shift, stream); return (std::max)(embedExpression(expr.vec, stream), embedExpression(expr.shift, stream));
} }
std::size_t embedMemoryInit(wasm::MemoryInit &expr, CircularBitStreamReader &stream) { SideEffect embedMemoryInit(wasm::MemoryInit &expr, CircularBitStreamReader &stream) {
return embedExpression(expr.dest, stream) + embedExpression(expr.offset, stream) + embedExpression(expr.dest, stream);
embedExpression(expr.offset, stream);
embedExpression(expr.size, stream); embedExpression(expr.size, stream);
return SideEffect::write;
} }
std::size_t embedDataDrop([[maybe_unused]] wasm::DataDrop &expr, SideEffect embedDataDrop([[maybe_unused]] wasm::DataDrop &expr,
[[maybe_unused]] CircularBitStreamReader &stream) { [[maybe_unused]] CircularBitStreamReader &stream) {
return 0; return SideEffect::write;
} }
std::size_t embedMemoryCopy(wasm::MemoryCopy &expr, CircularBitStreamReader &stream) { SideEffect embedMemoryCopy(wasm::MemoryCopy &expr, CircularBitStreamReader &stream) {
return embedExpression(expr.dest, stream) + embedExpression(expr.source, stream) + embedExpression(expr.dest, stream);
embedExpression(expr.source, stream);
embedExpression(expr.size, stream); embedExpression(expr.size, stream);
return SideEffect::write;
} }
std::size_t embedMemoryFill(wasm::MemoryFill &expr, CircularBitStreamReader &stream) { SideEffect embedMemoryFill(wasm::MemoryFill &expr, CircularBitStreamReader &stream) {
return embedExpression(expr.dest, stream) + embedExpression(expr.value, stream) + embedExpression(expr.dest, stream);
embedExpression(expr.value, stream);
embedExpression(expr.size, stream); embedExpression(expr.size, stream);
return SideEffect::write;
} }
std::size_t embedExpression(wasm::Expression *expr, CircularBitStreamReader &stream) { SideEffect embedExpression(wasm::Expression *expr, CircularBitStreamReader &stream) {
if (expr == nullptr) { if (expr == nullptr) {
return 0; return SideEffect::none;
} }
switch (expr->_id) { switch (expr->_id) {
...@@ -228,8 +285,8 @@ namespace kyut::watermarker { ...@@ -228,8 +285,8 @@ namespace kyut::watermarker {
} }
} }
std::size_t embedFunction(wasm::Function &function, CircularBitStreamReader &stream) { void embedFunction(wasm::Function &function, CircularBitStreamReader &stream) {
return embedExpression(function.body, stream); embedExpression(function.body, stream);
} }
} // namespace } // namespace
...@@ -246,20 +303,20 @@ namespace kyut::watermarker { ...@@ -246,20 +303,20 @@ namespace kyut::watermarker {
std::sort( std::sort(
std::begin(functions), std::end(functions), [](const auto a, const auto b) { return a->name < b->name; }); std::begin(functions), std::end(functions), [](const auto a, const auto b) { return a->name < b->name; });
// Number of bits embedded in the module
std::size_t numBits = 0;
// Embed watermarks // Embed watermarks
std::size_t posStart = stream.tell();
for (const auto f : functions) { for (const auto f : functions) {
numBits += embedFunction(*f, stream); embedFunction(*f, stream);
} }
return numBits; return stream.tell() - posStart;
} }
std::size_t extractOperandSwapping(wasm::Module &module, BitStreamWriter &stream) { std::size_t extractOperandSwapping(wasm::Module &module, BitStreamWriter &stream) {
(void)module; (void)module;
(void)stream; (void)stream;
return 0;
WASM_UNREACHABLE();
} }
} // namespace kyut::watermarker } // namespace kyut::watermarker
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment