sqapi.cpp

00001 /*
00002   see copyright notice in squirrel.h
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; //the ret val doesn't work(and cannot be fixed)
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 { //then must be a native closure
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_); //retval
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);//pop closure and args
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); //retval
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; //shutup compiler
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 

Generated on Sun Mar 15 22:49:43 2009 for openttd by  doxygen 1.5.6