107 lines
3.0 KiB
Python
107 lines
3.0 KiB
Python
from vyper.parser import (
|
|
parser,
|
|
)
|
|
from vyper.parser.global_context import (
|
|
GlobalContext
|
|
)
|
|
from vyper.types import (
|
|
ByteArrayType,
|
|
get_size_of_type,
|
|
MappingType,
|
|
StringType,
|
|
StructType,
|
|
TupleType,
|
|
)
|
|
from vyper import compile_lll
|
|
from vyper import optimizer
|
|
from vyper.parser.parser import parse_to_lll
|
|
|
|
|
|
def serialise_var_rec(var_rec):
|
|
if isinstance(var_rec.typ, ByteArrayType):
|
|
type_str = 'bytes[%s]' % var_rec.typ.maxlen
|
|
_size = get_size_of_type(var_rec.typ) * 32
|
|
elif isinstance(var_rec.typ, StringType):
|
|
type_str = 'string[%s]' % var_rec.typ.maxlen
|
|
_size = get_size_of_type(var_rec.typ) * 32
|
|
elif isinstance(var_rec.typ, StructType):
|
|
type_str = 'struct[%s]' % var_rec.typ.name
|
|
_size = get_size_of_type(var_rec.typ) * 32
|
|
elif isinstance(var_rec.typ, TupleType):
|
|
type_str = 'tuple'
|
|
_size = get_size_of_type(var_rec.typ) * 32
|
|
elif isinstance(var_rec.typ, MappingType):
|
|
type_str = str(var_rec.typ)
|
|
_size = 0
|
|
else:
|
|
type_str = str(var_rec.typ)
|
|
_size = get_size_of_type(var_rec.typ) * 32
|
|
|
|
out = {
|
|
'type': type_str,
|
|
'size': _size,
|
|
'position': var_rec.pos
|
|
}
|
|
return out
|
|
|
|
|
|
def produce_source_map(code, interface_codes=None):
|
|
global_ctx = GlobalContext.get_global_context(
|
|
parser.parse_to_ast(code),
|
|
interface_codes=interface_codes
|
|
)
|
|
asm_list = compile_lll.compile_to_assembly(
|
|
optimizer.optimize(
|
|
parse_to_lll(
|
|
code,
|
|
runtime_only=True,
|
|
interface_codes=interface_codes
|
|
)
|
|
)
|
|
)
|
|
c, line_number_map = compile_lll.assembly_to_evm(asm_list)
|
|
source_map = {
|
|
'globals': {},
|
|
'locals': {},
|
|
'line_number_map': line_number_map
|
|
}
|
|
source_map['globals'] = {
|
|
name: serialise_var_rec(var_record)
|
|
for name, var_record in global_ctx._globals.items()
|
|
}
|
|
# Fetch context for each function.
|
|
lll = parser.parse_tree_to_lll(
|
|
parser.parse_to_ast(code),
|
|
code,
|
|
interface_codes=interface_codes,
|
|
runtime_only=True
|
|
)
|
|
contexts = {
|
|
f.func_name: f.context
|
|
for f in lll.args[1:] if hasattr(f, 'context')
|
|
}
|
|
|
|
prev_func_name = None
|
|
for _def in global_ctx._defs:
|
|
if _def.name != '__init__':
|
|
func_info = {
|
|
'from_lineno': _def.lineno,
|
|
'variables': {}
|
|
}
|
|
# set local variables for specific function.
|
|
context = contexts[_def.name]
|
|
func_info['variables'] = {
|
|
var_name: serialise_var_rec(var_rec)
|
|
for var_name, var_rec in context.vars.items()
|
|
}
|
|
|
|
source_map['locals'][_def.name] = func_info
|
|
# set to_lineno
|
|
if prev_func_name:
|
|
source_map['locals'][prev_func_name]['to_lineno'] = _def.lineno
|
|
prev_func_name = _def.name
|
|
|
|
source_map['locals'][_def.name]['to_lineno'] = len(code.splitlines())
|
|
|
|
return source_map
|