Sq Plus Null Instance Pointers
Last changed: ad-remover-84.49.122.139

.

[Added to release 18, 5/28/06. jcs]

Currently, in SqPlus functions that accept or return pointer to instance of class don't work if this pointer is NULL. In case of parameter == NULL, valid Squirrel instance is created, but userpointer is NULL and any call to member function will cause access violation. Returning of nulls as pointer to object also produces an error.

The fix is to change DECLARE_INSTANCE_TYPE_NAME_ macro in SqPlus.h to following:

#define DECLARE_INSTANCE_TYPE_NAME_(TYPE,NAME) namespace SqPlus { \
  inline const SQChar * GetTypeName(const TYPE & n) { return _T(#NAME); } \
  inline void Push(HSQUIRRELVM v,TYPE * value) { \
      if (!value)  sq_pushnull(v); \
      else if (!CreateNativeClassInstance(v,GetTypeName(*value),value,0)) \
         throw SquirrelError(_T("Push(): could not create INSTANCE (check registration name)")); } \
  inline void Push(HSQUIRRELVM v,TYPE & value) { if (!CreateCopyInstance(GetTypeName(value),value)) throw SquirrelError(_T("Push(): could not create INSTANCE copy (check registration name)")); } \
  inline bool Match(TypeWrapper<TYPE &>,HSQUIRRELVM v,int idx) { return  GetInstance<TYPE>(v,idx) != NULL; } \
  inline bool Match(TypeWrapper<TYPE *>,HSQUIRRELVM v,int idx) { \
    return (sq_gettype(v,idx)==OT_NULL) || (GetInstance<TYPE>(v,idx) != NULL); } \
  inline TYPE & Get(TypeWrapper<TYPE &>,HSQUIRRELVM v,int idx) { return *GetInstance<TYPE>(v,idx); } \
  inline TYPE * Get(TypeWrapper<TYPE *>,HSQUIRRELVM v,int idx) { \
    if (sq_gettype(v,idx)==OT_NULL) return NULL;\
    return  GetInstance<TYPE>(v,idx); } \
  template<> \
  struct TypeInfo<TYPE> { \
    const SQChar * typeName; \
    TypeInfo() : typeName(_T(#NAME)) {} \
    enum {TypeID=VAR_TYPE_INSTANCE,Size=sizeof(TYPE)}; \
    operator ScriptVarType() { return ScriptVarType(TypeID); } \
  }; \
} // nameSpace SqPlus

and in SqPlusConst.h DECLARE_INSTANCE_TYPE_NAME_CONST macro to

#define DECLARE_INSTANCE_TYPE_NAME_CONST(TYPE,NAME) \
DECLARE_INSTANCE_TYPE_NAME_(TYPE,NAME) \
namespace SqPlus { \
inline void Push(HSQUIRRELVM v,const TYPE * value) { \
  if (!value)  sq_pushnull(v); \
  else if (!CreateNativeClassInstance(v,GetTypeName(*value),(TYPE*)value,0)) \
    throw SquirrelError(_T("Push(): could not create INSTANCE (check registration name)")); } \
inline void Push(HSQUIRRELVM v,const TYPE & value) { if (!CreateCopyInstance(GetTypeName(value),value)) throw SquirrelError(_T("Push(): could not create INSTANCE copy (check registration name)")); } \
inline bool		Match(TypeWrapper<const TYPE &>,HSQUIRRELVM v,int idx) { return  GetInstance<TYPE>(v,idx) != NULL; } \
inline const TYPE & Get(TypeWrapper<const TYPE &>,HSQUIRRELVM v,int idx) { return *GetInstance<TYPE>(v,idx); } \
} // nameSpace SqPlus