Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compilation error inEcPairing #153

Open
ColoCarletti opened this issue Sep 28, 2023 · 1 comment
Open

Compilation error inEcPairing #153

ColoCarletti opened this issue Sep 28, 2023 · 1 comment
Labels
bug Something isn't working

Comments

@ColoCarletti
Copy link
Member

ColoCarletti commented Sep 28, 2023

Context: EcPairing.yul

Description:
Although in the current state the ecPairing contract compiles, if more functions are added or some are changed, the following compilation error occurs:

assembly-to-bytecode conversion error: assembly parse error Label DEFAULT_UNWIND was tried to be used for either PC or constant at offset 238030 that is more than '65535' addressable space

This error comes from: https://github.com/matter-labs/era-zkEVM-assembly/blob/v1.3.2/src/error.rs#L41

#[derive(Debug, Error, PartialEq)]
pub enum AssemblyParseError {
    [...]
    #[error("Label {1} was tried to be used for either PC or constant at offset {0} that is more than `{2}` addressable space")]
    CodeIsTooLong(usize, String, u64),
}

And it is triggered by one of the following functions: https://github.com/matter-labs/era-zkEVM-assembly/blob/v1.3.2/src/assembly/instruction/mod.rs#L267

pub(crate) fn link_operand<const N: usize, E: VmEncodingMode<N>>(
    operand: &mut FullOperand,
    function_labels_to_pc: &HashMap<String, usize>,
    constant_labels_to_offset: &HashMap<String, usize>,
    globals_to_offsets: &HashMap<String, usize>,
) -> Result<(), AssemblyParseError> {
    match operand.clone() {
        FullOperand::Constant(ConstantOperand {
            label,
            register,
            immediate,
        }) => {
            if let Some(pc) = function_labels_to_pc.get(&*label).copied() {
                assert_eq!(
                    immediate, 0,
                    "jumps can not have immediates in labels addressing"
                );
                assert!(
                    register.is_void(),
                    "jumps can not have registers in labels addressing"
                );
                if pc > (E::PcOrImm::max()).as_u64() as usize {
                    return Err(AssemblyParseError::CodeIsTooLong(
                        pc,
                        label,
                        (E::PcOrImm::max()).as_u64(),
                    ));
                }
                // assert!(pc <= Offset::MAX as usize, "pc overflow in linker");
                *operand = FullOperand::Full(GenericOperand {
                    r#type: ImmMemHandlerFlags::UseImm16Only,
                    register: RegisterOperand::Null,
                    immediate: pc as u64,
                });
            } else if let Some(offset) = constant_labels_to_offset.get(&*label).copied() {
                if offset > (E::PcOrImm::max()).as_u64() as usize {
                    return Err(AssemblyParseError::CodeIsTooLong(
                        offset,
                        label,
                        (E::PcOrImm::max()).as_u64(),
                    ));
                }
                // assert!(offset <= Offset::MAX as usize, "offset overflow in linker");
                let imm = E::PcOrImm::from_u64_clipped(immediate)
                    .wrapping_add(E::PcOrImm::from_u64_clipped(offset as u64))
                    .as_u64();

                *operand = FullOperand::Full(GenericOperand {
                    r#type: ImmMemHandlerFlags::UseCodePage,
                    register,
                    immediate: imm,
                });
            } else {
                return Err(AssemblyParseError::LabelNotFound(label.to_owned()));
            }
        }
        FullOperand::GlobalVariable(GlobalVariable {
            label,
            register,
            immediate,
        }) => {
            if let Some(offset) = globals_to_offsets.get(&*label).copied() {
                if offset > (E::PcOrImm::max()).as_u64() as usize {
                    return Err(AssemblyParseError::CodeIsTooLong(
                        offset,
                        label,
                        (E::PcOrImm::max()).as_u64(),
                    ));
                }
                // assert!(offset <= Offset::MAX as usize, "offset overflow in linker");
                let imm = E::PcOrImm::from_u64_clipped(immediate)
                    .wrapping_add(E::PcOrImm::from_u64_clipped(offset as u64))
                    .as_u64();

                *operand = FullOperand::Full(GenericOperand {
                    r#type: ImmMemHandlerFlags::UseAbsoluteOnStack,
                    register,
                    immediate: imm,
                });
            } else {
                return Err(AssemblyParseError::LabelNotFound(label.to_owned()));
            }
        }
        _ => {}
    }

    Ok(())
}

Steps to reproduce:

  1. Go to this line: EcPairing.yul#L1294
  2. Replace it with: f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121 := fp12Square(f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121).
  3. make run.
@ilitteri ilitteri added the bug Something isn't working label Oct 2, 2023
@ColoCarletti ColoCarletti changed the title Precompiles don't compile when certain lines are added to EcPairing Compilation error inEcPairing Oct 3, 2023
@ilitteri
Copy link
Collaborator

Can this be closed @ColoCarletti?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants