Exemplo n.º 1
0
def gen_method(info, method_obj):
    node = method_obj.node
    assert node.name in 'MethodDeclaration'

    # 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 method.
    output.append(method_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))

    body = node[4] # MethodBody
    if len(body.children) != 0:
        output.extend(statement.gen_block(info, body[0], method_obj))

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

    return output
Exemplo n.º 2
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