def test_revoked_reference():
    reference_manager = ReferenceManager()
    ref_id = reference_manager.alloc_id(reference=Reference(
        pc=0,
        value=parse_expr('[ap + 1]'),
        ap_tracking_data=RegTrackingData(group=0, offset=2),
    ))

    identifier_values = {
        scope('x'): ReferenceDefinition(
            full_name=scope('x'), cairo_type=TypeFelt(), references=[]
        ),
    }
    identifiers = IdentifierManager.from_dict(identifier_values)
    prime = 2**64 + 13
    ap = 100
    fp = 200
    memory = {}

    flow_tracking_data = FlowTrackingDataActual(
        ap_tracking=RegTrackingData(group=1, offset=4),
        reference_ids={scope('x'): ref_id},
    )
    context = VmConstsContext(
        identifiers=identifiers,
        evaluator=ExpressionEvaluator(prime, ap, fp, memory, identifiers).eval,
        reference_manager=reference_manager,
        flow_tracking_data=flow_tracking_data,
        memory=memory,
        pc=0)
    consts = VmConsts(context=context, accessible_scopes=[ScopedName()])

    with pytest.raises(FlowTrackingError, match="Reference 'x' is revoked."):
        consts.x

    with pytest.raises(FlowTrackingError, match="Reference 'x' is revoked."):
        consts.x = 85
Example #2
0
def test_references():
    reference_manager = ReferenceManager()
    references = {
        scope('x.ref'):
        reference_manager.alloc_id(
            Reference(
                pc=0,
                value=parse_expr('[ap + 1]'),
                ap_tracking_data=RegTrackingData(group=0, offset=2),
            )),
        scope('x.ref2'):
        reference_manager.alloc_id(
            Reference(
                pc=0,
                value=parse_expr('[ap + 1] + 0'),
                ap_tracking_data=RegTrackingData(group=0, offset=2),
            )),
        scope('x.ref3'):
        reference_manager.alloc_id(
            Reference(
                pc=0,
                value=parse_expr('ap + 1'),
                ap_tracking_data=RegTrackingData(group=0, offset=2),
            )),
        scope('x.typeref'):
        reference_manager.alloc_id(
            Reference(
                pc=0,
                value=mark_types_in_expr_resolved(
                    parse_expr('cast(ap + 1, MyStruct*)')),
                ap_tracking_data=RegTrackingData(group=0, offset=3),
            )),
        scope('x.typeref2'):
        reference_manager.alloc_id(
            Reference(
                pc=0,
                value=mark_types_in_expr_resolved(
                    parse_expr('cast([ap + 1], MyStruct*)')),
                ap_tracking_data=RegTrackingData(group=0, offset=3),
            )),
    }
    my_struct_star = TypePointer(
        pointee=TypeStruct(scope=scope('MyStruct'), is_fully_resolved=True))
    identifier_values = {
        scope('x.ref'):
        ReferenceDefinition(full_name=scope('x.ref'),
                            cairo_type=TypeFelt(),
                            references=[]),
        scope('x.ref2'):
        ReferenceDefinition(full_name=scope('x.ref2'),
                            cairo_type=TypeFelt(),
                            references=[]),
        scope('x.ref3'):
        ReferenceDefinition(full_name=scope('x.ref3'),
                            cairo_type=TypeFelt(),
                            references=[]),
        scope('x.typeref'):
        ReferenceDefinition(full_name=scope('x.typeref'),
                            cairo_type=my_struct_star,
                            references=[]),
        scope('x.typeref2'):
        ReferenceDefinition(full_name=scope('x.typeref2'),
                            cairo_type=my_struct_star,
                            references=[]),
        scope('MyStruct'):
        StructDefinition(
            full_name=scope('MyStruct'),
            members={
                'member': MemberDefinition(offset=10, cairo_type=TypeFelt()),
            },
            size=11,
        ),
    }
    prime = 2**64 + 13
    ap = 100
    fp = 200
    memory = {
        (ap - 2) + 1: 1234,
        (ap - 1) + 1: 1000,
        (ap - 1) + 1 + 2: 13,
        (ap - 1) + 1 + 10: 17,
    }

    flow_tracking_data = FlowTrackingDataActual(
        ap_tracking=RegTrackingData(group=0, offset=4),
        reference_ids=references,
    )
    context = VmConstsContext(
        identifiers=IdentifierManager.from_dict(identifier_values),
        evaluator=ExpressionEvaluator(prime, ap, fp, memory).eval,
        reference_manager=reference_manager,
        flow_tracking_data=flow_tracking_data,
        memory=memory,
        pc=0)
    consts = VmConsts(context=context, accessible_scopes=[ScopedName()])

    assert consts.x.ref == memory[(ap - 2) + 1]
    assert consts.x.typeref.address_ == (ap - 1) + 1
    assert consts.x.typeref.member == memory[(ap - 1) + 1 + 10]
    with pytest.raises(IdentifierError,
                       match="'abc' is not a member of 'MyStruct'."):
        consts.x.typeref.abc

    with pytest.raises(IdentifierError,
                       match="'SIZE' is not a member of 'MyStruct'."):
        consts.x.typeref.SIZE

    with pytest.raises(
            AssertionError,
            match='Cannot change the value of a struct definition.'):
        consts.MyStruct = 13

    assert consts.MyStruct.member == 10
    with pytest.raises(AssertionError,
                       match='Cannot change the value of a constant.'):
        consts.MyStruct.member = 13

    assert consts.MyStruct.SIZE == 11
    with pytest.raises(AssertionError,
                       match='Cannot change the value of a constant.'):
        consts.MyStruct.SIZE = 13

    with pytest.raises(IdentifierError,
                       match="'abc' is not a member of 'MyStruct'."):
        consts.MyStruct.abc

    # Test that VmConsts can be used to assign values to references of the form '[...]'.
    memory.clear()

    consts.x.ref = 1234
    assert memory == {(ap - 2) + 1: 1234}

    memory.clear()
    consts.x.typeref.member = 1001
    assert memory == {(ap - 1) + 1 + 10: 1001}

    memory.clear()
    consts.x.typeref2 = 4321
    assert memory == {(ap - 1) + 1: 4321}

    consts.x.typeref2.member = 1
    assert memory == {
        (ap - 1) + 1: 4321,
        4321 + 10: 1,
    }

    with pytest.raises(AssertionError,
                       match='Cannot change the value of a scope definition'):
        consts.x = 1000
    with pytest.raises(
            AssertionError,
            match=
            r'x.ref2 \(= \[ap \+ 1\] \+ 0\) does not reference memory and cannot be assigned.',
    ):
        consts.x.ref2 = 1000
    with pytest.raises(
            AssertionError,
            match=
            r'x.typeref \(= ap \+ 1\) does not reference memory and cannot be assigned.',
    ):
        consts.x.typeref = 1000
Example #3
0
def test_references():
    reference_manager = ReferenceManager()
    references = {
        scope('x.ref'):
        reference_manager.get_id(
            Reference(
                pc=0,
                value=parse_expr('[ap + 1]'),
                ap_tracking_data=RegTrackingData(group=0, offset=2),
            )),
        scope('x.ref2'):
        reference_manager.get_id(
            Reference(
                pc=0,
                value=parse_expr('[ap + 1] + 0'),
                ap_tracking_data=RegTrackingData(group=0, offset=2),
            )),
        scope('x.ref3'):
        reference_manager.get_id(
            Reference(
                pc=0,
                value=parse_expr('ap + 1'),
                ap_tracking_data=RegTrackingData(group=0, offset=2),
            )),
        scope('x.typeref'):
        reference_manager.get_id(
            Reference(
                pc=0,
                value=mark_types_in_expr_resolved(
                    parse_expr('cast(ap + 1, a*)')),
                ap_tracking_data=RegTrackingData(group=0, offset=3),
            )),
        scope('x.typeref2'):
        reference_manager.get_id(
            Reference(
                pc=0,
                value=mark_types_in_expr_resolved(
                    parse_expr('cast([ap + 1], a*)')),
                ap_tracking_data=RegTrackingData(group=0, offset=3),
            )),
    }
    identifier_values = {
        scope('x.ref'):
        ReferenceDefinition(full_name=scope('x.ref'), references=[]),
        scope('x.ref2'):
        ReferenceDefinition(full_name=scope('x.ref2'), references=[]),
        scope('x.ref3'):
        ReferenceDefinition(full_name=scope('x.ref3'), references=[]),
        scope('x.typeref'):
        ReferenceDefinition(full_name=scope('x.typeref'), references=[]),
        scope('x.typeref2'):
        ReferenceDefinition(full_name=scope('x.typeref2'), references=[]),
        scope('a.member'):
        MemberDefinition(offset=10, cairo_type=TypeFelt()),
        scope('a.scope0.member'):
        MemberDefinition(offset=2, cairo_type=TypeFelt()),
    }
    prime = 2**64 + 13
    ap = 100
    fp = 200
    memory = {
        (ap - 2) + 1: 1234,
        (ap - 1) + 1: 1000,
        (ap - 1) + 1 + 2: 13,
        (ap - 1) + 1 + 10: 17,
    }

    flow_tracking_data = FlowTrackingDataActual(
        ap_tracking=RegTrackingData(group=0, offset=4),
        reference_ids=references,
    )
    context = VmConstsContext(
        identifiers=IdentifierManager.from_dict(identifier_values),
        evaluator=ExpressionEvaluator(prime, ap, fp, memory).eval,
        reference_manager=reference_manager,
        flow_tracking_data=flow_tracking_data,
        memory=memory,
        pc=0)
    consts = VmConsts(context=context, accessible_scopes=[ScopedName()])

    assert consts.x.ref == memory[(ap - 2) + 1]
    assert consts.x.typeref.address_ == (ap - 1) + 1
    assert consts.x.typeref.member == memory[(ap - 1) + 1 + 10]
    with pytest.raises(
            NotImplementedError,
            match="Expected a member, found 'scope0' which is 'scope'"):
        consts.x.typeref.scope0

    # Test that VmConsts can be used to assign values to references of the form '[...]'.
    memory.clear()

    consts.x.ref = 1234
    assert memory == {(ap - 2) + 1: 1234}

    memory.clear()
    consts.x.typeref.member = 1001
    assert memory == {(ap - 1) + 1 + 10: 1001}

    memory.clear()
    consts.x.typeref2 = 4321
    assert memory == {(ap - 1) + 1: 4321}

    consts.x.typeref2.member = 1
    assert memory == {
        (ap - 1) + 1: 4321,
        4321 + 10: 1,
    }

    with pytest.raises(AssertionError,
                       match='Cannot change the value of a scope definition'):
        consts.x = 1000
    with pytest.raises(
            AssertionError,
            match=
            r'x.ref2 \(= \[ap \+ 1\] \+ 0\) does not reference memory and cannot be assigned.',
    ):
        consts.x.ref2 = 1000
    with pytest.raises(
            AssertionError,
            match=
            r'x.typeref \(= ap \+ 1\) does not reference memory and cannot be assigned.',
    ):
        consts.x.typeref = 1000