Emerge Yul recompiler (#1)

Provide a modified (and incomplete) version of ZKSync zksolc that can compile the most basic contracts
This commit is contained in:
Cyrill Leutwiler
2024-03-12 12:06:02 +01:00
committed by GitHub
parent d238d8f39e
commit cffa14a4d2
247 changed files with 35357 additions and 4905 deletions
@@ -0,0 +1,137 @@
//!
//! The LLVM pointer.
//!
use inkwell::types::BasicType;
use crate::eravm::context::address_space::AddressSpace;
use crate::eravm::context::global::Global;
use crate::eravm::context::Context;
use crate::eravm::Dependency;
///
/// The LLVM pointer.
///
#[derive(Debug, Clone, Copy)]
pub struct Pointer<'ctx> {
/// The pointee type.
pub r#type: inkwell::types::BasicTypeEnum<'ctx>,
/// The address space.
pub address_space: AddressSpace,
/// The pointer value.
pub value: inkwell::values::PointerValue<'ctx>,
}
impl<'ctx> Pointer<'ctx> {
///
/// A shortcut constructor.
///
pub fn new<T>(
r#type: T,
address_space: AddressSpace,
value: inkwell::values::PointerValue<'ctx>,
) -> Self
where
T: BasicType<'ctx>,
{
Self {
r#type: r#type.as_basic_type_enum(),
address_space,
value,
}
}
///
/// Wraps a 256-bit primitive type pointer.
///
pub fn new_stack_field<D>(
context: &Context<'ctx, D>,
value: inkwell::values::PointerValue<'ctx>,
) -> Self
where
D: Dependency + Clone,
{
Self {
r#type: context.field_type().as_basic_type_enum(),
address_space: AddressSpace::Stack,
value,
}
}
///
/// Creates a new pointer with the specified `offset`.
///
pub fn new_with_offset<D, T>(
context: &Context<'ctx, D>,
address_space: AddressSpace,
r#type: T,
offset: inkwell::values::IntValue<'ctx>,
name: &str,
) -> Self
where
D: Dependency + Clone,
T: BasicType<'ctx>,
{
assert_ne!(
address_space,
AddressSpace::Stack,
"Stack pointers cannot be addressed"
);
let value = context
.builder
.build_int_to_ptr(
offset,
context.byte_type().ptr_type(address_space.into()),
name,
)
.unwrap();
Self::new(r#type, address_space, value)
}
///
/// Casts the pointer into another type.
///
pub fn cast<T>(self, r#type: T) -> Self
where
T: BasicType<'ctx>,
{
Self {
r#type: r#type.as_basic_type_enum(),
address_space: self.address_space,
value: self.value,
}
}
pub fn address_space_cast<D>(
self,
context: &Context<'ctx, D>,
address_space: AddressSpace,
name: &str,
) -> anyhow::Result<Self>
where
D: Dependency + Clone,
{
let value = context.builder().build_address_space_cast(
self.value,
self.r#type.ptr_type(address_space.into()),
name,
)?;
Ok(Self {
address_space,
value,
..self
})
}
}
impl<'ctx> From<Global<'ctx>> for Pointer<'ctx> {
fn from(global: Global<'ctx>) -> Self {
Self {
r#type: global.r#type,
address_space: AddressSpace::Stack,
value: global.value.as_pointer_value(),
}
}
}