def test_typecheck(filename="Object.java"): import typechecker import environment environment.cached_environments = {} environment.cached_trees = {} # stdlib = all_files_in_dir("test_cases/stdlib/6.0") trees = typechecker.check_files([filename]) to_file(trees[-1])
def check_and_generate(files): init_globals() # reset global state try: out = open("output/out.s", "w") trees = typechecker.check_files(files) initializer_list = [] mega_vtable_offset = 1 type_tag = 0 string_literal_index = 0 for tree in trees: clazz = find_type_decl(tree) clazz.type_tag = type_tag method_list.class_list += [clazz] type_tag += 1 methods = ( tree.findall(".//method") + tree.findall(".//constructor_declaration") + tree.findall(".//abstract_method") ) for method in methods: method.mega_vtable_offset = mega_vtable_offset mega_vtable_offset += 1 method_list.method_list += [method] if "static" in modifiers(method): slot = -2 else: slot = -3 for param in method.findall(".//param"): param.slot = slot slot -= 1 counters.mega_vtable_members = mega_vtable_offset for string_literal in tree.findall(".//string_literal"): string_literal.index = string_literal_index string_literal_index += 1 out.write(instanceof_table(trees)) for tree in trees: CurrentFile.name = tree.filename CurrentFile.mangled_name = CurrentFile.name.replace(".", "_").replace("$", "_").replace("/", "_") CurrentFile.static_slot = 0 for this in tree.findall(".//tok_this"): this.slot = -2 generate(tree) to_file(tree, tree.filename + ".xml") out.write("section .data\n") for clazz in tree.findall(".//class"): out.write(mega_vtable_for_class(clazz)) out.write("section .text\n") initializer_name = "static_init_" + CurrentFile.mangled_name out.write( """ ; global {initializer_name} {initializer_name}: push ebp mov ebp, esp sub esp, {frame_size} """.format( initializer_name=initializer_name, frame_size=CurrentFile.static_slot * 4 ) ) initializer_list.append(initializer_name) for field in tree.findall(".//field"): if "static" in modifiers(field): mangled_name = mangle_field_name(field) out.write( """ ; initializing {mangled_name} {field_assembly} mov eax, {mangled_name} mov ebx, {assigned_value} mov DWORD [eax], ebx """.format( mangled_name=mangled_name, field_assembly=field.assembly, assigned_value=stack_slot_to_operand(field.slot), ) ) out.write( """ leave ret ; done global static initialization """ ) for constructor in tree.findall(".//constructor_declaration"): out.write(constructor.assembly + "\n") for method in tree.findall(".//method"): if method.find("block") is not None: out.write(method.assembly + "\n") out.write("\nsection .data\n") for string_literal in tree.findall(".//string_literal"): string_value = string_literal.get("value") expanded_value = expand_string_literal(string_value) out.write("\n; string literal " + string_value + "\n") out.write("__string_literal_" + str(string_literal.index) + ":\n") out.write("dd _vtable_java_lang_$Array_ ; vtable pointer\n") out.write("dd -3 ; type tag for char\n") out.write("dd " + str(len(expanded_value)) + " ; string length\n") for character in expanded_value: out.write("dd " + str(hex(ord(character))) + "\n") out.write("") out.write("\nsection .bss\n") for field in tree.findall(".//field"): if "static" in modifiers(field): mangled_name = mangle_field_name(field) out.write("""{mangled_name} resb 4""".format(mangled_name=mangled_name) + "\n") out.write("section .text\n") out.write("; prelude\n") out.write("extern __malloc\n") out.write("extern __debexit\n") out.write("extern __exception\n") out.write("extern NATIVEjava.io.OutputStream.nativeWrite\n") out.write("global _start\n") out.write("_start:\n") out.write("call install_segv_handler\n") for initializer in initializer_list: out.write("call " + initializer + "\n") class_name = mangle_class_name(find_type_decl(trees[1]).get("canonical_name")) out.write("call " + class_name + "test_\n") out.write("mov ebx, eax\n") out.write("mov eax, 1\n") out.write("int 0x80 ; invoke exit(1)\n") out.write("; end prelude\n") out.write( """ %define __NR_signal 48 %define SIGSEGV 11 global install_segv_handler install_segv_handler: mov eax, __NR_signal mov ebx, SIGSEGV mov ecx, __exception int 0x80 ret """ ) return 0 except JoosSyntaxException, e: if Testing.testing: return 42 else: out.write("\n" + e.msg + "\n") raise