1 /*
2     see copyright notice in squirrel.h
3 */
4 #include "sqpcheader.h"
5 #include "sqvm.h"
6 #include "sqstring.h"
7 #include "sqtable.h"
8 #include "sqarray.h"
9 #include "sqfuncproto.h"
10 #include "sqclosure.h"
11 #include "squserdata.h"
12 #include "sqcompiler.h"
13 #include "sqfuncstate.h"
14 #include "sqclass.h"
15 
sq_aux_gettypedarg(HSQUIRRELVM v,SQInteger idx,SQObjectType type,SQObjectPtr ** o)16 static bool sq_aux_gettypedarg(HSQUIRRELVM v,SQInteger idx,SQObjectType type,SQObjectPtr **o)
17 {
18     *o = &stack_get(v,idx);
19     if(sq_type(**o) != type){
20         SQObjectPtr oval = v->PrintObjVal(**o);
21         v->Raise_Error(_SC("wrong argument type, expected '%s' got '%.50s'"),IdType2Name(type),_stringval(oval));
22         return false;
23     }
24     return true;
25 }
26 
27 #define _GETSAFE_OBJ(v,idx,type,o) { if(!sq_aux_gettypedarg(v,idx,type,&o)) return SQ_ERROR; }
28 
29 #define sq_aux_paramscheck(v,count) \
30 { \
31     if(sq_gettop(v) < count){ v->Raise_Error(_SC("not enough params in the stack")); return SQ_ERROR; }\
32 }
33 
34 
sq_aux_invalidtype(HSQUIRRELVM v,SQObjectType type)35 SQInteger sq_aux_invalidtype(HSQUIRRELVM v,SQObjectType type)
36 {
37     SQUnsignedInteger buf_size = 100 *sizeof(SQChar);
38     scsprintf(_ss(v)->GetScratchPad(buf_size), buf_size, _SC("unexpected type %s"), IdType2Name(type));
39     return sq_throwerror(v, _ss(v)->GetScratchPad(-1));
40 }
41 
sq_open(SQInteger initialstacksize)42 HSQUIRRELVM sq_open(SQInteger initialstacksize)
43 {
44     SQSharedState *ss;
45     SQVM *v;
46     sq_new(ss, SQSharedState);
47     ss->Init();
48     v = (SQVM *)SQ_MALLOC(sizeof(SQVM));
49     new (v) SQVM(ss);
50     ss->_root_vm = v;
51     if(v->Init(NULL, initialstacksize)) {
52         return v;
53     } else {
54         sq_delete(v, SQVM);
55         return NULL;
56     }
57     return v;
58 }
59 
sq_newthread(HSQUIRRELVM friendvm,SQInteger initialstacksize)60 HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, SQInteger initialstacksize)
61 {
62     SQSharedState *ss;
63     SQVM *v;
64     ss=_ss(friendvm);
65 
66     v= (SQVM *)SQ_MALLOC(sizeof(SQVM));
67     new (v) SQVM(ss);
68 
69     if(v->Init(friendvm, initialstacksize)) {
70         friendvm->Push(v);
71         return v;
72     } else {
73         sq_delete(v, SQVM);
74         return NULL;
75     }
76 }
77 
sq_getvmstate(HSQUIRRELVM v)78 SQInteger sq_getvmstate(HSQUIRRELVM v)
79 {
80     if(v->_suspended)
81         return SQ_VMSTATE_SUSPENDED;
82     else {
83         if(v->_callsstacksize != 0) return SQ_VMSTATE_RUNNING;
84         else return SQ_VMSTATE_IDLE;
85     }
86 }
87 
sq_seterrorhandler(HSQUIRRELVM v)88 void sq_seterrorhandler(HSQUIRRELVM v)
89 {
90     SQObject o = stack_get(v, -1);
91     if(sq_isclosure(o) || sq_isnativeclosure(o) || sq_isnull(o)) {
92         v->_errorhandler = o;
93         v->Pop();
94     }
95 }
96 
sq_setnativedebughook(HSQUIRRELVM v,SQDEBUGHOOK hook)97 void sq_setnativedebughook(HSQUIRRELVM v,SQDEBUGHOOK hook)
98 {
99     v->_debughook_native = hook;
100     v->_debughook_closure.Null();
101     v->_debughook = hook?true:false;
102 }
103 
sq_setdebughook(HSQUIRRELVM v)104 void sq_setdebughook(HSQUIRRELVM v)
105 {
106     SQObject o = stack_get(v,-1);
107     if(sq_isclosure(o) || sq_isnativeclosure(o) || sq_isnull(o)) {
108         v->_debughook_closure = o;
109         v->_debughook_native = NULL;
110         v->_debughook = !sq_isnull(o);
111         v->Pop();
112     }
113 }
114 
sq_close(HSQUIRRELVM v)115 void sq_close(HSQUIRRELVM v)
116 {
117     SQSharedState *ss = _ss(v);
118     _thread(ss->_root_vm)->Finalize();
119     sq_delete(ss, SQSharedState);
120 }
121 
sq_getversion()122 SQInteger sq_getversion()
123 {
124     return SQUIRREL_VERSION_NUMBER;
125 }
126 
sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar * sourcename,SQBool raiseerror)127 SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename,SQBool raiseerror)
128 {
129     SQObjectPtr o;
130 #ifndef NO_COMPILER
131     if(Compile(v, read, p, sourcename, o, raiseerror?true:false, _ss(v)->_debuginfo)) {
132         v->Push(SQClosure::Create(_ss(v), _funcproto(o), _table(v->_roottable)->GetWeakRef(OT_TABLE)));
133         return SQ_OK;
134     }
135     return SQ_ERROR;
136 #else
137     return sq_throwerror(v,_SC("this is a no compiler build"));
138 #endif
139 }
140 
sq_enabledebuginfo(HSQUIRRELVM v,SQBool enable)141 void sq_enabledebuginfo(HSQUIRRELVM v, SQBool enable)
142 {
143     _ss(v)->_debuginfo = enable?true:false;
144 }
145 
sq_notifyallexceptions(HSQUIRRELVM v,SQBool enable)146 void sq_notifyallexceptions(HSQUIRRELVM v, SQBool enable)
147 {
148     _ss(v)->_notifyallexceptions = enable?true:false;
149 }
150 
sq_addref(HSQUIRRELVM v,HSQOBJECT * po)151 void sq_addref(HSQUIRRELVM v,HSQOBJECT *po)
152 {
153     if(!ISREFCOUNTED(sq_type(*po))) return;
154 #ifdef NO_GARBAGE_COLLECTOR
155     __AddRef(po->_type,po->_unVal);
156 #else
157     _ss(v)->_refs_table.AddRef(*po);
158 #endif
159 }
160 
sq_getrefcount(HSQUIRRELVM v,HSQOBJECT * po)161 SQUnsignedInteger sq_getrefcount(HSQUIRRELVM v,HSQOBJECT *po)
162 {
163     if(!ISREFCOUNTED(sq_type(*po))) return 0;
164 #ifdef NO_GARBAGE_COLLECTOR
165    return po->_unVal.pRefCounted->_uiRef;
166 #else
167    return _ss(v)->_refs_table.GetRefCount(*po);
168 #endif
169 }
170 
sq_release(HSQUIRRELVM v,HSQOBJECT * po)171 SQBool sq_release(HSQUIRRELVM v,HSQOBJECT *po)
172 {
173     if(!ISREFCOUNTED(sq_type(*po))) return SQTrue;
174 #ifdef NO_GARBAGE_COLLECTOR
175     bool ret = (po->_unVal.pRefCounted->_uiRef <= 1) ? SQTrue : SQFalse;
176     __Release(po->_type,po->_unVal);
177     return ret; //the ret val doesn't work(and cannot be fixed)
178 #else
179     return _ss(v)->_refs_table.Release(*po);
180 #endif
181 }
182 
sq_getvmrefcount(HSQUIRRELVM SQ_UNUSED_ARG (v),const HSQOBJECT * po)183 SQUnsignedInteger sq_getvmrefcount(HSQUIRRELVM SQ_UNUSED_ARG(v), const HSQOBJECT *po)
184 {
185     if (!ISREFCOUNTED(sq_type(*po))) return 0;
186     return po->_unVal.pRefCounted->_uiRef;
187 }
188 
sq_objtostring(const HSQOBJECT * o)189 const SQChar *sq_objtostring(const HSQOBJECT *o)
190 {
191     if(sq_type(*o) == OT_STRING) {
192         return _stringval(*o);
193     }
194     return NULL;
195 }
196 
sq_objtointeger(const HSQOBJECT * o)197 SQInteger sq_objtointeger(const HSQOBJECT *o)
198 {
199     if(sq_isnumeric(*o)) {
200         return tointeger(*o);
201     }
202     return 0;
203 }
204 
sq_objtofloat(const HSQOBJECT * o)205 SQFloat sq_objtofloat(const HSQOBJECT *o)
206 {
207     if(sq_isnumeric(*o)) {
208         return tofloat(*o);
209     }
210     return 0;
211 }
212 
sq_objtobool(const HSQOBJECT * o)213 SQBool sq_objtobool(const HSQOBJECT *o)
214 {
215     if(sq_isbool(*o)) {
216         return _integer(*o);
217     }
218     return SQFalse;
219 }
220 
sq_objtouserpointer(const HSQOBJECT * o)221 SQUserPointer sq_objtouserpointer(const HSQOBJECT *o)
222 {
223     if(sq_isuserpointer(*o)) {
224         return _userpointer(*o);
225     }
226     return 0;
227 }
228 
sq_pushnull(HSQUIRRELVM v)229 void sq_pushnull(HSQUIRRELVM v)
230 {
231     v->PushNull();
232 }
233 
sq_pushstring(HSQUIRRELVM v,const SQChar * s,SQInteger len)234 void sq_pushstring(HSQUIRRELVM v,const SQChar *s,SQInteger len)
235 {
236     if(s)
237         v->Push(SQObjectPtr(SQString::Create(_ss(v), s, len)));
238     else v->PushNull();
239 }
240 
sq_pushinteger(HSQUIRRELVM v,SQInteger n)241 void sq_pushinteger(HSQUIRRELVM v,SQInteger n)
242 {
243     v->Push(n);
244 }
245 
sq_pushbool(HSQUIRRELVM v,SQBool b)246 void sq_pushbool(HSQUIRRELVM v,SQBool b)
247 {
248     v->Push(b?true:false);
249 }
250 
sq_pushfloat(HSQUIRRELVM v,SQFloat n)251 void sq_pushfloat(HSQUIRRELVM v,SQFloat n)
252 {
253     v->Push(n);
254 }
255 
sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p)256 void sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p)
257 {
258     v->Push(p);
259 }
260 
sq_pushthread(HSQUIRRELVM v,HSQUIRRELVM thread)261 void sq_pushthread(HSQUIRRELVM v, HSQUIRRELVM thread)
262 {
263     v->Push(thread);
264 }
265 
sq_newuserdata(HSQUIRRELVM v,SQUnsignedInteger size)266 SQUserPointer sq_newuserdata(HSQUIRRELVM v,SQUnsignedInteger size)
267 {
268     SQUserData *ud = SQUserData::Create(_ss(v), size + SQ_ALIGNMENT);
269     v->Push(ud);
270     return (SQUserPointer)sq_aligning(ud + 1);
271 }
272 
sq_newtable(HSQUIRRELVM v)273 void sq_newtable(HSQUIRRELVM v)
274 {
275     v->Push(SQTable::Create(_ss(v), 0));
276 }
277 
sq_newtableex(HSQUIRRELVM v,SQInteger initialcapacity)278 void sq_newtableex(HSQUIRRELVM v,SQInteger initialcapacity)
279 {
280     v->Push(SQTable::Create(_ss(v), initialcapacity));
281 }
282 
sq_newarray(HSQUIRRELVM v,SQInteger size)283 void sq_newarray(HSQUIRRELVM v,SQInteger size)
284 {
285     v->Push(SQArray::Create(_ss(v), size));
286 }
287 
sq_newclass(HSQUIRRELVM v,SQBool hasbase)288 SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase)
289 {
290     SQClass *baseclass = NULL;
291     if(hasbase) {
292         SQObjectPtr &base = stack_get(v,-1);
293         if(sq_type(base) != OT_CLASS)
294             return sq_throwerror(v,_SC("invalid base type"));
295         baseclass = _class(base);
296     }
297     SQClass *newclass = SQClass::Create(_ss(v), baseclass);
298     if(baseclass) v->Pop();
299     v->Push(newclass);
300     return SQ_OK;
301 }
302 
sq_instanceof(HSQUIRRELVM v)303 SQBool sq_instanceof(HSQUIRRELVM v)
304 {
305     SQObjectPtr &inst = stack_get(v,-1);
306     SQObjectPtr &cl = stack_get(v,-2);
307     if(sq_type(inst) != OT_INSTANCE || sq_type(cl) != OT_CLASS)
308         return sq_throwerror(v,_SC("invalid param type"));
309     return _instance(inst)->InstanceOf(_class(cl))?SQTrue:SQFalse;
310 }
311 
sq_arrayappend(HSQUIRRELVM v,SQInteger idx)312 SQRESULT sq_arrayappend(HSQUIRRELVM v,SQInteger idx)
313 {
314     sq_aux_paramscheck(v,2);
315     SQObjectPtr *arr;
316     _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);
317     _array(*arr)->Append(v->GetUp(-1));
318     v->Pop();
319     return SQ_OK;
320 }
321 
sq_arraypop(HSQUIRRELVM v,SQInteger idx,SQBool pushval)322 SQRESULT sq_arraypop(HSQUIRRELVM v,SQInteger idx,SQBool pushval)
323 {
324     sq_aux_paramscheck(v, 1);
325     SQObjectPtr *arr;
326     _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);
327     if(_array(*arr)->Size() > 0) {
328         if(pushval != 0){ v->Push(_array(*arr)->Top()); }
329         _array(*arr)->Pop();
330         return SQ_OK;
331     }
332     return sq_throwerror(v, _SC("empty array"));
333 }
334 
sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize)335 SQRESULT sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize)
336 {
337     sq_aux_paramscheck(v,1);
338     SQObjectPtr *arr;
339     _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);
340     if(newsize >= 0) {
341         _array(*arr)->Resize(newsize);
342         return SQ_OK;
343     }
344     return sq_throwerror(v,_SC("negative size"));
345 }
346 
347 
sq_arrayreverse(HSQUIRRELVM v,SQInteger idx)348 SQRESULT sq_arrayreverse(HSQUIRRELVM v,SQInteger idx)
349 {
350     sq_aux_paramscheck(v, 1);
351     SQObjectPtr *o;
352     _GETSAFE_OBJ(v, idx, OT_ARRAY,o);
353     SQArray *arr = _array(*o);
354     if(arr->Size() > 0) {
355         SQObjectPtr t;
356         SQInteger size = arr->Size();
357         SQInteger n = size >> 1; size -= 1;
358         for(SQInteger i = 0; i < n; i++) {
359             t = arr->_values[i];
360             arr->_values[i] = arr->_values[size-i];
361             arr->_values[size-i] = t;
362         }
363         return SQ_OK;
364     }
365     return SQ_OK;
366 }
367 
sq_arrayremove(HSQUIRRELVM v,SQInteger idx,SQInteger itemidx)368 SQRESULT sq_arrayremove(HSQUIRRELVM v,SQInteger idx,SQInteger itemidx)
369 {
370     sq_aux_paramscheck(v, 1);
371     SQObjectPtr *arr;
372     _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);
373     return _array(*arr)->Remove(itemidx) ? SQ_OK : sq_throwerror(v,_SC("index out of range"));
374 }
375 
sq_arrayinsert(HSQUIRRELVM v,SQInteger idx,SQInteger destpos)376 SQRESULT sq_arrayinsert(HSQUIRRELVM v,SQInteger idx,SQInteger destpos)
377 {
378     sq_aux_paramscheck(v, 1);
379     SQObjectPtr *arr;
380     _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);
381     SQRESULT ret = _array(*arr)->Insert(destpos, v->GetUp(-1)) ? SQ_OK : sq_throwerror(v,_SC("index out of range"));
382     v->Pop();
383     return ret;
384 }
385 
sq_newclosure(HSQUIRRELVM v,SQFUNCTION func,SQUnsignedInteger nfreevars)386 void sq_newclosure(HSQUIRRELVM v,SQFUNCTION func,SQUnsignedInteger nfreevars)
387 {
388     SQNativeClosure *nc = SQNativeClosure::Create(_ss(v), func,nfreevars);
389     nc->_nparamscheck = 0;
390     for(SQUnsignedInteger i = 0; i < nfreevars; i++) {
391         nc->_outervalues[i] = v->Top();
392         v->Pop();
393     }
394     v->Push(SQObjectPtr(nc));
395 }
396 
sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger * nparams,SQUnsignedInteger * nfreevars)397 SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger *nparams,SQUnsignedInteger *nfreevars)
398 {
399     SQObject o = stack_get(v, idx);
400     if(sq_type(o) == OT_CLOSURE) {
401         SQClosure *c = _closure(o);
402         SQFunctionProto *proto = c->_function;
403         *nparams = (SQUnsignedInteger)proto->_nparameters;
404         *nfreevars = (SQUnsignedInteger)proto->_noutervalues;
405         return SQ_OK;
406     }
407     else if(sq_type(o) == OT_NATIVECLOSURE)
408     {
409         SQNativeClosure *c = _nativeclosure(o);
410         *nparams = (SQUnsignedInteger)c->_nparamscheck;
411         *nfreevars = c->_noutervalues;
412         return SQ_OK;
413     }
414     return sq_throwerror(v,_SC("the object is not a closure"));
415 }
416 
sq_setnativeclosurename(HSQUIRRELVM v,SQInteger idx,const SQChar * name)417 SQRESULT sq_setnativeclosurename(HSQUIRRELVM v,SQInteger idx,const SQChar *name)
418 {
419     SQObject o = stack_get(v, idx);
420     if(sq_isnativeclosure(o)) {
421         SQNativeClosure *nc = _nativeclosure(o);
422         nc->_name = SQString::Create(_ss(v),name);
423         return SQ_OK;
424     }
425     return sq_throwerror(v,_SC("the object is not a nativeclosure"));
426 }
427 
sq_setparamscheck(HSQUIRRELVM v,SQInteger nparamscheck,const SQChar * typemask)428 SQRESULT sq_setparamscheck(HSQUIRRELVM v,SQInteger nparamscheck,const SQChar *typemask)
429 {
430     SQObject o = stack_get(v, -1);
431     if(!sq_isnativeclosure(o))
432         return sq_throwerror(v, _SC("native closure expected"));
433     SQNativeClosure *nc = _nativeclosure(o);
434     nc->_nparamscheck = nparamscheck;
435     if(typemask) {
436         SQIntVec res;
437         if(!CompileTypemask(res, typemask))
438             return sq_throwerror(v, _SC("invalid typemask"));
439         nc->_typecheck.copy(res);
440     }
441     else {
442         nc->_typecheck.resize(0);
443     }
444     if(nparamscheck == SQ_MATCHTYPEMASKSTRING) {
445         nc->_nparamscheck = nc->_typecheck.size();
446     }
447     return SQ_OK;
448 }
449 
sq_bindenv(HSQUIRRELVM v,SQInteger idx)450 SQRESULT sq_bindenv(HSQUIRRELVM v,SQInteger idx)
451 {
452     SQObjectPtr &o = stack_get(v,idx);
453     if(!sq_isnativeclosure(o) &&
454         !sq_isclosure(o))
455         return sq_throwerror(v,_SC("the target is not a closure"));
456     SQObjectPtr &env = stack_get(v,-1);
457     if(!sq_istable(env) &&
458         !sq_isarray(env) &&
459         !sq_isclass(env) &&
460         !sq_isinstance(env))
461         return sq_throwerror(v,_SC("invalid environment"));
462     SQWeakRef *w = _refcounted(env)->GetWeakRef(sq_type(env));
463     SQObjectPtr ret;
464     if(sq_isclosure(o)) {
465         SQClosure *c = _closure(o)->Clone();
466         __ObjRelease(c->_env);
467         c->_env = w;
468         __ObjAddRef(c->_env);
469         if(_closure(o)->_base) {
470             c->_base = _closure(o)->_base;
471             __ObjAddRef(c->_base);
472         }
473         ret = c;
474     }
475     else { //then must be a native closure
476         SQNativeClosure *c = _nativeclosure(o)->Clone();
477         __ObjRelease(c->_env);
478         c->_env = w;
479         __ObjAddRef(c->_env);
480         ret = c;
481     }
482     v->Pop();
483     v->Push(ret);
484     return SQ_OK;
485 }
486 
sq_getclosurename(HSQUIRRELVM v,SQInteger idx)487 SQRESULT sq_getclosurename(HSQUIRRELVM v,SQInteger idx)
488 {
489     SQObjectPtr &o = stack_get(v,idx);
490     if(!sq_isnativeclosure(o) &&
491         !sq_isclosure(o))
492         return sq_throwerror(v,_SC("the target is not a closure"));
493     if(sq_isnativeclosure(o))
494     {
495         v->Push(_nativeclosure(o)->_name);
496     }
497     else { //closure
498         v->Push(_closure(o)->_function->_name);
499     }
500     return SQ_OK;
501 }
502 
sq_setclosureroot(HSQUIRRELVM v,SQInteger idx)503 SQRESULT sq_setclosureroot(HSQUIRRELVM v,SQInteger idx)
504 {
505     SQObjectPtr &c = stack_get(v,idx);
506     SQObject o = stack_get(v, -1);
507     if(!sq_isclosure(c)) return sq_throwerror(v, _SC("closure expected"));
508     if(sq_istable(o)) {
509         _closure(c)->SetRoot(_table(o)->GetWeakRef(OT_TABLE));
510         v->Pop();
511         return SQ_OK;
512     }
513     return sq_throwerror(v, _SC("invalid type"));
514 }
515 
sq_getclosureroot(HSQUIRRELVM v,SQInteger idx)516 SQRESULT sq_getclosureroot(HSQUIRRELVM v,SQInteger idx)
517 {
518     SQObjectPtr &c = stack_get(v,idx);
519     if(!sq_isclosure(c)) return sq_throwerror(v, _SC("closure expected"));
520     v->Push(_closure(c)->_root->_obj);
521     return SQ_OK;
522 }
523 
sq_clear(HSQUIRRELVM v,SQInteger idx)524 SQRESULT sq_clear(HSQUIRRELVM v,SQInteger idx)
525 {
526     SQObject &o=stack_get(v,idx);
527     switch(sq_type(o)) {
528         case OT_TABLE: _table(o)->Clear();  break;
529         case OT_ARRAY: _array(o)->Resize(0); break;
530         default:
531             return sq_throwerror(v, _SC("clear only works on table and array"));
532         break;
533 
534     }
535     return SQ_OK;
536 }
537 
sq_pushroottable(HSQUIRRELVM v)538 void sq_pushroottable(HSQUIRRELVM v)
539 {
540     v->Push(v->_roottable);
541 }
542 
sq_pushregistrytable(HSQUIRRELVM v)543 void sq_pushregistrytable(HSQUIRRELVM v)
544 {
545     v->Push(_ss(v)->_registry);
546 }
547 
sq_pushconsttable(HSQUIRRELVM v)548 void sq_pushconsttable(HSQUIRRELVM v)
549 {
550     v->Push(_ss(v)->_consts);
551 }
552 
sq_setroottable(HSQUIRRELVM v)553 SQRESULT sq_setroottable(HSQUIRRELVM v)
554 {
555     SQObject o = stack_get(v, -1);
556     if(sq_istable(o) || sq_isnull(o)) {
557         v->_roottable = o;
558         v->Pop();
559         return SQ_OK;
560     }
561     return sq_throwerror(v, _SC("invalid type"));
562 }
563 
sq_setconsttable(HSQUIRRELVM v)564 SQRESULT sq_setconsttable(HSQUIRRELVM v)
565 {
566     SQObject o = stack_get(v, -1);
567     if(sq_istable(o)) {
568         _ss(v)->_consts = o;
569         v->Pop();
570         return SQ_OK;
571     }
572     return sq_throwerror(v, _SC("invalid type, expected table"));
573 }
574 
sq_setforeignptr(HSQUIRRELVM v,SQUserPointer p)575 void sq_setforeignptr(HSQUIRRELVM v,SQUserPointer p)
576 {
577     v->_foreignptr = p;
578 }
579 
sq_getforeignptr(HSQUIRRELVM v)580 SQUserPointer sq_getforeignptr(HSQUIRRELVM v)
581 {
582     return v->_foreignptr;
583 }
584 
sq_setsharedforeignptr(HSQUIRRELVM v,SQUserPointer p)585 void sq_setsharedforeignptr(HSQUIRRELVM v,SQUserPointer p)
586 {
587     _ss(v)->_foreignptr = p;
588 }
589 
sq_getsharedforeignptr(HSQUIRRELVM v)590 SQUserPointer sq_getsharedforeignptr(HSQUIRRELVM v)
591 {
592     return _ss(v)->_foreignptr;
593 }
594 
sq_setvmreleasehook(HSQUIRRELVM v,SQRELEASEHOOK hook)595 void sq_setvmreleasehook(HSQUIRRELVM v,SQRELEASEHOOK hook)
596 {
597     v->_releasehook = hook;
598 }
599 
sq_getvmreleasehook(HSQUIRRELVM v)600 SQRELEASEHOOK sq_getvmreleasehook(HSQUIRRELVM v)
601 {
602     return v->_releasehook;
603 }
604 
sq_setsharedreleasehook(HSQUIRRELVM v,SQRELEASEHOOK hook)605 void sq_setsharedreleasehook(HSQUIRRELVM v,SQRELEASEHOOK hook)
606 {
607     _ss(v)->_releasehook = hook;
608 }
609 
sq_getsharedreleasehook(HSQUIRRELVM v)610 SQRELEASEHOOK sq_getsharedreleasehook(HSQUIRRELVM v)
611 {
612     return _ss(v)->_releasehook;
613 }
614 
sq_push(HSQUIRRELVM v,SQInteger idx)615 void sq_push(HSQUIRRELVM v,SQInteger idx)
616 {
617     v->Push(stack_get(v, idx));
618 }
619 
sq_gettype(HSQUIRRELVM v,SQInteger idx)620 SQObjectType sq_gettype(HSQUIRRELVM v,SQInteger idx)
621 {
622     return sq_type(stack_get(v, idx));
623 }
624 
sq_typeof(HSQUIRRELVM v,SQInteger idx)625 SQRESULT sq_typeof(HSQUIRRELVM v,SQInteger idx)
626 {
627     SQObjectPtr &o = stack_get(v, idx);
628     SQObjectPtr res;
629     if(!v->TypeOf(o,res)) {
630         return SQ_ERROR;
631     }
632     v->Push(res);
633     return SQ_OK;
634 }
635 
sq_tostring(HSQUIRRELVM v,SQInteger idx)636 SQRESULT sq_tostring(HSQUIRRELVM v,SQInteger idx)
637 {
638     SQObjectPtr &o = stack_get(v, idx);
639     SQObjectPtr res;
640     if(!v->ToString(o,res)) {
641         return SQ_ERROR;
642     }
643     v->Push(res);
644     return SQ_OK;
645 }
646 
sq_tobool(HSQUIRRELVM v,SQInteger idx,SQBool * b)647 void sq_tobool(HSQUIRRELVM v, SQInteger idx, SQBool *b)
648 {
649     SQObjectPtr &o = stack_get(v, idx);
650     *b = SQVM::IsFalse(o)?SQFalse:SQTrue;
651 }
652 
sq_getinteger(HSQUIRRELVM v,SQInteger idx,SQInteger * i)653 SQRESULT sq_getinteger(HSQUIRRELVM v,SQInteger idx,SQInteger *i)
654 {
655     SQObjectPtr &o = stack_get(v, idx);
656     if(sq_isnumeric(o)) {
657         *i = tointeger(o);
658         return SQ_OK;
659     }
660     if(sq_isbool(o)) {
661         *i = SQVM::IsFalse(o)?SQFalse:SQTrue;
662         return SQ_OK;
663     }
664     return SQ_ERROR;
665 }
666 
sq_getfloat(HSQUIRRELVM v,SQInteger idx,SQFloat * f)667 SQRESULT sq_getfloat(HSQUIRRELVM v,SQInteger idx,SQFloat *f)
668 {
669     SQObjectPtr &o = stack_get(v, idx);
670     if(sq_isnumeric(o)) {
671         *f = tofloat(o);
672         return SQ_OK;
673     }
674     return SQ_ERROR;
675 }
676 
sq_getbool(HSQUIRRELVM v,SQInteger idx,SQBool * b)677 SQRESULT sq_getbool(HSQUIRRELVM v,SQInteger idx,SQBool *b)
678 {
679     SQObjectPtr &o = stack_get(v, idx);
680     if(sq_isbool(o)) {
681         *b = _integer(o);
682         return SQ_OK;
683     }
684     return SQ_ERROR;
685 }
686 
sq_getstringandsize(HSQUIRRELVM v,SQInteger idx,const SQChar ** c,SQInteger * size)687 SQRESULT sq_getstringandsize(HSQUIRRELVM v,SQInteger idx,const SQChar **c,SQInteger *size)
688 {
689     SQObjectPtr *o = NULL;
690     _GETSAFE_OBJ(v, idx, OT_STRING,o);
691     *c = _stringval(*o);
692     *size = _string(*o)->_len;
693     return SQ_OK;
694 }
695 
sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar ** c)696 SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c)
697 {
698     SQObjectPtr *o = NULL;
699     _GETSAFE_OBJ(v, idx, OT_STRING,o);
700     *c = _stringval(*o);
701     return SQ_OK;
702 }
703 
sq_getthread(HSQUIRRELVM v,SQInteger idx,HSQUIRRELVM * thread)704 SQRESULT sq_getthread(HSQUIRRELVM v,SQInteger idx,HSQUIRRELVM *thread)
705 {
706     SQObjectPtr *o = NULL;
707     _GETSAFE_OBJ(v, idx, OT_THREAD,o);
708     *thread = _thread(*o);
709     return SQ_OK;
710 }
711 
sq_clone(HSQUIRRELVM v,SQInteger idx)712 SQRESULT sq_clone(HSQUIRRELVM v,SQInteger idx)
713 {
714     SQObjectPtr &o = stack_get(v,idx);
715     v->PushNull();
716     if(!v->Clone(o, stack_get(v, -1))){
717         v->Pop();
718         return SQ_ERROR;
719     }
720     return SQ_OK;
721 }
722 
sq_getsize(HSQUIRRELVM v,SQInteger idx)723 SQInteger sq_getsize(HSQUIRRELVM v, SQInteger idx)
724 {
725     SQObjectPtr &o = stack_get(v, idx);
726     SQObjectType type = sq_type(o);
727     switch(type) {
728     case OT_STRING:     return _string(o)->_len;
729     case OT_TABLE:      return _table(o)->CountUsed();
730     case OT_ARRAY:      return _array(o)->Size();
731     case OT_USERDATA:   return _userdata(o)->_size;
732     case OT_INSTANCE:   return _instance(o)->_class->_udsize;
733     case OT_CLASS:      return _class(o)->_udsize;
734     default:
735         return sq_aux_invalidtype(v, type);
736     }
737 }
738 
sq_gethash(HSQUIRRELVM v,SQInteger idx)739 SQHash sq_gethash(HSQUIRRELVM v, SQInteger idx)
740 {
741     SQObjectPtr &o = stack_get(v, idx);
742     return HashObj(o);
743 }
744 
sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer * p,SQUserPointer * typetag)745 SQRESULT sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p,SQUserPointer *typetag)
746 {
747     SQObjectPtr *o = NULL;
748     _GETSAFE_OBJ(v, idx, OT_USERDATA,o);
749     (*p) = _userdataval(*o);
750     if(typetag) *typetag = _userdata(*o)->_typetag;
751     return SQ_OK;
752 }
753 
sq_settypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer typetag)754 SQRESULT sq_settypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer typetag)
755 {
756     SQObjectPtr &o = stack_get(v,idx);
757     switch(sq_type(o)) {
758         case OT_USERDATA:   _userdata(o)->_typetag = typetag;   break;
759         case OT_CLASS:      _class(o)->_typetag = typetag;      break;
760         default:            return sq_throwerror(v,_SC("invalid object type"));
761     }
762     return SQ_OK;
763 }
764 
sq_getobjtypetag(const HSQOBJECT * o,SQUserPointer * typetag)765 SQRESULT sq_getobjtypetag(const HSQOBJECT *o,SQUserPointer * typetag)
766 {
767   switch(sq_type(*o)) {
768     case OT_INSTANCE: *typetag = _instance(*o)->_class->_typetag; break;
769     case OT_USERDATA: *typetag = _userdata(*o)->_typetag; break;
770     case OT_CLASS:    *typetag = _class(*o)->_typetag; break;
771     default: return SQ_ERROR;
772   }
773   return SQ_OK;
774 }
775 
sq_gettypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer * typetag)776 SQRESULT sq_gettypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer *typetag)
777 {
778     SQObjectPtr &o = stack_get(v,idx);
779     if (SQ_FAILED(sq_getobjtypetag(&o, typetag)))
780         return SQ_ERROR;// this is not an error it should be a bool but would break backward compatibility
781     return SQ_OK;
782 }
783 
sq_getuserpointer(HSQUIRRELVM v,SQInteger idx,SQUserPointer * p)784 SQRESULT sq_getuserpointer(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p)
785 {
786     SQObjectPtr *o = NULL;
787     _GETSAFE_OBJ(v, idx, OT_USERPOINTER,o);
788     (*p) = _userpointer(*o);
789     return SQ_OK;
790 }
791 
sq_setinstanceup(HSQUIRRELVM v,SQInteger idx,SQUserPointer p)792 SQRESULT sq_setinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer p)
793 {
794     SQObjectPtr &o = stack_get(v,idx);
795     if(sq_type(o) != OT_INSTANCE) return sq_throwerror(v,_SC("the object is not a class instance"));
796     _instance(o)->_userpointer = p;
797     return SQ_OK;
798 }
799 
sq_setclassudsize(HSQUIRRELVM v,SQInteger idx,SQInteger udsize)800 SQRESULT sq_setclassudsize(HSQUIRRELVM v, SQInteger idx, SQInteger udsize)
801 {
802     SQObjectPtr &o = stack_get(v,idx);
803     if(sq_type(o) != OT_CLASS) return sq_throwerror(v,_SC("the object is not a class"));
804     if(_class(o)->_locked) return sq_throwerror(v,_SC("the class is locked"));
805     _class(o)->_udsize = udsize;
806     return SQ_OK;
807 }
808 
809 
sq_getinstanceup(HSQUIRRELVM v,SQInteger idx,SQUserPointer * p,SQUserPointer typetag)810 SQRESULT sq_getinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p,SQUserPointer typetag)
811 {
812     SQObjectPtr &o = stack_get(v,idx);
813     if(sq_type(o) != OT_INSTANCE) return sq_throwerror(v,_SC("the object is not a class instance"));
814     (*p) = _instance(o)->_userpointer;
815     if(typetag != 0) {
816         SQClass *cl = _instance(o)->_class;
817         do{
818             if(cl->_typetag == typetag)
819                 return SQ_OK;
820             cl = cl->_base;
821         }while(cl != NULL);
822         return sq_throwerror(v,_SC("invalid type tag"));
823     }
824     return SQ_OK;
825 }
826 
sq_gettop(HSQUIRRELVM v)827 SQInteger sq_gettop(HSQUIRRELVM v)
828 {
829     return (v->_top) - v->_stackbase;
830 }
831 
sq_settop(HSQUIRRELVM v,SQInteger newtop)832 void sq_settop(HSQUIRRELVM v, SQInteger newtop)
833 {
834     SQInteger top = sq_gettop(v);
835     if(top > newtop)
836         sq_pop(v, top - newtop);
837     else
838         while(top++ < newtop) sq_pushnull(v);
839 }
840 
sq_pop(HSQUIRRELVM v,SQInteger nelemstopop)841 void sq_pop(HSQUIRRELVM v, SQInteger nelemstopop)
842 {
843     assert(v->_top >= nelemstopop);
844     v->Pop(nelemstopop);
845 }
846 
sq_poptop(HSQUIRRELVM v)847 void sq_poptop(HSQUIRRELVM v)
848 {
849     assert(v->_top >= 1);
850     v->Pop();
851 }
852 
853 
sq_remove(HSQUIRRELVM v,SQInteger idx)854 void sq_remove(HSQUIRRELVM v, SQInteger idx)
855 {
856     v->Remove(idx);
857 }
858 
sq_cmp(HSQUIRRELVM v)859 SQInteger sq_cmp(HSQUIRRELVM v)
860 {
861     SQInteger res;
862     v->ObjCmp(stack_get(v, -1), stack_get(v, -2),res);
863     return res;
864 }
865 
sq_newslot(HSQUIRRELVM v,SQInteger idx,SQBool bstatic)866 SQRESULT sq_newslot(HSQUIRRELVM v, SQInteger idx, SQBool bstatic)
867 {
868     sq_aux_paramscheck(v, 3);
869     SQObjectPtr &self = stack_get(v, idx);
870     if(sq_type(self) == OT_TABLE || sq_type(self) == OT_CLASS) {
871         SQObjectPtr &key = v->GetUp(-2);
872         if(sq_type(key) == OT_NULL) return sq_throwerror(v, _SC("null is not a valid key"));
873         v->NewSlot(self, key, v->GetUp(-1),bstatic?true:false);
874         v->Pop(2);
875     }
876     return SQ_OK;
877 }
878 
sq_deleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval)879 SQRESULT sq_deleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval)
880 {
881     sq_aux_paramscheck(v, 2);
882     SQObjectPtr *self;
883     _GETSAFE_OBJ(v, idx, OT_TABLE,self);
884     SQObjectPtr &key = v->GetUp(-1);
885     if(sq_type(key) == OT_NULL) return sq_throwerror(v, _SC("null is not a valid key"));
886     SQObjectPtr res;
887     if(!v->DeleteSlot(*self, key, res)){
888         v->Pop();
889         return SQ_ERROR;
890     }
891     if(pushval) v->GetUp(-1) = res;
892     else v->Pop();
893     return SQ_OK;
894 }
895 
sq_set(HSQUIRRELVM v,SQInteger idx)896 SQRESULT sq_set(HSQUIRRELVM v,SQInteger idx)
897 {
898     SQObjectPtr &self = stack_get(v, idx);
899     if(v->Set(self, v->GetUp(-2), v->GetUp(-1),DONT_FALL_BACK)) {
900         v->Pop(2);
901         return SQ_OK;
902     }
903     return SQ_ERROR;
904 }
905 
sq_rawset(HSQUIRRELVM v,SQInteger idx)906 SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx)
907 {
908     SQObjectPtr &self = stack_get(v, idx);
909     SQObjectPtr &key = v->GetUp(-2);
910     if(sq_type(key) == OT_NULL) {
911         v->Pop(2);
912         return sq_throwerror(v, _SC("null key"));
913     }
914     switch(sq_type(self)) {
915     case OT_TABLE:
916         _table(self)->NewSlot(key, v->GetUp(-1));
917         v->Pop(2);
918         return SQ_OK;
919     break;
920     case OT_CLASS:
921         _class(self)->NewSlot(_ss(v), key, v->GetUp(-1),false);
922         v->Pop(2);
923         return SQ_OK;
924     break;
925     case OT_INSTANCE:
926         if(_instance(self)->Set(key, v->GetUp(-1))) {
927             v->Pop(2);
928             return SQ_OK;
929         }
930     break;
931     case OT_ARRAY:
932         if(v->Set(self, key, v->GetUp(-1),false)) {
933             v->Pop(2);
934             return SQ_OK;
935         }
936     break;
937     default:
938         v->Pop(2);
939         return sq_throwerror(v, _SC("rawset works only on array/table/class and instance"));
940     }
941     v->Raise_IdxError(v->GetUp(-2));return SQ_ERROR;
942 }
943 
sq_newmember(HSQUIRRELVM v,SQInteger idx,SQBool bstatic)944 SQRESULT sq_newmember(HSQUIRRELVM v,SQInteger idx,SQBool bstatic)
945 {
946     SQObjectPtr &self = stack_get(v, idx);
947     if(sq_type(self) != OT_CLASS) return sq_throwerror(v, _SC("new member only works with classes"));
948     SQObjectPtr &key = v->GetUp(-3);
949     if(sq_type(key) == OT_NULL) return sq_throwerror(v, _SC("null key"));
950     if(!v->NewSlotA(self,key,v->GetUp(-2),v->GetUp(-1),bstatic?true:false,false)) {
951         v->Pop(3);
952         return SQ_ERROR;
953     }
954     v->Pop(3);
955     return SQ_OK;
956 }
957 
sq_rawnewmember(HSQUIRRELVM v,SQInteger idx,SQBool bstatic)958 SQRESULT sq_rawnewmember(HSQUIRRELVM v,SQInteger idx,SQBool bstatic)
959 {
960     SQObjectPtr &self = stack_get(v, idx);
961     if(sq_type(self) != OT_CLASS) return sq_throwerror(v, _SC("new member only works with classes"));
962     SQObjectPtr &key = v->GetUp(-3);
963     if(sq_type(key) == OT_NULL) return sq_throwerror(v, _SC("null key"));
964     if(!v->NewSlotA(self,key,v->GetUp(-2),v->GetUp(-1),bstatic?true:false,true)) {
965         v->Pop(3);
966         return SQ_ERROR;
967     }
968     v->Pop(3);
969     return SQ_OK;
970 }
971 
sq_setdelegate(HSQUIRRELVM v,SQInteger idx)972 SQRESULT sq_setdelegate(HSQUIRRELVM v,SQInteger idx)
973 {
974     SQObjectPtr &self = stack_get(v, idx);
975     SQObjectPtr &mt = v->GetUp(-1);
976     SQObjectType type = sq_type(self);
977     switch(type) {
978     case OT_TABLE:
979         if(sq_type(mt) == OT_TABLE) {
980             if(!_table(self)->SetDelegate(_table(mt))) {
981                 return sq_throwerror(v, _SC("delagate cycle"));
982             }
983             v->Pop();
984         }
985         else if(sq_type(mt)==OT_NULL) {
986             _table(self)->SetDelegate(NULL); v->Pop(); }
987         else return sq_aux_invalidtype(v,type);
988         break;
989     case OT_USERDATA:
990         if(sq_type(mt)==OT_TABLE) {
991             _userdata(self)->SetDelegate(_table(mt)); v->Pop(); }
992         else if(sq_type(mt)==OT_NULL) {
993             _userdata(self)->SetDelegate(NULL); v->Pop(); }
994         else return sq_aux_invalidtype(v, type);
995         break;
996     default:
997             return sq_aux_invalidtype(v, type);
998         break;
999     }
1000     return SQ_OK;
1001 }
1002 
sq_rawdeleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval)1003 SQRESULT sq_rawdeleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval)
1004 {
1005     sq_aux_paramscheck(v, 2);
1006     SQObjectPtr *self;
1007     _GETSAFE_OBJ(v, idx, OT_TABLE,self);
1008     SQObjectPtr &key = v->GetUp(-1);
1009     SQObjectPtr t;
1010     if(_table(*self)->Get(key,t)) {
1011         _table(*self)->Remove(key);
1012     }
1013     if(pushval != 0)
1014         v->GetUp(-1) = t;
1015     else
1016         v->Pop();
1017     return SQ_OK;
1018 }
1019 
sq_getdelegate(HSQUIRRELVM v,SQInteger idx)1020 SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx)
1021 {
1022     SQObjectPtr &self=stack_get(v,idx);
1023     switch(sq_type(self)){
1024     case OT_TABLE:
1025     case OT_USERDATA:
1026         if(!_delegable(self)->_delegate){
1027             v->PushNull();
1028             break;
1029         }
1030         v->Push(SQObjectPtr(_delegable(self)->_delegate));
1031         break;
1032     default: return sq_throwerror(v,_SC("wrong type")); break;
1033     }
1034     return SQ_OK;
1035 
1036 }
1037 
sq_get(HSQUIRRELVM v,SQInteger idx)1038 SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx)
1039 {
1040     SQObjectPtr &self=stack_get(v,idx);
1041     SQObjectPtr &obj = v->GetUp(-1);
1042     if(v->Get(self,obj,obj,false,DONT_FALL_BACK))
1043         return SQ_OK;
1044     v->Pop();
1045     return SQ_ERROR;
1046 }
1047 
sq_rawget(HSQUIRRELVM v,SQInteger idx)1048 SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx)
1049 {
1050     SQObjectPtr &self=stack_get(v,idx);
1051     SQObjectPtr &obj = v->GetUp(-1);
1052     switch(sq_type(self)) {
1053     case OT_TABLE:
1054         if(_table(self)->Get(obj,obj))
1055             return SQ_OK;
1056         break;
1057     case OT_CLASS:
1058         if(_class(self)->Get(obj,obj))
1059             return SQ_OK;
1060         break;
1061     case OT_INSTANCE:
1062         if(_instance(self)->Get(obj,obj))
1063             return SQ_OK;
1064         break;
1065     case OT_ARRAY:{
1066         if(sq_isnumeric(obj)){
1067             if(_array(self)->Get(tointeger(obj),obj)) {
1068                 return SQ_OK;
1069             }
1070         }
1071         else {
1072             v->Pop();
1073             return sq_throwerror(v,_SC("invalid index type for an array"));
1074         }
1075                   }
1076         break;
1077     default:
1078         v->Pop();
1079         return sq_throwerror(v,_SC("rawget works only on array/table/instance and class"));
1080     }
1081     v->Pop();
1082     return sq_throwerror(v,_SC("the index doesn't exist"));
1083 }
1084 
sq_getstackobj(HSQUIRRELVM v,SQInteger idx,HSQOBJECT * po)1085 SQRESULT sq_getstackobj(HSQUIRRELVM v,SQInteger idx,HSQOBJECT *po)
1086 {
1087     *po=stack_get(v,idx);
1088     return SQ_OK;
1089 }
1090 
sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedInteger idx)1091 const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedInteger idx)
1092 {
1093     SQUnsignedInteger cstksize=v->_callsstacksize;
1094     SQUnsignedInteger lvl=(cstksize-level)-1;
1095     SQInteger stackbase=v->_stackbase;
1096     if(lvl<cstksize){
1097         for(SQUnsignedInteger i=0;i<level;i++){
1098             SQVM::CallInfo &ci=v->_callsstack[(cstksize-i)-1];
1099             stackbase-=ci._prevstkbase;
1100         }
1101         SQVM::CallInfo &ci=v->_callsstack[lvl];
1102         if(sq_type(ci._closure)!=OT_CLOSURE)
1103             return NULL;
1104         SQClosure *c=_closure(ci._closure);
1105         SQFunctionProto *func=c->_function;
1106         if(func->_noutervalues > (SQInteger)idx) {
1107             v->Push(*_outer(c->_outervalues[idx])->_valptr);
1108             return _stringval(func->_outervalues[idx]._name);
1109         }
1110         idx -= func->_noutervalues;
1111         return func->GetLocal(v,stackbase,idx,(SQInteger)(ci._ip-func->_instructions)-1);
1112     }
1113     return NULL;
1114 }
1115 
sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj)1116 void sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj)
1117 {
1118     v->Push(SQObjectPtr(obj));
1119 }
1120 
sq_resetobject(HSQOBJECT * po)1121 void sq_resetobject(HSQOBJECT *po)
1122 {
1123     po->_unVal.pUserPointer=NULL;po->_type=OT_NULL;
1124 }
1125 
sq_throwerror(HSQUIRRELVM v,const SQChar * err)1126 SQRESULT sq_throwerror(HSQUIRRELVM v,const SQChar *err)
1127 {
1128     v->_lasterror=SQString::Create(_ss(v),err);
1129     return SQ_ERROR;
1130 }
1131 
sq_throwobject(HSQUIRRELVM v)1132 SQRESULT sq_throwobject(HSQUIRRELVM v)
1133 {
1134     v->_lasterror = v->GetUp(-1);
1135     v->Pop();
1136     return SQ_ERROR;
1137 }
1138 
1139 
sq_reseterror(HSQUIRRELVM v)1140 void sq_reseterror(HSQUIRRELVM v)
1141 {
1142     v->_lasterror.Null();
1143 }
1144 
sq_getlasterror(HSQUIRRELVM v)1145 void sq_getlasterror(HSQUIRRELVM v)
1146 {
1147     v->Push(v->_lasterror);
1148 }
1149 
sq_reservestack(HSQUIRRELVM v,SQInteger nsize)1150 SQRESULT sq_reservestack(HSQUIRRELVM v,SQInteger nsize)
1151 {
1152     if (((SQUnsignedInteger)v->_top + nsize) > v->_stack.size()) {
1153         if(v->_nmetamethodscall) {
1154             return sq_throwerror(v,_SC("cannot resize stack while in a metamethod"));
1155         }
1156         v->_stack.resize(v->_stack.size() + ((v->_top + nsize) - v->_stack.size()));
1157     }
1158     return SQ_OK;
1159 }
1160 
sq_resume(HSQUIRRELVM v,SQBool retval,SQBool raiseerror)1161 SQRESULT sq_resume(HSQUIRRELVM v,SQBool retval,SQBool raiseerror)
1162 {
1163     if (sq_type(v->GetUp(-1)) == OT_GENERATOR)
1164     {
1165         v->PushNull(); //retval
1166         if (!v->Execute(v->GetUp(-2), 0, v->_top, v->GetUp(-1), raiseerror, SQVM::ET_RESUME_GENERATOR))
1167         {v->Raise_Error(v->_lasterror); return SQ_ERROR;}
1168         if(!retval)
1169             v->Pop();
1170         return SQ_OK;
1171     }
1172     return sq_throwerror(v,_SC("only generators can be resumed"));
1173 }
1174 
sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval,SQBool raiseerror)1175 SQRESULT sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval,SQBool raiseerror)
1176 {
1177     SQObjectPtr res;
1178     if(v->Call(v->GetUp(-(params+1)),params,v->_top-params,res,raiseerror?true:false)){
1179 
1180         if(!v->_suspended) {
1181             v->Pop(params);//pop args
1182         }
1183         if(retval){
1184             v->Push(res); return SQ_OK;
1185         }
1186         return SQ_OK;
1187     }
1188     else {
1189         v->Pop(params);
1190         return SQ_ERROR;
1191     }
1192     if(!v->_suspended)
1193         v->Pop(params);
1194     return sq_throwerror(v,_SC("call failed"));
1195 }
1196 
sq_tailcall(HSQUIRRELVM v,SQInteger nparams)1197 SQRESULT sq_tailcall(HSQUIRRELVM v, SQInteger nparams)
1198 {
1199 	SQObjectPtr &res = v->GetUp(-(nparams + 1));
1200 	if (sq_type(res) != OT_CLOSURE) {
1201 		return sq_throwerror(v, _SC("only closure can be tail called"));
1202 	}
1203 	SQClosure *clo = _closure(res);
1204 	if (clo->_function->_bgenerator)
1205 	{
1206 		return sq_throwerror(v, _SC("generators cannot be tail called"));
1207 	}
1208 
1209 	SQInteger stackbase = (v->_top - nparams) - v->_stackbase;
1210 	if (!v->TailCall(clo, stackbase, nparams)) {
1211 		return SQ_ERROR;
1212 	}
1213 	return SQ_TAILCALL_FLAG;
1214 }
1215 
sq_suspendvm(HSQUIRRELVM v)1216 SQRESULT sq_suspendvm(HSQUIRRELVM v)
1217 {
1218     return v->Suspend();
1219 }
1220 
sq_wakeupvm(HSQUIRRELVM v,SQBool wakeupret,SQBool retval,SQBool raiseerror,SQBool throwerror)1221 SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool wakeupret,SQBool retval,SQBool raiseerror,SQBool throwerror)
1222 {
1223     SQObjectPtr ret;
1224     if(!v->_suspended)
1225         return sq_throwerror(v,_SC("cannot resume a vm that is not running any code"));
1226     SQInteger target = v->_suspended_target;
1227     if(wakeupret) {
1228         if(target != -1) {
1229             v->GetAt(v->_stackbase+v->_suspended_target)=v->GetUp(-1); //retval
1230         }
1231         v->Pop();
1232     } else if(target != -1) { v->GetAt(v->_stackbase+v->_suspended_target).Null(); }
1233     SQObjectPtr dummy;
1234     if(!v->Execute(dummy,-1,-1,ret,raiseerror,throwerror?SQVM::ET_RESUME_THROW_VM : SQVM::ET_RESUME_VM)) {
1235         return SQ_ERROR;
1236     }
1237     if(retval)
1238         v->Push(ret);
1239     return SQ_OK;
1240 }
1241 
sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook)1242 void sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook)
1243 {
1244     SQObjectPtr &ud=stack_get(v,idx);
1245     switch(sq_type(ud) ) {
1246     case OT_USERDATA:   _userdata(ud)->_hook = hook;    break;
1247     case OT_INSTANCE:   _instance(ud)->_hook = hook;    break;
1248     case OT_CLASS:      _class(ud)->_hook = hook;       break;
1249     default: return;
1250     }
1251 }
1252 
sq_getreleasehook(HSQUIRRELVM v,SQInteger idx)1253 SQRELEASEHOOK sq_getreleasehook(HSQUIRRELVM v,SQInteger idx)
1254 {
1255     SQObjectPtr &ud=stack_get(v,idx);
1256     switch(sq_type(ud) ) {
1257     case OT_USERDATA:   return _userdata(ud)->_hook;    break;
1258     case OT_INSTANCE:   return _instance(ud)->_hook;    break;
1259     case OT_CLASS:      return _class(ud)->_hook;       break;
1260     default: return NULL;
1261     }
1262 }
1263 
sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f)1264 void sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f)
1265 {
1266     _ss(v)->_compilererrorhandler = f;
1267 }
1268 
sq_writeclosure(HSQUIRRELVM v,SQWRITEFUNC w,SQUserPointer up)1269 SQRESULT sq_writeclosure(HSQUIRRELVM v,SQWRITEFUNC w,SQUserPointer up)
1270 {
1271     SQObjectPtr *o = NULL;
1272     _GETSAFE_OBJ(v, -1, OT_CLOSURE,o);
1273     unsigned short tag = SQ_BYTECODE_STREAM_TAG;
1274     if(_closure(*o)->_function->_noutervalues)
1275         return sq_throwerror(v,_SC("a closure with free variables bound cannot be serialized"));
1276     if(w(up,&tag,2) != 2)
1277         return sq_throwerror(v,_SC("io error"));
1278     if(!_closure(*o)->Save(v,up,w))
1279         return SQ_ERROR;
1280     return SQ_OK;
1281 }
1282 
sq_readclosure(HSQUIRRELVM v,SQREADFUNC r,SQUserPointer up)1283 SQRESULT sq_readclosure(HSQUIRRELVM v,SQREADFUNC r,SQUserPointer up)
1284 {
1285     SQObjectPtr closure;
1286 
1287     unsigned short tag;
1288     if(r(up,&tag,2) != 2)
1289         return sq_throwerror(v,_SC("io error"));
1290     if(tag != SQ_BYTECODE_STREAM_TAG)
1291         return sq_throwerror(v,_SC("invalid stream"));
1292     if(!SQClosure::Load(v,up,r,closure))
1293         return SQ_ERROR;
1294     v->Push(closure);
1295     return SQ_OK;
1296 }
1297 
sq_getscratchpad(HSQUIRRELVM v,SQInteger minsize)1298 SQChar *sq_getscratchpad(HSQUIRRELVM v,SQInteger minsize)
1299 {
1300     return _ss(v)->GetScratchPad(minsize);
1301 }
1302 
sq_resurrectunreachable(HSQUIRRELVM v)1303 SQRESULT sq_resurrectunreachable(HSQUIRRELVM v)
1304 {
1305 #ifndef NO_GARBAGE_COLLECTOR
1306     _ss(v)->ResurrectUnreachable(v);
1307     return SQ_OK;
1308 #else
1309     return sq_throwerror(v,_SC("sq_resurrectunreachable requires a garbage collector build"));
1310 #endif
1311 }
1312 
sq_collectgarbage(HSQUIRRELVM v)1313 SQInteger sq_collectgarbage(HSQUIRRELVM v)
1314 {
1315 #ifndef NO_GARBAGE_COLLECTOR
1316     return _ss(v)->CollectGarbage(v);
1317 #else
1318     return -1;
1319 #endif
1320 }
1321 
sq_getcallee(HSQUIRRELVM v)1322 SQRESULT sq_getcallee(HSQUIRRELVM v)
1323 {
1324     if(v->_callsstacksize > 1)
1325     {
1326         v->Push(v->_callsstack[v->_callsstacksize - 2]._closure);
1327         return SQ_OK;
1328     }
1329     return sq_throwerror(v,_SC("no closure in the calls stack"));
1330 }
1331 
sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval)1332 const SQChar *sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval)
1333 {
1334     SQObjectPtr &self=stack_get(v,idx);
1335     const SQChar *name = NULL;
1336     switch(sq_type(self))
1337     {
1338     case OT_CLOSURE:{
1339         SQClosure *clo = _closure(self);
1340         SQFunctionProto *fp = clo->_function;
1341         if(((SQUnsignedInteger)fp->_noutervalues) > nval) {
1342             v->Push(*(_outer(clo->_outervalues[nval])->_valptr));
1343             SQOuterVar &ov = fp->_outervalues[nval];
1344             name = _stringval(ov._name);
1345         }
1346                     }
1347         break;
1348     case OT_NATIVECLOSURE:{
1349         SQNativeClosure *clo = _nativeclosure(self);
1350         if(clo->_noutervalues > nval) {
1351             v->Push(clo->_outervalues[nval]);
1352             name = _SC("@NATIVE");
1353         }
1354                           }
1355         break;
1356     default: break; //shutup compiler
1357     }
1358     return name;
1359 }
1360 
sq_setfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval)1361 SQRESULT sq_setfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval)
1362 {
1363     SQObjectPtr &self=stack_get(v,idx);
1364     switch(sq_type(self))
1365     {
1366     case OT_CLOSURE:{
1367         SQFunctionProto *fp = _closure(self)->_function;
1368         if(((SQUnsignedInteger)fp->_noutervalues) > nval){
1369             *(_outer(_closure(self)->_outervalues[nval])->_valptr) = stack_get(v,-1);
1370         }
1371         else return sq_throwerror(v,_SC("invalid free var index"));
1372                     }
1373         break;
1374     case OT_NATIVECLOSURE:
1375         if(_nativeclosure(self)->_noutervalues > nval){
1376             _nativeclosure(self)->_outervalues[nval] = stack_get(v,-1);
1377         }
1378         else return sq_throwerror(v,_SC("invalid free var index"));
1379         break;
1380     default:
1381         return sq_aux_invalidtype(v, sq_type(self));
1382     }
1383     v->Pop();
1384     return SQ_OK;
1385 }
1386 
sq_setattributes(HSQUIRRELVM v,SQInteger idx)1387 SQRESULT sq_setattributes(HSQUIRRELVM v,SQInteger idx)
1388 {
1389     SQObjectPtr *o = NULL;
1390     _GETSAFE_OBJ(v, idx, OT_CLASS,o);
1391     SQObjectPtr &key = stack_get(v,-2);
1392     SQObjectPtr &val = stack_get(v,-1);
1393     SQObjectPtr attrs;
1394     if(sq_type(key) == OT_NULL) {
1395         attrs = _class(*o)->_attributes;
1396         _class(*o)->_attributes = val;
1397         v->Pop(2);
1398         v->Push(attrs);
1399         return SQ_OK;
1400     }else if(_class(*o)->GetAttributes(key,attrs)) {
1401         _class(*o)->SetAttributes(key,val);
1402         v->Pop(2);
1403         v->Push(attrs);
1404         return SQ_OK;
1405     }
1406     return sq_throwerror(v,_SC("wrong index"));
1407 }
1408 
sq_getattributes(HSQUIRRELVM v,SQInteger idx)1409 SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx)
1410 {
1411     SQObjectPtr *o = NULL;
1412     _GETSAFE_OBJ(v, idx, OT_CLASS,o);
1413     SQObjectPtr &key = stack_get(v,-1);
1414     SQObjectPtr attrs;
1415     if(sq_type(key) == OT_NULL) {
1416         attrs = _class(*o)->_attributes;
1417         v->Pop();
1418         v->Push(attrs);
1419         return SQ_OK;
1420     }
1421     else if(_class(*o)->GetAttributes(key,attrs)) {
1422         v->Pop();
1423         v->Push(attrs);
1424         return SQ_OK;
1425     }
1426     return sq_throwerror(v,_SC("wrong index"));
1427 }
1428 
sq_getmemberhandle(HSQUIRRELVM v,SQInteger idx,HSQMEMBERHANDLE * handle)1429 SQRESULT sq_getmemberhandle(HSQUIRRELVM v,SQInteger idx,HSQMEMBERHANDLE *handle)
1430 {
1431     SQObjectPtr *o = NULL;
1432     _GETSAFE_OBJ(v, idx, OT_CLASS,o);
1433     SQObjectPtr &key = stack_get(v,-1);
1434     SQTable *m = _class(*o)->_members;
1435     SQObjectPtr val;
1436     if(m->Get(key,val)) {
1437         handle->_static = _isfield(val) ? SQFalse : SQTrue;
1438         handle->_index = _member_idx(val);
1439         v->Pop();
1440         return SQ_OK;
1441     }
1442     return sq_throwerror(v,_SC("wrong index"));
1443 }
1444 
_getmemberbyhandle(HSQUIRRELVM v,SQObjectPtr & self,const HSQMEMBERHANDLE * handle,SQObjectPtr * & val)1445 SQRESULT _getmemberbyhandle(HSQUIRRELVM v,SQObjectPtr &self,const HSQMEMBERHANDLE *handle,SQObjectPtr *&val)
1446 {
1447     switch(sq_type(self)) {
1448         case OT_INSTANCE: {
1449                 SQInstance *i = _instance(self);
1450                 if(handle->_static) {
1451                     SQClass *c = i->_class;
1452                     val = &c->_methods[handle->_index].val;
1453                 }
1454                 else {
1455                     val = &i->_values[handle->_index];
1456 
1457                 }
1458             }
1459             break;
1460         case OT_CLASS: {
1461                 SQClass *c = _class(self);
1462                 if(handle->_static) {
1463                     val = &c->_methods[handle->_index].val;
1464                 }
1465                 else {
1466                     val = &c->_defaultvalues[handle->_index].val;
1467                 }
1468             }
1469             break;
1470         default:
1471             return sq_throwerror(v,_SC("wrong type(expected class or instance)"));
1472     }
1473     return SQ_OK;
1474 }
1475 
sq_getbyhandle(HSQUIRRELVM v,SQInteger idx,const HSQMEMBERHANDLE * handle)1476 SQRESULT sq_getbyhandle(HSQUIRRELVM v,SQInteger idx,const HSQMEMBERHANDLE *handle)
1477 {
1478     SQObjectPtr &self = stack_get(v,idx);
1479     SQObjectPtr *val = NULL;
1480     if(SQ_FAILED(_getmemberbyhandle(v,self,handle,val))) {
1481         return SQ_ERROR;
1482     }
1483     v->Push(_realval(*val));
1484     return SQ_OK;
1485 }
1486 
sq_setbyhandle(HSQUIRRELVM v,SQInteger idx,const HSQMEMBERHANDLE * handle)1487 SQRESULT sq_setbyhandle(HSQUIRRELVM v,SQInteger idx,const HSQMEMBERHANDLE *handle)
1488 {
1489     SQObjectPtr &self = stack_get(v,idx);
1490     SQObjectPtr &newval = stack_get(v,-1);
1491     SQObjectPtr *val = NULL;
1492     if(SQ_FAILED(_getmemberbyhandle(v,self,handle,val))) {
1493         return SQ_ERROR;
1494     }
1495     *val = newval;
1496     v->Pop();
1497     return SQ_OK;
1498 }
1499 
sq_getbase(HSQUIRRELVM v,SQInteger idx)1500 SQRESULT sq_getbase(HSQUIRRELVM v,SQInteger idx)
1501 {
1502     SQObjectPtr *o = NULL;
1503     _GETSAFE_OBJ(v, idx, OT_CLASS,o);
1504     if(_class(*o)->_base)
1505         v->Push(SQObjectPtr(_class(*o)->_base));
1506     else
1507         v->PushNull();
1508     return SQ_OK;
1509 }
1510 
sq_getclass(HSQUIRRELVM v,SQInteger idx)1511 SQRESULT sq_getclass(HSQUIRRELVM v,SQInteger idx)
1512 {
1513     SQObjectPtr *o = NULL;
1514     _GETSAFE_OBJ(v, idx, OT_INSTANCE,o);
1515     v->Push(SQObjectPtr(_instance(*o)->_class));
1516     return SQ_OK;
1517 }
1518 
sq_createinstance(HSQUIRRELVM v,SQInteger idx)1519 SQRESULT sq_createinstance(HSQUIRRELVM v,SQInteger idx)
1520 {
1521     SQObjectPtr *o = NULL;
1522     _GETSAFE_OBJ(v, idx, OT_CLASS,o);
1523     v->Push(_class(*o)->CreateInstance());
1524     return SQ_OK;
1525 }
1526 
sq_weakref(HSQUIRRELVM v,SQInteger idx)1527 void sq_weakref(HSQUIRRELVM v,SQInteger idx)
1528 {
1529     SQObject &o=stack_get(v,idx);
1530     if(ISREFCOUNTED(sq_type(o))) {
1531         v->Push(_refcounted(o)->GetWeakRef(sq_type(o)));
1532         return;
1533     }
1534     v->Push(o);
1535 }
1536 
sq_getweakrefval(HSQUIRRELVM v,SQInteger idx)1537 SQRESULT sq_getweakrefval(HSQUIRRELVM v,SQInteger idx)
1538 {
1539     SQObjectPtr &o = stack_get(v,idx);
1540     if(sq_type(o) != OT_WEAKREF) {
1541         return sq_throwerror(v,_SC("the object must be a weakref"));
1542     }
1543     v->Push(_weakref(o)->_obj);
1544     return SQ_OK;
1545 }
1546 
sq_getdefaultdelegate(HSQUIRRELVM v,SQObjectType t)1547 SQRESULT sq_getdefaultdelegate(HSQUIRRELVM v,SQObjectType t)
1548 {
1549     SQSharedState *ss = _ss(v);
1550     switch(t) {
1551     case OT_TABLE: v->Push(ss->_table_default_delegate); break;
1552     case OT_ARRAY: v->Push(ss->_array_default_delegate); break;
1553     case OT_STRING: v->Push(ss->_string_default_delegate); break;
1554     case OT_INTEGER: case OT_FLOAT: v->Push(ss->_number_default_delegate); break;
1555     case OT_GENERATOR: v->Push(ss->_generator_default_delegate); break;
1556     case OT_CLOSURE: case OT_NATIVECLOSURE: v->Push(ss->_closure_default_delegate); break;
1557     case OT_THREAD: v->Push(ss->_thread_default_delegate); break;
1558     case OT_CLASS: v->Push(ss->_class_default_delegate); break;
1559     case OT_INSTANCE: v->Push(ss->_instance_default_delegate); break;
1560     case OT_WEAKREF: v->Push(ss->_weakref_default_delegate); break;
1561     default: return sq_throwerror(v,_SC("the type doesn't have a default delegate"));
1562     }
1563     return SQ_OK;
1564 }
1565 
sq_next(HSQUIRRELVM v,SQInteger idx)1566 SQRESULT sq_next(HSQUIRRELVM v,SQInteger idx)
1567 {
1568     SQObjectPtr o=stack_get(v,idx),&refpos = stack_get(v,-1),realkey,val;
1569     if(sq_type(o) == OT_GENERATOR) {
1570         return sq_throwerror(v,_SC("cannot iterate a generator"));
1571     }
1572     int faketojump;
1573     if(!v->FOREACH_OP(o,realkey,val,refpos,0,666,faketojump))
1574         return SQ_ERROR;
1575     if(faketojump != 666) {
1576         v->Push(realkey);
1577         v->Push(val);
1578         return SQ_OK;
1579     }
1580     return SQ_ERROR;
1581 }
1582 
1583 struct BufState{
1584     const SQChar *buf;
1585     SQInteger ptr;
1586     SQInteger size;
1587 };
1588 
buf_lexfeed(SQUserPointer file)1589 SQInteger buf_lexfeed(SQUserPointer file)
1590 {
1591     BufState *buf=(BufState*)file;
1592     if(buf->size<(buf->ptr+1))
1593         return 0;
1594     return buf->buf[buf->ptr++];
1595 }
1596 
sq_compilebuffer(HSQUIRRELVM v,const SQChar * s,SQInteger size,const SQChar * sourcename,SQBool raiseerror)1597 SQRESULT sq_compilebuffer(HSQUIRRELVM v,const SQChar *s,SQInteger size,const SQChar *sourcename,SQBool raiseerror) {
1598     BufState buf;
1599     buf.buf = s;
1600     buf.size = size;
1601     buf.ptr = 0;
1602     return sq_compile(v, buf_lexfeed, &buf, sourcename, raiseerror);
1603 }
1604 
sq_move(HSQUIRRELVM dest,HSQUIRRELVM src,SQInteger idx)1605 void sq_move(HSQUIRRELVM dest,HSQUIRRELVM src,SQInteger idx)
1606 {
1607     dest->Push(stack_get(src,idx));
1608 }
1609 
sq_setprintfunc(HSQUIRRELVM v,SQPRINTFUNCTION printfunc,SQPRINTFUNCTION errfunc)1610 void sq_setprintfunc(HSQUIRRELVM v, SQPRINTFUNCTION printfunc,SQPRINTFUNCTION errfunc)
1611 {
1612     _ss(v)->_printfunc = printfunc;
1613     _ss(v)->_errorfunc = errfunc;
1614 }
1615 
sq_getprintfunc(HSQUIRRELVM v)1616 SQPRINTFUNCTION sq_getprintfunc(HSQUIRRELVM v)
1617 {
1618     return _ss(v)->_printfunc;
1619 }
1620 
sq_geterrorfunc(HSQUIRRELVM v)1621 SQPRINTFUNCTION sq_geterrorfunc(HSQUIRRELVM v)
1622 {
1623     return _ss(v)->_errorfunc;
1624 }
1625 
sq_malloc(SQUnsignedInteger size)1626 void *sq_malloc(SQUnsignedInteger size)
1627 {
1628     return SQ_MALLOC(size);
1629 }
1630 
sq_realloc(void * p,SQUnsignedInteger oldsize,SQUnsignedInteger newsize)1631 void *sq_realloc(void* p,SQUnsignedInteger oldsize,SQUnsignedInteger newsize)
1632 {
1633     return SQ_REALLOC(p,oldsize,newsize);
1634 }
1635 
sq_free(void * p,SQUnsignedInteger size)1636 void sq_free(void *p,SQUnsignedInteger size)
1637 {
1638     SQ_FREE(p,size);
1639 }
1640