Prechádzať zdrojové kódy

Replaced size of return record by type descriptor of return type -- required for write barriers

git-svn-id: https://svn.inf.ethz.ch/svn/lecturers/a2/trunk@7247 8c9fc860-2736-0410-a75d-ab315db34111
felixf 8 rokov pred
rodič
commit
67e2809044
1 zmenil súbory, kde vykonal 71 pridanie a 11 odobranie
  1. 71 11
      source/FoxIntermediateBackend.Mod

+ 71 - 11
source/FoxIntermediateBackend.Mod

@@ -5728,16 +5728,18 @@ TYPE
 					d := SyntaxTree.NewSymbolDesignator(Basic.invalidPosition,NIL,variable);
 					d.SetType(variable.type);
 				END;
-				IF (procedureType.returnType.resolved IS SyntaxTree.RecordType) THEN
+				(*IF (procedureType.returnType.resolved IS SyntaxTree.RecordType) THEN
 					Designate(d,returnValue);
 					returnTypeSize := system.SizeOf(procedureType.returnType.resolved);
 					size := IntermediateCode.Immediate(addressType,ToMemoryUnits(system,returnTypeSize));
 			 		Emit(Push(position,size));
 			 		Emit(Push(position,returnValue.op));
 			 		ReleaseOperand(returnValue);
-				ELSE
+				ELSE*)
 					PushParameter(d,procedureType.returnParameter,procedureType.callingConvention, FALSE, dummy,-1)
+					(*
 		 		END;
+		 		*)
 		 	END;
 
 			firstWriteBackCall := NIL; (* reset write-back call list *)
@@ -9850,15 +9852,19 @@ TYPE
 			ReleaseIntermediateOperand(dst);
 		END ModifyAssignments;
 
-		PROCEDURE CopySize(left: SyntaxTree.Expression): IntermediateCode.Operand;
-		VAR type: SyntaxTree.Type; procedureType: SyntaxTree.ProcedureType; parameter: SyntaxTree.Parameter;
+		PROCEDURE CopySize(left: SyntaxTree.Expression; tag: IntermediateCode.Operand): IntermediateCode.Operand;
+		VAR type: SyntaxTree.Type; procedureType: SyntaxTree.ProcedureType; parameter: SyntaxTree.Parameter; mem: IntermediateCode.Operand;
 		BEGIN
 			type := left.type.resolved;
 			IF (type IS SyntaxTree.RecordType) & (left IS SyntaxTree.SymbolDesignator) & (left(SyntaxTree.SymbolDesignator).symbol IS SyntaxTree.Parameter) THEN
 				parameter := left(SyntaxTree.SymbolDesignator).symbol(SyntaxTree.Parameter);
 				procedureType := parameter.ownerType.resolved(SyntaxTree.ProcedureType);
 				IF procedureType.returnParameter = parameter THEN
-					RETURN IntermediateCode.Memory(addressType, fp, ToMemoryUnits(system, parameter.offsetInBits + system.addressSize));
+					(* this is the only case where the destination can be dynamically smaller than the source 
+						in all other cases the dynamic size has to be taken
+					*)
+					MakeMemory(mem, tag, addressType, 0);
+					RETURN mem;
 				END;
 			END;
 			RETURN IntermediateCode.Immediate(addressType,ToMemoryUnits(system,system.SizeOf(type)));
@@ -9867,8 +9873,8 @@ TYPE
 		PROCEDURE Assign(left,right: SyntaxTree.Expression);
 		VAR
 			leftO, rightO: Operand;
-			mem, sizeOp: IntermediateCode.Operand;
-			leftType, rightType, componentType: SyntaxTree.Type;
+			arg,mem, sizeOp: IntermediateCode.Operand;
+			leftType, rightType, componentType, base: SyntaxTree.Type;
 			size: LONGINT;
 			parameters: SyntaxTree.ExpressionList;
 			procedure: SyntaxTree.Procedure;
@@ -9909,8 +9915,9 @@ TYPE
 					CallAssignMethod(leftO.op, rightO.op, left.type);
 					Emit(Pop(position, rightO.op));
 					Emit(Pop(position, leftO.op));
-					sizeOp := CopySize(left);
+					sizeOp := CopySize(left, leftO.tag);
 					Emit(Copy(position,leftO.op,rightO.op,sizeOp));
+					ReleaseIntermediateOperand(sizeOp);
 					ReleaseOperand(leftO); 
 					ReleaseOperand(rightO);
 				ELSE
@@ -9934,6 +9941,56 @@ TYPE
 				END;
 				ModifyAssignments(false);
 				RETURN;
+			ELSIF backend.writeBarriers & left.NeedsTrace() THEN
+				IF SemanticChecker.IsPointerType(leftType) THEN
+					Evaluate(right,rightO);
+					Designate(left,leftO);
+					Emit(Push(position,leftO.op));
+					ReleaseOperand(leftO);
+					Emit(Push(position,rightO.op));
+					ReleaseOperand(rightO);
+					CallThis(position,"Heaps","Assign",2);
+				ELSIF leftType.IsRecordType() THEN
+					Designate(right,rightO);
+					Designate(left,leftO);
+					Emit(Push(position,leftO.op));
+					Emit(Push(position,leftO.tag)); (* type desc *)
+					ReleaseOperand(leftO);
+					Emit(Push(position,rightO.op));
+					ReleaseOperand(rightO);
+					CallThis(position,"Heaps","AssignRecord",3);
+				ELSIF IsStaticArray(leftType) THEN
+					size := StaticArrayNumElements(leftType);
+					base := StaticArrayBaseType(leftType);
+					Designate(right,rightO);
+					Designate(left,leftO);
+					Emit(Push(position,leftO.op));
+					ReleaseOperand(leftO);
+					
+					arg := TypeDescriptorAdr(base);
+					IF ~newObjectFile THEN IntermediateCode.MakeMemory(arg, addressType) END;
+					Emit(Push(position,arg));
+
+					Emit(Push(position,IntermediateCode.Immediate(addressType,size)));
+					Emit(Push(position,rightO.op));
+					ReleaseOperand(rightO);
+					CallThis(position,"Heaps","AssignArray",4);
+				ELSIF leftType IS SyntaxTree.ProcedureType THEN
+					ASSERT(leftType(SyntaxTree.ProcedureType).isDelegate); 
+					Evaluate(right,rightO);
+					Designate(left,leftO);
+					MakeMemory(mem,leftO.op,addressType,0);
+					Emit(Mov(position,mem,rightO.op));
+					ReleaseIntermediateOperand(mem);
+					IntermediateCode.MakeAddress(leftO.tag, addressType);
+					Emit (Push(position, leftO.tag));
+					ReleaseOperand(leftO);
+					Emit (Push(position, rightO.tag));
+					ReleaseOperand(rightO);
+					CallThis(position,"Heaps","Assign", 2);
+				ELSE HALT(100); (* missing ? *)
+				END;
+				RETURN;
 			END;
 
 			IF CanPassAsResultParameter(right) THEN
@@ -10029,13 +10086,14 @@ TYPE
 			ELSIF (leftType IS SyntaxTree.RecordType) THEN
 				Designate(right,rightO);
 				Designate(left,leftO);
-				sizeOp := CopySize(left);
+				sizeOp := CopySize(left, leftO.tag);
 				Emit(Copy(position,leftO.op,rightO.op,sizeOp));
+				ReleaseIntermediateOperand(sizeOp);
 				ReleaseOperand(leftO); ReleaseOperand(rightO);
 			ELSIF (leftType IS SyntaxTree.ArrayType) THEN
 				IF (rightType IS SyntaxTree.StringType) THEN
 					CopyString(left,right);
-				ELSIF ((rightType IS SyntaxTree.ArrayType) & (rightType(SyntaxTree.ArrayType).staticLength # 0) OR (rightType IS SyntaxTree.MathArrayType) & (rightType(SyntaxTree.MathArrayType).staticLength # 0)) & (leftType(SyntaxTree.ArrayType).staticLength # 0) THEN
+				ELSIF ((rightType IS SyntaxTree.ArrayType) & (rightType(SyntaxTree.ArrayType).staticLength # 0) OR (rightType IS SyntaxTree.MathArrayType) & (rightType(SyntaxTree.MathArrayType).staticLength # 0)) & (leftType(SyntaxTree.ArrayType).staticLength # 0) THEN	
 					Designate(right,rightO);
 					Designate(left,leftO);
 					size := ToMemoryUnits(system,system.SizeOf(rightType));
@@ -13400,7 +13458,7 @@ TYPE
 		preregisterStatic-: BOOLEAN;
 		dump-: Basic.Writer;
 		cellsAreObjects: BOOLEAN;
-		preciseGC: BOOLEAN; 
+		preciseGC, writeBarriers: BOOLEAN; 
 		
 		PROCEDURE &InitIntermediateBackend*;
 		BEGIN
@@ -13507,6 +13565,7 @@ TYPE
 			options.Add(0X,"preregisterStatic", Options.Flag);
 			options.Add(0X,"cellsAreObjects", Options.Flag);
 			options.Add(0X,"preciseGC", Options.Flag);
+			options.Add(0X,"writeBarriers", Options.Flag);
 		END DefineOptions;
 
 		PROCEDURE GetOptions(options: Options.Options);
@@ -13536,6 +13595,7 @@ TYPE
 			preregisterStatic := options.GetFlag("preregisterStatic");
 			cellsAreObjects := options.GetFlag("cellsAreObjects");
 			preciseGC := options.GetFlag("preciseGC");
+			writeBarriers := options.GetFlag("writeBarriers");
 
 		END GetOptions;