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

Commit

Permalink
Merge 80752ce into 9c23baf
Browse files Browse the repository at this point in the history
  • Loading branch information
meevee98 committed Aug 20, 2020
2 parents 9c23baf + 80752ce commit 3e4521c
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 23 deletions.
3 changes: 3 additions & 0 deletions .travis.yml
Expand Up @@ -7,6 +7,9 @@ matrix:
- python: 3.7
dist: xenial
sudo: true
- python: 3.8
dist: xenial
sudo: true

env:
- SKIP_DEPS_CHECK=1
Expand Down
27 changes: 18 additions & 9 deletions boa/code/method.py
Expand Up @@ -103,11 +103,12 @@ def args(self):
def stacksize(self):
return self.bytecode.argcount + len(self._blocks) + 2

def __init__(self, module, block, module_name, extra):
def __init__(self, module, block, module_name, extra, related_blocks=None):
self.module = module
self.block = block
self.module_name = module_name
self._extra = extra
self._related_blocks = related_blocks

method_block_index = self.get_code_block_index(self.block)
if method_block_index is None:
Expand Down Expand Up @@ -182,37 +183,45 @@ def setup(self):
self._expressions = []

def evaluate_annotations(self, index):
if self._related_blocks:
blocks = []
for block in self._related_blocks:
blocks.extend(block)
index = len(blocks)
else:
blocks = self.block

block_index = 0
args_types = []
while block_index < index:
if self.block[block_index].opcode == pyop.LOAD_NAME and 'abi' in self.block[block_index].arg:
block_index = self.include_abi_info(block_index)
if blocks[block_index].opcode == pyop.LOAD_NAME and 'abi' in blocks[block_index].arg:
block_index = self.include_abi_info(blocks, block_index)
else:
block_index = block_index + 1

def include_abi_info(self, start_index):
def include_abi_info(self, block, start_index):
index = start_index
load_method_instr = self.block[index]
load_method_instr = block[index]

while load_method_instr.opcode != pyop.LOAD_METHOD and load_method_instr.opcode != pyop.LOAD_NAME:
index = index + 1
load_method_instr = self.block[index]
load_method_instr = block[index]

args_types = []
if load_method_instr.arg == 'abi_method' or load_method_instr.arg == 'abi_entry_point':
index = index + 1
arg_instr = self.block[index]
arg_instr = block[index]
while arg_instr.opcode == pyop.LOAD_NAME or arg_instr.opcode == pyop.LOAD_ATTR:
if abi.is_abi_type(arg_instr.arg):
args_types.append(arg_instr.arg)
index = index + 1
arg_instr = self.block[index]
arg_instr = block[index]

# return type not specified
if len(args_types) == len(self.args):
args_types.append(abi.Void)

if arg_instr.opcode == pyop.CALL_METHOD:
if arg_instr.opcode in [pyop.CALL_METHOD, pyop.CALL_FUNCTION]:
index = index + 1

if load_method_instr.arg == 'abi_entry_point':
Expand Down
47 changes: 33 additions & 14 deletions boa/code/module.py
Expand Up @@ -201,12 +201,30 @@ def build(self):
elif type == BlockType.APPCALL_REG:
self.app_call_registrations.append(BoaAppcall(blk))

last_m = None
for m in new_method_blks:

new_method = BoaMethod(self, m, self.module_name, self._extra_instr)
new_method = BoaMethod(self, m, self.module_name, self._extra_instr, self._method_related_blocks(m, last_m))

if not self.has_method(new_method.full_name):
self.methods.append(new_method)
last_m = m

def _method_related_blocks(self, method_block, last_method_block):
# decorators were included in the same block as the method until python 3.7
# in python 3.8, they're in different blocks, that are in the `_extra_instr`
if sys.version_info >= (3, 8):
block = method_block
if last_method_block:
block = last_method_block.next_block
elif len(self._extra_instr) > 0:
block = self._extra_instr[0]

extra_instr = []
while block is not None and block is not method_block:
extra_instr.append(block)
block = block.next_block
return extra_instr

def write(self):
"""
Expand Down Expand Up @@ -375,19 +393,20 @@ def to_s(self):
return "\n".join(output)

def include_abi_method(self, method, types):
num_methods = len(method.args)
num_types = len(types)

args_types = {}
# params and return types
if num_types == num_methods + 1:
for index, arg in enumerate(method.args):
args_types[arg] = types[index]
args_types['return'] = types[num_types - 1]
else:
raise Exception("Number of arguments for the abi is incompatible with the function '%s'" % method.full_name)

self.abi_methods[method.full_name] = args_types
if method.full_name not in self.abi_methods:
num_methods = len(method.args)
num_types = len(types)

args_types = {}
# params and return types
if num_types == num_methods + 1:
for index, arg in enumerate(method.args):
args_types[arg] = types[index]
args_types['return'] = types[num_types - 1]
else:
raise Exception("Number of arguments for the abi is incompatible with the function '%s'" % method.full_name)

self.abi_methods[method.full_name] = args_types

def set_abi_entry_point(self, method, types):
if self.abi_entry_point is None:
Expand Down

0 comments on commit 3e4521c

Please sign in to comment.