Exemple #1
0
 def store_back_address(self, opcodes: OpcodeList):
     """
     INPUT:  | EoS | New Back address
     OUTPUT: | EoS |
     """
     self.load_back_address_addr(opcodes)
     opcodes.add('MSTORE')
Exemple #2
0
 def load_atom_value(self, opcodes: OpcodeList, atom_address: int):
     """
     INPUT:  | EoS |
     OUTPUT: | EoS | Value of Atom on provided address |
     """
     self.load_atom_address(opcodes, atom_address)
     opcodes.add('MLOAD')
Exemple #3
0
 def load_cur_atom_counter(self, opcodes: OpcodeList):
     """
     INPUT:  | EoS |
     OUTPUT: | EoS | Value of Current Atom counter
     """
     self.load_cur_atom_counter_addr(opcodes)
     opcodes.add('MLOAD')
Exemple #4
0
 def load_back_address(self, opcodes: OpcodeList):
     """
     INPUT:  | EoS |
     OUTPUT: | EoS | Current Back address
     """
     self.load_back_address_addr(opcodes)
     opcodes.add('MLOAD')
Exemple #5
0
 def store_new_gap(self, opcodes: OpcodeList):
     """
     INPUT:  | EoS | New gap
     OUTPUT: | EoS |
     """
     opcodes.add('PUSH', dec_to_hex(0, 2 * self.__address_length))
     opcodes.add('MSTORE')
Exemple #6
0
 def load_prev_gap(self, opcodes: OpcodeList):
     """
     INPUT:  | EoS |
     OUTPUT: | EoS | Address of previout frame's start
     """
     self.load_cur_gap(opcodes)
     opcodes.add('MLOAD')
Exemple #7
0
 def store_atom_value(self, opcodes: OpcodeList, atom_address: int):
     """
     INPUT:  | EoS | New value of Atom
     OUTPUT: | EoS |
     """
     self.load_atom_address(opcodes, atom_address)
     opcodes.add('MSTORE')
Exemple #8
0
 def load_cur_gap(self, opcodes: OpcodeList):
     """
     INPUT:  | EoS |
     OUTPUT: | EoS | Gap of current frame |
     """
     opcodes.add('PUSH', dec_to_hex(0, 2 * self.__address_length))
     opcodes.add('MLOAD')
Exemple #9
0
 def calc_new_frame_gap(self, opcodes: OpcodeList):
     """
     INPUT:  | EoS |
     OUTPUT: | EoS | Gap of new frame
     """
     self.load_cur_gap(opcodes)
     self.calc_cur_frame_size(opcodes)
     opcodes.add('ADD')
Exemple #10
0
 def load_back_address_addr(self, opcodes: OpcodeList):
     """
     INPUT:  | EoS |
     OUTPUT: | EoS | Address of Current Back address
     """
     self.load_cur_gap(opcodes)
     opcodes.add('PUSH', dec_to_hex(0x40, 2 * self.__address_length))
     opcodes.add('ADD')
Exemple #11
0
    def __plus(self, body: AstNode, ctx: Context, opcodes: OpcodeList):
        """
        INPUT  (2): | EoS | Value 1 | Value 2
        OUTPUT (1): | EoS | Sum of values
        """
        assert len(body.child_nodes) == 3

        opcodes.add('ADD')
Exemple #12
0
    def __and(self, body: AstNode, ctx: Context, opcodes: OpcodeList):
        """
        INPUT  (2): | EoS | v1 (bool) | v2 (bool)
        OUTPUT (1): | EoS | v1 AND v2 (bool)
        """
        assert len(body.child_nodes) == 3

        opcodes.add('AND')
Exemple #13
0
    def __greater(self, body: AstNode, ctx: Context, opcodes: OpcodeList):
        """
        INPUT  (2): | EoS | Value 1 | Value 2
        OUTPUT (1): | EoS | Is Value 1 greater than Value 2
        """
        assert len(body.child_nodes) == 3

        opcodes.add('LT')
Exemple #14
0
 def load_cur_atom_counter_addr(self, opcodes: OpcodeList):
     """
     INPUT:  | EoS |
     OUTPUT: | EoS | Address of Current Atom counter
     """
     self.load_cur_gap(opcodes)
     opcodes.add('PUSH', dec_to_hex(0x20, 2 * self.__address_length))
     opcodes.add('ADD')
Exemple #15
0
    def __equal(self, body: AstNode, ctx: Context, opcodes: OpcodeList):
        """
        INPUT  (2): | EoS | Value 1 | Value 2
        OUTPUT (1): | EoS | Does value 1 equals value 2 (bool)
        """
        assert len(body.child_nodes) == 3

        opcodes.add('EQ')
Exemple #16
0
    def __times(self, body: AstNode, ctx: Context, opcodes: OpcodeList):
        """
        INPUT  (2): | EoS | Value 1 | Value 2
        OUTPUT (1): | EoS | Value 1 * Value 2
        """
        assert len(body.child_nodes) == 3

        opcodes.add('MUL')
Exemple #17
0
    def __greatereq(self, body: AstNode, ctx: Context, opcodes: OpcodeList):
        """
        INPUT  (2): | EoS | Value 1 | Value 2
        OUTPUT (1): | EoS | Does Value 1 less or equals Value (bool)
        """
        assert len(body.child_nodes) == 3

        opcodes.add('GT')
        opcodes.add('ISZERO')
Exemple #18
0
    def __not(self, body: AstNode, ctx: Context, opcodes: OpcodeList):
        """
        INPUT  (1): | EoS | value (bool)
        OUTPUT (1): | EoS | !value (bool)
        """
        assert len(body.child_nodes) == 2

        opcodes.add('PUSH', dec_to_hex(0, 2 * self.address_length))
        opcodes.add('EQ')
 def __break(self, body: AstNode, ctx: Context, opcodes: OpcodeList):
     """
     INPUT:  | EoS |
     OUTPUT: | EoS |
     """
     assert len(body.child_nodes) == 1
     opcodes.add('PUSH', dec_to_hex(0, 2 * self.__address_length))
     opcodes.add('JUMP', dec_to_hex(self.__current_while_id, 2 * self.__address_length))
     pass
Exemple #20
0
 def load_atom_address(self, opcodes: OpcodeList, atom_address: int):
     """
     INPUT:  | EoS |
     OUTPUT: | EoS | Address of Atom on provided address
     """
     self.load_cur_gap(opcodes)
     opcodes.add('PUSH', dec_to_hex(atom_address,
                                    2 * self.__address_length))
     opcodes.add('ADD')
Exemple #21
0
    def __divide(self, body: AstNode, ctx: Context, opcodes: OpcodeList):
        """
        INPUT  (2): | EoS | Value 1 | Value 2
        OUTPUT (1): | EoS | Value 1 // Value 2
        """
        assert len(body.child_nodes) == 3

        opcodes.add('SWAP1')
        opcodes.add('DIV')
Exemple #22
0
    def add_frame(self, opcodes: OpcodeList):
        """
        INPUT:  | EoS | Arg1 | ... | ArgN | Back Address |
        OUTPUT: | EoS | Arg1 | ... | ArgN |
        """
        self.load_cur_gap(opcodes)
        self.calc_new_frame_gap(opcodes)
        opcodes.add('MSTORE')

        self.calc_new_frame_gap(opcodes)
        self.store_new_gap(opcodes)

        # Back address gone
        self.store_back_address(opcodes)
Exemple #23
0
    def calc_cur_frame_size(self, opcodes: OpcodeList):
        """
        INPUT:  | EoS |
        OUTPUT: | EoS | Size of current frame
        """
        opcodes.add(
            'PUSH',
            dec_to_hex(self.__frame_service_atoms * 0x20,
                       2 * self.__address_length))

        self.load_cur_atom_counter(opcodes)
        opcodes.add('PUSH', dec_to_hex(32, 2 * self.__address_length))
        opcodes.add('MUL')

        opcodes.add('ADD')
Exemple #24
0
    def __nonequal(self, body: AstNode, ctx: Context, opcodes: OpcodeList):
        """
        INPUT  (2): | EoS | Value 1 | Value 2
        OUTPUT (1): | EoS | Does Value 1 differs from Value 2 (bool)
        """
        assert len(body.child_nodes) == 3

        opcodes.add('EQ')
        opcodes.add('PUSH', dec_to_hex(0, 2 * self.address_length))
        opcodes.add('EQ')
Exemple #25
0
    def __read(self, body: AstNode, ctx: Context, opcodes: OpcodeList):
        """
        INPUT  (0): | EoS |
        OUTPUT (1): | EoS | Value from input
        """
        assert len(body.child_nodes) == 2

        opcodes.add('PUSH', dec_to_hex(0x20, 2 * self.address_length))
        opcodes.add('MUL')

        opcodes.add('CALLDATALOAD')
    def call(self, call_body: AstNode, ctx: Context, opcodes: OpcodeList):
        assert call_body.type == AstNodeType.List
        assert call_body.child_nodes[
            0].type == AstNodeType.Literal or call_body.child_nodes[
                0].type == AstNodeType.Atom

        # Prepare back address, part 1
        opcodes.add('PUSH')
        back_address = len(opcodes.list) - 1

        # Jump into the function
        opcodes.add(
            'PUSH',
            dec_to_hex(self.__funcs[call_body.child_nodes[0].value],
                       2 * self.address_length))
        opcodes.add('JUMP')

        # Prepare back address, part 2
        opcodes.add('JUMPDEST')
        opcodes.list[back_address].extra_value = dec_to_hex(
            opcodes.list[-1].id, 2 * self.address_length)
    def declare_function(self, call_body: AstNode, ctx: Context, opcodes: OpcodeList):
        assert call_body.type == AstNodeType.List
        assert call_body.child_nodes[0].type == AstNodeType.Literal or call_body.child_nodes[0].type == AstNodeType.Atom
        assert call_body.child_nodes[0].value == 'func'
        """
        INPUT:  | EoS | Arg1 | ... | ArgN | Back address
        OUTPUT: | EoS |
        """
        # Set entry point
        opcodes.add('JUMPDEST')
        Declared().add(call_body.child_nodes[1].value, opcodes.list[-1].id)

        # Make new stack frame
        # Back address gone
        VirtualStackHelper().add_frame(opcodes)

        # Set atom counter, part 1
        opcodes.add('PUSH')
        func_atom_counter = len(opcodes.list) - 1
        VirtualStackHelper().load_cur_atom_counter_addr(opcodes)
        opcodes.add('MSTORE')

        # Declare arguments in context
        # Args gone
        for arg_name in reversed(call_body.child_nodes[2].child_nodes):
            assert arg_name.type == AstNodeType.Atom
            address, is_new = ctx.get_atom_addr(arg_name.value)
            VirtualStackHelper().store_atom_value(opcodes, address)

        # Generate body
        self.process_call(call_body.child_nodes[3], ctx, opcodes)

        # Set atom counter, part 2
        opcodes.list[func_atom_counter].extra_value = \
            dec_to_hex(ctx.id_counter - self.__frame_service_atoms, 2 * self.__address_length)

        # Remove frame and leave function
        VirtualStackHelper().load_back_address(opcodes)
        VirtualStackHelper().remove_frame(opcodes)
        opcodes.add('JUMP')
Exemple #28
0
 def init_stack(self, opcodes: OpcodeList):
     """
     NO SIDE EFFECTS
     """
     # Set ZERO FRAME (prog frame) gap = 0x40
     opcodes.add('PUSH', dec_to_hex(0x40, 2 * self.__address_length))
     opcodes.add('PUSH', dec_to_hex(0, 2 * self.__address_length))
     opcodes.add('MSTORE')
     # Init zero frame
     # Set start of previous frame and back address as 0x00
     opcodes.add('PUSH', dec_to_hex(0x0, 2 * self.__address_length))
     opcodes.add('DUP1')
     opcodes.add('PUSH', dec_to_hex(0x40, 2 * self.__address_length))
     opcodes.add('MSTORE')
     opcodes.add('PUSH', dec_to_hex(0x40 + 0x40, 2 * self.__address_length))
     opcodes.add('MSTORE')
     # Set counter of atoms as 0x00
     opcodes.add('PUSH', dec_to_hex(0x0, 2 * self.__address_length))
     opcodes.add('PUSH', dec_to_hex(0x40 + 0x20, 2 * self.__address_length))
     opcodes.add('MSTORE')
    def __while(self, body: AstNode, ctx: Context, opcodes: OpcodeList, generator: Generator):
        """
        INPUT:  | EoS |
        OUTPUT: | EoS |
        """
        assert len(body.child_nodes) == 3
        prev_while = self.__current_while_id
        self.__current_while_id = self.__while_count
        self.__while_count += 1
        opcodes.add('JUMPDEST', dec_to_hex(self.__current_while_id, 2 * self.__address_length))
        jumpdest_to_condition_check_id = dec_to_hex(opcodes.list[-1].id, 2 * self.__address_length)
        generator.process_call(body.child_nodes[1], ctx, opcodes)
        # if true: jump to while body
        opcodes.add('PUSH')
        jump_to_while_body = len(opcodes.list) - 1
        opcodes.add('JUMPI')
        # else: jump to while end
        opcodes.add('PUSH')
        jump_to_while_end = len(opcodes.list) - 1
        opcodes.add('JUMP')

        # while body
        opcodes.add('JUMPDEST')
        opcodes.list[jump_to_while_body].extra_value = dec_to_hex(opcodes.list[-1].id, 2 * self.__address_length)
        generator.process_call(body.child_nodes[2], ctx, opcodes)
        opcodes.add('PUSH', jumpdest_to_condition_check_id)
        opcodes.add('JUMP')
        # while end
        opcodes.add('JUMPDEST')
        opcodes.list[jump_to_while_end].extra_value = dec_to_hex(opcodes.list[-1].id, 2 * self.__address_length)
        for i in range(len(opcodes.list)):
            if opcodes.list[i].name == 'JUMP' and opcodes.list[i].extra_value == dec_to_hex(self.__current_while_id,
                                                                                            2 * self.__address_length):
                opcodes.list[i - 1].extra_value = dec_to_hex(opcodes.list[-1].id, 2 * self.__address_length)
                opcodes.list[i].extra_value = None
        BuiltIns.current_while = prev_while
Exemple #30
0
    def __return(self, body: AstNode, ctx: Context, opcodes: OpcodeList):
        """
        INPUT  (1): | EoS | Some value
        OUTPUT (0): | EoS |
        """
        assert len(body.child_nodes) == 2

        if ctx.is_prog:
            opcodes.add('PUSH', dec_to_hex(0, 2 * self.address_length))
            opcodes.add('MSTORE')
            opcodes.add('PUSH', dec_to_hex(32, 2 * self.address_length))
            opcodes.add('PUSH', dec_to_hex(0, 2 * self.address_length))
            opcodes.add('RETURN')
        else:
            VirtualStackHelper().load_back_address(opcodes)
            VirtualStackHelper().remove_frame(opcodes)
            opcodes.add('JUMP')