コード例 #1
0
ファイル: expression.py プロジェクト: holdenli/CS-444
def gen_array_access_addr(info, node, method_obj):
    assert node.name == 'ArrayAccess'
    output = ['; BEGIN gen_array_access_addr']
    
    # Generate receiver code.
    output.extend(gen_expr(info, node[0][0], method_obj))

    # Make sure the array we're indexing into is not null.
    output.extend(util.gen_null_check())
    output.append('push eax')

    # Generate index code into ebx.
    output.extend(gen_expr(info, node[1], method_obj))
    output.append('mov ebx, eax')

    # eax has array.
    output.append('pop eax')

    # Check that index is within array bounds.
    output.extend(util.gen_array_bounds_check())

    # Skip SIT pointer and length field.
    # Note: java.lang.Object has no fields.
    output.append('add ebx, 4')
    output.append('shl ebx, 2') # Multiply index (offset) by 4.

    output.append('add eax, ebx') # Address is at array addr + offset.

    output.append('; END gen_array_access_addr')
 
    return output
コード例 #2
0
ファイル: expression.py プロジェクト: holdenli/CS-444
def gen_ambiguous_name(info, node, method_obj):
    output = ["; START gen_ambiguous_name"]

    output.extend(gen_ambiguous_name_addr(info, node, method_obj))
    output.extend(util.gen_null_check())
    output.append('mov eax, [eax]')

    output.append('; END gen_ambiguous_name')

    return output
コード例 #3
0
ファイル: expression.py プロジェクト: holdenli/CS-444
def gen_field_access_addr(info, node, method_obj):
    output = []

    # Gets the field receiver.
    obj_output = gen_expr(info, node.find_child("FieldReceiver")[0], method_obj)
    output.extend(obj_output)
    
    output.extend(util.gen_null_check())

    if typecheck.is_array_type(node[1][0].typ) == True: # Array
        output.append('add eax, %d' % 12)

    else: # Object.
        offset = info.get_field_offset(node)
        output.append("add eax, %i" % (12 + offset))

    return output
コード例 #4
0
ファイル: expression.py プロジェクト: holdenli/CS-444
def gen_method_invocation(info, node, method_obj):
    receiver = node.find_child("MethodReceiver")
    if len(receiver.children) != 0 and receiver[0].typ == None:
        return gen_static_method_invocation(info, node, method_obj)

    output = ["; START gen_method_invocation for %s" % node.decl.label]

    # get addr of method receiver
    output.append("; Eval receiver")
    obj_output = None
    if len(receiver.children) != 0:
        obj_output = gen_expr(info, receiver[0], method_obj)
    else:
        obj_output = gen_this(info, None, method_obj) 
    output.extend(obj_output)
    output.extend(util.gen_null_check())
    output.append("push eax")

    # calculate args, push args; left-to-right
    args = list(node.find_child("Arguments").children)
    num_args = len(args)
    output.append("; Eval %i args" % num_args)
    for arg in args:
        output.extend(gen_expr(info, arg, method_obj))
        output.append("push eax")

    # Get the label corresponding to the method, using the SIT.
    output.append("; Get method impl")
    offset = info.get_method_offset(node)
    output.append("mov eax, [esp + %i] ; addr of receiver" % (num_args*4))
    output.append("mov eax, [eax] ; SIT")
    output.append("mov eax, [eax + %i] ; addr of method" % (offset))

    output.append("call eax")
    
    # pop obj addr and args
    output.append("add esp, %i ; pop this and args" % (4 + num_args*4))

    output.append("; END gen_method_invocation")

    return output
コード例 #5
0
ファイル: expression.py プロジェクト: holdenli/CS-444
def gen_ambiguous_name_addr(info, node, method_obj):
    assert node.name == 'Name'

    output = ['; gen_ambiguous_name_addr']

    # Loop through each identifier node, looking for a significant node.
    significant_node = None
    significant_index = -1
    for i, id_node in enumerate(node.children):
        if hasattr(id_node, 'decl') or hasattr(id_node, 'canon'):
            significant_node = id_node
            significant_index = i
            break

    assert significant_index != -1 # Did not find anything, error.

    # We have Type.something, so there must be a next node.
    # This is a Static field access.
    id_node = significant_node
    i = significant_index
    prev_type = None
    if hasattr(id_node, 'canon') and id_node.canon != None:
        assert (i + 1) < len(node.children)

        # Return address of static field.
        next_node = node[i + 1].decl # decl should be static field ASTNode
        assert next_node.name == 'FieldDeclaration'
        assert 'static' in next_node.modifiers
        output.append('mov eax, %s' % next_node.label)

        i += 2 # Processed 2 nodes.
        prev_type = next_node[1].canon # Get type from Type node

    # We have local_var.something. Move its addr to eax.
    elif id_node.decl.name == 'LocalVariableDeclaration':
        assert i == 0 # Local variable must be first identifier.

        # Get the offset from the frame pointer.
        output.append('mov eax, ebp')
        local_var_offset = id_node.decl.frame_offset * 4
        output.append('add eax, %d' % local_var_offset)

        i += 1
        prev_type = id_node.decl[0].canon # Get type from Type node

    # We have a parameter.something. Move its addr to eax.
    elif id_node.decl.name == 'Parameter':
        assert i == 0 # Parameter must be first identifier.

        # Get the offset from the frame pointer.
        output.append('mov eax, ebp')
        param_offset = (id_node.decl.frame_offset * 4)
        output.append('add eax, %d' % param_offset)

        i += 1
        prev_type = id_node.decl[0].canon # Get type from Type node

    # We have an implicit 'this' on an instance field.
    elif id_node.decl.name == 'FieldDeclaration':
        assert i == 0 # Field declaration must be first identifier.

        # Get this into eax.
        output.extend(gen_this(info, None, method_obj))

        # If the field type is array, we must get the array field.
        offset = 0
        receiver_type = info.class_obj.name
        field_name = id_node.decl.obj.name
        offset = info.get_field_offset_from_field_name(receiver_type, field_name)
        offset += 12
        prev_type = id_node.decl[1].canon # Generic type.

        # Load the field address offset.
        output.append('add eax, %d' % offset)

        i += 1

    # All the remaining things are instance fields. We have the address in eax
    # already, so we just keep going.
    while i < len(node.children):
        assert i >= 1
        assert prev_type != None
        field_node = node[i]

        assert field_node.decl.name in ['FieldDeclaration',
            'FakeFieldDeclaration']

        # Nullcheck and dereference the previous result into eax.
        output.extend(util.gen_null_check())
        output.append('mov eax, [eax]')

        # Calculate the offset of the field.
        offset = 0

        # Array; length has type Int.
        if typecheck.is_array_type(prev_type):
            assert i == (len(node.children) - 1) # Must be last element.
            offset = 12
            prev_type = 'Int'

        # Object. Must search up the object's type (in prev_type) in the field
        # index and get the offset.
        else:
            prev_type_field_list = info.field_index[prev_type]
            field_name = field_node.decl.obj.name
            temp = class_hierarchy.Temp_Field(field_name)
            offset = (prev_type_field_list.index(temp) * 4) + 12
            # Keep the type.
            prev_type = field_node.decl[1].canon

        output.append('add eax, %d' % offset)

        i += 1   
        
    output.append('; end of gen_ambiguous_name_addr')    

    return output