Skip to content

Commit

Permalink
fix location check in extract32 to include tstorage
Browse files Browse the repository at this point in the history
  • Loading branch information
cyberthirst committed Mar 19, 2024
1 parent ee4b3cc commit 73a4a4b
Showing 1 changed file with 10 additions and 17 deletions.
27 changes: 10 additions & 17 deletions vyper/builtins/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
from vyper.codegen.expr import Expr
from vyper.codegen.ir_node import Encoding, scope_multi
from vyper.codegen.keccak256_helper import keccak256_helper
from vyper.evm.address_space import MEMORY, STORAGE
from vyper.evm.address_space import MEMORY
from vyper.exceptions import (
ArgumentException,
CompilerPanic,
Expand Down Expand Up @@ -828,19 +828,20 @@ class ECMul(_ECArith):
_precompile = 0x7


def _generic_element_getter(op):
def _generic_element_getter(loc):
def f(index):
scale = loc.word_scale
# Indexing is done by words
# - add 'scale' to skip the length slot
# - for byte-addressable locations multiply by 32
# - for word-addressable locations multiply by 1 which will be optimized out
return IRnode.from_list(
[op, ["add", "_sub", ["add", 32, ["mul", 32, index]]]], typ=INT128_T
[loc.load_op, ["add", "_sub", ["add", scale, ["mul", scale, index]]]], typ=INT128_T
)

return f


def _storage_element_getter(index):
return IRnode.from_list(["sload", ["add", "_sub", ["add", 1, index]]], typ=INT128_T)


class Extract32(BuiltinFunctionT):
_id = "extract32"
_inputs = [("b", BytesT.any()), ("start", IntegerT.unsigneds())]
Expand Down Expand Up @@ -875,18 +876,10 @@ def build_IR(self, expr, args, kwargs, context):
sub, index = args
ret_type = kwargs["output_type"]

# Get length and specific element
if sub.location == STORAGE:
lengetter = IRnode.from_list(["sload", "_sub"], typ=INT128_T)
elementgetter = _storage_element_getter

else:
op = sub.location.load_op
lengetter = IRnode.from_list([op, "_sub"], typ=INT128_T)
elementgetter = _generic_element_getter(op)
lengetter = IRnode.from_list([sub.location.load_op, "_sub"], typ=INT128_T)
elementgetter = _generic_element_getter(sub.location)

# TODO rewrite all this with cache_when_complex and bitshifts

# Special case: index known to be a multiple of 32
if isinstance(index.value, int) and not index.value % 32:
o = IRnode.from_list(
Expand Down

0 comments on commit 73a4a4b

Please sign in to comment.