├── .github └── workflows │ ├── build.yml │ └── release.yml ├── CMakeLists.txt ├── CMakePresets.json ├── LICENSE ├── LUA_LICENSE ├── README.md ├── cmake ├── Findlua.cmake └── luaConfig.cmake ├── doc ├── OSIApproved_100X125.png ├── contents.html ├── index.css ├── logo.gif ├── lua.1 ├── lua.css ├── luac.1 ├── manual.css ├── manual.html └── readme.html ├── logo.png ├── src ├── CMakeLists.txt ├── lapi.c ├── lapi.h ├── lauxlib.c ├── lauxlib.h ├── lbaselib.c ├── lcode.c ├── lcode.h ├── lcorolib.c ├── lctype.c ├── lctype.h ├── ldblib.c ├── ldebug.c ├── ldebug.h ├── ldo.c ├── ldo.h ├── ldump.c ├── lfunc.c ├── lfunc.h ├── lgc.c ├── lgc.h ├── linit.c ├── liolib.c ├── ljumptab.h ├── llex.c ├── llex.h ├── llimits.h ├── lmathlib.c ├── lmem.c ├── lmem.h ├── loadlib.c ├── lobject.c ├── lobject.h ├── lopcodes.c ├── lopcodes.h ├── lopnames.h ├── loslib.c ├── lparser.c ├── lparser.h ├── lprefix.h ├── lstate.c ├── lstate.h ├── lstring.c ├── lstring.h ├── lstrlib.c ├── ltable.c ├── ltable.h ├── ltablib.c ├── ltm.c ├── ltm.h ├── lua.c ├── lua.h ├── lua.hpp ├── luac.c ├── luaconf.h ├── lualib.h ├── lundump.c ├── lundump.h ├── lutf8lib.c ├── lvm.c ├── lvm.h ├── lzio.c └── lzio.h └── test ├── CMakeLists.txt ├── CMakePresets.json └── main.cpp /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | 7 | paths-ignore: 8 | - '**.md' 9 | - 'LICENSE' 10 | tags-ignore: 11 | - "*.*.*" 12 | pull_request: 13 | branches: [ master ] 14 | paths-ignore: 15 | - '**.md' 16 | - '**.rst' 17 | - 'LICENSE' 18 | - '**/release-*.yml' 19 | tags-ignore: 20 | - "*.*.*" 21 | workflow_dispatch: 22 | 23 | jobs: 24 | build: 25 | name: ${{ matrix.config.os }}-${{ matrix.build }} 26 | runs-on: ${{ matrix.config.os }} 27 | strategy: 28 | fail-fast: false 29 | matrix: 30 | config: 31 | - {os: "windows-latest", cxx: "msvc", cc: "msvc", preset: "msvc"} 32 | - {os: "ubuntu-24.04", cxx: "g++-14", cc: "gcc-14", preset: "linux"} 33 | - {os: "macos-latest", cxx: "clang++", cc: "clang", preset: "macOS"} 34 | build: ["Debug", "Release"] 35 | steps: 36 | - name: Checkout 37 | uses: actions/checkout@v4 38 | 39 | - name: Build Lua 40 | shell: bash 41 | env: 42 | BUILD_TYPE: ${{ matrix.build }} 43 | CONFIG_TYPE: ${{ matrix.config.preset }} 44 | CC: ${{ matrix.config.cc }} 45 | CXX: ${{ matrix.config.cxx }} 46 | run: | 47 | cmake --preset=$CONFIG_TYPE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_INSTALL_PREFIX=$HOME/lua 48 | cd ./build 49 | if [[ "$OSTYPE" == "msys" ]]; then 50 | cmake --build . --config $BUILD_TYPE 51 | else 52 | make 53 | fi 54 | 55 | - name: Install Lua 56 | shell: bash 57 | working-directory: ./build 58 | env: 59 | CC: ${{ matrix.config.cc }} 60 | CXX: ${{ matrix.config.cxx }} 61 | BUILD_TYPE: ${{ matrix.build }} 62 | run: | 63 | if [[ "$OSTYPE" == "msys" ]]; then 64 | cmake --install . --config $BUILD_TYPE 65 | else 66 | cmake --install . 67 | fi 68 | 69 | - name: Test App 70 | shell: bash 71 | working-directory: ./test 72 | env: 73 | BUILD_TYPE: ${{ matrix.build }} 74 | CONFIG_TYPE: ${{ matrix.config.preset }} 75 | CC: ${{ matrix.config.cc }} 76 | CXX: ${{ matrix.config.cxx }} 77 | run: | 78 | cmake --preset=$CONFIG_TYPE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_PREFIX_PATH=$HOME/lua 79 | cd ./build 80 | if [[ "$OSTYPE" == "msys" ]]; then 81 | cmake --build . --config $BUILD_TYPE 82 | else 83 | make 84 | fi 85 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | tags: 6 | - '[0-9]+.[0-9]+.[0-9]+' 7 | workflow_dispatch: 8 | 9 | permissions: 10 | contents: write 11 | 12 | jobs: 13 | build: 14 | name: ${{ matrix.config.os }} 15 | runs-on: ${{ matrix.config.os }} 16 | strategy: 17 | fail-fast: false 18 | matrix: 19 | config: 20 | - {os: "windows-latest", cxx: "msvc", cc: "msvc", preset: "msvc"} 21 | - {os: "ubuntu-24.04", cxx: "g++-14", cc: "gcc-14", preset: "linux"} 22 | - {os: "macos-latest", cxx: "clang++", cc: "clang", preset: "macOS"} 23 | steps: 24 | - name: Chekout 25 | uses: actions/checkout@v4 26 | 27 | - name: Build Lua 28 | shell: bash 29 | env: 30 | BUILD_TYPE: Release 31 | CONFIG_TYPE: ${{ matrix.config.preset }} 32 | CC: ${{ matrix.config.cc }} 33 | CXX: ${{ matrix.config.cxx }} 34 | run: | 35 | cmake --preset=$CONFIG_TYPE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_INSTALL_PREFIX=install/lua 36 | cd ./build 37 | if [[ "$OSTYPE" == "msys" ]]; then 38 | cmake --build . --config $BUILD_TYPE 39 | else 40 | make 41 | fi 42 | 43 | - name: Install 44 | shell: bash 45 | working-directory: ./build 46 | env: 47 | BUILD_TYPE: Release 48 | CONFIG_TYPE: ${{ matrix.config.preset }} 49 | CC: ${{ matrix.config.cc }} 50 | CXX: ${{ matrix.config.cxx }} 51 | run: | 52 | if [[ "$OSTYPE" == "msys" ]]; then 53 | cmake --build . --target INSTALL --config $BUILD_TYPE 54 | else 55 | make install 56 | fi 57 | 58 | - name: Package 59 | shell: bash 60 | working-directory: ./install 61 | env: 62 | CONFIG_TYPE: ${{ matrix.config.preset }} 63 | run: | 64 | if [[ "$OSTYPE" == "msys" ]]; then 65 | 7z a lua-$GITHUB_REF_NAME-$CONFIG_TYPE-x64.zip -r lua 66 | else 67 | zip lua-$GITHUB_REF_NAME-$CONFIG_TYPE-x64.zip -r lua 68 | fi 69 | 70 | - name: Publish 71 | uses: softprops/action-gh-release@v2 72 | with: 73 | draft: true 74 | files: "./install/*.zip" 75 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #================================ 2 | # Project setup. 3 | #================================ 4 | cmake_minimum_required(VERSION 3.30) 5 | project(lua VERSION 5.4.7 LANGUAGES CXX C) 6 | 7 | set_property(GLOBAL PROPERTY USE_FOLDERS ON) 8 | 9 | #================================ 10 | # Option variables. 11 | #================================ 12 | option(LUA_BUILD_COMPILER "Build Lua compiler" OFF) 13 | option(LUA_BUILD_INTERPRETER "Build Lua interpreter" OFF) 14 | option(LUA_INSTALL_TARGET "Create install target" OFF) 15 | 16 | #================================ 17 | # Directory variables. 18 | #================================ 19 | set(LUA_SOURCE_DIR ${PROJECT_SOURCE_DIR}) 20 | set(LUA_SOURCE_ROOT ${LUA_SOURCE_DIR}/src) 21 | set(LUA_TEST_ROOT ${LUA_SOURCE_ROOT}/test) 22 | 23 | #================================ 24 | # Add subdirectories. 25 | #================================ 26 | add_subdirectory(${LUA_SOURCE_ROOT}) 27 | 28 | #================================ 29 | # Install 30 | #================================ 31 | if (LUA_INSTALL_TARGET) 32 | install(TARGETS liblua 33 | EXPORT liblua 34 | LIBRARY DESTINATION lib 35 | ARCHIVE DESTINATION lib 36 | RUNTIME DESTINATION lib 37 | INCLUDES DESTINATION include 38 | ) 39 | 40 | include(CMakePackageConfigHelpers) 41 | include(GNUInstallDirs) 42 | write_basic_package_version_file( 43 | "${PROJECT_BINARY_DIR}/luaConfigVersion.cmake" 44 | VERSION ${PACKAGE_VERSION} 45 | COMPATIBILITY ExactVersion 46 | ) 47 | 48 | install(EXPORT liblua 49 | FILE luaTargets.cmake 50 | NAMESPACE lua:: 51 | DESTINATION lib/cmake/lua 52 | ) 53 | 54 | install(FILES 55 | "${CMAKE_CURRENT_SOURCE_DIR}/cmake/luaConfig.cmake" 56 | "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Findlua.cmake" 57 | "${CMAKE_CURRENT_BINARY_DIR}/luaConfigVersion.cmake" 58 | DESTINATION lib/cmake/lua 59 | ) 60 | 61 | install(FILES 62 | ${LUA_INSTALL_INCLUDE} 63 | DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/lua" 64 | ) 65 | 66 | if (MSVC) 67 | set(PDB_DIR_SUFFIX 68 | "$<$:Debug>$<$:RelWithDebInfo>") 69 | set(LIB_SUFFIX "$<$:d>") 70 | 71 | set(PDB_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${PDB_DIR_SUFFIX}") 72 | set(PDB_NAME "liblua${LIB_SUFFIX}.pdb") 73 | install(FILES 74 | "${PDB_OUTPUT_DIRECTORY}/${PDB_NAME}" 75 | DESTINATION lib OPTIONAL) 76 | endif() 77 | 78 | if (LUA_BUILD_COMPILER) 79 | install(TARGETS luac 80 | DESTINATION bin 81 | ) 82 | endif() 83 | 84 | if (LUA_BUILD_INTERPRETER) 85 | install(TARGETS lua 86 | DESTINATION bin 87 | ) 88 | endif() 89 | endif() 90 | -------------------------------------------------------------------------------- /CMakePresets.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "cmakeMinimumRequired":{ 4 | "major": 3, 5 | "minor": 30, 6 | "patch": 0 7 | }, 8 | "configurePresets": [ 9 | { 10 | "name": "default", 11 | "displayName": "default", 12 | "hidden": true, 13 | "binaryDir": "${sourceDir}/build", 14 | "cacheVariables": { 15 | "CMAKE_CXX_STANDARD": "20", 16 | "LUA_BUILD_COMPILER": "ON", 17 | "LUA_BUILD_INTERPRETER": "ON", 18 | "LUA_INSTALL_TARGET": "ON" 19 | } 20 | }, 21 | { 22 | "name": "unix", 23 | "displayName": "unix", 24 | "hidden": true, 25 | "inherits": "default", 26 | "generator": "Unix Makefiles" 27 | }, 28 | { 29 | "name": "msvc", 30 | "displayName": "MSVC", 31 | "inherits": "default", 32 | "description": "Default build for MSVC", 33 | "generator": "Visual Studio 17 2022" 34 | }, 35 | { 36 | "name": "linux", 37 | "displayName": "Linux", 38 | "description": "Default build for Linux systems", 39 | "inherits": "unix" 40 | }, 41 | { 42 | "name": "macOS", 43 | "displayName": "macOS", 44 | "description": "Default build for macOS", 45 | "inherits": "unix" 46 | } 47 | ] 48 | } 49 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2024, Mauricio A Rovira Galvez 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /LUA_LICENSE: -------------------------------------------------------------------------------- 1 | Copyright © 1994–2024 Lua.org, PUC-Rio. 2 | 3 | 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: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | 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. 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # The Lua Programming Language with Modern CMake 2 | 3 | 4 | [![Build](https://github.com/marovira/lua/actions/workflows/build.yml/badge.svg)](https://github.com/marovira/lua/actions/workflows/build.yml) 5 | 6 | ## Introduction 7 | 8 | This repository contains the CMake files for the Lua Programming Language aimed for those 9 | that wish to use the library in [Modern CMake](https://cliutils.gitlab.io/modern-cmake/README.html). 10 | 11 | > [!NOTE] 12 | > The bundle provided here is aimed at *modern* CMake. CMake has come a long way as a 13 | > build generation tool and most modern systems now ship with CMake versions 3.20+ by 14 | > default. As a result, this bundle **requires** a minimum CMake version of 3.30+. 15 | 16 | 17 | ![logo](https://github.com/marovira/lua/blob/master/logo.png) 18 | 19 | ## Usage Instructions 20 | 21 | There are a couple of ways to integrate this bundle into your project. All of 22 | them will use the same linking code, so let's discuss how to include it first. 23 | 24 | ### As a Subdirectory 25 | 26 | The easiest way is to clone this repository directly into your source tree (i.e. 27 | under `./external/lua` for example) and then adding this to your 28 | `CMakelists.txt` file 29 | 30 | ```cmake 31 | add_subdirectory() 32 | ``` 33 | 34 | You can also add this repository as a submodule using git. 35 | 36 | ### Using `FetchContent` 37 | 38 | An alternative use is to have CMake deal with downloading the code via `FetchContent`. To 39 | add this, add the following to your `CMakelists.txt`: 40 | 41 | ```cmake 42 | include(FetchContent) 43 | 44 | FetchContent_Declare( 45 | lua 46 | GIT_REPOSITORY "https://github.com/marovira/lua" 47 | GIT_TAG "" 48 | ) 49 | 50 | FetchContent_MakeAvailable(lua) 51 | ``` 52 | 53 | Where `` can be retrieved from this repository. 54 | 55 | ### Installing 56 | 57 | The final option is to directly install the bundle. To do this, you must install 58 | it as with any other CMake package (build and run the install target). Once that 59 | is done, you *must* copy `./cmake/Findlua.cmake` file into your project's 60 | directory (ideally under `./cmake/Findlua.cmake`) and then add the following to 61 | your `CMakelists.txt`: 62 | 63 | ```cmake 64 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ) 65 | find_package(lua REQUIRED) 66 | ``` 67 | 68 | The reason why we need a separate `Findlua.cmake` file is very simple: CMake 69 | does ship with a `FindLua.cmake`, but that file is written using an older CMake 70 | style (so we can't link using `target_link_libraries`). Moreover, the way in 71 | which you must install Lua isn't entirely straight-forward (especially if you 72 | don't use a package manager) unless you read through the code and figure out 73 | which directories it looks for. 74 | 75 | ### Linking 76 | 77 | Once you have added Lua to your build, you can link against it by adding: 78 | 79 | ```cmake 80 | target_link_libraries( PRIVATE lua::lua) 81 | ``` 82 | 83 | Once that is done you can include the Lua headers as follows: 84 | 85 | ```c++ 86 | #include 87 | ``` 88 | 89 | You will find an example executable under the `./test` directory containing a 90 | sample CMake configuration for building with this bundle. 91 | 92 | ## Licenses 93 | 94 | Lua is published under the MIT license and can be viewed 95 | [here](https://github.com/marovira/lua/blob/master/LUA_LICENSE). For more 96 | information, please see their official website [here](https://www.lua.org/). 97 | 98 | This bundle is published under the BSD-3 license can be viewed [here](https://github.com/marovira/lua/blob/master/LICENSE) 99 | -------------------------------------------------------------------------------- /cmake/Findlua.cmake: -------------------------------------------------------------------------------- 1 | # Locate Lua library 2 | # This module defines 3 | # LUA_EXECUTABLE, if found 4 | # LUA_FOUND, if false, do not try to link to Lua 5 | # LUA_LIBRARIES 6 | # LUA_INCLUDE_DIR, where to find lua.h 7 | # LUA_VERSION_STRING, the version of Lua found (since CMake 2.8.8) 8 | #============================================================================= 9 | # Copyright 2007-2009 Kitware, Inc. 10 | # Modified to support modern CMake syntax by Mauricio A. Rovira Galvez 2021. 11 | # 12 | # Distributed under the OSI-approved BSD License (the "License"); 13 | # see accompanying file Copyright.txt for details. 14 | # 15 | # This software is distributed WITHOUT ANY WARRANTY; without even the 16 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # See the License for more information. 18 | #============================================================================= 19 | # (To distribute this file outside of CMake, substitute the full 20 | # License text for the above reference.) 21 | # 22 | # The required version of Lua can be specified using the 23 | # standard syntax, e.g. FIND_PACKAGE(Lua 5.1) 24 | # Otherwise the module will search for any available Lua implementation 25 | 26 | # Always search for the non-versioned Lua first. 27 | set(_POSSIBLE_LUA_INCLUDE include include/lua) 28 | set(_POSSIBLE_LUA_EXECUTABLE lua) 29 | set(_POSSIBLE_LUA_LIBRARY_RELEASE lua liblua) 30 | set(_POSSIBLE_LUA_LIBRARY_DEBUG luad libluad) 31 | 32 | # Determine the possible naming suffixes (there is not standard for this). 33 | if (lua_FIND_VERSION_MAJOR AND lua_FIND_VERSION_MINOR) 34 | set(_POSSBILE_SUFFIXES 35 | "${lua_FIND_VERSION_MAJOR}${lua_FIND_VERSION_MINOR}" 36 | "${lua_FIND_VERSION_MAJOR}.${lua_FIND_VERSION_MINOR}" 37 | "-${lua_FIND_VERSION_MAJOR}.${lua_FIND_VERSION_MINOR}" 38 | ) 39 | else() 40 | set(_POSSIBLE_SUFFIXES 41 | "54" "5.4" "-5.4" 42 | "53" "5.3" "-5.3" 43 | "52" "5.2" "-5.2" 44 | ) 45 | endif() 46 | 47 | if (WIN32) 48 | set(_POSSIBLE_PATHS 49 | "C:/Program Files/lua" 50 | "C:/Program Files (x86)/lua" 51 | ) 52 | else() 53 | set(_POSSIBLE_PATHS 54 | "~/Library/Frameworks" 55 | "/Library/Frameworks" 56 | "/usr/local" 57 | "/usr" 58 | "/sw" 59 | "/opt/local" 60 | "/opt/csw" 61 | "/opt" 62 | ) 63 | endif() 64 | 65 | # Setup possible search names and locations. 66 | foreach(_SUFFIX ${_POSSIBLE_SUFFIXES}) 67 | list(APPEND _POSSIBLE_LUA_INCLUDE "include/lua$_SUFFIX") 68 | list(APPEND _POSSIBLE_LUA_EXECUTABLE "lua${_SUFFIX}") 69 | list(APPEND _POSSIBLE_LUA_LIBRARY_RELEASE "lua${_SUFFIX}") 70 | list(APPEND _POSSIBLE_LUA_LIBRARY_DEBUG "lua${_SUFFIX}d") 71 | endforeach() 72 | 73 | # Find the Lua executable. 74 | find_program(LUA_EXECUTABLE 75 | NAMES ${_POSSIBLE_LUA_EXECUTABLE} 76 | HINTS $ENV{LUA_DIR} 77 | PATH_SUFFIXES bin 78 | PATHS ${_POSSIBLE_PATHS} 79 | ) 80 | 81 | # Find the Lua header. 82 | find_path(LUA_INCLUDE_DIR lua.h 83 | HINTS $ENV{LUA_DIR} 84 | PATH_SUFFIXES ${_POSSIBLE_LUA_INCLUDE} 85 | PATHS ${_POSSIBLE_PATHS} 86 | ) 87 | 88 | # Find the Lua library. 89 | find_library(LUA_LIBRARY_RELEASE 90 | NAMES ${_POSSIBLE_LUA_LIBRARY_RELEASE} 91 | HINTS 92 | $ENV{LUA_DIR} 93 | PATH_SUFFIXES lib64 lib 94 | PATHS ${_POSSIBLE_PATHS} 95 | ) 96 | 97 | find_library(LUA_LIBRARY_DEBUG 98 | NAMES ${_POSSIBLE_LUA_LIBRARY_DEBUG} 99 | HINTS 100 | $ENV{LUA_DIR} 101 | PATH_SUFFIXES lib64 lib 102 | PATHS ${_POSSIBLE_PATHS} 103 | ) 104 | 105 | if (LUA_LIBRARY) 106 | if (UNIX AND NOT APPLE) 107 | find_library(LUA_MATH_LIBRARY m) 108 | set(LUA_LIBRARIES "${LUA_LIBRARY};${LUA_MATH_LIBRARY}" CACHE STRING "Lua 109 | libraries") 110 | else() 111 | set(LUA_LIBRARIES "${LUA_LIBRARY}" CACHE STRING "Lua libraries") 112 | endif() 113 | endif() 114 | 115 | if (LUA_INCLUDE_DIR AND EXISTS "${LUA_INCLUDE_DIR}/lua.h") 116 | file(STRINGS "${LUA_INCLUDE_DIR}/lua.h" lua_version_major_str 117 | REGEX "^#define[ \t]+LUA_VERSION_MAJOR[ \t]+\"[0-9]+\"") 118 | file(STRINGS "${LUA_INCLUDE_DIR}/lua.h" lua_version_minor_str 119 | REGEX "^#define[ \t]+LUA_VERSION_MINOR[ \t]+\"[0-9]+\"") 120 | file(STRINGS "${LUA_INCLUDE_DIR}/lua.h" lua_version_release_str 121 | REGEX "^#define[ \t]+LUA_VERSION_RELEASE[ \t]+\"[0-9]+\"") 122 | 123 | string(REGEX REPLACE 124 | "^#define[ \t]+LUA_VERSION_MAJOR[ \t]+\"([0-9]+)\"" "\\1" 125 | lua_version_major "${lua_version_major_str}") 126 | string(REGEX REPLACE 127 | "^#define[ \t]+LUA_VERSION_MINOR[ \t]+\"([0-9]+)\"" "\\1" 128 | lua_version_minor "${lua_version_minor_str}") 129 | string(REGEX REPLACE 130 | "^#define[ \t]+LUA_VERSION_RELEASE[ \t]+\"([0-9]+)\"" "\\1" 131 | lua_version_release "${lua_version_release_str}") 132 | 133 | set(LUA_VERSION_STRING 134 | "${lua_version_major}.${lua_version_minor}.${lua_version_release}") 135 | endif() 136 | 137 | include(FindPackageHandleStandardArgs) 138 | include(SelectLibraryConfigurations) 139 | 140 | select_library_configurations(LUA) 141 | 142 | find_package_handle_standard_args(lua 143 | REQUIRED_VARS LUA_LIBRARIES LUA_INCLUDE_DIR 144 | VERSION_VAR LUA_VERSION_STRING) 145 | mark_as_advanced(LUA_INCLUDE_DIR LUA_LIBRARIES LUA_LIBRARY LUA_MATH_LIBRARY 146 | LUA_EXECUTABLE) 147 | 148 | if(lua_FOUND AND NOT TARGET lua::liblua) 149 | add_library(lua::lua STATIC IMPORTED) 150 | set_target_properties(lua::lua PROPERTIES 151 | IMPORTED_LOCATION_DEBUG ${LUA_LIBRARY_DEBUG} 152 | IMPORTED_LOCATION_RELEASE ${LUA_LIBRARY_RELEASE} 153 | IMPORTED_LOCATION_RELWITHDEBINFO ${LUA_LIBRARY_RELEASE} 154 | IMPORTED_LOCATION_MINSIZEREL ${LUA_LIBRARY_RELEASE} 155 | INTERFACE_INCLUDE_DIRECTORIES ${LUA_INCLUDE_DIR} 156 | ) 157 | endif() 158 | -------------------------------------------------------------------------------- /cmake/luaConfig.cmake: -------------------------------------------------------------------------------- 1 | include(${CMAKE_CURRENT_LIST_DIR}/luaTargets.cmake) 2 | list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}") 3 | -------------------------------------------------------------------------------- /doc/OSIApproved_100X125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marovira/lua/49a74bfe83cc1ab0f2df19a36284e437d7f94fee/doc/OSIApproved_100X125.png -------------------------------------------------------------------------------- /doc/index.css: -------------------------------------------------------------------------------- 1 | ul { 2 | list-style-type: none ; 3 | } 4 | 5 | ul.contents { 6 | padding: 0 ; 7 | } 8 | 9 | table { 10 | border: none ; 11 | border-spacing: 0 ; 12 | border-collapse: collapse ; 13 | } 14 | 15 | td { 16 | vertical-align: top ; 17 | padding: 0 ; 18 | text-align: left ; 19 | line-height: 1.25 ; 20 | width: 15% ; 21 | } 22 | -------------------------------------------------------------------------------- /doc/logo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marovira/lua/49a74bfe83cc1ab0f2df19a36284e437d7f94fee/doc/logo.gif -------------------------------------------------------------------------------- /doc/lua.1: -------------------------------------------------------------------------------- 1 | .\" $Id: lua.man,v 1.14 2024/05/08 18:48:27 lhf Exp $ 2 | .TH LUA 1 "$Date: 2024/05/08 18:48:27 $" 3 | .SH NAME 4 | lua \- Lua interpreter 5 | .SH SYNOPSIS 6 | .B lua 7 | [ 8 | .I options 9 | ] 10 | [ 11 | .I script 12 | [ 13 | .I args 14 | ] 15 | ] 16 | .SH DESCRIPTION 17 | .B lua 18 | is the standalone Lua interpreter. 19 | It loads and executes Lua programs, 20 | either in textual source form or 21 | in precompiled binary form. 22 | (Precompiled binaries are output by 23 | .BR luac , 24 | the Lua compiler.) 25 | .B lua 26 | can be used as a batch interpreter and also interactively. 27 | .LP 28 | After handling the 29 | .IR options , 30 | the Lua program in file 31 | .I script 32 | is loaded and executed. 33 | The 34 | .I args 35 | are available to 36 | .I script 37 | as strings in a global table named 38 | .B arg 39 | and also as arguments to its main function. 40 | When called without arguments, 41 | .B lua 42 | behaves as 43 | .B "lua \-v \-i" 44 | if the standard input is a terminal, 45 | and as 46 | .B "lua \-" 47 | otherwise. 48 | .LP 49 | In interactive mode, 50 | .B lua 51 | prompts the user, 52 | reads lines from the standard input, 53 | and executes them as they are read. 54 | If the line contains an expression, 55 | then the line is evaluated and the result is printed. 56 | If a line does not contain a complete statement, 57 | then a secondary prompt is displayed and 58 | lines are read until a complete statement is formed or 59 | a syntax error is found. 60 | .LP 61 | Before handling command line options and scripts, 62 | .B lua 63 | checks the contents of the environment variables 64 | .B LUA_INIT_5_4 65 | and 66 | .BR LUA_INIT , 67 | in that order. 68 | If the contents are of the form 69 | .RI '@ filename ', 70 | then 71 | .I filename 72 | is executed. 73 | Otherwise, the contents are assumed to be a Lua statement and is executed. 74 | When 75 | .B LUA_INIT_5_4 76 | is defined, 77 | .B LUA_INIT 78 | is ignored. 79 | .SH OPTIONS 80 | .TP 81 | .BI \-e " stat" 82 | execute statement 83 | .IR stat . 84 | .TP 85 | .B \-i 86 | enter interactive mode after executing 87 | .IR script . 88 | .TP 89 | .BI \-l " mod" 90 | require library 91 | .I mod 92 | into global 93 | .IR mod . 94 | .TP 95 | .BI \-l " g=mod" 96 | require library 97 | .I mod 98 | into global 99 | .IR g . 100 | .TP 101 | .B \-v 102 | show version information. 103 | .TP 104 | .B \-E 105 | ignore environment variables. 106 | .TP 107 | .B \-W 108 | turn warnings on. 109 | .TP 110 | .B \-\- 111 | stop handling options. 112 | .TP 113 | .B \- 114 | stop handling options and execute the standard input as a file. 115 | .SH ENVIRONMENT VARIABLES 116 | The following environment variables affect the execution of 117 | .BR lua . 118 | When defined, 119 | the version-specific variants take priority 120 | and the version-neutral variants are ignored. 121 | .TP 122 | .B LUA_INIT, LUA_INIT_5_4 123 | Code to be executed before command line options and scripts. 124 | .TP 125 | .B LUA_PATH, LUA_PATH_5_4 126 | Initial value of package.path, 127 | the path used by require to search for Lua loaders. 128 | .TP 129 | .B LUA_CPATH, LUA_CPATH_5_4 130 | Initial value of package.cpath, 131 | the path used by require to search for C loaders. 132 | .SH EXIT STATUS 133 | If a script calls os.exit, 134 | then 135 | .B lua 136 | exits with the given exit status. 137 | Otherwise, 138 | .B lua 139 | exits 140 | with EXIT_SUCCESS (0 on POSIX systems) if there were no errors 141 | and 142 | with EXIT_FAILURE (1 on POSIX systems) if there were errors. 143 | Errors raised in interactive mode do not cause exits. 144 | .SH DIAGNOSTICS 145 | Error messages should be self explanatory. 146 | .SH "SEE ALSO" 147 | .BR luac (1) 148 | .br 149 | The documentation at lua.org, 150 | especially section 7 of the reference manual. 151 | .SH AUTHORS 152 | R. Ierusalimschy, 153 | L. H. de Figueiredo, 154 | W. Celes 155 | .\" EOF 156 | -------------------------------------------------------------------------------- /doc/lua.css: -------------------------------------------------------------------------------- 1 | html { 2 | background-color: #F8F8F8 ; 3 | } 4 | 5 | body { 6 | background-color: #FFFFFF ; 7 | color: #000000 ; 8 | font-family: Helvetica, Arial, sans-serif ; 9 | text-align: justify ; 10 | line-height: 1.25 ; 11 | margin: 16px auto ; 12 | padding: 32px ; 13 | border: solid #ccc 1px ; 14 | border-radius: 20px ; 15 | max-width: 70em ; 16 | width: 90% ; 17 | } 18 | 19 | h1, h2, h3, h4 { 20 | color: #000080 ; 21 | font-family: Verdana, Geneva, sans-serif ; 22 | font-weight: normal ; 23 | font-style: normal ; 24 | text-align: left ; 25 | } 26 | 27 | h1 { 28 | font-size: 28pt ; 29 | } 30 | 31 | h1 img { 32 | vertical-align: text-bottom ; 33 | } 34 | 35 | h2:before { 36 | content: "\2756" ; 37 | padding-right: 0.5em ; 38 | } 39 | 40 | a { 41 | text-decoration: none ; 42 | } 43 | 44 | a:link { 45 | color: #000080 ; 46 | } 47 | 48 | a:link:hover, a:visited:hover { 49 | background-color: #D0D0FF ; 50 | color: #000080 ; 51 | border-radius: 4px ; 52 | } 53 | 54 | a:link:active, a:visited:active { 55 | color: #FF0000 ; 56 | } 57 | 58 | div.menubar { 59 | padding-bottom: 0.5em ; 60 | } 61 | 62 | p.menubar { 63 | margin-left: 2.5em ; 64 | } 65 | 66 | .menubar a:hover { 67 | margin: -3px -3px -3px -3px ; 68 | padding: 3px 3px 3px 3px ; 69 | border-radius: 4px ; 70 | } 71 | 72 | :target { 73 | background-color: #F0F0F0 ; 74 | margin: -8px ; 75 | padding: 8px ; 76 | border-radius: 8px ; 77 | outline: none ; 78 | } 79 | 80 | hr { 81 | display: none ; 82 | } 83 | 84 | table hr { 85 | background-color: #a0a0a0 ; 86 | color: #a0a0a0 ; 87 | border: 0 ; 88 | height: 1px ; 89 | display: block ; 90 | } 91 | 92 | .footer { 93 | color: gray ; 94 | font-size: x-small ; 95 | text-transform: lowercase ; 96 | } 97 | 98 | input[type=text] { 99 | border: solid #a0a0a0 2px ; 100 | border-radius: 2em ; 101 | background-image: url('images/search.png') ; 102 | background-repeat: no-repeat ; 103 | background-position: 4px center ; 104 | padding-left: 20px ; 105 | height: 2em ; 106 | } 107 | 108 | pre.session { 109 | background-color: #F8F8F8 ; 110 | padding: 1em ; 111 | border-radius: 8px ; 112 | } 113 | 114 | table { 115 | border: none ; 116 | border-spacing: 0 ; 117 | border-collapse: collapse ; 118 | } 119 | 120 | td { 121 | padding: 0 ; 122 | margin: 0 ; 123 | } 124 | 125 | td.gutter { 126 | width: 4% ; 127 | } 128 | 129 | table.columns td { 130 | vertical-align: top ; 131 | padding-bottom: 1em ; 132 | text-align: justify ; 133 | line-height: 1.25 ; 134 | } 135 | 136 | table.book td { 137 | vertical-align: top ; 138 | } 139 | 140 | table.book td.cover { 141 | padding-right: 1em ; 142 | } 143 | 144 | table.book img { 145 | border: solid #000080 1px ; 146 | border-radius: 2px ; 147 | } 148 | 149 | table.book span { 150 | font-size: small ; 151 | text-align: left ; 152 | display: block ; 153 | margin-top: 0.25em ; 154 | } 155 | 156 | p.logos a:link:hover, p.logos a:visited:hover { 157 | background-color: inherit ; 158 | } 159 | 160 | img { 161 | background-color: white ; 162 | } 163 | -------------------------------------------------------------------------------- /doc/luac.1: -------------------------------------------------------------------------------- 1 | .\" $Id: luac.man,v 1.29 2011/11/16 13:53:40 lhf Exp $ 2 | .TH LUAC 1 "$Date: 2011/11/16 13:53:40 $" 3 | .SH NAME 4 | luac \- Lua compiler 5 | .SH SYNOPSIS 6 | .B luac 7 | [ 8 | .I options 9 | ] [ 10 | .I filenames 11 | ] 12 | .SH DESCRIPTION 13 | .B luac 14 | is the Lua compiler. 15 | It translates programs written in the Lua programming language 16 | into binary files containing precompiled chunks 17 | that can be later loaded and executed. 18 | .LP 19 | The main advantages of precompiling chunks are: 20 | faster loading, 21 | protecting source code from accidental user changes, 22 | and 23 | off-line syntax checking. 24 | Precompiling does not imply faster execution 25 | because in Lua chunks are always compiled into bytecodes before being executed. 26 | .B luac 27 | simply allows those bytecodes to be saved in a file for later execution. 28 | Precompiled chunks are not necessarily smaller than the corresponding source. 29 | The main goal in precompiling is faster loading. 30 | .LP 31 | In the command line, 32 | you can mix 33 | text files containing Lua source and 34 | binary files containing precompiled chunks. 35 | .B luac 36 | produces a single output file containing the combined bytecodes 37 | for all files given. 38 | Executing the combined file is equivalent to executing the given files. 39 | By default, 40 | the output file is named 41 | .BR luac.out , 42 | but you can change this with the 43 | .B \-o 44 | option. 45 | .LP 46 | Precompiled chunks are 47 | .I not 48 | portable across different architectures. 49 | Moreover, 50 | the internal format of precompiled chunks 51 | is likely to change when a new version of Lua is released. 52 | Make sure you save the source files of all Lua programs that you precompile. 53 | .LP 54 | .SH OPTIONS 55 | .TP 56 | .B \-l 57 | produce a listing of the compiled bytecode for Lua's virtual machine. 58 | Listing bytecodes is useful to learn about Lua's virtual machine. 59 | If no files are given, then 60 | .B luac 61 | loads 62 | .B luac.out 63 | and lists its contents. 64 | Use 65 | .B \-l \-l 66 | for a full listing. 67 | .TP 68 | .BI \-o " file" 69 | output to 70 | .IR file , 71 | instead of the default 72 | .BR luac.out . 73 | (You can use 74 | .B "'\-'" 75 | for standard output, 76 | but not on platforms that open standard output in text mode.) 77 | The output file may be one of the given files because 78 | all files are loaded before the output file is written. 79 | Be careful not to overwrite precious files. 80 | .TP 81 | .B \-p 82 | load files but do not generate any output file. 83 | Used mainly for syntax checking and for testing precompiled chunks: 84 | corrupted files will probably generate errors when loaded. 85 | If no files are given, then 86 | .B luac 87 | loads 88 | .B luac.out 89 | and tests its contents. 90 | No messages are displayed if the file loads without errors. 91 | .TP 92 | .B \-s 93 | strip debug information before writing the output file. 94 | This saves some space in very large chunks, 95 | but if errors occur when running a stripped chunk, 96 | then the error messages may not contain the full information they usually do. 97 | In particular, 98 | line numbers and names of local variables are lost. 99 | .TP 100 | .B \-v 101 | show version information. 102 | .TP 103 | .B \-\- 104 | stop handling options. 105 | .TP 106 | .B \- 107 | stop handling options and process standard input. 108 | .SH "SEE ALSO" 109 | .BR lua (1) 110 | .br 111 | The documentation at lua.org. 112 | .SH DIAGNOSTICS 113 | Error messages should be self explanatory. 114 | .SH AUTHORS 115 | R. Ierusalimschy, 116 | L. H. de Figueiredo, 117 | W. Celes 118 | .\" EOF 119 | -------------------------------------------------------------------------------- /doc/manual.css: -------------------------------------------------------------------------------- 1 | h3 code { 2 | font-family: inherit ; 3 | font-size: inherit ; 4 | } 5 | 6 | pre, code { 7 | font-size: 12pt ; 8 | } 9 | 10 | span.apii { 11 | color: gray ; 12 | float: right ; 13 | font-family: inherit ; 14 | font-style: normal ; 15 | font-size: small ; 16 | } 17 | 18 | h2:before { 19 | content: "" ; 20 | padding-right: 0em ; 21 | } 22 | -------------------------------------------------------------------------------- /doc/readme.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Lua 5.4 readme 5 | 6 | 7 | 27 | 28 | 29 | 30 | 31 |

32 | Lua 33 | Welcome to Lua 5.4 34 |

35 | 36 | 47 | 48 |

About Lua

49 |

50 | Lua is a powerful, efficient, lightweight, embeddable scripting language 51 | developed by a 52 | team 53 | at 54 | PUC-Rio, 55 | the Pontifical Catholic University of Rio de Janeiro in Brazil. 56 | Lua is 57 | free software 58 | used in 59 | many products and projects 60 | around the world. 61 | 62 |

63 | Lua's 64 | official website 65 | provides complete information 66 | about Lua, 67 | including 68 | an 69 | executive summary, 70 | tips on 71 | getting started, 72 | and 73 | updated 74 | documentation, 75 | especially the 76 | reference manual, 77 | which may differ slightly from the 78 | local copy 79 | distributed in this package. 80 | 81 |

Installing Lua

82 |

83 | Lua is distributed in 84 | source 85 | form. 86 | You need to build it before using it. 87 | Building Lua should be straightforward 88 | because 89 | Lua is implemented in pure ANSI C and compiles unmodified in all known 90 | platforms that have an ANSI C compiler. 91 | Lua also compiles unmodified as C++. 92 | The instructions given below for building Lua are for Unix-like platforms, 93 | such as Linux and macOS. 94 | See also 95 | instructions for other systems 96 | and 97 | customization options. 98 | 99 |

100 | If you don't have the time or the inclination to compile Lua yourself, 101 | get a binary from 102 | LuaBinaries. 103 | 104 |

Building Lua

105 |

106 | In most common Unix-like platforms, simply do "make". 107 | Here are the details. 108 | 109 |

    110 |
  1. 111 | Open a terminal window and move to 112 | the top-level directory, which is named lua-5.4.7. 113 | The Makefile there controls both the build process and the installation process. 114 |

    115 |

  2. 116 | Do "make". The Makefile will guess your platform and build Lua for it. 117 |

    118 |

  3. 119 | If the guess failed, do "make help" and see if your platform is listed. 120 | The platforms currently supported are: 121 |

    122 |

    123 | guess aix bsd c89 freebsd generic ios linux linux-readline macosx mingw posix solaris 124 |

    125 |

    126 | If your platform is listed, just do "make xxx", where xxx 127 | is your platform name. 128 |

    129 | If your platform is not listed, try the closest one or posix, generic, 130 | c89, in this order. 131 |

    132 |

  4. 133 | The compilation takes only a few moments 134 | and produces three files in the src directory: 135 | lua (the interpreter), 136 | luac (the compiler), 137 | and liblua.a (the library). 138 |

    139 |

  5. 140 | To check that Lua has been built correctly, do "make test" 141 | after building Lua. This will run the interpreter and print its version. 142 |
143 |

144 | If you're running Linux, try "make linux-readline" to build the interactive Lua interpreter with handy line-editing and history capabilities. 145 | If you get compilation errors, 146 | make sure you have installed the readline development package 147 | (which is probably named libreadline-dev or readline-devel). 148 | If you get link errors after that, 149 | then try "make linux-readline MYLIBS=-ltermcap". 150 | 151 |

Installing Lua

152 |

153 | Once you have built Lua, you may want to install it in an official 154 | place in your system. In this case, do "make install". The official 155 | place and the way to install files are defined in the Makefile. You'll 156 | probably need the right permissions to install files, and so may need to do "sudo make install". 157 | 158 |

159 | To build and install Lua in one step, do "make all install", 160 | or "make xxx install", 161 | where xxx is your platform name. 162 | 163 |

164 | To install Lua locally after building it, do "make local". 165 | This will create a directory install with subdirectories 166 | bin, include, lib, man, share, 167 | and install Lua as listed below. 168 | 169 | To install Lua locally, but in some other directory, do 170 | "make install INSTALL_TOP=xxx", where xxx is your chosen directory. 171 | The installation starts in the src and doc directories, 172 | so take care if INSTALL_TOP is not an absolute path. 173 | 174 |

175 |
176 | bin: 177 |
178 | lua luac 179 |
180 | include: 181 |
182 | lua.h luaconf.h lualib.h lauxlib.h lua.hpp 183 |
184 | lib: 185 |
186 | liblua.a 187 |
188 | man/man1: 189 |
190 | lua.1 luac.1 191 |
192 | 193 |

194 | These are the only directories you need for development. 195 | If you only want to run Lua programs, 196 | you only need the files in bin and man. 197 | The files in include and lib are needed for 198 | embedding Lua in C or C++ programs. 199 | 200 |

Customization

201 |

202 | Three kinds of things can be customized by editing a file: 203 |

    204 |
  • Where and how to install Lua — edit Makefile. 205 |
  • How to build Lua — edit src/Makefile. 206 |
  • Lua features — edit src/luaconf.h. 207 |
208 | 209 |

210 | You don't actually need to edit the Makefiles because you may set the 211 | relevant variables in the command line when invoking make. 212 | Nevertheless, it's probably best to edit and save the Makefiles to 213 | record the changes you've made. 214 | 215 |

216 | On the other hand, if you need to customize some Lua features, 217 | edit src/luaconf.h before building and installing Lua. 218 | The edited file will be the one installed, and 219 | it will be used by any Lua clients that you build, to ensure consistency. 220 | Further customization is available to experts by editing the Lua sources. 221 | 222 |

Building Lua on other systems

223 |

224 | If you're not using the usual Unix tools, then the instructions for 225 | building Lua depend on the compiler you use. You'll need to create 226 | projects (or whatever your compiler uses) for building the library, 227 | the interpreter, and the compiler, as follows: 228 | 229 |

230 |
231 | library: 232 |
233 | lapi.c lcode.c lctype.c ldebug.c ldo.c ldump.c lfunc.c lgc.c llex.c lmem.c lobject.c lopcodes.c lparser.c lstate.c lstring.c ltable.c ltm.c lundump.c lvm.c lzio.c 234 | lauxlib.c lbaselib.c lcorolib.c ldblib.c liolib.c lmathlib.c loadlib.c loslib.c lstrlib.c ltablib.c lutf8lib.c linit.c 235 |
236 | interpreter: 237 |
238 | library, lua.c 239 |
240 | compiler: 241 |
242 | library, luac.c 243 |
244 | 245 |

246 | To use Lua as a library in your own programs, you need to know how to 247 | create and use libraries with your compiler. Moreover, to dynamically load 248 | C libraries for Lua, you'll need to know how to create dynamic libraries 249 | and you'll need to make sure that the Lua API functions are accessible to 250 | those dynamic libraries — but don't link the Lua library 251 | into each dynamic library. For Unix, we recommend that the Lua library 252 | be linked statically into the host program and its symbols exported for 253 | dynamic linking; src/Makefile does this for the Lua interpreter. 254 | For Windows, we recommend that the Lua library be a DLL. 255 | In all cases, the compiler luac should be linked statically. 256 | 257 |

258 | As mentioned above, you may edit src/luaconf.h to customize 259 | some features before building Lua. 260 | 261 |

Changes since Lua 5.3

262 |

263 | Here are the main changes introduced in Lua 5.4. 264 | The 265 | reference manual 266 | lists the 267 | incompatibilities that had to be introduced. 268 | 269 |

Main changes

270 |
    271 |
  • new generational mode for garbage collection 272 |
  • to-be-closed variables 273 |
  • const variables 274 |
  • userdata can have multiple user values 275 |
  • new implementation for math.random 276 |
  • warning system 277 |
  • debug information about function arguments and returns 278 |
  • new semantics for the integer 'for' loop 279 |
  • optional 'init' argument to 'string.gmatch' 280 |
  • new functions 'lua_resetthread' and 'coroutine.close' 281 |
  • string-to-number coercions moved to the string library 282 |
  • allocation function allowed to fail when shrinking a memory block 283 |
  • new format '%p' in 'string.format' 284 |
  • utf8 library accepts codepoints up to 2^31 285 |
286 | 287 |

License

288 |

289 | 290 | [Open Source Initiative Approved License] 291 | 292 | Lua is free software distributed under the terms of the 293 | MIT license 294 | reproduced below; 295 | it may be used for any purpose, including commercial purposes, 296 | at absolutely no cost without having to ask us. 297 | 298 | The only requirement is that if you do use Lua, 299 | then you should give us credit by including the appropriate copyright notice somewhere in your product or its documentation. 300 | 301 | For details, see the 302 | license page. 303 | 304 |

305 | Copyright © 1994–2024 Lua.org, PUC-Rio. 306 | 307 |

308 | Permission is hereby granted, free of charge, to any person obtaining a copy 309 | of this software and associated documentation files (the "Software"), to deal 310 | in the Software without restriction, including without limitation the rights 311 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 312 | copies of the Software, and to permit persons to whom the Software is 313 | furnished to do so, subject to the following conditions: 314 | 315 |

316 | The above copyright notice and this permission notice shall be included in 317 | all copies or substantial portions of the Software. 318 | 319 |

320 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 321 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 322 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 323 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 324 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 325 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 326 | THE SOFTWARE. 327 |

328 |

329 | 330 |

334 | 337 | 338 | 339 | 340 | -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marovira/lua/49a74bfe83cc1ab0f2df19a36284e437d7f94fee/logo.png -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(SRC_ROOT ${CMAKE_CURRENT_LIST_DIR}) 2 | 3 | set(LIB_SRC_LIST 4 | ${SRC_ROOT}/lapi.c 5 | ${SRC_ROOT}/lauxlib.c 6 | ${SRC_ROOT}/lbaselib.c 7 | ${SRC_ROOT}/lcode.c 8 | ${SRC_ROOT}/lcorolib.c 9 | ${SRC_ROOT}/lctype.c 10 | ${SRC_ROOT}/ldblib.c 11 | ${SRC_ROOT}/ldebug.c 12 | ${SRC_ROOT}/ldo.c 13 | ${SRC_ROOT}/ldump.c 14 | ${SRC_ROOT}/lfunc.c 15 | ${SRC_ROOT}/lgc.c 16 | ${SRC_ROOT}/linit.c 17 | ${SRC_ROOT}/liolib.c 18 | ${SRC_ROOT}/llex.c 19 | ${SRC_ROOT}/lmathlib.c 20 | ${SRC_ROOT}/lmem.c 21 | ${SRC_ROOT}/loadlib.c 22 | ${SRC_ROOT}/lobject.c 23 | ${SRC_ROOT}/lopcodes.c 24 | ${SRC_ROOT}/loslib.c 25 | ${SRC_ROOT}/lparser.c 26 | ${SRC_ROOT}/lstate.c 27 | ${SRC_ROOT}/lstring.c 28 | ${SRC_ROOT}/lstrlib.c 29 | ${SRC_ROOT}/ltable.c 30 | ${SRC_ROOT}/ltablib.c 31 | ${SRC_ROOT}/ltm.c 32 | ${SRC_ROOT}/lundump.c 33 | ${SRC_ROOT}/lutf8lib.c 34 | ${SRC_ROOT}/lvm.c 35 | ${SRC_ROOT}/lzio.c 36 | ) 37 | 38 | set(LIB_INCLUDE_LIST 39 | ${SRC_ROOT}/lapi.h 40 | ${SRC_ROOT}/lauxlib.h 41 | ${SRC_ROOT}/lcode.h 42 | ${SRC_ROOT}/lctype.h 43 | ${SRC_ROOT}/ldebug.h 44 | ${SRC_ROOT}/ldo.h 45 | ${SRC_ROOT}/lfunc.h 46 | ${SRC_ROOT}/lgc.h 47 | ${SRC_ROOT}/ljumptab.h 48 | ${SRC_ROOT}/llex.h 49 | ${SRC_ROOT}/llimits.h 50 | ${SRC_ROOT}/lmem.h 51 | ${SRC_ROOT}/lobject.h 52 | ${SRC_ROOT}/lopcodes.h 53 | ${SRC_ROOT}/lopnames.h 54 | ${SRC_ROOT}/lparser.h 55 | ${SRC_ROOT}/lprefix.h 56 | ${SRC_ROOT}/lstate.h 57 | ${SRC_ROOT}/lstring.h 58 | ${SRC_ROOT}/ltable.h 59 | ${SRC_ROOT}/ltm.h 60 | ${SRC_ROOT}/lua.h 61 | ${SRC_ROOT}/luaconf.h 62 | ${SRC_ROOT}/lualib.h 63 | ${SRC_ROOT}/lundump.h 64 | ${SRC_ROOT}/lvm.h 65 | ${SRC_ROOT}/lzio.h 66 | ) 67 | 68 | #================================ 69 | # Libraries. 70 | #================================ 71 | set(LIBS) 72 | if (UNIX AND NOT APPLE) 73 | include(CheckLibraryExists) 74 | check_library_exists(m sin "" HAVE_LIB_M) 75 | if (HAVE_LIB_M) 76 | list(APPEND LIBS m) 77 | endif() 78 | 79 | endif() 80 | 81 | #================================ 82 | # Lua library. 83 | #================================ 84 | source_group("include" FILES ${LIB_INCLUDE_LIST}) 85 | source_group("source" FILES ${LIB_SRC_LIST}) 86 | add_library(liblua ${LIB_INCLUDE_LIST} ${LIB_SRC_LIST}) 87 | target_include_directories(liblua PUBLIC 88 | $ 89 | $ 90 | ) 91 | if (UNIX AND NOT APPLE) 92 | target_link_libraries(liblua PUBLIC ${LIBS}) 93 | endif() 94 | target_compile_features(liblua PRIVATE cxx_std_20) 95 | set_target_properties(liblua PROPERTIES DEBUG_POSTFIX "d") 96 | add_library(lua::lua ALIAS liblua) 97 | set_target_properties(liblua PROPERTIES FOLDER "lua") 98 | 99 | #================================ 100 | # Lua compiler. 101 | #================================ 102 | if (LUA_BUILD_COMPILER) 103 | set(COMPILER_SRC ${SRC_ROOT}/luac.c) 104 | source_group("source" FILES ${COMPILER_SRC}) 105 | add_executable(luac ${COMPILER_SRC}) 106 | target_link_libraries(luac PRIVATE liblua) 107 | set_target_properties(luac PROPERTIES FOLDER "lua") 108 | endif() 109 | 110 | #================================ 111 | # Lua interpreter 112 | #================================ 113 | if (LUA_BUILD_INTERPRETER) 114 | set(INTERP_SRC ${SRC_ROOT}/lua.c) 115 | source_group("source" FILES ${INTERP_SRC}) 116 | add_executable(lua ${INTERP_SRC}) 117 | target_link_libraries(lua PRIVATE liblua) 118 | set_target_properties(lua PROPERTIES FOLDER "lua") 119 | endif() 120 | 121 | 122 | set(LUA_INSTALL_INCLUDE 123 | ${LUA_SOURCE_ROOT}/lauxlib.h 124 | ${LUA_SOURCE_ROOT}/lua.h 125 | ${LUA_SOURCE_ROOT}/lua.hpp 126 | ${LUA_SOURCE_ROOT}/luaconf.h 127 | ${LUA_SOURCE_ROOT}/lualib.h 128 | PARENT_SCOPE) 129 | -------------------------------------------------------------------------------- /src/lapi.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lapi.h $ 3 | ** Auxiliary functions from Lua API 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lapi_h 8 | #define lapi_h 9 | 10 | 11 | #include "llimits.h" 12 | #include "lstate.h" 13 | 14 | 15 | /* Increments 'L->top.p', checking for stack overflows */ 16 | #define api_incr_top(L) {L->top.p++; \ 17 | api_check(L, L->top.p <= L->ci->top.p, \ 18 | "stack overflow");} 19 | 20 | 21 | /* 22 | ** If a call returns too many multiple returns, the callee may not have 23 | ** stack space to accommodate all results. In this case, this macro 24 | ** increases its stack space ('L->ci->top.p'). 25 | */ 26 | #define adjustresults(L,nres) \ 27 | { if ((nres) <= LUA_MULTRET && L->ci->top.p < L->top.p) \ 28 | L->ci->top.p = L->top.p; } 29 | 30 | 31 | /* Ensure the stack has at least 'n' elements */ 32 | #define api_checknelems(L,n) \ 33 | api_check(L, (n) < (L->top.p - L->ci->func.p), \ 34 | "not enough elements in the stack") 35 | 36 | 37 | /* 38 | ** To reduce the overhead of returning from C functions, the presence of 39 | ** to-be-closed variables in these functions is coded in the CallInfo's 40 | ** field 'nresults', in a way that functions with no to-be-closed variables 41 | ** with zero, one, or "all" wanted results have no overhead. Functions 42 | ** with other number of wanted results, as well as functions with 43 | ** variables to be closed, have an extra check. 44 | */ 45 | 46 | #define hastocloseCfunc(n) ((n) < LUA_MULTRET) 47 | 48 | /* Map [-1, inf) (range of 'nresults') into (-inf, -2] */ 49 | #define codeNresults(n) (-(n) - 3) 50 | #define decodeNresults(n) (-(n) - 3) 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /src/lauxlib.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lauxlib.h $ 3 | ** Auxiliary functions for building Lua libraries 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lauxlib_h 9 | #define lauxlib_h 10 | 11 | 12 | #include 13 | #include 14 | 15 | #include "luaconf.h" 16 | #include "lua.h" 17 | 18 | 19 | /* global table */ 20 | #define LUA_GNAME "_G" 21 | 22 | 23 | typedef struct luaL_Buffer luaL_Buffer; 24 | 25 | 26 | /* extra error code for 'luaL_loadfilex' */ 27 | #define LUA_ERRFILE (LUA_ERRERR+1) 28 | 29 | 30 | /* key, in the registry, for table of loaded modules */ 31 | #define LUA_LOADED_TABLE "_LOADED" 32 | 33 | 34 | /* key, in the registry, for table of preloaded loaders */ 35 | #define LUA_PRELOAD_TABLE "_PRELOAD" 36 | 37 | 38 | typedef struct luaL_Reg { 39 | const char *name; 40 | lua_CFunction func; 41 | } luaL_Reg; 42 | 43 | 44 | #define LUAL_NUMSIZES (sizeof(lua_Integer)*16 + sizeof(lua_Number)) 45 | 46 | LUALIB_API void (luaL_checkversion_) (lua_State *L, lua_Number ver, size_t sz); 47 | #define luaL_checkversion(L) \ 48 | luaL_checkversion_(L, LUA_VERSION_NUM, LUAL_NUMSIZES) 49 | 50 | LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); 51 | LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); 52 | LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len); 53 | LUALIB_API int (luaL_argerror) (lua_State *L, int arg, const char *extramsg); 54 | LUALIB_API int (luaL_typeerror) (lua_State *L, int arg, const char *tname); 55 | LUALIB_API const char *(luaL_checklstring) (lua_State *L, int arg, 56 | size_t *l); 57 | LUALIB_API const char *(luaL_optlstring) (lua_State *L, int arg, 58 | const char *def, size_t *l); 59 | LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int arg); 60 | LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int arg, lua_Number def); 61 | 62 | LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int arg); 63 | LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int arg, 64 | lua_Integer def); 65 | 66 | LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg); 67 | LUALIB_API void (luaL_checktype) (lua_State *L, int arg, int t); 68 | LUALIB_API void (luaL_checkany) (lua_State *L, int arg); 69 | 70 | LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname); 71 | LUALIB_API void (luaL_setmetatable) (lua_State *L, const char *tname); 72 | LUALIB_API void *(luaL_testudata) (lua_State *L, int ud, const char *tname); 73 | LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname); 74 | 75 | LUALIB_API void (luaL_where) (lua_State *L, int lvl); 76 | LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...); 77 | 78 | LUALIB_API int (luaL_checkoption) (lua_State *L, int arg, const char *def, 79 | const char *const lst[]); 80 | 81 | LUALIB_API int (luaL_fileresult) (lua_State *L, int stat, const char *fname); 82 | LUALIB_API int (luaL_execresult) (lua_State *L, int stat); 83 | 84 | 85 | /* predefined references */ 86 | #define LUA_NOREF (-2) 87 | #define LUA_REFNIL (-1) 88 | 89 | LUALIB_API int (luaL_ref) (lua_State *L, int t); 90 | LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref); 91 | 92 | LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename, 93 | const char *mode); 94 | 95 | #define luaL_loadfile(L,f) luaL_loadfilex(L,f,NULL) 96 | 97 | LUALIB_API int (luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz, 98 | const char *name, const char *mode); 99 | LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s); 100 | 101 | LUALIB_API lua_State *(luaL_newstate) (void); 102 | 103 | LUALIB_API lua_Integer (luaL_len) (lua_State *L, int idx); 104 | 105 | LUALIB_API void (luaL_addgsub) (luaL_Buffer *b, const char *s, 106 | const char *p, const char *r); 107 | LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, 108 | const char *p, const char *r); 109 | 110 | LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup); 111 | 112 | LUALIB_API int (luaL_getsubtable) (lua_State *L, int idx, const char *fname); 113 | 114 | LUALIB_API void (luaL_traceback) (lua_State *L, lua_State *L1, 115 | const char *msg, int level); 116 | 117 | LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname, 118 | lua_CFunction openf, int glb); 119 | 120 | /* 121 | ** =============================================================== 122 | ** some useful macros 123 | ** =============================================================== 124 | */ 125 | 126 | 127 | #define luaL_newlibtable(L,l) \ 128 | lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1) 129 | 130 | #define luaL_newlib(L,l) \ 131 | (luaL_checkversion(L), luaL_newlibtable(L,l), luaL_setfuncs(L,l,0)) 132 | 133 | #define luaL_argcheck(L, cond,arg,extramsg) \ 134 | ((void)(luai_likely(cond) || luaL_argerror(L, (arg), (extramsg)))) 135 | 136 | #define luaL_argexpected(L,cond,arg,tname) \ 137 | ((void)(luai_likely(cond) || luaL_typeerror(L, (arg), (tname)))) 138 | 139 | #define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) 140 | #define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) 141 | 142 | #define luaL_typename(L,i) lua_typename(L, lua_type(L,(i))) 143 | 144 | #define luaL_dofile(L, fn) \ 145 | (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0)) 146 | 147 | #define luaL_dostring(L, s) \ 148 | (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0)) 149 | 150 | #define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n))) 151 | 152 | #define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) 153 | 154 | #define luaL_loadbuffer(L,s,sz,n) luaL_loadbufferx(L,s,sz,n,NULL) 155 | 156 | 157 | /* 158 | ** Perform arithmetic operations on lua_Integer values with wrap-around 159 | ** semantics, as the Lua core does. 160 | */ 161 | #define luaL_intop(op,v1,v2) \ 162 | ((lua_Integer)((lua_Unsigned)(v1) op (lua_Unsigned)(v2))) 163 | 164 | 165 | /* push the value used to represent failure/error */ 166 | #define luaL_pushfail(L) lua_pushnil(L) 167 | 168 | 169 | /* 170 | ** Internal assertions for in-house debugging 171 | */ 172 | #if !defined(lua_assert) 173 | 174 | #if defined LUAI_ASSERT 175 | #include 176 | #define lua_assert(c) assert(c) 177 | #else 178 | #define lua_assert(c) ((void)0) 179 | #endif 180 | 181 | #endif 182 | 183 | 184 | 185 | /* 186 | ** {====================================================== 187 | ** Generic Buffer manipulation 188 | ** ======================================================= 189 | */ 190 | 191 | struct luaL_Buffer { 192 | char *b; /* buffer address */ 193 | size_t size; /* buffer size */ 194 | size_t n; /* number of characters in buffer */ 195 | lua_State *L; 196 | union { 197 | LUAI_MAXALIGN; /* ensure maximum alignment for buffer */ 198 | char b[LUAL_BUFFERSIZE]; /* initial buffer */ 199 | } init; 200 | }; 201 | 202 | 203 | #define luaL_bufflen(bf) ((bf)->n) 204 | #define luaL_buffaddr(bf) ((bf)->b) 205 | 206 | 207 | #define luaL_addchar(B,c) \ 208 | ((void)((B)->n < (B)->size || luaL_prepbuffsize((B), 1)), \ 209 | ((B)->b[(B)->n++] = (c))) 210 | 211 | #define luaL_addsize(B,s) ((B)->n += (s)) 212 | 213 | #define luaL_buffsub(B,s) ((B)->n -= (s)) 214 | 215 | LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B); 216 | LUALIB_API char *(luaL_prepbuffsize) (luaL_Buffer *B, size_t sz); 217 | LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l); 218 | LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s); 219 | LUALIB_API void (luaL_addvalue) (luaL_Buffer *B); 220 | LUALIB_API void (luaL_pushresult) (luaL_Buffer *B); 221 | LUALIB_API void (luaL_pushresultsize) (luaL_Buffer *B, size_t sz); 222 | LUALIB_API char *(luaL_buffinitsize) (lua_State *L, luaL_Buffer *B, size_t sz); 223 | 224 | #define luaL_prepbuffer(B) luaL_prepbuffsize(B, LUAL_BUFFERSIZE) 225 | 226 | /* }====================================================== */ 227 | 228 | 229 | 230 | /* 231 | ** {====================================================== 232 | ** File handles for IO library 233 | ** ======================================================= 234 | */ 235 | 236 | /* 237 | ** A file handle is a userdata with metatable 'LUA_FILEHANDLE' and 238 | ** initial structure 'luaL_Stream' (it may contain other fields 239 | ** after that initial structure). 240 | */ 241 | 242 | #define LUA_FILEHANDLE "FILE*" 243 | 244 | 245 | typedef struct luaL_Stream { 246 | FILE *f; /* stream (NULL for incompletely created streams) */ 247 | lua_CFunction closef; /* to close stream (NULL for closed streams) */ 248 | } luaL_Stream; 249 | 250 | /* }====================================================== */ 251 | 252 | /* 253 | ** {================================================================== 254 | ** "Abstraction Layer" for basic report of messages and errors 255 | ** =================================================================== 256 | */ 257 | 258 | /* print a string */ 259 | #if !defined(lua_writestring) 260 | #define lua_writestring(s,l) fwrite((s), sizeof(char), (l), stdout) 261 | #endif 262 | 263 | /* print a newline and flush the output */ 264 | #if !defined(lua_writeline) 265 | #define lua_writeline() (lua_writestring("\n", 1), fflush(stdout)) 266 | #endif 267 | 268 | /* print an error message */ 269 | #if !defined(lua_writestringerror) 270 | #define lua_writestringerror(s,p) \ 271 | (fprintf(stderr, (s), (p)), fflush(stderr)) 272 | #endif 273 | 274 | /* }================================================================== */ 275 | 276 | 277 | /* 278 | ** {============================================================ 279 | ** Compatibility with deprecated conversions 280 | ** ============================================================= 281 | */ 282 | #if defined(LUA_COMPAT_APIINTCASTS) 283 | 284 | #define luaL_checkunsigned(L,a) ((lua_Unsigned)luaL_checkinteger(L,a)) 285 | #define luaL_optunsigned(L,a,d) \ 286 | ((lua_Unsigned)luaL_optinteger(L,a,(lua_Integer)(d))) 287 | 288 | #define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) 289 | #define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) 290 | 291 | #define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n))) 292 | #define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d))) 293 | 294 | #endif 295 | /* }============================================================ */ 296 | 297 | 298 | 299 | #endif 300 | 301 | 302 | -------------------------------------------------------------------------------- /src/lcode.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lcode.h $ 3 | ** Code generator for Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lcode_h 8 | #define lcode_h 9 | 10 | #include "llex.h" 11 | #include "lobject.h" 12 | #include "lopcodes.h" 13 | #include "lparser.h" 14 | 15 | 16 | /* 17 | ** Marks the end of a patch list. It is an invalid value both as an absolute 18 | ** address, and as a list link (would link an element to itself). 19 | */ 20 | #define NO_JUMP (-1) 21 | 22 | 23 | /* 24 | ** grep "ORDER OPR" if you change these enums (ORDER OP) 25 | */ 26 | typedef enum BinOpr { 27 | /* arithmetic operators */ 28 | OPR_ADD, OPR_SUB, OPR_MUL, OPR_MOD, OPR_POW, 29 | OPR_DIV, OPR_IDIV, 30 | /* bitwise operators */ 31 | OPR_BAND, OPR_BOR, OPR_BXOR, 32 | OPR_SHL, OPR_SHR, 33 | /* string operator */ 34 | OPR_CONCAT, 35 | /* comparison operators */ 36 | OPR_EQ, OPR_LT, OPR_LE, 37 | OPR_NE, OPR_GT, OPR_GE, 38 | /* logical operators */ 39 | OPR_AND, OPR_OR, 40 | OPR_NOBINOPR 41 | } BinOpr; 42 | 43 | 44 | /* true if operation is foldable (that is, it is arithmetic or bitwise) */ 45 | #define foldbinop(op) ((op) <= OPR_SHR) 46 | 47 | 48 | #define luaK_codeABC(fs,o,a,b,c) luaK_codeABCk(fs,o,a,b,c,0) 49 | 50 | 51 | typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; 52 | 53 | 54 | /* get (pointer to) instruction of given 'expdesc' */ 55 | #define getinstruction(fs,e) ((fs)->f->code[(e)->u.info]) 56 | 57 | 58 | #define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET) 59 | 60 | #define luaK_jumpto(fs,t) luaK_patchlist(fs, luaK_jump(fs), t) 61 | 62 | LUAI_FUNC int luaK_code (FuncState *fs, Instruction i); 63 | LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); 64 | LUAI_FUNC int luaK_codeABCk (FuncState *fs, OpCode o, int A, 65 | int B, int C, int k); 66 | LUAI_FUNC int luaK_exp2const (FuncState *fs, const expdesc *e, TValue *v); 67 | LUAI_FUNC void luaK_fixline (FuncState *fs, int line); 68 | LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); 69 | LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n); 70 | LUAI_FUNC void luaK_checkstack (FuncState *fs, int n); 71 | LUAI_FUNC void luaK_int (FuncState *fs, int reg, lua_Integer n); 72 | LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e); 73 | LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); 74 | LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e); 75 | LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e); 76 | LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e); 77 | LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key); 78 | LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k); 79 | LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e); 80 | LUAI_FUNC void luaK_goiffalse (FuncState *fs, expdesc *e); 81 | LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e); 82 | LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults); 83 | LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e); 84 | LUAI_FUNC int luaK_jump (FuncState *fs); 85 | LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret); 86 | LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target); 87 | LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list); 88 | LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2); 89 | LUAI_FUNC int luaK_getlabel (FuncState *fs); 90 | LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v, int line); 91 | LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v); 92 | LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, 93 | expdesc *v2, int line); 94 | LUAI_FUNC void luaK_settablesize (FuncState *fs, int pc, 95 | int ra, int asize, int hsize); 96 | LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore); 97 | LUAI_FUNC void luaK_finish (FuncState *fs); 98 | LUAI_FUNC l_noret luaK_semerror (LexState *ls, const char *msg); 99 | 100 | 101 | #endif 102 | -------------------------------------------------------------------------------- /src/lcorolib.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lcorolib.c $ 3 | ** Coroutine Library 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lcorolib_c 8 | #define LUA_LIB 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "lauxlib.h" 18 | #include "lualib.h" 19 | 20 | 21 | static lua_State *getco (lua_State *L) { 22 | lua_State *co = lua_tothread(L, 1); 23 | luaL_argexpected(L, co, 1, "thread"); 24 | return co; 25 | } 26 | 27 | 28 | /* 29 | ** Resumes a coroutine. Returns the number of results for non-error 30 | ** cases or -1 for errors. 31 | */ 32 | static int auxresume (lua_State *L, lua_State *co, int narg) { 33 | int status, nres; 34 | if (l_unlikely(!lua_checkstack(co, narg))) { 35 | lua_pushliteral(L, "too many arguments to resume"); 36 | return -1; /* error flag */ 37 | } 38 | lua_xmove(L, co, narg); 39 | status = lua_resume(co, L, narg, &nres); 40 | if (l_likely(status == LUA_OK || status == LUA_YIELD)) { 41 | if (l_unlikely(!lua_checkstack(L, nres + 1))) { 42 | lua_pop(co, nres); /* remove results anyway */ 43 | lua_pushliteral(L, "too many results to resume"); 44 | return -1; /* error flag */ 45 | } 46 | lua_xmove(co, L, nres); /* move yielded values */ 47 | return nres; 48 | } 49 | else { 50 | lua_xmove(co, L, 1); /* move error message */ 51 | return -1; /* error flag */ 52 | } 53 | } 54 | 55 | 56 | static int luaB_coresume (lua_State *L) { 57 | lua_State *co = getco(L); 58 | int r; 59 | r = auxresume(L, co, lua_gettop(L) - 1); 60 | if (l_unlikely(r < 0)) { 61 | lua_pushboolean(L, 0); 62 | lua_insert(L, -2); 63 | return 2; /* return false + error message */ 64 | } 65 | else { 66 | lua_pushboolean(L, 1); 67 | lua_insert(L, -(r + 1)); 68 | return r + 1; /* return true + 'resume' returns */ 69 | } 70 | } 71 | 72 | 73 | static int luaB_auxwrap (lua_State *L) { 74 | lua_State *co = lua_tothread(L, lua_upvalueindex(1)); 75 | int r = auxresume(L, co, lua_gettop(L)); 76 | if (l_unlikely(r < 0)) { /* error? */ 77 | int stat = lua_status(co); 78 | if (stat != LUA_OK && stat != LUA_YIELD) { /* error in the coroutine? */ 79 | stat = lua_closethread(co, L); /* close its tbc variables */ 80 | lua_assert(stat != LUA_OK); 81 | lua_xmove(co, L, 1); /* move error message to the caller */ 82 | } 83 | if (stat != LUA_ERRMEM && /* not a memory error and ... */ 84 | lua_type(L, -1) == LUA_TSTRING) { /* ... error object is a string? */ 85 | luaL_where(L, 1); /* add extra info, if available */ 86 | lua_insert(L, -2); 87 | lua_concat(L, 2); 88 | } 89 | return lua_error(L); /* propagate error */ 90 | } 91 | return r; 92 | } 93 | 94 | 95 | static int luaB_cocreate (lua_State *L) { 96 | lua_State *NL; 97 | luaL_checktype(L, 1, LUA_TFUNCTION); 98 | NL = lua_newthread(L); 99 | lua_pushvalue(L, 1); /* move function to top */ 100 | lua_xmove(L, NL, 1); /* move function from L to NL */ 101 | return 1; 102 | } 103 | 104 | 105 | static int luaB_cowrap (lua_State *L) { 106 | luaB_cocreate(L); 107 | lua_pushcclosure(L, luaB_auxwrap, 1); 108 | return 1; 109 | } 110 | 111 | 112 | static int luaB_yield (lua_State *L) { 113 | return lua_yield(L, lua_gettop(L)); 114 | } 115 | 116 | 117 | #define COS_RUN 0 118 | #define COS_DEAD 1 119 | #define COS_YIELD 2 120 | #define COS_NORM 3 121 | 122 | 123 | static const char *const statname[] = 124 | {"running", "dead", "suspended", "normal"}; 125 | 126 | 127 | static int auxstatus (lua_State *L, lua_State *co) { 128 | if (L == co) return COS_RUN; 129 | else { 130 | switch (lua_status(co)) { 131 | case LUA_YIELD: 132 | return COS_YIELD; 133 | case LUA_OK: { 134 | lua_Debug ar; 135 | if (lua_getstack(co, 0, &ar)) /* does it have frames? */ 136 | return COS_NORM; /* it is running */ 137 | else if (lua_gettop(co) == 0) 138 | return COS_DEAD; 139 | else 140 | return COS_YIELD; /* initial state */ 141 | } 142 | default: /* some error occurred */ 143 | return COS_DEAD; 144 | } 145 | } 146 | } 147 | 148 | 149 | static int luaB_costatus (lua_State *L) { 150 | lua_State *co = getco(L); 151 | lua_pushstring(L, statname[auxstatus(L, co)]); 152 | return 1; 153 | } 154 | 155 | 156 | static int luaB_yieldable (lua_State *L) { 157 | lua_State *co = lua_isnone(L, 1) ? L : getco(L); 158 | lua_pushboolean(L, lua_isyieldable(co)); 159 | return 1; 160 | } 161 | 162 | 163 | static int luaB_corunning (lua_State *L) { 164 | int ismain = lua_pushthread(L); 165 | lua_pushboolean(L, ismain); 166 | return 2; 167 | } 168 | 169 | 170 | static int luaB_close (lua_State *L) { 171 | lua_State *co = getco(L); 172 | int status = auxstatus(L, co); 173 | switch (status) { 174 | case COS_DEAD: case COS_YIELD: { 175 | status = lua_closethread(co, L); 176 | if (status == LUA_OK) { 177 | lua_pushboolean(L, 1); 178 | return 1; 179 | } 180 | else { 181 | lua_pushboolean(L, 0); 182 | lua_xmove(co, L, 1); /* move error message */ 183 | return 2; 184 | } 185 | } 186 | default: /* normal or running coroutine */ 187 | return luaL_error(L, "cannot close a %s coroutine", statname[status]); 188 | } 189 | } 190 | 191 | 192 | static const luaL_Reg co_funcs[] = { 193 | {"create", luaB_cocreate}, 194 | {"resume", luaB_coresume}, 195 | {"running", luaB_corunning}, 196 | {"status", luaB_costatus}, 197 | {"wrap", luaB_cowrap}, 198 | {"yield", luaB_yield}, 199 | {"isyieldable", luaB_yieldable}, 200 | {"close", luaB_close}, 201 | {NULL, NULL} 202 | }; 203 | 204 | 205 | 206 | LUAMOD_API int luaopen_coroutine (lua_State *L) { 207 | luaL_newlib(L, co_funcs); 208 | return 1; 209 | } 210 | 211 | -------------------------------------------------------------------------------- /src/lctype.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lctype.c $ 3 | ** 'ctype' functions for Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lctype_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include "lctype.h" 14 | 15 | #if !LUA_USE_CTYPE /* { */ 16 | 17 | #include 18 | 19 | 20 | #if defined (LUA_UCID) /* accept UniCode IDentifiers? */ 21 | /* consider all non-ascii codepoints to be alphabetic */ 22 | #define NONA 0x01 23 | #else 24 | #define NONA 0x00 /* default */ 25 | #endif 26 | 27 | 28 | LUAI_DDEF const lu_byte luai_ctype_[UCHAR_MAX + 2] = { 29 | 0x00, /* EOZ */ 30 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0. */ 31 | 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 32 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1. */ 33 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 34 | 0x0c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* 2. */ 35 | 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 36 | 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, /* 3. */ 37 | 0x16, 0x16, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 38 | 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 4. */ 39 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 40 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 5. */ 41 | 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x05, 42 | 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 6. */ 43 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 44 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 7. */ 45 | 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x00, 46 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* 8. */ 47 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, 48 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* 9. */ 49 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, 50 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* a. */ 51 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, 52 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* b. */ 53 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, 54 | 0x00, 0x00, NONA, NONA, NONA, NONA, NONA, NONA, /* c. */ 55 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, 56 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* d. */ 57 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, 58 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* e. */ 59 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, 60 | NONA, NONA, NONA, NONA, NONA, 0x00, 0x00, 0x00, /* f. */ 61 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 62 | }; 63 | 64 | #endif /* } */ 65 | -------------------------------------------------------------------------------- /src/lctype.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lctype.h $ 3 | ** 'ctype' functions for Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lctype_h 8 | #define lctype_h 9 | 10 | #include "lua.h" 11 | 12 | 13 | /* 14 | ** WARNING: the functions defined here do not necessarily correspond 15 | ** to the similar functions in the standard C ctype.h. They are 16 | ** optimized for the specific needs of Lua. 17 | */ 18 | 19 | #if !defined(LUA_USE_CTYPE) 20 | 21 | #if 'A' == 65 && '0' == 48 22 | /* ASCII case: can use its own tables; faster and fixed */ 23 | #define LUA_USE_CTYPE 0 24 | #else 25 | /* must use standard C ctype */ 26 | #define LUA_USE_CTYPE 1 27 | #endif 28 | 29 | #endif 30 | 31 | 32 | #if !LUA_USE_CTYPE /* { */ 33 | 34 | #include 35 | 36 | #include "llimits.h" 37 | 38 | 39 | #define ALPHABIT 0 40 | #define DIGITBIT 1 41 | #define PRINTBIT 2 42 | #define SPACEBIT 3 43 | #define XDIGITBIT 4 44 | 45 | 46 | #define MASK(B) (1 << (B)) 47 | 48 | 49 | /* 50 | ** add 1 to char to allow index -1 (EOZ) 51 | */ 52 | #define testprop(c,p) (luai_ctype_[(c)+1] & (p)) 53 | 54 | /* 55 | ** 'lalpha' (Lua alphabetic) and 'lalnum' (Lua alphanumeric) both include '_' 56 | */ 57 | #define lislalpha(c) testprop(c, MASK(ALPHABIT)) 58 | #define lislalnum(c) testprop(c, (MASK(ALPHABIT) | MASK(DIGITBIT))) 59 | #define lisdigit(c) testprop(c, MASK(DIGITBIT)) 60 | #define lisspace(c) testprop(c, MASK(SPACEBIT)) 61 | #define lisprint(c) testprop(c, MASK(PRINTBIT)) 62 | #define lisxdigit(c) testprop(c, MASK(XDIGITBIT)) 63 | 64 | 65 | /* 66 | ** In ASCII, this 'ltolower' is correct for alphabetic characters and 67 | ** for '.'. That is enough for Lua needs. ('check_exp' ensures that 68 | ** the character either is an upper-case letter or is unchanged by 69 | ** the transformation, which holds for lower-case letters and '.'.) 70 | */ 71 | #define ltolower(c) \ 72 | check_exp(('A' <= (c) && (c) <= 'Z') || (c) == ((c) | ('A' ^ 'a')), \ 73 | (c) | ('A' ^ 'a')) 74 | 75 | 76 | /* one entry for each character and for -1 (EOZ) */ 77 | LUAI_DDEC(const lu_byte luai_ctype_[UCHAR_MAX + 2];) 78 | 79 | 80 | #else /* }{ */ 81 | 82 | /* 83 | ** use standard C ctypes 84 | */ 85 | 86 | #include 87 | 88 | 89 | #define lislalpha(c) (isalpha(c) || (c) == '_') 90 | #define lislalnum(c) (isalnum(c) || (c) == '_') 91 | #define lisdigit(c) (isdigit(c)) 92 | #define lisspace(c) (isspace(c)) 93 | #define lisprint(c) (isprint(c)) 94 | #define lisxdigit(c) (isxdigit(c)) 95 | 96 | #define ltolower(c) (tolower(c)) 97 | 98 | #endif /* } */ 99 | 100 | #endif 101 | 102 | -------------------------------------------------------------------------------- /src/ldebug.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldebug.h $ 3 | ** Auxiliary functions from Debug Interface module 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ldebug_h 8 | #define ldebug_h 9 | 10 | 11 | #include "lstate.h" 12 | 13 | 14 | #define pcRel(pc, p) (cast_int((pc) - (p)->code) - 1) 15 | 16 | 17 | /* Active Lua function (given call info) */ 18 | #define ci_func(ci) (clLvalue(s2v((ci)->func.p))) 19 | 20 | 21 | #define resethookcount(L) (L->hookcount = L->basehookcount) 22 | 23 | /* 24 | ** mark for entries in 'lineinfo' array that has absolute information in 25 | ** 'abslineinfo' array 26 | */ 27 | #define ABSLINEINFO (-0x80) 28 | 29 | 30 | /* 31 | ** MAXimum number of successive Instructions WiTHout ABSolute line 32 | ** information. (A power of two allows fast divisions.) 33 | */ 34 | #if !defined(MAXIWTHABS) 35 | #define MAXIWTHABS 128 36 | #endif 37 | 38 | 39 | LUAI_FUNC int luaG_getfuncline (const Proto *f, int pc); 40 | LUAI_FUNC const char *luaG_findlocal (lua_State *L, CallInfo *ci, int n, 41 | StkId *pos); 42 | LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o, 43 | const char *opname); 44 | LUAI_FUNC l_noret luaG_callerror (lua_State *L, const TValue *o); 45 | LUAI_FUNC l_noret luaG_forerror (lua_State *L, const TValue *o, 46 | const char *what); 47 | LUAI_FUNC l_noret luaG_concaterror (lua_State *L, const TValue *p1, 48 | const TValue *p2); 49 | LUAI_FUNC l_noret luaG_opinterror (lua_State *L, const TValue *p1, 50 | const TValue *p2, 51 | const char *msg); 52 | LUAI_FUNC l_noret luaG_tointerror (lua_State *L, const TValue *p1, 53 | const TValue *p2); 54 | LUAI_FUNC l_noret luaG_ordererror (lua_State *L, const TValue *p1, 55 | const TValue *p2); 56 | LUAI_FUNC l_noret luaG_runerror (lua_State *L, const char *fmt, ...); 57 | LUAI_FUNC const char *luaG_addinfo (lua_State *L, const char *msg, 58 | TString *src, int line); 59 | LUAI_FUNC l_noret luaG_errormsg (lua_State *L); 60 | LUAI_FUNC int luaG_traceexec (lua_State *L, const Instruction *pc); 61 | LUAI_FUNC int luaG_tracecall (lua_State *L); 62 | 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /src/ldo.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldo.h $ 3 | ** Stack and Call structure of Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ldo_h 8 | #define ldo_h 9 | 10 | 11 | #include "llimits.h" 12 | #include "lobject.h" 13 | #include "lstate.h" 14 | #include "lzio.h" 15 | 16 | 17 | /* 18 | ** Macro to check stack size and grow stack if needed. Parameters 19 | ** 'pre'/'pos' allow the macro to preserve a pointer into the 20 | ** stack across reallocations, doing the work only when needed. 21 | ** It also allows the running of one GC step when the stack is 22 | ** reallocated. 23 | ** 'condmovestack' is used in heavy tests to force a stack reallocation 24 | ** at every check. 25 | */ 26 | #define luaD_checkstackaux(L,n,pre,pos) \ 27 | if (l_unlikely(L->stack_last.p - L->top.p <= (n))) \ 28 | { pre; luaD_growstack(L, n, 1); pos; } \ 29 | else { condmovestack(L,pre,pos); } 30 | 31 | /* In general, 'pre'/'pos' are empty (nothing to save) */ 32 | #define luaD_checkstack(L,n) luaD_checkstackaux(L,n,(void)0,(void)0) 33 | 34 | 35 | 36 | #define savestack(L,pt) (cast_charp(pt) - cast_charp(L->stack.p)) 37 | #define restorestack(L,n) cast(StkId, cast_charp(L->stack.p) + (n)) 38 | 39 | 40 | /* macro to check stack size, preserving 'p' */ 41 | #define checkstackp(L,n,p) \ 42 | luaD_checkstackaux(L, n, \ 43 | ptrdiff_t t__ = savestack(L, p), /* save 'p' */ \ 44 | p = restorestack(L, t__)) /* 'pos' part: restore 'p' */ 45 | 46 | 47 | /* macro to check stack size and GC, preserving 'p' */ 48 | #define checkstackGCp(L,n,p) \ 49 | luaD_checkstackaux(L, n, \ 50 | ptrdiff_t t__ = savestack(L, p); /* save 'p' */ \ 51 | luaC_checkGC(L), /* stack grow uses memory */ \ 52 | p = restorestack(L, t__)) /* 'pos' part: restore 'p' */ 53 | 54 | 55 | /* macro to check stack size and GC */ 56 | #define checkstackGC(L,fsize) \ 57 | luaD_checkstackaux(L, (fsize), luaC_checkGC(L), (void)0) 58 | 59 | 60 | /* type of protected functions, to be ran by 'runprotected' */ 61 | typedef void (*Pfunc) (lua_State *L, void *ud); 62 | 63 | LUAI_FUNC void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop); 64 | LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, 65 | const char *mode); 66 | LUAI_FUNC void luaD_hook (lua_State *L, int event, int line, 67 | int fTransfer, int nTransfer); 68 | LUAI_FUNC void luaD_hookcall (lua_State *L, CallInfo *ci); 69 | LUAI_FUNC int luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, 70 | int narg1, int delta); 71 | LUAI_FUNC CallInfo *luaD_precall (lua_State *L, StkId func, int nResults); 72 | LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); 73 | LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults); 74 | LUAI_FUNC int luaD_closeprotected (lua_State *L, ptrdiff_t level, int status); 75 | LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, 76 | ptrdiff_t oldtop, ptrdiff_t ef); 77 | LUAI_FUNC void luaD_poscall (lua_State *L, CallInfo *ci, int nres); 78 | LUAI_FUNC int luaD_reallocstack (lua_State *L, int newsize, int raiseerror); 79 | LUAI_FUNC int luaD_growstack (lua_State *L, int n, int raiseerror); 80 | LUAI_FUNC void luaD_shrinkstack (lua_State *L); 81 | LUAI_FUNC void luaD_inctop (lua_State *L); 82 | 83 | LUAI_FUNC l_noret luaD_throw (lua_State *L, int errcode); 84 | LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud); 85 | 86 | #endif 87 | 88 | -------------------------------------------------------------------------------- /src/ldump.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldump.c $ 3 | ** save precompiled Lua chunks 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define ldump_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | #include 15 | 16 | #include "lua.h" 17 | 18 | #include "lobject.h" 19 | #include "lstate.h" 20 | #include "lundump.h" 21 | 22 | 23 | typedef struct { 24 | lua_State *L; 25 | lua_Writer writer; 26 | void *data; 27 | int strip; 28 | int status; 29 | } DumpState; 30 | 31 | 32 | /* 33 | ** All high-level dumps go through dumpVector; you can change it to 34 | ** change the endianness of the result 35 | */ 36 | #define dumpVector(D,v,n) dumpBlock(D,v,(n)*sizeof((v)[0])) 37 | 38 | #define dumpLiteral(D, s) dumpBlock(D,s,sizeof(s) - sizeof(char)) 39 | 40 | 41 | static void dumpBlock (DumpState *D, const void *b, size_t size) { 42 | if (D->status == 0 && size > 0) { 43 | lua_unlock(D->L); 44 | D->status = (*D->writer)(D->L, b, size, D->data); 45 | lua_lock(D->L); 46 | } 47 | } 48 | 49 | 50 | #define dumpVar(D,x) dumpVector(D,&x,1) 51 | 52 | 53 | static void dumpByte (DumpState *D, int y) { 54 | lu_byte x = (lu_byte)y; 55 | dumpVar(D, x); 56 | } 57 | 58 | 59 | /* 60 | ** 'dumpSize' buffer size: each byte can store up to 7 bits. (The "+6" 61 | ** rounds up the division.) 62 | */ 63 | #define DIBS ((sizeof(size_t) * CHAR_BIT + 6) / 7) 64 | 65 | static void dumpSize (DumpState *D, size_t x) { 66 | lu_byte buff[DIBS]; 67 | int n = 0; 68 | do { 69 | buff[DIBS - (++n)] = x & 0x7f; /* fill buffer in reverse order */ 70 | x >>= 7; 71 | } while (x != 0); 72 | buff[DIBS - 1] |= 0x80; /* mark last byte */ 73 | dumpVector(D, buff + DIBS - n, n); 74 | } 75 | 76 | 77 | static void dumpInt (DumpState *D, int x) { 78 | dumpSize(D, x); 79 | } 80 | 81 | 82 | static void dumpNumber (DumpState *D, lua_Number x) { 83 | dumpVar(D, x); 84 | } 85 | 86 | 87 | static void dumpInteger (DumpState *D, lua_Integer x) { 88 | dumpVar(D, x); 89 | } 90 | 91 | 92 | static void dumpString (DumpState *D, const TString *s) { 93 | if (s == NULL) 94 | dumpSize(D, 0); 95 | else { 96 | size_t size = tsslen(s); 97 | const char *str = getstr(s); 98 | dumpSize(D, size + 1); 99 | dumpVector(D, str, size); 100 | } 101 | } 102 | 103 | 104 | static void dumpCode (DumpState *D, const Proto *f) { 105 | dumpInt(D, f->sizecode); 106 | dumpVector(D, f->code, f->sizecode); 107 | } 108 | 109 | 110 | static void dumpFunction(DumpState *D, const Proto *f, TString *psource); 111 | 112 | static void dumpConstants (DumpState *D, const Proto *f) { 113 | int i; 114 | int n = f->sizek; 115 | dumpInt(D, n); 116 | for (i = 0; i < n; i++) { 117 | const TValue *o = &f->k[i]; 118 | int tt = ttypetag(o); 119 | dumpByte(D, tt); 120 | switch (tt) { 121 | case LUA_VNUMFLT: 122 | dumpNumber(D, fltvalue(o)); 123 | break; 124 | case LUA_VNUMINT: 125 | dumpInteger(D, ivalue(o)); 126 | break; 127 | case LUA_VSHRSTR: 128 | case LUA_VLNGSTR: 129 | dumpString(D, tsvalue(o)); 130 | break; 131 | default: 132 | lua_assert(tt == LUA_VNIL || tt == LUA_VFALSE || tt == LUA_VTRUE); 133 | } 134 | } 135 | } 136 | 137 | 138 | static void dumpProtos (DumpState *D, const Proto *f) { 139 | int i; 140 | int n = f->sizep; 141 | dumpInt(D, n); 142 | for (i = 0; i < n; i++) 143 | dumpFunction(D, f->p[i], f->source); 144 | } 145 | 146 | 147 | static void dumpUpvalues (DumpState *D, const Proto *f) { 148 | int i, n = f->sizeupvalues; 149 | dumpInt(D, n); 150 | for (i = 0; i < n; i++) { 151 | dumpByte(D, f->upvalues[i].instack); 152 | dumpByte(D, f->upvalues[i].idx); 153 | dumpByte(D, f->upvalues[i].kind); 154 | } 155 | } 156 | 157 | 158 | static void dumpDebug (DumpState *D, const Proto *f) { 159 | int i, n; 160 | n = (D->strip) ? 0 : f->sizelineinfo; 161 | dumpInt(D, n); 162 | dumpVector(D, f->lineinfo, n); 163 | n = (D->strip) ? 0 : f->sizeabslineinfo; 164 | dumpInt(D, n); 165 | for (i = 0; i < n; i++) { 166 | dumpInt(D, f->abslineinfo[i].pc); 167 | dumpInt(D, f->abslineinfo[i].line); 168 | } 169 | n = (D->strip) ? 0 : f->sizelocvars; 170 | dumpInt(D, n); 171 | for (i = 0; i < n; i++) { 172 | dumpString(D, f->locvars[i].varname); 173 | dumpInt(D, f->locvars[i].startpc); 174 | dumpInt(D, f->locvars[i].endpc); 175 | } 176 | n = (D->strip) ? 0 : f->sizeupvalues; 177 | dumpInt(D, n); 178 | for (i = 0; i < n; i++) 179 | dumpString(D, f->upvalues[i].name); 180 | } 181 | 182 | 183 | static void dumpFunction (DumpState *D, const Proto *f, TString *psource) { 184 | if (D->strip || f->source == psource) 185 | dumpString(D, NULL); /* no debug info or same source as its parent */ 186 | else 187 | dumpString(D, f->source); 188 | dumpInt(D, f->linedefined); 189 | dumpInt(D, f->lastlinedefined); 190 | dumpByte(D, f->numparams); 191 | dumpByte(D, f->is_vararg); 192 | dumpByte(D, f->maxstacksize); 193 | dumpCode(D, f); 194 | dumpConstants(D, f); 195 | dumpUpvalues(D, f); 196 | dumpProtos(D, f); 197 | dumpDebug(D, f); 198 | } 199 | 200 | 201 | static void dumpHeader (DumpState *D) { 202 | dumpLiteral(D, LUA_SIGNATURE); 203 | dumpByte(D, LUAC_VERSION); 204 | dumpByte(D, LUAC_FORMAT); 205 | dumpLiteral(D, LUAC_DATA); 206 | dumpByte(D, sizeof(Instruction)); 207 | dumpByte(D, sizeof(lua_Integer)); 208 | dumpByte(D, sizeof(lua_Number)); 209 | dumpInteger(D, LUAC_INT); 210 | dumpNumber(D, LUAC_NUM); 211 | } 212 | 213 | 214 | /* 215 | ** dump Lua function as precompiled chunk 216 | */ 217 | int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data, 218 | int strip) { 219 | DumpState D; 220 | D.L = L; 221 | D.writer = w; 222 | D.data = data; 223 | D.strip = strip; 224 | D.status = 0; 225 | dumpHeader(&D); 226 | dumpByte(&D, f->sizeupvalues); 227 | dumpFunction(&D, f, NULL); 228 | return D.status; 229 | } 230 | 231 | -------------------------------------------------------------------------------- /src/lfunc.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lfunc.c $ 3 | ** Auxiliary functions to manipulate prototypes and closures 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lfunc_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "ldebug.h" 18 | #include "ldo.h" 19 | #include "lfunc.h" 20 | #include "lgc.h" 21 | #include "lmem.h" 22 | #include "lobject.h" 23 | #include "lstate.h" 24 | 25 | 26 | 27 | CClosure *luaF_newCclosure (lua_State *L, int nupvals) { 28 | GCObject *o = luaC_newobj(L, LUA_VCCL, sizeCclosure(nupvals)); 29 | CClosure *c = gco2ccl(o); 30 | c->nupvalues = cast_byte(nupvals); 31 | return c; 32 | } 33 | 34 | 35 | LClosure *luaF_newLclosure (lua_State *L, int nupvals) { 36 | GCObject *o = luaC_newobj(L, LUA_VLCL, sizeLclosure(nupvals)); 37 | LClosure *c = gco2lcl(o); 38 | c->p = NULL; 39 | c->nupvalues = cast_byte(nupvals); 40 | while (nupvals--) c->upvals[nupvals] = NULL; 41 | return c; 42 | } 43 | 44 | 45 | /* 46 | ** fill a closure with new closed upvalues 47 | */ 48 | void luaF_initupvals (lua_State *L, LClosure *cl) { 49 | int i; 50 | for (i = 0; i < cl->nupvalues; i++) { 51 | GCObject *o = luaC_newobj(L, LUA_VUPVAL, sizeof(UpVal)); 52 | UpVal *uv = gco2upv(o); 53 | uv->v.p = &uv->u.value; /* make it closed */ 54 | setnilvalue(uv->v.p); 55 | cl->upvals[i] = uv; 56 | luaC_objbarrier(L, cl, uv); 57 | } 58 | } 59 | 60 | 61 | /* 62 | ** Create a new upvalue at the given level, and link it to the list of 63 | ** open upvalues of 'L' after entry 'prev'. 64 | **/ 65 | static UpVal *newupval (lua_State *L, StkId level, UpVal **prev) { 66 | GCObject *o = luaC_newobj(L, LUA_VUPVAL, sizeof(UpVal)); 67 | UpVal *uv = gco2upv(o); 68 | UpVal *next = *prev; 69 | uv->v.p = s2v(level); /* current value lives in the stack */ 70 | uv->u.open.next = next; /* link it to list of open upvalues */ 71 | uv->u.open.previous = prev; 72 | if (next) 73 | next->u.open.previous = &uv->u.open.next; 74 | *prev = uv; 75 | if (!isintwups(L)) { /* thread not in list of threads with upvalues? */ 76 | L->twups = G(L)->twups; /* link it to the list */ 77 | G(L)->twups = L; 78 | } 79 | return uv; 80 | } 81 | 82 | 83 | /* 84 | ** Find and reuse, or create if it does not exist, an upvalue 85 | ** at the given level. 86 | */ 87 | UpVal *luaF_findupval (lua_State *L, StkId level) { 88 | UpVal **pp = &L->openupval; 89 | UpVal *p; 90 | lua_assert(isintwups(L) || L->openupval == NULL); 91 | while ((p = *pp) != NULL && uplevel(p) >= level) { /* search for it */ 92 | lua_assert(!isdead(G(L), p)); 93 | if (uplevel(p) == level) /* corresponding upvalue? */ 94 | return p; /* return it */ 95 | pp = &p->u.open.next; 96 | } 97 | /* not found: create a new upvalue after 'pp' */ 98 | return newupval(L, level, pp); 99 | } 100 | 101 | 102 | /* 103 | ** Call closing method for object 'obj' with error message 'err'. The 104 | ** boolean 'yy' controls whether the call is yieldable. 105 | ** (This function assumes EXTRA_STACK.) 106 | */ 107 | static void callclosemethod (lua_State *L, TValue *obj, TValue *err, int yy) { 108 | StkId top = L->top.p; 109 | const TValue *tm = luaT_gettmbyobj(L, obj, TM_CLOSE); 110 | setobj2s(L, top, tm); /* will call metamethod... */ 111 | setobj2s(L, top + 1, obj); /* with 'self' as the 1st argument */ 112 | setobj2s(L, top + 2, err); /* and error msg. as 2nd argument */ 113 | L->top.p = top + 3; /* add function and arguments */ 114 | if (yy) 115 | luaD_call(L, top, 0); 116 | else 117 | luaD_callnoyield(L, top, 0); 118 | } 119 | 120 | 121 | /* 122 | ** Check whether object at given level has a close metamethod and raise 123 | ** an error if not. 124 | */ 125 | static void checkclosemth (lua_State *L, StkId level) { 126 | const TValue *tm = luaT_gettmbyobj(L, s2v(level), TM_CLOSE); 127 | if (ttisnil(tm)) { /* no metamethod? */ 128 | int idx = cast_int(level - L->ci->func.p); /* variable index */ 129 | const char *vname = luaG_findlocal(L, L->ci, idx, NULL); 130 | if (vname == NULL) vname = "?"; 131 | luaG_runerror(L, "variable '%s' got a non-closable value", vname); 132 | } 133 | } 134 | 135 | 136 | /* 137 | ** Prepare and call a closing method. 138 | ** If status is CLOSEKTOP, the call to the closing method will be pushed 139 | ** at the top of the stack. Otherwise, values can be pushed right after 140 | ** the 'level' of the upvalue being closed, as everything after that 141 | ** won't be used again. 142 | */ 143 | static void prepcallclosemth (lua_State *L, StkId level, int status, int yy) { 144 | TValue *uv = s2v(level); /* value being closed */ 145 | TValue *errobj; 146 | if (status == CLOSEKTOP) 147 | errobj = &G(L)->nilvalue; /* error object is nil */ 148 | else { /* 'luaD_seterrorobj' will set top to level + 2 */ 149 | errobj = s2v(level + 1); /* error object goes after 'uv' */ 150 | luaD_seterrorobj(L, status, level + 1); /* set error object */ 151 | } 152 | callclosemethod(L, uv, errobj, yy); 153 | } 154 | 155 | 156 | /* 157 | ** Maximum value for deltas in 'tbclist', dependent on the type 158 | ** of delta. (This macro assumes that an 'L' is in scope where it 159 | ** is used.) 160 | */ 161 | #define MAXDELTA \ 162 | ((256ul << ((sizeof(L->stack.p->tbclist.delta) - 1) * 8)) - 1) 163 | 164 | 165 | /* 166 | ** Insert a variable in the list of to-be-closed variables. 167 | */ 168 | void luaF_newtbcupval (lua_State *L, StkId level) { 169 | lua_assert(level > L->tbclist.p); 170 | if (l_isfalse(s2v(level))) 171 | return; /* false doesn't need to be closed */ 172 | checkclosemth(L, level); /* value must have a close method */ 173 | while (cast_uint(level - L->tbclist.p) > MAXDELTA) { 174 | L->tbclist.p += MAXDELTA; /* create a dummy node at maximum delta */ 175 | L->tbclist.p->tbclist.delta = 0; 176 | } 177 | level->tbclist.delta = cast(unsigned short, level - L->tbclist.p); 178 | L->tbclist.p = level; 179 | } 180 | 181 | 182 | void luaF_unlinkupval (UpVal *uv) { 183 | lua_assert(upisopen(uv)); 184 | *uv->u.open.previous = uv->u.open.next; 185 | if (uv->u.open.next) 186 | uv->u.open.next->u.open.previous = uv->u.open.previous; 187 | } 188 | 189 | 190 | /* 191 | ** Close all upvalues up to the given stack level. 192 | */ 193 | void luaF_closeupval (lua_State *L, StkId level) { 194 | UpVal *uv; 195 | StkId upl; /* stack index pointed by 'uv' */ 196 | while ((uv = L->openupval) != NULL && (upl = uplevel(uv)) >= level) { 197 | TValue *slot = &uv->u.value; /* new position for value */ 198 | lua_assert(uplevel(uv) < L->top.p); 199 | luaF_unlinkupval(uv); /* remove upvalue from 'openupval' list */ 200 | setobj(L, slot, uv->v.p); /* move value to upvalue slot */ 201 | uv->v.p = slot; /* now current value lives here */ 202 | if (!iswhite(uv)) { /* neither white nor dead? */ 203 | nw2black(uv); /* closed upvalues cannot be gray */ 204 | luaC_barrier(L, uv, slot); 205 | } 206 | } 207 | } 208 | 209 | 210 | /* 211 | ** Remove first element from the tbclist plus its dummy nodes. 212 | */ 213 | static void poptbclist (lua_State *L) { 214 | StkId tbc = L->tbclist.p; 215 | lua_assert(tbc->tbclist.delta > 0); /* first element cannot be dummy */ 216 | tbc -= tbc->tbclist.delta; 217 | while (tbc > L->stack.p && tbc->tbclist.delta == 0) 218 | tbc -= MAXDELTA; /* remove dummy nodes */ 219 | L->tbclist.p = tbc; 220 | } 221 | 222 | 223 | /* 224 | ** Close all upvalues and to-be-closed variables up to the given stack 225 | ** level. Return restored 'level'. 226 | */ 227 | StkId luaF_close (lua_State *L, StkId level, int status, int yy) { 228 | ptrdiff_t levelrel = savestack(L, level); 229 | luaF_closeupval(L, level); /* first, close the upvalues */ 230 | while (L->tbclist.p >= level) { /* traverse tbc's down to that level */ 231 | StkId tbc = L->tbclist.p; /* get variable index */ 232 | poptbclist(L); /* remove it from list */ 233 | prepcallclosemth(L, tbc, status, yy); /* close variable */ 234 | level = restorestack(L, levelrel); 235 | } 236 | return level; 237 | } 238 | 239 | 240 | Proto *luaF_newproto (lua_State *L) { 241 | GCObject *o = luaC_newobj(L, LUA_VPROTO, sizeof(Proto)); 242 | Proto *f = gco2p(o); 243 | f->k = NULL; 244 | f->sizek = 0; 245 | f->p = NULL; 246 | f->sizep = 0; 247 | f->code = NULL; 248 | f->sizecode = 0; 249 | f->lineinfo = NULL; 250 | f->sizelineinfo = 0; 251 | f->abslineinfo = NULL; 252 | f->sizeabslineinfo = 0; 253 | f->upvalues = NULL; 254 | f->sizeupvalues = 0; 255 | f->numparams = 0; 256 | f->is_vararg = 0; 257 | f->maxstacksize = 0; 258 | f->locvars = NULL; 259 | f->sizelocvars = 0; 260 | f->linedefined = 0; 261 | f->lastlinedefined = 0; 262 | f->source = NULL; 263 | return f; 264 | } 265 | 266 | 267 | void luaF_freeproto (lua_State *L, Proto *f) { 268 | luaM_freearray(L, f->code, f->sizecode); 269 | luaM_freearray(L, f->p, f->sizep); 270 | luaM_freearray(L, f->k, f->sizek); 271 | luaM_freearray(L, f->lineinfo, f->sizelineinfo); 272 | luaM_freearray(L, f->abslineinfo, f->sizeabslineinfo); 273 | luaM_freearray(L, f->locvars, f->sizelocvars); 274 | luaM_freearray(L, f->upvalues, f->sizeupvalues); 275 | luaM_free(L, f); 276 | } 277 | 278 | 279 | /* 280 | ** Look for n-th local variable at line 'line' in function 'func'. 281 | ** Returns NULL if not found. 282 | */ 283 | const char *luaF_getlocalname (const Proto *f, int local_number, int pc) { 284 | int i; 285 | for (i = 0; isizelocvars && f->locvars[i].startpc <= pc; i++) { 286 | if (pc < f->locvars[i].endpc) { /* is variable active? */ 287 | local_number--; 288 | if (local_number == 0) 289 | return getstr(f->locvars[i].varname); 290 | } 291 | } 292 | return NULL; /* not found */ 293 | } 294 | 295 | -------------------------------------------------------------------------------- /src/lfunc.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lfunc.h $ 3 | ** Auxiliary functions to manipulate prototypes and closures 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lfunc_h 8 | #define lfunc_h 9 | 10 | 11 | #include "lobject.h" 12 | 13 | 14 | #define sizeCclosure(n) (cast_int(offsetof(CClosure, upvalue)) + \ 15 | cast_int(sizeof(TValue)) * (n)) 16 | 17 | #define sizeLclosure(n) (cast_int(offsetof(LClosure, upvals)) + \ 18 | cast_int(sizeof(TValue *)) * (n)) 19 | 20 | 21 | /* test whether thread is in 'twups' list */ 22 | #define isintwups(L) (L->twups != L) 23 | 24 | 25 | /* 26 | ** maximum number of upvalues in a closure (both C and Lua). (Value 27 | ** must fit in a VM register.) 28 | */ 29 | #define MAXUPVAL 255 30 | 31 | 32 | #define upisopen(up) ((up)->v.p != &(up)->u.value) 33 | 34 | 35 | #define uplevel(up) check_exp(upisopen(up), cast(StkId, (up)->v.p)) 36 | 37 | 38 | /* 39 | ** maximum number of misses before giving up the cache of closures 40 | ** in prototypes 41 | */ 42 | #define MAXMISS 10 43 | 44 | 45 | 46 | /* special status to close upvalues preserving the top of the stack */ 47 | #define CLOSEKTOP (-1) 48 | 49 | 50 | LUAI_FUNC Proto *luaF_newproto (lua_State *L); 51 | LUAI_FUNC CClosure *luaF_newCclosure (lua_State *L, int nupvals); 52 | LUAI_FUNC LClosure *luaF_newLclosure (lua_State *L, int nupvals); 53 | LUAI_FUNC void luaF_initupvals (lua_State *L, LClosure *cl); 54 | LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); 55 | LUAI_FUNC void luaF_newtbcupval (lua_State *L, StkId level); 56 | LUAI_FUNC void luaF_closeupval (lua_State *L, StkId level); 57 | LUAI_FUNC StkId luaF_close (lua_State *L, StkId level, int status, int yy); 58 | LUAI_FUNC void luaF_unlinkupval (UpVal *uv); 59 | LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f); 60 | LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number, 61 | int pc); 62 | 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /src/lgc.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lgc.h $ 3 | ** Garbage Collector 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lgc_h 8 | #define lgc_h 9 | 10 | 11 | #include "lobject.h" 12 | #include "lstate.h" 13 | 14 | /* 15 | ** Collectable objects may have one of three colors: white, which means 16 | ** the object is not marked; gray, which means the object is marked, but 17 | ** its references may be not marked; and black, which means that the 18 | ** object and all its references are marked. The main invariant of the 19 | ** garbage collector, while marking objects, is that a black object can 20 | ** never point to a white one. Moreover, any gray object must be in a 21 | ** "gray list" (gray, grayagain, weak, allweak, ephemeron) so that it 22 | ** can be visited again before finishing the collection cycle. (Open 23 | ** upvalues are an exception to this rule.) These lists have no meaning 24 | ** when the invariant is not being enforced (e.g., sweep phase). 25 | */ 26 | 27 | 28 | /* 29 | ** Possible states of the Garbage Collector 30 | */ 31 | #define GCSpropagate 0 32 | #define GCSenteratomic 1 33 | #define GCSatomic 2 34 | #define GCSswpallgc 3 35 | #define GCSswpfinobj 4 36 | #define GCSswptobefnz 5 37 | #define GCSswpend 6 38 | #define GCScallfin 7 39 | #define GCSpause 8 40 | 41 | 42 | #define issweepphase(g) \ 43 | (GCSswpallgc <= (g)->gcstate && (g)->gcstate <= GCSswpend) 44 | 45 | 46 | /* 47 | ** macro to tell when main invariant (white objects cannot point to black 48 | ** ones) must be kept. During a collection, the sweep 49 | ** phase may break the invariant, as objects turned white may point to 50 | ** still-black objects. The invariant is restored when sweep ends and 51 | ** all objects are white again. 52 | */ 53 | 54 | #define keepinvariant(g) ((g)->gcstate <= GCSatomic) 55 | 56 | 57 | /* 58 | ** some useful bit tricks 59 | */ 60 | #define resetbits(x,m) ((x) &= cast_byte(~(m))) 61 | #define setbits(x,m) ((x) |= (m)) 62 | #define testbits(x,m) ((x) & (m)) 63 | #define bitmask(b) (1<<(b)) 64 | #define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2)) 65 | #define l_setbit(x,b) setbits(x, bitmask(b)) 66 | #define resetbit(x,b) resetbits(x, bitmask(b)) 67 | #define testbit(x,b) testbits(x, bitmask(b)) 68 | 69 | 70 | /* 71 | ** Layout for bit use in 'marked' field. First three bits are 72 | ** used for object "age" in generational mode. Last bit is used 73 | ** by tests. 74 | */ 75 | #define WHITE0BIT 3 /* object is white (type 0) */ 76 | #define WHITE1BIT 4 /* object is white (type 1) */ 77 | #define BLACKBIT 5 /* object is black */ 78 | #define FINALIZEDBIT 6 /* object has been marked for finalization */ 79 | 80 | #define TESTBIT 7 81 | 82 | 83 | 84 | #define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) 85 | 86 | 87 | #define iswhite(x) testbits((x)->marked, WHITEBITS) 88 | #define isblack(x) testbit((x)->marked, BLACKBIT) 89 | #define isgray(x) /* neither white nor black */ \ 90 | (!testbits((x)->marked, WHITEBITS | bitmask(BLACKBIT))) 91 | 92 | #define tofinalize(x) testbit((x)->marked, FINALIZEDBIT) 93 | 94 | #define otherwhite(g) ((g)->currentwhite ^ WHITEBITS) 95 | #define isdeadm(ow,m) ((m) & (ow)) 96 | #define isdead(g,v) isdeadm(otherwhite(g), (v)->marked) 97 | 98 | #define changewhite(x) ((x)->marked ^= WHITEBITS) 99 | #define nw2black(x) \ 100 | check_exp(!iswhite(x), l_setbit((x)->marked, BLACKBIT)) 101 | 102 | #define luaC_white(g) cast_byte((g)->currentwhite & WHITEBITS) 103 | 104 | 105 | /* object age in generational mode */ 106 | #define G_NEW 0 /* created in current cycle */ 107 | #define G_SURVIVAL 1 /* created in previous cycle */ 108 | #define G_OLD0 2 /* marked old by frw. barrier in this cycle */ 109 | #define G_OLD1 3 /* first full cycle as old */ 110 | #define G_OLD 4 /* really old object (not to be visited) */ 111 | #define G_TOUCHED1 5 /* old object touched this cycle */ 112 | #define G_TOUCHED2 6 /* old object touched in previous cycle */ 113 | 114 | #define AGEBITS 7 /* all age bits (111) */ 115 | 116 | #define getage(o) ((o)->marked & AGEBITS) 117 | #define setage(o,a) ((o)->marked = cast_byte(((o)->marked & (~AGEBITS)) | a)) 118 | #define isold(o) (getage(o) > G_SURVIVAL) 119 | 120 | #define changeage(o,f,t) \ 121 | check_exp(getage(o) == (f), (o)->marked ^= ((f)^(t))) 122 | 123 | 124 | /* Default Values for GC parameters */ 125 | #define LUAI_GENMAJORMUL 100 126 | #define LUAI_GENMINORMUL 20 127 | 128 | /* wait memory to double before starting new cycle */ 129 | #define LUAI_GCPAUSE 200 130 | 131 | /* 132 | ** some gc parameters are stored divided by 4 to allow a maximum value 133 | ** up to 1023 in a 'lu_byte'. 134 | */ 135 | #define getgcparam(p) ((p) * 4) 136 | #define setgcparam(p,v) ((p) = (v) / 4) 137 | 138 | #define LUAI_GCMUL 100 139 | 140 | /* how much to allocate before next GC step (log2) */ 141 | #define LUAI_GCSTEPSIZE 13 /* 8 KB */ 142 | 143 | 144 | /* 145 | ** Check whether the declared GC mode is generational. While in 146 | ** generational mode, the collector can go temporarily to incremental 147 | ** mode to improve performance. This is signaled by 'g->lastatomic != 0'. 148 | */ 149 | #define isdecGCmodegen(g) (g->gckind == KGC_GEN || g->lastatomic != 0) 150 | 151 | 152 | /* 153 | ** Control when GC is running: 154 | */ 155 | #define GCSTPUSR 1 /* bit true when GC stopped by user */ 156 | #define GCSTPGC 2 /* bit true when GC stopped by itself */ 157 | #define GCSTPCLS 4 /* bit true when closing Lua state */ 158 | #define gcrunning(g) ((g)->gcstp == 0) 159 | 160 | 161 | /* 162 | ** Does one step of collection when debt becomes positive. 'pre'/'pos' 163 | ** allows some adjustments to be done only when needed. macro 164 | ** 'condchangemem' is used only for heavy tests (forcing a full 165 | ** GC cycle on every opportunity) 166 | */ 167 | #define luaC_condGC(L,pre,pos) \ 168 | { if (G(L)->GCdebt > 0) { pre; luaC_step(L); pos;}; \ 169 | condchangemem(L,pre,pos); } 170 | 171 | /* more often than not, 'pre'/'pos' are empty */ 172 | #define luaC_checkGC(L) luaC_condGC(L,(void)0,(void)0) 173 | 174 | 175 | #define luaC_objbarrier(L,p,o) ( \ 176 | (isblack(p) && iswhite(o)) ? \ 177 | luaC_barrier_(L,obj2gco(p),obj2gco(o)) : cast_void(0)) 178 | 179 | #define luaC_barrier(L,p,v) ( \ 180 | iscollectable(v) ? luaC_objbarrier(L,p,gcvalue(v)) : cast_void(0)) 181 | 182 | #define luaC_objbarrierback(L,p,o) ( \ 183 | (isblack(p) && iswhite(o)) ? luaC_barrierback_(L,p) : cast_void(0)) 184 | 185 | #define luaC_barrierback(L,p,v) ( \ 186 | iscollectable(v) ? luaC_objbarrierback(L, p, gcvalue(v)) : cast_void(0)) 187 | 188 | LUAI_FUNC void luaC_fix (lua_State *L, GCObject *o); 189 | LUAI_FUNC void luaC_freeallobjects (lua_State *L); 190 | LUAI_FUNC void luaC_step (lua_State *L); 191 | LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask); 192 | LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency); 193 | LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz); 194 | LUAI_FUNC GCObject *luaC_newobjdt (lua_State *L, int tt, size_t sz, 195 | size_t offset); 196 | LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v); 197 | LUAI_FUNC void luaC_barrierback_ (lua_State *L, GCObject *o); 198 | LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt); 199 | LUAI_FUNC void luaC_changemode (lua_State *L, int newmode); 200 | 201 | 202 | #endif 203 | -------------------------------------------------------------------------------- /src/linit.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: linit.c $ 3 | ** Initialization of libraries for lua.c and other clients 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #define linit_c 9 | #define LUA_LIB 10 | 11 | /* 12 | ** If you embed Lua in your program and need to open the standard 13 | ** libraries, call luaL_openlibs in your program. If you need a 14 | ** different set of libraries, copy this file to your project and edit 15 | ** it to suit your needs. 16 | ** 17 | ** You can also *preload* libraries, so that a later 'require' can 18 | ** open the library, which is already linked to the application. 19 | ** For that, do the following code: 20 | ** 21 | ** luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE); 22 | ** lua_pushcfunction(L, luaopen_modname); 23 | ** lua_setfield(L, -2, modname); 24 | ** lua_pop(L, 1); // remove PRELOAD table 25 | */ 26 | 27 | #include "lprefix.h" 28 | 29 | 30 | #include 31 | 32 | #include "lua.h" 33 | 34 | #include "lualib.h" 35 | #include "lauxlib.h" 36 | 37 | 38 | /* 39 | ** these libs are loaded by lua.c and are readily available to any Lua 40 | ** program 41 | */ 42 | static const luaL_Reg loadedlibs[] = { 43 | {LUA_GNAME, luaopen_base}, 44 | {LUA_LOADLIBNAME, luaopen_package}, 45 | {LUA_COLIBNAME, luaopen_coroutine}, 46 | {LUA_TABLIBNAME, luaopen_table}, 47 | {LUA_IOLIBNAME, luaopen_io}, 48 | {LUA_OSLIBNAME, luaopen_os}, 49 | {LUA_STRLIBNAME, luaopen_string}, 50 | {LUA_MATHLIBNAME, luaopen_math}, 51 | {LUA_UTF8LIBNAME, luaopen_utf8}, 52 | {LUA_DBLIBNAME, luaopen_debug}, 53 | {NULL, NULL} 54 | }; 55 | 56 | 57 | LUALIB_API void luaL_openlibs (lua_State *L) { 58 | const luaL_Reg *lib; 59 | /* "require" functions from 'loadedlibs' and set results to global table */ 60 | for (lib = loadedlibs; lib->func; lib++) { 61 | luaL_requiref(L, lib->name, lib->func, 1); 62 | lua_pop(L, 1); /* remove lib */ 63 | } 64 | } 65 | 66 | -------------------------------------------------------------------------------- /src/ljumptab.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ljumptab.h $ 3 | ** Jump Table for the Lua interpreter 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #undef vmdispatch 9 | #undef vmcase 10 | #undef vmbreak 11 | 12 | #define vmdispatch(x) goto *disptab[x]; 13 | 14 | #define vmcase(l) L_##l: 15 | 16 | #define vmbreak vmfetch(); vmdispatch(GET_OPCODE(i)); 17 | 18 | 19 | static const void *const disptab[NUM_OPCODES] = { 20 | 21 | #if 0 22 | ** you can update the following list with this command: 23 | ** 24 | ** sed -n '/^OP_/\!d; s/OP_/\&\&L_OP_/ ; s/,.*/,/ ; s/\/.*// ; p' lopcodes.h 25 | ** 26 | #endif 27 | 28 | &&L_OP_MOVE, 29 | &&L_OP_LOADI, 30 | &&L_OP_LOADF, 31 | &&L_OP_LOADK, 32 | &&L_OP_LOADKX, 33 | &&L_OP_LOADFALSE, 34 | &&L_OP_LFALSESKIP, 35 | &&L_OP_LOADTRUE, 36 | &&L_OP_LOADNIL, 37 | &&L_OP_GETUPVAL, 38 | &&L_OP_SETUPVAL, 39 | &&L_OP_GETTABUP, 40 | &&L_OP_GETTABLE, 41 | &&L_OP_GETI, 42 | &&L_OP_GETFIELD, 43 | &&L_OP_SETTABUP, 44 | &&L_OP_SETTABLE, 45 | &&L_OP_SETI, 46 | &&L_OP_SETFIELD, 47 | &&L_OP_NEWTABLE, 48 | &&L_OP_SELF, 49 | &&L_OP_ADDI, 50 | &&L_OP_ADDK, 51 | &&L_OP_SUBK, 52 | &&L_OP_MULK, 53 | &&L_OP_MODK, 54 | &&L_OP_POWK, 55 | &&L_OP_DIVK, 56 | &&L_OP_IDIVK, 57 | &&L_OP_BANDK, 58 | &&L_OP_BORK, 59 | &&L_OP_BXORK, 60 | &&L_OP_SHRI, 61 | &&L_OP_SHLI, 62 | &&L_OP_ADD, 63 | &&L_OP_SUB, 64 | &&L_OP_MUL, 65 | &&L_OP_MOD, 66 | &&L_OP_POW, 67 | &&L_OP_DIV, 68 | &&L_OP_IDIV, 69 | &&L_OP_BAND, 70 | &&L_OP_BOR, 71 | &&L_OP_BXOR, 72 | &&L_OP_SHL, 73 | &&L_OP_SHR, 74 | &&L_OP_MMBIN, 75 | &&L_OP_MMBINI, 76 | &&L_OP_MMBINK, 77 | &&L_OP_UNM, 78 | &&L_OP_BNOT, 79 | &&L_OP_NOT, 80 | &&L_OP_LEN, 81 | &&L_OP_CONCAT, 82 | &&L_OP_CLOSE, 83 | &&L_OP_TBC, 84 | &&L_OP_JMP, 85 | &&L_OP_EQ, 86 | &&L_OP_LT, 87 | &&L_OP_LE, 88 | &&L_OP_EQK, 89 | &&L_OP_EQI, 90 | &&L_OP_LTI, 91 | &&L_OP_LEI, 92 | &&L_OP_GTI, 93 | &&L_OP_GEI, 94 | &&L_OP_TEST, 95 | &&L_OP_TESTSET, 96 | &&L_OP_CALL, 97 | &&L_OP_TAILCALL, 98 | &&L_OP_RETURN, 99 | &&L_OP_RETURN0, 100 | &&L_OP_RETURN1, 101 | &&L_OP_FORLOOP, 102 | &&L_OP_FORPREP, 103 | &&L_OP_TFORPREP, 104 | &&L_OP_TFORCALL, 105 | &&L_OP_TFORLOOP, 106 | &&L_OP_SETLIST, 107 | &&L_OP_CLOSURE, 108 | &&L_OP_VARARG, 109 | &&L_OP_VARARGPREP, 110 | &&L_OP_EXTRAARG 111 | 112 | }; 113 | -------------------------------------------------------------------------------- /src/llex.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: llex.h $ 3 | ** Lexical Analyzer 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef llex_h 8 | #define llex_h 9 | 10 | #include 11 | 12 | #include "lobject.h" 13 | #include "lzio.h" 14 | 15 | 16 | /* 17 | ** Single-char tokens (terminal symbols) are represented by their own 18 | ** numeric code. Other tokens start at the following value. 19 | */ 20 | #define FIRST_RESERVED (UCHAR_MAX + 1) 21 | 22 | 23 | #if !defined(LUA_ENV) 24 | #define LUA_ENV "_ENV" 25 | #endif 26 | 27 | 28 | /* 29 | * WARNING: if you change the order of this enumeration, 30 | * grep "ORDER RESERVED" 31 | */ 32 | enum RESERVED { 33 | /* terminal symbols denoted by reserved words */ 34 | TK_AND = FIRST_RESERVED, TK_BREAK, 35 | TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION, 36 | TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, 37 | TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, 38 | /* other terminal symbols */ 39 | TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, 40 | TK_SHL, TK_SHR, 41 | TK_DBCOLON, TK_EOS, 42 | TK_FLT, TK_INT, TK_NAME, TK_STRING 43 | }; 44 | 45 | /* number of reserved words */ 46 | #define NUM_RESERVED (cast_int(TK_WHILE-FIRST_RESERVED + 1)) 47 | 48 | 49 | typedef union { 50 | lua_Number r; 51 | lua_Integer i; 52 | TString *ts; 53 | } SemInfo; /* semantics information */ 54 | 55 | 56 | typedef struct Token { 57 | int token; 58 | SemInfo seminfo; 59 | } Token; 60 | 61 | 62 | /* state of the lexer plus state of the parser when shared by all 63 | functions */ 64 | typedef struct LexState { 65 | int current; /* current character (charint) */ 66 | int linenumber; /* input line counter */ 67 | int lastline; /* line of last token 'consumed' */ 68 | Token t; /* current token */ 69 | Token lookahead; /* look ahead token */ 70 | struct FuncState *fs; /* current function (parser) */ 71 | struct lua_State *L; 72 | ZIO *z; /* input stream */ 73 | Mbuffer *buff; /* buffer for tokens */ 74 | Table *h; /* to avoid collection/reuse strings */ 75 | struct Dyndata *dyd; /* dynamic structures used by the parser */ 76 | TString *source; /* current source name */ 77 | TString *envn; /* environment variable name */ 78 | } LexState; 79 | 80 | 81 | LUAI_FUNC void luaX_init (lua_State *L); 82 | LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, 83 | TString *source, int firstchar); 84 | LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l); 85 | LUAI_FUNC void luaX_next (LexState *ls); 86 | LUAI_FUNC int luaX_lookahead (LexState *ls); 87 | LUAI_FUNC l_noret luaX_syntaxerror (LexState *ls, const char *s); 88 | LUAI_FUNC const char *luaX_token2str (LexState *ls, int token); 89 | 90 | 91 | #endif 92 | -------------------------------------------------------------------------------- /src/llimits.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: llimits.h $ 3 | ** Limits, basic types, and some other 'installation-dependent' definitions 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef llimits_h 8 | #define llimits_h 9 | 10 | 11 | #include 12 | #include 13 | 14 | 15 | #include "lua.h" 16 | 17 | 18 | /* 19 | ** 'lu_mem' and 'l_mem' are unsigned/signed integers big enough to count 20 | ** the total memory used by Lua (in bytes). Usually, 'size_t' and 21 | ** 'ptrdiff_t' should work, but we use 'long' for 16-bit machines. 22 | */ 23 | #if defined(LUAI_MEM) /* { external definitions? */ 24 | typedef LUAI_UMEM lu_mem; 25 | typedef LUAI_MEM l_mem; 26 | #elif LUAI_IS32INT /* }{ */ 27 | typedef size_t lu_mem; 28 | typedef ptrdiff_t l_mem; 29 | #else /* 16-bit ints */ /* }{ */ 30 | typedef unsigned long lu_mem; 31 | typedef long l_mem; 32 | #endif /* } */ 33 | 34 | 35 | /* chars used as small naturals (so that 'char' is reserved for characters) */ 36 | typedef unsigned char lu_byte; 37 | typedef signed char ls_byte; 38 | 39 | 40 | /* maximum value for size_t */ 41 | #define MAX_SIZET ((size_t)(~(size_t)0)) 42 | 43 | /* maximum size visible for Lua (must be representable in a lua_Integer) */ 44 | #define MAX_SIZE (sizeof(size_t) < sizeof(lua_Integer) ? MAX_SIZET \ 45 | : (size_t)(LUA_MAXINTEGER)) 46 | 47 | 48 | #define MAX_LUMEM ((lu_mem)(~(lu_mem)0)) 49 | 50 | #define MAX_LMEM ((l_mem)(MAX_LUMEM >> 1)) 51 | 52 | 53 | #define MAX_INT INT_MAX /* maximum value of an int */ 54 | 55 | 56 | /* 57 | ** floor of the log2 of the maximum signed value for integral type 't'. 58 | ** (That is, maximum 'n' such that '2^n' fits in the given signed type.) 59 | */ 60 | #define log2maxs(t) (sizeof(t) * 8 - 2) 61 | 62 | 63 | /* 64 | ** test whether an unsigned value is a power of 2 (or zero) 65 | */ 66 | #define ispow2(x) (((x) & ((x) - 1)) == 0) 67 | 68 | 69 | /* number of chars of a literal string without the ending \0 */ 70 | #define LL(x) (sizeof(x)/sizeof(char) - 1) 71 | 72 | 73 | /* 74 | ** conversion of pointer to unsigned integer: this is for hashing only; 75 | ** there is no problem if the integer cannot hold the whole pointer 76 | ** value. (In strict ISO C this may cause undefined behavior, but no 77 | ** actual machine seems to bother.) 78 | */ 79 | #if !defined(LUA_USE_C89) && defined(__STDC_VERSION__) && \ 80 | __STDC_VERSION__ >= 199901L 81 | #include 82 | #if defined(UINTPTR_MAX) /* even in C99 this type is optional */ 83 | #define L_P2I uintptr_t 84 | #else /* no 'intptr'? */ 85 | #define L_P2I uintmax_t /* use the largest available integer */ 86 | #endif 87 | #else /* C89 option */ 88 | #define L_P2I size_t 89 | #endif 90 | 91 | #define point2uint(p) ((unsigned int)((L_P2I)(p) & UINT_MAX)) 92 | 93 | 94 | 95 | /* types of 'usual argument conversions' for lua_Number and lua_Integer */ 96 | typedef LUAI_UACNUMBER l_uacNumber; 97 | typedef LUAI_UACINT l_uacInt; 98 | 99 | 100 | /* 101 | ** Internal assertions for in-house debugging 102 | */ 103 | #if defined LUAI_ASSERT 104 | #undef NDEBUG 105 | #include 106 | #define lua_assert(c) assert(c) 107 | #endif 108 | 109 | #if defined(lua_assert) 110 | #define check_exp(c,e) (lua_assert(c), (e)) 111 | /* to avoid problems with conditions too long */ 112 | #define lua_longassert(c) ((c) ? (void)0 : lua_assert(0)) 113 | #else 114 | #define lua_assert(c) ((void)0) 115 | #define check_exp(c,e) (e) 116 | #define lua_longassert(c) ((void)0) 117 | #endif 118 | 119 | /* 120 | ** assertion for checking API calls 121 | */ 122 | #if !defined(luai_apicheck) 123 | #define luai_apicheck(l,e) ((void)l, lua_assert(e)) 124 | #endif 125 | 126 | #define api_check(l,e,msg) luai_apicheck(l,(e) && msg) 127 | 128 | 129 | /* macro to avoid warnings about unused variables */ 130 | #if !defined(UNUSED) 131 | #define UNUSED(x) ((void)(x)) 132 | #endif 133 | 134 | 135 | /* type casts (a macro highlights casts in the code) */ 136 | #define cast(t, exp) ((t)(exp)) 137 | 138 | #define cast_void(i) cast(void, (i)) 139 | #define cast_voidp(i) cast(void *, (i)) 140 | #define cast_num(i) cast(lua_Number, (i)) 141 | #define cast_int(i) cast(int, (i)) 142 | #define cast_uint(i) cast(unsigned int, (i)) 143 | #define cast_byte(i) cast(lu_byte, (i)) 144 | #define cast_uchar(i) cast(unsigned char, (i)) 145 | #define cast_char(i) cast(char, (i)) 146 | #define cast_charp(i) cast(char *, (i)) 147 | #define cast_sizet(i) cast(size_t, (i)) 148 | 149 | 150 | /* cast a signed lua_Integer to lua_Unsigned */ 151 | #if !defined(l_castS2U) 152 | #define l_castS2U(i) ((lua_Unsigned)(i)) 153 | #endif 154 | 155 | /* 156 | ** cast a lua_Unsigned to a signed lua_Integer; this cast is 157 | ** not strict ISO C, but two-complement architectures should 158 | ** work fine. 159 | */ 160 | #if !defined(l_castU2S) 161 | #define l_castU2S(i) ((lua_Integer)(i)) 162 | #endif 163 | 164 | 165 | /* 166 | ** non-return type 167 | */ 168 | #if !defined(l_noret) 169 | 170 | #if defined(__GNUC__) 171 | #define l_noret void __attribute__((noreturn)) 172 | #elif defined(_MSC_VER) && _MSC_VER >= 1200 173 | #define l_noret void __declspec(noreturn) 174 | #else 175 | #define l_noret void 176 | #endif 177 | 178 | #endif 179 | 180 | 181 | /* 182 | ** Inline functions 183 | */ 184 | #if !defined(LUA_USE_C89) 185 | #define l_inline inline 186 | #elif defined(__GNUC__) 187 | #define l_inline __inline__ 188 | #else 189 | #define l_inline /* empty */ 190 | #endif 191 | 192 | #define l_sinline static l_inline 193 | 194 | 195 | /* 196 | ** type for virtual-machine instructions; 197 | ** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h) 198 | */ 199 | #if LUAI_IS32INT 200 | typedef unsigned int l_uint32; 201 | #else 202 | typedef unsigned long l_uint32; 203 | #endif 204 | 205 | typedef l_uint32 Instruction; 206 | 207 | 208 | 209 | /* 210 | ** Maximum length for short strings, that is, strings that are 211 | ** internalized. (Cannot be smaller than reserved words or tags for 212 | ** metamethods, as these strings must be internalized; 213 | ** #("function") = 8, #("__newindex") = 10.) 214 | */ 215 | #if !defined(LUAI_MAXSHORTLEN) 216 | #define LUAI_MAXSHORTLEN 40 217 | #endif 218 | 219 | 220 | /* 221 | ** Initial size for the string table (must be power of 2). 222 | ** The Lua core alone registers ~50 strings (reserved words + 223 | ** metaevent keys + a few others). Libraries would typically add 224 | ** a few dozens more. 225 | */ 226 | #if !defined(MINSTRTABSIZE) 227 | #define MINSTRTABSIZE 128 228 | #endif 229 | 230 | 231 | /* 232 | ** Size of cache for strings in the API. 'N' is the number of 233 | ** sets (better be a prime) and "M" is the size of each set (M == 1 234 | ** makes a direct cache.) 235 | */ 236 | #if !defined(STRCACHE_N) 237 | #define STRCACHE_N 53 238 | #define STRCACHE_M 2 239 | #endif 240 | 241 | 242 | /* minimum size for string buffer */ 243 | #if !defined(LUA_MINBUFFER) 244 | #define LUA_MINBUFFER 32 245 | #endif 246 | 247 | 248 | /* 249 | ** Maximum depth for nested C calls, syntactical nested non-terminals, 250 | ** and other features implemented through recursion in C. (Value must 251 | ** fit in a 16-bit unsigned integer. It must also be compatible with 252 | ** the size of the C stack.) 253 | */ 254 | #if !defined(LUAI_MAXCCALLS) 255 | #define LUAI_MAXCCALLS 200 256 | #endif 257 | 258 | 259 | /* 260 | ** macros that are executed whenever program enters the Lua core 261 | ** ('lua_lock') and leaves the core ('lua_unlock') 262 | */ 263 | #if !defined(lua_lock) 264 | #define lua_lock(L) ((void) 0) 265 | #define lua_unlock(L) ((void) 0) 266 | #endif 267 | 268 | /* 269 | ** macro executed during Lua functions at points where the 270 | ** function can yield. 271 | */ 272 | #if !defined(luai_threadyield) 273 | #define luai_threadyield(L) {lua_unlock(L); lua_lock(L);} 274 | #endif 275 | 276 | 277 | /* 278 | ** these macros allow user-specific actions when a thread is 279 | ** created/deleted/resumed/yielded. 280 | */ 281 | #if !defined(luai_userstateopen) 282 | #define luai_userstateopen(L) ((void)L) 283 | #endif 284 | 285 | #if !defined(luai_userstateclose) 286 | #define luai_userstateclose(L) ((void)L) 287 | #endif 288 | 289 | #if !defined(luai_userstatethread) 290 | #define luai_userstatethread(L,L1) ((void)L) 291 | #endif 292 | 293 | #if !defined(luai_userstatefree) 294 | #define luai_userstatefree(L,L1) ((void)L) 295 | #endif 296 | 297 | #if !defined(luai_userstateresume) 298 | #define luai_userstateresume(L,n) ((void)L) 299 | #endif 300 | 301 | #if !defined(luai_userstateyield) 302 | #define luai_userstateyield(L,n) ((void)L) 303 | #endif 304 | 305 | 306 | 307 | /* 308 | ** The luai_num* macros define the primitive operations over numbers. 309 | */ 310 | 311 | /* floor division (defined as 'floor(a/b)') */ 312 | #if !defined(luai_numidiv) 313 | #define luai_numidiv(L,a,b) ((void)L, l_floor(luai_numdiv(L,a,b))) 314 | #endif 315 | 316 | /* float division */ 317 | #if !defined(luai_numdiv) 318 | #define luai_numdiv(L,a,b) ((a)/(b)) 319 | #endif 320 | 321 | /* 322 | ** modulo: defined as 'a - floor(a/b)*b'; the direct computation 323 | ** using this definition has several problems with rounding errors, 324 | ** so it is better to use 'fmod'. 'fmod' gives the result of 325 | ** 'a - trunc(a/b)*b', and therefore must be corrected when 326 | ** 'trunc(a/b) ~= floor(a/b)'. That happens when the division has a 327 | ** non-integer negative result: non-integer result is equivalent to 328 | ** a non-zero remainder 'm'; negative result is equivalent to 'a' and 329 | ** 'b' with different signs, or 'm' and 'b' with different signs 330 | ** (as the result 'm' of 'fmod' has the same sign of 'a'). 331 | */ 332 | #if !defined(luai_nummod) 333 | #define luai_nummod(L,a,b,m) \ 334 | { (void)L; (m) = l_mathop(fmod)(a,b); \ 335 | if (((m) > 0) ? (b) < 0 : ((m) < 0 && (b) > 0)) (m) += (b); } 336 | #endif 337 | 338 | /* exponentiation */ 339 | #if !defined(luai_numpow) 340 | #define luai_numpow(L,a,b) \ 341 | ((void)L, (b == 2) ? (a)*(a) : l_mathop(pow)(a,b)) 342 | #endif 343 | 344 | /* the others are quite standard operations */ 345 | #if !defined(luai_numadd) 346 | #define luai_numadd(L,a,b) ((a)+(b)) 347 | #define luai_numsub(L,a,b) ((a)-(b)) 348 | #define luai_nummul(L,a,b) ((a)*(b)) 349 | #define luai_numunm(L,a) (-(a)) 350 | #define luai_numeq(a,b) ((a)==(b)) 351 | #define luai_numlt(a,b) ((a)<(b)) 352 | #define luai_numle(a,b) ((a)<=(b)) 353 | #define luai_numgt(a,b) ((a)>(b)) 354 | #define luai_numge(a,b) ((a)>=(b)) 355 | #define luai_numisnan(a) (!luai_numeq((a), (a))) 356 | #endif 357 | 358 | 359 | 360 | 361 | 362 | /* 363 | ** macro to control inclusion of some hard tests on stack reallocation 364 | */ 365 | #if !defined(HARDSTACKTESTS) 366 | #define condmovestack(L,pre,pos) ((void)0) 367 | #else 368 | /* realloc stack keeping its size */ 369 | #define condmovestack(L,pre,pos) \ 370 | { int sz_ = stacksize(L); pre; luaD_reallocstack((L), sz_, 0); pos; } 371 | #endif 372 | 373 | #if !defined(HARDMEMTESTS) 374 | #define condchangemem(L,pre,pos) ((void)0) 375 | #else 376 | #define condchangemem(L,pre,pos) \ 377 | { if (gcrunning(G(L))) { pre; luaC_fullgc(L, 0); pos; } } 378 | #endif 379 | 380 | #endif 381 | -------------------------------------------------------------------------------- /src/lmem.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lmem.c $ 3 | ** Interface to Memory Manager 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lmem_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "ldebug.h" 18 | #include "ldo.h" 19 | #include "lgc.h" 20 | #include "lmem.h" 21 | #include "lobject.h" 22 | #include "lstate.h" 23 | 24 | 25 | 26 | /* 27 | ** About the realloc function: 28 | ** void *frealloc (void *ud, void *ptr, size_t osize, size_t nsize); 29 | ** ('osize' is the old size, 'nsize' is the new size) 30 | ** 31 | ** - frealloc(ud, p, x, 0) frees the block 'p' and returns NULL. 32 | ** Particularly, frealloc(ud, NULL, 0, 0) does nothing, 33 | ** which is equivalent to free(NULL) in ISO C. 34 | ** 35 | ** - frealloc(ud, NULL, x, s) creates a new block of size 's' 36 | ** (no matter 'x'). Returns NULL if it cannot create the new block. 37 | ** 38 | ** - otherwise, frealloc(ud, b, x, y) reallocates the block 'b' from 39 | ** size 'x' to size 'y'. Returns NULL if it cannot reallocate the 40 | ** block to the new size. 41 | */ 42 | 43 | 44 | /* 45 | ** Macro to call the allocation function. 46 | */ 47 | #define callfrealloc(g,block,os,ns) ((*g->frealloc)(g->ud, block, os, ns)) 48 | 49 | 50 | /* 51 | ** When an allocation fails, it will try again after an emergency 52 | ** collection, except when it cannot run a collection. The GC should 53 | ** not be called while the state is not fully built, as the collector 54 | ** is not yet fully initialized. Also, it should not be called when 55 | ** 'gcstopem' is true, because then the interpreter is in the middle of 56 | ** a collection step. 57 | */ 58 | #define cantryagain(g) (completestate(g) && !g->gcstopem) 59 | 60 | 61 | 62 | 63 | #if defined(EMERGENCYGCTESTS) 64 | /* 65 | ** First allocation will fail except when freeing a block (frees never 66 | ** fail) and when it cannot try again; this fail will trigger 'tryagain' 67 | ** and a full GC cycle at every allocation. 68 | */ 69 | static void *firsttry (global_State *g, void *block, size_t os, size_t ns) { 70 | if (ns > 0 && cantryagain(g)) 71 | return NULL; /* fail */ 72 | else /* normal allocation */ 73 | return callfrealloc(g, block, os, ns); 74 | } 75 | #else 76 | #define firsttry(g,block,os,ns) callfrealloc(g, block, os, ns) 77 | #endif 78 | 79 | 80 | 81 | 82 | 83 | /* 84 | ** {================================================================== 85 | ** Functions to allocate/deallocate arrays for the Parser 86 | ** =================================================================== 87 | */ 88 | 89 | /* 90 | ** Minimum size for arrays during parsing, to avoid overhead of 91 | ** reallocating to size 1, then 2, and then 4. All these arrays 92 | ** will be reallocated to exact sizes or erased when parsing ends. 93 | */ 94 | #define MINSIZEARRAY 4 95 | 96 | 97 | void *luaM_growaux_ (lua_State *L, void *block, int nelems, int *psize, 98 | int size_elems, int limit, const char *what) { 99 | void *newblock; 100 | int size = *psize; 101 | if (nelems + 1 <= size) /* does one extra element still fit? */ 102 | return block; /* nothing to be done */ 103 | if (size >= limit / 2) { /* cannot double it? */ 104 | if (l_unlikely(size >= limit)) /* cannot grow even a little? */ 105 | luaG_runerror(L, "too many %s (limit is %d)", what, limit); 106 | size = limit; /* still have at least one free place */ 107 | } 108 | else { 109 | size *= 2; 110 | if (size < MINSIZEARRAY) 111 | size = MINSIZEARRAY; /* minimum size */ 112 | } 113 | lua_assert(nelems + 1 <= size && size <= limit); 114 | /* 'limit' ensures that multiplication will not overflow */ 115 | newblock = luaM_saferealloc_(L, block, cast_sizet(*psize) * size_elems, 116 | cast_sizet(size) * size_elems); 117 | *psize = size; /* update only when everything else is OK */ 118 | return newblock; 119 | } 120 | 121 | 122 | /* 123 | ** In prototypes, the size of the array is also its number of 124 | ** elements (to save memory). So, if it cannot shrink an array 125 | ** to its number of elements, the only option is to raise an 126 | ** error. 127 | */ 128 | void *luaM_shrinkvector_ (lua_State *L, void *block, int *size, 129 | int final_n, int size_elem) { 130 | void *newblock; 131 | size_t oldsize = cast_sizet((*size) * size_elem); 132 | size_t newsize = cast_sizet(final_n * size_elem); 133 | lua_assert(newsize <= oldsize); 134 | newblock = luaM_saferealloc_(L, block, oldsize, newsize); 135 | *size = final_n; 136 | return newblock; 137 | } 138 | 139 | /* }================================================================== */ 140 | 141 | 142 | l_noret luaM_toobig (lua_State *L) { 143 | luaG_runerror(L, "memory allocation error: block too big"); 144 | } 145 | 146 | 147 | /* 148 | ** Free memory 149 | */ 150 | void luaM_free_ (lua_State *L, void *block, size_t osize) { 151 | global_State *g = G(L); 152 | lua_assert((osize == 0) == (block == NULL)); 153 | callfrealloc(g, block, osize, 0); 154 | g->GCdebt -= osize; 155 | } 156 | 157 | 158 | /* 159 | ** In case of allocation fail, this function will do an emergency 160 | ** collection to free some memory and then try the allocation again. 161 | */ 162 | static void *tryagain (lua_State *L, void *block, 163 | size_t osize, size_t nsize) { 164 | global_State *g = G(L); 165 | if (cantryagain(g)) { 166 | luaC_fullgc(L, 1); /* try to free some memory... */ 167 | return callfrealloc(g, block, osize, nsize); /* try again */ 168 | } 169 | else return NULL; /* cannot run an emergency collection */ 170 | } 171 | 172 | 173 | /* 174 | ** Generic allocation routine. 175 | */ 176 | void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { 177 | void *newblock; 178 | global_State *g = G(L); 179 | lua_assert((osize == 0) == (block == NULL)); 180 | newblock = firsttry(g, block, osize, nsize); 181 | if (l_unlikely(newblock == NULL && nsize > 0)) { 182 | newblock = tryagain(L, block, osize, nsize); 183 | if (newblock == NULL) /* still no memory? */ 184 | return NULL; /* do not update 'GCdebt' */ 185 | } 186 | lua_assert((nsize == 0) == (newblock == NULL)); 187 | g->GCdebt = (g->GCdebt + nsize) - osize; 188 | return newblock; 189 | } 190 | 191 | 192 | void *luaM_saferealloc_ (lua_State *L, void *block, size_t osize, 193 | size_t nsize) { 194 | void *newblock = luaM_realloc_(L, block, osize, nsize); 195 | if (l_unlikely(newblock == NULL && nsize > 0)) /* allocation failed? */ 196 | luaM_error(L); 197 | return newblock; 198 | } 199 | 200 | 201 | void *luaM_malloc_ (lua_State *L, size_t size, int tag) { 202 | if (size == 0) 203 | return NULL; /* that's all */ 204 | else { 205 | global_State *g = G(L); 206 | void *newblock = firsttry(g, NULL, tag, size); 207 | if (l_unlikely(newblock == NULL)) { 208 | newblock = tryagain(L, NULL, tag, size); 209 | if (newblock == NULL) 210 | luaM_error(L); 211 | } 212 | g->GCdebt += size; 213 | return newblock; 214 | } 215 | } 216 | -------------------------------------------------------------------------------- /src/lmem.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lmem.h $ 3 | ** Interface to Memory Manager 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lmem_h 8 | #define lmem_h 9 | 10 | 11 | #include 12 | 13 | #include "llimits.h" 14 | #include "lua.h" 15 | 16 | 17 | #define luaM_error(L) luaD_throw(L, LUA_ERRMEM) 18 | 19 | 20 | /* 21 | ** This macro tests whether it is safe to multiply 'n' by the size of 22 | ** type 't' without overflows. Because 'e' is always constant, it avoids 23 | ** the runtime division MAX_SIZET/(e). 24 | ** (The macro is somewhat complex to avoid warnings: The 'sizeof' 25 | ** comparison avoids a runtime comparison when overflow cannot occur. 26 | ** The compiler should be able to optimize the real test by itself, but 27 | ** when it does it, it may give a warning about "comparison is always 28 | ** false due to limited range of data type"; the +1 tricks the compiler, 29 | ** avoiding this warning but also this optimization.) 30 | */ 31 | #define luaM_testsize(n,e) \ 32 | (sizeof(n) >= sizeof(size_t) && cast_sizet((n)) + 1 > MAX_SIZET/(e)) 33 | 34 | #define luaM_checksize(L,n,e) \ 35 | (luaM_testsize(n,e) ? luaM_toobig(L) : cast_void(0)) 36 | 37 | 38 | /* 39 | ** Computes the minimum between 'n' and 'MAX_SIZET/sizeof(t)', so that 40 | ** the result is not larger than 'n' and cannot overflow a 'size_t' 41 | ** when multiplied by the size of type 't'. (Assumes that 'n' is an 42 | ** 'int' or 'unsigned int' and that 'int' is not larger than 'size_t'.) 43 | */ 44 | #define luaM_limitN(n,t) \ 45 | ((cast_sizet(n) <= MAX_SIZET/sizeof(t)) ? (n) : \ 46 | cast_uint((MAX_SIZET/sizeof(t)))) 47 | 48 | 49 | /* 50 | ** Arrays of chars do not need any test 51 | */ 52 | #define luaM_reallocvchar(L,b,on,n) \ 53 | cast_charp(luaM_saferealloc_(L, (b), (on)*sizeof(char), (n)*sizeof(char))) 54 | 55 | #define luaM_freemem(L, b, s) luaM_free_(L, (b), (s)) 56 | #define luaM_free(L, b) luaM_free_(L, (b), sizeof(*(b))) 57 | #define luaM_freearray(L, b, n) luaM_free_(L, (b), (n)*sizeof(*(b))) 58 | 59 | #define luaM_new(L,t) cast(t*, luaM_malloc_(L, sizeof(t), 0)) 60 | #define luaM_newvector(L,n,t) cast(t*, luaM_malloc_(L, (n)*sizeof(t), 0)) 61 | #define luaM_newvectorchecked(L,n,t) \ 62 | (luaM_checksize(L,n,sizeof(t)), luaM_newvector(L,n,t)) 63 | 64 | #define luaM_newobject(L,tag,s) luaM_malloc_(L, (s), tag) 65 | 66 | #define luaM_growvector(L,v,nelems,size,t,limit,e) \ 67 | ((v)=cast(t *, luaM_growaux_(L,v,nelems,&(size),sizeof(t), \ 68 | luaM_limitN(limit,t),e))) 69 | 70 | #define luaM_reallocvector(L, v,oldn,n,t) \ 71 | (cast(t *, luaM_realloc_(L, v, cast_sizet(oldn) * sizeof(t), \ 72 | cast_sizet(n) * sizeof(t)))) 73 | 74 | #define luaM_shrinkvector(L,v,size,fs,t) \ 75 | ((v)=cast(t *, luaM_shrinkvector_(L, v, &(size), fs, sizeof(t)))) 76 | 77 | LUAI_FUNC l_noret luaM_toobig (lua_State *L); 78 | 79 | /* not to be called directly */ 80 | LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize, 81 | size_t size); 82 | LUAI_FUNC void *luaM_saferealloc_ (lua_State *L, void *block, size_t oldsize, 83 | size_t size); 84 | LUAI_FUNC void luaM_free_ (lua_State *L, void *block, size_t osize); 85 | LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int nelems, 86 | int *size, int size_elem, int limit, 87 | const char *what); 88 | LUAI_FUNC void *luaM_shrinkvector_ (lua_State *L, void *block, int *nelem, 89 | int final_n, int size_elem); 90 | LUAI_FUNC void *luaM_malloc_ (lua_State *L, size_t size, int tag); 91 | 92 | #endif 93 | 94 | -------------------------------------------------------------------------------- /src/lopcodes.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lopcodes.c $ 3 | ** Opcodes for Lua virtual machine 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lopcodes_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include "lopcodes.h" 14 | 15 | 16 | /* ORDER OP */ 17 | 18 | LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { 19 | /* MM OT IT T A mode opcode */ 20 | opmode(0, 0, 0, 0, 1, iABC) /* OP_MOVE */ 21 | ,opmode(0, 0, 0, 0, 1, iAsBx) /* OP_LOADI */ 22 | ,opmode(0, 0, 0, 0, 1, iAsBx) /* OP_LOADF */ 23 | ,opmode(0, 0, 0, 0, 1, iABx) /* OP_LOADK */ 24 | ,opmode(0, 0, 0, 0, 1, iABx) /* OP_LOADKX */ 25 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_LOADFALSE */ 26 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_LFALSESKIP */ 27 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_LOADTRUE */ 28 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_LOADNIL */ 29 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_GETUPVAL */ 30 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_SETUPVAL */ 31 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_GETTABUP */ 32 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_GETTABLE */ 33 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_GETI */ 34 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_GETFIELD */ 35 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_SETTABUP */ 36 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_SETTABLE */ 37 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_SETI */ 38 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_SETFIELD */ 39 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_NEWTABLE */ 40 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SELF */ 41 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_ADDI */ 42 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_ADDK */ 43 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SUBK */ 44 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_MULK */ 45 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_MODK */ 46 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_POWK */ 47 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_DIVK */ 48 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_IDIVK */ 49 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BANDK */ 50 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BORK */ 51 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BXORK */ 52 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SHRI */ 53 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SHLI */ 54 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_ADD */ 55 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SUB */ 56 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_MUL */ 57 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_MOD */ 58 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_POW */ 59 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_DIV */ 60 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_IDIV */ 61 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BAND */ 62 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BOR */ 63 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BXOR */ 64 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SHL */ 65 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SHR */ 66 | ,opmode(1, 0, 0, 0, 0, iABC) /* OP_MMBIN */ 67 | ,opmode(1, 0, 0, 0, 0, iABC) /* OP_MMBINI*/ 68 | ,opmode(1, 0, 0, 0, 0, iABC) /* OP_MMBINK*/ 69 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_UNM */ 70 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BNOT */ 71 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_NOT */ 72 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_LEN */ 73 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_CONCAT */ 74 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_CLOSE */ 75 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_TBC */ 76 | ,opmode(0, 0, 0, 0, 0, isJ) /* OP_JMP */ 77 | ,opmode(0, 0, 0, 1, 0, iABC) /* OP_EQ */ 78 | ,opmode(0, 0, 0, 1, 0, iABC) /* OP_LT */ 79 | ,opmode(0, 0, 0, 1, 0, iABC) /* OP_LE */ 80 | ,opmode(0, 0, 0, 1, 0, iABC) /* OP_EQK */ 81 | ,opmode(0, 0, 0, 1, 0, iABC) /* OP_EQI */ 82 | ,opmode(0, 0, 0, 1, 0, iABC) /* OP_LTI */ 83 | ,opmode(0, 0, 0, 1, 0, iABC) /* OP_LEI */ 84 | ,opmode(0, 0, 0, 1, 0, iABC) /* OP_GTI */ 85 | ,opmode(0, 0, 0, 1, 0, iABC) /* OP_GEI */ 86 | ,opmode(0, 0, 0, 1, 0, iABC) /* OP_TEST */ 87 | ,opmode(0, 0, 0, 1, 1, iABC) /* OP_TESTSET */ 88 | ,opmode(0, 1, 1, 0, 1, iABC) /* OP_CALL */ 89 | ,opmode(0, 1, 1, 0, 1, iABC) /* OP_TAILCALL */ 90 | ,opmode(0, 0, 1, 0, 0, iABC) /* OP_RETURN */ 91 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_RETURN0 */ 92 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_RETURN1 */ 93 | ,opmode(0, 0, 0, 0, 1, iABx) /* OP_FORLOOP */ 94 | ,opmode(0, 0, 0, 0, 1, iABx) /* OP_FORPREP */ 95 | ,opmode(0, 0, 0, 0, 0, iABx) /* OP_TFORPREP */ 96 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_TFORCALL */ 97 | ,opmode(0, 0, 0, 0, 1, iABx) /* OP_TFORLOOP */ 98 | ,opmode(0, 0, 1, 0, 0, iABC) /* OP_SETLIST */ 99 | ,opmode(0, 0, 0, 0, 1, iABx) /* OP_CLOSURE */ 100 | ,opmode(0, 1, 0, 0, 1, iABC) /* OP_VARARG */ 101 | ,opmode(0, 0, 1, 0, 1, iABC) /* OP_VARARGPREP */ 102 | ,opmode(0, 0, 0, 0, 0, iAx) /* OP_EXTRAARG */ 103 | }; 104 | 105 | -------------------------------------------------------------------------------- /src/lopnames.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lopnames.h $ 3 | ** Opcode names 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #if !defined(lopnames_h) 8 | #define lopnames_h 9 | 10 | #include 11 | 12 | 13 | /* ORDER OP */ 14 | 15 | static const char *const opnames[] = { 16 | "MOVE", 17 | "LOADI", 18 | "LOADF", 19 | "LOADK", 20 | "LOADKX", 21 | "LOADFALSE", 22 | "LFALSESKIP", 23 | "LOADTRUE", 24 | "LOADNIL", 25 | "GETUPVAL", 26 | "SETUPVAL", 27 | "GETTABUP", 28 | "GETTABLE", 29 | "GETI", 30 | "GETFIELD", 31 | "SETTABUP", 32 | "SETTABLE", 33 | "SETI", 34 | "SETFIELD", 35 | "NEWTABLE", 36 | "SELF", 37 | "ADDI", 38 | "ADDK", 39 | "SUBK", 40 | "MULK", 41 | "MODK", 42 | "POWK", 43 | "DIVK", 44 | "IDIVK", 45 | "BANDK", 46 | "BORK", 47 | "BXORK", 48 | "SHRI", 49 | "SHLI", 50 | "ADD", 51 | "SUB", 52 | "MUL", 53 | "MOD", 54 | "POW", 55 | "DIV", 56 | "IDIV", 57 | "BAND", 58 | "BOR", 59 | "BXOR", 60 | "SHL", 61 | "SHR", 62 | "MMBIN", 63 | "MMBINI", 64 | "MMBINK", 65 | "UNM", 66 | "BNOT", 67 | "NOT", 68 | "LEN", 69 | "CONCAT", 70 | "CLOSE", 71 | "TBC", 72 | "JMP", 73 | "EQ", 74 | "LT", 75 | "LE", 76 | "EQK", 77 | "EQI", 78 | "LTI", 79 | "LEI", 80 | "GTI", 81 | "GEI", 82 | "TEST", 83 | "TESTSET", 84 | "CALL", 85 | "TAILCALL", 86 | "RETURN", 87 | "RETURN0", 88 | "RETURN1", 89 | "FORLOOP", 90 | "FORPREP", 91 | "TFORPREP", 92 | "TFORCALL", 93 | "TFORLOOP", 94 | "SETLIST", 95 | "CLOSURE", 96 | "VARARG", 97 | "VARARGPREP", 98 | "EXTRAARG", 99 | NULL 100 | }; 101 | 102 | #endif 103 | 104 | -------------------------------------------------------------------------------- /src/lparser.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lparser.h $ 3 | ** Lua Parser 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lparser_h 8 | #define lparser_h 9 | 10 | #include "llimits.h" 11 | #include "lobject.h" 12 | #include "lzio.h" 13 | 14 | 15 | /* 16 | ** Expression and variable descriptor. 17 | ** Code generation for variables and expressions can be delayed to allow 18 | ** optimizations; An 'expdesc' structure describes a potentially-delayed 19 | ** variable/expression. It has a description of its "main" value plus a 20 | ** list of conditional jumps that can also produce its value (generated 21 | ** by short-circuit operators 'and'/'or'). 22 | */ 23 | 24 | /* kinds of variables/expressions */ 25 | typedef enum { 26 | VVOID, /* when 'expdesc' describes the last expression of a list, 27 | this kind means an empty list (so, no expression) */ 28 | VNIL, /* constant nil */ 29 | VTRUE, /* constant true */ 30 | VFALSE, /* constant false */ 31 | VK, /* constant in 'k'; info = index of constant in 'k' */ 32 | VKFLT, /* floating constant; nval = numerical float value */ 33 | VKINT, /* integer constant; ival = numerical integer value */ 34 | VKSTR, /* string constant; strval = TString address; 35 | (string is fixed by the lexer) */ 36 | VNONRELOC, /* expression has its value in a fixed register; 37 | info = result register */ 38 | VLOCAL, /* local variable; var.ridx = register index; 39 | var.vidx = relative index in 'actvar.arr' */ 40 | VUPVAL, /* upvalue variable; info = index of upvalue in 'upvalues' */ 41 | VCONST, /* compile-time variable; 42 | info = absolute index in 'actvar.arr' */ 43 | VINDEXED, /* indexed variable; 44 | ind.t = table register; 45 | ind.idx = key's R index */ 46 | VINDEXUP, /* indexed upvalue; 47 | ind.t = table upvalue; 48 | ind.idx = key's K index */ 49 | VINDEXI, /* indexed variable with constant integer; 50 | ind.t = table register; 51 | ind.idx = key's value */ 52 | VINDEXSTR, /* indexed variable with literal string; 53 | ind.t = table register; 54 | ind.idx = key's K index */ 55 | VJMP, /* expression is a test/comparison; 56 | info = pc of corresponding jump instruction */ 57 | VRELOC, /* expression can put result in any register; 58 | info = instruction pc */ 59 | VCALL, /* expression is a function call; info = instruction pc */ 60 | VVARARG /* vararg expression; info = instruction pc */ 61 | } expkind; 62 | 63 | 64 | #define vkisvar(k) (VLOCAL <= (k) && (k) <= VINDEXSTR) 65 | #define vkisindexed(k) (VINDEXED <= (k) && (k) <= VINDEXSTR) 66 | 67 | 68 | typedef struct expdesc { 69 | expkind k; 70 | union { 71 | lua_Integer ival; /* for VKINT */ 72 | lua_Number nval; /* for VKFLT */ 73 | TString *strval; /* for VKSTR */ 74 | int info; /* for generic use */ 75 | struct { /* for indexed variables */ 76 | short idx; /* index (R or "long" K) */ 77 | lu_byte t; /* table (register or upvalue) */ 78 | } ind; 79 | struct { /* for local variables */ 80 | lu_byte ridx; /* register holding the variable */ 81 | unsigned short vidx; /* compiler index (in 'actvar.arr') */ 82 | } var; 83 | } u; 84 | int t; /* patch list of 'exit when true' */ 85 | int f; /* patch list of 'exit when false' */ 86 | } expdesc; 87 | 88 | 89 | /* kinds of variables */ 90 | #define VDKREG 0 /* regular */ 91 | #define RDKCONST 1 /* constant */ 92 | #define RDKTOCLOSE 2 /* to-be-closed */ 93 | #define RDKCTC 3 /* compile-time constant */ 94 | 95 | /* description of an active local variable */ 96 | typedef union Vardesc { 97 | struct { 98 | TValuefields; /* constant value (if it is a compile-time constant) */ 99 | lu_byte kind; 100 | lu_byte ridx; /* register holding the variable */ 101 | short pidx; /* index of the variable in the Proto's 'locvars' array */ 102 | TString *name; /* variable name */ 103 | } vd; 104 | TValue k; /* constant value (if any) */ 105 | } Vardesc; 106 | 107 | 108 | 109 | /* description of pending goto statements and label statements */ 110 | typedef struct Labeldesc { 111 | TString *name; /* label identifier */ 112 | int pc; /* position in code */ 113 | int line; /* line where it appeared */ 114 | lu_byte nactvar; /* number of active variables in that position */ 115 | lu_byte close; /* goto that escapes upvalues */ 116 | } Labeldesc; 117 | 118 | 119 | /* list of labels or gotos */ 120 | typedef struct Labellist { 121 | Labeldesc *arr; /* array */ 122 | int n; /* number of entries in use */ 123 | int size; /* array size */ 124 | } Labellist; 125 | 126 | 127 | /* dynamic structures used by the parser */ 128 | typedef struct Dyndata { 129 | struct { /* list of all active local variables */ 130 | Vardesc *arr; 131 | int n; 132 | int size; 133 | } actvar; 134 | Labellist gt; /* list of pending gotos */ 135 | Labellist label; /* list of active labels */ 136 | } Dyndata; 137 | 138 | 139 | /* control of blocks */ 140 | struct BlockCnt; /* defined in lparser.c */ 141 | 142 | 143 | /* state needed to generate code for a given function */ 144 | typedef struct FuncState { 145 | Proto *f; /* current function header */ 146 | struct FuncState *prev; /* enclosing function */ 147 | struct LexState *ls; /* lexical state */ 148 | struct BlockCnt *bl; /* chain of current blocks */ 149 | int pc; /* next position to code (equivalent to 'ncode') */ 150 | int lasttarget; /* 'label' of last 'jump label' */ 151 | int previousline; /* last line that was saved in 'lineinfo' */ 152 | int nk; /* number of elements in 'k' */ 153 | int np; /* number of elements in 'p' */ 154 | int nabslineinfo; /* number of elements in 'abslineinfo' */ 155 | int firstlocal; /* index of first local var (in Dyndata array) */ 156 | int firstlabel; /* index of first label (in 'dyd->label->arr') */ 157 | short ndebugvars; /* number of elements in 'f->locvars' */ 158 | lu_byte nactvar; /* number of active local variables */ 159 | lu_byte nups; /* number of upvalues */ 160 | lu_byte freereg; /* first free register */ 161 | lu_byte iwthabs; /* instructions issued since last absolute line info */ 162 | lu_byte needclose; /* function needs to close upvalues when returning */ 163 | } FuncState; 164 | 165 | 166 | LUAI_FUNC int luaY_nvarstack (FuncState *fs); 167 | LUAI_FUNC LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, 168 | Dyndata *dyd, const char *name, int firstchar); 169 | 170 | 171 | #endif 172 | -------------------------------------------------------------------------------- /src/lprefix.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lprefix.h $ 3 | ** Definitions for Lua code that must come before any other header file 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lprefix_h 8 | #define lprefix_h 9 | 10 | 11 | /* 12 | ** Allows POSIX/XSI stuff 13 | */ 14 | #if !defined(LUA_USE_C89) /* { */ 15 | 16 | #if !defined(_XOPEN_SOURCE) 17 | #define _XOPEN_SOURCE 600 18 | #elif _XOPEN_SOURCE == 0 19 | #undef _XOPEN_SOURCE /* use -D_XOPEN_SOURCE=0 to undefine it */ 20 | #endif 21 | 22 | /* 23 | ** Allows manipulation of large files in gcc and some other compilers 24 | */ 25 | #if !defined(LUA_32BITS) && !defined(_FILE_OFFSET_BITS) 26 | #define _LARGEFILE_SOURCE 1 27 | #define _FILE_OFFSET_BITS 64 28 | #endif 29 | 30 | #endif /* } */ 31 | 32 | 33 | /* 34 | ** Windows stuff 35 | */ 36 | #if defined(_WIN32) /* { */ 37 | 38 | #if !defined(_CRT_SECURE_NO_WARNINGS) 39 | #define _CRT_SECURE_NO_WARNINGS /* avoid warnings about ISO C functions */ 40 | #endif 41 | 42 | #endif /* } */ 43 | 44 | #endif 45 | 46 | -------------------------------------------------------------------------------- /src/lstate.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lstate.c $ 3 | ** Global State 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lstate_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | #include 15 | 16 | #include "lua.h" 17 | 18 | #include "lapi.h" 19 | #include "ldebug.h" 20 | #include "ldo.h" 21 | #include "lfunc.h" 22 | #include "lgc.h" 23 | #include "llex.h" 24 | #include "lmem.h" 25 | #include "lstate.h" 26 | #include "lstring.h" 27 | #include "ltable.h" 28 | #include "ltm.h" 29 | 30 | 31 | 32 | /* 33 | ** thread state + extra space 34 | */ 35 | typedef struct LX { 36 | lu_byte extra_[LUA_EXTRASPACE]; 37 | lua_State l; 38 | } LX; 39 | 40 | 41 | /* 42 | ** Main thread combines a thread state and the global state 43 | */ 44 | typedef struct LG { 45 | LX l; 46 | global_State g; 47 | } LG; 48 | 49 | 50 | 51 | #define fromstate(L) (cast(LX *, cast(lu_byte *, (L)) - offsetof(LX, l))) 52 | 53 | 54 | /* 55 | ** A macro to create a "random" seed when a state is created; 56 | ** the seed is used to randomize string hashes. 57 | */ 58 | #if !defined(luai_makeseed) 59 | 60 | #include 61 | 62 | /* 63 | ** Compute an initial seed with some level of randomness. 64 | ** Rely on Address Space Layout Randomization (if present) and 65 | ** current time. 66 | */ 67 | #define addbuff(b,p,e) \ 68 | { size_t t = cast_sizet(e); \ 69 | memcpy(b + p, &t, sizeof(t)); p += sizeof(t); } 70 | 71 | static unsigned int luai_makeseed (lua_State *L) { 72 | char buff[3 * sizeof(size_t)]; 73 | unsigned int h = cast_uint(time(NULL)); 74 | int p = 0; 75 | addbuff(buff, p, L); /* heap variable */ 76 | addbuff(buff, p, &h); /* local variable */ 77 | addbuff(buff, p, &lua_newstate); /* public function */ 78 | lua_assert(p == sizeof(buff)); 79 | return luaS_hash(buff, p, h); 80 | } 81 | 82 | #endif 83 | 84 | 85 | /* 86 | ** set GCdebt to a new value keeping the value (totalbytes + GCdebt) 87 | ** invariant (and avoiding underflows in 'totalbytes') 88 | */ 89 | void luaE_setdebt (global_State *g, l_mem debt) { 90 | l_mem tb = gettotalbytes(g); 91 | lua_assert(tb > 0); 92 | if (debt < tb - MAX_LMEM) 93 | debt = tb - MAX_LMEM; /* will make 'totalbytes == MAX_LMEM' */ 94 | g->totalbytes = tb - debt; 95 | g->GCdebt = debt; 96 | } 97 | 98 | 99 | LUA_API int lua_setcstacklimit (lua_State *L, unsigned int limit) { 100 | UNUSED(L); UNUSED(limit); 101 | return LUAI_MAXCCALLS; /* warning?? */ 102 | } 103 | 104 | 105 | CallInfo *luaE_extendCI (lua_State *L) { 106 | CallInfo *ci; 107 | lua_assert(L->ci->next == NULL); 108 | ci = luaM_new(L, CallInfo); 109 | lua_assert(L->ci->next == NULL); 110 | L->ci->next = ci; 111 | ci->previous = L->ci; 112 | ci->next = NULL; 113 | ci->u.l.trap = 0; 114 | L->nci++; 115 | return ci; 116 | } 117 | 118 | 119 | /* 120 | ** free all CallInfo structures not in use by a thread 121 | */ 122 | static void freeCI (lua_State *L) { 123 | CallInfo *ci = L->ci; 124 | CallInfo *next = ci->next; 125 | ci->next = NULL; 126 | while ((ci = next) != NULL) { 127 | next = ci->next; 128 | luaM_free(L, ci); 129 | L->nci--; 130 | } 131 | } 132 | 133 | 134 | /* 135 | ** free half of the CallInfo structures not in use by a thread, 136 | ** keeping the first one. 137 | */ 138 | void luaE_shrinkCI (lua_State *L) { 139 | CallInfo *ci = L->ci->next; /* first free CallInfo */ 140 | CallInfo *next; 141 | if (ci == NULL) 142 | return; /* no extra elements */ 143 | while ((next = ci->next) != NULL) { /* two extra elements? */ 144 | CallInfo *next2 = next->next; /* next's next */ 145 | ci->next = next2; /* remove next from the list */ 146 | L->nci--; 147 | luaM_free(L, next); /* free next */ 148 | if (next2 == NULL) 149 | break; /* no more elements */ 150 | else { 151 | next2->previous = ci; 152 | ci = next2; /* continue */ 153 | } 154 | } 155 | } 156 | 157 | 158 | /* 159 | ** Called when 'getCcalls(L)' larger or equal to LUAI_MAXCCALLS. 160 | ** If equal, raises an overflow error. If value is larger than 161 | ** LUAI_MAXCCALLS (which means it is handling an overflow) but 162 | ** not much larger, does not report an error (to allow overflow 163 | ** handling to work). 164 | */ 165 | void luaE_checkcstack (lua_State *L) { 166 | if (getCcalls(L) == LUAI_MAXCCALLS) 167 | luaG_runerror(L, "C stack overflow"); 168 | else if (getCcalls(L) >= (LUAI_MAXCCALLS / 10 * 11)) 169 | luaD_throw(L, LUA_ERRERR); /* error while handling stack error */ 170 | } 171 | 172 | 173 | LUAI_FUNC void luaE_incCstack (lua_State *L) { 174 | L->nCcalls++; 175 | if (l_unlikely(getCcalls(L) >= LUAI_MAXCCALLS)) 176 | luaE_checkcstack(L); 177 | } 178 | 179 | 180 | static void stack_init (lua_State *L1, lua_State *L) { 181 | int i; CallInfo *ci; 182 | /* initialize stack array */ 183 | L1->stack.p = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, StackValue); 184 | L1->tbclist.p = L1->stack.p; 185 | for (i = 0; i < BASIC_STACK_SIZE + EXTRA_STACK; i++) 186 | setnilvalue(s2v(L1->stack.p + i)); /* erase new stack */ 187 | L1->top.p = L1->stack.p; 188 | L1->stack_last.p = L1->stack.p + BASIC_STACK_SIZE; 189 | /* initialize first ci */ 190 | ci = &L1->base_ci; 191 | ci->next = ci->previous = NULL; 192 | ci->callstatus = CIST_C; 193 | ci->func.p = L1->top.p; 194 | ci->u.c.k = NULL; 195 | ci->nresults = 0; 196 | setnilvalue(s2v(L1->top.p)); /* 'function' entry for this 'ci' */ 197 | L1->top.p++; 198 | ci->top.p = L1->top.p + LUA_MINSTACK; 199 | L1->ci = ci; 200 | } 201 | 202 | 203 | static void freestack (lua_State *L) { 204 | if (L->stack.p == NULL) 205 | return; /* stack not completely built yet */ 206 | L->ci = &L->base_ci; /* free the entire 'ci' list */ 207 | freeCI(L); 208 | lua_assert(L->nci == 0); 209 | luaM_freearray(L, L->stack.p, stacksize(L) + EXTRA_STACK); /* free stack */ 210 | } 211 | 212 | 213 | /* 214 | ** Create registry table and its predefined values 215 | */ 216 | static void init_registry (lua_State *L, global_State *g) { 217 | /* create registry */ 218 | Table *registry = luaH_new(L); 219 | sethvalue(L, &g->l_registry, registry); 220 | luaH_resize(L, registry, LUA_RIDX_LAST, 0); 221 | /* registry[LUA_RIDX_MAINTHREAD] = L */ 222 | setthvalue(L, ®istry->array[LUA_RIDX_MAINTHREAD - 1], L); 223 | /* registry[LUA_RIDX_GLOBALS] = new table (table of globals) */ 224 | sethvalue(L, ®istry->array[LUA_RIDX_GLOBALS - 1], luaH_new(L)); 225 | } 226 | 227 | 228 | /* 229 | ** open parts of the state that may cause memory-allocation errors. 230 | */ 231 | static void f_luaopen (lua_State *L, void *ud) { 232 | global_State *g = G(L); 233 | UNUSED(ud); 234 | stack_init(L, L); /* init stack */ 235 | init_registry(L, g); 236 | luaS_init(L); 237 | luaT_init(L); 238 | luaX_init(L); 239 | g->gcstp = 0; /* allow gc */ 240 | setnilvalue(&g->nilvalue); /* now state is complete */ 241 | luai_userstateopen(L); 242 | } 243 | 244 | 245 | /* 246 | ** preinitialize a thread with consistent values without allocating 247 | ** any memory (to avoid errors) 248 | */ 249 | static void preinit_thread (lua_State *L, global_State *g) { 250 | G(L) = g; 251 | L->stack.p = NULL; 252 | L->ci = NULL; 253 | L->nci = 0; 254 | L->twups = L; /* thread has no upvalues */ 255 | L->nCcalls = 0; 256 | L->errorJmp = NULL; 257 | L->hook = NULL; 258 | L->hookmask = 0; 259 | L->basehookcount = 0; 260 | L->allowhook = 1; 261 | resethookcount(L); 262 | L->openupval = NULL; 263 | L->status = LUA_OK; 264 | L->errfunc = 0; 265 | L->oldpc = 0; 266 | } 267 | 268 | 269 | static void close_state (lua_State *L) { 270 | global_State *g = G(L); 271 | if (!completestate(g)) /* closing a partially built state? */ 272 | luaC_freeallobjects(L); /* just collect its objects */ 273 | else { /* closing a fully built state */ 274 | L->ci = &L->base_ci; /* unwind CallInfo list */ 275 | luaD_closeprotected(L, 1, LUA_OK); /* close all upvalues */ 276 | luaC_freeallobjects(L); /* collect all objects */ 277 | luai_userstateclose(L); 278 | } 279 | luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size); 280 | freestack(L); 281 | lua_assert(gettotalbytes(g) == sizeof(LG)); 282 | (*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0); /* free main block */ 283 | } 284 | 285 | 286 | LUA_API lua_State *lua_newthread (lua_State *L) { 287 | global_State *g = G(L); 288 | GCObject *o; 289 | lua_State *L1; 290 | lua_lock(L); 291 | luaC_checkGC(L); 292 | /* create new thread */ 293 | o = luaC_newobjdt(L, LUA_TTHREAD, sizeof(LX), offsetof(LX, l)); 294 | L1 = gco2th(o); 295 | /* anchor it on L stack */ 296 | setthvalue2s(L, L->top.p, L1); 297 | api_incr_top(L); 298 | preinit_thread(L1, g); 299 | L1->hookmask = L->hookmask; 300 | L1->basehookcount = L->basehookcount; 301 | L1->hook = L->hook; 302 | resethookcount(L1); 303 | /* initialize L1 extra space */ 304 | memcpy(lua_getextraspace(L1), lua_getextraspace(g->mainthread), 305 | LUA_EXTRASPACE); 306 | luai_userstatethread(L, L1); 307 | stack_init(L1, L); /* init stack */ 308 | lua_unlock(L); 309 | return L1; 310 | } 311 | 312 | 313 | void luaE_freethread (lua_State *L, lua_State *L1) { 314 | LX *l = fromstate(L1); 315 | luaF_closeupval(L1, L1->stack.p); /* close all upvalues */ 316 | lua_assert(L1->openupval == NULL); 317 | luai_userstatefree(L, L1); 318 | freestack(L1); 319 | luaM_free(L, l); 320 | } 321 | 322 | 323 | int luaE_resetthread (lua_State *L, int status) { 324 | CallInfo *ci = L->ci = &L->base_ci; /* unwind CallInfo list */ 325 | setnilvalue(s2v(L->stack.p)); /* 'function' entry for basic 'ci' */ 326 | ci->func.p = L->stack.p; 327 | ci->callstatus = CIST_C; 328 | if (status == LUA_YIELD) 329 | status = LUA_OK; 330 | L->status = LUA_OK; /* so it can run __close metamethods */ 331 | status = luaD_closeprotected(L, 1, status); 332 | if (status != LUA_OK) /* errors? */ 333 | luaD_seterrorobj(L, status, L->stack.p + 1); 334 | else 335 | L->top.p = L->stack.p + 1; 336 | ci->top.p = L->top.p + LUA_MINSTACK; 337 | luaD_reallocstack(L, cast_int(ci->top.p - L->stack.p), 0); 338 | return status; 339 | } 340 | 341 | 342 | LUA_API int lua_closethread (lua_State *L, lua_State *from) { 343 | int status; 344 | lua_lock(L); 345 | L->nCcalls = (from) ? getCcalls(from) : 0; 346 | status = luaE_resetthread(L, L->status); 347 | lua_unlock(L); 348 | return status; 349 | } 350 | 351 | 352 | /* 353 | ** Deprecated! Use 'lua_closethread' instead. 354 | */ 355 | LUA_API int lua_resetthread (lua_State *L) { 356 | return lua_closethread(L, NULL); 357 | } 358 | 359 | 360 | LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { 361 | int i; 362 | lua_State *L; 363 | global_State *g; 364 | LG *l = cast(LG *, (*f)(ud, NULL, LUA_TTHREAD, sizeof(LG))); 365 | if (l == NULL) return NULL; 366 | L = &l->l.l; 367 | g = &l->g; 368 | L->tt = LUA_VTHREAD; 369 | g->currentwhite = bitmask(WHITE0BIT); 370 | L->marked = luaC_white(g); 371 | preinit_thread(L, g); 372 | g->allgc = obj2gco(L); /* by now, only object is the main thread */ 373 | L->next = NULL; 374 | incnny(L); /* main thread is always non yieldable */ 375 | g->frealloc = f; 376 | g->ud = ud; 377 | g->warnf = NULL; 378 | g->ud_warn = NULL; 379 | g->mainthread = L; 380 | g->seed = luai_makeseed(L); 381 | g->gcstp = GCSTPGC; /* no GC while building state */ 382 | g->strt.size = g->strt.nuse = 0; 383 | g->strt.hash = NULL; 384 | setnilvalue(&g->l_registry); 385 | g->panic = NULL; 386 | g->gcstate = GCSpause; 387 | g->gckind = KGC_INC; 388 | g->gcstopem = 0; 389 | g->gcemergency = 0; 390 | g->finobj = g->tobefnz = g->fixedgc = NULL; 391 | g->firstold1 = g->survival = g->old1 = g->reallyold = NULL; 392 | g->finobjsur = g->finobjold1 = g->finobjrold = NULL; 393 | g->sweepgc = NULL; 394 | g->gray = g->grayagain = NULL; 395 | g->weak = g->ephemeron = g->allweak = NULL; 396 | g->twups = NULL; 397 | g->totalbytes = sizeof(LG); 398 | g->GCdebt = 0; 399 | g->lastatomic = 0; 400 | setivalue(&g->nilvalue, 0); /* to signal that state is not yet built */ 401 | setgcparam(g->gcpause, LUAI_GCPAUSE); 402 | setgcparam(g->gcstepmul, LUAI_GCMUL); 403 | g->gcstepsize = LUAI_GCSTEPSIZE; 404 | setgcparam(g->genmajormul, LUAI_GENMAJORMUL); 405 | g->genminormul = LUAI_GENMINORMUL; 406 | for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL; 407 | if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) { 408 | /* memory allocation error: free partial state */ 409 | close_state(L); 410 | L = NULL; 411 | } 412 | return L; 413 | } 414 | 415 | 416 | LUA_API void lua_close (lua_State *L) { 417 | lua_lock(L); 418 | L = G(L)->mainthread; /* only the main thread can be closed */ 419 | close_state(L); 420 | } 421 | 422 | 423 | void luaE_warning (lua_State *L, const char *msg, int tocont) { 424 | lua_WarnFunction wf = G(L)->warnf; 425 | if (wf != NULL) 426 | wf(G(L)->ud_warn, msg, tocont); 427 | } 428 | 429 | 430 | /* 431 | ** Generate a warning from an error message 432 | */ 433 | void luaE_warnerror (lua_State *L, const char *where) { 434 | TValue *errobj = s2v(L->top.p - 1); /* error object */ 435 | const char *msg = (ttisstring(errobj)) 436 | ? getstr(tsvalue(errobj)) 437 | : "error object is not a string"; 438 | /* produce warning "error in %s (%s)" (where, msg) */ 439 | luaE_warning(L, "error in ", 1); 440 | luaE_warning(L, where, 1); 441 | luaE_warning(L, " (", 1); 442 | luaE_warning(L, msg, 1); 443 | luaE_warning(L, ")", 0); 444 | } 445 | 446 | -------------------------------------------------------------------------------- /src/lstring.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lstring.c $ 3 | ** String table (keeps all strings handled by Lua) 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lstring_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "ldebug.h" 18 | #include "ldo.h" 19 | #include "lmem.h" 20 | #include "lobject.h" 21 | #include "lstate.h" 22 | #include "lstring.h" 23 | 24 | 25 | /* 26 | ** Maximum size for string table. 27 | */ 28 | #define MAXSTRTB cast_int(luaM_limitN(MAX_INT, TString*)) 29 | 30 | 31 | /* 32 | ** equality for long strings 33 | */ 34 | int luaS_eqlngstr (TString *a, TString *b) { 35 | size_t len = a->u.lnglen; 36 | lua_assert(a->tt == LUA_VLNGSTR && b->tt == LUA_VLNGSTR); 37 | return (a == b) || /* same instance or... */ 38 | ((len == b->u.lnglen) && /* equal length and ... */ 39 | (memcmp(getlngstr(a), getlngstr(b), len) == 0)); /* equal contents */ 40 | } 41 | 42 | 43 | unsigned int luaS_hash (const char *str, size_t l, unsigned int seed) { 44 | unsigned int h = seed ^ cast_uint(l); 45 | for (; l > 0; l--) 46 | h ^= ((h<<5) + (h>>2) + cast_byte(str[l - 1])); 47 | return h; 48 | } 49 | 50 | 51 | unsigned int luaS_hashlongstr (TString *ts) { 52 | lua_assert(ts->tt == LUA_VLNGSTR); 53 | if (ts->extra == 0) { /* no hash? */ 54 | size_t len = ts->u.lnglen; 55 | ts->hash = luaS_hash(getlngstr(ts), len, ts->hash); 56 | ts->extra = 1; /* now it has its hash */ 57 | } 58 | return ts->hash; 59 | } 60 | 61 | 62 | static void tablerehash (TString **vect, int osize, int nsize) { 63 | int i; 64 | for (i = osize; i < nsize; i++) /* clear new elements */ 65 | vect[i] = NULL; 66 | for (i = 0; i < osize; i++) { /* rehash old part of the array */ 67 | TString *p = vect[i]; 68 | vect[i] = NULL; 69 | while (p) { /* for each string in the list */ 70 | TString *hnext = p->u.hnext; /* save next */ 71 | unsigned int h = lmod(p->hash, nsize); /* new position */ 72 | p->u.hnext = vect[h]; /* chain it into array */ 73 | vect[h] = p; 74 | p = hnext; 75 | } 76 | } 77 | } 78 | 79 | 80 | /* 81 | ** Resize the string table. If allocation fails, keep the current size. 82 | ** (This can degrade performance, but any non-zero size should work 83 | ** correctly.) 84 | */ 85 | void luaS_resize (lua_State *L, int nsize) { 86 | stringtable *tb = &G(L)->strt; 87 | int osize = tb->size; 88 | TString **newvect; 89 | if (nsize < osize) /* shrinking table? */ 90 | tablerehash(tb->hash, osize, nsize); /* depopulate shrinking part */ 91 | newvect = luaM_reallocvector(L, tb->hash, osize, nsize, TString*); 92 | if (l_unlikely(newvect == NULL)) { /* reallocation failed? */ 93 | if (nsize < osize) /* was it shrinking table? */ 94 | tablerehash(tb->hash, nsize, osize); /* restore to original size */ 95 | /* leave table as it was */ 96 | } 97 | else { /* allocation succeeded */ 98 | tb->hash = newvect; 99 | tb->size = nsize; 100 | if (nsize > osize) 101 | tablerehash(newvect, osize, nsize); /* rehash for new size */ 102 | } 103 | } 104 | 105 | 106 | /* 107 | ** Clear API string cache. (Entries cannot be empty, so fill them with 108 | ** a non-collectable string.) 109 | */ 110 | void luaS_clearcache (global_State *g) { 111 | int i, j; 112 | for (i = 0; i < STRCACHE_N; i++) 113 | for (j = 0; j < STRCACHE_M; j++) { 114 | if (iswhite(g->strcache[i][j])) /* will entry be collected? */ 115 | g->strcache[i][j] = g->memerrmsg; /* replace it with something fixed */ 116 | } 117 | } 118 | 119 | 120 | /* 121 | ** Initialize the string table and the string cache 122 | */ 123 | void luaS_init (lua_State *L) { 124 | global_State *g = G(L); 125 | int i, j; 126 | stringtable *tb = &G(L)->strt; 127 | tb->hash = luaM_newvector(L, MINSTRTABSIZE, TString*); 128 | tablerehash(tb->hash, 0, MINSTRTABSIZE); /* clear array */ 129 | tb->size = MINSTRTABSIZE; 130 | /* pre-create memory-error message */ 131 | g->memerrmsg = luaS_newliteral(L, MEMERRMSG); 132 | luaC_fix(L, obj2gco(g->memerrmsg)); /* it should never be collected */ 133 | for (i = 0; i < STRCACHE_N; i++) /* fill cache with valid strings */ 134 | for (j = 0; j < STRCACHE_M; j++) 135 | g->strcache[i][j] = g->memerrmsg; 136 | } 137 | 138 | 139 | 140 | /* 141 | ** creates a new string object 142 | */ 143 | static TString *createstrobj (lua_State *L, size_t l, int tag, unsigned int h) { 144 | TString *ts; 145 | GCObject *o; 146 | size_t totalsize; /* total size of TString object */ 147 | totalsize = sizelstring(l); 148 | o = luaC_newobj(L, tag, totalsize); 149 | ts = gco2ts(o); 150 | ts->hash = h; 151 | ts->extra = 0; 152 | getstr(ts)[l] = '\0'; /* ending 0 */ 153 | return ts; 154 | } 155 | 156 | 157 | TString *luaS_createlngstrobj (lua_State *L, size_t l) { 158 | TString *ts = createstrobj(L, l, LUA_VLNGSTR, G(L)->seed); 159 | ts->u.lnglen = l; 160 | ts->shrlen = 0xFF; /* signals that it is a long string */ 161 | return ts; 162 | } 163 | 164 | 165 | void luaS_remove (lua_State *L, TString *ts) { 166 | stringtable *tb = &G(L)->strt; 167 | TString **p = &tb->hash[lmod(ts->hash, tb->size)]; 168 | while (*p != ts) /* find previous element */ 169 | p = &(*p)->u.hnext; 170 | *p = (*p)->u.hnext; /* remove element from its list */ 171 | tb->nuse--; 172 | } 173 | 174 | 175 | static void growstrtab (lua_State *L, stringtable *tb) { 176 | if (l_unlikely(tb->nuse == MAX_INT)) { /* too many strings? */ 177 | luaC_fullgc(L, 1); /* try to free some... */ 178 | if (tb->nuse == MAX_INT) /* still too many? */ 179 | luaM_error(L); /* cannot even create a message... */ 180 | } 181 | if (tb->size <= MAXSTRTB / 2) /* can grow string table? */ 182 | luaS_resize(L, tb->size * 2); 183 | } 184 | 185 | 186 | /* 187 | ** Checks whether short string exists and reuses it or creates a new one. 188 | */ 189 | static TString *internshrstr (lua_State *L, const char *str, size_t l) { 190 | TString *ts; 191 | global_State *g = G(L); 192 | stringtable *tb = &g->strt; 193 | unsigned int h = luaS_hash(str, l, g->seed); 194 | TString **list = &tb->hash[lmod(h, tb->size)]; 195 | lua_assert(str != NULL); /* otherwise 'memcmp'/'memcpy' are undefined */ 196 | for (ts = *list; ts != NULL; ts = ts->u.hnext) { 197 | if (l == ts->shrlen && (memcmp(str, getshrstr(ts), l * sizeof(char)) == 0)) { 198 | /* found! */ 199 | if (isdead(g, ts)) /* dead (but not collected yet)? */ 200 | changewhite(ts); /* resurrect it */ 201 | return ts; 202 | } 203 | } 204 | /* else must create a new string */ 205 | if (tb->nuse >= tb->size) { /* need to grow string table? */ 206 | growstrtab(L, tb); 207 | list = &tb->hash[lmod(h, tb->size)]; /* rehash with new size */ 208 | } 209 | ts = createstrobj(L, l, LUA_VSHRSTR, h); 210 | ts->shrlen = cast_byte(l); 211 | memcpy(getshrstr(ts), str, l * sizeof(char)); 212 | ts->u.hnext = *list; 213 | *list = ts; 214 | tb->nuse++; 215 | return ts; 216 | } 217 | 218 | 219 | /* 220 | ** new string (with explicit length) 221 | */ 222 | TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { 223 | if (l <= LUAI_MAXSHORTLEN) /* short string? */ 224 | return internshrstr(L, str, l); 225 | else { 226 | TString *ts; 227 | if (l_unlikely(l * sizeof(char) >= (MAX_SIZE - sizeof(TString)))) 228 | luaM_toobig(L); 229 | ts = luaS_createlngstrobj(L, l); 230 | memcpy(getlngstr(ts), str, l * sizeof(char)); 231 | return ts; 232 | } 233 | } 234 | 235 | 236 | /* 237 | ** Create or reuse a zero-terminated string, first checking in the 238 | ** cache (using the string address as a key). The cache can contain 239 | ** only zero-terminated strings, so it is safe to use 'strcmp' to 240 | ** check hits. 241 | */ 242 | TString *luaS_new (lua_State *L, const char *str) { 243 | unsigned int i = point2uint(str) % STRCACHE_N; /* hash */ 244 | int j; 245 | TString **p = G(L)->strcache[i]; 246 | for (j = 0; j < STRCACHE_M; j++) { 247 | if (strcmp(str, getstr(p[j])) == 0) /* hit? */ 248 | return p[j]; /* that is it */ 249 | } 250 | /* normal route */ 251 | for (j = STRCACHE_M - 1; j > 0; j--) 252 | p[j] = p[j - 1]; /* move out last element */ 253 | /* new element is first in the list */ 254 | p[0] = luaS_newlstr(L, str, strlen(str)); 255 | return p[0]; 256 | } 257 | 258 | 259 | Udata *luaS_newudata (lua_State *L, size_t s, int nuvalue) { 260 | Udata *u; 261 | int i; 262 | GCObject *o; 263 | if (l_unlikely(s > MAX_SIZE - udatamemoffset(nuvalue))) 264 | luaM_toobig(L); 265 | o = luaC_newobj(L, LUA_VUSERDATA, sizeudata(nuvalue, s)); 266 | u = gco2u(o); 267 | u->len = s; 268 | u->nuvalue = nuvalue; 269 | u->metatable = NULL; 270 | for (i = 0; i < nuvalue; i++) 271 | setnilvalue(&u->uv[i].uv); 272 | return u; 273 | } 274 | 275 | -------------------------------------------------------------------------------- /src/lstring.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lstring.h $ 3 | ** String table (keep all strings handled by Lua) 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lstring_h 8 | #define lstring_h 9 | 10 | #include "lgc.h" 11 | #include "lobject.h" 12 | #include "lstate.h" 13 | 14 | 15 | /* 16 | ** Memory-allocation error message must be preallocated (it cannot 17 | ** be created after memory is exhausted) 18 | */ 19 | #define MEMERRMSG "not enough memory" 20 | 21 | 22 | /* 23 | ** Size of a TString: Size of the header plus space for the string 24 | ** itself (including final '\0'). 25 | */ 26 | #define sizelstring(l) (offsetof(TString, contents) + ((l) + 1) * sizeof(char)) 27 | 28 | #define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ 29 | (sizeof(s)/sizeof(char))-1)) 30 | 31 | 32 | /* 33 | ** test whether a string is a reserved word 34 | */ 35 | #define isreserved(s) ((s)->tt == LUA_VSHRSTR && (s)->extra > 0) 36 | 37 | 38 | /* 39 | ** equality for short strings, which are always internalized 40 | */ 41 | #define eqshrstr(a,b) check_exp((a)->tt == LUA_VSHRSTR, (a) == (b)) 42 | 43 | 44 | LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed); 45 | LUAI_FUNC unsigned int luaS_hashlongstr (TString *ts); 46 | LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b); 47 | LUAI_FUNC void luaS_resize (lua_State *L, int newsize); 48 | LUAI_FUNC void luaS_clearcache (global_State *g); 49 | LUAI_FUNC void luaS_init (lua_State *L); 50 | LUAI_FUNC void luaS_remove (lua_State *L, TString *ts); 51 | LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, int nuvalue); 52 | LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); 53 | LUAI_FUNC TString *luaS_new (lua_State *L, const char *str); 54 | LUAI_FUNC TString *luaS_createlngstrobj (lua_State *L, size_t l); 55 | 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /src/ltable.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltable.h $ 3 | ** Lua tables (hash) 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ltable_h 8 | #define ltable_h 9 | 10 | #include "lobject.h" 11 | 12 | 13 | #define gnode(t,i) (&(t)->node[i]) 14 | #define gval(n) (&(n)->i_val) 15 | #define gnext(n) ((n)->u.next) 16 | 17 | 18 | /* 19 | ** Clear all bits of fast-access metamethods, which means that the table 20 | ** may have any of these metamethods. (First access that fails after the 21 | ** clearing will set the bit again.) 22 | */ 23 | #define invalidateTMcache(t) ((t)->flags &= ~maskflags) 24 | 25 | 26 | /* true when 't' is using 'dummynode' as its hash part */ 27 | #define isdummy(t) ((t)->lastfree == NULL) 28 | 29 | 30 | /* allocated size for hash nodes */ 31 | #define allocsizenode(t) (isdummy(t) ? 0 : sizenode(t)) 32 | 33 | 34 | /* returns the Node, given the value of a table entry */ 35 | #define nodefromval(v) cast(Node *, (v)) 36 | 37 | 38 | LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key); 39 | LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key, 40 | TValue *value); 41 | LUAI_FUNC const TValue *luaH_getshortstr (Table *t, TString *key); 42 | LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); 43 | LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); 44 | LUAI_FUNC void luaH_set (lua_State *L, Table *t, const TValue *key, 45 | TValue *value); 46 | LUAI_FUNC void luaH_finishset (lua_State *L, Table *t, const TValue *key, 47 | const TValue *slot, TValue *value); 48 | LUAI_FUNC Table *luaH_new (lua_State *L); 49 | LUAI_FUNC void luaH_resize (lua_State *L, Table *t, unsigned int nasize, 50 | unsigned int nhsize); 51 | LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize); 52 | LUAI_FUNC void luaH_free (lua_State *L, Table *t); 53 | LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); 54 | LUAI_FUNC lua_Unsigned luaH_getn (Table *t); 55 | LUAI_FUNC unsigned int luaH_realasize (const Table *t); 56 | 57 | 58 | #if defined(LUA_DEBUG) 59 | LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key); 60 | #endif 61 | 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /src/ltm.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltm.c $ 3 | ** Tag methods 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define ltm_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "ldebug.h" 18 | #include "ldo.h" 19 | #include "lgc.h" 20 | #include "lobject.h" 21 | #include "lstate.h" 22 | #include "lstring.h" 23 | #include "ltable.h" 24 | #include "ltm.h" 25 | #include "lvm.h" 26 | 27 | 28 | static const char udatatypename[] = "userdata"; 29 | 30 | LUAI_DDEF const char *const luaT_typenames_[LUA_TOTALTYPES] = { 31 | "no value", 32 | "nil", "boolean", udatatypename, "number", 33 | "string", "table", "function", udatatypename, "thread", 34 | "upvalue", "proto" /* these last cases are used for tests only */ 35 | }; 36 | 37 | 38 | void luaT_init (lua_State *L) { 39 | static const char *const luaT_eventname[] = { /* ORDER TM */ 40 | "__index", "__newindex", 41 | "__gc", "__mode", "__len", "__eq", 42 | "__add", "__sub", "__mul", "__mod", "__pow", 43 | "__div", "__idiv", 44 | "__band", "__bor", "__bxor", "__shl", "__shr", 45 | "__unm", "__bnot", "__lt", "__le", 46 | "__concat", "__call", "__close" 47 | }; 48 | int i; 49 | for (i=0; itmname[i] = luaS_new(L, luaT_eventname[i]); 51 | luaC_fix(L, obj2gco(G(L)->tmname[i])); /* never collect these names */ 52 | } 53 | } 54 | 55 | 56 | /* 57 | ** function to be used with macro "fasttm": optimized for absence of 58 | ** tag methods 59 | */ 60 | const TValue *luaT_gettm (Table *events, TMS event, TString *ename) { 61 | const TValue *tm = luaH_getshortstr(events, ename); 62 | lua_assert(event <= TM_EQ); 63 | if (notm(tm)) { /* no tag method? */ 64 | events->flags |= cast_byte(1u<metatable; 76 | break; 77 | case LUA_TUSERDATA: 78 | mt = uvalue(o)->metatable; 79 | break; 80 | default: 81 | mt = G(L)->mt[ttype(o)]; 82 | } 83 | return (mt ? luaH_getshortstr(mt, G(L)->tmname[event]) : &G(L)->nilvalue); 84 | } 85 | 86 | 87 | /* 88 | ** Return the name of the type of an object. For tables and userdata 89 | ** with metatable, use their '__name' metafield, if present. 90 | */ 91 | const char *luaT_objtypename (lua_State *L, const TValue *o) { 92 | Table *mt; 93 | if ((ttistable(o) && (mt = hvalue(o)->metatable) != NULL) || 94 | (ttisfulluserdata(o) && (mt = uvalue(o)->metatable) != NULL)) { 95 | const TValue *name = luaH_getshortstr(mt, luaS_new(L, "__name")); 96 | if (ttisstring(name)) /* is '__name' a string? */ 97 | return getstr(tsvalue(name)); /* use it as type name */ 98 | } 99 | return ttypename(ttype(o)); /* else use standard type name */ 100 | } 101 | 102 | 103 | void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1, 104 | const TValue *p2, const TValue *p3) { 105 | StkId func = L->top.p; 106 | setobj2s(L, func, f); /* push function (assume EXTRA_STACK) */ 107 | setobj2s(L, func + 1, p1); /* 1st argument */ 108 | setobj2s(L, func + 2, p2); /* 2nd argument */ 109 | setobj2s(L, func + 3, p3); /* 3rd argument */ 110 | L->top.p = func + 4; 111 | /* metamethod may yield only when called from Lua code */ 112 | if (isLuacode(L->ci)) 113 | luaD_call(L, func, 0); 114 | else 115 | luaD_callnoyield(L, func, 0); 116 | } 117 | 118 | 119 | void luaT_callTMres (lua_State *L, const TValue *f, const TValue *p1, 120 | const TValue *p2, StkId res) { 121 | ptrdiff_t result = savestack(L, res); 122 | StkId func = L->top.p; 123 | setobj2s(L, func, f); /* push function (assume EXTRA_STACK) */ 124 | setobj2s(L, func + 1, p1); /* 1st argument */ 125 | setobj2s(L, func + 2, p2); /* 2nd argument */ 126 | L->top.p += 3; 127 | /* metamethod may yield only when called from Lua code */ 128 | if (isLuacode(L->ci)) 129 | luaD_call(L, func, 1); 130 | else 131 | luaD_callnoyield(L, func, 1); 132 | res = restorestack(L, result); 133 | setobjs2s(L, res, --L->top.p); /* move result to its place */ 134 | } 135 | 136 | 137 | static int callbinTM (lua_State *L, const TValue *p1, const TValue *p2, 138 | StkId res, TMS event) { 139 | const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */ 140 | if (notm(tm)) 141 | tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ 142 | if (notm(tm)) return 0; 143 | luaT_callTMres(L, tm, p1, p2, res); 144 | return 1; 145 | } 146 | 147 | 148 | void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, 149 | StkId res, TMS event) { 150 | if (l_unlikely(!callbinTM(L, p1, p2, res, event))) { 151 | switch (event) { 152 | case TM_BAND: case TM_BOR: case TM_BXOR: 153 | case TM_SHL: case TM_SHR: case TM_BNOT: { 154 | if (ttisnumber(p1) && ttisnumber(p2)) 155 | luaG_tointerror(L, p1, p2); 156 | else 157 | luaG_opinterror(L, p1, p2, "perform bitwise operation on"); 158 | } 159 | /* calls never return, but to avoid warnings: *//* FALLTHROUGH */ 160 | default: 161 | luaG_opinterror(L, p1, p2, "perform arithmetic on"); 162 | } 163 | } 164 | } 165 | 166 | 167 | void luaT_tryconcatTM (lua_State *L) { 168 | StkId top = L->top.p; 169 | if (l_unlikely(!callbinTM(L, s2v(top - 2), s2v(top - 1), top - 2, 170 | TM_CONCAT))) 171 | luaG_concaterror(L, s2v(top - 2), s2v(top - 1)); 172 | } 173 | 174 | 175 | void luaT_trybinassocTM (lua_State *L, const TValue *p1, const TValue *p2, 176 | int flip, StkId res, TMS event) { 177 | if (flip) 178 | luaT_trybinTM(L, p2, p1, res, event); 179 | else 180 | luaT_trybinTM(L, p1, p2, res, event); 181 | } 182 | 183 | 184 | void luaT_trybiniTM (lua_State *L, const TValue *p1, lua_Integer i2, 185 | int flip, StkId res, TMS event) { 186 | TValue aux; 187 | setivalue(&aux, i2); 188 | luaT_trybinassocTM(L, p1, &aux, flip, res, event); 189 | } 190 | 191 | 192 | /* 193 | ** Calls an order tag method. 194 | ** For lessequal, LUA_COMPAT_LT_LE keeps compatibility with old 195 | ** behavior: if there is no '__le', try '__lt', based on l <= r iff 196 | ** !(r < l) (assuming a total order). If the metamethod yields during 197 | ** this substitution, the continuation has to know about it (to negate 198 | ** the result of rtop.p, event)) /* try original event */ 204 | return !l_isfalse(s2v(L->top.p)); 205 | #if defined(LUA_COMPAT_LT_LE) 206 | else if (event == TM_LE) { 207 | /* try '!(p2 < p1)' for '(p1 <= p2)' */ 208 | L->ci->callstatus |= CIST_LEQ; /* mark it is doing 'lt' for 'le' */ 209 | if (callbinTM(L, p2, p1, L->top.p, TM_LT)) { 210 | L->ci->callstatus ^= CIST_LEQ; /* clear mark */ 211 | return l_isfalse(s2v(L->top.p)); 212 | } 213 | /* else error will remove this 'ci'; no need to clear mark */ 214 | } 215 | #endif 216 | luaG_ordererror(L, p1, p2); /* no metamethod found */ 217 | return 0; /* to avoid warnings */ 218 | } 219 | 220 | 221 | int luaT_callorderiTM (lua_State *L, const TValue *p1, int v2, 222 | int flip, int isfloat, TMS event) { 223 | TValue aux; const TValue *p2; 224 | if (isfloat) { 225 | setfltvalue(&aux, cast_num(v2)); 226 | } 227 | else 228 | setivalue(&aux, v2); 229 | if (flip) { /* arguments were exchanged? */ 230 | p2 = p1; p1 = &aux; /* correct them */ 231 | } 232 | else 233 | p2 = &aux; 234 | return luaT_callorderTM(L, p1, p2, event); 235 | } 236 | 237 | 238 | void luaT_adjustvarargs (lua_State *L, int nfixparams, CallInfo *ci, 239 | const Proto *p) { 240 | int i; 241 | int actual = cast_int(L->top.p - ci->func.p) - 1; /* number of arguments */ 242 | int nextra = actual - nfixparams; /* number of extra arguments */ 243 | ci->u.l.nextraargs = nextra; 244 | luaD_checkstack(L, p->maxstacksize + 1); 245 | /* copy function to the top of the stack */ 246 | setobjs2s(L, L->top.p++, ci->func.p); 247 | /* move fixed parameters to the top of the stack */ 248 | for (i = 1; i <= nfixparams; i++) { 249 | setobjs2s(L, L->top.p++, ci->func.p + i); 250 | setnilvalue(s2v(ci->func.p + i)); /* erase original parameter (for GC) */ 251 | } 252 | ci->func.p += actual + 1; 253 | ci->top.p += actual + 1; 254 | lua_assert(L->top.p <= ci->top.p && ci->top.p <= L->stack_last.p); 255 | } 256 | 257 | 258 | void luaT_getvarargs (lua_State *L, CallInfo *ci, StkId where, int wanted) { 259 | int i; 260 | int nextra = ci->u.l.nextraargs; 261 | if (wanted < 0) { 262 | wanted = nextra; /* get all extra arguments available */ 263 | checkstackGCp(L, nextra, where); /* ensure stack space */ 264 | L->top.p = where + nextra; /* next instruction will need top */ 265 | } 266 | for (i = 0; i < wanted && i < nextra; i++) 267 | setobjs2s(L, where + i, ci->func.p - nextra + i); 268 | for (; i < wanted; i++) /* complete required results with nil */ 269 | setnilvalue(s2v(where + i)); 270 | } 271 | 272 | -------------------------------------------------------------------------------- /src/ltm.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltm.h $ 3 | ** Tag methods 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ltm_h 8 | #define ltm_h 9 | 10 | 11 | #include "lobject.h" 12 | 13 | 14 | /* 15 | * WARNING: if you change the order of this enumeration, 16 | * grep "ORDER TM" and "ORDER OP" 17 | */ 18 | typedef enum { 19 | TM_INDEX, 20 | TM_NEWINDEX, 21 | TM_GC, 22 | TM_MODE, 23 | TM_LEN, 24 | TM_EQ, /* last tag method with fast access */ 25 | TM_ADD, 26 | TM_SUB, 27 | TM_MUL, 28 | TM_MOD, 29 | TM_POW, 30 | TM_DIV, 31 | TM_IDIV, 32 | TM_BAND, 33 | TM_BOR, 34 | TM_BXOR, 35 | TM_SHL, 36 | TM_SHR, 37 | TM_UNM, 38 | TM_BNOT, 39 | TM_LT, 40 | TM_LE, 41 | TM_CONCAT, 42 | TM_CALL, 43 | TM_CLOSE, 44 | TM_N /* number of elements in the enum */ 45 | } TMS; 46 | 47 | 48 | /* 49 | ** Mask with 1 in all fast-access methods. A 1 in any of these bits 50 | ** in the flag of a (meta)table means the metatable does not have the 51 | ** corresponding metamethod field. (Bit 7 of the flag is used for 52 | ** 'isrealasize'.) 53 | */ 54 | #define maskflags (~(~0u << (TM_EQ + 1))) 55 | 56 | 57 | /* 58 | ** Test whether there is no tagmethod. 59 | ** (Because tagmethods use raw accesses, the result may be an "empty" nil.) 60 | */ 61 | #define notm(tm) ttisnil(tm) 62 | 63 | 64 | #define gfasttm(g,et,e) ((et) == NULL ? NULL : \ 65 | ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e])) 66 | 67 | #define fasttm(l,et,e) gfasttm(G(l), et, e) 68 | 69 | #define ttypename(x) luaT_typenames_[(x) + 1] 70 | 71 | LUAI_DDEC(const char *const luaT_typenames_[LUA_TOTALTYPES];) 72 | 73 | 74 | LUAI_FUNC const char *luaT_objtypename (lua_State *L, const TValue *o); 75 | 76 | LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename); 77 | LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, 78 | TMS event); 79 | LUAI_FUNC void luaT_init (lua_State *L); 80 | 81 | LUAI_FUNC void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1, 82 | const TValue *p2, const TValue *p3); 83 | LUAI_FUNC void luaT_callTMres (lua_State *L, const TValue *f, 84 | const TValue *p1, const TValue *p2, StkId p3); 85 | LUAI_FUNC void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, 86 | StkId res, TMS event); 87 | LUAI_FUNC void luaT_tryconcatTM (lua_State *L); 88 | LUAI_FUNC void luaT_trybinassocTM (lua_State *L, const TValue *p1, 89 | const TValue *p2, int inv, StkId res, TMS event); 90 | LUAI_FUNC void luaT_trybiniTM (lua_State *L, const TValue *p1, lua_Integer i2, 91 | int inv, StkId res, TMS event); 92 | LUAI_FUNC int luaT_callorderTM (lua_State *L, const TValue *p1, 93 | const TValue *p2, TMS event); 94 | LUAI_FUNC int luaT_callorderiTM (lua_State *L, const TValue *p1, int v2, 95 | int inv, int isfloat, TMS event); 96 | 97 | LUAI_FUNC void luaT_adjustvarargs (lua_State *L, int nfixparams, 98 | struct CallInfo *ci, const Proto *p); 99 | LUAI_FUNC void luaT_getvarargs (lua_State *L, struct CallInfo *ci, 100 | StkId where, int wanted); 101 | 102 | 103 | #endif 104 | -------------------------------------------------------------------------------- /src/lua.hpp: -------------------------------------------------------------------------------- 1 | // lua.hpp 2 | // Lua header files for C++ 3 | // <> not supplied automatically because Lua also compiles as C++ 4 | 5 | extern "C" { 6 | #include "lua.h" 7 | #include "lualib.h" 8 | #include "lauxlib.h" 9 | } 10 | -------------------------------------------------------------------------------- /src/lualib.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lualib.h $ 3 | ** Lua standard libraries 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lualib_h 9 | #define lualib_h 10 | 11 | #include "lua.h" 12 | 13 | 14 | /* version suffix for environment variable names */ 15 | #define LUA_VERSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR 16 | 17 | 18 | LUAMOD_API int (luaopen_base) (lua_State *L); 19 | 20 | #define LUA_COLIBNAME "coroutine" 21 | LUAMOD_API int (luaopen_coroutine) (lua_State *L); 22 | 23 | #define LUA_TABLIBNAME "table" 24 | LUAMOD_API int (luaopen_table) (lua_State *L); 25 | 26 | #define LUA_IOLIBNAME "io" 27 | LUAMOD_API int (luaopen_io) (lua_State *L); 28 | 29 | #define LUA_OSLIBNAME "os" 30 | LUAMOD_API int (luaopen_os) (lua_State *L); 31 | 32 | #define LUA_STRLIBNAME "string" 33 | LUAMOD_API int (luaopen_string) (lua_State *L); 34 | 35 | #define LUA_UTF8LIBNAME "utf8" 36 | LUAMOD_API int (luaopen_utf8) (lua_State *L); 37 | 38 | #define LUA_MATHLIBNAME "math" 39 | LUAMOD_API int (luaopen_math) (lua_State *L); 40 | 41 | #define LUA_DBLIBNAME "debug" 42 | LUAMOD_API int (luaopen_debug) (lua_State *L); 43 | 44 | #define LUA_LOADLIBNAME "package" 45 | LUAMOD_API int (luaopen_package) (lua_State *L); 46 | 47 | 48 | /* open all previous libraries */ 49 | LUALIB_API void (luaL_openlibs) (lua_State *L); 50 | 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /src/lundump.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lundump.c $ 3 | ** load precompiled Lua chunks 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lundump_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | #include 15 | 16 | #include "lua.h" 17 | 18 | #include "ldebug.h" 19 | #include "ldo.h" 20 | #include "lfunc.h" 21 | #include "lmem.h" 22 | #include "lobject.h" 23 | #include "lstring.h" 24 | #include "lundump.h" 25 | #include "lzio.h" 26 | 27 | 28 | #if !defined(luai_verifycode) 29 | #define luai_verifycode(L,f) /* empty */ 30 | #endif 31 | 32 | 33 | typedef struct { 34 | lua_State *L; 35 | ZIO *Z; 36 | const char *name; 37 | } LoadState; 38 | 39 | 40 | static l_noret error (LoadState *S, const char *why) { 41 | luaO_pushfstring(S->L, "%s: bad binary format (%s)", S->name, why); 42 | luaD_throw(S->L, LUA_ERRSYNTAX); 43 | } 44 | 45 | 46 | /* 47 | ** All high-level loads go through loadVector; you can change it to 48 | ** adapt to the endianness of the input 49 | */ 50 | #define loadVector(S,b,n) loadBlock(S,b,(n)*sizeof((b)[0])) 51 | 52 | static void loadBlock (LoadState *S, void *b, size_t size) { 53 | if (luaZ_read(S->Z, b, size) != 0) 54 | error(S, "truncated chunk"); 55 | } 56 | 57 | 58 | #define loadVar(S,x) loadVector(S,&x,1) 59 | 60 | 61 | static lu_byte loadByte (LoadState *S) { 62 | int b = zgetc(S->Z); 63 | if (b == EOZ) 64 | error(S, "truncated chunk"); 65 | return cast_byte(b); 66 | } 67 | 68 | 69 | static size_t loadUnsigned (LoadState *S, size_t limit) { 70 | size_t x = 0; 71 | int b; 72 | limit >>= 7; 73 | do { 74 | b = loadByte(S); 75 | if (x >= limit) 76 | error(S, "integer overflow"); 77 | x = (x << 7) | (b & 0x7f); 78 | } while ((b & 0x80) == 0); 79 | return x; 80 | } 81 | 82 | 83 | static size_t loadSize (LoadState *S) { 84 | return loadUnsigned(S, MAX_SIZET); 85 | } 86 | 87 | 88 | static int loadInt (LoadState *S) { 89 | return cast_int(loadUnsigned(S, INT_MAX)); 90 | } 91 | 92 | 93 | static lua_Number loadNumber (LoadState *S) { 94 | lua_Number x; 95 | loadVar(S, x); 96 | return x; 97 | } 98 | 99 | 100 | static lua_Integer loadInteger (LoadState *S) { 101 | lua_Integer x; 102 | loadVar(S, x); 103 | return x; 104 | } 105 | 106 | 107 | /* 108 | ** Load a nullable string into prototype 'p'. 109 | */ 110 | static TString *loadStringN (LoadState *S, Proto *p) { 111 | lua_State *L = S->L; 112 | TString *ts; 113 | size_t size = loadSize(S); 114 | if (size == 0) /* no string? */ 115 | return NULL; 116 | else if (--size <= LUAI_MAXSHORTLEN) { /* short string? */ 117 | char buff[LUAI_MAXSHORTLEN]; 118 | loadVector(S, buff, size); /* load string into buffer */ 119 | ts = luaS_newlstr(L, buff, size); /* create string */ 120 | } 121 | else { /* long string */ 122 | ts = luaS_createlngstrobj(L, size); /* create string */ 123 | setsvalue2s(L, L->top.p, ts); /* anchor it ('loadVector' can GC) */ 124 | luaD_inctop(L); 125 | loadVector(S, getlngstr(ts), size); /* load directly in final place */ 126 | L->top.p--; /* pop string */ 127 | } 128 | luaC_objbarrier(L, p, ts); 129 | return ts; 130 | } 131 | 132 | 133 | /* 134 | ** Load a non-nullable string into prototype 'p'. 135 | */ 136 | static TString *loadString (LoadState *S, Proto *p) { 137 | TString *st = loadStringN(S, p); 138 | if (st == NULL) 139 | error(S, "bad format for constant string"); 140 | return st; 141 | } 142 | 143 | 144 | static void loadCode (LoadState *S, Proto *f) { 145 | int n = loadInt(S); 146 | f->code = luaM_newvectorchecked(S->L, n, Instruction); 147 | f->sizecode = n; 148 | loadVector(S, f->code, n); 149 | } 150 | 151 | 152 | static void loadFunction(LoadState *S, Proto *f, TString *psource); 153 | 154 | 155 | static void loadConstants (LoadState *S, Proto *f) { 156 | int i; 157 | int n = loadInt(S); 158 | f->k = luaM_newvectorchecked(S->L, n, TValue); 159 | f->sizek = n; 160 | for (i = 0; i < n; i++) 161 | setnilvalue(&f->k[i]); 162 | for (i = 0; i < n; i++) { 163 | TValue *o = &f->k[i]; 164 | int t = loadByte(S); 165 | switch (t) { 166 | case LUA_VNIL: 167 | setnilvalue(o); 168 | break; 169 | case LUA_VFALSE: 170 | setbfvalue(o); 171 | break; 172 | case LUA_VTRUE: 173 | setbtvalue(o); 174 | break; 175 | case LUA_VNUMFLT: 176 | setfltvalue(o, loadNumber(S)); 177 | break; 178 | case LUA_VNUMINT: 179 | setivalue(o, loadInteger(S)); 180 | break; 181 | case LUA_VSHRSTR: 182 | case LUA_VLNGSTR: 183 | setsvalue2n(S->L, o, loadString(S, f)); 184 | break; 185 | default: lua_assert(0); 186 | } 187 | } 188 | } 189 | 190 | 191 | static void loadProtos (LoadState *S, Proto *f) { 192 | int i; 193 | int n = loadInt(S); 194 | f->p = luaM_newvectorchecked(S->L, n, Proto *); 195 | f->sizep = n; 196 | for (i = 0; i < n; i++) 197 | f->p[i] = NULL; 198 | for (i = 0; i < n; i++) { 199 | f->p[i] = luaF_newproto(S->L); 200 | luaC_objbarrier(S->L, f, f->p[i]); 201 | loadFunction(S, f->p[i], f->source); 202 | } 203 | } 204 | 205 | 206 | /* 207 | ** Load the upvalues for a function. The names must be filled first, 208 | ** because the filling of the other fields can raise read errors and 209 | ** the creation of the error message can call an emergency collection; 210 | ** in that case all prototypes must be consistent for the GC. 211 | */ 212 | static void loadUpvalues (LoadState *S, Proto *f) { 213 | int i, n; 214 | n = loadInt(S); 215 | f->upvalues = luaM_newvectorchecked(S->L, n, Upvaldesc); 216 | f->sizeupvalues = n; 217 | for (i = 0; i < n; i++) /* make array valid for GC */ 218 | f->upvalues[i].name = NULL; 219 | for (i = 0; i < n; i++) { /* following calls can raise errors */ 220 | f->upvalues[i].instack = loadByte(S); 221 | f->upvalues[i].idx = loadByte(S); 222 | f->upvalues[i].kind = loadByte(S); 223 | } 224 | } 225 | 226 | 227 | static void loadDebug (LoadState *S, Proto *f) { 228 | int i, n; 229 | n = loadInt(S); 230 | f->lineinfo = luaM_newvectorchecked(S->L, n, ls_byte); 231 | f->sizelineinfo = n; 232 | loadVector(S, f->lineinfo, n); 233 | n = loadInt(S); 234 | f->abslineinfo = luaM_newvectorchecked(S->L, n, AbsLineInfo); 235 | f->sizeabslineinfo = n; 236 | for (i = 0; i < n; i++) { 237 | f->abslineinfo[i].pc = loadInt(S); 238 | f->abslineinfo[i].line = loadInt(S); 239 | } 240 | n = loadInt(S); 241 | f->locvars = luaM_newvectorchecked(S->L, n, LocVar); 242 | f->sizelocvars = n; 243 | for (i = 0; i < n; i++) 244 | f->locvars[i].varname = NULL; 245 | for (i = 0; i < n; i++) { 246 | f->locvars[i].varname = loadStringN(S, f); 247 | f->locvars[i].startpc = loadInt(S); 248 | f->locvars[i].endpc = loadInt(S); 249 | } 250 | n = loadInt(S); 251 | if (n != 0) /* does it have debug information? */ 252 | n = f->sizeupvalues; /* must be this many */ 253 | for (i = 0; i < n; i++) 254 | f->upvalues[i].name = loadStringN(S, f); 255 | } 256 | 257 | 258 | static void loadFunction (LoadState *S, Proto *f, TString *psource) { 259 | f->source = loadStringN(S, f); 260 | if (f->source == NULL) /* no source in dump? */ 261 | f->source = psource; /* reuse parent's source */ 262 | f->linedefined = loadInt(S); 263 | f->lastlinedefined = loadInt(S); 264 | f->numparams = loadByte(S); 265 | f->is_vararg = loadByte(S); 266 | f->maxstacksize = loadByte(S); 267 | loadCode(S, f); 268 | loadConstants(S, f); 269 | loadUpvalues(S, f); 270 | loadProtos(S, f); 271 | loadDebug(S, f); 272 | } 273 | 274 | 275 | static void checkliteral (LoadState *S, const char *s, const char *msg) { 276 | char buff[sizeof(LUA_SIGNATURE) + sizeof(LUAC_DATA)]; /* larger than both */ 277 | size_t len = strlen(s); 278 | loadVector(S, buff, len); 279 | if (memcmp(s, buff, len) != 0) 280 | error(S, msg); 281 | } 282 | 283 | 284 | static void fchecksize (LoadState *S, size_t size, const char *tname) { 285 | if (loadByte(S) != size) 286 | error(S, luaO_pushfstring(S->L, "%s size mismatch", tname)); 287 | } 288 | 289 | 290 | #define checksize(S,t) fchecksize(S,sizeof(t),#t) 291 | 292 | static void checkHeader (LoadState *S) { 293 | /* skip 1st char (already read and checked) */ 294 | checkliteral(S, &LUA_SIGNATURE[1], "not a binary chunk"); 295 | if (loadByte(S) != LUAC_VERSION) 296 | error(S, "version mismatch"); 297 | if (loadByte(S) != LUAC_FORMAT) 298 | error(S, "format mismatch"); 299 | checkliteral(S, LUAC_DATA, "corrupted chunk"); 300 | checksize(S, Instruction); 301 | checksize(S, lua_Integer); 302 | checksize(S, lua_Number); 303 | if (loadInteger(S) != LUAC_INT) 304 | error(S, "integer format mismatch"); 305 | if (loadNumber(S) != LUAC_NUM) 306 | error(S, "float format mismatch"); 307 | } 308 | 309 | 310 | /* 311 | ** Load precompiled chunk. 312 | */ 313 | LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) { 314 | LoadState S; 315 | LClosure *cl; 316 | if (*name == '@' || *name == '=') 317 | S.name = name + 1; 318 | else if (*name == LUA_SIGNATURE[0]) 319 | S.name = "binary string"; 320 | else 321 | S.name = name; 322 | S.L = L; 323 | S.Z = Z; 324 | checkHeader(&S); 325 | cl = luaF_newLclosure(L, loadByte(&S)); 326 | setclLvalue2s(L, L->top.p, cl); 327 | luaD_inctop(L); 328 | cl->p = luaF_newproto(L); 329 | luaC_objbarrier(L, cl, cl->p); 330 | loadFunction(&S, cl->p, NULL); 331 | lua_assert(cl->nupvalues == cl->p->sizeupvalues); 332 | luai_verifycode(L, cl->p); 333 | return cl; 334 | } 335 | 336 | -------------------------------------------------------------------------------- /src/lundump.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lundump.h $ 3 | ** load precompiled Lua chunks 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lundump_h 8 | #define lundump_h 9 | 10 | #include "llimits.h" 11 | #include "lobject.h" 12 | #include "lzio.h" 13 | 14 | 15 | /* data to catch conversion errors */ 16 | #define LUAC_DATA "\x19\x93\r\n\x1a\n" 17 | 18 | #define LUAC_INT 0x5678 19 | #define LUAC_NUM cast_num(370.5) 20 | 21 | /* 22 | ** Encode major-minor version in one byte, one nibble for each 23 | */ 24 | #define LUAC_VERSION (((LUA_VERSION_NUM / 100) * 16) + LUA_VERSION_NUM % 100) 25 | 26 | #define LUAC_FORMAT 0 /* this is the official format */ 27 | 28 | /* load one chunk; from lundump.c */ 29 | LUAI_FUNC LClosure* luaU_undump (lua_State* L, ZIO* Z, const char* name); 30 | 31 | /* dump one chunk; from ldump.c */ 32 | LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, 33 | void* data, int strip); 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/lutf8lib.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lutf8lib.c $ 3 | ** Standard library for UTF-8 manipulation 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lutf8lib_c 8 | #define LUA_LIB 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include "lua.h" 19 | 20 | #include "lauxlib.h" 21 | #include "lualib.h" 22 | 23 | 24 | #define MAXUNICODE 0x10FFFFu 25 | 26 | #define MAXUTF 0x7FFFFFFFu 27 | 28 | 29 | #define MSGInvalid "invalid UTF-8 code" 30 | 31 | /* 32 | ** Integer type for decoded UTF-8 values; MAXUTF needs 31 bits. 33 | */ 34 | #if (UINT_MAX >> 30) >= 1 35 | typedef unsigned int utfint; 36 | #else 37 | typedef unsigned long utfint; 38 | #endif 39 | 40 | 41 | #define iscont(c) (((c) & 0xC0) == 0x80) 42 | #define iscontp(p) iscont(*(p)) 43 | 44 | 45 | /* from strlib */ 46 | /* translate a relative string position: negative means back from end */ 47 | static lua_Integer u_posrelat (lua_Integer pos, size_t len) { 48 | if (pos >= 0) return pos; 49 | else if (0u - (size_t)pos > len) return 0; 50 | else return (lua_Integer)len + pos + 1; 51 | } 52 | 53 | 54 | /* 55 | ** Decode one UTF-8 sequence, returning NULL if byte sequence is 56 | ** invalid. The array 'limits' stores the minimum value for each 57 | ** sequence length, to check for overlong representations. Its first 58 | ** entry forces an error for non-ascii bytes with no continuation 59 | ** bytes (count == 0). 60 | */ 61 | static const char *utf8_decode (const char *s, utfint *val, int strict) { 62 | static const utfint limits[] = 63 | {~(utfint)0, 0x80, 0x800, 0x10000u, 0x200000u, 0x4000000u}; 64 | unsigned int c = (unsigned char)s[0]; 65 | utfint res = 0; /* final result */ 66 | if (c < 0x80) /* ascii? */ 67 | res = c; 68 | else { 69 | int count = 0; /* to count number of continuation bytes */ 70 | for (; c & 0x40; c <<= 1) { /* while it needs continuation bytes... */ 71 | unsigned int cc = (unsigned char)s[++count]; /* read next byte */ 72 | if (!iscont(cc)) /* not a continuation byte? */ 73 | return NULL; /* invalid byte sequence */ 74 | res = (res << 6) | (cc & 0x3F); /* add lower 6 bits from cont. byte */ 75 | } 76 | res |= ((utfint)(c & 0x7F) << (count * 5)); /* add first byte */ 77 | if (count > 5 || res > MAXUTF || res < limits[count]) 78 | return NULL; /* invalid byte sequence */ 79 | s += count; /* skip continuation bytes read */ 80 | } 81 | if (strict) { 82 | /* check for invalid code points; too large or surrogates */ 83 | if (res > MAXUNICODE || (0xD800u <= res && res <= 0xDFFFu)) 84 | return NULL; 85 | } 86 | if (val) *val = res; 87 | return s + 1; /* +1 to include first byte */ 88 | } 89 | 90 | 91 | /* 92 | ** utf8len(s [, i [, j [, lax]]]) --> number of characters that 93 | ** start in the range [i,j], or nil + current position if 's' is not 94 | ** well formed in that interval 95 | */ 96 | static int utflen (lua_State *L) { 97 | lua_Integer n = 0; /* counter for the number of characters */ 98 | size_t len; /* string length in bytes */ 99 | const char *s = luaL_checklstring(L, 1, &len); 100 | lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), len); 101 | lua_Integer posj = u_posrelat(luaL_optinteger(L, 3, -1), len); 102 | int lax = lua_toboolean(L, 4); 103 | luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 2, 104 | "initial position out of bounds"); 105 | luaL_argcheck(L, --posj < (lua_Integer)len, 3, 106 | "final position out of bounds"); 107 | while (posi <= posj) { 108 | const char *s1 = utf8_decode(s + posi, NULL, !lax); 109 | if (s1 == NULL) { /* conversion error? */ 110 | luaL_pushfail(L); /* return fail ... */ 111 | lua_pushinteger(L, posi + 1); /* ... and current position */ 112 | return 2; 113 | } 114 | posi = s1 - s; 115 | n++; 116 | } 117 | lua_pushinteger(L, n); 118 | return 1; 119 | } 120 | 121 | 122 | /* 123 | ** codepoint(s, [i, [j [, lax]]]) -> returns codepoints for all 124 | ** characters that start in the range [i,j] 125 | */ 126 | static int codepoint (lua_State *L) { 127 | size_t len; 128 | const char *s = luaL_checklstring(L, 1, &len); 129 | lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), len); 130 | lua_Integer pose = u_posrelat(luaL_optinteger(L, 3, posi), len); 131 | int lax = lua_toboolean(L, 4); 132 | int n; 133 | const char *se; 134 | luaL_argcheck(L, posi >= 1, 2, "out of bounds"); 135 | luaL_argcheck(L, pose <= (lua_Integer)len, 3, "out of bounds"); 136 | if (posi > pose) return 0; /* empty interval; return no values */ 137 | if (pose - posi >= INT_MAX) /* (lua_Integer -> int) overflow? */ 138 | return luaL_error(L, "string slice too long"); 139 | n = (int)(pose - posi) + 1; /* upper bound for number of returns */ 140 | luaL_checkstack(L, n, "string slice too long"); 141 | n = 0; /* count the number of returns */ 142 | se = s + pose; /* string end */ 143 | for (s += posi - 1; s < se;) { 144 | utfint code; 145 | s = utf8_decode(s, &code, !lax); 146 | if (s == NULL) 147 | return luaL_error(L, MSGInvalid); 148 | lua_pushinteger(L, code); 149 | n++; 150 | } 151 | return n; 152 | } 153 | 154 | 155 | static void pushutfchar (lua_State *L, int arg) { 156 | lua_Unsigned code = (lua_Unsigned)luaL_checkinteger(L, arg); 157 | luaL_argcheck(L, code <= MAXUTF, arg, "value out of range"); 158 | lua_pushfstring(L, "%U", (long)code); 159 | } 160 | 161 | 162 | /* 163 | ** utfchar(n1, n2, ...) -> char(n1)..char(n2)... 164 | */ 165 | static int utfchar (lua_State *L) { 166 | int n = lua_gettop(L); /* number of arguments */ 167 | if (n == 1) /* optimize common case of single char */ 168 | pushutfchar(L, 1); 169 | else { 170 | int i; 171 | luaL_Buffer b; 172 | luaL_buffinit(L, &b); 173 | for (i = 1; i <= n; i++) { 174 | pushutfchar(L, i); 175 | luaL_addvalue(&b); 176 | } 177 | luaL_pushresult(&b); 178 | } 179 | return 1; 180 | } 181 | 182 | 183 | /* 184 | ** offset(s, n, [i]) -> index where n-th character counting from 185 | ** position 'i' starts; 0 means character at 'i'. 186 | */ 187 | static int byteoffset (lua_State *L) { 188 | size_t len; 189 | const char *s = luaL_checklstring(L, 1, &len); 190 | lua_Integer n = luaL_checkinteger(L, 2); 191 | lua_Integer posi = (n >= 0) ? 1 : len + 1; 192 | posi = u_posrelat(luaL_optinteger(L, 3, posi), len); 193 | luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 3, 194 | "position out of bounds"); 195 | if (n == 0) { 196 | /* find beginning of current byte sequence */ 197 | while (posi > 0 && iscontp(s + posi)) posi--; 198 | } 199 | else { 200 | if (iscontp(s + posi)) 201 | return luaL_error(L, "initial position is a continuation byte"); 202 | if (n < 0) { 203 | while (n < 0 && posi > 0) { /* move back */ 204 | do { /* find beginning of previous character */ 205 | posi--; 206 | } while (posi > 0 && iscontp(s + posi)); 207 | n++; 208 | } 209 | } 210 | else { 211 | n--; /* do not move for 1st character */ 212 | while (n > 0 && posi < (lua_Integer)len) { 213 | do { /* find beginning of next character */ 214 | posi++; 215 | } while (iscontp(s + posi)); /* (cannot pass final '\0') */ 216 | n--; 217 | } 218 | } 219 | } 220 | if (n == 0) /* did it find given character? */ 221 | lua_pushinteger(L, posi + 1); 222 | else /* no such character */ 223 | luaL_pushfail(L); 224 | return 1; 225 | } 226 | 227 | 228 | static int iter_aux (lua_State *L, int strict) { 229 | size_t len; 230 | const char *s = luaL_checklstring(L, 1, &len); 231 | lua_Unsigned n = (lua_Unsigned)lua_tointeger(L, 2); 232 | if (n < len) { 233 | while (iscontp(s + n)) n++; /* go to next character */ 234 | } 235 | if (n >= len) /* (also handles original 'n' being negative) */ 236 | return 0; /* no more codepoints */ 237 | else { 238 | utfint code; 239 | const char *next = utf8_decode(s + n, &code, strict); 240 | if (next == NULL || iscontp(next)) 241 | return luaL_error(L, MSGInvalid); 242 | lua_pushinteger(L, n + 1); 243 | lua_pushinteger(L, code); 244 | return 2; 245 | } 246 | } 247 | 248 | 249 | static int iter_auxstrict (lua_State *L) { 250 | return iter_aux(L, 1); 251 | } 252 | 253 | static int iter_auxlax (lua_State *L) { 254 | return iter_aux(L, 0); 255 | } 256 | 257 | 258 | static int iter_codes (lua_State *L) { 259 | int lax = lua_toboolean(L, 2); 260 | const char *s = luaL_checkstring(L, 1); 261 | luaL_argcheck(L, !iscontp(s), 1, MSGInvalid); 262 | lua_pushcfunction(L, lax ? iter_auxlax : iter_auxstrict); 263 | lua_pushvalue(L, 1); 264 | lua_pushinteger(L, 0); 265 | return 3; 266 | } 267 | 268 | 269 | /* pattern to match a single UTF-8 character */ 270 | #define UTF8PATT "[\0-\x7F\xC2-\xFD][\x80-\xBF]*" 271 | 272 | 273 | static const luaL_Reg funcs[] = { 274 | {"offset", byteoffset}, 275 | {"codepoint", codepoint}, 276 | {"char", utfchar}, 277 | {"len", utflen}, 278 | {"codes", iter_codes}, 279 | /* placeholders */ 280 | {"charpattern", NULL}, 281 | {NULL, NULL} 282 | }; 283 | 284 | 285 | LUAMOD_API int luaopen_utf8 (lua_State *L) { 286 | luaL_newlib(L, funcs); 287 | lua_pushlstring(L, UTF8PATT, sizeof(UTF8PATT)/sizeof(char) - 1); 288 | lua_setfield(L, -2, "charpattern"); 289 | return 1; 290 | } 291 | 292 | -------------------------------------------------------------------------------- /src/lvm.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lvm.h $ 3 | ** Lua virtual machine 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lvm_h 8 | #define lvm_h 9 | 10 | 11 | #include "ldo.h" 12 | #include "lobject.h" 13 | #include "ltm.h" 14 | 15 | 16 | #if !defined(LUA_NOCVTN2S) 17 | #define cvt2str(o) ttisnumber(o) 18 | #else 19 | #define cvt2str(o) 0 /* no conversion from numbers to strings */ 20 | #endif 21 | 22 | 23 | #if !defined(LUA_NOCVTS2N) 24 | #define cvt2num(o) ttisstring(o) 25 | #else 26 | #define cvt2num(o) 0 /* no conversion from strings to numbers */ 27 | #endif 28 | 29 | 30 | /* 31 | ** You can define LUA_FLOORN2I if you want to convert floats to integers 32 | ** by flooring them (instead of raising an error if they are not 33 | ** integral values) 34 | */ 35 | #if !defined(LUA_FLOORN2I) 36 | #define LUA_FLOORN2I F2Ieq 37 | #endif 38 | 39 | 40 | /* 41 | ** Rounding modes for float->integer coercion 42 | */ 43 | typedef enum { 44 | F2Ieq, /* no rounding; accepts only integral values */ 45 | F2Ifloor, /* takes the floor of the number */ 46 | F2Iceil /* takes the ceil of the number */ 47 | } F2Imod; 48 | 49 | 50 | /* convert an object to a float (including string coercion) */ 51 | #define tonumber(o,n) \ 52 | (ttisfloat(o) ? (*(n) = fltvalue(o), 1) : luaV_tonumber_(o,n)) 53 | 54 | 55 | /* convert an object to a float (without string coercion) */ 56 | #define tonumberns(o,n) \ 57 | (ttisfloat(o) ? ((n) = fltvalue(o), 1) : \ 58 | (ttisinteger(o) ? ((n) = cast_num(ivalue(o)), 1) : 0)) 59 | 60 | 61 | /* convert an object to an integer (including string coercion) */ 62 | #define tointeger(o,i) \ 63 | (l_likely(ttisinteger(o)) ? (*(i) = ivalue(o), 1) \ 64 | : luaV_tointeger(o,i,LUA_FLOORN2I)) 65 | 66 | 67 | /* convert an object to an integer (without string coercion) */ 68 | #define tointegerns(o,i) \ 69 | (l_likely(ttisinteger(o)) ? (*(i) = ivalue(o), 1) \ 70 | : luaV_tointegerns(o,i,LUA_FLOORN2I)) 71 | 72 | 73 | #define intop(op,v1,v2) l_castU2S(l_castS2U(v1) op l_castS2U(v2)) 74 | 75 | #define luaV_rawequalobj(t1,t2) luaV_equalobj(NULL,t1,t2) 76 | 77 | 78 | /* 79 | ** fast track for 'gettable': if 't' is a table and 't[k]' is present, 80 | ** return 1 with 'slot' pointing to 't[k]' (position of final result). 81 | ** Otherwise, return 0 (meaning it will have to check metamethod) 82 | ** with 'slot' pointing to an empty 't[k]' (if 't' is a table) or NULL 83 | ** (otherwise). 'f' is the raw get function to use. 84 | */ 85 | #define luaV_fastget(L,t,k,slot,f) \ 86 | (!ttistable(t) \ 87 | ? (slot = NULL, 0) /* not a table; 'slot' is NULL and result is 0 */ \ 88 | : (slot = f(hvalue(t), k), /* else, do raw access */ \ 89 | !isempty(slot))) /* result not empty? */ 90 | 91 | 92 | /* 93 | ** Special case of 'luaV_fastget' for integers, inlining the fast case 94 | ** of 'luaH_getint'. 95 | */ 96 | #define luaV_fastgeti(L,t,k,slot) \ 97 | (!ttistable(t) \ 98 | ? (slot = NULL, 0) /* not a table; 'slot' is NULL and result is 0 */ \ 99 | : (slot = (l_castS2U(k) - 1u < hvalue(t)->alimit) \ 100 | ? &hvalue(t)->array[k - 1] : luaH_getint(hvalue(t), k), \ 101 | !isempty(slot))) /* result not empty? */ 102 | 103 | 104 | /* 105 | ** Finish a fast set operation (when fast get succeeds). In that case, 106 | ** 'slot' points to the place to put the value. 107 | */ 108 | #define luaV_finishfastset(L,t,slot,v) \ 109 | { setobj2t(L, cast(TValue *,slot), v); \ 110 | luaC_barrierback(L, gcvalue(t), v); } 111 | 112 | 113 | /* 114 | ** Shift right is the same as shift left with a negative 'y' 115 | */ 116 | #define luaV_shiftr(x,y) luaV_shiftl(x,intop(-, 0, y)) 117 | 118 | 119 | 120 | LUAI_FUNC int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2); 121 | LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); 122 | LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r); 123 | LUAI_FUNC int luaV_tonumber_ (const TValue *obj, lua_Number *n); 124 | LUAI_FUNC int luaV_tointeger (const TValue *obj, lua_Integer *p, F2Imod mode); 125 | LUAI_FUNC int luaV_tointegerns (const TValue *obj, lua_Integer *p, 126 | F2Imod mode); 127 | LUAI_FUNC int luaV_flttointeger (lua_Number n, lua_Integer *p, F2Imod mode); 128 | LUAI_FUNC void luaV_finishget (lua_State *L, const TValue *t, TValue *key, 129 | StkId val, const TValue *slot); 130 | LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key, 131 | TValue *val, const TValue *slot); 132 | LUAI_FUNC void luaV_finishOp (lua_State *L); 133 | LUAI_FUNC void luaV_execute (lua_State *L, CallInfo *ci); 134 | LUAI_FUNC void luaV_concat (lua_State *L, int total); 135 | LUAI_FUNC lua_Integer luaV_idiv (lua_State *L, lua_Integer x, lua_Integer y); 136 | LUAI_FUNC lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y); 137 | LUAI_FUNC lua_Number luaV_modf (lua_State *L, lua_Number x, lua_Number y); 138 | LUAI_FUNC lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y); 139 | LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb); 140 | 141 | #endif 142 | -------------------------------------------------------------------------------- /src/lzio.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lzio.c $ 3 | ** Buffered streams 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lzio_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "llimits.h" 18 | #include "lmem.h" 19 | #include "lstate.h" 20 | #include "lzio.h" 21 | 22 | 23 | int luaZ_fill (ZIO *z) { 24 | size_t size; 25 | lua_State *L = z->L; 26 | const char *buff; 27 | lua_unlock(L); 28 | buff = z->reader(L, z->data, &size); 29 | lua_lock(L); 30 | if (buff == NULL || size == 0) 31 | return EOZ; 32 | z->n = size - 1; /* discount char being returned */ 33 | z->p = buff; 34 | return cast_uchar(*(z->p++)); 35 | } 36 | 37 | 38 | void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) { 39 | z->L = L; 40 | z->reader = reader; 41 | z->data = data; 42 | z->n = 0; 43 | z->p = NULL; 44 | } 45 | 46 | 47 | /* --------------------------------------------------------------- read --- */ 48 | size_t luaZ_read (ZIO *z, void *b, size_t n) { 49 | while (n) { 50 | size_t m; 51 | if (z->n == 0) { /* no bytes in buffer? */ 52 | if (luaZ_fill(z) == EOZ) /* try to read more */ 53 | return n; /* no more input; return number of missing bytes */ 54 | else { 55 | z->n++; /* luaZ_fill consumed first byte; put it back */ 56 | z->p--; 57 | } 58 | } 59 | m = (n <= z->n) ? n : z->n; /* min. between n and z->n */ 60 | memcpy(b, z->p, m); 61 | z->n -= m; 62 | z->p += m; 63 | b = (char *)b + m; 64 | n -= m; 65 | } 66 | return 0; 67 | } 68 | 69 | -------------------------------------------------------------------------------- /src/lzio.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lzio.h $ 3 | ** Buffered streams 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lzio_h 9 | #define lzio_h 10 | 11 | #include "lua.h" 12 | 13 | #include "lmem.h" 14 | 15 | 16 | #define EOZ (-1) /* end of stream */ 17 | 18 | typedef struct Zio ZIO; 19 | 20 | #define zgetc(z) (((z)->n--)>0 ? cast_uchar(*(z)->p++) : luaZ_fill(z)) 21 | 22 | 23 | typedef struct Mbuffer { 24 | char *buffer; 25 | size_t n; 26 | size_t buffsize; 27 | } Mbuffer; 28 | 29 | #define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0) 30 | 31 | #define luaZ_buffer(buff) ((buff)->buffer) 32 | #define luaZ_sizebuffer(buff) ((buff)->buffsize) 33 | #define luaZ_bufflen(buff) ((buff)->n) 34 | 35 | #define luaZ_buffremove(buff,i) ((buff)->n -= (i)) 36 | #define luaZ_resetbuffer(buff) ((buff)->n = 0) 37 | 38 | 39 | #define luaZ_resizebuffer(L, buff, size) \ 40 | ((buff)->buffer = luaM_reallocvchar(L, (buff)->buffer, \ 41 | (buff)->buffsize, size), \ 42 | (buff)->buffsize = size) 43 | 44 | #define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0) 45 | 46 | 47 | LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, 48 | void *data); 49 | LUAI_FUNC size_t luaZ_read (ZIO* z, void *b, size_t n); /* read next n bytes */ 50 | 51 | 52 | 53 | /* --------- Private Part ------------------ */ 54 | 55 | struct Zio { 56 | size_t n; /* bytes still unread */ 57 | const char *p; /* current position in buffer */ 58 | lua_Reader reader; /* reader function */ 59 | void *data; /* additional data */ 60 | lua_State *L; /* Lua state (for reader) */ 61 | }; 62 | 63 | 64 | LUAI_FUNC int luaZ_fill (ZIO *z); 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #================================ 2 | # Project setup. 3 | #================================ 4 | cmake_minimum_required(VERSION 3.30) 5 | project(lua_test LANGUAGES CXX C) 6 | 7 | set_property(GLOBAL PROPERTY USE_FOLDERS ON) 8 | 9 | #================================ 10 | # Directory variables. 11 | #================================ 12 | set(ROOT_DIR ${PROJECT_SOURCE_DIR}) 13 | set(CMAKE_DIR ${ROOT_DIR}/../cmake) 14 | list(APPEND CMAKE_MODULE_PATH ${CMAKE_DIR}) 15 | 16 | #================================ 17 | # Packages. 18 | #================================ 19 | find_package(lua 5.4.7 QUIET) 20 | 21 | if (NOT lua_FOUND) 22 | include(FetchContent) 23 | FetchContent_Declare( 24 | lua 25 | GIT_REPOSITORY https://github.com/marovira/lua 26 | ) 27 | 28 | FetchContent_MakeAvailable(lua) 29 | list(APPEND CMAKE_MODULE_PATH ${lua_SOURCE_DIR}/cmake) 30 | endif() 31 | 32 | source_group("source" FILES ${ROOT_DIR}/main.cpp) 33 | add_executable(lua_test ${ROOT_DIR}/main.cpp) 34 | target_link_libraries(lua_test PRIVATE lua::lua) 35 | -------------------------------------------------------------------------------- /test/CMakePresets.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "cmakeMinimumRequired":{ 4 | "major": 3, 5 | "minor": 30, 6 | "patch": 0 7 | }, 8 | "configurePresets": [ 9 | { 10 | "name": "default", 11 | "displayName": "default", 12 | "hidden": true, 13 | "binaryDir": "${sourceDir}/build" 14 | }, 15 | { 16 | "name": "unix", 17 | "displayName": "unix", 18 | "hidden": true, 19 | "inherits": "default", 20 | "generator": "Unix Makefiles" 21 | }, 22 | { 23 | "name": "msvc", 24 | "displayName": "MSVC", 25 | "inherits": "default", 26 | "description": "Default build for MSVC", 27 | "generator": "Visual Studio 17 2022" 28 | }, 29 | { 30 | "name": "linux", 31 | "displayName": "Linux", 32 | "description": "Default build for Linux systems", 33 | "inherits": "unix" 34 | }, 35 | { 36 | "name": "macOS", 37 | "displayName": "macOS", 38 | "description": "Default build for macOS", 39 | "inherits": "unix" 40 | } 41 | ] 42 | } 43 | -------------------------------------------------------------------------------- /test/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | lua_State* L = luaL_newstate(); 7 | luaL_openlibs(L); 8 | 9 | lua_close(L); 10 | return 0; 11 | } --------------------------------------------------------------------------------