0001
0002
0003
0004 #include "pspcheader.h"
0005 #include <stdarg.h>
0006 #include "psvm.h"
0007 #include "psfuncproto.h"
0008 #include "psclosure.h"
0009 #include "psstring.h"
0010
0011 PSRESULT ps_getfunctioninfo(HPSCRIPTVM v,PSInteger level,PSFunctionInfo *fi)
0012 {
0013 PSInteger cssize = v->_callsstacksize;
0014 if (cssize > level) {
0015 PSVM::CallInfo &ci = v->_callsstack[cssize-level-1];
0016 if(ps_isclosure(ci._closure)) {
0017 PSClosure *c = _closure(ci._closure);
0018 PSFunctionProto *proto = c->_function;
0019 fi->funcid = proto;
0020 fi->name = type(proto->_name) == OT_STRING?_stringval(proto->_name):_SC("unknown");
0021 fi->source = type(proto->_sourcename) == OT_STRING?_stringval(proto->_sourcename):_SC("unknown");
0022 fi->line = proto->_lineinfos[0]._line;
0023 return PS_OK;
0024 }
0025 }
0026 return ps_throwerror(v,_SC("the object is not a closure"));
0027 }
0028
0029 PSRESULT ps_stackinfos(HPSCRIPTVM v, PSInteger level, PSStackInfos *si)
0030 {
0031 PSInteger cssize = v->_callsstacksize;
0032 if (cssize > level) {
0033 memset(si, 0, sizeof(PSStackInfos));
0034 PSVM::CallInfo &ci = v->_callsstack[cssize-level-1];
0035 switch (type(ci._closure)) {
0036 case OT_CLOSURE:{
0037 PSFunctionProto *func = _closure(ci._closure)->_function;
0038 if (type(func->_name) == OT_STRING)
0039 si->funcname = _stringval(func->_name);
0040 if (type(func->_sourcename) == OT_STRING)
0041 si->source = _stringval(func->_sourcename);
0042 si->line = func->GetLine(ci._ip);
0043 }
0044 break;
0045 case OT_NATIVECLOSURE:
0046 si->source = _SC("NATIVE");
0047 si->funcname = _SC("unknown");
0048 if(type(_nativeclosure(ci._closure)->_name) == OT_STRING)
0049 si->funcname = _stringval(_nativeclosure(ci._closure)->_name);
0050 si->line = -1;
0051 break;
0052 default: break;
0053 }
0054 return PS_OK;
0055 }
0056 return PS_ERROR;
0057 }
0058
0059 void PSVM::Raise_Error(const PSChar *s, ...)
0060 {
0061 va_list vl;
0062 va_start(vl, s);
0063 PSInteger buffersize = (PSInteger)scstrlen(s)+(NUMBER_MAX_CHAR*2);
0064 scvsprintf(_sp(ps_rsl(buffersize)),buffersize, s, vl);
0065 va_end(vl);
0066 _lasterror = PSString::Create(_ss(this),_spval,-1);
0067 }
0068
0069 void PSVM::Raise_Error(const PSObjectPtr &desc)
0070 {
0071 _lasterror = desc;
0072 }
0073
0074 PSString *PSVM::PrintObjVal(const PSObjectPtr &o)
0075 {
0076 switch(type(o)) {
0077 case OT_STRING: return _string(o);
0078 case OT_INTEGER:
0079 scsprintf(_sp(ps_rsl(NUMBER_MAX_CHAR+1)),ps_rsl(NUMBER_MAX_CHAR), _PRINT_INT_FMT, _integer(o));
0080 return PSString::Create(_ss(this), _spval);
0081 break;
0082 case OT_FLOAT:
0083 scsprintf(_sp(ps_rsl(NUMBER_MAX_CHAR+1)), ps_rsl(NUMBER_MAX_CHAR), _SC("%.14g"), _float(o));
0084 return PSString::Create(_ss(this), _spval);
0085 break;
0086 default:
0087 return PSString::Create(_ss(this), GetTypeName(o));
0088 }
0089 }
0090
0091 void PSVM::Raise_IdxError(const PSObjectPtr &o)
0092 {
0093 PSObjectPtr oval = PrintObjVal(o);
0094 Raise_Error(_SC("the index '%.50s' does not exist"), _stringval(oval));
0095 }
0096
0097 void PSVM::Raise_CompareError(const PSObject &o1, const PSObject &o2)
0098 {
0099 PSObjectPtr oval1 = PrintObjVal(o1), oval2 = PrintObjVal(o2);
0100 Raise_Error(_SC("comparison between '%.50s' and '%.50s'"), _stringval(oval1), _stringval(oval2));
0101 }
0102
0103
0104 void PSVM::Raise_ParamTypeError(PSInteger nparam,PSInteger typemask,PSInteger type)
0105 {
0106 PSObjectPtr exptypes = PSString::Create(_ss(this), _SC(""), -1);
0107 PSInteger found = 0;
0108 for(PSInteger i=0; i<16; i++)
0109 {
0110 PSInteger mask = 0x00000001 << i;
0111 if(typemask & (mask)) {
0112 if(found>0) StringCat(exptypes,PSString::Create(_ss(this), _SC("|"), -1), exptypes);
0113 found ++;
0114 StringCat(exptypes,PSString::Create(_ss(this), IdType2Name((PSObjectType)mask), -1), exptypes);
0115 }
0116 }
0117 Raise_Error(_SC("parameter %d has an invalid type '%s' ; expected: '%s'"), nparam, IdType2Name((PSObjectType)type), _stringval(exptypes));
0118 }