1 /*
2 see copyright notice in squirrel.h
3 */
4 #include "sqpcheader.h"
5 #include <stdarg.h>
6 #include "sqvm.h"
7 #include "sqfuncproto.h"
8 #include "sqclosure.h"
9 #include "sqstring.h"
10
sq_getfunctioninfo(HSQUIRRELVM v,SQInteger level,SQFunctionInfo * fi)11 SQRESULT sq_getfunctioninfo(HSQUIRRELVM v,SQInteger level,SQFunctionInfo *fi)
12 {
13 SQInteger cssize = v->_callsstacksize;
14 if (cssize > level) {
15 SQVM::CallInfo &ci = v->_callsstack[cssize-level-1];
16 if(sq_isclosure(ci._closure)) {
17 SQClosure *c = _closure(ci._closure);
18 SQFunctionProto *proto = c->_function;
19 fi->funcid = proto;
20 fi->name = sqtype(proto->_name) == OT_STRING?_stringval(proto->_name):_SC("unknown");
21 fi->source = sqtype(proto->_sourcename) == OT_STRING?_stringval(proto->_sourcename):_SC("unknown");
22 fi->line = proto->_lineinfos[0]._line;
23 return SQ_OK;
24 }
25 }
26 return sq_throwerror(v,_SC("the object is not a closure"));
27 }
28
sq_stackinfos(HSQUIRRELVM v,SQInteger level,SQStackInfos * si)29 SQRESULT sq_stackinfos(HSQUIRRELVM v, SQInteger level, SQStackInfos *si)
30 {
31 SQInteger cssize = v->_callsstacksize;
32 if (cssize > level) {
33 memset(si, 0, sizeof(SQStackInfos));
34 SQVM::CallInfo &ci = v->_callsstack[cssize-level-1];
35 switch (sqtype(ci._closure)) {
36 case OT_CLOSURE:{
37 SQFunctionProto *func = _closure(ci._closure)->_function;
38 if (sqtype(func->_name) == OT_STRING)
39 si->funcname = _stringval(func->_name);
40 if (sqtype(func->_sourcename) == OT_STRING)
41 si->source = _stringval(func->_sourcename);
42 si->line = func->GetLine(ci._ip);
43 }
44 break;
45 case OT_NATIVECLOSURE:
46 si->source = _SC("NATIVE");
47 si->funcname = _SC("unknown");
48 if(sqtype(_nativeclosure(ci._closure)->_name) == OT_STRING)
49 si->funcname = _stringval(_nativeclosure(ci._closure)->_name);
50 si->line = -1;
51 break;
52 default: break; //shutup compiler
53 }
54 return SQ_OK;
55 }
56 return SQ_ERROR;
57 }
58
Raise_Error(const SQChar * s,...)59 void SQVM::Raise_Error(const SQChar *s, ...)
60 {
61 va_list vl;
62 va_start(vl, s);
63 SQInteger buffersize = (SQInteger)scstrlen(s)+(NUMBER_MAX_CHAR*2);
64 scvsprintf(_sp(sq_rsl(buffersize)),buffersize, s, vl);
65 va_end(vl);
66 _lasterror = SQString::Create(_ss(this),_spval,-1);
67 }
68
Raise_Error(const SQObjectPtr & desc)69 void SQVM::Raise_Error(const SQObjectPtr &desc)
70 {
71 _lasterror = desc;
72 }
73
PrintObjVal(const SQObjectPtr & o)74 SQString *SQVM::PrintObjVal(const SQObjectPtr &o)
75 {
76 switch(sqtype(o)) {
77 case OT_STRING: return _string(o);
78 case OT_INTEGER:
79 scsprintf(_sp(sq_rsl(NUMBER_MAX_CHAR+1)),sq_rsl(NUMBER_MAX_CHAR), _PRINT_INT_FMT, _integer(o));
80 return SQString::Create(_ss(this), _spval);
81 break;
82 case OT_FLOAT:
83 scsprintf(_sp(sq_rsl(NUMBER_MAX_CHAR+1)), sq_rsl(NUMBER_MAX_CHAR), _SC("%.14g"), _float(o));
84 return SQString::Create(_ss(this), _spval);
85 break;
86 default:
87 return SQString::Create(_ss(this), GetTypeName(o));
88 }
89 }
90
Raise_IdxError(const SQObjectPtr & o)91 void SQVM::Raise_IdxError(const SQObjectPtr &o)
92 {
93 SQObjectPtr oval = PrintObjVal(o);
94 Raise_Error(_SC("the index '%.50s' does not exist"), _stringval(oval));
95 }
96
Raise_CompareError(const SQObject & o1,const SQObject & o2)97 void SQVM::Raise_CompareError(const SQObject &o1, const SQObject &o2)
98 {
99 SQObjectPtr oval1 = PrintObjVal(o1), oval2 = PrintObjVal(o2);
100 Raise_Error(_SC("comparison between '%.50s' and '%.50s'"), _stringval(oval1), _stringval(oval2));
101 }
102
103
Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type)104 void SQVM::Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type)
105 {
106 SQObjectPtr exptypes = SQString::Create(_ss(this), _SC(""), -1);
107 SQInteger found = 0;
108 for(SQInteger i=0; i<16; i++)
109 {
110 SQInteger mask = 0x00000001 << i;
111 if(typemask & (mask)) {
112 if(found>0) StringCat(exptypes,SQString::Create(_ss(this), _SC("|"), -1), exptypes);
113 found ++;
114 StringCat(exptypes,SQString::Create(_ss(this), IdType2Name((SQObjectType)mask), -1), exptypes);
115 }
116 }
117 Raise_Error(_SC("parameter %d has an invalid type '%s' ; expected: '%s'"), nparam, IdType2Name((SQObjectType)type), _stringval(exptypes));
118 }
119