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

📄 frame.cpp

📁 在手机操作系统symbina上使用的一个脚本扩展语言的代码实现,可以参考用于自己的开发
💻 CPP
字号:
// FRAME.CPP
//
// Copyright (c) 1997-1999 Symbian Ltd.  All rights reserved.
//


#include "Frame.h"
#include <module.h>
#include <opldbg.h>
#include "oplutil.h"
#include "opldialg.h"

CFrame::CFrame()
	{
	}

_LIT(KOplFrame,"OPL Frame");
#define FPanic(A) User::Panic(KOplFrame,A)

void CFrame::ConstructL(CStack& aStack,COplRuntime& aRuntime,CProcDef* aProcDef,TUint8* aReturnIP,CFrame* aPrevFrame,TInt aFlags)
	{ // the order of these is important
	// any leave here is reported as an error in the calling frame
	__ASSERT_DEBUG(aProcDef!=NULL,FPanic(100));
	iRuntime=&aRuntime;
	iReturnIP=aReturnIP;
	iPrevFrame=aPrevFrame;
	iProcDef=aProcDef;
	iFlags=aFlags;
	iSP=aStack.StackPtr();
	iProcDef->IncCountL();
	CProcedure* procedure=iProcDef->Procedure();
	iMaxStack=procedure->iMaxStack;
	if (aStack.FreeBytes()<iMaxStack)
		User::LeaveNoMemory();
	iFrameCell=(TUint8*)aRuntime.Heap64().AllocL(procedure->iDataSize);
	if (aRuntime.UserFlags()&KOplState64kLimit)
		{
		RHeap& heap=aRuntime.Heap64();
		if (heap.Size()>K64Kbytes)
			{
			heap.Free(iFrameCell);
			iFrameCell=NULL;
			heap.Compress();
			User::LeaveNoMemory();
			}
		}
	Mem::FillZ(iFrameCell,procedure->iDataSize);
	procedure->AddGlobalsL(aRuntime,iFrameCell);
	iFlags|=KGlobalsAdded;
	GetParamsL(aStack,procedure);
	}

void CFrame::FinishConstructionL()
	{ // any leave here is reported as an error in this frame
	CDebuggerBase* debugger=iRuntime->Debugger();
	if (debugger!=NULL)
		{
		iFlags|=KDebuggerSignalled;
		debugger->FrameLoad(iProcDef->ProcName(),iProcDef->ModuleName(),iProcDef->Module().OplName());
		}
	CProcedure* procedure=iProcDef->Procedure();
	GetExternsL(procedure);
	iRuntime->SetIP(procedure->iQCodeCell);
	DoStringFixUps(); //these can not leave
	DoArrayFixUps();
	iStartOfIndTbl=procedure->iTotalTableSize+18;
	}

TAny* CFrame::VarAddrRel(TInt aOffset)
	{
	return iFrameCell+aOffset;
	}

TAny* CFrame::VarAddrInd(TInt aIndex)
	{
	__ASSERT_DEBUG(iIndirectTbl!=NULL,FPanic(5));
	TInt index=(aIndex-iStartOfIndTbl)/2;
	return iIndirectTbl->operator[](index);
	}

SOplSubProc CFrame::GetSubProc(TInt aIndex)
	{
	CArrayFixFlat<SOplSubProc>* iSPT=iProcDef->Procedure()->iSubProcs;
	__ASSERT_DEBUG(iSPT!=NULL,FPanic(7));
	TInt ii=iSPT->Count();
	FOREVER
		{
		ii--;
		__ASSERT_ALWAYS((ii>=0),FPanic(8)); // if not found
		if ((iSPT->operator[](ii)).offset==aIndex) // aIndex is an offset with opl1993 opo
			break;
		}
	return iSPT->operator[](ii);
	}



void CFrame::DoStringFixUps()
	{
	CArrayFixFlat<SStringFixUp>* iSFU;
	if ((iSFU=iProcDef->Procedure()->iStringFixUps)==NULL)
		return;
	SStringFixUp* stringFixUp=&(*iSFU)[0];
	for (TInt ii=iSFU->Count()-1;ii>=0;--ii,stringFixUp++)
		{
		OplUtil::PutWord((iFrameCell+stringFixUp->offset),(TInt16)stringFixUp->maxLen);
		}
	}

void CFrame::DoArrayFixUps()
	{
	CArrayFixFlat<SArrayFixUp>* iAFU;
	if ((iAFU=iProcDef->Procedure()->iArrayFixUps)==NULL)
		return;
	SArrayFixUp* arrayFixUp=&(*iAFU)[0];
	for (TInt ii=iAFU->Count()-1;ii>=0;--ii,arrayFixUp++)
		{
		OplUtil::PutWord((TUint16*)(iFrameCell+arrayFixUp->offset),(TUint16)arrayFixUp->maxIndex);
		}
	}

void CFrame::GetParamsL(CStack& aStack,CProcedure* aProcedure)
	{
	CArrayFixFlat<TInt>* pParamList=aProcedure->iParamList;
	if (pParamList!=NULL)
		{
		iIndirectTbl=new(ELeave) CArrayFixFlat<TAny*>(1);
		TInt count=pParamList->operator[](0);
		aStack.CheckParamCountL(count);
		for (TInt ii=1;ii<=count;++ii)
			{
			TAny* aPtr=aStack.NextParamL(pParamList->operator[](ii));
			iIndirectTbl->InsertL(0,aPtr);
			}
		aStack.SetStackPtr(iSP);
		}
	else
		{
		aStack.CheckParamCountL(0);
		aStack.SetStackPtr(iSP);
		}
	}

void CFrame::GetExternsL(CProcedure* aProcedure)
	{
	CArrayFixFlat<SOplGlobal>* pExtern=aProcedure->iExternals;
	if (pExtern!=NULL) // none to resolve
		{
		if (iIndirectTbl==NULL) //no params so create table here
			iIndirectTbl=new(ELeave) CArrayFixFlat<TAny*>(1);
		TBool globalNotFound=FALSE;
		CGlobalsTbl& globTbl=iRuntime->GlobalTbl();
		TInt count=pExtern->Count();
		for (TInt ii=0;ii<count;++ii)
			{
			SOplGlobal global=pExtern->operator[](ii);
			const TAny* ptr=globTbl.Find(global.name,global.type);
			if (ptr==NULL)
				{
				TBuf<256> buf(global.name);
				_LIT(KBrackets,"()");
				if (global.type&0x80)
					buf.Append(KBrackets);
				if (!globalNotFound)
					{
					iRuntime->SetErrorBuffer(&buf);
					globalNotFound=TRUE;
					}
				else
					{
					_LIT(KComma,",");
					if (iRuntime->AppendErrorText(KComma)||iRuntime->AppendErrorText(buf))
						break; // error buffer full
					}
				continue;
				}
			iIndirectTbl->AppendL(CONST_CAST(TAny*,ptr));
			}
		if (globalNotFound)
			User::Leave(KOplErrUndef);
		}
	}

void COplRuntime::SetFrame(CFrame* aFrame)
	{
	iFrame=aFrame;
	}


CFrame::~CFrame()
	{
	COplDialog* dialog=iRuntime->Dialog();
	if (dialog&&(dialog->InitFrame()==this))
		{
		delete dialog;
		iRuntime->SetDialog(NULL);
		}
	CProcedure* proc=iProcDef->Procedure();
	if (proc!=NULL)
		{
		CArrayFixFlat<SOplGlobal>* globals=proc->iGlobals;
		if (globals!=NULL && (iFlags&KGlobalsAdded))
			{
			TInt count=globals->Count();
			for (TInt ii=0;ii<count;++ii)
				{
				const SOplGlobal *global=&globals->At(ii);
				iRuntime->GlobalTbl().Remove(global->name);
				}
			}
		iProcDef->DecCount();
		}
	if (iFlags&KDebuggerSignalled) // debugger exists!
		iRuntime->Debugger()->FrameUnload();
	iRuntime->SetFrame(iPrevFrame);
	iRuntime->SetIP(iReturnIP);
	delete iIndirectTbl;
	iRuntime->Heap64().Free(iFrameCell);
	}

CProcedure::CProcedure()
	{
	}

void CProcedure::ConstructL(CProcDef* aProcDef,const RFile& aFile)
	{
	TInt offset=aProcDef->FileOffset();
	TBuf8<2> aBuf;
	User::LeaveIfError(aFile.Read(offset,aBuf,2));
	TInt dataDefSize=*(TUint16*)(aBuf.Ptr()); //implicit cast to TInt
	offset+=2;
	TUint8* dataPtr=(TUint8*)User::AllocLC(dataDefSize);
	TPtr8 des(dataPtr,dataDefSize);	
	User::LeaveIfError(aFile.Read(offset,des,dataDefSize));
	TInt QCodeOffset=dataDefSize+offset;
	offset=0;
	iDataSize=ReadWordL(offset,dataPtr);
	LoadQCodeL(QCodeOffset,ReadWordL(offset,dataPtr),aFile);
	iMaxStack=ReadWordL(offset,dataPtr);

	TInt count=ReadWordL(offset,dataPtr);

	if (count>0)
		{
		iParamList=new(ELeave) CArrayFixFlat<TInt>(1);
		iParamList->AppendL(count);
		for (;count>0;--count)
			{
			TInt aByte=ReadWordL(offset,dataPtr);
			iParamList->AppendL(aByte);
			}
		}
	TInt tableSize=ReadWordL(offset,dataPtr);
	TInt startOfGlobals=offset;

	if (tableSize>0)
		{
		iGlobals=new(ELeave) CArrayFixFlat<SOplGlobal>(1);
		tableSize+=offset;
		while (tableSize>offset)
			{
			SOplGlobal aGlobal;
			aGlobal.name=ReadStringL(offset,dataPtr);
			aGlobal.type=ReadWordL(offset,dataPtr);
			aGlobal.offset=ReadWordL(offset,dataPtr);
			iGlobals->AppendL(aGlobal);
			}
		__ASSERT_DEBUG(tableSize==offset,FPanic(2));
		}
	tableSize=ReadWordL(offset,dataPtr);
	iTotalTableSize=offset-startOfGlobals+tableSize-2;

	if (tableSize>0)
		{
		iSubProcs=new(ELeave) CArrayFixFlat<SOplSubProc>(1);
		tableSize+=offset;
		while (tableSize>offset)
			{
			SOplSubProc aSubProc;
			aSubProc.offset=offset-startOfGlobals+16;//18 header bytes - 2 for the table size
			aSubProc.name=ReadStringL(offset,dataPtr);
			aSubProc.noOfParam=ReadWordL(offset,dataPtr);
			iSubProcs->AppendL(aSubProc);
			}
		__ASSERT_DEBUG(tableSize==offset,FPanic(3));
		}
	if (ReadWordL(offset,dataPtr)>0)
		{
		offset-=(1+KOplAlignment); // "put back" first string's LBC
		iExternals=new(ELeave) CArrayFixFlat<SOplGlobal>(1);
		SOplGlobal aGlobal;
		aGlobal.name=ReadStringL(offset,dataPtr);
		aGlobal.type=ReadWordL(offset,dataPtr);
		iExternals->AppendL(aGlobal);
		while (ReadWordL(offset,dataPtr)>0)
			{
			offset-=(1+KOplAlignment); // "put back" string's LBC
			aGlobal.name=ReadStringL(offset,dataPtr);
			aGlobal.type=ReadWordL(offset,dataPtr);
			iExternals->AppendL(aGlobal);
			}
		}
	if (ReadWordL(offset,dataPtr)>0)
		{
		offset-=2;
		iStringFixUps=new(ELeave) CArrayFixFlat<SStringFixUp>(1);
		SStringFixUp stringFixUp;
		while ((stringFixUp.offset=ReadWordL(offset,dataPtr))>0)
			{
			stringFixUp.maxLen=ReadWordL(offset,dataPtr);
			iStringFixUps->AppendL(stringFixUp);
			}
		}
	if (ReadWordL(offset,dataPtr)>0)
		{
		offset-=2;
		iArrayFixUps=new(ELeave) CArrayFixFlat<SArrayFixUp>(1);
		SArrayFixUp arrayFixUp;
		while ((arrayFixUp.offset=ReadWordL(offset,dataPtr))>0)
			{
			arrayFixUp.maxIndex=ReadWordL(offset,dataPtr);
			iArrayFixUps->AppendL(arrayFixUp);
			}
		}
	CleanupStack::PopAndDestroy(); // dataDef
	}

void CProcedure::AddGlobalsL(COplRuntime& aRuntime,TUint8* aCell)
	{
	if (iGlobals==NULL)
		return;
	TInt count=iGlobals->Count();
	aRuntime.GlobalTbl().PrepareToAddC(); // will restore state on a leave
	for (TInt ii=0;ii<count;++ii)
		{
		const SOplGlobal *global=&iGlobals->At(ii);
		aRuntime.GlobalTbl().AddL(global->name,global->type,(aCell+global->offset));
		}
	CleanupStack::Pop(); // globals table
	}


TInt CProcedure::ReadWordL(TInt& aOffset,const TUint8* aDataPtr)
	{
	TInt word=(TUint16)OplUtil::GetWord((TUint16*)(aDataPtr+aOffset));
	aOffset+=2;
	return word;
	}

TBuf<KMaxGlobalNameLen> CProcedure::ReadStringL(TInt& aPos,const TUint8* aDataPtr)
	{
	TInt strLen=ReadWordL(aPos,aDataPtr);
	__ASSERT_ALWAYS(strLen<=KMaxGlobalNameLen,FPanic(strLen));
	TPtrC ptr((TText*)(aDataPtr+aPos),strLen);
	TBuf<KMaxGlobalNameLen> aBuf(ptr);
	aPos+=strLen*sizeof(TText);
	return aBuf;
	}

void CProcedure::LoadQCodeL(TInt aPos,TInt aLength,const RFile& aFile)
	{
	TUint8* aQCodeCell=(TUint8*)User::AllocLC(aLength);
	TPtr8 ptr(aQCodeCell,aLength);
	User::LeaveIfError(aFile.Read(aPos,ptr,aLength));
	CleanupStack::Pop();
	iQCodeCell=aQCodeCell;
	}

CProcedure::~CProcedure()
	{
	User::Free(iQCodeCell);
	delete iParamList;
	delete iGlobals;
	delete iSubProcs;
	delete iExternals;
	delete iStringFixUps;
	delete iArrayFixUps;
	}

⌨️ 快捷键说明

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