00001
00002
00003
00004 #include <squirrel.h>
00005 #include "sqpcheader.h"
00006 #include "sqvm.h"
00007 #include "sqstring.h"
00008 #include "sqtable.h"
00009 #include "sqarray.h"
00010 #include "sqfuncproto.h"
00011 #include "sqclosure.h"
00012 #include "squserdata.h"
00013 #include "sqcompiler.h"
00014 #include "sqfuncstate.h"
00015 #include "sqclass.h"
00016
00017 bool sq_aux_gettypedarg(HSQUIRRELVM v,SQInteger idx,SQObjectType type,SQObjectPtr **o)
00018 {
00019 *o = &stack_get(v,idx);
00020 if(type(**o) != type){
00021 SQObjectPtr oval = v->PrintObjVal(**o);
00022 v->Raise_Error(_SC("wrong argument type, expected '%s' got '%.50s'"),IdType2Name(type),_stringval(oval));
00023 return false;
00024 }
00025 return true;
00026 }
00027
00028 #define _GETSAFE_OBJ(v,idx,type,o) { if(!sq_aux_gettypedarg(v,idx,type,&o)) return SQ_ERROR; }
00029
00030 #define sq_aux_paramscheck(v,count) \
00031 { \
00032 if(sq_gettop(v) < count){ v->Raise_Error(_SC("not enough params in the stack")); return SQ_ERROR; }\
00033 }
00034
00035 SQInteger sq_aux_throwobject(HSQUIRRELVM v,SQObjectPtr &e)
00036 {
00037 v->_lasterror = e;
00038 return SQ_ERROR;
00039 }
00040
00041 SQInteger sq_aux_invalidtype(HSQUIRRELVM v,SQObjectType type)
00042 {
00043 scsprintf(_ss(v)->GetScratchPad(100), _SC("unexpected type %s"), IdType2Name(type));
00044 return sq_throwerror(v, _ss(v)->GetScratchPad(-1));
00045 }
00046
00047 HSQUIRRELVM sq_open(SQInteger initialstacksize)
00048 {
00049 SQSharedState *ss;
00050 SQVM *v;
00051 sq_new(ss, SQSharedState);
00052 ss->Init();
00053 v = (SQVM *)SQ_MALLOC(sizeof(SQVM));
00054 new (v) SQVM(ss);
00055 ss->_root_vm = v;
00056 if(v->Init(NULL, initialstacksize)) {
00057 return v;
00058 } else {
00059 sq_delete(v, SQVM);
00060 return NULL;
00061 }
00062 return v;
00063 }
00064
00065 HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, SQInteger initialstacksize)
00066 {
00067 SQSharedState *ss;
00068 SQVM *v;
00069 ss=_ss(friendvm);
00070
00071 v= (SQVM *)SQ_MALLOC(sizeof(SQVM));
00072 new (v) SQVM(ss);
00073
00074 if(v->Init(friendvm, initialstacksize)) {
00075 friendvm->Push(v);
00076 return v;
00077 } else {
00078 sq_delete(v, SQVM);
00079 return NULL;
00080 }
00081 }
00082
00083 SQInteger sq_getvmstate(HSQUIRRELVM v)
00084 {
00085 if(v->_suspended)
00086 return SQ_VMSTATE_SUSPENDED;
00087 else {
00088 if(v->_callsstacksize != 0) return SQ_VMSTATE_RUNNING;
00089 else return SQ_VMSTATE_IDLE;
00090 }
00091 }
00092
00093 bool sq_can_suspend(HSQUIRRELVM v)
00094 {
00095 return v->_nnativecalls <= 2;
00096 }
00097
00098 void sq_seterrorhandler(HSQUIRRELVM v)
00099 {
00100 SQObject o = stack_get(v, -1);
00101 if(sq_isclosure(o) || sq_isnativeclosure(o) || sq_isnull(o)) {
00102 v->_errorhandler = o;
00103 v->Pop();
00104 }
00105 }
00106
00107 void sq_setdebughook(HSQUIRRELVM v)
00108 {
00109 SQObject o = stack_get(v,-1);
00110 if(sq_isclosure(o) || sq_isnativeclosure(o) || sq_isnull(o)) {
00111 v->_debughook = o;
00112 v->Pop();
00113 }
00114 }
00115
00116 void sq_close(HSQUIRRELVM v)
00117 {
00118 SQSharedState *ss = _ss(v);
00119 _thread(ss->_root_vm)->Finalize();
00120 sq_delete(ss, SQSharedState);
00121 }
00122
00123 SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename,SQBool raiseerror)
00124 {
00125 SQObjectPtr o;
00126 if(Compile(v, read, p, sourcename, o, raiseerror?true:false, _ss(v)->_debuginfo)) {
00127 v->Push(SQClosure::Create(_ss(v), _funcproto(o)));
00128 return SQ_OK;
00129 }
00130 return SQ_ERROR;
00131 }
00132
00133 void sq_enabledebuginfo(HSQUIRRELVM v, SQBool enable)
00134 {
00135 _ss(v)->_debuginfo = enable?true:false;
00136 }
00137
00138 void sq_notifyallexceptions(HSQUIRRELVM v, SQBool enable)
00139 {
00140 _ss(v)->_notifyallexceptions = enable?true:false;
00141 }
00142
00143 void sq_addref(HSQUIRRELVM v,HSQOBJECT *po)
00144 {
00145 if(!ISREFCOUNTED(type(*po))) return;
00146 #ifdef NO_GARBAGE_COLLECTOR
00147 __AddRef(po->_type,po->_unVal);
00148 #else
00149 _ss(v)->_refs_table.AddRef(*po);
00150 #endif
00151 }
00152
00153 SQBool sq_release(HSQUIRRELVM v,HSQOBJECT *po)
00154 {
00155 if(!ISREFCOUNTED(type(*po))) return SQTrue;
00156 #ifdef NO_GARBAGE_COLLECTOR
00157 __Release(po->_type,po->_unVal);
00158 return SQFalse;
00159 #else
00160 return _ss(v)->_refs_table.Release(*po);
00161 #endif
00162 }
00163
00164 const SQChar *sq_objtostring(HSQOBJECT *o)
00165 {
00166 if(sq_type(*o) == OT_STRING) {
00167 return _stringval(*o);
00168 }
00169 return NULL;
00170 }
00171
00172 SQInteger sq_objtointeger(HSQOBJECT *o)
00173 {
00174 if(sq_isnumeric(*o)) {
00175 return tointeger(*o);
00176 }
00177 return 0;
00178 }
00179
00180 SQFloat sq_objtofloat(HSQOBJECT *o)
00181 {
00182 if(sq_isnumeric(*o)) {
00183 return tofloat(*o);
00184 }
00185 return 0;
00186 }
00187
00188 SQBool sq_objtobool(HSQOBJECT *o)
00189 {
00190 if(sq_isbool(*o)) {
00191 return _integer(*o);
00192 }
00193 return SQFalse;
00194 }
00195
00196 void sq_pushnull(HSQUIRRELVM v)
00197 {
00198 v->Push(_null_);
00199 }
00200
00201 void sq_pushstring(HSQUIRRELVM v,const SQChar *s,SQInteger len)
00202 {
00203 if(s)
00204 v->Push(SQObjectPtr(SQString::Create(_ss(v), s, len)));
00205 else v->Push(_null_);
00206 }
00207
00208 void sq_pushinteger(HSQUIRRELVM v,SQInteger n)
00209 {
00210 v->Push(n);
00211 }
00212
00213 void sq_pushbool(HSQUIRRELVM v,SQBool b)
00214 {
00215 v->Push(b?true:false);
00216 }
00217
00218 void sq_pushfloat(HSQUIRRELVM v,SQFloat n)
00219 {
00220 v->Push(n);
00221 }
00222
00223 void sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p)
00224 {
00225 v->Push(p);
00226 }
00227
00228 SQUserPointer sq_newuserdata(HSQUIRRELVM v,SQUnsignedInteger size)
00229 {
00230 SQUserData *ud = SQUserData::Create(_ss(v), size);
00231 v->Push(ud);
00232 return ud->_val;
00233 }
00234
00235 void sq_newtable(HSQUIRRELVM v)
00236 {
00237 v->Push(SQTable::Create(_ss(v), 0));
00238 }
00239
00240 void sq_newarray(HSQUIRRELVM v,SQInteger size)
00241 {
00242 v->Push(SQArray::Create(_ss(v), size));
00243 }
00244
00245 SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase)
00246 {
00247 SQClass *baseclass = NULL;
00248 if(hasbase) {
00249 SQObjectPtr &base = stack_get(v,-1);
00250 if(type(base) != OT_CLASS)
00251 return sq_throwerror(v,_SC("invalid base type"));
00252 baseclass = _class(base);
00253 }
00254 SQClass *newclass = SQClass::Create(_ss(v), baseclass);
00255 if(baseclass) v->Pop();
00256 v->Push(newclass);
00257 return SQ_OK;
00258 }
00259
00260 SQBool sq_instanceof(HSQUIRRELVM v)
00261 {
00262 SQObjectPtr &inst = stack_get(v,-1);
00263 SQObjectPtr &cl = stack_get(v,-2);
00264 if(type(inst) != OT_INSTANCE || type(cl) != OT_CLASS)
00265 return sq_throwerror(v,_SC("invalid param type"));
00266 return _instance(inst)->InstanceOf(_class(cl))?SQTrue:SQFalse;
00267 }
00268
00269 SQRESULT sq_arrayappend(HSQUIRRELVM v,SQInteger idx)
00270 {
00271 sq_aux_paramscheck(v,2);
00272 SQObjectPtr *arr;
00273 _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);
00274 _array(*arr)->Append(v->GetUp(-1));
00275 v->Pop(1);
00276 return SQ_OK;
00277 }
00278
00279 SQRESULT sq_arraypop(HSQUIRRELVM v,SQInteger idx,SQBool pushval)
00280 {
00281 sq_aux_paramscheck(v, 1);
00282 SQObjectPtr *arr;
00283 _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);
00284 if(_array(*arr)->Size() > 0) {
00285 if(pushval != 0){ v->Push(_array(*arr)->Top()); }
00286 _array(*arr)->Pop();
00287 return SQ_OK;
00288 }
00289 return sq_throwerror(v, _SC("empty array"));
00290 }
00291
00292 SQRESULT sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize)
00293 {
00294 sq_aux_paramscheck(v,1);
00295 SQObjectPtr *arr;
00296 _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);
00297 if(newsize >= 0) {
00298 _array(*arr)->Resize(newsize);
00299 return SQ_OK;
00300 }
00301 return sq_throwerror(v,_SC("negative size"));
00302 }
00303
00304
00305 SQRESULT sq_arrayreverse(HSQUIRRELVM v,SQInteger idx)
00306 {
00307 sq_aux_paramscheck(v, 1);
00308 SQObjectPtr *o;
00309 _GETSAFE_OBJ(v, idx, OT_ARRAY,o);
00310 SQArray *arr = _array(*o);
00311 if(arr->Size() > 0) {
00312 SQObjectPtr t;
00313 SQInteger size = arr->Size();
00314 SQInteger n = size >> 1; size -= 1;
00315 for(SQInteger i = 0; i < n; i++) {
00316 t = arr->_values[i];
00317 arr->_values[i] = arr->_values[size-i];
00318 arr->_values[size-i] = t;
00319 }
00320 return SQ_OK;
00321 }
00322 return SQ_OK;
00323 }
00324
00325 SQRESULT sq_arrayremove(HSQUIRRELVM v,SQInteger idx,SQInteger itemidx)
00326 {
00327 sq_aux_paramscheck(v, 1);
00328 SQObjectPtr *arr;
00329 _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);
00330 return _array(*arr)->Remove(itemidx) ? SQ_OK : sq_throwerror(v,_SC("index out of range"));
00331 }
00332
00333 SQRESULT sq_arrayinsert(HSQUIRRELVM v,SQInteger idx,SQInteger destpos)
00334 {
00335 sq_aux_paramscheck(v, 1);
00336 SQObjectPtr *arr;
00337 _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);
00338 SQRESULT ret = _array(*arr)->Insert(destpos, v->GetUp(-1)) ? SQ_OK : sq_throwerror(v,_SC("index out of range"));
00339 v->Pop();
00340 return ret;
00341 }
00342
00343
00344 void sq_newclosure(HSQUIRRELVM v,SQFUNCTION func,SQUnsignedInteger nfreevars)
00345 {
00346 SQNativeClosure *nc = SQNativeClosure::Create(_ss(v), func);
00347 nc->_nparamscheck = 0;
00348 for(SQUnsignedInteger i = 0; i < nfreevars; i++) {
00349 nc->_outervalues.push_back(v->Top());
00350 v->Pop();
00351 }
00352 v->Push(SQObjectPtr(nc));
00353 }
00354
00355 SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger *nparams,SQUnsignedInteger *nfreevars)
00356 {
00357 SQObject o = stack_get(v, idx);
00358 if(sq_isclosure(o)) {
00359 SQClosure *c = _closure(o);
00360 SQFunctionProto *proto = _funcproto(c->_function);
00361 *nparams = (SQUnsignedInteger)proto->_nparameters;
00362 *nfreevars = (SQUnsignedInteger)c->_outervalues.size();
00363 return SQ_OK;
00364 }
00365 return sq_throwerror(v,_SC("the object is not a closure"));
00366 }
00367
00368 SQRESULT sq_setnativeclosurename(HSQUIRRELVM v,SQInteger idx,const SQChar *name)
00369 {
00370 SQObject o = stack_get(v, idx);
00371 if(sq_isnativeclosure(o)) {
00372 SQNativeClosure *nc = _nativeclosure(o);
00373 nc->_name = SQString::Create(_ss(v),name);
00374 return SQ_OK;
00375 }
00376 return sq_throwerror(v,_SC("the object is not a nativeclosure"));
00377 }
00378
00379 SQRESULT sq_setparamscheck(HSQUIRRELVM v,SQInteger nparamscheck,const SQChar *typemask)
00380 {
00381 SQObject o = stack_get(v, -1);
00382 if(!sq_isnativeclosure(o))
00383 return sq_throwerror(v, _SC("native closure expected"));
00384 SQNativeClosure *nc = _nativeclosure(o);
00385 nc->_nparamscheck = nparamscheck;
00386 if(typemask) {
00387 SQIntVec res;
00388 if(!CompileTypemask(res, typemask))
00389 return sq_throwerror(v, _SC("invalid typemask"));
00390 nc->_typecheck.copy(res);
00391 }
00392 else {
00393 nc->_typecheck.resize(0);
00394 }
00395 if(nparamscheck == SQ_MATCHTYPEMASKSTRING) {
00396 nc->_nparamscheck = nc->_typecheck.size();
00397 }
00398 return SQ_OK;
00399 }
00400
00401 SQRESULT sq_bindenv(HSQUIRRELVM v,SQInteger idx)
00402 {
00403 SQObjectPtr &o = stack_get(v,idx);
00404 if(!sq_isnativeclosure(o) &&
00405 !sq_isclosure(o))
00406 return sq_throwerror(v,_SC("the target is not a closure"));
00407 SQObjectPtr &env = stack_get(v,-1);
00408 if(!sq_istable(env) &&
00409 !sq_isclass(env) &&
00410 !sq_isinstance(env))
00411 return sq_throwerror(v,_SC("invalid environment"));
00412 SQObjectPtr w = _refcounted(env)->GetWeakRef(type(env));
00413 SQObjectPtr ret;
00414 if(sq_isclosure(o)) {
00415 SQClosure *c = _closure(o)->Clone();
00416 c->_env = w;
00417 ret = c;
00418 }
00419 else {
00420 SQNativeClosure *c = _nativeclosure(o)->Clone();
00421 c->_env = w;
00422 ret = c;
00423 }
00424 v->Pop();
00425 v->Push(ret);
00426 return SQ_OK;
00427 }
00428
00429 SQRESULT sq_clear(HSQUIRRELVM v,SQInteger idx)
00430 {
00431 SQObject &o=stack_get(v,idx);
00432 switch(type(o)) {
00433 case OT_TABLE: _table(o)->Clear(); break;
00434 case OT_ARRAY: _array(o)->Resize(0); break;
00435 default:
00436 return sq_throwerror(v, _SC("clear only works on table and array"));
00437 break;
00438
00439 }
00440 return SQ_OK;
00441 }
00442
00443 void sq_pushroottable(HSQUIRRELVM v)
00444 {
00445 v->Push(v->_roottable);
00446 }
00447
00448 void sq_pushregistrytable(HSQUIRRELVM v)
00449 {
00450 v->Push(_ss(v)->_registry);
00451 }
00452
00453 void sq_pushconsttable(HSQUIRRELVM v)
00454 {
00455 v->Push(_ss(v)->_consts);
00456 }
00457
00458 SQRESULT sq_setroottable(HSQUIRRELVM v)
00459 {
00460 SQObject o = stack_get(v, -1);
00461 if(sq_istable(o) || sq_isnull(o)) {
00462 v->_roottable = o;
00463 v->Pop();
00464 return SQ_OK;
00465 }
00466 return sq_throwerror(v, _SC("ivalid type"));
00467 }
00468
00469 SQRESULT sq_setconsttable(HSQUIRRELVM v)
00470 {
00471 SQObject o = stack_get(v, -1);
00472 if(sq_istable(o)) {
00473 _ss(v)->_consts = o;
00474 v->Pop();
00475 return SQ_OK;
00476 }
00477 return sq_throwerror(v, _SC("ivalid type, expected table"));
00478 }
00479
00480 void sq_setforeignptr(HSQUIRRELVM v,SQUserPointer p)
00481 {
00482 v->_foreignptr = p;
00483 }
00484
00485 SQUserPointer sq_getforeignptr(HSQUIRRELVM v)
00486 {
00487 return v->_foreignptr;
00488 }
00489
00490 void sq_push(HSQUIRRELVM v,SQInteger idx)
00491 {
00492 v->Push(stack_get(v, idx));
00493 }
00494
00495 SQObjectType sq_gettype(HSQUIRRELVM v,SQInteger idx)
00496 {
00497 return type(stack_get(v, idx));
00498 }
00499
00500
00501 void sq_tostring(HSQUIRRELVM v,SQInteger idx)
00502 {
00503 SQObjectPtr &o = stack_get(v, idx);
00504 SQObjectPtr res;
00505 v->ToString(o,res);
00506 v->Push(res);
00507 }
00508
00509 void sq_tobool(HSQUIRRELVM v, SQInteger idx, SQBool *b)
00510 {
00511 SQObjectPtr &o = stack_get(v, idx);
00512 *b = v->IsFalse(o)?SQFalse:SQTrue;
00513 }
00514
00515 SQRESULT sq_getinteger(HSQUIRRELVM v,SQInteger idx,SQInteger *i)
00516 {
00517 SQObjectPtr &o = stack_get(v, idx);
00518 if(sq_isnumeric(o)) {
00519 *i = tointeger(o);
00520 return SQ_OK;
00521 }
00522 return SQ_ERROR;
00523 }
00524
00525 SQRESULT sq_getfloat(HSQUIRRELVM v,SQInteger idx,SQFloat *f)
00526 {
00527 SQObjectPtr &o = stack_get(v, idx);
00528 if(sq_isnumeric(o)) {
00529 *f = tofloat(o);
00530 return SQ_OK;
00531 }
00532 return SQ_ERROR;
00533 }
00534
00535 SQRESULT sq_getbool(HSQUIRRELVM v,SQInteger idx,SQBool *b)
00536 {
00537 SQObjectPtr &o = stack_get(v, idx);
00538 if(sq_isbool(o)) {
00539 *b = _integer(o);
00540 return SQ_OK;
00541 }
00542 return SQ_ERROR;
00543 }
00544
00545 SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c)
00546 {
00547 SQObjectPtr *o = NULL;
00548 _GETSAFE_OBJ(v, idx, OT_STRING,o);
00549 *c = _stringval(*o);
00550 return SQ_OK;
00551 }
00552
00553 SQRESULT sq_getthread(HSQUIRRELVM v,SQInteger idx,HSQUIRRELVM *thread)
00554 {
00555 SQObjectPtr *o = NULL;
00556 _GETSAFE_OBJ(v, idx, OT_THREAD,o);
00557 *thread = _thread(*o);
00558 return SQ_OK;
00559 }
00560
00561 SQRESULT sq_clone(HSQUIRRELVM v,SQInteger idx)
00562 {
00563 SQObjectPtr &o = stack_get(v,idx);
00564 v->Push(_null_);
00565 if(!v->Clone(o, stack_get(v, -1))){
00566 v->Pop();
00567 return sq_aux_invalidtype(v, type(o));
00568 }
00569 return SQ_OK;
00570 }
00571
00572 SQInteger sq_getsize(HSQUIRRELVM v, SQInteger idx)
00573 {
00574 SQObjectPtr &o = stack_get(v, idx);
00575 SQObjectType type = type(o);
00576 switch(type) {
00577 case OT_STRING: return _string(o)->_len;
00578 case OT_TABLE: return _table(o)->CountUsed();
00579 case OT_ARRAY: return _array(o)->Size();
00580 case OT_USERDATA: return _userdata(o)->_size;
00581 default:
00582 return sq_aux_invalidtype(v, type);
00583 }
00584 }
00585
00586 SQRESULT sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p,SQUserPointer *typetag)
00587 {
00588 SQObjectPtr *o = NULL;
00589 _GETSAFE_OBJ(v, idx, OT_USERDATA,o);
00590 (*p) = _userdataval(*o);
00591 if(typetag) *typetag = _userdata(*o)->_typetag;
00592 return SQ_OK;
00593 }
00594
00595 SQRESULT sq_settypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer typetag)
00596 {
00597 SQObjectPtr &o = stack_get(v,idx);
00598 switch(type(o)) {
00599 case OT_USERDATA: _userdata(o)->_typetag = typetag; break;
00600 case OT_CLASS: _class(o)->_typetag = typetag; break;
00601 default: return sq_throwerror(v,_SC("invalid object type"));
00602 }
00603 return SQ_OK;
00604 }
00605
00606 SQRESULT sq_getobjtypetag(HSQOBJECT *o,SQUserPointer * typetag)
00607 {
00608 switch(type(*o)) {
00609 case OT_INSTANCE: *typetag = _instance(*o)->_class->_typetag; break;
00610 case OT_USERDATA: *typetag = _userdata(*o)->_typetag; break;
00611 case OT_CLASS: *typetag = _class(*o)->_typetag; break;
00612 default: return SQ_ERROR;
00613 }
00614 return SQ_OK;
00615 }
00616
00617 SQRESULT sq_gettypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer *typetag)
00618 {
00619 SQObjectPtr &o = stack_get(v,idx);
00620 if(SQ_FAILED(sq_getobjtypetag(&o,typetag)))
00621 return sq_throwerror(v,_SC("invalid object type"));
00622 return SQ_OK;
00623 }
00624
00625 SQRESULT sq_getuserpointer(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p)
00626 {
00627 SQObjectPtr *o = NULL;
00628 _GETSAFE_OBJ(v, idx, OT_USERPOINTER,o);
00629 (*p) = _userpointer(*o);
00630 return SQ_OK;
00631 }
00632
00633 SQRESULT sq_setinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer p)
00634 {
00635 SQObjectPtr &o = stack_get(v,idx);
00636 if(type(o) != OT_INSTANCE) return sq_throwerror(v,_SC("the object is not a class instance"));
00637 _instance(o)->_userpointer = p;
00638 return SQ_OK;
00639 }
00640
00641 SQRESULT sq_setclassudsize(HSQUIRRELVM v, SQInteger idx, SQInteger udsize)
00642 {
00643 SQObjectPtr &o = stack_get(v,idx);
00644 if(type(o) != OT_CLASS) return sq_throwerror(v,_SC("the object is not a class"));
00645 if(_class(o)->_locked) return sq_throwerror(v,_SC("the class is locked"));
00646 _class(o)->_udsize = udsize;
00647 return SQ_OK;
00648 }
00649
00650
00651 SQRESULT sq_getinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p,SQUserPointer typetag)
00652 {
00653 SQObjectPtr &o = stack_get(v,idx);
00654 if(type(o) != OT_INSTANCE) return sq_throwerror(v,_SC("the object is not a class instance"));
00655 (*p) = _instance(o)->_userpointer;
00656 if(typetag != 0) {
00657 SQClass *cl = _instance(o)->_class;
00658 do{
00659 if(cl->_typetag == typetag)
00660 return SQ_OK;
00661 cl = cl->_base;
00662 }while(cl != NULL);
00663 return sq_throwerror(v,_SC("invalid type tag"));
00664 }
00665 return SQ_OK;
00666 }
00667
00668 SQInteger sq_gettop(HSQUIRRELVM v)
00669 {
00670 return (v->_top) - v->_stackbase;
00671 }
00672
00673 void sq_settop(HSQUIRRELVM v, SQInteger newtop)
00674 {
00675 SQInteger top = sq_gettop(v);
00676 if(top > newtop)
00677 sq_pop(v, top - newtop);
00678 else
00679 while(top++ < newtop) sq_pushnull(v);
00680 }
00681
00682 void sq_pop(HSQUIRRELVM v, SQInteger nelemstopop)
00683 {
00684 assert(v->_top >= nelemstopop);
00685 v->Pop(nelemstopop);
00686 }
00687
00688 void sq_poptop(HSQUIRRELVM v)
00689 {
00690 assert(v->_top >= 1);
00691 v->Pop();
00692 }
00693
00694
00695 void sq_remove(HSQUIRRELVM v, SQInteger idx)
00696 {
00697 v->Remove(idx);
00698 }
00699
00700 SQInteger sq_cmp(HSQUIRRELVM v)
00701 {
00702 SQInteger res;
00703 v->ObjCmp(stack_get(v, -1), stack_get(v, -2),res);
00704 return res;
00705 }
00706
00707 SQRESULT sq_newslot(HSQUIRRELVM v, SQInteger idx, SQBool bstatic)
00708 {
00709 sq_aux_paramscheck(v, 3);
00710 SQObjectPtr &self = stack_get(v, idx);
00711 if(type(self) == OT_TABLE || type(self) == OT_CLASS) {
00712 SQObjectPtr &key = v->GetUp(-2);
00713 if(type(key) == OT_NULL) return sq_throwerror(v, _SC("null is not a valid key"));
00714 v->NewSlot(self, key, v->GetUp(-1),bstatic?true:false);
00715 v->Pop(2);
00716 }
00717 return SQ_OK;
00718 }
00719
00720 SQRESULT sq_deleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval)
00721 {
00722 sq_aux_paramscheck(v, 2);
00723 SQObjectPtr *self;
00724 _GETSAFE_OBJ(v, idx, OT_TABLE,self);
00725 SQObjectPtr &key = v->GetUp(-1);
00726 if(type(key) == OT_NULL) return sq_throwerror(v, _SC("null is not a valid key"));
00727 SQObjectPtr res;
00728 if(!v->DeleteSlot(*self, key, res)){
00729 return SQ_ERROR;
00730 }
00731 if(pushval) v->GetUp(-1) = res;
00732 else v->Pop(1);
00733 return SQ_OK;
00734 }
00735
00736 SQRESULT sq_set(HSQUIRRELVM v,SQInteger idx)
00737 {
00738 SQObjectPtr &self = stack_get(v, idx);
00739 if(v->Set(self, v->GetUp(-2), v->GetUp(-1),false)) {
00740 v->Pop(2);
00741 return SQ_OK;
00742 }
00743 v->Raise_IdxError(v->GetUp(-2));return SQ_ERROR;
00744 }
00745
00746 SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx)
00747 {
00748 SQObjectPtr &self = stack_get(v, idx);
00749 if(type(v->GetUp(-2)) == OT_NULL) return sq_throwerror(v, _SC("null key"));
00750 switch(type(self)) {
00751 case OT_TABLE:
00752 _table(self)->NewSlot(v->GetUp(-2), v->GetUp(-1));
00753 v->Pop(2);
00754 return SQ_OK;
00755 break;
00756 case OT_CLASS:
00757 _class(self)->NewSlot(_ss(v), v->GetUp(-2), v->GetUp(-1),false);
00758 v->Pop(2);
00759 return SQ_OK;
00760 break;
00761 case OT_INSTANCE:
00762 if(_instance(self)->Set(v->GetUp(-2), v->GetUp(-1))) {
00763 v->Pop(2);
00764 return SQ_OK;
00765 }
00766 break;
00767 case OT_ARRAY:
00768 if(v->Set(self, v->GetUp(-2), v->GetUp(-1),false)) {
00769 v->Pop(2);
00770 return SQ_OK;
00771 }
00772 break;
00773 default:
00774 v->Pop(2);
00775 return sq_throwerror(v, _SC("rawset works only on array/table/class and instance"));
00776 }
00777 v->Raise_IdxError(v->GetUp(-2));return SQ_ERROR;
00778 }
00779
00780 SQRESULT sq_setdelegate(HSQUIRRELVM v,SQInteger idx)
00781 {
00782 SQObjectPtr &self = stack_get(v, idx);
00783 SQObjectPtr &mt = v->GetUp(-1);
00784 SQObjectType type = type(self);
00785 switch(type) {
00786 case OT_TABLE:
00787 if(type(mt) == OT_TABLE) {
00788 if(!_table(self)->SetDelegate(_table(mt))) return sq_throwerror(v, _SC("delagate cycle")); v->Pop();}
00789 else if(type(mt)==OT_NULL) {
00790 _table(self)->SetDelegate(NULL); v->Pop(); }
00791 else return sq_aux_invalidtype(v,type);
00792 break;
00793 case OT_USERDATA:
00794 if(type(mt)==OT_TABLE) {
00795 _userdata(self)->SetDelegate(_table(mt)); v->Pop(); }
00796 else if(type(mt)==OT_NULL) {
00797 _userdata(self)->SetDelegate(NULL); v->Pop(); }
00798 else return sq_aux_invalidtype(v, type);
00799 break;
00800 default:
00801 return sq_aux_invalidtype(v, type);
00802 break;
00803 }
00804 return SQ_OK;
00805 }
00806
00807 SQRESULT sq_rawdeleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval)
00808 {
00809 sq_aux_paramscheck(v, 2);
00810 SQObjectPtr *self;
00811 _GETSAFE_OBJ(v, idx, OT_TABLE,self);
00812 SQObjectPtr &key = v->GetUp(-1);
00813 SQObjectPtr t;
00814 if(_table(*self)->Get(key,t)) {
00815 _table(*self)->Remove(key);
00816 }
00817 if(pushval != 0) {
00818 if(pushval) v->GetUp(-1) = t;
00819 } else {
00820 v->Pop(1);
00821 }
00822 return SQ_OK;
00823 }
00824
00825 SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx)
00826 {
00827 SQObjectPtr &self=stack_get(v,idx);
00828 switch(type(self)){
00829 case OT_TABLE:
00830 case OT_USERDATA:
00831 if(!_delegable(self)->_delegate){
00832 v->Push(_null_);
00833 break;
00834 }
00835 v->Push(SQObjectPtr(_delegable(self)->_delegate));
00836 break;
00837 default: return sq_throwerror(v,_SC("wrong type")); break;
00838 }
00839 return SQ_OK;
00840
00841 }
00842
00843 SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx)
00844 {
00845 SQObjectPtr &self=stack_get(v,idx);
00846 if(v->Get(self,v->GetUp(-1),v->GetUp(-1),false,false))
00847 return SQ_OK;
00848 v->Pop(1);
00849 return sq_throwerror(v,_SC("the index doesn't exist"));
00850 }
00851
00852 SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx)
00853 {
00854 SQObjectPtr &self=stack_get(v,idx);
00855 switch(type(self)) {
00856 case OT_TABLE:
00857 if(_table(self)->Get(v->GetUp(-1),v->GetUp(-1)))
00858 return SQ_OK;
00859 break;
00860 case OT_CLASS:
00861 if(_class(self)->Get(v->GetUp(-1),v->GetUp(-1)))
00862 return SQ_OK;
00863 break;
00864 case OT_INSTANCE:
00865 if(_instance(self)->Get(v->GetUp(-1),v->GetUp(-1)))
00866 return SQ_OK;
00867 break;
00868 case OT_ARRAY:
00869 if(v->Get(self,v->GetUp(-1),v->GetUp(-1),false,false))
00870 return SQ_OK;
00871 break;
00872 default:
00873 v->Pop(1);
00874 return sq_throwerror(v,_SC("rawget works only on array/table/instance and class"));
00875 }
00876 v->Pop(1);
00877 return sq_throwerror(v,_SC("the index doesn't exist"));
00878 }
00879
00880 SQRESULT sq_getstackobj(HSQUIRRELVM v,SQInteger idx,HSQOBJECT *po)
00881 {
00882 *po=stack_get(v,idx);
00883 return SQ_OK;
00884 }
00885
00886 const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedInteger idx)
00887 {
00888 SQUnsignedInteger cstksize=v->_callsstacksize;
00889 SQUnsignedInteger lvl=(cstksize-level)-1;
00890 SQInteger stackbase=v->_stackbase;
00891 if(lvl<cstksize){
00892 for(SQUnsignedInteger i=0;i<level;i++){
00893 SQVM::CallInfo &ci=v->_callsstack[(cstksize-i)-1];
00894 stackbase-=ci._prevstkbase;
00895 }
00896 SQVM::CallInfo &ci=v->_callsstack[lvl];
00897 if(type(ci._closure)!=OT_CLOSURE)
00898 return NULL;
00899 SQClosure *c=_closure(ci._closure);
00900 SQFunctionProto *func=_funcproto(c->_function);
00901 if(func->_noutervalues > (SQInteger)idx) {
00902 v->Push(c->_outervalues[idx]);
00903 return _stringval(func->_outervalues[idx]._name);
00904 }
00905 idx -= func->_noutervalues;
00906 return func->GetLocal(v,stackbase,idx,(SQInteger)(ci._ip-func->_instructions)-1);
00907 }
00908 return NULL;
00909 }
00910
00911 void sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj)
00912 {
00913 v->Push(SQObjectPtr(obj));
00914 }
00915
00916 void sq_resetobject(HSQOBJECT *po)
00917 {
00918 po->_unVal.pUserPointer=NULL;po->_type=OT_NULL;
00919 }
00920
00921 SQRESULT sq_throwerror(HSQUIRRELVM v,const SQChar *err)
00922 {
00923 v->_lasterror=SQString::Create(_ss(v),err);
00924 return -1;
00925 }
00926
00927 void sq_reseterror(HSQUIRRELVM v)
00928 {
00929 v->_lasterror = _null_;
00930 }
00931
00932 void sq_getlasterror(HSQUIRRELVM v)
00933 {
00934 v->Push(v->_lasterror);
00935 }
00936
00937 void sq_reservestack(HSQUIRRELVM v,SQInteger nsize)
00938 {
00939 if (((SQUnsignedInteger)v->_top + nsize) > v->_stack.size()) {
00940 v->_stack.resize(v->_stack.size() + ((v->_top + nsize) - v->_stack.size()));
00941 }
00942 }
00943
00944 SQRESULT sq_resume(HSQUIRRELVM v,SQBool retval,SQBool raiseerror)
00945 {
00946 if(type(v->GetUp(-1))==OT_GENERATOR){
00947 v->Push(_null_);
00948 v->_can_suspend = false;
00949 if(!v->Execute(v->GetUp(-2),v->_top,0,v->_top,v->GetUp(-1),raiseerror,SQVM::ET_RESUME_GENERATOR))
00950 {v->Raise_Error(v->_lasterror); return SQ_ERROR;}
00951 if(!retval)
00952 v->Pop();
00953 return SQ_OK;
00954 }
00955 return sq_throwerror(v,_SC("only generators can be resumed"));
00956 }
00957
00958 SQRESULT sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval,SQBool raiseerror, int suspend)
00959 {
00960 SQObjectPtr res;
00961 v->_can_suspend = suspend >= 0;
00962 if (v->_can_suspend) v->_ops_till_suspend = suspend;
00963
00964 if(v->Call(v->GetUp(-(params+1)),params,v->_top-params,res,raiseerror?true:false,v->_can_suspend)){
00965 if(!v->_suspended) {
00966 v->Pop(params);
00967 }
00968 if(retval){
00969 v->Push(res); return SQ_OK;
00970 }
00971 return SQ_OK;
00972 }
00973 else {
00974 v->Pop(params);
00975 return SQ_ERROR;
00976 }
00977 if(!v->_suspended)
00978 v->Pop(params);
00979 return sq_throwerror(v,_SC("call failed"));
00980 }
00981
00982 SQRESULT sq_suspendvm(HSQUIRRELVM v)
00983 {
00984 return v->Suspend();
00985 }
00986
00987 SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool wakeupret,SQBool retval,SQBool raiseerror)
00988 {
00989 SQObjectPtr ret;
00990 if(!v->_suspended)
00991 return sq_throwerror(v,_SC("cannot resume a vm that is not running any code"));
00992 if(wakeupret) {
00993 v->GetAt(v->_stackbase+v->_suspended_target)=v->GetUp(-1);
00994 v->Pop();
00995 } else v->GetAt(v->_stackbase+v->_suspended_target)=_null_;
00996 v->_can_suspend = false;
00997 if(!v->Execute(_null_,v->_top,-1,-1,ret,raiseerror,SQVM::ET_RESUME_VM)) {
00998 return SQ_ERROR;
00999 }
01000 if(retval)
01001 v->Push(ret);
01002 return SQ_OK;
01003 }
01004
01005 bool sq_resumecatch(HSQUIRRELVM v, int suspend)
01006 {
01007 SQObjectPtr ret;
01008 v->_can_suspend = suspend >= 0;
01009 if (v->_can_suspend) v->_ops_till_suspend = suspend;
01010 return v->Execute(_null_, v->_top, -1, -1, ret, SQTrue, SQVM::ET_RESUME_OPENTTD);
01011 }
01012
01013 void sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook)
01014 {
01015 if(sq_gettop(v) >= 1){
01016 SQObjectPtr &ud=stack_get(v,idx);
01017 switch( type(ud) ) {
01018 case OT_USERDATA: _userdata(ud)->_hook = hook; break;
01019 case OT_INSTANCE: _instance(ud)->_hook = hook; break;
01020 case OT_CLASS: _class(ud)->_hook = hook; break;
01021 default: break;
01022 }
01023 }
01024 }
01025
01026 void sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f)
01027 {
01028 _ss(v)->_compilererrorhandler = f;
01029 }
01030
01031 SQRESULT sq_writeclosure(HSQUIRRELVM v,SQWRITEFUNC w,SQUserPointer up)
01032 {
01033 SQObjectPtr *o = NULL;
01034 _GETSAFE_OBJ(v, -1, OT_CLOSURE,o);
01035 unsigned short tag = SQ_BYTECODE_STREAM_TAG;
01036 if(w(up,&tag,2) != 2)
01037 return sq_throwerror(v,_SC("io error"));
01038 if(!_closure(*o)->Save(v,up,w))
01039 return SQ_ERROR;
01040 return SQ_OK;
01041 }
01042
01043 SQRESULT sq_readclosure(HSQUIRRELVM v,SQREADFUNC r,SQUserPointer up)
01044 {
01045 SQObjectPtr closure;
01046
01047 unsigned short tag;
01048 if(r(up,&tag,2) != 2)
01049 return sq_throwerror(v,_SC("io error"));
01050 if(tag != SQ_BYTECODE_STREAM_TAG)
01051 return sq_throwerror(v,_SC("invalid stream"));
01052 if(!SQClosure::Load(v,up,r,closure))
01053 return SQ_ERROR;
01054 v->Push(closure);
01055 return SQ_OK;
01056 }
01057
01058 SQChar *sq_getscratchpad(HSQUIRRELVM v,SQInteger minsize)
01059 {
01060 return _ss(v)->GetScratchPad(minsize);
01061 }
01062
01063 SQInteger sq_collectgarbage(HSQUIRRELVM v)
01064 {
01065 #ifndef NO_GARBAGE_COLLECTOR
01066 return _ss(v)->CollectGarbage(v);
01067 #else
01068 return -1;
01069 #endif
01070 }
01071
01072 const SQChar *sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval)
01073 {
01074 SQObjectPtr &self = stack_get(v,idx);
01075 const SQChar *name = NULL;
01076 if(type(self) == OT_CLOSURE) {
01077 if(_closure(self)->_outervalues.size()>nval) {
01078 v->Push(_closure(self)->_outervalues[nval]);
01079 SQFunctionProto *fp = _funcproto(_closure(self)->_function);
01080 SQOuterVar &ov = fp->_outervalues[nval];
01081 name = _stringval(ov._name);
01082 }
01083 }
01084 return name;
01085 }
01086
01087 SQRESULT sq_setfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval)
01088 {
01089 SQObjectPtr &self=stack_get(v,idx);
01090 switch(type(self))
01091 {
01092 case OT_CLOSURE:
01093 if(_closure(self)->_outervalues.size()>nval){
01094 _closure(self)->_outervalues[nval]=stack_get(v,-1);
01095 }
01096 else return sq_throwerror(v,_SC("invalid free var index"));
01097 break;
01098 case OT_NATIVECLOSURE:
01099 if(_nativeclosure(self)->_outervalues.size()>nval){
01100 _nativeclosure(self)->_outervalues[nval]=stack_get(v,-1);
01101 }
01102 else return sq_throwerror(v,_SC("invalid free var index"));
01103 break;
01104 default:
01105 return sq_aux_invalidtype(v,type(self));
01106 }
01107 v->Pop(1);
01108 return SQ_OK;
01109 }
01110
01111 SQRESULT sq_setattributes(HSQUIRRELVM v,SQInteger idx)
01112 {
01113 SQObjectPtr *o = NULL;
01114 _GETSAFE_OBJ(v, idx, OT_CLASS,o);
01115 SQObjectPtr &key = stack_get(v,-2);
01116 SQObjectPtr &val = stack_get(v,-1);
01117 SQObjectPtr attrs;
01118 if(type(key) == OT_NULL) {
01119 attrs = _class(*o)->_attributes;
01120 _class(*o)->_attributes = val;
01121 v->Pop(2);
01122 v->Push(attrs);
01123 return SQ_OK;
01124 }else if(_class(*o)->GetAttributes(key,attrs)) {
01125 _class(*o)->SetAttributes(key,val);
01126 v->Pop(2);
01127 v->Push(attrs);
01128 return SQ_OK;
01129 }
01130 return sq_throwerror(v,_SC("wrong index"));
01131 }
01132
01133 SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx)
01134 {
01135 SQObjectPtr *o = NULL;
01136 _GETSAFE_OBJ(v, idx, OT_CLASS,o);
01137 SQObjectPtr &key = stack_get(v,-1);
01138 SQObjectPtr attrs;
01139 if(type(key) == OT_NULL) {
01140 attrs = _class(*o)->_attributes;
01141 v->Pop();
01142 v->Push(attrs);
01143 return SQ_OK;
01144 }
01145 else if(_class(*o)->GetAttributes(key,attrs)) {
01146 v->Pop();
01147 v->Push(attrs);
01148 return SQ_OK;
01149 }
01150 return sq_throwerror(v,_SC("wrong index"));
01151 }
01152
01153 SQRESULT sq_getbase(HSQUIRRELVM v,SQInteger idx)
01154 {
01155 SQObjectPtr *o = NULL;
01156 _GETSAFE_OBJ(v, idx, OT_CLASS,o);
01157 if(_class(*o)->_base)
01158 v->Push(SQObjectPtr(_class(*o)->_base));
01159 else
01160 v->Push(_null_);
01161 return SQ_OK;
01162 }
01163
01164 SQRESULT sq_getclass(HSQUIRRELVM v,SQInteger idx)
01165 {
01166 SQObjectPtr *o = NULL;
01167 _GETSAFE_OBJ(v, idx, OT_INSTANCE,o);
01168 v->Push(SQObjectPtr(_instance(*o)->_class));
01169 return SQ_OK;
01170 }
01171
01172 SQRESULT sq_createinstance(HSQUIRRELVM v,SQInteger idx)
01173 {
01174 SQObjectPtr *o = NULL;
01175 _GETSAFE_OBJ(v, idx, OT_CLASS,o);
01176 v->Push(_class(*o)->CreateInstance());
01177 return SQ_OK;
01178 }
01179
01180 void sq_weakref(HSQUIRRELVM v,SQInteger idx)
01181 {
01182 SQObject &o=stack_get(v,idx);
01183 if(ISREFCOUNTED(type(o))) {
01184 v->Push(_refcounted(o)->GetWeakRef(type(o)));
01185 return;
01186 }
01187 v->Push(o);
01188 }
01189
01190 SQRESULT sq_getweakrefval(HSQUIRRELVM v,SQInteger idx)
01191 {
01192 SQObjectPtr &o = stack_get(v,idx);
01193 if(type(o) != OT_WEAKREF) {
01194 return sq_throwerror(v,_SC("the object must be a weakref"));
01195 }
01196 v->Push(_weakref(o)->_obj);
01197 return SQ_OK;
01198 }
01199
01200 SQRESULT sq_getdefaultdelegate(HSQUIRRELVM v,SQObjectType t)
01201 {
01202 SQSharedState *ss = _ss(v);
01203 switch(t) {
01204 case OT_TABLE: v->Push(ss->_table_default_delegate); break;
01205 case OT_ARRAY: v->Push(ss->_array_default_delegate); break;
01206 case OT_STRING: v->Push(ss->_string_default_delegate); break;
01207 case OT_INTEGER: case OT_FLOAT: v->Push(ss->_number_default_delegate); break;
01208 case OT_GENERATOR: v->Push(ss->_generator_default_delegate); break;
01209 case OT_CLOSURE: case OT_NATIVECLOSURE: v->Push(ss->_closure_default_delegate); break;
01210 case OT_THREAD: v->Push(ss->_thread_default_delegate); break;
01211 case OT_CLASS: v->Push(ss->_class_default_delegate); break;
01212 case OT_INSTANCE: v->Push(ss->_instance_default_delegate); break;
01213 case OT_WEAKREF: v->Push(ss->_weakref_default_delegate); break;
01214 default: return sq_throwerror(v,_SC("the type doesn't have a default delegate"));
01215 }
01216 return SQ_OK;
01217 }
01218
01219 SQRESULT sq_next(HSQUIRRELVM v,SQInteger idx)
01220 {
01221 SQObjectPtr o=stack_get(v,idx),&refpos = stack_get(v,-1),realkey,val;
01222 if(type(o) == OT_GENERATOR) {
01223 return sq_throwerror(v,_SC("cannot iterate a generator"));
01224 }
01225 int faketojump;
01226 if(!v->FOREACH_OP(o,realkey,val,refpos,0,666,faketojump))
01227 return SQ_ERROR;
01228 if(faketojump != 666) {
01229 v->Push(realkey);
01230 v->Push(val);
01231 return SQ_OK;
01232 }
01233 return SQ_ERROR;
01234 }
01235
01236 struct BufState{
01237 const SQChar *buf;
01238 SQInteger ptr;
01239 SQInteger size;
01240 };
01241
01242 SQInteger buf_lexfeed(SQUserPointer file)
01243 {
01244 BufState *buf=(BufState*)file;
01245 if(buf->size<(buf->ptr+1))
01246 return 0;
01247 return buf->buf[buf->ptr++];
01248 }
01249
01250 SQRESULT sq_compilebuffer(HSQUIRRELVM v,const SQChar *s,SQInteger size,const SQChar *sourcename,SQBool raiseerror) {
01251 BufState buf;
01252 buf.buf = s;
01253 buf.size = size;
01254 buf.ptr = 0;
01255 return sq_compile(v, buf_lexfeed, &buf, sourcename, raiseerror);
01256 }
01257
01258 void sq_move(HSQUIRRELVM dest,HSQUIRRELVM src,SQInteger idx)
01259 {
01260 dest->Push(stack_get(src,idx));
01261 }
01262
01263 void sq_setprintfunc(HSQUIRRELVM v, SQPRINTFUNCTION printfunc)
01264 {
01265 _ss(v)->_printfunc = printfunc;
01266 }
01267
01268 SQPRINTFUNCTION sq_getprintfunc(HSQUIRRELVM v)
01269 {
01270 return _ss(v)->_printfunc;
01271 }
01272
01273 void *sq_malloc(SQUnsignedInteger size)
01274 {
01275 return SQ_MALLOC(size);
01276 }
01277
01278 void *sq_realloc(void* p,SQUnsignedInteger oldsize,SQUnsignedInteger newsize)
01279 {
01280 return SQ_REALLOC(p,oldsize,newsize);
01281 }
01282
01283 void sq_free(void *p,SQUnsignedInteger size)
01284 {
01285 SQ_FREE(p,size);
01286 }
01287