summaryrefslogtreecommitdiffstats
path: root/squirrel_3_0_1_stable/_OLD_sqplus/SquirrelVM.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--squirrel_3_0_1_stable/_OLD_sqplus/SquirrelVM.cpp (renamed from squirrel_3_0_1_stable/sqplus/SquirrelVM.cpp)1010
1 files changed, 505 insertions, 505 deletions
diff --git a/squirrel_3_0_1_stable/sqplus/SquirrelVM.cpp b/squirrel_3_0_1_stable/_OLD_sqplus/SquirrelVM.cpp
index 2d506d700..12b84dbe5 100644
--- a/squirrel_3_0_1_stable/sqplus/SquirrelVM.cpp
+++ b/squirrel_3_0_1_stable/_OLD_sqplus/SquirrelVM.cpp
@@ -1,505 +1,505 @@
-#include <stdio.h>
-#include <stdarg.h>
-#include <assert.h>
-
-#define _DEBUG_DUMP
-
-#include "sqplus.h"
-
-#include <sqstdio.h>
-#include <sqstdmath.h>
-#include <sqstdstring.h>
-#include <sqstdaux.h>
-#include <sqstdblob.h>
-#include <sqstdsystem.h>
-
-
-HSQUIRRELVM SquirrelVM::_VM;
-bool SquirrelVM::_no_vm_ref;
-int SquirrelVM::_CallState = -1;
-SquirrelObject* SquirrelVM::_root;
-HSQUIRRELVM SquirrelVM::_sandboxVM;
-SquirrelObject SquirrelVM::_vm;
-
-
-// Helper struct to keep track of all SQSharedState:s created by SquirrelVM.
-#include "../squirrel/sqpcheader.h"
-#include "../squirrel/sqvm.h"
-struct SQSharedStateNode {
- SQSharedStateNode( SQSharedState* ps );
- ~SQSharedStateNode( );
- SQSharedState* m_ps;
- SQSharedStateNode* m_nxt;
-};
-
-// Linked list of shared states
-static SQSharedStateNode* g_sqss_fst;
-
-SQSharedStateNode::SQSharedStateNode( SQSharedState* ps ) : m_ps(ps), m_nxt(g_sqss_fst) {
- g_sqss_fst = this;
-}
-
-SQSharedStateNode::~SQSharedStateNode() {
- if(m_ps) sq_delete(m_ps,SQSharedState);
- delete m_nxt;
-}
-
-static struct SquirrelVM_ModConstr {
- ~SquirrelVM_ModConstr(){
- // Delete any shared states we created
- delete g_sqss_fst;
- g_sqss_fst = NULL;
- }
-} g_squirrelvm_mod_constr;
-
-
-
-SquirrelError::SquirrelError()
-{
- const SQChar *s;
- sq_getlasterror(SquirrelVM::_VM);
- sq_getstring(SquirrelVM::_VM,-1,&s);
- if(s) {
- desc = s;
- }
- else {
- desc = _SC("unknown error");
- }
-}
-
-
-SquirrelVMSys::~SquirrelVMSys() {
- // Must take care to release object with the 'ref' VM
- PushRefVM( _vm.GetObjectHandle()._unVal.pThread );
- _vm.Reset();
- PopRefVM();
-}
-
-void SquirrelVMSys::Set( HSQUIRRELVM v ){
- // Must take care to release object with the 'ref' VM
- PushRefVM( v );
- _vm = v;
- PopRefVM( );
-}
-
-void SquirrelVMSys::Set( const SquirrelObject& ov ){
- assert( ov.GetObjectHandle()._type==OT_THREAD );
- // Must take care to release object with the 'ref' VM
- PushRefVM( ov.GetObjectHandle()._unVal.pThread );
- _vm = ov;
- PopRefVM( );
-}
-
-SquirrelVMSys::operator HSQUIRRELVM () const {
- // Avoid const madness
- SquirrelObject *pvm = (SquirrelObject*)&_vm;
- assert( pvm->GetObjectHandle()._type==OT_THREAD );
- return pvm->GetObjectHandle()._unVal.pThread;
-}
-
-
-// When doing a SquirrelObject assignment, a reference using the current
-// VM is done.
-HSQUIRRELVM g_VM_pushed;
-void SquirrelVMSys::PushRefVM( HSQUIRRELVM v ){
- assert( !g_VM_pushed );
- g_VM_pushed = SquirrelVM::_VM;
- SquirrelVM::_VM = v;
-}
-
-void SquirrelVMSys::PopRefVM( ){
- SquirrelVM::_VM = g_VM_pushed;
- g_VM_pushed = NULL;
-}
-
-
-bool SquirrelVM::Init( HSQUIRRELVM v ){
- if( v && v==_VM )
- return true;
-
- // Do we have a previous state?
- Release( );
-
- bool created_new = false;
- if( !v ){
- // Create a new VM - a root VM with new SharedState.
- v = sq_open(1024);
- if( !v ) return false;
- // Store the associated shared state in a linked list. The state will only
- // be destroyed at app shutdown. Often that is fine, but if using many
- // VM:s briefly, this allocation is not optimal.
- new SQSharedStateNode( _ss(v) );
- created_new = true;
- sq_setprintfunc(v,SquirrelVM::PrintFunc, SquirrelVM::PrintFunc);
- sq_pushroottable(v);
- sqstd_register_iolib(v);
- sqstd_register_bloblib(v);
- sqstd_register_mathlib(v);
- sqstd_register_stringlib(v);
-#ifdef SQPLUS_SQUIRRELVM_WITH_SYSTEMLIB
- sqstd_register_systemlib(v);
-#endif
- sqstd_seterrorhandlers(v);
- //TODO error handler, compiler error handler
- sq_pop(v,1);
- }
-
- // After this we hold a ref
- _no_vm_ref = false;
- _VM = v;
- _vm = v;
-
- // In the case where Squirrel is ref counted we currently
- // hold two references to the VM (since it is created with
- // a ref count of 1). In the GC case, it is outside of the
- // chain of valid objects, so it is not referenced. Compensate
- // in ref counted case.
- if( created_new )
- DropVMRefIfRefCounted( v );
-
- return true;
-}
-
-bool SquirrelVM::InitNoRef( HSQUIRRELVM v ){
- if( v && v==_VM )
- return true;
-
- // Do we have a previous state?
- Release( );
-
- // Set pointer to this VM, without referencing it
- _no_vm_ref = true;
- _VM = v;
-
- return true;
-}
-
-/*
-void SquirrelVM::Init( HSQUIRRELVM v )
-{
- if( v && v==_VM ) {
- return;
- }
-
- // Do we have a previous state?
- Release();
-
- if( !v ){
- // Create a new VM and own it
- _VM = sq_open(1024);
- sq_setprintfunc(_VM,SquirrelVM::PrintFunc);
- sq_pushroottable(_VM);
- sqstd_register_iolib(_VM);
- sqstd_register_bloblib(_VM);
- sqstd_register_mathlib(_VM);
- sqstd_register_stringlib(_VM);
- sqstd_seterrorhandlers(_VM);
- //TODO error handler, compiler error handler
- sq_pop(_VM,1);
- }
- else {
- _VM = v;
- }
- // After this we hold a ref
- _vm = _VM;
-}
-*/
-
-void SquirrelVM::Release() {
- // Release root table object if we have one
- if( _root ){
- delete _root;
- _root = NULL;
- }
-
- // Release our ref on VM - if we should
- if( !_no_vm_ref )
- _vm.Reset();
-
- _VM = NULL;
-}
-
-void SquirrelVM::DropVMRefIfRefCounted( HSQUIRRELVM v ){
-#ifdef NO_GARBAGE_COLLECTOR
- if( v ){
- SQObject t;
- t._unVal.pThread = v;
- t._type = OT_THREAD;
- sq_release( v, &t );
- }
-#endif
-}
-
-BOOL SquirrelVM::Update()
-{
- //update remote debugger
- return TRUE;
-}
-
-void SquirrelVM::PrintFunc(HSQUIRRELVM v,const SQChar* s,...)
-{
- static SQChar temp[2048];
- va_list vl;
- va_start(vl, s);
- scvsprintf( temp,s, vl);
- SCPUTS(temp);
- va_end(vl);
-}
-
-SquirrelObject SquirrelVM::CompileScript(const SQChar *s)
-{
- SquirrelObject ret;
- if(SQ_SUCCEEDED(sqstd_loadfile(_VM,s,1))) {
- ret.AttachToStackObject(-1);
- sq_pop(_VM,1);
- return ret;
- }
- throw SquirrelError();
-}
-
-SquirrelObject SquirrelVM::CompileBuffer(const SQChar *s,const SQChar * debugInfo)
-{
- SquirrelObject ret;
- if(SQ_SUCCEEDED(sq_compilebuffer(_VM,s,(int)scstrlen(s)*sizeof(SQChar),debugInfo,1))) {
- ret.AttachToStackObject(-1);
- sq_pop(_VM,1);
- return ret;
- }
- throw SquirrelError();
-}
-
-SquirrelObject SquirrelVM::RunScript(const SquirrelObject &o,SquirrelObject *_this)
-{
- SquirrelObject ret;
- sq_pushobject(_VM,o._o);
- if(_this) {
- sq_pushobject(_VM,_this->_o);
- }
- else {
- sq_pushroottable(_VM);
- }
- if(SQ_SUCCEEDED(sq_call(_VM,1,SQTrue,SQ_CALL_RAISE_ERROR))) {
- ret.AttachToStackObject(-1);
- sq_pop(_VM,2);
- return ret;
- }
- sq_pop(_VM,1);
- throw SquirrelError();
-
-}
-
-
-BOOL SquirrelVM::BeginCall(const SquirrelObject &func)
-{
- if(_CallState != -1)
- return FALSE;
- _CallState = 1;
- sq_pushobject(_VM,func._o);
- sq_pushroottable(_VM);
- return TRUE;
-}
-
-BOOL SquirrelVM::BeginCall(const SquirrelObject &func,SquirrelObject &_this)
-{
- if(_CallState != -1)
- throw SquirrelError(_SC("call already initialized"));
- _CallState = 1;
- sq_pushobject(_VM,func._o);
- sq_pushobject(_VM,_this._o);
- return TRUE;
-}
-
-#define _CHECK_CALL_STATE \
- if(_CallState == -1) \
- throw SquirrelError(_SC("call not initialized"));
-
-void SquirrelVM::PushParam(const SquirrelObject &o)
-{
- _CHECK_CALL_STATE
- sq_pushobject(_VM,o._o);
- _CallState++;
-}
-
-void SquirrelVM::PushParam(const SQChar *s)
-{
- _CHECK_CALL_STATE
- sq_pushstring(_VM,s,-1);
- _CallState++;
-}
-
-void SquirrelVM::PushParam(SQInteger n)
-{
- _CHECK_CALL_STATE
- sq_pushinteger(_VM,n);
- _CallState++;
-}
-
-void SquirrelVM::PushParam(SQFloat f)
-{
- _CHECK_CALL_STATE
- sq_pushfloat(_VM,f);
- _CallState++;
-}
-
-void SquirrelVM::PushParamNull()
-{
- _CHECK_CALL_STATE
- sq_pushnull(_VM);
- _CallState++;
-}
-
-void SquirrelVM::PushParam(SQUserPointer up)
-{
- _CHECK_CALL_STATE
- sq_pushuserpointer(_VM,up);
- _CallState++;
-}
-
-SquirrelObject SquirrelVM::EndCall()
-{
- SquirrelObject ret;
- if(_CallState >= 0) {
- int oldtop = sq_gettop(_VM);
- int nparams = _CallState;
- _CallState = -1;
- if(SQ_SUCCEEDED(sq_call(_VM,nparams,SQTrue,SQ_CALL_RAISE_ERROR))) {
- ret.AttachToStackObject(-1);
- sq_pop(_VM,2);
- }else {
- sq_settop(_VM,oldtop-(nparams+1));
- throw SquirrelError();
- }
-
- }
- return ret;
-}
-
-SquirrelObject SquirrelVM::CreateInstance(SquirrelObject &oclass)
-{
- SquirrelObject ret;
- int oldtop = sq_gettop(_VM);
- sq_pushobject(_VM,oclass._o);
- if(SQ_FAILED(sq_createinstance(_VM,-1))) {
- sq_settop(_VM,oldtop);
- throw SquirrelError();
- }
- ret.AttachToStackObject(-1);
- sq_pop(_VM,2);
- return ret;
-}
-
-SquirrelObject SquirrelVM::CreateTable()
-{
- SquirrelObject ret;
- sq_newtable(_VM);
- ret.AttachToStackObject(-1);
- sq_pop(_VM,1);
- return ret;
-}
-
-SquirrelObject SquirrelVM::CreateString(const SQChar *s)
-{
- SquirrelObject ret;
- sq_pushstring(_VM,s,-1);
- ret.AttachToStackObject(-1);
- sq_pop(_VM,1);
- return ret;
-}
-
-
-SquirrelObject SquirrelVM::CreateArray(int size)
-{
- SquirrelObject ret;
- sq_newarray(_VM,size);
- ret.AttachToStackObject(-1);
- sq_pop(_VM,1);
- return ret;
-}
-
-SquirrelObject SquirrelVM::CreateFunction(SQFUNCTION func)
-{
- SquirrelObject ret;
- sq_newclosure(_VM,func,0);
- ret.AttachToStackObject(-1);
- sq_pop(_VM,1);
- return ret;
-}
-
-SquirrelObject SquirrelVM::CreateUserData(int size) {
- SquirrelObject ret;
- sq_newuserdata(_VM,size);
- ret.AttachToStackObject(-1);
- sq_pop(_VM,1);
- return ret;
-}
-
-const SquirrelObject &SquirrelVM::GetRootTable()
-{
- if( !_root ){
- sq_pushroottable(_VM);
- _root = new SquirrelObject();
- _root->AttachToStackObject(-1);
- sq_pop(_VM,1);
- }
- return *_root;
-}
-
-void SquirrelVM::PushRootTable(void) {
- sq_pushroottable(_VM);
-} // SquirrelVM::PushRootTable
-
-// Creates a function in the table or class currently on the stack.
-//void CreateFunction(HSQUIRRELVM v,const SQChar * scriptFuncName,SQFUNCTION func,int numParams=0,const SQChar * typeMask=0) {
-SquirrelObject SquirrelVM::CreateFunction(SQFUNCTION func,const SQChar * scriptFuncName,const SQChar * typeMask) {
- sq_pushstring(_VM,scriptFuncName,-1);
- sq_newclosure(_VM,func,0);
- SquirrelObject ret;
- ret.AttachToStackObject(-1);
- SQChar tm[64];
- SQChar * ptm = tm;
- int numParams = SQ_MATCHTYPEMASKSTRING;
- if (typeMask) {
- if (typeMask[0] == '*') {
- ptm = 0; // Variable args: don't check parameters.
- numParams = 0; // Clear SQ_MATCHTYPEMASKSTRING (does not mean match 0 params. See sq_setparamscheck()).
- } else {
- if (SCSNPRINTF(tm,sizeof(tm),_SC("t|y|x%s"),typeMask) < 0) {
-// sq_throwerror(_VM,_SC("CreateFunction: typeMask string too long."));
- throw SquirrelError(_SC("CreateFunction: typeMask string too long."));
- } // if
- } // if
- } else { // <TODO> Need to check object type on stack: table, class, instance, etc.
- SCSNPRINTF(tm,sizeof(tm),_SC("%s"),_SC("t|y|x")); // table, class, instance.
-// tm[0] = 't';
-// tm[1] = 0;
- } // if
-#if 0
- sq_setparamscheck(_VM,numParams+1,ptm); // Parameters are table+args (thus, the +1).
-#else
- if (ptm) {
- sq_setparamscheck(_VM,numParams,ptm); // Determine arg count from type string.
- } // if
-#endif
-#ifdef _DEBUG
- sq_setnativeclosurename(_VM,-1,scriptFuncName); // For debugging only.
-#endif
- sq_createslot(_VM,-3); // Create slot in table or class (assigning function to slot at scriptNameFunc).
- return ret;
-} // SquirrelVM::CreateFunction
-
-SquirrelObject SquirrelVM::CreateFunction(SquirrelObject & so,SQFUNCTION func,const SQChar * scriptFuncName,const SQChar * typeMask) {
- PushObject(so);
- SquirrelObject ret = CreateFunction(func,scriptFuncName,typeMask);
- Pop(1);
- return ret;
-} // SquirrelVM::CreateFunction
-
-// Create a Global function on the root table.
-//void CreateFunctionGlobal(HSQUIRRELVM v,const SQChar * scriptFuncName,SQFUNCTION func,int numParams=0,const SQChar * typeMask=0) {
-SquirrelObject SquirrelVM::CreateFunctionGlobal(SQFUNCTION func,const SQChar * scriptFuncName,const SQChar * typeMask) {
- PushRootTable(); // Push root table.
- // CreateFunction(scriptFuncName,func,numParams,typeMask);
- SquirrelObject ret = CreateFunction(func,scriptFuncName,typeMask);
- Pop(1); // Pop root table.
- return ret;
-} // SquirrelVM::CreateFunctionGlobal
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+
+#define _DEBUG_DUMP
+
+#include "sqplus.h"
+
+#include <sqstdio.h>
+#include <sqstdmath.h>
+#include <sqstdstring.h>
+#include <sqstdaux.h>
+#include <sqstdblob.h>
+#include <sqstdsystem.h>
+
+
+HSQUIRRELVM SquirrelVM::_VM;
+bool SquirrelVM::_no_vm_ref;
+int SquirrelVM::_CallState = -1;
+SquirrelObject* SquirrelVM::_root;
+HSQUIRRELVM SquirrelVM::_sandboxVM;
+SquirrelObject SquirrelVM::_vm;
+
+
+// Helper struct to keep track of all SQSharedState:s created by SquirrelVM.
+#include "../squirrel/sqpcheader.h"
+#include "../squirrel/sqvm.h"
+struct SQSharedStateNode {
+ SQSharedStateNode( SQSharedState* ps );
+ ~SQSharedStateNode( );
+ SQSharedState* m_ps;
+ SQSharedStateNode* m_nxt;
+};
+
+// Linked list of shared states
+static SQSharedStateNode* g_sqss_fst;
+
+SQSharedStateNode::SQSharedStateNode( SQSharedState* ps ) : m_ps(ps), m_nxt(g_sqss_fst) {
+ g_sqss_fst = this;
+}
+
+SQSharedStateNode::~SQSharedStateNode() {
+ if(m_ps) sq_delete(m_ps,SQSharedState);
+ delete m_nxt;
+}
+
+static struct SquirrelVM_ModConstr {
+ ~SquirrelVM_ModConstr(){
+ // Delete any shared states we created
+ delete g_sqss_fst;
+ g_sqss_fst = NULL;
+ }
+} g_squirrelvm_mod_constr;
+
+
+
+SquirrelError::SquirrelError()
+{
+ const SQChar *s;
+ sq_getlasterror(SquirrelVM::_VM);
+ sq_getstring(SquirrelVM::_VM,-1,&s);
+ if(s) {
+ desc = s;
+ }
+ else {
+ desc = _SC("unknown error");
+ }
+}
+
+
+SquirrelVMSys::~SquirrelVMSys() {
+ // Must take care to release object with the 'ref' VM
+ PushRefVM( _vm.GetObjectHandle()._unVal.pThread );
+ _vm.Reset();
+ PopRefVM();
+}
+
+void SquirrelVMSys::Set( HSQUIRRELVM v ){
+ // Must take care to release object with the 'ref' VM
+ PushRefVM( v );
+ _vm = v;
+ PopRefVM( );
+}
+
+void SquirrelVMSys::Set( const SquirrelObject& ov ){
+ assert( ov.GetObjectHandle()._type==OT_THREAD );
+ // Must take care to release object with the 'ref' VM
+ PushRefVM( ov.GetObjectHandle()._unVal.pThread );
+ _vm = ov;
+ PopRefVM( );
+}
+
+SquirrelVMSys::operator HSQUIRRELVM () const {
+ // Avoid const madness
+ SquirrelObject *pvm = (SquirrelObject*)&_vm;
+ assert( pvm->GetObjectHandle()._type==OT_THREAD );
+ return pvm->GetObjectHandle()._unVal.pThread;
+}
+
+
+// When doing a SquirrelObject assignment, a reference using the current
+// VM is done.
+HSQUIRRELVM g_VM_pushed;
+void SquirrelVMSys::PushRefVM( HSQUIRRELVM v ){
+ assert( !g_VM_pushed );
+ g_VM_pushed = SquirrelVM::_VM;
+ SquirrelVM::_VM = v;
+}
+
+void SquirrelVMSys::PopRefVM( ){
+ SquirrelVM::_VM = g_VM_pushed;
+ g_VM_pushed = NULL;
+}
+
+
+bool SquirrelVM::Init( HSQUIRRELVM v ){
+ if( v && v==_VM )
+ return true;
+
+ // Do we have a previous state?
+ Release( );
+
+ bool created_new = false;
+ if( !v ){
+ // Create a new VM - a root VM with new SharedState.
+ v = sq_open(1024);
+ if( !v ) return false;
+ // Store the associated shared state in a linked list. The state will only
+ // be destroyed at app shutdown. Often that is fine, but if using many
+ // VM:s briefly, this allocation is not optimal.
+ new SQSharedStateNode( _ss(v) );
+ created_new = true;
+ sq_setprintfunc(v,SquirrelVM::PrintFunc, SquirrelVM::PrintFunc);
+ sq_pushroottable(v);
+ sqstd_register_iolib(v);
+ sqstd_register_bloblib(v);
+ sqstd_register_mathlib(v);
+ sqstd_register_stringlib(v);
+#ifdef SQPLUS_SQUIRRELVM_WITH_SYSTEMLIB
+ sqstd_register_systemlib(v);
+#endif
+ sqstd_seterrorhandlers(v);
+ //TODO error handler, compiler error handler
+ sq_pop(v,1);
+ }
+
+ // After this we hold a ref
+ _no_vm_ref = false;
+ _VM = v;
+ _vm = v;
+
+ // In the case where Squirrel is ref counted we currently
+ // hold two references to the VM (since it is created with
+ // a ref count of 1). In the GC case, it is outside of the
+ // chain of valid objects, so it is not referenced. Compensate
+ // in ref counted case.
+ if( created_new )
+ DropVMRefIfRefCounted( v );
+
+ return true;
+}
+
+bool SquirrelVM::InitNoRef( HSQUIRRELVM v ){
+ if( v && v==_VM )
+ return true;
+
+ // Do we have a previous state?
+ Release( );
+
+ // Set pointer to this VM, without referencing it
+ _no_vm_ref = true;
+ _VM = v;
+
+ return true;
+}
+
+/*
+void SquirrelVM::Init( HSQUIRRELVM v )
+{
+ if( v && v==_VM ) {
+ return;
+ }
+
+ // Do we have a previous state?
+ Release();
+
+ if( !v ){
+ // Create a new VM and own it
+ _VM = sq_open(1024);
+ sq_setprintfunc(_VM,SquirrelVM::PrintFunc);
+ sq_pushroottable(_VM);
+ sqstd_register_iolib(_VM);
+ sqstd_register_bloblib(_VM);
+ sqstd_register_mathlib(_VM);
+ sqstd_register_stringlib(_VM);
+ sqstd_seterrorhandlers(_VM);
+ //TODO error handler, compiler error handler
+ sq_pop(_VM,1);
+ }
+ else {
+ _VM = v;
+ }
+ // After this we hold a ref
+ _vm = _VM;
+}
+*/
+
+void SquirrelVM::Release() {
+ // Release root table object if we have one
+ if( _root ){
+ delete _root;
+ _root = NULL;
+ }
+
+ // Release our ref on VM - if we should
+ if( !_no_vm_ref )
+ _vm.Reset();
+
+ _VM = NULL;
+}
+
+void SquirrelVM::DropVMRefIfRefCounted( HSQUIRRELVM v ){
+#ifdef NO_GARBAGE_COLLECTOR
+ if( v ){
+ SQObject t;
+ t._unVal.pThread = v;
+ t._type = OT_THREAD;
+ sq_release( v, &t );
+ }
+#endif
+}
+
+BOOL SquirrelVM::Update()
+{
+ //update remote debugger
+ return TRUE;
+}
+
+void SquirrelVM::PrintFunc(HSQUIRRELVM v,const SQChar* s,...)
+{
+ static SQChar temp[2048];
+ va_list vl;
+ va_start(vl, s);
+ scvsprintf( temp,s, vl);
+ SCPUTS(temp);
+ va_end(vl);
+}
+
+SquirrelObject SquirrelVM::CompileScript(const SQChar *s)
+{
+ SquirrelObject ret;
+ if(SQ_SUCCEEDED(sqstd_loadfile(_VM,s,1))) {
+ ret.AttachToStackObject(-1);
+ sq_pop(_VM,1);
+ return ret;
+ }
+ throw SquirrelError();
+}
+
+SquirrelObject SquirrelVM::CompileBuffer(const SQChar *s,const SQChar * debugInfo)
+{
+ SquirrelObject ret;
+ if(SQ_SUCCEEDED(sq_compilebuffer(_VM,s,(int)scstrlen(s)*sizeof(SQChar),debugInfo,1))) {
+ ret.AttachToStackObject(-1);
+ sq_pop(_VM,1);
+ return ret;
+ }
+ throw SquirrelError();
+}
+
+SquirrelObject SquirrelVM::RunScript(const SquirrelObject &o,SquirrelObject *_this)
+{
+ SquirrelObject ret;
+ sq_pushobject(_VM,o._o);
+ if(_this) {
+ sq_pushobject(_VM,_this->_o);
+ }
+ else {
+ sq_pushroottable(_VM);
+ }
+ if(SQ_SUCCEEDED(sq_call(_VM,1,SQTrue,SQ_CALL_RAISE_ERROR))) {
+ ret.AttachToStackObject(-1);
+ sq_pop(_VM,2);
+ return ret;
+ }
+ sq_pop(_VM,1);
+ throw SquirrelError();
+
+}
+
+
+BOOL SquirrelVM::BeginCall(const SquirrelObject &func)
+{
+ if(_CallState != -1)
+ return FALSE;
+ _CallState = 1;
+ sq_pushobject(_VM,func._o);
+ sq_pushroottable(_VM);
+ return TRUE;
+}
+
+BOOL SquirrelVM::BeginCall(const SquirrelObject &func,SquirrelObject &_this)
+{
+ if(_CallState != -1)
+ throw SquirrelError(_SC("call already initialized"));
+ _CallState = 1;
+ sq_pushobject(_VM,func._o);
+ sq_pushobject(_VM,_this._o);
+ return TRUE;
+}
+
+#define _CHECK_CALL_STATE \
+ if(_CallState == -1) \
+ throw SquirrelError(_SC("call not initialized"));
+
+void SquirrelVM::PushParam(const SquirrelObject &o)
+{
+ _CHECK_CALL_STATE
+ sq_pushobject(_VM,o._o);
+ _CallState++;
+}
+
+void SquirrelVM::PushParam(const SQChar *s)
+{
+ _CHECK_CALL_STATE
+ sq_pushstring(_VM,s,-1);
+ _CallState++;
+}
+
+void SquirrelVM::PushParam(SQInteger n)
+{
+ _CHECK_CALL_STATE
+ sq_pushinteger(_VM,n);
+ _CallState++;
+}
+
+void SquirrelVM::PushParam(SQFloat f)
+{
+ _CHECK_CALL_STATE
+ sq_pushfloat(_VM,f);
+ _CallState++;
+}
+
+void SquirrelVM::PushParamNull()
+{
+ _CHECK_CALL_STATE
+ sq_pushnull(_VM);
+ _CallState++;
+}
+
+void SquirrelVM::PushParam(SQUserPointer up)
+{
+ _CHECK_CALL_STATE
+ sq_pushuserpointer(_VM,up);
+ _CallState++;
+}
+
+SquirrelObject SquirrelVM::EndCall()
+{
+ SquirrelObject ret;
+ if(_CallState >= 0) {
+ int oldtop = sq_gettop(_VM);
+ int nparams = _CallState;
+ _CallState = -1;
+ if(SQ_SUCCEEDED(sq_call(_VM,nparams,SQTrue,SQ_CALL_RAISE_ERROR))) {
+ ret.AttachToStackObject(-1);
+ sq_pop(_VM,2);
+ }else {
+ sq_settop(_VM,oldtop-(nparams+1));
+ throw SquirrelError();
+ }
+
+ }
+ return ret;
+}
+
+SquirrelObject SquirrelVM::CreateInstance(SquirrelObject &oclass)
+{
+ SquirrelObject ret;
+ int oldtop = sq_gettop(_VM);
+ sq_pushobject(_VM,oclass._o);
+ if(SQ_FAILED(sq_createinstance(_VM,-1))) {
+ sq_settop(_VM,oldtop);
+ throw SquirrelError();
+ }
+ ret.AttachToStackObject(-1);
+ sq_pop(_VM,2);
+ return ret;
+}
+
+SquirrelObject SquirrelVM::CreateTable()
+{
+ SquirrelObject ret;
+ sq_newtable(_VM);
+ ret.AttachToStackObject(-1);
+ sq_pop(_VM,1);
+ return ret;
+}
+
+SquirrelObject SquirrelVM::CreateString(const SQChar *s)
+{
+ SquirrelObject ret;
+ sq_pushstring(_VM,s,-1);
+ ret.AttachToStackObject(-1);
+ sq_pop(_VM,1);
+ return ret;
+}
+
+
+SquirrelObject SquirrelVM::CreateArray(int size)
+{
+ SquirrelObject ret;
+ sq_newarray(_VM,size);
+ ret.AttachToStackObject(-1);
+ sq_pop(_VM,1);
+ return ret;
+}
+
+SquirrelObject SquirrelVM::CreateFunction(SQFUNCTION func)
+{
+ SquirrelObject ret;
+ sq_newclosure(_VM,func,0);
+ ret.AttachToStackObject(-1);
+ sq_pop(_VM,1);
+ return ret;
+}
+
+SquirrelObject SquirrelVM::CreateUserData(int size) {
+ SquirrelObject ret;
+ sq_newuserdata(_VM,size);
+ ret.AttachToStackObject(-1);
+ sq_pop(_VM,1);
+ return ret;
+}
+
+const SquirrelObject &SquirrelVM::GetRootTable()
+{
+ if( !_root ){
+ sq_pushroottable(_VM);
+ _root = new SquirrelObject();
+ _root->AttachToStackObject(-1);
+ sq_pop(_VM,1);
+ }
+ return *_root;
+}
+
+void SquirrelVM::PushRootTable(void) {
+ sq_pushroottable(_VM);
+} // SquirrelVM::PushRootTable
+
+// Creates a function in the table or class currently on the stack.
+//void CreateFunction(HSQUIRRELVM v,const SQChar * scriptFuncName,SQFUNCTION func,int numParams=0,const SQChar * typeMask=0) {
+SquirrelObject SquirrelVM::CreateFunction(SQFUNCTION func,const SQChar * scriptFuncName,const SQChar * typeMask) {
+ sq_pushstring(_VM,scriptFuncName,-1);
+ sq_newclosure(_VM,func,0);
+ SquirrelObject ret;
+ ret.AttachToStackObject(-1);
+ SQChar tm[64];
+ SQChar * ptm = tm;
+ int numParams = SQ_MATCHTYPEMASKSTRING;
+ if (typeMask) {
+ if (typeMask[0] == '*') {
+ ptm = 0; // Variable args: don't check parameters.
+ numParams = 0; // Clear SQ_MATCHTYPEMASKSTRING (does not mean match 0 params. See sq_setparamscheck()).
+ } else {
+ if (SCSNPRINTF(tm,sizeof(tm),_SC("t|y|x%s"),typeMask) < 0) {
+// sq_throwerror(_VM,_SC("CreateFunction: typeMask string too long."));
+ throw SquirrelError(_SC("CreateFunction: typeMask string too long."));
+ } // if
+ } // if
+ } else { // <TODO> Need to check object type on stack: table, class, instance, etc.
+ SCSNPRINTF(tm,sizeof(tm),_SC("%s"),_SC("t|y|x")); // table, class, instance.
+// tm[0] = 't';
+// tm[1] = 0;
+ } // if
+#if 0
+ sq_setparamscheck(_VM,numParams+1,ptm); // Parameters are table+args (thus, the +1).
+#else
+ if (ptm) {
+ sq_setparamscheck(_VM,numParams,ptm); // Determine arg count from type string.
+ } // if
+#endif
+#ifdef _DEBUG
+ sq_setnativeclosurename(_VM,-1,scriptFuncName); // For debugging only.
+#endif
+ sq_createslot(_VM,-3); // Create slot in table or class (assigning function to slot at scriptNameFunc).
+ return ret;
+} // SquirrelVM::CreateFunction
+
+SquirrelObject SquirrelVM::CreateFunction(SquirrelObject & so,SQFUNCTION func,const SQChar * scriptFuncName,const SQChar * typeMask) {
+ PushObject(so);
+ SquirrelObject ret = CreateFunction(func,scriptFuncName,typeMask);
+ Pop(1);
+ return ret;
+} // SquirrelVM::CreateFunction
+
+// Create a Global function on the root table.
+//void CreateFunctionGlobal(HSQUIRRELVM v,const SQChar * scriptFuncName,SQFUNCTION func,int numParams=0,const SQChar * typeMask=0) {
+SquirrelObject SquirrelVM::CreateFunctionGlobal(SQFUNCTION func,const SQChar * scriptFuncName,const SQChar * typeMask) {
+ PushRootTable(); // Push root table.
+ // CreateFunction(scriptFuncName,func,numParams,typeMask);
+ SquirrelObject ret = CreateFunction(func,scriptFuncName,typeMask);
+ Pop(1); // Pop root table.
+ return ret;
+} // SquirrelVM::CreateFunctionGlobal