diff options
author | Sam Atkins <atkinssj@serenityos.org> | 2023-01-28 15:24:04 +0000 |
---|---|---|
committer | Ali Mohammad Pur <Ali.mpfard@gmail.com> | 2023-01-28 22:57:25 +0330 |
commit | 330911a2742e7e91060083d84e885de1d141b7ae (patch) | |
tree | b6a0b39b836923bac5eef1da49198e2acd2a7a43 /Userland/Libraries | |
parent | 42adba5ad44ad34ac17ec7a6bea48164784f2de4 (diff) | |
download | serenity-330911a2742e7e91060083d84e885de1d141b7ae.zip |
LibWasm: Implement memory.copy instruction
Diffstat (limited to 'Userland/Libraries')
-rw-r--r-- | Userland/Libraries/LibWasm/AbstractMachine/BytecodeInterpreter.cpp | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/Userland/Libraries/LibWasm/AbstractMachine/BytecodeInterpreter.cpp b/Userland/Libraries/LibWasm/AbstractMachine/BytecodeInterpreter.cpp index 46cf447d46..0b956e8b1b 100644 --- a/Userland/Libraries/LibWasm/AbstractMachine/BytecodeInterpreter.cpp +++ b/Userland/Libraries/LibWasm/AbstractMachine/BytecodeInterpreter.cpp @@ -639,6 +639,39 @@ void BytecodeInterpreter::interpret(Configuration& configuration, InstructionPoi } return; } + // https://webassembly.github.io/spec/core/bikeshed/#exec-memory-copy + case Instructions::memory_copy.value(): { + auto address = configuration.frame().module().memories()[0]; + auto instance = configuration.store().get(address); + auto count = configuration.stack().pop().get<Value>().to<i32>().value(); + auto source_offset = configuration.stack().pop().get<Value>().to<i32>().value(); + auto destination_offset = configuration.stack().pop().get<Value>().to<i32>().value(); + + TRAP_IF_NOT(static_cast<size_t>(source_offset + count) <= instance->data().size()); + TRAP_IF_NOT(static_cast<size_t>(destination_offset + count) <= instance->data().size()); + + if (count == 0) + return; + + Instruction synthetic_store_instruction { + Instructions::i32_store8, + Instruction::MemoryArgument { 0, 0 } + }; + + if (destination_offset <= source_offset) { + for (auto i = 0; i < count; ++i) { + auto value = instance->data()[source_offset + i]; + store_to_memory(configuration, synthetic_store_instruction, { &value, sizeof(value) }, destination_offset + i); + } + } else { + for (auto i = count - 1; i >= 0; --i) { + auto value = instance->data()[source_offset + i]; + store_to_memory(configuration, synthetic_store_instruction, { &value, sizeof(value) }, destination_offset + i); + } + } + + return; + } case Instructions::table_get.value(): case Instructions::table_set.value(): goto unimplemented; @@ -973,7 +1006,6 @@ void BytecodeInterpreter::interpret(Configuration& configuration, InstructionPoi return; } case Instructions::data_drop.value(): - case Instructions::memory_copy.value(): case Instructions::table_init.value(): case Instructions::elem_drop.value(): case Instructions::table_copy.value(): |