File vm.hpp
File List > include > simplesquirrel > vm.hpp
Go to the documentation of this file.
#pragma once
#ifndef SSQ_VM_HEADER_H
#define SSQ_VM_HEADER_H
#include "exceptions.hpp"
#include "table.hpp"
#include "script.hpp"
#include "args.hpp"
#include "class.hpp"
#include "instance.hpp"
#include "function.hpp"
#include "array.hpp"
#include <memory>
#ifdef _MSC_VER
#pragma warning( push )
#pragma warning( disable: 4251 )
#endif
namespace ssq {
typedef void(*SqPrintFunc)(HSQUIRRELVM, const SQChar*, ...);
typedef void(*SqErrorFunc)(HSQUIRRELVM, const SQChar*, ...);
typedef SQInteger(*SqRuntimeErrorFunc)(HSQUIRRELVM);
typedef void(*SqCompileErrorFunc)(HSQUIRRELVM, const SQChar*, const SQChar*, SQInteger, SQInteger);
class Libs {
public:
typedef int Flag;
static const Flag NONE = 0x0000;
static const Flag IO = 0x0001;
static const Flag BLOB = 0x0002;
static const Flag MATH = 0x0004;
static const Flag SYSTEM = 0x0008;
static const Flag STRING = 0x0010;
static const Flag ALL = 0xFFFF;
};
class SSQ_API VM: public Table {
public:
VM(size_t stackSize, Libs::Flag flags = 0x00);
void destroy();
virtual ~VM();
void swap(VM& other) NOEXCEPT;
VM(const VM& other) = delete;
VM(VM&& other) NOEXCEPT;
void registerStdlib(Libs::Flag flags);
void setPrintFunc(SqPrintFunc printFunc, SqErrorFunc errorFunc);
void setRuntimeErrorFunc(SqRuntimeErrorFunc runtimeErrorFunc);
void setCompileErrorFunc(SqCompileErrorFunc compileErrorFunc);
SQInteger getTop() const;
const CompileException& getLastCompileException() const {
return *compileException.get();
}
const RuntimeException& getLastRuntimeException() const {
return *runtimeException.get();
}
Script compileSource(const char* source, const char* name = "buffer");
Script compileFile(const char* path);
void run(const Script& script) const;
template<class... Args>
Object callFunc(const Function& func, const Object& env, Args&&... args) const {
static const std::size_t params = sizeof...(Args);
if(func.getNumOfParams() != params){
throw RuntimeException("Number of arguments does not match");
}
auto top = sq_gettop(vm);
sq_pushobject(vm, func.getRaw());
sq_pushobject(vm, env.getRaw());
pushArgs(std::forward<Args>(args)...);
return callAndReturn(params, top);
}
template<class... Args>
Instance newInstance(const Class& cls, Args&&... args) const {
Instance inst = newInstanceNoCtor(cls);
Function ctor = cls.findFunc("constructor");
callFunc(ctor, inst, std::forward<Args>(args)...);
return inst;
}
Instance newInstanceNoCtor(const Class& cls) const {
Instance inst(vm);
sq_pushobject(vm, cls.getRaw());
sq_createinstance(vm, -1);
sq_remove(vm, -2);
sq_getstackobj(vm, -1, &inst.getRaw());
sq_addref(vm, &inst.getRaw());
sq_pop(vm, 1);
return inst;
}
Table newTable() const {
return Table(vm);
}
Array newArray() const {
return Array(vm);
}
template<class T>
Array newArray(const std::vector<T>& vector) const {
return Array(vm, vector);
}
Enum addEnum(const char* name);
template<typename T>
inline void setConst(const char* name, const T& value) {
sq_pushconsttable(vm);
sq_pushstring(vm, name, strlen(name));
detail::push<T>(vm, value);
sq_newslot(vm, -3, false);
sq_pop(vm,1); // pop table
}
void debugStack() const;
void addClassObj(size_t hashCode, const HSQOBJECT& obj);
const HSQOBJECT& getClassObj(size_t hashCode);
VM& operator = (const VM& other) = delete;
VM& operator = (VM&& other) NOEXCEPT;
private:
std::unique_ptr<CompileException> compileException;
std::unique_ptr<RuntimeException> runtimeException;
std::unordered_map<size_t, HSQOBJECT> classMap;
static void pushArgs();
template <class First, class... Rest>
void pushArgs(First&& first, Rest&&... rest) const {
detail::push(vm, first);
pushArgs(std::forward<Rest>(rest)...);
}
Object callAndReturn(SQUnsignedInteger nparams, SQInteger top) const;
static void defaultPrintFunc(HSQUIRRELVM vm, const SQChar *s, ...);
static void defaultErrorFunc(HSQUIRRELVM vm, const SQChar *s, ...);
static SQInteger defaultRuntimeErrorFunc(HSQUIRRELVM vm);
static void defaultCompilerErrorFunc(HSQUIRRELVM vm, const SQChar* desc, const SQChar* source, SQInteger line, SQInteger column);
};
}
#ifdef _MSC_VER
#pragma warning( pop )
#endif
#endif