Просмотр исходного кода

Add array_float64, array_float32, array_int64, array_int32, array_int16, array_int8 global functions to create native numeric arrays.

mingodad 7 лет назад
Родитель
Сommit
d32881d419

+ 3 - 2
SquiLu/include/sqapi.h

@@ -155,13 +155,14 @@ SQUIRREL_API_FUNC(SQRESULT, newmember, (HSQUIRRELVM v,SQInteger idx,SQBool bstat
 SQUIRREL_API_FUNC(SQRESULT, rawnewmember, (HSQUIRRELVM v,SQInteger idx,SQBool bstatic))
 SQUIRREL_API_FUNC(SQRESULT, arrayappend, (HSQUIRRELVM v,SQInteger idx))
 SQUIRREL_API_FUNC(SQRESULT, arraypop, (HSQUIRRELVM v,SQInteger idx,SQBool pushval))
-SQUIRREL_API_FUNC(SQRESULT, arrayresize, (HSQUIRRELVM v,SQInteger idx,SQInteger newsize))
-SQUIRREL_API_FUNC(SQRESULT, arrayminsize, (HSQUIRRELVM v,SQInteger idx,SQInteger minsize))
+SQUIRREL_API_FUNC(SQRESULT, arrayresize, (HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger newsize))
+SQUIRREL_API_FUNC(SQRESULT, arrayminsize, (HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger minsize))
 SQUIRREL_API_FUNC(SQRESULT, arrayreverse, (HSQUIRRELVM v,SQInteger idx))
 SQUIRREL_API_FUNC(SQRESULT, arrayremove, (HSQUIRRELVM v,SQInteger idx,SQInteger itemidx))
 SQUIRREL_API_FUNC(SQRESULT, arrayinsert, (HSQUIRRELVM v,SQInteger idx,SQInteger destpos))
 SQUIRREL_API_FUNC(SQRESULT, arrayget, (HSQUIRRELVM v,SQInteger idx,SQInteger pos))
 SQUIRREL_API_FUNC(SQRESULT, arrayset, (HSQUIRRELVM v,SQInteger idx,SQInteger destpos))
+SQUIRREL_API_FUNC(SQRESULT, arraygetsizeof, (HSQUIRRELVM v,SQInteger idx))
 SQUIRREL_API_FUNC(SQRESULT, setdelegate, (HSQUIRRELVM v,SQInteger idx))
 SQUIRREL_API_FUNC(SQRESULT, getdelegate, (HSQUIRRELVM v,SQInteger idx))
 SQUIRREL_API_FUNC(SQRESULT, clone, (HSQUIRRELVM v,SQInteger idx))

+ 11 - 9
SquiLu/include/sqconfig.h

@@ -1,13 +1,20 @@
 #ifndef NO_ABSTRACT_METHOD
-#define ABSTRACT_METHOD(m, i) m =0
+#define ABSTRACT_METHOD(m, i) m =0;
 #else
 #define ABSTRACT_METHOD(m, i) m i
 #endif
 
-#ifdef _SQ64
-
+typedef float SQFloat32;
+typedef double SQFloat64;
+typedef long long SQInt64;
+typedef int SQInt32; /*must be 32 bits(also on 64bits processors)*/
+typedef unsigned int SQUnsignedInteger32; /*must be 32 bits(also on 64bits processors)*/
 typedef short SQInt16;
 typedef unsigned short SQUnsignedInt16;
+typedef char SQInt8;
+
+#ifdef _SQ64
+
 #ifdef _MSC_VER
     #define SQ_INT_MAX _I64_MAX
     #define SQ_INT_MIN _I64_MIN
@@ -29,17 +36,11 @@ typedef long long SQInteger;
 typedef unsigned long long SQUnsignedInteger;
 typedef unsigned long long SQHash; /*should be the same size of a pointer*/
 #endif
-typedef int SQInt32;
-typedef unsigned int SQUnsignedInteger32;
 #else
 #define SQ_INT_MAX INT_MAX
 #define SQ_INT_MIN INT_MIN
 typedef int SQInteger;
 typedef unsigned int SQUnsignedInteger;
-typedef int SQInt32; /*must be 32 bits(also on 64bits processors)*/
-typedef unsigned int SQUnsignedInteger32; /*must be 32 bits(also on 64bits processors)*/
-typedef short SQInt16;
-typedef unsigned short SQUnsignedInt16;
 typedef unsigned int /*ptrdiff_t*/ SQHash; /*should be the same size of a pointer*/
 #endif
 
@@ -212,6 +213,7 @@ typedef unsigned char SQUChar;
 #define scstrftime strftime
 #define scremove remove
 #define screname rename
+
 #define sq_rsl(l) (l)
 #define sq_str_sizeof(p) (sizeof(p))
 

+ 17 - 0
SquiLu/include/squirrel.h

@@ -45,7 +45,14 @@ extern "C" {
 
 struct SQVM;
 struct SQTable;
+struct SQArrayBase;
 struct SQArray;
+struct SQFloat64Array;
+struct SQFloat32Array;
+struct SQInt64Array;
+struct SQInt32Array;
+struct SQInt16Array;
+struct SQInt8Array;
 struct SQString;
 struct SQClosure;
 struct SQGenerator;
@@ -132,7 +139,14 @@ typedef enum tagSQObjectType{
 typedef union tagSQObjectValue
 {
 	struct SQTable *pTable;
+	struct SQArrayBase *pArrayBase;
 	struct SQArray *pArray;
+	struct SQFloat64Array *pFloat64Array;
+	struct SQFloat32Array *pFloat32Array;
+	struct SQInt64Array *pInt64Array;
+	struct SQInt32Array *pInt32Array;
+	struct SQInt16Array *pInt16Array;
+	struct SQInt8Array *pInt8Array;
 	struct SQClosure *pClosure;
 	struct SQOuter *pOuter;
 	struct SQGenerator *pGenerator;
@@ -271,6 +285,7 @@ typedef struct {
 
 #define SQ_GET_STRING_NVD(v, idx, var)\
     if((_rc_ = sq_getstr_and_size(v,idx, &var, &var##_size)) < 0) return _rc_;
+
 #define SQ_GET_STRING(v, idx, var)\
     const SQChar *var;\
     SQInteger var##_size;\
@@ -335,7 +350,9 @@ typedef struct {
 #define SQ_OPT_FLOAT(v, idx, var, dflt)\
     SQFloat var;\
     SQ_OPT_FLOAT_NVD(v, idx, var, dflt)
+
 #define sq_pushliteral(v, str) sq_pushstring(v, str, sizeof(str)-1)
+
 #define SQ_GET_USERPOINTER_NVD(v, idx, var)\
     if((_rc_ = sq_getuserpointer(v,idx, &var)) < 0) return _rc_;
 

+ 23 - 12
SquiLu/squirrel/sqapi.cpp

@@ -175,6 +175,7 @@ SQBool sq_exists_define_name(HSQUIRRELVM v, const SQChar *define_name)
 {
 	return v->IsDefined(define_name);
 }
+
 SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename
                     ,SQBool raiseerror, SQBool show_warnings, SQInteger max_nested_includes)
 {
@@ -418,8 +419,10 @@ SQBool sq_instanceof(HSQUIRRELVM v)
 SQRESULT sq_arrayappend(HSQUIRRELVM v,SQInteger idx)
 {
     CHECK_ARRAY_AT(2, arr);
-	_array(arr)->Append(v->GetUp(-1));
+    bool rc = _array(arr)->Append(v->GetUp(-1));
 	v->Pop();
+	if(!rc)
+        return sq_throwerror(v, _SC("appending error"));
 	return SQ_OK;
 }
 
@@ -427,14 +430,19 @@ SQRESULT sq_arraypop(HSQUIRRELVM v,SQInteger idx,SQBool pushval)
 {
     CHECK_ARRAY_AT(1, arr);
 	if(_array(arr)->Size() > 0) {
-        if(pushval != 0){ v->Push(_array(arr)->Top()); }
+        if(pushval != 0){
+            v->PushNull();
+            SQObjectPtr &o = stack_get(v, -1);
+            _array(arr)->Top(o);
+            //v->Push(_array(arr)->Top());
+        }
 		_array(arr)->Pop();
 		return SQ_OK;
 	}
 	return sq_throwerror(v, _SC("empty array"));
 }
 
-static inline SQRESULT sq_arrayresize_base(HSQUIRRELVM v,SQArray *arr,SQInteger newsize)
+static inline SQRESULT sq_arrayresize_base(HSQUIRRELVM v,SQArrayBase *arr,SQInteger newsize)
 {
 	if(newsize >= 0) {
 		arr->Resize(newsize);
@@ -443,13 +451,13 @@ static inline SQRESULT sq_arrayresize_base(HSQUIRRELVM v,SQArray *arr,SQInteger
 	return sq_throwerror(v,_SC("negative size"));
 }
 
-SQRESULT sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize)
+SQRESULT sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger newsize)
 {
     CHECK_ARRAY_AT(1, arr);
     return sq_arrayresize_base(v, _array(arr), newsize);
 }
 
-SQRESULT sq_arrayminsize(HSQUIRRELVM v,SQInteger idx,SQInteger minsize)
+SQRESULT sq_arrayminsize(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger minsize)
 {
     CHECK_ARRAY_AT(1, arr);
 	if(_array(arr)->Size() < minsize) {
@@ -461,16 +469,12 @@ SQRESULT sq_arrayminsize(HSQUIRRELVM v,SQInteger idx,SQInteger minsize)
 SQRESULT sq_arrayreverse(HSQUIRRELVM v,SQInteger idx)
 {
     CHECK_ARRAY_AT(1, o);
-	SQArray *arr = _array(o);
+	SQArrayBase *arr = _array(o);
 	if(arr->Size() > 0) {
 		SQObjectPtr t;
 		SQInteger size = arr->Size();
 		SQInteger n = size >> 1; size -= 1;
-		for(SQInteger i = 0; i < n; i++) {
-			t = arr->_values[i];
-			arr->_values[i] = arr->_values[size-i];
-			arr->_values[size-i] = t;
-		}
+		for(SQInteger i = 0; i < n; i++) arr->_swap(i, size-i);
 		return SQ_OK;
 	}
 	return SQ_OK;
@@ -510,6 +514,13 @@ SQRESULT sq_arrayget(HSQUIRRELVM v,SQInteger idx,SQInteger pos)
 	return SQ_OK;
 }
 
+SQRESULT sq_arraygetsizeof(HSQUIRRELVM v,SQInteger idx)
+{
+    CHECK_ARRAY_AT(idx, arr);
+    sq_pushinteger(v, _array(arr)->SizeOf());
+	return SQ_OK;
+}
+
 void sq_newclosure(HSQUIRRELVM v,SQFUNCTION func,SQUnsignedInteger nfreevars)
 {
 	SQNativeClosure *nc = SQNativeClosure::Create(_ss(v), func,nfreevars);
@@ -534,7 +545,7 @@ SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQInteger *nparams,SQInte
 	else if(sq_type(o) == OT_NATIVECLOSURE)
 	{
 		SQNativeClosure *c = _nativeclosure(o);
-		*nparams = (SQUnsignedInteger)c->_nparamscheck;
+		*nparams = (SQInteger)c->_nparamscheck;
 		*nfreevars = c->_noutervalues;
 		return SQ_OK;
 	}

+ 348 - 54
SquiLu/squirrel/sqarray.h

@@ -2,105 +2,399 @@
 #ifndef _SQARRAY_H_
 #define _SQARRAY_H_
 
-struct SQArray : public CHAINABLE_OBJ
+struct SQArrayBase : public CHAINABLE_OBJ
 {
-private:
-	SQArray(SQSharedState *ss,SQInteger nsize){_values.resize(nsize); INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}
-	~SQArray()
+protected:
+	SQArrayBase(SQSharedState *ss,SQInteger nsize){
+	    INIT_CHAIN();
+	    ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);
+    }
+	~SQArrayBase()
 	{
 		REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
 	}
 public:
-	static SQArray* Create(SQSharedState *ss,SQInteger nInitialSize){
-		SQArray *newarray=(SQArray*)SQ_MALLOC(sizeof(SQArray));
-		new (newarray) SQArray(ss,nInitialSize);
-		return newarray;
-	}
+
 #ifndef NO_GARBAGE_COLLECTOR
+    ABSTRACT_METHOD(virtual bool isCollectable(), {return true;})
 	void Mark(SQCollectable **chain);
 	SQObjectType GetType() {return OT_ARRAY;}
 #endif
-	void Finalize(){
-		_values.resize(0);
-	}
+	void Finalize(){Resize(0);}
 	bool Get(const SQInteger nidx,SQObjectPtr &val)
 	{
-		if(nidx>=0 && nidx<(SQInteger)_values.size()){
-			SQObjectPtr &o = _values[nidx];
-			val = _realval(o);
+		if(((SQUnsignedInteger)nidx)<Size()){
+			_getRealObjectPtr(nidx, val);
 			return true;
 		}
-		else return false;
+		return false;
 	}
 	SQObjectPtr operator[](SQInteger nidx) {
-        SQObjectPtr val;
-        Get(nidx, val);
-        return val;
-    }
+		SQObjectPtr val;
+		Get(nidx, val);
+		return val;
+	}
 	bool Exists(const SQInteger nidx)
 	{
-		return (nidx>=0 && nidx<(SQInteger)_values.size());
+		return (((SQUnsignedInteger)nidx)<Size());
 	}
 	bool Set(const SQInteger nidx,const SQObjectPtr &val)
 	{
-		if(nidx>=0 && nidx<(SQInteger)_values.size()){
-			_values[nidx]=val;
-			return true;
-		}
-		else return false;
+		return (((SQUnsignedInteger)nidx)<Size())
+			&& _setObjectPtr(nidx, val);
 	}
 	SQInteger Next(const SQObjectPtr &refpos,SQObjectPtr &outkey,SQObjectPtr &outval)
 	{
 		SQUnsignedInteger idx=SQTranslateIndex(refpos);
-		while(idx<_values.size()){
+		while(idx<Size()){
 			//first found
 			outkey=(SQInteger)idx;
-			SQObjectPtr &o = _values[idx];
-			outval = _realval(o);
+			_getRealObjectPtr(idx, outval);
 			//return idx for the next iteration
 			return ++idx;
 		}
 		//nothing to iterate anymore
 		return -1;
 	}
-	SQArray *Clone(){SQArray *anew=Create(_opt_ss(this),0); anew->_values.copy(_values); return anew; }
-	SQInteger Size() const {return _values.size();}
-	void Resize(SQInteger size)
+	ABSTRACT_METHOD(virtual SQArrayBase *Clone(bool withData=true), { return NULL;})
+	ABSTRACT_METHOD(virtual SQUnsignedInteger SizeOf() const, { return 0;})
+	ABSTRACT_METHOD(virtual SQUnsignedInteger Size() const, { return 0;})
+	bool Resize(SQUnsignedInteger size)
 	{
 		SQObjectPtr _null;
-		Resize(size,_null);
-	}
-	void Minsize(SQInteger size) { if(Size() <= size) Resize(size);}
-	void Resize(SQInteger size,SQObjectPtr &fill) { _values.resize(size,fill); ShrinkIfNeeded(); }
-	void Minsize(SQInteger size,SQObjectPtr &fill) { if(Size() <= size) _values.resize(size,fill);}
-	void Reserve(SQInteger size) { _values.reserve(size); }
-	SQUnsignedInteger Capacity() { return _values.capacity(); }
-	void Append(const SQObject &o){_values.push_back(o);}
-	void Extend(const SQArray *a);
-	SQObjectPtr &Top(){return _values.top();}
-	void Pop(){_values.pop_back(); ShrinkIfNeeded(); }
+		return Resize(size,_null);
+	}
+	bool Resize(SQUnsignedInteger size,SQObjectPtr &fill) {
+	    bool rc = _resizeValues(size,fill);
+	    if(rc) ShrinkIfNeeded();
+	    return rc;
+    }
+	bool Minsize(SQUnsignedInteger size) { return (Size() < size) ? Resize(size) : true;}
+	bool Minsize(SQUnsignedInteger size,SQObjectPtr &fill) {
+	    return (Size() < size) ? _resizeValues(size,fill) : true;
+    }
+	ABSTRACT_METHOD(virtual void Reserve(SQUnsignedInteger size), {})
+	ABSTRACT_METHOD(virtual SQUnsignedInteger Capacity(), {return 0;})
+	ABSTRACT_METHOD(virtual bool Append(const SQObject &o), {return false;})
+	void Extend(SQArrayBase *a);
+	ABSTRACT_METHOD(virtual void Top(SQObjectPtr &out), {})
+	ABSTRACT_METHOD(virtual void Pop(), {})
 	bool Insert(SQInteger idx,const SQObject &val){
-		if(idx < 0 || idx > (SQInteger)_values.size())
-			return false;
-		_values.insert(idx,val);
-		return true;
+		return _insertValue((SQUnsignedInteger)idx,val);
 	}
 	void ShrinkIfNeeded() {
-		if(_values.size() <= _values.capacity()>>2) //shrink the array
-			_values.shrinktofit();
+		if(Size() <= Capacity()>>2) //shrink the array
+			_shrinktofit();
 	}
 	bool Remove(SQInteger idx){
-		if(idx < 0 || idx >= (SQInteger)_values.size())
-			return false;
-		_values.remove(idx);
+	    if(!_removeValue(idx)) return false;
 		ShrinkIfNeeded();
 		return true;
 	}
 	void Release()
 	{
-		sq_delete(this,SQArray);
+		sq_assert(NULL);
 	}
+	ABSTRACT_METHOD(virtual void _swap(SQInteger idx1, SQInteger idx2),{})
+	ABSTRACT_METHOD(virtual void _copy(SQInteger idx1, SQInteger idx2),{})
+	ABSTRACT_METHOD(virtual bool _set(SQInteger idx1, SQObjectPtr &val),{return false;})
+	ABSTRACT_METHOD(virtual void _get2(SQInteger idx, SQObject& out),{})
 
-	SQObjectPtrVec _values;
+private:
+    ABSTRACT_METHOD(virtual void _getObjectPtr(const SQInteger nidx,SQObjectPtr &val),{})
+    ABSTRACT_METHOD(virtual void _getRealObjectPtr(const SQInteger nidx,SQObjectPtr &val),{})
+    ABSTRACT_METHOD(virtual bool _setObjectPtr(const SQInteger nidx, const SQObjectPtr &val),{return false;})
+    ABSTRACT_METHOD(virtual bool _resizeValues(SQInteger size,SQObjectPtr &fill),{return false;})
+    ABSTRACT_METHOD(virtual bool _insertValue(SQInteger idx,const SQObject &val),{return false;})
+    ABSTRACT_METHOD(virtual bool _removeValue(SQInteger idx),{return false;})
+    ABSTRACT_METHOD(virtual void _shrinktofit(),{})
 };
+
+#define DECLARE_CLASS_ARRAY_MEMBERS(atype)\
+	static atype* Create(SQSharedState *ss,SQInteger nInitialSize){\
+		atype *newarray=(atype*)SQ_MALLOC(sizeof(atype));\
+		new (newarray) atype(ss,nInitialSize);\
+		return newarray;\
+	}\
+	atype *Clone(bool withData=true){\
+	    atype *anew=Create(_opt_ss(this),0);\
+	    if(withData) anew->_vec_values.copy(_vec_values);\
+	    return anew;\
+    }\
+	void Release(){sq_delete(this,atype);}
+
+struct SQArray : public SQArrayBase
+{
+protected:
+    SQObjectPtrVec _vec_values;
+    SQArray(SQSharedState *ss,SQInteger nsize):SQArrayBase(ss, nsize){
+	    Resize(nsize);
+    }
+    ~SQArray(){}
+
+public:
+#ifndef NO_GARBAGE_COLLECTOR
+    virtual bool isCollectable(){return true;}
+#endif
+	DECLARE_CLASS_ARRAY_MEMBERS(SQArray);
+	SQUnsignedInteger SizeOf() const {return _vec_values.sizeOf();}
+	SQUnsignedInteger Size() const {return _vec_values.size();}
+	void Reserve(SQUnsignedInteger size) { _vec_values.reserve(size); }
+	SQUnsignedInteger Capacity() { return _vec_values.capacity(); }
+	bool Append(const SQObject &o){_vec_values.push_back(o); return true;}
+	void Top(SQObjectPtr &out){out = _vec_values.top();}
+	void Pop(){_vec_values.pop_back(); ShrinkIfNeeded(); }
+	void _swap(SQInteger idx1, SQInteger idx2)
+	{
+	    SQObjectPtr t = _vec_values[idx1];
+        _vec_values[idx1] = _vec_values[idx2];
+        _vec_values[idx2] = t;
+	}
+	void _copy(SQInteger idx1, SQInteger idx2)
+	{
+        _vec_values[idx1] = _vec_values[idx2];
+	}
+	bool _set(SQInteger idx1, SQObjectPtr &val)
+	{
+        _vec_values[idx1] = val;
+        return true;
+	}
+	void _get2(SQInteger idx, SQObject& out)
+	{
+        out = _vec_values[idx];
+	}
+private:
+
+    virtual void _getObjectPtr(const SQInteger nidx,SQObjectPtr &val){
+        val = _vec_values[nidx];
+    }
+    virtual void _getRealObjectPtr(const SQInteger nidx,SQObjectPtr &val){
+        SQObjectPtr &o = _vec_values[nidx];
+        val = _realval(o);
+    }
+    virtual bool _setObjectPtr(const SQInteger nidx, const SQObjectPtr &val){
+        _vec_values[nidx] = val;
+        return true;
+    }
+    virtual bool _resizeValues(SQInteger size,SQObjectPtr &fill){
+        _vec_values.resize(size,fill);
+        return true;
+    }
+    virtual bool _insertValue(SQInteger idx,const SQObject &val){
+		_vec_values.insert(idx,val);
+		return true;
+    }
+    virtual bool _removeValue(SQInteger idx){
+        return _vec_values.remove(idx);
+    }
+    virtual void _shrinktofit(){
+        _vec_values.shrinktofit();
+    }
+};
+
+template <typename T>
+struct SQNumericBaseArray : public SQArrayBase
+{
+protected:
+    sqvector<T> _vec_values;
+    SQNumericBaseArray(SQSharedState *ss,SQInteger nsize):SQArrayBase(ss, nsize){
+	    Resize(nsize);
+    }
+
+    virtual bool isNumeric(const SQObject &o, T &tv)
+    {
+	    return false;
+    }
+public:
+#ifndef NO_GARBAGE_COLLECTOR
+    virtual bool isCollectable(){return false;}
+#endif
+	SQUnsignedInteger SizeOf() const {return _vec_values.sizeOf();}
+	SQUnsignedInteger Size() const {return _vec_values.size();}
+	void Reserve(SQUnsignedInteger size) { _vec_values.reserve(size); }
+	SQUnsignedInteger Capacity() { return _vec_values.capacity(); }
+	bool Append(const SQObject &o){
+	    T tv;
+	    if(!isNumeric(o, tv)) return false;
+	    _vec_values.push_back(tv);
+	    return true;
+	}
+	//void Top(SQObjectPtr& out){out = _vec_values.top();}
+	void Pop(){_vec_values.pop_back(); ShrinkIfNeeded(); }
+	void _swap(SQInteger idx1, SQInteger idx2)
+	{
+	    T tmp = _vec_values[idx1];
+        _vec_values[idx1] = _vec_values[idx2];
+        _vec_values[idx2] = tmp;
+	}
+	void _copy(SQInteger idx1, SQInteger idx2)
+	{
+        _vec_values[idx1] = _vec_values[idx2];
+	}
+	bool _set(SQInteger idx1, SQObjectPtr &val)
+	{
+        T tv;
+	    if(!isNumeric(val, tv)) return false;
+        _vec_values[idx1] = tv;
+        return true;
+	}
+private:
+
+    virtual bool _setObjectPtr(const SQInteger nidx, const SQObjectPtr &val){
+	    T tv;
+	    if(!isNumeric(val, tv)) return false;
+        _vec_values[nidx] = tv;
+        return true;
+    }
+    virtual bool _resizeValues(SQInteger size,SQObjectPtr &fill){
+	    T tv;
+	    switch(sq_type(fill))
+	    {
+	        case OT_NULL: tv = 0;break;
+	        case OT_FLOAT: tv = _float(fill);break;
+	        case OT_INTEGER: tv = _integer(fill);break;
+	        default:
+                return false;
+	    }
+        _vec_values.resize(size,tv);
+        return true;
+    }
+    virtual bool _insertValue(SQInteger idx,const SQObject &val){
+	    T tv;
+	    if(!isNumeric(val, tv)) return false;
+		_vec_values.insert(idx,tv);
+        return true;
+    }
+    virtual bool _removeValue(SQInteger idx){
+        return _vec_values.remove(idx);
+    }
+    virtual void _shrinktofit(){
+        _vec_values.shrinktofit();
+    }
+};
+
+template <typename T>
+struct SQFloatBaseArray : public SQNumericBaseArray<T>
+{
+protected:
+    SQFloatBaseArray(SQSharedState *ss,SQInteger nsize):
+        SQNumericBaseArray<T>(ss, nsize){
+    }
+
+    bool isNumeric(const SQObject &o, T &tv)
+    {
+	    switch(sq_type(o))
+	    {
+	        case OT_FLOAT: tv = _float(o);break;
+	        case OT_INTEGER: tv = _integer(o);break;
+	        default:
+                return false;
+	    }
+	    return true;
+    }
+public:
+    void Top(SQObjectPtr& out){out = SQNumericBaseArray<T>::_vec_values.top();}
+    virtual void _getObjectPtr(const SQInteger nidx,SQObjectPtr &val){
+        val = SQNumericBaseArray<T>::_vec_values[nidx];
+    }
+    virtual void _getRealObjectPtr(const SQInteger nidx,SQObjectPtr &val){
+        SQObjectPtr o = SQNumericBaseArray<T>::_vec_values[nidx];
+        val = _realval(o);
+    }
+	void _get2(SQInteger idx, SQObject& val)
+	{
+	    val._type = OT_FLOAT;
+        _float(val) = SQNumericBaseArray<T>::_vec_values[idx];
+	}
+};
+
+struct SQFloat64Array : public SQFloatBaseArray<SQFloat64>
+{
+protected:
+    SQFloat64Array(SQSharedState *ss,SQInteger nsize):SQFloatBaseArray(ss, nsize){}
+
+public:
+    DECLARE_CLASS_ARRAY_MEMBERS(SQFloat64Array);
+};
+
+struct SQFloat32Array : public SQFloatBaseArray<SQFloat32>
+{
+protected:
+    SQFloat32Array(SQSharedState *ss,SQInteger nsize):SQFloatBaseArray(ss, nsize){}
+
+public:
+    DECLARE_CLASS_ARRAY_MEMBERS(SQFloat32Array);
+};
+
+template <typename T>
+struct SQIntegerBaseArray : public SQNumericBaseArray<T>
+{
+protected:
+    SQIntegerBaseArray(SQSharedState *ss,SQInteger nsize):
+        SQNumericBaseArray<T>(ss, nsize){
+    }
+
+    bool isNumeric(const SQObject &o, T &tv)
+    {
+	    switch(sq_type(o))
+	    {
+	        //case OT_FLOAT: tv = _float(o);break;
+	        case OT_INTEGER: tv = _integer(o);break;
+	        default:
+                return false;
+	    }
+	    return true;
+    }
+public:
+    virtual void _getObjectPtr(const SQInteger nidx,SQObjectPtr &val){
+        val = (SQInteger)SQNumericBaseArray<T>::_vec_values[nidx];
+    }
+	void Top(SQObjectPtr& out){out = (SQInteger)SQNumericBaseArray<T>::_vec_values.top();}
+    virtual void _getRealObjectPtr(const SQInteger nidx,SQObjectPtr &val){
+        SQObjectPtr o = (SQInteger)SQNumericBaseArray<T>::_vec_values[nidx];
+        val = _realval(o);
+    }
+	void _get2(SQInteger idx, SQObject& val)
+	{
+	    val._type = OT_INTEGER;
+        _integer(val) = SQNumericBaseArray<T>::_vec_values[idx];
+	}
+};
+
+struct SQInt64Array : public SQIntegerBaseArray<SQInt64>
+{
+protected:
+    SQInt64Array(SQSharedState *ss,SQInteger nsize):SQIntegerBaseArray(ss, nsize){}
+
+public:
+    DECLARE_CLASS_ARRAY_MEMBERS(SQInt64Array);
+};
+
+struct SQInt32Array : public SQIntegerBaseArray<SQInt32>
+{
+protected:
+    SQInt32Array(SQSharedState *ss,SQInteger nsize):SQIntegerBaseArray(ss, nsize){}
+
+public:
+    DECLARE_CLASS_ARRAY_MEMBERS(SQInt32Array);
+};
+
+struct SQInt16Array : public SQIntegerBaseArray<SQInt16>
+{
+protected:
+    SQInt16Array(SQSharedState *ss,SQInteger nsize):SQIntegerBaseArray(ss, nsize){}
+
+public:
+    DECLARE_CLASS_ARRAY_MEMBERS(SQInt16Array);
+};
+
+struct SQInt8Array : public SQIntegerBaseArray<SQInt8>
+{
+protected:
+    SQInt8Array(SQSharedState *ss,SQInteger nsize):SQIntegerBaseArray(ss, nsize){}
+
+public:
+    DECLARE_CLASS_ARRAY_MEMBERS(SQInt8Array);
+};
+
 #endif //_SQARRAY_H_

+ 125 - 54
SquiLu/squirrel/sqbaselib.cpp

@@ -353,21 +353,57 @@ static SQRESULT base_suspend(HSQUIRRELVM v)
 	return sq_suspendvm(v);
 }
 
-static SQRESULT base_array(HSQUIRRELVM v)
+template <typename T>
+static SQRESULT base_array_base(HSQUIRRELVM v)
 {
-	SQArray *a;
+	T *a;
 	SQObject &size = stack_get(v,2);
 	if(sq_gettop(v) > 2) {
-		a = SQArray::Create(_ss(v),0);
+        a = T::Create(_ss(v),0);
 		a->Resize(tointeger(size),stack_get(v,3));
 	}
 	else {
-		a = SQArray::Create(_ss(v),tointeger(size));
+        a = T::Create(_ss(v),tointeger(size));
 	}
 	v->Push(a);
 	return 1;
 }
 
+static SQRESULT base_array(HSQUIRRELVM v)
+{
+    return base_array_base<SQArray>(v);
+}
+
+static SQRESULT base_array_float64(HSQUIRRELVM v)
+{
+    return base_array_base<SQFloat64Array>(v);
+}
+
+static SQRESULT base_array_float32(HSQUIRRELVM v)
+{
+    return base_array_base<SQFloat32Array>(v);
+}
+
+static SQRESULT base_array_int64(HSQUIRRELVM v)
+{
+    return base_array_base<SQInt64Array>(v);
+}
+
+static SQRESULT base_array_int32(HSQUIRRELVM v)
+{
+    return base_array_base<SQInt32Array>(v);
+}
+
+static SQRESULT base_array_int16(HSQUIRRELVM v)
+{
+    return base_array_base<SQInt16Array>(v);
+}
+
+static SQRESULT base_array_int8(HSQUIRRELVM v)
+{
+    return base_array_base<SQInt8Array>(v);
+}
+
 static SQRESULT base_type(HSQUIRRELVM v)
 {
 	SQObjectPtr &o = stack_get(v,2);
@@ -566,7 +602,13 @@ static SQRegFunction base_funcs[]={
 	{_SC("compilestring"),base_compilestring,-2, _SC(".ssb")},
 	{_SC("newthread"),base_newthread,2, _SC(".c")},
 	{_SC("suspend"),base_suspend,-1, NULL},
-	{_SC("array"),base_array,-2, _SC(".n")},
+	{_SC("array"),base_array,-2, _SC(".n.")},
+	{_SC("array_float64"),base_array_float64,-2, _SC(".nf")},
+	{_SC("array_float32"),base_array_float32,-2, _SC(".nf")},
+	{_SC("array_int64"),base_array_int64,-2, _SC(".ni")},
+	{_SC("array_int32"),base_array_int32,-2, _SC(".ni")},
+	{_SC("array_int16"),base_array_int16,-2, _SC(".ni")},
+	{_SC("array_int8"),base_array_int8,-2, _SC(".ni")},
 	{_SC("type"),base_type,2, NULL},
 	{_SC("callee"),base_callee,0,NULL},
 	{_SC("dummy"),base_dummy,0,NULL},
@@ -838,7 +880,10 @@ static SQRESULT array_top(HSQUIRRELVM v)
 {
 	SQObject &o=stack_get(v,1);
 	if(_array(o)->Size()>0){
-		v->Push(_array(o)->Top());
+        v->PushNull();
+        SQObjectPtr &ot = stack_get(v, -1);
+        _array(o)->Top(ot);
+		//v->Push(_array(o)->Top());
 		return 1;
 	}
 	else return sq_throwerror(v,_SC("top() on a empty array"));
@@ -884,28 +929,32 @@ static inline SQRESULT array_resize_base(HSQUIRRELVM v, e_array_op_type opType)
 {
 	SQObject &o = stack_get(v, 1);
 	if(opType == e_capacity)
-    {
-        sq_pushinteger(v, _array(o)->Capacity());
-        return 1;
-    }
+	{
+		sq_pushinteger(v, _array(o)->Capacity());
+		return 1;
+	}
 	SQObject &nsize = stack_get(v, 2);
 	SQObjectPtr fill;
 	if(sq_isnumeric(nsize)) {
-        switch(opType)
-        {
-        case e_reserve:
-            _array(o)->Reserve(tointeger(nsize));
-            break;
-        case e_minsize:
-            if(_array(o)->Size() >= tointeger(nsize)) break;
-            //falthrough
-        default:
-            if(sq_gettop(v) > 2)
-                fill = stack_get(v, 3);
-            _array(o)->Resize(tointeger(nsize),fill);
-            sq_settop(v, 1);
-            return 1;
-        }
+		SQInteger sz = tointeger(nsize);
+		if (sz<0)
+		  return sq_throwerror(v, _SC("resizing to negative length"));
+		SQUnsignedInteger usize = sz;
+		switch(opType)
+		{
+		case e_reserve:
+		    _array(o)->Reserve(usize);
+		    break;
+		case e_minsize:
+		    if(_array(o)->Size() >= usize) break;
+		    //falthrough
+		default:
+		    if(sq_gettop(v) > 2)
+			fill = stack_get(v, 3);
+		    _array(o)->Resize(usize,fill);
+		    sq_settop(v, 1);
+		    return 1;
+		}
 		return SQ_OK;
 	}
 	return sq_throwerror(v, _SC("size must be a number"));
@@ -931,7 +980,7 @@ static SQRESULT array_capacity(HSQUIRRELVM v)
     return array_resize_base(v, e_capacity);
 }
 
-static SQRESULT __map_array(SQArray *dest,SQArray *src,HSQUIRRELVM v) {
+static SQRESULT __map_array(SQArrayBase *dest,SQArrayBase *src,HSQUIRRELVM v) {
 	SQObjectPtr temp;
 	SQInteger size = src->Size();
 	for(SQInteger n = 0; n < size; n++) {
@@ -950,8 +999,7 @@ static SQRESULT __map_array(SQArray *dest,SQArray *src,HSQUIRRELVM v) {
 static SQRESULT array_map(HSQUIRRELVM v)
 {
 	SQObject &o = stack_get(v,1);
-	SQInteger size = _array(o)->Size();
-	SQObjectPtr ret = SQArray::Create(_ss(v),size);
+	SQObjectPtr ret = _array(o)->Clone();
 	if(SQ_FAILED(__map_array(_array(ret),_array(o),v)))
 		return SQ_ERROR;
 	v->Push(ret);
@@ -970,7 +1018,7 @@ static SQRESULT array_apply(HSQUIRRELVM v)
 static SQRESULT array_reduce(HSQUIRRELVM v)
 {
 	SQObject &o = stack_get(v,1);
-	SQArray *a = _array(o);
+	SQArrayBase *a = _array(o);
 	SQInteger size = a->Size();
 	if(size == 0) {
 		return 0;
@@ -998,8 +1046,8 @@ static SQRESULT array_reduce(HSQUIRRELVM v)
 static SQRESULT array_filter(HSQUIRRELVM v)
 {
 	SQObject &o = stack_get(v,1);
-	SQArray *a = _array(o);
-	SQObjectPtr ret = SQArray::Create(_ss(v),0);
+	SQArrayBase *a = _array(o);
+	SQObjectPtr ret = a->Clone(false);
 	SQInteger size = a->Size();
 	SQObjectPtr val;
 	for(SQInteger n = 0; n < size; n++) {
@@ -1023,7 +1071,7 @@ static SQRESULT array_find(HSQUIRRELVM v)
 {
 	SQObject &o = stack_get(v,1);
 	SQObjectPtr &val = stack_get(v,2);
-	SQArray *a = _array(o);
+	SQArrayBase *a = _array(o);
 	SQInteger size = a->Size();
 	SQObjectPtr temp;
 	for(SQInteger n = 0; n < size; n++) {
@@ -1041,7 +1089,7 @@ static SQRESULT array_bsearch(HSQUIRRELVM v)
 {
 	SQObject &o = stack_get(v,1);
 	SQObjectPtr &val = stack_get(v,2);
-	SQArray *a = _array(o);
+	SQArrayBase *a = _array(o);
 	SQObjectPtr temp;
 	SQInteger imid = 0, imin = 0, imax = a->Size()-1;
 	while(imax >= imin) {
@@ -1072,7 +1120,7 @@ static SQRESULT array_bsearch(HSQUIRRELVM v)
 }
 
 
-static bool _sort_compare(HSQUIRRELVM v,SQObjectPtr &a,SQObjectPtr &b,SQInteger func,SQInteger &ret)
+static bool _sort_compare(HSQUIRRELVM v,const SQObjectPtr &a,const SQObjectPtr &b,SQInteger func,SQInteger &ret)
 {
 	if(func < 0) {
 		if(!v->ObjCmp(a,b,ret)) return false;
@@ -1107,36 +1155,44 @@ static bool _sort_compare(HSQUIRRELVM v,SQObjectPtr &a,SQObjectPtr &b,SQInteger
 ** =======================================================
 */
 
-static bool lua_auxsort (HSQUIRRELVM v, SQArray *arr, SQInteger l, SQInteger u,
+static bool lua_auxsort (HSQUIRRELVM v, SQArrayBase *arr, SQInteger l, SQInteger u,
                                    SQInteger func) {
   while (l < u) {  /* for tail recursion */
     SQInteger i, j, ret;
     bool rc;
+    SQObject o1, o2;
     /* sort elements a[l], a[(l+u)/2] and a[u] */
-    if(!_sort_compare(v,arr->_values[u],arr->_values[l],func,ret))
+    arr->_get2(u, o1);
+    arr->_get2(l, o2);
+    if(!_sort_compare(v,o1,o2,func,ret))
         return false;
     if (ret < 0)  /* a[u] < a[l]? */
-      _Swap(arr->_values[l],arr->_values[u]);  /* swap a[l] - a[u] */
+      arr->_swap(l, u);  /* swap a[l] - a[u] */
     if (u-l == 1) break;  /* only 2 elements */
     i = (l+u)/2;
-    if(!_sort_compare(v,arr->_values[i],arr->_values[l],func,ret))
+    arr->_get2(i, o1);
+    arr->_get2(l, o2);
+    if(!_sort_compare(v,o1,o2,func,ret))
         return false;
     if (ret < 0)  /* a[i]<a[l]? */
-      _Swap(arr->_values[i],arr->_values[l]);
+      arr->_swap(i, l);
     else {
-      if(!_sort_compare(v,arr->_values[u],arr->_values[i],func,ret))
+      arr->_get2(u, o1);
+      arr->_get2(i, o2);
+      if(!_sort_compare(v,o1,o2,func,ret))
         return false;
       if (ret < 0)  /* a[u]<a[i]? */
-        _Swap(arr->_values[i],arr->_values[u]);
+        arr->_swap(i, u);
     }
     if (u-l == 2) break;  /* only 3 elements */
-    SQObjectPtr P = arr->_values[i];  /* Pivot */
-    _Swap(arr->_values[i],arr->_values[u-1]);
+    SQObject P;
+    arr->_get2(i, P);  /* Pivot */
+    arr->_swap(i, u-1);
     /* a[l] <= P == a[u-1] <= a[u], only need to sort from l+1 to u-2 */
     i = l; j = u-1;
     for (;;) {  /* invariant: a[l..i] <= P <= a[j..u] */
       /* repeat ++i until a[i] >= P */
-      while ((rc = _sort_compare(v,arr->_values[++i],P,func,ret)) && (ret < 0)) {
+      while (arr->_get2(++i, o1), (rc = _sort_compare(v,o1,P,func,ret)) && (ret < 0)) {
         if (i>u)
         {
             sq_throwerror(v, _SC("invalid order function for sorting"));
@@ -1145,7 +1201,7 @@ static bool lua_auxsort (HSQUIRRELVM v, SQArray *arr, SQInteger l, SQInteger u,
       }
       if(!rc) return false;
       /* repeat --j until a[j] <= P */
-      while ((rc = _sort_compare(v,P, arr->_values[--j],func,ret)) && (ret < 0)) {
+      while (arr->_get2(--j, o2), (rc = _sort_compare(v,P, o2,func,ret)) && (ret < 0)) {
         if (j<l)
         {
             sq_throwerror(v, _SC("invalid order function for sorting"));
@@ -1156,9 +1212,9 @@ static bool lua_auxsort (HSQUIRRELVM v, SQArray *arr, SQInteger l, SQInteger u,
       if (j<i) {
         break;
       }
-      _Swap(arr->_values[i],arr->_values[j]);
+      arr->_swap(i, j);
     }
-    _Swap(arr->_values[u-1],arr->_values[i]);  /* swap pivot (a[u-1]) with a[i] */
+    arr->_swap(u-1, i);  /* swap pivot (a[u-1]) with a[i] */
     /* a[l..i-1] <= a[i] == P <= a[i+1..u] */
     /* adjust so that smaller half is in [j..i] and larger one in [l..u] */
     if (i-l < u-i) {
@@ -1176,7 +1232,7 @@ static bool lua_auxsort (HSQUIRRELVM v, SQArray *arr, SQInteger l, SQInteger u,
 static SQRESULT array_sort(HSQUIRRELVM v) {
 	SQInteger func = -1;
 	SQObjectPtr &o = stack_get(v,1);
-	SQArray *arr = _array(o);
+	SQArrayBase *arr = _array(o);
 	if(arr->Size() > 1) {
 		if(sq_gettop(v) == 2) func = 2;
 		if(!lua_auxsort(v, arr, 0, arr->Size()-1, func))
@@ -1199,7 +1255,8 @@ static SQRESULT array_slice(HSQUIRRELVM v)
 	if(eidx < 0)eidx = alen + eidx;
 	if(eidx < sidx)return sq_throwerror(v,_SC("wrong indexes"));
 	if(eidx > alen || sidx < 0)return sq_throwerror(v, _SC("slice out of range"));
-	SQArray *arr=SQArray::Create(_ss(v),eidx-sidx);
+	SQArrayBase *arr=_array(o)->Clone(false);
+	arr->Resize(eidx-sidx);
 	SQObjectPtr t;
 	SQInteger count=0;
 	for(SQInteger i=sidx;i<eidx;i++){
@@ -1220,8 +1277,9 @@ static SQRESULT array_slice(HSQUIRRELVM v)
 static SQRESULT array_concat0 (HSQUIRRELVM v, int allowAll) {
     SQ_FUNC_VARS(v);
     SQObjectPtr &arobj = stack_get(v,1);
-    SQObjectPtrVec &aryvec = _array(arobj)->_values;
-    SQInteger last = aryvec.size()-1;
+    SQArrayBase *arr = _array(arobj);
+
+    SQInteger last = arr->Size()-1;
     if(last == -1){
         sq_pushstring(v, _SC(""), 0);
         return 1;
@@ -1241,7 +1299,9 @@ static SQRESULT array_concat0 (HSQUIRRELVM v, int allowAll) {
   SQBlob blob(0, 8192);
 
   for (int i=opt_first; i <= opt_last; ++i) {
-      SQObjectPtr str, &o = aryvec[i];
+      SQObject o;
+      SQObjectPtr str;
+      arr->_get2(i, o);
       switch(sq_type(o)){
           case OT_STRING:
               break;
@@ -1297,6 +1357,12 @@ static SQRESULT array_empty(HSQUIRRELVM v)
 	return 1;
 }
 
+static SQRESULT array_sizeofelm(HSQUIRRELVM v)
+{
+	sq_arraygetsizeof(v,1);
+	return 1;
+}
+
 //DAD end
 
 SQRegFunction SQSharedState::_array_default_delegate_funcz[]={
@@ -1334,6 +1400,7 @@ SQRegFunction SQSharedState::_array_default_delegate_funcz[]={
 	{_SC("get"),container_rawget, -2, _SC("ai.")},
 	{_SC("set"),array_set, 3, _SC("ai.")},
 	{_SC("isempty"),array_empty, 1, _SC("a")},
+	{_SC("sizeofelm"),array_sizeofelm, 1, _SC("a")},
 	{NULL,(SQFUNCTION)0,0,NULL}
 };
 
@@ -2519,11 +2586,15 @@ static SQRESULT closure_call(HSQUIRRELVM v)
 
 static SQRESULT _closure_acall(HSQUIRRELVM v,SQBool raiseerror, SQBool v2)
 {
-	SQArray *aparams=_array(stack_get(v, v2 ? 3 : 2));
+	SQArrayBase *aparams=_array(stack_get(v, v2 ? 3 : 2));
 	SQInteger nparams=aparams->Size();
 	v->Push(stack_get(v,1));
 	if(v2) v->Push(stack_get(v,2));
-	for(SQInteger i=0;i<nparams;i++)v->Push(aparams->_values[i]);
+	for(SQInteger i=0;i<nparams;i++){
+        v->PushNull();
+        SQObjectPtr &o = stack_get(v, -1);
+        aparams->_get2(i, o);
+	}
 	return SQ_SUCCEEDED(sq_call(v,nparams + (v2 ? 1 : 0),SQTrue,raiseerror))?1:SQ_ERROR;
 }
 

+ 21 - 8
SquiLu/squirrel/sqobject.cpp

@@ -224,11 +224,15 @@ bool SQGenerator::Resume(SQVM *v,SQObjectPtr &dest)
 	return true;
 }
 
-void SQArray::Extend(const SQArray *a){
+void SQArrayBase::Extend(SQArrayBase *a){
 	SQInteger xlen;
 	if((xlen=a->Size()))
 		for(SQInteger i=0;i<xlen;i++)
-			Append(a->_values[i]);
+        {
+            SQObject o;
+            a->_get2(i, o);
+			Append(o);
+        }
 }
 
 const SQChar* SQFunctionProto::GetLocal(SQVM *vm,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop)
@@ -620,6 +624,7 @@ const SQChar *SQGetVarTypeName(int it){
     }
 #undef SCASE
 }
+
 const SQChar *SQGetArithOpName(int it){
 #define SCASE(x, z) case x: return _SC(#z); break;
     switch(it){
@@ -759,7 +764,7 @@ bool SQFunctionProto::SaveAsSource(SQVM *v,SQUserPointer up,SQWRITEFUNC write)
                                  inst._arg0, inst._arg2, inst.op == _OP_PREPCALLK ? "literals" : "stk", inst._arg1, inst._arg3);
             break;
             case _OP_LOADFLOAT:
-                    SafeWriteFmt(v,write,up,"\t/* %f */", *((SQFloat*)&inst._arg1));
+                    SafeWriteFmt(v,write,up,"\t/* %f */", *((SQFloat32*)&inst._arg1));
             break;
             case _OP_GETOUTER:
                         SafeWriteFmt(v,write,up,"\t/* stk[%d] <- outervalues[%d] == (%s) */",
@@ -984,12 +989,20 @@ void SQVM::Mark(SQCollectable **chain)
 	END_MARK()
 }
 
-void SQArray::Mark(SQCollectable **chain)
+void SQArrayBase::Mark(SQCollectable **chain)
 {
-	START_MARK()
-		SQInteger len = _values.size();
-		for(SQInteger i = 0;i < len; i++) SQSharedState::MarkObject(_values[i], chain);
-	END_MARK()
+    if(isCollectable())
+    {
+        START_MARK()
+            SQInteger len = Size();
+            SQObjectPtr o;
+            for(SQInteger i = 0;i < len; i++){
+              _get2(i, o); //do not trigger refcount
+              SQSharedState::MarkObject(o, chain);
+            }
+            o._type=OT_NULL; //hack to not trigger dereference on this temp var
+        END_MARK()
+    }
 }
 void SQTable::Mark(SQCollectable **chain)
 {

+ 16 - 1
SquiLu/squirrel/sqobject.h

@@ -105,6 +105,8 @@ struct SQWeakRef : SQRefCounted
 
 struct SQObjectPtr;
 
+#define __IsLastRefCount(type,unval) (ISREFCOUNTED(type) && (unval.pRefCounted->_uiRef == 1))
+
 #define __AddRefRefCounted(unval) { unval.pRefCounted->_uiRef++; }
 
 #define __AddRef(type,unval) if(ISREFCOUNTED(type))	__AddRefRefCounted(unval)
@@ -136,7 +138,7 @@ struct SQObjectPtr;
 #define _float(obj) ((obj)._unVal.fFloat)
 #define _string(obj) ((obj)._unVal.pString)
 #define _table(obj) ((obj)._unVal.pTable)
-#define _array(obj) ((obj)._unVal.pArray)
+#define _array(obj) ((obj)._unVal.pArrayBase)
 #define _closure(obj) ((obj)._unVal.pClosure)
 #define _generator(obj) ((obj)._unVal.pGenerator)
 #define _nativeclosure(obj) ((obj)._unVal.pNativeClosure)
@@ -235,7 +237,14 @@ struct SQObjectPtr : public SQObject
 	_REF_TYPE_DECL(OT_TABLE,SQTable,Table)
 	_REF_TYPE_DECL(OT_CLASS,SQClass,Class)
 	_REF_TYPE_DECL(OT_INSTANCE,SQInstance,Instance)
+	_REF_TYPE_DECL(OT_ARRAY,SQArrayBase,ArrayBase)
 	_REF_TYPE_DECL(OT_ARRAY,SQArray,Array)
+	_REF_TYPE_DECL(OT_ARRAY,SQFloat64Array,Float64Array)
+	_REF_TYPE_DECL(OT_ARRAY,SQFloat32Array,Float32Array)
+	_REF_TYPE_DECL(OT_ARRAY,SQInt64Array,Int64Array)
+	_REF_TYPE_DECL(OT_ARRAY,SQInt32Array,Int32Array)
+	_REF_TYPE_DECL(OT_ARRAY,SQInt16Array,Int16Array)
+	_REF_TYPE_DECL(OT_ARRAY,SQInt8Array,Int8Array)
 	_REF_TYPE_DECL(OT_CLOSURE,SQClosure,Closure)
 	_REF_TYPE_DECL(OT_NATIVECLOSURE,SQNativeClosure,NativeClosure)
 	_REF_TYPE_DECL(OT_OUTER,SQOuter,Outer)
@@ -362,6 +371,12 @@ struct SQDelegable : public CHAINABLE_OBJ {
 SQUnsignedInteger SQTranslateIndex(const SQObjectPtr &idx);
 typedef sqvector<SQObjectPtr> SQObjectPtrVec;
 typedef sqvector<SQInteger> SQIntVec;
+typedef sqvector<SQFloat> SQFloatVec;
+typedef sqvector<SQInt16> SQInt16Vec;
+typedef sqvector<SQInt32> SQInt32Vec;
+typedef sqvector<SQInt64> SQInt64Vec;
+typedef sqvector<SQFloat32> SQFloat32Vec;
+typedef sqvector<SQFloat64> SQFloat64Vec;
 const SQChar *GetTypeName(const SQObjectPtr &obj1);
 const SQChar *IdType2Name(SQObjectType type);
 

+ 16 - 7
SquiLu/squirrel/squtils.h

@@ -77,6 +77,7 @@ public:
 	void shrinktofit() { if(_size > 4) { _realloc(_size); } }
 	T& top() const { return _vals[_size - 1]; }
 	inline SQUnsignedInteger size() const { return _size; }
+	inline SQUnsignedInteger sizeOf() const { return sizeof(T); }
 	bool empty() const { return (_size <= 0); }
 	inline T &push_back(const T& val = T())
 	{
@@ -88,21 +89,27 @@ public:
 	{
 		_size--; _vals[_size].~T();
 	}
-	void insert(SQUnsignedInteger idx, const T& val)
+	bool insert(SQUnsignedInteger idx, const T& val)
 	{
+	    if(idx > _size) return false;
 		resize(_size + 1);
 		for(SQUnsignedInteger i = _size - 1; i > idx; i--) {
 			_vals[i] = _vals[i - 1];
 		}
     	_vals[idx] = val;
+    	return true;
 	}
-	void remove(SQUnsignedInteger idx)
+	bool remove(SQUnsignedInteger idx)
 	{
-		_vals[idx].~T();
-		if(idx < (_size - 1)) {
-			memmove(&_vals[idx], &_vals[idx+1], sizeof(T) * (_size - idx - 1));
-		}
-		_size--;
+	    if(idx < _size){
+            _vals[idx].~T();
+            if(idx < (_size - 1)) {
+                memmove(&_vals[idx], &_vals[idx+1], sizeof(T) * (_size - idx - 1));
+            }
+            _size--;
+            return true;
+	    }
+		return false;
 	}
 	void removeFromBegining(SQUnsignedInteger count)
 	{
@@ -116,6 +123,8 @@ public:
 	}
 	SQUnsignedInteger capacity() { return _allocated; }
 	inline T &back() const { return _vals[_size - 1]; }
+	inline T get(SQUnsignedInteger pos) const{ return _vals[pos]; }
+	inline void set(SQUnsignedInteger pos, T val) const{ _vals[pos] = val; }
 	inline T& operator[](SQUnsignedInteger pos) const{ return _vals[pos]; }
 	T* _vals;
 private:

+ 26 - 9
SquiLu/squirrel/sqvm.cpp

@@ -274,6 +274,7 @@ static int sq_l_strcmp (const SQObjectPtr &ls,const SQObjectPtr &rs) {
     }
   }
 }
+
 #define _RET_SUCCEED(exp) { result = (exp); return true; }
 bool SQVM::ObjCmp(const SQObjectPtr &o1,const SQObjectPtr &o2,SQInteger &result)
 {
@@ -464,7 +465,7 @@ bool SQVM::StartCall(SQClosure *closure,SQInteger target,SQInteger args,SQIntege
 		SQArray *arr = SQArray::Create(_ss(this),nvargs);
 		SQInteger pbase = stackbase+paramssize;
 		for(SQInteger n = 0; n < nvargs; n++) {
-			arr->_values[n] = _stack._vals[pbase];
+			arr->_set(n, _stack._vals[pbase]);
 			_stack._vals[pbase].Null();
 			pbase++;
 
@@ -725,6 +726,7 @@ bool SQVM::IsEqualDeep(const SQObjectPtr &o1,const SQObjectPtr &o2)
 	}
 	return IsEqual(o1, o2);
 }
+
 bool SQVM::IsEqual(const SQObjectPtr &o1,const SQObjectPtr &o2)
 {
 	bool res = false;
@@ -952,12 +954,21 @@ exception_restore:
 			OPCODE_TARGET(LINE) { if (_debughook) CallDebugHook(_SC('l'),arg1); continue;}
 			OPCODE_TARGET(LOAD) { TARGET = ci->_literals[arg1]; continue;}
 			OPCODE_TARGET(LOADINT) {
-#ifndef _SQ64
-				TARGET = (SQInteger)arg1; continue;}
+#ifdef _SQ64
+				TARGET = (SQInteger)((SQUnsignedInteger32)arg1);
 #else
-				TARGET = (SQInteger)((SQUnsignedInteger32)arg1); continue;}
+				TARGET = (SQInteger)arg1;
 #endif
-			OPCODE_TARGET(LOADFLOAT) { TARGET = *((SQFloat *)&arg1); continue;}
+                continue;
+            }
+			OPCODE_TARGET(LOADFLOAT) {
+#ifdef _SQ64
+			    TARGET = *((SQFloat32*)&arg1);
+#else
+			    TARGET = *((SQFloat32*)&arg1);
+#endif
+                continue;
+            }
 			OPCODE_TARGET(DLOAD) { TARGET = ci->_literals[arg1]; STK(arg2) = ci->_literals[arg3];continue;}
 			OPCODE_TARGET(TAILCALL) {
 				SQObjectPtr &t = STK(arg1);
@@ -1154,15 +1165,19 @@ exception_restore:
 					val = ci->_literals[arg1]; break;
 				case AAT_INT:
 					val._type = OT_INTEGER;
-#ifndef _SQ64
-					val._unVal.nInteger = (SQInteger)arg1;
-#else
+#ifdef _SQ64
 					val._unVal.nInteger = (SQInteger)((SQUnsignedInteger32)arg1);
+#else
+					val._unVal.nInteger = (SQInteger)arg1;
 #endif
 					break;
 				case AAT_FLOAT:
 					val._type = OT_FLOAT;
+#ifdef _SQ64
+					val._unVal.fFloat = *((SQFloat32 *)&arg1);
+#else
 					val._unVal.fFloat = *((SQFloat *)&arg1);
+#endif
 					break;
 				case AAT_BOOL:
 					val._type = OT_BOOL;
@@ -1171,7 +1186,9 @@ exception_restore:
 				default: assert(0); break;
 
 				}
-				_array(STK(arg0))->Append(val);	continue;
+				if(!_array(STK(arg0))->Append(val))
+                    			{Raise_Error(_SC("error appending")); SQ_THROW();}
+				continue;
 				}}
 			OPCODE_TARGET(COMPARITH) {
 				SQInteger selfidx = (((SQUnsignedInteger)arg1&0xFFFF0000)>>16);