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 3214c99
Show file tree
Hide file tree
Showing 34 changed files with 1,682 additions and 1,059 deletions.
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
87 changes: 46 additions & 41 deletions tests/yul/address.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ from evm.exec_env import ExecutionEnvironment
from evm.memory import uint256_mstore
from evm.uint256 import is_eq, is_lt, is_zero, slt, u256_add, u256_shr
from evm.yul_api import address, 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 All @@ -18,27 +17,46 @@ func __warp_constant_0() -> (res : Uint256):
end

@constructor
func constructor{
pedersen_ptr : HashBuiltin*, range_check_ptr, syscall_ptr : felt*,
bitwise_ptr : BitwiseBuiltin*}(calldata_size, calldata_len, calldata : felt*):
func constructor{range_check_ptr}(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{range_check_ptr, syscall_ptr : felt*}(
calldata_size, calldata_len, calldata : felt*) -> (
returndata_size, returndata_len, returndata : 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)
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
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
else:
return ()
end
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 __constructor_meat{memory_dict : DictAccess*, msize, range_check_ptr}() -> ():
alloc_locals
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
else:
return ()
end
end

Expand Down Expand Up @@ -120,31 +138,18 @@ 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, 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
Loading

0 comments on commit 3214c99

Please sign in to comment.