bool csp::OpAlt::CheckArgs( lua::LuaStack& args, InitError& initError ) const { if( (args.NumArgs() & 1) != 0 ) return initError.Error( "even number of arguments required. (guard+closure) pairs required" ); bool nilCase = false; for( int i = 1; i <= args.NumArgs(); i += 2 ) { lua::LuaStackValue guard = args[i]; lua::LuaStackValue closure = args[i+1]; Channel* pChannel = NULL; if( IsChannelArg(guard) && ( pChannel = GetChannelArg(guard) ) != NULL ) { if( pChannel->InAttached() ) return initError.ArgError( i, "channel is in input operation already" ); } else if( guard.IsNumber() ) { } else if( guard.IsNil() ) { if( nilCase ) return initError.ArgError( i, "there must be just one nil case" ); nilCase = true; } else return initError.ArgError( i, "channel, number or nil required as a guard" ); if( !closure.IsFunction() ) return initError.ArgError( i+1, "closure required" ); } return true; }
int csp::OpLua::PushResults( lua::LuaStack& stack ) { int numResults = 0; int top = stack.GetTop(); if ( CallLua( stack, "PushResults", 0, lua::LUA_MULT_RET ) ) numResults = stack.GetTop() - top; UnrefSelf( stack ); return numResults; }
void csp::OpTestSuite_RunAll::InitTest( lua::LuaStack& stack, InitError&, const char* suiteName, const char* functionName, lua::LuaStackValue& function ) { TestClosure* pClosure = CORE_NEW TestClosure(); lua::LuaState thread = stack.NewThread(); function.PushValue(); stack.XMove( thread.GetStack(), 1 ); pClosure->process.SetLuaThread( thread ); pClosure->process.SetParentProcess( ThisProcess() ); pClosure->refKey = stack.RefInRegistry(); pClosure->suiteName = suiteName; pClosure->functionName = functionName; ListAddToTail( m_pClosuresHead, m_pClosuresTail, *pClosure ); }
void csp::OpAlt::UnrefProcess( lua::LuaStack const& stack ) { if( m_processRefKey != lua::LUA_NO_REF ) { stack.UnrefInRegistry( m_processRefKey ); m_processRefKey = lua::LUA_NO_REF; } }
void csp::OpAlt::UnrefArguments( lua::LuaStack const& stack ) { for( int i = 0; i < m_numArguments; ++i ) { stack.UnrefInRegistry( m_arguments[i].refKey ); m_arguments[i].refKey = lua::LUA_NO_REF; } }
bool csp::OpTestSuite_RunAll::Init( lua::LuaStack& args, InitError& initError ) { lua::LuaStackValue globals = args.PushGlobalTable(); for ( lua::LuaStackTableIterator it( globals ); it; it.Next() ) { lua::LuaStackValue name = it.Key(); lua::LuaStackValue value = it.Value(); if ( name.IsString() && value.IsTable() && CspHasMetatable( args.InternalState(), value, testSuiteFunctions ) ) { InitTestSuite( args, initError, name.GetString(), value ); } } return true; }
bool csp::OpLua::CallLua( lua::LuaStack& stack, const char* functionName, int numArgs, int numRets ) { CORE_ASSERT( m_self != lua::LUA_NO_REF ); stack.PushRegistryReferenced( m_self ); lua::LuaStackValue top = stack.GetTopValue(); CORE_ASSERT( top.IsTable() ); stack.GetField( top, functionName ); if ( !stack.GetTopValue().IsFunction() ) { stack.Pop( numArgs + 2 ); return false; } // stack at this point: arg1, arg2, argN, self, function stack.Insert( -numArgs-2 ); stack.Insert( -numArgs-1 ); // stack at this point: function, self, arg1, arg2, argN lua::LuaState luaState( stack.InternalState() ); lua::Return::Enum result = luaState.Call( 1+numArgs, numRets ); return result == lua::Return::OK; }
bool csp::OpLua::Init( lua::LuaStack& args, InitError& initError ) { lua::LuaStackValue self = args[1]; if( !self.IsTable() ) return initError.ArgError( 1, "OpLua table expected." ); self.PushValue(); m_self = args.RefInRegistry(); return true; }
void csp::OpAlt::CloseCase( lua::LuaStack& stack, AltCase& altCase ) { if( altCase.m_pChannel ) { altCase.m_pChannel->ResetAttachmentIn( *this ); altCase.m_pChannel = NULL; } if( altCase.m_channelRefKey != lua::LUA_NO_REF ) { stack.UnrefInRegistry( altCase.m_channelRefKey ); altCase.m_channelRefKey = lua::LUA_NO_REF; } if( altCase.m_closureRefKey != lua::LUA_NO_REF ) { stack.UnrefInRegistry( altCase.m_closureRefKey ); altCase.m_closureRefKey = lua::LUA_NO_REF; } }
void csp::OpAlt::UnrefClosures( lua::LuaStack const& stack ) { for( int i = 0; i < m_numCases; ++i ) { AltCase& altCase = m_cases[ i ]; if( altCase.m_closureRefKey != lua::LUA_NO_REF ) { stack.UnrefInRegistry( altCase.m_closureRefKey ); altCase.m_closureRefKey = lua::LUA_NO_REF; } } }
void csp::OpAlt::UnrefChannels( lua::LuaStack const& stack ) { for( int i = 0; i < m_numCases; ++i ) { if( m_cases[i].m_pChannel != NULL ) { m_cases[i].m_pChannel = NULL; stack.UnrefInRegistry( m_cases[i].m_channelRefKey ); m_cases[i].m_channelRefKey = lua::LUA_NO_REF; } } }
void csp::OpAlt::InitCases( lua::LuaStack& args ) { m_numCases = args.NumArgs()/2; m_cases = CORE_NEW AltCase [ m_numCases ]; int initCase = 0; for( int i = 1; i <= args.NumArgs(); i += 2 ) { lua::LuaStackValue guard = args[i]; lua::LuaStackValue closure = args[i+1]; closure.PushValue(); m_cases[ initCase ].m_closureRefKey = args.RefInRegistry(); if( IsChannelArg(guard) ) { Channel* pChannel = GetChannelArg( guard ); CORE_ASSERT( pChannel != NULL ); pChannel->SetAttachmentIn( *this ); guard.PushValue(); m_cases[ initCase ].m_channelRefKey = args.RefInRegistry(); m_cases[ initCase ].m_pChannel = pChannel; } else if( guard.IsNumber() ) { m_cases[ initCase ].m_time = guard.GetNumber(); } else if( guard.IsNil() ) { CORE_ASSERT( m_pNilCase == NULL ); m_pNilCase = m_cases + initCase; } ++initCase; } }
void csp::OpLua::UnrefSelf( lua::LuaStack& luaStack ) { CORE_ASSERT( m_self != lua::LUA_NO_REF ); luaStack.UnrefInRegistry( m_self ); m_self = lua::LUA_NO_REF; }