Skip to content

Commit

Permalink
feat(runtime): Simplify copy and fill polyfills in Memory module (
Browse files Browse the repository at this point in the history
#2148)

Co-authored-by: Oscar Spencer <[email protected]>
  • Loading branch information
spotandjake and ospencer authored Aug 17, 2024
1 parent 18b9cd2 commit 1b3a9f0
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 22 deletions.
44 changes: 24 additions & 20 deletions stdlib/runtime/unsafe/memory.gr
Original file line number Diff line number Diff line change
Expand Up @@ -4,38 +4,42 @@ module Memory
from "runtime/gc" include GC
use GC.{ malloc, free, incRef, decRef }
from "runtime/unsafe/wasmi32" include WasmI32
use WasmI32.{ (+), (-), (<<), (==), (!=), ltU as (<) }
use WasmI32.{ (+), (-), (!=), ltU as (<), gtU as (>) }

provide { malloc, free, incRef, decRef }

provide let copy = (dest, src, n) => {
let mut dest = dest
let mut src = src
let mut n = n
/**
* Copies the source memory region to the destination memory region. Regions may overlap.
*
* @param dest: The destination memory region
* @param src: The source memory region
* @param length: The length of the memory region to copy
*/
provide let copy = (dest, src, length) => {
if (dest != src) {
if (dest < src) {
while (n != 0n) {
WasmI32.store8(dest, WasmI32.load8U(src, 0n), 0n)
dest += 1n
src += 1n
n -= 1n
for (let mut i = 0n; i < length; i += 1n) {
WasmI32.store8(dest, WasmI32.load8U(src, i), i)
}
} else {
while (n != 0n) {
n -= 1n
WasmI32.store8(dest + n, WasmI32.load8U(src + n, 0n), 0n)
// Copy backwards to ensure we do not overwrite on overlapping regions
for (let mut n = length; n > 0n; n -= 1n) {
WasmI32.store8(dest + n - 1n, WasmI32.load8U(src + n - 1n, 0n), 0n)
}
}
}
}

provide let fill = (dest, c, n) => {
let mut dest = dest
let mut n = n
while (n != 0n) {
WasmI32.store8(dest, c, 0n)
dest += 1n
n -= 1n
/**
* Fills the given memory region with the given 1-byte value. Values larger than 1 byte will be truncated.
*
* @param dest: The destination memory region
* @param value: The value to fill the memory region with
* @param length: The length of the memory region to fill
*/
provide let fill = (dest, value, length) => {
for (let mut i = 0n; i < length; i += 1n) {
WasmI32.store8(dest, value, i)
}
}

Expand Down
24 changes: 22 additions & 2 deletions stdlib/runtime/unsafe/memory.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,35 @@ decRef : (userPtr: WasmI32) => WasmI32
### Memory.**copy**

```grain
copy : (dest: WasmI32, src: WasmI32, n: WasmI32) => Void
copy : (dest: WasmI32, src: WasmI32, length: WasmI32) => Void
```

Copies the source memory region to the destination memory region. Regions may overlap.

Parameters:

|param|type|description|
|-----|----|-----------|
|`dest`|`WasmI32`|The destination memory region|
|`src`|`WasmI32`|The source memory region|
|`length`|`WasmI32`|The length of the memory region to copy|

### Memory.**fill**

```grain
fill : (dest: WasmI32, c: WasmI32, n: WasmI32) => Void
fill : (dest: WasmI32, value: WasmI32, length: WasmI32) => Void
```

Fills the given memory region with the given 1-byte value. Values larger than 1 byte will be truncated.

Parameters:

|param|type|description|
|-----|----|-----------|
|`dest`|`WasmI32`|The destination memory region|
|`value`|`WasmI32`|The value to fill the memory region with|
|`length`|`WasmI32`|The length of the memory region to fill|

### Memory.**compare**

```grain
Expand Down

0 comments on commit 1b3a9f0

Please sign in to comment.