blob: c4e0f5cbc2e25ae6457d0ebcda4d2d202c71f6b4 [file] [log] [blame]
#ifdef WITH_RIVE_SCRIPTING
#ifndef _RIVE_SCRIPTING_VM_HPP_
#define _RIVE_SCRIPTING_VM_HPP_
#include "rive/refcnt.hpp"
#include "rive/span.hpp"
#include <memory>
struct lua_State;
namespace rive
{
class ModuleDetails;
class ScriptingContext;
class ScriptingVM : public RefCnt<ScriptingVM>
{
public:
// Creates a ScriptingVM that owns both the lua_State and the context.
explicit ScriptingVM(std::unique_ptr<ScriptingContext> context);
~ScriptingVM();
ScriptingContext* context() { return m_ownedContext.get(); }
lua_State* state() const { return m_state; }
// Replaces the owned context with a new one. The old context is deleted
// and the new context is owned by this VM. Also updates lua thread data.
void replaceContext(std::unique_ptr<ScriptingContext> newContext);
static void init(lua_State* state, ScriptingContext* context);
// Add a module to be registered later via performRegistration()
void addModule(ModuleDetails* moduleDetails);
// Perform registration of all added modules, handling dependencies and
// retries
void performRegistration();
static bool registerModule(lua_State* state,
const char* name,
Span<uint8_t> bytecode);
static void unregisterModule(lua_State* state, const char* name);
bool registerModule(const char* name, Span<uint8_t> bytecode);
void unregisterModule(const char* name);
static bool registerScript(lua_State* state,
const char* name,
Span<uint8_t> bytecode);
bool registerScript(const char* name, Span<uint8_t> bytecode);
// Loads bytecode into the VM, creating a sandboxed thread and
// deserializing the bytecode into an unexecuted closure. Pushes the
// module thread onto the stack. Returns true on success.
static bool loadModule(lua_State* state,
const char* name,
Span<uint8_t> bytecode);
// Executes a previously loaded module thread (on top of stack from
// loadModule). Runs lua_resume, validates the result, and for utility
// modules registers into the require cache. On success, the module
// result (table/function) replaces the thread on the stack.
// Returns true on success.
static bool executeModule(lua_State* state,
const char* name,
bool isUtility);
static void dumpStack(lua_State* state);
private:
lua_State* m_state;
std::unique_ptr<ScriptingContext> m_ownedContext;
};
} // namespace rive
#endif
#endif