⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bldfile.cpp

📁 虚拟机设计与实现——C/C++
💻 CPP
字号:
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+                                                                   +
+ bldfile.cpp -	construct header and output file                    +
+               append bytecode from pass2 on to end                +
+                                                                   +
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
+ macros                                                            +
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

/*#define PASS3_DEBUG		1*/

#ifdef	PASS3_DEBUG
#define	PASS3_DEBUG0(arg);						printf(arg);
#define PASS3_DEBUG1(arg1,arg2);				printf(arg1,arg2);
#define PASS3_DEBUG2(arg1,arg2,arg3);			printf(arg1,arg2,arg3);
#else
#define	PASS3_DEBUG0(arg);
#define PASS3_DEBUG1(arg1,arg2);
#define PASS3_DEBUG2(arg1,arg2,arg3);
#endif

/*byte sizes of records in debug DB*/

#define SIZE_GLOBREC	37
#define SIZE_PROCREC	25
#define SIZE_RETREC		16
#define SIZE_ARGREC		16
#define SIZE_LOCREC		16
#define SIZE_LBLREC		20


/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ declaration                                                       +
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

class BuildFile
{
	CommandLine *cmdLine;
	SymbolTable *symTbl;
	StringTable *strTbl;

	FILE *ofptr;			/*pointer to output file*/
	FILE *afptr;			/*pointer to temporary bytecode file*/

	char *ofile;			/*pointer to output file name*/
	char *afile;			/*pointer to temporary file name*/

	char ofBuffer[BUFFER_SIZE];		/*buffer for output file*/
	int iOFChar;					/*index into ofBuffer*/

	U1 output[8];		/*holds bytes to write to output file*/

	/*manage output buffer*/
	void putByteOutBuff(U1 byte);
	void flushOutBuff();

	/*these functions convert a number to big endian and write to output*/
	void commit2Bytes(U2 val);
	void commit4Bytes(U4 val);
	void commit8Bytes(U8 val);

	public:
	
	BuildFile(CommandLine *cptr, StringTable *st, SymbolTable *syt);
	~BuildFile();
	void buildFileFormat();

};

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ definitions                                                       +
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

BuildFile::BuildFile(CommandLine *cptr, StringTable *st, SymbolTable *syt)
{ 
	cmdLine = cptr;
	strTbl = st;
	symTbl = syt;

	ofile = (*cptr).outputFile;
	afile = (*cptr).tempFile;

	if(ofile==NULL)
	{
		ERROR0("BuildFile::BuildFile(): output file name has not been specified\n");
		FATAL_ERROR();
	}
	if(afile==NULL)
	{
		ERROR0("BuildFile::BuildFile(): temporary file's name has not been specified\n");
		FATAL_ERROR();
	}
	
	ofptr = fopen(ofile,"wb");
	afptr = fopen(afile,"rb");
	
	if(ofptr==NULL)
	{
		ERROR1("BuildFile::BuildFile(): could not open output file->%s\n",ofile);
		FATAL_ERROR();
	}
	if(afptr==NULL)
	{
		ERROR1("BuildFile::BuildFile(): could not open temporary file->%s\n",afile);
		FATAL_ERROR();
	}
	iOFChar = 0;
	return;

}/*end constructor*/

/*-----------------------------------------------------------------*/

BuildFile::~BuildFile()
{
	flushOutBuff();

	if(fclose(ofptr)){ ERROR1("BuildFile::BuildFile(): problem closing output file ->%s\n",ofile); }
	if(fclose(afptr)){ ERROR1("BuildFile::BuildFile(): problem closing temp file ->%s\n",afile); }
	
	return;

}/*end finalizePass3*/

/*-----------------------------------------------------------------*/

void BuildFile::putByteOutBuff(U1 byte)
{
	int nbytes;

	nbytes = 0;

	ofBuffer[iOFChar] = byte;
	iOFChar++;

	if(iOFChar==BUFFER_SIZE)
	{
		nbytes = fwrite(ofBuffer,sizeof(U1),BUFFER_SIZE,ofptr);
		if(nbytes!=BUFFER_SIZE)
		{
			ERROR1("BuildFile::putByteOutBuff(): error during fwrite to %s\n",ofile);
			FATAL_ERROR();
		}
		iOFChar = 0;
	}
	return;

}/*end putByteOutBuff*/

/*-----------------------------------------------------------------*/

void BuildFile::flushOutBuff()
{
	int nbytes;

	nbytes = 0;

	if(iOFChar>0)
	{
		PASS3_DEBUG1("BuildFile::flushOutBuff(): trying to flush %lu bytes\n",iOFChar);
		nbytes = fwrite(ofBuffer,sizeof(U1),iOFChar,ofptr);
		if(nbytes!=iOFChar)
		{
			ERROR1("BuildFile::flushOutBuff(): only flushed %lu bytes\n",nbytes);
			ERROR1("BuildFile::flushOutBuff(): error during fwrite to %s\n",ofile);
			FATAL_ERROR();
		}
		iOFChar = 0;	
	}
	return;

}/*end flushOutBuff*/

/*-----------------------------------------------------------------*/

void BuildFile::commit2Bytes(U2 val)
{
	wordToBytecode(val,output);
	putByteOutBuff(output[0]);
	putByteOutBuff(output[1]);
	return;

}/*end commit2Bytes*/

/*-----------------------------------------------------------------*/

void BuildFile::commit4Bytes(U4 val)
{
	dwordToBytecode(val,output);
	putByteOutBuff(output[0]);
	putByteOutBuff(output[1]);
	putByteOutBuff(output[2]);
	putByteOutBuff(output[3]);
	return;

}/*end commit4Bytes*/
/*-----------------------------------------------------------------*/

void BuildFile::commit8Bytes(U8 val)
{
	qwordToBytecode(val,output);
	putByteOutBuff(output[0]);
	putByteOutBuff(output[1]);
	putByteOutBuff(output[2]);
	putByteOutBuff(output[3]);
	putByteOutBuff(output[4]);
	putByteOutBuff(output[5]);
	putByteOutBuff(output[6]);
	putByteOutBuff(output[7]);
	return;

}/*end commit8Bytes*/

/*-----------------------------------------------------------------*/

void BuildFile::buildFileFormat()
{
	U8 size_symtbl;
	U8 size_strtbl;
	U8 size_bc;
	U8 i;
	U8 j;
	int ch;

	size_symtbl = 0;
	size_strtbl = 0;
	size_bc     = 0;

	/* 1) determine size of symbol table*/
	
	size_symtbl = size_symtbl + 8; /*table of contents */
	size_symtbl = size_symtbl + SIZE_GLOBREC*((*symTbl).iGlobVar); 
	size_symtbl = size_symtbl + SIZE_PROCREC*((*symTbl).iProc); 

	for(i=0;i<(*symTbl).iProc;i++)
	{
		size_symtbl = size_symtbl + SIZE_RETREC*(((*symTbl).proc[i]).nRet);
		size_symtbl = size_symtbl + SIZE_ARGREC*(((*symTbl).proc[i]).iArg);
		size_symtbl = size_symtbl + SIZE_LOCREC*(((*symTbl).proc[i]).iLocal);
		size_symtbl = size_symtbl + SIZE_LBLREC*(((*symTbl).proc[i]).iLabel);
	}

	/* 2) determine size of string table*/

	size_strtbl = (*strTbl).iStr;

	/* 3) determine size of bytecode */

	size_bc = getFileSize(afile);

	/* 4) commit header to output file */

	putByteOutBuff(0xDE); /*magic word to output file */
	putByteOutBuff(0xED);

	if((*cmdLine).omitDebugData==TRUE)
	{
		commit8Bytes((U8)0);
		commit8Bytes((U8)0);
		commit8Bytes(size_bc);

		ch = fgetc(afptr);
		while(ch!=EOF)
		{
			putByteOutBuff((U1)ch);
			ch = fgetc(afptr);
		}
		return;
	}

	commit8Bytes(size_symtbl);
	commit8Bytes(size_strtbl);
	commit8Bytes(size_bc);

	/* 5) commit tables of contents (# globals and # procs) */

	commit4Bytes((*symTbl).iGlobVar);
	commit4Bytes((*symTbl).iProc);

	/* 6) commit global vars to output file */

	for(i=0;i<(*symTbl).iGlobVar;i++)
	{
		commit8Bytes(((*symTbl).globVar[i]).text);
		putByteOutBuff(((*symTbl).globVar[i]).dType);
		commit8Bytes(((*symTbl).globVar[i]).len);
		commit8Bytes(((*symTbl).globVar[i]).size);
		commit8Bytes(-((S8)((*symTbl).globVar[i]).offset));
		commit4Bytes(((*symTbl).globVar[i]).line);
	}

	/* 7) commit procedures to output file */

	for(i=0;i<(*symTbl).iProc;i++)
	{
		commit8Bytes(((*symTbl).proc[i]).text);
		commit8Bytes(((*symTbl).proc[i]).address);
		commit4Bytes(((*symTbl).proc[i]).line);
		putByteOutBuff(((*symTbl).proc[i]).nRet);
		putByteOutBuff(((*symTbl).proc[i]).iArg);
		putByteOutBuff(((*symTbl).proc[i]).iLocal);
		commit2Bytes(((*symTbl).proc[i]).iLabel);

		for(j=0;j<((*symTbl).proc[i]).nRet;j++)
		{
			commit8Bytes((((*symTbl).proc[i]).ret).text);
			commit4Bytes((((*symTbl).proc[i]).ret).fpOffset);
			commit4Bytes((((*symTbl).proc[i]).ret).line);
		}
		for(j=0;j<((*symTbl).proc[i]).iArg;j++)
		{
			commit8Bytes((((*symTbl).proc[i]).arg[j]).text);
			commit4Bytes((((*symTbl).proc[i]).arg[j]).fpOffset);
			commit4Bytes((((*symTbl).proc[i]).arg[j]).line);
		}
		for(j=0;j<((*symTbl).proc[i]).iLocal;j++)
		{
			commit8Bytes((((*symTbl).proc[i]).local[j]).text);
			commit4Bytes((((*symTbl).proc[i]).local[j]).fpOffset);
			commit4Bytes((((*symTbl).proc[i]).local[j]).line);
		}
		for(j=0;j<((*symTbl).proc[i]).iLabel;j++)
		{
			commit8Bytes((((*symTbl).proc[i]).label[j]).text);
			commit8Bytes((((*symTbl).proc[i]).label[j]).address);
			commit4Bytes((((*symTbl).proc[i]).label[j]).line);
		}
	}

	/* 8) commit string table to output file */

	for(i=0;i<(*strTbl).iStr;i++){ putByteOutBuff((*strTbl).text[i]); }

	/* 9) append bytecode in temp to output file */

	ch = fgetc(afptr);
	while(ch!=EOF)
	{
		putByteOutBuff((U1)ch);
		ch = fgetc(afptr);
	}

	return;

}/*end buildFileFormat*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -