/** * Die Methode generiert den Assembler-Code für diesen Ausdruck. Sie geht davon aus, dass die * Kontextanalyse vorher erfolgreich abgeschlossen wurde. * * @param code Der Strom, in den die Ausgabe erfolgt. */ void generateCode(CodeStream code) { String lookupLabel = code.nextLabel(); code.println("; NEW " + newType.name); code.println("ADD R2, R1"); /** BEGIN Aufgabe (j): Garbage Collector */ // code.println("MMR (R2), R4 ; Referenz auf neues Objekt auf den Stapel legen"); // code.println("MRI R6, _free ; Adresse von _free holen"); // code.println("MRM R6, (R6) ; Referenz auf neues Objekt aus _free holen"); // code.println("MMR (R2), R6 ; Referenz auf neues Objekt auf den Stapel legen"); code.println("MRI R5, " + lookupLabel); code.println("MMR (R2), R5; Ruecksprungadresse"); code.println("MRI R5, " + ((ClassDeclaration) newType.declaration).objectSize); code.println("ADD R2, R1"); code.println("MMR (R2), R5; Objektgroesse"); code.println("MRI R0, _lookup; Rufe _lookup Methode auf"); code.println(lookupLabel + ":"); code.println("MRM R6, (R2); freie Stelle vom Stack nehmen"); /** BEGIN Aufgabe (i): Vererbung */ code.println("MRI R5, " + ((ClassDeclaration) newType.declaration).identifier.name); // code.println("MMR (R4), R5 ; Referenz auf die VMT des Objects"); code.println("MMR (R6), R5 ; Referenz auf die VMT des Objects"); /** END Aufgabe (i) */ // code.println("MRI R5, " + ((ClassDeclaration) newType.declaration).objectSize); // code.println("ADD R4, R5 ; Heap weiter zählen"); // code.println("ADD R6, R5 ; Heap weiter zählen"); /** BEGIN Aufgabe (j): Garbage Collector */ code.println("ADD R6, R1 ; Heap weiter zählen"); code.println("MRI R5, 0 ; NULL Pointer "); for (int i = 0; i < ((ClassDeclaration) newType.declaration).objectSize - 1; i++) { code.println("MMR (R6), R5 ; Attribut " + i + " nullen"); code.println("ADD R6, R1 ; Heap weiter zaehlen"); } /** END Aufgabe (j) */ code.println("MRI R5, _free ; Adresse von _free holen"); code.println("MMR (R5), R6 ; neuen Heap Pointer in _free ablegen"); /** END Aufgabe (j) */ }
/** * Die Methode generiert den Assembler-Code für diesen Ausdruck. Sie geht davon aus, dass die * Kontextanalyse vorher erfolgreich abgeschlossen wurde. * * @param code Der Strom, in den die Ausgabe erfolgt. */ void generateCode(CodeStream code) { if (identifier.declaration instanceof VarDeclaration) { VarDeclaration v = (VarDeclaration) identifier.declaration; if (v.isAttribute) { code.println("; Referenz auf Attribut " + identifier.name); code.println("MRM R5, (R2)"); code.println("MRI R6, " + v.offset); code.println("ADD R5, R6"); code.println("MMR (R2), R5"); } else { code.println("; Referenz auf Variable " + identifier.name); code.println("MRI R5, " + v.offset); code.println("ADD R5, R3"); code.println("ADD R2, R1"); code.println("MMR (R2), R5"); } } else if (identifier.declaration instanceof MethodDeclaration) { MethodDeclaration m = (MethodDeclaration) identifier.declaration; /** BEGIN Aufgabe (f): Methoden Parameter */ code.println("; CALL " + m.self.type.name + "." + m.identifier.name); /** BEGIN Aufgabe (j): Garbage Collector */ code.println("MRM R5, (R2) ; SELF von R2 nehmen"); code.println("SUB R2, R1"); code.println("ADD R4, R1"); code.println("MMR (R4), R5 ; SELF auf R4 legen"); /** END Aufgabe (j) */ if (!params.isEmpty()) { for (int i = 0; i < params.size(); i++) { Expression p = params.get(i); code.println("; Parameter " + i + ":"); p.generateCode(code); /** BEGIN Aufgabe (j): Garbage Collector */ code.println("MRM R5, (R2) ; Parameter " + i + " von R2 nehmen"); code.println("SUB R2, R1"); code.println("ADD R4, R1"); code.println("MMR (R4), R5 ; Parameter " + i + " auf R4 legen"); /** END Aufgabe (j) */ } } /** END Aufgabe (f) */ String returnLabel = code.nextLabel(); code.println("MRI R5, " + returnLabel); code.println("ADD R2, R1"); code.println("MMR (R2), R5 ; Rücksprungadresse auf den Stapel"); /** BEGIN Aufgabe (i): Vererbung */ if (dynamicBind) { // dynamisches Binden code.println("; Dynamischer Aufruf von " + identifier.name); code.println("MRI R5, " + (m.self.offset + 1)); /** BEGIN Aufgabe (j): Garbage Collector */ // code.println("ADD R5, R2 "); code.println("ADD R5, R4 "); /** END Aufgabe (j) */ code.println("MRM R5, (R5) ; Adresse von SELF auf dem Heap "); code.println("MRM R5, (R5) ; VMT Referenz "); code.println("MRI R6, " + m.index + " ; Methodenoffset"); code.println("ADD R5, R6 ; Methodenoffset anwenden"); code.println("MRM R5, (R5) ; Methodenadresse holen "); code.println("MRR R0, R5 ; Sprung zu " + m.identifier.name); } else { code.println("; Statischer Aufruf von " + identifier.name); code.println("MRI R0, " + m.self.type.name + "_" + m.identifier.name); } /** END Aufgabe (i) */ // code.println("; Statischer Aufruf von " + identifier.name); // code.println("MRI R0, " + m.self.type.name + "_" + m.identifier.name); code.println(returnLabel + ":"); } else { assert false; } }