Compare commits

..

22 Commits

Author SHA1 Message Date
Dibyendu Majumdar 68b0359383 resolve merge conflict
6 years ago
Dibyendu Majumdar be17c645c3 merge master
6 years ago
Dibyendu Majumdar 56c3af3285 merge master
6 years ago
Dibyendu Majumdar 320e6b5da6 issue #145 merge into lua54 branch
6 years ago
Dibyendu Majumdar e75b146bfc issue #140 missed change!
6 years ago
Dibyendu Majumdar 6cea3bc383 Merge branch 'master' into lua54
6 years ago
Dibyendu Majumdar 64dfadd3a6 tools update
6 years ago
Dibyendu Majumdar 6bbfb88799 issue #141 remove calls to GC from inside JIT compiler
6 years ago
Dibyendu Majumdar b450f3dac3 fix issue with recursive compiles
6 years ago
dylan ef7a270433 issue #139 maybe a bug in recursive compilation plus avoid requiring C++14
6 years ago
Dibyendu Majumdar 3426e55dd8 issue #139 some more merge
6 years ago
Dibyendu Majumdar 7c8e9bcf27 issue #139 In Ravi table has two additional sub types that need to be handled in GC
6 years ago
Dibyendu Majumdar 60b75db2ed issue #139 merge gc related changes
6 years ago
Dibyendu Majumdar bc68457199 issue #139 merge gc related changes
6 years ago
Dibyendu Majumdar 6bdfe1fbd2 issue #139 merge gc related changes
6 years ago
Dibyendu Majumdar 123fb4079a issue #139 lost in translation
6 years ago
Dibyendu Majumdar 7c5b846a7b issue #139 various bug fixes
6 years ago
Dibyendu Majumdar 971b548f1b issue #139 work in progress
6 years ago
Dibyendu Majumdar 157bc43162 issue #139 work in progress
6 years ago
Dibyendu Majumdar caf59c84a7 issue #139 refactor to enable upcoming changes in GC
6 years ago
Dibyendu Majumdar 136dd5623b issue #139 lua 5.4 merge e6c1e6005a
6 years ago
Dibyendu Majumdar 87cf534302 issue #139 lua 5.4 merge d266d40dea
6 years ago

@ -9,11 +9,11 @@ AlignEscapedNewlinesLeft: true
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortBlocksOnASingleLine: true
AllowShortCaseLabelsOnASingleLine: true
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: true
AllowShortLoopsOnASingleLine: true
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: true
@ -35,7 +35,7 @@ BreakBeforeBinaryOperators: None
BreakBeforeBraces: Custom
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
ColumnLimit: 120
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4

@ -1,7 +0,0 @@
# [Choice] Debian / Ubuntu version: debian-10, debian-9, ubuntu-20.04, ubuntu-18.04
ARG VARIANT=buster
FROM mcr.microsoft.com/vscode/devcontainers/cpp:dev-${VARIANT}
# [Optional] Uncomment this section to install additional packages.
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
# && apt-get -y install --no-install-recommends <your-package-list-here>

@ -1,12 +0,0 @@
# [Choice] Debian / Ubuntu version: debian-10, debian-9, ubuntu-20.04, ubuntu-18.04
ARG VARIANT=buster
FROM mcr.microsoft.com/vscode/devcontainers/base:${VARIANT}
# Install needed packages. Use a separate RUN statement to add your own dependencies.
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
&& apt-get -y install build-essential cmake cppcheck valgrind clang lldb llvm gdb \
&& apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/*
# [Optional] Uncomment this section to install additional OS packages.
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
# && apt-get -y install --no-install-recommends <your-package-list-here>

@ -1,28 +0,0 @@
{
"name": "C++",
"build": {
"dockerfile": "Dockerfile",
// Update 'VARIANT' to pick an Debian / Ubuntu OS version: debian-10, debian-9, ubuntu-20.04, ubuntu-18.04
"args": { "VARIANT": "debian-10" }
},
"runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined"],
// Set *default* container specific settings.json values on container create.
"settings": {
"terminal.integrated.shell.linux": "/bin/bash"
},
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"ms-vscode.cpptools"
],
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],
// Use 'postCreateCommand' to run commands after the container is created.
// "postCreateCommand": "gcc -v",
// Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
"remoteUser": "vscode"
}

@ -1,48 +0,0 @@
name: build
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Release
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v2
- name: Install Dependencies
run: sudo apt-get install -y libreadline-dev
- name: Create Build Environment
run: cmake -E make_directory ${{runner.workspace}}/build
- name: Configure CMake
# Use a bash shell so we can use the same syntax for environment variable
# access regardless of the host operating system
shell: bash
working-directory: ${{runner.workspace}}/build
# Note the current convention is to use the -S and -B options here to specify source
# and build directories, but this is only available with CMake 3.13 and higher.
# The CMake binaries on the Github Actions machines are (as of this writing) 3.12
run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE
- name: Build
working-directory: ${{runner.workspace}}/build
shell: bash
# Execute the build. You can specify a specific target with "--target <NAME>"
run: cmake --build . --config $BUILD_TYPE
- name: Test
shell: bash
run: cd tests && sh run_tests.sh ${{runner.workspace}}/build/ravi

11
.gitignore vendored

@ -4,14 +4,3 @@ CMakeScripts
cmake_install.cmake
install_manifest.txt
CTestTestfile.cmake
build
buildmir
omrjit
buildllvm
.vscode
.idea
cmake-build-debug
cmake-build-release
buildnojit
nojit
nojita

4
.gitmodules vendored

@ -1 +1,3 @@
[submodule "dmr_c"]
path = dmr_c
url = https://github.com/dibyendumajumdar/dmr_c.git

@ -1,20 +1,33 @@
language: cpp
os:
- linux
arch:
- amd64
- arm64
env:
- ARCH="x86_64"
compiler:
- gcc
cache: ccache
dist: focal
addons:
apt:
sources:
- llvm-toolchain-precise
- ubuntu-toolchain-r-test
packages:
- gcc
- clang-3.7
- g++-5
- gcc-5
- ccache
install:
- if [ "$CXX" = "g++" ]; then export CXX="ccache g++-5" CC="ccache gcc-5"; fi
- if [ "$CXX" = "clang++" ]; then export CXX="ccache clang++-3.7" CC="ccache clang-3.7"; fi
- curl https://cmake.org/files/v3.4/cmake-3.4.0-Linux-x86_64.tar.gz | tar -xzf -
- curl http://www.llvm.org/releases/3.7.0/llvm-3.7.0.src.tar.xz | tar -xJf -
- mkdir $TRAVIS_BUILD_DIR/llvm-3.7.0.src/build
- cd $TRAVIS_BUILD_DIR/llvm-3.7.0.src/build && $TRAVIS_BUILD_DIR/cmake-3.4.0-Linux-x86_64/bin/cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/tmp/LLVM37 -DLLVM_TARGETS_TO_BUILD="X86" ..
- cd $TRAVIS_BUILD_DIR/llvm-3.7.0.src/build && make install
script:
- mkdir $TRAVIS_BUILD_DIR/buildmir
- cd $TRAVIS_BUILD_DIR/buildmir && cmake -DCMAKE_BUILD_TYPE=Debug -DLTESTS=ON -DMIR_JIT=ON -G "Unix Makefiles" ..
- cd $TRAVIS_BUILD_DIR/buildmir && make
- cd $TRAVIS_BUILD_DIR/tests && sh ./run_tests.sh $TRAVIS_BUILD_DIR/buildmir/ravi
- if [ "$CXX" = "g++" ]; then export CXX="ccache g++-5" CC="ccache gcc-5"; fi
- if [ "$CXX" = "clang++" ]; then export CXX="ccache clang++-3.7" CC="ccache clang-3.7"; fi
- mkdir $TRAVIS_BUILD_DIR/build
- cd $TRAVIS_BUILD_DIR/build && $TRAVIS_BUILD_DIR/cmake-3.4.0-Linux-x86_64/bin/cmake -DCMAKE_BUILD_TYPE=Debug -DLLVM_DIR=/tmp/LLVM37/share/llvm/cmake -G "Unix Makefiles" -DLLVM_JIT=ON ..
- cd $TRAVIS_BUILD_DIR/build && make
- cd $TRAVIS_BUILD_DIR/lua-tests && sh ./run_travis_tests.sh $TRAVIS_BUILD_DIR/build/ravi

@ -1,99 +1,197 @@
cmake_minimum_required(VERSION 3.12)
project(Ravi VERSION 1.0.4 LANGUAGES C)
cmake_minimum_required(VERSION 2.8)
project(Ravi)
# By default MIR JIT backend is automatically enabled. To disable user must specify
# NO_JIT=ON
enable_language(CXX)
enable_language(C)
enable_language(ASM)
enable_testing()
option(NO_JIT "Controls whether JIT should be disabled, default is OFF" OFF)
# By default JIT is OFF
option(LLVM_JIT "Controls whether LLVM JIT compilation will be enabled, default is OFF" OFF)
option(STATIC_BUILD "Build static version of Ravi, default is OFF" OFF)
option(COMPUTED_GOTO "Controls whether the interpreter switch will use computed gotos on gcc/clang, default is ON" ON)
option(LTESTS "Controls whether ltests are enabled in Debug mode; note requires Debug build" ON)
option(ASAN "Controls whether address sanitizer should be enabled" OFF)
option(RAVICOMP "Controls whether to link in RaviComp" ON)
# By we enable MIR JIT
if (NOT NO_JIT)
set(MIR_JIT ON)
endif ()
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)
option(LTESTS "Controls whether ltests are enabled in Debug mode" OFF)
if (MIR_JIT)
set(STATIC_BUILD OFF) # Because we need to expose the symbols in the library
endif ()
if (LLVM_JIT)
set(ASM_VM OFF)
endif()
if (ASM_VM)
# For now we switch to static build
# TODO A fix is needed to ensure that in shared library the asm functions are resolved
set(STATIC_BUILD ON)
set(LTESTS OFF)
endif()
if (STATIC_BUILD)
message(STATUS "STATIC library build enabled")
set(LIBRAVI_BUILD_TYPE STATIC)
else ()
else()
message(STATUS "DYNAMIC library build enabled")
set(LIBRAVI_BUILD_TYPE SHARED)
endif ()
endif()
if (LLVM_JIT)
find_package(LLVM REQUIRED CONFIG)
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
include_directories(${LLVM_INCLUDE_DIRS})
add_definitions(${LLVM_DEFINITIONS})
# We also need to define USE_LLVM when compiling code
# but rather than setting globally we set this when building the
# library
endif()
message(STATUS "Computed goto ${COMPUTED_GOTO}")
if (COMPUTED_GOTO AND MSVC)
message(WARNING "Computed goto is not available with MSVC")
endif()
if (NOT LLVM_JIT)
message(WARNING "LLVM will not be enabled; specify -DLLVM_JIT=ON to enable")
endif()
if (MSVC)
set(CMAKE_C_FLAGS_DEBUG "/Od /D_DEBUG /MDd /Zi /RTC1 /EHsc")
set(CMAKE_C_FLAGS_RELEASE "/DNDEBUG /O2 /MD /EHsc")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "/DNDEBUG /O2 /MD /Zi /EHsc")
set(CMAKE_C_FLAGS_MINSIZEREL "/DNDEBUG /O2 /MD /EHsc")
set(CMAKE_CXX_FLAGS "/EHsc")
set(CMAKE_CXX_FLAGS_DEBUG "/Od /D_DEBUG /MDd /Zi /RTC1 /EHsc")
set(CMAKE_CXX_FLAGS_RELEASE "/DNDEBUG /O2 /MD /EHsc")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "/DNDEBUG /O2 /MD /Zi /EHsc")
set(CMAKE_CXX_FLAGS_MINSIZEREL "/DNDEBUG /O2 /MD /EHsc")
# Disable signed/unsigned int conversion warnings.
add_definitions("/wd4018")
# Disable warning about using struct/class for the same symobl.
add_definitions("/wd4099")
# Disable performance warning about int-to-bool conversion.
add_definitions("/wd4800")
# Disable signed/unsigned int conversion warnings.
add_definitions("/wd4018")
# Disable warning about the insecurity of using "std::copy".
add_definitions("/wd4996")
add_definitions("/wd4291")
add_definitions("/wd4624")
add_definitions("/wd4141")
add_definitions("/DLUA_COMPAT_5_2")
add_definitions("/DLUA_COMPAT_5_1")
elseif ((CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") AND NOT APPLE)
if (NOT WIN32)
# assume Linux
set(OS_FLAGS "-DLUA_USE_LINUX")
endif ()
# set(SANITIZER_FLAGS "-fsanitize=address")
set(LUA_COMPAT_FLAGS "-DLUA_COMPAT_5_2 -DLUA_COMPAT_5_1")
set(CMAKE_C_FLAGS "-std=c99 -O2 -fomit-frame-pointer -Wall -Wextra -Winline ${LUA_COMPAT_FLAGS} ${OS_FLAGS}")
set(CMAKE_C_FLAGS_DEBUG "${SANITIZER_FLAGS} -fno-omit-frame-pointer -std=c99 -O0 -g3 -Wall -Wextra ${LUA_COMPAT_FLAGS} ${OS_FLAGS}")
set(CMAKE_C_FLAGS_RELEASE "-std=c99 -O2 -fomit-frame-pointer -Wall -Wextra -Winline ${LUA_COMPAT_FLAGS} ${OS_FLAGS}")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${SANITIZER_FLAGS} -std=c99 -O1 -g3 -Wall -Wextra ${LUA_COMPAT_FLAGS} ${OS_FLAGS}")
set(CMAKE_CXX_FLAGS "-fno-rtti -O2 -fomit-frame-pointer -Wall -Wno-sign-compare -Winline -std=c++11 -fno-exceptions ${LUA_COMPAT_FLAGS} ${OS_FLAGS}")
set(CMAKE_CXX_FLAGS_RELEASE "-fno-rtti -O2 -fomit-frame-pointer -Wall -Wno-sign-compare -Winline -std=c++11 -fno-exceptions ${LUA_COMPAT_FLAGS} ${OS_FLAGS}")
set(CMAKE_CXX_FLAGS_DEBUG "${SANITIZER_FLAGS} -fno-omit-frame-pointer -fno-rtti -O0 -g3 -Wall -Wno-sign-compare -std=c++11 -fno-exceptions ${LUA_COMPAT_FLAGS} ${OS_FLAGS}")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${SANITIZER_FLAGS} -fno-rtti -O1 -g3 -Wall -Wno-sign-compare -std=c++11 -fno-exceptions ${LUA_COMPAT_FLAGS} ${OS_FLAGS}")
elseif (APPLE)
set(LUA_COMPAT_FLAGS "-DLUA_COMPAT_5_2 -DLUA_COMPAT_5_1")
set(CMAKE_C_FLAGS "-std=c99 -O3 -Wall -Wextra ${LUA_COMPAT_FLAGS} -DLUA_USE_MACOSX")
set(CMAKE_C_FLAGS_DEBUG "-std=c99 -O0 -g3 -Wall -Wextra ${LUA_COMPAT_FLAGS} -DLUA_USE_MACOSX")
set(CMAKE_C_FLAGS_RELEASE "-std=c99 -O3 -Wall -Wextra ${LUA_COMPAT_FLAGS} -DLUA_USE_MACOSX")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "-std=c99 -O1 -g3 -Wall -Wextra ${LUA_COMPAT_FLAGS} -DLUA_USE_MACOSX")
set(CMAKE_CXX_FLAGS "-O3 -Wall -fno-rtti -Wno-sign-compare -std=c++11 -fno-exceptions ${LUA_COMPAT_FLAGS} -DLUA_USE_MACOSX")
set(CMAKE_CXX_FLAGS_RELEASE "-fno-rtti -O3 -Wall -Wno-sign-compare -std=c++11 -fno-exceptions ${LUA_COMPAT_FLAGS} -DLUA_USE_MACOSX")
set(CMAKE_CXX_FLAGS_DEBUG "-fno-rtti -O0 -g3 -Wall -Wno-sign-compare -std=c++11 -fno-exceptions ${LUA_COMPAT_FLAGS} -DLUA_USE_MACOSX")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-fno-rtti -O1 -g3 -Wall -Wno-sign-compare -std=c++11 -fno-exceptions ${LUA_COMPAT_FLAGS} -DLUA_USE_MACOSX")
else()
message(FATAL_ERROR "Unsupported platform")
endif ()
include_directories("${PROJECT_SOURCE_DIR}/include")
if ((CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "DEBUG") AND LTESTS AND NOT ASM_VM)
# Note that enabling ltests.h messes with global_State and thus interferes with ASM_VM
message(STATUS "Enabling Lua extended test harness 'ltests'")
add_definitions(-DLUA_USER_H="ltests.h")
endif ()
if (ASM_VM)
# For now we switch to static build
# TODO A fix is needed to ensure that in shared library the asm functions are resolved
add_definitions(-DRAVI_USE_ASMVM)
set ( ASMVM_DEFS ${PROJECT_SOURCE_DIR}/include/ravi_asmvm_defs.h )
if (WIN32 AND NOT CYGWIN)
set(VMMODE peobj)
elseif (APPLE)
set(VMMODE machasm)
else()
set(VMMODE elfasm)
endif()
# This macro runs the buildvm command to generate the VM code
macro(add_buildvm_target _target _mode)
add_custom_command(OUTPUT ${_target}
COMMAND ${PROJECT_SOURCE_DIR}/vmbuilder/bin/buildvm ARGS -m ${_mode} -o ${_target} ${ARGN}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
DEPENDS ${PROJECT_SOURCE_DIR}/vmbuilder/bin/buildvm ${ARGN}
)
endmacro(add_buildvm_target)
# define the Lua core source files
# Generate ravi_asmvm.obj / ravi_asmvm.s (obj on Windows)
if ( WIN32 AND NOT CYGWIN )
add_buildvm_target ( ${CMAKE_CURRENT_BINARY_DIR}/ravi_asmvm.obj ${VMMODE} )
set (ASMVM_SRC ${CMAKE_CURRENT_BINARY_DIR}/ravi_asmvm.obj)
else ()
add_buildvm_target ( ${CMAKE_CURRENT_BINARY_DIR}/ravi_asmvm.s ${VMMODE} )
set (ASMVM_SRC ${CMAKE_CURRENT_BINARY_DIR}/ravi_asmvm.s)
endif ()
# Generate the ravi_bcdef.h header file
add_buildvm_target ( ${ASMVM_DEFS} bcdef ${LJLIB_C} )
SET (ASMVM_DEPS
${ASMVM_SRC}
${ASMVM_DEFS}
)
endif()
# define LLVM JIT compiler sources
if (LLVM_JIT)
set(LLVM_JIT_SRCS src/ravi_llvmjit.cpp src/ravi_llvmtypes.cpp
src/ravi_llvmcodegen.cpp src/ravi_llvmforprep.cpp src/ravi_llvmcomp.cpp
src/ravi_llvmreturn.cpp src/ravi_llvmload.cpp src/ravi_llvmforloop.cpp
src/ravi_llvmarith1.cpp src/ravi_llvmcall.cpp src/ravi_llvmtable.cpp
src/ravi_llvmarith2.cpp src/ravi_llvmtforcall.cpp src/ravi_llvmrest.cpp
src/ravi_llvmluaapi.cpp)
else()
set(NO_JIT_SRCS src/ravi_nojit.c)
endif()
# define the lua core source files
set(LUA_CORE_SRCS src/lapi.c src/lcode.c src/lctype.c src/ldebug.c src/ldo.c src/ldump.c
src/lfunc.c src/lgc.c src/llex.c src/lmem.c src/lobject.c src/lopcodes.c
src/lparser.c src/lstate.c src/lstring.c src/ltable.c src/ltm.c src/lundump.c
src/lvm.c src/lzio.c src/ravi_jit.c src/ltests.c src/ravi_profile.c
src/ravi_membuf.c src/ravi_jitshared.c src/bit.c src/ravi_alloc.c)
# define the Lua library source files
set(LUA_LIB_SRCS src/lauxlib.c src/lbaselib.c src/lbitlib.c src/lcorolib.c src/ldblib.c src/liolib.c
src/lmathlib.c src/loslib.c src/ltablib.c src/lstrlib.c src/loadlib.c src/linit.c src/lutf8lib.c)
set(LUA_HEADERS include/lua.h include/luaconf.h include/lualib.h include/lauxlib.h)
set(MIR_JIT_SRCS src/ravi_mirjit.c)
set(NO_JIT_SRCS src/ravi_nojit.c)
set(LUA_CMD_SRCS src/lua.c)
set(RAVICOMP_SRCS src/ravi_complib.c)
file(GLOB RAVI_HEADERS "${PROJECT_SOURCE_DIR}/include/*.h")
src/lvm.c src/lzio.c src/ravijit.cpp src/ltests.c src/ravi_profile.c src/ravi_membuf.c
src/ravi_jitshared.c src/bit.c)
if (COMPUTED_GOTO AND NOT MSVC)
if (CMAKE_C_COMPILER_ID MATCHES "Clang" OR CMAKE_C_COMPILER_ID MATCHES "AppleClang")
if (CMAKE_C_COMPILER_ID MATCHES "Clang")
set_source_files_properties(src/lvm.c PROPERTIES COMPILE_FLAGS -DRAVI_USE_COMPUTED_GOTO)
elseif (CMAKE_C_COMPILER_ID MATCHES "GNU")
elseif(CMAKE_C_COMPILER_ID MATCHES "GNU")
set_source_files_properties(src/lvm.c PROPERTIES COMPILE_FLAGS "-fno-crossjumping -fno-gcse -DRAVI_USE_COMPUTED_GOTO")
endif ()
endif ()
include(CheckCCompilerFlag)
check_c_compiler_flag("-march=native" COMPILER_OPT_ARCH_NATIVE_SUPPORTED)
if (COMPILER_OPT_ARCH_NATIVE_SUPPORTED AND NOT CMAKE_C_FLAGS MATCHES "-march=")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native")
endif ()
if (ASAN)
set(CMAKE_REQUIRED_FLAGS "-fsanitize=address")
check_c_compiler_flag("-fsanitize=address" COMPILER_ASAN_SUPPORTED)
if (COMPILER_ASAN_SUPPORTED AND NOT CMAKE_C_FLAGS_DEBUG MATCHES "-fsanitize=address")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fsanitize=address")
endif ()
endif ()
if (MIR_JIT)
message(STATUS "MIRJIT enabled")
add_subdirectory(mir)
set(MIRJIT_LIBRARIES c2mir)
set(JIT_SRCS ${MIR_JIT_SRCS})
else ()
set(JIT_SRCS ${NO_JIT_SRCS})
endif ()
endif()
endif()
# define the lua lib source files
set(LUA_LIB_SRCS src/lauxlib.c src/lbaselib.c src/lbitlib.c src/lcorolib.c src/ldblib.c src/liolib.c
src/lmathlib.c src/loslib.c src/ltablib.c src/lstrlib.c src/loadlib.c src/linit.c src/lutf8lib.c)
if (RAVICOMP)
set(ADDON_SRCS ${RAVICOMP_SRCS})
add_subdirectory(ravicomp)
set(RAVICOMP_LIBRARIES ravicomp)
endif ()
file(GLOB RAVI_HEADERS "${PROJECT_SOURCE_DIR}/include/*.h")
set(LUA_HEADERS include/lua.h include/luaconf.h include/lualib.h include/lauxlib.h)
# IDE stuff
if (MSVC OR APPLE)
source_group("Ravi Headers" FILES ${RAVI_HEADERS})
source_group("Ravi Source Files" FILES ${LUA_CORE_SRCS} ${LUA_LIB_SRCS} ${JIT_SRCS} ${ADDON_SRCS})
endif ()
# Misc setup
if (MSVC OR APPLE)
source_group("Ravi Source Files" FILES ${LUA_CORE_SRCS} ${LUA_LIB_SRCS}
${LLVM_JIT_SRCS})
if (APPLE)
set(EXTRA_LIBRARIES m readline)
endif ()
@ -104,132 +202,253 @@ elseif (NOT WIN32)
set(EXTRA_LIBRARIES m dl readline)
endif ()
set(LIBRAVI_NAME libravi)
if (EMBEDDED_DMRC)
if (CMAKE_COMPILER_IS_GNUCC)
execute_process(COMMAND ${CMAKE_C_COMPILER} --print-file-name=
OUTPUT_VARIABLE GCC_BASE OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(COMMAND ${CMAKE_C_COMPILER} -print-multiarch
OUTPUT_VARIABLE MULTIARCH_TRIPLET ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
add_definitions(-DGCC_BASE="${GCC_BASE}")
add_definitions(-DMULTIARCH_TRIPLET="${MULTIARCH_TRIPLET}")
endif()
message( STATUS "GCC_BASE_DIR : " ${GCC_BASE})
message( STATUS "MULTIARCH_TRIPLET : " ${MULTIARCH_TRIPLET} )
include_directories("${PROJECT_SOURCE_DIR}/dmr_c/src")
set(DMR_C_HEADERS
dmr_c/src/allocate.h
dmr_c/src/char.h
dmr_c/src/expression.h
dmr_c/src/flow.h
dmr_c/src/ident-list.h
dmr_c/src/linearize.h
dmr_c/src/lib.h
dmr_c/src/parse.h
dmr_c/src/port.h
dmr_c/src/ptrlist.h
dmr_c/src/scope.h
dmr_c/src/symbol.h
dmr_c/src/target.h
dmr_c/src/token.h
dmr_c/src/walksymbol.h
)
set(DMR_C_SRCS
dmr_c/src/allocate.c
dmr_c/src/builtin.c
dmr_c/src/char.c
dmr_c/src/cse.c
dmr_c/src/expression.c
dmr_c/src/evaluate.c
dmr_c/src/expand.c
dmr_c/src/flow.c
dmr_c/src/inline.c
dmr_c/src/lib.c
dmr_c/src/linearize.c
dmr_c/src/liveness.c
dmr_c/src/memops.c
dmr_c/src/parse.c
dmr_c/src/target.c
dmr_c/src/tokenize.c
dmr_c/src/pre-process.c
dmr_c/src/ptrlist.c
dmr_c/src/scope.c
dmr_c/src/show-parse.c
dmr_c/src/simplify.c
dmr_c/src/symbol.c
dmr_c/src/unssa.c
dmr_c/src/walksymbol.c
src/ravi_dmrc_parsesymbols.c
)
if (LLVM_JIT)
set(DMR_C_JIT_SRCS
dmr_c/llvm-backend/sparse-llvm.c
)
set(DMR_C_JIT_HEADERS
dmr_c/llvm-backend/dmr_c.h
)
include_directories("${PROJECT_SOURCE_DIR}/dmr_c/llvm-backend")
else()
set(DMR_C_JIT_HEADERS
dmr_c/null-backend/dmr_c.h
)
include_directories("${PROJECT_SOURCE_DIR}/dmr_c/null-backend")
endif()
if (MSVC OR APPLE)
source_group("dmrC Headers" FILES ${DMR_C_HEADERS} ${DMR_C_JIT_HEADERS})
source_group("dmrC Source Files" FILES ${DMR_C_SRCS} ${DMR_C_JIT_SRCS})
endif()
endif()
# Enable minimal required LLVM components so that the
# the size of the resulting binary is manageable
if (LLVM_JIT)
if (${LLVM_PACKAGE_VERSION} VERSION_LESS "3.8")
set(LLVM_EXTRA_LIBS ipa)
endif()
if (NOT ${LLVM_PACKAGE_VERSION} VERSION_LESS "5.0.0")
set(LLVM_EXTRA_LIBS orcjit)
endif()
message(STATUS "SYSTEM_PROCESSOR ${CMAKE_SYSTEM_PROCESSOR}")
if (CMAKE_SYSTEM_PROCESSOR MATCHES "(x86)|(X86)|(amd64)|(AMD64)")
set(LLVM_LIBS_PROCESSOR
X86CodeGen
X86AsmParser
X86Disassembler
X86AsmPrinter
X86Desc
X86Info
X86Utils
)
elseif (CMAKE_SYSTEM_PROCESSOR MATCHES "arm")
set(LLVM_LIBS_PROCESSOR
ARMCodeGen
ARMAsmParser
ARMDisassembler
ARMAsmPrinter
ARMDesc
ARMInfo
)
endif()
llvm_map_components_to_libnames(LLVM_LIBS
Analysis
AsmParser
AsmPrinter
BitReader
Core
CodeGen
ExecutionEngine
InstCombine
${LLVM_EXTRA_LIBS}
ipo
MC
MCJIT
MCParser
Object
RuntimeDyld
ScalarOpts
Support
Target
TransformUtils
${LLVM_LIBS_PROCESSOR}
)
message(STATUS "LLVM_LIBS ${LLVM_LIBS}")
endif ()
if (NOT STATIC_BUILD)
set(LIBRAVI_BUILD_TYPE SHARED)
endif()
if (LLVM_JIT)
set (LIBRAVI_NAME libravillvm)
else()
set (LIBRAVI_NAME libravinojit)
endif()
#Main library
add_library(${LIBRAVI_NAME} ${LIBRAVI_BUILD_TYPE}
add_library(${LIBRAVI_NAME} ${LIBRAVI_BUILD_TYPE}
${RAVI_HEADERS}
${LUA_LIB_SRCS}
${LUA_LIB_SRCS}
${LUA_CORE_SRCS}
${JIT_SRCS}
${ADDON_SRCS})
target_link_libraries(${LIBRAVI_NAME} LINK_PUBLIC ${EXTRA_LIBRARIES} ${MIRJIT_LIBRARIES} ${RAVICOMP_LIBRARIES})
${LLVM_JIT_SRCS}
${NO_JIT_SRCS}
${DMR_C_HEADERS}
${DMR_C_SRCS}
${DMR_C_JIT_SRCS}
${ASMVM_DEPS}
)
if (NOT STATIC_BUILD)
if (WIN32)
# enable DLL export
set_target_properties(${LIBRAVI_NAME} PROPERTIES DEFINE_SYMBOL "LUA_BUILD_AS_DLL")
else()
set_target_properties(${LIBRAVI_NAME} PROPERTIES PREFIX "")
endif ()
endif()
if (LLVM_JIT)
set_target_properties(${LIBRAVI_NAME} PROPERTIES COMPILE_DEFINITIONS "USE_LLVM=1")
endif()
if (EMBEDDED_DMRC)
set_target_properties(${LIBRAVI_NAME} PROPERTIES COMPILE_DEFINITIONS "USE_DMR_C=1")
endif()
target_link_libraries(${LIBRAVI_NAME} ${EXTRA_LIBRARIES} ${LLVM_LIBS})
# Main Ravi executable
add_executable(ravi ${LUA_CMD_SRCS})
add_executable(ravi src/lua.c)
if (LLVM_JIT)
set_target_properties(ravi PROPERTIES COMPILE_DEFINITIONS "USE_LLVM=1")
endif()
if (EMBEDDED_DMRC)
set_target_properties(ravi PROPERTIES COMPILE_DEFINITIONS "USE_DMR_C=1")
endif()
target_link_libraries(ravi ${LIBRAVI_NAME})
# Sources that are needed for a static NOJIT basic library
set(NOJIT_RAVI_SRCS
${RAVI_HEADERS}
${LUA_LIB_SRCS}
${LUA_CORE_SRCS}
${NO_JIT_SRCS})
set(RAVI_STATICEXEC_TARGET ravi_s)
set(NOJIT_RAVI_SRCS
${RAVI_HEADERS}
${LUA_LIB_SRCS}
${LUA_CORE_SRCS}
src/ravi_nojit.c)
# We always build a static library without JIT so that
# we can create some default executables
add_library(libravinojit_static
${NOJIT_RAVI_SRCS})
add_library(libravinojit_static
${NOJIT_RAVI_SRCS})
set_target_properties(libravinojit_static PROPERTIES PREFIX "") # As we already prefix with lib
target_link_libraries(libravinojit_static ${EXTRA_LIBRARIES})
# Create a simple NoJIT version of statically linked ravi
# This is sometimes useful in other projects that just need a Lua commandline
# but do not care about the shared library
add_executable(${RAVI_STATICEXEC_TARGET}
${LUA_CMD_SRCS})
# but do not care about the shared library
add_executable(ravi_s
src/lua.c)
target_link_libraries(ravi_s libravinojit_static)
if (NOT LTESTS)
# Note that enabling ltests.h messes with global_State
message(STATUS "Disabling Lua extended test harness 'ltests'")
set_property(
TARGET ${LIBRAVI_NAME} ravi
APPEND
PROPERTY COMPILE_DEFINITIONS NO_LUA_DEBUG)
set(NO_LUA_DEBUG 1)
endif ()
if (MIR_JIT)
set_property(
TARGET ${LIBRAVI_NAME} ravi
APPEND
PROPERTY COMPILE_DEFINITIONS "USE_MIRJIT=1")
set(USE_MIRJIT 1)
endif ()
if (NOT STATIC_BUILD)
if (WIN32)
# enable DLL export
set_property(
TARGET ${LIBRAVI_NAME}
APPEND
PROPERTY COMPILE_DEFINITIONS LUA_BUILD_AS_DLL)
else ()
set_target_properties(${LIBRAVI_NAME} PROPERTIES PREFIX "")
endif ()
else ()
set_target_properties(${LIBRAVI_NAME} PROPERTIES PREFIX "")
endif ()
if (RAVICOMP)
set_property(
TARGET ${LIBRAVI_NAME}
APPEND
PROPERTY COMPILE_DEFINITIONS "USE_RAVICOMP=1")
set(USE_RAVICOMP 1)
endif ()
if (APPLE)
set_property(
TARGET ${LIBRAVI_NAME} libravinojit_static
APPEND
PROPERTY COMPILE_DEFINITIONS "LUA_USE_MACOSX=1")
elseif (UNIX)
set_property(
TARGET ${LIBRAVI_NAME} libravinojit_static
APPEND
PROPERTY COMPILE_DEFINITIONS "LUA_USE_LINUX=1")
endif ()
include(GNUInstallDirs)
configure_file(ravi-config.h.in ravi-config.h @ONLY)
target_include_directories(${LIBRAVI} ravi
PUBLIC
"${PROJECT_BINARY_DIR}")
# Ravi VSCode Debug adapter
set(RAVI_DEBUGGER_TARGET ravidebug)
add_executable(${RAVI_DEBUGGER_TARGET}
vscode-debugger/src/ravidebug.c
vscode-debugger/src/json.c
vscode-debugger/src/protocol.c)
add_executable(${RAVI_DEBUGGER_TARGET}
vscode-debugger/src/ravidebug.c
vscode-debugger/src/json.c
vscode-debugger/src/protocol.c)
target_link_libraries(${RAVI_DEBUGGER_TARGET} libravinojit_static)
# Tests for VSCode Debug Adapter
add_executable(testravidebug
vscode-debugger/src/testravidebug.c
vscode-debugger/src/json.c
vscode-debugger/src/protocol.c)
# Tests for VSCode Debug Adapter
add_executable(testravidebug
vscode-debugger/src/testravidebug.c
vscode-debugger/src/json.c
vscode-debugger/src/protocol.c)
target_link_libraries(testravidebug libravinojit_static)
configure_file(lua-config.cmake.in lua-config.cmake @ONLY)
# Simple VM tests
add_executable(test_vm tests/test_vm.c)
target_link_libraries(test_vm ${LIBRAVI_NAME})
if (WIN32)
configure_file(ravi-env.bat.in ravi-env.bat @ONLY)
set(RAVI_SCRIPTS ${CMAKE_CURRENT_BINARY_DIR}/ravi-env.bat)
elseif (APPLE)
configure_file(ravi-env.osx.sh.in ravi-env.sh @ONLY)
set(RAVI_SCRIPTS ${CMAKE_CURRENT_BINARY_DIR}/ravi-env.sh)
else ()
configure_file(ravi-env.linux.sh.in ravi-env.sh @ONLY)
set(RAVI_SCRIPTS ${CMAKE_CURRENT_BINARY_DIR}/ravi-env.sh)
if (LLVM_JIT)
# LLVM playground
add_executable(test_llvm tests/test_llvm.cpp)
set_target_properties(test_llvm PROPERTIES COMPILE_DEFINITIONS "USE_LLVM=1")
target_link_libraries(test_llvm ${LIBRAVI_NAME})
endif ()
add_executable(test_misc tests/test_misc.c)
add_test(TestRaviDebug testravidebug)
if (LLVM_JIT)
add_test(TestLLVM test_llvm)
endif ()
add_test(TestVM test_vm)
add_test(TestMisc test_misc)
install(FILES ${LUA_HEADERS}
DESTINATION include/ravi)
install(TARGETS ${LIBRAVI_NAME} ravi ${RAVI_DEBUGGER_TARGET} ${RAVI_STATICEXEC_TARGET}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Ravi_Runtime
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Ravi_Development
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Ravi_Runtime)
install(FILES ${RAVI_SCRIPTS}
DESTINATION ${CMAKE_INSTALL_BINDIR})
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/lua-config.cmake
DESTINATION cmake)
install(TARGETS ${LIBRAVI_NAME} ravi ${RAVI_DEBUGGER_TARGET} ravi_s
RUNTIME DESTINATION bin
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib)

@ -1,23 +1,5 @@
/******************************************************************************
* Copyright (C) 1994-2019 Lua.org, PUC-Rio.
* Portions Copyright (C) 2015-2020 Dibyendu Majumdar
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
******************************************************************************/
Most of Ravi is under MIT License
There are components that are under GPL - please see relevant
source files. These are optional components that are part of the
libgccjit implementation of the JIT compiler. You can remove these
components if you do not want GPL license.

@ -6,7 +6,7 @@
# == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT =======================
# Your platform. See PLATS for possible values.
PLAT= guess
PLAT= none
# Where to install. The installation starts in the src and doc directories,
# so take care if INSTALL_TOP is not an absolute path. See the local target.
@ -38,7 +38,7 @@ RM= rm -f
# == END OF USER SETTINGS -- NO NEED TO CHANGE ANYTHING BELOW THIS LINE =======
# Convenience platforms targets.
PLATS= guess aix bsd c89 freebsd generic linux linux-noreadline macosx mingw posix solaris
PLATS= aix bsd c89 freebsd generic linux macosx mingw posix solaris
# What to install.
TO_BIN= ravi
@ -48,7 +48,7 @@ TO_LIB= libravinojit.a
# Lua version and release.
V= 5.3
R= $V.5
R= $V.4
# Targets start here.
all: $(PLAT)

@ -1,195 +0,0 @@
Ravi Programming Language
=========================
![image](https://travis-ci.org/dibyendumajumdar/ravi.svg?branch=master%0A%20:target:%20https://travis-ci.org/dibyendumajumdar/ravi)
Ravi is a dialect of [Lua](http://www.lua.org/) with limited optional
static typing and features [MIR](https://github.com/vnmakarov/mir)
powered JIT compilers. The name Ravi comes from the Sanskrit word for
the Sun. Interestingly a precursor to Lua was
[Sol](http://www.lua.org/history.html) which had support for static
types; Sol means the Sun in Portugese.
Lua is perfect as a small embeddable dynamic language so why a
derivative? Ravi extends Lua with static typing for improved performance
when JIT compilation is enabled. However, the static typing is optional
and therefore Lua programs are also valid Ravi programs.
There are other attempts to add static typing to Lua - e.g. [Typed
Lua](https://github.com/andremm/typedlua) but these efforts are mostly
about adding static type checks in the language while leaving the VM
unmodified. The Typed Lua effort is very similar to the approach taken
by Typescript in the JavaScript world. The static typing is to aid
programming in the large - the code is eventually translated to standard
Lua and executed in the unmodified Lua VM.
My motivation is somewhat different - I want to enhance the VM to
support more efficient operations when types are known. Type information
can be exploited by JIT compilation technology to improve performance.
At the same time, I want to keep the language safe and therefore usable
by non-expert programmers.
Of course there is the fantastic [LuaJIT](http://luajit.org)
implementation. Ravi has a different goal compared to LuaJIT. Ravi
prioritizes ease of maintenance and support, language safety, and
compatibility with Lua 5.3, over maximum performance. For more detailed
comparison please refer to the documentation links below.
Features
--------
- Optional static typing - for details [see the reference
manual](https://the-ravi-programming-language.readthedocs.io/en/latest/ravi-reference.html).
- Type specific bytecodes to improve performance
- Compatibility with Lua 5.3 (see Compatibility section below)
- Generational GC from Lua 5.4
- `defer` statement for releasing resources
- Compact JIT backend [MIR](https://github.com/vnmakarov/mir).
- A [distribution with
batteries](https://github.com/dibyendumajumdar/Suravi).
- A [Visual Studio Code debugger
extension](https://marketplace.visualstudio.com/items?itemName=ravilang.ravi-debug)
- interpreted mode debugger.
Documentation
-------------
- For the Lua extensions in Ravi see the [Reference
Manual](https://the-ravi-programming-language.readthedocs.io/en/latest/ravi-reference.html).
- [MIR JIT Build
instructions](https://the-ravi-programming-language.readthedocs.io/en/latest/ravi-mir-instructions.html).
- Also see [Ravi
Documentation](http://the-ravi-programming-language.readthedocs.org/en/latest/index.html).
- and the slides I presented at the [Lua 2015
Workshop](http://www.lua.org/wshop15.html).
Lua Goodies
-----------
- [An Introduction to
Lua](http://the-ravi-programming-language.readthedocs.io/en/latest/lua-introduction.html)
attempts to provide a quick overview of Lua for folks coming from
other languages.
- [Lua 5.3 Bytecode
Reference](http://the-ravi-programming-language.readthedocs.io/en/latest/lua_bytecode_reference.html)
is my attempt to bring up to date the [Lua 5.1 Bytecode
Reference](http://luaforge.net/docman/83/98/ANoFrillsIntroToLua51VMInstructions.pdf).
- A [patch for Lua
5.3](https://github.com/dibyendumajumdar/ravi/blob/master/patches/defer_statement_for_Lua_5_3.patch)
implements the 'defer' statement.
- A [patch for Lua
5.4.[0-2]](https://github.com/dibyendumajumdar/ravi/blob/master/patches/defer_statement_for_Lua_5_4.patch)
implements the 'defer' statement.
- Updated [patch for Lua
5.4.3](https://github.com/dibyendumajumdar/ravi/blob/master/patches/defer_statement_patch_for_Lua_5_4_3.patch)
implements the 'defer' statement.
Lua 5.4 Position Statement
--------------------------
Lua 5.4 relationship to Ravi is as follows:
- Generational GC - back-ported to Ravi.
- New random number generator - back-ported to Ravi.
- Multiple user values can be associated with userdata - under
consideration.
- `<const>` variables - not planned.
- `<close>` variables - Ravi has `'defer'` statement which is the
better option in my opinion, hence no plans to support `<close>`
variables.
- Interpreter performance improvements - these are beneficial to Lua
interpreter but not to the JIT backends, hence not much point in
back-porting.
- Table implementation changes - under consideration.
- String to number coercion is now part of string library metamethods
- back-ported to Ravi.
- utf8 library accepts codepoints up to 2\^31 - back-ported to Ravi.
- Removal of compatibility layers for 5.1, and 5.2 - not implemented
as Ravi continues to provide these layers as per Lua 5.3.
Compatibility with Lua 5.3
--------------------------
Ravi should be able to run all Lua 5.3 programs in interpreted mode, but
following should be noted:
- Ravi supports optional typing and enhanced types such as arrays (see
the documentation). Programs using these features cannot be run by
standard Lua. However all types in Ravi can be passed to Lua
functions; operations on Ravi arrays within Lua code will be subject
to restrictions as described in the section above on arrays.
- Values crossing from Lua to Ravi will be subjected to typechecks
should these values be assigned to typed variables.
- Upvalues cannot subvert the static typing of local variables (issue
\#26) when types are annotated.
- Certain Lua limits are reduced due to changed byte code structure.
These are described below.
- Ravi uses an extended bytecode which means it is not compatible with
Lua 5.x bytecode.
- Ravi incorporates the new Generational GC from Lua 5.4, hence the GC
interface has changed.
Limit name Lua value Ravi value
------------------ -------------- --------------
MAXUPVAL 255 125
LUAI\_MAXCCALLS 200 125
MAXREGS 255 125
MAXVARS 200 125
MAXARGLINE 250 120
When JIT compilation is enabled there are following additional
constraints:
- Ravi will only execute JITed code from the main Lua thread; any
secondary threads (coroutines) execute in interpreter mode.
- In JITed code tailcalls are implemented as regular calls so unlike
the interpreter VM which supports infinite tail recursion JIT
compiled code only supports tail recursion to a depth of about 110
(issue \#17)
- Debug api and hooks are not supported in JIT mode
History
-------
- 2015
: - Implemented JIT compilation using LLVM
- Implemented [libgccjit based alternative
JIT](https://github.com/dibyendumajumdar/ravi/tree/gccjit-ravi534)
(now discontinued)
- 2016
: - Implemented debugger for Ravi and Lua 5.3 for [Visual Studio
Code](https://github.com/dibyendumajumdar/ravi/tree/master/vscode-debugger)
- 2017
: - Embedded C compiler using dmrC project (C JIT compiler) (now
discontinued)
- Additional type-annotations
- 2018
: - Implemented [Eclipse OMR JIT
backend](https://github.com/dibyendumajumdar/ravi/tree/omrjit)
(now discontinued)
- Created [Ravi with
batteries](https://github.com/dibyendumajumdar/Suravi).
- 2019
: - New language feature - defer statement
- New JIT backend [MIR](https://github.com/vnmakarov/mir).
- 2020
: - [New parser / type checker /
compiler](https://github.com/dibyendumajumdar/ravi-compiler)
- Generational GC back-ported from Lua 5.4
- Support for [LLVM
backend](https://github.com/dibyendumajumdar/ravi/tree/llvm)
archived
- 2021 (Plan)
: - Integrated AOT and JIT compilation support
- Ravi 1.0 release
License
-------
MIT License

@ -0,0 +1,524 @@
=========================
Ravi Programming Language
=========================
Ravi is a derivative/dialect of `Lua 5.3 <http://www.lua.org/>`_ with limited optional static typing and an `LLVM <http://www.llvm.org/>`_ powered JIT compiler. The name Ravi comes from the Sanskrit word for the Sun. Interestingly a precursor to Lua was `Sol <http://www.lua.org/history.html>`_ which had support for static types; Sol means the Sun in Portugese.
Lua is perfect as a small embeddable dynamic language so why a derivative? Ravi extends Lua with static typing for greater performance under JIT compilation. However, the static typing is optional and therefore Lua programs are also valid Ravi programs.
There are other attempts to add static typing to Lua - e.g. `Typed Lua <https://github.com/andremm/typedlua>`_ but these efforts are mostly about adding static type checks in the language while leaving the VM unmodified. The Typed Lua effort is very similar to the approach taken by Typescript in the JavaScript world. The static typing is to aid programming in the large - the code is eventually translated to standard Lua and executed in the unmodified Lua VM.
My motivation is somewhat different - I want to enhance the VM to support more efficient operations when types are known. Type information can be exploited by JIT compilation technology to improve performance. At the same time, I want to keep the language safe and therefore usable by non-expert programmers.
Of course there is also the fantastic `LuaJIT <http://luajit.org>`_ implementation. Ravi has a different goal compared to
LuaJIT. Ravi prioritizes ease of maintenance and support, language safety, and compatibility with Lua 5.3, over maximum performance. For more detailed comparison please refer to the documentation links below.
.. contents:: Table of Contents
:depth: 1
:backlinks: top
Features
========
* Optional static typing
* Type specific bytecodes to improve performance
* Compatibility with Lua 5.3 (see Compatibility section below)
* `LLVM <http://www.llvm.org/>`_ powered JIT compiler
* Additionally a `libgccjit <https://gcc.gnu.org/wiki/JIT>`_ 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
===========
* A `distribution of Ravi/Lua 5.3 <https://github.com/dibyendumajumdar/ravi-distro>`_ is in the works - this will provide ready made binary downloads of Ravi/Lua with select high quality libraries.
* `Experimental Type Annotations`_ for user defined types was implemented in Oct 2017.
* A new `X86-64 VM written in assembler <https://github.com/dibyendumajumdar/ravi/tree/master/vmbuilder>`_ using `dynasm <https://luajit.org/dynasm.html>`_ tool is under development currently.
Documentation
=============
See `Ravi Documentation <http://the-ravi-programming-language.readthedocs.org/en/latest/index.html>`_.
As more stuff is built I will keep updating the documentation so please revisit for latest information.
Also see the slides I presented at the `Lua 2015 Workshop <http://www.lua.org/wshop15.html>`_.
Lua Goodies
===========
* `An Introduction to Lua <http://the-ravi-programming-language.readthedocs.io/en/latest/lua-introduction.html>`_ attempts to provide a quick overview of Lua for folks coming from other languages.
* `Lua 5.3 Bytecode Reference <http://the-ravi-programming-language.readthedocs.io/en/latest/lua_bytecode_reference.html>`_ is my attempt to bring up to date the `Lua 5.1 Bytecode Reference <http://luaforge.net/docman/83/98/ANoFrillsIntroToLua51VMInstructions.pdf>`_.
JIT Implementation
==================
The LLVM JIT compiler is functional. The Lua and Ravi bytecodes currently implemented in LLVM are described in `JIT Status <http://the-ravi-programming-language.readthedocs.org/en/latest/ravi-jit-status.html>`_ page.
Ravi also provides an `LLVM binding <http://the-ravi-programming-language.readthedocs.org/en/latest/llvm-bindings.html>`_; this is still work in progress so please check documentation for the latest status.
Ravi Extensions to Lua 5.3
==========================
Optional Static Typing
----------------------
Ravi allows you to annotate ``local`` variables and function parameters with static types. The supported types and the resulting behaviour are as follows:
``integer``
denotes an integral value of 64-bits.
``number``
denotes a double (floating point) value of 8 bytes.
``integer[]``
denotes an array of integers
``number[]``
denotes an array of numbers
``table``
a Lua table
Additionally there are some `Experimental Type Annotations`_.
Declaring the types of ``local`` variables and function parameters has following advantages.
* ``integer`` and ``number`` types are automatically initialized to zero
* Arithmetic operations on numeric types make use of type specific bytecodes which leads to more efficient JIT compilation
* Specialised operators to get/set from array types are implemented; this makes array access more efficient in JIT mode as the access can be inlined
* Declared tables allow specialized opcodes for table gets involving integer and short literal string keys; these opcodes result in more efficient JIT code
* Values assigned to typed variables are checked statically when possible; if the values are results from a function call then runtime type checking is performed
* The standard table operations on arrays are checked to ensure that the type is not subverted
* Even if a typed variable is captured in a closure its type must be respected
* When function parameters are decorated with types, Ravi performs an implicit coersion of those parameters to the required types. If the coersion fails a runtime error occurs.
The array types (``number[]`` and ``integer[]``) are specializations of Lua table with some additional special behaviour:
* Array types are not compatible with declared table variables, i.e. following is not allowed::
local t: table = {}
local t2: number[] = t -- error!
local t3: number[] = {}
local t4: table = t3 -- error!
But following is okay::
local t5: number[] = {}
local t6 = t5 -- t6 treated as table
The reason for these restrictions is that declared table types generate optimized JIT code which assumes that the keys are integers
or literal short strings. Similarly declared array types result in specialized JIT code that assume integer keys and numeric values.
The generated JIT code would be incorrect if the types were not as expected.
* Indices >= 1 should be used when accessing array elements. Ravi arrays (and slices) have a hidden slot at index 0 for performance reasons, but this is not visible in ``pairs()`` or ``ipairs()``, or when initializing an array using a literal initializer; only direct access via the ``[]`` operator can see this slot.
* Arrays must always be initialized::
local t: number[] = {} -- okay
local t2: number[] -- error!
This restriction is placed as otherwise the JIT code would need to insert tests to validate that the variable is not nil.
* An array will grow automatically (unless the array was created as fixed length using ``table.intarray()`` or ``table.numarray()``) if the user sets the element just past the array length::
local t: number[] = {} -- dynamic array
t[1] = 4.2 -- okay, array grows by 1
t[5] = 2.4 -- error! as attempt to set value
* It is an error to attempt to set an element that is beyond len+1 on dynamic arrays; for fixed length arrays attempting to set elements at positions greater than len will cause an error.
* The current used length of the array is recorded and returned by len operations
* The array only permits the right type of value to be assigned (this is also checked at runtime to allow compatibility with Lua)
* Accessing out of bounds elements will cause an error, except for setting the len+1 element on dynamic arrays
* It is possible to pass arrays to functions and return arrays from functions. Arrays passed to functions appear as Lua tables inside
those functions if the parameters are untyped - however the tables will still be subject to restrictions as above. If the parameters are typed then the arrays will be recognized at compile time::
local function f(a, b: integer[], c)
-- Here a is dynamic type
-- b is declared as integer[]
-- c is also a dynamic type
b[1] = a[1] -- Okay only if a is actually also integer[]
b[1] = c[1] -- Will fail if c[1] cannot be converted to an integer
end
local a : integer[] = {1}
local b : integer[] = {}
local c = {1}
f(a,b,c) -- ok as c[1] is integer
f(a,b, {'hi'}) -- error!
* Arrays returned from functions can be stored into appropriately typed local variables - there is validation that the types match::
local t: number[] = f() -- type will be checked at runtime
* Operations on array types can be optimised to special bytecode and JIT only when the array type is statically known. Otherwise regular table access will be used subject to runtime checks.
* Array types ignore ``__index``, ``__newindex`` and ``__len`` metamethods.
* Array types cannot be set as metatables for other values.
* ``pairs()`` and ``ipairs()`` work on arrays as normal
* There is no way to delete an array element.
* The array data is stored in contiguous memory just like native C arrays; morever the garbage collector does not scan the array data
A declared table (as shown below) has some additional nuances::
local t: table = {}
* Like array types, a variable of ``table`` type must be initialized
* Array types are not compatible with declared table variables, i.e. following is not allowed::
local t: table = {}
local t2: number[] = t -- error!
* When short string literals are used to access a table element, specialized bytecodes are generated that are more efficiently JIT compiled::
local t: table = { name='dibyendu'}
print(t.name) -- The GETTABLE opcode is specialized in this case
* As with array types, specialized bytecodes are generated when integer keys are used
Following library functions allow creation of array types of defined length.
``table.intarray(num_elements, initial_value)``
creates an integer array of specified size, and initializes with initial value. The return type is integer[]. The size of the array cannot be changed dynamically, i.e. it is fixed to the initial specified size. This allows slices to be created on such arrays.
``table.numarray(num_elements, initial_value)``
creates an number array of specified size, and initializes with initial value. The return type is number[]. The size of the array cannot be changed dynamically, i.e. it is fixed to the initial specified size. This allows slices to be created on such arrays.
Type Assertions
---------------
Ravi does not support defining new types, or structured types based on tables. This creates some practical issues when dynamic types are mixed with static types. For example::
local t = { 1,2,3 }
local i: integer = t[1] -- generates an error
Above code generates an error as the compiler does not know that the value in ``t[1]`` is an integer. However often we as programmers know the type that is expected and it would be nice to be able to tell the compiler what the expected type of ``t[1]`` is above. To enable this Ravi supports type assertion operators. A type assertion is introduced by the '``@``' symbol, which must be followed by the type name. So we can rewrite the above example as::
local t = { 1,2,3 }
local i: integer = @integer( t[1] )
The type assertion operator is a unary operator and binds to the expression following the operator. We use the parenthesis above to enure that the type assertion is applied to ``t[1]`` rather than ``t``. More examples are shown below::
local a: number[] = @number[] { 1,2,3 }
local t = { @number[] { 4,5,6 }, @integer[] { 6,7,8 } }
local a1: number[] = @number[]( t[1] )
local a2: integer[] = @integer[]( t[2] )
For a real example of how type assertions can be used, please have a look at the test program `gaussian2.lua <https://github.com/dibyendumajumdar/ravi/blob/master/ravi-tests/gaussian2.lua>`_
Experimental Type Annotations
-----------------------------
Following type annotations have experimental support. These type annotations are not always statically enforced. Furthermore using these types does not affect the JIT code generation, i.e. variables annotated using these types are still treated as dynamic types.
The scenarios where these type annotations have an impact are:
* Function parameters containing these annotations lead to type assertions at runtime.
* The type assertion operator @ can be applied to these types - leading to runtime assertions.
* Annotating ``local`` declarations results in type assertions.
``string``
denotes a string
``closure``
denotes a function
Name
Denotes a value that has a `metatable registered under Name <https://www.lua.org/pil/28.2.html>`_ in the Lua registry. The Name must be a valid Lua name - hence periods in the name are not allowed.
The main use case for these annotations is to help with type checking of larger Ravi programs. These type checks, particularly the one for user defined types, are executed directly by the VM and hence are more efficient than performing the checks in other ways.
All three types above allow ``nil`` assignment.
Examples::
-- Create a metatable
local mt = { __name='MyType'}
-- Register the metatable in Lua registry
debug.getregistry().MyType = mt
-- Create an object and assign the metatable as its type
local t = {}
setmetatable(t, mt)
-- Use the metatable name as the object's type
function x(s: MyType)
local assert = assert
assert(@MyType(s) == @MyType(t))
assert(@MyType(t) == t)
end
-- Here we use the string type
function x(s1: string, s2: string)
return @string( s1 .. s2 )
end
-- Following demonstrates an error caused by the type checking
-- Note that this error is raised at runtime
function x()
local s: string
-- call a function that returns integer value
-- and try to assign to s
s = (function() return 1 end)()
end
x() -- will fail at runtime
Array Slices
------------
Since release 0.6 Ravi supports array slices. An array slice allows a portion of a Ravi array to be treated as if it is an array - this allows efficient access to the underlying array elements. Following new functions are available:
``table.slice(array, start_index, num_elements)``
creates a slice from an existing *fixed size* array - allowing efficient access to the underlying array elements.
Slices access the memory of the underlying array; hence a slice can only be created on fixed size arrays (constructed by ``table.numarray()`` or ``table.intarray()``). This ensures that the array memory cannot be reallocated while a slice is referring to it. Ravi does not track the slices that refer to arrays - slices get garbage collected as normal.
Slices cannot extend the array size for the same reasons above.
The type of a slice is the same as that of the underlying array - hence slices get the same optimized JIT operations for array access.
Each slice holds an internal reference to the underlying array to ensure that the garbage collector does not reclaim the array while there are slices pointing to it.
For an example use of slices please see the `matmul1.ravi <https://github.com/dibyendumajumdar/ravi/blob/master/ravi-tests/matmul1.ravi>`_ benchmark program in the repository. Note that this feature is highly experimental and not very well tested.
Examples
--------
Example of code that works - you can copy this to the command line input::
function tryme()
local i,j = 5,6
return i,j
end
local i:integer, j:integer = tryme(); print(i+j)
When values from a function call are assigned to a typed variable, an implicit type coersion takes place. In above example an error would occur if the function returned values that could not converted to integers.
In the following example, the parameter ``j`` is defined as a ``number``, hence it is an error to pass a value that cannot be converted to a ``number``::
function tryme(j: number)
for i=1,1000000000 do
j = j+1
end
return j
end
print(tryme(0.0))
An example with arrays::
function tryme()
local a : number[], j:number = {}
for i=1,10 do
a[i] = i
j = j + a[i]
end
return j
end
print(tryme())
Another example using arrays. Here the function receives a parameter ``arr`` of type ``number[]`` - it would be an error to pass any other type to the function because only ``number[]`` types can be converted to ``number[]`` types::
function sum(arr: number[])
local n: number = 0.0
for i = 1,#arr do
n = n + arr[i]
end
return n
end
print(sum(table.numarray(10, 2.0)))
The ``table.numarray(n, initial_value)`` creates a ``number[]`` of specified size and initializes the array with the given initial value.
All type checks are at runtime
------------------------------
To keep with Lua's dynamic nature Ravi uses a mix of compile type checking and runtime type checks. However due to the dynamic nature of Lua, compilation happens at runtime anyway so effectually all checks are at runtime.
JIT API
-------
The LLVM based JIT compiler is functional.
There are two modes of JIT compilation.
auto mode
in this mode the compiler decides when to compile a Lua function. The current implementation is very simple - any Lua function call is checked to see if the bytecodes contained in it can be compiled. If this is true then the function is compiled provided either a) function has a fornum loop, or b) it is largish (greater than 150 bytecodes) or c) it is being executed many times (> 50). Because of the simplistic behaviour performance the benefit of JIT compilation is only available if the JIT compiled functions will be executed many times so that the cost of JIT compilation can be amortized.
manual mode
in this mode user must explicitly request compilation. This is the default mode. This mode is suitable for library developers who can pre compile the functions in library module table.
A JIT api is available with following functions:
``ravi.jit([b])``
returns enabled setting of JIT compiler; also enables/disables the JIT compiler; defaults to true
``ravi.auto([b [, min_size [, min_executions]]])``
returns setting of auto compilation and compilation thresholds; also sets the new settings if values are supplied; defaults are false, 150, 50.
``ravi.compile(func_or_table[, options])``
compiles a Lua function (or functions if a table is supplied) if possible, returns ``true`` if compilation was successful for at least one function. ``options`` is an optional table with compilation options - in particular ``omitArrayGetRangeCheck`` - which disables range checks in array get operations to improve performance in some cases. Note that at present if the first argument is a table of functions and has more than 100 functions then only the first 100 will be compiled. You can invoke compile() repeatedly on the table until it returns false. Each invocation leads to a new module being created; any functions already compiled are skipped.
``ravi.iscompiled(func)``
returns the JIT status of a function
``ravi.dumplua(func)``
dumps the Lua bytecode of the function
``ravi.dumpir(func)``
(deprecated) dumps the IR of the compiled function (only if function was compiled; only available in LLVM 4.0 and earlier)
``ravi.dumpasm(func)``
(deprecated) dumps the machine code using the currently set optimization level (only if function was compiled; only available in LLVM version 4.0 and earlier)
``ravi.optlevel([n])``
sets LLVM optimization level (0, 1, 2, 3); defaults to 2. These levels are handled by reusing LLVMs default pass definitions which are geared towards C/C++ programs, but appear to work well here. If level is set to 0, then an attempt is made to use fast instruction selection to further speed up compilation.
``ravi.sizelevel([n])``
sets LLVM size level (0, 1, 2); defaults to 0
``ravi.tracehook([b])``
Enables support for line hooks via the debug api. Note that enabling this option will result in inefficient JIT as a call to a C function will be inserted at beginning of every Lua bytecode boundary; use this option only when you want to use the debug api to step through code line by line
``ravi.verbosity([b])``
Controls the amount of verbose messages generated during compilation. Currently only available for LLVM.
Performance
===========
For performance benchmarks please visit the `Ravi Performance Benchmarks <http://the-ravi-programming-language.readthedocs.org/en/latest/ravi-benchmarks.html>`_ page.
To obtain the best possible performance, types must be annotated so that Ravi's JIT compiler can generate efficient code.
Additionally function calls are expensive - as the JIT compiler cannot inline function calls, all function calls go via the Lua call protocol which has a large overhead. This is true for both Lua functions and C functions. For best performance avoid function calls inside loops.
Compatibility with Lua
======================
Ravi should be able to run all Lua 5.3 programs in interpreted mode, but following should be noted:
* Ravi supports optional typing and enhanced types such as arrays (described above). Programs using these features cannot be run by standard Lua. However all types in Ravi can be passed to Lua functions; operations on Ravi arrays within Lua code will be subject to restrictions as described in the section above on arrays.
* Values crossing from Lua to Ravi will be subjected to typechecks should these values be assigned to typed variables.
* Upvalues cannot subvert the static typing of local variables (issue #26) when types are annotated.
* Certain Lua limits are reduced due to changed byte code structure. These are described below.
+-----------------+-------------+-------------+
| Limit name | Lua value | Ravi value |
+=================+=============+=============+
| MAXUPVAL | 255 | 125 |
+-----------------+-------------+-------------+
| LUAI_MAXCCALLS | 200 | 125 |
+-----------------+-------------+-------------+
| MAXREGS | 255 | 125 |
+-----------------+-------------+-------------+
| MAXVARS | 200 | 125 |
+-----------------+-------------+-------------+
| MAXARGLINE | 250 | 120 |
+-----------------+-------------+-------------+
When JIT compilation is enabled there are following additional constraints:
* Ravi will only execute JITed code from the main Lua thread; any secondary threads (coroutines) execute in interpreter mode.
* In JITed code tailcalls are implemented as regular calls so unlike the interpreter VM which supports infinite tail recursion JIT compiled code only supports tail recursion to a depth of about 110 (issue #17)
Building Ravi
=============
Quick build without JIT
-----------------------
A Makefile is supplied for a simple build without the JIT. Just run ``make`` and follow instructions. You may need to customize the Makefiles.
For building Ravi with JIT options please read on.
Build Dependencies
------------------
* CMake
Ravi can be built with or without LLVM. Following versions of LLVM work with Ravi.
* LLVM 3.7 or 3.8 or 3.9 or 4.0 or 5.0
* LLVM 3.5 and 3.6 should also work but have not been recently tested
Unless otherwise noted the instructions below should work for LLVM 3.9 and later.
Since LLVM 5.0 Ravi has begun to use the new ORC JIT apis. These apis are more memory efficient compared to the MCJIT apis because they release the Module IR as early as possible, whereas with MCJIT the Module IR hangs around as long as the compiled code is held. Because of this significant improvement, I recommend using LLVM 5.0 and above.
Building LLVM on Windows
------------------------
I built LLVM from source. I used the following sequence from the VS2017 command window::
cd \github\llvm
mkdir build
cd build
cmake -DCMAKE_INSTALL_PREFIX=c:\LLVM -DLLVM_TARGETS_TO_BUILD="X86" -G "Visual Studio 15 2017 Win64" ..
I then opened the generated solution in VS2017 and performed a INSTALL build from there. Above will build the 64-bit version of LLVM libraries. To build a 32-bit version omit the ``Win64`` parameter.
.. note:: Note that if you perform a Release build of LLVM then you will also need to do a Release build of Ravi otherwise you will get link errors.
Building LLVM on Ubuntu
-----------------------
On Ubuntu I found that the official LLVM distributions don't work with CMake. The CMake config files appear to be broken.
So I ended up downloading and building LLVM from source and that worked. The approach is similar to that described for MAC OS X below.
Building LLVM on MAC OS X
-------------------------
I am using Max OSX El Capitan. Pre-requisites are XCode 7.x and CMake.
Ensure cmake is on the path.
Assuming that LLVM source has been extracted to ``$HOME/llvm-3.7.0.src`` I follow these steps::
cd llvm-3.7.0.src
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$HOME/LLVM -DLLVM_TARGETS_TO_BUILD="X86" ..
make install
Building Ravi with JIT enabled
------------------------------
I am developing Ravi using Visual Studio 2017 Community Edition on Windows 10 64bit, gcc on Unbuntu 64-bit, and clang/Xcode on MAC OS X. I was also able to successfully build a Ubuntu version on Windows 10 using the newly released Ubuntu/Linux sub-system for Windows 10.
.. note:: Location of cmake files prior to LLVM 3.9 was ``$LLVM_INSTALL_DIR/share/llvm/cmake``.
Assuming that LLVM has been installed as described above, then on Windows I invoke the cmake config as follows::
cd build
cmake -DLLVM_JIT=ON -DCMAKE_INSTALL_PREFIX=c:\ravi -DLLVM_DIR=c:\LLVM\lib\cmake\llvm -G "Visual Studio 15 2017 Win64" ..
I then open the solution in VS2017 and do a build from there.
On Ubuntu I use::
cd build
cmake -DLLVM_JIT=ON -DCMAKE_INSTALL_PREFIX=$HOME/ravi -DLLVM_DIR=$HOME/LLVM/lib/cmake/llvm -DCMAKE_BUILD_TYPE=Release -G "Unix Makefiles" ..
make
Note that on a clean install of Ubuntu 15.10 I had to install following packages:
* cmake
* git
* libreadline-dev
On MAC OS X I use::
cd build
cmake -DLLVM_JIT=ON -DCMAKE_INSTALL_PREFIX=$HOME/ravi -DLLVM_DIR=$HOME/LLVM/lib/cmake/llvm -DCMAKE_BUILD_TYPE=Release -G "Xcode" ..
I open the generated project in Xcode and do a build from there. You can also use the command line build tools if you wish - generate the make files in the same way as for Linux.
Building without JIT
--------------------
You can omit ``-DLLVM_JIT=ON`` option above to build Ravi with a null JIT implementation.
Building Static Libraries
-------------------------
By default the build generates a shared library for Ravi. You can choose to create a static library and statically linked executables by supplying the argument ``-DSTATIC_BUILD=ON`` to CMake.
Build Artifacts
---------------
The Ravi build creates a shared or static depending upon options supplied to CMake, the Ravi executable and some test programs. Additionally when JIT compilation is switched off, the ``ravidebug`` executable is generated which is the `debug adapter for use by Visual Studio Code <https://github.com/dibyendumajumdar/ravi/tree/master/vscode-debugger>`_.
The ``ravi`` command recognizes following environment variables. Note that these are only for internal debugging purposes.
``RAVI_DEBUG_EXPR``
if set to a value this triggers debug output of expression parsing
``RAVI_DEBUG_CODEGEN``
if set to a value this triggers a dump of the code being generated
``RAVI_DEBUG_VARS``
if set this triggers a dump of local variables construction and destruction
Also see section above on available API for dumping either Lua bytecode or LLVM IR for compiled code.
Testing
-------
I test the build by running a modified version of Lua 5.3.3 test suite. These tests are located in the ``lua-tests`` folder. Additionally I have ravi specific tests in the ``ravi-tests`` folder. There is a also a travis build that occurs upon commits - this build runs the tests as well.
.. note:: To thoroughly test changes, you need to invoke CMake with ``-DCMAKE_BUILD_TYPE=Debug`` option. This turns on assertions, memory checking, and also enables an internal module used by Lua tests.
Roadmap
=======
* 2015
- Implemented JIT compilation using LLVM
- Implemented libgccjit based alternative JIT (now discontinued)
* 2016
- Implemented debugger for Ravi and Lua 5.3 for `Visual Studio Code <https://github.com/dibyendumajumdar/ravi/tree/master/vscode-debugger>`_
* 2017
- Embedded C compiler using dmrC project (C JIT compiler)
- Additional type annotations
* 2018
- 1.0 release of Ravi
- More testing and test cases
- ASM VM for X86-64 platform
- Better support for earlier Lua versions (5.1 especially)
License
=======
MIT License for LLVM version.

@ -5,4 +5,4 @@ The scripts here are unsupported - these are just my personal
build scripts.
The debug builds enable 'ltests' and address sanitizer.
The unix LLVM debug builds enable 'ltests' and address sanitizer.

@ -0,0 +1,5 @@
mkdir llvm32
cd llvm32
rem cmake -DCMAKE_INSTALL_PREFIX=\d\ravi32 -G "Visual Studio 14" -DLLVM_JIT=ON -DLLVM_DIR=\d\LLVM37_32\share\llvm\cmake -DBUILD_STATIC=OFF ..
cmake -DCMAKE_INSTALL_PREFIX=\d\ravi32 -G "Visual Studio 14" -DLLVM_JIT=ON -DLLVM_DIR=\d\LLVM39_32\lib\cmake\llvm -DSTATIC_BUILD=OFF ..
cd ..

@ -0,0 +1,5 @@
mkdir llvm32
cd llvm32
rem cmake -DCMAKE_INSTALL_PREFIX=\d\ravi32 -G "Visual Studio 14" -DLLVM_JIT=ON -DLLVM_DIR=\d\LLVM37_32\share\llvm\cmake ..
cmake -DCMAKE_INSTALL_PREFIX=\d\ravi32 -G "Visual Studio 14" -DLLVM_JIT=ON -DLLVM_DIR=\d\LLVM39\lib\cmake\llvm -DSTATIC_BUILD=ON ..
cd ..

@ -0,0 +1,5 @@
mkdir llvm32d
cd llvm32d
rem cmake -DCMAKE_INSTALL_PREFIX=\d\ravi32 -G "Visual Studio 14" -DLLVM_JIT=ON -DLLVM_DIR=\d\LLVM37_32\share\llvm\cmake ..
cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=\d\ravi32 -G "Visual Studio 14" -DLLVM_JIT=ON -DLLVM_DIR=\d\LLVM39D_32\lib\cmake\llvm -DSTATIC_BUILD=ON ..
cd ..

@ -0,0 +1,6 @@
mkdir llvm64d
cd llvm64d
rem cmake -DCMAKE_INSTALL_PREFIX=c:\ravi64llvmd -G "Visual Studio 14 Win64" -DLLVM_JIT=ON -DLLVM_DIR=c:\LLVM37debug\share\llvm\cmake ..
rem cmake -DSTATIC_BUILD=ON -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=c:\d\ravi64llvmd -G "Visual Studio 15 2017 Win64" -DLLVM_JIT=ON -DEMBEDDED_DMRC=ON -DLLVM_DIR=c:\d\LLVM39D64\lib\cmake\llvm ..
cmake -DCMAKE_INSTALL_PREFIX=c:\Software\ravi -G "Visual Studio 15 2017 Win64" -DLTESTS=ON -DSTATIC_BUILD=ON -DCMAKE_BUILD_TYPE=Debug -DLLVM_JIT=ON -DLLVM_DIR=c:\Software\llvm501d\lib\cmake\llvm ..
cd ..

@ -0,0 +1,8 @@
mkdir llvm64
cd llvm64
rem pre LLVM 3.9
rem cmake -DCMAKE_INSTALL_PREFIX=c:\ravi -G "Visual Studio 14 Win64" -DLLVM_JIT=ON -DLLVM_DIR=c:\LLVM37\share\llvm\cmake ..
rem cmake -DCMAKE_INSTALL_PREFIX=c:\ravi -G "Visual Studio 15 2017 Win64" -DLLVM_JIT=ON -DLLVM_DIR=c:\d\LLVM40_64\lib\cmake\llvm ..
cmake -DCMAKE_INSTALL_PREFIX=c:\Software\ravi -G "Visual Studio 15 2017 Win64" -DCMAKE_BUILD_TYPE=Release -DLLVM_JIT=ON -DLLVM_DIR=c:\Software\llvm501r\lib\cmake\llvm ..
rem cmake -DCMAKE_INSTALL_PREFIX=c:\Software\ravi -G "Visual Studio 15 2017 Win64" -DSTATIC_BUILD=ON -DLLVM_JIT=ON -DLLVM_DIR=c:\Software\llvm501r\lib\cmake\llvm ..
cd ..

@ -0,0 +1,4 @@
mkdir asmvm
cd asmvm
cmake -DCMAKE_INSTALL_PREFIX=c:\Software\ravi-asmvm -DSTATIC_BUILD=ON -DCMAKE_BUILD_TYPE=Debug -DASM_VM=ON -G "Visual Studio 15 2017 Win64" ..
cd ..

@ -1,4 +1,4 @@
mkdir nojit64a
cd nojit64a
cmake -DCMAKE_INSTALL_PREFIX=c:\Software\ravi -DCMAKE_BUILD_TYPE=Debug -DLTESTS=ON ..
cmake -DCMAKE_INSTALL_PREFIX=c:\Software\ravi -DCMAKE_BUILD_TYPE=Debug -DLTESTS=ON -G "Visual Studio 15 2017 Win64" ..
cd ..

@ -1,4 +1,4 @@
mkdir nojit64
cd nojit64
cmake -DCMAKE_INSTALL_PREFIX=c:\Software\ravi -DCMAKE_BUILD_TYPE=Release -DSTATIC_BUILD=OFF -G "Visual Studio 15 2017 Win64" ..
cmake -DCMAKE_INSTALL_PREFIX=c:\Software\ravi -DCMAKE_BUILD_TYPE=Debug -DSTATIC_BUILD=OFF -G "Visual Studio 15 2017 Win64" ..
cd ..

@ -0,0 +1,4 @@
mkdir xcodellvm
cd xcodellvm
#cmake -DCMAKE_BUILD_TYPE=Debug -G Xcode -DLLVM_JIT=ON -DCMAKE_INSTALL_PREFIX=$HOME/ravi -DLLVM_DIR=$HOME/LLVM/share/llvm/cmake ..
cmake -DCMAKE_BUILD_TYPE=Debug -G Xcode -DLLVM_JIT=ON -DCMAKE_INSTALL_PREFIX=$HOME/ravi -DLLVM_DIR=$HOME/LLVM5/lib/cmake/llvm ..

@ -0,0 +1,5 @@
mkdir buildllvmd
cd buildllvmd
#cmake -DCMAKE_BUILD_TYPE=Debug -DLLVM_JIT=ON -DCMAKE_INSTALL_PREFIX=$HOME/ravi -DLLVM_DIR=$HOME/LLVM/share/llvm/cmake ..
#cmake -DCMAKE_BUILD_TYPE=Debug -DLLVM_JIT=ON -DLTESTS=ON -DCMAKE_INSTALL_PREFIX=$HOME/ravi -DLLVM_DIR=$HOME/LLVM5/lib/cmake/llvm ..
cmake -DCMAKE_BUILD_TYPE=Debug -DLLVM_JIT=ON -DLTESTS=ON -DCMAKE_INSTALL_PREFIX=$HOME/ravillvm -DLLVM_DIR=$HOME/Software/llvm600/lib/cmake/llvm ..

@ -0,0 +1,4 @@
mkdir buildllvm
cd buildllvm
#cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_JIT=ON -DCMAKE_INSTALL_PREFIX=$HOME/ravi -DLLVM_DIR=$HOME/LLVM/share/llvm/cmake ..
cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_JIT=ON -DCMAKE_INSTALL_PREFIX=$HOME/ravi -DLLVM_DIR=$HOME/LLVM5/lib/cmake/llvm ..

@ -0,0 +1,3 @@
mkdir buildasmvm
cd buildasmvm
cmake -DSTATIC_BUILD=ON -DASM_VM=ON -DCMAKE_BUILD_TYPE=Debug -DCOMPUTED_GOTO=ON -DCMAKE_INSTALL_PREFIX=$HOME/ravi ..

@ -0,0 +1,73 @@
; ModuleID = 'inline_getstr.c'
source_filename = "inline_getstr.c"
target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
target triple = "i686-pc-windows-msvc"
%struct.TValue = type { %union.Value, i32 }
%union.Value = type { i64 }
%struct.Table = type { %struct.GCObject*, i8, i8, i8, i8, i32, %struct.TValue*, %struct.Node*, %struct.Node*, %struct.Table*, %struct.GCObject*, %struct.RaviArray, i32 }
%struct.Node = type { %struct.TValue, %union.TKey }
%union.TKey = type { %struct.anon.1 }
%struct.anon.1 = type { %union.Value, i32, i32 }
%struct.GCObject = type { %struct.GCObject*, i8, i8 }
%struct.RaviArray = type { i8*, i32, i32, i32 }
%struct.TString = type { %struct.GCObject*, i8, i8, i8, i8, i32, %union.anon.2 }
%union.anon.2 = type { i64 }
; Function Attrs: nounwind
define %struct.TValue* @ravi_getstr(%struct.Table* %t, %struct.TString* %key) local_unnamed_addr #0 {
entry:
%hash = getelementptr inbounds %struct.TString, %struct.TString* %key, i32 0, i32 5
%0 = load i32, i32* %hash, align 8, !tbaa !1
%hmask = getelementptr inbounds %struct.Table, %struct.Table* %t, i32 0, i32 12
%1 = load i32, i32* %hmask, align 4, !tbaa !7
%and = and i32 %1, %0
%node = getelementptr inbounds %struct.Table, %struct.Table* %t, i32 0, i32 7
%2 = load %struct.Node*, %struct.Node** %node, align 4, !tbaa !10
%3 = getelementptr inbounds %struct.Node, %struct.Node* %2, i32 %and, i32 1, i32 0, i32 1
%4 = load i32, i32* %3, align 8, !tbaa !11
%cmp = icmp eq i32 %4, 68
br i1 %cmp, label %land.lhs.true, label %if.end
land.lhs.true: ; preds = %entry
%value_ = getelementptr inbounds %struct.Node, %struct.Node* %2, i32 %and, i32 1, i32 0, i32 0
%5 = bitcast %union.Value* %value_ to %struct.TString**
%6 = load %struct.TString*, %struct.TString** %5, align 8, !tbaa !13
%cmp1 = icmp eq %struct.TString* %6, %key
br i1 %cmp1, label %if.then, label %if.end
if.then: ; preds = %land.lhs.true
%i_val = getelementptr inbounds %struct.Node, %struct.Node* %2, i32 %and, i32 0
br label %cleanup
if.end: ; preds = %land.lhs.true, %entry
%call = tail call %struct.TValue* @luaH_getstr(%struct.Table* nonnull %t, %struct.TString* nonnull %key) #2
br label %cleanup
cleanup: ; preds = %if.end, %if.then
%retval.0 = phi %struct.TValue* [ %i_val, %if.then ], [ %call, %if.end ]
ret %struct.TValue* %retval.0
}
declare %struct.TValue* @luaH_getstr(%struct.Table*, %struct.TString*) local_unnamed_addr #1
attributes #0 = { nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-features"="+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-features"="+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #2 = { nounwind }
!llvm.ident = !{!0}
!0 = !{!"clang version 3.9.0 (trunk)"}
!1 = !{!2, !6, i64 8}
!2 = !{!"TString", !3, i64 0, !4, i64 4, !4, i64 5, !4, i64 6, !4, i64 7, !6, i64 8, !4, i64 16}
!3 = !{!"any pointer", !4, i64 0}
!4 = !{!"omnipotent char", !5, i64 0}
!5 = !{!"Simple C/C++ TBAA"}
!6 = !{!"int", !4, i64 0}
!7 = !{!8, !6, i64 48}
!8 = !{!"Table", !3, i64 0, !4, i64 4, !4, i64 5, !4, i64 6, !4, i64 7, !6, i64 8, !3, i64 12, !3, i64 16, !3, i64 20, !3, i64 24, !3, i64 28, !9, i64 32, !6, i64 48}
!9 = !{!"RaviArray", !3, i64 0, !4, i64 4, !6, i64 8, !6, i64 12}
!10 = !{!8, !3, i64 16}
!11 = !{!12, !6, i64 8}
!12 = !{!"TValue", !4, i64 0, !6, i64 8}
!13 = !{!3, !3, i64 0}

@ -0,0 +1,784 @@
; ModuleID = 'lua_for_num.c'
target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-S32"
target triple = "i686-pc-windows-gnu"
%struct.GCObject = type { %struct.GCObject*, i8, i8 }
%struct.lua_State = type { %struct.GCObject*, i8, i8, i8, %struct.TValue*, %struct.global_State*, %struct.CallInfoLua*, i32*, %struct.TValue*, %struct.TValue*, %struct.UpVal*, %struct.GCObject*, %struct.lua_State*, %struct.lua_longjmp*, %struct.CallInfo, void (%struct.lua_State*, %struct.lua_Debug*)*, i64, i32, i32, i32, i16, i16, i8, i8 }
%struct.global_State = type opaque
%struct.CallInfoLua = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %struct.CallInfoL, i64, i16, i8, i8 }
%struct.CallInfoL = type { %struct.TValue*, i32*, i64 }
%struct.TValue = type { %union.Value, i32 }
%union.Value = type { i64 }
%struct.UpVal = type { %struct.TValue*, i64, %union.anon.0 }
%union.anon.0 = type { %struct.TValue }
%struct.lua_longjmp = type opaque
%struct.CallInfo = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %union.anon, i64, i16, i8, i8 }
%union.anon = type { %struct.CallInfoC }
%struct.CallInfoC = type { i32 (%struct.lua_State*, i32, i64)*, i64, i64 }
%struct.lua_Debug = type opaque
%struct.LClosure = type { %struct.GCObject*, i8, i8, i8, %struct.GCObject*, %struct.Proto*, [1 x %struct.UpVal*] }
%struct.Proto = type { %struct.GCObject*, i8, i8, i8, i8, i8, i32, i32, i32, i32, i32, i32, i32, i32, %struct.TValue*, i32*, %struct.Proto**, i32*, %struct.LocVar*, %struct.Upvaldesc*, %struct.LClosure*, %struct.TString*, %struct.GCObject*, %struct.RaviJITProto }
%struct.LocVar = type { %struct.TString*, i32, i32, i32 }
%struct.Upvaldesc = type { %struct.TString*, i32, i8, i8 }
%struct.TString = type { %struct.GCObject*, i8, i8, i8, i32, i64, %struct.TString* }
%struct.RaviJITProto = type { i8, i8*, i32 (%struct.lua_State*)* }
@.str = private unnamed_addr constant [12 x i8] c"value = %d\0A\00", align 1
@.str1 = private unnamed_addr constant [29 x i8] c"'for' limit must be a number\00", align 1
@.str2 = private unnamed_addr constant [28 x i8] c"'for' step must be a number\00", align 1
@.str3 = private unnamed_addr constant [37 x i8] c"'for' initial value must be a number\00", align 1
@.str4 = private unnamed_addr constant [13 x i8] c"ptr diff %d\0A\00", align 1
; Function Attrs: nounwind
define void @testfunc(%struct.GCObject* %obj) #0 {
entry:
%obj.addr = alloca %struct.GCObject*, align 4
store %struct.GCObject* %obj, %struct.GCObject** %obj.addr, align 4, !tbaa !1
%0 = load %struct.GCObject*, %struct.GCObject** %obj.addr, align 4, !tbaa !1
%tt = getelementptr inbounds %struct.GCObject, %struct.GCObject* %0, i32 0, i32 1
%1 = load i8, i8* %tt, align 1, !tbaa !5
%conv = zext i8 %1 to i32
%call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), i32 %conv)
ret void
}
declare i32 @printf(i8*, ...) #1
; Function Attrs: nounwind
define void @test1(%struct.lua_State* %L) #0 {
entry:
%L.addr = alloca %struct.lua_State*, align 4
%ci = alloca %struct.CallInfoLua*, align 4
%cl = alloca %struct.LClosure*, align 4
%k = alloca %struct.TValue*, align 4
%base = alloca %struct.TValue*, align 4
%cil = alloca %struct.CallInfoL*, align 4
%ra = alloca %struct.TValue*, align 4
%rb = alloca %struct.TValue*, align 4
%rc = alloca %struct.TValue*, align 4
%b = alloca i32, align 4
%init = alloca %struct.TValue*, align 4
%plimit = alloca %struct.TValue*, align 4
%pstep = alloca %struct.TValue*, align 4
%ilimit = alloca i64, align 8
%stopnow = alloca i32, align 4
%init_is_integer = alloca i32, align 4
%pstep_is_integer = alloca i32, align 4
%fl = alloca i32, align 4
%initv = alloca i64, align 8
%ninit = alloca double, align 8
%nlimit = alloca double, align 8
%nstep = alloca double, align 8
%plimit_is_float = alloca i32, align 4
%pstep_is_float = alloca i32, align 4
%init_is_float = alloca i32, align 4
%step = alloca i64, align 8
%idx = alloca i64, align 8
%limit = alloca i64, align 8
%cleanup.dest.slot = alloca i32
%step116 = alloca double, align 8
%idx119 = alloca double, align 8
%limit124 = alloca double, align 8
store %struct.lua_State* %L, %struct.lua_State** %L.addr, align 4, !tbaa !1
%0 = bitcast %struct.CallInfoLua** %ci to i8*
call void @llvm.lifetime.start(i64 4, i8* %0) #2
%1 = bitcast %struct.LClosure** %cl to i8*
call void @llvm.lifetime.start(i64 4, i8* %1) #2
%2 = bitcast %struct.TValue** %k to i8*
call void @llvm.lifetime.start(i64 4, i8* %2) #2
%3 = bitcast %struct.TValue** %base to i8*
call void @llvm.lifetime.start(i64 4, i8* %3) #2
%4 = bitcast %struct.CallInfoL** %cil to i8*
call void @llvm.lifetime.start(i64 4, i8* %4) #2
%5 = bitcast %struct.TValue** %ra to i8*
call void @llvm.lifetime.start(i64 4, i8* %5) #2
%6 = bitcast %struct.TValue** %rb to i8*
call void @llvm.lifetime.start(i64 4, i8* %6) #2
%7 = bitcast %struct.TValue** %rc to i8*
call void @llvm.lifetime.start(i64 4, i8* %7) #2
%8 = bitcast i32* %b to i8*
call void @llvm.lifetime.start(i64 4, i8* %8) #2
%9 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
%ci1 = getelementptr inbounds %struct.lua_State, %struct.lua_State* %9, i32 0, i32 6
%10 = load %struct.CallInfoLua*, %struct.CallInfoLua** %ci1, align 4, !tbaa !7
store %struct.CallInfoLua* %10, %struct.CallInfoLua** %ci, align 4, !tbaa !1
%11 = load %struct.CallInfoLua*, %struct.CallInfoLua** %ci, align 4, !tbaa !1
%l = getelementptr inbounds %struct.CallInfoLua, %struct.CallInfoLua* %11, i32 0, i32 4
%base2 = getelementptr inbounds %struct.CallInfoL, %struct.CallInfoL* %l, i32 0, i32 0
%12 = load %struct.TValue*, %struct.TValue** %base2, align 4, !tbaa !13
store %struct.TValue* %12, %struct.TValue** %base, align 4, !tbaa !1
%13 = load %struct.CallInfoLua*, %struct.CallInfoLua** %ci, align 4, !tbaa !1
%func = getelementptr inbounds %struct.CallInfoLua, %struct.CallInfoLua* %13, i32 0, i32 0
%14 = load %struct.TValue*, %struct.TValue** %func, align 4, !tbaa !16
%value_ = getelementptr inbounds %struct.TValue, %struct.TValue* %14, i32 0, i32 0
%gc = bitcast %union.Value* %value_ to %struct.GCObject**
%15 = load %struct.GCObject*, %struct.GCObject** %gc, align 4, !tbaa !1
%16 = bitcast %struct.GCObject* %15 to %struct.LClosure*
store %struct.LClosure* %16, %struct.LClosure** %cl, align 4, !tbaa !1
%17 = load %struct.LClosure*, %struct.LClosure** %cl, align 4, !tbaa !1
%p = getelementptr inbounds %struct.LClosure, %struct.LClosure* %17, i32 0, i32 5
%18 = load %struct.Proto*, %struct.Proto** %p, align 4, !tbaa !17
%k3 = getelementptr inbounds %struct.Proto, %struct.Proto* %18, i32 0, i32 14
%19 = load %struct.TValue*, %struct.TValue** %k3, align 4, !tbaa !19
store %struct.TValue* %19, %struct.TValue** %k, align 4, !tbaa !1
%20 = load %struct.TValue*, %struct.TValue** %base, align 4, !tbaa !1
%add.ptr = getelementptr inbounds %struct.TValue, %struct.TValue* %20, i32 0
store %struct.TValue* %add.ptr, %struct.TValue** %ra, align 4, !tbaa !1
%21 = load %struct.TValue*, %struct.TValue** %k, align 4, !tbaa !1
%add.ptr4 = getelementptr inbounds %struct.TValue, %struct.TValue* %21, i32 0
store %struct.TValue* %add.ptr4, %struct.TValue** %rb, align 4, !tbaa !1
%22 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%23 = load %struct.TValue*, %struct.TValue** %rb, align 4, !tbaa !1
%24 = bitcast %struct.TValue* %22 to i8*
%25 = bitcast %struct.TValue* %23 to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %24, i8* %25, i32 16, i32 8, i1 false), !tbaa.struct !22
%26 = load %struct.TValue*, %struct.TValue** %base, align 4, !tbaa !1
%add.ptr5 = getelementptr inbounds %struct.TValue, %struct.TValue* %26, i32 1
store %struct.TValue* %add.ptr5, %struct.TValue** %ra, align 4, !tbaa !1
%27 = load %struct.TValue*, %struct.TValue** %k, align 4, !tbaa !1
%add.ptr6 = getelementptr inbounds %struct.TValue, %struct.TValue* %27, i32 1
store %struct.TValue* %add.ptr6, %struct.TValue** %rb, align 4, !tbaa !1
%28 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%29 = load %struct.TValue*, %struct.TValue** %rb, align 4, !tbaa !1
%30 = bitcast %struct.TValue* %28 to i8*
%31 = bitcast %struct.TValue* %29 to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %30, i8* %31, i32 16, i32 8, i1 false), !tbaa.struct !22
%32 = load %struct.TValue*, %struct.TValue** %base, align 4, !tbaa !1
%add.ptr7 = getelementptr inbounds %struct.TValue, %struct.TValue* %32, i32 2
store %struct.TValue* %add.ptr7, %struct.TValue** %ra, align 4, !tbaa !1
%33 = load %struct.TValue*, %struct.TValue** %k, align 4, !tbaa !1
%add.ptr8 = getelementptr inbounds %struct.TValue, %struct.TValue* %33, i32 2
store %struct.TValue* %add.ptr8, %struct.TValue** %rb, align 4, !tbaa !1
%34 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%35 = load %struct.TValue*, %struct.TValue** %rb, align 4, !tbaa !1
%36 = bitcast %struct.TValue* %34 to i8*
%37 = bitcast %struct.TValue* %35 to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %36, i8* %37, i32 16, i32 8, i1 false), !tbaa.struct !22
%38 = load %struct.TValue*, %struct.TValue** %base, align 4, !tbaa !1
%add.ptr9 = getelementptr inbounds %struct.TValue, %struct.TValue* %38, i32 3
store %struct.TValue* %add.ptr9, %struct.TValue** %ra, align 4, !tbaa !1
%39 = load %struct.TValue*, %struct.TValue** %k, align 4, !tbaa !1
%add.ptr10 = getelementptr inbounds %struct.TValue, %struct.TValue* %39, i32 1
store %struct.TValue* %add.ptr10, %struct.TValue** %rb, align 4, !tbaa !1
%40 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%41 = load %struct.TValue*, %struct.TValue** %rb, align 4, !tbaa !1
%42 = bitcast %struct.TValue* %40 to i8*
%43 = bitcast %struct.TValue* %41 to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %42, i8* %43, i32 16, i32 8, i1 false), !tbaa.struct !22
br label %label_forprep
label_forprep: ; preds = %entry
%44 = load %struct.TValue*, %struct.TValue** %base, align 4, !tbaa !1
%add.ptr11 = getelementptr inbounds %struct.TValue, %struct.TValue* %44, i32 1
store %struct.TValue* %add.ptr11, %struct.TValue** %ra, align 4, !tbaa !1
%45 = bitcast %struct.TValue** %init to i8*
call void @llvm.lifetime.start(i64 4, i8* %45) #2
%46 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
store %struct.TValue* %46, %struct.TValue** %init, align 4, !tbaa !1
%47 = bitcast %struct.TValue** %plimit to i8*
call void @llvm.lifetime.start(i64 4, i8* %47) #2
%48 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%add.ptr12 = getelementptr inbounds %struct.TValue, %struct.TValue* %48, i32 1
store %struct.TValue* %add.ptr12, %struct.TValue** %plimit, align 4, !tbaa !1
%49 = bitcast %struct.TValue** %pstep to i8*
call void @llvm.lifetime.start(i64 4, i8* %49) #2
%50 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%add.ptr13 = getelementptr inbounds %struct.TValue, %struct.TValue* %50, i32 2
store %struct.TValue* %add.ptr13, %struct.TValue** %pstep, align 4, !tbaa !1
%51 = bitcast i64* %ilimit to i8*
call void @llvm.lifetime.start(i64 8, i8* %51) #2
%52 = bitcast i32* %stopnow to i8*
call void @llvm.lifetime.start(i64 4, i8* %52) #2
%53 = bitcast i32* %init_is_integer to i8*
call void @llvm.lifetime.start(i64 4, i8* %53) #2
%54 = load %struct.TValue*, %struct.TValue** %init, align 4, !tbaa !1
%tt_ = getelementptr inbounds %struct.TValue, %struct.TValue* %54, i32 0, i32 1
%55 = load i32, i32* %tt_, align 4, !tbaa !27
%cmp = icmp eq i32 %55, 19
%conv = zext i1 %cmp to i32
store i32 %conv, i32* %init_is_integer, align 4, !tbaa !23
%56 = bitcast i32* %pstep_is_integer to i8*
call void @llvm.lifetime.start(i64 4, i8* %56) #2
%57 = load %struct.TValue*, %struct.TValue** %pstep, align 4, !tbaa !1
%tt_14 = getelementptr inbounds %struct.TValue, %struct.TValue* %57, i32 0, i32 1
%58 = load i32, i32* %tt_14, align 4, !tbaa !27
%cmp15 = icmp eq i32 %58, 19
%conv16 = zext i1 %cmp15 to i32
store i32 %conv16, i32* %pstep_is_integer, align 4, !tbaa !23
%59 = bitcast i32* %fl to i8*
call void @llvm.lifetime.start(i64 4, i8* %59) #2
%60 = load %struct.TValue*, %struct.TValue** %plimit, align 4, !tbaa !1
%61 = load %struct.TValue*, %struct.TValue** %pstep, align 4, !tbaa !1
%value_17 = getelementptr inbounds %struct.TValue, %struct.TValue* %61, i32 0, i32 0
%i = bitcast %union.Value* %value_17 to i64*
%62 = load i64, i64* %i, align 8, !tbaa !24
%call = call i32 @forlimit(%struct.TValue* %60, i64* %ilimit, i64 %62, i32* %stopnow)
store i32 %call, i32* %fl, align 4, !tbaa !23
%63 = load i32, i32* %init_is_integer, align 4, !tbaa !23
%tobool = icmp ne i32 %63, 0
br i1 %tobool, label %land.lhs.true, label %if.else
land.lhs.true: ; preds = %label_forprep
%64 = load i32, i32* %pstep_is_integer, align 4, !tbaa !23
%tobool18 = icmp ne i32 %64, 0
br i1 %tobool18, label %land.lhs.true19, label %if.else
land.lhs.true19: ; preds = %land.lhs.true
%65 = load i32, i32* %fl, align 4, !tbaa !23
%tobool20 = icmp ne i32 %65, 0
br i1 %tobool20, label %if.then, label %if.else
if.then: ; preds = %land.lhs.true19
%66 = bitcast i64* %initv to i8*
call void @llvm.lifetime.start(i64 8, i8* %66) #2
%67 = load i32, i32* %stopnow, align 4, !tbaa !23
%tobool21 = icmp ne i32 %67, 0
br i1 %tobool21, label %cond.true, label %cond.false
cond.true: ; preds = %if.then
br label %cond.end
cond.false: ; preds = %if.then
%68 = load %struct.TValue*, %struct.TValue** %init, align 4, !tbaa !1
%value_22 = getelementptr inbounds %struct.TValue, %struct.TValue* %68, i32 0, i32 0
%i23 = bitcast %union.Value* %value_22 to i64*
%69 = load i64, i64* %i23, align 8, !tbaa !24
br label %cond.end
cond.end: ; preds = %cond.false, %cond.true
%cond = phi i64 [ 0, %cond.true ], [ %69, %cond.false ]
store i64 %cond, i64* %initv, align 8, !tbaa !24
%70 = load i64, i64* %ilimit, align 8, !tbaa !24
%71 = load %struct.TValue*, %struct.TValue** %plimit, align 4, !tbaa !1
%value_24 = getelementptr inbounds %struct.TValue, %struct.TValue* %71, i32 0, i32 0
%i25 = bitcast %union.Value* %value_24 to i64*
store i64 %70, i64* %i25, align 8, !tbaa !24
%72 = load %struct.TValue*, %struct.TValue** %plimit, align 4, !tbaa !1
%tt_26 = getelementptr inbounds %struct.TValue, %struct.TValue* %72, i32 0, i32 1
store i32 19, i32* %tt_26, align 4, !tbaa !27
%73 = load i64, i64* %initv, align 8, !tbaa !24
%74 = load %struct.TValue*, %struct.TValue** %pstep, align 4, !tbaa !1
%value_27 = getelementptr inbounds %struct.TValue, %struct.TValue* %74, i32 0, i32 0
%i28 = bitcast %union.Value* %value_27 to i64*
%75 = load i64, i64* %i28, align 8, !tbaa !24
%sub = sub nsw i64 %73, %75
%76 = load %struct.TValue*, %struct.TValue** %init, align 4, !tbaa !1
%value_29 = getelementptr inbounds %struct.TValue, %struct.TValue* %76, i32 0, i32 0
%i30 = bitcast %union.Value* %value_29 to i64*
store i64 %sub, i64* %i30, align 8, !tbaa !24
%77 = load %struct.TValue*, %struct.TValue** %init, align 4, !tbaa !1
%tt_31 = getelementptr inbounds %struct.TValue, %struct.TValue* %77, i32 0, i32 1
store i32 19, i32* %tt_31, align 4, !tbaa !27
%78 = bitcast i64* %initv to i8*
call void @llvm.lifetime.end(i64 8, i8* %78) #2
br label %if.end79
if.else: ; preds = %land.lhs.true19, %land.lhs.true, %label_forprep
%79 = bitcast double* %ninit to i8*
call void @llvm.lifetime.start(i64 8, i8* %79) #2
%80 = bitcast double* %nlimit to i8*
call void @llvm.lifetime.start(i64 8, i8* %80) #2
%81 = bitcast double* %nstep to i8*
call void @llvm.lifetime.start(i64 8, i8* %81) #2
%82 = bitcast i32* %plimit_is_float to i8*
call void @llvm.lifetime.start(i64 4, i8* %82) #2
store i32 0, i32* %plimit_is_float, align 4, !tbaa !23
%83 = load %struct.TValue*, %struct.TValue** %plimit, align 4, !tbaa !1
%tt_32 = getelementptr inbounds %struct.TValue, %struct.TValue* %83, i32 0, i32 1
%84 = load i32, i32* %tt_32, align 4, !tbaa !27
%cmp33 = icmp eq i32 %84, 3
br i1 %cmp33, label %if.then35, label %if.else37
if.then35: ; preds = %if.else
store i32 1, i32* %plimit_is_float, align 4, !tbaa !23
%85 = load %struct.TValue*, %struct.TValue** %plimit, align 4, !tbaa !1
%value_36 = getelementptr inbounds %struct.TValue, %struct.TValue* %85, i32 0, i32 0
%n = bitcast %union.Value* %value_36 to double*
%86 = load double, double* %n, align 8, !tbaa !25
store double %86, double* %nlimit, align 8, !tbaa !25
br label %if.end
if.else37: ; preds = %if.else
%87 = load %struct.TValue*, %struct.TValue** %plimit, align 4, !tbaa !1
%call38 = call i32 @luaV_tonumber_(%struct.TValue* %87, double* %nlimit)
store i32 %call38, i32* %plimit_is_float, align 4, !tbaa !23
br label %if.end
if.end: ; preds = %if.else37, %if.then35
%88 = load i32, i32* %plimit_is_float, align 4, !tbaa !23
%tobool39 = icmp ne i32 %88, 0
br i1 %tobool39, label %if.end42, label %if.then40
if.then40: ; preds = %if.end
%89 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
%call41 = call i32 bitcast (i32 (...)* @luaG_runerror to i32 (%struct.lua_State*, i8*)*)(%struct.lua_State* %89, i8* getelementptr inbounds ([29 x i8], [29 x i8]* @.str1, i32 0, i32 0))
br label %if.end42
if.end42: ; preds = %if.then40, %if.end
%90 = load double, double* %nlimit, align 8, !tbaa !25
%91 = load %struct.TValue*, %struct.TValue** %plimit, align 4, !tbaa !1
%value_43 = getelementptr inbounds %struct.TValue, %struct.TValue* %91, i32 0, i32 0
%n44 = bitcast %union.Value* %value_43 to double*
store double %90, double* %n44, align 8, !tbaa !25
%92 = load %struct.TValue*, %struct.TValue** %plimit, align 4, !tbaa !1
%tt_45 = getelementptr inbounds %struct.TValue, %struct.TValue* %92, i32 0, i32 1
store i32 3, i32* %tt_45, align 4, !tbaa !27
%93 = bitcast i32* %pstep_is_float to i8*
call void @llvm.lifetime.start(i64 4, i8* %93) #2
store i32 0, i32* %pstep_is_float, align 4, !tbaa !23
%94 = load %struct.TValue*, %struct.TValue** %pstep, align 4, !tbaa !1
%tt_46 = getelementptr inbounds %struct.TValue, %struct.TValue* %94, i32 0, i32 1
%95 = load i32, i32* %tt_46, align 4, !tbaa !27
%cmp47 = icmp eq i32 %95, 3
br i1 %cmp47, label %if.then49, label %if.else52
if.then49: ; preds = %if.end42
store i32 1, i32* %pstep_is_float, align 4, !tbaa !23
%96 = load %struct.TValue*, %struct.TValue** %pstep, align 4, !tbaa !1
%value_50 = getelementptr inbounds %struct.TValue, %struct.TValue* %96, i32 0, i32 0
%n51 = bitcast %union.Value* %value_50 to double*
%97 = load double, double* %n51, align 8, !tbaa !25
store double %97, double* %nstep, align 8, !tbaa !25
br label %if.end54
if.else52: ; preds = %if.end42
%98 = load %struct.TValue*, %struct.TValue** %pstep, align 4, !tbaa !1
%call53 = call i32 @luaV_tonumber_(%struct.TValue* %98, double* %nstep)
store i32 %call53, i32* %pstep_is_float, align 4, !tbaa !23
br label %if.end54
if.end54: ; preds = %if.else52, %if.then49
%99 = load i32, i32* %pstep_is_float, align 4, !tbaa !23
%tobool55 = icmp ne i32 %99, 0
br i1 %tobool55, label %if.end58, label %if.then56
if.then56: ; preds = %if.end54
%100 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
%call57 = call i32 bitcast (i32 (...)* @luaG_runerror to i32 (%struct.lua_State*, i8*)*)(%struct.lua_State* %100, i8* getelementptr inbounds ([28 x i8], [28 x i8]* @.str2, i32 0, i32 0))
br label %if.end58
if.end58: ; preds = %if.then56, %if.end54
%101 = load double, double* %nstep, align 8, !tbaa !25
%102 = load %struct.TValue*, %struct.TValue** %pstep, align 4, !tbaa !1
%value_59 = getelementptr inbounds %struct.TValue, %struct.TValue* %102, i32 0, i32 0
%n60 = bitcast %union.Value* %value_59 to double*
store double %101, double* %n60, align 8, !tbaa !25
%103 = load %struct.TValue*, %struct.TValue** %pstep, align 4, !tbaa !1
%tt_61 = getelementptr inbounds %struct.TValue, %struct.TValue* %103, i32 0, i32 1
store i32 3, i32* %tt_61, align 4, !tbaa !27
%104 = bitcast i32* %init_is_float to i8*
call void @llvm.lifetime.start(i64 4, i8* %104) #2
store i32 0, i32* %init_is_float, align 4, !tbaa !23
%105 = load %struct.TValue*, %struct.TValue** %init, align 4, !tbaa !1
%tt_62 = getelementptr inbounds %struct.TValue, %struct.TValue* %105, i32 0, i32 1
%106 = load i32, i32* %tt_62, align 4, !tbaa !27
%cmp63 = icmp eq i32 %106, 3
br i1 %cmp63, label %if.then65, label %if.else68
if.then65: ; preds = %if.end58
store i32 1, i32* %init_is_float, align 4, !tbaa !23
%107 = load %struct.TValue*, %struct.TValue** %init, align 4, !tbaa !1
%value_66 = getelementptr inbounds %struct.TValue, %struct.TValue* %107, i32 0, i32 0
%n67 = bitcast %union.Value* %value_66 to double*
%108 = load double, double* %n67, align 8, !tbaa !25
store double %108, double* %ninit, align 8, !tbaa !25
br label %if.end70
if.else68: ; preds = %if.end58
%109 = load %struct.TValue*, %struct.TValue** %init, align 4, !tbaa !1
%call69 = call i32 @luaV_tonumber_(%struct.TValue* %109, double* %ninit)
store i32 %call69, i32* %init_is_float, align 4, !tbaa !23
br label %if.end70
if.end70: ; preds = %if.else68, %if.then65
%110 = load i32, i32* %init_is_float, align 4, !tbaa !23
%tobool71 = icmp ne i32 %110, 0
br i1 %tobool71, label %if.end74, label %if.then72
if.then72: ; preds = %if.end70
%111 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
%call73 = call i32 bitcast (i32 (...)* @luaG_runerror to i32 (%struct.lua_State*, i8*)*)(%struct.lua_State* %111, i8* getelementptr inbounds ([37 x i8], [37 x i8]* @.str3, i32 0, i32 0))
br label %if.end74
if.end74: ; preds = %if.then72, %if.end70
%112 = load double, double* %ninit, align 8, !tbaa !25
%113 = load double, double* %nstep, align 8, !tbaa !25
%sub75 = fsub double %112, %113
%114 = load %struct.TValue*, %struct.TValue** %init, align 4, !tbaa !1
%value_76 = getelementptr inbounds %struct.TValue, %struct.TValue* %114, i32 0, i32 0
%n77 = bitcast %union.Value* %value_76 to double*
store double %sub75, double* %n77, align 8, !tbaa !25
%115 = load %struct.TValue*, %struct.TValue** %init, align 4, !tbaa !1
%tt_78 = getelementptr inbounds %struct.TValue, %struct.TValue* %115, i32 0, i32 1
store i32 3, i32* %tt_78, align 4, !tbaa !27
%116 = bitcast i32* %init_is_float to i8*
call void @llvm.lifetime.end(i64 4, i8* %116) #2
%117 = bitcast i32* %pstep_is_float to i8*
call void @llvm.lifetime.end(i64 4, i8* %117) #2
%118 = bitcast i32* %plimit_is_float to i8*
call void @llvm.lifetime.end(i64 4, i8* %118) #2
%119 = bitcast double* %nstep to i8*
call void @llvm.lifetime.end(i64 8, i8* %119) #2
%120 = bitcast double* %nlimit to i8*
call void @llvm.lifetime.end(i64 8, i8* %120) #2
%121 = bitcast double* %ninit to i8*
call void @llvm.lifetime.end(i64 8, i8* %121) #2
br label %if.end79
if.end79: ; preds = %if.end74, %cond.end
br label %label_forloop
label_loopbody: ; preds = %cleanup144, %cleanup
%122 = load %struct.TValue*, %struct.TValue** %base, align 4, !tbaa !1
%add.ptr80 = getelementptr inbounds %struct.TValue, %struct.TValue* %122, i32 0
store %struct.TValue* %add.ptr80, %struct.TValue** %ra, align 4, !tbaa !1
%123 = load %struct.TValue*, %struct.TValue** %base, align 4, !tbaa !1
%add.ptr81 = getelementptr inbounds %struct.TValue, %struct.TValue* %123, i32 4
store %struct.TValue* %add.ptr81, %struct.TValue** %rb, align 4, !tbaa !1
%124 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%125 = load %struct.TValue*, %struct.TValue** %rb, align 4, !tbaa !1
%126 = bitcast %struct.TValue* %124 to i8*
%127 = bitcast %struct.TValue* %125 to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %126, i8* %127, i32 16, i32 8, i1 false), !tbaa.struct !22
br label %label_forloop
label_forloop: ; preds = %label_loopbody, %if.end79
%128 = load %struct.TValue*, %struct.TValue** %base, align 4, !tbaa !1
%add.ptr82 = getelementptr inbounds %struct.TValue, %struct.TValue* %128, i32 1
store %struct.TValue* %add.ptr82, %struct.TValue** %ra, align 4, !tbaa !1
%129 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%tt_83 = getelementptr inbounds %struct.TValue, %struct.TValue* %129, i32 0, i32 1
%130 = load i32, i32* %tt_83, align 4, !tbaa !27
%cmp84 = icmp eq i32 %130, 19
br i1 %cmp84, label %if.then86, label %if.else114
if.then86: ; preds = %label_forloop
%131 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%add.ptr87 = getelementptr inbounds %struct.TValue, %struct.TValue* %131, i32 2
store %struct.TValue* %add.ptr87, %struct.TValue** %rb, align 4, !tbaa !1
%132 = bitcast i64* %step to i8*
call void @llvm.lifetime.start(i64 8, i8* %132) #2
%133 = load %struct.TValue*, %struct.TValue** %rb, align 4, !tbaa !1
%value_88 = getelementptr inbounds %struct.TValue, %struct.TValue* %133, i32 0, i32 0
%i89 = bitcast %union.Value* %value_88 to i64*
%134 = load i64, i64* %i89, align 8, !tbaa !24
store i64 %134, i64* %step, align 8, !tbaa !24
%135 = bitcast i64* %idx to i8*
call void @llvm.lifetime.start(i64 8, i8* %135) #2
%136 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%value_90 = getelementptr inbounds %struct.TValue, %struct.TValue* %136, i32 0, i32 0
%i91 = bitcast %union.Value* %value_90 to i64*
%137 = load i64, i64* %i91, align 8, !tbaa !24
%138 = load i64, i64* %step, align 8, !tbaa !24
%add = add nsw i64 %137, %138
store i64 %add, i64* %idx, align 8, !tbaa !24
%139 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%add.ptr92 = getelementptr inbounds %struct.TValue, %struct.TValue* %139, i32 1
store %struct.TValue* %add.ptr92, %struct.TValue** %rc, align 4, !tbaa !1
%140 = bitcast i64* %limit to i8*
call void @llvm.lifetime.start(i64 8, i8* %140) #2
%141 = load %struct.TValue*, %struct.TValue** %rc, align 4, !tbaa !1
%value_93 = getelementptr inbounds %struct.TValue, %struct.TValue* %141, i32 0, i32 0
%i94 = bitcast %union.Value* %value_93 to i64*
%142 = load i64, i64* %i94, align 8, !tbaa !24
store i64 %142, i64* %limit, align 8, !tbaa !24
%143 = load i64, i64* %step, align 8, !tbaa !24
%cmp95 = icmp slt i64 0, %143
br i1 %cmp95, label %cond.true97, label %cond.false100
cond.true97: ; preds = %if.then86
%144 = load i64, i64* %idx, align 8, !tbaa !24
%145 = load i64, i64* %limit, align 8, !tbaa !24
%cmp98 = icmp sle i64 %144, %145
br i1 %cmp98, label %if.then103, label %if.end111
cond.false100: ; preds = %if.then86
%146 = load i64, i64* %limit, align 8, !tbaa !24
%147 = load i64, i64* %idx, align 8, !tbaa !24
%cmp101 = icmp sle i64 %146, %147
br i1 %cmp101, label %if.then103, label %if.end111
if.then103: ; preds = %cond.false100, %cond.true97
%148 = load i64, i64* %idx, align 8, !tbaa !24
%149 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%value_104 = getelementptr inbounds %struct.TValue, %struct.TValue* %149, i32 0, i32 0
%i105 = bitcast %union.Value* %value_104 to i64*
store i64 %148, i64* %i105, align 8, !tbaa !24
%150 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%tt_106 = getelementptr inbounds %struct.TValue, %struct.TValue* %150, i32 0, i32 1
store i32 19, i32* %tt_106, align 4, !tbaa !27
%151 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%add.ptr107 = getelementptr inbounds %struct.TValue, %struct.TValue* %151, i32 3
store %struct.TValue* %add.ptr107, %struct.TValue** %rc, align 4, !tbaa !1
%152 = load i64, i64* %idx, align 8, !tbaa !24
%153 = load %struct.TValue*, %struct.TValue** %rc, align 4, !tbaa !1
%value_108 = getelementptr inbounds %struct.TValue, %struct.TValue* %153, i32 0, i32 0
%i109 = bitcast %union.Value* %value_108 to i64*
store i64 %152, i64* %i109, align 8, !tbaa !24
%154 = load %struct.TValue*, %struct.TValue** %rc, align 4, !tbaa !1
%tt_110 = getelementptr inbounds %struct.TValue, %struct.TValue* %154, i32 0, i32 1
store i32 19, i32* %tt_110, align 4, !tbaa !27
store i32 4, i32* %cleanup.dest.slot
br label %cleanup
if.end111: ; preds = %cond.false100, %cond.true97
store i32 0, i32* %cleanup.dest.slot
br label %cleanup
cleanup: ; preds = %if.end111, %if.then103
%155 = bitcast i64* %limit to i8*
call void @llvm.lifetime.end(i64 8, i8* %155) #2
%156 = bitcast i64* %idx to i8*
call void @llvm.lifetime.end(i64 8, i8* %156) #2
%157 = bitcast i64* %step to i8*
call void @llvm.lifetime.end(i64 8, i8* %157) #2
%cleanup.dest = load i32, i32* %cleanup.dest.slot
switch i32 %cleanup.dest, label %unreachable [
i32 0, label %cleanup.cont
i32 4, label %label_loopbody
]
cleanup.cont: ; preds = %cleanup
br label %if.end149
if.else114: ; preds = %label_forloop
%158 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%add.ptr115 = getelementptr inbounds %struct.TValue, %struct.TValue* %158, i32 2
store %struct.TValue* %add.ptr115, %struct.TValue** %rb, align 4, !tbaa !1
%159 = bitcast double* %step116 to i8*
call void @llvm.lifetime.start(i64 8, i8* %159) #2
%160 = load %struct.TValue*, %struct.TValue** %rb, align 4, !tbaa !1
%value_117 = getelementptr inbounds %struct.TValue, %struct.TValue* %160, i32 0, i32 0
%n118 = bitcast %union.Value* %value_117 to double*
%161 = load double, double* %n118, align 8, !tbaa !25
store double %161, double* %step116, align 8, !tbaa !25
%162 = bitcast double* %idx119 to i8*
call void @llvm.lifetime.start(i64 8, i8* %162) #2
%163 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%value_120 = getelementptr inbounds %struct.TValue, %struct.TValue* %163, i32 0, i32 0
%n121 = bitcast %union.Value* %value_120 to double*
%164 = load double, double* %n121, align 8, !tbaa !25
%165 = load double, double* %step116, align 8, !tbaa !25
%add122 = fadd double %164, %165
store double %add122, double* %idx119, align 8, !tbaa !25
%166 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%add.ptr123 = getelementptr inbounds %struct.TValue, %struct.TValue* %166, i32 1
store %struct.TValue* %add.ptr123, %struct.TValue** %rc, align 4, !tbaa !1
%167 = bitcast double* %limit124 to i8*
call void @llvm.lifetime.start(i64 8, i8* %167) #2
%168 = load %struct.TValue*, %struct.TValue** %rc, align 4, !tbaa !1
%value_125 = getelementptr inbounds %struct.TValue, %struct.TValue* %168, i32 0, i32 0
%n126 = bitcast %union.Value* %value_125 to double*
%169 = load double, double* %n126, align 8, !tbaa !25
store double %169, double* %limit124, align 8, !tbaa !25
%170 = load double, double* %step116, align 8, !tbaa !25
%cmp127 = fcmp olt double 0.000000e+00, %170
br i1 %cmp127, label %cond.true129, label %cond.false132
cond.true129: ; preds = %if.else114
%171 = load double, double* %idx119, align 8, !tbaa !25
%172 = load double, double* %limit124, align 8, !tbaa !25
%cmp130 = fcmp ole double %171, %172
br i1 %cmp130, label %if.then135, label %if.end143
cond.false132: ; preds = %if.else114
%173 = load double, double* %limit124, align 8, !tbaa !25
%174 = load double, double* %idx119, align 8, !tbaa !25
%cmp133 = fcmp ole double %173, %174
br i1 %cmp133, label %if.then135, label %if.end143
if.then135: ; preds = %cond.false132, %cond.true129
%175 = load double, double* %idx119, align 8, !tbaa !25
%176 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%value_136 = getelementptr inbounds %struct.TValue, %struct.TValue* %176, i32 0, i32 0
%n137 = bitcast %union.Value* %value_136 to double*
store double %175, double* %n137, align 8, !tbaa !25
%177 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%tt_138 = getelementptr inbounds %struct.TValue, %struct.TValue* %177, i32 0, i32 1
store i32 3, i32* %tt_138, align 4, !tbaa !27
%178 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%add.ptr139 = getelementptr inbounds %struct.TValue, %struct.TValue* %178, i32 3
store %struct.TValue* %add.ptr139, %struct.TValue** %rc, align 4, !tbaa !1
%179 = load double, double* %idx119, align 8, !tbaa !25
%180 = load %struct.TValue*, %struct.TValue** %rc, align 4, !tbaa !1
%value_140 = getelementptr inbounds %struct.TValue, %struct.TValue* %180, i32 0, i32 0
%n141 = bitcast %union.Value* %value_140 to double*
store double %179, double* %n141, align 8, !tbaa !25
%181 = load %struct.TValue*, %struct.TValue** %rc, align 4, !tbaa !1
%tt_142 = getelementptr inbounds %struct.TValue, %struct.TValue* %181, i32 0, i32 1
store i32 3, i32* %tt_142, align 4, !tbaa !27
store i32 4, i32* %cleanup.dest.slot
br label %cleanup144
if.end143: ; preds = %cond.false132, %cond.true129
store i32 0, i32* %cleanup.dest.slot
br label %cleanup144
cleanup144: ; preds = %if.end143, %if.then135
%182 = bitcast double* %limit124 to i8*
call void @llvm.lifetime.end(i64 8, i8* %182) #2
%183 = bitcast double* %idx119 to i8*
call void @llvm.lifetime.end(i64 8, i8* %183) #2
%184 = bitcast double* %step116 to i8*
call void @llvm.lifetime.end(i64 8, i8* %184) #2
%cleanup.dest147 = load i32, i32* %cleanup.dest.slot
switch i32 %cleanup.dest147, label %unreachable [
i32 0, label %cleanup.cont148
i32 4, label %label_loopbody
]
cleanup.cont148: ; preds = %cleanup144
br label %if.end149
if.end149: ; preds = %cleanup.cont148, %cleanup.cont
store i32 2, i32* %b, align 4, !tbaa !23
%185 = load %struct.TValue*, %struct.TValue** %base, align 4, !tbaa !1
%add.ptr150 = getelementptr inbounds %struct.TValue, %struct.TValue* %185, i32 0
store %struct.TValue* %add.ptr150, %struct.TValue** %ra, align 4, !tbaa !1
%186 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%187 = load i32, i32* %b, align 4, !tbaa !23
%add.ptr151 = getelementptr inbounds %struct.TValue, %struct.TValue* %186, i32 %187
%add.ptr152 = getelementptr inbounds %struct.TValue, %struct.TValue* %add.ptr151, i32 -1
%188 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
%top = getelementptr inbounds %struct.lua_State, %struct.lua_State* %188, i32 0, i32 4
store %struct.TValue* %add.ptr152, %struct.TValue** %top, align 4, !tbaa !29
%189 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%190 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
%top153 = getelementptr inbounds %struct.lua_State, %struct.lua_State* %190, i32 0, i32 4
%191 = load %struct.TValue*, %struct.TValue** %top153, align 4, !tbaa !29
%sub.ptr.lhs.cast = ptrtoint %struct.TValue* %189 to i32
%sub.ptr.rhs.cast = ptrtoint %struct.TValue* %191 to i32
%sub.ptr.sub = sub i32 %sub.ptr.lhs.cast, %sub.ptr.rhs.cast
%sub.ptr.div = sdiv exact i32 %sub.ptr.sub, 16
%call154 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str4, i32 0, i32 0), i32 %sub.ptr.div)
%192 = load %struct.LClosure*, %struct.LClosure** %cl, align 4, !tbaa !1
%p155 = getelementptr inbounds %struct.LClosure, %struct.LClosure* %192, i32 0, i32 5
%193 = load %struct.Proto*, %struct.Proto** %p155, align 4, !tbaa !17
%sizep = getelementptr inbounds %struct.Proto, %struct.Proto* %193, i32 0, i32 10
%194 = load i32, i32* %sizep, align 4, !tbaa !30
%cmp156 = icmp sgt i32 %194, 0
br i1 %cmp156, label %if.then158, label %if.end160
if.then158: ; preds = %if.end149
%195 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
%196 = load %struct.TValue*, %struct.TValue** %base, align 4, !tbaa !1
%call159 = call i32 bitcast (i32 (...)* @luaF_close to i32 (%struct.lua_State*, %struct.TValue*)*)(%struct.lua_State* %195, %struct.TValue* %196)
br label %if.end160
if.end160: ; preds = %if.then158, %if.end149
%197 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
%198 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%call161 = call i32 @luaD_poscall(%struct.lua_State* %197, %struct.TValue* %198)
store i32 %call161, i32* %b, align 4, !tbaa !23
%199 = load i32, i32* %b, align 4, !tbaa !23
%tobool162 = icmp ne i32 %199, 0
br i1 %tobool162, label %if.then163, label %if.end166
if.then163: ; preds = %if.end160
%200 = load %struct.CallInfoLua*, %struct.CallInfoLua** %ci, align 4, !tbaa !1
%top164 = getelementptr inbounds %struct.CallInfoLua, %struct.CallInfoLua* %200, i32 0, i32 1
%201 = load %struct.TValue*, %struct.TValue** %top164, align 4, !tbaa !31
%202 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
%top165 = getelementptr inbounds %struct.lua_State, %struct.lua_State* %202, i32 0, i32 4
store %struct.TValue* %201, %struct.TValue** %top165, align 4, !tbaa !29
br label %if.end166
if.end166: ; preds = %if.then163, %if.end160
store i32 1, i32* %cleanup.dest.slot
%203 = bitcast i32* %fl to i8*
call void @llvm.lifetime.end(i64 4, i8* %203) #2
%204 = bitcast i32* %pstep_is_integer to i8*
call void @llvm.lifetime.end(i64 4, i8* %204) #2
%205 = bitcast i32* %init_is_integer to i8*
call void @llvm.lifetime.end(i64 4, i8* %205) #2
%206 = bitcast i32* %stopnow to i8*
call void @llvm.lifetime.end(i64 4, i8* %206) #2
%207 = bitcast i64* %ilimit to i8*
call void @llvm.lifetime.end(i64 8, i8* %207) #2
%208 = bitcast %struct.TValue** %pstep to i8*
call void @llvm.lifetime.end(i64 4, i8* %208) #2
%209 = bitcast %struct.TValue** %plimit to i8*
call void @llvm.lifetime.end(i64 4, i8* %209) #2
%210 = bitcast %struct.TValue** %init to i8*
call void @llvm.lifetime.end(i64 4, i8* %210) #2
%211 = bitcast i32* %b to i8*
call void @llvm.lifetime.end(i64 4, i8* %211) #2
%212 = bitcast %struct.TValue** %rc to i8*
call void @llvm.lifetime.end(i64 4, i8* %212) #2
%213 = bitcast %struct.TValue** %rb to i8*
call void @llvm.lifetime.end(i64 4, i8* %213) #2
%214 = bitcast %struct.TValue** %ra to i8*
call void @llvm.lifetime.end(i64 4, i8* %214) #2
%215 = bitcast %struct.CallInfoL** %cil to i8*
call void @llvm.lifetime.end(i64 4, i8* %215) #2
%216 = bitcast %struct.TValue** %base to i8*
call void @llvm.lifetime.end(i64 4, i8* %216) #2
%217 = bitcast %struct.TValue** %k to i8*
call void @llvm.lifetime.end(i64 4, i8* %217) #2
%218 = bitcast %struct.LClosure** %cl to i8*
call void @llvm.lifetime.end(i64 4, i8* %218) #2
%219 = bitcast %struct.CallInfoLua** %ci to i8*
call void @llvm.lifetime.end(i64 4, i8* %219) #2
ret void
unreachable: ; preds = %cleanup144, %cleanup
unreachable
}
; Function Attrs: nounwind
declare void @llvm.lifetime.start(i64, i8* nocapture) #2
; Function Attrs: nounwind
declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture readonly, i32, i32, i1) #2
declare i32 @forlimit(%struct.TValue*, i64*, i64, i32*) #1
; Function Attrs: nounwind
declare void @llvm.lifetime.end(i64, i8* nocapture) #2
declare i32 @luaV_tonumber_(%struct.TValue*, double*) #1
declare i32 @luaG_runerror(...) #1
declare i32 @luaF_close(...) #1
declare i32 @luaD_poscall(%struct.lua_State*, %struct.TValue*) #1
attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #2 = { nounwind }
!llvm.ident = !{!0}
!0 = !{!"clang version 3.7.0 (trunk)"}
!1 = !{!2, !2, i64 0}
!2 = !{!"any pointer", !3, i64 0}
!3 = !{!"omnipotent char", !4, i64 0}
!4 = !{!"Simple C/C++ TBAA"}
!5 = !{!6, !3, i64 4}
!6 = !{!"GCObject", !2, i64 0, !3, i64 4, !3, i64 5}
!7 = !{!8, !2, i64 16}
!8 = !{!"lua_State", !2, i64 0, !3, i64 4, !3, i64 5, !3, i64 6, !2, i64 8, !2, i64 12, !2, i64 16, !2, i64 20, !2, i64 24, !2, i64 28, !2, i64 32, !2, i64 36, !2, i64 40, !2, i64 44, !9, i64 48, !2, i64 104, !10, i64 112, !12, i64 120, !12, i64 124, !12, i64 128, !11, i64 132, !11, i64 134, !3, i64 136, !3, i64 137}
!9 = !{!"CallInfo", !2, i64 0, !2, i64 4, !2, i64 8, !2, i64 12, !3, i64 16, !10, i64 40, !11, i64 48, !3, i64 50, !3, i64 51}
!10 = !{!"long long", !3, i64 0}
!11 = !{!"short", !3, i64 0}
!12 = !{!"int", !3, i64 0}
!13 = !{!14, !2, i64 16}
!14 = !{!"CallInfoLua", !2, i64 0, !2, i64 4, !2, i64 8, !2, i64 12, !15, i64 16, !10, i64 32, !11, i64 40, !3, i64 42, !3, i64 43}
!15 = !{!"CallInfoL", !2, i64 0, !2, i64 4, !10, i64 8}
!16 = !{!14, !2, i64 0}
!17 = !{!18, !2, i64 12}
!18 = !{!"LClosure", !2, i64 0, !3, i64 4, !3, i64 5, !3, i64 6, !2, i64 8, !2, i64 12, !3, i64 16}
!19 = !{!20, !2, i64 44}
!20 = !{!"Proto", !2, i64 0, !3, i64 4, !3, i64 5, !3, i64 6, !3, i64 7, !3, i64 8, !12, i64 12, !12, i64 16, !12, i64 20, !12, i64 24, !12, i64 28, !12, i64 32, !12, i64 36, !12, i64 40, !2, i64 44, !2, i64 48, !2, i64 52, !2, i64 56, !2, i64 60, !2, i64 64, !2, i64 68, !2, i64 72, !2, i64 76, !21, i64 80}
!21 = !{!"RaviJITProto", !3, i64 0, !2, i64 4, !2, i64 8}
!22 = !{i64 0, i64 4, !1, i64 0, i64 4, !1, i64 0, i64 4, !23, i64 0, i64 4, !1, i64 0, i64 8, !24, i64 0, i64 8, !25, i64 8, i64 4, !23}
!23 = !{!12, !12, i64 0}
!24 = !{!10, !10, i64 0}
!25 = !{!26, !26, i64 0}
!26 = !{!"double", !3, i64 0}
!27 = !{!28, !12, i64 8}
!28 = !{!"TValue", !3, i64 0, !12, i64 8}
!29 = !{!8, !2, i64 8}
!30 = !{!20, !12, i64 28}
!31 = !{!14, !2, i64 4}

@ -3,13 +3,13 @@
struct lua_State;
typedef unsigned char lu_byte;
typedef signed char ls_byte;
typedef int (*lua_CFunction) (struct lua_State *L);
#if 1 /* 64bit */
typedef long long lua_Integer;
typedef unsigned long long lua_Unsigned;
typedef double lua_Number;
typedef unsigned short LuaType;
typedef unsigned long long size_t;
typedef unsigned int Instruction;
typedef long long ptrdiff_t;
@ -37,7 +37,7 @@ union Value {
struct TValue {
union Value value_;
LuaType tt_;
lu_byte tt_;
};
struct TString {
@ -70,7 +70,7 @@ struct Udata {
struct GCObject *next;
lu_byte tt;
lu_byte marked;
LuaType ttuv_; /* user value's tag */
lu_byte ttuv_; /* user value's tag */
struct Table *metatable;
size_t len; /* number of bytes */
union Value user_; /* user value */
@ -111,11 +111,9 @@ struct LocVar {
};
struct RaviJITProto {
lu_byte jit_status; /* 0=not compiled, 1=can't compile */
lu_byte jit_flags;
unsigned short execution_count; /* how many times has function been executed */
lu_byte jit_status; // 0=not compiled, 1=can't compile, 2=compiled, 3=freed
void *jit_data;
lua_CFunction jit_function;
int (*jit_function) (struct lua_State *);
};
@ -144,6 +142,7 @@ struct Proto {
struct LClosure *cache; /* last created closure with this prototype */
struct TString *source; /* used for debug information */
struct GCObject *gclist;
lu_byte cachemiss;
struct RaviJITProto ravi_jit;
};
@ -174,29 +173,24 @@ union Closure {
struct LClosure l;
};
union TKey {
struct {
union Node {
struct NodeKey {
union Value value_;
LuaType tt_;
int next; /* for chaining (offset for next node) */
} nk;
struct TValue tvk;
};
struct Node {
struct TValue i_val;
union TKey i_key;
lu_byte tt_;
lu_byte key_tt; /* key type */
int next; /* for chaining */
union Value key_val; /* key value */
} u;
struct TValue i_val; /* direct access to node's value as a proper 'TValue' */
};
struct RaviArray {
char *data;
enum ravitype_t type; /* RAVI specialization */
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 */
};
struct Table {
struct GCObject *next;
lu_byte tt;
@ -205,8 +199,8 @@ struct Table {
lu_byte lsizenode; /* log2 of size of 'node' array */
unsigned int sizearray; /* size of 'array' array */
struct TValue *array; /* array part */
struct Node *node;
struct Node *lastfree; /* any free position is before this position */
union Node *node;
union Node *lastfree; /* any free position is before this position */
struct Table *metatable;
struct GCObject *gclist;
struct RaviArray ravi_array;
@ -256,10 +250,8 @@ struct CallInfo {
} 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; /* RAVI extension: Only valid if Lua function - if 1 means JITed - RAVI extension */
lu_byte magic;
lu_byte callstatus;
lu_byte jitstatus;
};
struct CallInfoLua {
@ -269,10 +261,9 @@ struct CallInfoLua {
struct CallInfoL l;
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; /* RAVI extension: Only valid if Lua function - if 1 means JITed - RAVI extension */
lu_byte magic;
lu_byte callstatus;
lu_byte jitstatus; /* Only valid if Lua function - if 1 means JITed - RAVI extension */
short stacklevel; /* Ravi extension - stack level, bootom level is 0 */
};
struct global_State;
@ -307,17 +298,18 @@ struct lua_State {
lu_byte hookmask; /* Lua 5.3 uses l_signalT */
lu_byte allowhook;
unsigned short nci; /* number of items in 'ci' list (different position than Lua 5.3) */
lu_byte magic;
};
/* lfunc.h */
struct UpVal {
struct GCObject *next;
lu_byte tt;
lu_byte marked;
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 */
struct UpVal **previous;
} open;
struct TValue value; /* the value (when closed) */
} u;
@ -338,13 +330,28 @@ union GCUnion {
#define rttype(o) ((o)->tt_)
#define BIT_ISCOLLECTABLE (1 << 15)
#define BIT_ISCOLLECTABLE (1 << 7)
#define iscollectable(o) (rttype(o) & BIT_ISCOLLECTABLE)
#define upisopen(up) ((up)->v != &(up)->u.value)
#define bitmask(b) (1<<(b))
#define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2))
#define testbits(x,m) ((x) & (m))
#define testbit(x,b) testbits(x, bitmask(b))
#define WHITE0BIT 3 /* object is white (type 0) */
#define WHITE1BIT 4 /* object is white (type 1) */
#define BLACKBIT 5 /* object is black */
#define FINALIZEDBIT 6 /* object has been marked for finalization */
#define TESTGRAYBIT 7 /* used by tests (luaL_checkmemory) */
#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT)
#define isblack(x) testbit((x)->marked, BLACKBIT)
#define iswhite(x) testbits((x)->marked, WHITEBITS)
#define val_(o) ((o)->value_)
#define cast(t, exp) ((t)(exp))
#define cast_u(o) cast(union GCUnion *, (o))
#define gco2t(o) &((cast_u(o))->h)
#define hvalue(o) gco2t(val_(o).gc)
#define gcvalue(o) (val_(o).gc)
#endif

@ -0,0 +1,406 @@
; ModuleID = 'lua_if_else.c'
target datalayout = "e-m:w-p:32:32-i64:64-f80:32-n8:16:32-S32"
target triple = "i686-pc-windows-gnu"
%struct.GCObject = type { %struct.GCObject*, i8, i8 }
%struct.lua_State = type { %struct.GCObject*, i8, i8, i8, %struct.TValue*, %struct.global_State*, %struct.CallInfoLua*, i32*, %struct.TValue*, %struct.TValue*, %struct.UpVal*, %struct.GCObject*, %struct.lua_State*, %struct.lua_longjmp*, %struct.CallInfo, void (%struct.lua_State*, %struct.lua_Debug*)*, i64, i32, i32, i32, i16, i16, i8, i8 }
%struct.global_State = type opaque
%struct.CallInfoLua = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %struct.CallInfoL, i64, i16, i8, i8 }
%struct.CallInfoL = type { %struct.TValue*, i32*, i64 }
%struct.TValue = type { %union.Value, i32 }
%union.Value = type { i64 }
%struct.UpVal = type { %struct.TValue*, i64, %union.anon.0 }
%union.anon.0 = type { %struct.TValue }
%struct.lua_longjmp = type opaque
%struct.CallInfo = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %union.anon, i64, i16, i8, i8 }
%union.anon = type { %struct.CallInfoC }
%struct.CallInfoC = type { i32 (%struct.lua_State*, i32, i64)*, i64, i64 }
%struct.lua_Debug = type opaque
%struct.LClosure = type { %struct.GCObject*, i8, i8, i8, %struct.GCObject*, %struct.Proto*, [1 x %struct.UpVal*] }
%struct.Proto = type { %struct.GCObject*, i8, i8, i8, i8, i8, i32, i32, i32, i32, i32, i32, i32, i32, %struct.TValue*, i32*, %struct.Proto**, i32*, %struct.LocVar*, %struct.Upvaldesc*, %struct.LClosure*, %struct.TString*, %struct.GCObject*, %struct.RaviJITProto }
%struct.LocVar = type { %struct.TString*, i32, i32, i32 }
%struct.Upvaldesc = type { %struct.TString*, i32, i8, i8 }
%struct.TString = type { %struct.GCObject*, i8, i8, i8, i32, i64, %struct.TString* }
%struct.RaviJITProto = type { i8, i8*, i32 (%struct.lua_State*)* }
@.str = private unnamed_addr constant [12 x i8] c"value = %d\0A\00", align 1
; Function Attrs: nounwind
define void @testfunc(%struct.GCObject* %obj) #0 {
entry:
%obj.addr = alloca %struct.GCObject*, align 4
store %struct.GCObject* %obj, %struct.GCObject** %obj.addr, align 4, !tbaa !1
%0 = load %struct.GCObject** %obj.addr, align 4, !tbaa !1
%tt = getelementptr inbounds %struct.GCObject* %0, i32 0, i32 1
%1 = load i8* %tt, align 1, !tbaa !5
%conv = zext i8 %1 to i32
%call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([12 x i8]* @.str, i32 0, i32 0), i32 %conv)
ret void
}
declare i32 @printf(i8*, ...) #1
; Function Attrs: nounwind
define void @test1(%struct.lua_State* %L) #0 {
entry:
%L.addr = alloca %struct.lua_State*, align 4
%ci = alloca %struct.CallInfoLua*, align 4
%cl = alloca %struct.LClosure*, align 4
%k = alloca %struct.TValue*, align 4
%base = alloca %struct.TValue*, align 4
%cil = alloca %struct.CallInfoL*, align 4
%ra2 = alloca %struct.TValue*, align 4
%rb2 = alloca %struct.TValue*, align 4
%ra3 = alloca %struct.TValue*, align 4
%b = alloca i32, align 4
%ra = alloca %struct.TValue*, align 4
%rb = alloca %struct.TValue*, align 4
%rc = alloca %struct.TValue*, align 4
%eq = alloca i32, align 4
%a = alloca i32, align 4
%a39 = alloca i32, align 4
store %struct.lua_State* %L, %struct.lua_State** %L.addr, align 4, !tbaa !1
%0 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
%ci1 = getelementptr inbounds %struct.lua_State* %0, i32 0, i32 6
%1 = load %struct.CallInfoLua** %ci1, align 4, !tbaa !7
store %struct.CallInfoLua* %1, %struct.CallInfoLua** %ci, align 4, !tbaa !1
%2 = load %struct.CallInfoLua** %ci, align 4, !tbaa !1
%l = getelementptr inbounds %struct.CallInfoLua* %2, i32 0, i32 4
%base2 = getelementptr inbounds %struct.CallInfoL* %l, i32 0, i32 0
%3 = load %struct.TValue** %base2, align 4, !tbaa !13
store %struct.TValue* %3, %struct.TValue** %base, align 4, !tbaa !1
%4 = load %struct.CallInfoLua** %ci, align 4, !tbaa !1
%func = getelementptr inbounds %struct.CallInfoLua* %4, i32 0, i32 0
%5 = load %struct.TValue** %func, align 4, !tbaa !16
%value_ = getelementptr inbounds %struct.TValue* %5, i32 0, i32 0
%gc = bitcast %union.Value* %value_ to %struct.GCObject**
%6 = load %struct.GCObject** %gc, align 4, !tbaa !1
%7 = bitcast %struct.GCObject* %6 to %struct.LClosure*
store %struct.LClosure* %7, %struct.LClosure** %cl, align 4, !tbaa !1
%8 = load %struct.LClosure** %cl, align 4, !tbaa !1
%p = getelementptr inbounds %struct.LClosure* %8, i32 0, i32 5
%9 = load %struct.Proto** %p, align 4, !tbaa !17
%k3 = getelementptr inbounds %struct.Proto* %9, i32 0, i32 14
%10 = load %struct.TValue** %k3, align 4, !tbaa !19
store %struct.TValue* %10, %struct.TValue** %k, align 4, !tbaa !1
%11 = load %struct.TValue** %base, align 4, !tbaa !1
%add.ptr = getelementptr inbounds %struct.TValue* %11, i32 0
store %struct.TValue* %add.ptr, %struct.TValue** %ra, align 4, !tbaa !1
%12 = load %struct.TValue** %base, align 4, !tbaa !1
%add.ptr4 = getelementptr inbounds %struct.TValue* %12, i32 0
store %struct.TValue* %add.ptr4, %struct.TValue** %rb, align 4, !tbaa !1
%13 = load %struct.TValue** %k, align 4, !tbaa !1
%add.ptr5 = getelementptr inbounds %struct.TValue* %13, i32 0
store %struct.TValue* %add.ptr5, %struct.TValue** %rc, align 4, !tbaa !1
%14 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
%15 = load %struct.TValue** %rb, align 4, !tbaa !1
%16 = load %struct.TValue** %rc, align 4, !tbaa !1
%call = call i32 bitcast (i32 (...)* @luaV_equalobj to i32 (%struct.lua_State*, %struct.TValue*, %struct.TValue*)*)(%struct.lua_State* %14, %struct.TValue* %15, %struct.TValue* %16)
store i32 %call, i32* %eq, align 4, !tbaa !22
%17 = load %struct.CallInfoLua** %ci, align 4, !tbaa !1
%l6 = getelementptr inbounds %struct.CallInfoLua* %17, i32 0, i32 4
%base7 = getelementptr inbounds %struct.CallInfoL* %l6, i32 0, i32 0
%18 = load %struct.TValue** %base7, align 4, !tbaa !13
store %struct.TValue* %18, %struct.TValue** %base, align 4, !tbaa !1
%19 = load i32* %eq, align 4, !tbaa !22
%cmp = icmp eq i32 %19, 0
br i1 %cmp, label %if.then, label %if.end15
if.then: ; preds = %entry
store i32 0, i32* %a, align 4, !tbaa !22
%20 = load i32* %a, align 4, !tbaa !22
%cmp8 = icmp sgt i32 %20, 0
br i1 %cmp8, label %if.then9, label %if.end
if.then9: ; preds = %if.then
%21 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
%22 = load %struct.CallInfoLua** %ci, align 4, !tbaa !1
%l10 = getelementptr inbounds %struct.CallInfoLua* %22, i32 0, i32 4
%base11 = getelementptr inbounds %struct.CallInfoL* %l10, i32 0, i32 0
%23 = load %struct.TValue** %base11, align 4, !tbaa !13
%24 = load i32* %a, align 4, !tbaa !22
%add.ptr12 = getelementptr inbounds %struct.TValue* %23, i32 %24
%add.ptr13 = getelementptr inbounds %struct.TValue* %add.ptr12, i32 -1
%call14 = call i32 bitcast (i32 (...)* @luaF_close to i32 (%struct.lua_State*, %struct.TValue*)*)(%struct.lua_State* %21, %struct.TValue* %add.ptr13)
br label %if.end
if.end: ; preds = %if.then9, %if.then
br label %label6
if.end15: ; preds = %entry
br label %label3
label3: ; preds = %if.end15
%25 = load %struct.TValue** %base, align 4, !tbaa !1
%add.ptr16 = getelementptr inbounds %struct.TValue* %25, i32 1
store %struct.TValue* %add.ptr16, %struct.TValue** %ra2, align 4, !tbaa !1
%26 = load %struct.TValue** %k, align 4, !tbaa !1
%add.ptr17 = getelementptr inbounds %struct.TValue* %26, i32 1
store %struct.TValue* %add.ptr17, %struct.TValue** %rb2, align 4, !tbaa !1
%27 = load %struct.TValue** %ra2, align 4, !tbaa !1
%28 = load %struct.TValue** %rb2, align 4, !tbaa !1
%29 = bitcast %struct.TValue* %27 to i8*
%30 = bitcast %struct.TValue* %28 to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %29, i8* %30, i32 16, i32 8, i1 false), !tbaa.struct !23
store i32 2, i32* %b, align 4, !tbaa !22
%31 = load %struct.TValue** %base, align 4, !tbaa !1
%add.ptr18 = getelementptr inbounds %struct.TValue* %31, i32 1
store %struct.TValue* %add.ptr18, %struct.TValue** %ra3, align 4, !tbaa !1
%32 = load %struct.TValue** %ra3, align 4, !tbaa !1
%33 = load i32* %b, align 4, !tbaa !22
%add.ptr19 = getelementptr inbounds %struct.TValue* %32, i32 %33
%add.ptr20 = getelementptr inbounds %struct.TValue* %add.ptr19, i32 -1
%34 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
%top = getelementptr inbounds %struct.lua_State* %34, i32 0, i32 4
store %struct.TValue* %add.ptr20, %struct.TValue** %top, align 4, !tbaa !27
%35 = load %struct.LClosure** %cl, align 4, !tbaa !1
%p21 = getelementptr inbounds %struct.LClosure* %35, i32 0, i32 5
%36 = load %struct.Proto** %p21, align 4, !tbaa !17
%sizep = getelementptr inbounds %struct.Proto* %36, i32 0, i32 10
%37 = load i32* %sizep, align 4, !tbaa !28
%cmp22 = icmp sgt i32 %37, 0
br i1 %cmp22, label %if.then23, label %if.end25
if.then23: ; preds = %label3
%38 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
%39 = load %struct.TValue** %base, align 4, !tbaa !1
%call24 = call i32 bitcast (i32 (...)* @luaF_close to i32 (%struct.lua_State*, %struct.TValue*)*)(%struct.lua_State* %38, %struct.TValue* %39)
br label %if.end25
if.end25: ; preds = %if.then23, %label3
%40 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
%41 = load %struct.TValue** %ra3, align 4, !tbaa !1
%call26 = call i32 @luaD_poscall(%struct.lua_State* %40, %struct.TValue* %41)
store i32 %call26, i32* %b, align 4, !tbaa !22
%42 = load i32* %b, align 4, !tbaa !22
%tobool = icmp ne i32 %42, 0
br i1 %tobool, label %if.then27, label %if.end30
if.then27: ; preds = %if.end25
%43 = load %struct.CallInfoLua** %ci, align 4, !tbaa !1
%top28 = getelementptr inbounds %struct.CallInfoLua* %43, i32 0, i32 1
%44 = load %struct.TValue** %top28, align 4, !tbaa !29
%45 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
%top29 = getelementptr inbounds %struct.lua_State* %45, i32 0, i32 4
store %struct.TValue* %44, %struct.TValue** %top29, align 4, !tbaa !27
br label %if.end30
if.end30: ; preds = %if.then27, %if.end25
br label %return
label6: ; preds = %if.end
%46 = load %struct.TValue** %base, align 4, !tbaa !1
%add.ptr31 = getelementptr inbounds %struct.TValue* %46, i32 0
store %struct.TValue* %add.ptr31, %struct.TValue** %ra, align 4, !tbaa !1
%47 = load %struct.TValue** %base, align 4, !tbaa !1
%add.ptr32 = getelementptr inbounds %struct.TValue* %47, i32 0
store %struct.TValue* %add.ptr32, %struct.TValue** %rb, align 4, !tbaa !1
%48 = load %struct.TValue** %k, align 4, !tbaa !1
%add.ptr33 = getelementptr inbounds %struct.TValue* %48, i32 2
store %struct.TValue* %add.ptr33, %struct.TValue** %rc, align 4, !tbaa !1
%49 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
%50 = load %struct.TValue** %rb, align 4, !tbaa !1
%51 = load %struct.TValue** %rc, align 4, !tbaa !1
%call34 = call i32 bitcast (i32 (...)* @luaV_equalobj to i32 (%struct.lua_State*, %struct.TValue*, %struct.TValue*)*)(%struct.lua_State* %49, %struct.TValue* %50, %struct.TValue* %51)
store i32 %call34, i32* %eq, align 4, !tbaa !22
%52 = load %struct.CallInfoLua** %ci, align 4, !tbaa !1
%l35 = getelementptr inbounds %struct.CallInfoLua* %52, i32 0, i32 4
%base36 = getelementptr inbounds %struct.CallInfoL* %l35, i32 0, i32 0
%53 = load %struct.TValue** %base36, align 4, !tbaa !13
store %struct.TValue* %53, %struct.TValue** %base, align 4, !tbaa !1
%54 = load i32* %eq, align 4, !tbaa !22
%cmp37 = icmp eq i32 %54, 0
br i1 %cmp37, label %if.then38, label %if.end48
if.then38: ; preds = %label6
store i32 0, i32* %a39, align 4, !tbaa !22
%55 = load i32* %a39, align 4, !tbaa !22
%cmp40 = icmp sgt i32 %55, 0
br i1 %cmp40, label %if.then41, label %if.end47
if.then41: ; preds = %if.then38
%56 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
%57 = load %struct.CallInfoLua** %ci, align 4, !tbaa !1
%l42 = getelementptr inbounds %struct.CallInfoLua* %57, i32 0, i32 4
%base43 = getelementptr inbounds %struct.CallInfoL* %l42, i32 0, i32 0
%58 = load %struct.TValue** %base43, align 4, !tbaa !13
%59 = load i32* %a39, align 4, !tbaa !22
%add.ptr44 = getelementptr inbounds %struct.TValue* %58, i32 %59
%add.ptr45 = getelementptr inbounds %struct.TValue* %add.ptr44, i32 -1
%call46 = call i32 bitcast (i32 (...)* @luaF_close to i32 (%struct.lua_State*, %struct.TValue*)*)(%struct.lua_State* %56, %struct.TValue* %add.ptr45)
br label %if.end47
if.end47: ; preds = %if.then41, %if.then38
br label %label11
if.end48: ; preds = %label6
br label %label8
label8: ; preds = %if.end48
%60 = load %struct.TValue** %base, align 4, !tbaa !1
%add.ptr49 = getelementptr inbounds %struct.TValue* %60, i32 1
store %struct.TValue* %add.ptr49, %struct.TValue** %ra2, align 4, !tbaa !1
%61 = load %struct.TValue** %k, align 4, !tbaa !1
%add.ptr50 = getelementptr inbounds %struct.TValue* %61, i32 3
store %struct.TValue* %add.ptr50, %struct.TValue** %rb2, align 4, !tbaa !1
%62 = load %struct.TValue** %ra2, align 4, !tbaa !1
%63 = load %struct.TValue** %rb2, align 4, !tbaa !1
%64 = bitcast %struct.TValue* %62 to i8*
%65 = bitcast %struct.TValue* %63 to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %64, i8* %65, i32 16, i32 8, i1 false), !tbaa.struct !23
store i32 2, i32* %b, align 4, !tbaa !22
%66 = load %struct.TValue** %base, align 4, !tbaa !1
%add.ptr51 = getelementptr inbounds %struct.TValue* %66, i32 1
store %struct.TValue* %add.ptr51, %struct.TValue** %ra3, align 4, !tbaa !1
%67 = load %struct.TValue** %ra3, align 4, !tbaa !1
%68 = load i32* %b, align 4, !tbaa !22
%add.ptr52 = getelementptr inbounds %struct.TValue* %67, i32 %68
%add.ptr53 = getelementptr inbounds %struct.TValue* %add.ptr52, i32 -1
%69 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
%top54 = getelementptr inbounds %struct.lua_State* %69, i32 0, i32 4
store %struct.TValue* %add.ptr53, %struct.TValue** %top54, align 4, !tbaa !27
%70 = load %struct.LClosure** %cl, align 4, !tbaa !1
%p55 = getelementptr inbounds %struct.LClosure* %70, i32 0, i32 5
%71 = load %struct.Proto** %p55, align 4, !tbaa !17
%sizep56 = getelementptr inbounds %struct.Proto* %71, i32 0, i32 10
%72 = load i32* %sizep56, align 4, !tbaa !28
%cmp57 = icmp sgt i32 %72, 0
br i1 %cmp57, label %if.then58, label %if.end60
if.then58: ; preds = %label8
%73 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
%74 = load %struct.TValue** %base, align 4, !tbaa !1
%call59 = call i32 bitcast (i32 (...)* @luaF_close to i32 (%struct.lua_State*, %struct.TValue*)*)(%struct.lua_State* %73, %struct.TValue* %74)
br label %if.end60
if.end60: ; preds = %if.then58, %label8
%75 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
%76 = load %struct.TValue** %ra3, align 4, !tbaa !1
%call61 = call i32 @luaD_poscall(%struct.lua_State* %75, %struct.TValue* %76)
store i32 %call61, i32* %b, align 4, !tbaa !22
%77 = load i32* %b, align 4, !tbaa !22
%tobool62 = icmp ne i32 %77, 0
br i1 %tobool62, label %if.then63, label %if.end66
if.then63: ; preds = %if.end60
%78 = load %struct.CallInfoLua** %ci, align 4, !tbaa !1
%top64 = getelementptr inbounds %struct.CallInfoLua* %78, i32 0, i32 1
%79 = load %struct.TValue** %top64, align 4, !tbaa !29
%80 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
%top65 = getelementptr inbounds %struct.lua_State* %80, i32 0, i32 4
store %struct.TValue* %79, %struct.TValue** %top65, align 4, !tbaa !27
br label %if.end66
if.end66: ; preds = %if.then63, %if.end60
br label %return
label11: ; preds = %if.end47
%81 = load %struct.TValue** %base, align 4, !tbaa !1
%add.ptr67 = getelementptr inbounds %struct.TValue* %81, i32 1
store %struct.TValue* %add.ptr67, %struct.TValue** %ra2, align 4, !tbaa !1
%82 = load %struct.TValue** %k, align 4, !tbaa !1
%add.ptr68 = getelementptr inbounds %struct.TValue* %82, i32 4
store %struct.TValue* %add.ptr68, %struct.TValue** %rb2, align 4, !tbaa !1
%83 = load %struct.TValue** %ra2, align 4, !tbaa !1
%84 = load %struct.TValue** %rb2, align 4, !tbaa !1
%85 = bitcast %struct.TValue* %83 to i8*
%86 = bitcast %struct.TValue* %84 to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %85, i8* %86, i32 16, i32 8, i1 false), !tbaa.struct !23
store i32 2, i32* %b, align 4, !tbaa !22
%87 = load %struct.TValue** %base, align 4, !tbaa !1
%add.ptr69 = getelementptr inbounds %struct.TValue* %87, i32 1
store %struct.TValue* %add.ptr69, %struct.TValue** %ra3, align 4, !tbaa !1
%88 = load %struct.TValue** %ra3, align 4, !tbaa !1
%89 = load i32* %b, align 4, !tbaa !22
%add.ptr70 = getelementptr inbounds %struct.TValue* %88, i32 %89
%add.ptr71 = getelementptr inbounds %struct.TValue* %add.ptr70, i32 -1
%90 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
%top72 = getelementptr inbounds %struct.lua_State* %90, i32 0, i32 4
store %struct.TValue* %add.ptr71, %struct.TValue** %top72, align 4, !tbaa !27
%91 = load %struct.LClosure** %cl, align 4, !tbaa !1
%p73 = getelementptr inbounds %struct.LClosure* %91, i32 0, i32 5
%92 = load %struct.Proto** %p73, align 4, !tbaa !17
%sizep74 = getelementptr inbounds %struct.Proto* %92, i32 0, i32 10
%93 = load i32* %sizep74, align 4, !tbaa !28
%cmp75 = icmp sgt i32 %93, 0
br i1 %cmp75, label %if.then76, label %if.end78
if.then76: ; preds = %label11
%94 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
%95 = load %struct.TValue** %base, align 4, !tbaa !1
%call77 = call i32 bitcast (i32 (...)* @luaF_close to i32 (%struct.lua_State*, %struct.TValue*)*)(%struct.lua_State* %94, %struct.TValue* %95)
br label %if.end78
if.end78: ; preds = %if.then76, %label11
%96 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
%97 = load %struct.TValue** %ra3, align 4, !tbaa !1
%call79 = call i32 @luaD_poscall(%struct.lua_State* %96, %struct.TValue* %97)
store i32 %call79, i32* %b, align 4, !tbaa !22
%98 = load i32* %b, align 4, !tbaa !22
%tobool80 = icmp ne i32 %98, 0
br i1 %tobool80, label %if.then81, label %if.end84
if.then81: ; preds = %if.end78
%99 = load %struct.CallInfoLua** %ci, align 4, !tbaa !1
%top82 = getelementptr inbounds %struct.CallInfoLua* %99, i32 0, i32 1
%100 = load %struct.TValue** %top82, align 4, !tbaa !29
%101 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
%top83 = getelementptr inbounds %struct.lua_State* %101, i32 0, i32 4
store %struct.TValue* %100, %struct.TValue** %top83, align 4, !tbaa !27
br label %if.end84
if.end84: ; preds = %if.then81, %if.end78
br label %return
label_return: ; No predecessors!
br label %return
return: ; preds = %label_return, %if.end84, %if.end66, %if.end30
ret void
}
declare i32 @luaV_equalobj(...) #1
declare i32 @luaF_close(...) #1
; Function Attrs: nounwind
declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture readonly, i32, i32, i1) #2
declare i32 @luaD_poscall(%struct.lua_State*, %struct.TValue*) #1
attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #2 = { nounwind }
!llvm.ident = !{!0}
!0 = metadata !{metadata !"clang version 3.6.0 (trunk)"}
!1 = metadata !{metadata !2, metadata !2, i64 0}
!2 = metadata !{metadata !"any pointer", metadata !3, i64 0}
!3 = metadata !{metadata !"omnipotent char", metadata !4, i64 0}
!4 = metadata !{metadata !"Simple C/C++ TBAA"}
!5 = metadata !{metadata !6, metadata !3, i64 4}
!6 = metadata !{metadata !"GCObject", metadata !2, i64 0, metadata !3, i64 4, metadata !3, i64 5}
!7 = metadata !{metadata !8, metadata !2, i64 16}
!8 = metadata !{metadata !"lua_State", metadata !2, i64 0, metadata !3, i64 4, metadata !3, i64 5, metadata !3, i64 6, metadata !2, i64 8, metadata !2, i64 12, metadata !2, i64 16, metadata !2, i64 20, metadata !2, i64 24, metadata !2, i64 28, metadata !2, i64 32, metadata !2, i64 36, metadata !2, i64 40, metadata !2, i64 44, metadata !9, i64 48, metadata !2, i64 104, metadata !10, i64 112, metadata !12, i64 120, metadata !12, i64 124, metadata !12, i64 128, metadata !11, i64 132, metadata !11, i64 134, metadata !3, i64 136, metadata !3, i64 137}
!9 = metadata !{metadata !"CallInfo", metadata !2, i64 0, metadata !2, i64 4, metadata !2, i64 8, metadata !2, i64 12, metadata !3, i64 16, metadata !10, i64 40, metadata !11, i64 48, metadata !3, i64 50, metadata !3, i64 51}
!10 = metadata !{metadata !"long long", metadata !3, i64 0}
!11 = metadata !{metadata !"short", metadata !3, i64 0}
!12 = metadata !{metadata !"int", metadata !3, i64 0}
!13 = metadata !{metadata !14, metadata !2, i64 16}
!14 = metadata !{metadata !"CallInfoLua", metadata !2, i64 0, metadata !2, i64 4, metadata !2, i64 8, metadata !2, i64 12, metadata !15, i64 16, metadata !10, i64 32, metadata !11, i64 40, metadata !3, i64 42, metadata !3, i64 43}
!15 = metadata !{metadata !"CallInfoL", metadata !2, i64 0, metadata !2, i64 4, metadata !10, i64 8}
!16 = metadata !{metadata !14, metadata !2, i64 0}
!17 = metadata !{metadata !18, metadata !2, i64 12}
!18 = metadata !{metadata !"LClosure", metadata !2, i64 0, metadata !3, i64 4, metadata !3, i64 5, metadata !3, i64 6, metadata !2, i64 8, metadata !2, i64 12, metadata !3, i64 16}
!19 = metadata !{metadata !20, metadata !2, i64 44}
!20 = metadata !{metadata !"Proto", metadata !2, i64 0, metadata !3, i64 4, metadata !3, i64 5, metadata !3, i64 6, metadata !3, i64 7, metadata !3, i64 8, metadata !12, i64 12, metadata !12, i64 16, metadata !12, i64 20, metadata !12, i64 24, metadata !12, i64 28, metadata !12, i64 32, metadata !12, i64 36, metadata !12, i64 40, metadata !2, i64 44, metadata !2, i64 48, metadata !2, i64 52, metadata !2, i64 56, metadata !2, i64 60, metadata !2, i64 64, metadata !2, i64 68, metadata !2, i64 72, metadata !2, i64 76, metadata !21, i64 80}
!21 = metadata !{metadata !"RaviJITProto", metadata !3, i64 0, metadata !2, i64 4, metadata !2, i64 8}
!22 = metadata !{metadata !12, metadata !12, i64 0}
!23 = metadata !{i64 0, i64 4, metadata !1, i64 0, i64 4, metadata !1, i64 0, i64 4, metadata !22, i64 0, i64 4, metadata !1, i64 0, i64 8, metadata !24, i64 0, i64 8, metadata !25, i64 8, i64 4, metadata !22}
!24 = metadata !{metadata !10, metadata !10, i64 0}
!25 = metadata !{metadata !26, metadata !26, i64 0}
!26 = metadata !{metadata !"double", metadata !3, i64 0}
!27 = metadata !{metadata !8, metadata !2, i64 8}
!28 = metadata !{metadata !20, metadata !12, i64 28}
!29 = metadata !{metadata !14, metadata !2, i64 4}

@ -0,0 +1,79 @@
; ModuleID = 'lua_op_call.c'
target datalayout = "e-m:w-p:32:32-i64:64-f80:32-n8:16:32-S32"
target triple = "i686-pc-windows-gnu"
%struct.lua_State = type { %struct.GCObject*, i8, i8, i8, %struct.TValue*, %struct.global_State*, %struct.CallInfoLua*, i32*, %struct.TValue*, %struct.TValue*, %struct.UpVal*, %struct.GCObject*, %struct.lua_State*, %struct.lua_longjmp*, %struct.CallInfo, void (%struct.lua_State*, %struct.lua_Debug*)*, i64, i32, i32, i32, i16, i16, i8, i8 }
%struct.global_State = type opaque
%struct.CallInfoLua = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %struct.CallInfoL, i64, i16, i8, i8 }
%struct.CallInfoL = type { %struct.TValue*, i32*, i64 }
%struct.UpVal = type { %struct.TValue*, i64, %union.anon.0 }
%union.anon.0 = type { %struct.TValue }
%struct.TValue = type { %union.Value, i32 }
%union.Value = type { i64 }
%struct.GCObject = type { %struct.GCObject*, i8, i8 }
%struct.lua_longjmp = type opaque
%struct.CallInfo = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %union.anon, i64, i16, i8, i8 }
%union.anon = type { %struct.CallInfoC }
%struct.CallInfoC = type { i32 (%struct.lua_State*, i32, i64)*, i64, i64 }
%struct.lua_Debug = type opaque
; Function Attrs: nounwind
define void @luaV_op_call(%struct.lua_State* %L, %struct.CallInfo* nocapture readonly %ci, %struct.TValue* %ra, i32 %b, i32 %c) #0 {
entry:
%sub = add nsw i32 %c, -1
%cmp = icmp eq i32 %b, 0
br i1 %cmp, label %if.end, label %if.then
if.then: ; preds = %entry
%add.ptr = getelementptr inbounds %struct.TValue* %ra, i32 %b
%top = getelementptr inbounds %struct.lua_State* %L, i32 0, i32 4
store %struct.TValue* %add.ptr, %struct.TValue** %top, align 4, !tbaa !1
br label %if.end
if.end: ; preds = %entry, %if.then
%call = tail call i32 @luaD_precall(%struct.lua_State* %L, %struct.TValue* %ra, i32 %sub, i32 1) #2
%tobool = icmp eq i32 %call, 0
br i1 %tobool, label %if.else, label %if.then1
if.then1: ; preds = %if.end
%cmp2 = icmp eq i32 %call, 1
%cmp3 = icmp sgt i32 %c, 0
%or.cond = and i1 %cmp3, %cmp2
br i1 %or.cond, label %if.then4, label %if.end8
if.then4: ; preds = %if.then1
%top5 = getelementptr inbounds %struct.CallInfo* %ci, i32 0, i32 1
%0 = load %struct.TValue** %top5, align 4, !tbaa !10
%top6 = getelementptr inbounds %struct.lua_State* %L, i32 0, i32 4
store %struct.TValue* %0, %struct.TValue** %top6, align 4, !tbaa !1
br label %if.end8
if.else: ; preds = %if.end
tail call void @luaV_execute(%struct.lua_State* %L) #2
br label %if.end8
if.end8: ; preds = %if.then1, %if.then4, %if.else
ret void
}
declare i32 @luaD_precall(%struct.lua_State*, %struct.TValue*, i32, i32) #1
declare void @luaV_execute(%struct.lua_State*) #1
attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #2 = { nounwind }
!llvm.ident = !{!0}
!0 = metadata !{metadata !"clang version 3.6.0 (trunk)"}
!1 = metadata !{metadata !2, metadata !3, i64 8}
!2 = metadata !{metadata !"lua_State", metadata !3, i64 0, metadata !4, i64 4, metadata !4, i64 5, metadata !4, i64 6, metadata !3, i64 8, metadata !3, i64 12, metadata !3, i64 16, metadata !3, i64 20, metadata !3, i64 24, metadata !3, i64 28, metadata !3, i64 32, metadata !3, i64 36, metadata !3, i64 40, metadata !3, i64 44, metadata !6, i64 48, metadata !3, i64 104, metadata !7, i64 112, metadata !9, i64 120, metadata !9, i64 124, metadata !9, i64 128, metadata !8, i64 132, metadata !8, i64 134, metadata !4, i64 136, metadata !4, i64 137}
!3 = metadata !{metadata !"any pointer", metadata !4, i64 0}
!4 = metadata !{metadata !"omnipotent char", metadata !5, i64 0}
!5 = metadata !{metadata !"Simple C/C++ TBAA"}
!6 = metadata !{metadata !"CallInfo", metadata !3, i64 0, metadata !3, i64 4, metadata !3, i64 8, metadata !3, i64 12, metadata !4, i64 16, metadata !7, i64 40, metadata !8, i64 48, metadata !4, i64 50, metadata !4, i64 51}
!7 = metadata !{metadata !"long long", metadata !4, i64 0}
!8 = metadata !{metadata !"short", metadata !4, i64 0}
!9 = metadata !{metadata !"int", metadata !4, i64 0}
!10 = metadata !{metadata !6, metadata !3, i64 4}

@ -0,0 +1,142 @@
; ModuleID = 'lua_op_forloop.c'
target datalayout = "e-m:w-p:32:32-i64:64-f80:32-n8:16:32-S32"
target triple = "i686-pc-windows-gnu"
%struct.GCObject = type { %struct.GCObject*, i8, i8 }
%struct.lua_State = type { %struct.GCObject*, i8, i8, i8, %struct.TValue*, %struct.global_State*, %struct.CallInfoLua*, i32*, %struct.TValue*, %struct.TValue*, %struct.UpVal*, %struct.GCObject*, %struct.lua_State*, %struct.lua_longjmp*, %struct.CallInfo, void (%struct.lua_State*, %struct.lua_Debug*)*, i64, i32, i32, i32, i16, i16, i8, i8 }
%struct.global_State = type opaque
%struct.CallInfoLua = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %struct.CallInfoL, i64, i16, i8, i8 }
%struct.CallInfoL = type { %struct.TValue*, i32*, i64 }
%struct.TValue = type { %union.Value, i32 }
%union.Value = type { i64 }
%struct.UpVal = type { %struct.TValue*, i64, %union.anon.0 }
%union.anon.0 = type { %struct.TValue }
%struct.lua_longjmp = type opaque
%struct.CallInfo = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %union.anon, i64, i16, i8, i8 }
%union.anon = type { %struct.CallInfoC }
%struct.CallInfoC = type { i32 (%struct.lua_State*, i32, i64)*, i64, i64 }
%struct.lua_Debug = type opaque
@.str = private unnamed_addr constant [12 x i8] c"value = %d\0A\00", align 1
@.str1 = private unnamed_addr constant [6 x i8] c"dummy\00", align 1
; Function Attrs: nounwind
define void @testfunc(%struct.GCObject* nocapture readonly %obj) #0 {
entry:
%tt = getelementptr inbounds %struct.GCObject* %obj, i32 0, i32 1
%0 = load i8* %tt, align 1, !tbaa !1
%conv = zext i8 %0 to i32
%call = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([12 x i8]* @.str, i32 0, i32 0), i32 %conv) #1
ret void
}
; Function Attrs: nounwind
declare i32 @printf(i8* nocapture readonly, ...) #0
; Function Attrs: nounwind
define void @test1(%struct.lua_State* nocapture readonly %L) #0 {
entry:
%ci1 = getelementptr inbounds %struct.lua_State* %L, i32 0, i32 6
%0 = load %struct.CallInfoLua** %ci1, align 4, !tbaa !6
%base2 = getelementptr inbounds %struct.CallInfoLua* %0, i32 0, i32 4, i32 0
%1 = load %struct.TValue** %base2, align 4, !tbaa !12
%add.ptr = getelementptr inbounds %struct.TValue* %1, i32 1
%tt_ = getelementptr inbounds %struct.TValue* %1, i32 1, i32 1
%value_5 = getelementptr inbounds %struct.TValue* %1, i32 3, i32 0
%i = getelementptr inbounds %union.Value* %value_5, i32 0, i32 0
%i7 = getelementptr inbounds %struct.TValue* %add.ptr, i32 0, i32 0, i32 0
%i12 = getelementptr inbounds %struct.TValue* %1, i32 2, i32 0, i32 0
%i23 = getelementptr inbounds %struct.TValue* %1, i32 4, i32 0, i32 0
%tt_24 = getelementptr inbounds %struct.TValue* %1, i32 4, i32 1
%n = bitcast %union.Value* %value_5 to double*
%n31 = bitcast %struct.TValue* %add.ptr to double*
%value_36 = getelementptr inbounds %struct.TValue* %1, i32 2, i32 0
%n37 = bitcast %union.Value* %value_36 to double*
%add.ptr48 = getelementptr inbounds %struct.TValue* %1, i32 4
%n50 = bitcast %struct.TValue* %add.ptr48 to double*
br label %label_loopbody
label_loopbody: ; preds = %label_loopbody.backedge, %entry
%call = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([6 x i8]* @.str1, i32 0, i32 0)) #1
%2 = load i32* %tt_, align 4, !tbaa !15
%cmp = icmp eq i32 %2, 19
br i1 %cmp, label %if.then, label %if.else
if.then: ; preds = %label_loopbody
%3 = load i64* %i, align 8, !tbaa !17
%4 = load i64* %i7, align 8, !tbaa !17
%add8 = add nsw i64 %4, %3
%5 = load i64* %i12, align 8, !tbaa !17
%cmp13 = icmp sgt i64 %3, 0
br i1 %cmp13, label %cond.true, label %cond.false
cond.true: ; preds = %if.then
%cmp14 = icmp sgt i64 %add8, %5
br i1 %cmp14, label %if.end53, label %if.then16
cond.false: ; preds = %if.then
%cmp15 = icmp sgt i64 %5, %add8
br i1 %cmp15, label %if.end53, label %if.then16
if.then16: ; preds = %cond.true, %cond.false
store i64 %add8, i64* %i7, align 8, !tbaa !17
store i32 19, i32* %tt_, align 4, !tbaa !15
store i64 %add8, i64* %i23, align 8, !tbaa !17
br label %label_loopbody.backedge
label_loopbody.backedge: ; preds = %if.then16, %if.then43
%storemerge = phi i32 [ 3, %if.then43 ], [ 19, %if.then16 ]
store i32 %storemerge, i32* %tt_24, align 4, !tbaa !15
br label %label_loopbody
if.else: ; preds = %label_loopbody
%6 = load double* %n, align 8, !tbaa !18
%7 = load double* %n31, align 8, !tbaa !18
%add32 = fadd double %6, %7
%8 = load double* %n37, align 8, !tbaa !18
%cmp38 = fcmp ogt double %6, 0.000000e+00
br i1 %cmp38, label %cond.true39, label %cond.false41
cond.true39: ; preds = %if.else
%cmp40 = fcmp ugt double %add32, %8
br i1 %cmp40, label %if.end53, label %if.then43
cond.false41: ; preds = %if.else
%cmp42 = fcmp ugt double %8, %add32
br i1 %cmp42, label %if.end53, label %if.then43
if.then43: ; preds = %cond.true39, %cond.false41
store double %add32, double* %n31, align 8, !tbaa !18
store i32 3, i32* %tt_, align 4, !tbaa !15
store double %add32, double* %n50, align 8, !tbaa !18
br label %label_loopbody.backedge
if.end53: ; preds = %cond.true, %cond.false, %cond.true39, %cond.false41
ret void
}
attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { nounwind }
!llvm.ident = !{!0}
!0 = metadata !{metadata !"clang version 3.6.0 (trunk)"}
!1 = metadata !{metadata !2, metadata !4, i64 4}
!2 = metadata !{metadata !"GCObject", metadata !3, i64 0, metadata !4, i64 4, metadata !4, i64 5}
!3 = metadata !{metadata !"any pointer", metadata !4, i64 0}
!4 = metadata !{metadata !"omnipotent char", metadata !5, i64 0}
!5 = metadata !{metadata !"Simple C/C++ TBAA"}
!6 = metadata !{metadata !7, metadata !3, i64 16}
!7 = metadata !{metadata !"lua_State", metadata !3, i64 0, metadata !4, i64 4, metadata !4, i64 5, metadata !4, i64 6, metadata !3, i64 8, metadata !3, i64 12, metadata !3, i64 16, metadata !3, i64 20, metadata !3, i64 24, metadata !3, i64 28, metadata !3, i64 32, metadata !3, i64 36, metadata !3, i64 40, metadata !3, i64 44, metadata !8, i64 48, metadata !3, i64 104, metadata !9, i64 112, metadata !11, i64 120, metadata !11, i64 124, metadata !11, i64 128, metadata !10, i64 132, metadata !10, i64 134, metadata !4, i64 136, metadata !4, i64 137}
!8 = metadata !{metadata !"CallInfo", metadata !3, i64 0, metadata !3, i64 4, metadata !3, i64 8, metadata !3, i64 12, metadata !4, i64 16, metadata !9, i64 40, metadata !10, i64 48, metadata !4, i64 50, metadata !4, i64 51}
!9 = metadata !{metadata !"long long", metadata !4, i64 0}
!10 = metadata !{metadata !"short", metadata !4, i64 0}
!11 = metadata !{metadata !"int", metadata !4, i64 0}
!12 = metadata !{metadata !13, metadata !3, i64 16}
!13 = metadata !{metadata !"CallInfoLua", metadata !3, i64 0, metadata !3, i64 4, metadata !3, i64 8, metadata !3, i64 12, metadata !14, i64 16, metadata !9, i64 32, metadata !10, i64 40, metadata !4, i64 42, metadata !4, i64 43}
!14 = metadata !{metadata !"CallInfoL", metadata !3, i64 0, metadata !3, i64 4, metadata !9, i64 8}
!15 = metadata !{metadata !16, metadata !11, i64 8}
!16 = metadata !{metadata !"TValue", metadata !4, i64 0, metadata !11, i64 8}
!17 = metadata !{metadata !9, metadata !9, i64 0}
!18 = metadata !{metadata !19, metadata !19, i64 0}
!19 = metadata !{metadata !"double", metadata !4, i64 0}

@ -0,0 +1,204 @@
; ModuleID = 'lua_op_forprep.c'
target datalayout = "e-m:w-p:32:32-i64:64-f80:32-n8:16:32-S32"
target triple = "i686-pc-windows-gnu"
%struct.GCObject = type { %struct.GCObject*, i8, i8 }
%struct.lua_State = type { %struct.GCObject*, i8, i8, i8, %struct.TValue*, %struct.global_State*, %struct.CallInfoLua*, i32*, %struct.TValue*, %struct.TValue*, %struct.UpVal*, %struct.GCObject*, %struct.lua_State*, %struct.lua_longjmp*, %struct.CallInfo, void (%struct.lua_State*, %struct.lua_Debug*)*, i64, i32, i32, i32, i16, i16, i8, i8 }
%struct.global_State = type opaque
%struct.CallInfoLua = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %struct.CallInfoL, i64, i16, i8, i8 }
%struct.CallInfoL = type { %struct.TValue*, i32*, i64 }
%struct.TValue = type { %union.Value, i32 }
%union.Value = type { i64 }
%struct.UpVal = type { %struct.TValue*, i64, %union.anon.0 }
%union.anon.0 = type { %struct.TValue }
%struct.lua_longjmp = type opaque
%struct.CallInfo = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %union.anon, i64, i16, i8, i8 }
%union.anon = type { %struct.CallInfoC }
%struct.CallInfoC = type { i32 (%struct.lua_State*, i32, i64)*, i64, i64 }
%struct.lua_Debug = type opaque
@.str = private unnamed_addr constant [12 x i8] c"value = %d\0A\00", align 1
@.str1 = private unnamed_addr constant [29 x i8] c"'for' limit must be a number\00", align 1
@.str2 = private unnamed_addr constant [28 x i8] c"'for' step must be a number\00", align 1
@.str3 = private unnamed_addr constant [37 x i8] c"'for' initial value must be a number\00", align 1
; Function Attrs: nounwind
define void @testfunc(%struct.GCObject* nocapture readonly %obj) #0 {
entry:
%tt = getelementptr inbounds %struct.GCObject* %obj, i32 0, i32 1
%0 = load i8* %tt, align 1, !tbaa !1
%conv = zext i8 %0 to i32
%call = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([12 x i8]* @.str, i32 0, i32 0), i32 %conv) #2
ret void
}
; Function Attrs: nounwind
declare i32 @printf(i8* nocapture readonly, ...) #0
; Function Attrs: nounwind
define void @test1(%struct.lua_State* %L) #0 {
entry:
%ilimit = alloca i64, align 8
%stopnow = alloca i32, align 4
%ninit = alloca double, align 8
%nlimit = alloca double, align 8
%nstep = alloca double, align 8
%ci1 = getelementptr inbounds %struct.lua_State* %L, i32 0, i32 6
%0 = load %struct.CallInfoLua** %ci1, align 4, !tbaa !6
%base2 = getelementptr inbounds %struct.CallInfoLua* %0, i32 0, i32 4, i32 0
%1 = load %struct.TValue** %base2, align 4, !tbaa !12
%add.ptr = getelementptr inbounds %struct.TValue* %1, i32 1
%add.ptr5 = getelementptr inbounds %struct.TValue* %1, i32 2
%add.ptr6 = getelementptr inbounds %struct.TValue* %1, i32 3
%tt_ = getelementptr inbounds %struct.TValue* %1, i32 1, i32 1
%2 = load i32* %tt_, align 4, !tbaa !15
%cmp = icmp eq i32 %2, 19
%tt_7 = getelementptr inbounds %struct.TValue* %1, i32 3, i32 1
%3 = load i32* %tt_7, align 4, !tbaa !15
%cmp8 = icmp eq i32 %3, 19
%i = getelementptr inbounds %struct.TValue* %add.ptr6, i32 0, i32 0, i32 0
%4 = load i64* %i, align 8, !tbaa !17
%call = call i32 @forlimit(%struct.TValue* %add.ptr5, i64* %ilimit, i64 %4, i32* %stopnow) #2
%or.cond = and i1 %cmp, %cmp8
%tobool13 = icmp ne i32 %call, 0
%or.cond73 = and i1 %or.cond, %tobool13
br i1 %or.cond73, label %if.then, label %if.else
if.then: ; preds = %entry
%5 = load i32* %stopnow, align 4, !tbaa !18
%tobool14 = icmp eq i32 %5, 0
%i16 = getelementptr inbounds %struct.TValue* %add.ptr, i32 0, i32 0, i32 0
br i1 %tobool14, label %cond.false, label %cond.end
cond.false: ; preds = %if.then
%6 = load i64* %i16, align 8, !tbaa !17
br label %cond.end
cond.end: ; preds = %if.then, %cond.false
%cond = phi i64 [ %6, %cond.false ], [ 0, %if.then ]
%7 = load i64* %ilimit, align 8, !tbaa !17
%i18 = getelementptr inbounds %struct.TValue* %add.ptr5, i32 0, i32 0, i32 0
store i64 %7, i64* %i18, align 8, !tbaa !17
%tt_19 = getelementptr inbounds %struct.TValue* %1, i32 2, i32 1
store i32 19, i32* %tt_19, align 4, !tbaa !15
%8 = load i64* %i, align 8, !tbaa !17
%sub = sub nsw i64 %cond, %8
store i64 %sub, i64* %i16, align 8, !tbaa !17
br label %label_forloop
if.else: ; preds = %entry
%tt_25 = getelementptr inbounds %struct.TValue* %1, i32 2, i32 1
%9 = load i32* %tt_25, align 4, !tbaa !15
%cmp26 = icmp eq i32 %9, 3
br i1 %cmp26, label %if.then28, label %if.else30
if.then28: ; preds = %if.else
%n = bitcast %struct.TValue* %add.ptr5 to double*
%10 = load double* %n, align 8, !tbaa !19
store double %10, double* %nlimit, align 8, !tbaa !19
br label %if.end35
if.else30: ; preds = %if.else
%call31 = call i32 @luaV_tonumber_(%struct.TValue* %add.ptr5, double* %nlimit) #2
%phitmp = icmp eq i32 %call31, 0
br i1 %phitmp, label %if.then33, label %if.end35
if.then33: ; preds = %if.else30
%call34 = call i32 bitcast (i32 (...)* @luaG_runerror to i32 (%struct.lua_State*, i8*)*)(%struct.lua_State* %L, i8* getelementptr inbounds ([29 x i8]* @.str1, i32 0, i32 0)) #2
br label %if.end35
if.end35: ; preds = %if.else30, %if.then28, %if.then33
%11 = load double* %nlimit, align 8, !tbaa !19
%n37 = bitcast %struct.TValue* %add.ptr5 to double*
store double %11, double* %n37, align 8, !tbaa !19
store i32 3, i32* %tt_25, align 4, !tbaa !15
%12 = load i32* %tt_7, align 4, !tbaa !15
%cmp40 = icmp eq i32 %12, 3
br i1 %cmp40, label %if.then42, label %if.else45
if.then42: ; preds = %if.end35
%n44 = bitcast %struct.TValue* %add.ptr6 to double*
%13 = load double* %n44, align 8, !tbaa !19
store double %13, double* %nstep, align 8, !tbaa !19
br label %if.end51
if.else45: ; preds = %if.end35
%call46 = call i32 @luaV_tonumber_(%struct.TValue* %add.ptr6, double* %nstep) #2
%phitmp104 = icmp eq i32 %call46, 0
br i1 %phitmp104, label %if.then49, label %if.end51
if.then49: ; preds = %if.else45
%call50 = call i32 bitcast (i32 (...)* @luaG_runerror to i32 (%struct.lua_State*, i8*)*)(%struct.lua_State* %L, i8* getelementptr inbounds ([28 x i8]* @.str2, i32 0, i32 0)) #2
br label %if.end51
if.end51: ; preds = %if.else45, %if.then42, %if.then49
%14 = load double* %nstep, align 8, !tbaa !19
%n53 = bitcast %struct.TValue* %add.ptr6 to double*
store double %14, double* %n53, align 8, !tbaa !19
store i32 3, i32* %tt_7, align 4, !tbaa !15
%15 = load i32* %tt_, align 4, !tbaa !15
%cmp56 = icmp eq i32 %15, 3
br i1 %cmp56, label %if.then58, label %if.else61
if.then58: ; preds = %if.end51
%n60 = bitcast %struct.TValue* %add.ptr to double*
%16 = load double* %n60, align 8, !tbaa !19
store double %16, double* %ninit, align 8, !tbaa !19
br label %if.end67
if.else61: ; preds = %if.end51
%call62 = call i32 @luaV_tonumber_(%struct.TValue* %add.ptr, double* %ninit) #2
%phitmp105 = icmp eq i32 %call62, 0
br i1 %phitmp105, label %if.then65, label %if.end67
if.then65: ; preds = %if.else61
%call66 = call i32 bitcast (i32 (...)* @luaG_runerror to i32 (%struct.lua_State*, i8*)*)(%struct.lua_State* %L, i8* getelementptr inbounds ([37 x i8]* @.str3, i32 0, i32 0)) #2
br label %if.end67
if.end67: ; preds = %if.else61, %if.then58, %if.then65
%17 = load double* %ninit, align 8, !tbaa !19
%18 = load double* %nstep, align 8, !tbaa !19
%sub68 = fsub double %17, %18
%n70 = bitcast %struct.TValue* %add.ptr to double*
store double %sub68, double* %n70, align 8, !tbaa !19
br label %label_forloop
label_forloop: ; preds = %cond.end, %if.end67
%storemerge = phi i32 [ 3, %if.end67 ], [ 19, %cond.end ]
store i32 %storemerge, i32* %tt_, align 4, !tbaa !15
ret void
}
declare i32 @forlimit(%struct.TValue*, i64*, i64, i32*) #1
declare i32 @luaV_tonumber_(%struct.TValue*, double*) #1
declare i32 @luaG_runerror(...) #1
attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #2 = { nounwind }
!llvm.ident = !{!0}
!0 = metadata !{metadata !"clang version 3.6.0 (trunk)"}
!1 = metadata !{metadata !2, metadata !4, i64 4}
!2 = metadata !{metadata !"GCObject", metadata !3, i64 0, metadata !4, i64 4, metadata !4, i64 5}
!3 = metadata !{metadata !"any pointer", metadata !4, i64 0}
!4 = metadata !{metadata !"omnipotent char", metadata !5, i64 0}
!5 = metadata !{metadata !"Simple C/C++ TBAA"}
!6 = metadata !{metadata !7, metadata !3, i64 16}
!7 = metadata !{metadata !"lua_State", metadata !3, i64 0, metadata !4, i64 4, metadata !4, i64 5, metadata !4, i64 6, metadata !3, i64 8, metadata !3, i64 12, metadata !3, i64 16, metadata !3, i64 20, metadata !3, i64 24, metadata !3, i64 28, metadata !3, i64 32, metadata !3, i64 36, metadata !3, i64 40, metadata !3, i64 44, metadata !8, i64 48, metadata !3, i64 104, metadata !9, i64 112, metadata !11, i64 120, metadata !11, i64 124, metadata !11, i64 128, metadata !10, i64 132, metadata !10, i64 134, metadata !4, i64 136, metadata !4, i64 137}
!8 = metadata !{metadata !"CallInfo", metadata !3, i64 0, metadata !3, i64 4, metadata !3, i64 8, metadata !3, i64 12, metadata !4, i64 16, metadata !9, i64 40, metadata !10, i64 48, metadata !4, i64 50, metadata !4, i64 51}
!9 = metadata !{metadata !"long long", metadata !4, i64 0}
!10 = metadata !{metadata !"short", metadata !4, i64 0}
!11 = metadata !{metadata !"int", metadata !4, i64 0}
!12 = metadata !{metadata !13, metadata !3, i64 16}
!13 = metadata !{metadata !"CallInfoLua", metadata !3, i64 0, metadata !3, i64 4, metadata !3, i64 8, metadata !3, i64 12, metadata !14, i64 16, metadata !9, i64 32, metadata !10, i64 40, metadata !4, i64 42, metadata !4, i64 43}
!14 = metadata !{metadata !"CallInfoL", metadata !3, i64 0, metadata !3, i64 4, metadata !9, i64 8}
!15 = metadata !{metadata !16, metadata !11, i64 8}
!16 = metadata !{metadata !"TValue", metadata !4, i64 0, metadata !11, i64 8}
!17 = metadata !{metadata !9, metadata !9, i64 0}
!18 = metadata !{metadata !11, metadata !11, i64 0}
!19 = metadata !{metadata !20, metadata !20, i64 0}
!20 = metadata !{metadata !"double", metadata !4, i64 0}

@ -0,0 +1,123 @@
; ModuleID = 'lua_op_loadk_return.c'
target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-S32"
target triple = "i686-pc-windows-gnu"
%struct.GCObject = type { %struct.GCObject*, i8, i8 }
%struct.lua_State = type { %struct.GCObject*, i8, i8, i8, %struct.TValue*, %struct.global_State*, %struct.CallInfoLua*, i32*, %struct.TValue*, %struct.TValue*, %struct.UpVal*, %struct.GCObject*, %struct.lua_State*, %struct.lua_longjmp*, %struct.CallInfo, void (%struct.lua_State*, %struct.lua_Debug*)*, i64, i32, i32, i32, i16, i16, i8, i8 }
%struct.global_State = type opaque
%struct.CallInfoLua = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %struct.CallInfoL, i64, i16, i8, i8 }
%struct.CallInfoL = type { %struct.TValue*, i32*, i64 }
%struct.TValue = type { %union.Value, i32 }
%union.Value = type { i64 }
%struct.UpVal = type { %struct.TValue*, i64, %union.anon.0 }
%union.anon.0 = type { %struct.TValue }
%struct.lua_longjmp = type opaque
%struct.CallInfo = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %union.anon, i64, i16, i8, i8 }
%union.anon = type { %struct.CallInfoC }
%struct.CallInfoC = type { i32 (%struct.lua_State*, i32, i64)*, i64, i64 }
%struct.lua_Debug = type opaque
%struct.LClosure = type { %struct.GCObject*, i8, i8, i8, %struct.GCObject*, %struct.Proto*, [1 x %struct.UpVal*] }
%struct.Proto = type { %struct.GCObject*, i8, i8, i8, i8, i8, i32, i32, i32, i32, i32, i32, i32, i32, %struct.TValue*, i32*, %struct.Proto**, i32*, %struct.LocVar*, %struct.Upvaldesc*, %struct.LClosure*, %struct.TString*, %struct.GCObject*, %struct.RaviJITProto }
%struct.LocVar = type { %struct.TString*, i32, i32, i32 }
%struct.Upvaldesc = type { %struct.TString*, i32, i8, i8 }
%struct.TString = type { %struct.GCObject*, i8, i8, i8, i8, i32, %union.anon.1 }
%union.anon.1 = type { i64 }
%struct.RaviJITProto = type { i8, i8*, i32 (%struct.lua_State*)* }
@.str = private unnamed_addr constant [12 x i8] c"value = %d\0A\00", align 1
; Function Attrs: nounwind
define void @testfunc(%struct.GCObject* %obj) #0 {
entry:
%obj.addr = alloca %struct.GCObject*, align 4
store %struct.GCObject* %obj, %struct.GCObject** %obj.addr, align 4, !tbaa !1
%0 = load %struct.GCObject*, %struct.GCObject** %obj.addr, align 4, !tbaa !1
%tt = getelementptr inbounds %struct.GCObject, %struct.GCObject* %0, i32 0, i32 1
%1 = load i8, i8* %tt, align 1, !tbaa !5
%conv = zext i8 %1 to i32
%call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), i32 %conv)
ret void
}
declare i32 @printf(i8*, ...) #1
; Function Attrs: nounwind
define void @test1(%struct.lua_State* %L, i32 %b, i32 %x) #0 {
entry:
%L.addr = alloca %struct.lua_State*, align 4
%b.addr = alloca i32, align 4
%x.addr = alloca i32, align 4
%ci = alloca %struct.CallInfoLua*, align 4
%cl = alloca %struct.LClosure*, align 4
%k = alloca %struct.TValue*, align 4
%base = alloca %struct.TValue*, align 4
%cil = alloca %struct.CallInfoL*, align 4
store %struct.lua_State* %L, %struct.lua_State** %L.addr, align 4, !tbaa !1
store i32 %b, i32* %b.addr, align 4, !tbaa !7
store i32 %x, i32* %x.addr, align 4, !tbaa !7
%0 = bitcast %struct.CallInfoLua** %ci to i8*
call void @llvm.lifetime.start(i64 4, i8* %0) #2
%1 = bitcast %struct.LClosure** %cl to i8*
call void @llvm.lifetime.start(i64 4, i8* %1) #2
%2 = bitcast %struct.TValue** %k to i8*
call void @llvm.lifetime.start(i64 4, i8* %2) #2
%3 = bitcast %struct.TValue** %base to i8*
call void @llvm.lifetime.start(i64 4, i8* %3) #2
%4 = bitcast %struct.CallInfoL** %cil to i8*
call void @llvm.lifetime.start(i64 4, i8* %4) #2
%5 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
%ci1 = getelementptr inbounds %struct.lua_State, %struct.lua_State* %5, i32 0, i32 6
%6 = load %struct.CallInfoLua*, %struct.CallInfoLua** %ci1, align 4, !tbaa !9
store %struct.CallInfoLua* %6, %struct.CallInfoLua** %ci, align 4, !tbaa !1
%7 = load %struct.CallInfoLua*, %struct.CallInfoLua** %ci, align 4, !tbaa !1
%l = getelementptr inbounds %struct.CallInfoLua, %struct.CallInfoLua* %7, i32 0, i32 4
%base2 = getelementptr inbounds %struct.CallInfoL, %struct.CallInfoL* %l, i32 0, i32 0
%8 = load %struct.TValue*, %struct.TValue** %base2, align 4, !tbaa !14
store %struct.TValue* %8, %struct.TValue** %base, align 4, !tbaa !1
%9 = load %struct.CallInfoLua*, %struct.CallInfoLua** %ci, align 4, !tbaa !1
%l3 = getelementptr inbounds %struct.CallInfoLua, %struct.CallInfoLua* %9, i32 0, i32 4
%savedpc = getelementptr inbounds %struct.CallInfoL, %struct.CallInfoL* %l3, i32 0, i32 1
store i32* %x.addr, i32** %savedpc, align 4, !tbaa !17
%10 = bitcast %struct.CallInfoL** %cil to i8*
call void @llvm.lifetime.end(i64 4, i8* %10) #2
%11 = bitcast %struct.TValue** %base to i8*
call void @llvm.lifetime.end(i64 4, i8* %11) #2
%12 = bitcast %struct.TValue** %k to i8*
call void @llvm.lifetime.end(i64 4, i8* %12) #2
%13 = bitcast %struct.LClosure** %cl to i8*
call void @llvm.lifetime.end(i64 4, i8* %13) #2
%14 = bitcast %struct.CallInfoLua** %ci to i8*
call void @llvm.lifetime.end(i64 4, i8* %14) #2
ret void
}
; Function Attrs: nounwind
declare void @llvm.lifetime.start(i64, i8* nocapture) #2
; Function Attrs: nounwind
declare void @llvm.lifetime.end(i64, i8* nocapture) #2
attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #2 = { nounwind }
!llvm.ident = !{!0}
!0 = !{!"clang version 3.7.0 (trunk)"}
!1 = !{!2, !2, i64 0}
!2 = !{!"any pointer", !3, i64 0}
!3 = !{!"omnipotent char", !4, i64 0}
!4 = !{!"Simple C/C++ TBAA"}
!5 = !{!6, !3, i64 4}
!6 = !{!"GCObject", !2, i64 0, !3, i64 4, !3, i64 5}
!7 = !{!8, !8, i64 0}
!8 = !{!"int", !3, i64 0}
!9 = !{!10, !2, i64 16}
!10 = !{!"lua_State", !2, i64 0, !3, i64 4, !3, i64 5, !3, i64 6, !2, i64 8, !2, i64 12, !2, i64 16, !2, i64 20, !2, i64 24, !2, i64 28, !2, i64 32, !2, i64 36, !2, i64 40, !2, i64 44, !11, i64 48, !2, i64 104, !12, i64 112, !8, i64 120, !8, i64 124, !8, i64 128, !13, i64 132, !13, i64 134, !3, i64 136, !3, i64 137}
!11 = !{!"CallInfo", !2, i64 0, !2, i64 4, !2, i64 8, !2, i64 12, !3, i64 16, !12, i64 40, !13, i64 48, !3, i64 50, !3, i64 51}
!12 = !{!"long long", !3, i64 0}
!13 = !{!"short", !3, i64 0}
!14 = !{!15, !2, i64 16}
!15 = !{!"CallInfoLua", !2, i64 0, !2, i64 4, !2, i64 8, !2, i64 12, !16, i64 16, !12, i64 32, !13, i64 40, !3, i64 42, !3, i64 43}
!16 = !{!"CallInfoL", !2, i64 0, !2, i64 4, !12, i64 8}
!17 = !{!15, !2, i64 20}

@ -0,0 +1,145 @@
; ModuleID = 'lua_savedpc.c'
target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-S32"
target triple = "i686-pc-windows-gnu"
%struct.lua_State = type { %struct.GCObject*, i8, i8, i8, %struct.TValue*, %struct.global_State*, %struct.CallInfoLua*, i32*, %struct.TValue*, %struct.TValue*, %struct.UpVal*, %struct.GCObject*, %struct.lua_State*, %struct.lua_longjmp*, %struct.CallInfo, void (%struct.lua_State*, %struct.lua_Debug*)*, i64, i32, i32, i32, i16, i16, i8, i8 }
%struct.global_State = type opaque
%struct.CallInfoLua = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %struct.CallInfoL, i64, i16, i8, i8 }
%struct.CallInfoL = type { %struct.TValue*, i32*, i64 }
%struct.TValue = type { %union.Value, i32 }
%union.Value = type { i64 }
%struct.UpVal = type { %struct.TValue*, i64, %union.anon.0 }
%union.anon.0 = type { %struct.TValue }
%struct.GCObject = type { %struct.GCObject*, i8, i8 }
%struct.lua_longjmp = type opaque
%struct.CallInfo = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %union.anon, i64, i16, i8, i8 }
%union.anon = type { %struct.CallInfoC }
%struct.CallInfoC = type { i32 (%struct.lua_State*, i32, i64)*, i64, i64 }
%struct.lua_Debug = type opaque
%struct.LClosure = type { %struct.GCObject*, i8, i8, i8, %struct.GCObject*, %struct.Proto*, [1 x %struct.UpVal*] }
%struct.Proto = type { %struct.GCObject*, i8, i8, i8, i8, i8, i32, i32, i32, i32, i32, i32, i32, i32, %struct.TValue*, i32*, %struct.Proto**, i32*, %struct.LocVar*, %struct.Upvaldesc*, %struct.LClosure*, %struct.TString*, %struct.GCObject*, %struct.RaviJITProto }
%struct.LocVar = type { %struct.TString*, i32, i32, i32 }
%struct.Upvaldesc = type { %struct.TString*, i32, i8, i8 }
%struct.TString = type { %struct.GCObject*, i8, i8, i8, i8, i32, %union.anon.1 }
%union.anon.1 = type { i64 }
%struct.RaviJITProto = type { i8, i8*, i32 (%struct.lua_State*)* }
; Function Attrs: nounwind
define void @test1(%struct.lua_State* %L, i32 %b) #0 {
entry:
%L.addr = alloca %struct.lua_State*, align 4
%b.addr = alloca i32, align 4
%ci = alloca %struct.CallInfoLua*, align 4
%cl = alloca %struct.LClosure*, align 4
%p = alloca %struct.Proto*, align 4
store %struct.lua_State* %L, %struct.lua_State** %L.addr, align 4, !tbaa !1
store i32 %b, i32* %b.addr, align 4, !tbaa !5
%0 = bitcast %struct.CallInfoLua** %ci to i8*
call void @llvm.lifetime.start(i64 4, i8* %0) #1
%1 = bitcast %struct.LClosure** %cl to i8*
call void @llvm.lifetime.start(i64 4, i8* %1) #1
%2 = bitcast %struct.Proto** %p to i8*
call void @llvm.lifetime.start(i64 4, i8* %2) #1
%3 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
%ci1 = getelementptr inbounds %struct.lua_State, %struct.lua_State* %3, i32 0, i32 6
%4 = load %struct.CallInfoLua*, %struct.CallInfoLua** %ci1, align 4, !tbaa !7
store %struct.CallInfoLua* %4, %struct.CallInfoLua** %ci, align 4, !tbaa !1
%5 = load %struct.CallInfoLua*, %struct.CallInfoLua** %ci, align 4, !tbaa !1
%func = getelementptr inbounds %struct.CallInfoLua, %struct.CallInfoLua* %5, i32 0, i32 0
%6 = load %struct.TValue*, %struct.TValue** %func, align 4, !tbaa !12
%value_ = getelementptr inbounds %struct.TValue, %struct.TValue* %6, i32 0, i32 0
%gc = bitcast %union.Value* %value_ to %struct.GCObject**
%7 = load %struct.GCObject*, %struct.GCObject** %gc, align 4, !tbaa !1
%8 = bitcast %struct.GCObject* %7 to %struct.LClosure*
store %struct.LClosure* %8, %struct.LClosure** %cl, align 4, !tbaa !1
%9 = load %struct.LClosure*, %struct.LClosure** %cl, align 4, !tbaa !1
%p2 = getelementptr inbounds %struct.LClosure, %struct.LClosure* %9, i32 0, i32 5
%10 = load %struct.Proto*, %struct.Proto** %p2, align 4, !tbaa !15
store %struct.Proto* %10, %struct.Proto** %p, align 4, !tbaa !1
%11 = load i32, i32* %b.addr, align 4, !tbaa !5
%12 = load %struct.Proto*, %struct.Proto** %p, align 4, !tbaa !1
%code = getelementptr inbounds %struct.Proto, %struct.Proto* %12, i32 0, i32 15
%13 = load i32*, i32** %code, align 4, !tbaa !17
%arrayidx = getelementptr inbounds i32, i32* %13, i32 %11
%14 = load %struct.CallInfoLua*, %struct.CallInfoLua** %ci, align 4, !tbaa !1
%l = getelementptr inbounds %struct.CallInfoLua, %struct.CallInfoLua* %14, i32 0, i32 4
%savedpc = getelementptr inbounds %struct.CallInfoL, %struct.CallInfoL* %l, i32 0, i32 1
store i32* %arrayidx, i32** %savedpc, align 4, !tbaa !20
%15 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
%hookmask = getelementptr inbounds %struct.lua_State, %struct.lua_State* %15, i32 0, i32 22
%16 = load i8, i8* %hookmask, align 1, !tbaa !21
%conv = zext i8 %16 to i32
%and = and i32 %conv, 12
%tobool = icmp ne i32 %and, 0
br i1 %tobool, label %land.lhs.true, label %if.end
land.lhs.true: ; preds = %entry
%17 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
%hookcount = getelementptr inbounds %struct.lua_State, %struct.lua_State* %17, i32 0, i32 19
%18 = load i32, i32* %hookcount, align 4, !tbaa !22
%dec = add nsw i32 %18, -1
store i32 %dec, i32* %hookcount, align 4, !tbaa !22
%cmp = icmp eq i32 %dec, 0
br i1 %cmp, label %if.then, label %lor.lhs.false
lor.lhs.false: ; preds = %land.lhs.true
%19 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
%hookmask4 = getelementptr inbounds %struct.lua_State, %struct.lua_State* %19, i32 0, i32 22
%20 = load i8, i8* %hookmask4, align 1, !tbaa !21
%conv5 = zext i8 %20 to i32
%and6 = and i32 %conv5, 4
%tobool7 = icmp ne i32 %and6, 0
br i1 %tobool7, label %if.then, label %if.end
if.then: ; preds = %lor.lhs.false, %land.lhs.true
%21 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
call void @luaG_traceexec(%struct.lua_State* %21)
br label %if.end
if.end: ; preds = %if.then, %lor.lhs.false, %entry
%22 = bitcast %struct.Proto** %p to i8*
call void @llvm.lifetime.end(i64 4, i8* %22) #1
%23 = bitcast %struct.LClosure** %cl to i8*
call void @llvm.lifetime.end(i64 4, i8* %23) #1
%24 = bitcast %struct.CallInfoLua** %ci to i8*
call void @llvm.lifetime.end(i64 4, i8* %24) #1
ret void
}
; Function Attrs: nounwind
declare void @llvm.lifetime.start(i64, i8* nocapture) #1
declare void @luaG_traceexec(%struct.lua_State*) #2
; Function Attrs: nounwind
declare void @llvm.lifetime.end(i64, i8* nocapture) #1
attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { nounwind }
attributes #2 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
!llvm.ident = !{!0}
!0 = !{!"clang version 3.7.0 (trunk)"}
!1 = !{!2, !2, i64 0}
!2 = !{!"any pointer", !3, i64 0}
!3 = !{!"omnipotent char", !4, i64 0}
!4 = !{!"Simple C/C++ TBAA"}
!5 = !{!6, !6, i64 0}
!6 = !{!"int", !3, i64 0}
!7 = !{!8, !2, i64 16}
!8 = !{!"lua_State", !2, i64 0, !3, i64 4, !3, i64 5, !3, i64 6, !2, i64 8, !2, i64 12, !2, i64 16, !2, i64 20, !2, i64 24, !2, i64 28, !2, i64 32, !2, i64 36, !2, i64 40, !2, i64 44, !9, i64 48, !2, i64 104, !10, i64 112, !6, i64 120, !6, i64 124, !6, i64 128, !11, i64 132, !11, i64 134, !3, i64 136, !3, i64 137}
!9 = !{!"CallInfo", !2, i64 0, !2, i64 4, !2, i64 8, !2, i64 12, !3, i64 16, !10, i64 40, !11, i64 48, !3, i64 50, !3, i64 51}
!10 = !{!"long long", !3, i64 0}
!11 = !{!"short", !3, i64 0}
!12 = !{!13, !2, i64 0}
!13 = !{!"CallInfoLua", !2, i64 0, !2, i64 4, !2, i64 8, !2, i64 12, !14, i64 16, !10, i64 32, !11, i64 40, !3, i64 42, !3, i64 43}
!14 = !{!"CallInfoL", !2, i64 0, !2, i64 4, !10, i64 8}
!15 = !{!16, !2, i64 12}
!16 = !{!"LClosure", !2, i64 0, !3, i64 4, !3, i64 5, !3, i64 6, !2, i64 8, !2, i64 12, !3, i64 16}
!17 = !{!18, !2, i64 48}
!18 = !{!"Proto", !2, i64 0, !3, i64 4, !3, i64 5, !3, i64 6, !3, i64 7, !3, i64 8, !6, i64 12, !6, i64 16, !6, i64 20, !6, i64 24, !6, i64 28, !6, i64 32, !6, i64 36, !6, i64 40, !2, i64 44, !2, i64 48, !2, i64 52, !2, i64 56, !2, i64 60, !2, i64 64, !2, i64 68, !2, i64 72, !2, i64 76, !19, i64 80}
!19 = !{!"RaviJITProto", !3, i64 0, !2, i64 4, !2, i64 8}
!20 = !{!13, !2, i64 20}
!21 = !{!8, !3, i64 136}
!22 = !{!8, !6, i64 128}

@ -0,0 +1,14 @@
#include "lua_hdr.h"
extern int printf(const char *, ...);
extern void luaC_upvalbarrier_ (struct lua_State *L, struct GCObject *o, struct GCObject *v);
void luaV_op_call(struct lua_State *L, struct LClosure *cl, struct TValue *ra, int b, int c) {
struct UpVal *uv = cl->upvals[b];
int ra_iscollectable = iscollectable(ra);
int uv_isblack = isblack(uv);
int rav_iswhite = iswhite(gcvalue(ra));
if (ra_iscollectable && uv_isblack && rav_iswhite)
luaC_upvalbarrier_(L,(struct GCObject *)uv, ra->value_.gc);
}

@ -0,0 +1,79 @@
; ModuleID = 'lua_upval.c'
source_filename = "lua_upval.c"
target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-windows-msvc"
%struct.lua_State = type { %struct.GCObject*, i8, i8, i8, %struct.TValue*, %struct.global_State*, %struct.CallInfoLua*, i32*, %struct.TValue*, %struct.TValue*, %struct.UpVal*, %struct.GCObject*, %struct.lua_State*, %struct.lua_longjmp*, %struct.CallInfo, void (%struct.lua_State*, %struct.lua_Debug*)*, i64, i32, i32, i32, i16, i16, i8, i8, i16 }
%struct.global_State = type opaque
%struct.CallInfoLua = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %struct.CallInfoL, i64, i16, i8, i8, i16 }
%struct.CallInfoL = type { %struct.TValue*, i32*, i64 }
%struct.UpVal = type { %struct.GCObject*, i8, i8, %struct.TValue*, %union.anon.0 }
%union.anon.0 = type { %struct.anon }
%struct.anon = type { %struct.UpVal*, %struct.UpVal** }
%struct.GCObject = type { %struct.GCObject*, i8, i8 }
%struct.lua_longjmp = type opaque
%struct.CallInfo = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %union.anon, i64, i16, i8, i8 }
%union.anon = type { %struct.CallInfoL }
%struct.lua_Debug = type opaque
%struct.LClosure = type { %struct.GCObject*, i8, i8, i8, %struct.GCObject*, %struct.Proto*, [1 x %struct.UpVal*] }
%struct.Proto = type { %struct.GCObject*, i8, i8, i8, i8, i8, i32, i32, i32, i32, i32, i32, i32, i32, %struct.TValue*, i32*, %struct.Proto**, i32*, %struct.LocVar*, %struct.Upvaldesc*, %struct.LClosure*, %struct.TString*, %struct.GCObject*, i8, %struct.RaviJITProto }
%struct.LocVar = type { %struct.TString*, %struct.TString*, i32, i32, i8 }
%struct.Upvaldesc = type { %struct.TString*, %struct.TString*, i8, i8, i8 }
%struct.TString = type { %struct.GCObject*, i8, i8, i8, i8, i32, %union.anon.1 }
%union.anon.1 = type { i64 }
%struct.RaviJITProto = type { i8, i8*, i32 (%struct.lua_State*)* }
%struct.TValue = type { %union.Value, i8 }
%union.Value = type { %struct.GCObject* }
; Function Attrs: nounwind
define void @luaV_op_call(%struct.lua_State* %L, %struct.LClosure* nocapture readonly %cl, %struct.TValue* nocapture readonly %ra, i32 %b, i32 %c) local_unnamed_addr #0 {
entry:
%idxprom = sext i32 %b to i64
%arrayidx = getelementptr inbounds %struct.LClosure, %struct.LClosure* %cl, i64 0, i32 6, i64 %idxprom
%0 = load %struct.UpVal*, %struct.UpVal** %arrayidx, align 8, !tbaa !1
%tt_ = getelementptr inbounds %struct.TValue, %struct.TValue* %ra, i64 0, i32 1
%1 = load i8, i8* %tt_, align 8, !tbaa !5
%2 = and i8 %1, 64
%marked = getelementptr inbounds %struct.UpVal, %struct.UpVal* %0, i64 0, i32 2
%3 = load i8, i8* %marked, align 1, !tbaa !7
%4 = and i8 %3, 32
%gc = getelementptr inbounds %struct.TValue, %struct.TValue* %ra, i64 0, i32 0, i32 0
%5 = load %struct.GCObject*, %struct.GCObject** %gc, align 8, !tbaa !1
%marked3 = getelementptr inbounds %struct.GCObject, %struct.GCObject* %5, i64 0, i32 2
%6 = load i8, i8* %marked3, align 1, !tbaa !9
%7 = and i8 %6, 24
%tobool = icmp ne i8 %2, 0
%tobool6 = icmp ne i8 %4, 0
%or.cond = and i1 %tobool, %tobool6
%tobool8 = icmp ne i8 %7, 0
%or.cond11 = and i1 %or.cond, %tobool8
br i1 %or.cond11, label %if.then, label %if.end
if.then: ; preds = %entry
%8 = bitcast %struct.UpVal* %0 to %struct.GCObject*
tail call void @luaC_upvalbarrier_(%struct.lua_State* %L, %struct.GCObject* %8, %struct.GCObject* %5) #2
br label %if.end
if.end: ; preds = %if.then, %entry
ret void
}
declare void @luaC_upvalbarrier_(%struct.lua_State*, %struct.GCObject*, %struct.GCObject*) local_unnamed_addr #1
attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-features"="+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-features"="+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #2 = { nounwind }
!llvm.ident = !{!0}
!0 = !{!"clang version 4.0.0 (tags/RELEASE_400/final)"}
!1 = !{!2, !2, i64 0}
!2 = !{!"any pointer", !3, i64 0}
!3 = !{!"omnipotent char", !4, i64 0}
!4 = !{!"Simple C/C++ TBAA"}
!5 = !{!6, !3, i64 8}
!6 = !{!"TValue", !3, i64 0, !3, i64 8}
!7 = !{!8, !3, i64 9}
!8 = !{!"UpVal", !2, i64 0, !3, i64 8, !3, i64 9, !2, i64 16, !3, i64 24}
!9 = !{!10, !3, i64 9}
!10 = !{!"GCObject", !2, i64 0, !3, i64 8, !3, i64 9}

@ -0,0 +1,5 @@
setlocal
set PATH=%PATH%;"c:\Program Files (x86)\LLVM\bin"
rem clang -cc1 -O1 -disable-llvm-optzns -S -emit-llvm %1
clang -cc1 -O2 -S -emit-llvm %1

@ -0,0 +1,37 @@
; ModuleID = 'tab.c'
source_filename = "tab.c"
target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
target triple = "i686-pc-windows-msvc"
%struct.TValue = type { %union.Value, i32 }
%union.Value = type { i64 }
%struct.Table = type { %struct.GCObject*, i8, i8, i8, i8, i32, %struct.TValue*, %struct.Node*, %struct.Node*, %struct.Table*, %struct.GCObject*, %struct.RaviArray, i32 }
%struct.Node = type { %struct.TValue, %union.TKey }
%union.TKey = type { %struct.anon.2 }
%struct.anon.2 = type { %union.Value, i32, i32 }
%struct.GCObject = type { %struct.GCObject*, i8, i8 }
%struct.RaviArray = type { i8*, i32, i32, i32 }
; Function Attrs: norecurse nounwind readonly
define i32 @tablevalue(%struct.TValue* nocapture readonly %v) local_unnamed_addr #0 {
entry:
%0 = bitcast %struct.TValue* %v to %struct.Table**
%1 = load %struct.Table*, %struct.Table** %0, align 8, !tbaa !1
%sizearray = getelementptr inbounds %struct.Table, %struct.Table* %1, i32 0, i32 5
%2 = load i32, i32* %sizearray, align 8, !tbaa !5
ret i32 %2
}
attributes #0 = { norecurse nounwind readonly "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-features"="+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
!llvm.ident = !{!0}
!0 = !{!"clang version 3.9.0 (trunk)"}
!1 = !{!2, !2, i64 0}
!2 = !{!"any pointer", !3, i64 0}
!3 = !{!"omnipotent char", !4, i64 0}
!4 = !{!"Simple C/C++ TBAA"}
!5 = !{!6, !7, i64 8}
!6 = !{!"Table", !2, i64 0, !3, i64 4, !3, i64 5, !3, i64 6, !3, i64 7, !7, i64 8, !2, i64 12, !2, i64 16, !2, i64 20, !2, i64 24, !2, i64 28, !8, i64 32, !7, i64 48}
!7 = !{!"int", !3, i64 0}
!8 = !{!"RaviArray", !2, i64 0, !3, i64 4, !7, i64 8, !7, i64 12}

@ -0,0 +1 @@
Subproject commit 5b42a99121627677952d4cf3445d795be85582de

@ -1,30 +0,0 @@
FROM ubuntu:18.04
RUN set -x \
&& apt-get update \
&& apt-get install -y libreadline-dev \
&& apt-get install -y build-essential \
&& apt-get install -y git wget \
&& apt-get install -y zlib1g-dev \
&& apt-get clean \
&& mkdir -p /Software \
&& wget -O "/Software/cmake-3.14.5-Linux-x86_64.tar.gz" "https://github.com/Kitware/CMake/releases/download/v3.14.5/cmake-3.14.5-Linux-x86_64.tar.gz" \
&& cd /Software \
&& tar xvf "cmake-3.14.5-Linux-x86_64.tar.gz" \
&& rm -rf "/Software/cmake-3.14.5-Linux-x86_64.tar.gz" \
&& mkdir -p /sources \
&& cd /sources \
&& git clone https://github.com/dibyendumajumdar/ravi.git \
&& cd /sources/ravi \
&& mkdir build \
&& cd build \
&& /Software/cmake-3.14.5-Linux-x86_64/bin/cmake -DCMAKE_INSTALL_PREFIX=/Software/ravi -DCMAKE_BUILD_TYPE=Release .. \
&& make install \
&& rm -rf /Software/cmake-3.14.5-Linux-x86_64 \
&& rm -rf /sources \
&& apt-get autoremove \
&& apt-get remove -y --purge git wget build-essential \
&& apt-get clean
ENV PATH /Software/ravi/bin:${PATH}

@ -1,5 +1,5 @@
/*
** $Id: lapi.h,v 2.9.1.1 2017/04/19 17:20:42 roberto Exp $
** $Id: lapi.h,v 2.9 2015/03/06 19:49:50 roberto Exp $
** Auxiliary functions from Lua API
** See Copyright Notice in lua.h
*/

@ -1,5 +1,5 @@
/*
** $Id: lauxlib.h $
** $Id: lauxlib.h,v 1.131 2016/12/06 14:54:31 roberto Exp $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
@ -15,12 +15,6 @@
#include "lua.h"
/* global table */
#define LUA_GNAME "_G"
typedef struct luaL_Buffer luaL_Buffer;
/* extra error code for 'luaL_loadfilex' */
#define LUA_ERRFILE (LUA_ERRERR+1)
@ -54,7 +48,6 @@ LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len);
api function ravi_typename() */
LUALIB_API const char *(raviL_tolstring) (lua_State *L, int idx, size_t *len);
LUALIB_API int (luaL_argerror) (lua_State *L, int arg, const char *extramsg);
LUALIB_API int (luaL_typeerror) (lua_State *L, int arg, const char *tname);
LUALIB_API const char *(luaL_checklstring) (lua_State *L, int arg,
size_t *l);
LUALIB_API const char *(luaL_optlstring) (lua_State *L, int arg,
@ -84,7 +77,6 @@ LUALIB_API int (luaL_checkoption) (lua_State *L, int arg, const char *def,
LUALIB_API int (luaL_fileresult) (lua_State *L, int stat, const char *fname);
LUALIB_API int (luaL_execresult) (lua_State *L, int stat);
/* predefined references */
#define LUA_NOREF (-2)
#define LUA_REFNIL (-1)
@ -105,10 +97,8 @@ LUALIB_API lua_State *(luaL_newstate) (void);
LUALIB_API lua_Integer (luaL_len) (lua_State *L, int idx);
LUALIB_API void luaL_addgsub (luaL_Buffer *b, const char *s,
const char *p, const char *r);
LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s,
const char *p, const char *r);
LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p,
const char *r);
LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup);
@ -135,10 +125,6 @@ LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname,
#define luaL_argcheck(L, cond,arg,extramsg) \
((void)((cond) || luaL_argerror(L, (arg), (extramsg))))
#define luaL_argexpected(L,cond,arg,tname) \
((void)((cond) || luaL_typeerror(L, (arg), (tname))))
#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL))
#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL))
@ -157,10 +143,6 @@ LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname,
#define luaL_loadbuffer(L,s,sz,n) luaL_loadbufferx(L,s,sz,n,NULL)
/* push the value used to represent failure/error */
#define luaL_pushfail(L) lua_pushnil(L)
/*
** {======================================================
** Generic Buffer manipulation
@ -289,12 +271,44 @@ LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname,
#endif
/* }============================================================ */
/*
The normal Lua metatable functions in C use string
keys - these are expensive as the key needs to be
converted to Lua string, hash code computed etc.
Following implementations are taken from a post in
Lua mailing list (http://lua-users.org/lists/lua-l/2010-11/msg00151.html)
meta_key is the key assigned to the meta table of the userdata
IMPORTANT: Caller must ensure that supplied meta_key points to somewhere in
static storage as otherwise memory fault will occur.
*/
LUALIB_API int (luaL_newmetatable)(lua_State *L, const char *tname);
LUALIB_API void (luaL_setmetatable)(lua_State *L, const char *tname);
LUALIB_API void *(luaL_testudata)(lua_State *L, int ud, const char *tname);
LUALIB_API void *(luaL_checkudata)(lua_State *L, int ud, const char *tname);
#if 0
LUALIB_API int raviL_newmetatable(lua_State *L, const void *meta_key,
const char *tname);
/* meta_key is the key assigned to the meta table of the userdata */
LUALIB_API void raviL_getmetatable(lua_State *L, const void *meta_key);
/*
arg_index is the position of userdata argument on the stack
meta_key is the key assigned to the meta table of the userdata
*/
LUALIB_API void *raviL_testudata(lua_State *L, int arg_index, const void *meta_key);
LUALIB_API void *ravi_alloc_f(void *msp, void *ptr, size_t osize, size_t nsize);
/*
arg_index is the position of userdata argument on the stack
meta_key is the key assigned to the meta table of the userdata
*/
LUALIB_API void *raviL_checkudata(lua_State *L, int arg_index, const void *meta_key);
#else
#define raviL_newmetatable(L, meta_key, tname) luaL_newmetatable(L, meta_key)
#define raviL_getmetatable(L, meta_key) luaL_getmetatable(L, meta_key)
#define raviL_testudata(L, arg_index, meta_key) luaL_testudata(L, arg_index, meta_key)
#define raviL_checkudata(L, arg_index, meta_key) luaL_checkudata(L, arg_index, meta_key)
#endif
#endif

@ -1,5 +1,5 @@
/*
** $Id: lcode.h,v 1.64.1.1 2017/04/19 17:20:42 roberto Exp $
** $Id: lcode.h,v 1.64 2016/01/05 16:22:37 roberto Exp $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
@ -38,8 +38,7 @@ typedef enum BinOpr {
/** RAVI change */
typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_TO_INTEGER,
OPR_TO_NUMBER, OPR_TO_INTARRAY, OPR_TO_NUMARRAY, OPR_TO_TABLE, OPR_TO_STRING,
OPR_TO_CLOSURE, OPR_TO_TYPE, OPR_NOUNOPR } UnOpr;
OPR_TO_NUMBER, OPR_TO_INTARRAY, OPR_TO_NUMARRAY, OPR_TO_TABLE, OPR_TO_STRING, OPR_TO_CLOSURE, OPR_TO_TYPE, OPR_NOUNOPR } UnOpr;
/* get (pointer to) instruction of given 'expdesc' */
#define getinstruction(fs,e) ((fs)->f->code[(e)->u.info])

@ -1,5 +1,5 @@
/*
** $Id: lctype.h,v 1.12.1.1 2013/04/12 18:48:47 roberto Exp $
** $Id: lctype.h,v 1.12 2011/07/15 12:50:29 roberto Exp $
** 'ctype' functions for Lua
** See Copyright Notice in lua.h
*/

@ -1,5 +1,5 @@
/*
** $Id: ldebug.h,v 2.14.1.1 2017/04/19 17:20:42 roberto Exp $
** $Id: ldebug.h,v 2.14 2015/05/22 17:45:56 roberto Exp $
** Auxiliary functions from Debug Interface module
** See Copyright Notice in lua.h
*/

@ -1,5 +1,5 @@
/*
** $Id: ldo.h,v 2.29.1.1 2017/04/19 17:20:42 roberto Exp $
** $Id: ldo.h,v 2.29 2015/12/21 13:02:14 roberto Exp $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@ -54,7 +54,6 @@ LUAI_FUNC void luaD_inctop (lua_State *L);
LUAI_FUNC l_noret luaD_throw (lua_State *L, int errcode);
LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud);
LUAI_FUNC void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop);
#endif

@ -1,5 +1,5 @@
/*
** $Id: lfunc.h,v 2.15.1.1 2017/04/19 17:39:34 roberto Exp $
** $Id: lfunc.h,v 2.15 2015/01/13 15:49:11 roberto Exp $
** Auxiliary functions to manipulate prototypes and closures
** See Copyright Notice in lua.h
*/
@ -29,29 +29,30 @@
#define MAXUPVAL 125
/* RAVI change; #define MAXUPVAL 255 */
#define upisopen(up) ((up)->v != &(up)->u.value)
#define uplevel(up) check_exp(upisopen(up), cast(StkId, (up)->v))
/*
** Special "status" for 'luaF_close'
** maximum number of misses before giving up the cache of closures
** in prototypes
*/
#define MAXMISS 10
/* close upvalues without running their closing methods */
#define NOCLOSINGMETH (-1)
/* close upvalues running all closing methods in protected mode */
#define CLOSEPROTECT (-2)
LUAI_FUNC Proto *luaF_newproto (lua_State *L);
LUAI_FUNC CClosure *luaF_newCclosure (lua_State *L, int nelems);
LUAI_FUNC LClosure *luaF_newLclosure (lua_State *L, int nelems);
LUAI_FUNC void luaF_initupvals (lua_State *L, LClosure *cl);
LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level);
LUAI_FUNC int luaF_close (lua_State *L, StkId level, int status);
LUAI_FUNC void luaF_close (lua_State *L, StkId level);
LUAI_FUNC void luaF_unlinkupval (UpVal *uv);
LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f);
/* The additional type argument is a Ravi extension */
LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number,
int pc, ravi_type_map* type, TString **usertype);
int pc, ravitype_t* type);
#endif

@ -1,5 +1,5 @@
/*
** $Id: lgc.h $
** $Id: lgc.h,v 2.91 2015/12/21 13:02:14 roberto Exp $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@ -12,16 +12,16 @@
#include "lstate.h"
/*
** Collectable objects may have one of three colors: white, which means
** the object is not marked; gray, which means the object is marked, but
** its references may be not marked; and black, which means that the
** object and all its references are marked. The main invariant of the
** garbage collector, while marking objects, is that a black object can
** never point to a white one. Moreover, any gray object must be in a
** "gray list" (gray, grayagain, weak, allweak, ephemeron) so that it
** can be visited again before finishing the collection cycle. (Open
** upvalues are an exception to this rule.) These lists have no meaning
** when the invariant is not being enforced (e.g., sweep phase).
** Collectable objects may have one of three colors: white, which
** means the object is not marked; gray, which means the
** object is marked, but its references may be not marked; and
** black, which means that the object and all its references are marked.
** The main invariant of the garbage collector, while marking objects,
** is that a black object can never point to a white one. Moreover,
** any gray object must be in a "gray list" (gray, grayagain, weak,
** allweak, ephemeron) so that it can be visited again before finishing
** the collection cycle. These lists have no meaning when the invariant
** is not being enforced (e.g., sweep phase).
*/
@ -57,7 +57,7 @@
/*
** some useful bit tricks
*/
#define resetbits(x,m) ((x) &= cast_byte(~(m)))
#define resetbits(x,m) ((x) &= cast(lu_byte, ~(m)))
#define setbits(x,m) ((x) |= (m))
#define testbits(x,m) ((x) & (m))
#define bitmask(b) (1<<(b))
@ -69,16 +69,13 @@
/*
** Layout for bit use in 'marked' field. First three bits are
** used for object "age" in generational mode. Last bit is used
** by tests.
** used for object "age" in generational mode.
*/
#define WHITE0BIT 3 /* object is white (type 0) */
#define WHITE1BIT 4 /* object is white (type 1) */
#define BLACKBIT 5 /* object is black */
#define FINALIZEDBIT 6 /* object has been marked for finalization */
#define TESTBIT 7
#define TESTGRAYBIT 7 /* used by tests (luaL_checkmemory) */
#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT)
@ -96,10 +93,9 @@
#define isdead(g,v) isdeadm(otherwhite(g), (v)->marked)
#define changewhite(x) ((x)->marked ^= WHITEBITS)
#define nw2black(x) \
check_exp(!iswhite(x), l_setbit((x)->marked, BLACKBIT))
#define gray2black(x) l_setbit((x)->marked, BLACKBIT)
#define luaC_white(g) cast_byte((g)->currentwhite & WHITEBITS)
#define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS)
/* object age in generational mode */
@ -123,31 +119,24 @@
/* Default Values for GC parameters */
#define LUAI_GENMAJORMUL 100
#define LUAI_GENMINORMUL 20
#define LUAI_GENMINORMUL 12
/* wait memory to double before starting new cycle */
#define LUAI_GCPAUSE 200
#define LUAI_GCPAUSE 200 /* 200% */
/*
** some gc parameters are stored divided by 4 to allow a maximum value
** up to 1023 in a 'lu_byte'.
** gc parameters ae stored divided by 4 to allow a maximum value larger
** than 1000 in an 'lu_byte'.
*/
#define getgcparam(p) ((p) * 4)
#define setgcparam(p,v) ((p) = (v) / 4)
#define LUAI_GCMUL 100
/* how much to allocate before next GC step (log2) */
#define LUAI_GCSTEPSIZE 13 /* 8 KB */
/*
** Check whether the declared GC mode is generational. While in
** generational mode, the collector can go temporarily to incremental
** mode to improve performance. This is signaled by 'g->lastatomic != 0'.
*/
#define isdecGCmodegen(g) (g->gckind == KGC_GEN || g->lastatomic != 0)
/*
** Does one step of collection when debt becomes positive. 'pre'/'pos'
** allows some adjustments to be done only when needed. macro
@ -174,9 +163,8 @@
(isblack(p) && iswhite(o)) ? \
luaC_barrier_(L,obj2gco(p),obj2gco(o)) : cast_void(0))
#define luaC_upvalbarrier(L,uv,x) ( \
(iscollectable(x) && !upisopen(uv)) ? \
luaC_upvalbarrier_(L,gcvalue(x)) : cast_void(0))
#define luaC_protobarrier(L,p,o) \
(isblack(p) ? luaC_protobarrier_(L,p) : cast_void(0))
LUAI_FUNC void luaC_fix (lua_State *L, GCObject *o);
LUAI_FUNC void luaC_freeallobjects (lua_State *L);
@ -185,10 +173,9 @@ LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask);
LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency);
LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz);
LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v);
LUAI_FUNC void luaC_barrierback_ (lua_State *L, GCObject *o);
LUAI_FUNC void luaC_upvalbarrier_(lua_State* L, GCObject* o);
LUAI_FUNC void luaC_barrierback_ (lua_State *L, Table *o);
LUAI_FUNC void luaC_protobarrier_ (lua_State *L, Proto *p);
LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt);
LUAI_FUNC void luaC_upvdeccount (lua_State *L, UpVal *uv);
LUAI_FUNC void luaC_changemode (lua_State *L, int newmode);

@ -1,5 +1,5 @@
/*
** $Id: llex.h,v 1.79.1.1 2017/04/19 17:20:42 roberto Exp $
** $Id: llex.h,v 1.79 2016/05/02 14:02:12 roberto Exp $
** Lexical Analyzer
** See Copyright Notice in lua.h
*/
@ -27,7 +27,7 @@ enum RESERVED {
/* terminal symbols denoted by reserved words */
TK_AND = FIRST_RESERVED, TK_BREAK,
TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION,
TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_DEFER, TK_NIL, TK_NOT, TK_OR, TK_REPEAT,
TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT,
TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE,
/* other terminal symbols */
TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE,

@ -1,5 +1,5 @@
/*
** $Id: llimits.h,v 1.141.1.1 2017/04/19 17:20:42 roberto Exp $
** $Id: llimits.h,v 1.141 2015/11/19 19:16:22 roberto Exp $
** Limits, basic types, and some other 'installation-dependent' definitions
** See Copyright Notice in lua.h
*/
@ -59,16 +59,6 @@ typedef signed char ls_byte;
#define log2maxs(t) (sizeof(t) * 8 - 2)
/*
** test whether an unsigned value is a power of 2 (or zero)
*/
#define ispow2(x) (((x) & ((x) - 1)) == 0)
/* number of chars of a literal string without the ending \0 */
#define LL(x) (sizeof(x)/sizeof(char) - 1)
/*
** conversion of pointer to unsigned integer:
** this is for hashing only; there is no problem if the integer
@ -102,7 +92,7 @@ typedef LUAI_UACINT l_uacInt;
#if defined(lua_assert)
/** RAVI changes */
#if !defined(RAVI_OPTION_STRING1)
#define RAVI_OPTION_STRING1 "assertions "
#define RAVI_OPTION_STRING1 " assertions"
#endif
#if !defined(RAVI_OPTION_STRING2)
#define RAVI_OPTION_STRING2
@ -114,7 +104,7 @@ typedef LUAI_UACINT l_uacInt;
#define lua_assert(c) ((void)0)
#define check_exp(c,e) (e)
#define lua_longassert(c) ((void)0)
/** RAVI changes */
/** RVAI changes */
#define RAVI_OPTION_STRING1
#define RAVI_OPTION_STRING2
#endif
@ -139,15 +129,10 @@ typedef LUAI_UACINT l_uacInt;
#define cast(t, exp) ((t)(exp))
#define cast_void(i) cast(void, (i))
#define cast_voidp(i) cast(void *, (i))
#define cast_byte(i) cast(lu_byte, (i))
#define cast_num(i) cast(lua_Number, (i))
#define cast_int(i) cast(int, (i))
#define cast_uint(i) cast(unsigned int, (i))
#define cast_byte(i) cast(lu_byte, (i))
#define cast_uchar(i) cast(unsigned char, (i))
#define cast_char(i) cast(char, (i))
#define cast_charp(i) cast(char *, (i))
#define cast_sizet(i) cast(size_t, (i))
/* cast a signed lua_Integer to lua_Unsigned */
@ -165,22 +150,6 @@ typedef LUAI_UACINT l_uacInt;
#endif
/*
** macros to improve jump prediction (used mainly for error handling)
*/
#if !defined(likely)
#if defined(__GNUC__)
#define likely(x) (__builtin_expect(((x) != 0), 1))
#define unlikely(x) (__builtin_expect(((x) != 0), 0))
#else
#define likely(x) (x)
#define unlikely(x) (x)
#endif
#endif
/*
** non-return type
*/

@ -1,5 +1,5 @@
/*
** $Id: lmem.h,v 1.43.1.1 2017/04/19 17:20:42 roberto Exp $
** $Id: lmem.h,v 1.43 2014/12/19 17:26:14 roberto Exp $
** Interface to Memory Manager
** See Copyright Notice in lua.h
*/
@ -49,26 +49,10 @@
#define luaM_newobject(L,tag,s) luaM_realloc_(L, NULL, tag, (s))
/*
* Note that this will grow the vector by unspecified amount and set the size parameter to new size!
*
* v - pointer to memory
* nelems - number of elements needed
* size - curent size of v, will be UPDATED!
* t - element type
* limit - max number allowed
* e - for error message?
*/
#define luaM_growvector(L,v,nelems,size,t,limit,e) \
if ((nelems)+1 > (size)) \
((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e)))
/*
* v - vector - will be updated!
* oldn - old size
* n - new size
* t - element type
*/
#define luaM_reallocvector(L, v,oldn,n,t) \
((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t))))

File diff suppressed because it is too large Load Diff

@ -1,5 +1,5 @@
/*
** $Id: lopcodes.h,v 1.149.1.1 2017/04/19 17:20:42 roberto Exp $
** $Id: lopcodes.h,v 1.149 2016/07/19 17:12:21 roberto Exp $
** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h
*/
@ -190,8 +190,8 @@ OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx]) */
OP_VARARG,/* A B R(A), R(A+1), ..., R(A+B-2) = vararg */
OP_EXTRAARG,/* Ax extra (larger) argument for previous opcode */
OP_RAVI_NEW_IARRAY, /* A R(A) := array of int */
OP_RAVI_NEW_FARRAY, /* A R(A) := array of float */
OP_RAVI_NEWARRAYI, /* A R(A) := array of int */
OP_RAVI_NEWARRAYF, /* A R(A) := array of float */
OP_RAVI_LOADIZ, /* A R(A) := tointeger(0) */
OP_RAVI_LOADFZ, /* A R(A) := tonumber(0) */
@ -219,46 +219,36 @@ OP_RAVI_DIVII, /* A B C R(A) := RK(B) / RK(C) */
OP_RAVI_TOINT, /* A R(A) := toint(R(A)) */
OP_RAVI_TOFLT, /* A R(A) := tofloat(R(A)) */
OP_RAVI_TOARRAYI, /* A R(A) := to_arrayi(R(A)) */
OP_RAVI_TOARRAYF, /* A R(A) := to_arrayf(R(A)) */
OP_RAVI_TOTAB, /* A R(A) := to_table(R(A)) */
OP_RAVI_TOSTRING, /* A R(A) := assert_string(R(A)) */
OP_RAVI_TOBOOLEAN, /* A R(A) := assert_string(R(A)) */
OP_RAVI_TOCLOSURE, /* A R(A) := assert_closure(R(A)) */
OP_RAVI_TOTYPE, /* A R(A) := assert_usertype(R(A)), where usertype has metatable in Lua registry */
OP_RAVI_TOINT_NIL, /* A R(A) := toint(R(A)) */
OP_RAVI_TOFLT_NIL, /* A R(A) := tofloat(R(A)) */
OP_RAVI_TOTAB_NIL, /* A R(A) := to_table(R(A)) */
OP_RAVI_TOSTRING_NIL, /* A R(A) := assert_string(R(A)) */
OP_RAVI_TOBOOLEAN_NIL, /* A R(A) := assert_string(R(A)) */
OP_RAVI_TOCLOSURE_NIL, /* A R(A) := assert_closure(R(A)) */
OP_RAVI_TOTYPE_NIL, /* A R(A) := assert_usertype(R(A)), where usertype has metatable in Lua registry */
OP_RAVI_TOIARRAY, /* A R(A) := to_arrayi(R(A)) */
OP_RAVI_TOFARRAY, /* A R(A) := to_arrayf(R(A)) */
OP_RAVI_MOVEI, /* A B R(A) := R(B), check R(B) is int */
OP_RAVI_MOVEF, /* A B R(A) := R(B), check R(B) is float */
OP_RAVI_MOVEIARRAY, /* A B R(A) := R(B), check R(B) is array of int */
OP_RAVI_MOVEFARRAY, /* A B R(A) := R(B), check R(B) is array of floats */
OP_RAVI_MOVETAB, /* A B R(A) := R(B), check R(B) is a table */
OP_RAVI_IARRAY_GET, /* A B C R(A) := R(B)[RK(C)] where R(B) is array of integers and RK(C) is int */
OP_RAVI_FARRAY_GET, /* A B C R(A) := R(B)[RK(C)] where R(B) is array of floats and RK(C) is int */
OP_RAVI_IARRAY_SET, /* A B C R(A)[RK(B)] := RK(C) where RK(B) is an int, R(A) is array of ints */
OP_RAVI_FARRAY_SET, /* A B C R(A)[RK(B)] := RK(C) where RK(B) is an int, R(A) is array of floats */
OP_RAVI_IARRAY_SETI, /* A B C R(A)[RK(B)] := RK(C) where RK(B) is an int, R(A) is array of ints, and RK(C) is an int */
OP_RAVI_FARRAY_SETF, /* A B C R(A)[RK(B)] := RK(C) where RK(B) is an int, R(A) is array of floats, and RK(C) is an float */
OP_RAVI_FORLOOP_IP, /* As FORLOOP, but with integer index and positive integer step */
OP_RAVI_FORLOOP_I1, /* As FORLOOP, but with integer index 1 and step 1 */
OP_RAVI_FORPREP_IP, /* As FORPREP, but with integer index and positive integer step */
OP_RAVI_FORPREP_I1, /* As FORPREP, but with integer index 1 and step 1 */
OP_RAVI_TOSTRING,
OP_RAVI_TOCLOSURE,
OP_RAVI_TOTYPE,
OP_RAVI_MOVEI, /* A B R(A) := R(B), check R(B) is int */
OP_RAVI_MOVEF, /* A B R(A) := R(B), check R(B) is float */
OP_RAVI_MOVEAI, /* A B R(A) := R(B), check R(B) is array of int */
OP_RAVI_MOVEAF, /* A B R(A) := R(B), check R(B) is array of floats */
OP_RAVI_MOVETAB, /* A B R(A) := R(B), check R(B) is a table */
OP_RAVI_GETTABLE_AI,/* A B C R(A) := R(B)[RK(C)] where R(B) is array of integers and RK(C) is int */
OP_RAVI_GETTABLE_AF,/* A B C R(A) := R(B)[RK(C)] where R(B) is array of floats and RK(C) is int */
OP_RAVI_SETTABLE_AI,/* A B C R(A)[RK(B)] := RK(C) where RK(B) is an int, R(A) is array of ints */
OP_RAVI_SETTABLE_AF,/* A B C R(A)[RK(B)] := RK(C) where RK(B) is an int, R(A) is array of floats */
OP_RAVI_SETTABLE_AII,/* A B C R(A)[RK(B)] := RK(C) where RK(B) is an int, R(A) is array of ints, and RK(C) is an int */
OP_RAVI_SETTABLE_AFF,/* A B C R(A)[RK(B)] := RK(C) where RK(B) is an int, R(A) is array of floats, and RK(C) is an float */
OP_RAVI_FORLOOP_IP,
OP_RAVI_FORLOOP_I1,
OP_RAVI_FORPREP_IP,
OP_RAVI_FORPREP_I1,
OP_RAVI_SETUPVALI, /* A B UpValue[B] := tointeger(R(A)) */
OP_RAVI_SETUPVALF, /* A B UpValue[B] := tonumber(R(A)) */
OP_RAVI_SETUPVAL_IARRAY, /* A B UpValue[B] := toarrayint(R(A)) */
OP_RAVI_SETUPVAL_FARRAY, /* A B UpValue[B] := toarrayflt(R(A)) */
OP_RAVI_SETUPVALAI, /* A B UpValue[B] := toarrayint(R(A)) */
OP_RAVI_SETUPVALAF, /* A B UpValue[B] := toarrayflt(R(A)) */
OP_RAVI_SETUPVALT,/* A B UpValue[B] := to_table(R(A)) */
OP_RAVI_BAND_II,/* A B C R(A) := RK(B) & RK(C) */
@ -277,23 +267,24 @@ OP_RAVI_LE_FF,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
/* Following op codes are specialised when it is known that indexing is being
done on a table and the key is known type */
OP_RAVI_TABLE_GETFIELD,/* A B C R(A) := R(B)[RK(C)], string key, R(B) references a table */
OP_RAVI_TABLE_SETFIELD,/* A B C R(A)[RK(B)] := RK(C), string key, R(A) references a table */
OP_RAVI_TABLE_SELF_SK, /* A B C R(A+1) := R(B); R(A) := R(B)[RK(C)], string key, R(B) references a table */
OP_RAVI_GETTABLE_S,/* A B C R(A) := R(B)[RK(C)], string key, known table */
OP_RAVI_SETTABLE_S,/* A B C R(A)[RK(B)] := RK(C), string key, known table */
OP_RAVI_SELF_S,/* A B C R(A+1) := R(B); R(A) := R(B)[RK(C)], string key, known table */
/* Following opcodes are specialized for indexing where the
key is known to be string or integer but the variable may or may not be
key is known to be string but the variable may or may not be
a table */
OP_RAVI_GETI, /* A B C R(A) := R(B)[RK(C)], integer key */
OP_RAVI_SETI, /* A B C R(A)[RK(B)] := RK(C), integer key */
OP_RAVI_GETFIELD, /* A B C R(A) := R(B)[RK(C)], string key */
OP_RAVI_SELF_SK, /* A B C R(A+1) := R(B); R(A) := R(B)[RK(C)], string key */
OP_RAVI_SETFIELD, /* A B C R(A)[RK(B)] := RK(C), string key */
OP_RAVI_GETTABUP_SK, /* A B C R(A) := UpValue[B][RK(C)], string key */
OP_RAVI_DEFER, /* A mark variable A "deferred" */
OP_RAVI_GETTABLE_I,/* A B C R(A) := R(B)[RK(C)], integer key, known table */
OP_RAVI_SETTABLE_I,/* A B C R(A)[RK(B)] := RK(C), integer key, known table */
OP_RAVI_GETTABLE_SK, /* A B C R(A) := R(B)[RK(C)], string key */
OP_RAVI_SELF_SK, /* A B C R(A+1) := R(B); R(A) := R(B)[RK(C)], string key */
OP_RAVI_SETTABLE_SK, /* A B C R(A)[RK(B)] := RK(C), string key */
OP_RAVI_GETTABUP_SK, /* A B C R(A) := UpValue[B][RK(C)], string key */
} OpCode;
#define NUM_OPCODES (cast(int, OP_RAVI_DEFER) + 1)
#define NUM_OPCODES (cast(int, OP_RAVI_GETTABUP_SK) + 1)
/*===========================================================================
Notes:

@ -1,5 +1,5 @@
/*
** $Id: lparser.h,v 1.76.1.1 2017/04/19 17:20:42 roberto Exp $
** $Id: lparser.h,v 1.76 2015/12/30 18:16:13 roberto Exp $
** Lua Parser
** See Copyright Notice in lua.h
*/
@ -66,15 +66,13 @@ typedef struct expdesc {
short idx; /* index (R/K) */
lu_byte t; /* table (register or upvalue) */
lu_byte vt; /* whether 't' is register (VLOCAL) or upvalue (VUPVAL) */
ravi_type_map key_ravi_type_map; /* Map of possible types the key could have */
// lu_byte key_ravi_type; /* RAVI change: key type */
lu_byte key_ravi_type; /* RAVI change: key type */
TString *usertype; /* RAVI change: usertype name */
} ind;
} u;
int t; /* patch list of 'exit when true' */
int f; /* patch list of 'exit when false' */
ravi_type_map ravi_type_map; /* Map of possible types this expression could have */
// lu_byte ravi_type; /* RAVI change: type of the expression if known, else RAVI_TANY */
lu_byte ravi_type; /* RAVI change: type of the expression if known, else RAVI_TANY */
TString *usertype; /* RAVI change: usertype name */
int pc; /* RAVI change: holds the program counter for OP_NEWTABLE instruction when a constructor expression is parsed */
} expdesc;
@ -243,9 +241,7 @@ LUAI_FUNC LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
Dyndata *dyd, const char *name, int firstchar);
/** RAVI extensions **/
#define RAVI_TYPEMAP_MAX_LEN (sizeof("nil|boolean|integer|number|integer[]|number[]|table|string|function|userdata|?|"))
LUAI_FUNC void raviY_typemap_string(ravi_type_map tm, char* buf);
LUAI_FUNC const char *raviY_typename(ravitype_t tt);
/* Special printf that recognises following conversions:
* %e - expdesc *
@ -263,7 +259,7 @@ LUAI_FUNC void raviY_printf(FuncState *fs, const char *format, ...);
* Else RAVI_TANY is returned. Note that this function only looks
* at active local variables - see note on FuncState on what this means.
*/
LUAI_FUNC ravi_type_map raviY_get_register_typeinfo(FuncState *fs, int reg, TString **);
LUAI_FUNC ravitype_t raviY_get_register_typeinfo(FuncState *fs, int reg, TString **);
#define DEBUG_EXPR(p) \
if ((ravi_parser_debug & 1) != 0) { \

@ -1,5 +1,5 @@
/*
** $Id: lprefix.h,v 1.2.1.1 2017/04/19 17:20:42 roberto Exp $
** $Id: lprefix.h,v 1.2 2014/12/29 16:54:13 roberto Exp $
** Definitions for Lua code that must come before any other header file
** See Copyright Notice in lua.h
*/

@ -1,5 +1,5 @@
/*
** $Id: lstate.h,v 2.133.1.1 2017/04/19 17:39:34 roberto Exp $
** $Id: lstate.h,v 2.133 2016/12/22 13:08:50 roberto Exp $
** Global State
** See Copyright Notice in lua.h
*/
@ -15,6 +15,7 @@
#include "lopcodes.h"
/*
** Some notes about garbage-collected objects: All objects in Lua must
** be kept somehow accessible until being freed, so all objects always
** belong to one (and only one) of these lists, using field 'next' of
@ -26,44 +27,12 @@
** 'fixedgc': all objects that are not to be collected (currently
** only small strings, such as reserved words).
**
** For the generational collector, some of these lists have marks for
** generations. Each mark points to the first element in the list for
** that particular generation; that generation goes until the next mark.
**
** 'allgc' -> 'survival': new objects;
** 'survival' -> 'old': objects that survived one collection;
** 'old1' -> 'reallyold': objects that became old in last collection;
** 'reallyold' -> NULL: objects old for more than one cycle.
**
** 'finobj' -> 'finobjsur': new objects marked for finalization;
** 'finobjsur' -> 'finobjold1': survived """";
** 'finobjold1' -> 'finobjrold': just old """";
** 'finobjrold' -> NULL: really old """".
**
** All lists can contain elements older than their main ages, due
** to 'luaC_checkfinalizer' and 'udata2finalize', which move
** objects between the normal lists and the "marked for finalization"
** lists. Moreover, barriers can age young objects in young lists as
** OLD0, which then become OLD1. However, a list never contains
** elements younger than their main ages.
**
** The generational collector also uses a pointer 'firstold1', which
** points to the first OLD1 object in the list. It is used to optimize
** 'markold'. (Potentially OLD1 objects can be anywhere between 'allgc'
** and 'reallyold', but often the list has no OLD1 objects or they are
** after 'old1'.) Note the difference between it and 'old1':
** 'firstold1': no OLD1 objects before this point; there can be all
** ages after it.
** 'old1': no objects younger than OLD1 after this point.
*/
/*
** Moreover, there is another set of lists that control gray objects.
** These lists are linked by fields 'gclist'. (All objects that
** can become gray have such a field. The field is not the same
** in all objects, but it always has this name.) Any gray object
** must belong to one of these lists, and all objects in these lists
** must be gray (with two exceptions explained below):
** must be gray:
**
** 'gray': regular gray objects, still waiting to be visited.
** 'grayagain': objects that must be revisited at the atomic phase.
@ -74,17 +43,10 @@
** 'weak': tables with weak values to be cleared;
** 'ephemeron': ephemeron tables with white->white entries;
** 'allweak': tables with weak keys and/or weak values to be cleared.
**
** The exceptions to that "gray rule" are:
** - TOUCHED2 objects in generational mode stay in a gray list (because
** they must be visited again at the end of the cycle), but they are
** marked black because assignments to them must activate barriers (to
** move them back to TOUCHED1).
** - Open upvales are kept gray to avoid barriers, but they stay out
** of gray lists. (They don't even have a 'gclist' field.)
*/
** There is also a list 'protogray' for prototypes that need to have
** their caches cleared.
*/
struct lua_longjmp; /* defined in ldo.c */
@ -106,8 +68,6 @@ struct lua_longjmp; /* defined in ldo.c */
#define BASIC_STACK_SIZE (2*LUA_MINSTACK)
#define stacksize(th) cast_int((th)->stack_last - (th)->stack)
/* kinds of Garbage Collection */
#define KGC_INC 0 /* incremental gc */
@ -188,7 +148,6 @@ typedef struct global_State {
l_mem totalbytes; /* number of bytes currently allocated - GCdebt */
l_mem GCdebt; /* bytes allocated not yet compensated by the collector */
lu_mem GCestimate; /* an estimate of the non-garbage memory in use */
lu_mem lastatomic; /* see function 'genstep' in file 'lgc.c' */
stringtable strt; /* hash table for strings */
TValue l_registry;
unsigned int seed; /* randomized seed for hashes */
@ -210,15 +169,15 @@ typedef struct global_State {
GCObject *weak; /* list of tables with weak values */
GCObject *ephemeron; /* list of ephemeron tables (weak keys) */
GCObject *allweak; /* list of all-weak tables */
GCObject *protogray; /* list of prototypes with "new" caches */
GCObject *tobefnz; /* list of userdata to be GC */
GCObject *fixedgc; /* list of objects not to be collected */
/* fields for generational collector */
GCObject *survival; /* start of objects that survived one GC cycle */
GCObject *old1; /* start of old1 objects */
GCObject *reallyold; /* objects more than one cycle old ("really old") */
GCObject *firstold1; /* first OLD1 object in the list (if any) */
GCObject *old; /* start of old objects */
GCObject *reallyold; /* old objects with more than one cycle */
GCObject *finobjsur; /* list of survival objects with finalizers */
GCObject *finobjold1; /* list of old1 objects with finalizers */
GCObject *finobjold; /* list of old objects with finalizers */
GCObject *finobjrold; /* list of really old objects with finalizers */
struct lua_State *twups; /* list of threads with open upvalues */
lua_CFunction panic; /* to be called in unprotected errors */
@ -230,6 +189,7 @@ typedef struct global_State {
TString *strcache[STRCACHE_N][STRCACHE_M]; /* cache for strings in API */
/* RAVI additions */
ravi_State *ravi_state;
ASMFunction dispatch[NUM_OPCODES];
ravi_Writeline ravi_writeline;
ravi_Writestring ravi_writestring;
ravi_Writestringerror ravi_writestringerror;
@ -241,6 +201,8 @@ typedef struct global_State {
#endif
} global_State;
#define DISPATCH_OFFSET ((int)offsetof(global_State, dispatch))
/*
** 'per thread' state
*/
@ -292,9 +254,9 @@ union GCUnion {
struct Udata u;
union Closure cl;
struct Table h;
struct RaviArray arr;
struct Proto p;
struct lua_State th; /* thread */
struct UpVal upv;
};
@ -309,15 +271,14 @@ union GCUnion {
#define gco2cl(o) \
check_exp(novariant((o)->tt) == LUA_TFUNCTION, &((cast_u(o))->cl))
/** RAVI change - we have table sub types in RAVI **/
#define gco2t(o) check_exp((o)->tt == LUA_TTABLE, &((cast_u(o))->h))
#define gco2array(o) check_exp(((o)->tt == RAVI_TIARRAY || (o)->tt == RAVI_TFARRAY), &((cast_u(o))->arr))
#define gco2t(o) check_exp(novariant((o)->tt) == LUA_TTABLE, &((cast_u(o))->h))
#define gco2p(o) check_exp((o)->tt == LUA_TPROTO, &((cast_u(o))->p))
#define gco2th(o) check_exp((o)->tt == LUA_TTHREAD, &((cast_u(o))->th))
#define gco2upv(o) check_exp((o)->tt == LUA_TUPVAL, &((cast_u(o))->upv))
/* macro to convert a Lua object into a GCObject */
#define obj2gco(v) \
check_exp(novariant((v)->tt) < LUA_TDEADKEY, (&(cast_u(v)->gc)))
#define obj2gco(v) (&(cast_u(v)->gc))
/* actual number of total bytes allocated */

@ -1,5 +1,5 @@
/*
** $Id: lstring.h,v 1.61.1.1 2017/04/19 17:20:42 roberto Exp $
** $Id: lstring.h,v 1.61 2015/11/03 15:36:01 roberto Exp $
** String table (keep all strings handled by Lua)
** See Copyright Notice in lua.h
*/

@ -1,5 +1,5 @@
/*
** $Id: ltable.h,v 2.23.1.2 2018/05/24 19:39:05 roberto Exp $
** $Id: ltable.h,v 2.23 2016/12/22 13:08:50 roberto Exp $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
@ -12,18 +12,9 @@
#define gnode(t,i) (&(t)->node[i])
#define gval(n) (&(n)->i_val)
#define gnext(n) ((n)->i_key.nk.next)
#define gnext(n) ((n)->u.next)
/* 'const' to avoid wrong writings that can mess up field 'next' */
#define gkey(n) cast(const TValue*, (&(n)->i_key.tvk))
/*
** writable version of 'gkey'; allows updates to individual fields,
** but not to the whole (which has incompatible type)
*/
#define wgkey(n) (&(n)->i_key.nk)
#define invalidateTMcache(t) ((t)->flags = 0)
@ -35,9 +26,8 @@
#define allocsizenode(t) (isdummy(t) ? 0 : sizenode(t))
/* returns the key, given the value of a table entry */
#define keyfromval(v) \
(gkey(cast(Node *, cast(char *, (v)) - offsetof(Node, i_val))))
/* returns the Node, given the value of a table entry */
#define nodefromval(v) cast(Node *, (v))
LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key);
@ -65,48 +55,22 @@ required to get to a node in the hash table
#else
#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t))))
#define hashstr(t,str) hashpow2(t, (str)->hash)
#define hashboolean(t,p) hashpow2(t, p)
#define hashint(t,i) hashpow2(t, i)
/*
** for some types, it is better to avoid modulus by power of 2, as
** they tend to have many 2 factors.
*/
#define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1))))
#define hashpointer(t,p) hashmod(t, point2uint(p))
#endif
/*
** search function for short strings
*/
#if !RAVI_USE_INLINE_SHORTSTR_TGET
LUAI_FUNC const TValue *luaH_getshortstr (Table *t, TString *key);
#else
LUAI_FUNC const TValue *luaH_getshortstr_continue(TString *key, Node *n);
static RAVI_ALWAYS_INLINE const TValue *luaH_getshortstr(Table *t, TString *key) {
/* We inline the lookup in first two slots */
Node *n = hashstr(t, key);
lua_assert(key->tt == LUA_TSHRSTR);
const TValue *k = gkey(n);
if (ttisshrstring(k) && eqshrstr(tsvalue(k), key))
return gval(n); /* that's it */
int nx = gnext(n);
if (nx == 0)
return luaO_nilobject; /* not found */
#if RAVI_USE_INLINE_SHORTSTR_TGET == 2
n += nx;
k = gkey(n);
if (ttisshrstring(k) && eqshrstr(tsvalue(k), key))
return gval(n); /* that's it */
nx = gnext(n);
if (nx == 0)
return luaO_nilobject; /* not found */
#endif
/* Okay continue search slowly */
return luaH_getshortstr_continue(key, n);
}
#endif
LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key);
LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key);
LUAI_FUNC TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key);
@ -124,49 +88,49 @@ LUAI_FUNC lua_Unsigned luaH_getn (Table *t);
/* Creates a specialized version of Lua Table to support Ravi's
* integer[] and number[] arrays.
*/
LUAI_FUNC RaviArray *raviH_new(lua_State *L, ravi_type_map array_type, int is_slice);
LUAI_FUNC void raviH_free(lua_State* L, RaviArray* t);
LUAI_FUNC int raviH_next(lua_State* L, RaviArray* t, StkId key);
LUAI_FUNC Table *raviH_new(lua_State *L, ravitype_t array_type, int is_slice);
LUAI_FUNC RaviArray *raviH_new_integer_array(lua_State *L, unsigned int len,
LUAI_FUNC Table *raviH_new_integer_array(lua_State *L, unsigned int len,
lua_Integer init_value);
LUAI_FUNC RaviArray *raviH_new_number_array(lua_State *L, unsigned int len,
LUAI_FUNC Table *raviH_new_number_array(lua_State *L, unsigned int len,
lua_Number init_value);
/* Returns the array length - note that this function will
* ignore any elements outside of the Ravi Array structure
*/
#define raviH_getn(t) ((t)->len - 1)
LUAI_FUNC int raviH_getn(Table *t);
/* Type specific array set operation */
LUAI_FUNC void raviH_set_int(lua_State *L, RaviArray *t, lua_Unsigned key,
LUAI_FUNC void raviH_set_int(lua_State *L, Table *t, lua_Unsigned key,
lua_Integer value);
/* Type specific array set operation */
LUAI_FUNC void raviH_set_float(lua_State *L, RaviArray *t, lua_Unsigned key,
LUAI_FUNC void raviH_set_float(lua_State *L, Table *t, lua_Unsigned key,
lua_Number value);
/*
* Create a slice of an existing array
* The original array is inserted into the
* the slice as a paren so that
* the parent array is not garbage collected while this array contains a
* reference to it. This is enforced in the GC.
/* Create a slice of an existing array
* The original table containing the array is inserted into the
* the slice as a value against special key pointer('key_orig_table') so that
* the parent table is not garbage collected while this array contains a
* reference to it
* The array slice starts at start but start-1 is also accessible because of the
* implementation having array values starting at 0.
* A slice must not attempt to release the data array as this is not owned by it,
* and in fact may point to garbage from a memory allocater's point of view.
*/
LUAI_FUNC RaviArray *raviH_new_slice(lua_State *L, TValue *parent,
LUAI_FUNC Table *raviH_new_slice(lua_State *L, TValue *parent,
unsigned int start, unsigned int len);
/* Obtain parent array of the slice */
LUAI_FUNC const TValue *raviH_slice_parent(lua_State *L, TValue *slice);
/* Type specific array get operation */
#define raviH_get_int_inline(L, t, key, v) \
{ \
unsigned int ukey = (unsigned int)((key)); \
lua_Integer *data = (lua_Integer *)t->data; \
if (ukey < t->len) { \
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"); \
@ -176,8 +140,8 @@ LUAI_FUNC RaviArray *raviH_new_slice(lua_State *L, TValue *parent,
#define raviH_get_float_inline(L, t, key, v) \
{ \
unsigned int ukey = (unsigned int)((key)); \
lua_Number *data = (lua_Number *)t->data; \
if (ukey < t->len) { \
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"); \
@ -187,8 +151,8 @@ LUAI_FUNC RaviArray *raviH_new_slice(lua_State *L, TValue *parent,
#define raviH_set_int_inline(L, t, key, value) \
{ \
unsigned int ukey = (unsigned int)((key)); \
lua_Integer *data = (lua_Integer *)t->data; \
if (ukey < t->len) { \
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)); \
@ -198,15 +162,15 @@ LUAI_FUNC RaviArray *raviH_new_slice(lua_State *L, TValue *parent,
#define raviH_set_float_inline(L, t, key, value) \
{ \
unsigned int ukey = (unsigned int)((key)); \
lua_Number *data = (lua_Number *)t->data; \
if (ukey < t->len) { \
lua_Number *data = (lua_Number *)t->ravi_array.data; \
if (ukey < t->ravi_array.len) { \
data[ukey] = (value); \
} else \
raviH_set_float(L, t, ukey, (value)); \
}
LUAI_FUNC void raviH_get_number_array_rawdata(lua_State *L, RaviArray *t, Ravi_NumberArray *data);
LUAI_FUNC void raviH_get_integer_array_rawdata(lua_State *L, RaviArray *t, Ravi_IntegerArray *data);
LUAI_FUNC void raviH_get_number_array_rawdata(lua_State *L, Table *t, lua_Number **startp, lua_Number **endp);
LUAI_FUNC void raviH_get_integer_array_rawdata(lua_State *L, Table *t, lua_Integer **startp, lua_Integer **endp);
#if defined(LUA_DEBUG)
LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key);

@ -0,0 +1,139 @@
/*
** $Id: ltests.h,v 2.49 2015/09/22 14:18:24 roberto Exp roberto $
** Internal Header for Debugging of the Lua Implementation
** See Copyright Notice in lua.h
*/
#ifndef ltests_h
#define ltests_h
#include <stdio.h>
#include <stdlib.h>
/* test Lua with no compatibility code */
#undef LUA_COMPAT_MATHLIB
#undef LUA_COMPAT_IPAIRS
#undef LUA_COMPAT_BITLIB
#undef LUA_COMPAT_APIINTCASTS
#undef LUA_COMPAT_FLOATSTRING
#undef LUA_COMPAT_UNPACK
#undef LUA_COMPAT_LOADERS
#undef LUA_COMPAT_LOG10
#undef LUA_COMPAT_LOADSTRING
#undef LUA_COMPAT_MAXN
#undef LUA_COMPAT_MODULE
#define LUA_DEBUG
/* turn on assertions */
#undef NDEBUG
#include <assert.h>
#define lua_assert(c) assert(c)
#if !defined(RAVI_OPTION_STRING1)
#define RAVI_OPTION_STRING1 " assertions"
#endif
#define RAVI_OPTION_STRING2 " ltests"
/* to avoid warnings, and to make sure value is really unused */
#define UNUSED(x) (x=0, (void)(x))
/* test for sizes in 'l_sprintf' (make sure whole buffer is available) */
#undef l_sprintf
#if !defined(LUA_USE_C89)
#define l_sprintf(s,sz,f,i) (memset(s,0xAB,sz), snprintf(s,sz,f,i))
#else
#define l_sprintf(s,sz,f,i) (memset(s,0xAB,sz), sprintf(s,f,i))
#endif
/* memory-allocator control variables */
typedef struct Memcontrol {
unsigned long numblocks;
unsigned long total;
unsigned long maxmem;
unsigned long memlimit;
unsigned long countlimit;
unsigned long objcount[LUA_NUMTAGS];
} Memcontrol;
// LUA_API Memcontrol l_memcontrol;
/*
** generic variable for debug tricks
*/
extern void *l_Trick;
/*
** Function to traverse and check all memory used by Lua
*/
int lua_checkmemory (lua_State *L);
/* test for lock/unlock */
struct L_EXTRA { int lock; int *plock; };
#undef LUA_EXTRASPACE
#define LUA_EXTRASPACE sizeof(struct L_EXTRA)
#define getlock(l) cast(struct L_EXTRA*, lua_getextraspace(l))
#define luai_userstateopen(l) \
(getlock(l)->lock = 0, getlock(l)->plock = &(getlock(l)->lock))
#define luai_userstateclose(l) \
lua_assert(getlock(l)->lock == 1 && getlock(l)->plock == &(getlock(l)->lock))
#define luai_userstatethread(l,l1) \
lua_assert(getlock(l1)->plock == getlock(l)->plock)
#define luai_userstatefree(l,l1) \
lua_assert(getlock(l)->plock == getlock(l1)->plock)
#define lua_lock(l) lua_assert((*getlock(l)->plock)++ == 0)
#define lua_unlock(l) lua_assert(--(*getlock(l)->plock) == 0)
LUA_API int luaB_opentests (lua_State *L);
LUA_API void *debug_realloc (void *ud, void *block,
size_t osize, size_t nsize);
LUA_API Memcontrol* luaB_getmemcontrol(void);
#if defined(lua_c)
#define luaL_newstate() lua_newstate(debug_realloc, luaB_getmemcontrol())
#define luaL_openlibs(L) \
{ (luaL_openlibs)(L); \
luaL_requiref(L, "T", luaB_opentests, 1); \
lua_pop(L, 1); }
#endif
/* change some sizes to give some bugs a chance */
#undef LUAL_BUFFERSIZE
#define LUAL_BUFFERSIZE 23
#define MINSTRTABSIZE 2
//#define MAXINDEXRK 1
/* make stack-overflow tests run faster */
#undef LUAI_MAXSTACK
#define LUAI_MAXSTACK 50000
#if 0 /* Ravi change */
#undef LUAI_USER_ALIGNMENT_T
#define LUAI_USER_ALIGNMENT_T union { char b[sizeof(void*) * 8]; }
#endif
#define STRCACHE_N 23
#define STRCACHE_M 5
#endif

@ -1,5 +1,5 @@
/*
** $Id: ltm.h,v 2.22.1.1 2017/04/19 17:20:42 roberto Exp $
** $Id: ltm.h,v 2.22 2016/02/26 19:20:15 roberto Exp $
** Tag methods
** See Copyright Notice in lua.h
*/

@ -1,5 +1,5 @@
/*
** $Id: lua.h,v 1.332.1.2 2018/06/13 16:58:17 roberto Exp $
** $Id: lua.h,v 1.332 2016/12/22 15:51:20 roberto Exp $
** Lua - A Scripting Language
** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
** See Copyright Notice at the end of this file
@ -19,11 +19,11 @@
#define LUA_VERSION_MAJOR "5"
#define LUA_VERSION_MINOR "3"
#define LUA_VERSION_NUM 503
#define LUA_VERSION_RELEASE "5"
#define LUA_VERSION_RELEASE "4"
#define LUA_VERSION "Ravi " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE
#define LUA_COPYRIGHT LUA_RELEASE "\nCopyright (C) 1994-2019 Lua.org, PUC-Rio\nPortions Copyright (C) 2015-2020 Dibyendu Majumdar"
#define LUA_COPYRIGHT LUA_RELEASE "\nCopyright (C) 1994-2017 Lua.org, PUC-Rio\nPortions Copyright (C) 2015-2017 Dibyendu Majumdar"
#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes, Dibyendu Majumdar"
@ -129,90 +129,13 @@ typedef void(*ravi_Writeline)(void);
typedef void(*ravi_Writestringerror)(const char *fmt, const char *p);
/** RAVI change end **/
/* RAVI change - always enable LTESTS in debug builds */
#if !defined(NDEBUG) && !defined(NO_LUA_DEBUG)
#define LUA_DEBUG
#endif
#ifdef LUA_DEBUG
/* turn on assertions */
#include <assert.h>
#define lua_assert(c) assert(c)
#if !defined(RAVI_OPTION_STRING1)
#define RAVI_OPTION_STRING1 "assertions "
#endif
#define RAVI_OPTION_STRING2 "ltests "
/* to avoid warnings, and to make sure value is really unused */
#define UNUSED(x) (x=0, (void)(x))
/* test for sizes in 'l_sprintf' (make sure whole buffer is available) */
#undef l_sprintf
#if !defined(LUA_USE_C89)
#define l_sprintf(s,sz,f,i) (memset(s,0xAB,sz), snprintf(s,sz,f,i))
#else
#define l_sprintf(s,sz,f,i) (memset(s,0xAB,sz), sprintf(s,f,i))
#endif
/* memory-allocator control variables */
typedef struct Memcontrol {
unsigned long numblocks;
unsigned long total;
unsigned long maxmem;
unsigned long memlimit;
unsigned long countlimit;
unsigned long objcount[LUA_NUMTAGS];
} Memcontrol;
/*
** generic variable for debug tricks
*/
extern void *l_Trick;
/*
** Function to traverse and check all memory used by Lua
** generic extra include file
*/
extern int lua_checkmemory(lua_State *L);
/* test for lock/unlock */
struct L_EXTRA { int lock; int *plock; };
#undef LUA_EXTRASPACE
#define LUA_EXTRASPACE sizeof(struct L_EXTRA)
#define getlock(l) cast(struct L_EXTRA*, lua_getextraspace(l))
#define luai_userstateopen(l) \
(getlock(l)->lock = 0, getlock(l)->plock = &(getlock(l)->lock))
#define luai_userstateclose(l) \
lua_assert(getlock(l)->lock == 1 && getlock(l)->plock == &(getlock(l)->lock))
#define luai_userstatethread(l,l1) \
lua_assert(getlock(l1)->plock == getlock(l)->plock)
#define luai_userstatefree(l,l1) \
lua_assert(getlock(l)->plock == getlock(l1)->plock)
#define lua_lock(l) lua_assert((*getlock(l)->plock)++ == 0)
#define lua_unlock(l) lua_assert(--(*getlock(l)->plock) == 0)
LUA_API int luaB_opentests(lua_State *L);
LUA_API void *debug_realloc(void *ud, void *block,
size_t osize, size_t nsize);
LUA_API Memcontrol* luaB_getmemcontrol(void);
#if defined(lua_c)
#define luaL_newstate() lua_newstate(debug_realloc, luaB_getmemcontrol())
#define luaL_openlibs(L) \
{ (luaL_openlibs)(L); \
luaL_requiref(L, "T", luaB_opentests, 1); \
lua_pop(L, 1); }
#if defined(LUA_USER_H)
#include LUA_USER_H
#endif
#endif
/*
** RCS ident string
@ -226,7 +149,8 @@ extern const char lua_ident[];
LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud);
LUA_API void (lua_close) (lua_State *L);
LUA_API lua_State *(lua_newthread) (lua_State *L);
LUA_API int (lua_resetthread) (lua_State *L);
LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf);
LUA_API const lua_Number *(lua_version) (lua_State *L);
@ -363,14 +287,11 @@ LUA_API int (lua_pcallk) (lua_State *L, int nargs, int nresults, int errfunc,
lua_KContext ctx, lua_KFunction k);
#define lua_pcall(L,n,r,f) lua_pcallk(L, (n), (r), (f), 0, NULL)
/* A Lua Closure must be on top of the stack. This will set _ENV upvalue */
LUA_API void (ravi_closure_setenv) (lua_State* L);
LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt,
const char *chunkname, const char *mode);
LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data, int strip);
LUA_API void (raviV_raise_error) (lua_State *L, int errorcode);
/*
** coroutine functions
@ -552,16 +473,6 @@ struct lua_Debug {
/* RAVI Extensions */
LUA_API void (ravi_pushcfastcall)(lua_State *L, void *ptr, int tag);
/* Allowed tags - subject to change. Max value is 128. Note that
each tag requires special handling in ldo.c */
enum {
RAVI_TFCF_EXP = 1,
RAVI_TFCF_LOG = 2,
RAVI_TFCF_D_D = 3,
};
/* Create an integer array (specialization of Lua table)
* of given size and initialize array with supplied initial value
*/
@ -599,24 +510,10 @@ LUA_API int ravi_is_integer_array(lua_State *L, int idx);
/* Get the raw data associated with the number array at idx.
* Note that Ravi arrays have an extra element at offset 0 - this
* function returns a pointer to &data[0]. The number of
* array elements is returned in length.
* array elements is returned in len.
*/
typedef struct {
lua_Number *data;
unsigned int length;
} Ravi_NumberArray;
LUA_API void ravi_get_number_array_rawdata(lua_State *L, int idx, Ravi_NumberArray *array_data);
/* Get the raw data associated with the integer array at idx.
* Note that Ravi arrays have an extra element at offset 0 - this
* function returns a pointer to &data[0]. The number of
* array elements is returned in length.
*/
typedef struct {
lua_Integer *data;
unsigned int length;
} Ravi_IntegerArray;
LUA_API void ravi_get_integer_array_rawdata(lua_State *L, int idx, Ravi_IntegerArray *array_data);
LUA_API lua_Number *ravi_get_number_array_rawdata(lua_State *L, int idx, size_t *len);
LUA_API lua_Integer *ravi_get_integer_array_rawdata(lua_State *L, int idx, size_t *len);
/* API to set the output functions used by Lua / Ravi
* This allows the default implementations to be overridden
@ -632,27 +529,34 @@ LUA_API void ravi_writestringerror(lua_State *L, const char *fmt, const char *p)
LUA_API void ravi_set_debugger_data(lua_State *L, void *data);
LUA_API void *ravi_get_debugger_data(lua_State *L);
/* Dumps the ravi Bytecode to stdout */
/////////////////////////////////////////////////////////////////////////////
/*
Bunch of useful functions for debugging
*/
struct lua_TValue;
struct Proto;
LUA_API void ravi_dump_value(lua_State *L, const struct lua_TValue *v);
LUA_API void ravi_dump_stack(lua_State *L, const char *s);
LUA_API void ravi_dump_stacktop(lua_State *L, const char *s);
LUA_API void ravi_debug_trace(lua_State *L, int opCode, int pc);
LUA_API void ravi_print_function(const struct Proto *f, int full);
LUA_API void ravi_dump_function(lua_State *L);
/* Returns a table of lines containing Ravi bytecode */
LUA_API int ravi_list_code(lua_State *L);
/* Returns a table with various system limits */
LUA_API int ravi_get_limits(lua_State *L);
/* Options */
LUA_API const char *raviV_options(struct lua_State *L);
/* Following are for debugging purposes only */
LUAI_DDEC int ravi_parser_debug;
LUA_API void ravi_set_debuglevel(int level);
#define RAVI_DEBUG_STACK(p) if ((ravi_parser_debug & 8) != 0) {p;} else {}
#define RAVI_ENABLED 1
#define RAVI_BYTECODE_PROFILING_ENABLED 0
/******************************************************************************
* Copyright (C) 1994-2019 Lua.org, PUC-Rio.
* Portions Copyright (C) 2015-2020 Dibyendu Majumdar
* Copyright (C) 1994-2017 Lua.org, PUC-Rio.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the

@ -1,5 +1,5 @@
/*
** $Id: luaconf.h,v 1.259.1.1 2017/04/19 17:29:57 roberto Exp $
** $Id: luaconf.h,v 1.259 2016/12/22 13:08:50 roberto Exp $
** Configuration file for Lua
** See Copyright Notice in lua.h
*/
@ -61,19 +61,15 @@
#if defined(LUA_USE_LINUX)
#define LUA_USE_POSIX
#define LUA_USE_DLOPEN /* needs an extra library: -ldl */
#ifndef LUA_USE_READLINE
#define LUA_USE_READLINE /* needs some extra libraries */
#endif
#endif
#if defined(LUA_USE_MACOSX)
#define LUA_USE_POSIX
#define LUA_USE_DLOPEN /* MacOS does not need -ldl */
#ifndef LUA_USE_READLINE
#define LUA_USE_READLINE /* needs an extra library: -lreadline */
#endif
#endif
/*
@ -260,11 +256,9 @@
#endif /* } */
/*
** More often than not the libs go together with the core.
*/
/* more often than not the libs go together with the core */
#define LUALIB_API LUA_API
#define LUAMOD_API LUA_API
#define LUAMOD_API LUALIB_API
/*
@ -281,17 +275,15 @@
** give a warning about it. To avoid these warnings, change to the
** default definition.
*/
#if 0
#if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \
defined(__ELF__) /* { */
#define LUAI_FUNC __attribute__((visibility("internal"))) extern
/** RAVI change **/
#define LUAI_FUNC /* __attribute__((visibility("hidden")))*/ extern
#else /* }{ */
#define LUAI_FUNC extern
#endif /* } */
#endif
#define LUAI_FUNC LUA_API /* AOT code needs to access symbols */
#define LUAI_DDEC extern
#define LUAI_DDEC LUAI_FUNC
#define LUAI_DDEF /* empty */
/* }================================================================== */
@ -303,8 +295,6 @@
** ===================================================================
*/
#define LUA_COMPAT_5_2
#define LUA_COMPAT_5_1
/*
@@ LUA_COMPAT_5_2 controls other macros for compatibility with Lua 5.2.
@@ LUA_COMPAT_5_1 controls other macros for compatibility with Lua 5.1.
@ -429,14 +419,14 @@
@@ LUA_NUMBER is the floating-point type used by Lua.
@@ LUAI_UACNUMBER is the result of a 'default argument promotion'
@@ over a floating number.
@@ l_floatatt(x) corrects float attribute 'x' to the proper float type
@@ l_mathlim(x) corrects limit name 'x' to the proper float type
** by prefixing it with one of FLT/DBL/LDBL.
@@ LUA_NUMBER_FRMLEN is the length modifier for writing floats.
@@ LUA_NUMBER_FMT is the format for writing floats.
@@ lua_number2str converts a float to a string.
@@ l_mathop allows the addition of an 'l' or 'f' to all math operations.
@@ l_floor takes the floor of a float.
@@ lua_str2number converts a decimal numeral to a number.
@@ lua_str2number converts a decimal numeric string to a number.
*/
@ -448,13 +438,12 @@
l_sprintf((s), sz, LUA_NUMBER_FMT, (LUAI_UACNUMBER)(n))
/*
@@ lua_numbertointeger converts a float number with an integral value
** to an integer, or returns 0 if float is not within the range of
** a lua_Integer. (The range comparisons are tricky because of
** rounding. The tests here assume a two-complement representation,
** where MININTEGER always has an exact representation as a float;
** MAXINTEGER may not have one, and therefore its conversion to float
** may have an ill-defined value.)
@@ lua_numbertointeger converts a float number to an integer, or
** returns 0 if float is not within the range of a lua_Integer.
** (The range comparisons are tricky because of rounding. The tests
** here assume a two-complement representation, where MININTEGER always
** has an exact representation as a float; MAXINTEGER may not have one,
** and therefore its conversion to float may have an ill-defined value.)
*/
#define lua_numbertointeger(n,p) \
((n) >= (LUA_NUMBER)(LUA_MININTEGER) && \
@ -468,7 +457,7 @@
#define LUA_NUMBER float
#define l_floatatt(n) (FLT_##n)
#define l_mathlim(n) (FLT_##n)
#define LUAI_UACNUMBER double
@ -484,7 +473,7 @@
#define LUA_NUMBER long double
#define l_floatatt(n) (LDBL_##n)
#define l_mathlim(n) (LDBL_##n)
#define LUAI_UACNUMBER long double
@ -499,7 +488,7 @@
#define LUA_NUMBER double
#define l_floatatt(n) (DBL_##n)
#define l_mathlim(n) (DBL_##n)
#define LUAI_UACNUMBER double
@ -524,13 +513,11 @@
@@ LUA_UNSIGNED is the unsigned version of LUA_INTEGER.
**
@@ LUAI_UACINT is the result of a 'default argument promotion'
@@ over a LUA_INTEGER.
@@ over a lUA_INTEGER.
@@ LUA_INTEGER_FRMLEN is the length modifier for reading/writing integers.
@@ LUA_INTEGER_FMT is the format for writing integers.
@@ LUA_MAXINTEGER is the maximum value for a LUA_INTEGER.
@@ LUA_MININTEGER is the minimum value for a LUA_INTEGER.
@@ LUA_MAXUNSIGNED is the maximum value for a LUA_UNSIGNED.
@@ LUA_UNSIGNEDBITS is the number of bits in a LUA_UNSIGNED.
@@ lua_integer2str converts an integer to a string.
*/
@ -551,9 +538,6 @@
#define LUA_UNSIGNED unsigned LUAI_UACINT
#define LUA_UNSIGNEDBITS (sizeof(LUA_UNSIGNED) * CHAR_BIT)
/* now the variable definitions */
#if LUA_INT_TYPE == LUA_INT_INT /* { int */
@ -564,8 +548,6 @@
#define LUA_MAXINTEGER INT_MAX
#define LUA_MININTEGER INT_MIN
#define LUA_MAXUNSIGNED UINT_MAX
#elif LUA_INT_TYPE == LUA_INT_LONG /* }{ long */
#define LUA_INTEGER long
@ -574,8 +556,6 @@
#define LUA_MAXINTEGER LONG_MAX
#define LUA_MININTEGER LONG_MIN
#define LUA_MAXUNSIGNED ULONG_MAX
#elif LUA_INT_TYPE == LUA_INT_LONGLONG /* }{ long long */
/* use presence of macro LLONG_MAX as proxy for C99 compliance */
@ -588,8 +568,6 @@
#define LUA_MAXINTEGER LLONG_MAX
#define LUA_MININTEGER LLONG_MIN
#define LUA_MAXUNSIGNED ULLONG_MAX
#elif defined(LUA_USE_WINDOWS) /* }{ */
/* in Windows, can use specific Windows types */
@ -599,8 +577,6 @@
#define LUA_MAXINTEGER _I64_MAX
#define LUA_MININTEGER _I64_MIN
#define LUA_MAXUNSIGNED _UI64_MAX
#else /* }{ */
#error "Compiler does not support 'long long'. Use option '-DLUA_32BITS' \
@ -635,7 +611,7 @@
/*
@@ lua_strx2number converts a hexadecimal numeral to a number.
@@ lua_strx2number converts an hexadecimal numeric string to a number.
** In C99, 'strtod' does that conversion. Otherwise, you can
** leave 'lua_strx2number' undefined and Lua will provide its own
** implementation.
@ -646,14 +622,7 @@
/*
@@ lua_pointer2str converts a pointer to a readable string in a
** non-specified way.
*/
#define lua_pointer2str(buff,sz,p) l_sprintf(buff,sz,"%p",p)
/*
@@ lua_number2strx converts a float to a hexadecimal numeral.
@@ lua_number2strx converts a float to an hexadecimal numeric string.
** In C99, 'sprintf' (with format specifiers '%a'/'%A') does that.
** Otherwise, you can leave 'lua_number2strx' undefined and Lua will
** provide its own implementation.
@ -699,7 +668,7 @@
/*
@@ lua_getlocaledecpoint gets the locale "radix character" (decimal point).
** Change that if you do not want to use C locales. (Code using this
** macro must include the header 'locale.h'.)
** macro must include header 'locale.h'.)
*/
#if !defined(lua_getlocaledecpoint)
#define lua_getlocaledecpoint() (localeconv()->decimal_point[0])
@ -740,7 +709,7 @@
** {==================================================================
** Macros that affect the API and must be stable (that is, must be the
** same when you compile Lua and when you compile code that links to
** Lua).
** Lua). You probably do not want/need to change them.
** =====================================================================
*/
@ -835,7 +804,7 @@
#endif
#if defined(_MSC_VER) && !defined(__clang__)
#if defined(_MSC_VER)
#define RAVI_NORETURN __declspec(noreturn)
#define RAVI_INLINE __inline
@ -847,11 +816,11 @@
#endif
/* Use LuaJIT style hashing */
#define RAVI_USE_NEWHASH 1
/* Following cause the first hash lookup to be inlined,
and if value is 2 then the second hash lookup is also inlined. */
#define RAVI_USE_INLINE_SHORTSTR_TGET 1
#define RAVI_USE_LLVM_BRANCH_WEIGHTS 1
/* If following is defined as true then LLVM instructions emitted for arithmetic ops
priority floating point ops, else default is to prioritise integer ops */
#define RAVI_USE_LLVM_ARITH_FLOATPRIORITY 1
#endif

@ -1,5 +1,5 @@
/*
** $Id: lualib.h,v 1.45.1.1 2017/04/19 17:20:42 roberto Exp $
** $Id: lualib.h,v 1.45 2017/01/12 17:14:26 roberto Exp $
** Lua standard libraries
** See Copyright Notice in lua.h
*/
@ -52,13 +52,13 @@ LUAMOD_API int (luaopen_package) (lua_State *L);
/** RAVI change start **/
#define LUA_RAVILIBNAME "ravi"
LUAMOD_API int (raviopen_jit)(lua_State *L);
#define LUA_RAVICOMPLIBNAME "compiler"
LUAMOD_API int (raviopen_compiler)(lua_State *L);
LUAMOD_API int (raviopen_llvmjit)(lua_State *L);
#ifdef USE_LLVM
#define LUA_LLVMLIBNAME "llvm"
LUAMOD_API int (raviopen_llvmluaapi)(lua_State *L);
#endif
/** RAVI change end */
/* open all previous libraries */
LUALIB_API void (luaL_openlibs) (lua_State *L);

@ -1,5 +1,5 @@
/*
** $Id: lundump.h,v 1.45.1.1 2017/04/19 17:20:42 roberto Exp $
** $Id: lundump.h,v 1.45 2015/09/08 15:41:05 roberto Exp $
** load precompiled Lua chunks
** See Copyright Notice in lua.h
*/
@ -20,7 +20,7 @@
#define MYINT(s) (s[0]-'0')
#define LUAC_VERSION (MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR))
#define LUAC_FORMAT 1 /* this is the official format */
#define LUAC_FORMAT 0 /* this is the official format */
/* load one chunk; from lundump.c */
LUAI_FUNC LClosure* luaU_undump (lua_State* L, ZIO* Z, const char* name);

@ -1,5 +1,5 @@
/*
** $Id: lvm.h,v 2.41.1.1 2017/04/19 17:20:42 roberto Exp $
** $Id: lvm.h,v 2.41 2016/12/22 13:08:50 roberto Exp $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@ -33,21 +33,10 @@
** integral values)
*/
#if !defined(LUA_FLOORN2I)
#define LUA_FLOORN2I F2Ieq
#define LUA_FLOORN2I 0
#endif
/*
** Rounding modes for float->integer coercion
*/
typedef enum {
F2Ieq, /* no rounding; accepts only integral values */
F2Ifloor, /* takes the floor of the number */
F2Iceil /* takes the ceil of the number */
} F2Imod;
/* convert an object to a float (including string coercion) */
#define tonumber(o,n) \
(RAVI_LIKELY(ttisfloat(o)) ? (*(n) = fltvalue(o), 1) : luaV_tonumber_(o,n))
@ -62,12 +51,6 @@ typedef enum {
#define tointeger(o,i) \
(RAVI_LIKELY(ttisinteger(o)) ? (*(i) = ivalue(o), 1) : luaV_tointeger(o,i,LUA_FLOORN2I))
/* convert an object to an integer (without string coercion) */
#define tointegerns(o,i) \
(ttisinteger(o) ? (*(i) = ivalue(o), 1) : luaV_tointegerns(o,i,LUA_FLOORN2I))
#define intop(op,v1,v2) l_castU2S(l_castS2U(v1) op l_castS2U(v2))
#define luaV_rawequalobj(t1,t2) luaV_equalobj(NULL,t1,t2)
@ -105,7 +88,7 @@ typedef enum {
*/
#define luaV_finishfastset(L,t,slot,v) \
{ setobj2t(L, cast(TValue *,slot), v); \
luaC_barrierback(L, gcvalue(t), v); }
luaC_barrierback(L, hvalue(t), v); }
@ -114,10 +97,7 @@ LUAI_FUNC int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2);
LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r);
LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r);
LUAI_FUNC int luaV_tonumber_ (const TValue *obj, lua_Number *n);
LUAI_FUNC int luaV_tointeger (const TValue *obj, lua_Integer *p, F2Imod mode);
LUAI_FUNC int luaV_tointegerns (const TValue *obj, lua_Integer *p,
F2Imod mode);
LUAI_FUNC int luaV_flttointeger (lua_Number n, lua_Integer *p, F2Imod mode);
LUAI_FUNC int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode);
/** RAVI changes start **/
LUAI_FUNC int luaV_tointeger_(const TValue *obj, lua_Integer *p);
LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key,
@ -133,9 +113,8 @@ LUAI_FUNC void luaV_finishOp (lua_State *L);
/* RAVI change: the int return value is a Ravi extension */
LUAI_FUNC int luaV_execute (lua_State *L);
LUAI_FUNC void luaV_concat (lua_State *L, int total);
LUAI_FUNC lua_Integer luaV_idiv (lua_State *L, lua_Integer x, lua_Integer y);
LUAI_FUNC lua_Integer luaV_div (lua_State *L, lua_Integer x, lua_Integer y);
LUAI_FUNC lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y);
LUAI_FUNC lua_Number luaV_modf (lua_State *L, lua_Number x, lua_Number y);
LUAI_FUNC lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y);
LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb);
@ -172,9 +151,5 @@ LUAI_FUNC void raviV_settable_sskey(lua_State *L, const TValue *t, TValue *key,
LUAI_FUNC void raviV_gettable_i(lua_State *L, const TValue *t, TValue *key, StkId val);
LUAI_FUNC void raviV_settable_i(lua_State *L, const TValue *t, TValue *key, StkId val);
LUAI_FUNC void raviV_op_totype(lua_State *L, TValue *ra, TValue *rb);
LUAI_FUNC int raviV_checktype(lua_State *L, TValue *input, ravi_type_map type, TString *usertype);
LUAI_FUNC int raviV_check_usertype(lua_State *L, TString *name, const TValue *o);
LUAI_FUNC void raviV_op_defer(lua_State *L, TValue *ra);
LUAI_FUNC void raviV_debug_trace(lua_State *L, int opCode, int pc);
#endif

@ -1,5 +1,5 @@
/*
** $Id: lzio.h,v 1.31.1.1 2017/04/19 17:20:42 roberto Exp $
** $Id: lzio.h,v 1.31 2015/09/08 15:41:05 roberto Exp $
** Buffered streams
** See Copyright Notice in lua.h
*/

@ -41,6 +41,7 @@
/* Select native target if no target defined. */
#ifndef RAVI__TARGET
#if defined(__i386) || defined(__i386__) || defined(_M_IX86)
#error "No support for this architecture (yet)"
#define RAVI__TARGET RAVI__ARCH_X86
#elif defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64)
#define RAVI__TARGET RAVI__ARCH_X64
@ -48,6 +49,7 @@
#error "No support for this architecture (yet)"
#define RAVI__TARGET RAVI__ARCH_ARM
#elif defined(__aarch64__)
#error "No support for this architecture (yet)"
#define RAVI__TARGET RAVI__ARCH_ARM64
#elif defined(__ppc__) || defined(__ppc) || defined(__PPC__) || defined(__PPC) || defined(__powerpc__) || defined(__powerpc) || defined(__POWERPC__) || defined(__POWERPC) || defined(_M_PPC)
#error "No support for this architecture (yet)"
@ -120,6 +122,10 @@
#endif
#define RAVI_TARGET_X86 1
#define RAVI_TARGET_X86ORX64 1
#define RAVI_TARGET_EHRETREG 0
#define RAVI_TARGET_MASKSHIFT 1
#define RAVI_TARGET_MASKROT 1
#define RAVI_TARGET_UNALIGNED 1
#elif RAVI__TARGET == RAVI__ARCH_X64
@ -133,21 +139,14 @@
#endif
#define RAVI_TARGET_X64 1
#define RAVI_TARGET_X86ORX64 1
#elif RAVI__TARGET == RAVI__ARCH_ARM64
#define RAVI_ARCH_BITS 64
#if defined(__AARCH64EB__)
#define RAVI_ARCH_NAME "arm64be"
#define RAVI_ARCH_ENDIAN RAVI__ARCH_BE
#else
#define RAVI_ARCH_NAME "arm64"
#define RAVI_ARCH_ENDIAN RAVI__ARCH_LE
#endif
#define RAVI_TARGET_ARM64 1
#define RAVI_TARGET_EHRETREG 0
#define RAVI_TARGET_JUMPRANGE 31 /* +-2^31 = +-2GB */
#define RAVI_TARGET_MASKSHIFT 1
#define RAVI_TARGET_MASKROT 1
#define RAVI_TARGET_UNALIGNED 1
#else
#error "No target architecture defined"
#error "No target architecture defined"
#endif
#ifndef RAVI_PAGESIZE
@ -174,4 +173,8 @@
#define RAVI_64 1
#endif
#ifndef RAVI_TARGET_UNALIGNED
#define RAVI_TARGET_UNALIGNED 0
#endif
#endif

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright (C) 2015-2021 Dibyendu Majumdar
* Copyright (C) 2015-2017 Dibyendu Majumdar
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@ -54,7 +54,7 @@ extern "C" {
#include "lua.h"
#include "lvm.h"
#include "ravi_membuf.h"
#include <ravi_membuf.h>
#define RA(i) (base + GETARG_A(i))
/* to be used after possible stack reallocation */
@ -89,9 +89,6 @@ enum errorcode {
Error_for_step_must_be_number,
Error_for_initial_value_must_be_number,
Error_array_out_of_bounds,
Error_string_expected,
Error_closure_expected,
Error_type_mismatch,
};
enum ravi_codegen_type {
@ -103,13 +100,10 @@ enum ravi_codegen_type {
struct ravi_compile_options_t {
/* Is this a manual request? */
unsigned int manual_request : 1;
int manual_request;
/* Should range check be omitted when compiling array access */
unsigned int omit_array_get_range_check : 1;
/* Should we generate inline code for Lua's arithmetc ops */
unsigned int inline_lua_arithmetic_operators : 1;
int omit_array_get_range_check;
enum ravi_codegen_type codegen_type;
};
@ -122,8 +116,6 @@ LUAI_FUNC bool raviJ_cancompile(Proto *p);
LUAI_FUNC bool raviJ_codegen(struct lua_State *L, struct Proto *p,
struct ravi_compile_options_t *options,
const char *fname, membuff_t *buf);
void raviV_raise_error(lua_State *L, int errorcode);
void raviV_raise_error_with_info(lua_State *L, int errorcode, const char *info);
#ifdef __cplusplus
};

@ -0,0 +1,104 @@
/******************************************************************************
* 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_LLVM_H
#define RAVI_LLVM_H
#ifdef USE_LLVM
#include "llvm/Config/llvm-config.h"
#if (LLVM_VERSION_MAJOR < 3 || LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 5)
#error Unsupported LLVM version
#endif
#if LLVM_VERSION_MAJOR >= 5
#define USE_ORC_JIT 1
#else
#define USE_ORC_JIT 0
#endif
// In lua.c we include this just to get version numbers
// We cannot have C++ headers in that case
#ifdef __cplusplus
#include "llvm/ADT/Triple.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/MCJIT.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include "llvm/ExecutionEngine/GenericValue.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
#include "llvm/IR/Metadata.h"
#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 7
#include "llvm/PassManager.h"
#else
#include "llvm/IR/LegacyPassManager.h"
#endif
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/Transforms/Instrumentation.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Support/FormattedStream.h"
#if USE_ORC_JIT
#include "llvm/ADT/STLExtras.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
#include "llvm/ExecutionEngine/Orc/IRTransformLayer.h"
#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
#include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
#include "llvm/IR/Mangler.h"
#include "llvm/Support/Error.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/Scalar/GVN.h"
#endif
#include <algorithm>
#include <cassert>
#include <cstdlib>
#include <memory>
#include <string>
#include <cstdio>
#include <vector>
#endif //__cplusplus
#endif //USE_LLVM
#endif

File diff suppressed because it is too large Load Diff

@ -4,7 +4,6 @@
#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>
#include <stdarg.h>
typedef struct {
char *buf;
@ -18,11 +17,9 @@ extern void membuff_resize(membuff_t *mb, size_t new_size);
extern void membuff_free(membuff_t *mb);
extern void membuff_add_string(membuff_t *mb, const char *str);
extern void membuff_add_fstring(membuff_t *mb, const char *str, ...);
extern void membuff_add_vfstring(membuff_t *mb, const char *fmt, va_list args);
extern void membuff_add_bool(membuff_t *mb, bool value);
extern void membuff_add_int(membuff_t *mb, int value);
extern void membuff_add_longlong(membuff_t *mb, int64_t value);
extern void membuff_add_char(membuff_t *mb, char c);
/* strncpy() with guaranteed 0 termination */
extern void ravi_string_copy(char *buf, const char *src, size_t buflen);

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright (C) 2015-2021 Dibyendu Majumdar
* 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
@ -27,10 +27,6 @@
extern "C" {
#endif
/**
* Definition of the API that all JIT backends must implement.
*/
struct lua_State;
struct Proto;
typedef struct ravi_compile_options_t ravi_compile_options_t;
@ -47,6 +43,7 @@ int raviV_compile(struct lua_State *L, struct Proto *p,
/* Compile an array of functions */
int raviV_compile_n(struct lua_State *L, struct Proto *p[], int n,
ravi_compile_options_t *options);
int raviV_iscompiled(struct lua_State *L, struct Proto *p);
/* Free the JIT structures associated with the prototype */
void raviV_freeproto(struct lua_State *L, struct Proto *p);
@ -82,6 +79,10 @@ int raviV_getminexeccount(struct lua_State *L);
/* Enable IR / codegen validations */
void raviV_setvalidation(struct lua_State *L, int enabled);
int raviV_getvalidation(struct lua_State *L);
/* Enable calls to GCSTEP */
void raviV_setgcstep(struct lua_State *L, int value);
int raviV_getgcstep(struct lua_State *L);
/* Enable or disable trace hook */
void raviV_settraceenabled(struct lua_State *L, int enabled);
@ -93,9 +94,6 @@ void raviV_dumpIR(struct lua_State *L, struct Proto *p);
/* Dump the compiled assembly code if available */
void raviV_dumpASM(struct lua_State *L, struct Proto *p);
/* Return JIT backend identifier */
const char *raviV_jit_id(struct lua_State *L);
#ifdef __cplusplus
}
#endif

@ -0,0 +1,8 @@
These are examples using the Lua LLVM bindings.
``helloworld.lua``
This illustrates creating a Lua callable C function that prints hello world.
``fib.lua``
This illustrates implementing a fibonacci sequence in LLVM using Lua.

@ -0,0 +1,107 @@
-- ensure that LLVM bindings are available
assert(llvm)
-- Get the LLVM context - right now this is the
-- global context
context = llvm.context()
assert(ravitype(context) == "LLVMcontext")
-- The bindings provide a number of predefined types that
-- are Lua specific plus some standard C types such as 'int',
-- 'double', 'int64_t', etc.
types = context:types()
print 'Listing types'
for k,v in pairs(types) do
print('\t', k, ravitype(v))
llvm.dump(v)
end
-- ***************************************************\
-- Test creating a struct type
-- Just as an exercise create a struct type
-- Initially we have an opaque struct
gcobject = context:structtype("GCObject")
assert(ravitype(gcobject) == "LLVMstructtype")
-- Create pointer to GCObject
gcobject_p = context:pointertype(gcobject)
assert(ravitype(gcobject_p) == "LLVMpointertype")
-- Add the members of the struct
-- Following demonstrates the use of predefined Lua types
gcobject:setbody {gcobject_p, types.lu_byte, types.lu_byte}
-- Display structure of gcobject
llvm.dump(gcobject)
-- ****************************************************/
-- ****************************************************\
-- Test building a Lua C function without writing C code!
--
-- Create a lua_CFunction instance
-- At this stage the function will get a module and
-- execution engine but no body
myfunc = context:lua_CFunction("myfunc")
assert(ravitype(myfunc) == "LLVMmainfunction")
-- Get a new IRBuilder intance
-- this will be garbage collected by Lua
irbuilder = context:irbuilder()
assert(ravitype(irbuilder) == "LLVMirbuilder")
-- Create a basic block
block = context:basicblock("entry")
-- Add it to the end of the function
myfunc:appendblock(block)
-- Set this as the next instruction point
irbuilder:setinsertpoint(block)
-----------------------------------------------
-- Test calling a predefined extern function
-- Get printf decl
-----------------------------------------------
printf = myfunc:extern("printf")
assert(ravitype(printf) == "LLVMconstant")
luaL_checklstring = myfunc:extern("luaL_checklstring")
assert(ravitype(luaL_checklstring) == "LLVMconstant")
hellostr = irbuilder:stringconstant("hello world!\n")
irbuilder:call(printf, { hellostr })
-------------------------------------------------
-- Test calling a random function
-------------------------------------------------
puts_type = context:functiontype(types.int, {types.pchar}, {vararg=false})
assert(ravitype(puts_type) == "LLVMfunctiontype")
-- Declare extern puts()
puts = myfunc:extern("puts", puts_type);
assert(ravitype(puts) == "LLVMconstant")
-- Get the L parameter of myfunc
L = myfunc:arg(1)
-- get the first argument as a string
str = irbuilder:call(luaL_checklstring, {L, context:intconstant(1),
context:nullconstant(types.psize_t)} )
-- Call puts
irbuilder:call(puts, { str })
-- add CreateRet(0)
inst = irbuilder:ret(context:intconstant(0))
assert(ravitype(inst) == "LLVMinstruction")
-- **************************************************/
-- what did we get?
llvm.dump(myfunc)
-- JIT compile the function
-- returns a C Closure
runnable = myfunc:compile()
print('Type of compiled function is', type(runnable))
assert(not runnable('ok\n'))

@ -0,0 +1,141 @@
-- This program demonstrates creating a
-- recursive fibonacci calc function in LLVM
-- Example based upon
-- https://llvm.org/svn/llvm-project/llvm/trunk/examples/Fibonacci/fibonacci.cpp
-- ensure that LLVM bindings are available
assert(llvm)
-- Generate the fibonacci function
local function makefib(context, module, types)
-- The goal of this snippet is to create in the memory the LLVM module
-- consisting of one function as follow:
--
-- int fib(int x) {
-- if(x<=2) return 1;
-- return fib(x-1)+fib(x-2);
-- }
--
-- Create the fib function and insert it into module M. This function is said
-- to return an int and take an int parameter.
local fibtype = context:functiontype(types.int, {types.int})
local FibF = module:newfunction("fib", fibtype)
-- Get a new IRBuilder intance
-- this will be garbage collected by Lua
local ir = context:irbuilder()
-- Add a basic block to the function.
local BB = context:basicblock("EntryBlock");
FibF:appendblock(BB)
ir:setinsertpoint(BB)
-- Get pointers to the constants.
local One = context:intconstant(1);
local Two = context:intconstant(2);
-- Get pointer to the integer argument of the add1 function...
local ArgX = FibF:arg(1); -- Get the arg.
-- Create the true_block.
local RetBB = context:basicblock("return");
FibF:appendblock(RetBB)
-- Create an exit block.
local RecurseBB = context:basicblock("recurse");
FibF:appendblock(RecurseBB)
-- Create the "if (arg <= 2) goto exitbb"
local CondInst = ir:icmpsle(ArgX, Two);
ir:condbr(CondInst, RetBB, RecurseBB);
ir:setinsertpoint(RetBB)
-- Create: ret int 1
ir:ret(One);
-- create fib(x-1)
ir:setinsertpoint(RecurseBB)
local Sub = ir:nswsub(ArgX, One);
local CallFibX1 = ir:call(FibF, {Sub}, {tailcall=true});
-- create fib(x-2)
Sub = ir:nswsub(ArgX, Two);
local CallFibX2 = ir:call(FibF, {Sub}, {tailcall=true});
-- fib(x-1)+fib(x-2)
local Sum = ir:nswadd(CallFibX1, CallFibX2);
-- Create the return instruction and add it to the basic block
ir:ret(Sum);
return FibF
end
-- Get the LLVM context - right now this is the
-- global context
local context = llvm.context()
-- The bindings provide a number of predefined types that
-- are Lua specific plus some standard C types such as 'int',
-- 'double', 'int64_t', etc.
local types = context:types()
-- Create a lua_CFunction instance
-- At this stage the function will get a module and
-- execution engine but no body
local mainfunc = context:lua_CFunction("demofib")
-- Get hold of the module
-- as we will create the fib function as an
-- iternal function
local module = mainfunc:module()
-- The actual fibonacci function is an internal
-- function so that it is pure native function
local fib = makefib(context, module, types)
-- Get a new IRBuilder
local ir = context:irbuilder()
-- Our main Lua function has only one block
local BB = context:basicblock("entry")
mainfunc:appendblock(BB)
ir:setinsertpoint(BB)
-- Declare prototypes
local luaL_checkinteger = mainfunc:extern("luaL_checkinteger")
local lua_pushinteger = mainfunc:extern("lua_pushinteger")
-- Get lua_State*
local L = mainfunc:arg(1)
-- We are expecting one integer parameter
local intparam = ir:call(luaL_checkinteger, {L, context:intconstant(1)})
-- cast from 64 to 32 bit
intparam = ir:truncorbitcast(intparam, types.int)
-- Call the fib calculator
local result = ir:call(fib, {intparam})
-- Extend from 32 to 64 bit
result = ir:zext(result, types.lua_Integer)
-- Push the final integer result
ir:call(lua_pushinteger, {L, result})
-- Return 1
ir:ret(context:intconstant(1))
---- We are done! ---
-- Dump the module for info
module:dump()
-- compile the Lua callable function
local runnable = mainfunc:compile()
assert(runnable(11) == 89)
print 'Ok'

@ -0,0 +1,63 @@
-- This small demo creates a compiled function
-- takes a string parameter and calls puts() to
-- print this
-- ensure that LLVM bindings are available
assert(llvm)
-- Get the LLVM context - right now this is the
-- global context
context = llvm.context()
-- The bindings provide a number of predefined types that
-- are Lua specific plus some standard C types such as 'int',
-- 'double', 'int64_t', etc.
types = context:types()
-- Create a lua_CFunction instance
-- At this stage the function will get a module and
-- execution engine but no body
myfunc = context:lua_CFunction("myfunc")
-- Get a new IRBuilder intance
-- this will be garbage collected by Lua
irbuilder = context:irbuilder()
-- Create a basic block
block = context:basicblock("entry")
-- Add it to the end of the function
myfunc:appendblock(block)
-- Set this as the next instruction point
irbuilder:setinsertpoint(block)
-- get declaration for luaL_checklstring
luaL_checklstring = myfunc:extern("luaL_checklstring")
-- Get the L parameter of myfunc
L = myfunc:arg(1)
-- get the first argument as a string
str = irbuilder:call(luaL_checklstring,
{L, context:intconstant(1),
context:nullconstant(types.psize_t)})
-- declare puts
puts_type = context:functiontype(types.int, {types.pchar})
puts = myfunc:extern("puts", puts_type);
-- Call puts
irbuilder:call(puts, {str})
-- add CreateRet(0)
irbuilder:ret(context:intconstant(0))
-- **************************************************/
-- what did we get?
llvm.dump(myfunc)
-- JIT compile the function
-- returns a C Closure
runnable = myfunc:compile()
assert(not runnable('hello world\n'))

@ -1,61 +0,0 @@
find_path(LUA_INCLUDE_DIR lua.h
PATHS
@CMAKE_INSTALL_PREFIX@/include/ravi
)
find_library(LUA_LIBRARIES
NAMES @LIBRAVI_NAME@ @LIBRAVI_NAME@.so @LIBRAVI_NAME@.dylib
PATHS
@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBDIR@
)
find_program(LUA_EXE
NAMES ravi_s
PATHS
@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_BINDIR@
)
# LUA_INCDIR - place where lua headers exist
set(LUA_INCDIR ${LUA_INCLUDE_DIR})
# LIBDIR - LUA_CPATH
if (WIN32)
get_filename_component(LIBDIR
${LUA_EXE}
DIRECTORY)
else()
get_filename_component(LIBDIR
${LUA_LIBRARIES}
DIRECTORY)
endif()
get_filename_component(LUA_BINDIR
${LUA_EXE}
DIRECTORY)
# LUA_LIBDIR - place where lua native libraries exist
get_filename_component(LUA_LIBDIR
${LUA_LIBRARIES}
DIRECTORY
)
if (NOT WIN32)
set(LUA_LIBRARIES "${LUA_LIBRARIES};m")
endif()
# LUALIB - the lua library to link against
set(LUALIB ${LUA_LIBRARIES})
# LUADIR - LUA_PATH
if (USE_LUA53)
set(LUADIR "${LUA_LIBDIR}/../share/lua/5.3")
else()
set(LUADIR "${LUA_LIBDIR}/../share/lua/5.3")
endif()
set(LUA "${LUA_EXE}")

@ -2,14 +2,14 @@ Lua 5.3.x Tests
===============
This folder contains a copy of the Lua 5.3 tests, amended slightly for Ravi. The changes are to skip some
tests that fail in Ravi due to lack of support for certain features of Lua - e.g. recursion limit for tail calls,
or other limits such as number of variables.
tests that fail in Ravi due to lack of support for certain features of Lua - e.g. tail calls, or different
limits.
Notes
-----
* The Lua 'ltests' library is included in Ravi in Debug builds.
* The tests may crash on Windows 64-bit environment when JIT mode is enabled; this appears to be due to lack of
support for Windows (64-bit) stack unwinding in the JIT backends. See issue #30. The 32-bit build does not have this
* The 'ltests' library is included in Ravi in Debug builds.
* The tests crash on Windows 64-bit environment when JIT mode is enabled; this appears to be due to lack of
support for Windows (64-bit) stack unwinding in LLVM. See issue #30. The 32-bit build does not have this
issue.
* In JIT mode the tests take much longer to run, especially if full JIT is switched on. This is because the tests
generate a lot of small Lua functions dynamically - in thousands - and all the time is spent in JIT compiling

@ -44,6 +44,7 @@ else
T = rawget(_G, "T") -- avoid problems with 'strict' module
end
math.randomseed(0)
--[=[
example of a long [comment],
@ -51,14 +52,6 @@ end
]=]
print("\n\tStarting Tests")
do
-- set random seed
local random_x, random_y = math.randomseed()
print(string.format("random seeds: %d, %d", random_x, random_y))
end
print("current path:\n****" .. package.path .. "****\n")
@ -169,7 +162,7 @@ olddofile('strings.lua')
olddofile('literals.lua')
dofile('tpack.lua')
assert(dofile('attrib.lua') == 27)
dofile('gengc.lua')
assert(dofile('locals.lua') == 5)
dofile('constructs.lua')
dofile('code.lua', true)

@ -863,25 +863,30 @@ end
-------------------------------------------------------------------------
do -- testing errors during GC
--warn("@off")
collectgarbage("stop")
local a = {}
for i=1,20 do
a[i] = T.newuserdata(i) -- creates several udata
end
for i=1,20,2 do -- mark half of them to raise errors during GC
debug.setmetatable(a[i],
{__gc = function (x) error("@expected error in gc") end})
debug.setmetatable(a[i], {__gc = function (x) error("error inside gc") end})
end
for i=2,20,2 do -- mark the other half to count and to create more garbage
debug.setmetatable(a[i], {__gc = function (x) load("A=A+1")() end})
end
a = nil
_G.A = 0
collectgarbage()
a = 0
while 1 do
local stat, msg = pcall(collectgarbage)
if stat then
break -- stop when no more errors
else
a = a + 1
assert(string.find(msg, "__gc"))
end
end
assert(a == 10) -- number of errors
assert(A == 10) -- number of normal collections
collectgarbage("restart")
--warn("@on")
end
-------------------------------------------------------------------------
-- test for userdata vals

@ -1,10 +1,8 @@
-- $Id: testes/bitwise.lua $
-- $Id: bitwise.lua,v 1.26 2016/11/07 13:11:28 roberto Exp $
-- See Copyright Notice in file all.lua
print("testing bitwise operations")
require "bwcoercion"
local numbits = string.packsize('j') * 8
assert(~0 == -1)
@ -56,22 +54,6 @@ assert("0xffffffffffffffff" | 0 == -1)
assert("0xfffffffffffffffe" & "-1" == -2)
assert(" \t-0xfffffffffffffffe\n\t" & "-1" == 2)
assert(" \n -45 \t " >> " -2 " == -45 * 4)
assert("1234.0" << "5.0" == 1234 * 32)
assert("0xffff.0" ~ "0xAAAA" == 0x5555)
assert(~"0x0.000p4" == -1)
assert(("7" .. 3) << 1 == 146)
assert(0xffffffff >> (1 .. "9") == 0x1fff)
assert(10 | (1 .. "9") == 27)
do
local st, msg = pcall(function () return 4 & "a" end)
assert(string.find(msg, "'band'"))
local st, msg = pcall(function () return ~"a" end)
assert(string.find(msg, "'bnot'"))
end
-- out of range number
assert(not pcall(function () return "0xffffffffffffffff.0" | 0 end))

@ -367,7 +367,7 @@ do
local header = string.pack("c5BBc6BBBBBj",
"\27Ravi", -- signature
5*16 + 3, -- version 5.3
1, -- format
0, -- format
"\x19\x93\r\n\x1a\n", -- data
string.packsize("i"), -- sizeof(int)
string.packsize("T"), -- sizeof(size_t)

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save