Exemple #1
0
def element_selection(expr, symbol_table):
    instrs = symbol_table['__ expression __'](left_exp(expr), symbol_table)
    # if we are loading the structure then just remove the Load instr, calculate the elements offset and Load that elem
    if is_load(instrs):
        return element_instrs(
            c_type(left_exp(expr)), right_exp(expr), loc(expr), load_instrs=all_but_last(instrs, Loads, loc(expr))
        )

    struct_size, member_size = size(c_type(left_exp(expr))), size_arrays_as_pointers(c_type(expr))
    addr_instrs = add(  # calculate the loaded structured members address
        load_stack_pointer(loc(expr)),
        push(struct_member_offset(c_type(left_exp(expr)), right_exp(expr)), loc(expr)),
        loc(expr)
    )
    return chain(  # copy the element then move it to the base of the structure and deallocate everything else
        set_instr(
            chain(  # load the value in question if its not an array (which is just an address ...)
                (addr_instrs if isinstance(c_type(expr), ArrayType) else load(addr_instrs, member_size, loc(expr))),
                add(load_stack_pointer(loc(expr)), push((struct_size + member_size), loc(expr)), loc(expr)),
            ),
            member_size,
            loc(expr)
        ),
        allocate(-(struct_size - member_size), loc(expr))  # deallocate structure and copied member (set leaves value)
    )
Exemple #2
0
def element_selection(expr, symbol_table):
    instrs = symbol_table['__ expression __'](left_exp(expr), symbol_table)
    # if we are loading the structure then just remove the Load instr, calculate the elements offset and Load that elem
    if is_load(instrs):
        return element_instrs(c_type(left_exp(expr)),
                              right_exp(expr),
                              loc(expr),
                              load_instrs=all_but_last(instrs, Loads,
                                                       loc(expr)))

    struct_size, member_size = size(c_type(
        left_exp(expr))), size_arrays_as_pointers(c_type(expr))
    addr_instrs = add(  # calculate the loaded structured members address
        load_stack_pointer(loc(expr)),
        push(struct_member_offset(c_type(left_exp(expr)), right_exp(expr)),
             loc(expr)), loc(expr))
    return chain(  # copy the element then move it to the base of the structure and deallocate everything else
        set_instr(
            chain(  # load the value in question if its not an array (which is just an address ...)
                (addr_instrs if isinstance(c_type(expr), ArrayType) else load(
                    addr_instrs, member_size, loc(expr))),
                add(load_stack_pointer(loc(expr)),
                    push((struct_size + member_size), loc(expr)), loc(expr)),
            ),
            member_size,
            loc(expr)),
        allocate(-(struct_size - member_size), loc(
            expr))  # deallocate structure and copied member (set leaves value)
    )
Exemple #3
0
def identifier_expression(expr, symbol_table):
    # Defaults to Load, assignment expression will update it to set.
    dec = symbol_table[name(expr)]
    if isinstance(
            c_type(dec),
        (FunctionType,
         ArrayType)):  # Function/Array Types are nothing more than addresses.
        return dec.load_address(loc(expr))
    return load(dec.load_address(loc(expr)),
                size_arrays_as_pointers(c_type(expr)), loc(expr))
Exemple #4
0
def array_subscript(expr, symbol_table):
    assert isinstance(c_type(left_exp(expr)), PointerType) and isinstance(
        c_type(right_exp(expr)), IntegralType)
    expression = symbol_table['__ expression __']
    l = loc(expr)
    addr_instrs = add(
        expression(left_exp(expr), symbol_table),
        multiply(
            cast(  # convert right expression to address type in order to properly multiply ...
                expression(right_exp(expr), symbol_table),
                c_type(right_exp(expr)), void_pointer_type, l),
            push(size(c_type(expr)), l),
            l),
        l,
    )  # Load value unless the return type is also an ArrayTyp
    return addr_instrs if isinstance(c_type(expr), ArrayType) \
        else load(addr_instrs, size_arrays_as_pointers(c_type(expr)), l)
Exemple #5
0
def array_subscript(expr, symbol_table):
    assert isinstance(c_type(left_exp(expr)), PointerType) and isinstance(c_type(right_exp(expr)), IntegralType)
    expression = symbol_table['__ expression __']
    l = loc(expr)
    addr_instrs = add(
        expression(left_exp(expr), symbol_table),
        multiply(
            cast(  # convert right expression to address type in order to properly multiply ...
                expression(right_exp(expr), symbol_table),
                c_type(right_exp(expr)),
                void_pointer_type,
                l
            ),
            push(size(c_type(expr)), l),
            l
        ),
        l,
    )   # Load value unless the return type is also an ArrayTyp
    return addr_instrs if isinstance(c_type(expr), ArrayType) \
        else load(addr_instrs, size_arrays_as_pointers(c_type(expr)), l)
Exemple #6
0
def return_statement(stmnt, symbol_table):
    # TODO: check if we can omit the setting the return value if if it is immediately removed ...
    return_type = c_type(c_type(symbol_table['__ CURRENT FUNCTION __']))
    assert not isinstance(c_type(return_type), ArrayType)
    if isinstance(return_type, VoidType) or not exp(stmnt):
     # just return if void type or expr is empty or size of expression is zero.
        return return_instrs(loc(stmnt))

    return chain(
        cast(symbol_table['__ expression __'](exp(stmnt), symbol_table), c_type(exp(stmnt)), return_type, loc(stmnt)),
        set_instr(
            load(
                add(load_base_stack_pointer(loc(stmnt)), push(size(void_pointer_type), loc(stmnt)), loc(stmnt)),
                size(void_pointer_type),
                loc(stmnt)
            ),
            size(return_type),
            loc(stmnt)
        ),
        # TODO: see if we can remove the following instr, since pop_frame will reset the base and stack pointers
        # allocate(-size(return_type), loc(stmnt)),  # Set leaves the value on the stack
        return_instrs(loc(stmnt))
    )
Exemple #7
0
def patch_comp_left_instrs(instrs, location, value_size):
    return load(                                     # duplicate address ...
        chain(all_but_last(instrs, Loads, location), dup(size(void_pointer_type), location)),
        value_size,
        location
    )
Exemple #8
0
def element_instrs(struct_obj, member_name, location, load_instrs=iter(())):
    instrs = add(load_instrs, push(struct_member_offset(struct_obj, member_name), location), location)
    return instrs if isinstance(c_type(struct_obj.members[member_name]), ArrayType) else \
        load(instrs, size_arrays_as_pointers(c_type(struct_obj.members[member_name])), location)
Exemple #9
0
def identifier_expression(expr, symbol_table):
    # Defaults to Load, assignment expression will update it to set.
    dec = symbol_table[name(expr)]
    if isinstance(c_type(dec), (FunctionType, ArrayType)):  # Function/Array Types are nothing more than addresses.
        return dec.load_address(loc(expr))
    return load(dec.load_address(loc(expr)), size_arrays_as_pointers(c_type(expr)), loc(expr))
Exemple #10
0
def element_instrs(struct_obj, member_name, location, load_instrs=iter(())):
    instrs = add(load_instrs,
                 push(struct_member_offset(struct_obj, member_name), location),
                 location)
    return instrs if isinstance(c_type(struct_obj.members[member_name]), ArrayType) else \
        load(instrs, size_arrays_as_pointers(c_type(struct_obj.members[member_name])), location)
Exemple #11
0
def dereference(expr, symbol_table):
    return load(
        symbol_table['__ expression __'](exp(expr), symbol_table), size_arrays_as_pointers(c_type(expr)), loc(expr)
    )
Exemple #12
0
def dereference(expr, symbol_table):
    return load(symbol_table['__ expression __'](exp(expr), symbol_table),
                size_arrays_as_pointers(c_type(expr)), loc(expr))
Exemple #13
0
def return_instrs(location):  # Jump back, caller is responsible for cleaning up as well as set up.
    return absolute_jump(load(load_base_stack_pointer(location), size(void_pointer_type), location), location)