| /******************************************************************************* | |
| * Copyright (c) 2016 CEA LIST. | |
| * | |
| * All rights reserved. This program and the accompanying materials | |
| * are made available under the terms of the Eclipse Public License v1.0 | |
| * which accompanies this distribution, and is available at | |
| * http://www.eclipse.org/legal/epl-v10.html | |
| * | |
| * Created on: 14 févr. 2013 | |
| * | |
| * Contributors: | |
| * Arnault Lapitre (CEA LIST) arnault.lapitre@cea.fr | |
| * - Initial API and implementation | |
| ******************************************************************************/ | |
| #include "CompilationEnvironment.h" | |
| namespace sep | |
| { | |
| /** | |
| * STATIC | |
| * ATTRIBUTES | |
| */ | |
| bool COMPILE_CONTEXT::DEFAUL_TYPE_CHECKING_MASK = true; | |
| bool COMPILE_CONTEXT::INLINE_DISABLE_MASK = false; | |
| bool COMPILE_CONTEXT::INLINE_ENABLE_MASK = false; | |
| bool COMPILE_CONTEXT::INLINE_PROCEDURE_MASK = true; | |
| /** | |
| * report debug Context | |
| */ | |
| OutStream & COMPILE_CONTEXT::debugContext(OutStream & os) | |
| { | |
| os << TAB << "Context:> " | |
| << mCompileCtx->getFullyQualifiedNameID() << std::endl; | |
| if( isSpecificRuntimeCtx() ) | |
| { | |
| os << TAB << "Runtime:> " | |
| << mRuntimeCtx->getFullyQualifiedNameID() << std::endl; | |
| } | |
| if( mVariableCtx != NULL ) | |
| { | |
| os << TAB << "DataVar:> " | |
| << mVariableCtx->getFullyQualifiedNameID() << std::endl; | |
| } | |
| return( os ); | |
| } | |
| /** | |
| * report error Context & Location | |
| */ | |
| OutStream & COMPILE_CONTEXT::errorContext(OutStream & os) | |
| { | |
| AVM_IF_DEBUG_FLAG( COMPILING ) | |
| os << "ctx:> " << mCompileCtx->getFullyQualifiedNameID() << std::endl; | |
| AVM_ENDIF_DEBUG_FLAG( COMPILING ) | |
| BaseAvmProgram * errorCtx = | |
| ( mCompileCtx == mRuntimeCtx )? mCompileCtx : mRuntimeCtx; | |
| errorCtx->getAstElement()->errorLocation(os, | |
| errorCtx->hasContainer() ? | |
| errorCtx->getContainer()->getAstElement() : NULL); | |
| return( os ); | |
| } | |
| PairOutStream & COMPILE_CONTEXT::errorContext(PairOutStream & os) | |
| { | |
| AVM_IF_DEBUG_FLAG( COMPILING ) | |
| os << "ctx:> " << mCompileCtx->getFullyQualifiedNameID() << std::endl; | |
| AVM_ENDIF_DEBUG_FLAG( COMPILING ) | |
| BaseAvmProgram * errorCtx = | |
| ( mCompileCtx == mRuntimeCtx )? mCompileCtx : mRuntimeCtx; | |
| errorCtx->getAstElement()->errorLocation(os, | |
| errorCtx->hasContainer() ? | |
| errorCtx->getContainer()->getAstElement() : NULL); | |
| return( os ); | |
| } | |
| TripleOutStream & COMPILE_CONTEXT::errorContext(TripleOutStream & os) | |
| { | |
| AVM_IF_DEBUG_FLAG( COMPILING ) | |
| os << "ctx:> " << mCompileCtx->getFullyQualifiedNameID() << std::endl; | |
| AVM_ENDIF_DEBUG_FLAG( COMPILING ) | |
| BaseAvmProgram * errorCtx = | |
| ( mCompileCtx == mRuntimeCtx )? mCompileCtx : mRuntimeCtx; | |
| errorCtx->getAstElement()->errorLocation(os, | |
| errorCtx->hasContainer() ? | |
| errorCtx->getContainer()->getAstElement() : NULL); | |
| return( os ); | |
| } | |
| /** | |
| * report warning Context & Location | |
| */ | |
| OutStream & COMPILE_CONTEXT::warningContext(OutStream & os) | |
| { | |
| AVM_IF_DEBUG_FLAG( COMPILING ) | |
| os << "ctx:> " << mCompileCtx->getFullyQualifiedNameID() << std::endl; | |
| AVM_ENDIF_DEBUG_FLAG( COMPILING ) | |
| BaseAvmProgram * warningCtx = | |
| ( mCompileCtx == mRuntimeCtx )? mCompileCtx : mRuntimeCtx; | |
| warningCtx->getAstElement()->warningLocation(os, | |
| warningCtx->hasContainer() ? | |
| warningCtx->getContainer()->getAstElement() : NULL); | |
| return( os ); | |
| } | |
| PairOutStream & COMPILE_CONTEXT::warningContext(PairOutStream & os) | |
| { | |
| AVM_IF_DEBUG_FLAG( COMPILING ) | |
| os << "ctx:> " << mCompileCtx->getFullyQualifiedNameID() << std::endl; | |
| AVM_ENDIF_DEBUG_FLAG( COMPILING ) | |
| BaseAvmProgram * warningCtx = | |
| ( mCompileCtx == mRuntimeCtx )? mCompileCtx : mRuntimeCtx; | |
| warningCtx->getAstElement()->warningLocation(os, | |
| warningCtx->hasContainer() ? | |
| warningCtx->getContainer()->getAstElement() : NULL); | |
| return( os ); | |
| } | |
| TripleOutStream & COMPILE_CONTEXT::warningContext(TripleOutStream & os) | |
| { | |
| AVM_IF_DEBUG_FLAG( COMPILING ) | |
| os << "ctx:> " << mCompileCtx->getFullyQualifiedNameID() << std::endl; | |
| AVM_ENDIF_DEBUG_FLAG( COMPILING ) | |
| BaseAvmProgram * warningCtx = | |
| ( mCompileCtx == mRuntimeCtx )? mCompileCtx : mRuntimeCtx; | |
| warningCtx->getAstElement()->warningLocation(os, | |
| warningCtx->hasContainer() ? | |
| warningCtx->getContainer()->getAstElement() : NULL); | |
| return( os ); | |
| } | |
| /** | |
| * Serialization | |
| */ | |
| void COMPILE_CONTEXT::strHeader(OutStream & os) const | |
| { | |
| os << TAB << ( hasModifier() ? getModifier().toString() : "" ) | |
| << "COMPILER< ctx: " << mCompileCtx->getFullyQualifiedNameID(); | |
| if( mCompileCtx != mRuntimeCtx ) | |
| { | |
| os << " , run: " << mRuntimeCtx->getFullyQualifiedNameID(); | |
| } | |
| if( (mType != NULL) && (mType != TypeManager::UNIVERSAL) ) | |
| { | |
| os << " , type " << ( mNeedTypeChecking ? "?:" : ":" ) | |
| << str_header( mType ); | |
| } | |
| os << " >"; | |
| } | |
| void COMPILE_CONTEXT::toStream(OutStream & os) const | |
| { | |
| os << TAB << ( hasModifier() ? getModifier().toString() : "" ) | |
| << "compiler {" << EOL | |
| << TAB2 << "context = " << str_header( mCompileCtx ) << EOL | |
| << TAB2 << "runtime = " << str_header( mRuntimeCtx ) << EOL; | |
| if( mType != NULL ) | |
| { | |
| os << TAB2 << ( mNeedTypeChecking ? "check_" : "" ) | |
| << "type = " << str_header( mType ) << EOL; | |
| } | |
| os << TAB << "}" << EOL; | |
| } | |
| /////////////////////////////////////////////////////////////////////////// | |
| // CACHE MANAGER | |
| /////////////////////////////////////////////////////////////////////////// | |
| List< COMPILE_CONTEXT * > CompilationEnvironment::COMPILE_CONTEXT_CACHE; | |
| void CompilationEnvironment::initCache() | |
| { | |
| for( avm_size_t i = 0 ; i < COMPILE_CONTEXT_INITIAL_COUNT ; ++i ) | |
| { | |
| COMPILE_CONTEXT_CACHE.append( | |
| new COMPILE_CONTEXT(NULL, NULL, NULL, NULL) ); | |
| } | |
| } | |
| void CompilationEnvironment::finalizeCache() | |
| { | |
| avm_size_t finalCacheSize = 0; | |
| while( COMPILE_CONTEXT_CACHE.nonempty() ) | |
| { | |
| AVM_IF_DEBUG_LEVEL_FLAG( HIGH , COMPILING ) | |
| AVM_OS_TRACE << "COMPILE_CONTEXT::finalize:> @" | |
| << avm_address_t( COMPILE_CONTEXT_CACHE.last() ) << std::endl; | |
| AVM_ENDIF_DEBUG_LEVEL_FLAG( HIGH , COMPILING ) | |
| ++finalCacheSize; | |
| delete( COMPILE_CONTEXT_CACHE.pop_last() ); | |
| } | |
| AVM_IF_DEBUG_LEVEL_FLAG( HIGH , COMPILING ) | |
| AVM_OS_TRACE << "COMPILE_CONTEXT::finalize#cache:> count = " | |
| << finalCacheSize << std::endl; | |
| AVM_ENDIF_DEBUG_LEVEL_FLAG( HIGH , COMPILING ) | |
| } | |
| COMPILE_CONTEXT * CompilationEnvironment::newCTX(COMPILE_CONTEXT * PREV, | |
| BaseAvmProgram * aCompileCtx, ExecutableForm * aRuntimeCtx, | |
| InstanceOfData * aVariableCtx, BaseTypeSpecifier * aType, | |
| bool needTypeChecking, const Modifier & aModifier) | |
| { | |
| COMPILE_CONTEXT * newCTX = NULL; | |
| if( COMPILE_CONTEXT_CACHE.nonempty() ) | |
| { | |
| COMPILE_CONTEXT_CACHE.pop_last_to( newCTX ); | |
| newCTX->PREV = PREV; | |
| // Used for safe memory management !!! | |
| if( PREV != NULL ) | |
| { | |
| newCTX->NEXT = PREV->NEXT; | |
| PREV->NEXT = newCTX; | |
| } | |
| else | |
| { | |
| newCTX->NEXT = NULL; | |
| } | |
| newCTX->mCompileCtx = aCompileCtx; | |
| newCTX->mRuntimeCtx = aRuntimeCtx; | |
| newCTX->mVariableCtx = aVariableCtx; | |
| newCTX->mType = aType; | |
| newCTX->mNeedTypeChecking = needTypeChecking; | |
| newCTX->setModifier( aModifier ); | |
| } | |
| else | |
| { | |
| newCTX = new COMPILE_CONTEXT(PREV, | |
| aCompileCtx, aRuntimeCtx, aVariableCtx, aType, aModifier); | |
| AVM_OS_ASSERT_OUT_OF_MEMORY_EXIT( newCTX ) | |
| << "CompilationEnvironment::newCTX !!!" | |
| << SEND_EXIT; | |
| } | |
| AVM_IF_DEBUG_LEVEL_FLAG( HIGH , COMPILING ) | |
| AVM_OS_TRACE << "COMPILE_CONTEXT::new:> @" << avm_address_t( newCTX ) | |
| << std::endl; | |
| AVM_ENDIF_DEBUG_LEVEL_FLAG( HIGH , COMPILING ) | |
| return( newCTX ); | |
| } | |
| void CompilationEnvironment::freeCTX(COMPILE_CONTEXT * & CTX) | |
| { | |
| if( CTX->NEXT == NULL ) | |
| { | |
| AVM_IF_DEBUG_LEVEL_FLAG( HIGH , COMPILING ) | |
| AVM_OS_TRACE << "COMPILE_CONTEXT::free:> @" | |
| << avm_address_t( CTX ) << std::endl; | |
| AVM_ENDIF_DEBUG_LEVEL_FLAG( HIGH , COMPILING ) | |
| COMPILE_CONTEXT_CACHE.append( CTX ); | |
| CTX = NULL; | |
| } | |
| else | |
| { | |
| for( COMPILE_CONTEXT * nextCTX = CTX ; CTX != NULL ; CTX = nextCTX ) | |
| { | |
| AVM_IF_DEBUG_LEVEL_FLAG( HIGH , COMPILING ) | |
| AVM_OS_TRACE << "COMPILE_CONTEXT::free:> @" | |
| << avm_address_t( CTX ) << std::endl; | |
| AVM_ENDIF_DEBUG_LEVEL_FLAG( HIGH , COMPILING ) | |
| nextCTX = CTX->NEXT; | |
| // CTX->NEXT = NULL; | |
| COMPILE_CONTEXT_CACHE.append( CTX ); | |
| } | |
| } | |
| } | |
| } /* namespace sep */ |