-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
406 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
//! Library for allocating memory | ||
//! Inspired from: https://doc.rust-lang.org/std/alloc/index.html | ||
library alloc; | ||
|
||
use ::intrinsics::*; | ||
|
||
/// Allocates zeroed memory on the heap | ||
/// | ||
/// In FuelVM, the heap begins at `VM_MAX_RAM - 1` and grows downward. | ||
/// Heap pointer `$hp` will always point to unallocated space. | ||
/// | ||
/// Initially the heap will look like this: | ||
/// ... 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | | ||
/// $hp^ ^VM_MAX_RAM | ||
/// | ||
/// After allocating with `let ptr = alloc(8)`: | ||
/// ... 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | | ||
/// $hp^ ^ptr ^VM_MAX_RAM | ||
/// | ||
/// After writing with `sw(ptr, u64::max())`: | ||
/// ... 00 00 00 00 00 00 00 00 FF FF FF FF FF FF FF FF | | ||
/// $hp^ ^ptr ^VM_MAX_RAM | ||
/// | ||
/// See: https://github.com/FuelLabs/fuel-specs/blob/master/specs/vm/main.md#vm-initialization | ||
/// See: https://github.com/FuelLabs/fuel-specs/blob/master/specs/vm/opcodes.md#aloc-allocate-memory | ||
pub fn alloc(size: u64) -> u64 { | ||
asm(size: size, ptr) { | ||
aloc size; | ||
// `$hp` points to unallocated space and heap grows downward so | ||
// our newly allocated space will be right after it | ||
addi ptr hp i1; | ||
ptr: u64 | ||
} | ||
} | ||
|
||
/// Reallocates the given area of memory | ||
pub fn realloc(ptr: u64, size: u64, new_size: u64) -> u64 { | ||
if new_size > size { | ||
let new_ptr = alloc(new_size); | ||
copy(new_ptr, ptr, size); | ||
new_ptr | ||
} else { | ||
ptr | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
//! Library for working with addresses in memory | ||
//! Inspired from: https://doc.rust-lang.org/std/primitive.pointer.html | ||
//! Inspired from: https://doc.rust-lang.org/std/ptr/index.html | ||
library ptr; | ||
|
||
use ::assert::*; | ||
use ::intrinsics::*; | ||
|
||
/// A point in memory with unknown type | ||
pub struct RawPointer { | ||
addr: u64, | ||
} | ||
|
||
impl RawPointer { | ||
pub fn new(addr: u64) -> Self { | ||
RawPointer { | ||
addr: addr, | ||
} | ||
} | ||
|
||
/// Creates a new pointer to the given reference-type value | ||
pub fn from<T>(val: T) -> Self { | ||
assert(is_reference_type::<T>()); | ||
RawPointer { | ||
addr: addr_of(val), | ||
} | ||
} | ||
|
||
pub fn addr(self) -> u64 { | ||
self.addr | ||
} | ||
|
||
/// Creates a new pointer with the given offset added to the current address | ||
pub fn add(self, offset: u64) -> Self { | ||
RawPointer { | ||
addr: self.addr + offset, | ||
} | ||
} | ||
|
||
/// Creates a new pointer with the given offset subtracted from the current address | ||
pub fn sub(self, offset: u64) -> Self { | ||
RawPointer { | ||
addr: self.addr - offset, | ||
} | ||
} | ||
|
||
/// Reads the given type of value from the pointer's address | ||
pub fn read<T>(self) -> T { | ||
if is_reference_type::<T>() { | ||
asm(r1: self.addr) { | ||
r1: T | ||
} | ||
} else { | ||
asm(r1: self.addr) { | ||
lw r1 r1 i0; | ||
r1: T | ||
} | ||
} | ||
} | ||
|
||
/// Writes the given value to the pointer's address | ||
pub fn write<T>(self, val: T) { | ||
if is_reference_type::<T>() { | ||
copy(self.addr, addr_of(val), size_of::<T>()); | ||
} else { | ||
asm(ptr: self.addr, val: val) { | ||
sw ptr val i0; | ||
}; | ||
} | ||
} | ||
|
||
/// Copies the data at the given pointer to the pointer's address | ||
pub fn copy_from(self, src: Self, len: u64) { | ||
copy(self.addr, src.addr, len); | ||
} | ||
|
||
/// Copies the data at the pointer's address to the given pointer | ||
pub fn copy_to(self, dst: Self, len: u64) { | ||
copy(dst.addr, self.addr, len); | ||
} | ||
|
||
// Non-generic aliases to workaround generics bugs | ||
// See: https://github.com/FuelLabs/sway/issues/1628 | ||
pub fn read_bool(self) -> bool { | ||
asm(r1: self.addr) { | ||
lw r1 r1 i0; | ||
r1: bool | ||
} | ||
} | ||
pub fn read_u64(self) -> u64 { | ||
asm(r1: self.addr) { | ||
lw r1 r1 i0; | ||
r1: u64 | ||
} | ||
} | ||
pub fn write_bool(self, val: bool) { | ||
asm(ptr: self.addr, val: val) { | ||
sw ptr val i0; | ||
}; | ||
} | ||
pub fn write_u64(self, val: u64) { | ||
asm(ptr: self.addr, val: val) { | ||
sw ptr val i0; | ||
}; | ||
} | ||
} | ||
|
||
impl core::ops::Eq for RawPointer { | ||
fn eq(self, other: Self) -> bool { | ||
self.addr == other.addr | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 11 additions & 0 deletions
11
test/src/e2e_vm_tests/test_programs/should_pass/stdlib/alloc/Forc.lock
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
[[package]] | ||
name = 'core' | ||
dependencies = [] | ||
|
||
[[package]] | ||
name = 'std' | ||
dependencies = ['core'] | ||
|
||
[[package]] | ||
name = 'std_alloc_test' | ||
dependencies = ['std'] |
8 changes: 8 additions & 0 deletions
8
test/src/e2e_vm_tests/test_programs/should_pass/stdlib/alloc/Forc.toml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
[project] | ||
authors = ["Fuel Labs <[email protected]>"] | ||
entry = "main.sw" | ||
license = "Apache-2.0" | ||
name = "std_alloc_test" | ||
|
||
[dependencies] | ||
std = { path = "../../../../../../../sway-lib-std" } |
47 changes: 47 additions & 0 deletions
47
test/src/e2e_vm_tests/test_programs/should_pass/stdlib/alloc/src/main.sw
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
script; | ||
|
||
use core::num::*; | ||
use std::alloc::*; | ||
use std::intrinsics::*; | ||
use std::context::registers::*; | ||
use std::assert::assert; | ||
|
||
fn lw(ptr: u64) -> u64 { | ||
asm(r1: ptr) { | ||
lw r1 r1 i0; | ||
r1: u64 | ||
} | ||
} | ||
|
||
fn sw(ptr: u64, val: u64) { | ||
asm(r1: ptr, val: val) { | ||
sw r1 val i0; | ||
}; | ||
} | ||
|
||
fn main() -> bool { | ||
let hp_start = heap_ptr(); | ||
|
||
// Allocate some memory | ||
let hp = heap_ptr(); | ||
let ptr = alloc(8); | ||
assert(ptr == hp - 8 + 1); | ||
assert(heap_ptr() == hp - 8); | ||
|
||
// Read from it | ||
let val = lw(ptr); | ||
assert(val == 0); | ||
|
||
// Write to it | ||
let val = ~u64::max(); | ||
sw(ptr, val); | ||
assert(lw(ptr) == val); | ||
|
||
// Grow it | ||
let hp = heap_ptr(); | ||
let ptr = realloc(ptr, 8, 16); | ||
assert(ptr == hp - 16 + 1); | ||
assert(heap_ptr() == hp - 16); | ||
|
||
true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 11 additions & 0 deletions
11
test/src/e2e_vm_tests/test_programs/should_pass/stdlib/ptr/Forc.lock
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
[[package]] | ||
name = 'core' | ||
dependencies = [] | ||
|
||
[[package]] | ||
name = 'std' | ||
dependencies = ['core'] | ||
|
||
[[package]] | ||
name = 'std_ptr_test' | ||
dependencies = ['std'] |
8 changes: 8 additions & 0 deletions
8
test/src/e2e_vm_tests/test_programs/should_pass/stdlib/ptr/Forc.toml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
[project] | ||
authors = ["Fuel Labs <[email protected]>"] | ||
entry = "main.sw" | ||
license = "Apache-2.0" | ||
name = "std_ptr_test" | ||
|
||
[dependencies] | ||
std = { path = "../../../../../../../sway-lib-std" } |
Oops, something went wrong.