diff --git a/CMakeLists.txt b/CMakeLists.txt index ecfc6f9..18daae1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,6 @@ project(Ravi) enable_language(CXX) enable_language(C) -enable_language(C) enable_language(ASM) enable_testing() @@ -12,23 +11,15 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") # By default JIT is OFF option(LLVM_JIT "Controls whether LLVM JIT compilation will be enabled, default is OFF" OFF) -option(GCC_JIT "Controls whether GCC JIT compilation will be enabled, default is OFF" OFF) option(NANO_JIT "Controls whether NanoJIT compilation will be enabled, default is OFF" OFF) option(STATIC_BUILD "Build static version of Ravi, default is OFF" OFF) option(EMBEDDED_DMRC "Controls whether the embedded dmrC feature should be enabled, default is OFF" OFF) option(COMPUTED_GOTO "Controls whether the interpreter switch will use computed gotos on gcc/clang, default is OFF" ON) option(ASM_VM "Controls whether to use the new VM (not ready yet! so don't turn on)" OFF) -# We cannot link to both LLVM and GCC JIT -if (LLVM_JIT AND GCC_JIT) - message(FATAL_ERROR - "Both LLVM_JIT and GCC_JIT cannot be set to ON at the same time") -elseif (LLVM_JIT AND NANO_JIT) +if (LLVM_JIT AND NANO_JIT) message(FATAL_ERROR "Both LLVM_JIT and NANO_JIT cannot be set to ON at the same time") -elseif (GCC_JIT AND NANO_JIT) - message(FATAL_ERROR - "Both GCC_JIT and NANO_JIT cannot be set to ON at the same time") endif() if (ASM_VM) @@ -67,23 +58,14 @@ if (COMPUTED_GOTO AND MSVC) message(WARNING "Computed goto is not available with MSVC") endif() -if (GCC_JIT) - find_package(GCCJIT REQUIRED) - - message(STATUS "Found GCCJIT") - - include_directories(${GCCJIT_INCLUDE_DIRS}) - add_definitions(-DUSE_GCCJIT) -endif() - if (NANO_JIT) find_package(NanoJIT REQUIRED) include_directories(${NANOJITEXTRA_INCLUDE_DIRS}) add_definitions(-DUSE_NANOJIT) endif() -if (NOT LLVM_JIT AND NOT GCC_JIT AND NOT NANO_JIT) - message(WARNING "Neither LLVM, NanoJIT nor gccjit will be enabled; specify -DLLVM_JIT=ON, -DNANO_JIT=ON or -DGCC_JIT=ON to enable") +if (NOT LLVM_JIT) + message(WARNING "LLVM will not be enabled; specify -DLLVM_JIT=ON to enable") endif() if (MSVC) @@ -202,17 +184,10 @@ if (LLVM_JIT) src/ravi_llvmarith2.cpp src/ravi_llvmtforcall.cpp src/ravi_llvmrest.cpp src/ravi_llvmluaapi.cpp) endif () -if (GCC_JIT) - set(GCC_JIT_SRCS src/ravi_gccjit.c src/ravi_gcctypes.c - src/ravi_gcccodegen.c src/ravi_gccforprep.c src/ravi_gcccomp.c - src/ravi_gccreturn.c src/ravi_gccload.c src/ravi_gccforloop.c - src/ravi_gccarith1.c src/ravi_gcccall.c src/ravi_gcctable.c - src/ravi_gccarith2.c src/ravi_gcctforcall.c src/ravi_gccrest.c) -endif () if (NANO_JIT) set(NANO_JIT_SRCS src/ravi_nanojit.c) endif() -if (NOT LLVM_JIT AND NOT GCC_JIT AND NOT NANO_JIT) +if (NOT LLVM_JIT AND NOT NANO_JIT) set(NO_JIT_SRCS src/ravi_nojit.c) endif() # define the lua core source files @@ -238,7 +213,7 @@ set(LUA_HEADERS include/lua.h include/luaconf.h include/lualib.h include/lauxlib if (MSVC OR APPLE) source_group("Ravi Headers" FILES ${RAVI_HEADERS}) source_group("Ravi Source Files" FILES ${LUA_CORE_SRCS} ${LUA_LIB_SRCS} - ${LLVM_JIT_SRCS} ${GCC_JIT_SRCS}) + ${LLVM_JIT_SRCS}) if (APPLE) set(EXTRA_LIBRARIES m readline) endif () @@ -405,8 +380,6 @@ endif() if (LLVM_JIT) set (LIBRAVI_NAME libravillvm) -elseif (GCC_JIT) - set (LIBRAVI_NAME libravigccjit) elseif (NANO_JIT) set (LIBRAVI_NAME libravinanojit) else() @@ -419,7 +392,6 @@ add_library(${LIBRAVI_NAME} ${LIBRAVI_BUILD_TYPE} ${LUA_LIB_SRCS} ${LUA_CORE_SRCS} ${LLVM_JIT_SRCS} - ${GCC_JIT_SRCS} ${NANO_JIT_SRCS} ${NO_JIT_SRCS} ${DMR_C_HEADERS} @@ -435,7 +407,7 @@ if (NOT STATIC_BUILD) set_target_properties(${LIBRAVI_NAME} PROPERTIES PREFIX "") endif () endif() -target_link_libraries(${LIBRAVI_NAME} ${EXTRA_LIBRARIES} ${LLVM_LIBS} ${GCCJIT_LIBRARIES} ${NANOJITEXTRA_LIBRARIES}) +target_link_libraries(${LIBRAVI_NAME} ${EXTRA_LIBRARIES} ${LLVM_LIBS} ${NANOJITEXTRA_LIBRARIES}) # Ravi executable add_executable(ravi src/lua.c) @@ -460,7 +432,7 @@ add_test(TestVM test_vm) add_test(TestMisc test_misc) # Build VSCode Debug Adapter for Ravi -if (STATIC_BUILD AND NOT GCC_JIT AND NOT NANO_JIT) +if (STATIC_BUILD AND NOT NANO_JIT) add_executable(testravidebug vscode-debugger/src/testravidebug.c vscode-debugger/src/json.c vscode-debugger/src/protocol.c) target_link_libraries(testravidebug ${LIBRAVI_NAME}) diff --git a/README.rst b/README.rst index aa0ccbf..2442755 100644 --- a/README.rst +++ b/README.rst @@ -24,7 +24,7 @@ Features * Type specific bytecodes to improve performance * Compatibility with Lua 5.3 (see Compatibility section below) * `LLVM `_ powered JIT compiler -* Additionally a `libgccjit `_ based alternative JIT compiler is also available, although this is not currently being worked on +* Additionally a `libgccjit `_ based alternative JIT compiler is also available (on a branch), although this is not currently being worked on * LLVM bindings exposed in Lua Recent Work @@ -50,8 +50,6 @@ The LLVM JIT compiler is functional. The Lua and Ravi bytecodes currently implem Ravi also provides an `LLVM binding `_; this is still work in progress so please check documentation for the latest status. -There is also a `libgccjit `_ based JIT implementation but this implementation is lagging behind the LLVM based implementation. Further development of this is currently not planned. - Ravi Extensions to Lua 5.3 ========================== @@ -508,7 +506,7 @@ I test the build by running a modified version of Lua 5.3.3 test suite. These te Roadmap ======= * 2015 - Implemented JIT compilation using LLVM -* 2015 - Implemented libgccjit based alternative JIT +* 2015 - Implemented libgccjit based alternative JIT (now discontinued) * 2016 - Implemented debugger for Ravi and Lua 5.3 for `Visual Studio Code `_ * 2017 - Main priorities are: diff --git a/build-utils/cmake-64bit-unix-gcc-release.sh b/build-utils/cmake-64bit-unix-gcc-release.sh deleted file mode 100644 index 2f6ddf0..0000000 --- a/build-utils/cmake-64bit-unix-gcc-release.sh +++ /dev/null @@ -1,3 +0,0 @@ -mkdir buildgcc -cd buildgcc -cmake -DCMAKE_BUILD_TYPE=Release -DGCC_JIT=ON -DCMAKE_INSTALL_PREFIX=$HOME/ravi .. diff --git a/cmake/FindGCCJIT.cmake b/cmake/FindGCCJIT.cmake deleted file mode 100644 index 01fd304..0000000 --- a/cmake/FindGCCJIT.cmake +++ /dev/null @@ -1,15 +0,0 @@ -find_path(GCCJIT_INC libgccjit.h - PATHS - ~/local/include - /usr/local/include -) - -find_library(GCCJIT_LIB - NAMES gccjit libgccjit - PATHS - ~/local/lib - /usr/local/lib/gcc/5 -) - -set( GCCJIT_INCLUDE_DIRS "${GCCJIT_INC}" ) -set( GCCJIT_LIBRARIES "${GCCJIT_LIB}" ) diff --git a/include/ravi_gccjit.h b/include/ravi_gccjit.h deleted file mode 100644 index af93c72..0000000 --- a/include/ravi_gccjit.h +++ /dev/null @@ -1,776 +0,0 @@ -/****************************************************************************** -* Copyright (C) 2015 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. -******************************************************************************/ - -#ifndef RAVI_RAVI_GCCJIT_H -#define RAVI_RAVI_GCCJIT_H - -#ifdef USE_GCCJIT -#include -#include "ravijit.h" - -#ifdef __cplusplus -extern "C" { -#endif - -// TODO we probably do not need all the headers -// below - -#define LUA_CORE - -#include "lprefix.h" - -#include -#include -#include -#include -#include -#include - -#include "lua.h" - -#include "ldebug.h" -#include "ldo.h" -#include "lfunc.h" -#include "lobject.h" -#include "lopcodes.h" -#include "lstate.h" -#include "lstring.h" -#include "ltable.h" -#include "lvm.h" - -typedef enum { - LUA__TNIL = LUA_TNIL, - LUA__TBOOLEAN = LUA_TBOOLEAN, - LUA__TLIGHTUSERDATA = LUA_TLIGHTUSERDATA, - LUA__TNUMBER = LUA_TNUMBER, - LUA__TSTRING = ctb(LUA_TSTRING), - LUA__TTABLE = ctb(LUA_TTABLE), - RAVI__TLTABLE = ctb(LUA_TTABLE), - RAVI__TIARRAY = ctb(RAVI_TIARRAY), - RAVI__TFARRAY = ctb(RAVI_TFARRAY), - LUA__TFUNCTION = ctb(LUA_TFUNCTION), - LUA__TUSERDATA = ctb(LUA_TUSERDATA), - LUA__TTHREAD = ctb(LUA_TTHREAD), - LUA__TLCL = ctb(LUA_TLCL), - LUA__TLCF = LUA_TLCF, - LUA__TCCL = ctb(LUA_TCCL), - LUA__TSHRSTR = ctb(LUA_TSHRSTR), - LUA__TLNGSTR = ctb(LUA_TLNGSTR), - LUA__TNUMFLT = LUA_TNUMFLT, - LUA__TNUMINT = LUA_TNUMINT -} lua_typecode_t; - -typedef struct ravi_gcc_context_t ravi_gcc_context_t; -typedef struct ravi_gcc_types_t ravi_gcc_types_t; -typedef struct ravi_gcc_codegen_t ravi_gcc_codegen_t; - -struct ravi_State { - ravi_gcc_context_t *jit; - ravi_gcc_codegen_t *code_generator; -}; - -struct ravi_gcc_types_t { - - gcc_jit_type *C_boolT; - gcc_jit_type *C_doubleT; - gcc_jit_type *C_intptr_t; - gcc_jit_type *C_size_t; - gcc_jit_type *C_ptrdiff_t; - gcc_jit_type *C_int64_t; - gcc_jit_type *C_shortT; - gcc_jit_type *C_unsigned_shortT; - gcc_jit_type *C_voidT; - gcc_jit_type *C_pvoidT; - - gcc_jit_type *lua_NumberT; - gcc_jit_type *plua_NumberT; - gcc_jit_type *pplua_NumberT; - - gcc_jit_type *lua_IntegerT; - gcc_jit_type *plua_IntegerT; - gcc_jit_type *pplua_IntegerT; - // gcc_jit_type *clua_IntegerT; - - gcc_jit_type *lua_UnsignedT; - gcc_jit_type *lua_KContextT; - - // gcc_jit_function *lua_CFunctionT; - gcc_jit_type *plua_CFunctionT; - - // gcc_jit_function *lua_KFunctionT; - gcc_jit_type *plua_KFunctionT; - - // gcc_jit_function *lua_HookT; - gcc_jit_type *plua_HookT; - - // gcc_jit_function *lua_AllocT; - gcc_jit_type *plua_AllocT; - - gcc_jit_type *l_memT; - gcc_jit_type *lu_memT; - - gcc_jit_type *tmsT; - - gcc_jit_type *lu_byteT; - gcc_jit_type *L_UmaxalignT; - gcc_jit_type *C_charT; - gcc_jit_type *C_pcharT; - gcc_jit_type *C_pconstcharT; - - gcc_jit_type *C_intT; - gcc_jit_type *C_pintT; - gcc_jit_type *C_unsigned_intT; - - gcc_jit_struct *lua_StateT; - gcc_jit_type *plua_StateT; - - gcc_jit_field *lua_State_ci; - gcc_jit_field *lua_State_top; - - gcc_jit_struct *global_StateT; - gcc_jit_type *pglobal_StateT; - - gcc_jit_struct *ravi_StateT; - gcc_jit_type *pravi_StateT; - - gcc_jit_struct *GCObjectT; - gcc_jit_type *pGCObjectT; - - gcc_jit_type *ValueT; - gcc_jit_struct *TValueT; - gcc_jit_type *cTValueT; - gcc_jit_type *pTValueT; - gcc_jit_type *pcTValueT; - - gcc_jit_field *Value_value; - gcc_jit_field *Value_value_gc; - gcc_jit_field *Value_value_n; - gcc_jit_field *Value_value_i; - gcc_jit_field *Value_value_b; - gcc_jit_field *Value_tt; - - gcc_jit_struct *TStringT; - gcc_jit_type *pTStringT; - gcc_jit_type *ppTStringT; - - gcc_jit_struct *UdataT; - gcc_jit_struct *RaviArrayT; - gcc_jit_field *RaviArray_len; - gcc_jit_field *RaviArray_data; - gcc_jit_field *RaviArray_array_type; - - gcc_jit_struct *TableT; - gcc_jit_type *pTableT; - gcc_jit_type *ppTableT; - gcc_jit_field *Table_ravi_array; - - gcc_jit_struct *UpvaldescT; - gcc_jit_type *pUpvaldescT; - - gcc_jit_type *ravitype_tT; - gcc_jit_struct *LocVarT; - gcc_jit_type *pLocVarT; - - gcc_jit_type *InstructionT; - gcc_jit_type *pInstructionT; - gcc_jit_struct *LClosureT; - gcc_jit_type *pLClosureT; - gcc_jit_type *ppLClosureT; - gcc_jit_type *pppLClosureT; - gcc_jit_type *ClosureT; - gcc_jit_type *pClosureT; - - gcc_jit_field *LClosure_p; - gcc_jit_field *LClosure_p_k; - gcc_jit_field *LClosure_upvals; - - gcc_jit_struct *RaviJITProtoT; - - gcc_jit_struct *ProtoT; - gcc_jit_type *pProtoT; - gcc_jit_type *ppProtoT; - - gcc_jit_field *Proto_sizep; - - gcc_jit_struct *UpValT; - gcc_jit_type *pUpValT; - gcc_jit_struct *UpVal_u_openT; - gcc_jit_type *UpVal_uT; - - gcc_jit_field *UpVal_v; - gcc_jit_field *UpVal_u; - gcc_jit_field *UpVal_u_value; - - gcc_jit_struct *CClosureT; - gcc_jit_type *pCClosureT; - - gcc_jit_type *TKeyT; - gcc_jit_type *pTKeyT; - - gcc_jit_struct *NodeT; - gcc_jit_type *pNodeT; - - gcc_jit_struct *lua_DebugT; - gcc_jit_type *plua_DebugT; - - gcc_jit_struct *lua_longjumpT; - gcc_jit_type *plua_longjumpT; - - gcc_jit_struct *MbufferT; - gcc_jit_struct *stringtableT; - - gcc_jit_type *StkIdT; - - gcc_jit_struct *CallInfoT; - gcc_jit_struct *CallInfo_cT; - gcc_jit_struct *CallInfo_lT; - gcc_jit_type *CallInfo_uT; - gcc_jit_type *pCallInfoT; - - gcc_jit_field *CallInfo_func; - gcc_jit_field *CallInfo_top; - gcc_jit_field *CallInfo_u; - gcc_jit_field *CallInfo_u_l; - gcc_jit_field *CallInfo_u_l_base; - - gcc_jit_function *jitFunctionT; - - gcc_jit_function *luaD_poscallT; - gcc_jit_function *luaD_precallT; - gcc_jit_function *luaD_callT; - gcc_jit_function *luaF_closeT; - gcc_jit_function *luaT_trybinTMT; - gcc_jit_function *luaG_runerrorT; - gcc_jit_function *luaV_equalobjT; - gcc_jit_function *luaV_lessthanT; - gcc_jit_function *luaV_lessequalT; - gcc_jit_function *luaV_forlimitT; - gcc_jit_function *luaV_tonumberT; - gcc_jit_function *luaV_tointegerT; - gcc_jit_function *luaV_modT; - gcc_jit_function *luaV_objlenT; - gcc_jit_function *luaV_divT; - gcc_jit_function *luaC_upvalbarrierT; - - gcc_jit_function *luaV_executeT; - gcc_jit_function *luaV_gettableT; - gcc_jit_function *luaV_settableT; - - // Following are functions that handle specific bytecodes - // We cheat for these bytecodes by calling the function that - // implements it - gcc_jit_function *raviV_op_newarrayintT; - gcc_jit_function *raviV_op_newarrayfloatT; - gcc_jit_function *raviV_op_setlistT; - gcc_jit_function *raviV_op_newtableT; - gcc_jit_function *raviV_op_loadnilT; - gcc_jit_function *raviV_op_concatT; - gcc_jit_function *raviV_op_closureT; - gcc_jit_function *raviV_op_varargT; - gcc_jit_function *raviV_op_setupvalT; - - gcc_jit_function *raviH_set_intT; - gcc_jit_function *raviH_set_floatT; - - gcc_jit_function *printfT; -}; - -struct ravi_gcc_context_t { - - /* parent JIT context - all functions are child contexts - * of this. - */ - gcc_jit_context *context; - - gcc_jit_result *parent_result_; - - /* Lua type definitions */ - ravi_gcc_types_t *types; - - /* Should we auto compile what we can? */ - bool auto_; - - /* Is JIT enabled */ - bool enabled_; - - /* Optimizer level */ - int opt_level_; - - /* Size level */ - int size_level_; - - /* min code size for compilation */ - int min_code_size_; - - /* min execution count for compilation */ - int min_exec_count_; -}; - -struct ravi_gcc_codegen_t { - - ravi_gcc_context_t *ravi; - - char temp[31]; - - int id; -}; - -// struct ravi_gcc_function_t { -// -// gcc_jit_result *jit_result; -// -//}; - -typedef struct ravi_branch_def_t { - // this field is used for all branches - gcc_jit_block *jmp; - - // These are local variables for a fornum - // loop - gcc_jit_lvalue *ilimit; - gcc_jit_lvalue *istep; - gcc_jit_lvalue *iidx; - gcc_jit_lvalue *flimit; - gcc_jit_lvalue *fstep; - gcc_jit_lvalue *fidx; - -} ravi_branch_def_t; - -typedef struct ravi_function_def_t { - - ravi_gcc_context_t *ravi; - - Proto *p; - - char name[31]; - - /* Child context for the function being compiled */ - gcc_jit_context *function_context; - - gcc_jit_param *L; - - gcc_jit_function *jit_function; - - gcc_jit_block *entry_block; - - struct ravi_branch_def_t **jmp_targets; - - /* Currently compiled function's stack frame L->ci */ - gcc_jit_lvalue *ci_val; - - /* Currently compiled function's stack value L->ci->func - * type is LClosure * - */ - gcc_jit_rvalue *lua_closure; - gcc_jit_lvalue *lua_closure_val; - - gcc_jit_lvalue *kOne_luaInteger; - - gcc_jit_block *current_block; - - bool current_block_terminated; - - /* The Lua stack base - this can change during execution so needs to be lvalue - */ - gcc_jit_rvalue *base_ref; - // gcc_jit_lvalue *base; - - /* Reference to lua_closure->p - never changes */ - gcc_jit_rvalue *proto; - - /* The Lua constants list for the function - this never changes */ - gcc_jit_rvalue *k; - - /* temporary buffer for creating unique names */ - char buf[80]; - - /* counter used for creating unique names */ - unsigned int counter; - - int dump_ir; - int dump_asm; - int opt_level; - -} ravi_function_def_t; - -/* Create a new context */ -extern ravi_gcc_context_t *ravi_jit_new_context(void); - -/* Destroy a context */ -extern void ravi_jit_context_free(ravi_gcc_context_t *); - -/* Setup Lua types */ -extern bool ravi_setup_lua_types(ravi_gcc_context_t *); - -extern ravi_gcc_codegen_t * -ravi_jit_new_codegen(ravi_gcc_context_t *global_context); - -extern void ravi_jit_codegen_free(ravi_gcc_codegen_t *); - -extern bool ravi_jit_has_errored(ravi_gcc_context_t *); - -extern void ravi_emit_load_base(ravi_function_def_t *def); - -extern gcc_jit_lvalue *ravi_emit_get_register(ravi_function_def_t *def, int A); - -extern gcc_jit_lvalue *ravi_emit_get_constant(ravi_function_def_t *def, int Bx); - -extern gcc_jit_lvalue * -ravi_emit_get_register_or_constant(ravi_function_def_t *def, int B); - -extern void ravi_emit_set_L_top_toreg(ravi_function_def_t *def, int B); - -extern void ravi_emit_refresh_L_top(ravi_function_def_t *def); - -extern gcc_jit_lvalue *ravi_emit_get_Proto_sizep(ravi_function_def_t *def); - -extern gcc_jit_rvalue *ravi_emit_get_upvals(ravi_function_def_t *def, - int offset); -// Get upval->v -extern gcc_jit_lvalue *ravi_emit_load_upval_v(ravi_function_def_t *def, - gcc_jit_rvalue *pupval); - -// Get upval->u.value -extern gcc_jit_lvalue *ravi_emit_load_upval_value(ravi_function_def_t *def, - gcc_jit_rvalue *pupval); - -extern void ravi_set_current_block(ravi_function_def_t *def, - gcc_jit_block *block); - -extern gcc_jit_rvalue *ravi_function_call1_rvalue(ravi_function_def_t *def, - gcc_jit_function *f, - gcc_jit_rvalue *arg1); - -extern gcc_jit_rvalue *ravi_function_call2_rvalue(ravi_function_def_t *def, - gcc_jit_function *f, - gcc_jit_rvalue *arg1, - gcc_jit_rvalue *arg2); - -extern gcc_jit_rvalue *ravi_function_call3_rvalue(ravi_function_def_t *def, - gcc_jit_function *f, - gcc_jit_rvalue *arg1, - gcc_jit_rvalue *arg2, - gcc_jit_rvalue *arg3); - -extern gcc_jit_rvalue * -ravi_function_call4_rvalue(ravi_function_def_t *def, gcc_jit_function *f, - gcc_jit_rvalue *arg1, gcc_jit_rvalue *arg2, - gcc_jit_rvalue *arg3, gcc_jit_rvalue *arg4); - -extern gcc_jit_rvalue * -ravi_function_call5_rvalue(ravi_function_def_t *def, gcc_jit_function *f, - gcc_jit_rvalue *arg1, gcc_jit_rvalue *arg2, - gcc_jit_rvalue *arg3, gcc_jit_rvalue *arg4, - gcc_jit_rvalue *arg5); - -extern const char *unique_name(ravi_function_def_t *def, const char *prefix, - int pc); - -extern gcc_jit_rvalue *ravi_emit_num_stack_elements(ravi_function_def_t *def, - gcc_jit_rvalue *ra); - -extern void ravi_emit_struct_assign(ravi_function_def_t *def, - gcc_jit_lvalue *reg_dest, - gcc_jit_lvalue *reg_src); - -/* Store an integer value and set type to TNUMINT */ -extern gcc_jit_lvalue *ravi_emit_load_reg_i(ravi_function_def_t *def, - gcc_jit_lvalue *reg); - -/* Store a number value and set type to TNUMFLT */ -extern gcc_jit_lvalue *ravi_emit_load_reg_n(ravi_function_def_t *def, - gcc_jit_lvalue *reg); - -/* Get TValue->value_.b */ -extern gcc_jit_lvalue *ravi_emit_load_reg_b(ravi_function_def_t *def, - gcc_jit_lvalue *reg); - -extern gcc_jit_lvalue *ravi_emit_load_type(ravi_function_def_t *def, - gcc_jit_lvalue *reg); - -extern gcc_jit_rvalue *ravi_emit_is_value_of_type(ravi_function_def_t *def, - gcc_jit_rvalue *value_type, - int lua_type); - -extern gcc_jit_rvalue * -ravi_emit_is_not_value_of_type(ravi_function_def_t *def, - gcc_jit_rvalue *value_type, int lua_type); - -extern gcc_jit_rvalue * -ravi_emit_is_not_value_of_type_class(ravi_function_def_t *def, - gcc_jit_rvalue *value_type, int lua_type); - -extern void ravi_emit_store_reg_i_withtype(ravi_function_def_t *def, - gcc_jit_rvalue *ivalue, - gcc_jit_lvalue *reg); - -extern void ravi_emit_store_reg_n_withtype(ravi_function_def_t *def, - gcc_jit_rvalue *nvalue, - gcc_jit_lvalue *reg); - -extern void ravi_emit_store_reg_b_withtype(ravi_function_def_t *def, - gcc_jit_rvalue *bvalue, - gcc_jit_lvalue *reg); - -extern gcc_jit_rvalue *ravi_emit_load_reg_h(ravi_function_def_t *def, - gcc_jit_lvalue *reg); - -extern gcc_jit_rvalue *ravi_emit_load_reg_h_floatarray(ravi_function_def_t *def, - gcc_jit_rvalue *h); - -extern gcc_jit_rvalue *ravi_emit_load_reg_h_intarray(ravi_function_def_t *def, - gcc_jit_rvalue *h); - -extern gcc_jit_lvalue *ravi_emit_load_ravi_arraylength(ravi_function_def_t *def, - gcc_jit_rvalue *h); - -extern gcc_jit_lvalue *ravi_emit_load_ravi_arraytype(ravi_function_def_t *def, - gcc_jit_rvalue *h); - -extern gcc_jit_rvalue *ravi_emit_array_get(ravi_function_def_t *def, - gcc_jit_rvalue *ptr, - gcc_jit_rvalue *index); - -extern gcc_jit_lvalue *ravi_emit_array_get_ptr(ravi_function_def_t *def, - gcc_jit_rvalue *ptr, - gcc_jit_rvalue *index); - -extern gcc_jit_rvalue *ravi_emit_comparison(ravi_function_def_t *def, - enum gcc_jit_comparison op, - gcc_jit_rvalue *a, - gcc_jit_rvalue *b); - -extern gcc_jit_lvalue *ravi_emit_tonumtype(ravi_function_def_t *def, - gcc_jit_lvalue *reg, - lua_typecode_t tt, int pc); - -extern void ravi_emit_conditional_branch(ravi_function_def_t *def, - gcc_jit_rvalue *cond, - gcc_jit_block *true_block, - gcc_jit_block *false_block); - -extern void ravi_emit_branch(ravi_function_def_t *def, - gcc_jit_block *target_block); - -extern gcc_jit_rvalue *ravi_emit_boolean_testfalse(ravi_function_def_t *def, - gcc_jit_lvalue *reg, - bool negate); - -extern void ravi_emit_raise_lua_error(ravi_function_def_t *def, - const char *msg); - -extern void ravi_emit_RETURN(ravi_function_def_t *def, int A, int B, int pc); - -extern void ravi_emit_LOADK(ravi_function_def_t *def, int A, int Bx, int pc); - -extern void ravi_emit_iFORPREP(ravi_function_def_t *def, int A, int pc, - int step_one); - -extern void ravi_emit_iFORLOOP(ravi_function_def_t *def, int A, int pc, - ravi_branch_def_t *b, int step_one); - -extern void ravi_emit_MOVE(ravi_function_def_t *def, int A, int B); - -extern void ravi_emit_MOVEI(ravi_function_def_t *def, int A, int B, int pc); - -extern void ravi_emit_MOVEF(ravi_function_def_t *def, int A, int B, int pc); - -extern void ravi_emit_LOADNIL(ravi_function_def_t *def, int A, int B, int pc); - -extern void ravi_emit_LOADFZ(ravi_function_def_t *def, int A, int pc); - -extern void ravi_emit_LOADIZ(ravi_function_def_t *def, int A, int pc); - -extern void ravi_emit_LOADBOOL(ravi_function_def_t *def, int A, int B, int C, - int j, int pc); - -// implements EQ, LE and LT - by using the supplied lua function to call. -extern void ravi_emit_EQ_LE_LT(ravi_function_def_t *def, int A, int B, int C, - int j, int jA, gcc_jit_function *callee, - const char *opname, OpCode op, int pc); - -extern void ravi_emit_JMP(ravi_function_def_t *def, int A, int j, int pc); - -// Handle OP_CALL -extern void ravi_emit_CALL(ravi_function_def_t *def, int A, int B, int C, - int pc); - -extern void ravi_emit_GETTABUP(ravi_function_def_t *def, int A, int B, int C, - int pc); - -extern void ravi_emit_SETTABUP(ravi_function_def_t *def, int A, int B, int C, - int pc); - -extern void ravi_emit_SETUPVAL(ravi_function_def_t *def, int A, int B, int pc); - -extern void ravi_emit_GETUPVAL(ravi_function_def_t *def, int A, int B, int pc); - -extern void ravi_emit_TEST(ravi_function_def_t *def, int A, int B, int C, int j, - int jA, int pc); - -extern void ravi_emit_TESTSET(ravi_function_def_t *def, int A, int B, int C, - int j, int jA, int pc); - -extern void ravi_emit_NOT(ravi_function_def_t *def, int A, int B, int pc); - -extern void ravi_emit_TOFLT(ravi_function_def_t *def, int A, int pc); - -extern void ravi_emit_TOINT(ravi_function_def_t *def, int A, int pc); - -extern void ravi_emit_CONCAT(ravi_function_def_t *def, int A, int B, int C, - int pc); - -extern void ravi_emit_CLOSURE(ravi_function_def_t *def, int A, int Bx, int pc); - -extern void ravi_emit_VARARG(ravi_function_def_t *def, int A, int B, int pc); - -extern void ravi_emit_UNMF(ravi_function_def_t *def, int A, int B, int pc); - -extern void ravi_emit_UNMI(ravi_function_def_t *def, int A, int B, int pc); - -extern void ravi_emit_ADDFF(ravi_function_def_t *def, int A, int B, int C, - int pc); - -extern void ravi_emit_ADDFI(ravi_function_def_t *def, int A, int B, int C, - int pc); - -extern void ravi_emit_ADDII(ravi_function_def_t *def, int A, int B, int C, - int pc); - -extern void ravi_emit_SUBFF(ravi_function_def_t *def, int A, int B, int C, - int pc); - -extern void ravi_emit_SUBFI(ravi_function_def_t *def, int A, int B, int C, - int pc); - -extern void ravi_emit_SUBIF(ravi_function_def_t *def, int A, int B, int C, - int pc); - -extern void ravi_emit_SUBII(ravi_function_def_t *def, int A, int B, int C, - int pc); - -extern void ravi_emit_DIVFF(ravi_function_def_t *def, int A, int B, int C, - int pc); - -extern void ravi_emit_DIVFI(ravi_function_def_t *def, int A, int B, int C, - int pc); - -extern void ravi_emit_DIVIF(ravi_function_def_t *def, int A, int B, int C, - int pc); - -extern void ravi_emit_DIVII(ravi_function_def_t *def, int A, int B, int C, - int pc); - -extern void ravi_emit_MULFF(ravi_function_def_t *def, int A, int B, int C, - int pc); - -extern void ravi_emit_MULFI(ravi_function_def_t *def, int A, int B, int C, - int pc); - -extern void ravi_emit_MULII(ravi_function_def_t *def, int A, int B, int C, - int pc); - -extern void ravi_emit_SELF(ravi_function_def_t *def, int A, int B, int C, - int pc); - -extern void ravi_emit_LEN(ravi_function_def_t *def, int A, int B, int pc); - -extern void ravi_emit_SETTABLE(ravi_function_def_t *def, int A, int B, int C, - int pc); - -extern void ravi_emit_GETTABLE(ravi_function_def_t *def, int A, int B, int C, - int pc); - -extern void ravi_emit_NEWTABLE(ravi_function_def_t *def, int A, int B, int C, - int pc); - -extern void ravi_emit_SETLIST(ravi_function_def_t *def, int A, int B, int C, - int pc); - -extern void ravi_emit_TFORCALL(ravi_function_def_t *def, int A, int B, int C, - int j, int jA, int pc); - -extern void ravi_emit_TFORLOOP(ravi_function_def_t *def, int A, int j, int pc); - -extern void ravi_emit_GETTABLE_AI(ravi_function_def_t *def, int A, int B, int C, - int pc, bool omitArrayGetRangeCheck); - -extern void ravi_emit_GETTABLE_AF(ravi_function_def_t *def, int A, int B, int C, - int pc, bool omitArrayGetRangeCheck); - -extern void ravi_emit_NEWARRAYFLOAT(ravi_function_def_t *def, int A, int pc); - -extern void ravi_emit_NEWARRAYINT(ravi_function_def_t *def, int A, int pc); - -extern void ravi_emit_TOARRAY(ravi_function_def_t *def, int A, - int array_type_expected, const char *errmsg, - int pc); - -extern void ravi_emit_MOVEAI(ravi_function_def_t *def, int A, int B, int pc); - -extern void ravi_emit_MOVEAF(ravi_function_def_t *def, int A, int B, int pc); - -extern void ravi_emit_SETTABLE_AI_AF(ravi_function_def_t *def, int A, int B, - int C, bool known_tt, lua_typecode_t tt, - int pc); - -extern void ravi_emit_ARITH(ravi_function_def_t *def, int A, int B, int C, - OpCode op, TMS tms, int pc); - -extern void ravi_dump_rvalue(gcc_jit_rvalue *rv); - -extern void ravi_dump_lvalue(gcc_jit_lvalue *lv); - -extern void ravi_debug_printf(ravi_function_def_t *def, const char *str); - -extern void ravi_debug_printf1(ravi_function_def_t *def, const char *str, - gcc_jit_rvalue *arg1); - -extern void ravi_debug_printf2(ravi_function_def_t *def, const char *str, - gcc_jit_rvalue *arg1, gcc_jit_rvalue *arg2); - -extern void ravi_debug_printf3(ravi_function_def_t *def, const char *str, - gcc_jit_rvalue *arg1, gcc_jit_rvalue *arg2, - gcc_jit_rvalue *arg3); - -extern void ravi_debug_printf4(ravi_function_def_t *def, const char *str, - gcc_jit_rvalue *arg1, gcc_jit_rvalue *arg2, - gcc_jit_rvalue *arg3, gcc_jit_rvalue *arg4); - -extern gcc_jit_rvalue *ravi_int_constant(ravi_function_def_t *def, int value); - -extern gcc_jit_rvalue *ravi_bool_constant(ravi_function_def_t *def, int value); - -extern gcc_jit_rvalue *ravi_lua_Integer_constant(ravi_function_def_t *def, - int value); - -extern gcc_jit_rvalue *ravi_lua_Number_constant(ravi_function_def_t *def, - double value); - -#ifdef __cplusplus -}; -#endif - -#endif /* USE_GCCJIT */ - -#endif /* RAVI_RAVI_GCCJIT_H */ diff --git a/readthedocs/index.rst b/readthedocs/index.rst index 815f3a0..fbb5919 100644 --- a/readthedocs/index.rst +++ b/readthedocs/index.rst @@ -25,7 +25,6 @@ Contents: llvm-bindings ravi-benchmarks ravi-jit-status - ravi-jit-libgccjit Indices and tables diff --git a/readthedocs/ravi-jit-libgccjit.rst b/readthedocs/ravi-jit-libgccjit.rst deleted file mode 100644 index 8640ea7..0000000 --- a/readthedocs/ravi-jit-libgccjit.rst +++ /dev/null @@ -1,315 +0,0 @@ -======================================== -JIT Compilation for Ravi using ``libgccjit`` -======================================== - -Introduction ------------- -The latest `gcc 5.2 release `_ contains a new component called ``libgccjit``. This basically exposes an API via a shared library to the compilation functions within gcc. - -I am keen to provide support for this in Ravi. From initial look it seems to contain all the features I need to implement a JIT compiler for Ravi. Obviously having implemented the LLVM version it is going to be a little easier as I can mostly do a port of the LLVM version. - -License -------- -Ravi itself is licensed under MIT license (including the code that implements the JIT compiler) - however I think that when linked to ``libgccjit`` the effective license will be GPLv3. - -Why another JIT engine? ------------------------ -Well partly as I feel I have a moral obligation to support gcc, given it has been instrumental in bringing about the OpenSource / Free Software ecosystem. - -Secondly I am always looking for alternatives that will let me reduce the footprint of Ravi. The ``libgccjit`` is offered as a shared library - this is a great thing. I hate to have to statically link LLVM. - -LLVM implementation and ``libgccjit`` implementation will both be kept in sync so that user can choose either option. Right now the LLVM implementation is more advanced and new features are implemented there first and then ported to the ``libgccjit`` implementation. - -Building GCC ------------- -I am running Ubuntu 14.04 LTS on VMWare virtual machine. - -I built gcc 5.2 from source as follows. - -1. Extracted gcc-5.2 source to ``~/gcc-5.2.0``. -2. Created a build folder ``~/buildgcc``. -3. Installed various pre-requisites for gcc. -4. Then ran following from inside the build folder:: - - ../gcc-5.2.0/configure --prefix=~/local --enable-host-shared --enable-languages=jit,c++ --disable-bootstrap --disable-multilib - -5. Next performed the build as follows:: - - make - make install - -On Mac OSX Yosemite -------------------- -It appears that the `HomeBrew `_ project supports creating the ``libgccjit 5.2`` library. However the default formula doesn't quite work and needs to be patched for libgccjit to work properly. A patched formula can be found at `here `_. To use the patched version edit the gcc formula and copy the patched version. After that following should build and install gcc 5.2 including the JIT library:: - - brew install gcc --with-jit --without-multilib - -Current Status --------------- -Many bytecodes are now compiled - see below for detailed status. The current version of Ravi passes the Lua test cases using ``libgccjit``. - -Building Ravi with ``libgccjit`` on Linux -------------------------------------- -.. warning:: Note that right now the Ravi's ``libgccjit`` based JIT implementation is work in progress - please expect bugs. - -You can build Ravi with ``libgccjit`` linked in as follows:: - - mkdir build - cd build - export LD_LIBRARY_PATH=~/local/lib64:$LD_LIBRARY_PATH - cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=~/local/bin/gcc -DCMAKE_CXX_COMPILER=~/local/bin/g++ -DLLVM_DIR=~/LLVM/share/llvm/cmake -DLLVM_JIT=ON -DGCC_JIT=OFF .. - make - -Above assumes that gccjit is installed under ``~/local`` as described in Building GCC section above. - -A helloworld test program is built. To run it though you need to ensure that your ``PATH`` and ``LD_LIBRARY_PATH`` variables include ``~/local/bin`` and ``~/local/lib`` respectively. - -Initial Observations --------------------- -In terms of packaging ``libgccjit`` consists of a C header file, a C++ header file and one shared library. That is pretty neat as it simplifies the usage. - -Setting up of the Lua types is proving easier in ``libgccjit`` due to the fact that Lua uses unions extensively and ``libgccjit`` supports defining union types. This means that most of the Lua types can be translated more naturally. LLVM on the other hand does not support unions so I had to carefully define structs that would match the size of the union, and in the JIT compilation use casts where needed. - -JIT Status of Lua/Ravi Bytecodes ---------------------------------- -Following is the status as of 4 July 2015. - -+-------------------------+----------+--------------------------------------------------+ -| name | JITed? | description | -+=========================+==========+==================================================+ -| OP_MOVE | YES | R(A) := R(B) | -+-------------------------+----------+--------------------------------------------------+ -| OP_LOADK | YES | R(A) := Kst(Bx) | -+-------------------------+----------+--------------------------------------------------+ -| OP_LOADKX | NO | R(A) := Kst(extra arg) | -+-------------------------+----------+--------------------------------------------------+ -| OP_LOADBOOL | YES | R(A) := (Bool)B; if (C) pc++ | -+-------------------------+----------+--------------------------------------------------+ -| OP_LOADNIL | YES | R(A), R(A+1), ..., R(A+B) := nil | -+-------------------------+----------+--------------------------------------------------+ -| OP_GETUPVAL | YES | R(A) := UpValue[B] | -+-------------------------+----------+--------------------------------------------------+ -| OP_GETTABUP | YES | R(A) := UpValue[B][RK(C)] | -+-------------------------+----------+--------------------------------------------------+ -| OP_GETTABLE | YES | R(A) := R(B)[RK(C)] | -+-------------------------+----------+--------------------------------------------------+ -| OP_SETTABUP | YES | UpValue[A][RK(B)] := RK(C) | -+-------------------------+----------+--------------------------------------------------+ -| OP_SETUPVAL | YES | UpValue[B] := R(A) | -+-------------------------+----------+--------------------------------------------------+ -| OP_SETTABLE | YES | R(A)[RK(B)] := RK(C) | -+-------------------------+----------+--------------------------------------------------+ -| OP_NEWTABLE | YES | R(A) := {} (size = B,C) | -+-------------------------+----------+--------------------------------------------------+ -| OP_SELF | YES | R(A+1) := R(B); R(A) := R(B)[RK(C)] | -+-------------------------+----------+--------------------------------------------------+ -| OP_ADD | YES | R(A) := RK(B) + RK(C) | -+-------------------------+----------+--------------------------------------------------+ -| OP_SUB | YES | R(A) := RK(B) - RK(C) | -+-------------------------+----------+--------------------------------------------------+ -| OP_MUL | YES | R(A) := RK(B) * RK(C) | -+-------------------------+----------+--------------------------------------------------+ -| OP_MOD | NO | R(A) := RK(B) % RK(C) | -+-------------------------+----------+--------------------------------------------------+ -| OP_POW | NO | R(A) := RK(B) ^ RK(C) | -+-------------------------+----------+--------------------------------------------------+ -| OP_DIV | YES | R(A) := RK(B) / RK(C) | -+-------------------------+----------+--------------------------------------------------+ -| OP_IDIV | NO | R(A) := RK(B) // RK(C) | -+-------------------------+----------+--------------------------------------------------+ -| OP_BAND | NO | R(A) := RK(B) & RK(C) | -+-------------------------+----------+--------------------------------------------------+ -| OP_BOR | NO | R(A) := RK(B) | RK(C) | -+-------------------------+----------+--------------------------------------------------+ -| OP_BXOR | NO | R(A) := RK(B) ~ RK(C) | -+-------------------------+----------+--------------------------------------------------+ -| OP_SHL | NO | R(A) := RK(B) << RK(C) | -+-------------------------+----------+--------------------------------------------------+ -| OP_SHR | NO | R(A) := RK(B) >> RK(C) | -+-------------------------+----------+--------------------------------------------------+ -| OP_UNM | NO | R(A) := -R(B) | -+-------------------------+----------+--------------------------------------------------+ -| OP_BNOT | NO | R(A) := ~R(B) | -+-------------------------+----------+--------------------------------------------------+ -| OP_NOT | YES | R(A) := not R(B) | -+-------------------------+----------+--------------------------------------------------+ -| OP_LEN | YES | R(A) := length of R(B) | -+-------------------------+----------+--------------------------------------------------+ -| OP_CONCAT | YES | R(A) := R(B).. ... ..R(C) | -+-------------------------+----------+--------------------------------------------------+ -| OP_JMP | YES | c+=sBx; if (A) close all upvalues >= R(A - 1) | -+-------------------------+----------+--------------------------------------------------+ -| OP_EQ | YES | if ((RK(B) == RK(C)) ~= A) then pc++ | -+-------------------------+----------+--------------------------------------------------+ -| OP_LT | YES | if ((RK(B) < RK(C)) ~= A) then pc++ | -+-------------------------+----------+--------------------------------------------------+ -| OP_LE | YES | if ((RK(B) <= RK(C)) ~= A) then pc++ | -+-------------------------+----------+--------------------------------------------------+ -| OP_TEST | YES | if not (R(A) <=> C) then pc++ | -+-------------------------+----------+--------------------------------------------------+ -| OP_TESTSET | YES | if (R(B) <=> C) then R(A) := R(B) else pc++ | -+-------------------------+----------+--------------------------------------------------+ -| OP_CALL | YES | R(A), .. ,R(A+C-2) := R(A)(R(A+1), .. ,R(A+B-1)) | -+-------------------------+----------+--------------------------------------------------+ -| OP_TAILCALL | YES | return R(A)(R(A+1), ... ,R(A+B-1)) | -| | | Compiled as OP_CALL so no tail call optimization | -+-------------------------+----------+--------------------------------------------------+ -| OP_RETURN | YES | return R(A), ... ,R(A+B-2) (see note) | -+-------------------------+----------+--------------------------------------------------+ -| OP_FORLOOP | NO | R(A)+=R(A+2); | -| | | if R(A) 1 | -+-------------------------+----------+--------------------------------------------------+ -| OP_RAVI_FORPREP_IP | YES | R(A)-=R(A+2); pc+=sBx | -| | | Specialization for integer step > 1 | -+-------------------------+----------+--------------------------------------------------+ -| OP_RAVI_FORLOOP_I1 | YES | R(A)+=R(A+2); | -| | | if R(A) > RK(C), operands are int | -+-------------------------+----------+--------------------------------------------------+ -| OP_RAVI_BNOT_I | NO | R(A) := ~R(B), int operand | -+-------------------------+----------+--------------------------------------------------+ -| OP_RAVI_EQ_II | YES | if ((RK(B) == RK(C)) ~= A) then pc++ | -+-------------------------+----------+--------------------------------------------------+ -| OP_RAVI_EQ_FF | YES | if ((RK(B) == RK(C)) ~= A) then pc++ | -+-------------------------+----------+--------------------------------------------------+ -| OP_RAVI_LT_II | YES | if ((RK(B) < RK(C)) ~= A) then pc++ | -+-------------------------+----------+--------------------------------------------------+ -| OP_RAVI_LT_FF | YES | if ((RK(B) < RK(C)) ~= A) then pc++ | -+-------------------------+----------+--------------------------------------------------+ -| OP_RAVI_LE_II | YES | if ((RK(B) <= RK(C)) ~= A) then pc++ | -+-------------------------+----------+--------------------------------------------------+ -| OP_RAVI_LE_FF | YES | if ((RK(B) <= RK(C)) ~= A) then pc++ | -+-------------------------+----------+--------------------------------------------------+ - -Ravi's libgccjit JIT compiler source ------------------------------------- -The libgccjit JIT implementation is in following sources: - -* ravijit.h - defines the JIT API -* ravi_gccjit.h - defines the types used by the code generator, and declares prototypes - -* ravijit.cpp - basic JIT infrastructure and Ravi API definition -* ravi_gcctypes.c - contains JIT type definitions for Lua objects -* ravi_gcccodegen.c - JIT compiler - main driver for compiling Lua bytecodes -* ravi_gccload.c - implements OP_LOADK and OP_MOVE, and related operations, also OP_LOADBOOL -* ravi_gcccomp.c - implements OP_EQ, OP_LT, OP_LE, OP_TEST and OP_TESTSET. -* ravi_gccreturn.c - implements OP_RETURN -* ravi_gccforprep.c - implements OP_RAVI_FORPREP_I1 and OP_RAVI_FORPREP_IP -* ravi_gccforloop.c - implements OP_RAVI_FORLOOP_I1 and OP_RAVI_FORLOOP_IP -* ravi_gcctforcall.c - implements OP_TFORCALL and OP_TFORLOOP -* ravi_gccarith1.c - implements various type specialized arithmetic operations - these are Ravi extensions -* ravi_gccarith2.c - implements Lua opcodes such as OP_ADD, OP_SUB, OP_MUL, OP_DIV, OP_UNM -* ravi_gcccall.c - implements OP_CALL, OP_JMP -* ravi_gcctable.c - implements OP_GETTABLE, OP_SETTABLE and various other table operations, OP_SELF, and also upvalue operations -* ravi_gccrest.c - OP_CLOSURE, OP_VARARG, OP_CONCAT diff --git a/readthedocs/ravi-overview.rst b/readthedocs/ravi-overview.rst index aa0ccbf..2442755 100644 --- a/readthedocs/ravi-overview.rst +++ b/readthedocs/ravi-overview.rst @@ -24,7 +24,7 @@ Features * Type specific bytecodes to improve performance * Compatibility with Lua 5.3 (see Compatibility section below) * `LLVM `_ powered JIT compiler -* Additionally a `libgccjit `_ based alternative JIT compiler is also available, although this is not currently being worked on +* Additionally a `libgccjit `_ based alternative JIT compiler is also available (on a branch), although this is not currently being worked on * LLVM bindings exposed in Lua Recent Work @@ -50,8 +50,6 @@ The LLVM JIT compiler is functional. The Lua and Ravi bytecodes currently implem Ravi also provides an `LLVM binding `_; this is still work in progress so please check documentation for the latest status. -There is also a `libgccjit `_ based JIT implementation but this implementation is lagging behind the LLVM based implementation. Further development of this is currently not planned. - Ravi Extensions to Lua 5.3 ========================== @@ -508,7 +506,7 @@ I test the build by running a modified version of Lua 5.3.3 test suite. These te Roadmap ======= * 2015 - Implemented JIT compilation using LLVM -* 2015 - Implemented libgccjit based alternative JIT +* 2015 - Implemented libgccjit based alternative JIT (now discontinued) * 2016 - Implemented debugger for Ravi and Lua 5.3 for `Visual Studio Code `_ * 2017 - Main priorities are: diff --git a/src/ravi_gccarith1.c b/src/ravi_gccarith1.c deleted file mode 100644 index 5fbef22..0000000 --- a/src/ravi_gccarith1.c +++ /dev/null @@ -1,382 +0,0 @@ -/****************************************************************************** -* Copyright (C) 2015 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 - -// R(A) := -R(B), floating point -void ravi_emit_UNMF(ravi_function_def_t *def, int A, int B, int pc) { - (void)pc; - // Load pointer to base - ravi_emit_load_base(def); - gcc_jit_lvalue *ra = ravi_emit_get_register(def, A); - gcc_jit_lvalue *rb = ravi_emit_get_register_or_constant(def, B); - // rb->value_.n - gcc_jit_lvalue *lhs = ravi_emit_load_reg_n(def, rb); - // result = -rb->value_.n; - gcc_jit_rvalue *result = gcc_jit_context_new_unary_op( - def->function_context, NULL, GCC_JIT_UNARY_OP_MINUS, - def->ravi->types->lua_NumberT, gcc_jit_lvalue_as_rvalue(lhs)); - ravi_emit_store_reg_n_withtype(def, result, ra); -} - -// R(A) := -R(B), integer -void ravi_emit_UNMI(ravi_function_def_t *def, int A, int B, int pc) { - (void)pc; - // Load pointer to base - ravi_emit_load_base(def); - gcc_jit_lvalue *ra = ravi_emit_get_register(def, A); - gcc_jit_lvalue *rb = ravi_emit_get_register_or_constant(def, B); - // rb->value_.n - gcc_jit_lvalue *lhs = ravi_emit_load_reg_i(def, rb); - gcc_jit_rvalue *result = gcc_jit_context_new_unary_op( - def->function_context, NULL, GCC_JIT_UNARY_OP_MINUS, - def->ravi->types->lua_IntegerT, gcc_jit_lvalue_as_rvalue(lhs)); - ravi_emit_store_reg_i_withtype(def, result, ra); -} - -// R(A) := RK(B) + RK(C), all floating -void ravi_emit_ADDFF(ravi_function_def_t *def, int A, int B, int C, int pc) { - (void)pc; - // Load pointer to base - ravi_emit_load_base(def); - gcc_jit_lvalue *ra = ravi_emit_get_register(def, A); - gcc_jit_lvalue *rb = ravi_emit_get_register_or_constant(def, B); - gcc_jit_lvalue *rc = ravi_emit_get_register_or_constant(def, C); - // rb->value_.n - gcc_jit_lvalue *lhs = ravi_emit_load_reg_n(def, rb); - // rc->value_.n - gcc_jit_lvalue *rhs = ravi_emit_load_reg_n(def, rc); - // result = rb->value_.n + rc->value_.n - gcc_jit_rvalue *result = gcc_jit_context_new_binary_op( - def->function_context, NULL, GCC_JIT_BINARY_OP_PLUS, - def->ravi->types->lua_NumberT, gcc_jit_lvalue_as_rvalue(lhs), - gcc_jit_lvalue_as_rvalue(rhs)); - // ra->value_.n = result - // ra->tt_ = LUA_TNUMFLT - ravi_emit_store_reg_n_withtype(def, result, ra); -} - -// R(A) := RK(B) * RK(C), float*float -void ravi_emit_MULFF(ravi_function_def_t *def, int A, int B, int C, int pc) { - (void)pc; - // Load pointer to base - ravi_emit_load_base(def); - gcc_jit_lvalue *ra = ravi_emit_get_register(def, A); - gcc_jit_lvalue *rb = ravi_emit_get_register_or_constant(def, B); - gcc_jit_lvalue *rc = ravi_emit_get_register_or_constant(def, C); - // rb->value_.n - gcc_jit_lvalue *lhs = ravi_emit_load_reg_n(def, rb); - // rc->value_.n - gcc_jit_lvalue *rhs = ravi_emit_load_reg_n(def, rc); - // result = rb->value_.n * rc->value_.n - gcc_jit_rvalue *result = gcc_jit_context_new_binary_op( - def->function_context, NULL, GCC_JIT_BINARY_OP_MULT, - def->ravi->types->lua_NumberT, gcc_jit_lvalue_as_rvalue(lhs), - gcc_jit_lvalue_as_rvalue(rhs)); - // ra->value_.n = result - // ra->tt_ = LUA_TNUMFLT - ravi_emit_store_reg_n_withtype(def, result, ra); -} - -// R(A) := RK(B) - RK(C), float-float -void ravi_emit_SUBFF(ravi_function_def_t *def, int A, int B, int C, int pc) { - (void)pc; - // Load pointer to base - ravi_emit_load_base(def); - gcc_jit_lvalue *ra = ravi_emit_get_register(def, A); - gcc_jit_lvalue *rb = ravi_emit_get_register_or_constant(def, B); - gcc_jit_lvalue *rc = ravi_emit_get_register_or_constant(def, C); - // rb->value_.n - gcc_jit_lvalue *lhs = ravi_emit_load_reg_n(def, rb); - // rc->value_.n - gcc_jit_lvalue *rhs = ravi_emit_load_reg_n(def, rc); - // result = rb->value_.n - rc->value_.n - gcc_jit_rvalue *result = gcc_jit_context_new_binary_op( - def->function_context, NULL, GCC_JIT_BINARY_OP_MINUS, - def->ravi->types->lua_NumberT, gcc_jit_lvalue_as_rvalue(lhs), - gcc_jit_lvalue_as_rvalue(rhs)); - // ra->value_.n = result - // ra->tt_ = LUA_TNUMFLT - ravi_emit_store_reg_n_withtype(def, result, ra); -} - -// R(A) := RK(B) / RK(C), float/float -void ravi_emit_DIVFF(ravi_function_def_t *def, int A, int B, int C, int pc) { - (void)pc; - // Load pointer to base - ravi_emit_load_base(def); - gcc_jit_lvalue *ra = ravi_emit_get_register(def, A); - gcc_jit_lvalue *rb = ravi_emit_get_register_or_constant(def, B); - gcc_jit_lvalue *rc = ravi_emit_get_register_or_constant(def, C); - // rb->value_.n - gcc_jit_lvalue *lhs = ravi_emit_load_reg_n(def, rb); - // rc->value_.n - gcc_jit_lvalue *rhs = ravi_emit_load_reg_n(def, rc); - // result = rb->value_.n / rc->value_.n - gcc_jit_rvalue *result = gcc_jit_context_new_binary_op( - def->function_context, NULL, GCC_JIT_BINARY_OP_DIVIDE, - def->ravi->types->lua_NumberT, gcc_jit_lvalue_as_rvalue(lhs), - gcc_jit_lvalue_as_rvalue(rhs)); - // ra->value_.n = result - // ra->tt_ = LUA_TNUMFLT - ravi_emit_store_reg_n_withtype(def, result, ra); -} - -// R(A) := RK(B) + RK(C), float+int -void ravi_emit_ADDFI(ravi_function_def_t *def, int A, int B, int C, int pc) { - (void)pc; - // Load pointer to base - ravi_emit_load_base(def); - gcc_jit_lvalue *ra = ravi_emit_get_register(def, A); - gcc_jit_lvalue *rb = ravi_emit_get_register_or_constant(def, B); - gcc_jit_lvalue *rc = ravi_emit_get_register_or_constant(def, C); - // rb->value_.n - gcc_jit_lvalue *lhs = ravi_emit_load_reg_n(def, rb); - // rc->value_.i - gcc_jit_lvalue *rhs = ravi_emit_load_reg_i(def, rc); - // result = rb->value_.n + (lua_number)rc->value_.i - gcc_jit_rvalue *result = gcc_jit_context_new_binary_op( - def->function_context, NULL, GCC_JIT_BINARY_OP_PLUS, - def->ravi->types->lua_NumberT, gcc_jit_lvalue_as_rvalue(lhs), - gcc_jit_context_new_cast(def->function_context, NULL, - gcc_jit_lvalue_as_rvalue(rhs), - def->ravi->types->lua_NumberT)); - // ra->value_.n = result - // ra->tt_ = LUA_TNUMFLT - ravi_emit_store_reg_n_withtype(def, result, ra); -} - -// R(A) := RK(B) * RK(C), float*int -void ravi_emit_MULFI(ravi_function_def_t *def, int A, int B, int C, int pc) { - (void)pc; - // Load pointer to base - ravi_emit_load_base(def); - gcc_jit_lvalue *ra = ravi_emit_get_register(def, A); - gcc_jit_lvalue *rb = ravi_emit_get_register_or_constant(def, B); - gcc_jit_lvalue *rc = ravi_emit_get_register_or_constant(def, C); - // rb->value_.n - gcc_jit_lvalue *lhs = ravi_emit_load_reg_n(def, rb); - // rc->value_.i - gcc_jit_lvalue *rhs = ravi_emit_load_reg_i(def, rc); - // result = rb->value_.n * (lua_number)rc->value_.i - gcc_jit_rvalue *result = gcc_jit_context_new_binary_op( - def->function_context, NULL, GCC_JIT_BINARY_OP_MULT, - def->ravi->types->lua_NumberT, gcc_jit_lvalue_as_rvalue(lhs), - gcc_jit_context_new_cast(def->function_context, NULL, - gcc_jit_lvalue_as_rvalue(rhs), - def->ravi->types->lua_NumberT)); - // ra->value_.n = result - // ra->tt_ = LUA_TNUMFLT - ravi_emit_store_reg_n_withtype(def, result, ra); -} - -// R(A) := RK(B) - RK(C), float-int -void ravi_emit_SUBFI(ravi_function_def_t *def, int A, int B, int C, int pc) { - (void)pc; - // Load pointer to base - ravi_emit_load_base(def); - gcc_jit_lvalue *ra = ravi_emit_get_register(def, A); - gcc_jit_lvalue *rb = ravi_emit_get_register_or_constant(def, B); - gcc_jit_lvalue *rc = ravi_emit_get_register_or_constant(def, C); - // rb->value_.n - gcc_jit_lvalue *lhs = ravi_emit_load_reg_n(def, rb); - // rc->value_.i - gcc_jit_lvalue *rhs = ravi_emit_load_reg_i(def, rc); - // result = rb->value_.n - (lua_number)rc->value_.i - gcc_jit_rvalue *result = gcc_jit_context_new_binary_op( - def->function_context, NULL, GCC_JIT_BINARY_OP_MINUS, - def->ravi->types->lua_NumberT, gcc_jit_lvalue_as_rvalue(lhs), - gcc_jit_context_new_cast(def->function_context, NULL, - gcc_jit_lvalue_as_rvalue(rhs), - def->ravi->types->lua_NumberT)); - // ra->value_.n = result - // ra->tt_ = LUA_TNUMFLT - ravi_emit_store_reg_n_withtype(def, result, ra); -} - -// R(A) := RK(B) / RK(C), float/int -void ravi_emit_DIVFI(ravi_function_def_t *def, int A, int B, int C, int pc) { - (void)pc; - // Load pointer to base - ravi_emit_load_base(def); - gcc_jit_lvalue *ra = ravi_emit_get_register(def, A); - gcc_jit_lvalue *rb = ravi_emit_get_register_or_constant(def, B); - gcc_jit_lvalue *rc = ravi_emit_get_register_or_constant(def, C); - // rb->value_.n - gcc_jit_lvalue *lhs = ravi_emit_load_reg_n(def, rb); - // rc->value_.i - gcc_jit_lvalue *rhs = ravi_emit_load_reg_i(def, rc); - // result = rb->value_.n / (lua_number)rc->value_.i - gcc_jit_rvalue *result = gcc_jit_context_new_binary_op( - def->function_context, NULL, GCC_JIT_BINARY_OP_DIVIDE, - def->ravi->types->lua_NumberT, gcc_jit_lvalue_as_rvalue(lhs), - gcc_jit_context_new_cast(def->function_context, NULL, - gcc_jit_lvalue_as_rvalue(rhs), - def->ravi->types->lua_NumberT)); - // ra->value_.n = result - // ra->tt_ = LUA_TNUMFLT - ravi_emit_store_reg_n_withtype(def, result, ra); -} - -// R(A) := RK(B) - RK(C), int-float -void ravi_emit_SUBIF(ravi_function_def_t *def, int A, int B, int C, int pc) { - (void)pc; - // Load pointer to base - ravi_emit_load_base(def); - gcc_jit_lvalue *ra = ravi_emit_get_register(def, A); - gcc_jit_lvalue *rb = ravi_emit_get_register_or_constant(def, B); - gcc_jit_lvalue *rc = ravi_emit_get_register_or_constant(def, C); - // rb->value_.i - gcc_jit_lvalue *lhs = ravi_emit_load_reg_i(def, rb); - // rc->value_.n - gcc_jit_lvalue *rhs = ravi_emit_load_reg_n(def, rc); - // result = (lua_Number) rb->value_.i - rc->value_.n - gcc_jit_rvalue *result = gcc_jit_context_new_binary_op( - def->function_context, NULL, GCC_JIT_BINARY_OP_MINUS, - def->ravi->types->lua_NumberT, - gcc_jit_context_new_cast(def->function_context, NULL, - gcc_jit_lvalue_as_rvalue(lhs), - def->ravi->types->lua_NumberT), - gcc_jit_lvalue_as_rvalue(rhs)); - // ra->value_.n = result - // ra->tt_ = LUA_TNUMFLT - ravi_emit_store_reg_n_withtype(def, result, ra); -} - -// R(A) := RK(B) / RK(C), int/float -void ravi_emit_DIVIF(ravi_function_def_t *def, int A, int B, int C, int pc) { - (void)pc; - // Load pointer to base - ravi_emit_load_base(def); - gcc_jit_lvalue *ra = ravi_emit_get_register(def, A); - gcc_jit_lvalue *rb = ravi_emit_get_register_or_constant(def, B); - gcc_jit_lvalue *rc = ravi_emit_get_register_or_constant(def, C); - // rb->value_.i - gcc_jit_lvalue *lhs = ravi_emit_load_reg_i(def, rb); - // rc->value_.n - gcc_jit_lvalue *rhs = ravi_emit_load_reg_n(def, rc); - // result = (lua_Number) rb->value_.i / rc->value_.n - gcc_jit_rvalue *result = gcc_jit_context_new_binary_op( - def->function_context, NULL, GCC_JIT_BINARY_OP_DIVIDE, - def->ravi->types->lua_NumberT, - gcc_jit_context_new_cast(def->function_context, NULL, - gcc_jit_lvalue_as_rvalue(lhs), - def->ravi->types->lua_NumberT), - gcc_jit_lvalue_as_rvalue(rhs)); - // ra->value_.n = result - // ra->tt_ = LUA_TNUMFLT - ravi_emit_store_reg_n_withtype(def, result, ra); -} - -// R(A) := RK(B) + RK(C), int+int -void ravi_emit_ADDII(ravi_function_def_t *def, int A, int B, int C, int pc) { - (void)pc; - // Load pointer to base - ravi_emit_load_base(def); - gcc_jit_lvalue *ra = ravi_emit_get_register(def, A); - gcc_jit_lvalue *rb = ravi_emit_get_register_or_constant(def, B); - gcc_jit_lvalue *rc = ravi_emit_get_register_or_constant(def, C); - // rb->value_.i - gcc_jit_lvalue *lhs = ravi_emit_load_reg_i(def, rb); - // rc->value_.i - gcc_jit_lvalue *rhs = ravi_emit_load_reg_i(def, rc); - // result = rb->value_.i + rc->value_.i - gcc_jit_rvalue *result = gcc_jit_context_new_binary_op( - def->function_context, NULL, GCC_JIT_BINARY_OP_PLUS, - def->ravi->types->lua_IntegerT, gcc_jit_lvalue_as_rvalue(lhs), - gcc_jit_lvalue_as_rvalue(rhs)); - // ra->value_.i = result - // ra->tt_ = LUA_TNUMINT - ravi_emit_store_reg_i_withtype(def, result, ra); -} - -// R(A) := RK(B) * RK(C), int*int -void ravi_emit_MULII(ravi_function_def_t *def, int A, int B, int C, int pc) { - (void)pc; - // Load pointer to base - ravi_emit_load_base(def); - gcc_jit_lvalue *ra = ravi_emit_get_register(def, A); - gcc_jit_lvalue *rb = ravi_emit_get_register_or_constant(def, B); - gcc_jit_lvalue *rc = ravi_emit_get_register_or_constant(def, C); - // rb->value_.i - gcc_jit_lvalue *lhs = ravi_emit_load_reg_i(def, rb); - // rc->value_.i - gcc_jit_lvalue *rhs = ravi_emit_load_reg_i(def, rc); - // result = rb->value_.i * rc->value_.i - gcc_jit_rvalue *result = gcc_jit_context_new_binary_op( - def->function_context, NULL, GCC_JIT_BINARY_OP_MULT, - def->ravi->types->lua_IntegerT, gcc_jit_lvalue_as_rvalue(lhs), - gcc_jit_lvalue_as_rvalue(rhs)); - // ra->value_.i = result - // ra->tt_ = LUA_TNUMINT - ravi_emit_store_reg_i_withtype(def, result, ra); -} - -// R(A) := RK(B) - RK(C), int-int -void ravi_emit_SUBII(ravi_function_def_t *def, int A, int B, int C, int pc) { - (void)pc; - // Load pointer to base - ravi_emit_load_base(def); - gcc_jit_lvalue *ra = ravi_emit_get_register(def, A); - gcc_jit_lvalue *rb = ravi_emit_get_register_or_constant(def, B); - gcc_jit_lvalue *rc = ravi_emit_get_register_or_constant(def, C); - // rb->value_.i - gcc_jit_lvalue *lhs = ravi_emit_load_reg_i(def, rb); - // rc->value_.i - gcc_jit_lvalue *rhs = ravi_emit_load_reg_i(def, rc); - // result = rb->value_.i - rc->value_.i - gcc_jit_rvalue *result = gcc_jit_context_new_binary_op( - def->function_context, NULL, GCC_JIT_BINARY_OP_MINUS, - def->ravi->types->lua_IntegerT, gcc_jit_lvalue_as_rvalue(lhs), - gcc_jit_lvalue_as_rvalue(rhs)); - // ra->value_.i = result - // ra->tt_ = LUA_TNUMINT - ravi_emit_store_reg_i_withtype(def, result, ra); -} - -// R(A) := RK(B) / RK(C), int/int but result is float -void ravi_emit_DIVII(ravi_function_def_t *def, int A, int B, int C, int pc) { - (void)pc; - // Load pointer to base - ravi_emit_load_base(def); - gcc_jit_lvalue *ra = ravi_emit_get_register(def, A); - gcc_jit_lvalue *rb = ravi_emit_get_register_or_constant(def, B); - gcc_jit_lvalue *rc = ravi_emit_get_register_or_constant(def, C); - // rb->value_.i - gcc_jit_lvalue *lhs = ravi_emit_load_reg_i(def, rb); - // rc->value_.i - gcc_jit_lvalue *rhs = ravi_emit_load_reg_i(def, rc); - // result = (lua_Number)rb->value_.i / (lua_Number)rc->value_.i - gcc_jit_rvalue *result = gcc_jit_context_new_binary_op( - def->function_context, NULL, GCC_JIT_BINARY_OP_DIVIDE, - def->ravi->types->lua_IntegerT, - gcc_jit_context_new_cast(def->function_context, NULL, - gcc_jit_lvalue_as_rvalue(lhs), - def->ravi->types->lua_NumberT), - gcc_jit_context_new_cast(def->function_context, NULL, - gcc_jit_lvalue_as_rvalue(rhs), - def->ravi->types->lua_NumberT)); - // ra->value_.i = result - // ra->tt_ = LUA_TNUMINT - ravi_emit_store_reg_i_withtype(def, result, ra); -} diff --git a/src/ravi_gccarith2.c b/src/ravi_gccarith2.c deleted file mode 100644 index 33ab500..0000000 --- a/src/ravi_gccarith2.c +++ /dev/null @@ -1,247 +0,0 @@ -/****************************************************************************** -* Copyright (C) 2015 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 - -// OP_ADD, OP_SUB, OP_MUL and OP_DIV -void ravi_emit_ARITH(ravi_function_def_t *def, int A, int B, int C, OpCode op, - TMS tms, int pc) { - - // TValue *rb = RKB(i); - // TValue *rc = RKC(i); - // lua_Number nb; lua_Number nc; - // if (ttisinteger(rb) && ttisinteger(rc)) { - // lua_Integer ib = ivalue(rb); lua_Integer ic = ivalue(rc); - // setivalue(ra, intop(+, ib, ic)); - //} - // else if (tonumber(rb, &nb) && tonumber(rc, &nc)) { - // setfltvalue(ra, luai_numadd(L, nb, nc)); - //} - // else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_ADD)); } - - gcc_jit_lvalue *nb = gcc_jit_function_new_local( - def->jit_function, NULL, def->ravi->types->lua_NumberT, - unique_name(def, "ARITH_nb", pc)); - gcc_jit_lvalue *nc = gcc_jit_function_new_local( - def->jit_function, NULL, def->ravi->types->lua_NumberT, - unique_name(def, "ARITH_nc", pc)); - - ravi_emit_load_base(def); - gcc_jit_lvalue *ra = ravi_emit_get_register(def, A); - gcc_jit_lvalue *rb = ravi_emit_get_register_or_constant(def, B); - gcc_jit_lvalue *rc = ravi_emit_get_register_or_constant(def, C); - - gcc_jit_lvalue *rb_type = ravi_emit_load_type(def, rb); - gcc_jit_lvalue *rc_type = ravi_emit_load_type(def, rc); - - gcc_jit_block *float_op = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "ARITH_float.op", pc)); - gcc_jit_block *try_meta = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "ARITH_try_meta", pc)); - gcc_jit_block *done_block = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "done", pc)); - - if (op != OP_DIV) { - gcc_jit_rvalue *cmp1 = ravi_emit_is_value_of_type( - def, gcc_jit_lvalue_as_rvalue(rb_type), LUA__TNUMINT); - gcc_jit_rvalue *cmp2 = ravi_emit_is_value_of_type( - def, gcc_jit_lvalue_as_rvalue(rc_type), LUA__TNUMINT); - - gcc_jit_rvalue *andvalue = gcc_jit_context_new_binary_op( - def->function_context, NULL, GCC_JIT_BINARY_OP_LOGICAL_AND, - def->ravi->types->C_boolT, cmp1, cmp2); - - // Check if both RB and RC are integers - gcc_jit_block *then_block = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "ARITH_if_integer", pc)); - gcc_jit_block *else_block = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "ARITH_if_not_integer", pc)); - ravi_emit_conditional_branch(def, andvalue, then_block, else_block); - ravi_set_current_block(def, then_block); - - // Both are integers - gcc_jit_lvalue *lhs = ravi_emit_load_reg_i(def, rb); - gcc_jit_lvalue *rhs = ravi_emit_load_reg_i(def, rc); - - gcc_jit_rvalue *result = NULL; - switch (op) { - case OP_ADD: - result = gcc_jit_context_new_binary_op( - def->function_context, NULL, GCC_JIT_BINARY_OP_PLUS, - def->ravi->types->lua_IntegerT, gcc_jit_lvalue_as_rvalue(lhs), - gcc_jit_lvalue_as_rvalue(rhs)); - break; - case OP_SUB: - result = gcc_jit_context_new_binary_op( - def->function_context, NULL, GCC_JIT_BINARY_OP_MINUS, - def->ravi->types->lua_IntegerT, gcc_jit_lvalue_as_rvalue(lhs), - gcc_jit_lvalue_as_rvalue(rhs)); - break; - case OP_MUL: - result = gcc_jit_context_new_binary_op( - def->function_context, NULL, GCC_JIT_BINARY_OP_MULT, - def->ravi->types->lua_IntegerT, gcc_jit_lvalue_as_rvalue(lhs), - gcc_jit_lvalue_as_rvalue(rhs)); - break; - default: - lua_assert(0); - } - - ravi_emit_store_reg_i_withtype(def, result, ra); - - ravi_emit_branch(def, done_block); - - // Not integer - ravi_set_current_block(def, else_block); - } - - // Is RB a float? - gcc_jit_rvalue *cmp1 = ravi_emit_is_value_of_type( - def, gcc_jit_lvalue_as_rvalue(rb_type), LUA__TNUMFLT); - - gcc_jit_block *convert_rb = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "ARITH_convert_rb", pc)); - gcc_jit_block *test_rc = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "ARITH_test_rc", pc)); - gcc_jit_block *load_rb = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "ARITH_load_rb", pc)); - - // If RB is floating then load RB, else convert RB - ravi_emit_conditional_branch(def, cmp1, load_rb, convert_rb); - - // Convert RB - ravi_set_current_block(def, convert_rb); - - // Call luaV_tonumber_() - gcc_jit_rvalue *rb_isnum = - ravi_function_call2_rvalue(def, def->ravi->types->luaV_tonumberT, - gcc_jit_lvalue_get_address(rb, NULL), - gcc_jit_lvalue_get_address(nb, NULL)); - cmp1 = ravi_emit_comparison(def, GCC_JIT_COMPARISON_EQ, rb_isnum, - ravi_int_constant(def, 1)); - - // If not number then go to meta block - // Else proceed to test RC - ravi_emit_conditional_branch(def, cmp1, test_rc, try_meta); - - ravi_set_current_block(def, load_rb); - - // Copy RB to local nb - gcc_jit_lvalue *src = ravi_emit_load_reg_n(def, rb); - gcc_jit_block_add_assignment(def->current_block, NULL, nb, - gcc_jit_lvalue_as_rvalue(src)); - - ravi_emit_branch(def, test_rc); - - ravi_set_current_block(def, test_rc); - - // Is RC a float? - cmp1 = ravi_emit_is_value_of_type(def, gcc_jit_lvalue_as_rvalue(rc_type), - LUA__TNUMFLT); - - gcc_jit_block *convert_rc = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "ARITH_convert_rc", pc)); - gcc_jit_block *load_rc = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "ARITH_load_rc", pc)); - - // If RC is float load RC - // else try to convert RC - ravi_emit_conditional_branch(def, cmp1, load_rc, convert_rc); - - ravi_set_current_block(def, convert_rc); - - // Call luaV_tonumber_() - gcc_jit_rvalue *rc_isnum = - ravi_function_call2_rvalue(def, def->ravi->types->luaV_tonumberT, - gcc_jit_lvalue_get_address(rc, NULL), - gcc_jit_lvalue_get_address(nc, NULL)); - cmp1 = ravi_emit_comparison(def, GCC_JIT_COMPARISON_EQ, rc_isnum, - ravi_int_constant(def, 1)); - - // If not number then go to meta block - // else both RB and RC float so go to op - ravi_emit_conditional_branch(def, cmp1, float_op, try_meta); - - ravi_set_current_block(def, load_rc); - - // Copy RC to local; - src = ravi_emit_load_reg_n(def, rc); - gcc_jit_block_add_assignment(def->current_block, NULL, nc, - gcc_jit_lvalue_as_rvalue(src)); - - ravi_emit_branch(def, float_op); - - ravi_set_current_block(def, float_op); - - gcc_jit_lvalue *lhs = nb; - gcc_jit_lvalue *rhs = nc; - - gcc_jit_rvalue *result = NULL; - // Add and set RA - switch (op) { - case OP_ADD: - result = gcc_jit_context_new_binary_op( - def->function_context, NULL, GCC_JIT_BINARY_OP_PLUS, - def->ravi->types->lua_NumberT, gcc_jit_lvalue_as_rvalue(lhs), - gcc_jit_lvalue_as_rvalue(rhs)); - break; - case OP_SUB: - result = gcc_jit_context_new_binary_op( - def->function_context, NULL, GCC_JIT_BINARY_OP_MINUS, - def->ravi->types->lua_NumberT, gcc_jit_lvalue_as_rvalue(lhs), - gcc_jit_lvalue_as_rvalue(rhs)); - break; - case OP_MUL: - result = gcc_jit_context_new_binary_op( - def->function_context, NULL, GCC_JIT_BINARY_OP_MULT, - def->ravi->types->lua_NumberT, gcc_jit_lvalue_as_rvalue(lhs), - gcc_jit_lvalue_as_rvalue(rhs)); - break; - case OP_DIV: - result = gcc_jit_context_new_binary_op( - def->function_context, NULL, GCC_JIT_BINARY_OP_DIVIDE, - def->ravi->types->lua_NumberT, gcc_jit_lvalue_as_rvalue(lhs), - gcc_jit_lvalue_as_rvalue(rhs)); - break; - default: - lua_assert(0); - } - - ravi_emit_store_reg_n_withtype(def, result, ra); - - ravi_emit_branch(def, done_block); - - // Neither integer nor float so try meta - ravi_set_current_block(def, try_meta); - - gcc_jit_block_add_eval( - def->current_block, NULL, - ravi_function_call5_rvalue( - def, def->ravi->types->luaT_trybinTMT, - gcc_jit_param_as_rvalue(def->L), gcc_jit_lvalue_get_address(rb, NULL), - gcc_jit_lvalue_get_address(rc, NULL), - gcc_jit_lvalue_get_address(ra, NULL), ravi_int_constant(def, tms))); - ravi_emit_branch(def, done_block); - - ravi_set_current_block(def, done_block); -} diff --git a/src/ravi_gcccall.c b/src/ravi_gcccall.c deleted file mode 100644 index b62b7f9..0000000 --- a/src/ravi_gcccall.c +++ /dev/null @@ -1,170 +0,0 @@ -/****************************************************************************** -* Copyright (C) 2015 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 -#include - -// OP_JMP -void ravi_emit_JMP(ravi_function_def_t *def, int A, int j, int pc) { - - //#define dojump(ci,i,e) - // { int a = GETARG_A(i); - // if (a > 0) luaF_close(L, ci->u.l.base + a - 1); - // ci->u.l.savedpc += GETARG_sBx(i) + e; } - // - // dojump(ci, i, 0); - - assert(def->jmp_targets[j]->jmp); - if (def->current_block_terminated) { - gcc_jit_block *jmp_block = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "OP_JMP", pc)); - ravi_set_current_block(def, jmp_block); - } - // ravi_debug_printf2(def, "OP_JMP(%d) jmp to %d\n", ravi_int_constant(def, - // pc+1), ravi_int_constant(def, j+1)); - - // if (a > 0) luaF_close(L, ci->u.l.base + a - 1); - if (A > 0) { - ravi_emit_load_base(def); - // base + a - 1 - gcc_jit_lvalue *val = ravi_emit_get_register(def, A - 1); - // Call luaF_close - gcc_jit_block_add_eval( - def->current_block, NULL, - ravi_function_call2_rvalue(def, def->ravi->types->luaF_closeT, - gcc_jit_param_as_rvalue(def->L), - gcc_jit_lvalue_get_address(val, NULL))); - } - - ravi_emit_branch(def, def->jmp_targets[j]->jmp); - - gcc_jit_block *block = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "OP_JMP_post", pc)); - ravi_set_current_block(def, block); -} - -// Handle OP_CALL -void ravi_emit_CALL(ravi_function_def_t *def, int A, int B, int C, int pc) { - - // int nresults = c - 1; - // if (b != 0) - // L->top = ra + b; /* else previous instruction set top */ - // int c = luaD_precall(L, ra, nresults); /* C or JITed function? */ - // if (c) { - // if (c == 1 && nresults >= 0) - // L->top = ci->top; /* adjust results if C function */ - // } - // else { /* Lua function */ - // luaV_execute(L); - // } - - ravi_emit_load_base(def); - - // int nresults = c - 1; - int nresults = C - 1; - - // if (b != 0) - if (B != 0) { - ravi_emit_set_L_top_toreg(def, A + B); - } - - // luaD_precall() returns following - // 1 - C function called, results to be adjusted - // 2 - JITed Lua function called, no action - // 0 - Run interpreter on Lua function - - // int c = luaD_precall(L, ra, nresults); /* C or JITed function? */ - gcc_jit_lvalue *ra = ravi_emit_get_register(def, A); - gcc_jit_rvalue *nresults_const = gcc_jit_context_new_rvalue_from_int( - def->function_context, def->ravi->types->C_intT, nresults); - gcc_jit_rvalue *precall_result = ravi_function_call4_rvalue( - def, def->ravi->types->luaD_precallT, gcc_jit_param_as_rvalue(def->L), - gcc_jit_lvalue_get_address(ra, NULL), nresults_const, - ravi_int_constant(def, 1)); - /* Need to save the result of the luaD_precall() so that we can do another - * check later on - */ - gcc_jit_lvalue *tmp_var = gcc_jit_function_new_local( - def->jit_function, NULL, def->ravi->types->C_intT, - unique_name(def, "OP_CALL_luaD_precall_result", pc)); - gcc_jit_block_add_assignment(def->current_block, NULL, tmp_var, - precall_result); - gcc_jit_rvalue *zero_const = gcc_jit_context_new_rvalue_from_int( - def->function_context, def->ravi->types->C_intT, 0); - gcc_jit_rvalue *precall_bool = - ravi_emit_comparison(def, GCC_JIT_COMPARISON_EQ, - gcc_jit_lvalue_as_rvalue(tmp_var), zero_const); - - gcc_jit_block *then_block = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "OP_CALL_if_lua_function", pc)); - gcc_jit_block *else_block = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "OP_CALL_else_lua_function", pc)); - gcc_jit_block *end_block = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "OP_CALL_done", pc)); - - ravi_emit_conditional_branch(def, precall_bool, then_block, else_block); - ravi_set_current_block(def, then_block); - - // Lua function, not compiled, so call luaV_execute - gcc_jit_rvalue *b = ravi_function_call1_rvalue( - def, def->ravi->types->luaV_executeT, gcc_jit_param_as_rvalue(def->L)); - - // If the return value is non zero then we need to refresh L->top = ci->top - gcc_jit_rvalue *b_not_zero = ravi_emit_comparison( - def, GCC_JIT_COMPARISON_NE, b, ravi_int_constant(def, 0)); - - gcc_jit_block *if_b_block = gcc_jit_function_new_block( - def->jit_function, - unique_name(def, "OP_CALL_if_luaV_execute_b_value", pc)); - ravi_emit_conditional_branch(def, b_not_zero, if_b_block, else_block); - - ravi_set_current_block(def, if_b_block); - - ravi_emit_refresh_L_top(def); - ravi_emit_branch(def, end_block); - - ravi_set_current_block(def, else_block); - - if (nresults >= 0) { - // In case the precall returned 1 then a C function was - // called so we need to update L->top - // if (c == 1 && nresults >= 0) - // L->top = ci->top; /* adjust results if C function */ - gcc_jit_rvalue *one_const = gcc_jit_context_new_rvalue_from_int( - def->function_context, def->ravi->types->C_intT, 1); - gcc_jit_rvalue *precall_C = - ravi_emit_comparison(def, GCC_JIT_COMPARISON_EQ, - gcc_jit_lvalue_as_rvalue(tmp_var), one_const); - - gcc_jit_block *then1_block = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "OP_CALL_if_C_function", pc)); - ravi_emit_conditional_branch(def, precall_C, then1_block, end_block); - ravi_set_current_block(def, then1_block); - - // L->top = ci->top; /* adjust results if C function */ - ravi_emit_refresh_L_top(def); - } - - ravi_emit_branch(def, end_block); - ravi_set_current_block(def, end_block); -} diff --git a/src/ravi_gcccodegen.c b/src/ravi_gcccodegen.c deleted file mode 100644 index 587b3d3..0000000 --- a/src/ravi_gcccodegen.c +++ /dev/null @@ -1,1503 +0,0 @@ -/****************************************************************************** -* Copyright (C) 2015 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 -#include -#include -#include - -// Create a unique function name in the context -// of this generator -static const char *unique_function_name(ravi_function_def_t *def, - ravi_gcc_codegen_t *cg) { - snprintf(def->name, sizeof def->name, "ravif%d", cg->id++); - return def->name; -} - -const char *unique_name(ravi_function_def_t *def, const char *prefix, int pc) { - snprintf(def->buf, sizeof def->buf, "%s_%d_%d", prefix, pc, def->counter++); - return def->buf; -} - -// We can only compile a subset of op codes -// and not all features are supported -static bool can_compile(Proto *p) { - if (p->ravi_jit.jit_status == 1) - return false; - const Instruction *code = p->code; - int pc, n = p->sizecode; - // Loop over the byte codes; as Lua compiler inserts - // an extra RETURN op we need to ignore the last op - for (pc = 0; pc < n; pc++) { - Instruction i = code[pc]; - OpCode o = GET_OPCODE(i); - switch (o) { - case OP_RETURN: - case OP_LOADK: - case OP_LOADKX: - case OP_RAVI_FORLOOP_IP: - case OP_RAVI_FORLOOP_I1: - case OP_RAVI_FORPREP_IP: - case OP_RAVI_FORPREP_I1: - case OP_MOVE: - case OP_LOADNIL: - case OP_RAVI_LOADIZ: - case OP_RAVI_LOADFZ: - case OP_CALL: - case OP_TAILCALL: - case OP_JMP: - case OP_EQ: - case OP_RAVI_EQ_II: - case OP_RAVI_EQ_FF: - case OP_LT: - case OP_RAVI_LT_II: - case OP_RAVI_LT_FF: - case OP_LE: - case OP_RAVI_LE_II: - case OP_RAVI_LE_FF: - case OP_GETTABUP: - case OP_LOADBOOL: - case OP_NOT: - case OP_TEST: - case OP_TESTSET: - case OP_RAVI_MOVEI: - case OP_RAVI_MOVEF: - case OP_RAVI_TOINT: - case OP_RAVI_TOFLT: - case OP_VARARG: - case OP_CONCAT: - case OP_CLOSURE: - case OP_RAVI_ADDFF: - case OP_RAVI_ADDFI: - case OP_RAVI_ADDII: - case OP_RAVI_SUBFF: - case OP_RAVI_SUBFI: - case OP_RAVI_SUBIF: - case OP_RAVI_SUBII: - case OP_RAVI_MULFF: - case OP_RAVI_MULFI: - case OP_RAVI_MULII: - case OP_RAVI_DIVFF: - case OP_RAVI_DIVFI: - case OP_RAVI_DIVIF: - case OP_RAVI_DIVII: - case OP_SELF: - case OP_LEN: - case OP_SETTABLE: - case OP_GETTABLE: - case OP_NEWTABLE: - case OP_SETLIST: - case OP_TFORCALL: - case OP_TFORLOOP: - case OP_RAVI_NEWARRAYI: - case OP_RAVI_NEWARRAYF: - case OP_RAVI_GETTABLE_AI: - case OP_RAVI_GETTABLE_AF: - case OP_RAVI_TOARRAYI: - case OP_RAVI_TOARRAYF: - case OP_RAVI_MOVEAI: - case OP_RAVI_MOVEAF: - case OP_RAVI_SETTABLE_AI: - case OP_RAVI_SETTABLE_AII: - case OP_RAVI_SETTABLE_AF: - case OP_RAVI_SETTABLE_AFF: - case OP_SETTABUP: - case OP_ADD: - case OP_SUB: - case OP_MUL: - case OP_DIV: - case OP_GETUPVAL: - case OP_SETUPVAL: - break; - case OP_FORPREP: - case OP_FORLOOP: - case OP_MOD: - case OP_IDIV: - case OP_UNM: - case OP_POW: - default: { - p->ravi_jit.jit_status = 1; - return false; - } - } - } - return true; -} - -static bool create_function(ravi_gcc_codegen_t *codegen, - ravi_function_def_t *def) { - - /* The child context will hold function specific stuff - so that we can - * release - * this when we have compiled the function - */ - def->function_context = - gcc_jit_context_new_child_context(codegen->ravi->context); - if (!def->function_context) { - fprintf(stderr, "error creating child context\n"); - goto on_error; - } - // gcc_jit_context_set_bool_option(def->function_context, - // GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING, 1); - // gcc_jit_context_set_bool_option(def->function_context, - // GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES, 1); - if (def->dump_asm) { - gcc_jit_context_set_bool_option(def->function_context, - GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 1); - // gcc_jit_context_set_bool_option(def->function_context, - // GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE, - // 1); - gcc_jit_context_set_bool_option(def->function_context, - GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, 1); - } - gcc_jit_context_set_bool_allow_unreachable_blocks(def->function_context, 1); - gcc_jit_context_set_int_option(def->function_context, - GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, - def->opt_level); - // gcc_jit_context_add_command_line_option(def->function_context, - // "-fno-strict-aliasing"); - - /* each function is given a unique name - as Lua functions are closures and do - * not really have names */ - unique_function_name(def, codegen); - - /* the function signature is int (*) (lua_State *) */ - gcc_jit_param *param = gcc_jit_context_new_param( - def->function_context, NULL, codegen->ravi->types->plua_StateT, "L"); - def->L = param; /* store the L parameter as we will need it */ - def->jit_function = gcc_jit_context_new_function( - def->function_context, NULL, GCC_JIT_FUNCTION_EXPORTED, - codegen->ravi->types->C_intT, def->name, 1, ¶m, 0); - - /* The entry block of the function */ - def->entry_block = gcc_jit_function_new_block(def->jit_function, "entry"); - def->current_block = def->entry_block; - - // def->base = gcc_jit_function_new_local(def->jit_function, NULL, - // def->ravi->types->pTValueT, - // "base"); - def->lua_closure_val = gcc_jit_function_new_local( - def->jit_function, NULL, def->ravi->types->pLClosureT, "cl"); - - return true; - -on_error: - return false; -} - -/* release the resources allocated when compiling a function - * note that the compiled function is not released here */ -static void free_function_def(ravi_function_def_t *def) { - if (def->function_context) - gcc_jit_context_release(def->function_context); - if (def->jmp_targets) { - for (int i = 0; i < def->p->sizecode; i++) { - if (def->jmp_targets[i]) - free(def->jmp_targets[i]); - } - free(def->jmp_targets); - } -} - -/* Scan the Lua bytecode to identify the jump targets and pre-create - * basic blocks for each target. The blocks are saved in an array - * def->jmp_targets - * which is indexed by the byte code offset 0 .. p->sizecode-1. - */ -static void scan_jump_targets(ravi_function_def_t *def, Proto *p) { - // We need to pre-create blocks for jump targets so that we - // can generate branch instructions in the code - const Instruction *code = p->code; - int pc, n = p->sizecode; - def->jmp_targets = - (ravi_branch_def_t **)calloc(n, sizeof(ravi_branch_def_t *)); - for (pc = 0; pc < n; pc++) { - Instruction i = code[pc]; - OpCode op = GET_OPCODE(i); - switch (op) { - case OP_LOADBOOL: { - int C = GETARG_C(i); - int j = pc + 2; // jump target - if (C && !def->jmp_targets[j]) { - def->jmp_targets[j] = - (ravi_branch_def_t *)calloc(1, sizeof(ravi_branch_def_t)); - def->jmp_targets[j]->jmp = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "loadbool", j)); - } - } break; - case OP_JMP: - case OP_RAVI_FORPREP_IP: - case OP_RAVI_FORPREP_I1: - case OP_RAVI_FORLOOP_IP: - case OP_RAVI_FORLOOP_I1: - case OP_FORLOOP: - case OP_FORPREP: - case OP_TFORLOOP: { - const char *targetname = NULL; - if (op == OP_JMP) - targetname = "jmp"; - else if (op == OP_FORLOOP || op == OP_RAVI_FORLOOP_IP || - op == OP_RAVI_FORLOOP_I1) - targetname = "forbody"; - else if (op == OP_FORPREP || op == OP_RAVI_FORPREP_IP || - op == OP_RAVI_FORPREP_I1) - targetname = "forloop"; - else - targetname = "tforbody"; - int sbx = GETARG_sBx(i); - int j = sbx + pc + 1; - if (!def->jmp_targets[j]) { - def->jmp_targets[j] = - (ravi_branch_def_t *)calloc(1, sizeof(ravi_branch_def_t)); - def->jmp_targets[j]->jmp = gcc_jit_function_new_block( - def->jit_function, unique_name(def, targetname, j + 1)); - } - } break; - default: - break; - } - } -} - -void ravi_emit_raise_lua_error(ravi_function_def_t *def, const char *str) { - gcc_jit_block_add_eval( - def->current_block, NULL, - ravi_function_call2_rvalue( - def, def->ravi->types->luaG_runerrorT, - gcc_jit_param_as_rvalue(def->L), - gcc_jit_context_new_string_literal(def->function_context, str))); -} - -void ravi_emit_struct_assign(ravi_function_def_t *def, gcc_jit_lvalue *dest, - gcc_jit_lvalue *src) { - // gcc_jit_block_add_assignment(def->current_block, NULL, - // gcc_jit_rvalue_dereference(dest, NULL), - // gcc_jit_lvalue_as_rvalue(gcc_jit_rvalue_dereference(src, - // NULL))); - gcc_jit_lvalue *dest_value = - gcc_jit_lvalue_access_field(dest, NULL, def->ravi->types->Value_value); - assert(!gcc_jit_context_get_first_error(def->function_context)); - - gcc_jit_lvalue *dest_value_i = gcc_jit_lvalue_access_field( - dest_value, NULL, def->ravi->types->Value_value_i); - - gcc_jit_lvalue *src_value = - gcc_jit_lvalue_access_field(src, NULL, def->ravi->types->Value_value); - assert(!gcc_jit_context_get_first_error(def->function_context)); - - gcc_jit_lvalue *src_value_i = gcc_jit_lvalue_access_field( - src_value, NULL, def->ravi->types->Value_value_i); - - gcc_jit_block_add_assignment(def->current_block, NULL, dest_value_i, - gcc_jit_lvalue_as_rvalue(src_value_i)); - - gcc_jit_lvalue *dest_tt = - gcc_jit_lvalue_access_field(dest, NULL, def->ravi->types->Value_tt); - gcc_jit_lvalue *src_tt = - gcc_jit_lvalue_access_field(src, NULL, def->ravi->types->Value_tt); - - gcc_jit_block_add_assignment(def->current_block, NULL, dest_tt, - gcc_jit_lvalue_as_rvalue(src_tt)); -} - -void ravi_dump_rvalue(gcc_jit_rvalue *rv) { - const char *debugstr = - gcc_jit_object_get_debug_string(gcc_jit_rvalue_as_object(rv)); - fprintf(stderr, "%s\n", debugstr); -} - -void ravi_dump_lvalue(gcc_jit_lvalue *lv) { - const char *debugstr = - gcc_jit_object_get_debug_string(gcc_jit_lvalue_as_object(lv)); - fprintf(stderr, "%s\n", debugstr); -} - -/* Obtain reference to currently executing function (LClosure*) - * L->ci->func.value_.gc */ -static void emit_ci_func_value_gc_asLClosure(ravi_function_def_t *def, - gcc_jit_lvalue *ci) { - gcc_jit_lvalue *func = gcc_jit_rvalue_dereference_field( - gcc_jit_lvalue_as_rvalue(ci), NULL, def->ravi->types->CallInfo_func); - gcc_jit_lvalue *value = gcc_jit_rvalue_dereference_field( - gcc_jit_lvalue_as_rvalue(func), NULL, def->ravi->types->Value_value); - gcc_jit_lvalue *gc = gcc_jit_lvalue_access_field( - value, NULL, def->ravi->types->Value_value_gc); - - def->lua_closure = gcc_jit_context_new_cast(def->function_context, NULL, - gcc_jit_lvalue_as_rvalue(gc), - def->ravi->types->pLClosureT); - gcc_jit_block_add_assignment(def->current_block, NULL, def->lua_closure_val, - def->lua_closure); -} - -/* Obtain reference to L->ci */ -static void emit_getL_ci_value(ravi_function_def_t *def) { - def->ci_val = gcc_jit_rvalue_dereference_field( - gcc_jit_param_as_rvalue(def->L), NULL, def->ravi->types->lua_State_ci); -} - -/* Refresh local copy of L->ci->u.l.base */ -void ravi_emit_load_base(ravi_function_def_t *def) { - (void)def; - // gcc_jit_block_add_assignment(def->current_block, NULL, def->base, - // def->base_ref); -} - -// L->top = ci->top -void ravi_emit_refresh_L_top(ravi_function_def_t *def) { - // Load ci->top - gcc_jit_lvalue *citop = - gcc_jit_rvalue_dereference_field(gcc_jit_lvalue_as_rvalue(def->ci_val), - NULL, def->ravi->types->CallInfo_top); - - // Get L->top - gcc_jit_lvalue *top = gcc_jit_rvalue_dereference_field( - gcc_jit_param_as_rvalue(def->L), NULL, def->ravi->types->lua_State_top); - - // Assign ci>top to L->top - gcc_jit_block_add_assignment(def->current_block, NULL, top, - gcc_jit_lvalue_as_rvalue(citop)); -} - -gcc_jit_rvalue *ravi_emit_array_get(ravi_function_def_t *def, - gcc_jit_rvalue *ptr, - gcc_jit_rvalue *index) { - /* Note we assume that base is correct */ - gcc_jit_lvalue *el = - gcc_jit_context_new_array_access(def->function_context, NULL, ptr, index); - return gcc_jit_lvalue_as_rvalue(el); -} - -gcc_jit_lvalue *ravi_emit_array_get_ptr(ravi_function_def_t *def, - gcc_jit_rvalue *ptr, - gcc_jit_rvalue *index) { - /* Note we assume that base is correct */ - gcc_jit_lvalue *el = - gcc_jit_context_new_array_access(def->function_context, NULL, ptr, index); - return el; -} - -/* Get access to the register identified by A - registers as just &base[offset] - */ -gcc_jit_lvalue *ravi_emit_get_register(ravi_function_def_t *def, int A) { - /* Note we assume that base is correct */ - gcc_jit_lvalue *reg = gcc_jit_context_new_array_access( - // def->function_context, NULL, gcc_jit_lvalue_as_rvalue(def->base), - def->function_context, NULL, def->base_ref, - gcc_jit_context_new_rvalue_from_int(def->function_context, - def->ravi->types->C_intT, A)); - return reg; -} - -/* Get access to a constant identify by Bx */ -gcc_jit_lvalue *ravi_emit_get_constant(ravi_function_def_t *def, int Bx) { - gcc_jit_lvalue *kst = gcc_jit_context_new_array_access( - def->function_context, NULL, def->k, - gcc_jit_context_new_rvalue_from_int(def->function_context, - def->ravi->types->C_intT, Bx)); - return kst; -} - -gcc_jit_lvalue *ravi_emit_get_register_or_constant(ravi_function_def_t *def, - int B) { - if (ISK(B)) - return ravi_emit_get_constant(def, INDEXK(B)); - else - return ravi_emit_get_register(def, B); -} - -// L->top = R(B) -void ravi_emit_set_L_top_toreg(ravi_function_def_t *def, int B) { - // Get pointer to register at R(B) - gcc_jit_lvalue *reg = ravi_emit_get_register(def, B); - // Get pointer to L->top - gcc_jit_lvalue *top = gcc_jit_rvalue_dereference_field( - gcc_jit_param_as_rvalue(def->L), NULL, def->ravi->types->lua_State_top); - // L->top = R(B) - gcc_jit_block_add_assignment(def->current_block, NULL, top, - gcc_jit_lvalue_get_address(reg, NULL)); -} - -gcc_jit_rvalue *ravi_emit_num_stack_elements(ravi_function_def_t *def, - gcc_jit_rvalue *ra) { - gcc_jit_lvalue *top = gcc_jit_rvalue_dereference_field( - gcc_jit_param_as_rvalue(def->L), NULL, def->ravi->types->lua_State_top); - gcc_jit_rvalue *diff = gcc_jit_context_new_binary_op( - def->function_context, NULL, GCC_JIT_BINARY_OP_MINUS, - def->ravi->types->C_ptrdiff_t, gcc_jit_lvalue_as_rvalue(top), ra); - gcc_jit_rvalue *n_elements = gcc_jit_context_new_binary_op( - def->function_context, NULL, GCC_JIT_BINARY_OP_DIVIDE, - def->ravi->types->C_ptrdiff_t, diff, - gcc_jit_context_new_rvalue_from_int(def->function_context, - def->ravi->types->C_ptrdiff_t, - sizeof(TValue))); - gcc_jit_rvalue *n = gcc_jit_context_new_cast( - def->function_context, NULL, n_elements, def->ravi->types->C_intT); - return n; -} - -/* Obtain reference to L->ci->u.l.base */ -static void emit_getL_base_reference(ravi_function_def_t *def, - gcc_jit_lvalue *ci) { - gcc_jit_lvalue *u = gcc_jit_rvalue_dereference_field( - gcc_jit_lvalue_as_rvalue(ci), NULL, def->ravi->types->CallInfo_u); - gcc_jit_rvalue *u_l = gcc_jit_rvalue_access_field( - gcc_jit_lvalue_as_rvalue(u), NULL, def->ravi->types->CallInfo_u_l); - gcc_jit_rvalue *u_l_base = gcc_jit_rvalue_access_field( - u_l, NULL, def->ravi->types->CallInfo_u_l_base); - def->base_ref = u_l_base; - ravi_emit_load_base(def); -} - -/* Get TValue->value_.i */ -gcc_jit_lvalue *ravi_emit_load_reg_i(ravi_function_def_t *def, - gcc_jit_lvalue *tv) { - gcc_jit_lvalue *value = - gcc_jit_lvalue_access_field(tv, NULL, def->ravi->types->Value_value); - assert(!gcc_jit_context_get_first_error(def->function_context)); - - gcc_jit_lvalue *i = - gcc_jit_lvalue_access_field(value, NULL, def->ravi->types->Value_value_i); - return i; -} - -/* Get TValue->value_.b */ -gcc_jit_lvalue *ravi_emit_load_reg_b(ravi_function_def_t *def, - gcc_jit_lvalue *tv) { - gcc_jit_lvalue *value = - gcc_jit_lvalue_access_field(tv, NULL, def->ravi->types->Value_value); - assert(!gcc_jit_context_get_first_error(def->function_context)); - gcc_jit_lvalue *i = - gcc_jit_lvalue_access_field(value, NULL, def->ravi->types->Value_value_b); - return i; -} - -/* Get TValue->value_.n */ -gcc_jit_lvalue *ravi_emit_load_reg_n(ravi_function_def_t *def, - gcc_jit_lvalue *tv) { - gcc_jit_lvalue *value = - gcc_jit_lvalue_access_field(tv, NULL, def->ravi->types->Value_value); - assert(!gcc_jit_context_get_first_error(def->function_context)); - gcc_jit_lvalue *n = - gcc_jit_lvalue_access_field(value, NULL, def->ravi->types->Value_value_n); - return n; -} - -/* Get (Table *) TValue->value_.gc */ -gcc_jit_rvalue *ravi_emit_load_reg_h(ravi_function_def_t *def, - gcc_jit_lvalue *tv) { - - gcc_jit_lvalue *value = - gcc_jit_lvalue_access_field(tv, NULL, def->ravi->types->Value_value); - assert(!gcc_jit_context_get_first_error(def->function_context)); - gcc_jit_lvalue *gc = gcc_jit_lvalue_access_field( - value, NULL, def->ravi->types->Value_value_gc); - gcc_jit_rvalue *h = gcc_jit_context_new_cast(def->function_context, NULL, - gcc_jit_lvalue_as_rvalue(gc), - def->ravi->types->pTableT); - return h; -} - -/* Get Table->ravi_array.data as lua_Number* */ -gcc_jit_rvalue *ravi_emit_load_reg_h_floatarray(ravi_function_def_t *def, - gcc_jit_rvalue *h) { - - gcc_jit_lvalue *value = gcc_jit_rvalue_dereference_field( - h, NULL, def->ravi->types->Table_ravi_array); - gcc_jit_lvalue *data = gcc_jit_lvalue_access_field( - value, NULL, def->ravi->types->RaviArray_data); - gcc_jit_rvalue *floatarray = gcc_jit_context_new_cast( - def->function_context, NULL, gcc_jit_lvalue_as_rvalue(data), - def->ravi->types->plua_NumberT); - return floatarray; -} - -/* Get Table->ravi_array.data as lua_Integer* */ -gcc_jit_rvalue *ravi_emit_load_reg_h_intarray(ravi_function_def_t *def, - gcc_jit_rvalue *h) { - - gcc_jit_lvalue *value = gcc_jit_rvalue_dereference_field( - h, NULL, def->ravi->types->Table_ravi_array); - gcc_jit_lvalue *data = gcc_jit_lvalue_access_field( - value, NULL, def->ravi->types->RaviArray_data); - gcc_jit_rvalue *intarray = gcc_jit_context_new_cast( - def->function_context, NULL, gcc_jit_lvalue_as_rvalue(data), - def->ravi->types->plua_IntegerT); - return intarray; -} - -/* Get Table->ravi_array.len */ -gcc_jit_lvalue *ravi_emit_load_ravi_arraylength(ravi_function_def_t *def, - gcc_jit_rvalue *h) { - - gcc_jit_lvalue *value = gcc_jit_rvalue_dereference_field( - h, NULL, def->ravi->types->Table_ravi_array); - gcc_jit_lvalue *len = - gcc_jit_lvalue_access_field(value, NULL, def->ravi->types->RaviArray_len); - return len; -} - -/* Get Table->ravi_array.array_type */ -gcc_jit_lvalue *ravi_emit_load_ravi_arraytype(ravi_function_def_t *def, - gcc_jit_rvalue *h) { - - gcc_jit_lvalue *value = gcc_jit_rvalue_dereference_field( - h, NULL, def->ravi->types->Table_ravi_array); - gcc_jit_lvalue *t = gcc_jit_lvalue_access_field( - value, NULL, def->ravi->types->RaviArray_array_type); - return t; -} - -gcc_jit_lvalue *ravi_emit_load_type(ravi_function_def_t *def, - gcc_jit_lvalue *reg) { - return gcc_jit_lvalue_access_field(reg, NULL, def->ravi->types->Value_tt); -} - -gcc_jit_rvalue *ravi_emit_comparison(ravi_function_def_t *def, - enum gcc_jit_comparison op, - gcc_jit_rvalue *a, gcc_jit_rvalue *b) { - gcc_jit_lvalue *tmp_var = gcc_jit_function_new_local( - def->jit_function, NULL, def->ravi->types->C_boolT, - unique_name(def, "comparison", 0)); - gcc_jit_rvalue *cmp = - gcc_jit_context_new_comparison(def->function_context, NULL, op, a, b); - gcc_jit_block_add_assignment(def->current_block, NULL, tmp_var, cmp); - return gcc_jit_lvalue_as_rvalue(tmp_var); -} - -gcc_jit_rvalue *ravi_emit_is_value_of_type(ravi_function_def_t *def, - gcc_jit_rvalue *value_type, - int lua_type) { -#if RAVI_NAN_TAGGING -#error NaN tagging not supported -#else - return ravi_emit_comparison( - def, GCC_JIT_COMPARISON_EQ, value_type, - gcc_jit_context_new_rvalue_from_int(def->function_context, - def->ravi->types->C_intT, lua_type)); -#endif -} - -gcc_jit_rvalue *ravi_emit_is_not_value_of_type(ravi_function_def_t *def, - gcc_jit_rvalue *value_type, - int lua_type) { -#if RAVI_NAN_TAGGING -#error NaN tagging not supported -#else - return gcc_jit_context_new_unary_op( - def->function_context, NULL, GCC_JIT_UNARY_OP_LOGICAL_NEGATE, - def->ravi->types->C_boolT, - ravi_emit_is_value_of_type(def, value_type, lua_type)); -#endif -} - -gcc_jit_rvalue * -ravi_emit_is_not_value_of_type_class(ravi_function_def_t *def, - gcc_jit_rvalue *value_type, int lua_type) { - gcc_jit_rvalue *bit_mask = ravi_int_constant(def, 0x0F); - gcc_jit_rvalue *novariant_type = gcc_jit_context_new_binary_op( - def->function_context, NULL, GCC_JIT_BINARY_OP_BITWISE_AND, - def->ravi->types->C_intT, value_type, - bit_mask); - return gcc_jit_context_new_unary_op( - def->function_context, NULL, GCC_JIT_UNARY_OP_LOGICAL_NEGATE, - def->ravi->types->C_boolT, - ravi_emit_is_value_of_type(def, novariant_type, lua_type)); -} - -/* Store an integer value and set type to TNUMINT */ -void ravi_emit_store_reg_i_withtype(ravi_function_def_t *def, - gcc_jit_rvalue *ivalue, - gcc_jit_lvalue *reg) { - gcc_jit_lvalue *value = - gcc_jit_lvalue_access_field(reg, NULL, def->ravi->types->Value_value); - assert(!gcc_jit_context_get_first_error(def->function_context)); - - gcc_jit_lvalue *i = - gcc_jit_lvalue_access_field(value, NULL, def->ravi->types->Value_value_i); - gcc_jit_block_add_assignment(def->current_block, NULL, i, ivalue); - gcc_jit_rvalue *type = gcc_jit_context_new_rvalue_from_int( - def->function_context, def->ravi->types->C_intT, LUA_TNUMINT); - gcc_jit_lvalue *tt = - gcc_jit_lvalue_access_field(reg, NULL, def->ravi->types->Value_tt); - gcc_jit_block_add_assignment(def->current_block, NULL, tt, type); -} - -/* Store a boolean value and set type to TBOOLEAN */ -void ravi_emit_store_reg_b_withtype(ravi_function_def_t *def, - gcc_jit_rvalue *bvalue, - gcc_jit_lvalue *reg) { - gcc_jit_lvalue *value = - gcc_jit_lvalue_access_field(reg, NULL, def->ravi->types->Value_value); - assert(!gcc_jit_context_get_first_error(def->function_context)); - gcc_jit_lvalue *n = - gcc_jit_lvalue_access_field(value, NULL, def->ravi->types->Value_value_b); - gcc_jit_block_add_assignment(def->current_block, NULL, n, bvalue); - gcc_jit_rvalue *type = gcc_jit_context_new_rvalue_from_int( - def->function_context, def->ravi->types->C_intT, LUA__TBOOLEAN); - gcc_jit_lvalue *tt = - gcc_jit_lvalue_access_field(reg, NULL, def->ravi->types->Value_tt); - gcc_jit_block_add_assignment(def->current_block, NULL, tt, type); -} - -/* Store a number value and set type to TNUMFLT */ -void ravi_emit_store_reg_n_withtype(ravi_function_def_t *def, - gcc_jit_rvalue *nvalue, - gcc_jit_lvalue *reg) { - gcc_jit_lvalue *value = - gcc_jit_lvalue_access_field(reg, NULL, def->ravi->types->Value_value); - assert(!gcc_jit_context_get_first_error(def->function_context)); - gcc_jit_lvalue *n = - gcc_jit_lvalue_access_field(value, NULL, def->ravi->types->Value_value_n); - gcc_jit_block_add_assignment(def->current_block, NULL, n, nvalue); - gcc_jit_rvalue *type = gcc_jit_context_new_rvalue_from_int( - def->function_context, def->ravi->types->C_intT, LUA_TNUMFLT); - gcc_jit_lvalue *tt = - gcc_jit_lvalue_access_field(reg, NULL, def->ravi->types->Value_tt); - gcc_jit_block_add_assignment(def->current_block, NULL, tt, type); -} - -/* Get the Lua function prototype and constants table */ -static void emit_get_proto_and_k(ravi_function_def_t *def) { - gcc_jit_lvalue *proto = gcc_jit_rvalue_dereference_field( - gcc_jit_lvalue_as_rvalue(def->lua_closure_val), NULL, - def->ravi->types->LClosure_p); - def->proto = gcc_jit_lvalue_as_rvalue(proto); - gcc_jit_lvalue *k = gcc_jit_rvalue_dereference_field( - def->proto, NULL, def->ravi->types->LClosure_p_k); - def->k = gcc_jit_lvalue_as_rvalue(k); -} - -gcc_jit_lvalue *ravi_emit_get_Proto_sizep(ravi_function_def_t *def) { - gcc_jit_lvalue *psize = gcc_jit_rvalue_dereference_field( - def->proto, NULL, def->ravi->types->Proto_sizep); - return psize; -} - -static void link_block(ravi_function_def_t *def, int pc) { - // If the current bytecode offset pc is on a jump target - // then we need to insert the block we previously created in - // scan_jump_targets() - // and make it the current insert block; also if the previous block - // is unterminated then we simply provide a branch from previous block to the - // new block - if (def->jmp_targets[pc]) { - assert(def->jmp_targets[pc]->jmp); - // We are on a jump target - // Get the block we previously created scan_jump_targets - gcc_jit_block *block = def->jmp_targets[pc]->jmp; - if (!def->current_block_terminated) { - // Previous block not terminated so branch to the - // new block - ravi_emit_branch(def, block); - } - // Now add the new block and make it current - ravi_set_current_block(def, block); - } else if (def->current_block_terminated) { - gcc_jit_block *block = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "LINK_BLOCK", pc)); - ravi_set_current_block(def, block); - } -} - -gcc_jit_rvalue * -ravi_function_call5_rvalue(ravi_function_def_t *def, gcc_jit_function *f, - gcc_jit_rvalue *arg1, gcc_jit_rvalue *arg2, - gcc_jit_rvalue *arg3, gcc_jit_rvalue *arg4, - gcc_jit_rvalue *arg5) { - gcc_jit_rvalue *args[5]; - args[0] = arg1; - args[1] = arg2; - args[2] = arg3; - args[3] = arg4; - args[4] = arg5; - return gcc_jit_context_new_call(def->function_context, NULL, f, 5, args); -} - -gcc_jit_rvalue * -ravi_function_call4_rvalue(ravi_function_def_t *def, gcc_jit_function *f, - gcc_jit_rvalue *arg1, gcc_jit_rvalue *arg2, - gcc_jit_rvalue *arg3, gcc_jit_rvalue *arg4) { - gcc_jit_rvalue *args[4]; - args[0] = arg1; - args[1] = arg2; - args[2] = arg3; - args[3] = arg4; - return gcc_jit_context_new_call(def->function_context, NULL, f, 4, args); -} - -gcc_jit_rvalue *ravi_function_call3_rvalue(ravi_function_def_t *def, - gcc_jit_function *f, - gcc_jit_rvalue *arg1, - gcc_jit_rvalue *arg2, - gcc_jit_rvalue *arg3) { - gcc_jit_rvalue *args[3]; - args[0] = arg1; - args[1] = arg2; - args[2] = arg3; - return gcc_jit_context_new_call(def->function_context, NULL, f, 3, args); -} - -gcc_jit_rvalue *ravi_function_call2_rvalue(ravi_function_def_t *def, - gcc_jit_function *f, - gcc_jit_rvalue *arg1, - gcc_jit_rvalue *arg2) { - gcc_jit_rvalue *args[2]; - args[0] = arg1; - args[1] = arg2; - return gcc_jit_context_new_call(def->function_context, NULL, f, 2, args); -} - -gcc_jit_rvalue *ravi_function_call1_rvalue(ravi_function_def_t *def, - gcc_jit_function *f, - gcc_jit_rvalue *arg1) { - gcc_jit_rvalue *args[1]; - args[0] = arg1; - return gcc_jit_context_new_call(def->function_context, NULL, f, 1, args); -} - -gcc_jit_rvalue *ravi_emit_get_upvals(ravi_function_def_t *def, int offset) { - gcc_jit_lvalue *upvals = gcc_jit_rvalue_dereference_field( - gcc_jit_lvalue_as_rvalue(def->lua_closure_val), NULL, - def->ravi->types->LClosure_upvals); - gcc_jit_lvalue *upval = gcc_jit_context_new_array_access( - def->function_context, NULL, gcc_jit_lvalue_as_rvalue(upvals), - gcc_jit_context_new_rvalue_from_int(def->function_context, - def->ravi->types->C_intT, offset)); - return gcc_jit_lvalue_as_rvalue(upval); -} - -// Get upval->v -gcc_jit_lvalue *ravi_emit_load_upval_v(ravi_function_def_t *def, - gcc_jit_rvalue *pupval) { - return gcc_jit_rvalue_dereference_field(pupval, NULL, - def->ravi->types->UpVal_v); -} - -// Get upval->u.value -gcc_jit_lvalue *ravi_emit_load_upval_value(ravi_function_def_t *def, - gcc_jit_rvalue *pupval) { - gcc_jit_lvalue *u = - gcc_jit_rvalue_dereference_field(pupval, NULL, def->ravi->types->UpVal_u); - return gcc_jit_lvalue_access_field(u, NULL, def->ravi->types->UpVal_u_value); -} - -void ravi_set_current_block(ravi_function_def_t *def, gcc_jit_block *block) { - def->current_block = block; - def->current_block_terminated = false; -} - -void ravi_emit_branch(ravi_function_def_t *def, gcc_jit_block *target_block) { - assert(!def->current_block_terminated); - gcc_jit_block_end_with_jump(def->current_block, NULL, target_block); - def->current_block_terminated = true; -} - -void ravi_emit_conditional_branch(ravi_function_def_t *def, - gcc_jit_rvalue *cond, - gcc_jit_block *true_block, - gcc_jit_block *false_block) { - assert(!def->current_block_terminated); - gcc_jit_block_end_with_conditional(def->current_block, NULL, cond, true_block, - false_block); - def->current_block_terminated = true; -} - -gcc_jit_lvalue *ravi_emit_tonumtype(ravi_function_def_t *def, - gcc_jit_lvalue *reg, lua_typecode_t tt, - int pc) { - - gcc_jit_lvalue *value = gcc_jit_function_new_local( - def->jit_function, NULL, - tt == LUA__TNUMFLT ? def->ravi->types->lua_NumberT - : def->ravi->types->lua_IntegerT, - unique_name(def, "value", pc)); - gcc_jit_lvalue *reg_type = ravi_emit_load_type(def, reg); - - // Is reg an number? - gcc_jit_rvalue *cmp1 = - ravi_emit_is_value_of_type(def, gcc_jit_lvalue_as_rvalue(reg_type), tt); - - gcc_jit_block *convert_reg = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "convert_reg", pc)); - gcc_jit_block *copy_reg = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "copy_reg", pc)); - gcc_jit_block *load_val = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "load_val", pc)); - gcc_jit_block *failed_conversion = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "if_conversion_failed", pc)); - - // If reg is integer then copy reg, else convert reg - ravi_emit_conditional_branch(def, cmp1, copy_reg, convert_reg); - - // Convert RB - ravi_set_current_block(def, convert_reg); - - // Do the conversion - gcc_jit_rvalue *var_istt = ravi_function_call2_rvalue( - def, tt == LUA__TNUMFLT ? def->ravi->types->luaV_tonumberT - : def->ravi->types->luaV_tointegerT, - gcc_jit_lvalue_get_address(reg, NULL), - gcc_jit_lvalue_get_address(value, NULL)); - gcc_jit_rvalue *zero = gcc_jit_context_new_rvalue_from_int( - def->function_context, def->ravi->types->C_intT, 0); - gcc_jit_rvalue *conversion_failed = - ravi_emit_comparison(def, GCC_JIT_COMPARISON_EQ, var_istt, zero); - - // Did conversion fail? - ravi_emit_conditional_branch(def, conversion_failed, failed_conversion, - load_val); - - // Conversion failed, so raise error - ravi_set_current_block(def, failed_conversion); - ravi_emit_raise_lua_error(def, tt == LUA__TNUMFLT ? "number expected" - : "integer expected"); - ravi_emit_branch(def, load_val); - - // Conversion OK - ravi_set_current_block(def, copy_reg); - - gcc_jit_lvalue *i = tt == LUA__TNUMFLT ? ravi_emit_load_reg_n(def, reg) - : ravi_emit_load_reg_i(def, reg); - gcc_jit_block_add_assignment(def->current_block, NULL, value, - gcc_jit_lvalue_as_rvalue(i)); - ravi_emit_branch(def, load_val); - - ravi_set_current_block(def, load_val); - - return value; -} - -static void init_def(ravi_function_def_t *def, ravi_gcc_context_t *ravi, - Proto *p) { - def->ravi = ravi; - def->entry_block = NULL; - def->function_context = NULL; - def->jit_function = NULL; - def->jmp_targets = NULL; - def->ci_val = NULL; - def->lua_closure = NULL; - def->current_block = NULL; - def->proto = NULL; - def->k = NULL; - // def->base = NULL; - def->current_block_terminated = false; - def->buf[0] = 0; - def->counter = 1; - def->name[0] = 0; - def->p = p; - def->dump_ir = 0; - def->dump_asm = 0; -} - -int raviV_compile_n(struct lua_State *L, struct Proto *p[], int n, - ravi_compile_options_t *options) { - int count = 0; - for (int i = 0; i < n; i++) { - if (raviV_compile(L, p[i], options)) - count++; - } - return count > 0; -} - -// Compile a Lua function -// If JIT is turned off then compilation is skipped -// Compilation occurs if either auto compilation is ON (subject to some -// thresholds) -// or if a manual compilation request was made -// Returns true if compilation was successful -int raviV_compile(struct lua_State *L, struct Proto *p, - ravi_compile_options_t *options) { - // Compile given function if possible - // The p->ravi_jit structure will be updated - // Note that if a function fails to compile then - // a flag is set so that it doesn't get compiled again - int manual_request = options ? options->manual_request : 0; - int dump = 0; // options ? options->dump_level : 0; - bool omitArrayGetRangeCheck = - options ? options->omit_array_get_range_check != 0 : false; - if (p->ravi_jit.jit_status == 2) - return true; - global_State *G = G(L); - if (G->ravi_state == NULL) - return 0; - if (!G->ravi_state->jit->enabled_) { - return 0; - } - bool doCompile = (bool)manual_request; - if (!doCompile && G->ravi_state->jit->auto_) { - if (p->ravi_jit.jit_flags != 0) /* function has fornum loop, so compile */ - doCompile = true; - else if (p->sizecode > - G->ravi_state->jit - ->min_code_size_) /* function is long so compile */ - doCompile = true; - else { - if (p->ravi_jit.execution_count < - G->ravi_state->jit - ->min_exec_count_) /* function has been executed many - times so compile */ - p->ravi_jit.execution_count++; - else - doCompile = true; - } - } - if (!doCompile) - return 0; - - int status = 0; - - if (!can_compile(p)) - return 0; - - ravi_State *ravi_state = (ravi_State *)G->ravi_state; - ravi_gcc_codegen_t *codegen = ravi_state->code_generator; - - ravi_function_def_t def; - init_def(&def, ravi_state->jit, p); - def.dump_ir = def.dump_asm = dump; - def.opt_level = G->ravi_state->jit->opt_level_; - - if (!create_function(codegen, &def)) { - p->ravi_jit.jit_status = 1; // can't compile - goto on_error; - } - - scan_jump_targets(&def, p); - - /* Get L->ci */ - emit_getL_ci_value(&def); - - /* Get L->ci->func as LClosure* */ - emit_ci_func_value_gc_asLClosure(&def, def.ci_val); - - /* Get L->ci->u.l.base */ - emit_getL_base_reference(&def, def.ci_val); - - /* get Lclosure->p and p->k */ - emit_get_proto_and_k(&def); - - const Instruction *code = p->code; - int pc, n = p->sizecode; - for (pc = 0; pc < n; pc++) { - link_block(&def, pc); - Instruction i = code[pc]; - OpCode op = GET_OPCODE(i); - int A = GETARG_A(i); - switch (op) { - case OP_CONCAT: { - int B = GETARG_B(i); - int C = GETARG_C(i); - ravi_emit_CONCAT(&def, A, B, C, pc); - } break; - case OP_CLOSURE: { - int Bx = GETARG_Bx(i); - ravi_emit_CLOSURE(&def, A, Bx, pc); - } break; - case OP_VARARG: { - int B = GETARG_B(i); - ravi_emit_VARARG(&def, A, B, pc); - } break; - case OP_RAVI_MOVEI: { - int B = GETARG_B(i); - ravi_emit_MOVEI(&def, A, B, pc); - } break; - case OP_RAVI_MOVEF: { - int B = GETARG_B(i); - ravi_emit_MOVEF(&def, A, B, pc); - } break; - case OP_RAVI_TOINT: { - ravi_emit_TOINT(&def, A, pc); - } break; - case OP_RAVI_TOFLT: { - ravi_emit_TOFLT(&def, A, pc); - } break; - case OP_RETURN: { - int B = GETARG_B(i); - ravi_emit_RETURN(&def, A, B, pc); - } break; - case OP_LOADK: { - int Bx = GETARG_Bx(i); - ravi_emit_LOADK(&def, A, Bx, pc); - } break; - case OP_LOADKX: { - // OP_LOADKX is followed by OP_EXTRAARG - Instruction inst = code[++pc]; - int Ax = GETARG_Ax(inst); - lua_assert(GET_OPCODE(inst) == OP_EXTRAARG); - ravi_emit_LOADK(&def, A, Ax, pc); - } break; - - case OP_RAVI_FORPREP_I1: - case OP_RAVI_FORPREP_IP: { - int sbx = GETARG_sBx(i); - int j = sbx + pc + 1; - ravi_emit_iFORPREP(&def, A, j, op == OP_RAVI_FORPREP_I1); - } break; - case OP_RAVI_FORLOOP_I1: - case OP_RAVI_FORLOOP_IP: { - int sbx = GETARG_sBx(i); - int j = sbx + pc + 1; - ravi_emit_iFORLOOP(&def, A, j, def.jmp_targets[pc], - op == OP_RAVI_FORLOOP_I1); - } break; - case OP_TFORCALL: { - int B = GETARG_B(i); - int C = GETARG_C(i); - // OP_TFORCALL is followed by OP_TFORLOOP - we process this - // along with OP_TFORCALL - pc++; - i = code[pc]; - op = GET_OPCODE(i); - lua_assert(op == OP_TFORLOOP); - int sbx = GETARG_sBx(i); - // j below is the jump target - int j = sbx + pc + 1; - ravi_emit_TFORCALL(&def, A, B, C, j, GETARG_A(i), pc - 1); - } break; - case OP_TFORLOOP: { - int sbx = GETARG_sBx(i); - int j = sbx + pc + 1; - ravi_emit_TFORLOOP(&def, A, j, pc); - } break; - - case OP_MOVE: { - int B = GETARG_B(i); - ravi_emit_MOVE(&def, A, B); - } break; - case OP_LOADNIL: { - int B = GETARG_B(i); - ravi_emit_LOADNIL(&def, A, B, pc); - } break; - case OP_RAVI_LOADFZ: { - ravi_emit_LOADFZ(&def, A, pc); - } break; - case OP_RAVI_LOADIZ: { - ravi_emit_LOADIZ(&def, A, pc); - } break; - case OP_LOADBOOL: { - int B = GETARG_B(i); - int C = GETARG_C(i); - ravi_emit_LOADBOOL(&def, A, B, C, pc + 2, pc); - } break; - case OP_JMP: { - int sbx = GETARG_sBx(i); - int j = sbx + pc + 1; - ravi_emit_JMP(&def, A, j, pc); - } break; - - case OP_TAILCALL: - case OP_CALL: { - int B = GETARG_B(i); - int C = GETARG_C(i); - ravi_emit_CALL(&def, A, B, C, pc); - } break; - - case OP_RAVI_EQ_II: - case OP_RAVI_EQ_FF: - case OP_RAVI_LT_II: - case OP_RAVI_LT_FF: - case OP_RAVI_LE_II: - case OP_RAVI_LE_FF: - case OP_LT: - case OP_LE: - case OP_EQ: { - int B = GETARG_B(i); - int C = GETARG_C(i); - OpCode comparison_op = op; - const char *opname = - ((op == OP_EQ || op == OP_RAVI_EQ_II || op == OP_RAVI_EQ_FF) - ? "OP_EQ" - : ((op == OP_LT || op == OP_RAVI_LT_II || op == OP_RAVI_LT_FF) - ? "OP_LT" - : "OP_LE")); - gcc_jit_function *comparison_function = - ((op == OP_EQ || op == OP_RAVI_EQ_II || op == OP_RAVI_EQ_FF) - ? def.ravi->types->luaV_equalobjT - : ((op == OP_LT || op == OP_RAVI_LT_II || op == OP_RAVI_LT_FF) - ? def.ravi->types->luaV_lessthanT - : def.ravi->types->luaV_lessequalT)); - // OP_EQ is followed by OP_JMP - we process this - // along with OP_EQ - pc++; - i = code[pc]; - op = GET_OPCODE(i); - lua_assert(op == OP_JMP); - int sbx = GETARG_sBx(i); - // j below is the jump target - int j = sbx + pc + 1; - ravi_emit_EQ_LE_LT(&def, A, B, C, j, GETARG_A(i), comparison_function, - opname, comparison_op, pc); - } break; - - case OP_NEWTABLE: { - int B = GETARG_B(i); - int C = GETARG_C(i); - ravi_emit_NEWTABLE(&def, A, B, C, pc); - } break; - case OP_RAVI_NEWARRAYI: { - ravi_emit_NEWARRAYINT(&def, A, pc); - } break; - case OP_RAVI_NEWARRAYF: { - ravi_emit_NEWARRAYFLOAT(&def, A, pc); - } break; - case OP_RAVI_GETTABLE_AI: { - int B = GETARG_B(i); - int C = GETARG_C(i); - ravi_emit_GETTABLE_AI(&def, A, B, C, pc, omitArrayGetRangeCheck); - } break; - case OP_RAVI_GETTABLE_AF: { - int B = GETARG_B(i); - int C = GETARG_C(i); - ravi_emit_GETTABLE_AF(&def, A, B, C, pc, omitArrayGetRangeCheck); - } break; - case OP_RAVI_TOARRAYI: { - ravi_emit_TOARRAY(&def, A, RAVI_TARRAYINT, "integer[] expected", pc); - } break; - case OP_RAVI_TOARRAYF: { - ravi_emit_TOARRAY(&def, A, RAVI_TARRAYFLT, "number[] expected", pc); - } break; - case OP_RAVI_MOVEAI: { - int B = GETARG_B(i); - ravi_emit_MOVEAI(&def, A, B, pc); - } break; - case OP_RAVI_MOVEAF: { - int B = GETARG_B(i); - ravi_emit_MOVEAF(&def, A, B, pc); - } break; - - case OP_SETLIST: { - int B = GETARG_B(i); - int C = GETARG_C(i); - ravi_emit_SETLIST(&def, A, B, C, pc); - } break; - case OP_GETTABUP: { - int B = GETARG_B(i); - int C = GETARG_C(i); - ravi_emit_GETTABUP(&def, A, B, C, pc); - } break; - case OP_GETUPVAL: { - int B = GETARG_B(i); - ravi_emit_GETUPVAL(&def, A, B, pc); - } break; - case OP_SETTABUP: { - int B = GETARG_B(i); - int C = GETARG_C(i); - ravi_emit_SETTABUP(&def, A, B, C, pc); - } break; - case OP_SETUPVAL: { - int B = GETARG_B(i); - ravi_emit_SETUPVAL(&def, A, B, pc); - } break; - case OP_SELF: { - int B = GETARG_B(i); - int C = GETARG_C(i); - ravi_emit_SELF(&def, A, B, C, pc); - } break; - case OP_LEN: { - int B = GETARG_B(i); - ravi_emit_LEN(&def, A, B, pc); - } break; - case OP_SETTABLE: { - int B = GETARG_B(i); - int C = GETARG_C(i); - ravi_emit_SETTABLE(&def, A, B, C, pc); - } break; - case OP_GETTABLE: { - int B = GETARG_B(i); - int C = GETARG_C(i); - ravi_emit_GETTABLE(&def, A, B, C, pc); - } break; - - case OP_NOT: { - int B = GETARG_B(i); - ravi_emit_NOT(&def, A, B, pc); - } break; - case OP_TEST: { - int B = GETARG_B(i); - int C = GETARG_C(i); - // OP_TEST is followed by OP_JMP - we process this - // along with OP_EQ - pc++; - i = code[pc]; - op = GET_OPCODE(i); - lua_assert(op == OP_JMP); - int sbx = GETARG_sBx(i); - // j below is the jump target - int j = sbx + pc + 1; - ravi_emit_TEST(&def, A, B, C, j, GETARG_A(i), pc - 1); - } break; - case OP_TESTSET: { - int B = GETARG_B(i); - int C = GETARG_C(i); - // OP_TESTSET is followed by OP_JMP - we process this - // along with OP_EQ - pc++; - i = code[pc]; - op = GET_OPCODE(i); - lua_assert(op == OP_JMP); - int sbx = GETARG_sBx(i); - // j below is the jump target - int j = sbx + pc + 1; - ravi_emit_TESTSET(&def, A, B, C, j, GETARG_A(i), pc - 1); - } break; - - case OP_RAVI_ADDFF: { - int B = GETARG_B(i); - int C = GETARG_C(i); - ravi_emit_ADDFF(&def, A, B, C, pc); - } break; - case OP_RAVI_ADDFI: { - int B = GETARG_B(i); - int C = GETARG_C(i); - ravi_emit_ADDFI(&def, A, B, C, pc); - } break; - case OP_RAVI_ADDII: { - int B = GETARG_B(i); - int C = GETARG_C(i); - ravi_emit_ADDII(&def, A, B, C, pc); - } break; - case OP_RAVI_SUBFF: { - int B = GETARG_B(i); - int C = GETARG_C(i); - ravi_emit_SUBFF(&def, A, B, C, pc); - } break; - case OP_RAVI_SUBFI: { - int B = GETARG_B(i); - int C = GETARG_C(i); - ravi_emit_SUBFI(&def, A, B, C, pc); - } break; - case OP_RAVI_SUBIF: { - int B = GETARG_B(i); - int C = GETARG_C(i); - ravi_emit_SUBIF(&def, A, B, C, pc); - } break; - case OP_RAVI_SUBII: { - int B = GETARG_B(i); - int C = GETARG_C(i); - ravi_emit_SUBII(&def, A, B, C, pc); - } break; - case OP_RAVI_MULFF: { - int B = GETARG_B(i); - int C = GETARG_C(i); - ravi_emit_MULFF(&def, A, B, C, pc); - } break; - case OP_RAVI_MULFI: { - int B = GETARG_B(i); - int C = GETARG_C(i); - ravi_emit_MULFI(&def, A, B, C, pc); - } break; - case OP_RAVI_MULII: { - int B = GETARG_B(i); - int C = GETARG_C(i); - ravi_emit_MULII(&def, A, B, C, pc); - } break; - - case OP_RAVI_DIVFF: { - int B = GETARG_B(i); - int C = GETARG_C(i); - ravi_emit_DIVFF(&def, A, B, C, pc); - } break; - case OP_RAVI_DIVFI: { - int B = GETARG_B(i); - int C = GETARG_C(i); - ravi_emit_DIVFI(&def, A, B, C, pc); - } break; - case OP_RAVI_DIVIF: { - int B = GETARG_B(i); - int C = GETARG_C(i); - ravi_emit_DIVIF(&def, A, B, C, pc); - } break; - case OP_RAVI_DIVII: { - int B = GETARG_B(i); - int C = GETARG_C(i); - ravi_emit_DIVII(&def, A, B, C, pc); - } break; - case OP_RAVI_SETTABLE_AII: - case OP_RAVI_SETTABLE_AI: { - int B = GETARG_B(i); - int C = GETARG_C(i); - ravi_emit_SETTABLE_AI_AF(&def, A, B, C, op == OP_RAVI_SETTABLE_AII, - LUA__TNUMINT, pc); - } break; - case OP_RAVI_SETTABLE_AFF: - case OP_RAVI_SETTABLE_AF: { - int B = GETARG_B(i); - int C = GETARG_C(i); - ravi_emit_SETTABLE_AI_AF(&def, A, B, C, op == OP_RAVI_SETTABLE_AFF, - LUA__TNUMFLT, pc); - } break; - - case OP_ADD: { - int B = GETARG_B(i); - int C = GETARG_C(i); - ravi_emit_ARITH(&def, A, B, C, OP_ADD, TM_ADD, pc); - } break; - case OP_SUB: { - int B = GETARG_B(i); - int C = GETARG_C(i); - ravi_emit_ARITH(&def, A, B, C, OP_SUB, TM_SUB, pc); - } break; - case OP_MUL: { - int B = GETARG_B(i); - int C = GETARG_C(i); - ravi_emit_ARITH(&def, A, B, C, OP_MUL, TM_MUL, pc); - } break; - case OP_DIV: { - int B = GETARG_B(i); - int C = GETARG_C(i); - ravi_emit_ARITH(&def, A, B, C, OP_DIV, TM_DIV, pc); - } break; - - default: - break; - } - } - - if (def.dump_ir) { - gcc_jit_context_dump_to_file(def.ravi->context, "cdump.txt", 0); - gcc_jit_context_dump_to_file(def.function_context, "fdump.txt", 0); - gcc_jit_context_dump_reproducer_to_file(def.function_context, "rdump.txt"); - } - // gcc_jit_context_set_logfile (def.function_context, stderr, 0, 0); - - if (gcc_jit_context_get_first_error(def.function_context)) { - fprintf(stderr, "aborting due to JIT error: %s\n", - gcc_jit_context_get_first_error(def.function_context)); - ravi_print_function(p, 1); - abort(); - } - gcc_jit_result *compilation_result = - gcc_jit_context_compile(def.function_context); - if (gcc_jit_context_get_first_error(def.function_context)) { - fprintf(stderr, "aborting due to JIT error: %s\n", - gcc_jit_context_get_first_error(def.function_context)); - abort(); - } - - p->ravi_jit.jit_data = compilation_result; - p->ravi_jit.jit_function = - (lua_CFunction)gcc_jit_result_get_code(compilation_result, def.name); - lua_assert(p->ravi_jit.jit_function); - - if (p->ravi_jit.jit_function == NULL) { - p->ravi_jit.jit_status = 1; // can't compile - p->ravi_jit.jit_data = NULL; - goto on_error; - } else { - p->ravi_jit.jit_status = 2; - } - status = 1; - -on_error: - - free_function_def(&def); - - return status; -} - -void ravi_debug_printf(ravi_function_def_t *def, const char *str) { - gcc_jit_block_add_eval( - def->current_block, NULL, - ravi_function_call1_rvalue( - def, def->ravi->types->printfT, - gcc_jit_context_new_string_literal(def->function_context, str))); -} - -void ravi_debug_printf1(ravi_function_def_t *def, const char *str, - gcc_jit_rvalue *arg1) { - gcc_jit_block_add_eval( - def->current_block, NULL, - ravi_function_call2_rvalue( - def, def->ravi->types->printfT, - gcc_jit_context_new_string_literal(def->function_context, str), - arg1)); -} - -void ravi_debug_printf2(ravi_function_def_t *def, const char *str, - gcc_jit_rvalue *arg1, gcc_jit_rvalue *arg2) { - gcc_jit_block_add_eval( - def->current_block, NULL, - ravi_function_call3_rvalue( - def, def->ravi->types->printfT, - gcc_jit_context_new_string_literal(def->function_context, str), arg1, - arg2)); -} - -void ravi_debug_printf3(ravi_function_def_t *def, const char *str, - gcc_jit_rvalue *arg1, gcc_jit_rvalue *arg2, - gcc_jit_rvalue *arg3) { - gcc_jit_block_add_eval( - def->current_block, NULL, - ravi_function_call4_rvalue( - def, def->ravi->types->printfT, - gcc_jit_context_new_string_literal(def->function_context, str), arg1, - arg2, arg3)); -} - -void ravi_debug_printf4(ravi_function_def_t *def, const char *str, - gcc_jit_rvalue *arg1, gcc_jit_rvalue *arg2, - gcc_jit_rvalue *arg3, gcc_jit_rvalue *arg4) { - gcc_jit_block_add_eval( - def->current_block, NULL, - ravi_function_call5_rvalue( - def, def->ravi->types->printfT, - gcc_jit_context_new_string_literal(def->function_context, str), arg1, - arg2, arg3, arg4)); -} - -gcc_jit_rvalue *ravi_int_constant(ravi_function_def_t *def, int value) { - return gcc_jit_context_new_rvalue_from_int(def->function_context, - def->ravi->types->C_intT, value); -} - -gcc_jit_rvalue *ravi_bool_constant(ravi_function_def_t *def, int value) { - return gcc_jit_context_new_rvalue_from_int( - def->function_context, def->ravi->types->C_boolT, value ? 1 : 0); -} - -gcc_jit_rvalue *ravi_lua_Integer_constant(ravi_function_def_t *def, int value) { - return gcc_jit_context_new_rvalue_from_int( - def->function_context, def->ravi->types->lua_IntegerT, value); -} - -gcc_jit_rvalue *ravi_lua_Number_constant(ravi_function_def_t *def, - double value) { - return gcc_jit_context_new_rvalue_from_double( - def->function_context, def->ravi->types->lua_NumberT, value); -} - -// Free the JIT compiled function -// Note that this is called by the garbage collector -void raviV_freeproto(struct lua_State *L, struct Proto *p) { - (void)L; - if (p->ravi_jit.jit_status == 2) /* compiled */ { - gcc_jit_result *f = (gcc_jit_result *)(p->ravi_jit.jit_data); - if (f) - gcc_jit_result_release(f); - p->ravi_jit.jit_status = 3; - p->ravi_jit.jit_function = NULL; - p->ravi_jit.jit_data = NULL; - p->ravi_jit.execution_count = 0; - } -} diff --git a/src/ravi_gcccomp.c b/src/ravi_gcccomp.c deleted file mode 100644 index 0f8c505..0000000 --- a/src/ravi_gcccomp.c +++ /dev/null @@ -1,356 +0,0 @@ -/****************************************************************************** -* Copyright (C) 2015 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 -#include - -// implements EQ, LE and LT - by using the supplied lua function to call. -void ravi_emit_EQ_LE_LT(ravi_function_def_t *def, int A, int B, int C, int j, - int jA, gcc_jit_function *callee, const char *opname, - OpCode opCode, int pc) { - // case OP_EQ: { - // TValue *rb = RKB(i); - // TValue *rc = RKC(i); - // Protect( - // if (cast_int(luaV_equalobj(L, rb, rc)) != GETARG_A(i)) - // ci->u.l.savedpc++; - // else - // donextjump(ci); - // ) - // } break; - - // Load pointer to base - ravi_emit_load_base(def); - - // Get pointer to register B - gcc_jit_lvalue *regB = ravi_emit_get_register_or_constant(def, B); - // Get pointer to register C - gcc_jit_lvalue *regC = ravi_emit_get_register_or_constant(def, C); - - gcc_jit_rvalue *result = NULL; - switch (opCode) { - - case OP_RAVI_LT_II: - case OP_RAVI_LE_II: - case OP_RAVI_EQ_II: { - gcc_jit_lvalue *p1 = ravi_emit_load_reg_i(def, regB); - gcc_jit_lvalue *p2 = ravi_emit_load_reg_i(def, regC); - - switch (opCode) { - case OP_RAVI_EQ_II: - result = ravi_emit_comparison(def, GCC_JIT_COMPARISON_EQ, - gcc_jit_lvalue_as_rvalue(p1), - gcc_jit_lvalue_as_rvalue(p2)); - break; - case OP_RAVI_LT_II: - result = ravi_emit_comparison(def, GCC_JIT_COMPARISON_LT, - gcc_jit_lvalue_as_rvalue(p1), - gcc_jit_lvalue_as_rvalue(p2)); - break; - case OP_RAVI_LE_II: - result = ravi_emit_comparison(def, GCC_JIT_COMPARISON_LE, - gcc_jit_lvalue_as_rvalue(p1), - gcc_jit_lvalue_as_rvalue(p2)); - break; - default: - assert(0); - } - result = gcc_jit_context_new_cast(def->function_context, NULL, result, - def->ravi->types->C_intT); - - } break; - - case OP_RAVI_LT_FF: - case OP_RAVI_LE_FF: - case OP_RAVI_EQ_FF: { - gcc_jit_lvalue *p1 = ravi_emit_load_reg_n(def, regB); - gcc_jit_lvalue *p2 = ravi_emit_load_reg_n(def, regC); - - switch (opCode) { - case OP_RAVI_EQ_FF: - result = ravi_emit_comparison(def, GCC_JIT_COMPARISON_EQ, - gcc_jit_lvalue_as_rvalue(p1), - gcc_jit_lvalue_as_rvalue(p2)); - break; - case OP_RAVI_LT_FF: - result = ravi_emit_comparison(def, GCC_JIT_COMPARISON_LT, - gcc_jit_lvalue_as_rvalue(p1), - gcc_jit_lvalue_as_rvalue(p2)); - break; - case OP_RAVI_LE_FF: - result = ravi_emit_comparison(def, GCC_JIT_COMPARISON_LE, - gcc_jit_lvalue_as_rvalue(p1), - gcc_jit_lvalue_as_rvalue(p2)); - break; - default: - assert(0); - } - result = gcc_jit_context_new_cast(def->function_context, NULL, result, - def->ravi->types->C_intT); - - } break; - - default: - // Call luaV_equalobj with register B and C - result = - ravi_function_call3_rvalue(def, callee, gcc_jit_param_as_rvalue(def->L), - gcc_jit_lvalue_get_address(regB, NULL), - gcc_jit_lvalue_get_address(regC, NULL)); - } - - // Test if result is equal to operand A - gcc_jit_rvalue *A_const = ravi_int_constant(def, A); - gcc_jit_rvalue *result_eq_A = - ravi_emit_comparison(def, GCC_JIT_COMPARISON_EQ, result, A_const); - // If result == A then we need to execute the next statement which is a jump - char temp[80]; - snprintf(temp, sizeof temp, "%s_then", opname); - gcc_jit_block *then_block = - gcc_jit_function_new_block(def->jit_function, unique_name(def, temp, pc)); - - snprintf(temp, sizeof temp, "%s_else", opname); - gcc_jit_block *else_block = - gcc_jit_function_new_block(def->jit_function, unique_name(def, temp, pc)); - ravi_emit_conditional_branch(def, result_eq_A, then_block, else_block); - ravi_set_current_block(def, then_block); - - // if (a > 0) luaF_close(L, ci->u.l.base + a - 1); - if (jA > 0) { - // jA is the A operand of the Jump instruction - - // Reload pointer to base as the call to luaV_equalobj() may - // have invoked a Lua function and as a result the stack may have - // been reallocated - so the previous base pointer could be stale - ravi_emit_load_base(def); - - // base + a - 1 - gcc_jit_lvalue *val = ravi_emit_get_register(def, jA - 1); - - // Call luaF_close - gcc_jit_block_add_eval( - def->current_block, NULL, - ravi_function_call2_rvalue(def, def->ravi->types->luaF_closeT, - gcc_jit_param_as_rvalue(def->L), - gcc_jit_lvalue_get_address(val, NULL))); - } - // Do the jump - ravi_emit_branch(def, def->jmp_targets[j]->jmp); - // Add the else block and make it current so that the next instruction flows - // here - ravi_set_current_block(def, else_block); -} - -gcc_jit_rvalue *ravi_emit_boolean_testfalse(ravi_function_def_t *def, - gcc_jit_lvalue *reg, bool negate) { - // (isnil() || isbool() && b == 0) - - gcc_jit_lvalue *var = gcc_jit_function_new_local( - def->jit_function, NULL, def->ravi->types->C_boolT, - unique_name(def, "isfalse", 0)); - gcc_jit_lvalue *type = ravi_emit_load_type(def, reg); - - // Test if type == LUA_TNIL (0) - gcc_jit_rvalue *isnil = ravi_emit_is_value_of_type( - def, gcc_jit_lvalue_as_rvalue(type), LUA__TNIL); - - // Test if type == LUA_TBOOLEAN - gcc_jit_rvalue *isbool = ravi_emit_is_value_of_type( - def, gcc_jit_lvalue_as_rvalue(type), LUA__TBOOLEAN); - - // Test if bool value == 0 - gcc_jit_lvalue *bool_value = ravi_emit_load_reg_b(def, reg); - gcc_jit_rvalue *zero = gcc_jit_context_new_rvalue_from_int( - def->function_context, def->ravi->types->C_intT, 0); - gcc_jit_rvalue *boolzero = ravi_emit_comparison( - def, GCC_JIT_COMPARISON_EQ, gcc_jit_lvalue_as_rvalue(bool_value), zero); - - // Test type == LUA_TBOOLEAN && bool value == 0 - gcc_jit_rvalue *andvalue = gcc_jit_context_new_binary_op( - def->function_context, NULL, GCC_JIT_BINARY_OP_LOGICAL_AND, - def->ravi->types->C_boolT, isbool, boolzero); - - gcc_jit_rvalue *orvalue = gcc_jit_context_new_binary_op( - def->function_context, NULL, GCC_JIT_BINARY_OP_LOGICAL_OR, - def->ravi->types->C_boolT, isnil, andvalue); - - gcc_jit_block_add_assignment(def->current_block, NULL, var, orvalue); - - gcc_jit_rvalue *result = NULL; - if (negate) { - result = gcc_jit_context_new_unary_op( - def->function_context, NULL, GCC_JIT_UNARY_OP_LOGICAL_NEGATE, - def->ravi->types->C_boolT, gcc_jit_lvalue_as_rvalue(var)); - } else { - result = gcc_jit_lvalue_as_rvalue(var); - } - return result; -} - -void ravi_emit_TEST(ravi_function_def_t *def, int A, int B, int C, int j, - int jA, int pc) { - - // case OP_TEST: { - // if (GETARG_C(i) ? l_isfalse(ra) : !l_isfalse(ra)) - // ci->u.l.savedpc++; - // else - // donextjump(ci); - // } break; - - (void)B; - - // if (C) { - // ravi_debug_printf3(def, "OP_TEST(%d C=1)) if (!reg(A=%d)) then skip next - // else jmp to %d\n", ravi_int_constant(def, pc+1), - // ravi_int_constant(def, A), ravi_int_constant(def, - // j+1)); - // } - // else { - // ravi_debug_printf3(def, "OP_TEST(%d C=0) if (reg(A=%d)) then skip next - // else jmp to %d\n", ravi_int_constant(def, pc+1), - // ravi_int_constant(def, A), ravi_int_constant(def, - // j+1)); - // } - - // Load pointer to base - ravi_emit_load_base(def); - - // Get pointer to register A - gcc_jit_lvalue *ra = ravi_emit_get_register(def, A); - // v = C ? is_false(ra) : !is_false(ra) - gcc_jit_rvalue *v = C ? ravi_emit_boolean_testfalse(def, ra, false) - : ravi_emit_boolean_testfalse(def, ra, true); - - // Test NOT v - gcc_jit_rvalue *result = gcc_jit_context_new_unary_op( - def->function_context, NULL, GCC_JIT_UNARY_OP_LOGICAL_NEGATE, - def->ravi->types->C_boolT, v); - // If !v then we need to execute the next statement which is a jump - gcc_jit_block *then_block = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "OP_TEST_do_jmp", pc)); - gcc_jit_block *else_block = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "OP_TEST_do_skip", pc)); - ravi_emit_conditional_branch(def, result, then_block, else_block); - ravi_set_current_block(def, then_block); - - // if (a > 0) luaF_close(L, ci->u.l.base + a - 1); - if (jA > 0) { - // jA is the A operand of the Jump instruction - - // base + a - 1 - gcc_jit_lvalue *val = ravi_emit_get_register(def, jA - 1); - - // Call luaF_close - gcc_jit_block_add_eval( - def->current_block, NULL, - ravi_function_call2_rvalue(def, def->ravi->types->luaF_closeT, - gcc_jit_param_as_rvalue(def->L), - gcc_jit_lvalue_get_address(val, NULL))); - } - // Do the jump - ravi_emit_branch(def, def->jmp_targets[j]->jmp); - - // Add the else block and make it current so that the next instruction flows - // here - ravi_set_current_block(def, else_block); -} - -void ravi_emit_NOT(ravi_function_def_t *def, int A, int B, int pc) { - // case OP_NOT: { - // TValue *rb = RB(i); - // int res = l_isfalse(rb); /* next assignment may change this value */ - // setbvalue(ra, res); - // } break; - (void)pc; - - ravi_emit_load_base(def); - // Get pointer to register B - gcc_jit_lvalue *rb = ravi_emit_get_register(def, B); - gcc_jit_rvalue *v = ravi_emit_boolean_testfalse(def, rb, false); - gcc_jit_lvalue *ra = ravi_emit_get_register(def, A); - ravi_emit_store_reg_b_withtype( - def, gcc_jit_context_new_cast(def->function_context, NULL, v, - def->ravi->types->C_intT), - ra); -} - -void ravi_emit_TESTSET(ravi_function_def_t *def, int A, int B, int C, int j, - int jA, int pc) { - - // case OP_TESTSET: { - // TValue *rb = RB(i); - // if (GETARG_C(i) ? l_isfalse(rb) : !l_isfalse(rb)) - // ci->u.l.savedpc++; - // else { - // setobjs2s(L, ra, rb); - // donextjump(ci); - // } - // } break; - - (void)pc; - // Load pointer to base - ravi_emit_load_base(def); - - // Get pointer to register B - gcc_jit_lvalue *rb = ravi_emit_get_register(def, B); - // v = C ? is_false(ra) : !is_false(ra) - gcc_jit_rvalue *v = C ? ravi_emit_boolean_testfalse(def, rb, false) - : ravi_emit_boolean_testfalse(def, rb, true); - - // Test NOT v - gcc_jit_rvalue *result = gcc_jit_context_new_unary_op( - def->function_context, NULL, GCC_JIT_UNARY_OP_LOGICAL_NEGATE, - def->ravi->types->C_boolT, v); - - // If !v then we need to execute the next statement which is a jump - gcc_jit_block *then_block = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "OP_TESTSET_if_then", pc)); - gcc_jit_block *else_block = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "OP_TESTSET_if_else", pc)); - ravi_emit_conditional_branch(def, result, then_block, else_block); - ravi_set_current_block(def, then_block); - - // Get pointer to register A - gcc_jit_lvalue *ra = ravi_emit_get_register(def, A); - ravi_emit_struct_assign(def, ra, rb); - - // if (a > 0) luaF_close(L, ci->u.l.base + a - 1); - if (jA > 0) { - // jA is the A operand of the Jump instruction - - // base + a - 1 - gcc_jit_lvalue *val = ravi_emit_get_register(def, jA - 1); - - // Call luaF_close - gcc_jit_block_add_eval( - def->current_block, NULL, - ravi_function_call2_rvalue(def, def->ravi->types->luaF_closeT, - gcc_jit_param_as_rvalue(def->L), - gcc_jit_lvalue_get_address(val, NULL))); - } - // Do the jump - ravi_emit_branch(def, def->jmp_targets[j]->jmp); - - // Add the else block and make it current so that the next instruction flows - // here - ravi_set_current_block(def, else_block); -} diff --git a/src/ravi_gccforloop.c b/src/ravi_gccforloop.c deleted file mode 100644 index 9237dee..0000000 --- a/src/ravi_gccforloop.c +++ /dev/null @@ -1,87 +0,0 @@ -/****************************************************************************** -* Copyright (C) 2015 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 - -void ravi_emit_iFORLOOP(ravi_function_def_t *def, int A, int pc, - ravi_branch_def_t *b, int step_one) { - - // lua_Integer step = ivalue(ra + 2); - // lua_Integer idx = ivalue(ra) + step; /* increment index */ - // lua_Integer limit = ivalue(ra + 1); - // if (idx <= limit) { - // ci->u.l.savedpc += GETARG_sBx(i); /* jump back */ - // setivalue(ra, idx); /* update internal index... */ - // setivalue(ra + 3, idx); /* ...and external index */ - // } - - // We are in b->jmp as this is already the current block - lua_assert(def->current_block == b->jmp); - - // Create the done block - gcc_jit_block *exit_block = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "FORLOOP_I1_exit", 0)); - - gcc_jit_rvalue *new_idx; - - if (!step_one) { - // lua_Integer step = ivalue(ra + 2); - new_idx = gcc_jit_context_new_binary_op( - def->function_context, NULL, GCC_JIT_BINARY_OP_PLUS, - def->ravi->types->lua_IntegerT, gcc_jit_lvalue_as_rvalue(b->iidx), - gcc_jit_lvalue_as_rvalue(b->istep)); - } else - new_idx = gcc_jit_context_new_binary_op( - def->function_context, NULL, GCC_JIT_BINARY_OP_PLUS, - def->ravi->types->lua_IntegerT, gcc_jit_lvalue_as_rvalue(b->iidx), - gcc_jit_context_new_rvalue_from_int(def->function_context, - def->ravi->types->lua_IntegerT, 1)); - - // save new index - gcc_jit_block_add_assignment(def->current_block, NULL, b->iidx, new_idx); - - // lua_Integer limit = ivalue(ra + 1); - - // idx > limit? - gcc_jit_rvalue *new_idx_gt_limit = ravi_emit_comparison( - def, GCC_JIT_COMPARISON_GT, gcc_jit_lvalue_as_rvalue(b->iidx), - gcc_jit_lvalue_as_rvalue(b->ilimit)); - - // If idx > limit we are done - gcc_jit_block *update_block = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "FORLOOP_I1_updatei", 0)); - ravi_emit_conditional_branch(def, new_idx_gt_limit, exit_block, update_block); - - ravi_set_current_block(def, update_block); - - // Load pointer to base - ravi_emit_load_base(def); - - // setivalue(ra + 3, idx); /* ...and external index */ - gcc_jit_lvalue *rvar = ravi_emit_get_register(def, A + 3); - ravi_emit_store_reg_i_withtype(def, gcc_jit_lvalue_as_rvalue(b->iidx), rvar); - - // ci->u.l.savedpc += GETARG_sBx(i); /* jump back */ - ravi_emit_branch(def, def->jmp_targets[pc]->jmp); - ravi_set_current_block(def, exit_block); -} diff --git a/src/ravi_gccforprep.c b/src/ravi_gccforprep.c deleted file mode 100644 index 99ee5ab..0000000 --- a/src/ravi_gccforprep.c +++ /dev/null @@ -1,95 +0,0 @@ -/****************************************************************************** -* Copyright (C) 2015 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 -#include - -void ravi_emit_iFORPREP(ravi_function_def_t *def, int A, int pc, int step_one) { - ravi_branch_def_t *forloop_target = def->jmp_targets[pc]; - assert(forloop_target); - - forloop_target->ilimit = gcc_jit_function_new_local( - def->jit_function, NULL, def->ravi->types->lua_IntegerT, - unique_name(def, "ilimit", 0)); - if (!step_one) { - forloop_target->istep = gcc_jit_function_new_local( - def->jit_function, NULL, def->ravi->types->lua_IntegerT, - unique_name(def, "istep", 0)); - } - forloop_target->iidx = gcc_jit_function_new_local( - def->jit_function, NULL, def->ravi->types->lua_IntegerT, - unique_name(def, "iidx", 0)); - - // lua_Integer initv = ivalue(init); - // setivalue(init, initv - ivalue(pstep)); - - // Load pointer to base - ravi_emit_load_base(def); - - // TValue *init = ra; - // TValue *pstep = ra + 2; - gcc_jit_lvalue *init = ravi_emit_get_register(def, A); - gcc_jit_lvalue *plimit = ravi_emit_get_register(def, A + 1); - gcc_jit_lvalue *pstep = NULL; - if (!step_one) - pstep = ravi_emit_get_register(def, A + 2); - // Get ivalue(pstep) - - gcc_jit_lvalue *limit_ivalue = ravi_emit_load_reg_i(def, plimit); - gcc_jit_lvalue *init_ivalue = ravi_emit_load_reg_i(def, init); - - if (!step_one) { - // setivalue(init, initv - ivalue(pstep)); - gcc_jit_lvalue *step_ivalue = ravi_emit_load_reg_i(def, pstep); - gcc_jit_rvalue *idx = gcc_jit_context_new_binary_op( - def->function_context, NULL, GCC_JIT_BINARY_OP_MINUS, - def->ravi->types->lua_IntegerT, gcc_jit_lvalue_as_rvalue(init_ivalue), - gcc_jit_lvalue_as_rvalue(step_ivalue)); - // Save idx - gcc_jit_block_add_assignment(def->current_block, NULL, forloop_target->iidx, - idx); - - // Save step - gcc_jit_block_add_assignment(def->current_block, NULL, - forloop_target->istep, - gcc_jit_lvalue_as_rvalue(step_ivalue)); - } else { - // setivalue(init, initv - ivalue(pstep)); - gcc_jit_rvalue *idx = gcc_jit_context_new_binary_op( - def->function_context, NULL, GCC_JIT_BINARY_OP_MINUS, - def->ravi->types->lua_IntegerT, gcc_jit_lvalue_as_rvalue(init_ivalue), - gcc_jit_context_new_rvalue_from_int(def->function_context, - def->ravi->types->lua_IntegerT, 1)); - - // Save idx - gcc_jit_block_add_assignment(def->current_block, NULL, forloop_target->iidx, - idx); - } - - // Save limit - gcc_jit_block_add_assignment(def->current_block, NULL, forloop_target->ilimit, - gcc_jit_lvalue_as_rvalue(limit_ivalue)); - - // We are done so jump to forloop - lua_assert(def->jmp_targets[pc]->jmp); - ravi_emit_branch(def, def->jmp_targets[pc]->jmp); -} diff --git a/src/ravi_gccjit.c b/src/ravi_gccjit.c deleted file mode 100644 index 5a2e536..0000000 --- a/src/ravi_gccjit.c +++ /dev/null @@ -1,270 +0,0 @@ -/****************************************************************************** -* Copyright (C) 2015 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 -#include "ravi_gccjit.h" - -ravi_gcc_context_t *ravi_jit_new_context(void) { - ravi_gcc_context_t *ravi = NULL; - gcc_jit_context *gcc_ctx = gcc_jit_context_acquire(); - if (!gcc_ctx) { - fprintf(stderr, "failed to allocate a GCC JIT context\n"); - goto on_error; - } - - ravi = (ravi_gcc_context_t *)calloc(1, sizeof(ravi_gcc_context_t)); - if (!ravi) { - fprintf(stderr, "failed to allocate a Ravi JIT context\n"); - goto on_error; - } - ravi->context = gcc_ctx; - ravi->auto_ = false; - ravi->enabled_ = true; - ravi->min_code_size_ = 150; - ravi->min_exec_count_ = 50; - ravi->opt_level_ = 3; - ravi->size_level_ = 0; - - if (!ravi_setup_lua_types(ravi)) { - fprintf(stderr, "failed to setup types\n"); - goto on_error; - } - - ravi->parent_result_ = gcc_jit_context_compile(ravi->context); - if (gcc_jit_context_get_first_error(ravi->context)) { - fprintf(stderr, "aborting due to JIT error: %s\n", - gcc_jit_context_get_first_error(ravi->context)); - abort(); - } - - return ravi; -on_error: - if (ravi) { - ravi_jit_context_free(ravi); - } else if (gcc_ctx) { - gcc_jit_context_release(gcc_ctx); - } - return NULL; -} - -void ravi_jit_context_free(ravi_gcc_context_t *ravi) { - if (ravi == NULL) - return; - if (ravi->parent_result_) { - gcc_jit_result_release(ravi->parent_result_); - ravi->parent_result_ = NULL; - } - if (ravi->context) { - gcc_jit_context_release(ravi->context); - ravi->context = NULL; - } - if (ravi->types) { - free(ravi->types); - ravi->types = NULL; - } - free(ravi); -} - -ravi_gcc_codegen_t *ravi_jit_new_codegen(ravi_gcc_context_t *ravi) { - ravi_gcc_codegen_t *cg = NULL; - cg = (ravi_gcc_codegen_t *)calloc(1, sizeof(ravi_gcc_codegen_t)); - if (cg == NULL) { - fprintf(stderr, "error creating a new context: out of memory\n"); - goto on_error; - } - cg->id = 1; - cg->temp[0] = 0; - cg->ravi = ravi; - return cg; - -on_error: - if (cg) - ravi_jit_codegen_free(cg); - return NULL; -} - -void ravi_jit_codegen_free(ravi_gcc_codegen_t *codegen) { - if (codegen == NULL) - return; - free(codegen); -} - -bool ravi_jit_has_errored(ravi_gcc_context_t *ravi) { - const char *msg = gcc_jit_context_get_first_error(ravi->context); - if (msg) { - fprintf(stderr, "JIT error: %s\n", msg); - return true; - } - return false; -} - -#include - -// Initialize the JIT State and attach it to the -// Global Lua State -// If a JIT State already exists then this function -// will return -1 -int raviV_initjit(struct lua_State *L) { - global_State *G = G(L); - if (G->ravi_state != NULL) - return -1; - ravi_State *jit = (ravi_State *)calloc(1, sizeof(ravi_State)); - jit->jit = ravi_jit_new_context(); - jit->code_generator = ravi_jit_new_codegen(jit->jit); - G->ravi_state = jit; - return 0; -} - -// Free up the JIT State -void raviV_close(struct lua_State *L) { - global_State *G = G(L); - if (G->ravi_state == NULL) - return; - ravi_jit_codegen_free(G->ravi_state->code_generator); - ravi_jit_context_free(G->ravi_state->jit); - free(G->ravi_state); -} - -// Dump the LLVM IR -void raviV_dumpIR(struct lua_State *L, struct Proto *p) { - (void)L; - (void)p; -} - -// Dump the LLVM ASM -void raviV_dumpASM(struct lua_State *L, struct Proto *p) { - (void)L; - (void)p; -} - -void raviV_setminexeccount(lua_State *L, int value) { - global_State *G = G(L); - if (!G->ravi_state) - return; - G->ravi_state->jit->min_exec_count_ = value; -} -int raviV_getminexeccount(lua_State *L) { - global_State *G = G(L); - if (!G->ravi_state) - return 0; - return G->ravi_state->jit->min_exec_count_; -} - -void raviV_setmincodesize(lua_State *L, int value) { - global_State *G = G(L); - if (!G->ravi_state) - return; - G->ravi_state->jit->min_code_size_ = value; -} -int raviV_getmincodesize(lua_State *L) { - global_State *G = G(L); - if (!G->ravi_state) - return 0; - return G->ravi_state->jit->min_code_size_; -} - -void raviV_setauto(lua_State *L, int value) { - global_State *G = G(L); - if (!G->ravi_state) - return; - G->ravi_state->jit->auto_ = value; -} -int raviV_getauto(lua_State *L) { - global_State *G = G(L); - if (!G->ravi_state) - return 0; - return G->ravi_state->jit->auto_; -} - -// Turn on/off the JIT compiler -void raviV_setjitenabled(lua_State *L, int value) { - global_State *G = G(L); - if (!G->ravi_state) - return; - G->ravi_state->jit->enabled_ = value; -} -int raviV_getjitenabled(lua_State *L) { - global_State *G = G(L); - if (!G->ravi_state) - return 0; - return G->ravi_state->jit->enabled_; -} - -void raviV_setoptlevel(lua_State *L, int value) { - global_State *G = G(L); - if (!G->ravi_state) - return; - G->ravi_state->jit->opt_level_ = value; -} -int raviV_getoptlevel(lua_State *L) { - global_State *G = G(L); - if (!G->ravi_state) - return 0; - return G->ravi_state->jit->opt_level_; -} - -void raviV_setsizelevel(lua_State *L, int value) { - (void)L; - (void)value; -} -int raviV_getsizelevel(lua_State *L) { - (void)L; - return 0; -} - -void raviV_setvalidation(lua_State *L, int value) { - (void)L; - (void)value; -} -int raviV_getvalidation(lua_State *L) { - (void)L; - return 0; -} - -void raviV_setverbosity(lua_State *L, int value) { - (void)L; - (void)value; -} -int raviV_getverbosity(lua_State *L) { - (void)L; - return 0; -} - -void raviV_setgcstep(lua_State *L, int value) { - (void)L; - (void)value; -} -int raviV_getgcstep(lua_State *L) { - (void)L; - return 0; -} - -// Turn on/off the JIT compiler -void raviV_settraceenabled(lua_State *L, int value) { - (void)L; - (void)value; -} -int raviV_gettraceenabled(lua_State *L) { - (void)L; - return 0; -} \ No newline at end of file diff --git a/src/ravi_gccload.c b/src/ravi_gccload.c deleted file mode 100644 index ef66ba8..0000000 --- a/src/ravi_gccload.c +++ /dev/null @@ -1,467 +0,0 @@ -/****************************************************************************** -* Copyright (C) 2015 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 - -// R(A+1), ..., R(A+B) := nil -void ravi_emit_LOADNIL(ravi_function_def_t *def, int A, int B, int pc) { - (void)pc; - - gcc_jit_block_add_eval( - def->current_block, NULL, - ravi_function_call3_rvalue( - def, def->ravi->types->raviV_op_loadnilT, - gcc_jit_lvalue_as_rvalue(def->ci_val), - gcc_jit_context_new_rvalue_from_int(def->function_context, - def->ravi->types->C_intT, A), - gcc_jit_context_new_rvalue_from_int(def->function_context, - def->ravi->types->C_intT, B))); -} - -// R(A) := tonumber(0) -void ravi_emit_LOADFZ(ravi_function_def_t *def, int A, int pc) { - (void)pc; - - // Load pointer to base - ravi_emit_load_base(def); - - // ra - gcc_jit_lvalue *dest = ravi_emit_get_register(def, A); - - // destvalue->value_.n = 0.0 - ravi_emit_store_reg_n_withtype( - def, gcc_jit_context_new_rvalue_from_double( - def->function_context, def->ravi->types->lua_NumberT, 0.0), - dest); -} - -// R(A) := tointeger(0) -void ravi_emit_LOADIZ(ravi_function_def_t *def, int A, int pc) { - (void)pc; - - // Load pointer to base - ravi_emit_load_base(def); - - // ra - gcc_jit_lvalue *dest = ravi_emit_get_register(def, A); - - // destvalue->value_.i = - ravi_emit_store_reg_i_withtype( - def, gcc_jit_context_new_rvalue_from_int( - def->function_context, def->ravi->types->lua_IntegerT, 0), - dest); -} - -void ravi_emit_LOADK(ravi_function_def_t *def, int A, int Bx, int pc) { - - (void)pc; - - // TValue *rb = k + GETARG_Bx(i); - // setobj2s(L, ra, rb); - - // Load pointer to base - ravi_emit_load_base(def); - - // ra - gcc_jit_lvalue *dest = ravi_emit_get_register(def, A); - -#if 1 - TValue *Konst = &def->p->k[Bx]; - switch (Konst->tt_) { - case LUA_TNUMINT: - ravi_emit_store_reg_i_withtype( - def, gcc_jit_context_new_rvalue_from_int(def->function_context, - def->ravi->types->lua_IntegerT, - Konst->value_.i), - dest); - break; - case LUA_TNUMFLT: - ravi_emit_store_reg_n_withtype(def, gcc_jit_context_new_rvalue_from_double( - def->function_context, - def->ravi->types->lua_NumberT, - Konst->value_.n), - dest); - break; - case LUA_TBOOLEAN: - ravi_emit_store_reg_b_withtype( - def, - gcc_jit_context_new_rvalue_from_int( - def->function_context, def->ravi->types->C_intT, Konst->value_.b), - dest); - break; - default: { -#endif - // rb - gcc_jit_lvalue *src = ravi_emit_get_constant(def, Bx); - - // *ra = *rb - ravi_emit_struct_assign(def, dest, src); -#if 1 - } - } -#endif -} - -// R(A) := R(B) -void ravi_emit_MOVE(ravi_function_def_t *def, int A, int B) { - // setobjs2s(L, ra, RB(i)); - - lua_assert(A != B); - - // Load pointer to base - ravi_emit_load_base(def); - - // rb - gcc_jit_lvalue *src = ravi_emit_get_register(def, B); - // ra - gcc_jit_lvalue *dest = ravi_emit_get_register(def, A); - - // *ra = *rb - ravi_emit_struct_assign(def, dest, src); -} - -// R(A) := (Bool)B; if (C) pc++ -void ravi_emit_LOADBOOL(ravi_function_def_t *def, int A, int B, int C, int j, - int pc) { - - // setbvalue(ra, GETARG_B(i)); - // if (GETARG_C(i)) ci->u.l.savedpc++; /* skip next instruction (if C) */ - - // ravi_debug_printf4(def, "LOADBOOL(pc=%d) set reg(A=%d) to boolean(B=%d); - // if ((C=%d) != 0) skip next\n", ravi_int_constant(def, pc+1), - // ravi_int_constant(def, A), ravi_int_constant(def, B), - // ravi_int_constant(def, C)); - // Load pointer to base - ravi_emit_load_base(def); - // ra - gcc_jit_lvalue *dest = ravi_emit_get_register(def, A); - // dest->i = 0 - ravi_emit_store_reg_b_withtype( - def, gcc_jit_context_new_rvalue_from_int(def->function_context, - def->ravi->types->C_intT, B), - dest); - if (C) { - // Skip next instruction if C - ravi_emit_branch(def, def->jmp_targets[j]->jmp); - - gcc_jit_block *block = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "OP_LOADBOOL_skip_next", pc)); - ravi_set_current_block(def, block); - } -} - -// R(A) := R(B), check R(B) is int -void ravi_emit_MOVEI(ravi_function_def_t *def, int A, int B, int pc) { - - // TValue *rb = RB(i); - // lua_Integer j; - // if (tointeger(rb, &j)) { - // setivalue(ra, j); - // } - // else - // luaG_runerror(L, "integer expected"); - - gcc_jit_lvalue *var = gcc_jit_function_new_local( - def->jit_function, NULL, def->ravi->types->lua_IntegerT, - unique_name(def, "OP_RAVI_MOVEI_i", pc)); - - // Load pointer to base - ravi_emit_load_base(def); - - gcc_jit_lvalue *dest = ravi_emit_get_register(def, A); - gcc_jit_lvalue *src = ravi_emit_get_register(def, B); - - gcc_jit_lvalue *src_type = ravi_emit_load_type(def, src); - - // Compare src->tt == LUA_TNUMINT - gcc_jit_rvalue *cmp1 = ravi_emit_is_value_of_type( - def, gcc_jit_lvalue_as_rvalue(src_type), LUA__TNUMINT); - - gcc_jit_block *then1 = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "OP_RAVI_MOVEI_if_integer", pc)); - gcc_jit_block *else1 = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "OP_RAVI_MOVEI_if_not_integer", pc)); - gcc_jit_block *end1 = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "OP_RAVI_MOVEI_done", pc)); - - ravi_emit_conditional_branch(def, cmp1, then1, else1); - ravi_set_current_block(def, then1); - - // Already a int - move - gcc_jit_lvalue *tmp = ravi_emit_load_reg_i(def, src); - gcc_jit_block_add_assignment(def->current_block, NULL, var, - gcc_jit_lvalue_as_rvalue(tmp)); - ravi_emit_branch(def, end1); - - // we need to convert - ravi_set_current_block(def, else1); - - // Call luaV_tointeger_() - gcc_jit_rvalue *var_isint = - ravi_function_call2_rvalue(def, def->ravi->types->luaV_tointegerT, - gcc_jit_lvalue_get_address(src, NULL), - gcc_jit_lvalue_get_address(var, NULL)); - gcc_jit_rvalue *zero = gcc_jit_context_new_rvalue_from_int( - def->function_context, def->ravi->types->C_intT, 0); - gcc_jit_rvalue *tobool = - ravi_emit_comparison(def, GCC_JIT_COMPARISON_EQ, var_isint, zero); - - // Did conversion fail? - gcc_jit_block *else2 = gcc_jit_function_new_block( - def->jit_function, - unique_name(def, "OP_RAVI_MOVEI_if_conversion_failed", pc)); - ravi_emit_conditional_branch(def, tobool, else2, end1); - - // Conversion failed, so raise error - ravi_set_current_block(def, else2); - ravi_emit_raise_lua_error(def, "integer expected"); - - ravi_emit_branch(def, end1); - - // Conversion OK - ravi_set_current_block(def, end1); - - // Set R(A) - ravi_emit_store_reg_i_withtype(def, gcc_jit_lvalue_as_rvalue(var), dest); -} - -void ravi_emit_MOVEF(ravi_function_def_t *def, int A, int B, int pc) { - - // case OP_RAVI_MOVEF: { - // TValue *rb = RB(i); - // lua_Number j; - // if (tonumber(rb, &j)) { - // setfltvalue(ra, j); - // } - // else - // luaG_runerror(L, "float expected"); - // } break; - - gcc_jit_lvalue *var = gcc_jit_function_new_local( - def->jit_function, NULL, def->ravi->types->lua_NumberT, - unique_name(def, "OP_RAVI_MOVEF_n", pc)); - - // Load pointer to base - ravi_emit_load_base(def); - - gcc_jit_lvalue *dest = ravi_emit_get_register(def, A); - gcc_jit_lvalue *src = ravi_emit_get_register(def, B); - - gcc_jit_lvalue *src_type = ravi_emit_load_type(def, src); - - // Compare src->tt == LUA_TNUMFLT - gcc_jit_rvalue *cmp1 = ravi_emit_is_value_of_type( - def, gcc_jit_lvalue_as_rvalue(src_type), LUA__TNUMFLT); - - gcc_jit_block *then1 = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "OP_RAVI_MOVEF_if_float", pc)); - gcc_jit_block *else1 = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "OP_RAVI_MOVEF_if_not_float", pc)); - gcc_jit_block *end1 = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "OP_RAVI_MOVEF_done", pc)); - - ravi_emit_conditional_branch(def, cmp1, then1, else1); - ravi_set_current_block(def, then1); - - // Already a float - copy to var - gcc_jit_lvalue *tmp = ravi_emit_load_reg_n(def, src); - gcc_jit_block_add_assignment(def->current_block, NULL, var, - gcc_jit_lvalue_as_rvalue(tmp)); - ravi_emit_branch(def, end1); - - // we need to convert - ravi_set_current_block(def, else1); - - // Call luaV_tonumber() - gcc_jit_rvalue *var_isflt = - ravi_function_call2_rvalue(def, def->ravi->types->luaV_tonumberT, - gcc_jit_lvalue_get_address(src, NULL), - gcc_jit_lvalue_get_address(var, NULL)); - gcc_jit_rvalue *zero = gcc_jit_context_new_rvalue_from_int( - def->function_context, def->ravi->types->C_intT, 0); - gcc_jit_rvalue *tobool = - ravi_emit_comparison(def, GCC_JIT_COMPARISON_EQ, var_isflt, zero); - - // Did conversion fail? - gcc_jit_block *else2 = gcc_jit_function_new_block( - def->jit_function, - unique_name(def, "OP_RAVI_MOVEF_if_conversion_failed", pc)); - ravi_emit_conditional_branch(def, tobool, else2, end1); - - // Conversion failed, so raise error - ravi_set_current_block(def, else2); - ravi_emit_raise_lua_error(def, "number expected"); - - ravi_emit_branch(def, end1); - - // Conversion OK - ravi_set_current_block(def, end1); - - // Set R(A) - ravi_emit_store_reg_n_withtype(def, gcc_jit_lvalue_as_rvalue(var), dest); -} - -void ravi_emit_TOINT(ravi_function_def_t *def, int A, int pc) { - - // case OP_RAVI_TOINT: { - // lua_Integer j; - // if (tointeger(ra, &j)) { - // setivalue(ra, j); - // } - // else - // luaG_runerror(L, "integer expected"); - // } break; - - gcc_jit_lvalue *var = gcc_jit_function_new_local( - def->jit_function, NULL, def->ravi->types->lua_IntegerT, - unique_name(def, "OP_RAVI_TOINT_i", pc)); - - // Load pointer to base - ravi_emit_load_base(def); - - gcc_jit_lvalue *dest = ravi_emit_get_register(def, A); - gcc_jit_lvalue *src = dest; - - gcc_jit_lvalue *src_type = ravi_emit_load_type(def, src); - - // Is src->tt != LUA_TNUMINT? - gcc_jit_rvalue *cmp1 = ravi_emit_is_not_value_of_type( - def, gcc_jit_lvalue_as_rvalue(src_type), LUA__TNUMINT); - - gcc_jit_block *then1 = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "OP_RAVI_TOINT_if_not_integer", pc)); - gcc_jit_block *end1 = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "OP_RAVI_TOINT_done", pc)); - - ravi_emit_conditional_branch(def, cmp1, then1, end1); - ravi_set_current_block(def, then1); - - // Call luaV_tointeger_() - gcc_jit_rvalue *var_isint = - ravi_function_call2_rvalue(def, def->ravi->types->luaV_tointegerT, - gcc_jit_lvalue_get_address(src, NULL), - gcc_jit_lvalue_get_address(var, NULL)); - gcc_jit_rvalue *zero = gcc_jit_context_new_rvalue_from_int( - def->function_context, def->ravi->types->C_intT, 0); - gcc_jit_rvalue *failed_conversion = - ravi_emit_comparison(def, GCC_JIT_COMPARISON_EQ, var_isint, zero); - - // Did conversion fail? - gcc_jit_block *then2 = gcc_jit_function_new_block( - def->jit_function, - unique_name(def, "OP_RAVI_TOINT_if_conversion_failed", pc)); - gcc_jit_block *else2 = gcc_jit_function_new_block( - def->jit_function, - unique_name(def, "OP_RAVI_TOINT_if_conversion_ok", pc)); - ravi_emit_conditional_branch(def, failed_conversion, then2, else2); - - ravi_set_current_block(def, then2); - - // Conversion failed, so raise error - ravi_emit_raise_lua_error(def, "integer expected"); - - ravi_emit_branch(def, else2); - - // Conversion OK - ravi_set_current_block(def, else2); - - ravi_emit_store_reg_i_withtype(def, gcc_jit_lvalue_as_rvalue(var), dest); - - ravi_emit_branch(def, end1); - - ravi_set_current_block(def, end1); -} - -void ravi_emit_TOFLT(ravi_function_def_t *def, int A, int pc) { - - // case OP_RAVI_TOFLT: { - // lua_Number j; - // if (tonumber(ra, &j)) { - // setfltvalue(ra, j); - // } - // else - // luaG_runerror(L, "float expected"); - // } break; - - gcc_jit_lvalue *var = gcc_jit_function_new_local( - def->jit_function, NULL, def->ravi->types->lua_NumberT, - unique_name(def, "OP_RAVI_TOFLT_n", pc)); - - // Load pointer to base - ravi_emit_load_base(def); - - gcc_jit_lvalue *dest = ravi_emit_get_register(def, A); - gcc_jit_lvalue *src = dest; - - gcc_jit_lvalue *src_type = ravi_emit_load_type(def, src); - - // Is src->tt != LUA_TNUMFLT? - gcc_jit_rvalue *cmp1 = ravi_emit_is_not_value_of_type( - def, gcc_jit_lvalue_as_rvalue(src_type), LUA__TNUMFLT); - - gcc_jit_block *then1 = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "OP_RAVI_TOFLT_if_not_float", pc)); - gcc_jit_block *end1 = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "OP_RAVI_TOFLT_done", pc)); - - ravi_emit_conditional_branch(def, cmp1, then1, end1); - ravi_set_current_block(def, then1); - - // Call luaV_tonumber() - gcc_jit_rvalue *var_ptr = gcc_jit_lvalue_get_address(var, NULL); - // ravi_debug_printf3(def, "number %p = %f before call to luaV_number\n", - // var_ptr, gcc_jit_lvalue_as_rvalue(var)); - gcc_jit_rvalue *var_isflt = ravi_function_call2_rvalue( - def, def->ravi->types->luaV_tonumberT, - gcc_jit_lvalue_get_address(src, NULL), var_ptr); - gcc_jit_rvalue *zero = gcc_jit_context_new_rvalue_from_int( - def->function_context, def->ravi->types->C_intT, 0); - gcc_jit_rvalue *failed_conversion = - ravi_emit_comparison(def, GCC_JIT_COMPARISON_EQ, var_isflt, zero); - - // Did conversion fail? - gcc_jit_block *then2 = gcc_jit_function_new_block( - def->jit_function, - unique_name(def, "OP_RAVI_TOFLT_if_conversion_failed", pc)); - gcc_jit_block *else2 = gcc_jit_function_new_block( - def->jit_function, - unique_name(def, "OP_RAVI_TOFLT_if_conversion_ok", pc)); - ravi_emit_conditional_branch(def, failed_conversion, then2, else2); - - ravi_set_current_block(def, then2); - - // Conversion failed, so raise error - ravi_emit_raise_lua_error(def, "number expected"); - - ravi_emit_branch(def, else2); - - // Conversion OK - ravi_set_current_block(def, else2); - - // ravi_debug_printf2(def, "number ok = %f\n", gcc_jit_lvalue_as_rvalue(var)); - ravi_emit_store_reg_n_withtype(def, gcc_jit_lvalue_as_rvalue(var), dest); - - ravi_emit_branch(def, end1); - - ravi_set_current_block(def, end1); -} diff --git a/src/ravi_gccrest.c b/src/ravi_gccrest.c deleted file mode 100644 index 0307e9e..0000000 --- a/src/ravi_gccrest.c +++ /dev/null @@ -1,68 +0,0 @@ -#include - -/****************************************************************************** -* Copyright (C) 2015 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. -******************************************************************************/ - -void ravi_emit_CONCAT(ravi_function_def_t *def, int A, int B, int C, int pc) { - (void)pc; - gcc_jit_block_add_eval( - def->current_block, NULL, - ravi_function_call5_rvalue( - def, def->ravi->types->raviV_op_concatT, - gcc_jit_param_as_rvalue(def->L), - gcc_jit_lvalue_as_rvalue(def->ci_val), - gcc_jit_context_new_rvalue_from_int(def->function_context, - def->ravi->types->C_intT, A), - gcc_jit_context_new_rvalue_from_int(def->function_context, - def->ravi->types->C_intT, B), - gcc_jit_context_new_rvalue_from_int(def->function_context, - def->ravi->types->C_intT, C))); -} - -void ravi_emit_CLOSURE(ravi_function_def_t *def, int A, int Bx, int pc) { - (void)pc; - gcc_jit_block_add_eval( - def->current_block, NULL, - ravi_function_call5_rvalue( - def, def->ravi->types->raviV_op_closureT, - gcc_jit_param_as_rvalue(def->L), - gcc_jit_lvalue_as_rvalue(def->ci_val), def->lua_closure, - gcc_jit_context_new_rvalue_from_int(def->function_context, - def->ravi->types->C_intT, A), - gcc_jit_context_new_rvalue_from_int(def->function_context, - def->ravi->types->C_intT, Bx))); -} - -void ravi_emit_VARARG(ravi_function_def_t *def, int A, int B, int pc) { - (void)pc; - gcc_jit_block_add_eval( - def->current_block, NULL, - ravi_function_call5_rvalue( - def, def->ravi->types->raviV_op_varargT, - gcc_jit_param_as_rvalue(def->L), - gcc_jit_lvalue_as_rvalue(def->ci_val), def->lua_closure, - gcc_jit_context_new_rvalue_from_int(def->function_context, - def->ravi->types->C_intT, A), - gcc_jit_context_new_rvalue_from_int(def->function_context, - def->ravi->types->C_intT, B))); -} \ No newline at end of file diff --git a/src/ravi_gccreturn.c b/src/ravi_gccreturn.c deleted file mode 100644 index a5af704..0000000 --- a/src/ravi_gccreturn.c +++ /dev/null @@ -1,103 +0,0 @@ -/****************************************************************************** -* Copyright (C) 2015 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 - -void ravi_emit_RETURN(ravi_function_def_t *def, int A, int B, int pc) { - - // Here is what OP_RETURN looks like. We only compile steps - // marked with //*. This is because the rest is only relevant in the - // interpreter - - // case OP_RETURN: { - // int b = GETARG_B(i); - //* if (cl->p->sizep > 0) luaF_close(L, base); - //* b = luaD_poscall(L, ra, (b != 0 ? b - 1 : L->top - ra)); - // if (!(ci->callstatus & CIST_REENTRY)) /* 'ci' still the called one */ - // return; /* external invocation: return */ - // else { /* invocation via reentry: continue execution */ - // ci = L->ci; - // if (b) L->top = ci->top; - // goto newframe; /* restart luaV_execute over new Lua function */ - // } - // } - - // As Lua inserts redundant OP_RETURN instructions it is - // possible that this is one of them. If this is the case then the - // current block may already be terminated - so we have to insert - // a new block - if (def->current_block_terminated) { - gcc_jit_block *block = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "OP_RETURN", pc)); - ravi_set_current_block(def, block); - } - - // Load pointer to base - ravi_emit_load_base(def); - - // Get pointer to register A - gcc_jit_lvalue *ra_ptr = ravi_emit_get_register(def, A); - - // if (cl->p->sizep > 0) luaF_close(L, base); - // Get pointer to Proto->sizep - gcc_jit_lvalue *psize = ravi_emit_get_Proto_sizep(def); - - // Test if psize > 0 - gcc_jit_rvalue *psize_gt_0 = ravi_emit_comparison( - def, GCC_JIT_COMPARISON_GT, gcc_jit_lvalue_as_rvalue(psize), - gcc_jit_context_new_rvalue_from_int(def->function_context, - def->ravi->types->C_intT, 0)); - - gcc_jit_block *then_block = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "OP_RETURN_if_sizep_gt_0", pc)); - gcc_jit_block *else_block = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "OP_RETURN_else_sizep_gt_0", pc)); - - ravi_emit_conditional_branch(def, psize_gt_0, then_block, else_block); - - ravi_set_current_block(def, then_block); - gcc_jit_block_add_eval(def->current_block, NULL, - ravi_function_call2_rvalue( - def, def->ravi->types->luaF_closeT, - gcc_jit_param_as_rvalue(def->L), def->base_ref)); - // gcc_jit_lvalue_as_rvalue(def->base))); - - ravi_emit_branch(def, else_block); - ravi_set_current_block(def, else_block); - - gcc_jit_rvalue *nresults = NULL; - if (B != 0) - nresults = ravi_int_constant(def, B - 1); - else - nresults = ravi_emit_num_stack_elements( - def, gcc_jit_lvalue_get_address(ra_ptr, NULL)); - - //* b = luaD_poscall(L, ci, ra, (b != 0 ? b - 1 : L->top - ra)); - gcc_jit_rvalue *b = ravi_function_call4_rvalue( - def, def->ravi->types->luaD_poscallT, gcc_jit_param_as_rvalue(def->L), - gcc_jit_lvalue_as_rvalue(def->ci_val), - gcc_jit_lvalue_get_address(ra_ptr, NULL), nresults); - - gcc_jit_block_end_with_return(def->current_block, NULL, b); - def->current_block_terminated = true; -} diff --git a/src/ravi_gcctable.c b/src/ravi_gcctable.c deleted file mode 100644 index 9580508..0000000 --- a/src/ravi_gcctable.c +++ /dev/null @@ -1,577 +0,0 @@ -/****************************************************************************** -* Copyright (C) 2015 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 -#include - -// R(A+1) := R(B); R(A) := R(B)[RK(C)] -void ravi_emit_SELF(ravi_function_def_t *def, int A, int B, int C, int pc) { - // StkId rb = RB(i); - // setobjs2s(L, ra + 1, rb); - // Protect(luaV_gettable(L, rb, RKC(i), ra)); - (void)pc; - ravi_emit_load_base(def); - gcc_jit_lvalue *rb = ravi_emit_get_register(def, B); - gcc_jit_lvalue *ra1 = ravi_emit_get_register(def, A + 1); - ravi_emit_struct_assign(def, ra1, rb); - gcc_jit_lvalue *ra = ravi_emit_get_register(def, A); - gcc_jit_lvalue *rc = ravi_emit_get_register_or_constant(def, C); - gcc_jit_block_add_eval( - def->current_block, NULL, - ravi_function_call4_rvalue(def, def->ravi->types->luaV_gettableT, - gcc_jit_param_as_rvalue(def->L), - gcc_jit_lvalue_get_address(rb, NULL), - gcc_jit_lvalue_get_address(rc, NULL), - gcc_jit_lvalue_get_address(ra, NULL))); -} - -// R(A) := length of R(B) -void ravi_emit_LEN(ravi_function_def_t *def, int A, int B, int pc) { - // Protect(luaV_objlen(L, ra, RB(i))); - (void)pc; - ravi_emit_load_base(def); - gcc_jit_lvalue *ra = ravi_emit_get_register(def, A); - gcc_jit_lvalue *rb = ravi_emit_get_register(def, B); - gcc_jit_block_add_eval( - def->current_block, NULL, - ravi_function_call3_rvalue(def, def->ravi->types->luaV_objlenT, - gcc_jit_param_as_rvalue(def->L), - gcc_jit_lvalue_get_address(ra, NULL), - gcc_jit_lvalue_get_address(rb, NULL))); -} - -// R(A)[RK(B)] := RK(C) -void ravi_emit_SETTABLE(ravi_function_def_t *def, int A, int B, int C, int pc) { - // Protect(luaV_settable(L, ra, RKB(i), RKC(i))); - (void)pc; - ravi_emit_load_base(def); - gcc_jit_lvalue *ra = ravi_emit_get_register(def, A); - gcc_jit_lvalue *rb = ravi_emit_get_register_or_constant(def, B); - gcc_jit_lvalue *rc = ravi_emit_get_register_or_constant(def, C); - gcc_jit_block_add_eval( - def->current_block, NULL, - ravi_function_call4_rvalue(def, def->ravi->types->luaV_settableT, - gcc_jit_param_as_rvalue(def->L), - gcc_jit_lvalue_get_address(ra, NULL), - gcc_jit_lvalue_get_address(rb, NULL), - gcc_jit_lvalue_get_address(rc, NULL))); -} - -// R(A) := R(B)[RK(C)] -void ravi_emit_GETTABLE(ravi_function_def_t *def, int A, int B, int C, int pc) { - // Protect(luaV_gettable(L, RB(i), RKC(i), ra)); - (void)pc; - ravi_emit_load_base(def); - gcc_jit_lvalue *ra = ravi_emit_get_register(def, A); - gcc_jit_lvalue *rb = ravi_emit_get_register(def, B); - gcc_jit_lvalue *rc = ravi_emit_get_register_or_constant(def, C); - gcc_jit_block_add_eval( - def->current_block, NULL, - ravi_function_call4_rvalue(def, def->ravi->types->luaV_gettableT, - gcc_jit_param_as_rvalue(def->L), - gcc_jit_lvalue_get_address(rb, NULL), - gcc_jit_lvalue_get_address(rc, NULL), - gcc_jit_lvalue_get_address(ra, NULL))); -} - -void ravi_emit_GETTABLE_AF(ravi_function_def_t *def, int A, int B, int C, - int pc, bool omitArrayGetRangeCheck) { - //#define raviH_get_float_inline(L, t, key, v) - //{ unsigned ukey = (unsigned)((key)); - // lua_Number *data = (lua_Number *)t->ravi_array.data; - // if (ukey < t->ravi_array.len) { - // setfltvalue(v, data[ukey]); - // }else - // luaG_runerror(L, "array out of bounds"); - //} - - // TValue *rb = RB(i); - // TValue *rc = RKC(i); - // lua_Integer idx = ivalue(rc); - // Table *t = hvalue(rb); - // raviH_get_float_inline(L, t, idx, ra); - - ravi_emit_load_base(def); - gcc_jit_lvalue *ra = ravi_emit_get_register(def, A); - gcc_jit_lvalue *rb = ravi_emit_get_register(def, B); - gcc_jit_lvalue *rc = ravi_emit_get_register_or_constant(def, C); - gcc_jit_lvalue *key = ravi_emit_load_reg_i(def, rc); - gcc_jit_rvalue *t = ravi_emit_load_reg_h(def, rb); - gcc_jit_rvalue *data = ravi_emit_load_reg_h_floatarray(def, t); - gcc_jit_lvalue *len = ravi_emit_load_ravi_arraylength(def, t); - gcc_jit_rvalue *ukey = gcc_jit_context_new_cast( - def->function_context, NULL, gcc_jit_lvalue_as_rvalue(key), - def->ravi->types->lua_UnsignedT); - - gcc_jit_block *then_block = NULL; - gcc_jit_block *else_block = NULL; - gcc_jit_block *end_block = NULL; - - if (omitArrayGetRangeCheck) { - gcc_jit_rvalue *ulen = gcc_jit_context_new_cast( - def->function_context, NULL, gcc_jit_lvalue_as_rvalue(len), - def->ravi->types->lua_UnsignedT); - - gcc_jit_rvalue *cmp = - ravi_emit_comparison(def, GCC_JIT_COMPARISON_LT, ukey, ulen); - then_block = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "GETTABLE_AF_if_in_range", pc)); - else_block = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "GETTABLE_AF_if_not_in_range", pc)); - end_block = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "GETTABLE_AF_if_end", pc)); - ravi_emit_conditional_branch(def, cmp, then_block, else_block); - ravi_set_current_block(def, then_block); - } - gcc_jit_rvalue *value = ravi_emit_array_get(def, data, ukey); - ravi_emit_store_reg_n_withtype(def, value, ra); - - if (omitArrayGetRangeCheck) { - ravi_emit_branch(def, end_block); - - ravi_set_current_block(def, else_block); - - ravi_emit_raise_lua_error(def, "array out of bounds"); - ravi_emit_branch(def, end_block); - - ravi_set_current_block(def, end_block); - } -} - -void ravi_emit_GETTABLE_AI(ravi_function_def_t *def, int A, int B, int C, - int pc, bool omitArrayGetRangeCheck) { - //#define raviH_get_int_inline(L, t, key, v) - //{ unsigned ukey = (unsigned)((key)); - // lua_Integer *data = (lua_Integer *)t->ravi_array.data; - // if (ukey < t->ravi_array.len) { - // setivalue(v, data[ukey]); - // } else - // luaG_runerror(L, "array out of bounds"); - //} - - // TValue *rb = RB(i); - // TValue *rc = RKC(i); - // lua_Integer idx = ivalue(rc); - // Table *t = hvalue(rb); - // raviH_get_int_inline(L, t, idx, ra); - - ravi_emit_load_base(def); - gcc_jit_lvalue *ra = ravi_emit_get_register(def, A); - gcc_jit_lvalue *rb = ravi_emit_get_register(def, B); - gcc_jit_lvalue *rc = ravi_emit_get_register_or_constant(def, C); - gcc_jit_lvalue *key = ravi_emit_load_reg_i(def, rc); - gcc_jit_rvalue *t = ravi_emit_load_reg_h(def, rb); - gcc_jit_rvalue *data = ravi_emit_load_reg_h_intarray(def, t); - gcc_jit_lvalue *len = ravi_emit_load_ravi_arraylength(def, t); - gcc_jit_rvalue *ukey = gcc_jit_context_new_cast( - def->function_context, NULL, gcc_jit_lvalue_as_rvalue(key), - def->ravi->types->lua_UnsignedT); - - gcc_jit_block *then_block = NULL; - gcc_jit_block *else_block = NULL; - gcc_jit_block *end_block = NULL; - - if (omitArrayGetRangeCheck) { - gcc_jit_rvalue *ulen = gcc_jit_context_new_cast( - def->function_context, NULL, gcc_jit_lvalue_as_rvalue(len), - def->ravi->types->lua_UnsignedT); - - gcc_jit_rvalue *cmp = - ravi_emit_comparison(def, GCC_JIT_COMPARISON_LT, ukey, ulen); - then_block = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "GETTABLE_AI_if_in_range", pc)); - else_block = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "GETTABLE_AI_if_not_in_range", pc)); - end_block = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "GETTABLE_AI_if_end", pc)); - ravi_emit_conditional_branch(def, cmp, then_block, else_block); - ravi_set_current_block(def, then_block); - } - gcc_jit_rvalue *value = ravi_emit_array_get(def, data, ukey); - - ravi_emit_store_reg_i_withtype(def, value, ra); - if (omitArrayGetRangeCheck) { - ravi_emit_branch(def, end_block); - - ravi_set_current_block(def, else_block); - - ravi_emit_raise_lua_error(def, "array out of bounds"); - ravi_emit_branch(def, end_block); - - ravi_set_current_block(def, end_block); - } -} - -void ravi_emit_SETTABLE_AI_AF(ravi_function_def_t *def, int A, int B, int C, - bool known_tt, lua_typecode_t tt, int pc) { - - //#define raviH_set_int_inline(L, t, key, value) - //{ unsigned ukey = (unsigned)((key)); - // lua_Integer *data = (lua_Integer *)t->ravi_array.data; - // if (ukey < t->ravi_array.len) { - // data[ukey] = value; - // } else - // raviH_set_int(L, t, ukey, value); - //} - - // Table *t = hvalue(ra); - // TValue *rb = RKB(i); - // TValue *rc = RKC(i); - // lua_Integer idx = ivalue(rb); - // lua_Integer value = ivalue(rc); - // raviH_set_int_inline(L, t, idx, value); - - ravi_emit_load_base(def); - gcc_jit_lvalue *ra = ravi_emit_get_register(def, A); - gcc_jit_lvalue *rb = ravi_emit_get_register_or_constant(def, B); - gcc_jit_lvalue *rc = ravi_emit_get_register_or_constant(def, C); - gcc_jit_lvalue *key = ravi_emit_load_reg_i(def, rb); - gcc_jit_lvalue *value = NULL; - - switch (tt) { - case LUA__TNUMINT: - value = known_tt ? ravi_emit_load_reg_i(def, rc) - : ravi_emit_tonumtype(def, rc, LUA__TNUMINT, pc); - break; - case LUA__TNUMFLT: - value = known_tt ? ravi_emit_load_reg_n(def, rc) - : ravi_emit_tonumtype(def, rc, LUA__TNUMFLT, pc); - break; - default: - assert(false); - abort(); - } - - gcc_jit_rvalue *t = ravi_emit_load_reg_h(def, ra); - gcc_jit_rvalue *data = NULL; - switch (tt) { - case LUA__TNUMINT: - data = ravi_emit_load_reg_h_intarray(def, t); - break; - case LUA__TNUMFLT: - data = ravi_emit_load_reg_h_floatarray(def, t); - break; - default: - assert(false); - abort(); - } - - gcc_jit_lvalue *len = ravi_emit_load_ravi_arraylength(def, t); - gcc_jit_rvalue *ukey = gcc_jit_context_new_cast( - def->function_context, NULL, gcc_jit_lvalue_as_rvalue(key), - def->ravi->types->lua_UnsignedT); - gcc_jit_rvalue *ulen = gcc_jit_context_new_cast( - def->function_context, NULL, gcc_jit_lvalue_as_rvalue(len), - def->ravi->types->lua_UnsignedT); - - gcc_jit_rvalue *cmp = - ravi_emit_comparison(def, GCC_JIT_COMPARISON_LT, ukey, ulen); - gcc_jit_block *then_block = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "SETTABLE_AX_if_in_range", pc)); - gcc_jit_block *else_block = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "SETTABLE_AX_if_not_in_range", pc)); - gcc_jit_block *end_block = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "SETTABLE_AX_if_end", pc)); - ravi_emit_conditional_branch(def, cmp, then_block, else_block); - ravi_set_current_block(def, then_block); - - gcc_jit_lvalue *ptr = ravi_emit_array_get_ptr(def, data, ukey); - - gcc_jit_block_add_assignment(def->current_block, NULL, ptr, - gcc_jit_lvalue_as_rvalue(value)); - ravi_emit_branch(def, end_block); - - ravi_set_current_block(def, else_block); - - gcc_jit_function *f = NULL; - switch (tt) { - case LUA__TNUMINT: - f = def->ravi->types->raviH_set_intT; - break; - case LUA__TNUMFLT: - f = def->ravi->types->raviH_set_floatT; - break; - default: - assert(false); - abort(); - } - gcc_jit_block_add_eval( - def->current_block, NULL, - ravi_function_call4_rvalue(def, f, gcc_jit_param_as_rvalue(def->L), t, - ukey, gcc_jit_lvalue_as_rvalue(value))); - ravi_emit_branch(def, end_block); - - ravi_set_current_block(def, end_block); -} - -// R(A) := UpValue[B] -void ravi_emit_GETUPVAL(ravi_function_def_t *def, int A, int B, int pc) { - // int b = GETARG_B(i); - // setobj2s(L, ra, cl->upvals[b]->v); - (void)pc; - ravi_emit_load_base(def); - gcc_jit_lvalue *ra = ravi_emit_get_register(def, A); - gcc_jit_rvalue *upval = ravi_emit_get_upvals(def, B); - gcc_jit_lvalue *v = ravi_emit_load_upval_v(def, upval); - ravi_emit_struct_assign( - def, ra, gcc_jit_rvalue_dereference(gcc_jit_lvalue_as_rvalue(v), NULL)); -} - -// UpValue[B] := R(A) -void ravi_emit_SETUPVAL(ravi_function_def_t *def, int A, int B, int pc) { -#if 1 - // Work around libgccjit compilation failure - // The inline version causes segmentation fault during compilation - (void)pc; - ravi_emit_load_base(def); - gcc_jit_lvalue *ra = ravi_emit_get_register(def, A); - gcc_jit_block_add_eval( - def->current_block, NULL, - ravi_function_call4_rvalue(def, def->ravi->types->raviV_op_setupvalT, - gcc_jit_param_as_rvalue(def->L), - gcc_jit_lvalue_as_rvalue(def->lua_closure_val), - gcc_jit_lvalue_get_address(ra, NULL), - ravi_int_constant(def, B))); -#else - // UpVal *uv = cl->upvals[GETARG_B(i)]; - // setobj(L, uv->v, ra); - // luaC_upvalbarrier(L, uv); - - ravi_emit_load_base(def); - gcc_jit_lvalue *ra = ravi_emit_get_register(def, A); - gcc_jit_rvalue *upval = ravi_emit_get_upvals(def, B); - gcc_jit_lvalue *v = ravi_emit_load_upval_v(def, upval); - ravi_emit_struct_assign(def, v, ra); - - gcc_jit_lvalue *type = ravi_emit_load_type(def, v); - - // (type & BIT_ISCOLLECTIBLE) != 0 - gcc_jit_rvalue *bit_iscollectible = ravi_int_constant(def, BIT_ISCOLLECTABLE); - gcc_jit_rvalue *is_collectible_bit = gcc_jit_context_new_binary_op( - def->function_context, NULL, GCC_JIT_BINARY_OP_BITWISE_AND, - def->ravi->types->C_intT, gcc_jit_lvalue_as_rvalue(type), - bit_iscollectible); - gcc_jit_rvalue *zero = ravi_int_constant(def, 0); - gcc_jit_rvalue *is_collectible = ravi_emit_comparison( - def, GCC_JIT_COMPARISON_NE, is_collectible_bit, zero); - - // Is upvalue closed? - // (up->v == &up->u.value) - gcc_jit_lvalue *value = ravi_emit_load_upval_value(def, upval); - gcc_jit_rvalue *upisclosed = ravi_emit_comparison( - def, GCC_JIT_COMPARISON_EQ, gcc_jit_lvalue_as_rvalue(v), - gcc_jit_lvalue_get_address(value, NULL)); - - // Collectible type and upvalue is closed - // ((type & BIT_ISCOLLECTIBLE) != 0) && ((up)->v == &(up)->u.value)) - gcc_jit_rvalue *andcond = gcc_jit_context_new_binary_op( - def->function_context, NULL, GCC_JIT_BINARY_OP_LOGICAL_AND, - def->ravi->types->C_boolT, is_collectible, upisclosed); - - gcc_jit_block *then = gcc_jit_function_new_block( - def->jit_function, - unique_name(def, "SETUPVAL_if_collectible_and_upval_is_closed", pc)); - gcc_jit_block *end = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "SETUPVAL_if_end", pc)); - - ravi_emit_conditional_branch(def, andcond, then, end); - ravi_set_current_block(def, then); - - gcc_jit_block_add_eval( - def->current_block, NULL, - ravi_function_call2_rvalue(def, def->ravi->types->luaC_upvalbarrierT, - gcc_jit_param_as_rvalue(def->L), upval)); - ravi_emit_branch(def, end); - - ravi_set_current_block(def, end); -#endif -} - -// UpValue[A][RK(B)] := RK(C) -void ravi_emit_SETTABUP(ravi_function_def_t *def, int A, int B, int C, int pc) { - - // int a = GETARG_A(i); - // Protect(luaV_settable(L, cl->upvals[a]->v, RKB(i), RKC(i))); - - (void)pc; - ravi_emit_load_base(def); - gcc_jit_lvalue *rb = ravi_emit_get_register_or_constant(def, B); - gcc_jit_lvalue *rc = ravi_emit_get_register_or_constant(def, C); - - gcc_jit_rvalue *upval = ravi_emit_get_upvals(def, A); - gcc_jit_lvalue *v = ravi_emit_load_upval_v(def, upval); - gcc_jit_block_add_eval( - def->current_block, NULL, - ravi_function_call4_rvalue(def, def->ravi->types->luaV_settableT, - gcc_jit_param_as_rvalue(def->L), - gcc_jit_lvalue_as_rvalue(v), - gcc_jit_lvalue_get_address(rb, NULL), - gcc_jit_lvalue_get_address(rc, NULL))); -} - -// R(A) := UpValue[B][RK(C)] -void ravi_emit_GETTABUP(ravi_function_def_t *def, int A, int B, int C, int pc) { - // int b = GETARG_B(i); - // Protect(luaV_gettable(L, cl->upvals[b]->v, RKC(i), ra)); - - (void)pc; - ravi_emit_load_base(def); - gcc_jit_lvalue *ra = ravi_emit_get_register(def, A); - gcc_jit_lvalue *rc = ravi_emit_get_register_or_constant(def, C); - - gcc_jit_rvalue *upval = ravi_emit_get_upvals(def, B); - gcc_jit_lvalue *v = ravi_emit_load_upval_v(def, upval); - gcc_jit_block_add_eval( - def->current_block, NULL, - ravi_function_call4_rvalue(def, def->ravi->types->luaV_gettableT, - gcc_jit_param_as_rvalue(def->L), - gcc_jit_lvalue_as_rvalue(v), - gcc_jit_lvalue_get_address(rc, NULL), - gcc_jit_lvalue_get_address(ra, NULL))); -} - -void ravi_emit_NEWTABLE(ravi_function_def_t *def, int A, int B, int C, int pc) { - // case OP_NEWTABLE: { - // int b = GETARG_B(i); - // int c = GETARG_C(i); - // Table *t = luaH_new(L); - // sethvalue(L, ra, t); - // if (b != 0 || c != 0) - // luaH_resize(L, t, luaO_fb2int(b), luaO_fb2int(c)); - // checkGC(L, ra + 1); - // } break; - (void)pc; - - ravi_emit_load_base(def); - gcc_jit_lvalue *ra = ravi_emit_get_register(def, A); - gcc_jit_block_add_eval( - def->current_block, NULL, - ravi_function_call5_rvalue( - def, def->ravi->types->raviV_op_newtableT, - gcc_jit_param_as_rvalue(def->L), - gcc_jit_lvalue_as_rvalue(def->ci_val), - gcc_jit_lvalue_get_address(ra, NULL), - gcc_jit_context_new_rvalue_from_int(def->function_context, - def->ravi->types->C_intT, B), - gcc_jit_context_new_rvalue_from_int(def->function_context, - def->ravi->types->C_intT, C))); -} - -void ravi_emit_NEWARRAYINT(ravi_function_def_t *def, int A, int pc) { - (void)pc; - - ravi_emit_load_base(def); - gcc_jit_lvalue *ra = ravi_emit_get_register(def, A); - gcc_jit_block_add_eval( - def->current_block, NULL, - ravi_function_call3_rvalue(def, def->ravi->types->raviV_op_newarrayintT, - gcc_jit_param_as_rvalue(def->L), - gcc_jit_lvalue_as_rvalue(def->ci_val), - gcc_jit_lvalue_get_address(ra, NULL))); -} - -void ravi_emit_NEWARRAYFLOAT(ravi_function_def_t *def, int A, int pc) { - (void)pc; - ravi_emit_load_base(def); - gcc_jit_lvalue *ra = ravi_emit_get_register(def, A); - gcc_jit_block_add_eval( - def->current_block, NULL, - ravi_function_call3_rvalue(def, def->ravi->types->raviV_op_newarrayfloatT, - gcc_jit_param_as_rvalue(def->L), - gcc_jit_lvalue_as_rvalue(def->ci_val), - gcc_jit_lvalue_get_address(ra, NULL))); -} - -void ravi_emit_SETLIST(ravi_function_def_t *def, int A, int B, int C, int pc) { - (void)pc; - - ravi_emit_load_base(def); - gcc_jit_lvalue *ra = ravi_emit_get_register(def, A); - gcc_jit_block_add_eval( - def->current_block, NULL, - ravi_function_call5_rvalue( - def, def->ravi->types->raviV_op_setlistT, - gcc_jit_param_as_rvalue(def->L), - gcc_jit_lvalue_as_rvalue(def->ci_val), - gcc_jit_lvalue_get_address(ra, NULL), - gcc_jit_context_new_rvalue_from_int(def->function_context, - def->ravi->types->C_intT, B), - gcc_jit_context_new_rvalue_from_int(def->function_context, - def->ravi->types->C_intT, C))); -} - -void ravi_emit_TOARRAY(ravi_function_def_t *def, int A, int array_type_expected, - const char *errmsg, int pc) { - - // if (!ttistable(ra) || hvalue(ra)->ravi_array.type != RAVI_TARRAYINT) - // luaG_runerror(L, "integer[] expected"); - OpCode op = OP_RAVI_TOTAB; - lua_typecode_t expected_type = RAVI__TLTABLE; - switch (array_type_expected) { - case RAVI_TARRAYINT: - op = OP_RAVI_TOARRAYI; - expected_type = RAVI__TIARRAY; - break; - case RAVI_TARRAYFLT: - op = OP_RAVI_TOARRAYF; - expected_type = RAVI__TFARRAY; - break; - case RAVI_TTABLE: - default: break; - } - - ravi_emit_load_base(def); - gcc_jit_lvalue *ra = ravi_emit_get_register(def, A); - gcc_jit_lvalue *type = ravi_emit_load_type(def, ra); - - // type != expected_type ? - gcc_jit_rvalue *cmp1 = ravi_emit_is_not_value_of_type( - def, gcc_jit_lvalue_as_rvalue(type), expected_type); - - gcc_jit_block *raise_error = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "TOARRAY_if_not_table", pc)); - gcc_jit_block *done = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "TOARRAY_done", pc)); - ravi_emit_conditional_branch(def, cmp1, raise_error, done); - ravi_set_current_block(def, raise_error); - - // Conversion failed, so raise error - ravi_emit_raise_lua_error(def, errmsg); - ravi_emit_branch(def, done); - - ravi_set_current_block(def, done); -} - -void ravi_emit_MOVEAI(ravi_function_def_t *def, int A, int B, int pc) { - ravi_emit_TOARRAY(def, B, RAVI_TARRAYINT, "integer[] expected", pc); - gcc_jit_lvalue *src = ravi_emit_get_register(def, B); - gcc_jit_lvalue *dest = ravi_emit_get_register(def, A); - ravi_emit_struct_assign(def, dest, src); -} - -void ravi_emit_MOVEAF(ravi_function_def_t *def, int A, int B, int pc) { - ravi_emit_TOARRAY(def, B, RAVI_TARRAYFLT, "number[] expected", pc); - gcc_jit_lvalue *src = ravi_emit_get_register(def, B); - gcc_jit_lvalue *dest = ravi_emit_get_register(def, A); - ravi_emit_struct_assign(def, dest, src); -} diff --git a/src/ravi_gcctforcall.c b/src/ravi_gcctforcall.c deleted file mode 100644 index 82ac6f2..0000000 --- a/src/ravi_gcctforcall.c +++ /dev/null @@ -1,140 +0,0 @@ -/****************************************************************************** -* Copyright (C) 2015 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 - -void ravi_emit_TFORCALL(ravi_function_def_t *def, int A, int B, int C, int j, - int jA, int pc) { - - // case OP_TFORCALL: { - // StkId cb = ra + 3; /* call base */ - // setobjs2s(L, cb + 2, ra + 2); - // setobjs2s(L, cb + 1, ra + 1); - // setobjs2s(L, cb, ra); - // L->top = cb + 3; /* func. + 2 args (state and index) */ - // Protect(luaD_call(L, cb, GETARG_C(i), 1)); - // L->top = ci->top; - // i = *(ci->u.l.savedpc++); /* go to next instruction */ - // ra = RA(i); - // lua_assert(GET_OPCODE(i) == OP_TFORLOOP); - // goto l_tforloop; - // } - // case OP_TFORLOOP: { - // l_tforloop: - // if (!ttisnil(ra + 1)) { /* continue loop? */ - // setobjs2s(L, ra, ra + 1); /* save control variable */ - // ci->u.l.savedpc += GETARG_sBx(i); /* jump back */ - // } - // } break; - (void)B; - - // Load pointer to base - ravi_emit_load_base(def); - - // Get pointer to register A - gcc_jit_lvalue *ra = ravi_emit_get_register(def, A); - gcc_jit_lvalue *ra1 = ravi_emit_get_register(def, A + 1); - gcc_jit_lvalue *ra2 = ravi_emit_get_register(def, A + 2); - gcc_jit_lvalue *cb = ravi_emit_get_register(def, A + 3); - gcc_jit_lvalue *cb1 = ravi_emit_get_register(def, A + 4); - gcc_jit_lvalue *cb2 = ravi_emit_get_register(def, A + 5); - - ravi_emit_struct_assign(def, cb2, ra2); - ravi_emit_struct_assign(def, cb1, ra1); - ravi_emit_struct_assign(def, cb, ra); - - // L->top = cb + 3; /* func. + 2 args (state and index) */ - ravi_emit_set_L_top_toreg(def, A + 6); - - // Protect(luaD_call(L, cb, GETARG_C(i))); - gcc_jit_block_add_eval( - def->current_block, NULL, - ravi_function_call3_rvalue( - def, def->ravi->types->luaD_callT, gcc_jit_param_as_rvalue(def->L), - gcc_jit_lvalue_get_address(cb, NULL), - gcc_jit_context_new_rvalue_from_int(def->function_context, - def->ravi->types->C_intT, C))); - // reload base - ravi_emit_load_base(def); - // L->top = ci->top; - ravi_emit_refresh_L_top(def); - ra = ravi_emit_get_register(def, jA); - ra1 = ravi_emit_get_register(def, jA + 1); - gcc_jit_lvalue *type = ravi_emit_load_type(def, ra1); - - // Test if type != LUA_TNIL (0) - gcc_jit_rvalue *isnotnil = ravi_emit_is_not_value_of_type( - def, gcc_jit_lvalue_as_rvalue(type), LUA__TNIL); - gcc_jit_block *then_block = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "OP_TFORCALL_if_not_nil", pc)); - gcc_jit_block *else_block = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "OP_TFORCALL_if_nil", pc)); - ravi_emit_conditional_branch(def, isnotnil, then_block, else_block); - - ravi_set_current_block(def, then_block); - - ravi_emit_struct_assign(def, ra, ra1); - // Do the jump - ravi_emit_branch(def, def->jmp_targets[j]->jmp); - - // Add the else block and make it current so that the next instruction flows - // here - ravi_set_current_block(def, else_block); -} - -void ravi_emit_TFORLOOP(ravi_function_def_t *def, int A, int j, int pc) { - // case OP_TFORLOOP: { - // l_tforloop: - // if (!ttisnil(ra + 1)) { /* continue loop? */ - // setobjs2s(L, ra, ra + 1); /* save control variable */ - // ci->u.l.savedpc += GETARG_sBx(i); /* jump back */ - // } - // } break; - - // Load pointer to base - ravi_emit_load_base(def); - - // Get pointer to register A - gcc_jit_lvalue *ra = ravi_emit_get_register(def, A); - gcc_jit_lvalue *ra1 = ravi_emit_get_register(def, A + 1); - gcc_jit_lvalue *type = ravi_emit_load_type(def, ra1); - - // Test if type != LUA_TNIL (0) - gcc_jit_rvalue *isnotnil = ravi_emit_is_not_value_of_type( - def, gcc_jit_lvalue_as_rvalue(type), LUA__TNIL); - gcc_jit_block *then_block = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "OP_TFORLOOP_if_not_nil", pc)); - gcc_jit_block *else_block = gcc_jit_function_new_block( - def->jit_function, unique_name(def, "OP_TFORLOOP_if_nil", pc)); - ravi_emit_conditional_branch(def, isnotnil, then_block, else_block); - - ravi_set_current_block(def, then_block); - - ravi_emit_struct_assign(def, ra, ra1); - // Do the jump - ravi_emit_branch(def, def->jmp_targets[j]->jmp); - - // Add the else block and make it current so that the next instruction flows - // here - ravi_set_current_block(def, else_block); -} \ No newline at end of file diff --git a/src/ravi_gcctypes.c b/src/ravi_gcctypes.c deleted file mode 100644 index 0b81cf5..0000000 --- a/src/ravi_gcctypes.c +++ /dev/null @@ -1,1157 +0,0 @@ -/****************************************************************************** -* Copyright (C) 2015 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 -#include "ravi_gccjit.h" - -bool ravi_setup_lua_types(ravi_gcc_context_t *ravi) { - ravi->types = (ravi_gcc_types_t *)calloc(1, sizeof(ravi_gcc_types_t)); - if (!ravi->types) - return false; - -#ifdef LUA_32BITS -#error 32-bit number is not supported for gcc jit -#endif - - ravi_gcc_types_t *t = ravi->types; - - t->C_boolT = gcc_jit_context_get_type(ravi->context, GCC_JIT_TYPE_BOOL); - t->C_doubleT = gcc_jit_context_get_type(ravi->context, GCC_JIT_TYPE_DOUBLE); - t->lua_NumberT = t->C_doubleT; - t->plua_NumberT = gcc_jit_type_get_pointer(t->lua_NumberT); - t->pplua_NumberT = gcc_jit_type_get_pointer(t->plua_NumberT); - - t->lua_IntegerT = - gcc_jit_context_get_int_type(ravi->context, sizeof(lua_Integer), 1); - t->plua_IntegerT = gcc_jit_type_get_pointer(t->lua_IntegerT); - t->pplua_IntegerT = gcc_jit_type_get_pointer(t->plua_IntegerT); - // t->clua_IntegerT = gcc_jit_type_get_const(t->lua_IntegerT); - - t->lua_UnsignedT = - gcc_jit_context_get_int_type(ravi->context, sizeof(lua_Unsigned), 0); - - t->C_intptr_t = - gcc_jit_context_get_int_type(ravi->context, sizeof(intptr_t), 1); - t->C_size_t = gcc_jit_context_get_type(ravi->context, GCC_JIT_TYPE_SIZE_T); - t->C_ptrdiff_t = - gcc_jit_context_get_int_type(ravi->context, sizeof(ptrdiff_t), 1); - t->C_int64_t = - gcc_jit_context_get_int_type(ravi->context, sizeof(int64_t), 1); - t->C_intT = gcc_jit_context_get_type(ravi->context, GCC_JIT_TYPE_INT); - t->C_pintT = gcc_jit_type_get_pointer(t->C_intT); - t->C_shortT = gcc_jit_context_get_type(ravi->context, GCC_JIT_TYPE_SHORT); - t->C_unsigned_shortT = - gcc_jit_context_get_type(ravi->context, GCC_JIT_TYPE_UNSIGNED_SHORT); - t->C_unsigned_intT = - gcc_jit_context_get_type(ravi->context, GCC_JIT_TYPE_UNSIGNED_INT); - - t->lu_memT = t->C_size_t; - - t->l_memT = t->C_ptrdiff_t; - - t->tmsT = t->C_intT; - - t->L_UmaxalignT = t->C_doubleT; - - t->lu_byteT = - gcc_jit_context_get_type(ravi->context, GCC_JIT_TYPE_UNSIGNED_CHAR); - t->C_charT = gcc_jit_context_get_type(ravi->context, GCC_JIT_TYPE_CHAR); - t->C_pcharT = gcc_jit_type_get_pointer(t->C_charT); - t->C_pconstcharT = - gcc_jit_context_get_type(ravi->context, GCC_JIT_TYPE_CONST_CHAR_PTR); - - t->C_voidT = gcc_jit_context_get_type(ravi->context, GCC_JIT_TYPE_VOID); - t->C_pvoidT = gcc_jit_context_get_type(ravi->context, GCC_JIT_TYPE_VOID_PTR); - - /* typedef unsigned int Instruction */ - t->InstructionT = t->C_unsigned_intT; - t->pInstructionT = gcc_jit_type_get_pointer(t->InstructionT); - - t->ravitype_tT = - gcc_jit_context_get_int_type(ravi->context, sizeof(ravitype_t), 1); - - t->lua_StateT = - gcc_jit_context_new_opaque_struct(ravi->context, NULL, "ravi_lua_State"); - t->plua_StateT = - gcc_jit_type_get_pointer(gcc_jit_struct_as_type(t->lua_StateT)); - - t->lua_KContextT = t->C_ptrdiff_t; - - gcc_jit_type *elements[32]; - - /* - ** Type for C functions registered with Lua - * typedef int (*lua_CFunction) (lua_State *L); - */ - elements[0] = t->plua_StateT; - t->plua_CFunctionT = gcc_jit_context_new_function_ptr_type( - ravi->context, NULL, t->C_intT, 1, elements, 0); - - /* - ** Type for continuation functions - * typedef int (*lua_KFunction) (lua_State *L, int status, lua_KContext ctx); - */ - elements[0] = t->plua_StateT; - elements[1] = t->C_intT; - elements[2] = t->lua_KContextT; - t->plua_KFunctionT = gcc_jit_context_new_function_ptr_type( - ravi->context, NULL, t->C_intT, 3, elements, 0); - - /* - ** Type for memory-allocation functions - * typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t - *nsize); - */ - elements[0] = t->C_pvoidT; - elements[1] = t->C_pvoidT; - elements[2] = t->C_size_t; - elements[3] = t->C_size_t; - t->plua_AllocT = gcc_jit_context_new_function_ptr_type( - ravi->context, NULL, t->C_voidT, 4, elements, 0); - - t->lua_DebugT = - gcc_jit_context_new_opaque_struct(ravi->context, NULL, "ravi_lua_Debug"); - t->plua_DebugT = - gcc_jit_type_get_pointer(gcc_jit_struct_as_type(t->lua_DebugT)); - - /* typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); */ - elements[0] = t->plua_StateT; - elements[1] = t->plua_DebugT; - t->plua_HookT = gcc_jit_context_new_function_ptr_type( - ravi->context, NULL, t->C_pvoidT, 2, elements, 0); - - gcc_jit_field *fields[32]; - - // struct GCObject { - // GCObject *next; - // lu_byte tt; - // lu_byte marked - // }; - t->GCObjectT = - gcc_jit_context_new_opaque_struct(ravi->context, NULL, "ravi_GCObject"); - t->pGCObjectT = - gcc_jit_type_get_pointer(gcc_jit_struct_as_type(t->GCObjectT)); - fields[0] = - gcc_jit_context_new_field(ravi->context, NULL, t->pGCObjectT, "next"); - fields[1] = gcc_jit_context_new_field(ravi->context, NULL, t->lu_byteT, "tt"); - fields[2] = - gcc_jit_context_new_field(ravi->context, NULL, t->lu_byteT, "marked"); - gcc_jit_struct_set_fields(t->GCObjectT, NULL, 3, fields); - - // 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 */ - // }; - t->Value_value_gc = fields[0] = - gcc_jit_context_new_field(ravi->context, NULL, t->pGCObjectT, "gc"); - fields[1] = gcc_jit_context_new_field(ravi->context, NULL, t->C_pvoidT, "p"); - t->Value_value_b = fields[2] = - gcc_jit_context_new_field(ravi->context, NULL, t->C_intT, "b"); - fields[3] = - gcc_jit_context_new_field(ravi->context, NULL, t->plua_CFunctionT, "f"); - t->Value_value_i = fields[4] = - gcc_jit_context_new_field(ravi->context, NULL, t->lua_IntegerT, "i"); - t->Value_value_n = fields[5] = - gcc_jit_context_new_field(ravi->context, NULL, t->lua_NumberT, "n"); - t->ValueT = gcc_jit_context_new_union_type(ravi->context, NULL, "ravi_Value", - 6, fields); - - // NOTE: Following structure changes when NaN tagging is enabled - // struct TValue { - // union Value value_; - // int tt_; - // }; - t->Value_value = fields[0] = - gcc_jit_context_new_field(ravi->context, NULL, t->ValueT, "value_"); - t->Value_tt = fields[1] = - gcc_jit_context_new_field(ravi->context, NULL, t->C_intT, "tt_"); - t->TValueT = gcc_jit_context_new_struct_type(ravi->context, NULL, - "ravi_TValue", 2, fields); - t->pTValueT = gcc_jit_type_get_pointer(gcc_jit_struct_as_type(t->TValueT)); - t->cTValueT = gcc_jit_type_get_const(gcc_jit_struct_as_type(t->TValueT)); - t->pcTValueT = gcc_jit_type_get_pointer(t->cTValueT); - - t->StkIdT = t->pTValueT; - - // 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; - t->TStringT = - gcc_jit_context_new_opaque_struct(ravi->context, NULL, "ravi_TString"); - t->pTStringT = gcc_jit_type_get_pointer(gcc_jit_struct_as_type(t->TStringT)); - t->ppTStringT = gcc_jit_type_get_pointer(t->pTStringT); - fields[0] = - gcc_jit_context_new_field(ravi->context, NULL, t->pGCObjectT, "next"); - fields[1] = gcc_jit_context_new_field(ravi->context, NULL, t->lu_byteT, "tt"); - fields[2] = - gcc_jit_context_new_field(ravi->context, NULL, t->lu_byteT, "marked"); - fields[3] = - gcc_jit_context_new_field(ravi->context, NULL, t->lu_byteT, "extra"); - fields[4] = - gcc_jit_context_new_field(ravi->context, NULL, t->lu_byteT, "shrlen"); - fields[5] = gcc_jit_context_new_field(ravi->context, NULL, t->C_unsigned_intT, - "hash"); - /* union not mapped */ - fields[6] = - gcc_jit_context_new_field(ravi->context, NULL, t->C_size_t, "lnglen"); - gcc_jit_struct_set_fields(t->TStringT, NULL, 7, fields); - - // Table - t->TableT = - gcc_jit_context_new_opaque_struct(ravi->context, NULL, "ravi_Table"); - t->pTableT = gcc_jit_type_get_pointer(gcc_jit_struct_as_type(t->TableT)); - t->ppTableT = gcc_jit_type_get_pointer(t->pTableT); - - // 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; - fields[0] = - gcc_jit_context_new_field(ravi->context, NULL, t->pGCObjectT, "next"); - fields[1] = gcc_jit_context_new_field(ravi->context, NULL, t->lu_byteT, "tt"); - fields[2] = - gcc_jit_context_new_field(ravi->context, NULL, t->lu_byteT, "marked"); - fields[3] = - gcc_jit_context_new_field(ravi->context, NULL, t->lu_byteT, "ttuv_"); - fields[4] = - gcc_jit_context_new_field(ravi->context, NULL, t->pTableT, "metatable"); - fields[5] = - gcc_jit_context_new_field(ravi->context, NULL, t->C_size_t, "len"); - fields[6] = - gcc_jit_context_new_field(ravi->context, NULL, t->ValueT, "user_"); - t->UdataT = gcc_jit_context_new_struct_type(ravi->context, NULL, "ravi_Udata", - 7, fields); - - // 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; - fields[0] = - gcc_jit_context_new_field(ravi->context, NULL, t->pTStringT, "name"); - fields[1] = - gcc_jit_context_new_field(ravi->context, NULL, t->ravitype_tT, "type"); - fields[2] = - gcc_jit_context_new_field(ravi->context, NULL, t->lu_byteT, "instack"); - fields[3] = - gcc_jit_context_new_field(ravi->context, NULL, t->lu_byteT, "idx"); - t->UpvaldescT = gcc_jit_context_new_struct_type(ravi->context, NULL, - "ravi_Upvaldesc", 4, fields); - t->pUpvaldescT = - gcc_jit_type_get_pointer(gcc_jit_struct_as_type(t->UpvaldescT)); - - // 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; - fields[0] = - gcc_jit_context_new_field(ravi->context, NULL, t->pTStringT, "varname"); - fields[1] = - gcc_jit_context_new_field(ravi->context, NULL, t->C_intT, "startpc"); - fields[2] = - gcc_jit_context_new_field(ravi->context, NULL, t->C_intT, "endpc"); - fields[3] = gcc_jit_context_new_field(ravi->context, NULL, t->ravitype_tT, - "ravi_type"); - t->LocVarT = gcc_jit_context_new_struct_type(ravi->context, NULL, - "ravi_LocVar", 4, fields); - t->pLocVarT = gcc_jit_type_get_pointer(gcc_jit_struct_as_type(t->LocVarT)); - - t->LClosureT = - gcc_jit_context_new_opaque_struct(ravi->context, NULL, "ravi_LClosure"); - t->pLClosureT = - gcc_jit_type_get_pointer(gcc_jit_struct_as_type(t->LClosureT)); - t->ppLClosureT = gcc_jit_type_get_pointer(t->pLClosureT); - t->pppLClosureT = gcc_jit_type_get_pointer(t->ppLClosureT); - - // typedef struct RaviJITProto { - // lu_byte jit_status; /* 0=not compiled, 1=can't compile, 2=compiled, - // 3=freed */ - // lu_byte jit_flags; - // unsigned short execution_count; /* how many times has function been - // executed */ - // void *jit_data; - // lua_CFunction jit_function; - //} RaviJITProto; - fields[0] = - gcc_jit_context_new_field(ravi->context, NULL, t->lu_byteT, "jit_status"); - fields[1] = - gcc_jit_context_new_field(ravi->context, NULL, t->lu_byteT, "jit_flags"); - fields[2] = gcc_jit_context_new_field( - ravi->context, NULL, t->C_unsigned_shortT, "execution_count"); - fields[3] = - gcc_jit_context_new_field(ravi->context, NULL, t->C_pvoidT, "jit_data"); - fields[4] = gcc_jit_context_new_field(ravi->context, NULL, t->plua_CFunctionT, - "jit_function"); - t->RaviJITProtoT = gcc_jit_context_new_struct_type( - ravi->context, NULL, "ravi_RaviJITProto", 5, fields); - - // 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; - t->ProtoT = - gcc_jit_context_new_opaque_struct(ravi->context, NULL, "ravi_Proto"); - t->pProtoT = gcc_jit_type_get_pointer(gcc_jit_struct_as_type(t->ProtoT)); - t->ppProtoT = gcc_jit_type_get_pointer(t->pProtoT); - fields[0] = - gcc_jit_context_new_field(ravi->context, NULL, t->pGCObjectT, "next"); - fields[1] = gcc_jit_context_new_field(ravi->context, NULL, t->lu_byteT, "tt"); - fields[2] = - gcc_jit_context_new_field(ravi->context, NULL, t->lu_byteT, "marked"); - fields[3] = - gcc_jit_context_new_field(ravi->context, NULL, t->lu_byteT, "numparams"); - fields[4] = - gcc_jit_context_new_field(ravi->context, NULL, t->lu_byteT, "is_vararg"); - fields[5] = gcc_jit_context_new_field(ravi->context, NULL, t->lu_byteT, - "maxstacksize"); - fields[6] = - gcc_jit_context_new_field(ravi->context, NULL, t->C_intT, "sizeupvalues"); - fields[7] = - gcc_jit_context_new_field(ravi->context, NULL, t->C_intT, "sizek"); - fields[8] = - gcc_jit_context_new_field(ravi->context, NULL, t->C_intT, "sizecode"); - fields[9] = - gcc_jit_context_new_field(ravi->context, NULL, t->C_intT, "sizelineinfo"); - t->Proto_sizep = fields[10] = - gcc_jit_context_new_field(ravi->context, NULL, t->C_intT, "sizep"); - fields[11] = - gcc_jit_context_new_field(ravi->context, NULL, t->C_intT, "sizelocvars"); - fields[12] = - gcc_jit_context_new_field(ravi->context, NULL, t->C_intT, "linedefined"); - fields[13] = gcc_jit_context_new_field(ravi->context, NULL, t->C_intT, - "lastlinedefined"); - t->LClosure_p_k = fields[14] = - gcc_jit_context_new_field(ravi->context, NULL, t->pTValueT, "k"); - fields[15] = - gcc_jit_context_new_field(ravi->context, NULL, t->pInstructionT, "code"); - fields[16] = gcc_jit_context_new_field(ravi->context, NULL, t->ppProtoT, "p"); - fields[17] = - gcc_jit_context_new_field(ravi->context, NULL, t->C_pintT, "lineinfo"); - fields[18] = - gcc_jit_context_new_field(ravi->context, NULL, t->pLocVarT, "locvars"); - fields[19] = gcc_jit_context_new_field(ravi->context, NULL, t->pUpvaldescT, - "upvalues"); - fields[20] = - gcc_jit_context_new_field(ravi->context, NULL, t->pLClosureT, "cache"); - fields[21] = - gcc_jit_context_new_field(ravi->context, NULL, t->pTStringT, "source"); - fields[22] = - gcc_jit_context_new_field(ravi->context, NULL, t->pGCObjectT, "gclist"); - fields[23] = gcc_jit_context_new_field( - ravi->context, NULL, gcc_jit_struct_as_type(t->RaviJITProtoT), - "ravi_jit"); - gcc_jit_struct_set_fields(t->ProtoT, NULL, 24, fields); - - // typedef struct UpVal UpVal; - t->UpValT = - gcc_jit_context_new_opaque_struct(ravi->context, NULL, "ravi_UpVal"); - t->pUpValT = gcc_jit_type_get_pointer(gcc_jit_struct_as_type(t->UpValT)); - - //#define ClosureHeader CommonHeader; lu_byte nupvalues; GCObject *gclist - // typedef struct CClosure { - // ClosureHeader; - // lua_CFunction f; - // TValue upvalue[1]; /* list of upvalues */ - //} CClosure; - fields[0] = - gcc_jit_context_new_field(ravi->context, NULL, t->pGCObjectT, "next"); - fields[1] = gcc_jit_context_new_field(ravi->context, NULL, t->lu_byteT, "tt"); - fields[2] = - gcc_jit_context_new_field(ravi->context, NULL, t->lu_byteT, "marked"); - fields[3] = - gcc_jit_context_new_field(ravi->context, NULL, t->lu_byteT, "nupvalues"); - fields[4] = - gcc_jit_context_new_field(ravi->context, NULL, t->pGCObjectT, "gclist"); - fields[5] = - gcc_jit_context_new_field(ravi->context, NULL, t->plua_CFunctionT, "f"); - fields[6] = gcc_jit_context_new_field( - ravi->context, NULL, - gcc_jit_context_new_array_type(ravi->context, NULL, - gcc_jit_struct_as_type(t->TValueT), 1), - "upvalue"); - t->CClosureT = gcc_jit_context_new_struct_type(ravi->context, NULL, - "ravi_CClosure", 7, fields); - t->pCClosureT = - gcc_jit_type_get_pointer(gcc_jit_struct_as_type(t->CClosureT)); - - // typedef struct LClosure { - // ClosureHeader; - // struct Proto *p; - // UpVal *upvals[1]; /* list of upvalues */ - //} LClosure; - fields[0] = - gcc_jit_context_new_field(ravi->context, NULL, t->pGCObjectT, "next"); - fields[1] = gcc_jit_context_new_field(ravi->context, NULL, t->lu_byteT, "tt"); - fields[2] = - gcc_jit_context_new_field(ravi->context, NULL, t->lu_byteT, "marked"); - fields[3] = - gcc_jit_context_new_field(ravi->context, NULL, t->lu_byteT, "nupvalues"); - fields[4] = - gcc_jit_context_new_field(ravi->context, NULL, t->pGCObjectT, "gclist"); - t->LClosure_p = fields[5] = - gcc_jit_context_new_field(ravi->context, NULL, t->pProtoT, "p"); - t->LClosure_upvals = fields[6] = gcc_jit_context_new_field( - ravi->context, NULL, - gcc_jit_context_new_array_type(ravi->context, NULL, t->pUpValT, 1), - "upvals"); - gcc_jit_struct_set_fields(t->LClosureT, NULL, 7, fields); - - // typedef union Closure { - // CClosure c; - // LClosure l; - //} Closure; - - fields[0] = gcc_jit_context_new_field( - ravi->context, NULL, gcc_jit_struct_as_type(t->CClosureT), "c"); - fields[1] = gcc_jit_context_new_field( - ravi->context, NULL, gcc_jit_struct_as_type(t->LClosureT), "l"); - t->ClosureT = gcc_jit_context_new_union_type(ravi->context, NULL, - "ravi_Closure", 2, fields); - t->pCClosureT = gcc_jit_type_get_pointer(t->ClosureT); - - // typedef union TKey { - // struct { - // TValuefields; - // int next; /* for chaining (offset for next node) */ - // } nk; - // TValue tvk; - //} TKey; - - fields[0] = - gcc_jit_context_new_field(ravi->context, NULL, t->ValueT, "value_"); - fields[1] = gcc_jit_context_new_field(ravi->context, NULL, t->C_intT, "tt_"); - fields[2] = gcc_jit_context_new_field(ravi->context, NULL, t->C_intT, "next"); - gcc_jit_struct *nk = gcc_jit_context_new_struct_type( - ravi->context, NULL, "ravi_TKey_nk", 3, fields); - - fields[0] = gcc_jit_context_new_field(ravi->context, NULL, - gcc_jit_struct_as_type(nk), "nk"); - fields[1] = gcc_jit_context_new_field( - ravi->context, NULL, gcc_jit_struct_as_type(t->TValueT), "tvk"); - t->TKeyT = gcc_jit_context_new_union_type(ravi->context, NULL, "ravi_TKey", 2, - fields); - t->pTKeyT = gcc_jit_type_get_pointer(t->TKeyT); - - // typedef struct Node { - // TValue i_val; - // TKey i_key; - //} Node; - fields[0] = gcc_jit_context_new_field( - ravi->context, NULL, gcc_jit_struct_as_type(t->TValueT), "i_val"); - fields[1] = gcc_jit_context_new_field(ravi->context, NULL, t->TKeyT, "i_key"); - t->NodeT = gcc_jit_context_new_struct_type(ravi->context, NULL, "ravi_Node", - 2, fields); - t->pNodeT = gcc_jit_type_get_pointer(gcc_jit_struct_as_type(t->NodeT)); - - // 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; - - t->RaviArray_data = fields[0] = - gcc_jit_context_new_field(ravi->context, NULL, t->C_pvoidT, "data"); - t->RaviArray_len = fields[1] = - gcc_jit_context_new_field(ravi->context, NULL, t->C_unsigned_intT, "len"); - fields[2] = gcc_jit_context_new_field(ravi->context, NULL, t->C_unsigned_intT, - "size"); - t->RaviArray_array_type = fields[3] = - gcc_jit_context_new_field(ravi->context, NULL, t->lu_byteT, "array_type"); - fields[4] = gcc_jit_context_new_field(ravi->context, NULL, t->lu_byteT, - "array_modifier"); - t->RaviArrayT = gcc_jit_context_new_struct_type(ravi->context, NULL, - "ravi_RaviArray", 5, fields); - - // typedef struct Table { - // CommonHeader; - // lu_byte flags; /* 1<

context, NULL, t->pGCObjectT, "next"); - fields[1] = gcc_jit_context_new_field(ravi->context, NULL, t->lu_byteT, "tt"); - fields[2] = - gcc_jit_context_new_field(ravi->context, NULL, t->lu_byteT, "marked"); - fields[3] = - gcc_jit_context_new_field(ravi->context, NULL, t->lu_byteT, "flags"); - fields[4] = - gcc_jit_context_new_field(ravi->context, NULL, t->lu_byteT, "lsizenode"); - fields[5] = gcc_jit_context_new_field(ravi->context, NULL, t->C_unsigned_intT, - "sizearray"); - fields[6] = - gcc_jit_context_new_field(ravi->context, NULL, t->pTValueT, "array"); - fields[7] = gcc_jit_context_new_field(ravi->context, NULL, t->pNodeT, "node"); - fields[8] = - gcc_jit_context_new_field(ravi->context, NULL, t->pNodeT, "lastfree"); - fields[9] = - gcc_jit_context_new_field(ravi->context, NULL, t->pTableT, "metatable"); - fields[10] = - gcc_jit_context_new_field(ravi->context, NULL, t->pGCObjectT, "gclist"); - t->Table_ravi_array = fields[11] = gcc_jit_context_new_field( - ravi->context, NULL, gcc_jit_struct_as_type(t->RaviArrayT), "ravi_array"); - gcc_jit_struct_set_fields(t->TableT, NULL, 12, fields); - - // struct lua_longjmp; /* defined in ldo.c */ - t->lua_longjumpT = gcc_jit_context_new_opaque_struct(ravi->context, NULL, - "ravi_lua_longjmp"); - t->plua_longjumpT = - gcc_jit_type_get_pointer(gcc_jit_struct_as_type(t->lua_longjumpT)); - - // lzio.h - // typedef struct Mbuffer { - // char *buffer; - // size_t n; - // size_t buffsize; - //} Mbuffer; - fields[0] = - gcc_jit_context_new_field(ravi->context, NULL, t->C_pcharT, "buffer"); - fields[1] = gcc_jit_context_new_field(ravi->context, NULL, t->C_size_t, "n"); - fields[2] = - gcc_jit_context_new_field(ravi->context, NULL, t->C_size_t, "buffsize"); - t->MbufferT = gcc_jit_context_new_struct_type(ravi->context, NULL, - "ravi_Mbuffer", 3, fields); - - // typedef struct stringtable { - // TString **hash; - // int nuse; /* number of elements */ - // int size; - //} stringtable; - fields[0] = - gcc_jit_context_new_field(ravi->context, NULL, t->ppTStringT, "hash"); - fields[1] = gcc_jit_context_new_field(ravi->context, NULL, t->C_intT, "nuse"); - fields[2] = gcc_jit_context_new_field(ravi->context, NULL, t->C_intT, "size"); - t->stringtableT = gcc_jit_context_new_struct_type( - ravi->context, NULL, "ravi_stringtable", 3, fields); - - ///* - //** 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; - - t->CallInfoT = - gcc_jit_context_new_opaque_struct(ravi->context, NULL, "ravi_CallInfo"); - t->pCallInfoT = - gcc_jit_type_get_pointer(gcc_jit_struct_as_type(t->CallInfoT)); - - t->CallInfo_u_l_base = fields[0] = - gcc_jit_context_new_field(ravi->context, NULL, t->StkIdT, "base"); - fields[1] = gcc_jit_context_new_field(ravi->context, NULL, t->pInstructionT, - "savedpc"); - t->CallInfo_lT = gcc_jit_context_new_struct_type( - ravi->context, NULL, "ravi_CallInfo_lua", 2, fields); - - fields[0] = - gcc_jit_context_new_field(ravi->context, NULL, t->plua_KFunctionT, "k"); - fields[1] = gcc_jit_context_new_field(ravi->context, NULL, t->C_ptrdiff_t, - "old_errfunc"); - fields[2] = - gcc_jit_context_new_field(ravi->context, NULL, t->lua_KContextT, "ctx"); - t->CallInfo_cT = gcc_jit_context_new_struct_type( - ravi->context, NULL, "ravi_CallInfo_C", 3, fields); - - t->CallInfo_u_l = fields[0] = gcc_jit_context_new_field( - ravi->context, NULL, gcc_jit_struct_as_type(t->CallInfo_lT), "l"); - fields[1] = gcc_jit_context_new_field( - ravi->context, NULL, gcc_jit_struct_as_type(t->CallInfo_cT), "c"); - t->CallInfo_uT = gcc_jit_context_new_union_type(ravi->context, NULL, - "ravi_CallInfo_u", 2, fields); - - t->CallInfo_func = fields[0] = - gcc_jit_context_new_field(ravi->context, NULL, t->StkIdT, "func"); - t->CallInfo_top = fields[1] = - gcc_jit_context_new_field(ravi->context, NULL, t->StkIdT, "top"); - fields[2] = - gcc_jit_context_new_field(ravi->context, NULL, t->pCallInfoT, "previous"); - fields[3] = - gcc_jit_context_new_field(ravi->context, NULL, t->pCallInfoT, "next"); - t->CallInfo_u = fields[4] = - gcc_jit_context_new_field(ravi->context, NULL, t->CallInfo_uT, "u"); - fields[5] = - gcc_jit_context_new_field(ravi->context, NULL, t->C_ptrdiff_t, "extra"); - fields[6] = - gcc_jit_context_new_field(ravi->context, NULL, t->C_shortT, "nresults"); - fields[7] = - gcc_jit_context_new_field(ravi->context, NULL, t->C_shortT, "callstatus"); - fields[8] = - gcc_jit_context_new_field(ravi->context, NULL, t->C_shortT, "stacklevel"); - fields[9] = - gcc_jit_context_new_field(ravi->context, NULL, t->lu_byteT, "jitstatus"); - - gcc_jit_struct_set_fields(t->CallInfoT, NULL, 10, fields); - - // typedef struct ravi_State ravi_State; - t->ravi_StateT = - gcc_jit_context_new_opaque_struct(ravi->context, NULL, "ravi_State"); - t->pravi_StateT = - gcc_jit_type_get_pointer(gcc_jit_struct_as_type(t->ravi_StateT)); - - // typedef struct global_State global_State; - t->global_StateT = gcc_jit_context_new_opaque_struct(ravi->context, NULL, - "ravi_global_State"); - t->pglobal_StateT = - gcc_jit_type_get_pointer(gcc_jit_struct_as_type(t->global_StateT)); - - ///* - //** '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 */ - //}; - fields[0] = - gcc_jit_context_new_field(ravi->context, NULL, t->pGCObjectT, "next"); - fields[1] = gcc_jit_context_new_field(ravi->context, NULL, t->lu_byteT, "tt"); - fields[2] = - gcc_jit_context_new_field(ravi->context, NULL, t->lu_byteT, "marked"); - fields[3] = - gcc_jit_context_new_field(ravi->context, NULL, t->lu_byteT, "status"); - t->lua_State_top = fields[4] = - gcc_jit_context_new_field(ravi->context, NULL, t->StkIdT, "top"); - fields[5] = - gcc_jit_context_new_field(ravi->context, NULL, t->pglobal_StateT, "l_G"); - t->lua_State_ci = fields[6] = - gcc_jit_context_new_field(ravi->context, NULL, t->pCallInfoT, "ci"); - fields[7] = - gcc_jit_context_new_field(ravi->context, NULL, t->pInstructionT, "oldpc"); - fields[8] = - gcc_jit_context_new_field(ravi->context, NULL, t->StkIdT, "stack_last"); - fields[9] = - gcc_jit_context_new_field(ravi->context, NULL, t->StkIdT, "stack"); - fields[10] = - gcc_jit_context_new_field(ravi->context, NULL, t->pUpValT, "openupval"); - fields[11] = - gcc_jit_context_new_field(ravi->context, NULL, t->pGCObjectT, "gclist"); - fields[12] = - gcc_jit_context_new_field(ravi->context, NULL, t->plua_StateT, "twups"); - fields[13] = gcc_jit_context_new_field(ravi->context, NULL, t->plua_longjumpT, - "errorJmp"); - fields[14] = gcc_jit_context_new_field( - ravi->context, NULL, gcc_jit_struct_as_type(t->CallInfoT), "base_ci"); - fields[15] = - gcc_jit_context_new_field(ravi->context, NULL, t->plua_HookT, "hook"); - fields[16] = - gcc_jit_context_new_field(ravi->context, NULL, t->C_ptrdiff_t, "errfunc"); - fields[17] = - gcc_jit_context_new_field(ravi->context, NULL, t->C_intT, "stacksize"); - fields[18] = gcc_jit_context_new_field(ravi->context, NULL, t->C_intT, - "basehookcount"); - fields[19] = - gcc_jit_context_new_field(ravi->context, NULL, t->C_intT, "hookcount"); - fields[20] = gcc_jit_context_new_field(ravi->context, NULL, - t->C_unsigned_shortT, "nny"); - fields[21] = gcc_jit_context_new_field(ravi->context, NULL, - t->C_unsigned_shortT, "nCcalls"); - fields[22] = - gcc_jit_context_new_field(ravi->context, NULL, t->lu_byteT, "hookmask"); - fields[23] = - gcc_jit_context_new_field(ravi->context, NULL, t->lu_byteT, "allowhook"); - fields[24] = - gcc_jit_context_new_field(ravi->context, NULL, t->C_unsigned_shortT, "nci"); - gcc_jit_struct_set_fields(t->lua_StateT, NULL, 25, fields); - - // struct UpVal { - // struct TValue *v; /* points to stack or to its own value */ - // lu_mem refcount; /* reference counter */ - // 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; - //}; - - fields[0] = - gcc_jit_context_new_field(ravi->context, NULL, t->pUpValT, "next"); - fields[1] = - gcc_jit_context_new_field(ravi->context, NULL, t->C_intT, "touched"); - t->UpVal_u_openT = gcc_jit_context_new_struct_type( - ravi->context, NULL, "ravi_UpVal_u_open", 2, fields); - - fields[0] = gcc_jit_context_new_field( - ravi->context, NULL, gcc_jit_struct_as_type(t->UpVal_u_openT), "open"); - t->UpVal_u_value = fields[1] = gcc_jit_context_new_field( - ravi->context, NULL, gcc_jit_struct_as_type(t->TValueT), "value"); - t->UpVal_uT = gcc_jit_context_new_union_type(ravi->context, NULL, - "ravi_UpVal_u", 2, fields); - - t->UpVal_v = fields[0] = - gcc_jit_context_new_field(ravi->context, NULL, t->pTValueT, "v"); - fields[1] = - gcc_jit_context_new_field(ravi->context, NULL, t->lu_memT, "refcount"); - t->UpVal_u = fields[2] = - gcc_jit_context_new_field(ravi->context, NULL, t->UpVal_uT, "u"); - gcc_jit_struct_set_fields(t->UpValT, NULL, 3, fields); - - gcc_jit_param *params[12]; - - // int luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, int nres); - params[0] = - gcc_jit_context_new_param(ravi->context, NULL, t->plua_StateT, "L"); - params[1] = - gcc_jit_context_new_param(ravi->context, NULL, t->pCallInfoT, "ci"); - params[2] = - gcc_jit_context_new_param(ravi->context, NULL, t->StkIdT, "firstResult"); - params[3] = gcc_jit_context_new_param(ravi->context, NULL, t->C_intT, "nres"); - t->luaD_poscallT = gcc_jit_context_new_function( - ravi->context, NULL, GCC_JIT_FUNCTION_IMPORTED, t->C_intT, "luaD_poscall", - 4, params, 0); - - // void luaC_upvalbarrier_ (lua_State *L, UpVal *uv) - params[0] = - gcc_jit_context_new_param(ravi->context, NULL, t->plua_StateT, "L"); - params[1] = gcc_jit_context_new_param(ravi->context, NULL, t->pUpValT, "uv"); - t->luaC_upvalbarrierT = gcc_jit_context_new_function( - ravi->context, NULL, GCC_JIT_FUNCTION_IMPORTED, t->C_voidT, - "luaC_upvalbarrier_", 2, params, 0); - - // int luaD_precall (lua_State *L, StkId func, int nresults, int op_call); - params[0] = - gcc_jit_context_new_param(ravi->context, NULL, t->plua_StateT, "L"); - params[1] = gcc_jit_context_new_param(ravi->context, NULL, t->StkIdT, "func"); - params[2] = - gcc_jit_context_new_param(ravi->context, NULL, t->C_intT, "nresults"); - params[3] = - gcc_jit_context_new_param(ravi->context, NULL, t->C_intT, "op_call"); - t->luaD_precallT = gcc_jit_context_new_function( - ravi->context, NULL, GCC_JIT_FUNCTION_IMPORTED, t->C_intT, "luaD_precall", - 4, params, 0); - - // void luaD_call (lua_State *L, StkId func, int nResults) - params[0] = - gcc_jit_context_new_param(ravi->context, NULL, t->plua_StateT, "L"); - params[1] = gcc_jit_context_new_param(ravi->context, NULL, t->StkIdT, "func"); - params[2] = - gcc_jit_context_new_param(ravi->context, NULL, t->C_intT, "nresults"); - t->luaD_callT = gcc_jit_context_new_function( - ravi->context, NULL, GCC_JIT_FUNCTION_IMPORTED, t->C_intT, "luaD_call", 3, - params, 0); - - // void luaV_execute(lua_State L); - params[0] = - gcc_jit_context_new_param(ravi->context, NULL, t->plua_StateT, "L"); - t->luaV_executeT = gcc_jit_context_new_function( - ravi->context, NULL, GCC_JIT_FUNCTION_IMPORTED, t->C_intT, "luaV_execute", - 1, params, 0); - - // void luaF_close (lua_State *L, StkId level) - params[0] = - gcc_jit_context_new_param(ravi->context, NULL, t->plua_StateT, "L"); - params[1] = - gcc_jit_context_new_param(ravi->context, NULL, t->StkIdT, "level"); - t->luaF_closeT = gcc_jit_context_new_function( - ravi->context, NULL, GCC_JIT_FUNCTION_IMPORTED, t->C_voidT, "luaF_close", - 2, params, 0); - - // TODO const - // int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) - params[0] = - gcc_jit_context_new_param(ravi->context, NULL, t->plua_StateT, "L"); - params[1] = - gcc_jit_context_new_param(ravi->context, NULL, t->pcTValueT, "t1"); - params[2] = - gcc_jit_context_new_param(ravi->context, NULL, t->pcTValueT, "t2"); - t->luaV_equalobjT = gcc_jit_context_new_function( - ravi->context, NULL, GCC_JIT_FUNCTION_IMPORTED, t->C_intT, - "luaV_equalobj", 3, params, 0); - - // TODO const - // int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) - params[0] = - gcc_jit_context_new_param(ravi->context, NULL, t->plua_StateT, "L"); - params[1] = gcc_jit_context_new_param(ravi->context, NULL, t->pcTValueT, "l"); - params[2] = gcc_jit_context_new_param(ravi->context, NULL, t->pcTValueT, "r"); - t->luaV_lessthanT = gcc_jit_context_new_function( - ravi->context, NULL, GCC_JIT_FUNCTION_IMPORTED, t->C_intT, - "luaV_lessthan", 3, params, 0); - - // TODO const - // int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) - params[0] = - gcc_jit_context_new_param(ravi->context, NULL, t->plua_StateT, "L"); - params[1] = gcc_jit_context_new_param(ravi->context, NULL, t->pcTValueT, "l"); - params[2] = gcc_jit_context_new_param(ravi->context, NULL, t->pcTValueT, "r"); - t->luaV_lessequalT = gcc_jit_context_new_function( - ravi->context, NULL, GCC_JIT_FUNCTION_IMPORTED, t->C_intT, - "luaV_lessequal", 3, params, 0); - - // TODO const - // l_noret luaG_runerror (lua_State *L, const char *fmt, ...) - params[0] = - gcc_jit_context_new_param(ravi->context, NULL, t->plua_StateT, "L"); - params[1] = - gcc_jit_context_new_param(ravi->context, NULL, t->C_pconstcharT, "fmt"); - t->luaG_runerrorT = gcc_jit_context_new_function( - ravi->context, NULL, GCC_JIT_FUNCTION_IMPORTED, t->C_voidT, - "luaG_runerror", 2, params, 1); - - // TODO const - // int luaV_forlimit (const TValue *obj, lua_Integer *p, lua_Integer step, - // int *stopnow) - params[0] = - gcc_jit_context_new_param(ravi->context, NULL, t->pTValueT, "obj"); - params[1] = - gcc_jit_context_new_param(ravi->context, NULL, t->plua_IntegerT, "p"); - params[2] = - gcc_jit_context_new_param(ravi->context, NULL, t->lua_IntegerT, "step"); - params[3] = - gcc_jit_context_new_param(ravi->context, NULL, t->C_pintT, "stopnow"); - t->luaV_forlimitT = gcc_jit_context_new_function( - ravi->context, NULL, GCC_JIT_FUNCTION_IMPORTED, t->C_intT, - "luaV_forlimit", 4, params, 0); - - // TODO const - // int luaV_tonumber_ (const TValue *obj, lua_Number *n) - params[0] = - gcc_jit_context_new_param(ravi->context, NULL, t->pcTValueT, "obj"); - params[1] = - gcc_jit_context_new_param(ravi->context, NULL, t->plua_NumberT, "n"); - t->luaV_tonumberT = gcc_jit_context_new_function( - ravi->context, NULL, GCC_JIT_FUNCTION_IMPORTED, t->C_intT, - "luaV_tonumber_", 2, params, 0); - - // TODO const - // int luaV_tointeger_ (const TValue *obj, lua_Integer *p) - params[0] = - gcc_jit_context_new_param(ravi->context, NULL, t->pcTValueT, "obj"); - params[1] = - gcc_jit_context_new_param(ravi->context, NULL, t->plua_IntegerT, "p"); - t->luaV_tointegerT = gcc_jit_context_new_function( - ravi->context, NULL, GCC_JIT_FUNCTION_IMPORTED, t->C_intT, - "luaV_tointeger_", 2, params, 0); - - // TODO const - // void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) - params[0] = - gcc_jit_context_new_param(ravi->context, NULL, t->plua_StateT, "L"); - params[1] = gcc_jit_context_new_param(ravi->context, NULL, t->StkIdT, "ra"); - params[2] = - gcc_jit_context_new_param(ravi->context, NULL, t->pcTValueT, "rb"); - t->luaV_objlenT = gcc_jit_context_new_function( - ravi->context, NULL, GCC_JIT_FUNCTION_IMPORTED, t->C_voidT, "luaV_objlen", - 3, params, 0); - - // TODO const - // void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) - params[0] = - gcc_jit_context_new_param(ravi->context, NULL, t->plua_StateT, "L"); - params[1] = gcc_jit_context_new_param(ravi->context, NULL, t->pcTValueT, "t"); - params[2] = - gcc_jit_context_new_param(ravi->context, NULL, t->pTValueT, "key"); - params[3] = gcc_jit_context_new_param(ravi->context, NULL, t->StkIdT, "val"); - t->luaV_gettableT = gcc_jit_context_new_function( - ravi->context, NULL, GCC_JIT_FUNCTION_IMPORTED, t->C_voidT, - "luaV_gettable", 4, params, 0); - - // TODO const - // void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) - params[0] = - gcc_jit_context_new_param(ravi->context, NULL, t->plua_StateT, "L"); - params[1] = gcc_jit_context_new_param(ravi->context, NULL, t->pcTValueT, "t"); - params[2] = - gcc_jit_context_new_param(ravi->context, NULL, t->pTValueT, "key"); - params[3] = gcc_jit_context_new_param(ravi->context, NULL, t->StkIdT, "val"); - t->luaV_settableT = gcc_jit_context_new_function( - ravi->context, NULL, GCC_JIT_FUNCTION_IMPORTED, t->C_voidT, - "luaV_settable", 4, params, 0); - - // TODO const - // void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, - // StkId res, TMS event); - params[0] = - gcc_jit_context_new_param(ravi->context, NULL, t->plua_StateT, "L"); - params[1] = - gcc_jit_context_new_param(ravi->context, NULL, t->pcTValueT, "p1"); - params[2] = - gcc_jit_context_new_param(ravi->context, NULL, t->pcTValueT, "p2"); - params[3] = gcc_jit_context_new_param(ravi->context, NULL, t->StkIdT, "res"); - params[4] = gcc_jit_context_new_param(ravi->context, NULL, t->tmsT, "event"); - t->luaT_trybinTMT = gcc_jit_context_new_function( - ravi->context, NULL, GCC_JIT_FUNCTION_IMPORTED, t->C_voidT, - "luaT_trybinTM", 5, params, 0); - - // void raviV_op_loadnil(CallInfo *ci, int a, int b) - params[0] = - gcc_jit_context_new_param(ravi->context, NULL, t->pCallInfoT, "ci"); - params[1] = gcc_jit_context_new_param(ravi->context, NULL, t->C_intT, "a"); - params[2] = gcc_jit_context_new_param(ravi->context, NULL, t->C_intT, "b"); - t->raviV_op_loadnilT = gcc_jit_context_new_function( - ravi->context, NULL, GCC_JIT_FUNCTION_IMPORTED, t->C_voidT, - "raviV_op_loadnil", 3, params, 0); - - // void raviV_op_newarrayint(lua_State *L, CallInfo *ci, TValue *ra) - params[0] = - gcc_jit_context_new_param(ravi->context, NULL, t->plua_StateT, "L"); - params[1] = - gcc_jit_context_new_param(ravi->context, NULL, t->pCallInfoT, "ci"); - params[2] = gcc_jit_context_new_param(ravi->context, NULL, t->pTValueT, "ra"); - t->raviV_op_newarrayintT = gcc_jit_context_new_function( - ravi->context, NULL, GCC_JIT_FUNCTION_IMPORTED, t->C_voidT, - "raviV_op_newarrayint", 3, params, 0); - - // void raviV_op_newarrayfloat(lua_State *L, CallInfo *ci, TValue *ra) - params[0] = - gcc_jit_context_new_param(ravi->context, NULL, t->plua_StateT, "L"); - params[1] = - gcc_jit_context_new_param(ravi->context, NULL, t->pCallInfoT, "ci"); - params[2] = gcc_jit_context_new_param(ravi->context, NULL, t->pTValueT, "ra"); - t->raviV_op_newarrayfloatT = gcc_jit_context_new_function( - ravi->context, NULL, GCC_JIT_FUNCTION_IMPORTED, t->C_voidT, - "raviV_op_newarrayfloat", 3, params, 0); - - // void raviV_op_newtable(lua_State *L, CallInfo *ci, TValue *ra, int b, int - // c) - params[0] = - gcc_jit_context_new_param(ravi->context, NULL, t->plua_StateT, "L"); - params[1] = - gcc_jit_context_new_param(ravi->context, NULL, t->pCallInfoT, "ci"); - params[2] = gcc_jit_context_new_param(ravi->context, NULL, t->pTValueT, "ra"); - params[3] = gcc_jit_context_new_param(ravi->context, NULL, t->C_intT, "b"); - params[4] = gcc_jit_context_new_param(ravi->context, NULL, t->C_intT, "c"); - t->raviV_op_newtableT = gcc_jit_context_new_function( - ravi->context, NULL, GCC_JIT_FUNCTION_IMPORTED, t->C_voidT, - "raviV_op_newtable", 5, params, 0); - - // void raviV_op_setlist(lua_State *L, CallInfo *ci, TValue *ra, int b, int c) - params[0] = - gcc_jit_context_new_param(ravi->context, NULL, t->plua_StateT, "L"); - params[1] = - gcc_jit_context_new_param(ravi->context, NULL, t->pCallInfoT, "ci"); - params[2] = gcc_jit_context_new_param(ravi->context, NULL, t->pTValueT, "ra"); - params[3] = gcc_jit_context_new_param(ravi->context, NULL, t->C_intT, "b"); - params[4] = gcc_jit_context_new_param(ravi->context, NULL, t->C_intT, "c"); - t->raviV_op_setlistT = gcc_jit_context_new_function( - ravi->context, NULL, GCC_JIT_FUNCTION_IMPORTED, t->C_voidT, - "raviV_op_setlist", 5, params, 0); - - // lua_Integer luaV_div (lua_State *L, lua_Integer m, lua_Integer n) - params[0] = - gcc_jit_context_new_param(ravi->context, NULL, t->plua_StateT, "L"); - params[1] = - gcc_jit_context_new_param(ravi->context, NULL, t->lua_IntegerT, "m"); - params[2] = - gcc_jit_context_new_param(ravi->context, NULL, t->lua_IntegerT, "n"); - t->luaV_divT = gcc_jit_context_new_function( - ravi->context, NULL, GCC_JIT_FUNCTION_IMPORTED, t->lua_IntegerT, - "luaV_div", 3, params, 0); - - // lua_Integer luaV_mod (lua_State *L, lua_Integer m, lua_Integer n) - params[0] = - gcc_jit_context_new_param(ravi->context, NULL, t->plua_StateT, "L"); - params[1] = - gcc_jit_context_new_param(ravi->context, NULL, t->lua_IntegerT, "m"); - params[2] = - gcc_jit_context_new_param(ravi->context, NULL, t->lua_IntegerT, "n"); - t->luaV_modT = gcc_jit_context_new_function( - ravi->context, NULL, GCC_JIT_FUNCTION_IMPORTED, t->lua_IntegerT, - "luaV_mod", 3, params, 0); - - // void raviV_op_concat(lua_State *L, CallInfo *ci, int a, int b, int c) - params[0] = - gcc_jit_context_new_param(ravi->context, NULL, t->plua_StateT, "L"); - params[1] = - gcc_jit_context_new_param(ravi->context, NULL, t->pCallInfoT, "ci"); - params[2] = gcc_jit_context_new_param(ravi->context, NULL, t->C_intT, "a"); - params[3] = gcc_jit_context_new_param(ravi->context, NULL, t->C_intT, "b"); - params[4] = gcc_jit_context_new_param(ravi->context, NULL, t->C_intT, "c"); - t->raviV_op_concatT = gcc_jit_context_new_function( - ravi->context, NULL, GCC_JIT_FUNCTION_IMPORTED, t->C_voidT, - "raviV_op_concat", 5, params, 0); - - // void raviV_op_closure(lua_State *L, CallInfo *ci, LClosure *cl, int a, int - // Bx) - params[0] = - gcc_jit_context_new_param(ravi->context, NULL, t->plua_StateT, "L"); - params[1] = - gcc_jit_context_new_param(ravi->context, NULL, t->pCallInfoT, "ci"); - params[2] = - gcc_jit_context_new_param(ravi->context, NULL, t->pLClosureT, "cl"); - params[3] = gcc_jit_context_new_param(ravi->context, NULL, t->C_intT, "a"); - params[4] = gcc_jit_context_new_param(ravi->context, NULL, t->C_intT, "Bx"); - t->raviV_op_closureT = gcc_jit_context_new_function( - ravi->context, NULL, GCC_JIT_FUNCTION_IMPORTED, t->C_voidT, - "raviV_op_closure", 5, params, 0); - - // void raviV_op_vararg(lua_State *L, CallInfo *ci, LClosure *cl, int a, int - // b) - params[0] = - gcc_jit_context_new_param(ravi->context, NULL, t->plua_StateT, "L"); - params[1] = - gcc_jit_context_new_param(ravi->context, NULL, t->pCallInfoT, "ci"); - params[2] = - gcc_jit_context_new_param(ravi->context, NULL, t->pLClosureT, "cl"); - params[3] = gcc_jit_context_new_param(ravi->context, NULL, t->C_intT, "a"); - params[4] = gcc_jit_context_new_param(ravi->context, NULL, t->C_intT, "b"); - t->raviV_op_varargT = gcc_jit_context_new_function( - ravi->context, NULL, GCC_JIT_FUNCTION_IMPORTED, t->C_voidT, - "raviV_op_vararg", 5, params, 0); - - // void raviH_set_int(lua_State *L, Table *t, lua_Unsigned key, lua_Integer - // value); - params[0] = - gcc_jit_context_new_param(ravi->context, NULL, t->plua_StateT, "L"); - params[1] = - gcc_jit_context_new_param(ravi->context, NULL, t->pTableT, "table"); - params[2] = - gcc_jit_context_new_param(ravi->context, NULL, t->lua_UnsignedT, "key"); - params[3] = - gcc_jit_context_new_param(ravi->context, NULL, t->lua_IntegerT, "value"); - t->raviH_set_intT = gcc_jit_context_new_function( - ravi->context, NULL, GCC_JIT_FUNCTION_IMPORTED, t->C_voidT, - "raviH_set_int", 4, params, 0); - - // void raviH_set_float(lua_State *L, Table *t, lua_Unsigned key, lua_Number - // value); - params[0] = - gcc_jit_context_new_param(ravi->context, NULL, t->plua_StateT, "L"); - params[1] = - gcc_jit_context_new_param(ravi->context, NULL, t->pTableT, "table"); - params[2] = - gcc_jit_context_new_param(ravi->context, NULL, t->lua_UnsignedT, "key"); - params[3] = - gcc_jit_context_new_param(ravi->context, NULL, t->lua_NumberT, "value"); - t->raviH_set_floatT = gcc_jit_context_new_function( - ravi->context, NULL, GCC_JIT_FUNCTION_IMPORTED, t->C_voidT, - "raviH_set_float", 4, params, 0); - - // void raviV_op_setupval(lua_State *L, LClosure *cl, TValue *ra, int b) - params[0] = - gcc_jit_context_new_param(ravi->context, NULL, t->plua_StateT, "L"); - params[1] = - gcc_jit_context_new_param(ravi->context, NULL, t->pLClosureT, "cl"); - params[2] = gcc_jit_context_new_param(ravi->context, NULL, t->pTValueT, "ra"); - params[3] = gcc_jit_context_new_param(ravi->context, NULL, t->C_intT, "b"); - t->raviV_op_setupvalT = gcc_jit_context_new_function( - ravi->context, NULL, GCC_JIT_FUNCTION_IMPORTED, t->C_voidT, - "raviV_op_setupval", 4, params, 0); - - params[0] = gcc_jit_context_new_param(ravi->context, NULL, t->C_pconstcharT, - "format"); - t->printfT = gcc_jit_context_new_function(ravi->context, NULL, - GCC_JIT_FUNCTION_IMPORTED, - t->C_intT, "printf", 1, params, 1); - - return ravi_jit_has_errored(ravi) ? false : true; -}