bool CreateConstructNativeClassInstance(HSQUIRRELVM v, const SQChar * className) { int oldtop = sq_gettop(v); sq_pushroottable(v); sq_pushstring(v, className, -1); if (SQ_FAILED(sq_rawget(v, -2))) { // Get the class (created with sq_newclass()). sq_settop(v, oldtop); return false; } // if #if 0 sq_remove(v, -3); // Remove the root table. sq_push(v, 1); // Push the 'this'. #else // Kamaitati's change. 5/28/06 jcs. sq_remove(v, -2); // Remove the root table. sq_pushroottable(v); // Push the 'this'. #endif if (SQ_FAILED(sq_call(v, 1, SQTrue, false))) { // Call ClassName(): creates new instance and calls constructor (instead of sq_createinstance() where constructor is not called). sq_settop(v, oldtop); return false; } // if sq_remove(v, -2); // Remove the class. // int newtop = sq_gettop(v); return true; } // CreateConstructNativeClassInstance
bool Squirrel::CallMethod(HSQOBJECT instance, const char *method_name, HSQOBJECT *ret, int suspend) { assert(!this->crashed); /* Store the stack-location for the return value. We need to * restore this after saving or the stack will be corrupted * if we're in the middle of a DoCommand. */ SQInteger last_target = this->vm->_suspended_target; /* Store the current top */ int top = sq_gettop(this->vm); /* Go to the instance-root */ sq_pushobject(this->vm, instance); /* Find the function-name inside the script */ sq_pushstring(this->vm, OTTD2SQ(method_name), -1); if (SQ_FAILED(sq_get(this->vm, -2))) { DEBUG(misc, 0, "[squirrel] Could not find '%s' in the class", method_name); sq_settop(this->vm, top); return false; } /* Call the method */ sq_pushobject(this->vm, instance); if (SQ_FAILED(sq_call(this->vm, 1, ret == NULL ? SQFalse : SQTrue, SQTrue, suspend))) return false; if (ret != NULL) sq_getstackobj(vm, -1, ret); /* Reset the top, but don't do so for the AI main function, as we need * a correct stack when resuming. */ if (suspend == -1 || !this->IsSuspended()) sq_settop(this->vm, top); /* Restore the return-value location. */ this->vm->_suspended_target = last_target; return true; }
bool _sort_compare(HSQUIRRELVM v,SQObjectPtr &a,SQObjectPtr &b,SQInteger func,SQInteger &ret) { if(func < 0) { if(!v->ObjCmp(a,b,ret)) return false; } else { SQInteger top = sq_gettop(v); sq_push(v, func); sq_pushroottable(v); v->Push(a); v->Push(b); if(SQ_FAILED(sq_call(v, 3, SQTrue, SQFalse))) { if(!sq_isstring( v->_lasterror)) v->Raise_Error(_SC("compare func failed")); return false; } if(SQ_FAILED(sq_getinteger(v, -1, &ret))) { v->Raise_Error(_SC("numeric value expected as return value of the compare function")); return false; } sq_settop(v, top); return true; } return true; }
void CScripts::Call(const char * szFunc, int iArgCount, SQObjectPtr * pArguments) { for(int i = 0; i < MAX_SCRIPTS; i++) { if(m_pScripts[i]) { // get the script vm pointer SQVM * pVM = m_pScripts[i]->GetVM(); // Get the stack top int iTop = sq_gettop(pVM); // Push the root table onto the stack sq_pushroottable(pVM); // Push the function name onto the stack sq_pushstring(pVM, szFunc, -1); if(SQ_SUCCEEDED(sq_get(pVM, -2))) { // Push the root table onto the stack sq_pushroottable(pVM); if(pArguments != NULL) { for(int j = 0; j < iArgCount; ++j) sq_pushobject(pVM, pArguments[j]); //pVM->Push(pArguments[j]); } sq_call(pVM, iArgCount + 1, true, true); } // Restore the stack top sq_settop(pVM, iTop); } } }
static SQInteger array_reduce(HSQUIRRELVM v) { SQObject &o = stack_get(v,1); SQArray *a = _array(o); SQInteger size = a->Size(); if(size == 0) { return 0; } SQObjectPtr res; a->Get(0,res); if(size > 1) { SQObjectPtr other; for(SQInteger n = 1; n < size; n++) { a->Get(n,other); v->Push(o); v->Push(res); v->Push(other); if(SQ_FAILED(sq_call(v,3,SQTrue,SQFalse))) { return SQ_ERROR; } res = v->GetUp(-1); v->Pop(); } } v->Push(res); return 1; }
void CScripts::onInit(int iScript) { if(m_pScripts[iScript]) { // get the script vm pointer SQVM * pVM = m_pScripts[iScript]->GetVM(); // Get the stack top int iTop = sq_gettop(pVM); // Push the root table onto the stack sq_pushroottable(pVM); // Push the function name onto the stack sq_pushstring(pVM, "onInit", -1); // Get the closure for the function if(SQ_SUCCEEDED(sq_get(pVM, -2))) { // Push the root table onto the stack sq_pushroottable(pVM); // Call the function sq_call(pVM, 1, true, true); } // Restore the stack top sq_settop(pVM, iTop); } }
/* * load squirrel script from given file name */ bool loadScript(const char* fname) { FILE* fp = fopen(fname, "r"); if (fp == NULL) { engine->setLastError(ERR_SCRIPT_OPEN); LOGW("loadScript: failed to open main script file"); LOGW(fname); return false; } if (SQ_SUCCEEDED(sq_compile(engine->sqvm, sq_lexer_fp, fp, fname, SQTrue))) { sq_pushroottable(engine->sqvm); if (SQ_FAILED(sq_call(engine->sqvm, 1, SQFalse, SQTrue))) { engine->setLastError(ERR_SCRIPT_CALL_ROOT); LOGW("loadScript: failed to sq_call"); LOGW(fname); fclose(fp); return false; } } else { engine->setLastError(ERR_SCRIPT_COMPILE); LOGW("loadScript: failed to compile squirrel script"); LOGW(fname); fclose(fp); return false; } fclose(fp); return true; }
void CScripts::onBan(const char *szText) { for(int i = 0; i < MAX_SCRIPTS; i++) { if(m_pScripts[i]) { // get the script vm pointer SQVM * pVM = m_pScripts[i]->GetVM(); // Get the stack top int iTop = sq_gettop(pVM); // Push the root table onto the stack sq_pushroottable(pVM); // Push the function name onto the stack sq_pushstring(pVM, "onBan", -1); // Get the closure for the function if(SQ_SUCCEEDED(sq_get(pVM, -2))) { // Push the root table onto the stack sq_pushroottable(pVM); // Push the ban mask onto the stack sq_pushstring(pVM, szText, -1); // Call the function sq_call(pVM, 2, true, true); } // Restore the stack top sq_settop(pVM, iTop); } } }
void ConsoleImpl::execute(const std::string& str_) { std::string str = str_; //"return (" + str_ + ")"; int i = str.length(); const char* buffer = str.c_str(); HSQUIRRELVM vm = script_manager->get_vm(); int oldtop=sq_gettop(vm); try { int retval = 1; if(i>0){ if(SQ_SUCCEEDED(sq_compilebuffer(vm,buffer,i,_SC("interactive console"),SQTrue))){ sq_pushroottable(vm); if(SQ_SUCCEEDED(sq_call(vm,1, retval, true))) { if (sq_gettype(vm, -1) != OT_NULL) console << squirrel2string(vm, -1) << std::endl; } } } } catch(std::exception& e) { std::cerr << "Couldn't execute command '" << str_ << "': " << e.what() << "\n"; } sq_settop(vm,oldtop); }
int main(int argc, char** argv) { HSQUIRRELVM vm=sq_open(SQUIRREL_STACK_SIZE); sq_setprintfunc(vm, squirrel_print_function, NULL); register_global_func(vm,ShowVersion,"ShowVersion"); register_global_func(vm,Multiply,"Multiply"); if(SQ_FAILED(sqstd_dofile(vm,"test.nut",SQFalse,SQFalse))) return 1; /*const SQChar *program = "::print(\"Hello World!\\n\");"; if (SQ_FAILED(sq_compilebuffer(vm, program, sizeof(SQChar) * strlen(program), "program", SQFalse))) { return 1; }*/ sq_pushroottable(vm); if (SQ_FAILED(sq_call(vm, 1, SQFalse, SQFalse))) { //squirrel_print_last_error(sqvm); return 1; } sq_close(vm); return 0; }
void SQDbgServer::SerializeState() { sq_pushnull(_v); sq_setdebughook(_v); sq_pushnull(_v); sq_seterrorhandler(_v); const SQChar *sz; sq_pushobject(_v,_serializefunc); sq_pushobject(_v,_debugroot); sq_pushstring(_v,_SC("watches"),-1); sq_newtable(_v); for(WatchSetItor i=_watches.begin(); i!=_watches.end(); ++i) { sq_pushinteger(_v,i->_id); sq_pushstring(_v,i->_exp.c_str(),(int)i->_exp.length()); sq_createslot(_v,-3); } sq_rawset(_v,-3); if(SQ_SUCCEEDED(sq_call(_v,1,SQTrue,SQTrue))){ if(SQ_SUCCEEDED(sqstd_getblob(_v,-1,(SQUserPointer*)&sz))) SendChunk(sz); } sq_pop(_v,2); SetErrorHandlers(); }
void CScripts::onTimerCreate(int timerId) { for(int i = 0; i < MAX_SCRIPTS; i++) { if(m_pScripts[i]) { // get the script vm pointer SQVM * pVM = m_pScripts[i]->GetVM(); // Get the stack top int iTop = sq_gettop(pVM); // Push the root table onto the stack sq_pushroottable(pVM); // Push the function name onto the stack sq_pushstring(pVM, "onTimerCreate", -1); // Get the closure for the function if(SQ_SUCCEEDED(sq_get(pVM, -2))) { // Push the root table onto the stack sq_pushroottable(pVM); // Push the timer id onto the stack sq_pushinteger(pVM, timerId); // Call the function sq_call(pVM, 2, true, true); } // Restore the stack top sq_settop(pVM, iTop); } } }
/** Run the dummy info.nut. */ void Script_CreateDummyInfo(HSQUIRRELVM vm, const char *type, const char *dir) { char dummy_script[4096]; char *dp = dummy_script; dp += seprintf(dp, lastof(dummy_script), "class Dummy%s extends %sInfo {\n", type, type); dp += seprintf(dp, lastof(dummy_script), "function GetAuthor() { return \"OpenTTD Developers Team\"; }\n"); dp += seprintf(dp, lastof(dummy_script), "function GetName() { return \"Dummy%s\"; }\n", type); dp += seprintf(dp, lastof(dummy_script), "function GetShortName() { return \"DUMM\"; }\n"); dp += seprintf(dp, lastof(dummy_script), "function GetDescription() { return \"A Dummy %s that is loaded when your %s/ dir is empty\"; }\n", type, dir); dp += seprintf(dp, lastof(dummy_script), "function GetVersion() { return 1; }\n"); dp += seprintf(dp, lastof(dummy_script), "function GetDate() { return \"2008-07-26\"; }\n"); dp += seprintf(dp, lastof(dummy_script), "function CreateInstance() { return \"Dummy%s\"; }\n", type); dp += seprintf(dp, lastof(dummy_script), "} RegisterDummy%s(Dummy%s());\n", type, type); const SQChar *sq_dummy_script = dummy_script; sq_pushroottable(vm); /* Load and run the script */ if (SQ_SUCCEEDED(sq_compilebuffer(vm, sq_dummy_script, strlen(sq_dummy_script), "dummy", SQTrue))) { sq_push(vm, -2); if (SQ_SUCCEEDED(sq_call(vm, 1, SQFalse, SQTrue))) { sq_pop(vm, 1); return; } } NOT_REACHED(); }
/* * invoke impact event */ static SQBool invokeImpactEvent(HSQUIRRELVM v, ContactPoint cp) { SQBool result = false; SQInteger top = sq_gettop(v); sq_pushroottable(v); sq_pushstring(v, "emo", -1); if (SQ_SUCCEEDED(sq_get(v, -2))) { sq_pushstring(v, "_onImpact", -1); if(SQ_SUCCEEDED(sq_get(v, -2))) { sq_pushroottable(v); sq_pushuserpointer(v, cp.fixtureA); sq_pushuserpointer(v, cp.fixtureB); sq_pushuserpointer(v, cp.fixtureA->GetBody()); sq_pushuserpointer(v, cp.fixtureB->GetBody()); pushVec2(v, cp.position); pushVec2(v, cp.normal); sq_pushfloat(v, cp.normalImpulse); sq_pushfloat(v, cp.tangentImpulse); result = SQ_SUCCEEDED(sq_call(v, 9, SQFalse, SQTrue)); } } sq_settop(v,top); return result; }
static SQInteger _closure_acall(HSQUIRRELVM v,SQBool raiseerror) { SQArray *aparams=_array(stack_get(v,2)); SQInteger nparams=aparams->Size(); v->Push(stack_get(v,1)); for(SQInteger i=0;i<nparams;i++)v->Push(aparams->_values[i]); return SQ_SUCCEEDED(sq_call(v,nparams,SQTrue,raiseerror))?1:SQ_ERROR; }
// ------------------------------------------------------------------------------------------------ SQInteger Signal::SqEmit(HSQUIRRELVM vm) { const Int32 top = sq_gettop(vm); // The signal instance Signal * signal = nullptr; // Attempt to extract the signal instance try { signal = Var< Signal * >(vm, 1).value; } catch (const Sqrat::Exception & e) { return sq_throwerror(vm, e.what()); } // Do we have a valid signal instance? if (!signal) { return sq_throwerror(vm, "Invalid signal instance"); } // Walk down the chain and trigger slots for (Slot * node = signal->m_Head, * next = nullptr; node != nullptr; node = next) { // Grab the next node upfront next = node->mNext; // Remember the current stack size const StackGuard sg(vm); // Push the callback object sq_pushobject(vm, node->mFuncRef); // Is there an explicit environment? if (sq_isnull(node->mEnvRef)) { sq_pushroottable(vm); } else { sq_pushobject(vm, node->mEnvRef); } // Are there any parameters to forward? if (top > 1) { for (SQInteger i = 2; i <= top; ++i) { sq_push(vm, i); } } // Make the function call and store the result const SQRESULT res = sq_call(vm, top, false, ErrorHandling::IsEnabled()); // Validate the result if (SQ_FAILED(res)) { return res; // Propagate the error } } // Specify that we don't return anything return 0; }
static void call(HSQUIRRELVM v, const wgChar *devicename) { sq_pushroottable(v); sq_pushstring(v, _SC("flash_device_get"), -1); if(SQ_SUCCEEDED(sq_get(v,-2))){ sq_pushroottable(v); sq_pushstring(v, devicename, -1); sq_call(v, 2, SQTrue, SQTrue); } }
/* * Comple script buffers */ SQInteger sqCompileBuffer(HSQUIRRELVM v, const char* script, const char* sourcename) { if (SQ_SUCCEEDED(sq_compilebuffer(v, script, scstrlen(script), sourcename, SQTrue))) { sq_pushroottable(v); if (SQ_FAILED(sq_call(v, 1, SQFalse, SQTrue))) { return ERR_SCRIPT_CALL_ROOT; } } else { return ERR_SCRIPT_COMPILE; } return EMO_NO_ERROR; }
void sc_OnGameModeInit(HSQUIRRELVM v) { int top = sq_gettop(v); sq_pushroottable(v); sq_pushstring(v, _SC("OnGameModeInit"), -1); if (SQ_SUCCEEDED(sq_get(v, -2))) { sq_pushroottable(v); sq_call(v, 1, 0, 1); } sq_settop(v, top); }
bool Context::executeBuffer(const String& buffer, const String& source) const { StackLock lock(*this); sq_pushroottable(vm_); if (SQ_FAILED( sq_compilebuffer(vm_, buffer.c_str(), buffer.size(), source.c_str(), SQTrue) )) return false; sq_push(vm_, -2); return SQ_SUCCEEDED( sq_call(vm_, 1, SQFalse, SQTrue) ); }
static SQRESULT sqrat_importscript(HSQUIRRELVM v, const SQChar* moduleName) { std::basic_string<SQChar> filename(moduleName); filename += _SC(".nut"); if(SQ_FAILED(sqstd_loadfile(v, moduleName, true))) { if(SQ_FAILED(sqstd_loadfile(v, filename.c_str(), true))) { return SQ_ERROR; } } sq_push(v, -2); sq_call(v, 1, false, true); return SQ_OK; }
void sc_CommandCallback(HSQUIRRELVM v, const wchar_t *callback, const unsigned char numargs) { int top = sq_gettop(v); sq_pushroottable(v); sq_pushstring(v, callback, -1); if(SQ_SUCCEEDED(sq_get(v, -2))) { sq_pushroottable(v); sq_pushinteger(v, numargs); sq_call(v, 2, 0, 1); } sq_settop(v, top); }
void sc_OnPlayerSpawn(HSQUIRRELVM v, const short index) { int top = sq_gettop(v); sq_pushroottable(v); sq_pushstring(v, _SC("OnPlayerSpawn"), -1); if (SQ_SUCCEEDED(sq_get(v, -2))) { sq_pushroottable(v); sq_pushinteger(v, index); sq_call(v, 2, 0, 1); } sq_settop(v, top); }
/** Run the dummy AI and let it generate an error message. */ void Script_CreateDummy(HSQUIRRELVM vm, StringID string, const char *type) { /* We want to translate the error message. * We do this in three steps: * 1) We get the error message */ char error_message[1024]; GetString(error_message, string, lastof(error_message)); /* Make escapes for all quotes and slashes. */ char safe_error_message[1024]; char *q = safe_error_message; for (const char *p = error_message; *p != '\0' && q < lastof(safe_error_message) - 2; p++, q++) { if (*p == '"' || *p == '\\') *q++ = '\\'; *q = *p; } *q = '\0'; /* 2) We construct the AI's code. This is done by merging a header, body and footer */ char dummy_script[4096]; char *dp = dummy_script; dp += seprintf(dp, lastof(dummy_script), "class Dummy%s extends %sController {\n function Start()\n {\n", type, type); /* As special trick we need to split the error message on newlines and * emit each newline as a separate error printing string. */ char *newline; char *p = safe_error_message; do { newline = strchr(p, '\n'); if (newline != NULL) *newline = '\0'; dp += seprintf(dp, lastof(dummy_script), " %sLog.Error(\"%s\");\n", type, p); p = newline + 1; } while (newline != NULL); dp = strecpy(dp, " }\n}\n", lastof(dummy_script)); /* 3) We translate the error message in the character format that Squirrel wants. * We can use the fact that the wchar string printing also uses %s to print * old style char strings, which is what was generated during the script generation. */ const SQChar *sq_dummy_script = dummy_script; /* And finally we load and run the script */ sq_pushroottable(vm); if (SQ_SUCCEEDED(sq_compilebuffer(vm, sq_dummy_script, strlen(sq_dummy_script), "dummy", SQTrue))) { sq_push(vm, -2); if (SQ_SUCCEEDED(sq_call(vm, 1, SQFalse, SQTrue))) { sq_pop(vm, 1); return; } } NOT_REACHED(); }
void call_print_hulla(HSQUIRRELVM v) { SQInteger top = sq_gettop(v); //saves the stack size before the call sq_pushroottable(v); //pushes the global table sq_pushstring(v, _SC("hola"), -1); if (SQ_SUCCEEDED(sq_get(v, -2))) { //gets the field 'foo' from the global table sq_pushroottable(v); //push the 'this' (in this case is the global table) sq_call(v, 1, SQFalse, SQTrue); //calls the function } sq_settop(v, top); //restores the original stack size }
/** * ベースVM上でスクリプトを実行する。 * この呼び出しはスレッドによるものではないため、処理中に suspend() / wait() を * 呼ぶとエラーになるので注意してください。必ず1度で呼びきれるものを渡す必要があります。 * @param func グローバル関数。※ファイルは指定できません * @param ... 引数 */ SQRESULT Thread::global_execOnBase(HSQUIRRELVM v) { SQInteger max = sq_gettop(v); if (max <= 1) { return ERROR_INVALIDPARAM(v); } HSQUIRRELVM gv = getGlobalVM(); SQRESULT result = SQ_OK; if (gv == v) { sq_push(gv, 2); sq_pushroottable(gv); // 引数:self(root) int argc = 1; for (int i=3;i<=max;i++) { sq_push(v, i); argc++; } if (SQ_SUCCEEDED(result = sq_call(gv, argc, SQTrue, SQTrue))) { sq_remove(gv, -2); // func } else { sq_pop(gv, 1); // func } } else { sq_move(gv, v, 2); // func sq_pushroottable(gv); // 引数:self(root) int argc = 1; for (int i=3;i<=max;i++) { sq_move(gv, v, i); argc++; } if (SQ_SUCCEEDED(result = sq_call(gv, argc, SQTrue, SQTrue))) { sq_move(v, gv, sq_gettop(gv)); sq_pop(gv, 2); } else { sq_pop(gv, 1); // func } } return result; }
//------------------------------------------------------------------------------ bool Script::execute() { SN_ASSERT(!isNull(), "Script is null"); SQInteger top = sq_gettop(m_vm); sq_pushobject(m_vm, m_object); sq_pushroottable(m_vm); SQRESULT result = sq_call(m_vm, 1, false, true); sq_settop(m_vm, top); return !SQ_FAILED(result); }
void sc_OnPlayerDeath(HSQUIRRELVM v, const short playerindex, const short killerindex, const char reason) { int top = sq_gettop(v); sq_pushroottable(v); sq_pushstring(v, _SC("OnPlayerDeath"), -1); if (SQ_SUCCEEDED(sq_get(v, -2))) { sq_pushroottable(v); sq_pushinteger(v, playerindex); sq_pushinteger(v, killerindex); sq_pushinteger(v, reason); sq_call(v, 4, 0, 1); } sq_settop(v, top); }
void call_foo(HSQUIRRELVM v, int n,float f,const SQChar *s) { SQInteger top = sq_gettop(v); //saves the stack size before the call sq_pushroottable(v); //pushes the global table sq_pushstring(v,_SC("foo"),-1); if(SQ_SUCCEEDED(sq_get(v,-2))) { //gets the field 'foo' from the global table sq_pushroottable(v); //push the 'this' (in this case is the global table) sq_pushinteger(v,n); sq_pushfloat(v,f); sq_pushstring(v,s,-1); sq_call(v,4,SQFalse,SQTrue); //calls the function } sq_settop(v,top); //restores the original stack size }
static SQInteger __map_array(SQArray *dest,SQArray *src,HSQUIRRELVM v) { SQObjectPtr temp; SQInteger size = src->Size(); for(SQInteger n = 0; n < size; n++) { src->Get(n,temp); v->Push(src); v->Push(temp); if(SQ_FAILED(sq_call(v,2,SQTrue,SQFalse))) { return SQ_ERROR; } dest->Set(n,v->GetUp(-1)); v->Pop(); } return 0; }