Пример #1
0
def gen_for_stmt(info, node, method_obj):
    output = []

    # Initialize, if any.
    if len(node[0].children) == 1:
        if node[0][0].name == 'LocalVariableDeclaration':
            output.extend(gen_local_variable_decl(info, node[0][0], method_obj))
        else: # expression
            output.extend(expression.gen_expr(info, node[0][0], method_obj))

    loop_lbl = info.get_jump_label()
    end_lbl = info.get_jump_label()

    output.append(loop_lbl + ':')

    # Generate cond, if any.
    if len(node[1].children) == 1:
        output.extend(expression.gen_expr(info, node[1][0], method_obj))
        output.append('mov ebx, 0')
        output.append('cmp eax, ebx')
        output.append('je %s' % end_lbl) # If false, go to end.

    # Generate body, if any.
    if len(node[3].children) == 1:
        output.extend(gen_stmt(info, node[3][0], method_obj)) 

    # Generate update, if any.
    if len(node[2].children) == 1:
        output.extend(expression.gen_expr(info, node[2][0], method_obj))

    output.append('jmp %s' % loop_lbl)

    output.append(end_lbl + ':')

    return output
Пример #2
0
def gen_static_field_decl(info, node):
    assert node.name == 'FieldDeclaration'
    output = []

    # If there's no initializer, nothing needs to be done. Otherwise, generate
    # the expression code and set it.
    initializer = node[3]
    if len(initializer.children) == 1:
        output.extend(expression.gen_expr(info, initializer[0], None))
        output.append('mov [%s], eax' % node.label)

    return output
Пример #3
0
def gen_return_stmt(info, node, method_obj):
    output = []

    if len(node.children) != 0:
        output.extend(expression.gen_expr(info, node[0], method_obj))
        pass
    else:
        output.append("mov eax, %d" % 0xDEADBEEF)

    output.append("jmp END~%s" % (method_obj.node.label))

    return output
Пример #4
0
def gen_local_variable_decl(info, node, method_obj):
    output = ["; gen_local_variable_decl"]

    # Generate the initialization code.
    output.extend(expression.gen_expr(info, node[2][0], method_obj))

    # Get the offset.
    offset = node.frame_offset * 4
    output.append('mov ebx, %d' % offset)

    # Calculate address and assign.
    output.append('mov [ebp+ebx], eax')

    return output
Пример #5
0
def gen_while_stmt(info, node, method_obj):
    output = []

    loop_lbl = info.get_jump_label()
    end_lbl = info.get_jump_label()

    output.append(loop_lbl + ':')

    # Generate condition.
    output.extend(expression.gen_expr(info, node[0], method_obj))
    output.append('mov ebx, 0')
    output.append('cmp eax, ebx')
    output.append('je %s' % end_lbl) # If false, go to end.

    # Loop body.
    output.extend(gen_stmt(info, node[1], method_obj))

    output.append('jmp %s' % loop_lbl)

    output.append(end_lbl + ':')

    return output
Пример #6
0
def gen_if_stmt(info, node, method_obj):
    output = []

    else_label = info.get_jump_label()
    end_label = info.get_jump_label()

    # Check condition.
    output.extend(expression.gen_expr(info, node[0], method_obj))
    output.append('mov ebx, 0')
    output.append('cmp eax, ebx')
    output.append('je %s' % else_label) # statement is false, jump to else

    # True path.
    output.extend(gen_stmt(info, node[1], method_obj))
    output.append('jmp %s' % end_label)

    # False path.
    output.append(else_label + ':')
    if len(node.children) == 3: # If there's an else condition, gen some code
        output.extend(gen_stmt(info, node[2], method_obj))

    output.append(end_label + ':')

    return output
Пример #7
0
def gen_expr_stmt(info, node, method_obj):
    output = []
    output.extend(expression.gen_expr(info, node[0], method_obj))
    return output
Пример #8
0
def gen_constructor(info, constructor_obj):
    node = constructor_obj.node
    assert node.name == 'ConstructorDeclaration'

    # Preprocessing:
    # Assign frame pointer offsets to each parameter and local variable
    # declaration node.
    param_start_index = len(node.find_child('Parameters').children) + 1
    for decl in node.find_child('Parameters').children:
        decl.frame_offset = param_start_index
        param_start_index -= 1

    local_var_start_index = -1
    num_vars = 0
    all_local_decls = list(node.select(['LocalVariableDeclaration']))
    for decl in all_local_decls:
        decl.frame_offset = local_var_start_index
        local_var_start_index -= 1
        num_vars += 1

    output = []

    # Preamble for constructor.
    output.append(constructor_obj.node.label + ':')

    # save ebp & esp
    output.extend([
        "push ebp",
        "mov ebp, esp",
    ])
    # make room for local vars in the stack
    output.append("sub esp, %d" % (num_vars*4))

    # Call superclass default constructor if this is not java.lang.Object.
    if info.class_obj.name != 'java.lang.Object':
        this_offset = (len(constructor_obj.params) * 4) + 8
        output.append('mov eax, %d' % this_offset)
        output.append('mov eax, [eax+ebp]')
        output.append('push eax')
        superclass = info.class_obj.extends.name
        superclass_simple = superclass.split('.')[-1]
        superclass_label = 'CONSTRUCTOR~%s.%s~' % (superclass, superclass_simple)
        output.append('call %s' % superclass_label)
        output.append('add esp, 4')

    # Initialize instance fields.
    for member in info.class_obj.declare:
        if isinstance(member, class_hierarchy.Field) == False:
            continue
        field_obj = member
        field_node = field_obj.node
        if 'Static' not in field_obj.mods and \
            len(field_node[3].children) == 1: # Initializer

            # Evaluate initializer.
            output.extend(expression.gen_expr(info, field_node[3][0], constructor_obj))

            # Get the address of 'this'.
            this_offset = (len(constructor_obj.params) * 4) + 8 
            output.append('mov ebx, ebp')
            output.append('add ebx, %d' % this_offset)
            output.append('mov ebx, [ebx]')

            # Assign to field offset.
            receiver_type = info.class_obj.name
            field_name = field_obj.name
            field_offset = info.get_field_offset_from_field_name(receiver_type, field_name)
            field_offset += 12
            output.append('mov [ebx+%d], eax' % field_offset)

    body = node # ConstructorBody
    if len(body.children) != 0:
        output.extend(statement.gen_block(info, body[3], constructor_obj))

    # restore ebp & esp
    output.extend([
        "END~%s:" % (constructor_obj.node.label),
        "mov esp, ebp",
        "pop ebp",
        "ret"
    ])

    return output