diff --git a/Cargo.lock b/Cargo.lock index 3b5f9b8..a54d86b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -16,9 +16,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] @@ -68,7 +68,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.53", "syn-solidity", "tiny-keccak", ] @@ -229,7 +229,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.53", ] [[package]] @@ -273,9 +273,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "bitvec" @@ -545,6 +545,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "env_logger" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" +dependencies = [ + "log", +] + [[package]] name = "equivalent" version = "1.0.1" @@ -852,7 +861,7 @@ source = "git+https://github.com/TheDan64/inkwell.git#69c5a3fcc3e8b997c36e20021c dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.53", ] [[package]] @@ -1154,7 +1163,7 @@ dependencies = [ [[package]] name = "polkavm" version = "0.9.3" -source = "git+https://github.com/koute/polkavm.git#e278c34af27cf2c32fc44bcbfe2b17333312eb02" +source = "git+https://github.com/koute/polkavm.git#1f74006e596bcdcc92856a14a115e285dfc3368e" dependencies = [ "libc", "log", @@ -1166,7 +1175,7 @@ dependencies = [ [[package]] name = "polkavm-assembler" version = "0.9.0" -source = "git+https://github.com/koute/polkavm.git#e278c34af27cf2c32fc44bcbfe2b17333312eb02" +source = "git+https://github.com/koute/polkavm.git#1f74006e596bcdcc92856a14a115e285dfc3368e" dependencies = [ "log", ] @@ -1174,7 +1183,7 @@ dependencies = [ [[package]] name = "polkavm-common" version = "0.9.0" -source = "git+https://github.com/koute/polkavm.git#e278c34af27cf2c32fc44bcbfe2b17333312eb02" +source = "git+https://github.com/koute/polkavm.git#1f74006e596bcdcc92856a14a115e285dfc3368e" dependencies = [ "log", ] @@ -1182,7 +1191,7 @@ dependencies = [ [[package]] name = "polkavm-linker" version = "0.9.2" -source = "git+https://github.com/koute/polkavm.git#e278c34af27cf2c32fc44bcbfe2b17333312eb02" +source = "git+https://github.com/koute/polkavm.git#1f74006e596bcdcc92856a14a115e285dfc3368e" dependencies = [ "gimli", "hashbrown 0.14.3", @@ -1196,7 +1205,7 @@ dependencies = [ [[package]] name = "polkavm-linux-raw" version = "0.9.0" -source = "git+https://github.com/koute/polkavm.git#e278c34af27cf2c32fc44bcbfe2b17333312eb02" +source = "git+https://github.com/koute/polkavm.git#1f74006e596bcdcc92856a14a115e285dfc3368e" [[package]] name = "ppv-lite86" @@ -1268,7 +1277,7 @@ checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" dependencies = [ "bit-set", "bit-vec", - "bitflags 2.4.2", + "bitflags 2.5.0", "lazy_static", "num-traits", "rand", @@ -1428,6 +1437,7 @@ version = "0.1.0" dependencies = [ "alloy-primitives", "alloy-sol-types", + "env_logger", "era-compiler-llvm-context", "hex", "parity-scale-codec", @@ -1505,9 +1515,9 @@ dependencies = [ [[package]] name = "ruint" -version = "1.12.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49b1d9521f889713d1221270fdd63370feca7e5c71a18745343402fa86e4f04f" +checksum = "8f308135fef9fc398342da5472ce7c484529df23743fb7c734e0f3d472971e62" dependencies = [ "alloy-rlp", "ark-ff 0.3.0", @@ -1571,11 +1581,11 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.31" +version = "0.38.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" +checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.5.0", "errno", "libc", "linux-raw-sys", @@ -1658,7 +1668,7 @@ checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.53", ] [[package]] @@ -1731,9 +1741,9 @@ checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "spki" @@ -1813,9 +1823,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.52" +version = "2.0.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" +checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032" dependencies = [ "proc-macro2", "quote", @@ -1831,7 +1841,7 @@ dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.53", ] [[package]] @@ -1878,7 +1888,7 @@ checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.53", ] [[package]] @@ -2184,7 +2194,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.53", ] [[package]] @@ -2204,7 +2214,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.53", ] [[package]] @@ -2212,7 +2222,7 @@ name = "zkevm_opcode_defs" version = "1.4.1" source = "git+https://github.com/matter-labs/era-zkevm_opcode_defs?branch=v1.4.1#ba8228ff0582d21f64d6a319d50d0aec48e9e7b6" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.5.0", "blake2", "ethereum-types", "k256", diff --git a/Cargo.toml b/Cargo.toml index 568b4fb..a308f6f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,6 +32,7 @@ polkavm = { git = "https://github.com/koute/polkavm.git" } parity-scale-codec = "3.6" alloy-primitives = "0.6" alloy-sol-types = "0.6" +env_logger = { version = "0.10.0", default-features = false } [workspace.dependencies.inkwell] git = "https://github.com/TheDan64/inkwell.git" diff --git a/README.md b/README.md index fc4dc84..3e83135 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ The project is in a very early PoC phase. Don't yet expect the produced code to - [ ] Efficient implementations of byte swaps, memset, memmove, mulmod and the like - [ ] Use `drink` for integration tests once we have 64bit support in PolkaVM -- [ ] Use PolkaVM allocator for heap space +- [x] Use PolkaVM allocator for heap space - [ ] Exercice `schlau` and possibly `smart-bench` benchmark cases - [ ] Tests currently rely on the binary being in $PATH, which is very annoying and requires `cargo install` all the times - [ ] Define how to do deployments diff --git a/crates/extensions/Cargo.toml b/crates/extensions/Cargo.toml index 06fc411..2ede70b 100644 --- a/crates/extensions/Cargo.toml +++ b/crates/extensions/Cargo.toml @@ -6,4 +6,4 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -inkwell = { workspace = true, no-default-features = true, features = ["target-riscv", "no-libffi-linking", "llvm16-0"] } +inkwell = { workspace = true, features = ["target-riscv", "no-libffi-linking", "llvm16-0"] } diff --git a/crates/integration/Cargo.toml b/crates/integration/Cargo.toml index 0c31c40..210e510 100644 --- a/crates/integration/Cargo.toml +++ b/crates/integration/Cargo.toml @@ -6,10 +6,13 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -hex = { workspace = true } polkavm = { workspace = true } +alloy-primitives = { workspace = true } parity-scale-codec = { workspace = true } revive-solidity = { path = "../solidity" } era-compiler-llvm-context = { path = "../llvm-context" } -alloy-primitives = { workspace = true } +hex = { workspace = true } +env_logger = { workspace = true } + +[dev-dependencies] alloy-sol-types = { workspace = true } diff --git a/crates/integration/contracts/Computation.sol b/crates/integration/contracts/Computation.sol index 04baeba..39cc006 100644 --- a/crates/integration/contracts/Computation.sol +++ b/crates/integration/contracts/Computation.sol @@ -1,3 +1,6 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.24; + contract Computation { function triangle_number(int64 n) public pure returns (int64 sum) { unchecked { diff --git a/crates/integration/contracts/flipper.sol b/crates/integration/contracts/flipper.sol index b4fc578..269c489 100644 --- a/crates/integration/contracts/flipper.sol +++ b/crates/integration/contracts/flipper.sol @@ -1,3 +1,6 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.24; + contract Flipper { bool coin; diff --git a/crates/integration/src/mock_runtime.rs b/crates/integration/src/mock_runtime.rs index 1110d4e..789a28e 100644 --- a/crates/integration/src/mock_runtime.rs +++ b/crates/integration/src/mock_runtime.rs @@ -217,9 +217,21 @@ pub fn call(mut state: State, on: &InstancePre, export: ExportIndex) -> S let call_args = polkavm::CallArgs::new(&mut state, export); + init_logs(); + match on.instantiate().unwrap().call(state_args, call_args) { Err(polkavm::ExecutionError::Trap(_)) => state, Err(other) => panic!("unexpected error: {other}"), Ok(_) => panic!("unexpected return"), } } + +fn init_logs() { + if std::env::var("RUST_LOG").is_ok() { + #[cfg(test)] + let test = true; + #[cfg(not(test))] + let test = false; + let _ = env_logger::builder().is_test(test).try_init(); + } +} diff --git a/crates/llvm-context/src/eravm/context/address_space.rs b/crates/llvm-context/src/eravm/context/address_space.rs index 20d4266..5480782 100644 --- a/crates/llvm-context/src/eravm/context/address_space.rs +++ b/crates/llvm-context/src/eravm/context/address_space.rs @@ -5,9 +5,10 @@ /// /// The address space aliases. /// -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum AddressSpace { /// The stack memory. + #[default] Stack, /// The heap memory. Heap, diff --git a/crates/llvm-context/src/eravm/context/function/runtime/entry.rs b/crates/llvm-context/src/eravm/context/function/runtime/entry.rs index 2c2db30..d15b540 100644 --- a/crates/llvm-context/src/eravm/context/function/runtime/entry.rs +++ b/crates/llvm-context/src/eravm/context/function/runtime/entry.rs @@ -30,7 +30,7 @@ impl Entry { /// Initializes the global variables. /// The pointers are not initialized, because it's not possible to create a null pointer. - pub fn initialize_globals(context: &mut Context) + pub fn initialize_globals(context: &mut Context) -> anyhow::Result<()> where D: Dependency + Clone, { @@ -42,13 +42,18 @@ impl Entry { calldata_type.get_undef(), ); - let heap_memory_type = context.array_type(context.byte_type(), 1024 * 1024); context.set_global( crate::eravm::GLOBAL_HEAP_MEMORY_POINTER, - heap_memory_type, + context.byte_type().ptr_type(AddressSpace::Generic.into()), AddressSpace::Stack, - heap_memory_type.get_undef(), + context.integer_type(32).get_undef(), ); + context.build_store( + context + .get_global(crate::eravm::GLOBAL_HEAP_MEMORY_POINTER)? + .into(), + context.build_sbrk(context.integer_const(32, 0))?, + )?; context.set_global( crate::eravm::GLOBAL_CALLDATA_SIZE, @@ -80,6 +85,8 @@ impl Entry { AddressSpace::Stack, extra_abi_data_type.const_zero(), ); + + Ok(()) } /// Load the calldata via seal `input` and initialize the calldata end @@ -256,7 +263,7 @@ where context.set_current_function(Runtime::FUNCTION_ENTRY)?; context.set_basic_block(context.current_function().borrow().entry_block()); - Self::initialize_globals(context); + Self::initialize_globals(context)?; Self::load_calldata(context)?; Self::leave_entry(context)?; diff --git a/crates/llvm-context/src/eravm/context/mod.rs b/crates/llvm-context/src/eravm/context/mod.rs index edd814e..76594c0 100644 --- a/crates/llvm-context/src/eravm/context/mod.rs +++ b/crates/llvm-context/src/eravm/context/mod.rs @@ -662,26 +662,22 @@ where ) -> anyhow::Result> { match pointer.address_space { AddressSpace::Heap => { - let heap_pointer = self - .get_global(crate::eravm::GLOBAL_HEAP_MEMORY_POINTER)? - .value - .as_pointer_value(); - - // TODO: Ensure safe casts somehow - let offset = self.builder().build_ptr_to_int( - pointer.value, - self.integer_type(32), - "offset_ptrtoint", + let heap_pointer = self.build_heap_gep( + self.builder().build_ptr_to_int( + pointer.value, + self.integer_type(32), + "offset_ptrtoint", + )?, + pointer + .r#type + .size_of() + .expect("should be IntValue") + .const_truncate(self.integer_type(32)), )?; - let pointer_value = self.build_gep( - Pointer::new(self.byte_type(), AddressSpace::Stack, heap_pointer), - &[offset], - self.byte_type(), - "heap_offset_via_gep", - ); + let value = self .builder() - .build_load(pointer.r#type, pointer_value.value, name)?; + .build_load(pointer.r#type, heap_pointer.value, name)?; self.basic_block() .get_last_instruction() .expect("Always exists") @@ -758,17 +754,12 @@ where .builder() .build_load(pointer.r#type, pointer.value, name)?; - let alignment = if AddressSpace::Stack == pointer.address_space { - era_compiler_common::BYTE_LENGTH_FIELD - } else { - era_compiler_common::BYTE_LENGTH_BYTE - }; - self.basic_block() .get_last_instruction() .expect("Always exists") - .set_alignment(alignment as u32) + .set_alignment(era_compiler_common::BYTE_LENGTH_FIELD as u32) .expect("Alignment is valid"); + Ok(value) } } @@ -785,32 +776,23 @@ where { match pointer.address_space { AddressSpace::Heap => { - let heap_pointer = self - .get_global(crate::eravm::GLOBAL_HEAP_MEMORY_POINTER) - .unwrap() - .value - .as_pointer_value(); - - // TODO: Ensure safe casts somehow - let offset = self.builder().build_ptr_to_int( - pointer.value, - self.integer_type(32), - "offset_ptrtoint", + let heap_pointer = self.build_heap_gep( + self.builder().build_ptr_to_int( + pointer.value, + self.integer_type(32), + "offset_ptrtoint", + )?, + value + .as_basic_value_enum() + .get_type() + .size_of() + .expect("should be IntValue") + .const_truncate(self.integer_type(32)), )?; - let pointer_value = self.build_gep( - Pointer::new(self.byte_type(), AddressSpace::Stack, heap_pointer), - &[offset], - self.byte_type(), - "heap_offset_via_gep", - ); - let value = self.build_byte_swap(value.as_basic_value_enum()); - let instruction = self - .builder - .build_store(pointer_value.value, value) - .unwrap(); - instruction + self.builder + .build_store(heap_pointer.value, value)? .set_alignment(era_compiler_common::BYTE_LENGTH_BYTE as u32) .expect("Alignment is valid"); } @@ -875,17 +857,6 @@ where }; Ok(()) - // let instruction = self.builder.build_store(pointer.value, value).unwrap(); - - // let alignment = if AddressSpace::Stack == pointer.address_space { - // era_compiler_common::BYTE_LENGTH_FIELD - // } else { - // era_compiler_common::BYTE_LENGTH_BYTE - // }; - - // instruction - // .set_alignment(alignment as u32) - // .expect("Alignment is valid"); } /// Swap the endianness of an intvalue @@ -1212,17 +1183,9 @@ where // zkevm_opcode_defs::RetForwardPageType::UseHeap //}; - let heap_pointer = self - .get_global(crate::eravm::GLOBAL_HEAP_MEMORY_POINTER)? - .value - .as_pointer_value(); let offset_truncated = self.safe_truncate_int_to_i32(offset)?; - let offset_into_heap = self.build_gep( - Pointer::new(self.byte_type(), AddressSpace::Stack, heap_pointer), - &[offset_truncated], - self.byte_type(), - "heap_offset_via_gep", - ); + let length_truncated = self.safe_truncate_int_to_i32(length)?; + let offset_into_heap = self.build_heap_gep(offset_truncated, length_truncated)?; let length_pointer = self.safe_truncate_int_to_i32(length)?; let offset_pointer = self.builder().build_ptr_to_int( @@ -1279,6 +1242,99 @@ where Ok(truncated) } + /// Build a call to PolkaVM `sbrk` for extending the heap by `size`. + pub fn build_sbrk( + &self, + size: inkwell::values::IntValue<'ctx>, + ) -> anyhow::Result> { + Ok(self + .builder() + .build_call( + self.module().get_function("__sbrk").expect("is declared"), + &[size.into()], + "call_sbrk", + )? + .try_as_basic_value() + .left() + .expect("sbrk returns a pointer") + .into_pointer_value()) + } + + /// Call PolkaVM `sbrk` for extending the heap by `size`, + /// trapping the contract if the call failed. + pub fn build_heap_alloc( + &self, + size: inkwell::values::IntValue<'ctx>, + ) -> anyhow::Result> { + let end_of_memory = self.build_sbrk(size)?; + let return_is_nil = self.builder().build_int_compare( + inkwell::IntPredicate::EQ, + end_of_memory, + self.byte_type().ptr_type(Default::default()).const_null(), + "compare_end_of_memory_nil", + )?; + + let continue_block = self.append_basic_block("sbrk_not_nil"); + let trap_block = self.append_basic_block("sbrk_nil"); + self.build_conditional_branch(return_is_nil, trap_block, continue_block)?; + + self.set_basic_block(trap_block); + self.build_call(self.intrinsics().trap, &[], "invalid_trap"); + self.build_unreachable(); + + self.set_basic_block(continue_block); + + Ok(end_of_memory) + } + + /// Returns a pointer to `offset` into the heap, allocating `length` + /// bytes more memory if `offset + length` would be out of bounds. + /// + /// # Panics + /// Assumes `offset` and `length` to be an i32 value. + pub fn build_heap_gep( + &self, + offset: inkwell::values::IntValue<'ctx>, + length: inkwell::values::IntValue<'ctx>, + ) -> anyhow::Result> { + assert_eq!(offset.get_type(), self.integer_type(32)); + assert_eq!(length.get_type(), self.integer_type(32)); + + let heap_start = self + .get_global(crate::eravm::GLOBAL_HEAP_MEMORY_POINTER)? + .value + .as_pointer_value(); + let heap_end = self.build_sbrk(self.integer_const(32, 0))?; + let value_end = self.build_gep( + Pointer::new(self.byte_type(), AddressSpace::Stack, heap_start), + &[self.builder().build_int_nuw_add(offset, length, "end")?], + self.byte_type(), + "heap_end_gep", + ); + let is_out_of_bounds = self.builder().build_int_compare( + inkwell::IntPredicate::UGT, + value_end.value, + heap_end, + "is_value_overflowing_heap", + )?; + + let out_of_bounds_block = self.append_basic_block("heap_offset_out_of_bounds"); + let heap_offset_block = self.append_basic_block("build_heap_pointer"); + self.build_conditional_branch(is_out_of_bounds, out_of_bounds_block, heap_offset_block)?; + + self.set_basic_block(out_of_bounds_block); + self.build_heap_alloc(length)?; + self.build_unconditional_branch(heap_offset_block); + + self.set_basic_block(heap_offset_block); + Ok(self.build_gep( + Pointer::new(self.byte_type(), AddressSpace::Stack, heap_start), + &[offset], + self.byte_type(), + "heap_offset_via_gep", + )) + } + /// /// Writes the ABI pointer to the global variable. /// diff --git a/crates/llvm-context/src/eravm/evm/calldata.rs b/crates/llvm-context/src/eravm/evm/calldata.rs index 392d0b7..8a75a92 100644 --- a/crates/llvm-context/src/eravm/evm/calldata.rs +++ b/crates/llvm-context/src/eravm/evm/calldata.rs @@ -59,16 +59,9 @@ pub fn copy<'ctx, D>( where D: Dependency + Clone, { - let heap_pointer = context - .get_global(crate::eravm::GLOBAL_HEAP_MEMORY_POINTER)? - .value - .as_pointer_value(); - let destination = context.build_gep( - Pointer::new(context.byte_type(), AddressSpace::Stack, heap_pointer), - &[context.safe_truncate_int_to_i32(destination_offset)?], - context.byte_type(), - "heap_pointer_with_offset", - ); + let offset = context.safe_truncate_int_to_i32(destination_offset)?; + let size = context.safe_truncate_int_to_i32(size)?; + let destination = context.build_heap_gep(offset, size)?; let calldata_pointer = context .get_global(crate::eravm::GLOBAL_CALLDATA_POINTER)? diff --git a/crates/llvm-context/src/eravm/evm/crypto.rs b/crates/llvm-context/src/eravm/evm/crypto.rs index d29a7d2..0719432 100644 --- a/crates/llvm-context/src/eravm/evm/crypto.rs +++ b/crates/llvm-context/src/eravm/evm/crypto.rs @@ -17,23 +17,14 @@ where D: Dependency + Clone, { let offset_casted = context.safe_truncate_int_to_i32(offset)?; - let heap_pointer = context.get_global(crate::eravm::GLOBAL_HEAP_MEMORY_POINTER)?; - let input_pointer = unsafe { - context.builder().build_gep( - context.byte_type(), - heap_pointer.value.as_pointer_value(), - &[offset_casted], - "heap_offset_via_gep", - ) - }?; + let length_casted = context.safe_truncate_int_to_i32(length)?; + let input_pointer = context.build_heap_gep(offset_casted, length_casted)?; let input_pointer_casted = context.builder().build_ptr_to_int( - input_pointer, + input_pointer.value, context.integer_type(32), "input_pointer_casted", )?; - let length_casted = context.safe_truncate_int_to_i32(length)?; - let output_pointer = context.build_alloca(context.field_type(), "output_pointer"); let output_pointer_casted = context.builder().build_ptr_to_int( output_pointer.value, diff --git a/crates/pallet-contracts-pvm-llapi/Cargo.toml b/crates/pallet-contracts-pvm-llapi/Cargo.toml index 83afe54..4c44a38 100644 --- a/crates/pallet-contracts-pvm-llapi/Cargo.toml +++ b/crates/pallet-contracts-pvm-llapi/Cargo.toml @@ -4,4 +4,4 @@ version = "0.1.0" edition = "2021" [dependencies] -inkwell = { workspace = true, no-default-features = true, features = ["target-riscv", "no-libffi-linking", "llvm16-0"] } \ No newline at end of file +inkwell = { workspace = true, features = ["target-riscv", "no-libffi-linking", "llvm16-0"] } \ No newline at end of file diff --git a/crates/pallet-contracts-pvm-llapi/src/polkavm_guest.c b/crates/pallet-contracts-pvm-llapi/src/polkavm_guest.c index 0aa0721..dc92241 100644 --- a/crates/pallet-contracts-pvm-llapi/src/polkavm_guest.c +++ b/crates/pallet-contracts-pvm-llapi/src/polkavm_guest.c @@ -21,6 +21,16 @@ void * memcpy(void *dst, const void *_src, size_t len) { return dst; } +void * __sbrk(uint32_t size) { + uint32_t address; + __asm__ __volatile__( + ".insn r 0xb, 1, 0, %[dst], %[sz], zero" + : [dst] "=r" (address) + : [sz] "ir" (size) + : + ); + return (void *)address; +} // Exports diff --git a/crates/pallet-contracts-pvm-llapi/src/polkavm_guest.h b/crates/pallet-contracts-pvm-llapi/src/polkavm_guest.h index cf5b154..51767e3 100644 --- a/crates/pallet-contracts-pvm-llapi/src/polkavm_guest.h +++ b/crates/pallet-contracts-pvm-llapi/src/polkavm_guest.h @@ -162,4 +162,3 @@ static void __attribute__ ((naked, used)) POLKAVM_UNIQUE(polkavm_stack_size)() { } #endif - \ No newline at end of file diff --git a/crates/stdlib/Cargo.toml b/crates/stdlib/Cargo.toml index d41e6ee..1a41182 100644 --- a/crates/stdlib/Cargo.toml +++ b/crates/stdlib/Cargo.toml @@ -6,4 +6,4 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -inkwell = { workspace = true, no-default-features = true, features = ["target-riscv", "no-libffi-linking", "llvm16-0"] } +inkwell = { workspace = true, features = ["target-riscv", "no-libffi-linking", "llvm16-0"] }