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