diff --git a/include/opp/iostream.cpp b/include/opp/iostream.cpp index 5e730d2..1faabed 100644 --- a/include/opp/iostream.cpp +++ b/include/opp/iostream.cpp @@ -253,10 +253,11 @@ void ostream::numput(unsigned n, char sign) if (mFlags & uppercase) o = 'A' - 10; - while (n) + unsigned nt = n; + while (nt) { - char d = n % base; - n /= base; + char d = nt % base; + nt /= base; if (d < 10) d += '0'; @@ -289,10 +290,11 @@ void ostream::numput(unsigned long n, char sign) if (mFlags & uppercase) o = 'A' - 10; - while (n) + unsigned long nt = n; + while (nt) { - char d = n % base; - n /= base; + char d = nt % base; + nt /= base; if (d < 10) d += '0'; diff --git a/include/opp/iterator.h b/include/opp/iterator.h index 6d50174..2cedc75 100644 --- a/include/opp/iterator.h +++ b/include/opp/iterator.h @@ -128,8 +128,8 @@ back_insert_iterator back_inserter (CT & c) return back_insert_iterator(c); } -template -insert_iterator inserter (CT & c, const CI & i) +template +insert_iterator inserter (CT & c, const CT::iterator_type & i) { return insert_iterator(c, i); } diff --git a/include/opp/vector.h b/include/opp/vector.h index 07bd2d2..30c8013 100644 --- a/include/opp/vector.h +++ b/include/opp/vector.h @@ -16,11 +16,28 @@ public: typedef T element_type; vector(void) : _data(nullptr), _size(0), _capacity(0) {} + vector(int n) : _data((T*)malloc(n * sizeof(T))), _size(n), _capacity(n) { for(int i=0; iPreMangle("enum "); } + else if (mType == DT_TYPE_VOID) + { + mMangleIdent = Ident::Unique("void"); + } else if (mType == DT_TEMPLATE) { mMangleIdent = Ident::Unique("<"); @@ -1151,7 +1155,18 @@ bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec) } else if (tdec->mType == DT_TYPE_TEMPLATE) { - Declaration* pdec = mScope->Insert(tdec->mIdent, fdec); + Declaration* pdec; + if (tdec->mBase) + { + pdec = mScope->Lookup(tdec->mBase->mIdent); + if (!pdec) + return false; + if (pdec->mType == DT_TYPE_STRUCT) + pdec = pdec->mScope->Lookup(tdec->mIdent); + } + else + pdec = mScope->Insert(tdec->mIdent, fdec); + if (pdec && !pdec->IsSame(fdec)) return false; diff --git a/oscar64/GlobalAnalyzer.cpp b/oscar64/GlobalAnalyzer.cpp index 479330f..558af40 100644 --- a/oscar64/GlobalAnalyzer.cpp +++ b/oscar64/GlobalAnalyzer.cpp @@ -220,7 +220,7 @@ void GlobalAnalyzer::AutoInline(void) { pdec->mVarIndex = dec->mNumVars++; - Expression* aexp = new Expression(pdec->mLocation, EX_ASSIGNMENT); + Expression* aexp = new Expression(pdec->mLocation, EX_INITIALIZATION); Expression* pexp = new Expression(pdec->mLocation, EX_VARIABLE); Expression* lexp = new Expression(dec->mLocation, EX_SEQUENCE); @@ -476,6 +476,27 @@ void GlobalAnalyzer::CheckInterrupt(void) } while (changed); } +bool GlobalAnalyzer::IsStackParam(const Declaration* pdec) const +{ + if (pdec->mType == DT_TYPE_STRUCT) + { + if (pdec->mSize > 4) + return true; + if (pdec->mCopyConstructor) + { + if (!((mCompilerOptions & COPT_OPTIMIZE_INLINE) && (pdec->mCopyConstructor->mFlags & DTF_REQUEST_INLINE))) + return true; + } + if (pdec->mDestructor) + { + if (!((mCompilerOptions & COPT_OPTIMIZE_INLINE) && (pdec->mDestructor->mFlags & DTF_REQUEST_INLINE))) + return true; + } + } + + return false; +} + void GlobalAnalyzer::AnalyzeProcedure(Expression* exp, Declaration* dec) { dec->mUseCount++; @@ -495,7 +516,7 @@ void GlobalAnalyzer::AnalyzeProcedure(Expression* exp, Declaration* dec) Declaration* pdec = dec->mBase->mParams; while (pdec) { - if (pdec->mBase->mType == DT_TYPE_STRUCT && (pdec->mBase->mCopyConstructor || pdec->mBase->mDestructor)) + if (IsStackParam(pdec->mBase)) dec->mBase->mFlags |= DTF_STACKCALL; pdec = pdec->mNext; } @@ -802,7 +823,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo RegisterCall(procDec, pdec->mBase->mCopyConstructor); } - if (pex->mType == EX_CALL && pex->mDecType->mType == DT_TYPE_STRUCT && !(pdec && (pdec->mBase->mType == DT_TYPE_REFERENCE || pdec->mBase->mType == DT_TYPE_RVALUEREF))) + if (pex->mType == EX_CALL && IsStackParam(pex->mDecType) && !(pdec && (pdec->mBase->mType == DT_TYPE_REFERENCE || pdec->mBase->mType == DT_TYPE_RVALUEREF))) ldec->mBase->mFlags |= DTF_STACKCALL; if (pdec) diff --git a/oscar64/GlobalAnalyzer.h b/oscar64/GlobalAnalyzer.h index 7b8570d..ddcfad7 100644 --- a/oscar64/GlobalAnalyzer.h +++ b/oscar64/GlobalAnalyzer.h @@ -34,6 +34,7 @@ protected: Declaration* Analyze(Expression* exp, Declaration* procDec, bool lhs); + bool IsStackParam(const Declaration* pdec) const; bool MarkCycle(Declaration* rootDec, Declaration* procDec); uint64 GetProcFlags(Declaration* to) const; diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index cd03c94..aa32b2c 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -11156,6 +11156,43 @@ void InterCodeBasicBlock::RemoveNonRelevantStatics(void) } } +bool InterCodeBasicBlock::RecheckOuterFrame(void) +{ + if (!mVisited) + { + mVisited = true; + + for (int i = 0; i < mInstructions.Size(); i++) + { + InterInstruction* ins(mInstructions[i]); + if (ins->mCode == IC_LOAD) + { + if (ins->mSrc[0].mMemory == IM_FRAME) + return true; + } + else if (ins->mCode == IC_STORE || ins->mCode == IC_LEA) + { + if (ins->mSrc[1].mMemory == IM_FRAME) + return true; + } + else if (ins->mCode == IC_CONSTANT) + { + if (ins->mConst.mType == IT_POINTER && ins->mConst.mMemory == IM_FRAME) + return true; + } + else if (ins->mCode == IC_PUSH_FRAME) + return true; + } + + if (mTrueJump && mTrueJump->RecheckOuterFrame()) + return true; + if (mFalseJump && mFalseJump->RecheckOuterFrame()) + return true; + } + + return false; +} + void InterCodeBasicBlock::CollectOuterFrame(int level, int& size, bool &inner, bool &inlineAssembler, bool &byteCodeCall) { int i; @@ -11352,6 +11389,44 @@ bool InterCodeBasicBlock::IsEqual(const InterCodeBasicBlock* block) const return false; } +bool InterCodeBasicBlock::PreventsCallerStaticStack(void) +{ + if (!mVisited) + { + mVisited = true; + + for (int i = 0; i < mInstructions.Size(); i++) + { + InterInstruction* ins(mInstructions[i]); + if (ins->mCode == IC_CALL || ins->mCode == IC_CALL_NATIVE) + { + if (ins->mSrc[0].mTemp >= 0 || !ins->mSrc[0].mLinkerObject) + return false; + else if (ins->mSrc[0].mLinkerObject == mProc->mLinkerObject) + ; // Simple recursion + else if (!(ins->mSrc[0].mLinkerObject->mFlags & LOBJF_STATIC_STACK)) + return false; + } + else if (ins->mCode == IC_DISPATCH) + { + for (int j = 0; j < mProc->mCalledFunctions.Size(); j++) + { + if (!(mProc->mCalledFunctions[j]->mLinkerObject && (mProc->mCalledFunctions[j]->mLinkerObject->mFlags & LOBJF_STATIC_STACK))) + return false; + } + } + } + + if (mTrueJump && mTrueJump->PreventsCallerStaticStack()) + return true; + if (mFalseJump && mFalseJump->PreventsCallerStaticStack()) + return true; + } + + return false; +} + + bool InterCodeBasicBlock::CheckStaticStack(void) { if (!mVisited) @@ -11368,7 +11443,13 @@ bool InterCodeBasicBlock::CheckStaticStack(void) return false; } else if (mInstructions[i]->mCode == IC_DISPATCH) - return false; + { + for (int j = 0; j < mProc->mCalledFunctions.Size(); j++) + { + if (!(mProc->mCalledFunctions[j]->mLinkerObject && (mProc->mCalledFunctions[j]->mLinkerObject->mFlags & LOBJF_STATIC_STACK))) + return false; + } + } } if (mTrueJump && !mTrueJump->CheckStaticStack()) @@ -12571,6 +12652,8 @@ static int FindStore(InterCodeBasicBlock* block, int pos, const InterOperand& op op.mVarIndex == ins->mSrc[1].mVarIndex) return pos; } + if (ins->mCode == IC_POP_FRAME && op.mMemory == IM_PARAM) + return -1; } return -1; @@ -17592,6 +17675,13 @@ void InterCodeProcedure::Close(void) mLinkerObject->mFlags |= LOBJF_STATIC_STACK; } + if (!(mLinkerObject->mFlags & LOBJF_STATIC_STACK)) + { + ResetVisited(); + if (!mEntryBlock->PreventsCallerStaticStack()) + mLinkerObject->mFlags |= LOBJF_STATIC_STACK; + } + if (!mEntryBlock->mTrueJump) { int nconst = 0, nvariables = 0, nparams = 0, ncalls = 0, nret = 0, nother = 0, nops = 0; @@ -17668,7 +17758,14 @@ void InterCodeProcedure::Close(void) mLoadsIndirect = false; mReferencedGlobals.Reset(mModule->mGlobalVars.Size()); mModifiedGlobals.Reset(mModule->mGlobalVars.Size()); - +#if 1 + if (!mLeafProcedure && mCommonFrameSize > 0) + { + ResetVisited(); + if (!mEntryBlock->RecheckOuterFrame()) + mCommonFrameSize = 0; + } +#endif ResetVisited(); mEntryBlock->CollectGlobalReferences(mReferencedGlobals, mModifiedGlobals, mStoresIndirect, mLoadsIndirect, mGlobalsChecked); } diff --git a/oscar64/InterCode.h b/oscar64/InterCode.h index 1049569..0f4b4f8 100644 --- a/oscar64/InterCode.h +++ b/oscar64/InterCode.h @@ -60,16 +60,16 @@ extern int InterTypeSize[]; enum InterMemory { IM_NONE, - IM_PARAM, + IM_PARAM, // Memory used to access parameters on stack IM_LOCAL, IM_GLOBAL, - IM_FRAME, + IM_FRAME, // Memory used to pass parameters on stack IM_PROCEDURE, IM_INDIRECT, IM_TEMPORARY, IM_ABSOLUTE, - IM_FPARAM, - IM_FFRAME, + IM_FPARAM, // Memory used to access parameters in zp + IM_FFRAME, // Memory used to pass parameters in zp }; enum InterOperator @@ -488,8 +488,10 @@ public: void MapVariables(GrowingVariableArray& globalVars, GrowingVariableArray& localVars); void CollectOuterFrame(int level, int& size, bool& inner, bool& inlineAssembler, bool& byteCodeCall); + bool RecheckOuterFrame(void); bool IsLeafProcedure(void); + bool PreventsCallerStaticStack(void); bool ForwardDiamondMovedTemp(void); bool ForwardLoopMovedTemp(void); diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index ce7a70f..e4d6c1a 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -1018,7 +1018,10 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro ExValue vp(pdec ? pdec->mBase : TheSignedIntTypeDeclaration, ains->mDst.mTemp, 1); - vr = TranslateExpression(procType, proc, block, texp, destack, breakBlock, continueBlock, inlineMapper, &vp); + if (pdec && (pdec->mBase->mType == DT_TYPE_STRUCT || pdec->mBase->mType == DT_TYPE_UNION)) + vr = TranslateExpression(procType, proc, block, texp, destack, breakBlock, continueBlock, inlineMapper, &vp); + else + vr = TranslateExpression(procType, proc, block, texp, destack, breakBlock, continueBlock, inlineMapper, nullptr); if (!(pdec && pdec->mBase->IsReference()) && (vr.mType->mType == DT_TYPE_STRUCT || vr.mType->mType == DT_TYPE_UNION)) { @@ -1056,6 +1059,11 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro vr = Dereference(proc, texp, block, vr, 1); else if (pdec && (pdec->mBase->IsReference() && !vr.mType->IsReference())) vr = Dereference(proc, texp, block, vr, 1); + else if (vr.mType->IsReference() && !(pdec && pdec->mBase->IsReference())) + { + vr.mReference++; + vr = Dereference(proc, texp, block, vr); + } else vr = Dereference(proc, texp, block, vr); @@ -4710,8 +4718,8 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod { InterCodeProcedure* proc = new InterCodeProcedure(mod, dec->mLocation, dec->mQualIdent, mLinker->AddObject(dec->mLocation, dec->mQualIdent, dec->mSection, LOT_BYTE_CODE, dec->mAlignment)); -#if 0 - if (proc->mIdent && !strcmp(proc->mIdent->mString, "opp::insert_iterator>::+insert_iterator")) +#if 1 + if (proc->mIdent && !strcmp(proc->mIdent->mString, "dividers")) exp->Dump(0); #endif #if 0 diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index d0964bf..9c83f53 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -40784,7 +40784,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc) { mInterProc = proc; - CheckFunc = !strcmp(mInterProc->mIdent->mString, "main"); + CheckFunc = !strcmp(mInterProc->mIdent->mString, "dump>"); int nblocks = proc->mBlocks.Size(); tblocks = new NativeCodeBasicBlock * [nblocks]; diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index 80982a5..ce6bce8 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -612,12 +612,22 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags, bool qualified) else mScanner->NextToken(); - while (qualified && dec && (dec->mType == DT_TYPE_STRUCT || dec->mType == DT_NAMESPACE) && ConsumeTokenIf(TK_COLCOLON)) + while (qualified && dec && (dec->mType == DT_TYPE_STRUCT || dec->mType == DT_NAMESPACE || dec->mType == DT_TYPE_TEMPLATE) && ConsumeTokenIf(TK_COLCOLON)) { if (ExpectToken(TK_IDENT)) { pident = mScanner->mTokenIdent; - dec = dec->mScope->Lookup(mScanner->mTokenIdent); + if (dec->mType == DT_TYPE_TEMPLATE) + { + Declaration* ndec = new Declaration(mScanner->mLocation, DT_TYPE_TEMPLATE); + ndec->mFlags |= DTF_DEFINED; + ndec->mBase = dec; + ndec->mIdent = mScanner->mTokenIdent; + dec = ndec; + } + else + dec = dec->mScope->Lookup(mScanner->mTokenIdent); + mScanner->NextToken(); } } @@ -1851,6 +1861,7 @@ void Parser::AddDefaultConstructors(Declaration* pthis) bool simpleDestructor = true, simpleAssignment = true, simpleConstructor = true, simpleCopy = true; bool inlineDestructor = true; bool inlineConstructor = true; + bool inlineCopy = true; const Ident* dtorident = pthis->mBase->mIdent->PreMangle("~");; @@ -1904,7 +1915,11 @@ void Parser::AddDefaultConstructors(Declaration* pthis) inlineConstructor = false; } if (bcdec->mBase->mCopyConstructor) + { simpleCopy = false; + if (!(bcdec->mBase->mCopyConstructor->mBase->mFlags & DTF_REQUEST_INLINE)) + inlineCopy = false; + } if (bcdec->mBase->mCopyAssignment) simpleAssignment = false; bcdec = bcdec->mNext; @@ -2061,6 +2076,8 @@ void Parser::AddDefaultConstructors(Declaration* pthis) cdec->mBase = ctdec; cdec->mFlags |= cdec->mBase->mFlags & (DTF_CONST | DTF_VOLATILE); + if (inlineCopy) + cdec->mFlags |= DTF_REQUEST_INLINE; cdec->mSection = mCodeSection; @@ -2254,7 +2271,7 @@ void Parser::AddDefaultConstructors(Declaration* pthis) Expression* thisexp = new Expression(mScanner->mLocation, EX_PREFIX); thisexp->mToken = TK_MUL; - thisexp->mDecType = pthis->mBase; + thisexp->mDecType = pthis->mBase->ToMutableType(); thisexp->mLeft = pthisexp; cdec->mValue = new Expression(mScanner->mLocation, EX_RETURN); @@ -4547,6 +4564,8 @@ Expression* Parser::ParseSimpleExpression(bool lhs) dexp->mDecType = texp->mDecType->mBase; dexp->mLeft = texp; + dexp = dexp->ConstantFold(mErrors); + exp = ParseQualify(dexp); } else @@ -4742,6 +4761,8 @@ Expression* Parser::ParseQualify(Expression* exp) { Declaration* dtype = exp->mDecType; + exp = exp->ConstantFold(mErrors); + if (dtype->mType == DT_TYPE_REFERENCE || dtype->mType == DT_TYPE_RVALUEREF) dtype = dtype->mBase; @@ -6403,7 +6424,7 @@ Expression* Parser::CheckOperatorOverload(Expression* exp) texp->mDecType->mSize = 2; Expression* lexp = new Expression(nexp->mLocation, EX_LIST); - lexp->mLeft = texp; + lexp->mLeft = texp->ConstantFold(mErrors); lexp->mRight = nexp->mRight; nexp->mRight = lexp; @@ -6446,7 +6467,7 @@ Expression* Parser::CheckOperatorOverload(Expression* exp) texp->mDecType->mSize = 2; Expression* lexp = new Expression(nexp->mLocation, EX_LIST); - lexp->mLeft = texp; + lexp->mLeft = texp->ConstantFold(mErrors); lexp->mRight = nexp->mRight; nexp->mRight = lexp; @@ -6495,7 +6516,7 @@ Expression* Parser::CheckOperatorOverload(Expression* exp) texp->mDecType->mBase = exp->mLeft->mDecType; texp->mDecType->mSize = 2; - nexp->mRight = texp; + nexp->mRight = texp->ConstantFold(mErrors); nexp = ResolveOverloadCall(nexp); nexp->mDecType = nexp->mLeft->mDecType->mBase; @@ -6544,7 +6565,7 @@ Expression* Parser::CheckOperatorOverload(Expression* exp) texp->mDecType->mSize = 2; Expression* lexp = new Expression(nexp->mLocation, EX_LIST); - lexp->mLeft = texp; + lexp->mLeft = texp->ConstantFold(mErrors); lexp->mRight = new Expression(nexp->mLocation, EX_CONSTANT); lexp->mRight->mDecType = TheSignedIntTypeDeclaration; lexp->mRight->mDecValue = new Declaration(nexp->mLocation, DT_CONST_INTEGER); @@ -6660,7 +6681,7 @@ Expression* Parser::CheckOperatorOverload(Expression* exp) texp->mDecType->mSize = 2; Expression* lexp = new Expression(nexp->mLocation, EX_LIST); - lexp->mLeft = texp; + lexp->mLeft = texp->ConstantFold(mErrors); lexp->mRight = nexp->mRight; nexp->mRight = lexp; @@ -6719,7 +6740,7 @@ Expression* Parser::CheckOperatorOverload(Expression* exp) texp->mDecType->mBase = tdec; texp->mDecType->mSize = 2; - nexp->mRight = texp; + nexp->mRight = texp->ConstantFold(mErrors); nexp = ResolveOverloadCall(nexp); nexp->mDecType = nexp->mLeft->mDecType->mBase; @@ -6758,7 +6779,7 @@ Expression* Parser::CheckOperatorOverload(Expression* exp) texp->mDecType->mBase = tdec; texp->mDecType->mSize = 2; - nexp->mRight = texp; + nexp->mRight = texp->ConstantFold(mErrors); nexp = ResolveOverloadCall(nexp); nexp->mDecType = nexp->mLeft->mDecType->mBase; @@ -7614,6 +7635,7 @@ void Parser::ParseTemplateDeclaration(void) { bdec->mIdent = mScanner->mTokenIdent; bdec->mQualIdent = mScope->Mangle(mScanner->mTokenIdent); + bdec->mScope = new DeclarationScope(nullptr, SLEVEL_CLASS, bdec->mQualIdent); while (mScanner->mToken != TK_SEMICOLON && mScanner->mToken != TK_OPEN_BRACE) mScanner->NextToken();