/****************************************************************************** * Copyright (C) 2015-2020 Dibyendu Majumdar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ #include "ravi_llvmcodegen.h" namespace ravi { /* Adds the bits that are defined in macro CommonHeader in lobject.h */ void LuaLLVMTypes::addCommonGCHeader(std::vector &elements) { /* Common Header for all collectable objects (in macro form, to be included in other objects) #define CommonHeader GCObject *next; lu_byte tt; lu_byte marked */ elements.push_back(pGCObjectT); elements.push_back(lu_byteT); elements.push_back(lu_byteT); } LuaLLVMTypes::LuaLLVMTypes(llvm::LLVMContext &context) : mdbuilder(context) { C_voidT = llvm::Type::getVoidTy(context); C_floatT = llvm::Type::getFloatTy(context); C_doubleT = llvm::Type::getDoubleTy(context); #ifdef LUA_32BITS // issue #93 add support for 32-bit Lua lua_NumberT = C_floatT; static_assert(std::is_floating_point::value && sizeof(lua_Number) == sizeof(float), "lua_Number is not a float"); static_assert(sizeof(lua_Integer) == sizeof(lua_Number) && sizeof(lua_Integer) == sizeof(int32_t), "lua_Integer size (32-bit) does not match lua_Number"); #else lua_NumberT = C_doubleT; static_assert(std::is_floating_point::value && sizeof(lua_Number) == sizeof(double), "lua_Number is not a double"); static_assert(sizeof(lua_Integer) == sizeof(lua_Number) && sizeof(lua_Integer) == sizeof(int64_t), "lua_Integer size (64-bit) does not match lua_Number"); #endif plua_NumberT = llvm::PointerType::get(lua_NumberT, 0); pplua_NumberT = llvm::PointerType::get(plua_NumberT, 0); static_assert(std::is_integral::value, "lua_Integer is not an integer type"); lua_IntegerT = llvm::Type::getIntNTy(context, sizeof(lua_Integer) * 8); plua_IntegerT = llvm::PointerType::get(lua_IntegerT, 0); pplua_IntegerT = llvm::PointerType::get(plua_IntegerT, 0); 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_psize_t = llvm::PointerType::get(C_size_t, 0); C_ptrdiff_t = llvm::Type::getIntNTy(context, sizeof(ptrdiff_t) * 8); C_int64_t = llvm::Type::getIntNTy(context, sizeof(int64_t) * 8); C_intT = llvm::Type::getIntNTy(context, sizeof(int) * 8); C_pintT = llvm::PointerType::get(C_intT, 0); C_shortT = llvm::Type::getIntNTy(context, sizeof(short) * 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; tmsT = C_intT; static_assert(sizeof(L_Umaxalign) == sizeof(double), "L_Umaxalign is not same size as double"); L_UmaxalignT = C_doubleT; static_assert(sizeof(lu_byte) == sizeof(char), "lu_byte is not same size as char"); lu_byteT = llvm::Type::getInt8Ty(context); C_pcharT = llvm::Type::getInt8PtrTy(context); static_assert(sizeof(Instruction) == sizeof(int), "Instruction is not same size as int"); InstructionT = C_intT; pInstructionT = llvm::PointerType::get(InstructionT, 0); ravitype_tT = llvm::Type::getIntNTy(context, sizeof(ravitype_t) * 8); lua_StateT = llvm::StructType::create(context, "struct.lua_State"); plua_StateT = llvm::PointerType::get(lua_StateT, 0); lua_LuaTypeT = C_shortT; // Type for Lua typecode lua_KContextT = C_ptrdiff_t; std::vector 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, "struct.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, "struct.GCObject"); pGCObjectT = llvm::PointerType::get(GCObjectT, 0); elements.clear(); addCommonGCHeader(elements); GCObjectT->setBody(elements); static_assert(sizeof(Value) == sizeof(lua_Number) && sizeof(Value) == sizeof(lua_Integer), "Value type is larger than lua_Number"); static_assert(sizeof(TValue) == sizeof(lua_Number) * 2, "TValue type is not 2*sizeof(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, "union.Value"); elements.clear(); elements.push_back(lua_NumberT); ValueT->setBody(elements); // NOTE: Following structure changes when NaN tagging is enabled // struct TValue { // union Value value_; // lu_byte tt_; // }; TValueT = llvm::StructType::create(context, "struct.TValue"); elements.clear(); elements.push_back(ValueT); elements.push_back(lua_LuaTypeT); 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 // */ // lu_byte shrlen; /* length for short strings */ // unsigned int hash; // union { // size_t lnglen; /* length for long strings */ // struct TString *hnext; /* linked list for hash table */ // } u; // } 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, "struct.TString"); pTStringT = llvm::PointerType::get(TStringT, 0); ppTStringT = llvm::PointerType::get(pTStringT, 0); elements.clear(); addCommonGCHeader(elements); elements.push_back(lu_byteT); /* extra */ elements.push_back(lu_byteT); /* shrlen */ elements.push_back(C_intT); /* hash */ elements.push_back(C_size_t); /* len (as this is the larger member) */ TStringT->setBody(elements); // Table TableT = llvm::StructType::create(context, "struct.Table"); pTableT = llvm::PointerType::get(TableT, 0); ppTableT = llvm::PointerType::get(pTableT, 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 // LuaType 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, "struct.Udata"); elements.clear(); addCommonGCHeader(elements); elements.push_back(lua_LuaTypeT); /* 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) */ // ravitype_t type; // 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, "struct.Upvaldesc"); // FIXME (issue #136) this structure is changing hence better to keep it // opaque // elements.clear(); // elements.push_back(pTStringT); /* name */ // elements.push_back(ravitype_tT); /* type */ // elements.push_back(lu_byteT); /* instack */ // elements.push_back(lu_byteT); /* idx */ // 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; LocVarT = llvm::StructType::create(context, "struct.LocVar"); // FIXME (issue #136) this structure is changing hence better to keep it // opaque // 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, "struct.LClosure"); pLClosureT = llvm::PointerType::get(LClosureT, 0); ppLClosureT = llvm::PointerType::get(pLClosureT, 0); pppLClosureT = llvm::PointerType::get(ppLClosureT, 0); RaviJITProtoT = llvm::StructType::create(context, "struct.RaviJITProto"); elements.clear(); elements.push_back(lu_byteT); /* jit_status*/ elements.push_back(lu_byteT); /* jit_flags */ elements.push_back(C_shortT); /* execution_count */ elements.push_back(C_pcharT); /* jit_data */ elements.push_back(plua_CFunctionT); /* jit_function */ RaviJITProtoT->setBody(elements); ///* //** 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, "struct.Proto"); pProtoT = llvm::PointerType::get(ProtoT, 0); ppProtoT = llvm::PointerType::get(pProtoT, 0); elements.clear(); addCommonGCHeader(elements); 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(RaviJITProtoT); /* ravi_jit */ ProtoT->setBody(elements); ///* //** Lua Upvalues //*/ // typedef struct UpVal UpVal; UpValT = llvm::StructType::create(context, "struct.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, "struct.CClosure"); elements.clear(); addCommonGCHeader(elements); 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(); addCommonGCHeader(elements); 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 //*/ // NOTE following structure changes when NaN Tagging is enabled // typedef union TKey { // struct { // TValuefields; // int next; /* for chaining (offset for next node) */ // } nk; // TValue tvk; //} TKey; TKeyT = llvm::StructType::create(context, "struct.TKey"); elements.clear(); elements.push_back(ValueT); elements.push_back(lua_LuaTypeT); 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, "struct.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 RaviArray { // char *data; // unsigned int len; /* RAVI len specialization */ // unsigned int size; /* amount of memory allocated */ // lu_byte array_type; /* RAVI specialization */ // lu_byte array_modifier; /* Flags that affect how the array is handled */ //} RaviArray; RaviArrayT = llvm::StructType::create(context, "struct.RaviArray"); elements.clear(); elements.push_back(C_pcharT); elements.push_back(C_intT); elements.push_back(C_intT); elements.push_back(lu_byteT); elements.push_back(lu_byteT); RaviArrayT->setBody(elements); // typedef struct Table { // CommonHeader; // lu_byte flags; /* 1<

setBody(elements); // struct lua_longjmp; /* defined in ldo.c */ lua_longjumpT = llvm::StructType::create(context, "struct.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, "struct.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, "struct.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 */ // unsigned short callstatus; // unsigned short stacklevel; /* Ravi extension - stack level, bottom level // is 0 */ // lu_byte jitstatus; /* Only valid if Lua function - if 1 means JITed - RAVI // extension */ //} 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, "struct.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(C_shortT); /* nresults */ elements.push_back(C_shortT); /* callstatus */ elements.push_back(C_shortT); /* stacklevel RAVI extension */ elements.push_back(lu_byteT); /* jitstatus RAVI extension*/ elements.push_back(lu_byteT); /* magic */ CallInfoT->setBody(elements); // typedef struct ravi_State ravi_State; ravi_StateT = llvm::StructType::create(context, "struct.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 */ // TString *strcache[STRCACHE_SIZE][1]; /* cache for strings in API */ // /* RAVI */ // ravi_State *ravi_state; //} global_State; global_StateT = llvm::StructType::create(context, "struct.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; // unsigned short nci; /* number of items in 'ci' list */ // lu_byte magic; //}; elements.clear(); addCommonGCHeader(elements); 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(C_shortT); /* nny */ elements.push_back(C_shortT); /* nCcalls */ elements.push_back(lu_byteT); /* hookmask */ elements.push_back(lu_byteT); /* allowhook */ elements.push_back(C_shortT); elements.push_back(lu_byteT); lua_StateT->setBody(elements); // struct UpVal { // struct TValue *v; /* points to stack or to its own value */ // unsigned int refcount; /* reference counter */ // unsigned int flags; /* Used to mark deferred values */ // union { // struct { /* (when open) */ // struct UpVal *next; /* linked list */ // int touched; /* mark to avoid cycles with dead threads */ // } open; // struct TValue value; /* the value (when closed) */ // } u; //}; elements.clear(); elements.push_back(pTValueT); elements.push_back(C_intT); elements.push_back(C_intT); elements.push_back(TValueT); UpValT->setBody(elements); // int luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, int nres); elements.clear(); elements.push_back(plua_StateT); elements.push_back(pCallInfoT); elements.push_back(StkIdT); elements.push_back(C_intT); luaD_poscallT = llvm::FunctionType::get(C_intT, elements, false); // void luaC_upvalbarrier_ (lua_State *L, UpVal *uv) elements.clear(); elements.push_back(plua_StateT); elements.push_back(pUpValT); luaC_upvalbarrierT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false); // int luaD_precall (lua_State *L, StkId func, int nresults, int op_call); elements.clear(); elements.push_back(plua_StateT); elements.push_back(StkIdT); elements.push_back(C_intT); elements.push_back(C_intT); luaD_precallT = llvm::FunctionType::get(C_intT, elements, false); // void luaD_call (lua_State *L, StkId func, int nResults); elements.clear(); elements.push_back(plua_StateT); elements.push_back(StkIdT); elements.push_back(C_intT); luaD_callT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false); // int luaV_execute(lua_State L); elements.clear(); elements.push_back(plua_StateT); luaV_executeT = llvm::FunctionType::get(C_intT, elements, false); // int luaF_close (lua_State *L, StkId level, int status) elements.clear(); elements.push_back(plua_StateT); elements.push_back(StkIdT); elements.push_back(C_intT); luaF_closeT = llvm::FunctionType::get(C_intT, elements, false); // int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) elements.clear(); elements.push_back(plua_StateT); elements.push_back(pTValueT); // void raviV_op_defer(lua_State *L, TValue *ra); raviV_op_deferT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false); elements.push_back(pTValueT); luaV_equalobjT = llvm::FunctionType::get(C_intT, elements, false); // int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) luaV_lessthanT = llvm::FunctionType::get(C_intT, elements, false); // int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) luaV_lessequalT = llvm::FunctionType::get(C_intT, elements, false); // void raviV_op_totype(lua_State *L, TValue *ra, TValue *rb); raviV_op_totypeT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false); // l_noret luaG_runerror (lua_State *L, const char *fmt, ...) elements.clear(); elements.push_back(plua_StateT); elements.push_back(C_pcharT); luaG_runerrorT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, true); // int luaV_forlimit (const TValue *obj, lua_Integer *p, lua_Integer step, // int *stopnow) elements.clear(); elements.push_back(pTValueT); elements.push_back(plua_IntegerT); elements.push_back(lua_IntegerT); elements.push_back(C_pintT); luaV_forlimitT = llvm::FunctionType::get(C_intT, elements, false); // int luaV_tonumber_ (const TValue *obj, lua_Number *n) elements.clear(); elements.push_back(pTValueT); elements.push_back(plua_NumberT); luaV_tonumberT = llvm::FunctionType::get(C_intT, elements, false); // int luaV_tointeger_ (const TValue *obj, lua_Integer *p) elements.clear(); elements.push_back(pTValueT); elements.push_back(plua_IntegerT); luaV_tointegerT = llvm::FunctionType::get(C_intT, elements, false); // void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) elements.clear(); elements.push_back(plua_StateT); elements.push_back(pTValueT); elements.push_back(pTValueT); luaV_objlenT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false); // void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) elements.push_back(pTValueT); luaV_gettableT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false); // void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) luaV_settableT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false); raviV_gettable_sskeyT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false); raviV_settable_sskeyT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false); raviV_gettable_iT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false); raviV_settable_iT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false); // void luaV_finishget (lua_State *L, const TValue *t, TValue *key, // StkId val, const TValue *slot); elements.push_back(pTValueT); luaV_finishgetT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false); // void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, // StkId res, TMS event); elements.clear(); elements.push_back(plua_StateT); elements.push_back(pTValueT); elements.push_back(pTValueT); elements.push_back(pTValueT); elements.push_back(tmsT); luaT_trybinTMT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false); // void raviV_op_loadnil(CallInfo *ci, int a, int b) elements.clear(); elements.push_back(pCallInfoT); elements.push_back(C_intT); elements.push_back(C_intT); raviV_op_loadnilT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false); // void raviV_op_newarrayint(lua_State *L, CallInfo *ci, TValue *ra) // void raviV_op_newarrayfloat(lua_State *L, CallInfo *ci, TValue *ra) elements.clear(); elements.push_back(plua_StateT); elements.push_back(pCallInfoT); elements.push_back(pTValueT); raviV_op_newarrayintT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false); raviV_op_newarrayfloatT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false); // void raviV_op_newtable(lua_State *L, CallInfo *ci, TValue *ra, int b, int // c) // void raviV_op_setlist(lua_State *L, CallInfo *ci, TValue *ra, int b, int c) elements.push_back(C_intT); elements.push_back(C_intT); raviV_op_newtableT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false); raviV_op_setlistT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false); // lua_Integer luaV_div (lua_State *L, lua_Integer m, lua_Integer n) // lua_Integer luaV_mod (lua_State *L, lua_Integer m, lua_Integer n) elements.clear(); elements.push_back(plua_StateT); elements.push_back(lua_IntegerT); elements.push_back(lua_IntegerT); luaV_modT = llvm::FunctionType::get(lua_IntegerT, elements, false); luaV_divT = llvm::FunctionType::get(lua_IntegerT, elements, false); // void raviV_op_concat(lua_State *L, CallInfo *ci, int a, int b, int c) elements.clear(); elements.push_back(plua_StateT); elements.push_back(pCallInfoT); elements.push_back(C_intT); elements.push_back(C_intT); elements.push_back(C_intT); raviV_op_concatT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false); // void raviV_op_closure(lua_State *L, CallInfo *ci, LClosure *cl, int a, int // Bx) // void raviV_op_vararg(lua_State *L, CallInfo *ci, LClosure *cl, int a, int // b) elements.clear(); elements.push_back(plua_StateT); elements.push_back(pCallInfoT); elements.push_back(pLClosureT); elements.push_back(C_intT); elements.push_back(C_intT); raviV_op_closureT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false); raviV_op_varargT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false); // void raviV_op_setupvali(lua_State *L, LClosure *cl, TValue *ra, int b); // void raviV_op_setupvalf(lua_State *L, LClosure *cl, TValue *ra, int b); // void raviV_op_setupvalai(lua_State *L, LClosure *cl, TValue *ra, int b); // void raviV_op_setupvalaf(lua_State *L, LClosure *cl, TValue *ra, int b); // void raviV_op_setupvalt(lua_State *L, LClosure *cl, TValue *ra, int b); elements.clear(); elements.push_back(plua_StateT); elements.push_back(pLClosureT); elements.push_back(pTValueT); elements.push_back(C_intT); raviV_op_setupvaliT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false); raviV_op_setupvalfT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false); raviV_op_setupvalaiT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false); raviV_op_setupvalafT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false); raviV_op_setupvaltT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false); // void raviV_op_bor(lua_State *L, TValue *ra, TValue *rb, TValue *rc); // void raviV_op_bxor(lua_State *L, TValue *ra, TValue *rb, TValue *rc); // void raviV_op_band(lua_State *L, TValue *ra, TValue *rb, TValue *rc); // void raviV_op_bnot(lua_State *L, TValue *ra, TValue *rb); // void raviV_op_shl(lua_State *L, TValue *ra, TValue *rb, TValue *rc); // void raviV_op_shr(lua_State *L, TValue *ra, TValue *rb, TValue *rc); elements.clear(); elements.push_back(plua_StateT); elements.push_back(pTValueT); elements.push_back(pTValueT); raviV_op_bnotT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false); elements.push_back(pTValueT); raviV_op_shlT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false); raviV_op_shrT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false); raviV_op_borT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false); raviV_op_bxorT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false); raviV_op_bandT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false); raviV_op_addT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false); raviV_op_subT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false); raviV_op_mulT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false); raviV_op_divT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false); // const TValue *luaH_getint(Table *t, lua_Integer key); elements.clear(); elements.push_back(pTableT); elements.push_back(lua_IntegerT); luaH_getintT = llvm::FunctionType::get(pTValueT, elements, false); // void luaH_setint(lua_State *L, Table *t, lua_Integer key, TValue *value); elements.clear(); elements.push_back(plua_StateT); elements.push_back(pTableT); elements.push_back(lua_IntegerT); elements.push_back(pTValueT); luaH_setintT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false); // const TValue *luaH_getstr(Table *t, TString *key); elements.clear(); elements.push_back(pTableT); elements.push_back(pTStringT); luaH_getstrT = llvm::FunctionType::get(pTValueT, elements, false); // void raviH_set_int(lua_State *L, Table *t, lua_Unsigned key, lua_Integer // value); elements.clear(); elements.push_back(plua_StateT); elements.push_back(pTableT); elements.push_back(lua_UnsignedT); elements.push_back(lua_IntegerT); raviH_set_intT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false); // void raviH_set_float(lua_State *L, Table *t, lua_Unsigned key, lua_Number // value); elements.clear(); elements.push_back(plua_StateT); elements.push_back(pTableT); elements.push_back(lua_UnsignedT); elements.push_back(lua_NumberT); raviH_set_floatT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false); elements.clear(); elements.push_back(plua_StateT); elements.push_back(pTValueT); ravi_dump_valueT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false); elements.clear(); elements.push_back(plua_StateT); elements.push_back(C_pcharT); ravi_dump_stackT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false); ravi_dump_stacktopT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false); elements.clear(); elements.push_back(plua_StateT); elements.push_back(C_intT); elements.push_back(C_intT); ravi_debug_traceT = llvm::FunctionType::get(llvm::Type::getVoidTy(context), elements, false); for (int j = 0; j < kInt.size(); j++) kInt[j] = llvm::ConstantInt::get(C_intT, j); for (int j = 0; j < kluaInteger.size(); j++) kluaInteger[j] = llvm::ConstantInt::get(lua_IntegerT, j); kFalse = llvm::ConstantInt::getFalse(llvm::Type::getInt1Ty(context)); // Do what Clang does //! 5 = metadata !{metadata !"Simple C/C++ TBAA"} tbaa_root = mdbuilder.createTBAARoot("Simple C / C++ TBAA"); //! 4 = metadata !{metadata !"omnipotent char", metadata !5, i64 0} tbaa_charT = mdbuilder.createTBAAScalarTypeNode("omnipotent char", tbaa_root, 0); tbaa_pcharT = mdbuilder.createTBAAStructTagNode(tbaa_charT, tbaa_charT, 0); //! 3 = metadata !{metadata !"any pointer", metadata !4, i64 0} tbaa_pointerT = mdbuilder.createTBAAScalarTypeNode("any pointer", tbaa_charT, 0); tbaa_ppointerT = mdbuilder.createTBAAStructTagNode(tbaa_pointerT, tbaa_pointerT, 0); //! 10 = metadata !{metadata !"short", metadata !4, i64 0} tbaa_shortT = mdbuilder.createTBAAScalarTypeNode("short", tbaa_charT, 0); tbaa_pshortT = mdbuilder.createTBAAStructTagNode(tbaa_shortT, tbaa_shortT, 0); //! 11 = metadata !{metadata !"int", metadata !4, i64 0} tbaa_intT = mdbuilder.createTBAAScalarTypeNode("int", tbaa_charT, 0); tbaa_pintT = mdbuilder.createTBAAStructTagNode(tbaa_intT, tbaa_intT, 0); //! 9 = metadata !{metadata !"long long", metadata !4, i64 0} tbaa_longlongT = mdbuilder.createTBAAScalarTypeNode("long long", tbaa_charT, 0); tbaa_plonglongT = mdbuilder.createTBAAStructTagNode(tbaa_longlongT, tbaa_longlongT, 0); tbaa_doubleT = mdbuilder.createTBAAScalarTypeNode("double", tbaa_charT, 0); tbaa_pdoubleT = mdbuilder.createTBAAStructTagNode(tbaa_doubleT, tbaa_doubleT, 0); //! 14 = metadata !{metadata !"CallInfoL", metadata !3, i64 0, metadata !3, //! i64 // 4, metadata !9, i64 8} std::vector> nodes; nodes.push_back(std::pair(tbaa_pointerT, 0)); nodes.push_back(std::pair(tbaa_pointerT, 4)); nodes.push_back(std::pair(tbaa_longlongT, 8)); tbaa_CallInfo_lT = mdbuilder.createTBAAStructTypeNode("CallInfo_l", nodes); //! 13 = metadata !{metadata !"CallInfoLua", // metadata !3, i64 0, metadata !3, i64 4, metadata !3, i64 8, // metadata !3, i64 12, metadata !14, i64 16, metadata !9, i64 // 32, // metadata !10, i64 40, metadata !4, i64 42} nodes.clear(); nodes.push_back( std::pair(tbaa_pointerT, 0)); // func nodes.push_back( std::pair(tbaa_pointerT, 4)); // top nodes.push_back( std::pair(tbaa_pointerT, 8)); // previous nodes.push_back( std::pair(tbaa_pointerT, 12)); // next nodes.push_back( std::pair(tbaa_CallInfo_lT, 16)); // l nodes.push_back( std::pair(tbaa_longlongT, 32)); // extra nodes.push_back( std::pair(tbaa_shortT, 40)); // nresults nodes.push_back( std::pair(tbaa_shortT, 42)); // callstatus nodes.push_back( std::pair(tbaa_shortT, 44)); // stacklevel nodes.push_back( std::pair(tbaa_charT, 46)); // jitstatus tbaa_CallInfoT = mdbuilder.createTBAAStructTypeNode("CallInfo", nodes); //! 7 = metadata !{metadata !"lua_State", // metadata !3, i64 0, metadata !4, i64 4, metadata !4, i64 5, // metadata !4, i64 6, metadata !3, i64 8, metadata !3, i64 12, // metadata !3, i64 16, metadata !3, i64 20, metadata !3, i64 // 24, // metadata !3, i64 28, metadata !3, i64 32, metadata !3, i64 // 36, // metadata !3, i64 40, metadata !3, i64 44, metadata !8, i64 // 48, // metadata !3, i64 104, metadata !9, i64 112, metadata !11, // i64 120, // metadata !11, i64 124, metadata !11, i64 128, metadata !10, // i64 132, // metadata !10, i64 134, metadata !4, i64 136, metadata !4, // i64 137} nodes.clear(); nodes.push_back(std::pair(tbaa_pointerT, 0)); nodes.push_back(std::pair(tbaa_charT, 4)); nodes.push_back(std::pair(tbaa_charT, 5)); nodes.push_back(std::pair(tbaa_charT, 6)); nodes.push_back(std::pair(tbaa_pointerT, 8)); nodes.push_back(std::pair(tbaa_pointerT, 12)); nodes.push_back(std::pair(tbaa_pointerT, 16)); nodes.push_back(std::pair(tbaa_pointerT, 20)); nodes.push_back(std::pair(tbaa_pointerT, 24)); nodes.push_back(std::pair(tbaa_pointerT, 28)); nodes.push_back(std::pair(tbaa_pointerT, 32)); nodes.push_back(std::pair(tbaa_pointerT, 36)); nodes.push_back(std::pair(tbaa_pointerT, 40)); nodes.push_back(std::pair(tbaa_pointerT, 44)); nodes.push_back(std::pair(tbaa_CallInfoT, 48)); nodes.push_back(std::pair(tbaa_pointerT, 92)); nodes.push_back(std::pair(tbaa_longlongT, 96)); nodes.push_back(std::pair(tbaa_intT, 104)); nodes.push_back(std::pair(tbaa_intT, 108)); nodes.push_back(std::pair(tbaa_intT, 112)); nodes.push_back(std::pair(tbaa_shortT, 114)); nodes.push_back(std::pair(tbaa_shortT, 116)); nodes.push_back(std::pair(tbaa_charT, 118)); nodes.push_back(std::pair(tbaa_charT, 119)); nodes.push_back(std::pair(tbaa_shortT, 120)); tbaa_luaStateT = mdbuilder.createTBAAStructTypeNode("lua_State", nodes); tbaa_luaState_ciT = mdbuilder.createTBAAStructTagNode(tbaa_luaStateT, tbaa_pointerT, 16); tbaa_luaState_ci_baseT = mdbuilder.createTBAAStructTagNode(tbaa_CallInfoT, tbaa_pointerT, 16); tbaa_CallInfo_funcT = mdbuilder.createTBAAStructTagNode(tbaa_CallInfoT, tbaa_pointerT, 0); tbaa_CallInfo_func_LClosureT = mdbuilder.createTBAAStructTagNode(tbaa_pointerT, tbaa_pointerT, 0); tbaa_CallInfo_topT = mdbuilder.createTBAAStructTagNode(tbaa_CallInfoT, tbaa_pointerT, 4); tbaa_CallInfo_savedpcT = mdbuilder.createTBAAStructTagNode(tbaa_CallInfoT, tbaa_pointerT, 20); tbaa_CallInfo_callstatusT = mdbuilder.createTBAAStructTagNode(tbaa_CallInfoT, tbaa_shortT, 42); tbaa_CallInfo_jitstatusT = mdbuilder.createTBAAStructTagNode(tbaa_CallInfoT, tbaa_charT, 46); //! 20 = metadata !{metadata !"Proto", // metadata !3, i64 0, metadata !4, i64 4, metadata !4, i64 5, // metadata !4, i64 6, metadata !4, i64 7, metadata !4, i64 8, // metadata !11, i64 12, metadata !11, i64 16, metadata !11, // i64 20, // metadata !11, i64 24, metadata !11, i64 28, metadata !11, // i64 32, // metadata !11, i64 36, metadata !11, i64 40, metadata !3, // i64 44, // metadata !3, i64 48, metadata !3, i64 52, metadata !3, i64 // 56, // metadata !3, i64 60, metadata !3, i64 64, metadata !3, i64 // 68, // metadata !3, i64 72, metadata !3, i64 76} nodes.clear(); nodes.push_back( std::pair(tbaa_pointerT, 0)); // next nodes.push_back(std::pair(tbaa_charT, 4)); // tt nodes.push_back( std::pair(tbaa_charT, 5)); // marked nodes.push_back( std::pair(tbaa_charT, 6)); // numparams nodes.push_back( std::pair(tbaa_charT, 7)); // is_vararg nodes.push_back( std::pair(tbaa_charT, 8)); // maxstacksize nodes.push_back( std::pair(tbaa_intT, 12)); // sizeupvalues nodes.push_back(std::pair(tbaa_intT, 16)); // sizek nodes.push_back( std::pair(tbaa_intT, 20)); // sizecode nodes.push_back( std::pair(tbaa_intT, 24)); // sizelineinfo nodes.push_back(std::pair(tbaa_intT, 28)); // sizep nodes.push_back( std::pair(tbaa_intT, 32)); // sizelocvars nodes.push_back( std::pair(tbaa_intT, 36)); // linedefined nodes.push_back( std::pair(tbaa_intT, 40)); // lastlinedefined nodes.push_back(std::pair(tbaa_pointerT, 44)); // k nodes.push_back( std::pair(tbaa_pointerT, 48)); // code nodes.push_back(std::pair(tbaa_pointerT, 52)); // p nodes.push_back( std::pair(tbaa_pointerT, 56)); // lineinfo nodes.push_back( std::pair(tbaa_pointerT, 60)); // locvars nodes.push_back( std::pair(tbaa_pointerT, 64)); // upvalues nodes.push_back( std::pair(tbaa_pointerT, 68)); // cache nodes.push_back( std::pair(tbaa_pointerT, 72)); // source nodes.push_back( std::pair(tbaa_pointerT, 76)); // gclist nodes.push_back( std::pair(tbaa_charT, 80)); // ravi_jit tbaa_ProtoT = mdbuilder.createTBAAStructTypeNode("Proto", nodes); //! 18 = metadata !{metadata !"LClosure", // metadata !3, i64 0, metadata !4, i64 4, metadata !4, i64 5, // metadata !4, i64 6, metadata !3, i64 8, metadata !3, i64 // 12, // metadata !4, i64 16} nodes.clear(); nodes.push_back(std::pair(tbaa_pointerT, 0)); nodes.push_back(std::pair(tbaa_charT, 4)); nodes.push_back(std::pair(tbaa_charT, 5)); nodes.push_back(std::pair(tbaa_charT, 6)); nodes.push_back(std::pair(tbaa_pointerT, 8)); nodes.push_back(std::pair(tbaa_pointerT, 12)); nodes.push_back(std::pair(tbaa_pointerT, 16)); tbaa_LClosureT = mdbuilder.createTBAAStructTypeNode("LClosure", nodes); tbaa_LClosure_pT = mdbuilder.createTBAAStructTagNode(tbaa_LClosureT, tbaa_pointerT, 12); tbaa_LClosure_upvalsT = mdbuilder.createTBAAStructTagNode(tbaa_LClosureT, tbaa_pointerT, 16); tbaa_Proto_kT = mdbuilder.createTBAAStructTagNode(tbaa_ProtoT, tbaa_pointerT, 44); tbaa_Proto_sizepT = mdbuilder.createTBAAStructTagNode(tbaa_ProtoT, tbaa_intT, 28); tbaa_Proto_codeT = mdbuilder.createTBAAStructTagNode(tbaa_ProtoT, tbaa_pointerT, 48); nodes.clear(); nodes.push_back(std::pair(tbaa_longlongT, 0)); nodes.push_back(std::pair(tbaa_shortT, 8)); tbaa_TValueT = mdbuilder.createTBAAStructTypeNode("TValue", nodes); tbaa_TValue_nT = mdbuilder.createTBAAStructTagNode(tbaa_TValueT, tbaa_longlongT, 0); tbaa_TValue_hT = mdbuilder.createTBAAStructTagNode(tbaa_pointerT, tbaa_pointerT, 0); tbaa_TValue_ttT = mdbuilder.createTBAAStructTagNode(tbaa_TValueT, tbaa_shortT, 8); tbaa_luaState_topT = mdbuilder.createTBAAStructTagNode(tbaa_luaStateT, tbaa_pointerT, 8); nodes.clear(); nodes.push_back(std::pair(tbaa_pointerT, 0)); nodes.push_back(std::pair(tbaa_intT, 4)); nodes.push_back(std::pair(tbaa_intT, 4)); nodes.push_back(std::pair(tbaa_TValueT, 16)); tbaa_UpValT = mdbuilder.createTBAAStructTypeNode("UpVal", nodes); tbaa_UpVal_vT = mdbuilder.createTBAAStructTagNode(tbaa_UpValT, tbaa_pointerT, 0); // RaviArray nodes.clear(); nodes.push_back( std::pair(tbaa_pointerT, 0)); /* data */ nodes.push_back(std::pair(tbaa_intT, 4)); /* len */ nodes.push_back(std::pair(tbaa_intT, 8)); /* size */ nodes.push_back( std::pair(tbaa_charT, 12)); /* type */ nodes.push_back( std::pair(tbaa_charT, 13)); /* modifiers */ tbaa_RaviArrayT = mdbuilder.createTBAAStructTypeNode("RaviArray", nodes); // Table TBAA struct type nodes.clear(); nodes.push_back( std::pair(tbaa_pointerT, 0)); /* next */ nodes.push_back(std::pair(tbaa_charT, 4)); /* tt */ nodes.push_back( std::pair(tbaa_charT, 5)); /* marked */ nodes.push_back( std::pair(tbaa_charT, 6)); /* flags */ nodes.push_back( std::pair(tbaa_charT, 7)); /* lsizenode */ nodes.push_back( std::pair(tbaa_intT, 8)); /* size array */ nodes.push_back( std::pair(tbaa_pointerT, 12)); /* array */ nodes.push_back( std::pair(tbaa_pointerT, 16)); /* node */ nodes.push_back( std::pair(tbaa_pointerT, 20)); /* lastfree */ nodes.push_back( std::pair(tbaa_pointerT, 24)); /* metatable */ nodes.push_back( std::pair(tbaa_pointerT, 28)); /* gclist */ nodes.push_back(std::pair(tbaa_RaviArrayT, 32)); /* ravi_array */ #if RAVI_USE_NEWHASH nodes.push_back( std::pair(tbaa_intT, 48)); /* hmask */ #endif tbaa_TableT = mdbuilder.createTBAAStructTypeNode("Table", nodes); tbaa_Table_flags = mdbuilder.createTBAAStructTagNode(tbaa_TableT, tbaa_charT, 6); tbaa_Table_lsizenode = mdbuilder.createTBAAStructTagNode(tbaa_TableT, tbaa_charT, 7); tbaa_Table_sizearray = mdbuilder.createTBAAStructTagNode(tbaa_TableT, tbaa_intT, 8); tbaa_Table_array = mdbuilder.createTBAAStructTagNode(tbaa_TableT, tbaa_pointerT, 12); tbaa_Table_node = mdbuilder.createTBAAStructTagNode(tbaa_TableT, tbaa_pointerT, 16); tbaa_Table_metatable = mdbuilder.createTBAAStructTagNode(tbaa_TableT, tbaa_pointerT, 24); tbaa_RaviArray_dataT = mdbuilder.createTBAAStructTagNode(tbaa_TableT, tbaa_pointerT, 32); tbaa_RaviArray_lenT = mdbuilder.createTBAAStructTagNode(tbaa_TableT, tbaa_intT, 36); tbaa_RaviArray_typeT = mdbuilder.createTBAAStructTagNode(tbaa_TableT, tbaa_charT, 44); #if RAVI_USE_NEWHASH tbaa_Table_hmask = mdbuilder.createTBAAStructTagNode(tbaa_TableT, tbaa_intT, 48); #endif } void LuaLLVMTypes::dump() { #if LLVM_VERSION_MAJOR < 5 GCObjectT->dump(); fputs("\n", stdout); TValueT->dump(); fputs("\n", stdout); TStringT->dump(); fputs("\n", stdout); UdataT->dump(); fputs("\n", stdout); UpvaldescT->dump(); fputs("\n", stdout); LocVarT->dump(); fputs("\n", stdout); RaviJITProtoT->dump(); fputs("\n", stdout); ProtoT->dump(); fputs("\n", stdout); CClosureT->dump(); fputs("\n", stdout); LClosureT->dump(); fputs("\n", stdout); TKeyT->dump(); fputs("\n", stdout); NodeT->dump(); fputs("\n", stdout); TableT->dump(); fputs("\n", stdout); MbufferT->dump(); fputs("\n", stdout); stringtableT->dump(); fputs("\n", stdout); CallInfoT->dump(); fputs("\n", stdout); lua_StateT->dump(); fputs("\n", stdout); #endif } } // namespace ravi