private bool Populate()
{
bool result = true;
_InnerCode = new List<CodePoint>();
//
// Add labels and source code
//
CodePoint p = new CodePoint();
for ( int i = 0; i < _SourceCode.Count; i++ )
{
if ( _SourceCode[ i ].EndsWith( ":" ) && ( ! _SourceCode[i].Contains(" ") ) )
{
p.Label = _SourceCode[ i ];
}
else
{
p.Source = _SourceCode[ i ];
_InnerCode.Add( p );
p = new CodePoint();
}
}
// Support for Label-at-the-end-of-code special case
// Here: the CodePoint with label but without code is added
if ( null != p.Label )
{
_InnerCode.Add( p );
}
for ( int i = 0; i < _InnerCode.Count; i++ )
{
string actionName;
string statement = null;
// Support for Label-at-the-end-of-code special case
// Here: Don't try to render last label into code as it doesn't have any
if ( null == _InnerCode[ i ].Source )
continue;
try
{
statement = PrepareAndReplaceLabel( _InnerCode[ i ].Source, out actionName );
}
catch ( AVM1ExceptionSourceFormat e )
{
String s = String.Format( "Preparation failed: {0}, Error was: {1}", _InnerCode[ i ].Source, e.Message );
Log.Error(this, s);
result = false;
break;
}
try
{
AbstractAction a;
if ( ( null != _OriginalInstructionMarker) && ( actionName.Equals( _OriginalInstructionMarker, StringComparison.InvariantCulture ) ) )
{
a = _OriginalInstruction;
}
else
{
a = AVM1.AVM1Factory.Create( actionName, statement );
}
_InnerCode[ i ].Code = a;
//Log.Debug(this, a.ToString() );
}
catch ( AVM1ExceptionSourceFormat )
{
Log.Error(this, "Syntax error: " + _InnerCode[ i ].Source );
result = false;
break;
}
}
if ( false == result )
return result;
// Support for Label-at-the-end-of-code special case
// Here: remove the _InnerCode element, as it's no longer needed since the
// branch targets have been resolved to indices
if ( null == _InnerCode[ _InnerCode.Count - 1 ].Source )
_InnerCode.RemoveAt( _InnerCode.Count - 1 );
//
// resolve the branch targets (which are still indices) into actual
// byte addresses
//
for ( int i = 0; i < _InnerCode.Count; i++ )
{
// TODO: make this better!
if ( ( _InnerCode[ i ].Code.IsBranch )
|| ( _InnerCode[ i ].Code.ActionType == AVM1Actions.ActionDefineFunction )
|| ( _InnerCode[ i ].Code.ActionType == AVM1Actions.ActionDefineFunction2 ) )
{
if ( _InnerCode[ i ].Code.BranchTarget > _InnerCode.Count )
{
Log.Error(this, _InnerCode[ i ].Source + " branch target out of range (" +
_InnerCode[ i ].Code.BranchTarget.ToString( "d" ) + " > " +
_InnerCode.Count.ToString( "d" ) + ")" );
result = false;
break;
}
int replacementTarget = _InnerCode[ i ].Code.BranchTarget;
int begin = i < replacementTarget ? i : replacementTarget;
int end = i > replacementTarget ? i : replacementTarget;
uint codesize = 0;
for ( int j = begin; j < end; j++ )
{
codesize += _InnerCode[ j ].Code.ActionLength;
}
_InnerCode[ i ].Code.BranchTargetAdjusted = (int)(i < replacementTarget? codesize : ( -1 * codesize ));
}
}
return result;
}