Compilation error in`EcPairing`
ColoCarletti opened this issue · 1 comments
ColoCarletti commented
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:
- Go to this line: EcPairing.yul#L1294
- 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)
. make run
.
ilitteri commented
Can this be closed @ColoCarletti?