// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details #pragma once #include "Luau/Bytecode.h" #include "Luau/CodeAllocator.h" #include "Luau/Label.h" #include #include #include "ldebug.h" #include "lobject.h" #include "ltm.h" #include "lstate.h" typedef int (*luau_FastFunction)(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams); namespace Luau { namespace CodeGen { class UnwindBuilder; struct NativeContext { // Gateway (C => native transition) entry & exit, compiled at runtime uint8_t* gateEntry = nullptr; uint8_t* gateExit = nullptr; // Helper functions, implemented in C int (*luaV_lessthan)(lua_State* L, const TValue* l, const TValue* r) = nullptr; int (*luaV_lessequal)(lua_State* L, const TValue* l, const TValue* r) = nullptr; int (*luaV_equalval)(lua_State* L, const TValue* t1, const TValue* t2) = nullptr; void (*luaV_doarith)(lua_State* L, StkId ra, const TValue* rb, const TValue* rc, TMS op) = nullptr; void (*luaV_dolen)(lua_State* L, StkId ra, const TValue* rb) = nullptr; void (*luaV_prepareFORN)(lua_State* L, StkId plimit, StkId pstep, StkId pinit) = nullptr; void (*luaV_gettable)(lua_State* L, const TValue* t, TValue* key, StkId val) = nullptr; void (*luaV_settable)(lua_State* L, const TValue* t, TValue* key, StkId val) = nullptr; void (*luaV_getimport)(lua_State* L, Table* env, TValue* k, StkId res, uint32_t id, bool propagatenil) = nullptr; void (*luaV_concat)(lua_State* L, int total, int last) = nullptr; int (*luaH_getn)(Table* t) = nullptr; Table* (*luaH_new)(lua_State* L, int narray, int lnhash) = nullptr; Table* (*luaH_clone)(lua_State* L, Table* tt) = nullptr; void (*luaH_resizearray)(lua_State* L, Table* t, int nasize) = nullptr; void (*luaC_barriertable)(lua_State* L, Table* t, GCObject* v) = nullptr; void (*luaC_barrierf)(lua_State* L, GCObject* o, GCObject* v) = nullptr; void (*luaC_barrierback)(lua_State* L, GCObject* o, GCObject** gclist) = nullptr; size_t (*luaC_step)(lua_State* L, bool assist) = nullptr; void (*luaF_close)(lua_State* L, StkId level) = nullptr; const TValue* (*luaT_gettm)(Table* events, TMS event, TString* ename) = nullptr; const TString* (*luaT_objtypenamestr)(lua_State* L, const TValue* o) = nullptr; double (*libm_exp)(double) = nullptr; double (*libm_pow)(double, double) = nullptr; double (*libm_fmod)(double, double) = nullptr; double (*libm_asin)(double) = nullptr; double (*libm_sin)(double) = nullptr; double (*libm_sinh)(double) = nullptr; double (*libm_acos)(double) = nullptr; double (*libm_cos)(double) = nullptr; double (*libm_cosh)(double) = nullptr; double (*libm_atan)(double) = nullptr; double (*libm_atan2)(double, double) = nullptr; double (*libm_tan)(double) = nullptr; double (*libm_tanh)(double) = nullptr; double (*libm_log)(double) = nullptr; double (*libm_log2)(double) = nullptr; double (*libm_log10)(double) = nullptr; double (*libm_ldexp)(double, int) = nullptr; double (*libm_round)(double) = nullptr; double (*libm_frexp)(double, int*) = nullptr; double (*libm_modf)(double, double*) = nullptr; // Helper functions bool (*forgLoopTableIter)(lua_State* L, Table* h, int index, TValue* ra) = nullptr; bool (*forgLoopNodeIter)(lua_State* L, Table* h, int index, TValue* ra) = nullptr; bool (*forgLoopNonTableFallback)(lua_State* L, int insnA, int aux) = nullptr; void (*forgPrepXnextFallback)(lua_State* L, TValue* ra, int pc) = nullptr; Closure* (*callProlog)(lua_State* L, TValue* ra, StkId argtop, int nresults) = nullptr; void (*callEpilogC)(lua_State* L, int nresults, int n) = nullptr; Closure* (*callFallback)(lua_State* L, StkId ra, StkId argtop, int nresults) = nullptr; // Opcode fallbacks, implemented in C const Instruction* (*executeGETGLOBAL)(lua_State* L, const Instruction* pc, StkId base, TValue* k) = nullptr; const Instruction* (*executeSETGLOBAL)(lua_State* L, const Instruction* pc, StkId base, TValue* k) = nullptr; const Instruction* (*executeGETTABLEKS)(lua_State* L, const Instruction* pc, StkId base, TValue* k) = nullptr; const Instruction* (*executeSETTABLEKS)(lua_State* L, const Instruction* pc, StkId base, TValue* k) = nullptr; const Instruction* (*executeNEWCLOSURE)(lua_State* L, const Instruction* pc, StkId base, TValue* k) = nullptr; const Instruction* (*executeNAMECALL)(lua_State* L, const Instruction* pc, StkId base, TValue* k) = nullptr; const Instruction* (*executeSETLIST)(lua_State* L, const Instruction* pc, StkId base, TValue* k) = nullptr; const Instruction* (*executeFORGPREP)(lua_State* L, const Instruction* pc, StkId base, TValue* k) = nullptr; const Instruction* (*executeGETVARARGS)(lua_State* L, const Instruction* pc, StkId base, TValue* k) = nullptr; const Instruction* (*executeDUPCLOSURE)(lua_State* L, const Instruction* pc, StkId base, TValue* k) = nullptr; const Instruction* (*executePREPVARARGS)(lua_State* L, const Instruction* pc, StkId base, TValue* k) = nullptr; // Fast call methods, implemented in C luau_FastFunction luauF_table[256] = {}; }; using GateFn = int (*)(lua_State*, Proto*, uintptr_t, NativeContext*); struct NativeState { NativeState(); ~NativeState(); CodeAllocator codeAllocator; std::unique_ptr unwindBuilder; uint8_t* gateData = nullptr; size_t gateDataSize = 0; NativeContext context; }; void initFunctions(NativeState& data); } // namespace CodeGen } // namespace Luau