Example #1
0
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;
}
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();
}
Example #3
0
void SquirrelThread::initThread(HSQUIRRELVM parentVm)
{
    m_oldTop = -1;
    m_parentVm = parentVm;

    createThread();

    // create a local environment for the m_thread
    HSQOBJECT env;
    sq_resetobject(&env);

    sq_newtable(m_thread);

    // store the object in env
    if(sq_getstackobj(m_thread, -1, &env) < 0) 
    { return; }
    
    sq_addref(m_thread, &env); 
    sq_pop(m_thread, 1); // remove env from stack

    // set old roottable as delegate on env
    sq_pushobject(m_thread, env); // push env
    sq_pushroottable(m_thread);   // [env, root]
    sq_setdelegate(m_thread, -2); // env.set_delegate(root)
    sq_pop(m_thread, 1);          // pop env

    // set env as new roottable
    sq_pushobject(m_thread, env);
    sq_setroottable(m_thread);

    sq_release(m_thread, &env);
}
Example #4
0
BOOL SquirrelVM::BeginCall(const SquirrelObject &func,SquirrelObject &_this)
{
	if(_CallState != -1)
		throw SquirrelError(_VM,_SC("call already initialized"));
	_CallState = 1;
	sq_pushobject(_VM,func._o);
	sq_pushobject(_VM,_this._o);
	return TRUE;
}
Example #5
0
void SquirrelObject::Append(const SquirrelObject &o)
{
	if(sq_isarray(_o)) {
		sq_pushobject(m_Vm.GetVMPtr(),_o);
		sq_pushobject(m_Vm.GetVMPtr(),o._o);
		sq_arrayappend(m_Vm.GetVMPtr(),-2);
		sq_pop(m_Vm.GetVMPtr(),1);
	}
}
Example #6
0
// ------------------------------------------------------------------------------------------------
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;
}
Example #7
0
BOOL SquirrelObject::SetValue(const SquirrelObject &key,const SquirrelObject &val)
{
	BOOL ret = FALSE;
	int top = sq_gettop(m_Vm.GetVMPtr());
	sq_pushobject(m_Vm.GetVMPtr(),_o);
	sq_pushobject(m_Vm.GetVMPtr(),key._o);
	sq_pushobject(m_Vm.GetVMPtr(),val._o);
	if(SQ_SUCCEEDED(sq_rawset(m_Vm.GetVMPtr(),-3))) {
		ret = TRUE;
	}
	sq_settop(m_Vm.GetVMPtr(),top);
	return ret;
}
Example #8
0
	inline SQInteger DefSQNonStaticCallback(HSQUIRRELVM vm)
	{
		/* Find the amount of params we got */
		int nparam = sq_gettop(vm);
		SQUserPointer ptr = NULL;
		SQUserPointer real_instance = NULL;
		HSQOBJECT instance;

		/* Get the 'SQ' instance of this class */
		Squirrel::GetInstance(vm, &instance);

		/* Protect against calls to a non-static method in a static way */
		sq_pushroottable(vm);
		sq_pushstring(vm, OTTD2SQ(Tcls::GetClassName()), -1);
		sq_get(vm, -2);
		sq_pushobject(vm, instance);
		if (sq_instanceof(vm) != SQTrue) return sq_throwerror(vm, _SC("class method is non-static"));
		sq_pop(vm, 3);

		/* Get the 'real' instance of this class */
		sq_getinstanceup(vm, 1, &real_instance, 0);
		/* Get the real function pointer */
		sq_getuserdata(vm, nparam, &ptr, 0);
		if (real_instance == NULL) return sq_throwerror(vm, _SC("couldn't detect real instance of class for non-static call"));
		/* Remove the userdata from the stack */
		sq_pop(vm, 1);

		try {
			/* Delegate it to a template that can handle this specific function */
			return HelperT<Tmethod>::SQCall((Tcls *)real_instance, *(Tmethod *)ptr, vm);
		} catch (SQInteger e) {
			sq_pop(vm, nparam);
			return e;
		}
	}
Example #9
0
	template <> inline Array      *GetParam(ForceType<Array *>,      HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr)
	{
		SQObject obj;
		sq_getstackobj(vm, index, &obj);
		sq_pushobject(vm, obj);
		sq_pushnull(vm);

		SmallVector<int32, 2> data;

		while (SQ_SUCCEEDED(sq_next(vm, -2))) {
			SQInteger tmp;
			if (SQ_SUCCEEDED(sq_getinteger(vm, -1, &tmp))) {
				*data.Append() = (int32)tmp;
			} else {
				sq_pop(vm, 4);
				throw sq_throwerror(vm, _SC("a member of an array used as parameter to a function is not numeric"));
			}

			sq_pop(vm, 2);
		}
		sq_pop(vm, 2);

		Array *arr = (Array*)MallocT<byte>(sizeof(Array) + sizeof(int32) * data.Length());
		arr->size = data.Length();
		memcpy(arr->array, data.Begin(), sizeof(int32) * data.Length());

		*ptr->Append() = arr;
		return arr;
	}
Example #10
0
void
ThreadQueue::wakeup()
{
  // we traverse the list in reverse orders and use indices. This should be
  // robust for scripts that add new entries to the list while we're traversing
  // it
  size_t i = threads.size() - 1;
  size_t end = static_cast<size_t>(0 - 1);
  size_t size_begin = threads.size();
  while(i != end) {
    HSQOBJECT object = threads[i];

    sq_pushobject(global_vm, object);
    sq_getweakrefval(global_vm, -1);

    HSQUIRRELVM scheduled_vm;
    if(sq_gettype(global_vm, -1) == OT_THREAD &&
       SQ_SUCCEEDED(sq_getthread(global_vm, -1, &scheduled_vm))) {
      if(SQ_FAILED(sq_wakeupvm(scheduled_vm, SQFalse, SQFalse, SQTrue, SQFalse))) {
        log_warning << "Couldn't wakeup scheduled squirrel VM" << std::endl;
      }
    }

    sq_release(global_vm, &object);
    sq_pop(global_vm, 1);
    i--;
  }

  threads.erase(threads.begin(), threads.begin() + size_begin);
}
Example #11
0
BOOL SquirrelObject::SetDelegate(SquirrelObject &obj)
{
	if(obj.GetType() == OT_TABLE ||
		obj.GetType() == OT_NULL) {
			switch(_o._type) {
				case OT_USERDATA:
				case OT_TABLE:
					sq_pushobject(m_Vm.GetVMPtr(),_o);
					sq_pushobject(m_Vm.GetVMPtr(),obj._o);
					if(SQ_SUCCEEDED(sq_setdelegate(m_Vm.GetVMPtr(),-2)))
						return TRUE;
					break;
			}
		}
	return FALSE;
}
Example #12
0
	inline SQInteger DefSQAdvancedNonStaticCallback(HSQUIRRELVM vm)
	{
		/* Find the amount of params we got */
		int nparam = sq_gettop(vm);
		SQUserPointer ptr = NULL;
		SQUserPointer real_instance = NULL;
		HSQOBJECT instance;

		/* Get the 'SQ' instance of this class */
		Squirrel::GetInstance(vm, &instance);

		/* Protect against calls to a non-static method in a static way */
		sq_pushroottable(vm);
		sq_pushstring(vm, OTTD2SQ(Tcls::GetClassName()), -1);
		sq_get(vm, -2);
		sq_pushobject(vm, instance);
		if (sq_instanceof(vm) != SQTrue) return sq_throwerror(vm, _SC("class method is non-static"));
		sq_pop(vm, 3);

		/* Get the 'real' instance of this class */
		sq_getinstanceup(vm, 1, &real_instance, 0);
		/* Get the real function pointer */
		sq_getuserdata(vm, nparam, &ptr, 0);
		if (real_instance == NULL) return sq_throwerror(vm, _SC("couldn't detect real instance of class for non-static call"));
		/* Remove the userdata from the stack */
		sq_pop(vm, 1);

		/* Call the function, which its only param is always the VM */
		return (SQInteger)(((Tcls *)real_instance)->*(*(Tmethod *)ptr))(vm);
	}
Example #13
0
void
TimeScheduler::update(float time)
{
  while(!schedule.empty() && schedule.front().wakeup_time < time) {
    HSQOBJECT thread_ref = schedule.front().thread_ref;

    sq_pushobject(global_vm, thread_ref);
    sq_getweakrefval(global_vm, -1);

    HSQUIRRELVM scheduled_vm;
    if(sq_gettype(global_vm, -1) == OT_THREAD &&
       SQ_SUCCEEDED(sq_getthread(global_vm, -1, &scheduled_vm))) {
      if(SQ_FAILED(sq_wakeupvm(scheduled_vm, SQFalse, SQFalse, SQTrue, SQFalse))) {
        std::ostringstream msg;
        msg << "Error waking VM: ";
        sq_getlasterror(scheduled_vm);
        if(sq_gettype(scheduled_vm, -1) != OT_STRING) {
          msg << "(no info)";
        } else {
          const char* lasterr;
          sq_getstring(scheduled_vm, -1, &lasterr);
          msg << lasterr;
        }
        log_warning << msg.str() << std::endl;
        sq_pop(scheduled_vm, 1);
      }
    }

    sq_release(global_vm, &thread_ref);
    sq_pop(global_vm, 2);

    std::pop_heap(schedule.begin(), schedule.end());
    schedule.pop_back();
  }
}
Example #14
0
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);
		}
	}
}
Example #15
0
bool ScriptObject::setInstanceUp(SQUserPointer up)
{
	MCD_ASSERT(sq_isinstance(mObj));
	sq_pushobject(mSqvm, mObj);
	sq_setinstanceup(mSqvm, -1, up);
	sq_poptop(mSqvm);
	return true;
}
Example #16
0
SQUserPointer SquirrelObject::GetInstanceUP(unsigned int tag) //const
{
	SQUserPointer up = NULL;
	sq_pushobject(m_Vm.GetVMPtr(),_o);
	sq_getinstanceup(m_Vm.GetVMPtr(),-1,(SQUserPointer*)&up,(SQUserPointer)tag);
	sq_pop(m_Vm.GetVMPtr(),1);
	return up;
}
Example #17
0
BOOL SquirrelObject::SetInstanceUP(SQUserPointer up)
{
	if(!sq_isinstance(_o)) return FALSE;
	sq_pushobject(m_Vm.GetVMPtr(),_o);
	sq_setinstanceup(m_Vm.GetVMPtr(),-1,up);
	sq_pop(m_Vm.GetVMPtr(),1);
	return TRUE;
}
Example #18
0
//
// Transport.Position class
//
SQInteger TransportPositionPush(HSQUIRRELVM vm, TimePosition *obj)
{
    sq_pushobject(vm, TransportPositionObject);
    sq_createinstance(vm, -1);
    sq_remove(vm, -2);
    sq_setinstanceup(vm, -1, new TimePosition(*obj));
    sq_setreleasehook(vm, -1, &TransportPositionRelease);
}
void ScriptBehavior::Start()
{
    if( !m_initialize || !m_haveStart )
    {
        return;
    }

    int top = sq_gettop(m_vm);

    sq_pushobject(m_vm, m_instance);
    sq_pushobject(m_vm, m_startFunction);

    sq_push( m_vm,-2 );
    sq_call( m_vm,1,SQFalse,SQTrue );

    sq_settop( m_vm,top );
}
Example #20
0
SQUserPointer ScriptObject::getInstanceUp(SQUserPointer tag) const
{
	SQUserPointer up = 0;
	sq_pushobject(mSqvm, mObj);
	sq_getinstanceup(mSqvm, -1, (SQUserPointer*)&up, tag);
	sq_poptop(mSqvm);
	return up;
}
Example #21
0
BOOL SquirrelObject::BeginIteration()
{
	if(!sq_istable(_o) && !sq_isarray(_o) && !sq_isclass(_o))
		return FALSE;
	sq_pushobject(m_Vm.GetVMPtr(),_o);
	sq_pushnull(m_Vm.GetVMPtr());
	return TRUE;
}
Example #22
0
SQInteger register_member_func(HSQUIRRELVM& v,SQFUNCTION f,const char *fname,HSQOBJECT id)
{
	sq_pushobject(v,id);
	sq_pushstring(v,fname,-1);
	sq_newclosure(v,f,0);
	sq_newslot(v,-3,SQFalse);
	sq_pop(v,1);
}
SQInteger ScriptText::_SetParam(int parameter, HSQUIRRELVM vm)
{
	if (parameter >= SCRIPT_TEXT_MAX_PARAMETERS) return SQ_ERROR;

	free(this->params[parameter]);
	if (this->paramt[parameter] != NULL) this->paramt[parameter]->Release();

	this->parami[parameter] = 0;
	this->params[parameter] = NULL;
	this->paramt[parameter] = NULL;

	switch (sq_gettype(vm, -1)) {
		case OT_STRING: {
			const SQChar *value;
			sq_getstring(vm, -1, &value);

			this->params[parameter] = strdup(SQ2OTTD(value));
			break;
		}

		case OT_INTEGER: {
			SQInteger value;
			sq_getinteger(vm, -1, &value);

			this->parami[parameter] = value;
			break;
		}

		case OT_INSTANCE: {
			SQUserPointer real_instance = NULL;
			HSQOBJECT instance;

			sq_getstackobj(vm, -1, &instance);

			/* Validate if it is a GSText instance */
			sq_pushroottable(vm);
			sq_pushstring(vm, _SC("GSText"), -1);
			sq_get(vm, -2);
			sq_pushobject(vm, instance);
			if (sq_instanceof(vm) != SQTrue) return SQ_ERROR;
			sq_pop(vm, 3);

			/* Get the 'real' instance of this class */
			sq_getinstanceup(vm, -1, &real_instance, 0);
			if (real_instance == NULL) return SQ_ERROR;

			ScriptText *value = static_cast<ScriptText *>(real_instance);
			value->AddRef();
			this->paramt[parameter] = value;
			break;
		}

		default: return SQ_ERROR;
	}

	if (this->paramc <= parameter) this->paramc = parameter + 1;
	return 0;
}
Example #24
0
BOOL SquirrelVM::BeginCall(const SquirrelObject &func)
{
	if(_CallState != -1)
		return FALSE;
	_CallState = 1;
	sq_pushobject(_VM,func._o);
	sq_pushroottable(_VM);
	return TRUE;
}
Example #25
0
int SquirrelObject::Len() /*const*/
{
	int ret = 0;
	if(sq_isarray(_o) || sq_istable(_o) || sq_isstring(_o)) {
		sq_pushobject(m_Vm.GetVMPtr(),_o);
		ret = sq_getsize(m_Vm.GetVMPtr(),-1);
		sq_pop(m_Vm.GetVMPtr(),1);
	}
	return ret;
}
Example #26
0
BOOL SquirrelObject::GetSlot(int key) /*const*/
{
	sq_pushobject(m_Vm.GetVMPtr(),_o);
	sq_pushinteger(m_Vm.GetVMPtr(),key);
	if(SQ_SUCCEEDED(sq_get(m_Vm.GetVMPtr(),-2))) {
		return TRUE;
	}
	
	return FALSE;
}
Example #27
0
BOOL SquirrelObject::GetSlot(const SQChar *name) /*const*/
{
	sq_pushobject(m_Vm.GetVMPtr(),_o);
	sq_pushstring(m_Vm.GetVMPtr(),name,-1);
	if(SQ_SUCCEEDED(sq_get(m_Vm.GetVMPtr(),-2))) {
		return TRUE;
	}
	
	return FALSE;
}
Example #28
0
SquirrelObject SquirrelVM::RunScript(const SquirrelObject &o,SquirrelObject *_this)
{
	SquirrelObject ret(_VM);
	sq_pushobject(_VM,o._o);
	if(_this) {
		sq_pushobject(_VM,_this->_o);
	}
	else {
		sq_pushroottable(_VM);
	}
	if(SQ_SUCCEEDED(sq_call(_VM,1,1,1))) {
		ret.AttachToStackObject(-1);
		sq_pop(_VM,1);
		return ret;
	}
	sq_pop(_VM,1);
	throw SquirrelError(_VM);
	
}
Example #29
0
void loadVariablePath(HSQUIRRELVM vm, const std::vector<std::string>& path) {
	for (const std::string& i : path) {
		sq_pushstring(vm, i.c_str(), i.size());
		CSQ(sq_get(vm, -2));
	}

	HSQOBJECT h;
	CSQ(sq_getstackobj(vm, -1, &h));
	sq_pop(vm, path.size() - 1);
	sq_pushobject(vm, h);
}
Example #30
0
SquirrelObject SquirrelObject::GetDelegate()
{
	SquirrelObject ret;
	if(_o._type == OT_TABLE || _o._type == OT_USERDATA)
	{
		sq_pushobject(m_Vm.GetVMPtr(),_o);
		sq_getdelegate(m_Vm.GetVMPtr(),-1);
		ret.AttachToStackObject(-1);
		sq_pop(m_Vm.GetVMPtr(),2);
	}
	return ret;
}