Browse Source

Fix for a bug reported and solved by https://github.com/virt00l on squirrel

mingodad 8 years ago
parent
commit
1cfc0f80f5
2 changed files with 14 additions and 10 deletions
  1. 4 1
      SquiLu/squirrel/sqcompiler.cpp
  2. 10 9
      SquiLu/squirrel/sqvm.cpp

+ 4 - 1
SquiLu/squirrel/sqcompiler.cpp

@@ -1577,7 +1577,10 @@ public:
 		 for(SQInteger i = 0; i < (nargs - 1); i++) _fs->PopTarget();
 		 for(SQInteger i = 0; i < (nargs - 1); i++) _fs->PopTarget();
 		 SQInteger stackbase = _fs->PopTarget();
 		 SQInteger stackbase = _fs->PopTarget();
 		 SQInteger closure = _fs->PopTarget();
 		 SQInteger closure = _fs->PopTarget();
-         _fs->AddInstruction(_OP_CALL, _fs->PushTarget(), closure, stackbase, nargs);
+         SQInteger target = _fs->PushTarget();
+         assert(target >= -1);
+         assert(target < 255);
+         _fs->AddInstruction(_OP_CALL, target, closure, stackbase, nargs);
 	}
 	}
 	void AddClassMemberExists(SQObjectPtr &member_names, SQObject &name)
 	void AddClassMemberExists(SQObjectPtr &member_names, SQObject &name)
 	{
 	{

+ 10 - 9
SquiLu/squirrel/sqvm.cpp

@@ -952,35 +952,36 @@ exception_restore:
 							  }
 							  }
 			OPCODE_TARGET(CALL) {
 			OPCODE_TARGET(CALL) {
 					SQObjectPtr clo = STK(arg1);
 					SQObjectPtr clo = STK(arg1);
+					int tgt0 = arg0 == 255 ? -1 : arg0;
 					switch (sq_type(clo)) {
 					switch (sq_type(clo)) {
 					case OT_CLOSURE:
 					case OT_CLOSURE:
-						_GUARD(StartCall(_closure(clo), sarg0, arg3, _stackbase+arg2, false));
+						_GUARD(StartCall(_closure(clo), tgt0, arg3, _stackbase+arg2, false));
 						continue;
 						continue;
 					case OT_NATIVECLOSURE: {
 					case OT_NATIVECLOSURE: {
 						bool suspend;
 						bool suspend;
 						bool tailcall;
 						bool tailcall;
-                        _GUARD(CallNative(_nativeclosure(clo), arg3, _stackbase+arg2, clo, (SQInt32)sarg0, suspend, tailcall));
+                        _GUARD(CallNative(_nativeclosure(clo), arg3, _stackbase+arg2, clo, tgt0, suspend, tailcall));
 #ifdef SQ_WITH_DELAYED_RELEASE_HOOKS
 #ifdef SQ_WITH_DELAYED_RELEASE_HOOKS
 						if(_check_delayed_relase_hooks) _sharedstate->CallDelayedReleaseHooks(this);
 						if(_check_delayed_relase_hooks) _sharedstate->CallDelayedReleaseHooks(this);
 #endif
 #endif
 						if(suspend){
 						if(suspend){
 							_suspended = SQTrue;
 							_suspended = SQTrue;
-							_suspended_target = sarg0;
+							_suspended_target = tgt0;
 							_suspended_root = ci->_root;
 							_suspended_root = ci->_root;
 							_suspended_traps = traps;
 							_suspended_traps = traps;
 							outres = clo;
 							outres = clo;
 							return true;
 							return true;
 						}
 						}
-						if((sarg0 != -1) && !tailcall) {
-							STK(arg0) = clo;
+						if((tgt0 != -1) && !tailcall) {
+							STK(tgt0) = clo;
 						}
 						}
                     }
                     }
 						continue;
 						continue;
 					case OT_CLASS:{
 					case OT_CLASS:{
 						SQObjectPtr inst;
 						SQObjectPtr inst;
 						_GUARD(CreateClassInstance(_class(clo),inst,clo));
 						_GUARD(CreateClassInstance(_class(clo),inst,clo));
-						if(sarg0 != -1) {
-							STK(arg0) = inst;
+						if(tgt0 != -1) {
+							STK(tgt0) = inst;
 						}
 						}
 						SQInteger stkbase;
 						SQInteger stkbase;
 						switch(sq_type(clo)) {
 						switch(sq_type(clo)) {
@@ -1007,8 +1008,8 @@ exception_restore:
 							Push(clo);
 							Push(clo);
 							for (SQInteger i = 0; i < arg3; i++) Push(STK(arg2 + i));
 							for (SQInteger i = 0; i < arg3; i++) Push(STK(arg2 + i));
 							if(!CallMetaMethod(closure, MT_CALL, arg3+1, clo)) SQ_THROW();
 							if(!CallMetaMethod(closure, MT_CALL, arg3+1, clo)) SQ_THROW();
-							if(sarg0 != -1) {
-								STK(arg0) = clo;
+							if(tgt0 != -1) {
+								STK(tgt0) = clo;
 							}
 							}
 							break;
 							break;
 						}
 						}