def fill_mem(exp, mem_idx, mem_val):

    # speed - if exp contains a variable used in mem_idx
    #         or mem_idx contains a variable not used in exp
    #         there can be no match.
    #
    #         ugly, but shaves off 15% exec time
    logger.info(f'filling mem: {exp} with mem[{mem_idx}] == {mem_val}')

    if mem_idx ~ ('range', ('var', :num), _) and \
       not contains(exp, ('var', num)):
            assert not strict or __fill_data(exp, mem_idx, mem_val) == exp
            return exp
Exemplo n.º 2
0
def fill_mem(exp, mem_idx, mem_val):

    # speed - if exp contains a variable used in mem_idx
    #         or mem_idx contains a variable not used in exp
    #         there can be no match.
    #
    #         ugly, but shaves off 15% exec time
    logger.debug(f"filling mem: {exp} with mem[{mem_idx}] == {mem_val}")

    if (m := match(
            mem_idx,
        ("range",
         ("var", ":num"), Any))) and not contains(exp, ("var", m.num)):
        assert not strict
        return exp
Exemplo n.º 3
0
        When writing strings to storage, there are usually three cases - when string is 0,
        when string is < 31 (special format that takes just one storage slot), and when string >= 32.

        e.g. 0xf97187f566eC6374cB08470CCe593fF0Dd36d8A9, baseURI
             0xFcD0d8E3ae34922A2921f7E7065172e5317f8ad8, name

        The below hides the cases for < 31, and for 0, and shows only for >31. Technically incorrect,
        and I'm not super comfortable with this, but some of the code would be very unreadable without it.


    '''

    if line ~ ('if', ('lt', 31, :some_len), :if_true, :if_false):
        if len(if_true) == 2:
            first, second = if_true[0], if_true[1]
            if first ~ ('store', ...) and contains(first, some_len) \
               and second ~ ('if', ('iszero', some_len), :deep_true, :deep_false):
                    return [first] + deep_false

    if line ~ ('if', ('iszero', ('mask_shl', 255, 1, 0, ('and', ('storage', 256, 0, :loc), ('add', -1, ('mask_shl', 248, 0, 8, ('iszero', ('storage', 1, 0, loc))))))), :if_true, :if_false) \
        or line ~ ('if', ('iszero', ('mask_shl', 255, 1, 0, ('and', ('add', -1, ('mask_shl', 248, 0, 8, ('iszero', ('storage', 1, 0, :loc)))), ('storage', 256, 0, loc)))), :if_true, :if_false):

        if len(if_false) == 1:
            first = if_false[0]

            if first ~ ('if', ('lt', 31, ('storage', 256, 0, ('length', loc))), :deep_true, :deep_false) \
                or first ~ ('if', ('lt', 31, ('storage', 256, 0, ('length', ('loc', loc)))), :deep_true, :deep_false):
                return deep_true

    return [line]
def fill_mem(exp, mem_idx, mem_val):

    # speed - if exp contains a variable used in mem_idx
    #         or mem_idx contains a variable not used in exp
    #         there can be no match.
    #
    #         ugly, but shaves off 15% exec time
    logger.info(f'filling mem: {exp} with mem[{mem_idx}] == {mem_val}')

    if mem_idx ~ ('range', ('var', :num), _) and \
       not contains(exp, ('var', num)):
            assert not strict or __fill_data(exp, mem_idx, mem_val) == exp
            return exp

    if exp ~ ('mem', ('range', ('var', :num), _)) and \
       not contains(mem_idx, ('var', num)):
            assert not strict or __fill_data(exp, mem_idx, mem_val) == exp
            return exp

    logger.info(f'no speed improvements')


    # /speed

    f = _fill_mem(exp, mem_idx, mem_val)
    return f
    


def _fill_mem(exp, split, split_val):
    if exp == ('mem', split):
Exemplo n.º 5
0
    #
    #         ugly, but shaves off 15% exec time
    logger.debug(f"filling mem: {exp} with mem[{mem_idx}] == {mem_val}")

    if (m := match(
            mem_idx,
        ("range",
         ("var", ":num"), Any))) and not contains(exp, ("var", m.num)):
        assert not strict
        return exp

    if (m := match(
            exp,
        ("mem",
         ("range",
          ("var", ":num"), Any)))) and not contains(mem_idx, ("var", m.num)):
        assert not strict
        return exp

    logger.debug("no speed improvements")

    # /speed

    f = _fill_mem(exp, mem_idx, mem_val)
    return f


def _fill_mem(exp, split, split_val):
    if exp == ("mem", split):
        return split_val
Exemplo n.º 6
0
        e.g. 0xf97187f566eC6374cB08470CCe593fF0Dd36d8A9, baseURI
             0xFcD0d8E3ae34922A2921f7E7065172e5317f8ad8, name

        The below hides the cases for < 31, and for 0, and shows only for >31. Technically incorrect,
        and I'm not super comfortable with this, but some of the code would be very unreadable without it.


    """

    if m := match(line,
                  ("if", ("lt", 31, ":some_len"), ":if_true", ":if_false")):
        some_len, if_true, if_false = m.some_len, m.if_true, m.if_false
        if len(if_true) == 2:
            first, second = if_true[0], if_true[1]
            if (opcode(first) == "store" and contains(first, some_len)
                    and (m := match(
                        second,
                        ("if",
                         ("iszero", some_len), ":deep_true", ":deep_false"),
                    ))):
                return [first] + m.deep_false

    if (m := match(
            line,
        (
            "if",
            (
                "iszero",
                (
                    "mask_shl",