Skip to content

Commit

Permalink
Merge pull request #1619 from iamdefinitelyahuman/compile-lll-bug
Browse files Browse the repository at this point in the history
Fix incorrect compile_to_assembly call args
  • Loading branch information
charles-cooper committed Sep 23, 2019
2 parents 089d0c4 + 7f63da6 commit efdc6e2
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 6 deletions.
34 changes: 34 additions & 0 deletions tests/parser/features/test_assert.py
Expand Up @@ -163,3 +163,37 @@ def test():
c2 = get_contract(code, *[c1.address])
# static call prohibits state change
assert_tx_failed(lambda: c2.test())


def test_assert_in_for_loop(get_contract, assert_tx_failed):
code = """
@public
def test(x: uint256[3]) -> bool:
for i in range(3):
assert x[i] < 5
return True
"""

c = get_contract(code)

c.test([1, 2, 3])
assert_tx_failed(lambda: c.test([5, 1, 3]))
assert_tx_failed(lambda: c.test([1, 5, 3]))
assert_tx_failed(lambda: c.test([1, 3, 5]))


def test_assert_with_reason_in_for_loop(get_contract, assert_tx_failed):
code = """
@public
def test(x: uint256[3]) -> bool:
for i in range(3):
assert x[i] < 5, "because reasons"
return True
"""

c = get_contract(code)

c.test([1, 2, 3])
assert_tx_failed(lambda: c.test([5, 1, 3]))
assert_tx_failed(lambda: c.test([1, 5, 3]))
assert_tx_failed(lambda: c.test([1, 3, 5]))
17 changes: 11 additions & 6 deletions vyper/compile_lll.py
@@ -1,5 +1,8 @@
import functools

from vyper.exceptions import (
CompilerPanic,
)
from vyper.parser.parser import (
LLLnode,
)
Expand Down Expand Up @@ -88,11 +91,13 @@ def apply_line_no_wrapper(*args, **kwargs):
def compile_to_assembly(code, withargs=None, existing_labels=None, break_dest=None, height=0):
if withargs is None:
withargs = {}
assert isinstance(withargs, dict)
if not isinstance(withargs, dict):
raise CompilerPanic(f"Incorrect type for withargs: {type(withargs)}")

if existing_labels is None:
existing_labels = set()
assert isinstance(existing_labels, set)
if not isinstance(existing_labels, set):
raise CompilerPanic(f"Incorrect type for existing_labels: {type(existing_labels)}")

# Opcodes
if isinstance(code.value, str) and code.value.upper() in opcodes:
Expand Down Expand Up @@ -136,7 +141,7 @@ def compile_to_assembly(code, withargs=None, existing_labels=None, break_dest=No
['codecopy', MemoryPositions.FREE_VAR_SPACE, code.args[0], 32],
['mload', MemoryPositions.FREE_VAR_SPACE]
]
), withargs, break_dest, height)
), withargs, existing_labels, break_dest, height)
# If statements (2 arguments, ie. if x: y)
elif code.value in ('if', 'if_unchecked') and len(code.args) == 2:
o = []
Expand Down Expand Up @@ -270,9 +275,9 @@ def compile_to_assembly(code, withargs=None, existing_labels=None, break_dest=No
o.extend(get_revert())
return o
elif code.value == 'assert_reason':
o = compile_to_assembly(code.args[0], withargs, break_dest, height)
mem_start = compile_to_assembly(code.args[1], withargs, break_dest, height)
mem_len = compile_to_assembly(code.args[2], withargs, break_dest, height)
o = compile_to_assembly(code.args[0], withargs, existing_labels, break_dest, height)
mem_start = compile_to_assembly(code.args[1], withargs, existing_labels, break_dest, height)
mem_len = compile_to_assembly(code.args[2], withargs, existing_labels, break_dest, height)
o.extend(get_revert(mem_start, mem_len))
return o
# Unsigned/signed clamp, check less-than
Expand Down

0 comments on commit efdc6e2

Please sign in to comment.