mirror of
https://github.com/pezkuwichain/revive.git
synced 2026-05-10 01:47:58 +00:00
llvm-context: remove the linear memory pointer indirection (#211)
This commit is contained in:
@@ -6,6 +6,10 @@ This is a development pre-release.
|
||||
|
||||
Supported `polkadot-sdk` rev: `274a781e8ca1a9432c7ec87593bd93214abbff50`
|
||||
|
||||
### Fixed
|
||||
- A bug causing incorrect loads from the emulated EVM linear memory.
|
||||
- A missing integer truncate after switching to 64bit.
|
||||
|
||||
## v0.1.0-dev.10
|
||||
|
||||
This is a development pre-release.
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.8.28;
|
||||
|
||||
/* runner.json
|
||||
{
|
||||
"differential": true,
|
||||
"actions": [
|
||||
{
|
||||
"Instantiate": {
|
||||
"code": {
|
||||
"Solidity": {
|
||||
"contract": "MLoad"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Call": {
|
||||
"dest": {
|
||||
"Instantiated": 0
|
||||
},
|
||||
"data": "e2179b8e"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
*/
|
||||
|
||||
contract MLoad {
|
||||
constructor() payable {
|
||||
assert(g() == 0);
|
||||
}
|
||||
|
||||
function g() public payable returns (uint m) {
|
||||
assembly {
|
||||
m := mload(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -55,6 +55,7 @@ test_spec!(create2, "CreateB", "Create2.sol");
|
||||
test_spec!(transfer, "Transfer", "Transfer.sol");
|
||||
test_spec!(send, "Send", "Send.sol");
|
||||
test_spec!(function_pointer, "FunctionPointer", "FunctionPointer.sol");
|
||||
test_spec!(mload, "MLoad", "MLoad.sol");
|
||||
|
||||
fn instantiate(path: &str, contract: &str) -> Vec<SpecsAction> {
|
||||
vec![Instantiate {
|
||||
|
||||
@@ -6,15 +6,9 @@ pub const LLVM_VERSION: semver::Version = semver::Version::new(18, 1, 4);
|
||||
/// The pointer width sized type.
|
||||
pub static XLEN: usize = revive_common::BIT_LENGTH_X32;
|
||||
|
||||
/// The heap memory pointer pointer global variable name.
|
||||
pub static GLOBAL_HEAP_MEMORY_POINTER: &str = "memory_pointer";
|
||||
|
||||
/// The calldata size global variable name.
|
||||
pub static GLOBAL_CALLDATA_SIZE: &str = "calldatasize";
|
||||
|
||||
/// The call flags global variable name.
|
||||
pub static GLOBAL_CALL_FLAGS: &str = "call_flags";
|
||||
|
||||
/// The deployer call header size that consists of:
|
||||
/// - bytecode hash (32 bytes)
|
||||
pub const DEPLOYER_CALL_HEADER_SIZE: usize = revive_common::BYTE_LENGTH_WORD;
|
||||
|
||||
@@ -24,22 +24,6 @@ impl Entry {
|
||||
where
|
||||
D: Dependency + Clone,
|
||||
{
|
||||
context.set_global(
|
||||
crate::polkavm::GLOBAL_HEAP_MEMORY_POINTER,
|
||||
context.llvm().ptr_type(AddressSpace::Heap.into()),
|
||||
AddressSpace::Stack,
|
||||
context.xlen_type().get_undef(),
|
||||
);
|
||||
context.build_store(
|
||||
context
|
||||
.get_global(crate::polkavm::GLOBAL_HEAP_MEMORY_POINTER)?
|
||||
.into(),
|
||||
context.build_sbrk(
|
||||
context.xlen_type().const_zero(),
|
||||
context.xlen_type().const_zero(),
|
||||
)?,
|
||||
)?;
|
||||
|
||||
context.set_global(
|
||||
crate::polkavm::GLOBAL_CALLDATA_SIZE,
|
||||
context.xlen_type(),
|
||||
@@ -47,13 +31,6 @@ impl Entry {
|
||||
context.xlen_type().get_undef(),
|
||||
);
|
||||
|
||||
context.set_global(
|
||||
crate::polkavm::GLOBAL_CALL_FLAGS,
|
||||
context.word_type(),
|
||||
AddressSpace::Stack,
|
||||
context.word_const(0),
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -70,6 +47,11 @@ impl Entry {
|
||||
.build_runtime_call(revive_runtime_api::polkavm_imports::CALL_DATA_SIZE, &[])
|
||||
.expect("the call_data_size syscall method should return a value")
|
||||
.into_int_value();
|
||||
let call_data_size_value = context.builder().build_int_truncate(
|
||||
call_data_size_value,
|
||||
context.xlen_type(),
|
||||
"call_data_size_truncated",
|
||||
)?;
|
||||
context
|
||||
.builder()
|
||||
.build_store(call_data_size_pointer, call_data_size_value)?;
|
||||
@@ -90,13 +72,6 @@ impl Entry {
|
||||
.borrow()
|
||||
.get_nth_param(Self::ARGUMENT_INDEX_CALL_FLAGS);
|
||||
|
||||
context.set_global(
|
||||
crate::polkavm::GLOBAL_CALL_FLAGS,
|
||||
is_deploy.get_type(),
|
||||
AddressSpace::Stack,
|
||||
is_deploy.into_int_value(),
|
||||
);
|
||||
|
||||
let deploy_code_call_block = context.append_basic_block("deploy_code_call_block");
|
||||
let runtime_code_call_block = context.append_basic_block("runtime_code_call_block");
|
||||
|
||||
|
||||
@@ -1209,17 +1209,17 @@ where
|
||||
|
||||
/// Build a call to PolkaVM `msize` for querying the linear memory size.
|
||||
pub fn build_msize(&self) -> anyhow::Result<inkwell::values::IntValue<'ctx>> {
|
||||
Ok(self
|
||||
.builder()
|
||||
.build_call(
|
||||
self.runtime_api_method(revive_runtime_api::polkavm_imports::MEMORY_SIZE),
|
||||
&[],
|
||||
"call_msize",
|
||||
)?
|
||||
.try_as_basic_value()
|
||||
.left()
|
||||
.expect("sbrk returns an int")
|
||||
.into_int_value())
|
||||
let memory_size_pointer = self
|
||||
.module()
|
||||
.get_global(revive_runtime_api::polkavm_imports::MEMORY_SIZE)
|
||||
.expect("the memory size symbol should have been declared")
|
||||
.as_pointer_value();
|
||||
let memory_size_value = self.builder().build_load(
|
||||
self.xlen_type(),
|
||||
memory_size_pointer,
|
||||
"memory_size_value",
|
||||
)?;
|
||||
Ok(memory_size_value.into_int_value())
|
||||
}
|
||||
|
||||
/// Call PolkaVM `sbrk` for extending the heap by `offset` + `size`,
|
||||
@@ -1265,8 +1265,9 @@ where
|
||||
self.build_heap_alloc(offset, length)?;
|
||||
|
||||
let heap_start = self
|
||||
.get_global(crate::polkavm::GLOBAL_HEAP_MEMORY_POINTER)?
|
||||
.value
|
||||
.module()
|
||||
.get_global(revive_runtime_api::polkavm_imports::MEMORY)
|
||||
.expect("the memory symbol should have been declared")
|
||||
.as_pointer_value();
|
||||
Ok(self.build_gep(
|
||||
Pointer::new(self.byte_type(), AddressSpace::Stack, heap_start),
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
#define EVM_WORD_SIZE 32
|
||||
#define ALIGN(size) ((size + EVM_WORD_SIZE - 1) & ~(EVM_WORD_SIZE - 1))
|
||||
#define MAX_MEMORY_SIZE (64 * 1024)
|
||||
static char __memory[MAX_MEMORY_SIZE];
|
||||
static uint32_t __memory_size = 0;
|
||||
char __memory[MAX_MEMORY_SIZE];
|
||||
uint32_t __memory_size = 0;
|
||||
|
||||
void * __sbrk_internal(uint32_t offset, uint32_t size) {
|
||||
void * __sbrk_internal(uint32_t offset, uint32_t size) {
|
||||
if (offset >= MAX_MEMORY_SIZE || size > MAX_MEMORY_SIZE) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -27,10 +27,6 @@ void * __sbrk_internal(uint32_t offset, uint32_t size) {
|
||||
return (void *)&__memory[__memory_size];
|
||||
}
|
||||
|
||||
uint32_t __msize() {
|
||||
return __memory_size;
|
||||
}
|
||||
|
||||
void * memset(void *b, int c, size_t len) {
|
||||
uint8_t *dest = b;
|
||||
while (len-- > 0) *dest++ = c;
|
||||
|
||||
@@ -1,18 +1,14 @@
|
||||
//! This crate vendors the [PolkaVM][0] C API and provides a LLVM module for interacting
|
||||
//! with the `pallet-revive` runtime API.
|
||||
//! At present, the revive pallet requires blobs to export `call` and `deploy`,
|
||||
//! and offers a bunch of [runtime API methods][1]. The provided [module] implements
|
||||
//! those exports and imports.
|
||||
//! [0]: [https://crates.io/crates/polkavm]
|
||||
//! [1]: [https://docs.rs/pallet-contracts/26.0.0/pallet_contracts/api_doc/index.html]
|
||||
|
||||
use inkwell::{context::Context, memory_buffer::MemoryBuffer, module::Module, support::LLVMString};
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/polkavm_imports.rs"));
|
||||
|
||||
pub static SBRK: &str = "__sbrk_internal";
|
||||
/// The emulated EVM heap memory global symbol.
|
||||
pub static MEMORY: &str = "__memory";
|
||||
|
||||
pub static MEMORY_SIZE: &str = "__msize";
|
||||
/// The emulated EVM heap memory size global symbol.
|
||||
pub static MEMORY_SIZE: &str = "__memory_size";
|
||||
|
||||
pub static SBRK: &str = "__sbrk_internal";
|
||||
|
||||
pub static ADDRESS: &str = "address";
|
||||
|
||||
@@ -82,9 +78,8 @@ pub static WEIGHT_TO_FEE: &str = "weight_to_fee";
|
||||
|
||||
/// All imported runtime API symbols.
|
||||
/// Useful for configuring common attributes and linkage.
|
||||
pub static IMPORTS: [&str; 35] = [
|
||||
pub static IMPORTS: [&str; 34] = [
|
||||
SBRK,
|
||||
MEMORY_SIZE,
|
||||
ADDRESS,
|
||||
BALANCE,
|
||||
BALANCE_OF,
|
||||
|
||||
Reference in New Issue
Block a user