BlockInfo * _CfrTil_BeginBlock ( ) { Compiler * compiler = _Context_->Compiler0 ; BlockInfo *bi = ( BlockInfo * ) _Mem_Allocate ( sizeof (BlockInfo ), SESSION ) ; compiler->BlockLevel ++ ; if ( ! CompileMode ) // first block { CfrTil_TurnOnBlockCompiler ( ) ; } bi->ActualCodeStart = Here ; _Compile_UninitializedJump ( ) ; bi->JumpOffset = Here - CELL_SIZE ; // before CfrTil_CheckCompileLocalFrame after CompileUninitializedJump bi->bp_First = Here ; // after the jump for inlining if ( _Stack_IsEmpty ( compiler->BlockStack ) ) { // remember : we always jmp around the blocks to the combinator ; the combinator sees the blocks on the stack and uses them otherwise they are lost // the jmps are optimized out so the word->Definition is a call to the first combinator //CheckAddLocalFrame ( _Context->Compiler0 ) ; // // since we are supporting nested locals a lookahead here would have to check to the end of the word, so ... // we always add a frame and if not needed move the blocks to overwrite it bi->FrameStart = Here ; // before _Compile_AddLocalFrame _Compile_ESP_Save ( ) ; bi->AfterEspSave = Here ; // before _Compile_AddLocalFrame _Compiler_AddLocalFrame ( compiler ) ; // cf EndBlock : if frame is not needed we use BI_Start else BI_FrameStart -- ?? could waste some code space ?? Compile_InitRegisterVariables ( compiler ) ; // this function is called twice to deal with words that have locals before the first block and regular colon words } bi->Start = Here ; // after CheckAddLocalFrame return bi ; }
void CheckAddLocalFrame ( Compiler * compiler ) { if ( GetState ( compiler, ADD_FRAME ) ) { _Compiler_AddLocalFrame ( compiler ) ; SetState ( compiler, ADD_FRAME, false ) ; // only one frame necessary } }