1 
2 // The CScriptWeakRef class was originally implemented by vroad in March 2013
3 
4 #include "weakref.h"
5 #include <new>
6 #include <assert.h>
7 #include <string.h> // strstr()
8 
9 BEGIN_AS_NAMESPACE
10 
ScriptWeakRefConstruct(asITypeInfo * type,void * mem)11 static void ScriptWeakRefConstruct(asITypeInfo *type, void *mem)
12 {
13 	new(mem) CScriptWeakRef(type);
14 }
15 
ScriptWeakRefConstruct2(asITypeInfo * type,void * ref,void * mem)16 static void ScriptWeakRefConstruct2(asITypeInfo *type, void *ref, void *mem)
17 {
18 	new(mem) CScriptWeakRef(ref, type);
19 
20 	// It's possible the constructor raised a script exception, in which case we
21 	// need to call the destructor in order to cleanup the memory before returning
22 	asIScriptContext *ctx = asGetActiveContext();
23 	if( ctx && ctx->GetState() == asEXECUTION_EXCEPTION )
24 		reinterpret_cast<CScriptWeakRef*>(mem)->~CScriptWeakRef();
25 }
26 
ScriptWeakRefDestruct(CScriptWeakRef * obj)27 static void ScriptWeakRefDestruct(CScriptWeakRef *obj)
28 {
29 	obj->~CScriptWeakRef();
30 }
31 
ScriptWeakRefTemplateCallback(asITypeInfo * ti,bool &)32 static bool ScriptWeakRefTemplateCallback(asITypeInfo *ti, bool &/*dontGarbageCollect*/)
33 {
34 	asITypeInfo *subType = ti->GetSubType();
35 
36 	// Weak references only work for reference types
37 	if( subType == 0 ) return false;
38 	if( !(subType->GetFlags() & asOBJ_REF) ) return false;
39 
40 	// The subtype shouldn't be a handle
41 	if( ti->GetSubTypeId() & asTYPEID_OBJHANDLE )
42 		return false;
43 
44 	// Make sure the type really supports weak references
45 	asUINT cnt = subType->GetBehaviourCount();
46 	for( asUINT n = 0; n < cnt; n++ )
47 	{
48 		asEBehaviours beh;
49 		subType->GetBehaviourByIndex(n, &beh);
50 		if( beh == asBEHAVE_GET_WEAKREF_FLAG )
51 			return true;
52 	}
53 
54 	ti->GetEngine()->WriteMessage("weakref", 0, 0, asMSGTYPE_ERROR, "The subtype doesn't support weak references");
55 	return false;
56 }
57 
CScriptWeakRef(asITypeInfo * type)58 CScriptWeakRef::CScriptWeakRef(asITypeInfo *type)
59 {
60 	m_ref  = 0;
61 	m_type = type;
62 	m_type->AddRef();
63 	m_weakRefFlag = 0;
64 }
65 
CScriptWeakRef(const CScriptWeakRef & other)66 CScriptWeakRef::CScriptWeakRef(const CScriptWeakRef &other)
67 {
68 	m_ref  = other.m_ref;
69 	m_type = other.m_type;
70 	m_type->AddRef();
71 	m_weakRefFlag = other.m_weakRefFlag;
72 	if( m_weakRefFlag )
73 		m_weakRefFlag->AddRef();
74 }
75 
CScriptWeakRef(void * ref,asITypeInfo * type)76 CScriptWeakRef::CScriptWeakRef(void *ref, asITypeInfo *type)
77 {
78 	m_ref  = ref;
79 	m_type = type;
80 	m_type->AddRef();
81 
82 	// The given type should be the weakref template instance
83 	assert( strcmp(type->GetName(), "weakref") == 0 ||
84 	        strcmp(type->GetName(), "const_weakref") == 0 );
85 
86 	// Get the shared flag that will tell us when the object has been destroyed
87 	// This is threadsafe as we hold a strong reference to the object
88 	m_weakRefFlag = m_type->GetEngine()->GetWeakRefFlagOfScriptObject(m_ref, m_type->GetSubType());
89 	if( m_weakRefFlag )
90 		m_weakRefFlag->AddRef();
91 }
92 
~CScriptWeakRef()93 CScriptWeakRef::~CScriptWeakRef()
94 {
95 	if( m_type )
96 		m_type->Release();
97 	if( m_weakRefFlag )
98 		m_weakRefFlag->Release();
99 }
100 
operator =(const CScriptWeakRef & other)101 CScriptWeakRef &CScriptWeakRef::operator =(const CScriptWeakRef &other)
102 {
103 	// Don't do anything if it is the same reference
104 	if( m_ref == other.m_ref )
105 		return *this;
106 
107 	// Must not allow changing the type
108 	if( m_type != other.m_type )
109 	{
110 		// We can allow a weakref to be assigned to a const_weakref
111 		if( !(strcmp(m_type->GetName(), "const_weakref") == 0 &&
112 			  strcmp(other.m_type->GetName(), "weakref") == 0 &&
113 			  m_type->GetSubType() == other.m_type->GetSubType()) )
114 		{
115 			  assert( false );
116 			  return *this;
117 		}
118 	}
119 
120 	m_ref = other.m_ref;
121 
122 	if( m_weakRefFlag )
123 		m_weakRefFlag->Release();
124 	m_weakRefFlag = other.m_weakRefFlag;
125 	if( m_weakRefFlag )
126 		m_weakRefFlag->AddRef();
127 
128 	return *this;
129 }
130 
Set(void * newRef)131 CScriptWeakRef &CScriptWeakRef::Set(void *newRef)
132 {
133 	// Release the previous weak ref
134 	if( m_weakRefFlag )
135 		m_weakRefFlag->Release();
136 
137 	// Retrieve the new weak ref
138 	m_ref = newRef;
139 	if( newRef )
140 	{
141 		m_weakRefFlag = m_type->GetEngine()->GetWeakRefFlagOfScriptObject(newRef, m_type->GetSubType());
142 		m_weakRefFlag->AddRef();
143 	}
144 	else
145 		m_weakRefFlag = 0;
146 
147 	// Release the newRef since we're only supposed to hold a weakref
148 	m_type->GetEngine()->ReleaseScriptObject(newRef, m_type->GetSubType());
149 
150 	return *this;
151 }
152 
GetRefType() const153 asITypeInfo *CScriptWeakRef::GetRefType() const
154 {
155 	return m_type->GetSubType();
156 }
157 
operator ==(const CScriptWeakRef & o) const158 bool CScriptWeakRef::operator==(const CScriptWeakRef &o) const
159 {
160 	if( m_ref  == o.m_ref &&
161 		m_type == o.m_type )
162 		return true;
163 
164 	// TODO: If type is not the same, we should attempt to do a dynamic cast,
165 	//       which may change the pointer for application registered classes
166 
167 	return false;
168 }
169 
operator !=(const CScriptWeakRef & o) const170 bool CScriptWeakRef::operator!=(const CScriptWeakRef &o) const
171 {
172 	return !(*this == o);
173 }
174 
175 // AngelScript: used as '@obj = ref.get();'
Get() const176 void *CScriptWeakRef::Get() const
177 {
178 	// If we hold a null handle, then just return null
179 	if( m_ref == 0 || m_weakRefFlag == 0 )
180 		return 0;
181 
182 	// Lock on the shared bool, so we can be certain it won't be changed to true
183 	// between the inspection of the flag and the increase of the ref count in the
184 	// owning object.
185 	m_weakRefFlag->Lock();
186 	if( !m_weakRefFlag->Get() )
187 	{
188 		m_type->GetEngine()->AddRefScriptObject(m_ref, m_type->GetSubType());
189 		m_weakRefFlag->Unlock();
190 		return m_ref;
191 	}
192 	m_weakRefFlag->Unlock();
193 
194 	return 0;
195 }
196 
Equals(void * ref) const197 bool CScriptWeakRef::Equals(void *ref) const
198 {
199 	// Release the ref since we'll not keep it
200 	m_type->GetEngine()->ReleaseScriptObject(ref, m_type->GetSubType());
201 
202 	if( m_ref == ref )
203 		return true;
204 
205 	return false;
206 }
207 
RegisterScriptWeakRef_Native(asIScriptEngine * engine)208 void RegisterScriptWeakRef_Native(asIScriptEngine *engine)
209 {
210 	int r;
211 
212 	// Register a type for non-const handles
213 	r = engine->RegisterObjectType("weakref<class T>", sizeof(CScriptWeakRef), asOBJ_VALUE | asOBJ_ASHANDLE | asOBJ_TEMPLATE | asOBJ_APP_CLASS_DAK); assert( r >= 0 );
214 
215 	r = engine->RegisterObjectBehaviour("weakref<T>", asBEHAVE_CONSTRUCT, "void f(int&in)", asFUNCTION(ScriptWeakRefConstruct), asCALL_CDECL_OBJLAST); assert( r>= 0 );
216 	r = engine->RegisterObjectBehaviour("weakref<T>", asBEHAVE_CONSTRUCT, "void f(int&in, T@+)", asFUNCTION(ScriptWeakRefConstruct2), asCALL_CDECL_OBJLAST); assert( r>= 0 );
217 	r = engine->RegisterObjectBehaviour("weakref<T>", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(ScriptWeakRefDestruct), asCALL_CDECL_OBJLAST); assert( r >= 0 );
218 	r = engine->RegisterObjectBehaviour("weakref<T>", asBEHAVE_TEMPLATE_CALLBACK, "bool f(int&in, bool&out)", asFUNCTION(ScriptWeakRefTemplateCallback), asCALL_CDECL); assert( r >= 0 );
219 
220 	r = engine->RegisterObjectMethod("weakref<T>", "T@ opImplCast()", asMETHOD(CScriptWeakRef, Get), asCALL_THISCALL); assert(r >= 0);
221 	r = engine->RegisterObjectMethod("weakref<T>", "T@ get() const", asMETHODPR(CScriptWeakRef, Get, () const, void*), asCALL_THISCALL); assert( r >= 0 );
222 	r = engine->RegisterObjectMethod("weakref<T>", "weakref<T> &opHndlAssign(const weakref<T> &in)", asMETHOD(CScriptWeakRef, operator=), asCALL_THISCALL); assert( r >= 0 );
223 	r = engine->RegisterObjectMethod("weakref<T>", "bool opEquals(const weakref<T> &in) const", asMETHODPR(CScriptWeakRef, operator==, (const CScriptWeakRef &) const, bool), asCALL_THISCALL); assert( r >= 0 );
224 	r = engine->RegisterObjectMethod("weakref<T>", "weakref<T> &opHndlAssign(T@)", asMETHOD(CScriptWeakRef, Set), asCALL_THISCALL); assert( r >= 0 );
225 	r = engine->RegisterObjectMethod("weakref<T>", "bool opEquals(const T@) const", asMETHOD(CScriptWeakRef, Equals), asCALL_THISCALL); assert(r >= 0);
226 
227 	// Register another type for const handles
228 	r = engine->RegisterObjectType("const_weakref<class T>", sizeof(CScriptWeakRef), asOBJ_VALUE | asOBJ_ASHANDLE | asOBJ_TEMPLATE | asOBJ_APP_CLASS_DAK); assert( r >= 0 );
229 
230 	r = engine->RegisterObjectBehaviour("const_weakref<T>", asBEHAVE_CONSTRUCT, "void f(int&in)", asFUNCTION(ScriptWeakRefConstruct), asCALL_CDECL_OBJLAST); assert( r>= 0 );
231 	r = engine->RegisterObjectBehaviour("const_weakref<T>", asBEHAVE_CONSTRUCT, "void f(int&in, const T@+)", asFUNCTION(ScriptWeakRefConstruct2), asCALL_CDECL_OBJLAST); assert( r>= 0 );
232 	r = engine->RegisterObjectBehaviour("const_weakref<T>", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(ScriptWeakRefDestruct), asCALL_CDECL_OBJLAST); assert( r >= 0 );
233 	r = engine->RegisterObjectBehaviour("const_weakref<T>", asBEHAVE_TEMPLATE_CALLBACK, "bool f(int&in, bool&out)", asFUNCTION(ScriptWeakRefTemplateCallback), asCALL_CDECL); assert( r >= 0 );
234 
235 	r = engine->RegisterObjectMethod("const_weakref<T>", "const T@ opImplCast() const", asMETHOD(CScriptWeakRef, Get), asCALL_THISCALL); assert(r >= 0);
236 	r = engine->RegisterObjectMethod("const_weakref<T>", "const T@ get() const", asMETHODPR(CScriptWeakRef, Get, () const, void*), asCALL_THISCALL); assert( r >= 0 );
237 	r = engine->RegisterObjectMethod("const_weakref<T>", "const_weakref<T> &opHndlAssign(const const_weakref<T> &in)", asMETHOD(CScriptWeakRef, operator=), asCALL_THISCALL); assert( r >= 0 );
238 	r = engine->RegisterObjectMethod("const_weakref<T>", "bool opEquals(const const_weakref<T> &in) const", asMETHODPR(CScriptWeakRef, operator==, (const CScriptWeakRef &) const, bool), asCALL_THISCALL); assert( r >= 0 );
239 	r = engine->RegisterObjectMethod("const_weakref<T>", "const_weakref<T> &opHndlAssign(const T@)", asMETHOD(CScriptWeakRef, Set), asCALL_THISCALL); assert( r >= 0 );
240 	r = engine->RegisterObjectMethod("const_weakref<T>", "bool opEquals(const T@) const", asMETHOD(CScriptWeakRef, Equals), asCALL_THISCALL); assert(r >= 0);
241 
242 	// Allow non-const weak references to be converted to const weak references
243 	r = engine->RegisterObjectMethod("const_weakref<T>", "const_weakref<T> &opHndlAssign(const weakref<T> &in)", asMETHOD(CScriptWeakRef, operator=), asCALL_THISCALL); assert( r >= 0 );
244 	r = engine->RegisterObjectMethod("const_weakref<T>", "bool opEquals(const weakref<T> &in) const", asMETHODPR(CScriptWeakRef, operator==, (const CScriptWeakRef &) const, bool), asCALL_THISCALL); assert( r >= 0 );
245 }
246 
ScriptWeakRefConstruct_Generic(asIScriptGeneric * gen)247 static void ScriptWeakRefConstruct_Generic(asIScriptGeneric *gen)
248 {
249 	asITypeInfo *ti = *reinterpret_cast<asITypeInfo**>(gen->GetAddressOfArg(0));
250 
251 	ScriptWeakRefConstruct(ti, gen->GetObject());
252 }
253 
ScriptWeakRefConstruct2_Generic(asIScriptGeneric * gen)254 static void ScriptWeakRefConstruct2_Generic(asIScriptGeneric *gen)
255 {
256 	asITypeInfo *ti = *reinterpret_cast<asITypeInfo**>(gen->GetAddressOfArg(0));
257 	void *ref = gen->GetArgAddress(1);
258 
259 	ScriptWeakRefConstruct2(ti, ref, gen->GetObject());
260 }
261 
ScriptWeakRefDestruct_Generic(asIScriptGeneric * gen)262 static void ScriptWeakRefDestruct_Generic(asIScriptGeneric *gen)
263 {
264 	CScriptWeakRef *self = reinterpret_cast<CScriptWeakRef*>(gen->GetObject());
265 	self->~CScriptWeakRef();
266 }
267 
CScriptWeakRef_Get_Generic(asIScriptGeneric * gen)268 void CScriptWeakRef_Get_Generic(asIScriptGeneric *gen)
269 {
270 	CScriptWeakRef *self = reinterpret_cast<CScriptWeakRef*>(gen->GetObject());
271 	gen->SetReturnAddress(self->Get());
272 }
273 
CScriptWeakRef_Assign_Generic(asIScriptGeneric * gen)274 void CScriptWeakRef_Assign_Generic(asIScriptGeneric *gen)
275 {
276 	CScriptWeakRef *other = reinterpret_cast<CScriptWeakRef*>(gen->GetArgAddress(0));
277 	CScriptWeakRef *self = reinterpret_cast<CScriptWeakRef*>(gen->GetObject());
278 	*self = *other;
279 	gen->SetReturnAddress(self);
280 }
281 
CScriptWeakRef_Assign2_Generic(asIScriptGeneric * gen)282 void CScriptWeakRef_Assign2_Generic(asIScriptGeneric *gen)
283 {
284 	void *other = gen->GetArgAddress(0);
285 	CScriptWeakRef *self = reinterpret_cast<CScriptWeakRef*>(gen->GetObject());
286 
287 	// Must increase the refcount of the object, since Set() will decrease it
288 	// If this is not done, the object will be destroyed too early since the
289 	// generic interface also automatically decreases the refcount of received handles
290 	gen->GetEngine()->AddRefScriptObject(other, self->GetRefType());
291 
292 	self->Set(other);
293 	gen->SetReturnAddress(self);
294 }
295 
CScriptWeakRef_Equals_Generic(asIScriptGeneric * gen)296 void CScriptWeakRef_Equals_Generic(asIScriptGeneric *gen)
297 {
298 	CScriptWeakRef *other = reinterpret_cast<CScriptWeakRef*>(gen->GetArgAddress(0));
299 	CScriptWeakRef *self = reinterpret_cast<CScriptWeakRef*>(gen->GetObject());
300 	gen->SetReturnByte(*self == *other);
301 }
302 
CScriptWeakRef_Equals2_Generic(asIScriptGeneric * gen)303 void CScriptWeakRef_Equals2_Generic(asIScriptGeneric *gen)
304 {
305 	void *other = gen->GetArgAddress(0);
306 	CScriptWeakRef *self = reinterpret_cast<CScriptWeakRef*>(gen->GetObject());
307 
308 	// Must increase the refcount of the object, since Equals() will decrease it
309 	// If this is not done, the object will be destroyed too early since the
310 	// generic interface also automatically decreases the refcount of received handles
311 	gen->GetEngine()->AddRefScriptObject(other, self->GetRefType());
312 
313 	gen->SetReturnByte(self->Equals(other));
314 }
315 
ScriptWeakRefTemplateCallback_Generic(asIScriptGeneric * gen)316 static void ScriptWeakRefTemplateCallback_Generic(asIScriptGeneric *gen)
317 {
318 	asITypeInfo *ti = *reinterpret_cast<asITypeInfo**>(gen->GetAddressOfArg(0));
319 	bool *dontGarbageCollect = *reinterpret_cast<bool**>(gen->GetAddressOfArg(1));
320 	*reinterpret_cast<bool*>(gen->GetAddressOfReturnLocation()) = ScriptWeakRefTemplateCallback(ti, *dontGarbageCollect);
321 }
322 
RegisterScriptWeakRef_Generic(asIScriptEngine * engine)323 void RegisterScriptWeakRef_Generic(asIScriptEngine *engine)
324 {
325 	int r;
326 
327 	// Register a type for non-const handles
328 	r = engine->RegisterObjectType("weakref<class T>", sizeof(CScriptWeakRef), asOBJ_VALUE | asOBJ_ASHANDLE | asOBJ_TEMPLATE | asOBJ_APP_CLASS_DAK); assert( r >= 0 );
329 
330 	r = engine->RegisterObjectBehaviour("weakref<T>", asBEHAVE_CONSTRUCT, "void f(int&in)", asFUNCTION(ScriptWeakRefConstruct_Generic), asCALL_GENERIC); assert( r>= 0 );
331 	r = engine->RegisterObjectBehaviour("weakref<T>", asBEHAVE_CONSTRUCT, "void f(int&in, T@)", asFUNCTION(ScriptWeakRefConstruct2_Generic), asCALL_GENERIC); assert( r>= 0 );
332 	r = engine->RegisterObjectBehaviour("weakref<T>", asBEHAVE_TEMPLATE_CALLBACK, "bool f(int&in, bool&out)", asFUNCTION(ScriptWeakRefTemplateCallback_Generic), asCALL_GENERIC); assert( r >= 0 );
333 	r = engine->RegisterObjectBehaviour("weakref<T>", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(ScriptWeakRefDestruct_Generic), asCALL_GENERIC); assert( r >= 0 );
334 
335 	r = engine->RegisterObjectMethod("weakref<T>", "T@ opImplCast()", asFUNCTION(CScriptWeakRef_Get_Generic), asCALL_GENERIC); assert(r >= 0);
336 	r = engine->RegisterObjectMethod("weakref<T>", "T@ get() const", asFUNCTION(CScriptWeakRef_Get_Generic), asCALL_GENERIC); assert( r >= 0 );
337 	r = engine->RegisterObjectMethod("weakref<T>", "weakref<T> &opHndlAssign(const weakref<T> &in)", asFUNCTION(CScriptWeakRef_Assign_Generic), asCALL_GENERIC); assert( r >= 0 );
338 	r = engine->RegisterObjectMethod("weakref<T>", "bool opEquals(const weakref<T> &in) const", asFUNCTION(CScriptWeakRef_Equals_Generic), asCALL_GENERIC); assert( r >= 0 );
339 	r = engine->RegisterObjectMethod("weakref<T>", "weakref<T> &opHndlAssign(T@)", asFUNCTION(CScriptWeakRef_Assign2_Generic), asCALL_GENERIC); assert( r >= 0 );
340 	r = engine->RegisterObjectMethod("weakref<T>", "bool opEquals(const T@) const", asFUNCTION(CScriptWeakRef_Equals2_Generic), asCALL_GENERIC); assert(r >= 0);
341 
342 	// Register another type for const handles
343 	r = engine->RegisterObjectType("const_weakref<class T>", sizeof(CScriptWeakRef), asOBJ_VALUE | asOBJ_ASHANDLE | asOBJ_TEMPLATE | asOBJ_APP_CLASS_DAK); assert( r >= 0 );
344 
345 	r = engine->RegisterObjectBehaviour("const_weakref<T>", asBEHAVE_CONSTRUCT, "void f(int&in)", asFUNCTION(ScriptWeakRefConstruct_Generic), asCALL_GENERIC); assert( r>= 0 );
346 	r = engine->RegisterObjectBehaviour("const_weakref<T>", asBEHAVE_CONSTRUCT, "void f(int&in, const T@)", asFUNCTION(ScriptWeakRefConstruct2_Generic), asCALL_GENERIC); assert( r>= 0 );
347 	r = engine->RegisterObjectBehaviour("const_weakref<T>", asBEHAVE_TEMPLATE_CALLBACK, "bool f(int&in, bool&out)", asFUNCTION(ScriptWeakRefTemplateCallback_Generic), asCALL_GENERIC); assert( r >= 0 );
348 	r = engine->RegisterObjectBehaviour("const_weakref<T>", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(ScriptWeakRefDestruct_Generic), asCALL_GENERIC); assert( r >= 0 );
349 
350 	r = engine->RegisterObjectMethod("const_weakref<T>", "const T@ opImplCast() const", asFUNCTION(CScriptWeakRef_Get_Generic), asCALL_GENERIC); assert(r >= 0);
351 	r = engine->RegisterObjectMethod("const_weakref<T>", "const T@ get() const", asFUNCTION(CScriptWeakRef_Get_Generic), asCALL_GENERIC); assert( r >= 0 );
352 	r = engine->RegisterObjectMethod("const_weakref<T>", "const_weakref<T> &opHndlAssign(const const_weakref<T> &in)", asFUNCTION(CScriptWeakRef_Assign_Generic), asCALL_GENERIC); assert( r >= 0 );
353 	r = engine->RegisterObjectMethod("const_weakref<T>", "bool opEquals(const const_weakref<T> &in) const", asFUNCTION(CScriptWeakRef_Equals_Generic), asCALL_GENERIC); assert( r >= 0 );
354 	r = engine->RegisterObjectMethod("const_weakref<T>", "const_weakref<T> &opHndlAssign(const T@)", asFUNCTION(CScriptWeakRef_Assign2_Generic), asCALL_GENERIC); assert( r >= 0 );
355 	r = engine->RegisterObjectMethod("const_weakref<T>", "bool opEquals(const T@) const", asFUNCTION(CScriptWeakRef_Equals2_Generic), asCALL_GENERIC); assert(r >= 0);
356 
357 	// Allow non-const weak references to be converted to const weak references
358 	r = engine->RegisterObjectMethod("const_weakref<T>", "const_weakref<T> &opHndlAssign(const weakref<T> &in)", asFUNCTION(CScriptWeakRef_Assign_Generic), asCALL_GENERIC); assert( r >= 0 );
359 	r = engine->RegisterObjectMethod("const_weakref<T>", "bool opEquals(const weakref<T> &in) const", asFUNCTION(CScriptWeakRef_Equals_Generic), asCALL_GENERIC); assert( r >= 0 );
360 }
361 
RegisterScriptWeakRef(asIScriptEngine * engine)362 void RegisterScriptWeakRef(asIScriptEngine *engine)
363 {
364 	if( strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
365 		RegisterScriptWeakRef_Generic(engine);
366 	else
367 		RegisterScriptWeakRef_Native(engine);
368 }
369 
370 
371 END_AS_NAMESPACE
372