Ejemplo n.º 1
0
def test_eval_reference():
    x = Reference(pc=0,
                  value=parse_expr('2 * ap + 3 * fp - 5'),
                  ap_tracking_data=RegTrackingData(group=1, offset=5))
    with pytest.raises(FlowTrackingError):
        x.eval(RegTrackingData(group=2, offset=5))
    assert x.eval(RegTrackingData(
        group=1, offset=8)).format() == '2 * (ap - 3) + 3 * fp - 5'
Ejemplo n.º 2
0
    def handle_ReferenceDefinition(self, name: str,
                                   identifier: ReferenceDefinition,
                                   scope: ScopedName,
                                   set_value: Optional[MaybeRelocatable]):
        # In set mode, take the address of the given reference instead.
        reference = self._context.flow_tracking_data.resolve_reference(
            reference_manager=self._context.reference_manager,
            name=identifier.full_name)

        if set_value is None:
            expr = reference.eval(self._context.flow_tracking_data.ap_tracking)
            expr, expr_type = simplify_type_system(expr)
            if isinstance(expr_type, TypeStruct):
                # If the reference is of type T, take its address and treat it as T*.
                assert isinstance(expr, ExprDeref), \
                    f"Expected expression of type '{expr_type.format()}' to have an address."
                expr = expr.addr
                expr_type = TypePointer(pointee=expr_type)
            val = self._context.evaluator(expr)

            # Check if the type is felt* or any_type**.
            is_pointer_to_felt_or_pointer = (
                isinstance(expr_type, TypePointer)
                and isinstance(expr_type.pointee, (TypePointer, TypeFelt)))
            if isinstance(expr_type,
                          TypeFelt) or is_pointer_to_felt_or_pointer:
                return val
            else:
                # Typed reference, return VmConstsReference which allows accessing members.
                assert isinstance(expr_type, TypePointer) and \
                    isinstance(expr_type.pointee, TypeStruct), \
                    'Type must be of the form T*.'
                return VmConstsReference(
                    context=self._context,
                    accessible_scopes=[expr_type.pointee.scope],
                    reference_value=val,
                    add_addr_var=True)
        else:
            assert str(scope[-1:]) == name, 'Expecting scope to end with name.'
            value, value_type = simplify_type_system(reference.value)
            assert isinstance(value, ExprDeref), f"""\
{scope} (= {value.format()}) does not reference memory and cannot be assigned."""

            value_ref = Reference(
                pc=reference.pc,
                value=ExprCast(expr=value.addr, dest_type=value_type),
                ap_tracking_data=reference.ap_tracking_data,
            )

            addr = self._context.evaluator(
                value_ref.eval(self._context.flow_tracking_data.ap_tracking))
            self._context.memory[addr] = set_value
Ejemplo n.º 3
0
def test_eval_reference_fp_only():
    x = Reference(pc=0,
                  value=parse_expr('3 * fp - 5 + fp * fp'),
                  ap_tracking_data=RegTrackingData(group=1, offset=5))
    assert x.eval(RegTrackingData(
        group=2, offset=7)) == parse_expr('3 * fp - 5 + fp * fp')