blob: b6a79074e3722590c8fa8e6fb2ff60bf66fd396f [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: 18 mai 2010
*
* Contributors:
* Arnault Lapitre (CEA LIST) arnault.lapitre@cea.fr
* - Initial API and implementation
******************************************************************************/
#include "AvmPrimitiveProcessor.h"
#include <computer/ExecutionEnvironment.h>
#include <computer/primitive/BaseAvmPrimitive.h>
#include <computer/primitive/AvmActivityPrimitive.h>
#include <computer/primitive/AvmAssignPrimitive.h>
#include <computer/primitive/AvmBitwisePrimitive.h>
#include <computer/primitive/AvmBufferPrimitive.h>
#include <computer/primitive/AvmCommunicationPrimitive.h>
#include <computer/primitive/AvmConcurrencyPrimitive.h>
#include <computer/primitive/AvmCtorPrimitive.h>
#include <computer/primitive/AvmExpressionPrimitive.h>
#include <computer/primitive/AvmGuardPrimitive.h>
#include <computer/primitive/AvmInputEnabledPrimitive.h>
#include <computer/primitive/AvmInvokePrimitive.h>
#include <computer/primitive/AvmItePrimitive.h>
#include <computer/primitive/AvmIterationPrimitive.h>
#include <computer/primitive/AvmJumpPrimitive.h>
#include <computer/primitive/AvmLookupPrimitive.h>
#include <computer/primitive/AvmMathPrimitive.h>
#include <computer/primitive/AvmMetaPrimitive.h>
#include <computer/primitive/AvmSchedulingPrimitive.h>
#include <computer/primitive/AvmSequencePrimitive.h>
#include <computer/primitive/AvmStatusPrimitive.h>
#include <computer/EvaluationEnvironment.h>
#include <computer/ExecutionEnvironment.h>
#include <computer/instruction/InstructionEnvironment.h>
#include <fml/executable/ExecutableLib.h>
#include <fml/operator/Operator.h>
#include <fml/operator/OperatorManager.h>
#include <fml/runtime/RuntimeDef.h>
#include <fml/runtime/RuntimeLib.h>
#include <sew/SymbexEngine.h>
namespace sep
{
/**
* DESTRUCTOR
*/
AvmPrimitiveProcessor::~AvmPrimitiveProcessor()
{
VectorOfAvmPrimitive::iterator it = AVM_PRIMITIVE_TABLE.begin();
VectorOfAvmPrimitive::iterator endIt = AVM_PRIMITIVE_TABLE.end();
for( ; it != endIt ; ++it )
{
if( ((*it) != DEFAULT_AVM_PRIMITIVE) &&
((*it) != DEFAULT_INVOKE_ROUTINE) &&
((*it) != DEFAULT_EVAL_EXPRESSION_ALU) )
{
delete( *it );
}
}
delete( DEFAULT_AVM_PRIMITIVE );
delete( DEFAULT_INVOKE_ROUTINE );
delete( DEFAULT_EVAL_EXPRESSION_ALU );
}
/**
* GETTER
* Builder
* Loader
*/
Builder & AvmPrimitiveProcessor::getBuilder()
{
return( mSymbexEngine.getBuilder() );
}
Loader & AvmPrimitiveProcessor::getLoader()
{
return( mSymbexEngine.getLoader() );
}
/**
* CONFIGURE
*/
bool AvmPrimitiveProcessor::configure()
{
DEFAULT_AVM_PRIMITIVE = new BaseAvmPrimitive( *this );
DEFAULT_INVOKE_ROUTINE = new AvmPrimitive_InvokeRoutine( *this );
DEFAULT_EVAL_EXPRESSION_ALU = new AvmPrimitive_EvalExpressionALU( *this );
AVM_PRIMITIVE_TABLE.resize(
OperatorManager::TABLE_OF_OPERATOR.size(),
DEFAULT_AVM_PRIMITIVE);
if( not configureOther() )
{
return( false );
}
if( not configureMeta() )
{
return( false );
}
if( not configureLambdaPrimitive() )
{
return( false );
}
if( not configureActivityPrimitive() )
{
return( false );
}
if( not configureStatusPrimitive() )
{
return( false );
}
if( not configureConcurrencyPrimitive() )
{
return( false );
}
if( not configureBasicPrimitive() )
{
return( false );
}
if( not configureArithmeticPrimitive() )
{
return( false );
}
if( not configureBitwisePrimitive() )
{
return( false );
}
if( not configureLogicPrimitive() )
{
return( false );
}
if( not configureLookupPrimitive() )
{
return( false );
}
if( not configureMathematicPrimitive() )
{
return( false );
}
if( not configureStringPrimitive() )
{
return( false );
}
if( not configureIoltPrimitive() )
{
return( false );
}
return( true );
}
#define OPCODE_COMPUTER( OPID ) \
AVM_PRIMITIVE_TABLE[ OperatorManager::OPERATOR_##OPID->getOffset() ]
#define SET_OPCODE_COMPUTER( OPID , CLASS ) \
AVM_PRIMITIVE_TABLE[ OperatorManager::OPERATOR_##OPID->getOffset() ] = new CLASS(*this)
bool AvmPrimitiveProcessor::configureOther()
{
////////////////////////////////////////////////////////////////////////////
// AVM NOP STATEMENT
////////////////////////////////////////////////////////////////////////////
OPCODE_COMPUTER( NOP ) = new AvmPrimitive_Nop( *this );
////////////////////////////////////////////////////////////////////////////
// AVM UFI STATEMENT
////////////////////////////////////////////////////////////////////////////
// OPCODE_COMPUTER( UFI ) = mAvmUfiPrimitive = new AvmPrimitive_Ufi( *this );
////////////////////////////////////////////////////////////////////////////
// AVM FORM CONSTRUCTOR STATEMENT
////////////////////////////////////////////////////////////////////////////
OPCODE_COMPUTER( CTOR ) = new AvmPrimitive_Ctor( *this );
return( true );
}
bool AvmPrimitiveProcessor::configureMeta()
{
////////////////////////////////////////////////////////////////////////////
// AVM META STATEMENT
////////////////////////////////////////////////////////////////////////////
OPCODE_COMPUTER( INFORMAL ) = new AvmPrimitive_Informal( *this );
OPCODE_COMPUTER( TRACE ) = new AvmPrimitive_Trace( *this );
OPCODE_COMPUTER( DEBUG ) = new AvmPrimitive_Debug( *this );
OPCODE_COMPUTER( COMMENT ) = new AvmPrimitive_Comment( *this );
OPCODE_COMPUTER( QUOTE ) = new AvmPrimitive_Quote( *this );
OPCODE_COMPUTER( META_EVAL ) = new AvmPrimitive_MetaEval( *this );
OPCODE_COMPUTER( META_RUN ) = new AvmPrimitive_MetaRun( *this );
return( true );
}
bool AvmPrimitiveProcessor::configureLambdaPrimitive()
{
////////////////////////////////////////////////////////////////////////////
// LAMBDA STATEMENT
////////////////////////////////////////////////////////////////////////////
OPCODE_COMPUTER( APPLY ) = DEFAULT_AVM_PRIMITIVE;
OPCODE_COMPUTER( LAMBDA ) = DEFAULT_AVM_PRIMITIVE;
////////////////////////////////////////////////////////////////////////////
// LET STATEMENT
////////////////////////////////////////////////////////////////////////////
OPCODE_COMPUTER( LET ) = DEFAULT_AVM_PRIMITIVE;
return( true );
}
bool AvmPrimitiveProcessor::configureActivityPrimitive()
{
////////////////////////////////////////////////////////////////////////////
// AVM MACHINE MANAGING
////////////////////////////////////////////////////////////////////////////
OPCODE_COMPUTER( CONTEXT_SWITCHER ) = new AvmPrimitive_ContextSwitcher( *this );
OPCODE_COMPUTER( INIT ) = new AvmPrimitive_Init( *this );
OPCODE_COMPUTER( FINAL ) = new AvmPrimitive_Final( *this );
OPCODE_COMPUTER( DESTROY ) = new AvmPrimitive_Destroy( *this );
OPCODE_COMPUTER( START ) = new AvmPrimitive_Start( *this );
OPCODE_COMPUTER( RESTART ) = new AvmPrimitive_Restart( *this );
OPCODE_COMPUTER( STOP ) = new AvmPrimitive_Stop( *this );
OPCODE_COMPUTER( WAIT ) = new AvmPrimitive_Wait( *this );
OPCODE_COMPUTER( SUSPEND ) = new AvmPrimitive_Suspend( *this );
OPCODE_COMPUTER( RESUME ) = new AvmPrimitive_Resume( *this );
OPCODE_COMPUTER( IENABLE_INVOKE ) = new AvmPrimitive_IEnableInvoke( *this );
OPCODE_COMPUTER( ENABLE_INVOKE ) = new AvmPrimitive_EnableInvoke( *this );
OPCODE_COMPUTER( ENABLE_SET ) = new AvmPrimitive_EnableSet( *this );
OPCODE_COMPUTER( IDISABLE_INVOKE ) = new AvmPrimitive_IDisableInvoke( *this );
OPCODE_COMPUTER( DISABLE_INVOKE ) = new AvmPrimitive_DisableInvoke( *this );
OPCODE_COMPUTER( DISABLE_SET ) = new AvmPrimitive_DisableSet( *this );
OPCODE_COMPUTER( DISABLE_CHILD ) = new AvmPrimitive_DisableChild( *this );
OPCODE_COMPUTER( DISABLE_SELF ) = new AvmPrimitive_DisableSelf( *this );
OPCODE_COMPUTER( DISABLE_SELVES ) = new AvmPrimitive_DisableSelves( *this );
OPCODE_COMPUTER( IABORT_INVOKE ) = new AvmPrimitive_IAbortInvoke( *this );
OPCODE_COMPUTER( ABORT_INVOKE ) = new AvmPrimitive_AbortInvoke( *this );
OPCODE_COMPUTER( ABORT_SET ) = new AvmPrimitive_AbortSet( *this );
OPCODE_COMPUTER( ABORT_CHILD ) = new AvmPrimitive_AbortChild( *this );
OPCODE_COMPUTER( ABORT_SELF ) = new AvmPrimitive_AbortSelf( *this );
OPCODE_COMPUTER( ABORT_SELVES ) = new AvmPrimitive_AbortSelves( *this );
OPCODE_COMPUTER( HISTORY_CLEAR ) = new AvmPrimitive_HistoryClear( *this );
OPCODE_COMPUTER( DEEP_HISTORY_INVOKE ) = new AvmPrimitive_DeepHistoryInvoke( *this );
OPCODE_COMPUTER( SHALLOW_HISTORY_INVOKE ) = new AvmPrimitive_ShallowHistoryInvoke( *this );
OPCODE_COMPUTER( IRUN ) = new AvmPrimitive_IRun( *this );
OPCODE_COMPUTER( RUN ) = new AvmPrimitive_Run( *this );
OPCODE_COMPUTER( RTC ) = new AvmPrimitive_Rtc( *this );
OPCODE_COMPUTER( INVOKE_NEW ) = new AvmPrimitive_InvokeNew( *this );
OPCODE_COMPUTER( INVOKE_ROUTINE ) = DEFAULT_INVOKE_ROUTINE;
OPCODE_COMPUTER( INVOKE_TRANSITION ) = new AvmPrimitive_InvokeTransition( *this );
OPCODE_COMPUTER( INVOKE_METHOD ) = new AvmPrimitive_InvokeMethod( *this );
OPCODE_COMPUTER( INVOKE_PROGRAM ) = new AvmPrimitive_InvokeProgram( *this );
OPCODE_COMPUTER( INVOKE_FUNCTION ) = new AvmPrimitive_InvokeFunction( *this );
OPCODE_COMPUTER( INVOKE_LAMBDA_APPLY ) = new AvmPrimitive_InvokeLambdaApply( *this );
OPCODE_COMPUTER( INVOKE_LAMBDA_LET ) = new AvmPrimitive_InvokeLambdaLet( *this );
OPCODE_COMPUTER( SCHEDULE_INVOKE ) = new AvmPrimitive_ScheduleInvoke( *this );
OPCODE_COMPUTER( SCHEDULE_GET ) = new AvmPrimitive_ScheduleGet( *this );
OPCODE_COMPUTER( SCHEDULE_IN ) = new AvmPrimitive_ScheduleIn( *this );
OPCODE_COMPUTER( SCHEDULE_SET ) = new AvmPrimitive_ScheduleSet( *this );
OPCODE_COMPUTER( DEFER_INVOKE ) = new AvmPrimitive_DeferInvoke( *this );
OPCODE_COMPUTER( DEFER_GET ) = new AvmPrimitive_DeferGet( *this );
OPCODE_COMPUTER( DEFER_SET ) = new AvmPrimitive_DeferSet( *this );
OPCODE_COMPUTER( GOTO ) = new AvmPrimitive_Goto( *this );
OPCODE_COMPUTER( FORK ) = new AvmPrimitive_Fork( *this );
OPCODE_COMPUTER( JOIN ) = new AvmPrimitive_Join( *this );
OPCODE_COMPUTER( INPUT_ENABLED ) = new AvmPrimitive_InputEnabled( *this );
OPCODE_COMPUTER( RDV ) = new AvmPrimitive_Rdv( *this );
OPCODE_COMPUTER( SYNCHRONIZE ) = new AvmPrimitive_Synchronize( *this );
return( true );
}
bool AvmPrimitiveProcessor::configureStatusPrimitive()
{
////////////////////////////////////////////////////////////////////////////
// AVM MACHINE STATUS
////////////////////////////////////////////////////////////////////////////
OPCODE_COMPUTER( STATUS_WAS ) = new AvmPrimitive_StatusWas( *this );
OPCODE_COMPUTER( STATUS_IS ) = new AvmPrimitive_StatusIs( *this );
OPCODE_COMPUTER( STATUS_BEING ) = new AvmPrimitive_StatusBeing( *this );
OPCODE_COMPUTER( STATUS_WILL ) = new AvmPrimitive_StatusWill( *this );
OPCODE_COMPUTER( CHANGED ) = new AvmPrimitive_Changed( *this );
OPCODE_COMPUTER( CHANGED_TO ) = new AvmPrimitive_ChangedTo( *this );
return( true );
}
bool AvmPrimitiveProcessor::configureConcurrencyPrimitive()
{
////////////////////////////////////////////////////////////////////////////
// AVM PROGRAM SCHEDULING
////////////////////////////////////////////////////////////////////////////
OPCODE_COMPUTER( ASYNCHRONOUS ) = new AvmPrimitive_Asynchronous( *this );
OPCODE_COMPUTER( STRONG_SYNCHRONOUS ) = new AvmPrimitive_StrongSynchronous( *this );
OPCODE_COMPUTER( WEAK_SYNCHRONOUS ) = new AvmPrimitive_WeakSynchronous( *this );
OPCODE_COMPUTER( INTERLEAVING ) = new AvmPrimitive_Interleaving( *this );
OPCODE_COMPUTER( PARALLEL ) = new AvmPrimitive_Parallel( *this );
OPCODE_COMPUTER( RDV_ASYNCHRONOUS ) = new AvmPrimitive_RdvAsynchronous( *this );
OPCODE_COMPUTER( RDV_STRONG_SYNCHRONOUS ) = new AvmPrimitive_RdvStrongSynchronous( *this );
OPCODE_COMPUTER( RDV_WEAK_SYNCHRONOUS ) = new AvmPrimitive_RdvWeakSynchronous( *this );
OPCODE_COMPUTER( RDV_INTERLEAVING ) = new AvmPrimitive_RdvInterleaving( *this );
OPCODE_COMPUTER( RDV_PARALLEL ) = new AvmPrimitive_RdvParallel( *this );
OPCODE_COMPUTER( EXCLUSIVE ) = new AvmPrimitive_Exclusive( *this );
OPCODE_COMPUTER( NONDETERMINISM ) = new AvmPrimitive_Nondeterminism( *this );
OPCODE_COMPUTER( PRIOR_GT ) = new AvmPrimitive_Prior( *this );
OPCODE_COMPUTER( PRIOR_LT ) = new AvmPrimitive_Prior( *this );
OPCODE_COMPUTER( SCHEDULE_AND_THEN ) = new AvmPrimitive_ScheduleAndThen( *this );
OPCODE_COMPUTER( SCHEDULE_OR_ELSE ) = new AvmPrimitive_ScheduleOrElse( *this );
OPCODE_COMPUTER( ATOMIC_SEQUENCE ) = new AvmPrimitive_AtomicSequence( *this );
OPCODE_COMPUTER( SEQUENCE ) = new AvmPrimitive_Sequence( *this );
OPCODE_COMPUTER( SEQUENCE_SIDE ) = new AvmPrimitive_SideSequence( *this );
OPCODE_COMPUTER( SEQUENCE_WEAK ) = new AvmPrimitive_WeakSequence( *this );
OPCODE_COMPUTER( PRODUCT ) = new AvmPrimitive_Product( *this );
return( true );
}
bool AvmPrimitiveProcessor::configureBasicPrimitive()
{
////////////////////////////////////////////////////////////////////////////
// AVM BUFFER MANAGING
////////////////////////////////////////////////////////////////////////////
OPCODE_COMPUTER( UPDATE_BUFFER ) = new AvmPrimitive_UpdateBuffer( *this );
////////////////////////////////////////////////////////////////////////////
// AVM PRIMITIVE STATEMENT
////////////////////////////////////////////////////////////////////////////
OPCODE_COMPUTER( ASSIGN ) = new AvmPrimitive_Assignment( *this );
OPCODE_COMPUTER( ASSIGN_AFTER ) = new AvmPrimitive_AssignmentAfter( *this );
OPCODE_COMPUTER( ASSIGN_OP_AFTER ) = new AvmPrimitive_AssignmentOpAfter( *this );
OPCODE_COMPUTER( ASSIGN_REF ) = new AvmPrimitive_AssignmentRef( *this );
OPCODE_COMPUTER( ASSIGN_MACRO ) = new AvmPrimitive_AssignmentMacro( *this );
OPCODE_COMPUTER( ASSIGN_NEWFRESH ) = new AvmPrimitive_AssignNewFresh( *this );
OPCODE_COMPUTER( ASSIGN_RESET ) = new AvmPrimitive_AssignReset( *this );
OPCODE_COMPUTER( GUARD ) = new AvmPrimitive_Guard( *this );
OPCODE_COMPUTER( TIMED_GUARD ) = new AvmPrimitive_TimedGuard( *this );
OPCODE_COMPUTER( EVENT ) = new AvmPrimitive_Event( *this );
OPCODE_COMPUTER( CHECK_SAT ) = new AvmPrimitive_CheckSat( *this );
OPCODE_COMPUTER( INPUT ) = new AvmPrimitive_Input( *this );
OPCODE_COMPUTER( INPUT_FROM ) = new AvmPrimitive_InputFrom( *this );
// Optimized version of INPUT
OPCODE_COMPUTER( INPUT_VAR ) = new AvmPrimitive_InputVar( *this );
OPCODE_COMPUTER( INPUT_ENV ) = new AvmPrimitive_InputEnv( *this );
OPCODE_COMPUTER( INPUT_BUFFER ) = new AvmPrimitive_InputBuffer( *this );
OPCODE_COMPUTER( INPUT_RDV ) = new AvmPrimitive_InputRdv( *this );
OPCODE_COMPUTER( INPUT_FLOW ) = new AvmPrimitive_Input( *this );
OPCODE_COMPUTER( INPUT_BROADCAST ) = new AvmPrimitive_Input( *this );
OPCODE_COMPUTER( INPUT_DELEGATE ) = new AvmPrimitive_Input( *this );
OPCODE_COMPUTER( OUTPUT ) = new AvmPrimitive_Output( *this );
OPCODE_COMPUTER( OUTPUT_TO ) = new AvmPrimitive_OutputTo( *this );
// Optimized version of OUTPUT
OPCODE_COMPUTER( OUTPUT_VAR ) = new AvmPrimitive_OutputVar( *this );
OPCODE_COMPUTER( OUTPUT_ENV ) = new AvmPrimitive_OutputEnv( *this );
OPCODE_COMPUTER( OUTPUT_BUFFER ) = new AvmPrimitive_OutputBuffer( *this );
OPCODE_COMPUTER( OUTPUT_RDV ) = new AvmPrimitive_OutputRdv( *this );
OPCODE_COMPUTER( OUTPUT_FLOW ) = new AvmPrimitive_Output( *this );
OPCODE_COMPUTER( OUTPUT_BROADCAST ) = new AvmPrimitive_Output( *this );
OPCODE_COMPUTER( OUTPUT_DELEGATE ) = new AvmPrimitive_Output( *this );
OPCODE_COMPUTER( PRESENT ) = new AvmPrimitive_Present( *this );
OPCODE_COMPUTER( ABSENT ) = new AvmPrimitive_Absent( *this );
OPCODE_COMPUTER( IF ) = new AvmPrimitive_If( *this );
OPCODE_COMPUTER( IFE ) = new AvmPrimitive_Ife( *this );
OPCODE_COMPUTER( FOR ) = new AvmPrimitive_For( *this );
OPCODE_COMPUTER( FOREACH ) = new AvmPrimitive_Foreach( *this );
OPCODE_COMPUTER( WHILE_DO ) = new AvmPrimitive_WhileDo( *this );
OPCODE_COMPUTER( DO_WHILE ) = new AvmPrimitive_DoWhile( *this );
OPCODE_COMPUTER( BREAK ) = new AvmPrimitive_Break( *this );
OPCODE_COMPUTER( CONTINUE ) = new AvmPrimitive_Continue( *this );
OPCODE_COMPUTER( RETURN ) = new AvmPrimitive_Return( *this );
OPCODE_COMPUTER( EXIT ) = new AvmPrimitive_Exit( *this );
OPCODE_COMPUTER( STEP_MARK ) = new AvmPrimitive_StepMark( *this );
return( true );
}
bool AvmPrimitiveProcessor::configureBitwisePrimitive()
{
////////////////////////////////////////////////////////////////////////////
// AVM BITWISE EXPRESSION
////////////////////////////////////////////////////////////////////////////
OPCODE_COMPUTER( BNOT ) = new AvmPrimitive_BNOT( *this );
OPCODE_COMPUTER( BAND ) = new AvmPrimitive_BAND( *this );
OPCODE_COMPUTER( BOR ) = new AvmPrimitive_BOR( *this );
OPCODE_COMPUTER( BXOR ) = new AvmPrimitive_BXOR( *this );
OPCODE_COMPUTER( LSHIFT ) = new AvmPrimitive_LSHIFT( *this );
OPCODE_COMPUTER( RSHIFT ) = new AvmPrimitive_RSHIFT( *this );
return( true );
}
bool AvmPrimitiveProcessor::configureLogicPrimitive()
{
////////////////////////////////////////////////////////////////////////////
// AVM PREDICAT EXPRESSION
////////////////////////////////////////////////////////////////////////////
OPCODE_COMPUTER( NOT ) = DEFAULT_EVAL_EXPRESSION_ALU;
OPCODE_COMPUTER( AND ) = DEFAULT_EVAL_EXPRESSION_ALU;
OPCODE_COMPUTER( AND_THEN ) = DEFAULT_EVAL_EXPRESSION_ALU;
OPCODE_COMPUTER( NAND ) = DEFAULT_EVAL_EXPRESSION_ALU;
OPCODE_COMPUTER( XAND ) = DEFAULT_EVAL_EXPRESSION_ALU;
OPCODE_COMPUTER( OR ) = DEFAULT_EVAL_EXPRESSION_ALU;
OPCODE_COMPUTER( OR_ELSE ) = DEFAULT_EVAL_EXPRESSION_ALU;
OPCODE_COMPUTER( NOR ) = DEFAULT_EVAL_EXPRESSION_ALU;
OPCODE_COMPUTER( XOR ) = DEFAULT_EVAL_EXPRESSION_ALU;
OPCODE_COMPUTER( XNOR ) = DEFAULT_EVAL_EXPRESSION_ALU;
////////////////////////////////////////////////////////////////////////////
// AVM COMPARISON EXPRESSION
////////////////////////////////////////////////////////////////////////////
OPCODE_COMPUTER( EQ ) = DEFAULT_EVAL_EXPRESSION_ALU;
OPCODE_COMPUTER( NEQ ) = DEFAULT_EVAL_EXPRESSION_ALU;
OPCODE_COMPUTER( SEQ ) = DEFAULT_EVAL_EXPRESSION_ALU;
OPCODE_COMPUTER( NSEQ ) = DEFAULT_EVAL_EXPRESSION_ALU;
OPCODE_COMPUTER( LT ) = DEFAULT_EVAL_EXPRESSION_ALU;
OPCODE_COMPUTER( LTE ) = DEFAULT_EVAL_EXPRESSION_ALU;
OPCODE_COMPUTER( GT ) = DEFAULT_EVAL_EXPRESSION_ALU;
OPCODE_COMPUTER( GTE ) = DEFAULT_EVAL_EXPRESSION_ALU;
return( true );
}
bool AvmPrimitiveProcessor::configureArithmeticPrimitive()
{
////////////////////////////////////////////////////////////////////////////
// AVM ARITHMETIC EXPRESSION
////////////////////////////////////////////////////////////////////////////
OPCODE_COMPUTER( PLUS ) = DEFAULT_EVAL_EXPRESSION_ALU;
OPCODE_COMPUTER( MINUS ) = DEFAULT_EVAL_EXPRESSION_ALU;
OPCODE_COMPUTER( UMINUS ) = DEFAULT_EVAL_EXPRESSION_ALU;
OPCODE_COMPUTER( MULT ) = DEFAULT_EVAL_EXPRESSION_ALU;
OPCODE_COMPUTER( POW ) = DEFAULT_EVAL_EXPRESSION_ALU;
OPCODE_COMPUTER( DIV ) = DEFAULT_EVAL_EXPRESSION_ALU;
OPCODE_COMPUTER( MOD ) = new AvmPrimitive_MOD( *this );
return( true );
}
bool AvmPrimitiveProcessor::configureLookupPrimitive()
{
////////////////////////////////////////////////////////////////////////////
// LOOKUP STATEMENT
////////////////////////////////////////////////////////////////////////////
OPCODE_COMPUTER( LOOKUP_INT ) = new AvmPrimitive_Lookup_Int( *this );
OPCODE_COMPUTER( LOOKUP_INT_EXT ) = new AvmPrimitive_Lookup_IntExt( *this );
OPCODE_COMPUTER( LOOKUP_NEAREST ) = new AvmPrimitive_Lookup_Nearest( *this );
OPCODE_COMPUTER( LOOKUP_BELOW ) = new AvmPrimitive_Lookup_Below( *this );
OPCODE_COMPUTER( LOOKUP_ABOVE ) = new AvmPrimitive_Lookup_Above( *this );
OPCODE_COMPUTER( LOOKUP2D_INT_EXT ) = new AvmPrimitive_Lookup2D_IntExt( *this );
return( true );
}
bool AvmPrimitiveProcessor::configureMathematicPrimitive()
{
////////////////////////////////////////////////////////////////////////////
// AVM MATHEMATICAL FUNCTION
////////////////////////////////////////////////////////////////////////////
// MIN - MAX
OPCODE_COMPUTER( MIN ) = new AvmPrimitive_MIN( *this );
OPCODE_COMPUTER( MAX ) = new AvmPrimitive_MAX( *this );
// RANDOM
OPCODE_COMPUTER( RANDOM ) = new AvmPrimitive_RANDOM( *this );
// ABS
OPCODE_COMPUTER( ABS ) = new AvmPrimitive_ABS( *this );
// ROUNDING
OPCODE_COMPUTER( CEIL ) = new AvmPrimitive_CEIL( *this );
OPCODE_COMPUTER( FLOOR ) = new AvmPrimitive_FLOOR( *this );
OPCODE_COMPUTER( ROUND ) = new AvmPrimitive_ROUND( *this );
OPCODE_COMPUTER( TRUNCATE ) = new AvmPrimitive_TRUNCATE( *this );
// EXP - LOG
OPCODE_COMPUTER( SQRT ) = new AvmPrimitive_SQRT( *this );
OPCODE_COMPUTER( EXP ) = new AvmPrimitive_EXP( *this );
OPCODE_COMPUTER( LOG ) = new AvmPrimitive_LOG( *this );
// TRIGONOMETRIC
OPCODE_COMPUTER( SIN ) = new AvmPrimitive_SIN( *this );
OPCODE_COMPUTER( COS ) = new AvmPrimitive_COS( *this );
OPCODE_COMPUTER( TAN ) = new AvmPrimitive_TAN( *this );
OPCODE_COMPUTER( SINH ) = new AvmPrimitive_SINH( *this );
OPCODE_COMPUTER( COSH ) = new AvmPrimitive_COSH( *this );
OPCODE_COMPUTER( TANH ) = new AvmPrimitive_TANH( *this );
OPCODE_COMPUTER( ASIN ) = new AvmPrimitive_ASIN( *this );
OPCODE_COMPUTER( ACOS ) = new AvmPrimitive_ACOS( *this );
OPCODE_COMPUTER( ATAN ) = new AvmPrimitive_ATAN( *this );
OPCODE_COMPUTER( ATAN2 ) = new AvmPrimitive_ATAN2( *this );
OPCODE_COMPUTER( ASINH ) = new AvmPrimitive_ASINH( *this );
OPCODE_COMPUTER( ACOSH ) = new AvmPrimitive_ACOSH( *this );
OPCODE_COMPUTER( ATANH ) = new AvmPrimitive_ATANH( *this );
return( true );
}
bool AvmPrimitiveProcessor::configureStringPrimitive()
{
////////////////////////////////////////////////////////////////////////////
// AVM STRING / COLLECTION OPERATOR
////////////////////////////////////////////////////////////////////////////
OPCODE_COMPUTER( CONTAINS ) = new AvmPrimitive_CONTAINS( *this );
OPCODE_COMPUTER( IN ) = new AvmPrimitive_IN( *this );
OPCODE_COMPUTER( NOTIN ) = new AvmPrimitive_NOTIN( *this );
OPCODE_COMPUTER( SUBSET ) = DEFAULT_AVM_PRIMITIVE;
OPCODE_COMPUTER( SUBSETEQ ) = DEFAULT_AVM_PRIMITIVE;
OPCODE_COMPUTER( INTERSECT ) = DEFAULT_AVM_PRIMITIVE;
OPCODE_COMPUTER( STARTS_WITH ) = DEFAULT_AVM_PRIMITIVE;
OPCODE_COMPUTER( ENDS_WITH ) = DEFAULT_AVM_PRIMITIVE;
OPCODE_COMPUTER( CONCAT ) = DEFAULT_AVM_PRIMITIVE;
OPCODE_COMPUTER( APPEND ) = new AvmPrimitive_APPEND( *this );
OPCODE_COMPUTER( REMOVE ) = new AvmPrimitive_REMOVE( *this );
OPCODE_COMPUTER( CLEAR ) = new AvmPrimitive_CLEAR( *this );
OPCODE_COMPUTER( RESIZE ) = new AvmPrimitive_RESIZE( *this );
OPCODE_COMPUTER( PUSH ) = new AvmPrimitive_PUSH( *this );
OPCODE_COMPUTER( ASSIGN_TOP ) = new AvmPrimitive_ASSIGN_TOP( *this );
OPCODE_COMPUTER( TOP ) = new AvmPrimitive_TOP( *this );
OPCODE_COMPUTER( POP ) = new AvmPrimitive_POP( *this );
OPCODE_COMPUTER( POP_FROM ) = new AvmPrimitive_POP_FROM( *this );
OPCODE_COMPUTER( EMPTY ) = new AvmPrimitive_EMPTY( *this );
OPCODE_COMPUTER( NONEMPTY ) = new AvmPrimitive_NONEMPTY( *this );
OPCODE_COMPUTER( SINGLETON ) = new AvmPrimitive_SINGLETON( *this );
OPCODE_COMPUTER( POPULATED ) = new AvmPrimitive_POPULATED( *this );
OPCODE_COMPUTER( FULL ) = new AvmPrimitive_FULL( *this );
OPCODE_COMPUTER( SIZE ) = new AvmPrimitive_SIZE( *this );
return( true );
}
bool AvmPrimitiveProcessor::configureIoltPrimitive()
{
////////////////////////////////////////////////////////////////////////////
// IOLTL BEHAVIORAL PREDICAT
////////////////////////////////////////////////////////////////////////////
OPCODE_COMPUTER( GLOBALLY ) = DEFAULT_AVM_PRIMITIVE;
OPCODE_COMPUTER( UNTIL ) = DEFAULT_AVM_PRIMITIVE;
OPCODE_COMPUTER( NEXT ) = DEFAULT_AVM_PRIMITIVE;
OPCODE_COMPUTER( EVENTUALLY ) = DEFAULT_AVM_PRIMITIVE;
OPCODE_COMPUTER( RELEASES ) = DEFAULT_AVM_PRIMITIVE;
OPCODE_COMPUTER( OBS ) = new AvmPrimitive_OBS( *this );
////////////////////////////////////////////////////////////////////////////
// IOLTL LOGICAL PREDICAT
////////////////////////////////////////////////////////////////////////////
OPCODE_COMPUTER( AND_T ) = DEFAULT_AVM_PRIMITIVE;
OPCODE_COMPUTER( OR_T ) = DEFAULT_AVM_PRIMITIVE;
OPCODE_COMPUTER( NOT_T ) = DEFAULT_AVM_PRIMITIVE;
OPCODE_COMPUTER( IMP_T ) = DEFAULT_AVM_PRIMITIVE;
return( true );
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//// TOOLS for POST-RUN
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
void AvmPrimitiveProcessor::postRun(
ExecutionContext & anEC, ListOfAPExecutionData & runEDS)
{
if( runEDS.nonempty() )
{
avm_uint32_t nHeight = anEC.getHeight() + 1;
avm_uint32_t aWidth = anEC.getWidth();
ListOfAPExecutionData::iterator itED = runEDS.begin();
ListOfAPExecutionData::iterator endED = runEDS.end();
for( ; itED != endED ; ++itED )
{
switch( (*itED)->mAEES )
{
case AEES_STMNT_NOTHING:
{
if( not (*itED)->hasRunnableElementTrace() )
{
//!! NOTHING
break;
}
//!! NO BREAk
}
default:
{
// if( ((*itED)->getExecutionContext() ==
// theED->getExecutionContext())
// /* || (not (*itED)->hasExecutionContext()) */ )
{
anEC.appendChildContext(
new ExecutionContext(anEC, *itED, nHeight, aWidth) );
}
break;
}
}
}
}
}
void AvmPrimitiveProcessor::postRun(
ExecutionContext & anEC, ExecutionEnvironment & ENV)
{
postRun(anEC, ENV.outEDS);
postRun(anEC, ENV.exitEDS);
postRun(anEC, ENV.irqEDS);
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//// the INIT statement
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
void AvmPrimitiveProcessor::init(ExecutionContext & anEC)
{
AVM_IF_DEBUG_NOT_FLAG( QUALIFIED_NAME_ID )
BaseCompiledForm::USE_ONLY_ID = true;
AVM_ENDIF_DEBUG_NOT_FLAG( QUALIFIED_NAME_ID )
// anEC.writeTraceBeforeExec(AVM_OS_TRACE);
// anEC.writeTraceBeforeExec(AVM_OS_COUT);
// SAVE AND UNSET THE ASSIGN TABLE
anEC.resetDataBeforeEvaluation();
ExecutionEnvironment ENV(*this, (& anEC));
if( ENV.run(ENV.inED->getOnInit()) )
{
}
// POST-RUN
postRun(anEC, ENV);
// RESTORE THE ASSIGN TABLE
anEC.restoreDataAfterEvaluation();
// anEC.writeTraceAfterExec(AVM_OS_TRACE);
// anEC.writeTraceAfterExec(AVM_OS_COUT);
AVM_IF_DEBUG_NOT_FLAG( QUALIFIED_NAME_ID )
BaseCompiledForm::USE_ONLY_ID = false;
AVM_ENDIF_DEBUG_NOT_FLAG( QUALIFIED_NAME_ID )
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//// the RUN statement
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/**
* the RUN statement
*/
void AvmPrimitiveProcessor::run(ExecutionContext & anEC)
{
AVM_IF_DEBUG_NOT_FLAG( QUALIFIED_NAME_ID )
BaseCompiledForm::USE_ONLY_ID = true;
AVM_ENDIF_DEBUG_NOT_FLAG( QUALIFIED_NAME_ID )
// anEC.writeTraceBeforeExec(AVM_OS_TRACE);
// anEC.writeTraceBeforeExec(AVM_OS_COUT);
// SAVE AND UNSET THE ASSIGN TABLE
anEC.resetDataBeforeEvaluation();
ExecutionEnvironment ENV(*this, (& anEC));
switch( ENV.inED->mAEES )
{
case AEES_STEP_MARK:
{
ENV.inED.mwsetAEES(AEES_STEP_RESUME);
if( decode_resume( ENV ) )
{
}
break;
}
case AEES_STMNT_NOTHING:
case AEES_STMNT_FINAL:
case AEES_STMNT_DESTROY:
{
if( not ENV.inED->isFinalizedOrDestroyed(ENV.inED->getSystemRID()) )
{
ENV.inED.mwsetAEES(AEES_OK);
}
//!! NO BREAk
}
case AEES_OK:
{
ENV.inED->setSystemRID();
if( ENV.inED->getOnSchedule()->empty() &&
(ENV.inED->getOnSchedule()->isOpCode(AVM_OPCODE_SCHEDULE_INVOKE)) )
{
if( ENV.run(ENV.inED->getSystemRuntime().getOnSchedule()) )
{
}
}
else if( ENV.run(ENV.inED->getOnSchedule()) )
{
}
break;
}
case AEES_WAITING_JOIN_FORK:
case AEES_STMNT_EXIT:
case AEES_STMNT_EXIT_ALL:
case AEES_STMNT_FATAL_ERROR:
case AEES_SYMBOLIC_EXECUTION_LIMITATION:
{
break;
}
case AEES_STMNT_BREAK:
case AEES_STMNT_CONTINUE:
case AEES_STMNT_RETURN:
case AEES_STEP_RESUME:
default:
{
AVM_OS_FATAL_ERROR_EXIT
<< "Unexpected an input Execution Context for running"
" with the AVM EXECECUTION ENDING STATUS << "
<< RuntimeDef::strAEES( ENV.inED->mAEES ) << " >> !!!"
<< SEND_EXIT;
break;
}
}
// POST-RUN
postRun(anEC, ENV);
// RESTORE THE ASSIGN TABLE
anEC.restoreDataAfterEvaluation();
// anEC.writeTraceAfterExec(AVM_OS_TRACE);
// anEC.writeTraceAfterExec(AVM_OS_COUT);
AVM_IF_DEBUG_NOT_FLAG( QUALIFIED_NAME_ID )
BaseCompiledForm::USE_ONLY_ID = false;
AVM_ENDIF_DEBUG_NOT_FLAG( QUALIFIED_NAME_ID )
}
static bool isDebugProgram(const Operator * anOperator)
{
switch( anOperator->getAvmOpCode() )
{
/*
***********************************************************************
* AVM MACHINE ACTIVITY
***********************************************************************
*/
case AVM_OPCODE_CONTEXT_SWITCHER:
case AVM_OPCODE_INIT:
case AVM_OPCODE_FINAL:
case AVM_OPCODE_DESTROY:
case AVM_OPCODE_START:
case AVM_OPCODE_RESTART:
case AVM_OPCODE_STOP:
case AVM_OPCODE_WAIT:
case AVM_OPCODE_SUSPEND:
case AVM_OPCODE_RESUME:
case AVM_OPCODE_IENABLE_INVOKE:
case AVM_OPCODE_ENABLE_INVOKE:
case AVM_OPCODE_ENABLE_SET:
case AVM_OPCODE_IDISABLE_INVOKE:
case AVM_OPCODE_DISABLE_INVOKE:
case AVM_OPCODE_DISABLE_SET:
case AVM_OPCODE_DISABLE_CHILD:
case AVM_OPCODE_DISABLE_SELF:
case AVM_OPCODE_DISABLE_SELVES:
case AVM_OPCODE_IABORT_INVOKE:
case AVM_OPCODE_ABORT_INVOKE:
case AVM_OPCODE_ABORT_SET:
case AVM_OPCODE_ABORT_CHILD:
case AVM_OPCODE_ABORT_SELF:
case AVM_OPCODE_ABORT_SELVES:
case AVM_OPCODE_HISTORY_CLEAR:
case AVM_OPCODE_DEEP_HISTORY_INVOKE:
case AVM_OPCODE_SHALLOW_HISTORY_INVOKE:
case AVM_OPCODE_IRUN:
case AVM_OPCODE_RUN:
case AVM_OPCODE_RTC:
case AVM_OPCODE_SCHEDULE_INVOKE:
case AVM_OPCODE_SCHEDULE_GET:
case AVM_OPCODE_SCHEDULE_SET:
case AVM_OPCODE_DEFER_INVOKE:
case AVM_OPCODE_DEFER_GET:
case AVM_OPCODE_DEFER_SET:
case AVM_OPCODE_FORK:
case AVM_OPCODE_JOIN:
case AVM_OPCODE_RDV:
case AVM_OPCODE_INPUT_ENABLED:
case AVM_OPCODE_SYNCHRONIZE:
case AVM_OPCODE_INVOKE_NEW:
/*
***********************************************************************
* AVM PROGRAM SCHEDULING
***********************************************************************
*/
case AVM_OPCODE_ASYNCHRONOUS:
case AVM_OPCODE_STRONG_SYNCHRONOUS:
case AVM_OPCODE_WEAK_SYNCHRONOUS:
case AVM_OPCODE_INTERLEAVING:
case AVM_OPCODE_PARALLEL:
case AVM_OPCODE_EXCLUSIVE:
case AVM_OPCODE_NONDETERMINISM:
case AVM_OPCODE_PRIOR_GT:
case AVM_OPCODE_PRIOR_LT:
// case AVM_OPCODE_ATOMIC_SEQUENCE:
//
// case AVM_OPCODE_SEQUENCE:
// case AVM_OPCODE_SEQUENCE_SIDE:
// case AVM_OPCODE_SEQUENCE_WEAK:
//
// case AVM_OPCODE_PRODUCT:
/*
***********************************************************************
* LAMBDA STATEMENT
***********************************************************************
*/
// case AVM_OPCODE_APPLY:
//
// case AVM_OPCODE_LAMBDA:
//
// case AVM_OPCODE_INVOKE_ROUTINE:
case AVM_OPCODE_INVOKE_TRANSITION:
case AVM_OPCODE_INVOKE_METHOD:
case AVM_OPCODE_INVOKE_PROGRAM:
case AVM_OPCODE_INVOKE_FUNCTION:
// case AVM_OPCODE_INVOKE_LAMBDA_APPLY:
// case AVM_OPCODE_INVOKE_LAMBDA_LET:
{
return( true );
}
default:
{
return( false );
}
}
}
bool AvmPrimitiveProcessor::run(avm_offset_t opOffset, ExecutionEnvironment & ENV)
{
const AvmCode * aCode = ENV.inCODE;
if( aCode == NULL )
{
return( false );
}
AVM_IF_DEBUG_FLAG_AND( COMPUTING , AVM_DEBUG_FLAG_OR( STATEMENT,
AVM_DEBUG_FLAG_AND( PROGRAM ,
isDebugProgram(aCode->getOperator()) ) ) )
AVM_OS_TRACE << INCR_INDENT_TAB << "<< "
<< ENV.inED->mRID.strUniqId() << " |=> ";
aCode->toStream( AVM_OS_TRACE << IGNORE_FIRST_TAB );
AVM_IF_DEBUG_LEVEL_FLAG( HIGH , DATA )
ENV.inED->toStreamData(AVM_OS_TRACE);
AVM_ENDIF_DEBUG_LEVEL_FLAG( HIGH , DATA )
AVM_IF_DEBUG_LEVEL_GT_HIGH
AVM_OS_COUT << AVM_OS_TRACE.INDENT.TABS << "<< "
<< ENV.inED->mRID.strUniqId() << " |=> ";
aCode->toStream( AVM_OS_COUT << IGNORE_FIRST_TAB );
AVM_ENDIF_DEBUG_LEVEL_GT_HIGH
AVM_OS_TRACE << std::flush;
AVM_ENDIF_DEBUG_FLAG_AND( COMPUTING )
bool rtCode = false;
try
{
if( ENV.inCODE->hasInstruction() )
{
InstructionEnvironment INSTRUCTION_ENV(ENV);
if( (ENV.mARG = INSTRUCTION_ENV.itARG)->main_decode_eval_args(ENV.inCODE) )
{
// while( ENV.mARG != NULL )
{
ENV.inED = ENV.mARG->outED;
rtCode = AVM_PRIMITIVE_TABLE[ opOffset ]->run(ENV) || rtCode;
// ENV.mARG = INSTRUCTION_ENV.itARG = INSTRUCTION_ENV.itARG->NEXT;
}
}
}
else
{
rtCode = AVM_PRIMITIVE_TABLE[ opOffset ]->run(ENV);
}
}
catch( const AvmExitException & aee )
{
// TODO !!!
// avm_set_exit_code( aee.mExitCode );
}
catch( const std::exception & e )
{
AVM_OS_WARN << std::endl << EMPHASIS(
"AvmPrimitiveProcessor::run< std::exception >",
e.what(), '*', 80);
}
catch( ... )
{
AVM_OS_WARN << std::endl << EMPHASIS( "AvmPrimitiveProcessor::"
"run< unknown::exception > !!!", '*', 80);
}
AVM_IF_DEBUG_FLAG_AND( COMPUTING , AVM_DEBUG_FLAG_OR( STATEMENT,
AVM_DEBUG_FLAG_AND( PROGRAM ,
isDebugProgram(aCode->getOperator()) ) ) )
AVM_IF_DEBUG_LEVEL_GTE_HIGH
AVM_OS_TRACE << TAB_DECR_INDENT
<< ">> " << ENV.inED->mRID.strUniqId()
<< " |=> " << aCode->str() << std::endl;
AVM_IF_DEBUG_FLAG( DATA )
ENV.inED->toStreamData(AVM_OS_TRACE);
AVM_ENDIF_DEBUG_FLAG( DATA )
AVM_IF_DEBUG_LEVEL_GT_HIGH
AVM_OS_COUT << AVM_OS_TRACE.INDENT.TABS << " >> "
<< ENV.inED->mRID.strUniqId()
<< " |=> " << aCode->str() << std::endl;
AVM_ENDIF_DEBUG_LEVEL_GT_HIGH
AVM_OS_TRACE << std::flush;
AVM_DEBUG_ELSE
AVM_OS_TRACE << DECR_INDENT;
AVM_ENDIF_DEBUG_LEVEL_GTE_HIGH
AVM_ENDIF_DEBUG_FLAG_AND( COMPUTING )
return( rtCode );
}
bool AvmPrimitiveProcessor::invokeRoutine(ExecutionEnvironment & ENV,
AvmProgram * aRoutine, const BF & aParam)
{
AVM_IF_DEBUG_LEVEL_FLAG2( MEDIUM , COMPUTING , STATEMENT )
AVM_OS_TRACE << INCR_INDENT_TAB << "<< "
<< ENV.inED->mRID.strUniqId() << " |=> invoke#routine "
<< aRoutine->getFullyQualifiedNameID() << " " << aParam.str() << std::endl;
AVM_IF_DEBUG_LEVEL_FLAG( HIGH , DATA )
ENV.inED->toStreamData(AVM_OS_TRACE);
AVM_ENDIF_DEBUG_LEVEL_FLAG( HIGH , DATA )
AVM_IF_DEBUG_LEVEL_GT_HIGH
AVM_OS_COUT << AVM_OS_TRACE.INDENT.TABS << "<< "
<< ENV.inED->mRID.strUniqId()
<< " |=> invoke#routine " << aRoutine->getFullyQualifiedNameID()
<< " " << aParam.str() << std::flush;
AVM_ENDIF_DEBUG_LEVEL_GT_HIGH
AVM_OS_TRACE << std::flush;
AVM_ENDIF_DEBUG_LEVEL_FLAG2( MEDIUM , COMPUTING , STATEMENT )
bool rtCode = ( aRoutine->hasParam() )
? DEFAULT_INVOKE_ROUTINE->run(ENV, *aRoutine, aParam)
: DEFAULT_INVOKE_ROUTINE->run(ENV, *aRoutine);
AVM_IF_DEBUG_LEVEL_FLAG2( MEDIUM , COMPUTING , STATEMENT )
AVM_IF_DEBUG_LEVEL_GTE_HIGH
AVM_OS_TRACE << TAB_DECR_INDENT << ">> "
<< ENV.inED->mRID.strUniqId() << " |=> invoke#routine "
<< aRoutine->getFullyQualifiedNameID() << " " << aParam.str() << std::endl;
AVM_IF_DEBUG_FLAG( DATA )
ENV.inED->toStreamData(AVM_OS_TRACE);
AVM_ENDIF_DEBUG_FLAG( DATA )
AVM_IF_DEBUG_LEVEL_GT_HIGH
AVM_OS_COUT << AVM_OS_TRACE.INDENT.TABS << " >> "
<< ENV.inED->mRID.strUniqId()
<< " |=> invoke#routine " << aRoutine->getFullyQualifiedNameID()
<< " " << aParam.str() << std::endl;
AVM_ENDIF_DEBUG_LEVEL_GT_HIGH
AVM_OS_TRACE << std::flush;
AVM_DEBUG_ELSE
AVM_OS_TRACE << DECR_INDENT;
AVM_ENDIF_DEBUG_LEVEL_GTE_HIGH
AVM_ENDIF_DEBUG_LEVEL_FLAG2( MEDIUM , COMPUTING , STATEMENT )
return( rtCode );
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
///// the RESUME & EVAL statement
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
bool AvmPrimitiveProcessor::resume(ExecutionEnvironment & ENV)
{
const AvmCode * aCode = ENV.inCODE;
if( aCode == NULL )
{
return( false );
}
AVM_IF_DEBUG_LEVEL_FLAG2( MEDIUM , COMPUTING , STATEMENT )
AVM_OS_TRACE << INCR_INDENT_TAB << "<<|| pos:"
<< static_cast< avm_size_t >(
ENV.inEXEC_LOCATION->itCode - aCode->begin())
// << " ?!? |=> " << aProgram->->str() << std::endl
<< " " << ENV.inED->mRID.strUniqId() << " |=> ";
aCode->toStream( AVM_OS_TRACE << IGNORE_FIRST_TAB );
AVM_IF_DEBUG_LEVEL_FLAG( HIGH , DATA )
ENV.inED->toStreamData(AVM_OS_TRACE);
AVM_ENDIF_DEBUG_LEVEL_FLAG( HIGH , DATA )
AVM_IF_DEBUG_LEVEL_GT_HIGH
AVM_OS_COUT << AVM_OS_TRACE.INDENT.TABS << "<<|| "
<< ENV.inED->mRID.strUniqId() << " |=> ";
aCode->toStream( AVM_OS_COUT << IGNORE_FIRST_TAB );
AVM_ENDIF_DEBUG_LEVEL_GT_HIGH
AVM_OS_TRACE << std::flush;
AVM_ENDIF_DEBUG_LEVEL_FLAG2( MEDIUM , COMPUTING , STATEMENT )
bool rtCode = AVM_PRIMITIVE_TABLE[ aCode->getOpOffset() ]->resume(ENV);
AVM_IF_DEBUG_LEVEL_FLAG2( MEDIUM , COMPUTING , STATEMENT )
AVM_IF_DEBUG_LEVEL_GTE_HIGH
AVM_OS_TRACE << TAB_DECR_INDENT << "||>> "
<< ENV.inED->mRID.strUniqId()
<< " |=> " << aCode->str() << std::endl;
AVM_IF_DEBUG_FLAG( DATA )
ENV.inED->toStreamData(AVM_OS_TRACE);
AVM_ENDIF_DEBUG_FLAG( DATA )
AVM_IF_DEBUG_LEVEL_GT_HIGH
AVM_OS_COUT << AVM_OS_TRACE.INDENT.TABS << " ||>> "
<< ENV.inED->mRID.strUniqId()
<< " |=> " << aCode->str() << std::endl;
AVM_ENDIF_DEBUG_LEVEL_GT_HIGH
AVM_OS_TRACE << std::flush;
AVM_DEBUG_ELSE
AVM_OS_TRACE << DECR_INDENT;
AVM_ENDIF_DEBUG_LEVEL_GTE_HIGH
AVM_ENDIF_DEBUG_LEVEL_FLAG2( MEDIUM , COMPUTING , STATEMENT )
return( rtCode );
}
bool AvmPrimitiveProcessor::decode_resume(ExecutionEnvironment & ENV)
{
APExecutionData tmpED = ENV.inED;
tmpED.makeWritable();
tmpED->mSTATEMENT_QUEUE.pushCache();
ListOfAPExecutionData tmpListOfInputED( tmpED );
ExecutionEnvironment tmpENV(ENV.PRIMITIVE_PROCESSOR);
while( tmpListOfInputED.nonempty() )
{
tmpListOfInputED.pop_first_to( tmpED );
if( not tmpENV.resume(ENV, tmpED) )
{
AVM_OS_EXIT( FAILED )
<< "Failed to RESUME< STATEMENT >!!!"
<< SEND_EXIT;
return( false );
}
while( tmpENV.outEDS.nonempty() )
{
tmpENV.outEDS.pop_last_to( tmpED );
switch( tmpED->getAEES() )
{
case AEES_STMNT_NOTHING:
case AEES_STMNT_FINAL:
case AEES_STMNT_DESTROY:
{
tmpED.mwsetAEES( AEES_OK );
//!!! NO << break >> for these statement
}
case AEES_STEP_RESUME:
{
if( tmpED->mSTATEMENT_QUEUE.nonempty() )
{
tmpListOfInputED.append( tmpED );
}
else
{
tmpED.mwsetAEES( AEES_OK );
ENV.outEDS.append( tmpED );
}
break;
}
case AEES_OK:
case AEES_STMNT_RETURN:
{
if( tmpED->mSTATEMENT_QUEUE.nonempty() )
{
tmpListOfInputED.append( tmpED );
}
else
{
ENV.outEDS.append( tmpED );
}
break;
}
default:
{
AVM_OS_FATAL_ERROR_EXIT
<< "Unexpected ENDIND EXECUTION STATUS :> "
<< RuntimeDef::strAEES( tmpED->mAEES ) << " !!!"
<< SEND_EXIT;
return( false );
}
}
}
}
// Sync EDS traitement
while( tmpENV.syncEDS.nonempty() )
{
tmpENV.syncEDS.first()->mSTATEMENT_QUEUE.pushCache();
ENV.appendSync( tmpENV.syncEDS.pop_first() );
}
// IRQ EDS traitement
ENV.spliceNotOutput(tmpENV);
return( true );
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
///// the DECODE & EVAL statement
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/**
* the EVAL instruction
*/
bool AvmPrimitiveProcessor::seval(EvaluationEnvironment & ENV)
{
const AvmCode * anExpression = ENV.inCODE;
AVM_IF_DEBUG_LEVEL_FLAG2( MEDIUM , COMPUTING , STATEMENT )
AVM_OS_TRACE << INCR_INDENT_TAB << "<< "
<< ENV.inED->mRID.strUniqId() << " , ED |-> ";
anExpression->toStream( AVM_OS_TRACE << IGNORE_FIRST_TAB );
AVM_IF_DEBUG_LEVEL_FLAG( HIGH , DATA )
ENV.outED->toStreamData(AVM_OS_TRACE);
AVM_ENDIF_DEBUG_LEVEL_FLAG( HIGH , DATA )
AVM_IF_DEBUG_LEVEL_GT_HIGH
AVM_OS_COUT << AVM_OS_TRACE.INDENT.TABS << "<< ED |-> ";
anExpression->toStream( AVM_OS_COUT << IGNORE_FIRST_TAB );
AVM_ENDIF_DEBUG_LEVEL_GT_HIGH
AVM_OS_TRACE << std::flush;
AVM_ENDIF_DEBUG_LEVEL_FLAG2( MEDIUM , COMPUTING , STATEMENT )
bool rtCode = false;
if( ENV.inCODE->hasInstruction() )
{
switch( ENV.inCODE->getInstruction()->getMainContext() )
{
case AVM_ARG_STANDARD_CTX:
{
InstructionEnvironment INSTRUCTION_ENV(ENV);
if( (ENV.mARG = INSTRUCTION_ENV.itARG)
->main_decode_eval_args(ENV.inCODE) )
{
ENV.outED = ENV.mARG->outED;
rtCode = AVM_PRIMITIVE_TABLE
[anExpression->getOpOffset()]->seval(ENV);
}
break;
}
case AVM_ARG_ARGUMENT_CTX:
case AVM_ARG_PARAMETER_CTX:
case AVM_ARG_RETURN_CTX:
{
InstructionEnvironment INSTRUCTION_ENV(ENV, 1);
if( (ENV.mARG = INSTRUCTION_ENV.itARG)
->main_decode_eval(ENV.inCODE) )
{
ENV.outED = ENV.mARG->outED;
ENV.outVAL = ENV.mARG->at(0);
rtCode = true;
}
break;
}
case AVM_ARG_UNDEFINED_CONTEXT:
default:
{
AVM_OS_FATAL_ERROR_EXIT
<< "AvmPrimitiveProcessor::seval :> Unexpected "
"opcode << " << ENV.inCODE->strDebug() << " >> !!!"
<< SEND_EXIT;
return( false );
}
}
}
else
{
rtCode = AVM_PRIMITIVE_TABLE[ anExpression->getOpOffset() ]->seval(ENV);
}
AVM_IF_DEBUG_LEVEL_FLAG2( MEDIUM , COMPUTING , STATEMENT )
AVM_IF_DEBUG_LEVEL_GTE_HIGH
AVM_OS_TRACE << TAB_DECR_INDENT << ">> "
<< ENV.inED->mRID.strUniqId() << " , ED |-> "
<< anExpression->str() << std::endl;
AVM_IF_DEBUG_FLAG( DATA )
ENV.inED->toStreamData(AVM_OS_TRACE);
AVM_ENDIF_DEBUG_FLAG( DATA )
AVM_IF_DEBUG_LEVEL_GT_HIGH
AVM_OS_COUT << AVM_OS_TRACE.INDENT.TABS << " >> " <<
ENV.inED->mRID.strUniqId() << " , ED |-> "
<< anExpression->str() << std::endl;
AVM_ENDIF_DEBUG_LEVEL_GT_HIGH
AVM_OS_TRACE << std::flush;
AVM_DEBUG_ELSE
AVM_OS_TRACE << DECR_INDENT;
AVM_ENDIF_DEBUG_LEVEL_GTE_HIGH
AVM_ENDIF_DEBUG_LEVEL_FLAG2( MEDIUM , COMPUTING , STATEMENT )
return( rtCode );
}
bool AvmPrimitiveProcessor::seval_wrt_ARG(EvaluationEnvironment & ENV)
{
return( AVM_PRIMITIVE_TABLE[ ENV.inCODE->getOpOffset() ]->seval(ENV) );
}
/**
* the DECODE EVAL instruction
*/
bool AvmPrimitiveProcessor::decode_seval(EvaluationEnvironment & ENV)
{
switch( ENV.inFORM.classKind() )
{
case FORM_AVMCODE_KIND:
{
ENV.inCODE = ENV.inFORM.bfCode();
return( seval(ENV) );
}
case FORM_INSTANCE_DATA_KIND:
{
InstanceOfData * anInstance = ENV.inFORM.to_ptr< InstanceOfData >();
if( (anInstance->getModifier().hasNatureReference()) )
{
ENV.outVAL = ENV.getRvalue(ENV.outED, ENV.getRvalue(
ENV.outED, anInstance).to_ptr< InstanceOfData >() );
}
else if( (anInstance->getModifier().hasNatureMacro()) )
{
ENV.inFORM = ENV.getRvalue(ENV.outED, anInstance);
return( decode_seval(ENV) );
}
else if( anInstance->getModifier().hasFeatureMutable() )
{
ENV.outVAL = ENV.getRvalue(ENV.outED, anInstance);
}
else if( anInstance->isEnumSymbolPointer() )
{
ENV.outVAL = ( anInstance->hasValue() &&
(not anInstance->getModifier().hasFeatureUnsafe()) )
? anInstance->getValue() : ENV.inFORM;
}
else if( ExecutableLib::MACHINE_SELF == anInstance )
{
ENV.outVAL = ENV.inED->mRID;
}
else if( ExecutableLib::MACHINE_PARENT == anInstance )
{
ENV.outVAL = ENV.inED->mRID.getPRID();
}
else
{
ENV.outVAL = ENV.inFORM;
}
return( true );
}
case FORM_BUILTIN_BOOLEAN_KIND:
case FORM_BUILTIN_CHARACTER_KIND:
case FORM_BUILTIN_INTEGER_KIND:
case FORM_BUILTIN_RATIONAL_KIND:
case FORM_BUILTIN_FLOAT_KIND:
case FORM_BUILTIN_STRING_KIND:
case FORM_BUILTIN_IDENTIFIER_KIND:
case FORM_BUILTIN_QUALIFIED_IDENTIFIER_KIND:
case FORM_OPERATOR_KIND:
case FORM_AVMLAMBDA_KIND:
case FORM_AVMPROGRAM_KIND:
case FORM_AVMTRANSITION_KIND:
case FORM_EXECUTABLE_MACHINE_KIND:
case FORM_EXECUTABLE_SYSTEM_KIND:
{
ENV.outVAL = ENV.inFORM;
return( true );
}
// case FORM_UFI_KIND:
// {
// return( mAvmUfiPrimitive->s_evalUfi(ENV, ENV.inFORM.bfUFI()) );
// }
case FORM_INSTANCE_MACHINE_KIND:
{
InstanceOfMachine * anInstance =
ENV.inFORM.to_ptr< InstanceOfMachine >();
if( anInstance->hasRuntimeRID() )
{
ENV.outVAL = anInstance->getRuntimeRID();
}
else if( ExecutableLib::MACHINE_NULL == anInstance )
{
ENV.outVAL = RuntimeLib::RID_NIL;
}
else if( ExecutableLib::MACHINE_ENVIRONMENT == anInstance )
{
ENV.outVAL = RuntimeLib::RID_ENVIRONMENT;
}
else
{
ENV.outVAL = ENV.outED->getRuntimeID(anInstance);
}
return( true );
}
case FORM_RUNTIME_ID_KIND:
case FORM_INSTANCE_PORT_KIND:
case FORM_INSTANCE_BUFFER_KIND:
case FORM_INSTANCE_CONNECTOR_KIND:
{
ENV.outVAL = ENV.inFORM;
return( true );
}
case FORM_ARRAY_BOOLEAN_KIND:
case FORM_ARRAY_INTEGER_KIND:
case FORM_ARRAY_RATIONAL_KIND:
case FORM_ARRAY_FLOAT_KIND:
case FORM_ARRAY_CHARACTER_KIND:
case FORM_ARRAY_IDENTIFIER_KIND:
case FORM_ARRAY_STRING_KIND:
case FORM_ARRAY_QUALIFIED_IDENTIFIER_KIND:
{
ENV.outVAL.renew( ENV.inFORM.to_ptr< BuiltinArray >()->getArrayBF() );
return( true );
}
case FORM_ARRAY_BF_KIND:
{
ArrayBF * inArray = ENV.inFORM.to_ptr< ArrayBF >();
ArrayBF * outArrayBF = new ArrayBF(
inArray->getTypeSpecifier(), inArray->size());
for( avm_size_t i = 0 ; i < inArray->size() ; ++i )
{
if( ENV.seval( inArray->at(i) ) )
{
outArrayBF->set(i, ENV.outVAL);
}
else
{
ENV.outVAL.renew( outArrayBF );
return( false );
}
}
ENV.outVAL.renew( outArrayBF );
return( true );
}
default:
{
if( ENV.inFORM.is< BuiltinList >() )
{
BuiltinList * inContainer = ENV.inFORM.to_ptr< BuiltinList >();
BuiltinList * outContainer = new BuiltinList(
inContainer->classKind(), inContainer->capacity());
BuiltinList::const_iterator it = inContainer->begin();
BuiltinList::const_iterator endIt = inContainer->end();
for( ; it != endIt ; ++it )
{
if( ENV.seval( *it ) )
{
outContainer->push(ENV.outVAL);
}
else
{
ENV.outVAL.renew( outContainer );
return( false );
}
}
ENV.outVAL.renew( outContainer );
return( true );
}
else if( ENV.inFORM.is< BuiltinVector >() )
{
BuiltinVector * inContainer = ENV.inFORM.to_ptr< BuiltinVector >();
BuiltinVector * outContainer = new BuiltinVector(
inContainer->classKind(),
((BuiltinContainer *)inContainer)->capacity());
for( avm_size_t i = 0 ; i < inContainer->size() ; ++i )
{
if( ENV.seval( inContainer->at(i) ) )
{
outContainer->push(ENV.outVAL);
}
else
{
ENV.outVAL.renew( outContainer );
return( false );
}
}
ENV.outVAL.renew( outContainer );
return( true );
}
// TODO
AVM_OS_WARNING_ALERT
<< "AvmPrimitiveProcessor is trying "
"to decode_seval the Expression\n"
<< ENV.inFORM.toString( AVM_TAB1_INDENT )
<< SEND_ALERT;
ENV.outVAL = ENV.inFORM;
return( false );
}
}
return( true );
}
}