def pre_alloc(self, val_expr, type_expr, copy=False, network=None): def alloc_selector(val_node, type_node, res, type_path): prim = type_node['prim'] if prim in ['list', 'set']: return res if prim in ['pair', 'or']: return {'prim': val_node['prim'], 'args': res} elif prim == 'option' and val_node['prim'] == 'Some': return {'prim': val_node['prim'], 'args': res} elif prim == 'map': return list(map(make_elt, res)) elif prim == 'big_map': if isinstance(val_node, list): return self._pre_alloc(val_node, type_node) elif copy: return self._pre_copy(val_node, type_node, network=network) else: return self._pre_remove(val_node, type_node, network=network) return val_node val_expr = parse_expression(val_expr, type_expr, alloc_selector) return StackItem.parse(val_expr=val_expr, type_expr=type_expr)
def do_unpack(ctx: Context, prim, args, annots): top = ctx.pop1() assert_stack_type(top, Bytes) try: val_expr = unpack(data=bytes(top), type_expr=args[0]) item = StackItem.parse(val_expr=val_expr, type_expr=args[0]) res = Option.some(item) except Exception as e: ctx.print(f'failed: {e}') res = Option.none(args[0]) ctx.push(res, annots=annots)
def find(self, big_map: BigMap, key: StackItem) -> 'StackItem': if key in big_map: return big_map.find(key) if int(big_map) >= 0: if big_map.val_expr.get('_network'): v_val_expr = self._get_big_map_val(big_map, key) if v_val_expr: return StackItem.parse( val_expr=v_val_expr, type_expr=big_map.type_expr['args'][1]) else: assert int( big_map) in self.maps, f'#{int(big_map)} is not allocated' return self.maps[int(big_map)].find(key)
def diff(self, storage: StackItem): res = [] alloc_id = self.alloc_id maybe_remove = self.maybe_remove def diff_selector(val_node, type_node, val, type_path): nonlocal res, alloc_id, maybe_remove prim = type_node['prim'] if prim in ['list', 'set']: return val if prim in ['pair', 'or']: return {'prim': val_node['prim'], 'args': val} elif prim == 'option' and val_node['prim'] == 'Some': return {'prim': val_node['prim'], 'args': val} elif prim == 'map': return list(map(make_elt, val)) elif prim == 'big_map': assert isinstance(val, int), f'expected big map pointer' if val < 0: big_map_id = alloc_id if val_node.get('_copy'): res.append({ 'action': 'copy', 'source_big_map': str(val_node['_copy']), 'destination_big_map': str(big_map_id) }) else: res.append({ 'action': 'alloc', 'big_map': str(big_map_id), 'key_type': type_node['args'][0], 'value_type': type_node['args'][1] }) alloc_id += 1 else: big_map_id = val maybe_remove.remove(big_map_id) res.extend( map(lambda x: { **x, 'big_map': str(big_map_id) }, val_node['_diff'].values())) return {'int': str(big_map_id)} else: return val_node val_expr = parse_expression(storage.val_expr, storage.type_expr, diff_selector) res.extend([{'action': 'remove', 'big_map': x} for x in maybe_remove]) return StackItem.parse(val_expr, storage.type_expr), res
def push(self, item: StackItem, annots=None): assert_stack_item(item) self.stack.insert(self.protected, item.rename(annots)) self.pushed = True self.print(f'push {repr(item)}')
def do_push(ctx: Context, prim, args, annots): item = StackItem.parse(val_expr=args[1], type_expr=args[0]) assert_pushable(item.type_expr) ctx.push(item, annots=annots)