blob: a5d9052456be377dccf86360157bc75527ba3e57 [file] [log] [blame]
/*******************************************************************************
* 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: 23 sept. 2009
*
* Contributors:
* Arnault Lapitre (CEA LIST) arnault.lapitre@cea.fr
* - Initial API and implementation
******************************************************************************/
#include "StatementFactory.h"
#include <fml/executable/AvmProgram.h>
#include <fml/executable/ExecutableForm.h>
#include <fml/executable/ExecutableLib.h>
#include <fml/expression/AvmCode.h>
#include <fml/runtime/ExecutionData.h>
namespace sep
{
/**
* COLLECT
* [state]machine
*/
void StatementFactory::collectRunMachine(ExecutableForm * anExecutableForm,
const BF & aStatement, ListOfInstanceOfMachine & listOfMachine)
{
switch( aStatement.classKind() )
{
case FORM_AVMCODE_KIND:
{
AvmCode* aCode = aStatement.to_ptr< AvmCode >();
switch( aCode->getAvmOpCode() )
{
case AVM_OPCODE_RUN:
// case AVM_OPCODE_RESUME:
// case AVM_OPCODE_RESTART:
case AVM_OPCODE_START:
{
if( aCode->first().is< InstanceOfMachine >() )
{
listOfMachine.add_union(
aCode->first().to_ptr< InstanceOfMachine >() );
}
break;
}
default:
{
AvmCode::iterator it = aCode->begin();
AvmCode::iterator itEnd = aCode->end();
for( ; it != itEnd ; ++it )
{
collectRunMachine(anExecutableForm, (*it), listOfMachine);
}
break;
}
}
break;
}
case FORM_INSTANCE_MACHINE_KIND:
{
// listOfMachine.add_union( aStatement.to_ptr< InstanceOfMachine >() );
break;
}
default:
{
break;
}
}
}
void StatementFactory::collectActivityMachine(
ExecutableForm * anExecutableForm, AVM_OPCODE opCode,
const BF & aStatement, ListOfInstanceOfMachine & listOfMachine)
{
switch( aStatement.classKind() )
{
case FORM_AVMCODE_KIND:
{
AvmCode* aCode = aStatement.to_ptr< AvmCode >();
if( aCode->isOpCode(opCode) )
{
if( aCode->first().is< InstanceOfMachine >() )
{
listOfMachine.add_union(
aCode->first().to_ptr< InstanceOfMachine >() );
}
}
else
{
AvmCode::iterator it = aCode->begin();
AvmCode::iterator itEnd = aCode->end();
for( ; it != itEnd ; ++it )
{
collectActivityMachine(
anExecutableForm, opCode, (*it), listOfMachine);
}
}
break;
}
case FORM_INSTANCE_MACHINE_KIND:
{
// listOfMachine.add_union( aStatement.to_ptr< InstanceOfMachine >() );
break;
}
default:
{
break;
}
}
}
void StatementFactory::collectActivityMachine(ExecutableForm * anExecutableForm,
AVM_OPCODE opCode1, AVM_OPCODE opCode2,
const BF & aStatement, ListOfInstanceOfMachine & listOfMachine)
{
switch( aStatement.classKind() )
{
case FORM_AVMCODE_KIND:
{
AvmCode* aCode = aStatement.to_ptr< AvmCode >();
if( aCode->isOpCode(opCode1) || aCode->isOpCode(opCode2) )
{
if( aCode->first().is< InstanceOfMachine >() )
{
listOfMachine.add_union(
aCode->first().to_ptr< InstanceOfMachine >() );
}
}
else
{
AvmCode::iterator it = aCode->begin();
AvmCode::iterator itEnd = aCode->end();
for( ; it != itEnd ; ++it )
{
collectActivityMachine(anExecutableForm,
opCode1, opCode2, (*it), listOfMachine);
}
}
break;
}
case FORM_INSTANCE_MACHINE_KIND:
{
// listOfMachine.add_union( aStatement.to_ptr< InstanceOfMachine >() );
break;
}
default:
{
break;
}
}
}
/**
* COLLECT
* Transition
*/
void StatementFactory::collectInvokeTransition(ExecutableForm * anExecutableForm,
const BF & aStatement, ListOfAvmTransition & listOfTransition)
{
switch( aStatement.classKind() )
{
case FORM_AVMCODE_KIND:
{
AvmCode* aCode = aStatement.to_ptr< AvmCode >();
switch( aCode->getAvmOpCode() )
{
case AVM_OPCODE_INVOKE_TRANSITION:
{
if( aCode->first().is< AvmTransition >() )
{
listOfTransition.add_union(
aCode->first().to_ptr< AvmTransition >() );
}
break;
}
case AVM_OPCODE_SCHEDULE_INVOKE:
{
if( aCode->empty() )
{
collectInvokeTransition(anExecutableForm,
anExecutableForm->getOnSchedule(),
listOfTransition );
}
break;
}
default:
{
AvmCode::iterator it = aCode->begin();
AvmCode::iterator itEnd = aCode->end();
for( ; it != itEnd ; ++it )
{
collectInvokeTransition(
anExecutableForm, (*it), listOfTransition);
}
break;
}
}
break;
}
case FORM_AVMTRANSITION_KIND:
{
// listOfTransition.add_union( aStatement.to_ptr< AvmTransition >() );
break;
}
default:
{
break;
}
}
}
/**
* COLLECT
* RID
*/
void StatementFactory::collectRID(const BF & aStatement,
List< RuntimeID > & listOfRID)
{
switch( aStatement.classKind() )
{
case FORM_AVMCODE_KIND:
{
AvmCode::iterator it = aStatement.to_ptr< AvmCode >()->begin();
AvmCode::iterator itEnd = aStatement.to_ptr< AvmCode >()->end();
for( ; it != itEnd ; ++it )
{
collectRID((*it), listOfRID);
}
break;
}
case FORM_RUNTIME_ID_KIND:
{
listOfRID.add_union( aStatement.bfRID() );
break;
}
default:
{
break;
}
}
}
/**
* CONTAINS
* Activity on RID
*/
bool StatementFactory::containsOperationOnRID(AvmCode * aCode,
const AVM_OPCODE opActivity, const RuntimeID & aRID)
{
if( aCode->nonempty() )
{
AvmCode::iterator it = aCode->begin();
if( aCode->isOpCode(opActivity) && ((aRID == (*it))
/*|| aCode->contains(aRID)*/) )
{
return( true );
}
AvmCode::iterator itEnd = aCode->end();
for( ; it != itEnd ; ++it )
{
if( (*it).is< AvmCode >() && containsOperationOnRID(
(*it).to_ptr< AvmCode >(), opActivity, aRID) )
{
return( true );
}
}
}
return( false );
}
/**
* get activity
* ExecutableForm
* or
* RuntimeID
*/
ExecutableForm * StatementFactory::getActivityTargetExecutable(
AvmProgram * anAvmProgram, AvmCode * aCode)
{
// AVM_OS_ASSERT_FATAL_NULL_POINTER_EXIT( aCode ) << "AvmCode !!!"
// << SEND_EXIT;
if( aCode->empty() )
{
return( anAvmProgram->getExecutable() );
}
else // if( aCode->singleton() )
{
if( aCode->first() == ExecutableLib::MACHINE_SELF )
{
return( anAvmProgram->getExecutable() );
}
else if( aCode->first().is< InstanceOfMachine >() )
{
return( aCode->first().to_ptr< InstanceOfMachine >()
->getExecutable() );
}
else if( aCode->first().is< RuntimeID >() )
{
return( aCode->first().as_bf< RuntimeID >().getExecutable() );
}
}
return( NULL );
}
const RuntimeID & StatementFactory::getActivityTargetRID(
const ExecutionData & anED, const RuntimeID & aRID, AvmCode * aCode)
{
if( aCode->empty() )
{
return( aRID );
}
else // if( aCode->singleton() )
{
if( aCode->first() == ExecutableLib::MACHINE_SELF )
{
return( aRID );
}
else if( aCode->first().is< RuntimeID >() )
{
return( aCode->first().as_bf< RuntimeID >() );
}
else if( aCode->first().is< InstanceOfMachine >() )
{
return( anED.getRuntimeID(
aCode->first().to_ptr< InstanceOfMachine >()) );
}
}
return( RuntimeID::REF_NULL );
}
}