ソースを参照

Add a vector to SharedState where to store release hooks to be called when is safe to work with the vm, right now I'm calling it after calls to closures and whe finalizing the vm.
With this I also added a vm pointer to the release hook function because now we can send the vm to release hooks.

mingodad 13 年 前
コミット
1829e76e0f

+ 1 - 1
include/squirrel.h

@@ -298,7 +298,7 @@ typedef struct SQVM* HSQUIRRELVM;
 typedef SQObject HSQOBJECT;
 typedef SQObject HSQOBJECT;
 typedef SQMemberHandle HSQMEMBERHANDLE;
 typedef SQMemberHandle HSQMEMBERHANDLE;
 typedef SQInteger (*SQFUNCTION)(HSQUIRRELVM);
 typedef SQInteger (*SQFUNCTION)(HSQUIRRELVM);
-typedef SQInteger (*SQRELEASEHOOK)(SQUserPointer ptr, SQInteger size);
+typedef SQInteger (*SQRELEASEHOOK)(SQUserPointer ptr, SQInteger size, HSQUIRRELVM v);
 typedef void (*SQCOMPILERERROR)(HSQUIRRELVM,const SQChar * /*desc*/,const SQChar * /*source*/,SQInteger /*line*/,SQInteger /*column*/);
 typedef void (*SQCOMPILERERROR)(HSQUIRRELVM,const SQChar * /*desc*/,const SQChar * /*source*/,SQInteger /*line*/,SQInteger /*column*/);
 typedef void (*SQPRINTFUNCTION)(HSQUIRRELVM,const SQChar * ,...);
 typedef void (*SQPRINTFUNCTION)(HSQUIRRELVM,const SQChar * ,...);
 typedef void (*SQDEBUGHOOK)(HSQUIRRELVM /*v*/, SQInteger /*type*/, const SQChar * /*sourcename*/, SQInteger /*line*/, const SQChar * /*funcname*/);
 typedef void (*SQDEBUGHOOK)(HSQUIRRELVM /*v*/, SQInteger /*type*/, const SQChar * /*sourcename*/, SQInteger /*line*/, const SQChar * /*funcname*/);

+ 1 - 1
sqstdlib/sqstdblob.cpp

@@ -226,7 +226,7 @@ static SQInteger _blob__typeof(HSQUIRRELVM v)
 	return 1;
 	return 1;
 }
 }
 
 
-static SQInteger _blob_releasehook(SQUserPointer p, SQInteger size)
+static SQInteger _blob_releasehook(SQUserPointer p, SQInteger size, HSQUIRRELVM v)
 {
 {
 	SQBlob *self = (SQBlob*)p;
 	SQBlob *self = (SQBlob*)p;
 	self->~SQBlob();
 	self->~SQBlob();

+ 1 - 1
sqstdlib/sqstdio.cpp

@@ -114,7 +114,7 @@ static SQInteger _file__typeof(HSQUIRRELVM v)
 	return 1;
 	return 1;
 }
 }
 
 
-static SQInteger _file_releasehook(SQUserPointer p, SQInteger size)
+static SQInteger _file_releasehook(SQUserPointer p, SQInteger size, HSQUIRRELVM v)
 {
 {
 	SQFile *self = (SQFile*)p;
 	SQFile *self = (SQFile*)p;
 	self->~SQFile();
 	self->~SQFile();

+ 1 - 1
sqstdlib/sqstdmath.cpp

@@ -338,7 +338,7 @@ static SQRegFunction mathlib_funcs[] = {
 SQRESULT sqstd_register_mathlib(HSQUIRRELVM v)
 SQRESULT sqstd_register_mathlib(HSQUIRRELVM v)
 {
 {
     sq_pushstring(v,_SC("math"),-1);
     sq_pushstring(v,_SC("math"),-1);
-    sq_newclass(v,SQFalse);
+    sq_newtable(v);
 
 
 	SQInteger i=0;
 	SQInteger i=0;
 	while(mathlib_funcs[i].name!=0)	{
 	while(mathlib_funcs[i].name!=0)	{

+ 1 - 1
sqstdlib/sqstdstring.cpp

@@ -305,7 +305,7 @@ static SQInteger _string_split(HSQUIRRELVM v)
 	SQRex *self = NULL; \
 	SQRex *self = NULL; \
 	sq_getinstanceup(v,1,(SQUserPointer *)&self,0);
 	sq_getinstanceup(v,1,(SQUserPointer *)&self,0);
 
 
-static SQInteger _rexobj_releasehook(SQUserPointer p, SQInteger size)
+static SQInteger _rexobj_releasehook(SQUserPointer p, SQInteger size, HSQUIRRELVM v)
 {
 {
 	SQRex *self = ((SQRex *)p);
 	SQRex *self = ((SQRex *)p);
 	sqstd_rex_free(self);
 	sqstd_rex_free(self);

+ 27 - 1
squirrel/sqbaselib.cpp

@@ -1139,6 +1139,32 @@ static SQInteger string_find_lua(HSQUIRRELVM v)
         if(ms.error) return sq_throwerror(v, ms.error);
         if(ms.error) return sq_throwerror(v, ms.error);
         sq_pushinteger(v, rc);
         sq_pushinteger(v, rc);
         return 1;
         return 1;
+    }
+    else if(rtype == OT_TABLE || rtype == OT_ARRAY){
+        LuaMatchState ms;
+        memset(&ms, 0, sizeof(ms));
+        int rc = str_find(&ms, src, src_size, pattern, pattern_size,
+                start, raw == SQTrue, 0, 0);
+        if(ms.error) return sq_throwerror(v, ms.error);
+        if(rtype == OT_TABLE){
+            sq_pushstring(v, _SC("start_pos"), -1);
+            sq_pushinteger(v, ms.start_pos);
+            sq_rawset(v, 3);
+            sq_pushstring(v, _SC("end_pos"), -1);
+            sq_pushinteger(v, ms.end_pos);
+            sq_rawset(v, 3);
+        }
+        else if(rtype == OT_ARRAY)
+        {
+            sq_pushinteger(v, 0);
+            sq_pushinteger(v, ms.start_pos);
+            sq_rawset(v, 3);
+            sq_pushinteger(v, 1);
+            sq_pushinteger(v, ms.end_pos);
+            sq_rawset(v, 3);
+        }
+        sq_pushinteger(v, rc);
+        return 1;
     }
     }
 	return sq_throwerror(v,"invalid type for parameter 3 function expected");
 	return sq_throwerror(v,"invalid type for parameter 3 function expected");
 }
 }
@@ -1157,7 +1183,7 @@ SQRegFunction SQSharedState::_string_default_delegate_funcz[]={
 	{_SC("tostring"),default_delegate_tostring,1, _SC(".")},
 	{_SC("tostring"),default_delegate_tostring,1, _SC(".")},
 	{_SC("slice"),string_slice,-1, _SC(" s n  n")},
 	{_SC("slice"),string_slice,-1, _SC(" s n  n")},
 	{_SC("find"),string_find,-2, _SC("s s n ")},
 	{_SC("find"),string_find,-2, _SC("s s n ")},
-	{_SC("find_lua"),string_find_lua,-3, _SC("s s c i b")},
+	{_SC("find_lua"),string_find_lua,-3, _SC("s s c|t|a i b")},
 	{_SC("gsub"),string_gsub,-3, _SC("s s s|a|t|c n")},
 	{_SC("gsub"),string_gsub,-3, _SC("s s s|a|t|c n")},
 	{_SC("gmatch"),string_gmatch, 3, _SC("s s c")},
 	{_SC("gmatch"),string_gmatch, 3, _SC("s s c")},
 	{_SC("tolower"),string_tolower,1, _SC("s")},
 	{_SC("tolower"),string_tolower,1, _SC("s")},

+ 10 - 4
squirrel/sqclass.h

@@ -56,9 +56,9 @@ public:
 	bool SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val);
 	bool SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val);
 	bool GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval);
 	bool GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval);
 	void Lock() { _locked = true; if(_base) _base->Lock(); }
 	void Lock() { _locked = true; if(_base) _base->Lock(); }
-	void Release() { 
-		if (_hook) { _hook(_typetag,0);}
-		sq_delete(this, SQClass);	
+	void Release() {
+		if (_hook) { _hook(_typetag,0, 0);}
+		sq_delete(this, SQClass);
 	}
 	}
 	void Finalize();
 	void Finalize();
 #ifndef NO_GARBAGE_COLLECTOR
 #ifndef NO_GARBAGE_COLLECTOR
@@ -133,7 +133,13 @@ public:
 	}
 	}
 	void Release() {
 	void Release() {
 		_uiRef++;
 		_uiRef++;
-		if (_hook) { _hook(_userpointer,0);}
+		if (_hook) {
+		    SQDelayedReleseHook dh;
+		    dh.hook = _hook;
+		    dh.ptr = _userpointer;
+		    _sharedstate->_delayed_release_hook.push_back(dh);
+		    //_hook(_userpointer,0);
+        }
 		_uiRef--;
 		_uiRef--;
 		if(_uiRef > 0) return;
 		if(_uiRef > 0) return;
 		SQInteger size = _memsize;
 		SQInteger size = _memsize;

+ 6 - 0
squirrel/sqstate.h

@@ -60,6 +60,11 @@ private:
 
 
 struct SQObjectPtr;
 struct SQObjectPtr;
 
 
+struct SQDelayedReleseHook {
+    SQRELEASEHOOK hook;
+    SQUserPointer ptr;
+};
+
 struct SQSharedState
 struct SQSharedState
 {
 {
 	SQSharedState();
 	SQSharedState();
@@ -86,6 +91,7 @@ public:
 #ifndef NO_GARBAGE_COLLECTOR
 #ifndef NO_GARBAGE_COLLECTOR
 	SQCollectable *_gc_chain;
 	SQCollectable *_gc_chain;
 #endif
 #endif
+    sqvector<SQDelayedReleseHook> _delayed_release_hook;
 	SQObjectPtr _root_vm;
 	SQObjectPtr _root_vm;
 	SQObjectPtr _table_default_delegate;
 	SQObjectPtr _table_default_delegate;
 	static SQRegFunction _table_default_delegate_funcz[];
 	static SQRegFunction _table_default_delegate_funcz[];

+ 1 - 1
squirrel/squserdata.h

@@ -24,7 +24,7 @@ struct SQUserData : SQDelegable
 	SQObjectType GetType(){ return OT_USERDATA;}
 	SQObjectType GetType(){ return OT_USERDATA;}
 #endif
 #endif
 	void Release() {
 	void Release() {
-		if (_hook) _hook((SQUserPointer)sq_aligning(this + 1),_size);
+		if (_hook) _hook((SQUserPointer)sq_aligning(this + 1),_size, 0);
 		SQInteger tsize = _size;
 		SQInteger tsize = _size;
 		this->~SQUserData();
 		this->~SQUserData();
 		SQ_FREE(this, sq_aligning(sizeof(SQUserData)) + tsize);
 		SQ_FREE(this, sq_aligning(sizeof(SQUserData)) + tsize);

+ 10 - 0
squirrel/sqvm.cpp

@@ -125,6 +125,11 @@ SQVM::SQVM(SQSharedState *ss)
 
 
 void SQVM::Finalize()
 void SQVM::Finalize()
 {
 {
+    while(_sharedstate->_delayed_release_hook.size()){
+        SQDelayedReleseHook &dh = _sharedstate->_delayed_release_hook.back();
+        dh.hook(dh.ptr, 0, this);
+        _sharedstate->_delayed_release_hook.pop_back();
+    }
 	if(_openouters) CloseOuters(&_stack._vals[0]);
 	if(_openouters) CloseOuters(&_stack._vals[0]);
 	_roottable.Null();
 	_roottable.Null();
 	_lasterror.Null();
 	_lasterror.Null();
@@ -730,6 +735,11 @@ exception_restore:
 					switch (type(clo)) {
 					switch (type(clo)) {
 					case OT_CLOSURE:
 					case OT_CLOSURE:
 						_GUARD(StartCall(_closure(clo), sarg0, arg3, _stackbase+arg2, false));
 						_GUARD(StartCall(_closure(clo), sarg0, arg3, _stackbase+arg2, false));
+                        if(_sharedstate->_delayed_release_hook.size()){
+                            SQDelayedReleseHook &dh = _sharedstate->_delayed_release_hook.back();
+                            dh.hook(dh.ptr, 0, this);
+                            _sharedstate->_delayed_release_hook.pop_back();
+                        }
 						continue;
 						continue;
 					case OT_NATIVECLOSURE: {
 					case OT_NATIVECLOSURE: {
 						bool suspend;
 						bool suspend;