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 bool sq_aux_gettypedarg( HSQUIRRELVM v, SQInteger idx, SQObjectType type, SQObjectPtr **o ) {
17 *o = &stack_get( v, idx );
18 if ( squirrel_type( **o ) != type ) {
19 SQObjectPtr oval = v->PrintObjVal( **o );
20 v->Raise_Error( _SC( "wrong argument type, expected '%s' got '%.50s'" ), IdType2Name( type ), _stringval( oval ) );
21 return false;
22 }
23 return true;
24 }
25
26 #define _GETSAFE_OBJ(v,idx,type,o) { if(!sq_aux_gettypedarg(v,idx,type,&o)) return SQ_ERROR; }
27
28 #define sq_aux_paramscheck(v,count) \
29 { \
30 if(sq_gettop(v) < count){ v->Raise_Error(_SC("not enough params in the stack")); return SQ_ERROR; }\
31 }
32
sq_aux_throwobject(HSQUIRRELVM v,SQObjectPtr & e)33 SQInteger sq_aux_throwobject( HSQUIRRELVM v, SQObjectPtr &e ) {
34 v->_lasterror = e;
35 return SQ_ERROR;
36 }
37
sq_aux_invalidtype(HSQUIRRELVM v,SQObjectType type)38 SQInteger sq_aux_invalidtype( HSQUIRRELVM v, SQObjectType type ) {
39 scsprintf( _ss( v )->GetScratchPad( 100 ), _SC( "unexpected type %s" ), IdType2Name( type ) );
40 return sq_throwerror( v, _ss( v )->GetScratchPad( -1 ) );
41 }
42
sq_open(SQInteger initialstacksize)43 HSQUIRRELVM sq_open( SQInteger initialstacksize ) {
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 SQSharedState *ss;
62 SQVM *v;
63 ss = _ss( friendvm );
64
65 v = ( SQVM * )SQ_MALLOC( sizeof( SQVM ) );
66 new ( v ) SQVM( ss );
67
68 if ( v->Init( friendvm, initialstacksize ) ) {
69 friendvm->Push( v );
70 return v;
71 } else {
72 sq_delete( v, SQVM );
73 return NULL;
74 }
75 }
76
sq_getvmstate(HSQUIRRELVM v)77 SQInteger sq_getvmstate( HSQUIRRELVM v ) {
78 if ( v->_suspended )
79 return SQ_VMSTATE_SUSPENDED;
80 else {
81 if ( !v->_callsstack.empty() ) return SQ_VMSTATE_RUNNING;
82 else return SQ_VMSTATE_IDLE;
83 }
84 }
85
sq_seterrorhandler(HSQUIRRELVM v)86 void sq_seterrorhandler( HSQUIRRELVM v ) {
87 SQObject o = stack_get( v, -1 );
88 if ( sq_isclosure( o ) || sq_isnativeclosure( o ) || sq_isnull( o ) ) {
89 v->_errorhandler = o;
90 v->Pop();
91 }
92 }
93
sq_setdebughook(HSQUIRRELVM v)94 void sq_setdebughook( HSQUIRRELVM v ) {
95 SQObject o = stack_get( v, -1 );
96 if ( sq_isclosure( o ) || sq_isnativeclosure( o ) || sq_isnull( o ) ) {
97 v->_debughook = o;
98 v->Pop();
99 }
100 }
101
sq_close(HSQUIRRELVM v)102 void sq_close( HSQUIRRELVM v ) {
103 SQSharedState *ss = _ss( v );
104 _thread( ss->_root_vm )->Finalize();
105 sq_delete( ss, SQSharedState );
106 }
107
sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar * sourcename,SQBool raiseerror)108 SQRESULT sq_compile( HSQUIRRELVM v, SQLEXREADFUNC read, SQUserPointer p, const SQChar *sourcename, SQBool raiseerror ) {
109 SQObjectPtr o;
110 if ( Compile( v, read, p, sourcename, o, raiseerror ? true : false, _ss( v )->_debuginfo ) ) {
111 v->Push( SQClosure::Create( _ss( v ), _funcproto( o ) ) );
112 return SQ_OK;
113 }
114 return SQ_ERROR;
115 }
116
sq_enabledebuginfo(HSQUIRRELVM v,SQBool debuginfo)117 void sq_enabledebuginfo( HSQUIRRELVM v, SQBool debuginfo ) {
118 _ss( v )->_debuginfo = debuginfo ? true : false;
119 }
120
sq_addref(HSQUIRRELVM v,HSQOBJECT * po)121 void sq_addref( HSQUIRRELVM v, HSQOBJECT *po ) {
122 SQObjectPtr refs;
123 if ( !ISREFCOUNTED( squirrel_type( *po ) ) ) return;
124 if ( _table( _ss( v )->_refs_table )->Get( *po, refs ) ) {
125 refs = _integer( refs ) + 1;
126 } else {
127 refs = 1;
128 }
129 _table( _ss( v )->_refs_table )->NewSlot( *po, refs );
130 }
131
sq_release(HSQUIRRELVM v,HSQOBJECT * po)132 SQBool sq_release( HSQUIRRELVM v, HSQOBJECT *po ) {
133 SQObjectPtr refs;
134 if ( !ISREFCOUNTED( squirrel_type( *po ) ) ) return SQTrue;
135 if ( _table( _ss( v )->_refs_table )->Get( *po, refs ) ) {
136 SQInteger n = _integer( refs ) - 1;
137 if ( n <= 0 ) {
138 _table( _ss( v )->_refs_table )->Remove( *po );
139 sq_resetobject( po );
140 } else {
141 refs = n;_table( _ss( v )->_refs_table )->Set( *po, refs );
142 return SQFalse;
143 }
144 }
145 return SQTrue;
146 }
147
sq_objtostring(HSQOBJECT * o)148 const SQChar *sq_objtostring( HSQOBJECT *o ) {
149 if ( sq_type( *o ) == OT_STRING ) {
150 return _stringval( *o );
151 }
152 return NULL;
153 }
154
sq_objtointeger(HSQOBJECT * o)155 SQInteger sq_objtointeger( HSQOBJECT *o ) {
156 if ( sq_isnumeric( *o ) ) {
157 return tointeger( *o );
158 }
159 return 0;
160 }
161
sq_objtofloat(HSQOBJECT * o)162 SQFloat sq_objtofloat( HSQOBJECT *o ) {
163 if ( sq_isnumeric( *o ) ) {
164 return tofloat( *o );
165 }
166 return 0;
167 }
168
sq_objtobool(HSQOBJECT * o)169 SQBool sq_objtobool( HSQOBJECT *o ) {
170 if ( sq_isbool( *o ) ) {
171 return _integer( *o );
172 }
173 return SQFalse;
174 }
175
sq_pushnull(HSQUIRRELVM v)176 void sq_pushnull( HSQUIRRELVM v ) {
177 v->Push( _null_ );
178 }
179
sq_pushstring(HSQUIRRELVM v,const SQChar * s,SQInteger len)180 void sq_pushstring( HSQUIRRELVM v, const SQChar *s, SQInteger len ) {
181 if ( s )
182 v->Push( SQObjectPtr( SQString::Create( _ss( v ), s, len ) ) );
183 else v->Push( _null_ );
184 }
185
sq_pushinteger(HSQUIRRELVM v,SQInteger n)186 void sq_pushinteger( HSQUIRRELVM v, SQInteger n ) {
187 v->Push( n );
188 }
189
sq_pushbool(HSQUIRRELVM v,SQBool b)190 void sq_pushbool( HSQUIRRELVM v, SQBool b ) {
191 v->Push( b ? true : false );
192 }
193
sq_pushfloat(HSQUIRRELVM v,SQFloat n)194 void sq_pushfloat( HSQUIRRELVM v, SQFloat n ) {
195 v->Push( n );
196 }
197
sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p)198 void sq_pushuserpointer( HSQUIRRELVM v, SQUserPointer p ) {
199 v->Push( p );
200 }
201
sq_newuserdata(HSQUIRRELVM v,SQUnsignedInteger size)202 SQUserPointer sq_newuserdata( HSQUIRRELVM v, SQUnsignedInteger size ) {
203 SQUserData *ud = SQUserData::Create( _ss( v ), size );
204 v->Push( ud );
205 return ud->_val;
206 }
207
sq_newtable(HSQUIRRELVM v)208 void sq_newtable( HSQUIRRELVM v ) {
209 v->Push( SQTable::Create( _ss( v ), 0 ) );
210 }
211
sq_newarray(HSQUIRRELVM v,SQInteger size)212 void sq_newarray( HSQUIRRELVM v, SQInteger size ) {
213 v->Push( SQArray::Create( _ss( v ), size ) );
214 }
215
sq_newclass(HSQUIRRELVM v,SQBool hasbase)216 SQRESULT sq_newclass( HSQUIRRELVM v, SQBool hasbase ) {
217 SQClass *baseclass = NULL;
218 if ( hasbase ) {
219 SQObjectPtr &base = stack_get( v, -1 );
220 if ( squirrel_type( base ) != OT_CLASS )
221 return sq_throwerror( v, _SC( "invalid base type" ) );
222 baseclass = _class( base );
223 }
224 SQClass *newclass = SQClass::Create( _ss( v ), baseclass );
225 if ( baseclass ) v->Pop();
226 v->Push( newclass );
227 return SQ_OK;
228 }
229
sq_instanceof(HSQUIRRELVM v)230 SQInteger sq_instanceof( HSQUIRRELVM v ) {
231 SQObjectPtr &inst = stack_get( v, -1 );
232 SQObjectPtr &cl = stack_get( v, -2 );
233 if ( squirrel_type( inst ) != OT_INSTANCE || squirrel_type( cl ) != OT_CLASS )
234 return sq_throwerror( v, _SC( "invalid param type" ) );
235 return _instance( inst )->InstanceOf( _class( cl ) ) ? 1 : 0;
236 }
237
sq_arrayappend(HSQUIRRELVM v,SQInteger idx)238 SQRESULT sq_arrayappend( HSQUIRRELVM v, SQInteger idx ) {
239 sq_aux_paramscheck( v, 2 );
240 SQObjectPtr *arr;
241 _GETSAFE_OBJ( v, idx, OT_ARRAY, arr );
242 _array( *arr )->Append( v->GetUp( -1 ) );
243 v->Pop( 1 );
244 return SQ_OK;
245 }
246
sq_arraypop(HSQUIRRELVM v,SQInteger idx,SQBool pushval)247 SQRESULT sq_arraypop( HSQUIRRELVM v, SQInteger idx, SQBool pushval ) {
248 sq_aux_paramscheck( v, 1 );
249 SQObjectPtr *arr;
250 _GETSAFE_OBJ( v, idx, OT_ARRAY, arr );
251 if ( _array( *arr )->Size() > 0 ) {
252 if ( pushval != 0 ) {
253 v->Push( _array( *arr )->Top() );
254 }
255 _array( *arr )->Pop();
256 return SQ_OK;
257 }
258 return sq_throwerror( v, _SC( "empty array" ) );
259 }
260
sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize)261 SQRESULT sq_arrayresize( HSQUIRRELVM v, SQInteger idx, SQInteger newsize ) {
262 sq_aux_paramscheck( v, 1 );
263 SQObjectPtr *arr;
264 _GETSAFE_OBJ( v, idx, OT_ARRAY, arr );
265 if ( _array( *arr )->Size() > 0 ) {
266 _array( *arr )->Resize( newsize );
267 return SQ_OK;
268 }
269 return SQ_OK;
270 }
271
sq_arrayreverse(HSQUIRRELVM v,SQInteger idx)272 SQRESULT sq_arrayreverse( HSQUIRRELVM v, SQInteger idx ) {
273 sq_aux_paramscheck( v, 1 );
274 SQObjectPtr *o;
275 _GETSAFE_OBJ( v, idx, OT_ARRAY, o );
276 SQArray *arr = _array( *o );
277 if ( arr->Size() > 0 ) {
278 SQObjectPtr t;
279 SQInteger size = arr->Size();
280 SQInteger n = size >> 1; size -= 1;
281 for ( SQInteger i = 0; i < n; i++ ) {
282 t = arr->_values[i];
283 arr->_values[i] = arr->_values[size-i];
284 arr->_values[size-i] = t;
285 }
286 return SQ_OK;
287 }
288 return SQ_OK;
289 }
290
sq_newclosure(HSQUIRRELVM v,SQFUNCTION func,SQUnsignedInteger nfreevars)291 void sq_newclosure( HSQUIRRELVM v, SQFUNCTION func, SQUnsignedInteger nfreevars ) {
292 SQNativeClosure *nc = SQNativeClosure::Create( _ss( v ), func );
293 nc->_nparamscheck = 0;
294 for ( SQUnsignedInteger i = 0; i < nfreevars; i++ ) {
295 nc->_outervalues.push_back( v->Top() );
296 v->Pop();
297 }
298 v->Push( SQObjectPtr( nc ) );
299 }
300
sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger * nparams,SQUnsignedInteger * nfreevars)301 SQRESULT sq_getclosureinfo( HSQUIRRELVM v, SQInteger idx, SQUnsignedInteger *nparams, SQUnsignedInteger *nfreevars ) {
302 SQObject o = stack_get( v, idx );
303 if ( sq_isclosure( o ) ) {
304 SQClosure *c = _closure( o );
305 SQFunctionProto *proto = _funcproto( c->_function );
306 *nparams = ( SQUnsignedInteger )proto->_parameters.size();
307 *nfreevars = ( SQUnsignedInteger )c->_outervalues.size();
308 return SQ_OK;
309 }
310 return sq_throwerror( v, _SC( "the object is not a closure" ) );
311 }
312
sq_setnativeclosurename(HSQUIRRELVM v,SQInteger idx,const SQChar * name)313 SQRESULT sq_setnativeclosurename( HSQUIRRELVM v, SQInteger idx, const SQChar *name ) {
314 SQObject o = stack_get( v, idx );
315 if ( sq_isnativeclosure( o ) ) {
316 SQNativeClosure *nc = _nativeclosure( o );
317 nc->_name = SQString::Create( _ss( v ), name );
318 return SQ_OK;
319 }
320 return sq_throwerror( v, _SC( "the object is not a nativeclosure" ) );
321 }
322
sq_setparamscheck(HSQUIRRELVM v,SQInteger nparamscheck,const SQChar * typemask)323 SQRESULT sq_setparamscheck( HSQUIRRELVM v, SQInteger nparamscheck, const SQChar *typemask ) {
324 SQObject o = stack_get( v, -1 );
325 if ( !sq_isnativeclosure( o ) )
326 return sq_throwerror( v, _SC( "native closure expected" ) );
327 SQNativeClosure *nc = _nativeclosure( o );
328 nc->_nparamscheck = nparamscheck;
329 if ( typemask ) {
330 SQIntVec res;
331 if ( !CompileTypemask( res, typemask ) )
332 return sq_throwerror( v, _SC( "invalid typemask" ) );
333 nc->_typecheck.copy( res );
334 } else {
335 nc->_typecheck.resize( 0 );
336 }
337 if ( nparamscheck == SQ_MATCHTYPEMASKSTRING ) {
338 nc->_nparamscheck = nc->_typecheck.size();
339 }
340 return SQ_OK;
341 }
342
sq_pushroottable(HSQUIRRELVM v)343 void sq_pushroottable( HSQUIRRELVM v ) {
344 v->Push( v->_roottable );
345 }
346
sq_pushregistrytable(HSQUIRRELVM v)347 void sq_pushregistrytable( HSQUIRRELVM v ) {
348 v->Push( _ss( v )->_registry );
349 }
350
sq_setroottable(HSQUIRRELVM v)351 SQRESULT sq_setroottable( HSQUIRRELVM v ) {
352 SQObject o = stack_get( v, -1 );
353 if ( sq_istable( o ) || sq_isnull( o ) ) {
354 v->_roottable = o;
355 v->Pop();
356 return SQ_OK;
357 }
358 return sq_throwerror( v, _SC( "ivalid type" ) );
359 }
360
sq_setforeignptr(HSQUIRRELVM v,SQUserPointer p)361 void sq_setforeignptr( HSQUIRRELVM v, SQUserPointer p ) {
362 v->_foreignptr = p;
363 }
364
sq_getforeignptr(HSQUIRRELVM v)365 SQUserPointer sq_getforeignptr( HSQUIRRELVM v ) {
366 return v->_foreignptr;
367 }
368
sq_push(HSQUIRRELVM v,SQInteger idx)369 void sq_push( HSQUIRRELVM v, SQInteger idx ) {
370 v->Push( stack_get( v, idx ) );
371 }
372
sq_gettype(HSQUIRRELVM v,SQInteger idx)373 SQObjectType sq_gettype( HSQUIRRELVM v, SQInteger idx ) {
374 return squirrel_type( stack_get( v, idx ) );
375 }
376
sq_tostring(HSQUIRRELVM v,SQInteger idx)377 void sq_tostring( HSQUIRRELVM v, SQInteger idx ) {
378 SQObjectPtr &o = stack_get( v, idx );
379 SQObjectPtr res;
380 v->ToString( o, res );
381 v->Push( res );
382 }
383
sq_getinteger(HSQUIRRELVM v,SQInteger idx,SQInteger * i)384 SQRESULT sq_getinteger( HSQUIRRELVM v, SQInteger idx, SQInteger *i ) {
385 SQObjectPtr &o = stack_get( v, idx );
386 if ( sq_isnumeric( o ) ) {
387 *i = tointeger( o );
388 return SQ_OK;
389 }
390 return SQ_ERROR;
391 }
392
sq_getfloat(HSQUIRRELVM v,SQInteger idx,SQFloat * f)393 SQRESULT sq_getfloat( HSQUIRRELVM v, SQInteger idx, SQFloat *f ) {
394 SQObjectPtr &o = stack_get( v, idx );
395 if ( sq_isnumeric( o ) ) {
396 *f = tofloat( o );
397 return SQ_OK;
398 }
399 return SQ_ERROR;
400 }
401
sq_getbool(HSQUIRRELVM v,SQInteger idx,SQBool * b)402 SQRESULT sq_getbool( HSQUIRRELVM v, SQInteger idx, SQBool *b ) {
403 SQObjectPtr &o = stack_get( v, idx );
404 if ( sq_isbool( o ) ) {
405 *b = _integer( o );
406 return SQ_OK;
407 }
408 return SQ_ERROR;
409 }
410
sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar ** c)411 SQRESULT sq_getstring( HSQUIRRELVM v, SQInteger idx, const SQChar **c ) {
412 SQObjectPtr *o = NULL;
413 _GETSAFE_OBJ( v, idx, OT_STRING, o );
414 *c = _stringval( *o );
415 return SQ_OK;
416 }
417
sq_getthread(HSQUIRRELVM v,SQInteger idx,HSQUIRRELVM * thread)418 SQRESULT sq_getthread( HSQUIRRELVM v, SQInteger idx, HSQUIRRELVM *thread ) {
419 SQObjectPtr *o = NULL;
420 _GETSAFE_OBJ( v, idx, OT_THREAD, o );
421 *thread = _thread( *o );
422 return SQ_OK;
423 }
424
sq_clone(HSQUIRRELVM v,SQInteger idx)425 SQRESULT sq_clone( HSQUIRRELVM v, SQInteger idx ) {
426 SQObjectPtr &o = stack_get( v, idx );
427 v->Push( _null_ );
428 if ( !v->Clone( o, stack_get( v, -1 ) ) ) {
429 v->Pop();
430 return sq_aux_invalidtype( v, squirrel_type( o ) );
431 }
432 return SQ_OK;
433 }
434
sq_getsize(HSQUIRRELVM v,SQInteger idx)435 SQInteger sq_getsize( HSQUIRRELVM v, SQInteger idx ) {
436 SQObjectPtr &o = stack_get( v, idx );
437 SQObjectType type = squirrel_type( o );
438 switch ( type ) {
439 case OT_STRING: return _string( o )->_len;
440 case OT_TABLE: return _table( o )->CountUsed();
441 case OT_ARRAY: return _array( o )->Size();
442 case OT_USERDATA: return _userdata( o )->_size;
443 default:
444 return sq_aux_invalidtype( v, type );
445 }
446 }
447
sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer * p,SQUserPointer * typetag)448 SQRESULT sq_getuserdata( HSQUIRRELVM v, SQInteger idx, SQUserPointer *p, SQUserPointer *typetag ) {
449 SQObjectPtr *o = NULL;
450 _GETSAFE_OBJ( v, idx, OT_USERDATA, o );
451 ( *p ) = _userdataval( *o );
452 if ( typetag ) *typetag = _userdata( *o )->_typetag;
453 return SQ_OK;
454 }
455
sq_settypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer typetag)456 SQRESULT sq_settypetag( HSQUIRRELVM v, SQInteger idx, SQUserPointer typetag ) {
457 SQObjectPtr &o = stack_get( v, idx );
458 switch ( squirrel_type( o ) ) {
459 case OT_USERDATA: _userdata( o )->_typetag = typetag; break;
460 case OT_CLASS: _class( o )->_typetag = typetag; break;
461 default: return sq_throwerror( v, _SC( "invalid object type" ) );
462 }
463 return SQ_OK;
464 }
465
sq_getobjtypetag(HSQOBJECT * o,SQUserPointer * typetag)466 SQRESULT sq_getobjtypetag( HSQOBJECT *o, SQUserPointer * typetag ) {
467 switch ( squirrel_type( *o ) ) {
468 case OT_INSTANCE: *typetag = _instance( *o )->_class->_typetag; break;
469 case OT_USERDATA: *typetag = _userdata( *o )->_typetag; break;
470 case OT_CLASS: *typetag = _class( *o )->_typetag; break;
471 default: return SQ_ERROR;
472 }
473 return SQ_OK;
474 }
475
sq_gettypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer * typetag)476 SQRESULT sq_gettypetag( HSQUIRRELVM v, SQInteger idx, SQUserPointer *typetag ) {
477 SQObjectPtr &o = stack_get( v, idx );
478 if ( SQ_FAILED( sq_getobjtypetag( &o, typetag ) ) )
479 return sq_throwerror( v, _SC( "invalid object type" ) );
480 return SQ_OK;
481 }
482
sq_getuserpointer(HSQUIRRELVM v,SQInteger idx,SQUserPointer * p)483 SQRESULT sq_getuserpointer( HSQUIRRELVM v, SQInteger idx, SQUserPointer *p ) {
484 SQObjectPtr *o = NULL;
485 _GETSAFE_OBJ( v, idx, OT_USERPOINTER, o );
486 ( *p ) = _userpointer( *o );
487 return SQ_OK;
488 }
489
sq_setinstanceup(HSQUIRRELVM v,SQInteger idx,SQUserPointer p)490 SQRESULT sq_setinstanceup( HSQUIRRELVM v, SQInteger idx, SQUserPointer p ) {
491 SQObjectPtr &o = stack_get( v, idx );
492 if ( squirrel_type( o ) != OT_INSTANCE ) return sq_throwerror( v, _SC( "the object is not a class instance" ) );
493 _instance( o )->_userpointer = p;
494 return SQ_OK;
495 }
496
sq_getinstanceup(HSQUIRRELVM v,SQInteger idx,SQUserPointer * p,SQUserPointer typetag)497 SQRESULT sq_getinstanceup( HSQUIRRELVM v, SQInteger idx, SQUserPointer *p, SQUserPointer typetag ) {
498 SQObjectPtr &o = stack_get( v, idx );
499 if ( squirrel_type( o ) != OT_INSTANCE ) return sq_throwerror( v, _SC( "the object is not a class instance" ) );
500 ( *p ) = _instance( o )->_userpointer;
501 if ( typetag != 0 ) {
502 SQClass *cl = _instance( o )->_class;
503 do {
504 if ( cl->_typetag == typetag )
505 return SQ_OK;
506 cl = cl->_base;
507 } while ( cl != NULL );
508 return sq_throwerror( v, _SC( "invalid type tag" ) );
509 }
510 return SQ_OK;
511 }
512
sq_gettop(HSQUIRRELVM v)513 SQInteger sq_gettop( HSQUIRRELVM v ) {
514 return ( v->_top ) - v->_stackbase;
515 }
516
sq_settop(HSQUIRRELVM v,SQInteger newtop)517 void sq_settop( HSQUIRRELVM v, SQInteger newtop ) {
518 SQInteger top = sq_gettop( v );
519 if ( top > newtop )
520 sq_pop( v, top - newtop );
521 else
522 while ( top < newtop ) sq_pushnull( v );
523 }
524
sq_pop(HSQUIRRELVM v,SQInteger nelemstopop)525 void sq_pop( HSQUIRRELVM v, SQInteger nelemstopop ) {
526 assert( v->_top >= nelemstopop );
527 v->Pop( nelemstopop );
528 }
529
sq_poptop(HSQUIRRELVM v)530 void sq_poptop( HSQUIRRELVM v ) {
531 assert( v->_top >= 1 );
532 v->Pop();
533 }
534
535
sq_remove(HSQUIRRELVM v,SQInteger idx)536 void sq_remove( HSQUIRRELVM v, SQInteger idx ) {
537 v->Remove( idx );
538 }
539
sq_cmp(HSQUIRRELVM v)540 SQInteger sq_cmp( HSQUIRRELVM v ) {
541 SQInteger res;
542 v->ObjCmp( stack_get( v, -1 ), stack_get( v, -2 ), res );
543 return res;
544 }
545
sq_createslot(HSQUIRRELVM v,SQInteger idx)546 SQRESULT sq_createslot( HSQUIRRELVM v, SQInteger idx ) {
547 sq_aux_paramscheck( v, 3 );
548 SQObjectPtr &self = stack_get( v, idx );
549 if ( squirrel_type( self ) == OT_TABLE || squirrel_type( self ) == OT_CLASS ) {
550 SQObjectPtr &key = v->GetUp( -2 );
551 if ( squirrel_type( key ) == OT_NULL ) return sq_throwerror( v, _SC( "null is not a valid key" ) );
552 v->NewSlot( self, key, v->GetUp( -1 ) );
553 v->Pop( 2 );
554 }
555 return SQ_OK;
556 }
557
sq_deleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval)558 SQRESULT sq_deleteslot( HSQUIRRELVM v, SQInteger idx, SQBool pushval ) {
559 sq_aux_paramscheck( v, 2 );
560 SQObjectPtr *self;
561 _GETSAFE_OBJ( v, idx, OT_TABLE, self );
562 SQObjectPtr &key = v->GetUp( -1 );
563 if ( squirrel_type( key ) == OT_NULL ) return sq_throwerror( v, _SC( "null is not a valid key" ) );
564 SQObjectPtr res;
565 if ( !v->DeleteSlot( *self, key, res ) ) {
566 return SQ_ERROR;
567 }
568 if ( pushval ) v->GetUp( -1 ) = res;
569 else v->Pop( 1 );
570 return SQ_OK;
571 }
572
sq_set(HSQUIRRELVM v,SQInteger idx)573 SQRESULT sq_set( HSQUIRRELVM v, SQInteger idx ) {
574 SQObjectPtr &self = stack_get( v, idx );
575 if ( v->Set( self, v->GetUp( -2 ), v->GetUp( -1 ), false ) ) {
576 v->Pop( 2 );
577 return SQ_OK;
578 }
579 v->Raise_IdxError( v->GetUp( -2 ) );return SQ_ERROR;
580 }
581
sq_rawset(HSQUIRRELVM v,SQInteger idx)582 SQRESULT sq_rawset( HSQUIRRELVM v, SQInteger idx ) {
583 SQObjectPtr &self = stack_get( v, idx );
584 if ( squirrel_type( v->GetUp( -2 ) ) == OT_NULL ) return sq_throwerror( v, _SC( "null key" ) );
585 switch ( squirrel_type( self ) ) {
586 case OT_TABLE:
587 _table( self )->NewSlot( v->GetUp( -2 ), v->GetUp( -1 ) );
588 v->Pop( 2 );
589 return SQ_OK;
590 break;
591 case OT_CLASS:
592 _class( self )->NewSlot( v->GetUp( -2 ), v->GetUp( -1 ) );
593 v->Pop( 2 );
594 return SQ_OK;
595 break;
596 case OT_INSTANCE:
597 if ( _instance( self )->Set( v->GetUp( -2 ), v->GetUp( -1 ) ) ) {
598 v->Pop( 2 );
599 return SQ_OK;
600 }
601 break;
602 case OT_ARRAY:
603 if ( v->Set( self, v->GetUp( -2 ), v->GetUp( -1 ), false ) ) {
604 v->Pop( 2 );
605 return SQ_OK;
606 }
607 break;
608 default:
609 v->Pop( 2 );
610 return sq_throwerror( v, _SC( "rawset works only on array/table/calsse and instance" ) );
611 }
612 v->Raise_IdxError( v->GetUp( -2 ) );return SQ_ERROR;
613 }
614
sq_setdelegate(HSQUIRRELVM v,SQInteger idx)615 SQRESULT sq_setdelegate( HSQUIRRELVM v, SQInteger idx ) {
616 SQObjectPtr &self = stack_get( v, idx );
617 SQObjectPtr &mt = v->GetUp( -1 );
618 SQObjectType type = squirrel_type( self );
619 switch ( type ) {
620 case OT_TABLE:
621 if ( squirrel_type( mt ) == OT_TABLE ) {
622 if ( !_table( self )->SetDelegate( _table( mt ) ) ) return sq_throwerror( v, _SC( "delagate cycle" ) ); v->Pop();
623 } else if ( squirrel_type( mt ) == OT_NULL ) {
624 _table( self )->SetDelegate( NULL ); v->Pop();
625 } else return sq_aux_invalidtype( v, type );
626 break;
627 case OT_USERDATA:
628 if ( squirrel_type( mt ) == OT_TABLE ) {
629 _userdata( self )->SetDelegate( _table( mt ) ); v->Pop();
630 } else if ( squirrel_type( mt ) == OT_NULL ) {
631 _userdata( self )->SetDelegate( NULL ); v->Pop();
632 } else return sq_aux_invalidtype( v, type );
633 break;
634 default:
635 return sq_aux_invalidtype( v, type );
636 break;
637 }
638 return SQ_OK;
639 }
640
sq_rawdeleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval)641 SQRESULT sq_rawdeleteslot( HSQUIRRELVM v, SQInteger idx, SQBool pushval ) {
642 sq_aux_paramscheck( v, 2 );
643 SQObjectPtr *self;
644 _GETSAFE_OBJ( v, idx, OT_TABLE, self );
645 SQObjectPtr &key = v->GetUp( -1 );
646 SQObjectPtr t;
647 if ( _table( *self )->Get( key, t ) ) {
648 _table( *self )->Remove( key );
649 }
650 if ( pushval != 0 )
651 if ( pushval ) v->GetUp( -1 ) = t;
652 else
653 v->Pop( 1 );
654 return SQ_OK;
655 }
656
sq_getdelegate(HSQUIRRELVM v,SQInteger idx)657 SQRESULT sq_getdelegate( HSQUIRRELVM v, SQInteger idx ) {
658 SQObjectPtr &self = stack_get( v, idx );
659 switch ( squirrel_type( self ) ) {
660 case OT_TABLE:
661 if ( !_table( self )->_delegate )break;
662 v->Push( SQObjectPtr( _table( self )->_delegate ) );
663 return SQ_OK;
664 break;
665 case OT_USERDATA:
666 if ( !_userdata( self )->_delegate )break;
667 v->Push( SQObjectPtr( _userdata( self )->_delegate ) );
668 return SQ_OK;
669 break;
670 }
671 return sq_throwerror( v, _SC( "wrong type" ) );
672 }
673
sq_get(HSQUIRRELVM v,SQInteger idx)674 SQRESULT sq_get( HSQUIRRELVM v, SQInteger idx ) {
675 SQObjectPtr &self = stack_get( v, idx );
676 if ( v->Get( self, v->GetUp( -1 ), v->GetUp( -1 ), false, false ) )
677 return SQ_OK;
678 v->Pop( 1 );
679 return sq_throwerror( v, _SC( "the index doesn't exist" ) );
680 }
681
sq_rawget(HSQUIRRELVM v,SQInteger idx)682 SQRESULT sq_rawget( HSQUIRRELVM v, SQInteger idx ) {
683 SQObjectPtr &self = stack_get( v, idx );
684 switch ( squirrel_type( self ) ) {
685 case OT_TABLE:
686 if ( _table( self )->Get( v->GetUp( -1 ), v->GetUp( -1 ) ) )
687 return SQ_OK;
688 break;
689 case OT_CLASS:
690 if ( _class( self )->Get( v->GetUp( -1 ), v->GetUp( -1 ) ) )
691 return SQ_OK;
692 break;
693 case OT_INSTANCE:
694 if ( _instance( self )->Get( v->GetUp( -1 ), v->GetUp( -1 ) ) )
695 return SQ_OK;
696 break;
697 case OT_ARRAY:
698 if ( v->Get( self, v->GetUp( -1 ), v->GetUp( -1 ), false, false ) )
699 return SQ_OK;
700 break;
701 default:
702 v->Pop( 1 );
703 return sq_throwerror( v, _SC( "rawget works only on array/table/instance and class" ) );
704 }
705 v->Pop( 1 );
706 return sq_throwerror( v, _SC( "the index doesn't exist" ) );
707 }
708
sq_getstackobj(HSQUIRRELVM v,SQInteger idx,HSQOBJECT * po)709 SQRESULT sq_getstackobj( HSQUIRRELVM v, SQInteger idx, HSQOBJECT *po ) {
710 *po = stack_get( v, idx );
711 return SQ_OK;
712 }
713
sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedInteger idx)714 const SQChar *sq_getlocal( HSQUIRRELVM v, SQUnsignedInteger level, SQUnsignedInteger idx ) {
715 SQUnsignedInteger cstksize = v->_callsstack.size();
716 SQUnsignedInteger lvl = ( cstksize - level ) - 1;
717 SQInteger stackbase = v->_stackbase;
718 if ( lvl < cstksize ) {
719 for ( SQUnsignedInteger i = 0;i < level;i++ ) {
720 SQVM::CallInfo &ci = v->_callsstack[( cstksize-i )-1];
721 stackbase -= ci._prevstkbase;
722 }
723 SQVM::CallInfo &ci = v->_callsstack[lvl];
724 if ( squirrel_type( ci._closure ) != OT_CLOSURE )
725 return NULL;
726 SQClosure *c = _closure( ci._closure );
727 SQFunctionProto *func = _funcproto( c->_function );
728 return func->GetLocal( v, stackbase, idx, ( ci._ip - func->_instructions._vals ) - 1 );
729 }
730 return NULL;
731 }
732
sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj)733 void sq_pushobject( HSQUIRRELVM v, HSQOBJECT obj ) {
734 v->Push( SQObjectPtr( obj ) );
735 }
736
sq_resetobject(HSQOBJECT * po)737 void sq_resetobject( HSQOBJECT *po ) {
738 po->_unVal.pUserPointer = NULL;po->_type = OT_NULL;
739 }
740
sq_throwerror(HSQUIRRELVM v,const SQChar * err)741 SQRESULT sq_throwerror( HSQUIRRELVM v, const SQChar *err ) {
742 v->_lasterror = SQString::Create( _ss( v ), err );
743 return -1;
744 }
745
sq_reseterror(HSQUIRRELVM v)746 void sq_reseterror( HSQUIRRELVM v ) {
747 v->_lasterror = _null_;
748 }
749
sq_getlasterror(HSQUIRRELVM v)750 void sq_getlasterror( HSQUIRRELVM v ) {
751 v->Push( v->_lasterror );
752 }
753
sq_reservestack(HSQUIRRELVM v,SQInteger nsize)754 void sq_reservestack( HSQUIRRELVM v, SQInteger nsize ) {
755 if ( ( ( SQUnsignedInteger )v->_top + nsize ) > v->_stack.size() ) {
756 v->_stack.resize( v->_stack.size() + ( ( v->_top + nsize ) - v->_stack.size() ) );
757 }
758 }
759
sq_resume(HSQUIRRELVM v,SQBool retval)760 SQRESULT sq_resume( HSQUIRRELVM v, SQBool retval ) {
761 if ( squirrel_type( v->GetUp( -1 ) ) == OT_GENERATOR ) {
762 v->Push( _null_ ); //retval
763 if ( !v->Execute( v->GetUp( -2 ), v->_top, 0, v->_top, v->GetUp( -1 ), SQVM::ET_RESUME_GENERATOR ) ) {
764 v->Raise_Error( v->_lasterror ); return SQ_ERROR;
765 }
766 if ( !retval )
767 v->Pop();
768 return SQ_OK;
769 }
770 return sq_throwerror( v, _SC( "only generators can be resumed" ) );
771 }
772
sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval)773 SQRESULT sq_call( HSQUIRRELVM v, SQInteger params, SQBool retval ) {
774 SQObjectPtr res;
775 if ( v->Call( v->GetUp( -( params + 1 ) ), params, v->_top - params, res ) ) {
776 v->Pop( params );//pop closure and args
777 if ( retval ) {
778 v->Push( res ); return SQ_OK;
779 }
780 return SQ_OK;
781 } else {
782 v->Pop( params );
783 return SQ_ERROR;
784 }
785 if ( !v->_suspended )
786 v->Pop( params );
787 return sq_throwerror( v, _SC( "call failed" ) );
788 }
789
sq_suspendvm(HSQUIRRELVM v)790 SQRESULT sq_suspendvm( HSQUIRRELVM v ) {
791 return v->Suspend();
792 }
793
sq_wakeupvm(HSQUIRRELVM v,SQBool wakeupret,SQBool retval)794 SQRESULT sq_wakeupvm( HSQUIRRELVM v, SQBool wakeupret, SQBool retval ) {
795 SQObjectPtr ret;
796 if ( !v->_suspended )
797 return sq_throwerror( v, _SC( "cannot resume a vm that is not running any code" ) );
798 if ( wakeupret ) {
799 v->GetAt( v->_stackbase + v->_suspended_target ) = v->GetUp( -1 ); //retval
800 v->Pop();
801 } else v->GetAt( v->_stackbase + v->_suspended_target ) = _null_;
802 if ( !v->Execute( _null_, v->_top, -1, -1, ret, SQVM::ET_RESUME_VM ) )
803 return SQ_ERROR;
804 if ( sq_getvmstate( v ) == SQ_VMSTATE_IDLE ) {
805 while ( v->_top > 1 ) v->_stack[--v->_top] = _null_;
806 }
807 if ( retval )
808 v->Push( ret );
809 return SQ_OK;
810 }
811
sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook)812 void sq_setreleasehook( HSQUIRRELVM v, SQInteger idx, SQRELEASEHOOK hook ) {
813 if ( sq_gettop( v ) >= 1 ) {
814 SQObjectPtr &ud = stack_get( v, idx );
815 switch ( squirrel_type( ud ) ) {
816 case OT_USERDATA:
817 _userdata( ud )->_hook = hook;
818 break;
819 case OT_INSTANCE:
820 _instance( ud )->_hook = hook;
821 break;
822 }
823 }
824 }
825
sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f)826 void sq_setcompilererrorhandler( HSQUIRRELVM v, SQCOMPILERERROR f ) {
827 _ss( v )->_compilererrorhandler = f;
828 }
829
sq_writeclosure(HSQUIRRELVM v,SQWRITEFUNC w,SQUserPointer up)830 SQRESULT sq_writeclosure( HSQUIRRELVM v, SQWRITEFUNC w, SQUserPointer up ) {
831 SQObjectPtr *o = NULL;
832 _GETSAFE_OBJ( v, -1, OT_CLOSURE, o );
833 SQClosure *c = _closure( *o );
834 unsigned short tag = SQ_BYTECODE_STREAM_TAG;
835 if ( w( up, &tag, 2 ) != 2 )
836 return sq_throwerror( v, _SC( "io error" ) );
837 if ( !_closure( *o )->Save( v, up, w ) )
838 return SQ_ERROR;
839 return SQ_OK;
840 }
841
sq_readclosure(HSQUIRRELVM v,SQREADFUNC r,SQUserPointer up)842 SQRESULT sq_readclosure( HSQUIRRELVM v, SQREADFUNC r, SQUserPointer up ) {
843 SQObjectPtr func = SQFunctionProto::Create();
844 SQObjectPtr closure = SQClosure::Create( _ss( v ), _funcproto( func ) );
845 unsigned short tag;
846 if ( r( up, &tag, 2 ) != 2 )
847 return sq_throwerror( v, _SC( "io error" ) );
848 if ( tag != SQ_BYTECODE_STREAM_TAG )
849 return sq_throwerror( v, _SC( "invalid stream" ) );
850 if ( !_closure( closure )->Load( v, up, r ) )
851 return SQ_ERROR;
852 v->Push( closure );
853 return SQ_OK;
854 }
855
sq_getscratchpad(HSQUIRRELVM v,SQInteger minsize)856 SQChar *sq_getscratchpad( HSQUIRRELVM v, SQInteger minsize ) {
857 return _ss( v )->GetScratchPad( minsize );
858 }
859
sq_collectgarbage(HSQUIRRELVM v)860 SQInteger sq_collectgarbage( HSQUIRRELVM v ) {
861 #ifndef NO_GARBAGE_COLLECTOR
862 return _ss( v )->CollectGarbage( v );
863 #else
864 return -1;
865 #endif
866 }
867
sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval)868 const SQChar *sq_getfreevariable( HSQUIRRELVM v, SQInteger idx, SQUnsignedInteger nval ) {
869 SQObjectPtr &self = stack_get( v, idx );
870 const SQChar *name = NULL;
871 if ( squirrel_type( self ) == OT_CLOSURE ) {
872 if ( _closure( self )->_outervalues.size() > nval ) {
873 v->Push( _closure( self )->_outervalues[nval] );
874 SQFunctionProto *fp = _funcproto( _closure( self )->_function );
875 SQOuterVar &ov = fp->_outervalues[nval];
876 name = _stringval( ov._name );
877 }
878 }
879 return name;
880 }
881
sq_setfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval)882 SQRESULT sq_setfreevariable( HSQUIRRELVM v, SQInteger idx, SQUnsignedInteger nval ) {
883 SQObjectPtr &self = stack_get( v, idx );
884 switch ( squirrel_type( self ) ) {
885 case OT_CLOSURE:
886 if ( _closure( self )->_outervalues.size() > nval ) {
887 _closure( self )->_outervalues[nval] = stack_get( v, -1 );
888 } else return sq_throwerror( v, _SC( "invalid free var index" ) );
889 break;
890 case OT_NATIVECLOSURE:
891 if ( _nativeclosure( self )->_outervalues.size() > nval ) {
892 _nativeclosure( self )->_outervalues[nval] = stack_get( v, -1 );
893 } else return sq_throwerror( v, _SC( "invalid free var index" ) );
894 break;
895 default:
896 return sq_aux_invalidtype( v, squirrel_type( self ) );
897 }
898 v->Pop( 1 );
899 return SQ_OK;
900 }
901
sq_setattributes(HSQUIRRELVM v,SQInteger idx)902 SQRESULT sq_setattributes( HSQUIRRELVM v, SQInteger idx ) {
903 SQObjectPtr *o = NULL;
904 _GETSAFE_OBJ( v, idx, OT_CLASS, o );
905 SQObjectPtr &key = stack_get( v, -2 );
906 SQObjectPtr &val = stack_get( v, -1 );
907 SQObjectPtr attrs;
908 if ( squirrel_type( key ) == OT_NULL ) {
909 attrs = _class( *o )->_attributes;
910 _class( *o )->_attributes = val;
911 v->Pop( 2 );
912 v->Push( attrs );
913 return SQ_OK;
914 } else if ( _class( *o )->GetAttributes( key, attrs ) ) {
915 _class( *o )->SetAttributes( key, val );
916 v->Pop( 2 );
917 v->Push( attrs );
918 return SQ_OK;
919 }
920 return sq_throwerror( v, _SC( "wrong index" ) );
921 }
922
sq_getattributes(HSQUIRRELVM v,SQInteger idx)923 SQRESULT sq_getattributes( HSQUIRRELVM v, SQInteger idx ) {
924 SQObjectPtr *o = NULL;
925 _GETSAFE_OBJ( v, idx, OT_CLASS, o );
926 SQObjectPtr &key = stack_get( v, -1 );
927 SQObjectPtr attrs;
928 if ( squirrel_type( key ) == OT_NULL ) {
929 attrs = _class( *o )->_attributes;
930 v->Pop();
931 v->Push( attrs );
932 return SQ_OK;
933 } else if ( _class( *o )->GetAttributes( key, attrs ) ) {
934 v->Pop();
935 v->Push( attrs );
936 return SQ_OK;
937 }
938 return sq_throwerror( v, _SC( "wrong index" ) );
939 }
940
sq_getclass(HSQUIRRELVM v,SQInteger idx)941 SQRESULT sq_getclass( HSQUIRRELVM v, SQInteger idx ) {
942 SQObjectPtr *o = NULL;
943 _GETSAFE_OBJ( v, idx, OT_INSTANCE, o );
944 v->Push( SQObjectPtr( _instance( *o )->_class ) );
945 return SQ_OK;
946 }
947
sq_createinstance(HSQUIRRELVM v,SQInteger idx)948 SQRESULT sq_createinstance( HSQUIRRELVM v, SQInteger idx ) {
949 SQObjectPtr *o = NULL;
950 _GETSAFE_OBJ( v, idx, OT_CLASS, o );
951 v->Push( _class( *o )->CreateInstance() );
952 return SQ_OK;
953 }
954
sq_weakref(HSQUIRRELVM v,SQInteger idx)955 void sq_weakref( HSQUIRRELVM v, SQInteger idx ) {
956 SQObject &o = stack_get( v, idx );
957 if ( ISREFCOUNTED( squirrel_type( o ) ) ) {
958 v->Push( _refcounted( o )->GetWeakRef( squirrel_type( o ) ) );
959 return;
960 }
961 v->Push( o );
962 }
963
sq_getweakrefval(HSQUIRRELVM v,SQInteger idx)964 SQRESULT sq_getweakrefval( HSQUIRRELVM v, SQInteger idx ) {
965 SQObjectPtr &o = stack_get( v, idx );
966 if ( squirrel_type( o ) != OT_WEAKREF ) {
967 return sq_throwerror( v, _SC( "the object must be a weakref" ) );
968 }
969 v->Push( _weakref( o )->_obj );
970 return SQ_OK;
971 }
972
sq_next(HSQUIRRELVM v,SQInteger idx)973 SQRESULT sq_next( HSQUIRRELVM v, SQInteger idx ) {
974 SQObjectPtr o = stack_get( v, idx ), &refpos = stack_get( v, -1 ), realkey, val;
975 if ( squirrel_type( o ) == OT_GENERATOR ) {
976 return sq_throwerror( v, _SC( "cannot iterate a generator" ) );
977 }
978 bool finished;
979 if ( !v->FOREACH_OP( o, realkey, val, refpos, 0, finished ) )
980 return SQ_ERROR;
981 if ( !finished ) {
982 v->Push( realkey );
983 v->Push( val );
984 return SQ_OK;
985 }
986 return SQ_ERROR;
987 }
988
989 struct BufState {
990 const SQChar *buf;
991 SQInteger ptr;
992 SQInteger size;
993 };
994
buf_lexfeed(SQUserPointer file)995 SQInteger buf_lexfeed( SQUserPointer file ) {
996 BufState *buf = ( BufState* )file;
997 if ( buf->size < ( buf->ptr + 1 ) )
998 return 0;
999 return buf->buf[buf->ptr++];
1000 }
1001
sq_compilebuffer(HSQUIRRELVM v,const SQChar * s,SQInteger size,const SQChar * sourcename,SQBool raiseerror)1002 SQRESULT sq_compilebuffer( HSQUIRRELVM v, const SQChar *s, SQInteger size, const SQChar *sourcename, SQBool raiseerror ) {
1003 BufState buf;
1004 buf.buf = s;
1005 buf.size = size;
1006 buf.ptr = 0;
1007 return sq_compile( v, buf_lexfeed, &buf, sourcename, raiseerror );
1008 }
1009
sq_move(HSQUIRRELVM dest,HSQUIRRELVM src,SQInteger idx)1010 void sq_move( HSQUIRRELVM dest, HSQUIRRELVM src, SQInteger idx ) {
1011 dest->Push( stack_get( src, idx ) );
1012 }
1013
sq_setprintfunc(HSQUIRRELVM v,SQPRINTFUNCTION printfunc)1014 void sq_setprintfunc( HSQUIRRELVM v, SQPRINTFUNCTION printfunc ) {
1015 _ss( v )->_printfunc = printfunc;
1016 }
1017
sq_getprintfunc(HSQUIRRELVM v)1018 SQPRINTFUNCTION sq_getprintfunc( HSQUIRRELVM v ) {
1019 return _ss( v )->_printfunc;
1020 }
1021
sq_malloc(SQUnsignedInteger size)1022 void *sq_malloc( SQUnsignedInteger size ) {
1023 return SQ_MALLOC( size );
1024 }
1025
sq_realloc(void * p,SQUnsignedInteger oldsize,SQUnsignedInteger newsize)1026 void *sq_realloc( void* p, SQUnsignedInteger oldsize, SQUnsignedInteger newsize ) {
1027 return SQ_REALLOC( p, oldsize, newsize );
1028 }
sq_free(void * p,SQUnsignedInteger size)1029 void sq_free( void *p, SQUnsignedInteger size ) {
1030 SQ_FREE( p, size );
1031 }
1032