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