Example #1
0
def type_tag_of_subtree(subtree, if_array_then_contents=False):
    if isarray(collect_token_text(subtree)):
        if if_array_then_contents:
            subtree = subtree[0]
    if subtree.tag == "primitive_type":
        return {"short": -1, "int": -2, "char": -3, "byte": -4, "boolean": -5}[collect_token_text(subtree)]
    return subtree.env.findclass(name_to_str(subtree)).type_tag
Example #2
0
def comparison_expression(subtree):
    if subtree[1].tag == "tok_instanceof":
        instanceof_expression(subtree)
        return
    label_no = new_label_no()
    zero_case = "EQUALITY_ZERO_" + str(label_no)
    one_case = "EQUALITY_ONE_" + str(label_no)
    final = "EQUALITY_FINAL_" + str(label_no)

    lhs_location = subtree[0].slot
    rhs_location = subtree[2].slot
    subtree.slot = generate_new_stack_slot(subtree)
    jump_if_zero_location = one_case
    jump = ""
    cmp_expression = ""
    if collect_token_text(subtree[1]) == "==":
        jump = "JZ"
    elif subtree[1].tag == "tok_gt":
        jump = "JG"
    elif subtree[1].tag == "tok_lt":
        jump = "JL"
    elif subtree[1].tag == "tok_lteq":
        jump = "JLE"
    elif subtree[1].tag == "tok_gteq":
        jump = "JGE"
    elif collect_token_text(subtree[1]) == "!=":
        jump = "JNZ"

    subtree.assembly = """
; equality expression
mov eax, {lhs}
mov ebx, {rhs}
sub eax, ebx
{jump} .{jump_if_zero_location}
.{zero_case}:
mov {result}, {false}
JMP .{final_location}
.{one_case}:
mov {result}, {true}
.{final_location}:
;end equality expression
""".format(
        lhs=stack_slot_to_operand(lhs_location),
        rhs=stack_slot_to_operand(rhs_location),
        result=stack_slot_to_operand(subtree.slot),
        cmp_expression=cmp_expression,
        jump_if_zero_location=jump_if_zero_location,
        final_location=final,
        zero_case=zero_case,
        one_case=one_case,
        jump=jump,
        false=false,
        true=true,
    )
Example #3
0
def array_creation_expression(element):
    base_name = collect_token_text(element[1])
    if element.find(".//dim_expr") is not None:
        base_name += "[]"
    if element.find(".//dim_expr/expression") is not None:
        type_str = element.find(".//dim_expr/expression").attrib["type"]
        error_if(not is_integral_primitive(type_str),
              "dim_expr require integral type")
    element.attrib["type"] = element.env.canonicalize_name(base_name)
Example #4
0
def constructor_declaration(subtree):
    mangled_name = mangle_fn_name(subtree)
    constructor_body = subtree.find("constructor_body")
    error_if(constructor_body is None, "No constructor body")

    superclass = subtree.env.findclass("this").superclass
    superclass_mangled_name = mangle_class_name(superclass.get("canonical_name"))
    superclass_constructor = superclass_mangled_name + mangle_class_name(superclass.get("name"))

    fields = subtree.env.findclass("this").findall(".//field")
    field_initializers = ""
    for field in fields:
        if "static" not in modifiers(field) and field.find("expression") is not None:
            if not hasattr(field.find("expression"), "assembly"):
                generate(field.find("expression"))
            field_initializers += field.find("expression").assembly + "\n"
            field_initializers += """
; field_initializer
mov eax, DWORD [ebp + 8] ; this -> eax
add eax, {field_location}
mov ebx, {value}
mov DWORD [eax], ebx
; end_field_initializer
""".format(
                field_location=field.env.find_nonlocal(collect_token_text(field.find("variable"))).field_offset * 4,
                value=stack_slot_to_operand(field.find("expression").slot),
            )

    chained_constructor_call = """
;initialize fields
{field_initializers}
; call superclass default constructor
push DWORD [ebp + 8]
call {superclass_constructor}
""".format(
        superclass_constructor=superclass_constructor, field_initializers=field_initializers
    )
    this_class = subtree.env.findclass("this")
    if this_class.get("canonical_name") == "java.lang.Object":
        chained_constructor_call = field_initializers

    subtree.assembly = method_declaration_asm(
        constructor_body.assembly, mangled_name, subtree, chained_constructor_call
    )
    subtree.assembly += """
mov eax, {this_ptr}
leave
ret
; end constructor {name}
""".format(
        this_ptr=stack_slot_to_operand(this), name=mangled_name
    )
Example #5
0
def multiplicative_expression(subtree):
    lhs_location = subtree[0].slot
    rhs_location = subtree[2].slot
    new_stack_slot = generate_new_stack_slot(subtree)
    operator_type = collect_token_text(subtree[1])
    result = operator = ""
    if operator_type == "*":
        operator = "imul"
        result = "eax"
        check = ""
    elif operator_type == "/":
        operator = "idiv"
        result = "eax"
        label_no = new_label_no()
        check = """
sub ebx, 0
jne .{okay_label}
call __exception
.{okay_label}:
""".format(
            okay_label="DIV0_CHECK_" + str(label_no)
        )
    elif operator_type == "%":
        operator = "idiv"
        result = "edx"
        check = ""
    else:
        error_if(True, "Unknown argument to mulitplicative expression")
    subtree.assembly = """
; multiplicative {dbg}
mov edx, {lhs}
mov eax, edx
sar edx, 31
mov ebx, {rhs}
{check}
{op} ebx
mov {nss}, {result}
; end multiplicative
""".format(
        nss=stack_slot_to_operand(new_stack_slot),
        lhs=stack_slot_to_operand(lhs_location),
        rhs=stack_slot_to_operand(rhs_location),
        result=result,
        check=check,
        op=operator,
        imul_part=operator == "imul" and ", edx" or "",
        dbg=collect_debug_text(subtree),
    )
    subtree.slot = new_stack_slot
Example #6
0
def additive_expression(subtree):
    lhs_slot = subtree[0].slot
    rhs_slot = subtree[2].slot
    result_slot = generate_new_stack_slot(subtree)

    lhs_type = subtree[0].get("type")
    rhs_type = subtree[2].get("type")
    if "java.lang.String" in [lhs_type, rhs_type]:
        (lhs_slot, lhs_assembly) = generate_promotion_to_string(subtree[0])
        (rhs_slot, rhs_assembly) = generate_promotion_to_string(subtree[2])
        assembly = """
; string additive expression
{lhs_assembly}
{rhs_assembly}

mov eax, {lhs_slot}
mov ebx, {rhs_slot}

push ebx
push eax
call java_lang_String_concat_java_lang_String_
mov {result_slot}, eax
""".format(
            lhs_assembly=lhs_assembly,
            rhs_assembly=rhs_assembly,
            rhs_slot=stack_slot_to_operand(rhs_slot),
            lhs_slot=stack_slot_to_operand(lhs_slot),
            result_slot=stack_slot_to_operand(result_slot),
        )
        subtree.assembly = assembly
        subtree.slot = result_slot
        return

    operator_type = collect_token_text(subtree[1])
    operator = ""
    if operator_type == "+":
        operator = "add"
    elif operator_type == "-":
        operator = "sub"
    else:
        error_if(True, "Unknown additive_expression operator_type")

    subtree.assembly = binary_operator_assembly(lhs_slot, rhs_slot, operator, result_slot, collect_debug_text(subtree))
    subtree.slot = result_slot
Example #7
0
def cast_expression(element):
    if element[1].tag == "name":
        expression_being_cast = element.find("unary_expression_not_plus_minus")
        cast_type = element.env.canonicalize_name(name_to_str(element[1]))
        if element.find("dims"):
            cast_type += "[]"
    elif element[1].tag == "expression":
        # Expression case
        cast_type = element[1].attrib["type"]
        expression_being_cast = element[-1]
    else:
        # Primitive cast case
        cast_type = collect_token_text(element[1])
        if element[2].tag == "dims":
            cast_type += "[]"
        expression_being_cast = element[-1]

    error_if(not element.env.can_be_cast(expression_being_cast.attrib["type"],
                                  cast_type), "TODO(thurn): This is an error.")
    element.attrib["type"] = cast_type
Example #8
0
def reference_type(element):
    name_string = collect_token_text(element)
    canonical_name = element.env.canonicalize_name(name_string)
    element.attrib["type"] = canonical_name
Example #9
0
def mangle_field_name(field_decl):
    return mangle_class_name(classof(field_decl)) + "_" + collect_token_text(field_decl.find("./variable")) + "_"