@@ -284,6 +284,14 @@ class SquirrelVM : public IScriptVM
284284 WriteObject ( (const SQObjectPtr&)obj, pBuffer, writeState );
285285 }
286286
287+ void WriteObject ( SQGenerator *pObj, CUtlBuffer* pBuffer, WriteStateMap& writeState )
288+ {
289+ SQObject obj;
290+ obj._type = OT_GENERATOR;
291+ obj._unVal .pUserPointer = pObj;
292+ WriteObject ( (const SQObjectPtr&)obj, pBuffer, writeState );
293+ }
294+
287295 void ReadObject ( SQObjectPtr &obj, CUtlBuffer* pBuffer, ReadStateMap& readState );
288296
289297 // Do not implicity add/remove ref
@@ -3671,23 +3679,25 @@ void SquirrelVM::WriteObject( const SQObjectPtr &obj, CUtlBuffer* pBuffer, Write
36713679
36723680 if ( pThis->_callsstacksize )
36733681 {
3674- int stackidx = -1 ;
3675-
36763682 for ( int i = pThis->_callsstacksize ; i--; )
36773683 {
36783684 const SQVM::CallInfo *ci = &pThis->_callsstack [i];
36793685
3680- if ( pThis->ci == ci )
3681- stackidx = i;
3682-
3683- Assert ( !ci->_generator );
3684- Assert ( ci->_ip && ci->_ip >= ci->_closure ._unVal .pClosure ->_function ->_instructions );
3686+ Assert ( ci->_ip >= ci->_closure ._unVal .pClosure ->_function ->_instructions &&
3687+ ci->_ip < ci->_closure ._unVal .pClosure ->_function ->_instructions +
3688+ ci->_closure ._unVal .pClosure ->_function ->_ninstructions );
36853689 Assert ( pThis->_etraps .size () >= (SQUnsignedInteger)ci->_etraps );
36863690 Assert ( ci->_closure ._type == OT_CLOSURE && ci->_closure ._unVal .pClosure );
36873691
36883692 WriteObject ( ci->_closure , pBuffer, writeState );
36893693
3690- int offset = (int )ci->_ip - (int )ci->_closure ._unVal .pClosure ->_function ->_instructions ;
3694+ Assert ( ci->_ip - ci->_closure ._unVal .pClosure ->_function ->_instructions <= INT_MAX );
3695+
3696+ pBuffer->PutChar ( ci->_generator != 0 );
3697+ if ( ci->_generator )
3698+ WriteObject ( ci->_generator , pBuffer, writeState );
3699+
3700+ int offset = ci->_ip - ci->_closure ._unVal .pClosure ->_function ->_instructions ;
36913701 pBuffer->PutInt ( offset );
36923702 pBuffer->PutInt ( ci->_etraps );
36933703 pBuffer->PutInt ( ci->_prevstkbase );
@@ -3699,13 +3709,15 @@ void SquirrelVM::WriteObject( const SQObjectPtr &obj, CUtlBuffer* pBuffer, Write
36993709 for ( int j = ci->_etraps ; j--; )
37003710 {
37013711 const SQExceptionTrap &et = pThis->_etraps [j];
3702- pBuffer->PutInt ( et._extarget );
3703- pBuffer->PutInt ( et._stackbase );
37043712 pBuffer->PutInt ( et._stacksize );
3705- Assert ( et._ip == ci->_ip );
3713+ pBuffer->PutInt ( et._stackbase );
3714+ Assert ( et._ip - ci->_ip <= INT_MAX );
3715+ pBuffer->PutInt ( et._ip - ci->_ip );
3716+ pBuffer->PutInt ( et._extarget );
37063717 }
37073718 }
37083719
3720+ int stackidx = pThis->ci - pThis->_callsstack ;
37093721 Assert ( stackidx >= 0 && stackidx < pThis->_callsstacksize );
37103722 pBuffer->PutInt ( stackidx );
37113723 }
@@ -3736,29 +3748,37 @@ void SquirrelVM::WriteObject( const SQObjectPtr &obj, CUtlBuffer* pBuffer, Write
37363748
37373749 WriteObject ( pThis->_closure , pBuffer, writeState );
37383750
3739- const SQVM::CallInfo &ci = pThis->_ci ;
3751+ const SQVM::CallInfo *ci = &pThis->_ci ;
3752+
3753+ Assert ( pThis->_closure ._unVal .pClosure == ci->_closure ._unVal .pClosure );
3754+ Assert ( ci->_ip >= ci->_closure ._unVal .pClosure ->_function ->_instructions &&
3755+ ci->_ip < ci->_closure ._unVal .pClosure ->_function ->_instructions +
3756+ ci->_closure ._unVal .pClosure ->_function ->_ninstructions );
3757+ Assert ( pThis->_etraps .size () >= (SQUnsignedInteger)ci->_etraps );
37403758
3741- Assert ( !ci._generator );
3742- Assert ( pThis->_closure ._unVal .pClosure == ci._closure ._unVal .pClosure );
3743- Assert ( ci._ip && ci._ip >= ci._closure ._unVal .pClosure ->_function ->_instructions );
3744- Assert ( pThis->_etraps .size () >= (SQUnsignedInteger)ci._etraps );
3759+ Assert ( ci->_ip - ci->_closure ._unVal .pClosure ->_function ->_instructions <= INT_MAX );
37453760
3746- int offset = (int )ci._ip - (int )ci._closure ._unVal .pClosure ->_function ->_instructions ;
3761+ pBuffer->PutChar ( ci->_generator != 0 );
3762+ if ( ci->_generator )
3763+ WriteObject ( ci->_generator , pBuffer, writeState );
3764+
3765+ int offset = ci->_ip - ci->_closure ._unVal .pClosure ->_function ->_instructions ;
37473766 pBuffer->PutInt ( offset );
3748- pBuffer->PutInt ( ci. _etraps );
3749- pBuffer->PutInt ( ci. _prevstkbase );
3750- pBuffer->PutInt ( ci. _prevtop );
3751- pBuffer->PutInt ( ci. _target );
3752- pBuffer->PutInt ( ci. _ncalls );
3753- pBuffer->PutChar ( ci. _root );
3767+ pBuffer->PutInt ( ci-> _etraps );
3768+ pBuffer->PutInt ( ci-> _prevstkbase );
3769+ pBuffer->PutInt ( ci-> _prevtop );
3770+ pBuffer->PutInt ( ci-> _target );
3771+ pBuffer->PutInt ( ci-> _ncalls );
3772+ pBuffer->PutChar ( ci-> _root );
37543773
3755- for ( int j = ci. _etraps ; j--; )
3774+ for ( int j = ci-> _etraps ; j--; )
37563775 {
37573776 const SQExceptionTrap &et = pThis->_etraps [j];
3758- pBuffer->PutInt ( et._extarget );
3759- pBuffer->PutInt ( et._stackbase );
37603777 pBuffer->PutInt ( et._stacksize );
3761- Assert ( et._ip == ci._ip );
3778+ pBuffer->PutInt ( et._stackbase );
3779+ Assert ( et._ip - ci->_ip <= INT_MAX );
3780+ pBuffer->PutInt ( et._ip - ci->_ip );
3781+ pBuffer->PutInt ( et._extarget );
37623782 }
37633783
37643784 int stacksize = pThis->_stack .size ();
@@ -4331,23 +4351,31 @@ void SquirrelVM::ReadObject( SQObjectPtr &pObj, CUtlBuffer* pBuffer, ReadStateMa
43314351 ReadObject ( closure, pBuffer, readState );
43324352 Assert ( closure._type == OT_CLOSURE && closure._unVal .pClosure );
43334353
4354+ if ( pBuffer->GetChar () )
4355+ {
4356+ SQObject generator;
4357+ ReadObject ( generator, pBuffer, readState );
4358+ Assert ( generator._type == OT_GENERATOR && generator._unVal .pGenerator );
4359+ ci->_generator = generator._unVal .pGenerator ;
4360+ }
4361+ else
4362+ {
4363+ ci->_generator = NULL ;
4364+ }
4365+
43344366 int offset = pBuffer->GetInt ();
4335- int funcsize = sizeof (SQInstruction) * closure._unVal .pClosure ->_function ->_ninstructions ;
4336- int start = (int )(closure._unVal .pClosure ->_function ->_instructions );
4337- int pos = start + offset;
4338- ci->_ip = (SQInstruction*)pos;
4367+ SQInstruction *start = closure._unVal .pClosure ->_function ->_instructions ;
4368+ SQInstruction *end = start + closure._unVal .pClosure ->_function ->_ninstructions ;
4369+ SQInstruction *pos = start + offset;
43394370
4340- Assert ( pos < ( start + funcsize) );
4371+ Assert ( pos >= start && pos < end );
43414372
4342- // don't read past boundary
4343- if ( pos >= (start + funcsize) )
4344- {
4345- ci->_ip = (SQInstruction*)start;
4346- }
4373+ if ( pos < start || pos >= end )
4374+ pos = start;
43474375
4376+ ci->_ip = pos;
43484377 ci->_literals = closure._unVal .pClosure ->_function ->_literals ;
43494378 ci->_closure = closure;
4350- ci->_generator = NULL ;
43514379 ci->_etraps = pBuffer->GetInt ();
43524380 ci->_prevstkbase = pBuffer->GetInt ();
43534381 ci->_prevtop = pBuffer->GetInt ();
@@ -4360,10 +4388,10 @@ void SquirrelVM::ReadObject( SQObjectPtr &pObj, CUtlBuffer* pBuffer, ReadStateMa
43604388 for ( int j = ci->_etraps ; j--; )
43614389 {
43624390 SQExceptionTrap &et = pThis->_etraps [j];
4363- et._extarget = pBuffer->GetInt ();
4364- et._stackbase = pBuffer->GetInt ();
43654391 et._stacksize = pBuffer->GetInt ();
4366- et._ip = ci->_ip ;
4392+ et._stackbase = pBuffer->GetInt ();
4393+ et._ip = ci->_ip + pBuffer->GetInt ();
4394+ et._extarget = pBuffer->GetInt ();
43674395 }
43684396 }
43694397
@@ -4410,41 +4438,49 @@ void SquirrelVM::ReadObject( SQObjectPtr &pObj, CUtlBuffer* pBuffer, ReadStateMa
44104438
44114439 pThis->_state = (SQGenerator::SQGeneratorState)state;
44124440
4413- SQVM::CallInfo &ci = pThis->_ci ;
4441+ SQVM::CallInfo *ci = &pThis->_ci ;
4442+
4443+ if ( pBuffer->GetChar () )
4444+ {
4445+ SQObject generator;
4446+ ReadObject ( generator, pBuffer, readState );
4447+ Assert ( generator._type == OT_GENERATOR && generator._unVal .pGenerator );
4448+ ci->_generator = generator._unVal .pGenerator ;
4449+ }
4450+ else
4451+ {
4452+ ci->_generator = NULL ;
4453+ }
44144454
44154455 int offset = pBuffer->GetInt ();
4416- int funcsize = sizeof (SQInstruction) * closure._unVal .pClosure ->_function ->_ninstructions ;
4417- int start = (int )(closure._unVal .pClosure ->_function ->_instructions );
4418- int pos = start + offset;
4419- ci._ip = (SQInstruction*)pos;
4456+ SQInstruction *start = closure._unVal .pClosure ->_function ->_instructions ;
4457+ SQInstruction *end = start + closure._unVal .pClosure ->_function ->_ninstructions ;
4458+ SQInstruction *pos = start + offset;
44204459
4421- Assert ( pos < ( start + funcsize) );
4460+ Assert ( pos >= start && pos < end );
44224461
4423- // don't read past boundary
4424- if ( pos >= (start + funcsize) )
4425- {
4426- ci._ip = (SQInstruction*)start;
4427- }
4462+ if ( pos < start || pos >= end )
4463+ pos = start;
44284464
4429- ci. _literals = closure. _unVal . pClosure -> _function -> _literals ;
4430- ci. _closure = closure;
4431- ci. _generator = NULL ;
4432- ci. _etraps = pBuffer->GetInt ();
4433- ci. _prevstkbase = pBuffer->GetInt ();
4434- ci. _prevtop = pBuffer->GetInt ();
4435- ci. _target = pBuffer->GetInt ();
4436- ci. _ncalls = pBuffer->GetInt ();
4437- ci. _root = pBuffer->GetChar ();
4465+ ci-> _ip = pos ;
4466+ ci-> _literals = closure. _unVal . pClosure -> _function -> _literals ;
4467+ ci-> _closure = closure ;
4468+ ci-> _etraps = pBuffer->GetInt ();
4469+ ci-> _prevstkbase = pBuffer->GetInt ();
4470+ ci-> _prevtop = pBuffer->GetInt ();
4471+ ci-> _target = pBuffer->GetInt ();
4472+ ci-> _ncalls = pBuffer->GetInt ();
4473+ ci-> _root = pBuffer->GetChar ();
44384474
4439- pThis->_etraps .resize ( ci. _etraps );
4475+ pThis->_etraps .resize ( ci-> _etraps );
44404476
4441- for ( int j = ci. _etraps ; j--; )
4477+ for ( int j = ci-> _etraps ; j--; )
44424478 {
44434479 SQExceptionTrap &et = pThis->_etraps [j];
4444- et._extarget = pBuffer->GetInt ();
4445- et._stackbase = pBuffer->GetInt ();
44464480 et._stacksize = pBuffer->GetInt ();
4447- et._ip = ci._ip ;
4481+ et._stackbase = pBuffer->GetInt ();
4482+ et._ip = ci->_ip + pBuffer->GetInt ();
4483+ et._extarget = pBuffer->GetInt ();
44484484 }
44494485
44504486 int stacksize = pBuffer->GetInt ();
0 commit comments