Skip to content

Commit

Permalink
refactor: initcode generation (#3574)
Browse files Browse the repository at this point in the history
move internal function generation to after ctor generation. prior to
this commit, the existing code relies on the fact that the code
generation of runtime internal functions properly sets the frame
information of the ctor's callees. if this precondition is not met in
the future, the compiler could panic because the memory allocation info
will not be available.

chainsec june 2023 review 6.2
  • Loading branch information
charles-cooper authored Aug 31, 2023
1 parent fa89ca2 commit ef1c589
Showing 1 changed file with 16 additions and 12 deletions.
28 changes: 16 additions & 12 deletions vyper/codegen/module.py
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,20 @@ def generate_ir_for_module(global_ctx: GlobalContext) -> tuple[IRnode, IRnode]:
deploy_code: List[Any] = ["seq"]
immutables_len = global_ctx.immutable_section_bytes
if init_function:
# cleanly rerun codegen for internal functions with `is_ctor_ctx=True`
ctor_internal_func_irs = []
internal_functions = [f for f in runtime_functions if _is_internal(f)]
for f in internal_functions:
init_func_t = init_function._metadata["type"]
if f.name not in init_func_t.recursive_calls:
# unreachable code, delete it
continue

func_ir = _ir_for_internal_function(f, global_ctx, is_ctor_context=True)
ctor_internal_func_irs.append(func_ir)

# generate init_func_ir after callees to ensure they have analyzed
# memory usage.
# TODO might be cleaner to separate this into an _init_ir helper func
init_func_ir = _ir_for_fallback_or_ctor(init_function, global_ctx, is_ctor_context=True)

Expand All @@ -468,19 +482,9 @@ def generate_ir_for_module(global_ctx: GlobalContext) -> tuple[IRnode, IRnode]:
deploy_code.append(["iload", max(0, immutables_len - 32)])

deploy_code.append(init_func_ir)

deploy_code.append(["deploy", init_mem_used, runtime, immutables_len])

# internal functions come after everything else
internal_functions = [f for f in runtime_functions if _is_internal(f)]
for f in internal_functions:
init_func_t = init_function._metadata["type"]
if f.name not in init_func_t.recursive_calls:
# unreachable code, delete it
continue

func_ir = _ir_for_internal_function(f, global_ctx, is_ctor_context=True)
deploy_code.append(func_ir)
# internal functions come at end of initcode
deploy_code.extend(ctor_internal_func_irs)

else:
if immutables_len != 0:
Expand Down

0 comments on commit ef1c589

Please sign in to comment.