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_stackinfos(HSQUIRRELVM v,SQInteger level,SQStackInfos * si)11 SQRESULT sq_stackinfos( HSQUIRRELVM v, SQInteger level, SQStackInfos *si ) {
12 	SQInteger cssize = v->_callsstack.size();
13 	if ( cssize > level ) {
14 		memset( si, 0, sizeof( SQStackInfos ) );
15 		SQVM::CallInfo &ci = v->_callsstack[cssize-level-1];
16 		switch ( squirrel_type( ci._closure ) ) {
17 		case OT_CLOSURE: {
18 				SQFunctionProto *func = _funcproto( _closure( ci._closure )->_function );
19 				if ( squirrel_type( func->_name ) == OT_STRING )
20 					si->funcname = _stringval( func->_name );
21 				if ( squirrel_type( func->_sourcename ) == OT_STRING )
22 					si->source = _stringval( func->_sourcename );
23 				si->line = func->GetLine( ci._ip );
24 			}
25 			break;
26 		case OT_NATIVECLOSURE:
27 			si->source = _SC( "NATIVE" );
28 			si->funcname = _SC( "unknown" );
29 			if ( squirrel_type( _nativeclosure( ci._closure )->_name ) == OT_STRING )
30 				si->funcname = _stringval( _nativeclosure( ci._closure )->_name );
31 			si->line = -1;
32 			break;
33 		}
34 		return SQ_OK;
35 	}
36 	return SQ_ERROR;
37 }
38 
Raise_Error(const SQChar * s,...)39 void SQVM::Raise_Error( const SQChar *s, ... ) {
40 	va_list vl;
41 	va_start( vl, s );
42 	scvsprintf( _sp( rsl( scstrlen( s ) + ( NUMBER_MAX_CHAR*2 ) ) ), s, vl );
43 	va_end( vl );
44 	_lasterror = SQString::Create( _ss( this ), _spval, -1 );
45 }
46 
Raise_Error(SQObjectPtr & desc)47 void SQVM::Raise_Error( SQObjectPtr &desc ) {
48 	_lasterror = desc;
49 }
50 
PrintObjVal(const SQObject & o)51 SQString *SQVM::PrintObjVal( const SQObject &o ) {
52 	switch ( squirrel_type( o ) ) {
53 	case OT_STRING: return _string( o );
54 	case OT_INTEGER:
55 		scsprintf( _sp( rsl( NUMBER_MAX_CHAR + 1 ) ), _SC( "%d" ), _integer( o ) );
56 		return SQString::Create( _ss( this ), _spval );
57 		break;
58 	case OT_FLOAT:
59 		scsprintf( _sp( rsl( NUMBER_MAX_CHAR + 1 ) ), _SC( "%.14g" ), _float( o ) );
60 		return SQString::Create( _ss( this ), _spval );
61 		break;
62 	default:
63 		return SQString::Create( _ss( this ), GetTypeName( o ) );
64 	}
65 }
66 
Raise_IdxError(SQObject & o)67 void SQVM::Raise_IdxError( SQObject &o ) {
68 	SQObjectPtr oval = PrintObjVal( o );
69 	Raise_Error( _SC( "the index '%.50s' does not exist" ), _stringval( oval ) );
70 }
71 
Raise_CompareError(const SQObject & o1,const SQObject & o2)72 void SQVM::Raise_CompareError( const SQObject &o1, const SQObject &o2 ) {
73 	SQObjectPtr oval1 = PrintObjVal( o1 ), oval2 = PrintObjVal( o2 );
74 	Raise_Error( _SC( "comparsion between '%.50s' and '%.50s'" ), _stringval( oval1 ), _stringval( oval2 ) );
75 }
76 
77 
Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type)78 void SQVM::Raise_ParamTypeError( SQInteger nparam, SQInteger typemask, SQInteger type ) {
79 	SQObjectPtr exptypes = SQString::Create( _ss( this ), _SC( "" ), -1 );
80 	SQInteger found = 0;
81 	for ( SQInteger i = 0; i < 16; i++ ) {
82 		SQInteger mask = 0x00000001 << i;
83 		if ( typemask & ( mask ) ) {
84 			if ( found > 0 ) StringCat( exptypes, SQString::Create( _ss( this ), _SC( "|" ), -1 ), exptypes );
85 			found ++;
86 			StringCat( exptypes, SQString::Create( _ss( this ), IdType2Name( ( SQObjectType )mask ), -1 ), exptypes );
87 		}
88 	}
89 	Raise_Error( _SC( "parameter %d has an invalid type '%s' ; expected: '%s'" ), nparam, IdType2Name( ( SQObjectType )type ), _stringval( exptypes ) );
90 }
91