Skip to content
This repository has been archived by the owner on Sep 5, 2023. It is now read-only.

Commit

Permalink
fix missing returns in the entry point function
Browse files Browse the repository at this point in the history
Problem: we replace returns with empty strings in the main
     function. The reason is that we change the signature of the main
     function, add return variables, so the returns are not
     valid. However, it might change semantics and it leads to
     non-compiling code for the new contract 'ctor-check.sol'.

     Another issue is that sometimes we don't finalize certain
    implicits on early returns

Solution: transpile the main and constructor function as is, without
     any changes. Add wrappers that initialize and finalize implicits
     and perform the outermost returning. The semantics are unchanged
     and finalization is guaranteed.

Also now we add only necessary implicits to the constructor and main
     functions.
  • Loading branch information
temyurchenko committed Dec 10, 2021
1 parent 3dd2ade commit 39707e5
Show file tree
Hide file tree
Showing 36 changed files with 1,685 additions and 1,062 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ test_bats: warp $(BATS_FILES) tests/cli/*.bats
test_yul: warp
mkdir -p benchmark/stats
mkdir -p benchmark/tmp
python -m pytest tests/ast/ -v --tb=short --workers=auto $(ARGS)
python -m pytest scripts/yul/transpile_test.py -v --tb=short --workers=auto $(ARGS)
python -m pytest scripts/yul/compilation_test.py -v --tb=short --workers=auto $(ARGS)
python -m pytest tests/yul/ -v --tb=short --workers=auto $(ARGS)
python -m pytest tests/ast/ -v --tb=short --workers=auto $(ARGS)
.PHONY: test_yul

benchmark: warp
Expand Down
4 changes: 2 additions & 2 deletions tests/ast/deployment-runtime-mix_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ def test_function_with_the_same_name_in_deployment_and_runtime():
actual = YulPrinter().format(combined)
expected = """
{
\tfunction constructor() { do_stuff_deployment() }
\tfunction __constructor_meat() { do_stuff_deployment() }
\tfunction do_stuff_deployment() { }
\tfunction fun_ENTRY_POINT() { do_stuff() }
\tfunction __main_meat() { do_stuff() }
\tfunction do_stuff() { }
}
"""
Expand Down
2 changes: 1 addition & 1 deletion tests/ast/functions-to-prune.ast
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Block:
Body:
Block:
FunctionDefinition:
Name: fun_ENTRY_POINT
Name: __main_meat
Parameters:
Return Variables:
Body:
Expand Down
2 changes: 1 addition & 1 deletion tests/ast/functions-to-prune.ast.result
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
function funD() { }
function fun_ENTRY_POINT() { funD() }
function __main_meat() { funD() }
}
103 changes: 56 additions & 47 deletions tests/yul/ERC20.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ from evm.hashing import uint256_pedersen
from evm.memory import uint256_mload, uint256_mstore
from evm.uint256 import is_eq, is_gt, is_lt, is_zero, slt, u256_add, u256_shl, u256_shr
from evm.yul_api import warp_return
from starkware.cairo.common.alloc import alloc
from starkware.cairo.common.cairo_builtins import BitwiseBuiltin, HashBuiltin
from starkware.cairo.common.default_dict import default_dict_finalize, default_dict_new
from starkware.cairo.common.dict_access import DictAccess
Expand Down Expand Up @@ -38,6 +37,39 @@ end
func evm_storage(arg0_low, arg0_high) -> (res : Uint256):
end
@constructor
func constructor{pedersen_ptr : HashBuiltin*, range_check_ptr, syscall_ptr : felt*}(
calldata_size, calldata_len, calldata : felt*):
alloc_locals
let (memory_dict) = default_dict_new(0)
let memory_dict_start = memory_dict
let msize = 0
with memory_dict, msize:
__constructor_meat()
end
default_dict_finalize(memory_dict_start, memory_dict, 0)
return ()
end

@external
func __main{pedersen_ptr : HashBuiltin*, range_check_ptr, syscall_ptr : felt*}(
calldata_size, calldata_len, calldata : felt*) -> (
returndata_size, returndata_len, returndata : felt*):
alloc_locals
let (__fp__, _) = get_fp_and_pc()
local exec_env_ : ExecutionEnvironment = ExecutionEnvironment(calldata_size=calldata_size, calldata_len=calldata_len, calldata=calldata, returndata_size=0, returndata_len=0, returndata=cast(0, felt*), to_returndata_size=0, to_returndata_len=0, to_returndata=cast(0, felt*))
let exec_env : ExecutionEnvironment* = &exec_env_
let (memory_dict) = default_dict_new(0)
let memory_dict_start = memory_dict
let msize = 0
let termination_token = 0
with exec_env, memory_dict, msize, termination_token:
__main_meat()
end
default_dict_finalize(memory_dict_start, memory_dict, 0)
return (exec_env.to_returndata_size, exec_env.to_returndata_len, exec_env.to_returndata)
end

func update_byte_slice_shift_deployment(value : Uint256, toInsert : Uint256) -> (result : Uint256):
alloc_locals
let result : Uint256 = toInsert
Expand All @@ -61,29 +93,18 @@ func constructor_WARP{pedersen_ptr : HashBuiltin*, range_check_ptr, syscall_ptr
return ()
end

@constructor
func constructor{
pedersen_ptr : HashBuiltin*, range_check_ptr, syscall_ptr : felt*,
bitwise_ptr : BitwiseBuiltin*}(calldata_size, calldata_len, calldata : felt*):
func __constructor_meat{
memory_dict : DictAccess*, msize, pedersen_ptr : HashBuiltin*, range_check_ptr,
syscall_ptr : felt*}() -> ():
alloc_locals
let termination_token = 0
let (returndata_ptr : felt*) = alloc()
let (__fp__, _) = get_fp_and_pc()
local exec_env_ : ExecutionEnvironment = ExecutionEnvironment(calldata_size=calldata_size, calldata_len=calldata_len, calldata=calldata, returndata_size=0, returndata_len=0, returndata=returndata_ptr, to_returndata_size=0, to_returndata_len=0, to_returndata=returndata_ptr)
let exec_env : ExecutionEnvironment* = &exec_env_
let (memory_dict) = default_dict_new(0)
let memory_dict_start = memory_dict
let msize = 0
with memory_dict, msize, exec_env, termination_token:
uint256_mstore(offset=Uint256(low=64, high=0), value=Uint256(low=128, high=0))
let (__warp_subexpr_0 : Uint256) = __warp_constant_0()
if __warp_subexpr_0.low + __warp_subexpr_0.high != 0:
assert 0 = 1
jmp rel 0
end
constructor_WARP()
return ()
uint256_mstore(offset=Uint256(low=64, high=0), value=Uint256(low=128, high=0))
let (__warp_subexpr_0 : Uint256) = __warp_constant_0()
if __warp_subexpr_0.low + __warp_subexpr_0.high != 0:
assert 0 = 1
jmp rel 0
end
constructor_WARP()
return ()
end

func abi_decode{range_check_ptr}(headStart : Uint256, dataEnd : Uint256) -> ():
Expand Down Expand Up @@ -690,31 +711,19 @@ func __warp_if_0{
end
end

@external
func fun_ENTRY_POINT{
pedersen_ptr : HashBuiltin*, range_check_ptr, syscall_ptr : felt*,
bitwise_ptr : BitwiseBuiltin*}(calldata_size, calldata_len, calldata : felt*) -> (
returndata_size : felt, returndata_len : felt, returndata : felt*):
func __main_meat{
exec_env : ExecutionEnvironment*, memory_dict : DictAccess*, msize,
pedersen_ptr : HashBuiltin*, range_check_ptr, syscall_ptr : felt*, termination_token}() -> (
):
alloc_locals
let termination_token = 0
let (__fp__, _) = get_fp_and_pc()
let (returndata_ptr : felt*) = alloc()
local exec_env_ : ExecutionEnvironment = ExecutionEnvironment(calldata_size=calldata_size, calldata_len=calldata_len, calldata=calldata, returndata_size=0, returndata_len=0, returndata=returndata_ptr, to_returndata_size=0, to_returndata_len=0, to_returndata=returndata_ptr)
let exec_env = &exec_env_
let (memory_dict) = default_dict_new(0)
let memory_dict_start = memory_dict
let msize = 0
with exec_env, msize, memory_dict, termination_token:
uint256_mstore(offset=Uint256(low=64, high=0), value=Uint256(low=128, high=0))
let (__warp_subexpr_2 : Uint256) = calldatasize()
let (__warp_subexpr_1 : Uint256) = is_lt(__warp_subexpr_2, Uint256(low=4, high=0))
let (__warp_subexpr_0 : Uint256) = is_zero(__warp_subexpr_1)
__warp_if_0(__warp_subexpr_0)
if termination_token == 1:
default_dict_finalize(memory_dict_start, memory_dict, 0)
return (exec_env.to_returndata_size, exec_env.to_returndata_len, exec_env.to_returndata)
end
assert 0 = 1
jmp rel 0
uint256_mstore(offset=Uint256(low=64, high=0), value=Uint256(low=128, high=0))
let (__warp_subexpr_2 : Uint256) = calldatasize()
let (__warp_subexpr_1 : Uint256) = is_lt(__warp_subexpr_2, Uint256(low=4, high=0))
let (__warp_subexpr_0 : Uint256) = is_zero(__warp_subexpr_1)
__warp_if_0(__warp_subexpr_0)
if termination_token == 1:
return ()
end
assert 0 = 1
jmp rel 0
end
103 changes: 56 additions & 47 deletions tests/yul/ERC20_storage.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ from evm.hashing import uint256_pedersen
from evm.memory import uint256_mload, uint256_mstore
from evm.uint256 import is_eq, is_gt, is_lt, is_zero, slt, u256_add, u256_shl, u256_shr
from evm.yul_api import warp_return
from starkware.cairo.common.alloc import alloc
from starkware.cairo.common.cairo_builtins import BitwiseBuiltin, HashBuiltin
from starkware.cairo.common.default_dict import default_dict_finalize, default_dict_new
from starkware.cairo.common.dict_access import DictAccess
Expand Down Expand Up @@ -38,6 +37,39 @@ end
func evm_storage(arg0_low, arg0_high) -> (res : Uint256):
end
@constructor
func constructor{pedersen_ptr : HashBuiltin*, range_check_ptr, syscall_ptr : felt*}(
calldata_size, calldata_len, calldata : felt*):
alloc_locals
let (memory_dict) = default_dict_new(0)
let memory_dict_start = memory_dict
let msize = 0
with memory_dict, msize:
__constructor_meat()
end
default_dict_finalize(memory_dict_start, memory_dict, 0)
return ()
end

@external
func __main{pedersen_ptr : HashBuiltin*, range_check_ptr, syscall_ptr : felt*}(
calldata_size, calldata_len, calldata : felt*) -> (
returndata_size, returndata_len, returndata : felt*):
alloc_locals
let (__fp__, _) = get_fp_and_pc()
local exec_env_ : ExecutionEnvironment = ExecutionEnvironment(calldata_size=calldata_size, calldata_len=calldata_len, calldata=calldata, returndata_size=0, returndata_len=0, returndata=cast(0, felt*), to_returndata_size=0, to_returndata_len=0, to_returndata=cast(0, felt*))
let exec_env : ExecutionEnvironment* = &exec_env_
let (memory_dict) = default_dict_new(0)
let memory_dict_start = memory_dict
let msize = 0
let termination_token = 0
with exec_env, memory_dict, msize, termination_token:
__main_meat()
end
default_dict_finalize(memory_dict_start, memory_dict, 0)
return (exec_env.to_returndata_size, exec_env.to_returndata_len, exec_env.to_returndata)
end

func update_byte_slice_shift_0{range_check_ptr}(value : Uint256, toInsert : Uint256) -> (
result : Uint256):
alloc_locals
Expand Down Expand Up @@ -85,29 +117,18 @@ func constructor_WARP{pedersen_ptr : HashBuiltin*, range_check_ptr, syscall_ptr
return ()
end

@constructor
func constructor{
pedersen_ptr : HashBuiltin*, range_check_ptr, syscall_ptr : felt*,
bitwise_ptr : BitwiseBuiltin*}(calldata_size, calldata_len, calldata : felt*):
func __constructor_meat{
memory_dict : DictAccess*, msize, pedersen_ptr : HashBuiltin*, range_check_ptr,
syscall_ptr : felt*}() -> ():
alloc_locals
let termination_token = 0
let (returndata_ptr : felt*) = alloc()
let (__fp__, _) = get_fp_and_pc()
local exec_env_ : ExecutionEnvironment = ExecutionEnvironment(calldata_size=calldata_size, calldata_len=calldata_len, calldata=calldata, returndata_size=0, returndata_len=0, returndata=returndata_ptr, to_returndata_size=0, to_returndata_len=0, to_returndata=returndata_ptr)
let exec_env : ExecutionEnvironment* = &exec_env_
let (memory_dict) = default_dict_new(0)
let memory_dict_start = memory_dict
let msize = 0
with memory_dict, msize, exec_env, termination_token:
uint256_mstore(offset=Uint256(low=64, high=0), value=Uint256(low=128, high=0))
let (__warp_subexpr_0 : Uint256) = __warp_constant_0()
if __warp_subexpr_0.low + __warp_subexpr_0.high != 0:
assert 0 = 1
jmp rel 0
end
constructor_WARP()
return ()
uint256_mstore(offset=Uint256(low=64, high=0), value=Uint256(low=128, high=0))
let (__warp_subexpr_0 : Uint256) = __warp_constant_0()
if __warp_subexpr_0.low + __warp_subexpr_0.high != 0:
assert 0 = 1
jmp rel 0
end
constructor_WARP()
return ()
end

func abi_decode{range_check_ptr}(headStart : Uint256, dataEnd : Uint256) -> ():
Expand Down Expand Up @@ -731,31 +752,19 @@ func __warp_if_1{
end
end

@external
func fun_ENTRY_POINT{
pedersen_ptr : HashBuiltin*, range_check_ptr, syscall_ptr : felt*,
bitwise_ptr : BitwiseBuiltin*}(calldata_size, calldata_len, calldata : felt*) -> (
returndata_size : felt, returndata_len : felt, returndata : felt*):
func __main_meat{
exec_env : ExecutionEnvironment*, memory_dict : DictAccess*, msize,
pedersen_ptr : HashBuiltin*, range_check_ptr, syscall_ptr : felt*, termination_token}() -> (
):
alloc_locals
let termination_token = 0
let (__fp__, _) = get_fp_and_pc()
let (returndata_ptr : felt*) = alloc()
local exec_env_ : ExecutionEnvironment = ExecutionEnvironment(calldata_size=calldata_size, calldata_len=calldata_len, calldata=calldata, returndata_size=0, returndata_len=0, returndata=returndata_ptr, to_returndata_size=0, to_returndata_len=0, to_returndata=returndata_ptr)
let exec_env = &exec_env_
let (memory_dict) = default_dict_new(0)
let memory_dict_start = memory_dict
let msize = 0
with exec_env, msize, memory_dict, termination_token:
uint256_mstore(offset=Uint256(low=64, high=0), value=Uint256(low=128, high=0))
let (__warp_subexpr_2 : Uint256) = calldatasize()
let (__warp_subexpr_1 : Uint256) = is_lt(__warp_subexpr_2, Uint256(low=4, high=0))
let (__warp_subexpr_0 : Uint256) = is_zero(__warp_subexpr_1)
__warp_if_1(__warp_subexpr_0)
if termination_token == 1:
default_dict_finalize(memory_dict_start, memory_dict, 0)
return (exec_env.to_returndata_size, exec_env.to_returndata_len, exec_env.to_returndata)
end
assert 0 = 1
jmp rel 0
uint256_mstore(offset=Uint256(low=64, high=0), value=Uint256(low=128, high=0))
let (__warp_subexpr_2 : Uint256) = calldatasize()
let (__warp_subexpr_1 : Uint256) = is_lt(__warp_subexpr_2, Uint256(low=4, high=0))
let (__warp_subexpr_0 : Uint256) = is_zero(__warp_subexpr_1)
__warp_if_1(__warp_subexpr_0)
if termination_token == 1:
return ()
end
assert 0 = 1
jmp rel 0
end
Loading

0 comments on commit 39707e5

Please sign in to comment.