You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
708 lines
25 KiB
708 lines
25 KiB
Lua Types in LLVM
|
|
=================
|
|
|
|
We need to map Lua types to equivalent type definitions in LLVM. In Ravi we do hold all the type definitions in a struct as shown below::
|
|
|
|
struct LuaLLVMTypes {
|
|
|
|
llvm::Type *C_intptr_t;
|
|
llvm::Type *C_size_t;
|
|
llvm::Type *C_ptrdiff_t;
|
|
|
|
llvm::Type *lua_NumberT;
|
|
llvm::Type *lua_IntegerT;
|
|
llvm::Type *lua_UnsignedT;
|
|
llvm::Type *lua_KContextT;
|
|
|
|
llvm::FunctionType *lua_CFunctionT;
|
|
llvm::PointerType *plua_CFunctionT;
|
|
|
|
llvm::FunctionType *lua_KFunctionT;
|
|
llvm::PointerType *plua_KFunctionT;
|
|
|
|
llvm::FunctionType *lua_HookT;
|
|
llvm::PointerType *plua_HookT;
|
|
|
|
llvm::FunctionType *lua_AllocT;
|
|
llvm::PointerType *plua_AllocT;
|
|
|
|
llvm::Type *l_memT;
|
|
llvm::Type *lu_memT;
|
|
|
|
llvm::Type *lu_byteT;
|
|
llvm::Type *L_UmaxalignT;
|
|
llvm::Type *C_pcharT;
|
|
|
|
llvm::Type *C_intT;
|
|
|
|
llvm::StructType *lua_StateT;
|
|
llvm::PointerType *plua_StateT;
|
|
|
|
llvm::StructType *global_StateT;
|
|
llvm::PointerType *pglobal_StateT;
|
|
|
|
llvm::StructType *ravi_StateT;
|
|
llvm::PointerType *pravi_StateT;
|
|
|
|
llvm::StructType *GCObjectT;
|
|
llvm::PointerType *pGCObjectT;
|
|
|
|
llvm::StructType *ValueT;
|
|
llvm::StructType *TValueT;
|
|
llvm::PointerType *pTValueT;
|
|
|
|
llvm::StructType *TStringT;
|
|
llvm::PointerType *pTStringT;
|
|
llvm::PointerType *ppTStringT;
|
|
|
|
llvm::StructType *UdataT;
|
|
llvm::StructType *TableT;
|
|
llvm::PointerType *pTableT;
|
|
|
|
llvm::StructType *UpvaldescT;
|
|
llvm::PointerType *pUpvaldescT;
|
|
|
|
llvm::Type *ravitype_tT;
|
|
llvm::StructType *LocVarT;
|
|
llvm::PointerType *pLocVarT;
|
|
|
|
llvm::Type *InstructionT;
|
|
llvm::PointerType *pInstructionT;
|
|
llvm::StructType *LClosureT;
|
|
llvm::PointerType *pLClosureT;
|
|
llvm::PointerType *ppLClosureT;
|
|
llvm::PointerType *pppLClosureT;
|
|
|
|
llvm::StructType *RaviJITProtoT;
|
|
llvm::PointerType *pRaviJITProtoT;
|
|
|
|
llvm::StructType *ProtoT;
|
|
llvm::PointerType *pProtoT;
|
|
llvm::PointerType *ppProtoT;
|
|
|
|
llvm::StructType *UpValT;
|
|
llvm::PointerType *pUpValT;
|
|
|
|
llvm::StructType *CClosureT;
|
|
llvm::PointerType *pCClosureT;
|
|
|
|
llvm::StructType *TKeyT;
|
|
llvm::PointerType *pTKeyT;
|
|
|
|
llvm::StructType *NodeT;
|
|
llvm::PointerType *pNodeT;
|
|
|
|
llvm::StructType *lua_DebugT;
|
|
llvm::PointerType *plua_DebugT;
|
|
|
|
llvm::StructType *lua_longjumpT;
|
|
llvm::PointerType *plua_longjumpT;
|
|
|
|
llvm::StructType *MbufferT;
|
|
llvm::StructType *stringtableT;
|
|
|
|
llvm::PointerType *StkIdT;
|
|
|
|
llvm::StructType *CallInfoT;
|
|
llvm::StructType *CallInfo_cT;
|
|
llvm::StructType *CallInfo_lT;
|
|
llvm::PointerType *pCallInfoT;
|
|
|
|
llvm::FunctionType *jitFunctionT;
|
|
|
|
llvm::FunctionType *luaD_poscallT;
|
|
|
|
};
|
|
|
|
The actual definition of the types above is shown below::
|
|
|
|
static_assert(std::is_floating_point<lua_Number>::value &&
|
|
sizeof(lua_Number) == sizeof(double),
|
|
"lua_Number is not a double");
|
|
lua_NumberT = llvm::Type::getDoubleTy(context);
|
|
|
|
static_assert(std::is_integral<lua_Integer>::value,
|
|
"lua_Integer is not an integer type");
|
|
lua_IntegerT = llvm::Type::getIntNTy(context, sizeof(lua_Integer) * 8);
|
|
|
|
static_assert(sizeof(lua_Integer) == sizeof(lua_Unsigned),
|
|
"lua_Integer and lua_Unsigned are of different size");
|
|
lua_UnsignedT = lua_IntegerT;
|
|
|
|
C_intptr_t = llvm::Type::getIntNTy(context, sizeof(intptr_t) * 8);
|
|
C_size_t = llvm::Type::getIntNTy(context, sizeof(size_t) * 8);
|
|
C_ptrdiff_t = llvm::Type::getIntNTy(context, sizeof(ptrdiff_t) * 8);
|
|
C_intT = llvm::Type::getIntNTy(context, sizeof(int) * 8);
|
|
|
|
static_assert(sizeof(size_t) == sizeof(lu_mem),
|
|
"lu_mem size is not same as size_t");
|
|
lu_memT = C_size_t;
|
|
|
|
static_assert(sizeof(ptrdiff_t) == sizeof(l_mem),
|
|
"l_mem size is not same as ptrdiff_t");
|
|
l_memT = C_ptrdiff_t;
|
|
|
|
static_assert(sizeof(L_Umaxalign) == sizeof(double),
|
|
"L_Umaxalign is not same size as double");
|
|
L_UmaxalignT = llvm::Type::getDoubleTy(context);
|
|
|
|
lu_byteT = llvm::Type::getInt8Ty(context);
|
|
C_pcharT = llvm::Type::getInt8PtrTy(context);
|
|
|
|
InstructionT = C_intT;
|
|
pInstructionT = llvm::PointerType::get(InstructionT, 0);
|
|
|
|
lua_StateT = llvm::StructType::create(context, "ravi.lua_State");
|
|
plua_StateT = llvm::PointerType::get(lua_StateT, 0);
|
|
|
|
lua_KContextT = C_ptrdiff_t;
|
|
|
|
std::vector<llvm::Type *> elements;
|
|
elements.push_back(plua_StateT);
|
|
lua_CFunctionT = llvm::FunctionType::get(C_intT, elements, false);
|
|
plua_CFunctionT = llvm::PointerType::get(lua_CFunctionT, 0);
|
|
|
|
jitFunctionT = lua_CFunctionT;
|
|
|
|
elements.clear();
|
|
elements.push_back(plua_StateT);
|
|
elements.push_back(C_intT);
|
|
elements.push_back(lua_KContextT);
|
|
lua_KFunctionT = llvm::FunctionType::get(C_intT, elements, false);
|
|
plua_KFunctionT = llvm::PointerType::get(lua_KFunctionT, 0);
|
|
|
|
elements.clear();
|
|
elements.push_back(llvm::Type::getInt8PtrTy(context));
|
|
elements.push_back(llvm::Type::getInt8PtrTy(context));
|
|
elements.push_back(C_size_t);
|
|
elements.push_back(C_size_t);
|
|
lua_AllocT = llvm::FunctionType::get(llvm::Type::getInt8PtrTy(context),
|
|
elements, false);
|
|
plua_AllocT = llvm::PointerType::get(lua_AllocT, 0);
|
|
|
|
lua_DebugT = llvm::StructType::create(context, "ravi.lua_Debug");
|
|
plua_DebugT = llvm::PointerType::get(lua_DebugT, 0);
|
|
|
|
elements.clear();
|
|
elements.push_back(plua_StateT);
|
|
elements.push_back(plua_DebugT);
|
|
lua_HookT = llvm::FunctionType::get(llvm::Type::getInt8PtrTy(context),
|
|
elements, false);
|
|
plua_HookT = llvm::PointerType::get(lua_HookT, 0);
|
|
|
|
// struct GCObject {
|
|
// GCObject *next;
|
|
// lu_byte tt;
|
|
// lu_byte marked
|
|
// };
|
|
GCObjectT = llvm::StructType::create(context, "ravi.GCObject");
|
|
pGCObjectT = llvm::PointerType::get(GCObjectT, 0);
|
|
elements.clear();
|
|
elements.push_back(pGCObjectT);
|
|
elements.push_back(lu_byteT);
|
|
elements.push_back(lu_byteT);
|
|
GCObjectT->setBody(elements);
|
|
|
|
static_assert(sizeof(Value) == sizeof(lua_Number),
|
|
"Value type is larger than lua_Number");
|
|
// In LLVM unions should be set to the largest member
|
|
// So in the case of a Value this is the double type
|
|
// union Value {
|
|
// GCObject *gc; /* collectable objects */
|
|
// void *p; /* light userdata */
|
|
// int b; /* booleans */
|
|
// lua_CFunction f; /* light C functions */
|
|
// lua_Integer i; /* integer numbers */
|
|
// lua_Number n; /* float numbers */
|
|
// };
|
|
ValueT = llvm::StructType::create(context, "ravi.Value");
|
|
elements.clear();
|
|
elements.push_back(lua_NumberT);
|
|
ValueT->setBody(elements);
|
|
|
|
// struct TValue {
|
|
// union Value value_;
|
|
// int tt_;
|
|
// };
|
|
TValueT = llvm::StructType::create(context, "ravi.TValue");
|
|
elements.clear();
|
|
elements.push_back(ValueT);
|
|
elements.push_back(C_intT);
|
|
TValueT->setBody(elements);
|
|
pTValueT = llvm::PointerType::get(TValueT, 0);
|
|
|
|
StkIdT = pTValueT;
|
|
|
|
///*
|
|
//** Header for string value; string bytes follow the end of this structure
|
|
//** (aligned according to 'UTString'; see next).
|
|
//*/
|
|
// typedef struct TString {
|
|
// GCObject *next;
|
|
// lu_byte tt;
|
|
// lu_byte marked
|
|
// lu_byte extra; /* reserved words for short strings; "has hash" for longs
|
|
// */
|
|
// unsigned int hash;
|
|
// size_t len; /* number of characters in string */
|
|
// struct TString *hnext; /* linked list for hash table */
|
|
// } TString;
|
|
|
|
///*
|
|
//** Ensures that address after this type is always fully aligned.
|
|
//*/
|
|
// typedef union UTString {
|
|
// L_Umaxalign dummy; /* ensures maximum alignment for strings */
|
|
// TString tsv;
|
|
//} UTString;
|
|
TStringT = llvm::StructType::create(context, "ravi.TString");
|
|
pTStringT = llvm::PointerType::get(TStringT, 0);
|
|
ppTStringT = llvm::PointerType::get(pTStringT, 0);
|
|
elements.clear();
|
|
elements.push_back(pGCObjectT);
|
|
elements.push_back(lu_byteT);
|
|
elements.push_back(lu_byteT);
|
|
elements.push_back(lu_byteT); /* extra */
|
|
elements.push_back(C_intT); /* hash */
|
|
elements.push_back(C_size_t); /* len */
|
|
elements.push_back(pTStringT); /* hnext */
|
|
TStringT->setBody(elements);
|
|
|
|
// Table
|
|
TableT = llvm::StructType::create(context, "ravi.Table");
|
|
pTableT = llvm::PointerType::get(TableT, 0);
|
|
|
|
///*
|
|
//** Header for userdata; memory area follows the end of this structure
|
|
//** (aligned according to 'UUdata'; see next).
|
|
//*/
|
|
// typedef struct Udata {
|
|
// GCObject *next;
|
|
// lu_byte tt;
|
|
// lu_byte marked
|
|
// lu_byte ttuv_; /* user value's tag */
|
|
// struct Table *metatable;
|
|
// size_t len; /* number of bytes */
|
|
// union Value user_; /* user value */
|
|
//} Udata;
|
|
UdataT = llvm::StructType::create(context, "ravi.Udata");
|
|
elements.clear();
|
|
elements.push_back(pGCObjectT);
|
|
elements.push_back(lu_byteT);
|
|
elements.push_back(lu_byteT);
|
|
elements.push_back(lu_byteT); /* ttuv_ */
|
|
elements.push_back(pTableT); /* metatable */
|
|
elements.push_back(C_size_t); /* len */
|
|
elements.push_back(ValueT); /* user_ */
|
|
UdataT->setBody(elements);
|
|
|
|
///*
|
|
//** Description of an upvalue for function prototypes
|
|
//*/
|
|
// typedef struct Upvaldesc {
|
|
// TString *name; /* upvalue name (for debug information) */
|
|
// lu_byte instack; /* whether it is in stack */
|
|
// lu_byte idx; /* index of upvalue (in stack or in outer function's list)
|
|
// */
|
|
//}Upvaldesc;
|
|
UpvaldescT = llvm::StructType::create(context, "ravi.Upvaldesc");
|
|
elements.clear();
|
|
elements.push_back(pTStringT);
|
|
elements.push_back(lu_byteT);
|
|
elements.push_back(lu_byteT);
|
|
UpvaldescT->setBody(elements);
|
|
pUpvaldescT = llvm::PointerType::get(UpvaldescT, 0);
|
|
|
|
///*
|
|
//** Description of a local variable for function prototypes
|
|
//** (used for debug information)
|
|
//*/
|
|
// typedef struct LocVar {
|
|
// TString *varname;
|
|
// int startpc; /* first point where variable is active */
|
|
// int endpc; /* first point where variable is dead */
|
|
// ravitype_t ravi_type; /* RAVI type of the variable - RAVI_TANY if unknown
|
|
// */
|
|
//} LocVar;
|
|
ravitype_tT = llvm::Type::getIntNTy(context, sizeof(ravitype_t) * 8);
|
|
LocVarT = llvm::StructType::create(context, "ravi.LocVar");
|
|
elements.clear();
|
|
elements.push_back(pTStringT); /* varname */
|
|
elements.push_back(C_intT); /* startpc */
|
|
elements.push_back(C_intT); /* endpc */
|
|
elements.push_back(ravitype_tT); /* ravi_type */
|
|
LocVarT->setBody(elements);
|
|
pLocVarT = llvm::PointerType::get(LocVarT, 0);
|
|
|
|
LClosureT = llvm::StructType::create(context, "ravi.LClosure");
|
|
pLClosureT = llvm::PointerType::get(LClosureT, 0);
|
|
ppLClosureT = llvm::PointerType::get(pLClosureT, 0);
|
|
pppLClosureT = llvm::PointerType::get(ppLClosureT, 0);
|
|
|
|
RaviJITProtoT = llvm::StructType::create(context, "ravi.RaviJITProto");
|
|
pRaviJITProtoT = llvm::PointerType::get(RaviJITProtoT, 0);
|
|
|
|
///*
|
|
//** Function Prototypes
|
|
//*/
|
|
// typedef struct Proto {
|
|
// CommonHeader;
|
|
// lu_byte numparams; /* number of fixed parameters */
|
|
// lu_byte is_vararg;
|
|
// lu_byte maxstacksize; /* maximum stack used by this function */
|
|
// int sizeupvalues; /* size of 'upvalues' */
|
|
// int sizek; /* size of 'k' */
|
|
// int sizecode;
|
|
// int sizelineinfo;
|
|
// int sizep; /* size of 'p' */
|
|
// int sizelocvars;
|
|
// int linedefined;
|
|
// int lastlinedefined;
|
|
// TValue *k; /* constants used by the function */
|
|
// Instruction *code;
|
|
// struct Proto **p; /* functions defined inside the function */
|
|
// int *lineinfo; /* map from opcodes to source lines (debug information) */
|
|
// LocVar *locvars; /* information about local variables (debug information)
|
|
// */
|
|
// Upvaldesc *upvalues; /* upvalue information */
|
|
// struct LClosure *cache; /* last created closure with this prototype */
|
|
// TString *source; /* used for debug information */
|
|
// GCObject *gclist;
|
|
// /* RAVI */
|
|
// RaviJITProto *ravi_jit;
|
|
//} Proto;
|
|
|
|
ProtoT = llvm::StructType::create(context, "ravi.Proto");
|
|
pProtoT = llvm::PointerType::get(ProtoT, 0);
|
|
ppProtoT = llvm::PointerType::get(pProtoT, 0);
|
|
elements.clear();
|
|
elements.push_back(pGCObjectT);
|
|
elements.push_back(lu_byteT);
|
|
elements.push_back(lu_byteT);
|
|
elements.push_back(lu_byteT); /* numparams */
|
|
elements.push_back(lu_byteT); /* is_vararg */
|
|
elements.push_back(lu_byteT); /* maxstacksize */
|
|
elements.push_back(C_intT); /* sizeupvalues */
|
|
elements.push_back(C_intT); /* sizek */
|
|
elements.push_back(C_intT); /* sizecode */
|
|
elements.push_back(C_intT); /* sizelineinfo */
|
|
elements.push_back(C_intT); /* sizep */
|
|
elements.push_back(C_intT); /* sizelocvars */
|
|
elements.push_back(C_intT); /* linedefined */
|
|
elements.push_back(C_intT); /* lastlinedefined */
|
|
elements.push_back(pTValueT); /* k */
|
|
elements.push_back(pInstructionT); /* code */
|
|
elements.push_back(ppProtoT); /* p */
|
|
elements.push_back(llvm::PointerType::get(C_intT, 0)); /* lineinfo */
|
|
elements.push_back(pLocVarT); /* locvars */
|
|
elements.push_back(pUpvaldescT); /* upvalues */
|
|
elements.push_back(pLClosureT); /* cache */
|
|
elements.push_back(pTStringT); /* source */
|
|
elements.push_back(pGCObjectT); /* gclist */
|
|
elements.push_back(pRaviJITProtoT); /* ravi_jit */
|
|
ProtoT->setBody(elements);
|
|
|
|
///*
|
|
//** Lua Upvalues
|
|
//*/
|
|
// typedef struct UpVal UpVal;
|
|
UpValT = llvm::StructType::create(context, "ravi.UpVal");
|
|
pUpValT = llvm::PointerType::get(UpValT, 0);
|
|
|
|
///*
|
|
//** Closures
|
|
//*/
|
|
|
|
//#define ClosureHeader \
|
|
//CommonHeader; lu_byte nupvalues; GCObject *gclist
|
|
|
|
// typedef struct CClosure {
|
|
// ClosureHeader;
|
|
// lua_CFunction f;
|
|
// TValue upvalue[1]; /* list of upvalues */
|
|
//} CClosure;
|
|
|
|
CClosureT = llvm::StructType::create(context, "ravi.CClosure");
|
|
elements.clear();
|
|
elements.push_back(pGCObjectT);
|
|
elements.push_back(lu_byteT);
|
|
elements.push_back(lu_byteT);
|
|
elements.push_back(lu_byteT); /* nupvalues */
|
|
elements.push_back(pGCObjectT); /* gclist */
|
|
elements.push_back(plua_CFunctionT); /* f */
|
|
elements.push_back(llvm::ArrayType::get(TValueT, 1));
|
|
CClosureT->setBody(elements);
|
|
pCClosureT = llvm::PointerType::get(CClosureT, 0);
|
|
|
|
// typedef struct LClosure {
|
|
// ClosureHeader;
|
|
// struct Proto *p;
|
|
// UpVal *upvals[1]; /* list of upvalues */
|
|
//} LClosure;
|
|
elements.clear();
|
|
elements.push_back(pGCObjectT);
|
|
elements.push_back(lu_byteT);
|
|
elements.push_back(lu_byteT);
|
|
elements.push_back(lu_byteT); /* nupvalues */
|
|
elements.push_back(pGCObjectT); /* gclist */
|
|
elements.push_back(pProtoT); /* p */
|
|
elements.push_back(llvm::ArrayType::get(pUpValT, 1));
|
|
LClosureT->setBody(elements);
|
|
|
|
///*
|
|
//** Tables
|
|
//*/
|
|
|
|
// typedef union TKey {
|
|
// struct {
|
|
// TValuefields;
|
|
// int next; /* for chaining (offset for next node) */
|
|
// } nk;
|
|
// TValue tvk;
|
|
//} TKey;
|
|
TKeyT = llvm::StructType::create(context, "ravi.TKey");
|
|
elements.clear();
|
|
elements.push_back(ValueT);
|
|
elements.push_back(C_intT);
|
|
elements.push_back(C_intT); /* next */
|
|
TKeyT->setBody(elements);
|
|
pTKeyT = llvm::PointerType::get(TKeyT, 0);
|
|
|
|
// typedef struct Node {
|
|
// TValue i_val;
|
|
// TKey i_key;
|
|
//} Node;
|
|
NodeT = llvm::StructType::create(context, "ravi.Node");
|
|
elements.clear();
|
|
elements.push_back(TValueT); /* i_val */
|
|
elements.push_back(TKeyT); /* i_key */
|
|
NodeT->setBody(elements);
|
|
pNodeT = llvm::PointerType::get(NodeT, 0);
|
|
|
|
// typedef struct Table {
|
|
// CommonHeader;
|
|
// lu_byte flags; /* 1<<p means tagmethod(p) is not present */
|
|
// lu_byte lsizenode; /* log2 of size of 'node' array */
|
|
// unsigned int sizearray; /* size of 'array' array */
|
|
// TValue *array; /* array part */
|
|
// Node *node;
|
|
// Node *lastfree; /* any free position is before this position */
|
|
// struct Table *metatable;
|
|
// GCObject *gclist;
|
|
// ravitype_t ravi_array_type; /* RAVI specialization */
|
|
// unsigned int ravi_array_len; /* RAVI len specialization */
|
|
//} Table;
|
|
elements.clear();
|
|
elements.push_back(pGCObjectT);
|
|
elements.push_back(lu_byteT);
|
|
elements.push_back(lu_byteT);
|
|
elements.push_back(lu_byteT); /* flags */
|
|
elements.push_back(lu_byteT); /* lsizenode */
|
|
elements.push_back(C_intT); /* sizearray */
|
|
elements.push_back(pTValueT); /* array part */
|
|
elements.push_back(pNodeT); /* node */
|
|
elements.push_back(pNodeT); /* lastfree */
|
|
elements.push_back(pTableT); /* metatable */
|
|
elements.push_back(pGCObjectT); /* gclist */
|
|
elements.push_back(ravitype_tT); /* ravi_array_type */
|
|
elements.push_back(C_intT); /* ravi_array_len */
|
|
TableT->setBody(elements);
|
|
|
|
// struct lua_longjmp; /* defined in ldo.c */
|
|
lua_longjumpT = llvm::StructType::create(context, "ravi.lua_longjmp");
|
|
plua_longjumpT = llvm::PointerType::get(lua_longjumpT, 0);
|
|
|
|
// lzio.h
|
|
// typedef struct Mbuffer {
|
|
// char *buffer;
|
|
// size_t n;
|
|
// size_t buffsize;
|
|
//} Mbuffer;
|
|
MbufferT = llvm::StructType::create(context, "ravi.Mbuffer");
|
|
elements.clear();
|
|
elements.push_back(llvm::Type::getInt8PtrTy(context)); /* buffer */
|
|
elements.push_back(C_size_t); /* n */
|
|
elements.push_back(C_size_t); /* buffsize */
|
|
MbufferT->setBody(elements);
|
|
|
|
// typedef struct stringtable {
|
|
// TString **hash;
|
|
// int nuse; /* number of elements */
|
|
// int size;
|
|
//} stringtable;
|
|
stringtableT = llvm::StructType::create(context, "ravi.stringtable");
|
|
elements.clear();
|
|
elements.push_back(ppTStringT); /* hash */
|
|
elements.push_back(C_intT); /* nuse */
|
|
elements.push_back(C_intT); /* size */
|
|
stringtableT->setBody(elements);
|
|
|
|
///*
|
|
//** Information about a call.
|
|
//** When a thread yields, 'func' is adjusted to pretend that the
|
|
//** top function has only the yielded values in its stack; in that
|
|
//** case, the actual 'func' value is saved in field 'extra'.
|
|
//** When a function calls another with a continuation, 'extra' keeps
|
|
//** the function index so that, in case of errors, the continuation
|
|
//** function can be called with the correct top.
|
|
//*/
|
|
// typedef struct CallInfo {
|
|
// StkId func; /* function index in the stack */
|
|
// StkId top; /* top for this function */
|
|
// struct CallInfo *previous, *next; /* dynamic call link */
|
|
// union {
|
|
// struct { /* only for Lua functions */
|
|
// StkId base; /* base for this function */
|
|
// const Instruction *savedpc;
|
|
// } l;
|
|
// struct { /* only for C functions */
|
|
// lua_KFunction k; /* continuation in case of yields */
|
|
// ptrdiff_t old_errfunc;
|
|
// lua_KContext ctx; /* context info. in case of yields */
|
|
// } c;
|
|
// } u;
|
|
// ptrdiff_t extra;
|
|
// short nresults; /* expected number of results from this function */
|
|
// lu_byte callstatus;
|
|
//} CallInfo;
|
|
|
|
elements.clear();
|
|
elements.push_back(StkIdT); /* base */
|
|
elements.push_back(pInstructionT); /* savedpc */
|
|
elements.push_back(
|
|
C_ptrdiff_t); /* dummy to make this same size as the other member */
|
|
CallInfo_lT = llvm::StructType::create(elements);
|
|
|
|
elements.clear();
|
|
elements.push_back(plua_KFunctionT); /* k */
|
|
elements.push_back(C_ptrdiff_t); /* old_errfunc */
|
|
elements.push_back(lua_KContextT); /* ctx */
|
|
CallInfo_cT = llvm::StructType::create(elements);
|
|
|
|
CallInfoT = llvm::StructType::create(context, "ravi.CallInfo");
|
|
pCallInfoT = llvm::PointerType::get(CallInfoT, 0);
|
|
elements.clear();
|
|
elements.push_back(StkIdT); /* func */
|
|
elements.push_back(StkIdT); /* top */
|
|
elements.push_back(pCallInfoT); /* previous */
|
|
elements.push_back(pCallInfoT); /* next */
|
|
elements.push_back(
|
|
CallInfo_lT); /* u.l - as we will typically access the lua call details
|
|
*/
|
|
elements.push_back(C_ptrdiff_t); /* extra */
|
|
elements.push_back(llvm::Type::getInt16Ty(context)); /* nresults */
|
|
elements.push_back(lu_byteT); /* callstatus */
|
|
CallInfoT->setBody(elements);
|
|
|
|
// typedef struct ravi_State ravi_State;
|
|
|
|
ravi_StateT = llvm::StructType::create(context, "ravi.ravi_State");
|
|
pravi_StateT = llvm::PointerType::get(ravi_StateT, 0);
|
|
|
|
///*
|
|
//** 'global state', shared by all threads of this state
|
|
//*/
|
|
// typedef struct global_State {
|
|
// lua_Alloc frealloc; /* function to reallocate memory */
|
|
// void *ud; /* auxiliary data to 'frealloc' */
|
|
// lu_mem totalbytes; /* number of bytes currently allocated - GCdebt */
|
|
// l_mem GCdebt; /* bytes allocated not yet compensated by the collector */
|
|
// lu_mem GCmemtrav; /* memory traversed by the GC */
|
|
// lu_mem GCestimate; /* an estimate of the non-garbage memory in use */
|
|
// stringtable strt; /* hash table for strings */
|
|
// TValue l_registry;
|
|
// unsigned int seed; /* randomized seed for hashes */
|
|
// lu_byte currentwhite;
|
|
// lu_byte gcstate; /* state of garbage collector */
|
|
// lu_byte gckind; /* kind of GC running */
|
|
// lu_byte gcrunning; /* true if GC is running */
|
|
// GCObject *allgc; /* list of all collectable objects */
|
|
// GCObject **sweepgc; /* current position of sweep in list */
|
|
// GCObject *finobj; /* list of collectable objects with finalizers */
|
|
// GCObject *gray; /* list of gray objects */
|
|
// GCObject *grayagain; /* list of objects to be traversed atomically */
|
|
// GCObject *weak; /* list of tables with weak values */
|
|
// GCObject *ephemeron; /* list of ephemeron tables (weak keys) */
|
|
// GCObject *allweak; /* list of all-weak tables */
|
|
// GCObject *tobefnz; /* list of userdata to be GC */
|
|
// GCObject *fixedgc; /* list of objects not to be collected */
|
|
// struct lua_State *twups; /* list of threads with open upvalues */
|
|
// Mbuffer buff; /* temporary buffer for string concatenation */
|
|
// unsigned int gcfinnum; /* number of finalizers to call in each GC step */
|
|
// int gcpause; /* size of pause between successive GCs */
|
|
// int gcstepmul; /* GC 'granularity' */
|
|
// lua_CFunction panic; /* to be called in unprotected errors */
|
|
// struct lua_State *mainthread;
|
|
// const lua_Number *version; /* pointer to version number */
|
|
// TString *memerrmsg; /* memory-error message */
|
|
// TString *tmname[TM_N]; /* array with tag-method names */
|
|
// struct Table *mt[LUA_NUMTAGS]; /* metatables for basic types */
|
|
// /* RAVI */
|
|
// ravi_State *ravi_state;
|
|
//} global_State;
|
|
|
|
global_StateT = llvm::StructType::create(context, "ravi.global_State");
|
|
pglobal_StateT = llvm::PointerType::get(global_StateT, 0);
|
|
|
|
///*
|
|
//** 'per thread' state
|
|
//*/
|
|
// struct lua_State {
|
|
// CommonHeader;
|
|
// lu_byte status;
|
|
// StkId top; /* first free slot in the stack */
|
|
// global_State *l_G;
|
|
// CallInfo *ci; /* call info for current function */
|
|
// const Instruction *oldpc; /* last pc traced */
|
|
// StkId stack_last; /* last free slot in the stack */
|
|
// StkId stack; /* stack base */
|
|
// UpVal *openupval; /* list of open upvalues in this stack */
|
|
// GCObject *gclist;
|
|
// struct lua_State *twups; /* list of threads with open upvalues */
|
|
// struct lua_longjmp *errorJmp; /* current error recover point */
|
|
// CallInfo base_ci; /* CallInfo for first level (C calling Lua) */
|
|
// lua_Hook hook;
|
|
// ptrdiff_t errfunc; /* current error handling function (stack index) */
|
|
// int stacksize;
|
|
// int basehookcount;
|
|
// int hookcount;
|
|
// unsigned short nny; /* number of non-yieldable calls in stack */
|
|
// unsigned short nCcalls; /* number of nested C calls */
|
|
// lu_byte hookmask;
|
|
// lu_byte allowhook;
|
|
//};
|
|
elements.clear();
|
|
elements.push_back(pGCObjectT);
|
|
elements.push_back(lu_byteT);
|
|
elements.push_back(lu_byteT);
|
|
elements.push_back(lu_byteT); /* status */
|
|
elements.push_back(StkIdT); /* top */
|
|
elements.push_back(pglobal_StateT); /* l_G */
|
|
elements.push_back(pCallInfoT); /* ci */
|
|
elements.push_back(pInstructionT); /* oldpc */
|
|
elements.push_back(StkIdT); /* stack_last */
|
|
elements.push_back(StkIdT); /* stack */
|
|
elements.push_back(pUpValT); /* openupval */
|
|
elements.push_back(pGCObjectT); /* gclist */
|
|
elements.push_back(plua_StateT); /* twups */
|
|
elements.push_back(plua_longjumpT); /* errorJmp */
|
|
elements.push_back(CallInfoT); /* base_ci */
|
|
elements.push_back(plua_HookT); /* hook */
|
|
elements.push_back(C_ptrdiff_t); /* errfunc */
|
|
elements.push_back(C_intT); /* stacksize */
|
|
elements.push_back(C_intT); /* basehookcount */
|
|
elements.push_back(C_intT); /* hookcount */
|
|
elements.push_back(llvm::Type::getInt16Ty(context)); /* nny */
|
|
elements.push_back(llvm::Type::getInt16Ty(context)); /* nCcalls */
|
|
elements.push_back(lu_byteT); /* hookmask */
|
|
elements.push_back(lu_byteT); /* allowhook */
|
|
lua_StateT->setBody(elements);
|
|
|
|
// int luaD_poscall (lua_State *L, StkId firstResult)
|
|
elements.clear();
|
|
elements.push_back(plua_StateT);
|
|
elements.push_back(StkIdT);
|
|
luaD_poscallT = llvm::FunctionType::get(C_intT, elements, false);
|
|
|
|
|