Skip to content

Feat: add compile-time evaluation for convert, slice and extract32 #4634

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions tests/functional/builtins/codegen/test_create_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -785,6 +785,30 @@ def deploy_from_memory() -> address:
assert env.get_code(res) == runtime


# `initcode` and `value` arguments overlap
def test_raw_create_memory_overlap(get_contract, env):
to_deploy_code = """
foo: public(uint256)
"""

out = compile_code(to_deploy_code, output_formats=["bytecode", "bytecode_runtime"])
initcode = bytes.fromhex(out["bytecode"].removeprefix("0x"))
runtime = bytes.fromhex(out["bytecode_runtime"].removeprefix("0x"))

deployer_code = """
@external
def deploy_from_calldata(s: Bytes[49152]) -> address:
v: DynArray[Bytes[49152], 2] = [s]
x: address = raw_create(v[0], value = 0 if v.pop() == b'' else 0, revert_on_failure=False)
return x
"""

deployer = get_contract(deployer_code)

res = deployer.deploy_from_calldata(initcode)
assert env.get_code(res) == runtime


def test_raw_create_double_eval(get_contract, env):
to_deploy_code = """
foo: public(uint256)
Expand Down Expand Up @@ -1095,6 +1119,8 @@ def __init__(arg: uint256):
initcode = bytes.fromhex(out["bytecode"].removeprefix("0x"))
runtime = bytes.fromhex(out["bytecode_runtime"].removeprefix("0x"))

# the implementation of `raw_create` firstly caches
# `value` and then `salt`, here the source order is `salt` then `value`
deployer_code = """
c: Bytes[1024]
salt: bytes32
Expand Down Expand Up @@ -1122,3 +1148,33 @@ def deploy_from_calldata(s: Bytes[1024], arg: uint256, salt: bytes32, value_: ui
assert HexBytes(res) == create2_address_of(deployer.address, salt, initcode)
assert env.get_code(res) == runtime
assert env.get_balance(res) == value


# test vararg and kwarg order of evaluation
# test fails because `value` gets evaluated
# before the 1st vararg which doesn't follow
# source code order
@pytest.mark.xfail(raises=AssertionError)
def test_raw_create_eval_order(get_contract):
code = """
a: public(uint256)

@deploy
def __init__():
initcode: Bytes[100] = b"a"
res: address = raw_create(
initcode, self.test1(), value=self.test2(), revert_on_failure=False
)

@internal
def test1() -> uint256:
self.a = 1
return 1

@internal
def test2() -> uint256:
self.a = 2
return 2
"""
c = get_contract(code)
assert c.a() == 2
4 changes: 2 additions & 2 deletions tests/hevm.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from tests.venom_utils import parse_from_basic_block
from vyper.ir.compile_ir import assembly_to_evm
from vyper.venom import LowerDloadPass, SimplifyCFGPass, StoreExpansionPass, VenomCompiler
from vyper.venom import LowerDloadPass, SimplifyCFGPass, SingleUseExpansion, VenomCompiler
from vyper.venom.analysis import IRAnalysesCache
from vyper.venom.basicblock import IRInstruction, IRLiteral

Expand Down Expand Up @@ -64,7 +64,7 @@ def _prep_hevm_venom_ctx(ctx, verbose=False):

# requirements for venom_to_assembly
LowerDloadPass(ac, fn).run_pass()
StoreExpansionPass(ac, fn).run_pass()
SingleUseExpansion(ac, fn).run_pass()

compiler = VenomCompiler([ctx])
asm = compiler.generate_evm(no_optimize=False)
Expand Down
4 changes: 2 additions & 2 deletions tests/unit/compiler/venom/test_algebraic_binopt.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import pytest

from tests.venom_utils import PrePostChecker
from vyper.venom.passes import AlgebraicOptimizationPass, StoreElimination
from vyper.venom.passes import AlgebraicOptimizationPass, AssignElimination

"""
Test abstract binop+unop optimizations in algebraic optimizations pass
"""

pytestmark = pytest.mark.hevm

_check_pre_post = PrePostChecker([StoreElimination, AlgebraicOptimizationPass, StoreElimination])
_check_pre_post = PrePostChecker([AssignElimination, AlgebraicOptimizationPass, AssignElimination])


def test_sccp_algebraic_opt_sub_xor():
Expand Down
4 changes: 2 additions & 2 deletions tests/unit/compiler/venom/test_duplicate_operands.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from vyper.venom import generate_assembly_experimental
from vyper.venom.analysis import IRAnalysesCache
from vyper.venom.context import IRContext
from vyper.venom.passes import StoreExpansionPass
from vyper.venom.passes import SingleUseExpansion


def test_duplicate_operands():
Expand All @@ -26,7 +26,7 @@ def test_duplicate_operands():
bb.append_instruction("stop")

ac = IRAnalysesCache(fn)
StoreExpansionPass(ac, fn).run_pass()
SingleUseExpansion(ac, fn).run_pass()

optimize = OptimizationLevel.GAS
asm = generate_assembly_experimental(ctx, optimize=optimize)
Expand Down
4 changes: 2 additions & 2 deletions tests/unit/compiler/venom/test_load_elimination.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from tests.venom_utils import PrePostChecker
from vyper.evm.address_space import CALLDATA, DATA, MEMORY, STORAGE, TRANSIENT
from vyper.venom.passes import LoadElimination, StoreElimination
from vyper.venom.passes import AssignElimination, LoadElimination

pytestmark = pytest.mark.hevm

Expand All @@ -11,7 +11,7 @@
# and the second/in post is needed to create
# easier equivalence in the test for pre and post
_check_pre_post = PrePostChecker(
passes=[StoreElimination, LoadElimination, StoreElimination], post=[StoreElimination]
passes=[AssignElimination, LoadElimination, AssignElimination], post=[AssignElimination]
)


Expand Down
Loading