↑ arvau

MDN / copy: Wasm memory instruction

The memory.copy memory instruction copies data from one memory region to another.

This is analogous to memmove in C.

(module
  (memory $memory1 (export "memory") 1)
  (data $greeting (memory $memory1) (i32.const 0) "Hello ")

  (func (export "copy")
    i32.const 6      ;; destination memory offset
    i32.const 0      ;; source memory offset
    i32.const 5      ;; number of bytes to copy
    memory.copy
  )
)
WebAssembly.instantiateStreaming(fetch("{%wasm-url%}")).then((result) => {
  result.instance.exports.copy();
  const memBuffer = result.instance.exports.memory.buffer;
  const memArray = new Uint8Array(memBuffer, 0, 11);
  console.log(new TextDecoder().decode(memArray));
});

In the above example, we define an exported memory called $memory1 with a maximum size of one page. We then include:

  • A data definition that contains the string “Hello “ and immediately copies it into $memory1.

  • An exported copy() function that copies the string “Hello” starting from byte 0 in $memory1 to a region starting at byte 6 in $memory1. This results in the memory contents becoming “Hello Hello”.

In the JavaScript, we call the copy() function to update the exported memory’s contents, then decode the exported memory’s buffer and log the result to the console.

Syntax

memory.copy dest_memory source_memory
  • memory.copy

    • : The memory.copy instruction type. Must always be included first.

    dest_memory

    • : The identifier for the memory you want to copy the data into.

    source_memory

    • : The identifier for the memory you want to copy the data from.

dest_memory and source_memory can be one of the following:

  • name

    • : An identifying name set for the memory when it was first defined. This must begin with a $ symbol, for example $my_mem.

    index

    • : The memory’s index number, for example 0 for the first memory in the wasm module, 1 for the second, etc.

If dest_memory or source_memory are omitted, they default to 0.

Type

[dest_offset source_offset length] -> []
  • dest_offset

    • : An integer representing the offset to start writing the copied data to, in the destination memory. This will be an i32 or an i64, to match the address_type the memory was defined with.

    source_offset

    • : An integer representing the offset to start copying data from, in the source memory. This will be an i32 or an i64, to match the address_type the memory was defined with.

    length

    • : An integer representing the number of bytes to copy. This will be an i32 or an i64, to match the address_type the memory was defined with. When copying between a 32-bit and 64-bit memory, an i32 must be used for the length.

memory.copy copies memory regions in an overlap-aware way. In other words, the copy proceeds as if the source data identified by source_offset and length was first copied into a temporary value before being copied to dest_offset, meaning that if your source and destination data overlap, they don’t interfere with one another and the source is cleanly copied into the destination region as expected.

Traps

If any copied byte would be out of bounds in the source or destination, the instruction traps.

Binary encoding

InstructionBinary formatExample text => binarymemory.copy0xfc 10:u32 x:memidx x:memidxmemory.copy 0 0 => 0xfc 0x0a 0x00 0x00

Examples

Copy within the default (0-index) memory

;; Copy data in default memory from [100, 125] to [50, 75]
i32.const 50 ;; Destination address to copy to
i32.const 100 ;; Source address to copy from
i32.const 25 ;; Number of bytes to copy
memory.copy  ;; Copy memory

;; Copy in default memory using an S-expression
(memory.copy (i32.const 50) (i32.const 100) (i32.const 25))

Copy within a specified memory

;; Copy data within specific memory from [100, 125] to [50, 75]
i32.const 50 ;; Destination address to copy to
i32.const 100 ;; Source address to copy from
i32.const 25 ;; Number of bytes to copy
memory.copy (memory 2) (memory 2) ;; Copy memory within memory with index 2

;; Copy between memories referenced by their names
i32.const 50 ;; Destination address (in $destMem)
i32.const 100 ;; Source address (in $sourceMem)
i32.const 25 ;; Number of bytes to copy
memory.copy (memory $destMem) (memory $sourceMem) ;; Copy memory from "$sourceMem" to "$destMem"

;; Copy between memories using an S-expression
(memory.copy (memory $destMem) (memory $sourceMem) (i32.const 50) (i32.const 100) (i32.const 25))

Specifications

Browser compatibility

See also