void _Block_Copy ( byte * srcAddress, int32 qsize ) { byte * saveHere = Here, * saveAddress = srcAddress ; ud_t * ud = Debugger_UdisInit ( _CfrTil_->Debugger0 ) ; int32 isize, left ; for ( left = qsize ; left > 0 ; srcAddress += isize ) { isize = _Udis_GetInstructionSize ( ud, srcAddress ) ; left -= isize ; if ( * srcAddress == _RET ) { if ( left && ( ( * srcAddress + 1 ) != NOOP ) ) // noop from our logic overwrite { // ?? unable at present to compile inline with more than one return in the block SetHere ( saveHere ) ; _Compile_Call ( saveAddress ) ; } break ; // don't include RET } else if ( * srcAddress == CALLI32 ) { int32 offset = * ( int32* ) ( srcAddress + 1 ) ; // 1 : 1 byte opCode if ( ! offset ) { _CfrTil_WordName_Run ( ( byte* ) "recurse" ) ; continue ; } else { byte * jcAddress = JumpCallInstructionAddress ( srcAddress ) ; Word * word = Word_GetFromCodeAddress ( jcAddress ) ; if ( word ) { _CompileWord ( word ) ; continue ; } //else (drop to) _CompileN ( srcAddress, isize ) } } else if ( * srcAddress == JMPI32 ) { int32 offset = * ( int32* ) ( srcAddress + 1 ) ; // 1 : 1 byte opCode if ( offset == 0 ) // signature of a goto point { _CfrTil_MoveGotoPoint ( ( int32 ) srcAddress + 1, 0, ( int32 ) Here + 1 ) ; _CompileN ( srcAddress, isize ) ; // memcpy ( dstAddress, address, size ) ; continue ; } //else (drop to) _CompileN ( srcAddress, isize ) } _CompileN ( srcAddress, isize ) ; // memcpy ( dstAddress, address, size ) ; } }
void linrec ( ) { CfrTil_BeginCombinator ( 4 ) ; byte * start = Here ; _Compile_Block ( ( byte* ) ifBlock, 3, 1 ) ; _Compile_Block ( ( byte* ) thenBlock, 2, 0 ) ; CfrTil_Else ( ) ; _Compile_Block ( ( byte* ) else1Block, 1, 0 ) ; _Compile_Call ( ( byte* ) start ) ; _Compile_Block ( ( byte* ) else2Block, 0, 0 ) ; CfrTil_EndIf ( ) ; CfrTil_EndCombinator ( 4, 1 ) ; }
void CfrTil_Combinator_LinRec ( ) { block else2Block = ( block ) TOS, else1Block = ( block ) Dsp [ - 1 ], thenBlock = ( block ) Dsp [ - 2 ], ifBlock = ( block ) Dsp [ - 3 ] ; _DataStack_DropN ( 4 ) ; if ( CompileMode ) { CfrTil_BeginCombinator ( 4 ) ; byte * start = Here ; _Compile_Block ( ( byte* ) ifBlock, 3, 1 ) ; _Compile_Block ( ( byte* ) thenBlock, 2, 0 ) ; CfrTil_Else ( ) ; _Compile_Block ( ( byte* ) else1Block, 1, 0 ) ; _Compile_Call ( ( byte* ) start ) ; _Compile_Block ( ( byte* ) else2Block, 0, 0 ) ; CfrTil_EndIf ( ) ; CfrTil_EndCombinator ( 4, 1 ) ; RET ( ) ; } else ilinrec ( ifBlock, thenBlock, else1Block, else2Block ) ; }
void Compile_Call ( byte * callAddr ) { int32 imm = _CalculateOffsetForCallOrJump ( Here + 1, callAddr, 1 ) ; _Compile_Call ( imm ) ; }